From b97edd05b13641f6f723db0e90c706d8291e5e6d Mon Sep 17 00:00:00 2001 From: Hideaki Yoshifuji Date: Sun, 26 Oct 2003 07:58:17 -0800 Subject: [PATCH] [IPV4,6]: Use common storage for cork'd flow, needed to handle mapped-ipv4 ipv6 addresses properly. --- include/linux/ip.h | 2 ++ include/linux/ipv6.h | 2 -- include/linux/udp.h | 6 +----- net/ipv4/udp.c | 20 +++++++++++--------- net/ipv6/ip6_output.c | 9 +++++---- net/ipv6/udp.c | 13 ++++++------- 6 files changed, 25 insertions(+), 27 deletions(-) diff --git a/include/linux/ip.h b/include/linux/ip.h index ac117b884331a..1adc75a76926a 100644 --- a/include/linux/ip.h +++ b/include/linux/ip.h @@ -83,6 +83,7 @@ #include #include #include +#include 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; }; diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index cabbeb633fde2..da2e64899c957 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -174,7 +174,6 @@ enum { #include /* struct ipv6_mc_socklist */ #include #include -#include /* 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; }; diff --git a/include/linux/udp.h b/include/linux/udp.h index 5269673e007dd..492b258c76c84 100644 --- a/include/linux/udp.h +++ b/include/linux/udp.h @@ -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 */ }; diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index f57dfd28743f3..fabe268b99855 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -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: diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 8ad10be871de6..fab42831db5a8 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -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)); } diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 9087433412e1b..1bd8e3ab03b88 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -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 */ -- 2.53.0