summaryrefslogtreecommitdiffstats
path: root/net/ipv6/raw.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/raw.c')
-rw-r--r--net/ipv6/raw.c33
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);