]> git.hungrycats.org Git - linux/commitdiff
[IPV4,6]: Use common storage for cork'd flow, needed to handle mapped-ipv4 ipv6 addre...
authorHideaki Yoshifuji <yoshfuji@linux-ipv6.org>
Sun, 26 Oct 2003 15:58:17 +0000 (07:58 -0800)
committerDavid S. Miller <davem@nuts.ninka.net>
Sun, 26 Oct 2003 15:58:17 +0000 (07:58 -0800)
include/linux/ip.h
include/linux/ipv6.h
include/linux/udp.h
net/ipv4/udp.c
net/ipv6/ip6_output.c
net/ipv6/udp.c

index ac117b884331a0a21d4fd8e6998299c06619d0ce..1adc75a76926a2e717ee7634b4bc07054a60a6b1 100644 (file)
@@ -83,6 +83,7 @@
 #include <linux/types.h>
 #include <net/sock.h>
 #include <linux/igmp.h>
+#include <net/flow.h>
 
 struct ip_options {
   __u32                faddr;                          /* Saved first hop address */
@@ -141,6 +142,7 @@ struct inet_opt {
                struct rtable           *rt;
                int                     length; /* Total length of all frames */
                u32                     addr;
+               struct flowi            fl;
        } cork;
 };
 
index cabbeb633fde266b8e5504004703cb4cdd2131ce..da2e64899c9574e04f67e65df58255352feaa05b 100644 (file)
@@ -174,7 +174,6 @@ enum {
 #include <net/if_inet6.h>       /* struct ipv6_mc_socklist */
 #include <linux/tcp.h>
 #include <linux/udp.h>
-#include <net/flow.h>
 
 /* 
    This structure contains results of exthdrs parsing
@@ -235,7 +234,6 @@ struct ipv6_pinfo {
        struct {
                struct ipv6_txoptions *opt;
                struct rt6_info *rt;
-               struct flowi fl;
                int hop_limit;
        } cork;
 };
index 5269673e007dde099c2bc0341476ab0cc05ed146..492b258c76c84e8fc9e674f7db87b47c0ca793e2 100644 (file)
@@ -44,13 +44,9 @@ struct udp_opt {
        unsigned int    corkflag;       /* Cork is required */
        __u16           encap_type;     /* Is this an Encapsulation socket? */
        /*
-        * Following members retains the infomation to create a UDP header
+        * Following member retains the infomation to create a UDP header
         * when the socket is uncorked.
         */
-       u32             saddr;          /* source address */
-       u32             daddr;          /* destination address */
-       __u16           sport;          /* source port */
-       __u16           dport;          /* destination port */
        __u16           len;            /* total length of pending frames */
 };
 
index f57dfd28743f3166538b80a80706574448fa66ec..fabe268b99855c7dbef6004c0e875229f0b9bf7a 100644 (file)
@@ -398,6 +398,8 @@ static void udp_flush_pending_frames(struct sock *sk)
  */
 static int udp_push_pending_frames(struct sock *sk, struct udp_opt *up)
 {
+       struct inet_opt *inet = inet_sk(sk);
+       struct flowi *fl = &inet->cork.fl;
        struct sk_buff *skb;
        struct udphdr *uh;
        int err = 0;
@@ -410,8 +412,8 @@ static int udp_push_pending_frames(struct sock *sk, struct udp_opt *up)
         * Create a UDP header
         */
        uh = skb->h.uh;
-       uh->source = up->sport;
-       uh->dest = up->dport;
+       uh->source = fl->fl_ip_sport;
+       uh->dest = fl->fl_ip_dport;
        uh->len = htons(up->len);
        uh->check = 0;
 
@@ -426,12 +428,12 @@ static int udp_push_pending_frames(struct sock *sk, struct udp_opt *up)
                 */
                if (skb->ip_summed == CHECKSUM_HW) {
                        skb->csum = offsetof(struct udphdr, check);
-                       uh->check = ~csum_tcpudp_magic(up->saddr, up->daddr,
+                       uh->check = ~csum_tcpudp_magic(fl->fl4_src, fl->fl4_dst,
                                        up->len, IPPROTO_UDP, 0);
                } else {
                        skb->csum = csum_partial((char *)uh,
                                        sizeof(struct udphdr), skb->csum);
-                       uh->check = csum_tcpudp_magic(up->saddr, up->daddr,
+                       uh->check = csum_tcpudp_magic(fl->fl4_src, fl->fl4_dst,
                                        up->len, IPPROTO_UDP, skb->csum);
                        if (uh->check == 0)
                                uh->check = -1;
@@ -456,7 +458,7 @@ static int udp_push_pending_frames(struct sock *sk, struct udp_opt *up)
                skb_queue_walk(&sk->sk_write_queue, skb) {
                        csum = csum_add(csum, skb->csum);
                }
-               uh->check = csum_tcpudp_magic(up->saddr, up->daddr,
+               uh->check = csum_tcpudp_magic(fl->fl4_src, fl->fl4_dst,
                                up->len, IPPROTO_UDP, csum);
                if (uh->check == 0)
                        uh->check = -1;
@@ -636,10 +638,10 @@ back_from_confirm:
        /*
         *      Now cork the socket to pend data.
         */
-       up->daddr = daddr;
-       up->dport = dport;
-       up->saddr = saddr;
-       up->sport = inet->sport;
+       inet->cork.fl.fl4_dst = daddr;
+       inet->cork.fl.fl_ip_dport = dport;
+       inet->cork.fl.fl4_src = saddr;
+       inet->cork.fl.fl_ip_sport = inet->sport;
        up->pending = 1;
 
 do_append_data:
index 8ad10be871de6c08f58001fb634750810fb9fc1d..fab42831db5a8297b9aea985503344a408c1b24f 100644 (file)
@@ -1239,7 +1239,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offse
                }
                dst_hold(&rt->u.dst);
                np->cork.rt = rt;
-               np->cork.fl = *fl;
+               inet->cork.fl = *fl;
                np->cork.hop_limit = hlimit;
                inet->cork.fragsize = mtu = dst_pmtu(&rt->u.dst);
                inet->cork.length = 0;
@@ -1250,6 +1250,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offse
                transhdrlen += exthdrlen;
        } else {
                rt = np->cork.rt;
+               fl = &inet->cork.fl;
                if (inet->cork.flags & IPCORK_OPT)
                        opt = np->cork.opt;
                transhdrlen = 0;
@@ -1423,7 +1424,7 @@ int ip6_push_pending_frames(struct sock *sk)
        struct ipv6hdr *hdr;
        struct ipv6_txoptions *opt = np->cork.opt;
        struct rt6_info *rt = np->cork.rt;
-       struct flowi *fl = &np->cork.fl;
+       struct flowi *fl = &inet->cork.fl;
        unsigned char proto = fl->proto;
        int err = 0;
 
@@ -1487,7 +1488,7 @@ out:
                dst_release(&np->cork.rt->u.dst);
                np->cork.rt = NULL;
        }
-       memset(&np->cork.fl, 0, sizeof(np->cork.fl));
+       memset(&inet->cork.fl, 0, sizeof(inet->cork.fl));
        return err;
 error:
        goto out;
@@ -1512,5 +1513,5 @@ void ip6_flush_pending_frames(struct sock *sk)
                dst_release(&np->cork.rt->u.dst);
                np->cork.rt = NULL;
        }
-       memset(&np->cork.fl, 0, sizeof(np->cork.fl));
+       memset(&inet->cork.fl, 0, sizeof(inet->cork.fl));
 }
index 9087433412e1b09cb7b8da202fa6f769c65afbb5..1bd8e3ab03b881c45de8928d3ba828d8a0322866 100644 (file)
@@ -720,8 +720,8 @@ static int udp_v6_push_pending_frames(struct sock *sk, struct udp_opt *up)
 {
        struct sk_buff *skb;
        struct udphdr *uh;
-       struct ipv6_pinfo *np = inet6_sk(sk);
-       struct flowi *fl = &np->cork.fl;
+       struct inet_opt *inet = inet_sk(sk);
+       struct flowi *fl = &inet->cork.fl;
        int err = 0;
 
        /* Grab the skbuff where UDP header space exists. */
@@ -783,7 +783,7 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg
        struct in6_addr *daddr;
        struct ipv6_txoptions *opt = NULL;
        struct ip6_flowlabel *flowlabel = NULL;
-       struct flowi *fl = &np->cork.fl;
+       struct flowi *fl = &inet->cork.fl;
        struct dst_entry *dst;
        int addr_len = msg->msg_namelen;
        int ulen = len;
@@ -830,7 +830,7 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg
                if (sin6->sin6_port == 0)
                        return -EINVAL;
 
-               up->dport = sin6->sin6_port;
+               fl->fl_ip_dport = sin6->sin6_port;
                daddr = &sin6->sin6_addr;
 
                if (np->sndflow) {
@@ -859,7 +859,7 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg
                if (sk->sk_state != TCP_ESTABLISHED)
                        return -EDESTADDRREQ;
 
-               up->dport = inet->dport;
+               fl->fl_ip_dport = inet->dport;
                daddr = &np->daddr;
                fl->fl6_flowlabel = np->flow_label;
        }
@@ -874,7 +874,7 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg
 
                sin.sin_family = AF_INET;
                sin.sin_addr.s_addr = daddr->s6_addr32[3];
-               sin.sin_port = up->dport;
+               sin.sin_port = inet->cork.fl.fl_ip_dport;
                msg->msg_name = (struct sockaddr *)(&sin);
                msg->msg_namelen = sizeof(sin);
                fl6_sock_release(flowlabel);
@@ -911,7 +911,6 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg
        ipv6_addr_copy(&fl->fl6_dst, daddr);
        if (ipv6_addr_any(&fl->fl6_src) && !ipv6_addr_any(&np->saddr))
                ipv6_addr_copy(&fl->fl6_src, &np->saddr);
-       fl->fl_ip_dport = up->dport;
        fl->fl_ip_sport = inet->sport;
        
        /* merge ip6_build_xmit from ip6_output */