diff options
-rw-r--r-- | drivers/net/tun.c | 3 | ||||
-rw-r--r-- | include/net/ipv6.h | 6 | ||||
-rw-r--r-- | include/net/sock.h | 10 | ||||
-rw-r--r-- | net/can/raw.c | 2 | ||||
-rw-r--r-- | net/ipv4/ping.c | 5 | ||||
-rw-r--r-- | net/ipv4/raw.c | 11 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 20 | ||||
-rw-r--r-- | net/ipv4/udp.c | 7 | ||||
-rw-r--r-- | net/ipv6/icmp.c | 6 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 15 | ||||
-rw-r--r-- | net/ipv6/ping.c | 3 | ||||
-rw-r--r-- | net/ipv6/raw.c | 5 | ||||
-rw-r--r-- | net/ipv6/udp.c | 7 | ||||
-rw-r--r-- | net/l2tp/l2tp_ip6.c | 2 | ||||
-rw-r--r-- | net/packet/af_packet.c | 30 | ||||
-rw-r--r-- | net/socket.c | 10 |
16 files changed, 93 insertions, 49 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 510e90a6bb26..9abc36bf77ea 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -861,7 +861,8 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) | |||
861 | goto drop; | 861 | goto drop; |
862 | 862 | ||
863 | if (skb->sk && sk_fullsock(skb->sk)) { | 863 | if (skb->sk && sk_fullsock(skb->sk)) { |
864 | sock_tx_timestamp(skb->sk, &skb_shinfo(skb)->tx_flags); | 864 | sock_tx_timestamp(skb->sk, skb->sk->sk_tsflags, |
865 | &skb_shinfo(skb)->tx_flags); | ||
865 | sw_tx_timestamp(skb); | 866 | sw_tx_timestamp(skb); |
866 | } | 867 | } |
867 | 868 | ||
diff --git a/include/net/ipv6.h b/include/net/ipv6.h index d0aeb97aec5d..55ee1eb7d026 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h | |||
@@ -867,7 +867,8 @@ int ip6_append_data(struct sock *sk, | |||
867 | int odd, struct sk_buff *skb), | 867 | int odd, struct sk_buff *skb), |
868 | void *from, int length, int transhdrlen, int hlimit, | 868 | void *from, int length, int transhdrlen, int hlimit, |
869 | int tclass, struct ipv6_txoptions *opt, struct flowi6 *fl6, | 869 | int tclass, struct ipv6_txoptions *opt, struct flowi6 *fl6, |
870 | struct rt6_info *rt, unsigned int flags, int dontfrag); | 870 | struct rt6_info *rt, unsigned int flags, int dontfrag, |
871 | const struct sockcm_cookie *sockc); | ||
871 | 872 | ||
872 | int ip6_push_pending_frames(struct sock *sk); | 873 | int ip6_push_pending_frames(struct sock *sk); |
873 | 874 | ||
@@ -884,7 +885,8 @@ struct sk_buff *ip6_make_skb(struct sock *sk, | |||
884 | void *from, int length, int transhdrlen, | 885 | void *from, int length, int transhdrlen, |
885 | int hlimit, int tclass, struct ipv6_txoptions *opt, | 886 | int hlimit, int tclass, struct ipv6_txoptions *opt, |
886 | struct flowi6 *fl6, struct rt6_info *rt, | 887 | struct flowi6 *fl6, struct rt6_info *rt, |
887 | unsigned int flags, int dontfrag); | 888 | unsigned int flags, int dontfrag, |
889 | const struct sockcm_cookie *sockc); | ||
888 | 890 | ||
889 | static inline struct sk_buff *ip6_finish_skb(struct sock *sk) | 891 | static inline struct sk_buff *ip6_finish_skb(struct sock *sk) |
890 | { | 892 | { |
diff --git a/include/net/sock.h b/include/net/sock.h index af012da5e608..e91b87f54f99 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -2057,19 +2057,21 @@ static inline void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, | |||
2057 | sk->sk_stamp = skb->tstamp; | 2057 | sk->sk_stamp = skb->tstamp; |
2058 | } | 2058 | } |
2059 | 2059 | ||
2060 | void __sock_tx_timestamp(const struct sock *sk, __u8 *tx_flags); | 2060 | void __sock_tx_timestamp(__u16 tsflags, __u8 *tx_flags); |
2061 | 2061 | ||
2062 | /** | 2062 | /** |
2063 | * sock_tx_timestamp - checks whether the outgoing packet is to be time stamped | 2063 | * sock_tx_timestamp - checks whether the outgoing packet is to be time stamped |
2064 | * @sk: socket sending this packet | 2064 | * @sk: socket sending this packet |
2065 | * @tsflags: timestamping flags to use | ||
2065 | * @tx_flags: completed with instructions for time stamping | 2066 | * @tx_flags: completed with instructions for time stamping |
2066 | * | 2067 | * |
2067 | * Note : callers should take care of initial *tx_flags value (usually 0) | 2068 | * Note : callers should take care of initial *tx_flags value (usually 0) |
2068 | */ | 2069 | */ |
2069 | static inline void sock_tx_timestamp(const struct sock *sk, __u8 *tx_flags) | 2070 | static inline void sock_tx_timestamp(const struct sock *sk, __u16 tsflags, |
2071 | __u8 *tx_flags) | ||
2070 | { | 2072 | { |
2071 | if (unlikely(sk->sk_tsflags)) | 2073 | if (unlikely(tsflags)) |
2072 | __sock_tx_timestamp(sk, tx_flags); | 2074 | __sock_tx_timestamp(tsflags, tx_flags); |
2073 | if (unlikely(sock_flag(sk, SOCK_WIFI_STATUS))) | 2075 | if (unlikely(sock_flag(sk, SOCK_WIFI_STATUS))) |
2074 | *tx_flags |= SKBTX_WIFI_STATUS; | 2076 | *tx_flags |= SKBTX_WIFI_STATUS; |
2075 | } | 2077 | } |
diff --git a/net/can/raw.c b/net/can/raw.c index 2e67b1423cd3..972c187d40ab 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
@@ -755,7 +755,7 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) | |||
755 | if (err < 0) | 755 | if (err < 0) |
756 | goto free_skb; | 756 | goto free_skb; |
757 | 757 | ||
758 | sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags); | 758 | sock_tx_timestamp(sk, sk->sk_tsflags, &skb_shinfo(skb)->tx_flags); |
759 | 759 | ||
760 | skb->dev = dev; | 760 | skb->dev = dev; |
761 | skb->sk = sk; | 761 | skb->sk = sk; |
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index 670639bf9f7e..66ddcb60519a 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c | |||
@@ -737,6 +737,7 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
737 | /* no remote port */ | 737 | /* no remote port */ |
738 | } | 738 | } |
739 | 739 | ||
740 | ipc.sockc.tsflags = sk->sk_tsflags; | ||
740 | ipc.addr = inet->inet_saddr; | 741 | ipc.addr = inet->inet_saddr; |
741 | ipc.opt = NULL; | 742 | ipc.opt = NULL; |
742 | ipc.oif = sk->sk_bound_dev_if; | 743 | ipc.oif = sk->sk_bound_dev_if; |
@@ -744,8 +745,6 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
744 | ipc.ttl = 0; | 745 | ipc.ttl = 0; |
745 | ipc.tos = -1; | 746 | ipc.tos = -1; |
746 | 747 | ||
747 | sock_tx_timestamp(sk, &ipc.tx_flags); | ||
748 | |||
749 | if (msg->msg_controllen) { | 748 | if (msg->msg_controllen) { |
750 | err = ip_cmsg_send(sk, msg, &ipc, false); | 749 | err = ip_cmsg_send(sk, msg, &ipc, false); |
751 | if (unlikely(err)) { | 750 | if (unlikely(err)) { |
@@ -768,6 +767,8 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
768 | rcu_read_unlock(); | 767 | rcu_read_unlock(); |
769 | } | 768 | } |
770 | 769 | ||
770 | sock_tx_timestamp(sk, ipc.sockc.tsflags, &ipc.tx_flags); | ||
771 | |||
771 | saddr = ipc.addr; | 772 | saddr = ipc.addr; |
772 | ipc.addr = faddr = daddr; | 773 | ipc.addr = faddr = daddr; |
773 | 774 | ||
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 088ce665fc7b..438f50c1a676 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -339,8 +339,8 @@ int raw_rcv(struct sock *sk, struct sk_buff *skb) | |||
339 | 339 | ||
340 | static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4, | 340 | static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4, |
341 | struct msghdr *msg, size_t length, | 341 | struct msghdr *msg, size_t length, |
342 | struct rtable **rtp, | 342 | struct rtable **rtp, unsigned int flags, |
343 | unsigned int flags) | 343 | const struct sockcm_cookie *sockc) |
344 | { | 344 | { |
345 | struct inet_sock *inet = inet_sk(sk); | 345 | struct inet_sock *inet = inet_sk(sk); |
346 | struct net *net = sock_net(sk); | 346 | struct net *net = sock_net(sk); |
@@ -379,7 +379,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4, | |||
379 | 379 | ||
380 | skb->ip_summed = CHECKSUM_NONE; | 380 | skb->ip_summed = CHECKSUM_NONE; |
381 | 381 | ||
382 | sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags); | 382 | sock_tx_timestamp(sk, sockc->tsflags, &skb_shinfo(skb)->tx_flags); |
383 | 383 | ||
384 | skb->transport_header = skb->network_header; | 384 | skb->transport_header = skb->network_header; |
385 | err = -EFAULT; | 385 | err = -EFAULT; |
@@ -540,6 +540,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
540 | daddr = inet->inet_daddr; | 540 | daddr = inet->inet_daddr; |
541 | } | 541 | } |
542 | 542 | ||
543 | ipc.sockc.tsflags = sk->sk_tsflags; | ||
543 | ipc.addr = inet->inet_saddr; | 544 | ipc.addr = inet->inet_saddr; |
544 | ipc.opt = NULL; | 545 | ipc.opt = NULL; |
545 | ipc.tx_flags = 0; | 546 | ipc.tx_flags = 0; |
@@ -638,10 +639,10 @@ back_from_confirm: | |||
638 | 639 | ||
639 | if (inet->hdrincl) | 640 | if (inet->hdrincl) |
640 | err = raw_send_hdrinc(sk, &fl4, msg, len, | 641 | err = raw_send_hdrinc(sk, &fl4, msg, len, |
641 | &rt, msg->msg_flags); | 642 | &rt, msg->msg_flags, &ipc.sockc); |
642 | 643 | ||
643 | else { | 644 | else { |
644 | sock_tx_timestamp(sk, &ipc.tx_flags); | 645 | sock_tx_timestamp(sk, ipc.sockc.tsflags, &ipc.tx_flags); |
645 | 646 | ||
646 | if (!ipc.addr) | 647 | if (!ipc.addr) |
647 | ipc.addr = fl4.daddr; | 648 | ipc.addr = fl4.daddr; |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index ce3c9eb901a0..4d73858991af 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -428,13 +428,13 @@ void tcp_init_sock(struct sock *sk) | |||
428 | } | 428 | } |
429 | EXPORT_SYMBOL(tcp_init_sock); | 429 | EXPORT_SYMBOL(tcp_init_sock); |
430 | 430 | ||
431 | static void tcp_tx_timestamp(struct sock *sk, struct sk_buff *skb) | 431 | static void tcp_tx_timestamp(struct sock *sk, u16 tsflags, struct sk_buff *skb) |
432 | { | 432 | { |
433 | if (sk->sk_tsflags) { | 433 | if (sk->sk_tsflags || tsflags) { |
434 | struct skb_shared_info *shinfo = skb_shinfo(skb); | 434 | struct skb_shared_info *shinfo = skb_shinfo(skb); |
435 | struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); | 435 | struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); |
436 | 436 | ||
437 | sock_tx_timestamp(sk, &shinfo->tx_flags); | 437 | sock_tx_timestamp(sk, tsflags, &shinfo->tx_flags); |
438 | if (shinfo->tx_flags & SKBTX_ANY_TSTAMP) | 438 | if (shinfo->tx_flags & SKBTX_ANY_TSTAMP) |
439 | shinfo->tskey = TCP_SKB_CB(skb)->seq + skb->len - 1; | 439 | shinfo->tskey = TCP_SKB_CB(skb)->seq + skb->len - 1; |
440 | tcb->txstamp_ack = !!(shinfo->tx_flags & SKBTX_ACK_TSTAMP); | 440 | tcb->txstamp_ack = !!(shinfo->tx_flags & SKBTX_ACK_TSTAMP); |
@@ -959,7 +959,7 @@ new_segment: | |||
959 | offset += copy; | 959 | offset += copy; |
960 | size -= copy; | 960 | size -= copy; |
961 | if (!size) { | 961 | if (!size) { |
962 | tcp_tx_timestamp(sk, skb); | 962 | tcp_tx_timestamp(sk, sk->sk_tsflags, skb); |
963 | goto out; | 963 | goto out; |
964 | } | 964 | } |
965 | 965 | ||
@@ -1079,6 +1079,7 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) | |||
1079 | { | 1079 | { |
1080 | struct tcp_sock *tp = tcp_sk(sk); | 1080 | struct tcp_sock *tp = tcp_sk(sk); |
1081 | struct sk_buff *skb; | 1081 | struct sk_buff *skb; |
1082 | struct sockcm_cookie sockc; | ||
1082 | int flags, err, copied = 0; | 1083 | int flags, err, copied = 0; |
1083 | int mss_now = 0, size_goal, copied_syn = 0; | 1084 | int mss_now = 0, size_goal, copied_syn = 0; |
1084 | bool sg; | 1085 | bool sg; |
@@ -1121,6 +1122,15 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) | |||
1121 | /* 'common' sending to sendq */ | 1122 | /* 'common' sending to sendq */ |
1122 | } | 1123 | } |
1123 | 1124 | ||
1125 | sockc.tsflags = sk->sk_tsflags; | ||
1126 | if (msg->msg_controllen) { | ||
1127 | err = sock_cmsg_send(sk, msg, &sockc); | ||
1128 | if (unlikely(err)) { | ||
1129 | err = -EINVAL; | ||
1130 | goto out_err; | ||
1131 | } | ||
1132 | } | ||
1133 | |||
1124 | /* This should be in poll */ | 1134 | /* This should be in poll */ |
1125 | sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); | 1135 | sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); |
1126 | 1136 | ||
@@ -1239,7 +1249,7 @@ new_segment: | |||
1239 | 1249 | ||
1240 | copied += copy; | 1250 | copied += copy; |
1241 | if (!msg_data_left(msg)) { | 1251 | if (!msg_data_left(msg)) { |
1242 | tcp_tx_timestamp(sk, skb); | 1252 | tcp_tx_timestamp(sk, sockc.tsflags, skb); |
1243 | goto out; | 1253 | goto out; |
1244 | } | 1254 | } |
1245 | 1255 | ||
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index bccb4e11047a..45ff590661f4 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -1027,12 +1027,11 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
1027 | */ | 1027 | */ |
1028 | connected = 1; | 1028 | connected = 1; |
1029 | } | 1029 | } |
1030 | ipc.addr = inet->inet_saddr; | ||
1031 | 1030 | ||
1031 | ipc.sockc.tsflags = sk->sk_tsflags; | ||
1032 | ipc.addr = inet->inet_saddr; | ||
1032 | ipc.oif = sk->sk_bound_dev_if; | 1033 | ipc.oif = sk->sk_bound_dev_if; |
1033 | 1034 | ||
1034 | sock_tx_timestamp(sk, &ipc.tx_flags); | ||
1035 | |||
1036 | if (msg->msg_controllen) { | 1035 | if (msg->msg_controllen) { |
1037 | err = ip_cmsg_send(sk, msg, &ipc, sk->sk_family == AF_INET6); | 1036 | err = ip_cmsg_send(sk, msg, &ipc, sk->sk_family == AF_INET6); |
1038 | if (unlikely(err)) { | 1037 | if (unlikely(err)) { |
@@ -1059,6 +1058,8 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
1059 | saddr = ipc.addr; | 1058 | saddr = ipc.addr; |
1060 | ipc.addr = faddr = daddr; | 1059 | ipc.addr = faddr = daddr; |
1061 | 1060 | ||
1061 | sock_tx_timestamp(sk, ipc.sockc.tsflags, &ipc.tx_flags); | ||
1062 | |||
1062 | if (ipc.opt && ipc.opt->opt.srr) { | 1063 | if (ipc.opt && ipc.opt->opt.srr) { |
1063 | if (!daddr) | 1064 | if (!daddr) |
1064 | return -EINVAL; | 1065 | return -EINVAL; |
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 0a37ddc7af51..6b573ebe49de 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -400,6 +400,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) | |||
400 | struct icmp6hdr tmp_hdr; | 400 | struct icmp6hdr tmp_hdr; |
401 | struct flowi6 fl6; | 401 | struct flowi6 fl6; |
402 | struct icmpv6_msg msg; | 402 | struct icmpv6_msg msg; |
403 | struct sockcm_cookie sockc_unused = {0}; | ||
403 | int iif = 0; | 404 | int iif = 0; |
404 | int addr_type = 0; | 405 | int addr_type = 0; |
405 | int len; | 406 | int len; |
@@ -527,7 +528,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) | |||
527 | len + sizeof(struct icmp6hdr), | 528 | len + sizeof(struct icmp6hdr), |
528 | sizeof(struct icmp6hdr), hlimit, | 529 | sizeof(struct icmp6hdr), hlimit, |
529 | np->tclass, NULL, &fl6, (struct rt6_info *)dst, | 530 | np->tclass, NULL, &fl6, (struct rt6_info *)dst, |
530 | MSG_DONTWAIT, np->dontfrag); | 531 | MSG_DONTWAIT, np->dontfrag, &sockc_unused); |
531 | if (err) { | 532 | if (err) { |
532 | ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTERRORS); | 533 | ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTERRORS); |
533 | ip6_flush_pending_frames(sk); | 534 | ip6_flush_pending_frames(sk); |
@@ -566,6 +567,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb) | |||
566 | int hlimit; | 567 | int hlimit; |
567 | u8 tclass; | 568 | u8 tclass; |
568 | u32 mark = IP6_REPLY_MARK(net, skb->mark); | 569 | u32 mark = IP6_REPLY_MARK(net, skb->mark); |
570 | struct sockcm_cookie sockc_unused = {0}; | ||
569 | 571 | ||
570 | saddr = &ipv6_hdr(skb)->daddr; | 572 | saddr = &ipv6_hdr(skb)->daddr; |
571 | 573 | ||
@@ -617,7 +619,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb) | |||
617 | err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr), | 619 | err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr), |
618 | sizeof(struct icmp6hdr), hlimit, tclass, NULL, &fl6, | 620 | sizeof(struct icmp6hdr), hlimit, tclass, NULL, &fl6, |
619 | (struct rt6_info *)dst, MSG_DONTWAIT, | 621 | (struct rt6_info *)dst, MSG_DONTWAIT, |
620 | np->dontfrag); | 622 | np->dontfrag, &sockc_unused); |
621 | 623 | ||
622 | if (err) { | 624 | if (err) { |
623 | ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS); | 625 | ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS); |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 9428345d3a07..612f3d138bf0 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -1258,7 +1258,8 @@ static int __ip6_append_data(struct sock *sk, | |||
1258 | int getfrag(void *from, char *to, int offset, | 1258 | int getfrag(void *from, char *to, int offset, |
1259 | int len, int odd, struct sk_buff *skb), | 1259 | int len, int odd, struct sk_buff *skb), |
1260 | void *from, int length, int transhdrlen, | 1260 | void *from, int length, int transhdrlen, |
1261 | unsigned int flags, int dontfrag) | 1261 | unsigned int flags, int dontfrag, |
1262 | const struct sockcm_cookie *sockc) | ||
1262 | { | 1263 | { |
1263 | struct sk_buff *skb, *skb_prev = NULL; | 1264 | struct sk_buff *skb, *skb_prev = NULL; |
1264 | unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu; | 1265 | unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu; |
@@ -1329,7 +1330,7 @@ emsgsize: | |||
1329 | csummode = CHECKSUM_PARTIAL; | 1330 | csummode = CHECKSUM_PARTIAL; |
1330 | 1331 | ||
1331 | if (sk->sk_type == SOCK_DGRAM || sk->sk_type == SOCK_RAW) { | 1332 | if (sk->sk_type == SOCK_DGRAM || sk->sk_type == SOCK_RAW) { |
1332 | sock_tx_timestamp(sk, &tx_flags); | 1333 | sock_tx_timestamp(sk, sockc->tsflags, &tx_flags); |
1333 | if (tx_flags & SKBTX_ANY_SW_TSTAMP && | 1334 | if (tx_flags & SKBTX_ANY_SW_TSTAMP && |
1334 | sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) | 1335 | sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) |
1335 | tskey = sk->sk_tskey++; | 1336 | tskey = sk->sk_tskey++; |
@@ -1565,7 +1566,8 @@ int ip6_append_data(struct sock *sk, | |||
1565 | int odd, struct sk_buff *skb), | 1566 | int odd, struct sk_buff *skb), |
1566 | void *from, int length, int transhdrlen, int hlimit, | 1567 | void *from, int length, int transhdrlen, int hlimit, |
1567 | int tclass, struct ipv6_txoptions *opt, struct flowi6 *fl6, | 1568 | int tclass, struct ipv6_txoptions *opt, struct flowi6 *fl6, |
1568 | struct rt6_info *rt, unsigned int flags, int dontfrag) | 1569 | struct rt6_info *rt, unsigned int flags, int dontfrag, |
1570 | const struct sockcm_cookie *sockc) | ||
1569 | { | 1571 | { |
1570 | struct inet_sock *inet = inet_sk(sk); | 1572 | struct inet_sock *inet = inet_sk(sk); |
1571 | struct ipv6_pinfo *np = inet6_sk(sk); | 1573 | struct ipv6_pinfo *np = inet6_sk(sk); |
@@ -1593,7 +1595,8 @@ int ip6_append_data(struct sock *sk, | |||
1593 | 1595 | ||
1594 | return __ip6_append_data(sk, fl6, &sk->sk_write_queue, &inet->cork.base, | 1596 | return __ip6_append_data(sk, fl6, &sk->sk_write_queue, &inet->cork.base, |
1595 | &np->cork, sk_page_frag(sk), getfrag, | 1597 | &np->cork, sk_page_frag(sk), getfrag, |
1596 | from, length, transhdrlen, flags, dontfrag); | 1598 | from, length, transhdrlen, flags, dontfrag, |
1599 | sockc); | ||
1597 | } | 1600 | } |
1598 | EXPORT_SYMBOL_GPL(ip6_append_data); | 1601 | EXPORT_SYMBOL_GPL(ip6_append_data); |
1599 | 1602 | ||
@@ -1752,7 +1755,7 @@ struct sk_buff *ip6_make_skb(struct sock *sk, | |||
1752 | int hlimit, int tclass, | 1755 | int hlimit, int tclass, |
1753 | struct ipv6_txoptions *opt, struct flowi6 *fl6, | 1756 | struct ipv6_txoptions *opt, struct flowi6 *fl6, |
1754 | struct rt6_info *rt, unsigned int flags, | 1757 | struct rt6_info *rt, unsigned int flags, |
1755 | int dontfrag) | 1758 | int dontfrag, const struct sockcm_cookie *sockc) |
1756 | { | 1759 | { |
1757 | struct inet_cork_full cork; | 1760 | struct inet_cork_full cork; |
1758 | struct inet6_cork v6_cork; | 1761 | struct inet6_cork v6_cork; |
@@ -1779,7 +1782,7 @@ struct sk_buff *ip6_make_skb(struct sock *sk, | |||
1779 | err = __ip6_append_data(sk, fl6, &queue, &cork.base, &v6_cork, | 1782 | err = __ip6_append_data(sk, fl6, &queue, &cork.base, &v6_cork, |
1780 | ¤t->task_frag, getfrag, from, | 1783 | ¤t->task_frag, getfrag, from, |
1781 | length + exthdrlen, transhdrlen + exthdrlen, | 1784 | length + exthdrlen, transhdrlen + exthdrlen, |
1782 | flags, dontfrag); | 1785 | flags, dontfrag, sockc); |
1783 | if (err) { | 1786 | if (err) { |
1784 | __ip6_flush_pending_frames(sk, &queue, &cork, &v6_cork); | 1787 | __ip6_flush_pending_frames(sk, &queue, &cork, &v6_cork); |
1785 | return ERR_PTR(err); | 1788 | return ERR_PTR(err); |
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c index c382db7a2e73..da1cff79e447 100644 --- a/net/ipv6/ping.c +++ b/net/ipv6/ping.c | |||
@@ -62,6 +62,7 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
62 | struct dst_entry *dst; | 62 | struct dst_entry *dst; |
63 | struct rt6_info *rt; | 63 | struct rt6_info *rt; |
64 | struct pingfakehdr pfh; | 64 | struct pingfakehdr pfh; |
65 | struct sockcm_cookie junk = {0}; | ||
65 | 66 | ||
66 | pr_debug("ping_v6_sendmsg(sk=%p,sk->num=%u)\n", inet, inet->inet_num); | 67 | pr_debug("ping_v6_sendmsg(sk=%p,sk->num=%u)\n", inet, inet->inet_num); |
67 | 68 | ||
@@ -144,7 +145,7 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
144 | err = ip6_append_data(sk, ping_getfrag, &pfh, len, | 145 | err = ip6_append_data(sk, ping_getfrag, &pfh, len, |
145 | 0, hlimit, | 146 | 0, hlimit, |
146 | np->tclass, NULL, &fl6, rt, | 147 | np->tclass, NULL, &fl6, rt, |
147 | MSG_DONTWAIT, np->dontfrag); | 148 | MSG_DONTWAIT, np->dontfrag, &junk); |
148 | 149 | ||
149 | if (err) { | 150 | if (err) { |
150 | ICMP6_INC_STATS(sock_net(sk), rt->rt6i_idev, | 151 | ICMP6_INC_STATS(sock_net(sk), rt->rt6i_idev, |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index f175ec0a97ce..b07ce21983aa 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -822,8 +822,7 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
822 | if (fl6.flowi6_oif == 0) | 822 | if (fl6.flowi6_oif == 0) |
823 | fl6.flowi6_oif = sk->sk_bound_dev_if; | 823 | fl6.flowi6_oif = sk->sk_bound_dev_if; |
824 | 824 | ||
825 | sockc.tsflags = 0; | 825 | sockc.tsflags = sk->sk_tsflags; |
826 | |||
827 | if (msg->msg_controllen) { | 826 | if (msg->msg_controllen) { |
828 | opt = &opt_space; | 827 | opt = &opt_space; |
829 | memset(opt, 0, sizeof(struct ipv6_txoptions)); | 828 | memset(opt, 0, sizeof(struct ipv6_txoptions)); |
@@ -901,7 +900,7 @@ back_from_confirm: | |||
901 | lock_sock(sk); | 900 | lock_sock(sk); |
902 | err = ip6_append_data(sk, raw6_getfrag, &rfv, | 901 | err = ip6_append_data(sk, raw6_getfrag, &rfv, |
903 | len, 0, hlimit, tclass, opt, &fl6, (struct rt6_info *)dst, | 902 | len, 0, hlimit, tclass, opt, &fl6, (struct rt6_info *)dst, |
904 | msg->msg_flags, dontfrag); | 903 | msg->msg_flags, dontfrag, &sockc); |
905 | 904 | ||
906 | if (err) | 905 | if (err) |
907 | ip6_flush_pending_frames(sk); | 906 | ip6_flush_pending_frames(sk); |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 2a787af42163..b772a7641fbd 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -1248,7 +1248,7 @@ do_udp_sendmsg: | |||
1248 | fl6.flowi6_oif = np->sticky_pktinfo.ipi6_ifindex; | 1248 | fl6.flowi6_oif = np->sticky_pktinfo.ipi6_ifindex; |
1249 | 1249 | ||
1250 | fl6.flowi6_mark = sk->sk_mark; | 1250 | fl6.flowi6_mark = sk->sk_mark; |
1251 | sockc.tsflags = 0; | 1251 | sockc.tsflags = sk->sk_tsflags; |
1252 | 1252 | ||
1253 | if (msg->msg_controllen) { | 1253 | if (msg->msg_controllen) { |
1254 | opt = &opt_space; | 1254 | opt = &opt_space; |
@@ -1324,7 +1324,7 @@ back_from_confirm: | |||
1324 | skb = ip6_make_skb(sk, getfrag, msg, ulen, | 1324 | skb = ip6_make_skb(sk, getfrag, msg, ulen, |
1325 | sizeof(struct udphdr), hlimit, tclass, opt, | 1325 | sizeof(struct udphdr), hlimit, tclass, opt, |
1326 | &fl6, (struct rt6_info *)dst, | 1326 | &fl6, (struct rt6_info *)dst, |
1327 | msg->msg_flags, dontfrag); | 1327 | msg->msg_flags, dontfrag, &sockc); |
1328 | err = PTR_ERR(skb); | 1328 | err = PTR_ERR(skb); |
1329 | if (!IS_ERR_OR_NULL(skb)) | 1329 | if (!IS_ERR_OR_NULL(skb)) |
1330 | err = udp_v6_send_skb(skb, &fl6); | 1330 | err = udp_v6_send_skb(skb, &fl6); |
@@ -1351,7 +1351,8 @@ do_append_data: | |||
1351 | err = ip6_append_data(sk, getfrag, msg, ulen, | 1351 | err = ip6_append_data(sk, getfrag, msg, ulen, |
1352 | sizeof(struct udphdr), hlimit, tclass, opt, &fl6, | 1352 | sizeof(struct udphdr), hlimit, tclass, opt, &fl6, |
1353 | (struct rt6_info *)dst, | 1353 | (struct rt6_info *)dst, |
1354 | corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags, dontfrag); | 1354 | corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags, dontfrag, |
1355 | &sockc); | ||
1355 | if (err) | 1356 | if (err) |
1356 | udp_v6_flush_pending_frames(sk); | 1357 | udp_v6_flush_pending_frames(sk); |
1357 | else if (!corkreq) | 1358 | else if (!corkreq) |
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index 4f29a4a0f360..1a38f20b1ca6 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c | |||
@@ -627,7 +627,7 @@ back_from_confirm: | |||
627 | err = ip6_append_data(sk, ip_generic_getfrag, msg, | 627 | err = ip6_append_data(sk, ip_generic_getfrag, msg, |
628 | ulen, transhdrlen, hlimit, tclass, opt, | 628 | ulen, transhdrlen, hlimit, tclass, opt, |
629 | &fl6, (struct rt6_info *)dst, | 629 | &fl6, (struct rt6_info *)dst, |
630 | msg->msg_flags, dontfrag); | 630 | msg->msg_flags, dontfrag, &sockc_unused); |
631 | if (err) | 631 | if (err) |
632 | ip6_flush_pending_frames(sk); | 632 | ip6_flush_pending_frames(sk); |
633 | else if (!(msg->msg_flags & MSG_MORE)) | 633 | else if (!(msg->msg_flags & MSG_MORE)) |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 1ecfa710ca98..0007e23202e4 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -1837,6 +1837,7 @@ static int packet_sendmsg_spkt(struct socket *sock, struct msghdr *msg, | |||
1837 | DECLARE_SOCKADDR(struct sockaddr_pkt *, saddr, msg->msg_name); | 1837 | DECLARE_SOCKADDR(struct sockaddr_pkt *, saddr, msg->msg_name); |
1838 | struct sk_buff *skb = NULL; | 1838 | struct sk_buff *skb = NULL; |
1839 | struct net_device *dev; | 1839 | struct net_device *dev; |
1840 | struct sockcm_cookie sockc; | ||
1840 | __be16 proto = 0; | 1841 | __be16 proto = 0; |
1841 | int err; | 1842 | int err; |
1842 | int extra_len = 0; | 1843 | int extra_len = 0; |
@@ -1925,12 +1926,21 @@ retry: | |||
1925 | goto out_unlock; | 1926 | goto out_unlock; |
1926 | } | 1927 | } |
1927 | 1928 | ||
1929 | sockc.tsflags = 0; | ||
1930 | if (msg->msg_controllen) { | ||
1931 | err = sock_cmsg_send(sk, msg, &sockc); | ||
1932 | if (unlikely(err)) { | ||
1933 | err = -EINVAL; | ||
1934 | goto out_unlock; | ||
1935 | } | ||
1936 | } | ||
1937 | |||
1928 | skb->protocol = proto; | 1938 | skb->protocol = proto; |
1929 | skb->dev = dev; | 1939 | skb->dev = dev; |
1930 | skb->priority = sk->sk_priority; | 1940 | skb->priority = sk->sk_priority; |
1931 | skb->mark = sk->sk_mark; | 1941 | skb->mark = sk->sk_mark; |
1932 | 1942 | ||
1933 | sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags); | 1943 | sock_tx_timestamp(sk, sockc.tsflags, &skb_shinfo(skb)->tx_flags); |
1934 | 1944 | ||
1935 | if (unlikely(extra_len == 4)) | 1945 | if (unlikely(extra_len == 4)) |
1936 | skb->no_fcs = 1; | 1946 | skb->no_fcs = 1; |
@@ -2486,7 +2496,8 @@ static int packet_snd_vnet_gso(struct sk_buff *skb, | |||
2486 | 2496 | ||
2487 | static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, | 2497 | static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, |
2488 | void *frame, struct net_device *dev, void *data, int tp_len, | 2498 | void *frame, struct net_device *dev, void *data, int tp_len, |
2489 | __be16 proto, unsigned char *addr, int hlen, int copylen) | 2499 | __be16 proto, unsigned char *addr, int hlen, int copylen, |
2500 | const struct sockcm_cookie *sockc) | ||
2490 | { | 2501 | { |
2491 | union tpacket_uhdr ph; | 2502 | union tpacket_uhdr ph; |
2492 | int to_write, offset, len, nr_frags, len_max; | 2503 | int to_write, offset, len, nr_frags, len_max; |
@@ -2500,7 +2511,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, | |||
2500 | skb->dev = dev; | 2511 | skb->dev = dev; |
2501 | skb->priority = po->sk.sk_priority; | 2512 | skb->priority = po->sk.sk_priority; |
2502 | skb->mark = po->sk.sk_mark; | 2513 | skb->mark = po->sk.sk_mark; |
2503 | sock_tx_timestamp(&po->sk, &skb_shinfo(skb)->tx_flags); | 2514 | sock_tx_timestamp(&po->sk, sockc->tsflags, &skb_shinfo(skb)->tx_flags); |
2504 | skb_shinfo(skb)->destructor_arg = ph.raw; | 2515 | skb_shinfo(skb)->destructor_arg = ph.raw; |
2505 | 2516 | ||
2506 | skb_reserve(skb, hlen); | 2517 | skb_reserve(skb, hlen); |
@@ -2624,6 +2635,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
2624 | struct sk_buff *skb; | 2635 | struct sk_buff *skb; |
2625 | struct net_device *dev; | 2636 | struct net_device *dev; |
2626 | struct virtio_net_hdr *vnet_hdr = NULL; | 2637 | struct virtio_net_hdr *vnet_hdr = NULL; |
2638 | struct sockcm_cookie sockc; | ||
2627 | __be16 proto; | 2639 | __be16 proto; |
2628 | int err, reserve = 0; | 2640 | int err, reserve = 0; |
2629 | void *ph; | 2641 | void *ph; |
@@ -2655,6 +2667,13 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
2655 | dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex); | 2667 | dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex); |
2656 | } | 2668 | } |
2657 | 2669 | ||
2670 | sockc.tsflags = 0; | ||
2671 | if (msg->msg_controllen) { | ||
2672 | err = sock_cmsg_send(&po->sk, msg, &sockc); | ||
2673 | if (unlikely(err)) | ||
2674 | goto out; | ||
2675 | } | ||
2676 | |||
2658 | err = -ENXIO; | 2677 | err = -ENXIO; |
2659 | if (unlikely(dev == NULL)) | 2678 | if (unlikely(dev == NULL)) |
2660 | goto out; | 2679 | goto out; |
@@ -2712,7 +2731,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
2712 | goto out_status; | 2731 | goto out_status; |
2713 | } | 2732 | } |
2714 | tp_len = tpacket_fill_skb(po, skb, ph, dev, data, tp_len, proto, | 2733 | tp_len = tpacket_fill_skb(po, skb, ph, dev, data, tp_len, proto, |
2715 | addr, hlen, copylen); | 2734 | addr, hlen, copylen, &sockc); |
2716 | if (likely(tp_len >= 0) && | 2735 | if (likely(tp_len >= 0) && |
2717 | tp_len > dev->mtu + reserve && | 2736 | tp_len > dev->mtu + reserve && |
2718 | !po->has_vnet_hdr && | 2737 | !po->has_vnet_hdr && |
@@ -2851,6 +2870,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) | |||
2851 | if (unlikely(!(dev->flags & IFF_UP))) | 2870 | if (unlikely(!(dev->flags & IFF_UP))) |
2852 | goto out_unlock; | 2871 | goto out_unlock; |
2853 | 2872 | ||
2873 | sockc.tsflags = 0; | ||
2854 | sockc.mark = sk->sk_mark; | 2874 | sockc.mark = sk->sk_mark; |
2855 | if (msg->msg_controllen) { | 2875 | if (msg->msg_controllen) { |
2856 | err = sock_cmsg_send(sk, msg, &sockc); | 2876 | err = sock_cmsg_send(sk, msg, &sockc); |
@@ -2908,7 +2928,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) | |||
2908 | goto out_free; | 2928 | goto out_free; |
2909 | } | 2929 | } |
2910 | 2930 | ||
2911 | sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags); | 2931 | sock_tx_timestamp(sk, sockc.tsflags, &skb_shinfo(skb)->tx_flags); |
2912 | 2932 | ||
2913 | if (!vnet_hdr.gso_type && (len > dev->mtu + reserve + extra_len) && | 2933 | if (!vnet_hdr.gso_type && (len > dev->mtu + reserve + extra_len) && |
2914 | !packet_extra_vlan_len_allowed(dev, skb)) { | 2934 | !packet_extra_vlan_len_allowed(dev, skb)) { |
diff --git a/net/socket.c b/net/socket.c index 5f77a8e93830..979d3146b081 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -587,20 +587,20 @@ void sock_release(struct socket *sock) | |||
587 | } | 587 | } |
588 | EXPORT_SYMBOL(sock_release); | 588 | EXPORT_SYMBOL(sock_release); |
589 | 589 | ||
590 | void __sock_tx_timestamp(const struct sock *sk, __u8 *tx_flags) | 590 | void __sock_tx_timestamp(__u16 tsflags, __u8 *tx_flags) |
591 | { | 591 | { |
592 | u8 flags = *tx_flags; | 592 | u8 flags = *tx_flags; |
593 | 593 | ||
594 | if (sk->sk_tsflags & SOF_TIMESTAMPING_TX_HARDWARE) | 594 | if (tsflags & SOF_TIMESTAMPING_TX_HARDWARE) |
595 | flags |= SKBTX_HW_TSTAMP; | 595 | flags |= SKBTX_HW_TSTAMP; |
596 | 596 | ||
597 | if (sk->sk_tsflags & SOF_TIMESTAMPING_TX_SOFTWARE) | 597 | if (tsflags & SOF_TIMESTAMPING_TX_SOFTWARE) |
598 | flags |= SKBTX_SW_TSTAMP; | 598 | flags |= SKBTX_SW_TSTAMP; |
599 | 599 | ||
600 | if (sk->sk_tsflags & SOF_TIMESTAMPING_TX_SCHED) | 600 | if (tsflags & SOF_TIMESTAMPING_TX_SCHED) |
601 | flags |= SKBTX_SCHED_TSTAMP; | 601 | flags |= SKBTX_SCHED_TSTAMP; |
602 | 602 | ||
603 | if (sk->sk_tsflags & SOF_TIMESTAMPING_TX_ACK) | 603 | if (tsflags & SOF_TIMESTAMPING_TX_ACK) |
604 | flags |= SKBTX_ACK_TSTAMP; | 604 | flags |= SKBTX_ACK_TSTAMP; |
605 | 605 | ||
606 | *tx_flags = flags; | 606 | *tx_flags = flags; |