* [PATCH 1/3] IPv6: Fix odd IPv6 header in UDPv6 packets when sending MSG_MORE flag
2003-10-26 9:50 ` YOSHIFUJI Hideaki / 吉藤英明
@ 2003-10-26 9:54 ` YOSHIFUJI Hideaki / 吉藤英明
2003-10-26 9:54 ` [PATCH 2/3] NET: store cork'ing flow information in common storage YOSHIFUJI Hideaki / 吉藤英明
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2003-10-26 9:54 UTC (permalink / raw)
To: davem; +Cc: netdev, miyazawa, yoshfuji
Hello.
> I'm about to send 3 patches to fix them.
>
> [1/3] IPv6: Odd IPv6 header in UDPv6 packets when sending MSG_MORE flag
> [2/3] NET: store cork'ing flow information in common storage in inet_opt
> [3/3] IPv6: breakage of sendmsg to IPv4-mapped address via UDPv6 socket
[1/3] IPv6: Odd IPv6 header in UDPv6 packets when sending MSG_MORE flag
D: Broken IPv6 header for UDPv6 was generated with MSG_MORE flag.
D: Remember cork'ed flow information in real storage.
===== include/linux/ipv6.h 1.12 vs edited =====
--- 1.12/include/linux/ipv6.h Sat Sep 13 09:25:13 2003
+++ edited/include/linux/ipv6.h Sun Oct 26 14:56:16 2003
@@ -174,6 +174,7 @@
#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
@@ -234,7 +235,7 @@
struct {
struct ipv6_txoptions *opt;
struct rt6_info *rt;
- struct flowi *fl;
+ struct flowi fl;
int hop_limit;
} cork;
};
===== net/ipv6/ip6_output.c 1.44 vs edited =====
--- 1.44/net/ipv6/ip6_output.c Mon Sep 1 17:44:26 2003
+++ edited/net/ipv6/ip6_output.c Sun Oct 26 14:56:16 2003
@@ -1239,7 +1239,7 @@
}
dst_hold(&rt->u.dst);
np->cork.rt = rt;
- np->cork.fl = fl;
+ np->cork.fl = *fl;
np->cork.hop_limit = hlimit;
inet->cork.fragsize = mtu = dst_pmtu(&rt->u.dst);
inet->cork.length = 0;
@@ -1423,7 +1423,7 @@
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 = &np->cork.fl;
unsigned char proto = fl->proto;
int err = 0;
@@ -1487,9 +1487,7 @@
dst_release(&np->cork.rt->u.dst);
np->cork.rt = NULL;
}
- if (np->cork.fl) {
- np->cork.fl = NULL;
- }
+ memset(&np->cork.fl, 0, sizeof(np->cork.fl));
return err;
error:
goto out;
@@ -1514,7 +1512,5 @@
dst_release(&np->cork.rt->u.dst);
np->cork.rt = NULL;
}
- if (np->cork.fl) {
- np->cork.fl = NULL;
- }
+ memset(&np->cork.fl, 0, sizeof(np->cork.fl));
}
===== net/ipv6/udp.c 1.50 vs edited =====
--- 1.50/net/ipv6/udp.c Thu Oct 9 00:27:40 2003
+++ edited/net/ipv6/udp.c Sun Oct 26 14:56:16 2003
@@ -721,7 +721,7 @@
struct sk_buff *skb;
struct udphdr *uh;
struct ipv6_pinfo *np = inet6_sk(sk);
- struct flowi *fl = np->cork.fl;
+ struct flowi *fl = &np->cork.fl;
int err = 0;
/* Grab the skbuff where UDP header space exists. */
@@ -783,7 +783,7 @@
struct in6_addr *daddr;
struct ipv6_txoptions *opt = NULL;
struct ip6_flowlabel *flowlabel = NULL;
- struct flowi fl;
+ struct flowi *fl = &np->cork.fl;
struct dst_entry *dst;
int addr_len = msg->msg_namelen;
int ulen = len;
@@ -812,7 +812,7 @@
}
ulen += sizeof(struct udphdr);
- memset(&fl, 0, sizeof(fl));
+ memset(fl, 0, sizeof(*fl));
if (sin6) {
if (sin6->sin6_family == AF_INET) {
@@ -834,9 +834,9 @@
daddr = &sin6->sin6_addr;
if (np->sndflow) {
- fl.fl6_flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
- if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
- flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
+ fl->fl6_flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
+ if (fl->fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
+ flowlabel = fl6_sock_lookup(sk, fl->fl6_flowlabel);
if (flowlabel == NULL)
return -EINVAL;
daddr = &flowlabel->dst;
@@ -854,14 +854,14 @@
if (addr_len >= sizeof(struct sockaddr_in6) &&
sin6->sin6_scope_id &&
ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL)
- fl.oif = sin6->sin6_scope_id;
+ fl->oif = sin6->sin6_scope_id;
} else {
if (sk->sk_state != TCP_ESTABLISHED)
return -EDESTADDRREQ;
up->dport = inet->dport;
daddr = &np->daddr;
- fl.fl6_flowlabel = np->flow_label;
+ fl->fl6_flowlabel = np->flow_label;
}
addr_type = ipv6_addr_type(daddr);
@@ -882,20 +882,20 @@
return udp_sendmsg(iocb, sk, msg, len);
}
- if (!fl.oif)
- fl.oif = sk->sk_bound_dev_if;
+ if (!fl->oif)
+ fl->oif = sk->sk_bound_dev_if;
if (msg->msg_controllen) {
opt = &opt_space;
memset(opt, 0, sizeof(struct ipv6_txoptions));
- err = datagram_send_ctl(msg, &fl, opt, &hlimit);
+ err = datagram_send_ctl(msg, fl, opt, &hlimit);
if (err < 0) {
fl6_sock_release(flowlabel);
return err;
}
- if ((fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) {
- flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
+ if ((fl->fl6_flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) {
+ flowlabel = fl6_sock_lookup(sk, fl->fl6_flowlabel);
if (flowlabel == NULL)
return -EINVAL;
}
@@ -907,28 +907,28 @@
if (flowlabel)
opt = fl6_merge_options(&opt_space, flowlabel, opt);
- fl.proto = IPPROTO_UDP;
- 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;
+ fl->proto = IPPROTO_UDP;
+ 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 */
if (opt && opt->srcrt) {
struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
- ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+ ipv6_addr_copy(&fl->fl6_dst, rt0->addr);
}
- if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
- fl.oif = np->mcast_oif;
+ if (!fl->oif && ipv6_addr_is_multicast(&fl->fl6_dst))
+ fl->oif = np->mcast_oif;
- err = ip6_dst_lookup(sk, &dst, &fl);
+ err = ip6_dst_lookup(sk, &dst, fl);
if (err)
goto out;
if (hlimit < 0) {
- if (ipv6_addr_is_multicast(&fl.fl6_dst))
+ if (ipv6_addr_is_multicast(&fl->fl6_dst))
hlimit = np->mcast_hops;
else
hlimit = np->hop_limit;
@@ -956,7 +956,7 @@
do_append_data:
up->len += ulen;
err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen, sizeof(struct udphdr),
- hlimit, opt, &fl, (struct rt6_info*)dst,
+ hlimit, opt, fl, (struct rt6_info*)dst,
corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
if (err)
udp_v6_flush_pending_frames(sk);
@@ -965,7 +965,7 @@
if (dst)
ip6_dst_store(sk, dst,
- !ipv6_addr_cmp(&fl.fl6_dst, &np->daddr) ?
+ !ipv6_addr_cmp(&fl->fl6_dst, &np->daddr) ?
&np->daddr : NULL);
if (err > 0)
err = np->recverr ? net_xmit_errno(err) : 0;
--
Hideaki YOSHIFUJI @ USAGI Project <yoshfuji@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 2/3] NET: store cork'ing flow information in common storage
2003-10-26 9:50 ` YOSHIFUJI Hideaki / 吉藤英明
2003-10-26 9:54 ` [PATCH 1/3] IPv6: Fix odd IPv6 header in UDPv6 packets when sending MSG_MORE flag YOSHIFUJI Hideaki / 吉藤英明
@ 2003-10-26 9:54 ` YOSHIFUJI Hideaki / 吉藤英明
2003-10-26 9:54 ` [PATCH 3/3] IPv6: breakage of sendmsg to IPv4-mapped address via UDPv6 socket YOSHIFUJI Hideaki / 吉藤英明
2003-10-27 7:56 ` ipv6 UDP MSG_MORE oops fix David S. Miller
3 siblings, 0 replies; 7+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2003-10-26 9:54 UTC (permalink / raw)
To: davem; +Cc: netdev, miyazawa, yoshfuji
Hello.
> I'm about to send 3 patches to fix them.
>
> [1/3] IPv6: Odd IPv6 header in UDPv6 packets when sending MSG_MORE flag
> [2/3] NET: store cork'ing flow information in common storage in inet_opt
> [3/3] IPv6: breakage of sendmsg to IPv4-mapped address via UDPv6 socket
[2/3] NET: store cork'ing flow information in common storage in inet_opt.
--- linux-2.5-net/include/linux/ip.h Sun Oct 19 01:10:46 2003
+++ linux-2.5-udp6_append_data/include/linux/ip.h Sun Oct 26 16:19:58 2003
@@ -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 rtable *rt;
int length; /* Total length of all frames */
u32 addr;
+ struct flowi fl;
} cork;
};
--- linux-2.5-net/include/linux/ipv6.h Sun Oct 26 16:19:19 2003
+++ linux-2.5-udp6_append_data/include/linux/ipv6.h Sun Oct 26 16:19:58 2003
@@ -174,7 +174,6 @@
#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 {
struct ipv6_txoptions *opt;
struct rt6_info *rt;
- struct flowi fl;
int hop_limit;
} cork;
};
--- linux-2.5-net/include/linux/udp.h Sun Oct 19 01:10:47 2003
+++ linux-2.5-udp6_append_data/include/linux/udp.h Sun Oct 26 16:20:00 2003
@@ -44,13 +44,9 @@
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 */
};
--- linux-2.5-net/net/ipv4/udp.c Sun Oct 19 01:10:53 2003
+++ linux-2.5-udp6_append_data/net/ipv4/udp.c Sun Oct 26 16:20:04 2003
@@ -398,6 +398,8 @@
*/
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 @@
* 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 @@
*/
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 @@
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 @@
/*
* 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:
--- linux-2.5-net/net/ipv6/udp.c Sun Oct 26 16:19:19 2003
+++ linux-2.5-udp6_append_data/net/ipv6/udp.c Sun Oct 26 16:20:00 2003
@@ -720,8 +720,8 @@
{
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 @@
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 @@
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 @@
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 @@
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 @@
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 */
--- linux-2.5-net/net/ipv6/ip6_output.c Sun Oct 26 16:19:19 2003
+++ linux-2.5-udp6_append_data/net/ipv6/ip6_output.c Sun Oct 26 16:20:00 2003
@@ -1239,7 +1239,7 @@
}
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 @@
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 @@
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 @@
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 @@
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));
}
--
Hideaki YOSHIFUJI @ USAGI Project <yoshfuji@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 3/3] IPv6: breakage of sendmsg to IPv4-mapped address via UDPv6 socket
2003-10-26 9:50 ` YOSHIFUJI Hideaki / 吉藤英明
2003-10-26 9:54 ` [PATCH 1/3] IPv6: Fix odd IPv6 header in UDPv6 packets when sending MSG_MORE flag YOSHIFUJI Hideaki / 吉藤英明
2003-10-26 9:54 ` [PATCH 2/3] NET: store cork'ing flow information in common storage YOSHIFUJI Hideaki / 吉藤英明
@ 2003-10-26 9:54 ` YOSHIFUJI Hideaki / 吉藤英明
2003-10-27 7:56 ` ipv6 UDP MSG_MORE oops fix David S. Miller
3 siblings, 0 replies; 7+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2003-10-26 9:54 UTC (permalink / raw)
To: davem; +Cc: netdev, miyazawa, yoshfuji
Hello.
> I'm about to send 3 patches to fix them.
>
> [1/3] IPv6: Odd IPv6 header in UDPv6 packets when sending MSG_MORE flag
> [2/3] NET: store cork'ing flow information in common storage in inet_opt
> [3/3] IPv6: breakage of sendmsg to IPv4-mapped address via UDPv6 socket
[3/3] IPv6: breakage of sendmsg to IPv4-mapped address via UDPv6 socket
D: Fixing breakage of sendmsg to IPv4-mapped address via UDPv6 socket;
D: check destination address before checking cork flag to process
D: appropriately.
--- linux-2.5-net/net/ipv4/udp.c Sun Oct 26 16:23:36 2003
+++ linux-2.5-udp6_append_data/net/ipv4/udp.c Sun Oct 26 16:23:55 2003
@@ -522,8 +522,13 @@
* The socket lock must be held while it's corked.
*/
lock_sock(sk);
- if (likely(up->pending))
+ if (likely(up->pending)) {
+ if (unlikely(up->pending != AF_INET)) {
+ release_sock(sk);
+ return -EINVAL;
+ }
goto do_append_data;
+ }
release_sock(sk);
}
ulen += sizeof(struct udphdr);
@@ -642,7 +647,7 @@
inet->cork.fl.fl_ip_dport = dport;
inet->cork.fl.fl4_src = saddr;
inet->cork.fl.fl_ip_sport = inet->sport;
- up->pending = 1;
+ up->pending = AF_INET;
do_append_data:
up->len += ulen;
--- linux-2.5-net/net/ipv6/udp.c Sun Oct 26 16:23:36 2003
+++ linux-2.5-udp6_append_data/net/ipv6/udp.c Sun Oct 26 16:23:55 2003
@@ -787,11 +787,56 @@
struct dst_entry *dst;
int addr_len = msg->msg_namelen;
int ulen = len;
- int addr_type;
int hlimit = -1;
int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
int err;
-
+
+ /* destination address check */
+ if (sin6) {
+ if (addr_len < offsetof(struct sockaddr, sa_data))
+ return -EINVAL;
+
+ switch (sin6->sin6_family) {
+ case AF_INET6:
+ if (addr_len < SIN6_LEN_RFC2133)
+ return -EINVAL;
+ daddr = &sin6->sin6_addr;
+ break;
+ case AF_INET:
+ goto do_udp_sendmsg;
+ case AF_UNSPEC:
+ msg->msg_name = sin6 = NULL;
+ msg->msg_namelen = addr_len = 0;
+ daddr = NULL;
+ break;
+ default:
+ return -EINVAL;
+ }
+ } else if (!up->pending) {
+ if (sk->sk_state != TCP_ESTABLISHED)
+ return -EDESTADDRREQ;
+ daddr = &np->daddr;
+ } else
+ daddr = NULL;
+
+ if (daddr) {
+ if (ipv6_addr_type(daddr) == IPV6_ADDR_MAPPED) {
+ struct sockaddr_in sin;
+ sin.sin_family = AF_INET;
+ sin.sin_port = sin6 ? sin6->sin6_port : inet->dport;
+ sin.sin_addr.s_addr = daddr->s6_addr[3];
+ msg->msg_name = &sin;
+ msg->msg_namelen = sizeof(sin);
+do_udp_sendmsg:
+ if (__ipv6_only_sock(sk))
+ return -ENETUNREACH;
+ return udp_sendmsg(iocb, sk, msg, len);
+ }
+ }
+
+ if (up->pending == AF_INET)
+ return udp_sendmsg(iocb, sk, msg, len);
+
/* Rough check on arithmetic overflow,
better check is made in ip6_build_xmit
*/
@@ -805,6 +850,10 @@
*/
lock_sock(sk);
if (likely(up->pending)) {
+ if (unlikely(up->pending != AF_INET6)) {
+ release_sock(sk);
+ return -EINVAL;
+ }
dst = NULL;
goto do_append_data;
}
@@ -815,18 +864,6 @@
memset(fl, 0, sizeof(*fl));
if (sin6) {
- if (sin6->sin6_family == AF_INET) {
- if (__ipv6_only_sock(sk))
- return -ENETUNREACH;
- return udp_sendmsg(iocb, sk, msg, len);
- }
-
- if (addr_len < SIN6_LEN_RFC2133)
- return -EINVAL;
-
- if (sin6->sin6_family && sin6->sin6_family != AF_INET6)
- return -EINVAL;
-
if (sin6->sin6_port == 0)
return -EINVAL;
@@ -864,24 +901,6 @@
fl->fl6_flowlabel = np->flow_label;
}
- addr_type = ipv6_addr_type(daddr);
-
- if (addr_type == IPV6_ADDR_MAPPED) {
- struct sockaddr_in sin;
-
- if (__ipv6_only_sock(sk))
- return -ENETUNREACH;
-
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = daddr->s6_addr32[3];
- sin.sin_port = inet->cork.fl.fl_ip_dport;
- msg->msg_name = (struct sockaddr *)(&sin);
- msg->msg_namelen = sizeof(sin);
- fl6_sock_release(flowlabel);
-
- return udp_sendmsg(iocb, sk, msg, len);
- }
-
if (!fl->oif)
fl->oif = sk->sk_bound_dev_if;
@@ -950,7 +969,7 @@
goto out;
}
- up->pending = 1;
+ up->pending = AF_INET6;
do_append_data:
up->len += ulen;
--
Hideaki YOSHIFUJI @ USAGI Project <yoshfuji@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: ipv6 UDP MSG_MORE oops fix
2003-10-26 9:50 ` YOSHIFUJI Hideaki / 吉藤英明
` (2 preceding siblings ...)
2003-10-26 9:54 ` [PATCH 3/3] IPv6: breakage of sendmsg to IPv4-mapped address via UDPv6 socket YOSHIFUJI Hideaki / 吉藤英明
@ 2003-10-27 7:56 ` David S. Miller
3 siblings, 0 replies; 7+ messages in thread
From: David S. Miller @ 2003-10-27 7:56 UTC (permalink / raw)
To: YOSHIFUJI Hideaki / _$B5HF#1QL@; +Cc: kuznet, netdev, yoshfuji, miyazawa
On Sun, 26 Oct 2003 18:50:23 +0900 (JST)
YOSHIFUJI Hideaki / _$B5HF#1QL@ <yoshfuji@linux-ipv6.org> wrote:
> [1/3] IPv6: Odd IPv6 header in UDPv6 packets when sending MSG_MORE flag
> [2/3] NET: store cork'ing flow information in common storage in inet_opt
> [3/3] IPv6: breakage of sendmsg to IPv4-mapped address via UDPv6 socket
All three patches applied, thanks Yoshfuji.
^ permalink raw reply [flat|nested] 7+ messages in thread