aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/tcp.c12
-rw-r--r--net/ipv4/tcp_ipv4.c36
-rw-r--r--net/ipv4/tcp_offload.c8
-rw-r--r--net/ipv6/tcp_ipv6.c25
-rw-r--r--net/netlink/af_netlink.c1
-rw-r--r--net/netlink/af_netlink.h1
-rw-r--r--net/netlink/diag.c3
-rw-r--r--net/socket.c20
8 files changed, 73 insertions, 33 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 744af67a5989..181b70ebd964 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -426,13 +426,15 @@ void tcp_init_sock(struct sock *sk)
426} 426}
427EXPORT_SYMBOL(tcp_init_sock); 427EXPORT_SYMBOL(tcp_init_sock);
428 428
429void tcp_tx_timestamp(struct sock *sk, struct sk_buff *skb) 429static void tcp_tx_timestamp(struct sock *sk, struct sk_buff *skb)
430{ 430{
431 struct skb_shared_info *shinfo = skb_shinfo(skb); 431 if (sk->sk_tsflags) {
432 struct skb_shared_info *shinfo = skb_shinfo(skb);
432 433
433 sock_tx_timestamp(sk, &shinfo->tx_flags); 434 sock_tx_timestamp(sk, &shinfo->tx_flags);
434 if (shinfo->tx_flags & SKBTX_ANY_SW_TSTAMP) 435 if (shinfo->tx_flags & SKBTX_ANY_TSTAMP)
435 shinfo->tskey = TCP_SKB_CB(skb)->seq + skb->len - 1; 436 shinfo->tskey = TCP_SKB_CB(skb)->seq + skb->len - 1;
437 }
436} 438}
437 439
438/* 440/*
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 992a1f926009..dceff5fe8e66 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1167,7 +1167,8 @@ clear_hash_noput:
1167} 1167}
1168EXPORT_SYMBOL(tcp_v4_md5_hash_skb); 1168EXPORT_SYMBOL(tcp_v4_md5_hash_skb);
1169 1169
1170static bool tcp_v4_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) 1170static bool __tcp_v4_inbound_md5_hash(struct sock *sk,
1171 const struct sk_buff *skb)
1171{ 1172{
1172 /* 1173 /*
1173 * This gets called for each TCP segment that arrives 1174 * This gets called for each TCP segment that arrives
@@ -1220,6 +1221,17 @@ static bool tcp_v4_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb)
1220 return false; 1221 return false;
1221} 1222}
1222 1223
1224static bool tcp_v4_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb)
1225{
1226 bool ret;
1227
1228 rcu_read_lock();
1229 ret = __tcp_v4_inbound_md5_hash(sk, skb);
1230 rcu_read_unlock();
1231
1232 return ret;
1233}
1234
1223#endif 1235#endif
1224 1236
1225static void tcp_v4_init_req(struct request_sock *req, struct sock *sk, 1237static void tcp_v4_init_req(struct request_sock *req, struct sock *sk,
@@ -1432,16 +1444,6 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
1432int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) 1444int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
1433{ 1445{
1434 struct sock *rsk; 1446 struct sock *rsk;
1435#ifdef CONFIG_TCP_MD5SIG
1436 /*
1437 * We really want to reject the packet as early as possible
1438 * if:
1439 * o We're expecting an MD5'd packet and this is no MD5 tcp option
1440 * o There is an MD5 option and we're not expecting one
1441 */
1442 if (tcp_v4_inbound_md5_hash(sk, skb))
1443 goto discard;
1444#endif
1445 1447
1446 if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ 1448 if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
1447 struct dst_entry *dst = sk->sk_rx_dst; 1449 struct dst_entry *dst = sk->sk_rx_dst;
@@ -1644,6 +1646,18 @@ process:
1644 1646
1645 if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) 1647 if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
1646 goto discard_and_relse; 1648 goto discard_and_relse;
1649
1650#ifdef CONFIG_TCP_MD5SIG
1651 /*
1652 * We really want to reject the packet as early as possible
1653 * if:
1654 * o We're expecting an MD5'd packet and this is no MD5 tcp option
1655 * o There is an MD5 option and we're not expecting one
1656 */
1657 if (tcp_v4_inbound_md5_hash(sk, skb))
1658 goto discard_and_relse;
1659#endif
1660
1647 nf_reset(skb); 1661 nf_reset(skb);
1648 1662
1649 if (sk_filter(sk, skb)) 1663 if (sk_filter(sk, skb))
diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c
index f597119fc4e7..bc1b83cb8309 100644
--- a/net/ipv4/tcp_offload.c
+++ b/net/ipv4/tcp_offload.c
@@ -14,12 +14,12 @@
14#include <net/tcp.h> 14#include <net/tcp.h>
15#include <net/protocol.h> 15#include <net/protocol.h>
16 16
17void tcp_gso_tstamp(struct sk_buff *skb, unsigned int ts_seq, unsigned int seq, 17static void tcp_gso_tstamp(struct sk_buff *skb, unsigned int ts_seq,
18 unsigned int mss) 18 unsigned int seq, unsigned int mss)
19{ 19{
20 while (skb) { 20 while (skb) {
21 if (ts_seq < (__u64) seq + mss) { 21 if (before(ts_seq, seq + mss)) {
22 skb_shinfo(skb)->tx_flags = SKBTX_SW_TSTAMP; 22 skb_shinfo(skb)->tx_flags |= SKBTX_SW_TSTAMP;
23 skb_shinfo(skb)->tskey = ts_seq; 23 skb_shinfo(skb)->tskey = ts_seq;
24 return; 24 return;
25 } 25 }
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 22055b098428..f2ce95502392 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -667,7 +667,8 @@ clear_hash_noput:
667 return 1; 667 return 1;
668} 668}
669 669
670static int tcp_v6_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) 670static int __tcp_v6_inbound_md5_hash(struct sock *sk,
671 const struct sk_buff *skb)
671{ 672{
672 const __u8 *hash_location = NULL; 673 const __u8 *hash_location = NULL;
673 struct tcp_md5sig_key *hash_expected; 674 struct tcp_md5sig_key *hash_expected;
@@ -707,6 +708,18 @@ static int tcp_v6_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb)
707 } 708 }
708 return 0; 709 return 0;
709} 710}
711
712static int tcp_v6_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb)
713{
714 int ret;
715
716 rcu_read_lock();
717 ret = __tcp_v6_inbound_md5_hash(sk, skb);
718 rcu_read_unlock();
719
720 return ret;
721}
722
710#endif 723#endif
711 724
712static void tcp_v6_init_req(struct request_sock *req, struct sock *sk, 725static void tcp_v6_init_req(struct request_sock *req, struct sock *sk,
@@ -1247,11 +1260,6 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
1247 if (skb->protocol == htons(ETH_P_IP)) 1260 if (skb->protocol == htons(ETH_P_IP))
1248 return tcp_v4_do_rcv(sk, skb); 1261 return tcp_v4_do_rcv(sk, skb);
1249 1262
1250#ifdef CONFIG_TCP_MD5SIG
1251 if (tcp_v6_inbound_md5_hash(sk, skb))
1252 goto discard;
1253#endif
1254
1255 if (sk_filter(sk, skb)) 1263 if (sk_filter(sk, skb))
1256 goto discard; 1264 goto discard;
1257 1265
@@ -1424,6 +1432,11 @@ process:
1424 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) 1432 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
1425 goto discard_and_relse; 1433 goto discard_and_relse;
1426 1434
1435#ifdef CONFIG_TCP_MD5SIG
1436 if (tcp_v6_inbound_md5_hash(sk, skb))
1437 goto discard_and_relse;
1438#endif
1439
1427 if (sk_filter(sk, skb)) 1440 if (sk_filter(sk, skb))
1428 goto discard_and_relse; 1441 goto discard_and_relse;
1429 1442
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 479a344563d8..a324b4b34c90 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -104,6 +104,7 @@ static atomic_t nl_table_users = ATOMIC_INIT(0);
104 104
105/* Protects netlink socket hash table mutations */ 105/* Protects netlink socket hash table mutations */
106DEFINE_MUTEX(nl_sk_hash_lock); 106DEFINE_MUTEX(nl_sk_hash_lock);
107EXPORT_SYMBOL_GPL(nl_sk_hash_lock);
107 108
108static int lockdep_nl_sk_hash_is_held(void) 109static int lockdep_nl_sk_hash_is_held(void)
109{ 110{
diff --git a/net/netlink/af_netlink.h b/net/netlink/af_netlink.h
index 60f631fb7087..b20a1731759b 100644
--- a/net/netlink/af_netlink.h
+++ b/net/netlink/af_netlink.h
@@ -73,5 +73,6 @@ struct netlink_table {
73 73
74extern struct netlink_table *nl_table; 74extern struct netlink_table *nl_table;
75extern rwlock_t nl_table_lock; 75extern rwlock_t nl_table_lock;
76extern struct mutex nl_sk_hash_lock;
76 77
77#endif 78#endif
diff --git a/net/netlink/diag.c b/net/netlink/diag.c
index 7301850eb56f..de8c74a3c061 100644
--- a/net/netlink/diag.c
+++ b/net/netlink/diag.c
@@ -170,6 +170,7 @@ static int netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
170 170
171 req = nlmsg_data(cb->nlh); 171 req = nlmsg_data(cb->nlh);
172 172
173 mutex_lock(&nl_sk_hash_lock);
173 read_lock(&nl_table_lock); 174 read_lock(&nl_table_lock);
174 175
175 if (req->sdiag_protocol == NDIAG_PROTO_ALL) { 176 if (req->sdiag_protocol == NDIAG_PROTO_ALL) {
@@ -183,6 +184,7 @@ static int netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
183 } else { 184 } else {
184 if (req->sdiag_protocol >= MAX_LINKS) { 185 if (req->sdiag_protocol >= MAX_LINKS) {
185 read_unlock(&nl_table_lock); 186 read_unlock(&nl_table_lock);
187 mutex_unlock(&nl_sk_hash_lock);
186 return -ENOENT; 188 return -ENOENT;
187 } 189 }
188 190
@@ -190,6 +192,7 @@ static int netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
190 } 192 }
191 193
192 read_unlock(&nl_table_lock); 194 read_unlock(&nl_table_lock);
195 mutex_unlock(&nl_sk_hash_lock);
193 196
194 return skb->len; 197 return skb->len;
195} 198}
diff --git a/net/socket.c b/net/socket.c
index ae89569a2db5..95ee7d8682e7 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -610,20 +610,26 @@ void sock_release(struct socket *sock)
610} 610}
611EXPORT_SYMBOL(sock_release); 611EXPORT_SYMBOL(sock_release);
612 612
613void sock_tx_timestamp(struct sock *sk, __u8 *tx_flags) 613void sock_tx_timestamp(const struct sock *sk, __u8 *tx_flags)
614{ 614{
615 *tx_flags = 0; 615 u8 flags = *tx_flags;
616
616 if (sk->sk_tsflags & SOF_TIMESTAMPING_TX_HARDWARE) 617 if (sk->sk_tsflags & SOF_TIMESTAMPING_TX_HARDWARE)
617 *tx_flags |= SKBTX_HW_TSTAMP; 618 flags |= SKBTX_HW_TSTAMP;
619
618 if (sk->sk_tsflags & SOF_TIMESTAMPING_TX_SOFTWARE) 620 if (sk->sk_tsflags & SOF_TIMESTAMPING_TX_SOFTWARE)
619 *tx_flags |= SKBTX_SW_TSTAMP; 621 flags |= SKBTX_SW_TSTAMP;
622
620 if (sk->sk_tsflags & SOF_TIMESTAMPING_TX_SCHED) 623 if (sk->sk_tsflags & SOF_TIMESTAMPING_TX_SCHED)
621 *tx_flags |= SKBTX_SCHED_TSTAMP; 624 flags |= SKBTX_SCHED_TSTAMP;
625
622 if (sk->sk_tsflags & SOF_TIMESTAMPING_TX_ACK) 626 if (sk->sk_tsflags & SOF_TIMESTAMPING_TX_ACK)
623 *tx_flags |= SKBTX_ACK_TSTAMP; 627 flags |= SKBTX_ACK_TSTAMP;
624 628
625 if (sock_flag(sk, SOCK_WIFI_STATUS)) 629 if (sock_flag(sk, SOCK_WIFI_STATUS))
626 *tx_flags |= SKBTX_WIFI_STATUS; 630 flags |= SKBTX_WIFI_STATUS;
631
632 *tx_flags = flags;
627} 633}
628EXPORT_SYMBOL(sock_tx_timestamp); 634EXPORT_SYMBOL(sock_tx_timestamp);
629 635