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

ipv6: add new struct ipcm6_cookie

In the sendmsg function of UDP, raw, ICMP and l2tp sockets, we use local
variables like hlimits, tclass, opt and dontfrag and pass them to corresponding
functions like ip6_make_skb, ip6_append_data and xxx_push_pending_frames.
This is not a good practice and makes it hard to add new parameters.
This fix introduces a new struct ipcm6_cookie similar to ipcm_cookie in
ipv4 and include the above mentioned variables. And we only pass the
pointer to this structure to corresponding functions. This makes it easier
to add new parameters in the future and makes the function cleaner.

Signed-off-by: Wei Wang <weiwan@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Wei Wang and committed by
David S. Miller
26879da5 1d2077ac

+123 -109
+12 -6
include/net/ipv6.h
··· 251 251 struct rcu_head rcu; 252 252 }; 253 253 254 + struct ipcm6_cookie { 255 + __s16 hlimit; 256 + __s16 tclass; 257 + __s8 dontfrag; 258 + struct ipv6_txoptions *opt; 259 + }; 260 + 254 261 static inline struct ipv6_txoptions *txopt_get(const struct ipv6_pinfo *np) 255 262 { 256 263 struct ipv6_txoptions *opt; ··· 870 863 int ip6_append_data(struct sock *sk, 871 864 int getfrag(void *from, char *to, int offset, int len, 872 865 int odd, struct sk_buff *skb), 873 - void *from, int length, int transhdrlen, int hlimit, 874 - int tclass, struct ipv6_txoptions *opt, struct flowi6 *fl6, 875 - struct rt6_info *rt, unsigned int flags, int dontfrag, 866 + void *from, int length, int transhdrlen, 867 + struct ipcm6_cookie *ipc6, struct flowi6 *fl6, 868 + struct rt6_info *rt, unsigned int flags, 876 869 const struct sockcm_cookie *sockc); 877 870 878 871 int ip6_push_pending_frames(struct sock *sk); ··· 888 881 int getfrag(void *from, char *to, int offset, 889 882 int len, int odd, struct sk_buff *skb), 890 883 void *from, int length, int transhdrlen, 891 - int hlimit, int tclass, struct ipv6_txoptions *opt, 892 - struct flowi6 *fl6, struct rt6_info *rt, 893 - unsigned int flags, int dontfrag, 884 + struct ipcm6_cookie *ipc6, struct flowi6 *fl6, 885 + struct rt6_info *rt, unsigned int flags, 894 886 const struct sockcm_cookie *sockc); 895 887 896 888 static inline struct sk_buff *ip6_finish_skb(struct sock *sk)
+1 -2
include/net/transp_v6.h
··· 41 41 struct sk_buff *skb); 42 42 43 43 int ip6_datagram_send_ctl(struct net *net, struct sock *sk, struct msghdr *msg, 44 - struct flowi6 *fl6, struct ipv6_txoptions *opt, 45 - int *hlimit, int *tclass, int *dontfrag, 44 + struct flowi6 *fl6, struct ipcm6_cookie *ipc6, 46 45 struct sockcm_cookie *sockc); 47 46 48 47 void ip6_dgram_sock_seq_show(struct seq_file *seq, struct sock *sp,
+6 -7
net/ipv6/datagram.c
··· 727 727 728 728 int ip6_datagram_send_ctl(struct net *net, struct sock *sk, 729 729 struct msghdr *msg, struct flowi6 *fl6, 730 - struct ipv6_txoptions *opt, 731 - int *hlimit, int *tclass, int *dontfrag, 732 - struct sockcm_cookie *sockc) 730 + struct ipcm6_cookie *ipc6, struct sockcm_cookie *sockc) 733 731 { 734 732 struct in6_pktinfo *src_info; 735 733 struct cmsghdr *cmsg; 736 734 struct ipv6_rt_hdr *rthdr; 737 735 struct ipv6_opt_hdr *hdr; 736 + struct ipv6_txoptions *opt = ipc6->opt; 738 737 int len; 739 738 int err = 0; 740 739 ··· 952 953 goto exit_f; 953 954 } 954 955 955 - *hlimit = *(int *)CMSG_DATA(cmsg); 956 - if (*hlimit < -1 || *hlimit > 0xff) { 956 + ipc6->hlimit = *(int *)CMSG_DATA(cmsg); 957 + if (ipc6->hlimit < -1 || ipc6->hlimit > 0xff) { 957 958 err = -EINVAL; 958 959 goto exit_f; 959 960 } ··· 973 974 goto exit_f; 974 975 975 976 err = 0; 976 - *tclass = tc; 977 + ipc6->tclass = tc; 977 978 978 979 break; 979 980 } ··· 991 992 goto exit_f; 992 993 993 994 err = 0; 994 - *dontfrag = df; 995 + ipc6->dontfrag = df; 995 996 996 997 break; 997 998 }
+16 -12
net/ipv6/icmp.c
··· 401 401 struct flowi6 fl6; 402 402 struct icmpv6_msg msg; 403 403 struct sockcm_cookie sockc_unused = {0}; 404 + struct ipcm6_cookie ipc6; 404 405 int iif = 0; 405 406 int addr_type = 0; 406 407 int len; 407 - int hlimit; 408 408 int err = 0; 409 409 u32 mark = IP6_REPLY_MARK(net, skb->mark); 410 410 ··· 507 507 if (IS_ERR(dst)) 508 508 goto out; 509 509 510 - hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); 510 + ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); 511 + ipc6.tclass = np->tclass; 512 + ipc6.dontfrag = np->dontfrag; 513 + ipc6.opt = NULL; 511 514 512 515 msg.skb = skb; 513 516 msg.offset = skb_network_offset(skb); ··· 529 526 530 527 err = ip6_append_data(sk, icmpv6_getfrag, &msg, 531 528 len + sizeof(struct icmp6hdr), 532 - sizeof(struct icmp6hdr), hlimit, 533 - np->tclass, NULL, &fl6, (struct rt6_info *)dst, 534 - MSG_DONTWAIT, np->dontfrag, &sockc_unused); 529 + sizeof(struct icmp6hdr), 530 + &ipc6, &fl6, (struct rt6_info *)dst, 531 + MSG_DONTWAIT, &sockc_unused); 535 532 if (err) { 536 533 ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTERRORS); 537 534 ip6_flush_pending_frames(sk); ··· 566 563 struct flowi6 fl6; 567 564 struct icmpv6_msg msg; 568 565 struct dst_entry *dst; 566 + struct ipcm6_cookie ipc6; 569 567 int err = 0; 570 - int hlimit; 571 - u8 tclass; 572 568 u32 mark = IP6_REPLY_MARK(net, skb->mark); 573 569 struct sockcm_cookie sockc_unused = {0}; 574 570 ··· 609 607 if (IS_ERR(dst)) 610 608 goto out; 611 609 612 - hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); 613 - 614 610 idev = __in6_dev_get(skb->dev); 615 611 616 612 msg.skb = skb; 617 613 msg.offset = 0; 618 614 msg.type = ICMPV6_ECHO_REPLY; 619 615 620 - tclass = ipv6_get_dsfield(ipv6_hdr(skb)); 616 + ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); 617 + ipc6.tclass = ipv6_get_dsfield(ipv6_hdr(skb)); 618 + ipc6.dontfrag = np->dontfrag; 619 + ipc6.opt = NULL; 620 + 621 621 err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr), 622 - sizeof(struct icmp6hdr), hlimit, tclass, NULL, &fl6, 622 + sizeof(struct icmp6hdr), &ipc6, &fl6, 623 623 (struct rt6_info *)dst, MSG_DONTWAIT, 624 - np->dontfrag, &sockc_unused); 624 + &sockc_unused); 625 625 626 626 if (err) { 627 627 __ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTERRORS);
+3 -3
net/ipv6/ip6_flowlabel.c
··· 373 373 struct msghdr msg; 374 374 struct flowi6 flowi6; 375 375 struct sockcm_cookie sockc_junk; 376 - int junk; 376 + struct ipcm6_cookie ipc6; 377 377 378 378 err = -ENOMEM; 379 379 fl->opt = kmalloc(sizeof(*fl->opt) + olen, GFP_KERNEL); ··· 390 390 msg.msg_control = (void *)(fl->opt+1); 391 391 memset(&flowi6, 0, sizeof(flowi6)); 392 392 393 - err = ip6_datagram_send_ctl(net, sk, &msg, &flowi6, fl->opt, 394 - &junk, &junk, &junk, &sockc_junk); 393 + ipc6.opt = fl->opt; 394 + err = ip6_datagram_send_ctl(net, sk, &msg, &flowi6, &ipc6, &sockc_junk); 395 395 if (err) 396 396 goto done; 397 397 err = -EINVAL;
+20 -22
net/ipv6/ip6_output.c
··· 1182 1182 } 1183 1183 1184 1184 static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork, 1185 - struct inet6_cork *v6_cork, 1186 - int hlimit, int tclass, struct ipv6_txoptions *opt, 1185 + struct inet6_cork *v6_cork, struct ipcm6_cookie *ipc6, 1187 1186 struct rt6_info *rt, struct flowi6 *fl6) 1188 1187 { 1189 1188 struct ipv6_pinfo *np = inet6_sk(sk); 1190 1189 unsigned int mtu; 1190 + struct ipv6_txoptions *opt = ipc6->opt; 1191 1191 1192 1192 /* 1193 1193 * setup for corking ··· 1229 1229 dst_hold(&rt->dst); 1230 1230 cork->base.dst = &rt->dst; 1231 1231 cork->fl.u.ip6 = *fl6; 1232 - v6_cork->hop_limit = hlimit; 1233 - v6_cork->tclass = tclass; 1232 + v6_cork->hop_limit = ipc6->hlimit; 1233 + v6_cork->tclass = ipc6->tclass; 1234 1234 if (rt->dst.flags & DST_XFRM_TUNNEL) 1235 1235 mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ? 1236 1236 rt->dst.dev->mtu : dst_mtu(&rt->dst); ··· 1258 1258 int getfrag(void *from, char *to, int offset, 1259 1259 int len, int odd, struct sk_buff *skb), 1260 1260 void *from, int length, int transhdrlen, 1261 - unsigned int flags, int dontfrag, 1261 + unsigned int flags, struct ipcm6_cookie *ipc6, 1262 1262 const struct sockcm_cookie *sockc) 1263 1263 { 1264 1264 struct sk_buff *skb, *skb_prev = NULL; ··· 1298 1298 sizeof(struct frag_hdr) : 0) + 1299 1299 rt->rt6i_nfheader_len; 1300 1300 1301 - if (cork->length + length > mtu - headersize && dontfrag && 1301 + if (cork->length + length > mtu - headersize && ipc6->dontfrag && 1302 1302 (sk->sk_protocol == IPPROTO_UDP || 1303 1303 sk->sk_protocol == IPPROTO_RAW)) { 1304 1304 ipv6_local_rxpmtu(sk, fl6, mtu - headersize + ··· 1564 1564 int ip6_append_data(struct sock *sk, 1565 1565 int getfrag(void *from, char *to, int offset, int len, 1566 1566 int odd, struct sk_buff *skb), 1567 - void *from, int length, int transhdrlen, int hlimit, 1568 - int tclass, struct ipv6_txoptions *opt, struct flowi6 *fl6, 1569 - struct rt6_info *rt, unsigned int flags, int dontfrag, 1567 + void *from, int length, int transhdrlen, 1568 + struct ipcm6_cookie *ipc6, struct flowi6 *fl6, 1569 + struct rt6_info *rt, unsigned int flags, 1570 1570 const struct sockcm_cookie *sockc) 1571 1571 { 1572 1572 struct inet_sock *inet = inet_sk(sk); ··· 1580 1580 /* 1581 1581 * setup for corking 1582 1582 */ 1583 - err = ip6_setup_cork(sk, &inet->cork, &np->cork, hlimit, 1584 - tclass, opt, rt, fl6); 1583 + err = ip6_setup_cork(sk, &inet->cork, &np->cork, 1584 + ipc6, rt, fl6); 1585 1585 if (err) 1586 1586 return err; 1587 1587 1588 - exthdrlen = (opt ? opt->opt_flen : 0); 1588 + exthdrlen = (ipc6->opt ? ipc6->opt->opt_flen : 0); 1589 1589 length += exthdrlen; 1590 1590 transhdrlen += exthdrlen; 1591 1591 } else { ··· 1595 1595 1596 1596 return __ip6_append_data(sk, fl6, &sk->sk_write_queue, &inet->cork.base, 1597 1597 &np->cork, sk_page_frag(sk), getfrag, 1598 - from, length, transhdrlen, flags, dontfrag, 1599 - sockc); 1598 + from, length, transhdrlen, flags, ipc6, sockc); 1600 1599 } 1601 1600 EXPORT_SYMBOL_GPL(ip6_append_data); 1602 1601 ··· 1751 1752 int getfrag(void *from, char *to, int offset, 1752 1753 int len, int odd, struct sk_buff *skb), 1753 1754 void *from, int length, int transhdrlen, 1754 - int hlimit, int tclass, 1755 - struct ipv6_txoptions *opt, struct flowi6 *fl6, 1755 + struct ipcm6_cookie *ipc6, struct flowi6 *fl6, 1756 1756 struct rt6_info *rt, unsigned int flags, 1757 - int dontfrag, const struct sockcm_cookie *sockc) 1757 + const struct sockcm_cookie *sockc) 1758 1758 { 1759 1759 struct inet_cork_full cork; 1760 1760 struct inet6_cork v6_cork; 1761 1761 struct sk_buff_head queue; 1762 - int exthdrlen = (opt ? opt->opt_flen : 0); 1762 + int exthdrlen = (ipc6->opt ? ipc6->opt->opt_flen : 0); 1763 1763 int err; 1764 1764 1765 1765 if (flags & MSG_PROBE) ··· 1770 1772 cork.base.addr = 0; 1771 1773 cork.base.opt = NULL; 1772 1774 v6_cork.opt = NULL; 1773 - err = ip6_setup_cork(sk, &cork, &v6_cork, hlimit, tclass, opt, rt, fl6); 1775 + err = ip6_setup_cork(sk, &cork, &v6_cork, ipc6, rt, fl6); 1774 1776 if (err) 1775 1777 return ERR_PTR(err); 1776 1778 1777 - if (dontfrag < 0) 1778 - dontfrag = inet6_sk(sk)->dontfrag; 1779 + if (ipc6->dontfrag < 0) 1780 + ipc6->dontfrag = inet6_sk(sk)->dontfrag; 1779 1781 1780 1782 err = __ip6_append_data(sk, fl6, &queue, &cork.base, &v6_cork, 1781 1783 &current->task_frag, getfrag, from, 1782 1784 length + exthdrlen, transhdrlen + exthdrlen, 1783 - flags, dontfrag, sockc); 1785 + flags, ipc6, sockc); 1784 1786 if (err) { 1785 1787 __ip6_flush_pending_frames(sk, &queue, &cork, &v6_cork); 1786 1788 return ERR_PTR(err);
+3 -3
net/ipv6/ipv6_sockglue.c
··· 473 473 struct msghdr msg; 474 474 struct flowi6 fl6; 475 475 struct sockcm_cookie sockc_junk; 476 - int junk; 476 + struct ipcm6_cookie ipc6; 477 477 478 478 memset(&fl6, 0, sizeof(fl6)); 479 479 fl6.flowi6_oif = sk->sk_bound_dev_if; ··· 503 503 504 504 msg.msg_controllen = optlen; 505 505 msg.msg_control = (void *)(opt+1); 506 + ipc6.opt = opt; 506 507 507 - retv = ip6_datagram_send_ctl(net, sk, &msg, &fl6, opt, &junk, 508 - &junk, &junk, &sockc_junk); 508 + retv = ip6_datagram_send_ctl(net, sk, &msg, &fl6, &ipc6, &sockc_junk); 509 509 if (retv) 510 510 goto done; 511 511 update:
+7 -5
net/ipv6/ping.c
··· 58 58 int iif = 0; 59 59 struct flowi6 fl6; 60 60 int err; 61 - int hlimit; 62 61 struct dst_entry *dst; 63 62 struct rt6_info *rt; 64 63 struct pingfakehdr pfh; 65 64 struct sockcm_cookie junk = {0}; 65 + struct ipcm6_cookie ipc6; 66 66 67 67 pr_debug("ping_v6_sendmsg(sk=%p,sk->num=%u)\n", inet, inet->inet_num); 68 68 ··· 139 139 pfh.wcheck = 0; 140 140 pfh.family = AF_INET6; 141 141 142 - hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); 142 + ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); 143 + ipc6.tclass = np->tclass; 144 + ipc6.dontfrag = np->dontfrag; 145 + ipc6.opt = NULL; 143 146 144 147 lock_sock(sk); 145 148 err = ip6_append_data(sk, ping_getfrag, &pfh, len, 146 - 0, hlimit, 147 - np->tclass, NULL, &fl6, rt, 148 - MSG_DONTWAIT, np->dontfrag, &junk); 149 + 0, &ipc6, &fl6, rt, 150 + MSG_DONTWAIT, &junk); 149 151 150 152 if (err) { 151 153 ICMP6_INC_STATS(sock_net(sk), rt->rt6i_idev,
+18 -15
net/ipv6/raw.c
··· 746 746 struct raw6_frag_vec rfv; 747 747 struct flowi6 fl6; 748 748 struct sockcm_cookie sockc; 749 + struct ipcm6_cookie ipc6; 749 750 int addr_len = msg->msg_namelen; 750 - int hlimit = -1; 751 - int tclass = -1; 752 - int dontfrag = -1; 753 751 u16 proto; 754 752 int err; 755 753 ··· 767 769 memset(&fl6, 0, sizeof(fl6)); 768 770 769 771 fl6.flowi6_mark = sk->sk_mark; 772 + 773 + ipc6.hlimit = -1; 774 + ipc6.tclass = -1; 775 + ipc6.dontfrag = -1; 776 + ipc6.opt = NULL; 770 777 771 778 if (sin6) { 772 779 if (addr_len < SIN6_LEN_RFC2133) ··· 830 827 opt = &opt_space; 831 828 memset(opt, 0, sizeof(struct ipv6_txoptions)); 832 829 opt->tot_len = sizeof(struct ipv6_txoptions); 830 + ipc6.opt = opt; 833 831 834 - err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt, 835 - &hlimit, &tclass, &dontfrag, 836 - &sockc); 832 + err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, &ipc6, &sockc); 837 833 if (err < 0) { 838 834 fl6_sock_release(flowlabel); 839 835 return err; ··· 848 846 if (!opt) { 849 847 opt = txopt_get(np); 850 848 opt_to_free = opt; 851 - } 849 + } 852 850 if (flowlabel) 853 851 opt = fl6_merge_options(&opt_space, flowlabel, opt); 854 852 opt = ipv6_fixup_options(&opt_space, opt); ··· 883 881 err = PTR_ERR(dst); 884 882 goto out; 885 883 } 886 - if (hlimit < 0) 887 - hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); 884 + if (ipc6.hlimit < 0) 885 + ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); 888 886 889 - if (tclass < 0) 890 - tclass = np->tclass; 887 + if (ipc6.tclass < 0) 888 + ipc6.tclass = np->tclass; 891 889 892 - if (dontfrag < 0) 893 - dontfrag = np->dontfrag; 890 + if (ipc6.dontfrag < 0) 891 + ipc6.dontfrag = np->dontfrag; 894 892 895 893 if (msg->msg_flags&MSG_CONFIRM) 896 894 goto do_confirm; ··· 899 897 if (inet->hdrincl) 900 898 err = rawv6_send_hdrinc(sk, msg, len, &fl6, &dst, msg->msg_flags); 901 899 else { 900 + ipc6.opt = opt; 902 901 lock_sock(sk); 903 902 err = ip6_append_data(sk, raw6_getfrag, &rfv, 904 - len, 0, hlimit, tclass, opt, &fl6, (struct rt6_info *)dst, 905 - msg->msg_flags, dontfrag, &sockc); 903 + len, 0, &ipc6, &fl6, (struct rt6_info *)dst, 904 + msg->msg_flags, &sockc); 906 905 907 906 if (err) 908 907 ip6_flush_pending_frames(sk);
+19 -19
net/ipv6/udp.c
··· 1064 1064 struct ip6_flowlabel *flowlabel = NULL; 1065 1065 struct flowi6 fl6; 1066 1066 struct dst_entry *dst; 1067 + struct ipcm6_cookie ipc6; 1067 1068 int addr_len = msg->msg_namelen; 1068 1069 int ulen = len; 1069 - int hlimit = -1; 1070 - int tclass = -1; 1071 - int dontfrag = -1; 1072 1070 int corkreq = up->corkflag || msg->msg_flags&MSG_MORE; 1073 1071 int err; 1074 1072 int connected = 0; 1075 1073 int is_udplite = IS_UDPLITE(sk); 1076 1074 int (*getfrag)(void *, char *, int, int, int, struct sk_buff *); 1077 1075 struct sockcm_cookie sockc; 1076 + 1077 + ipc6.hlimit = -1; 1078 + ipc6.tclass = -1; 1079 + ipc6.dontfrag = -1; 1078 1080 1079 1081 /* destination address check */ 1080 1082 if (sin6) { ··· 1202 1200 opt = &opt_space; 1203 1201 memset(opt, 0, sizeof(struct ipv6_txoptions)); 1204 1202 opt->tot_len = sizeof(*opt); 1203 + ipc6.opt = opt; 1205 1204 1206 - err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt, 1207 - &hlimit, &tclass, &dontfrag, 1208 - &sockc); 1205 + err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, &ipc6, &sockc); 1209 1206 if (err < 0) { 1210 1207 fl6_sock_release(flowlabel); 1211 1208 return err; ··· 1225 1224 if (flowlabel) 1226 1225 opt = fl6_merge_options(&opt_space, flowlabel, opt); 1227 1226 opt = ipv6_fixup_options(&opt_space, opt); 1227 + ipc6.opt = opt; 1228 1228 1229 1229 fl6.flowi6_proto = sk->sk_protocol; 1230 1230 if (!ipv6_addr_any(daddr)) ··· 1255 1253 goto out; 1256 1254 } 1257 1255 1258 - if (hlimit < 0) 1259 - hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); 1256 + if (ipc6.hlimit < 0) 1257 + ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); 1260 1258 1261 - if (tclass < 0) 1262 - tclass = np->tclass; 1259 + if (ipc6.tclass < 0) 1260 + ipc6.tclass = np->tclass; 1263 1261 1264 1262 if (msg->msg_flags&MSG_CONFIRM) 1265 1263 goto do_confirm; ··· 1270 1268 struct sk_buff *skb; 1271 1269 1272 1270 skb = ip6_make_skb(sk, getfrag, msg, ulen, 1273 - sizeof(struct udphdr), hlimit, tclass, opt, 1271 + sizeof(struct udphdr), &ipc6, 1274 1272 &fl6, (struct rt6_info *)dst, 1275 - msg->msg_flags, dontfrag, &sockc); 1273 + msg->msg_flags, &sockc); 1276 1274 err = PTR_ERR(skb); 1277 1275 if (!IS_ERR_OR_NULL(skb)) 1278 1276 err = udp_v6_send_skb(skb, &fl6); ··· 1293 1291 up->pending = AF_INET6; 1294 1292 1295 1293 do_append_data: 1296 - if (dontfrag < 0) 1297 - dontfrag = np->dontfrag; 1294 + if (ipc6.dontfrag < 0) 1295 + ipc6.dontfrag = np->dontfrag; 1298 1296 up->len += ulen; 1299 - err = ip6_append_data(sk, getfrag, msg, ulen, 1300 - sizeof(struct udphdr), hlimit, tclass, opt, &fl6, 1301 - (struct rt6_info *)dst, 1302 - corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags, dontfrag, 1303 - &sockc); 1297 + err = ip6_append_data(sk, getfrag, msg, ulen, sizeof(struct udphdr), 1298 + &ipc6, &fl6, (struct rt6_info *)dst, 1299 + corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags, &sockc); 1304 1300 if (err) 1305 1301 udp_v6_flush_pending_frames(sk); 1306 1302 else if (!corkreq)
+18 -15
net/l2tp/l2tp_ip6.c
··· 495 495 struct dst_entry *dst = NULL; 496 496 struct flowi6 fl6; 497 497 struct sockcm_cookie sockc_unused = {0}; 498 + struct ipcm6_cookie ipc6; 498 499 int addr_len = msg->msg_namelen; 499 - int hlimit = -1; 500 - int tclass = -1; 501 - int dontfrag = -1; 502 500 int transhdrlen = 4; /* zero session-id */ 503 501 int ulen = len + transhdrlen; 504 502 int err; ··· 517 519 memset(&fl6, 0, sizeof(fl6)); 518 520 519 521 fl6.flowi6_mark = sk->sk_mark; 522 + 523 + ipc6.hlimit = -1; 524 + ipc6.tclass = -1; 525 + ipc6.dontfrag = -1; 520 526 521 527 if (lsa) { 522 528 if (addr_len < SIN6_LEN_RFC2133) ··· 566 564 opt = &opt_space; 567 565 memset(opt, 0, sizeof(struct ipv6_txoptions)); 568 566 opt->tot_len = sizeof(struct ipv6_txoptions); 567 + ipc6.opt = opt; 569 568 570 - err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt, 571 - &hlimit, &tclass, &dontfrag, 572 - &sockc_unused); 573 - if (err < 0) { 569 + err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, &ipc6, 570 + &sockc_unused); 571 + if (err < 0) { 574 572 fl6_sock_release(flowlabel); 575 573 return err; 576 574 } ··· 590 588 if (flowlabel) 591 589 opt = fl6_merge_options(&opt_space, flowlabel, opt); 592 590 opt = ipv6_fixup_options(&opt_space, opt); 591 + ipc6.opt = opt; 593 592 594 593 fl6.flowi6_proto = sk->sk_protocol; 595 594 if (!ipv6_addr_any(daddr)) ··· 615 612 goto out; 616 613 } 617 614 618 - if (hlimit < 0) 619 - hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); 615 + if (ipc6.hlimit < 0) 616 + ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); 620 617 621 - if (tclass < 0) 622 - tclass = np->tclass; 618 + if (ipc6.tclass < 0) 619 + ipc6.tclass = np->tclass; 623 620 624 - if (dontfrag < 0) 625 - dontfrag = np->dontfrag; 621 + if (ipc6.dontfrag < 0) 622 + ipc6.dontfrag = np->dontfrag; 626 623 627 624 if (msg->msg_flags & MSG_CONFIRM) 628 625 goto do_confirm; ··· 630 627 back_from_confirm: 631 628 lock_sock(sk); 632 629 err = ip6_append_data(sk, ip_generic_getfrag, msg, 633 - ulen, transhdrlen, hlimit, tclass, opt, 630 + ulen, transhdrlen, &ipc6, 634 631 &fl6, (struct rt6_info *)dst, 635 - msg->msg_flags, dontfrag, &sockc_unused); 632 + msg->msg_flags, &sockc_unused); 636 633 if (err) 637 634 ip6_flush_pending_frames(sk); 638 635 else if (!(msg->msg_flags & MSG_MORE))