diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/tcp.c | 12 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 36 | ||||
-rw-r--r-- | net/ipv4/tcp_offload.c | 8 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 25 | ||||
-rw-r--r-- | net/netlink/af_netlink.c | 1 | ||||
-rw-r--r-- | net/netlink/af_netlink.h | 1 | ||||
-rw-r--r-- | net/netlink/diag.c | 3 | ||||
-rw-r--r-- | net/socket.c | 20 |
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 | } |
427 | EXPORT_SYMBOL(tcp_init_sock); | 427 | EXPORT_SYMBOL(tcp_init_sock); |
428 | 428 | ||
429 | void tcp_tx_timestamp(struct sock *sk, struct sk_buff *skb) | 429 | static 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 | } |
1168 | EXPORT_SYMBOL(tcp_v4_md5_hash_skb); | 1168 | EXPORT_SYMBOL(tcp_v4_md5_hash_skb); |
1169 | 1169 | ||
1170 | static bool tcp_v4_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) | 1170 | static 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 | ||
1224 | static 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 | ||
1225 | static void tcp_v4_init_req(struct request_sock *req, struct sock *sk, | 1237 | static 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) | |||
1432 | int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) | 1444 | int 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 | ||
17 | void tcp_gso_tstamp(struct sk_buff *skb, unsigned int ts_seq, unsigned int seq, | 17 | static 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 | ||
670 | static int tcp_v6_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) | 670 | static 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 | |||
712 | static 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 | ||
712 | static void tcp_v6_init_req(struct request_sock *req, struct sock *sk, | 725 | static 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 */ |
106 | DEFINE_MUTEX(nl_sk_hash_lock); | 106 | DEFINE_MUTEX(nl_sk_hash_lock); |
107 | EXPORT_SYMBOL_GPL(nl_sk_hash_lock); | ||
107 | 108 | ||
108 | static int lockdep_nl_sk_hash_is_held(void) | 109 | static 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 | ||
74 | extern struct netlink_table *nl_table; | 74 | extern struct netlink_table *nl_table; |
75 | extern rwlock_t nl_table_lock; | 75 | extern rwlock_t nl_table_lock; |
76 | extern 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 | } |
611 | EXPORT_SYMBOL(sock_release); | 611 | EXPORT_SYMBOL(sock_release); |
612 | 612 | ||
613 | void sock_tx_timestamp(struct sock *sk, __u8 *tx_flags) | 613 | void 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 | } |
628 | EXPORT_SYMBOL(sock_tx_timestamp); | 634 | EXPORT_SYMBOL(sock_tx_timestamp); |
629 | 635 | ||