aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/udp.c')
-rw-r--r--net/ipv4/udp.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index bc0dab2593e0..544f435d1aff 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -804,6 +804,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
804 int corkreq = up->corkflag || msg->msg_flags&MSG_MORE; 804 int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
805 int (*getfrag)(void *, char *, int, int, int, struct sk_buff *); 805 int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
806 struct sk_buff *skb; 806 struct sk_buff *skb;
807 struct ip_options_data opt_copy;
807 808
808 if (len > 0xFFFF) 809 if (len > 0xFFFF)
809 return -EMSGSIZE; 810 return -EMSGSIZE;
@@ -877,22 +878,32 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
877 free = 1; 878 free = 1;
878 connected = 0; 879 connected = 0;
879 } 880 }
880 if (!ipc.opt) 881 if (!ipc.opt) {
881 ipc.opt = inet->opt; 882 struct ip_options_rcu *inet_opt;
883
884 rcu_read_lock();
885 inet_opt = rcu_dereference(inet->inet_opt);
886 if (inet_opt) {
887 memcpy(&opt_copy, inet_opt,
888 sizeof(*inet_opt) + inet_opt->opt.optlen);
889 ipc.opt = &opt_copy.opt;
890 }
891 rcu_read_unlock();
892 }
882 893
883 saddr = ipc.addr; 894 saddr = ipc.addr;
884 ipc.addr = faddr = daddr; 895 ipc.addr = faddr = daddr;
885 896
886 if (ipc.opt && ipc.opt->srr) { 897 if (ipc.opt && ipc.opt->opt.srr) {
887 if (!daddr) 898 if (!daddr)
888 return -EINVAL; 899 return -EINVAL;
889 faddr = ipc.opt->faddr; 900 faddr = ipc.opt->opt.faddr;
890 connected = 0; 901 connected = 0;
891 } 902 }
892 tos = RT_TOS(inet->tos); 903 tos = RT_TOS(inet->tos);
893 if (sock_flag(sk, SOCK_LOCALROUTE) || 904 if (sock_flag(sk, SOCK_LOCALROUTE) ||
894 (msg->msg_flags & MSG_DONTROUTE) || 905 (msg->msg_flags & MSG_DONTROUTE) ||
895 (ipc.opt && ipc.opt->is_strictroute)) { 906 (ipc.opt && ipc.opt->opt.is_strictroute)) {
896 tos |= RTO_ONLINK; 907 tos |= RTO_ONLINK;
897 connected = 0; 908 connected = 0;
898 } 909 }