Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: relax PKTINFO non local ipv6 udp xmit check

Allow transparent sockets to be less restrictive about
the source ip of ipv6 udp packets being sent.

Google-Bug-Id: 5018138
Signed-off-by: Maciej Żenczykowski <maze@google.com>
CC: "Erik Kline" <ek@google.com>
CC: "Lorenzo Colitti" <lorenzo@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Maciej Żenczykowski and committed by
David S. Miller
ec0506db 0f43dd54

+13 -11
+1
include/net/transp_v6.h
··· 39 39 struct sk_buff *skb); 40 40 41 41 extern int datagram_send_ctl(struct net *net, 42 + struct sock *sk, 42 43 struct msghdr *msg, 43 44 struct flowi6 *fl6, 44 45 struct ipv6_txoptions *opt,
+3 -2
net/ipv6/datagram.c
··· 599 599 return 0; 600 600 } 601 601 602 - int datagram_send_ctl(struct net *net, 602 + int datagram_send_ctl(struct net *net, struct sock *sk, 603 603 struct msghdr *msg, struct flowi6 *fl6, 604 604 struct ipv6_txoptions *opt, 605 605 int *hlimit, int *tclass, int *dontfrag) ··· 658 658 659 659 if (addr_type != IPV6_ADDR_ANY) { 660 660 int strict = __ipv6_addr_src_scope(addr_type) <= IPV6_ADDR_SCOPE_LINKLOCAL; 661 - if (!ipv6_chk_addr(net, &src_info->ipi6_addr, 661 + if (!inet_sk(sk)->transparent && 662 + !ipv6_chk_addr(net, &src_info->ipi6_addr, 662 663 strict ? dev : NULL, 0)) 663 664 err = -EINVAL; 664 665 else
+4 -4
net/ipv6/ip6_flowlabel.c
··· 322 322 } 323 323 324 324 static struct ip6_flowlabel * 325 - fl_create(struct net *net, struct in6_flowlabel_req *freq, char __user *optval, 326 - int optlen, int *err_p) 325 + fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq, 326 + char __user *optval, int optlen, int *err_p) 327 327 { 328 328 struct ip6_flowlabel *fl = NULL; 329 329 int olen; ··· 360 360 msg.msg_control = (void*)(fl->opt+1); 361 361 memset(&flowi6, 0, sizeof(flowi6)); 362 362 363 - err = datagram_send_ctl(net, &msg, &flowi6, fl->opt, &junk, 363 + err = datagram_send_ctl(net, sk, &msg, &flowi6, fl->opt, &junk, 364 364 &junk, &junk); 365 365 if (err) 366 366 goto done; ··· 528 528 if (freq.flr_label & ~IPV6_FLOWLABEL_MASK) 529 529 return -EINVAL; 530 530 531 - fl = fl_create(net, &freq, optval, optlen, &err); 531 + fl = fl_create(net, sk, &freq, optval, optlen, &err); 532 532 if (fl == NULL) 533 533 return err; 534 534 sfl1 = kmalloc(sizeof(*sfl1), GFP_KERNEL);
+1 -1
net/ipv6/ipv6_sockglue.c
··· 475 475 msg.msg_controllen = optlen; 476 476 msg.msg_control = (void*)(opt+1); 477 477 478 - retv = datagram_send_ctl(net, &msg, &fl6, opt, &junk, &junk, 478 + retv = datagram_send_ctl(net, sk, &msg, &fl6, opt, &junk, &junk, 479 479 &junk); 480 480 if (retv) 481 481 goto done;
+2 -2
net/ipv6/raw.c
··· 817 817 memset(opt, 0, sizeof(struct ipv6_txoptions)); 818 818 opt->tot_len = sizeof(struct ipv6_txoptions); 819 819 820 - err = datagram_send_ctl(sock_net(sk), msg, &fl6, opt, &hlimit, 821 - &tclass, &dontfrag); 820 + err = datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt, 821 + &hlimit, &tclass, &dontfrag); 822 822 if (err < 0) { 823 823 fl6_sock_release(flowlabel); 824 824 return err;
+2 -2
net/ipv6/udp.c
··· 1090 1090 memset(opt, 0, sizeof(struct ipv6_txoptions)); 1091 1091 opt->tot_len = sizeof(*opt); 1092 1092 1093 - err = datagram_send_ctl(sock_net(sk), msg, &fl6, opt, &hlimit, 1094 - &tclass, &dontfrag); 1093 + err = datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt, 1094 + &hlimit, &tclass, &dontfrag); 1095 1095 if (err < 0) { 1096 1096 fl6_sock_release(flowlabel); 1097 1097 return err;