diff options
Diffstat (limited to 'net/ipv6/raw.c')
-rw-r--r-- | net/ipv6/raw.c | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index b07ce21983aa..896350df6423 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -746,10 +746,8 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
746 | struct raw6_frag_vec rfv; | 746 | struct raw6_frag_vec rfv; |
747 | struct flowi6 fl6; | 747 | struct flowi6 fl6; |
748 | struct sockcm_cookie sockc; | 748 | struct sockcm_cookie sockc; |
749 | struct ipcm6_cookie ipc6; | ||
749 | int addr_len = msg->msg_namelen; | 750 | int addr_len = msg->msg_namelen; |
750 | int hlimit = -1; | ||
751 | int tclass = -1; | ||
752 | int dontfrag = -1; | ||
753 | u16 proto; | 751 | u16 proto; |
754 | int err; | 752 | int err; |
755 | 753 | ||
@@ -770,6 +768,11 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
770 | 768 | ||
771 | fl6.flowi6_mark = sk->sk_mark; | 769 | fl6.flowi6_mark = sk->sk_mark; |
772 | 770 | ||
771 | ipc6.hlimit = -1; | ||
772 | ipc6.tclass = -1; | ||
773 | ipc6.dontfrag = -1; | ||
774 | ipc6.opt = NULL; | ||
775 | |||
773 | if (sin6) { | 776 | if (sin6) { |
774 | if (addr_len < SIN6_LEN_RFC2133) | 777 | if (addr_len < SIN6_LEN_RFC2133) |
775 | return -EINVAL; | 778 | return -EINVAL; |
@@ -827,10 +830,9 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
827 | opt = &opt_space; | 830 | opt = &opt_space; |
828 | memset(opt, 0, sizeof(struct ipv6_txoptions)); | 831 | memset(opt, 0, sizeof(struct ipv6_txoptions)); |
829 | opt->tot_len = sizeof(struct ipv6_txoptions); | 832 | opt->tot_len = sizeof(struct ipv6_txoptions); |
833 | ipc6.opt = opt; | ||
830 | 834 | ||
831 | err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt, | 835 | err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, &ipc6, &sockc); |
832 | &hlimit, &tclass, &dontfrag, | ||
833 | &sockc); | ||
834 | if (err < 0) { | 836 | if (err < 0) { |
835 | fl6_sock_release(flowlabel); | 837 | fl6_sock_release(flowlabel); |
836 | return err; | 838 | return err; |
@@ -846,7 +848,7 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
846 | if (!opt) { | 848 | if (!opt) { |
847 | opt = txopt_get(np); | 849 | opt = txopt_get(np); |
848 | opt_to_free = opt; | 850 | opt_to_free = opt; |
849 | } | 851 | } |
850 | if (flowlabel) | 852 | if (flowlabel) |
851 | opt = fl6_merge_options(&opt_space, flowlabel, opt); | 853 | opt = fl6_merge_options(&opt_space, flowlabel, opt); |
852 | opt = ipv6_fixup_options(&opt_space, opt); | 854 | opt = ipv6_fixup_options(&opt_space, opt); |
@@ -881,14 +883,14 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
881 | err = PTR_ERR(dst); | 883 | err = PTR_ERR(dst); |
882 | goto out; | 884 | goto out; |
883 | } | 885 | } |
884 | if (hlimit < 0) | 886 | if (ipc6.hlimit < 0) |
885 | hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); | 887 | ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); |
886 | 888 | ||
887 | if (tclass < 0) | 889 | if (ipc6.tclass < 0) |
888 | tclass = np->tclass; | 890 | ipc6.tclass = np->tclass; |
889 | 891 | ||
890 | if (dontfrag < 0) | 892 | if (ipc6.dontfrag < 0) |
891 | dontfrag = np->dontfrag; | 893 | ipc6.dontfrag = np->dontfrag; |
892 | 894 | ||
893 | if (msg->msg_flags&MSG_CONFIRM) | 895 | if (msg->msg_flags&MSG_CONFIRM) |
894 | goto do_confirm; | 896 | goto do_confirm; |
@@ -897,10 +899,11 @@ back_from_confirm: | |||
897 | if (inet->hdrincl) | 899 | if (inet->hdrincl) |
898 | err = rawv6_send_hdrinc(sk, msg, len, &fl6, &dst, msg->msg_flags); | 900 | err = rawv6_send_hdrinc(sk, msg, len, &fl6, &dst, msg->msg_flags); |
899 | else { | 901 | else { |
902 | ipc6.opt = opt; | ||
900 | lock_sock(sk); | 903 | lock_sock(sk); |
901 | err = ip6_append_data(sk, raw6_getfrag, &rfv, | 904 | err = ip6_append_data(sk, raw6_getfrag, &rfv, |
902 | len, 0, hlimit, tclass, opt, &fl6, (struct rt6_info *)dst, | 905 | len, 0, &ipc6, &fl6, (struct rt6_info *)dst, |
903 | msg->msg_flags, dontfrag, &sockc); | 906 | msg->msg_flags, &sockc); |
904 | 907 | ||
905 | if (err) | 908 | if (err) |
906 | ip6_flush_pending_frames(sk); | 909 | ip6_flush_pending_frames(sk); |