diff options
author | David S. Miller <davem@davemloft.net> | 2016-06-30 05:03:36 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-06-30 05:03:36 -0400 |
commit | ee58b57100ca953da7320c285315a95db2f7053d (patch) | |
tree | 77b815a31240adc4d6326346908137fc6c2c3a96 /net/ipv4 | |
parent | 6f30e8b022c8e3a722928ddb1a2ae0be852fcc0e (diff) | |
parent | e7bdea7750eb2a64aea4a08fa5c0a31719c8155d (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Several cases of overlapping changes, except the packet scheduler
conflicts which deal with the addition of the free list parameter
to qdisc_enqueue().
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/esp4.c | 52 | ||||
-rw-r--r-- | net/ipv4/gre_demux.c | 10 | ||||
-rw-r--r-- | net/ipv4/ip_gre.c | 26 | ||||
-rw-r--r-- | net/ipv4/ipconfig.c | 4 | ||||
-rw-r--r-- | net/ipv4/ipmr.c | 4 | ||||
-rw-r--r-- | net/ipv4/tcp_output.c | 7 | ||||
-rw-r--r-- | net/ipv4/udp.c | 80 |
7 files changed, 85 insertions, 98 deletions
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 477937465a20..d95631d09248 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c | |||
@@ -23,6 +23,11 @@ struct esp_skb_cb { | |||
23 | void *tmp; | 23 | void *tmp; |
24 | }; | 24 | }; |
25 | 25 | ||
26 | struct esp_output_extra { | ||
27 | __be32 seqhi; | ||
28 | u32 esphoff; | ||
29 | }; | ||
30 | |||
26 | #define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0])) | 31 | #define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0])) |
27 | 32 | ||
28 | static u32 esp4_get_mtu(struct xfrm_state *x, int mtu); | 33 | static u32 esp4_get_mtu(struct xfrm_state *x, int mtu); |
@@ -35,11 +40,11 @@ static u32 esp4_get_mtu(struct xfrm_state *x, int mtu); | |||
35 | * | 40 | * |
36 | * TODO: Use spare space in skb for this where possible. | 41 | * TODO: Use spare space in skb for this where possible. |
37 | */ | 42 | */ |
38 | static void *esp_alloc_tmp(struct crypto_aead *aead, int nfrags, int seqhilen) | 43 | static void *esp_alloc_tmp(struct crypto_aead *aead, int nfrags, int extralen) |
39 | { | 44 | { |
40 | unsigned int len; | 45 | unsigned int len; |
41 | 46 | ||
42 | len = seqhilen; | 47 | len = extralen; |
43 | 48 | ||
44 | len += crypto_aead_ivsize(aead); | 49 | len += crypto_aead_ivsize(aead); |
45 | 50 | ||
@@ -57,15 +62,16 @@ static void *esp_alloc_tmp(struct crypto_aead *aead, int nfrags, int seqhilen) | |||
57 | return kmalloc(len, GFP_ATOMIC); | 62 | return kmalloc(len, GFP_ATOMIC); |
58 | } | 63 | } |
59 | 64 | ||
60 | static inline __be32 *esp_tmp_seqhi(void *tmp) | 65 | static inline void *esp_tmp_extra(void *tmp) |
61 | { | 66 | { |
62 | return PTR_ALIGN((__be32 *)tmp, __alignof__(__be32)); | 67 | return PTR_ALIGN(tmp, __alignof__(struct esp_output_extra)); |
63 | } | 68 | } |
64 | static inline u8 *esp_tmp_iv(struct crypto_aead *aead, void *tmp, int seqhilen) | 69 | |
70 | static inline u8 *esp_tmp_iv(struct crypto_aead *aead, void *tmp, int extralen) | ||
65 | { | 71 | { |
66 | return crypto_aead_ivsize(aead) ? | 72 | return crypto_aead_ivsize(aead) ? |
67 | PTR_ALIGN((u8 *)tmp + seqhilen, | 73 | PTR_ALIGN((u8 *)tmp + extralen, |
68 | crypto_aead_alignmask(aead) + 1) : tmp + seqhilen; | 74 | crypto_aead_alignmask(aead) + 1) : tmp + extralen; |
69 | } | 75 | } |
70 | 76 | ||
71 | static inline struct aead_request *esp_tmp_req(struct crypto_aead *aead, u8 *iv) | 77 | static inline struct aead_request *esp_tmp_req(struct crypto_aead *aead, u8 *iv) |
@@ -99,7 +105,7 @@ static void esp_restore_header(struct sk_buff *skb, unsigned int offset) | |||
99 | { | 105 | { |
100 | struct ip_esp_hdr *esph = (void *)(skb->data + offset); | 106 | struct ip_esp_hdr *esph = (void *)(skb->data + offset); |
101 | void *tmp = ESP_SKB_CB(skb)->tmp; | 107 | void *tmp = ESP_SKB_CB(skb)->tmp; |
102 | __be32 *seqhi = esp_tmp_seqhi(tmp); | 108 | __be32 *seqhi = esp_tmp_extra(tmp); |
103 | 109 | ||
104 | esph->seq_no = esph->spi; | 110 | esph->seq_no = esph->spi; |
105 | esph->spi = *seqhi; | 111 | esph->spi = *seqhi; |
@@ -107,7 +113,11 @@ static void esp_restore_header(struct sk_buff *skb, unsigned int offset) | |||
107 | 113 | ||
108 | static void esp_output_restore_header(struct sk_buff *skb) | 114 | static void esp_output_restore_header(struct sk_buff *skb) |
109 | { | 115 | { |
110 | esp_restore_header(skb, skb_transport_offset(skb) - sizeof(__be32)); | 116 | void *tmp = ESP_SKB_CB(skb)->tmp; |
117 | struct esp_output_extra *extra = esp_tmp_extra(tmp); | ||
118 | |||
119 | esp_restore_header(skb, skb_transport_offset(skb) + extra->esphoff - | ||
120 | sizeof(__be32)); | ||
111 | } | 121 | } |
112 | 122 | ||
113 | static void esp_output_done_esn(struct crypto_async_request *base, int err) | 123 | static void esp_output_done_esn(struct crypto_async_request *base, int err) |
@@ -121,6 +131,7 @@ static void esp_output_done_esn(struct crypto_async_request *base, int err) | |||
121 | static int esp_output(struct xfrm_state *x, struct sk_buff *skb) | 131 | static int esp_output(struct xfrm_state *x, struct sk_buff *skb) |
122 | { | 132 | { |
123 | int err; | 133 | int err; |
134 | struct esp_output_extra *extra; | ||
124 | struct ip_esp_hdr *esph; | 135 | struct ip_esp_hdr *esph; |
125 | struct crypto_aead *aead; | 136 | struct crypto_aead *aead; |
126 | struct aead_request *req; | 137 | struct aead_request *req; |
@@ -137,8 +148,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) | |||
137 | int tfclen; | 148 | int tfclen; |
138 | int nfrags; | 149 | int nfrags; |
139 | int assoclen; | 150 | int assoclen; |
140 | int seqhilen; | 151 | int extralen; |
141 | __be32 *seqhi; | ||
142 | __be64 seqno; | 152 | __be64 seqno; |
143 | 153 | ||
144 | /* skb is pure payload to encrypt */ | 154 | /* skb is pure payload to encrypt */ |
@@ -166,21 +176,21 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) | |||
166 | nfrags = err; | 176 | nfrags = err; |
167 | 177 | ||
168 | assoclen = sizeof(*esph); | 178 | assoclen = sizeof(*esph); |
169 | seqhilen = 0; | 179 | extralen = 0; |
170 | 180 | ||
171 | if (x->props.flags & XFRM_STATE_ESN) { | 181 | if (x->props.flags & XFRM_STATE_ESN) { |
172 | seqhilen += sizeof(__be32); | 182 | extralen += sizeof(*extra); |
173 | assoclen += seqhilen; | 183 | assoclen += sizeof(__be32); |
174 | } | 184 | } |
175 | 185 | ||
176 | tmp = esp_alloc_tmp(aead, nfrags, seqhilen); | 186 | tmp = esp_alloc_tmp(aead, nfrags, extralen); |
177 | if (!tmp) { | 187 | if (!tmp) { |
178 | err = -ENOMEM; | 188 | err = -ENOMEM; |
179 | goto error; | 189 | goto error; |
180 | } | 190 | } |
181 | 191 | ||
182 | seqhi = esp_tmp_seqhi(tmp); | 192 | extra = esp_tmp_extra(tmp); |
183 | iv = esp_tmp_iv(aead, tmp, seqhilen); | 193 | iv = esp_tmp_iv(aead, tmp, extralen); |
184 | req = esp_tmp_req(aead, iv); | 194 | req = esp_tmp_req(aead, iv); |
185 | sg = esp_req_sg(aead, req); | 195 | sg = esp_req_sg(aead, req); |
186 | 196 | ||
@@ -247,8 +257,10 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) | |||
247 | * encryption. | 257 | * encryption. |
248 | */ | 258 | */ |
249 | if ((x->props.flags & XFRM_STATE_ESN)) { | 259 | if ((x->props.flags & XFRM_STATE_ESN)) { |
250 | esph = (void *)(skb_transport_header(skb) - sizeof(__be32)); | 260 | extra->esphoff = (unsigned char *)esph - |
251 | *seqhi = esph->spi; | 261 | skb_transport_header(skb); |
262 | esph = (struct ip_esp_hdr *)((unsigned char *)esph - 4); | ||
263 | extra->seqhi = esph->spi; | ||
252 | esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output.hi); | 264 | esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output.hi); |
253 | aead_request_set_callback(req, 0, esp_output_done_esn, skb); | 265 | aead_request_set_callback(req, 0, esp_output_done_esn, skb); |
254 | } | 266 | } |
@@ -445,7 +457,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) | |||
445 | goto out; | 457 | goto out; |
446 | 458 | ||
447 | ESP_SKB_CB(skb)->tmp = tmp; | 459 | ESP_SKB_CB(skb)->tmp = tmp; |
448 | seqhi = esp_tmp_seqhi(tmp); | 460 | seqhi = esp_tmp_extra(tmp); |
449 | iv = esp_tmp_iv(aead, tmp, seqhilen); | 461 | iv = esp_tmp_iv(aead, tmp, seqhilen); |
450 | req = esp_tmp_req(aead, iv); | 462 | req = esp_tmp_req(aead, iv); |
451 | sg = esp_req_sg(aead, req); | 463 | sg = esp_req_sg(aead, req); |
diff --git a/net/ipv4/gre_demux.c b/net/ipv4/gre_demux.c index c4c3e439f424..b798862b6be5 100644 --- a/net/ipv4/gre_demux.c +++ b/net/ipv4/gre_demux.c | |||
@@ -62,26 +62,26 @@ EXPORT_SYMBOL_GPL(gre_del_protocol); | |||
62 | 62 | ||
63 | /* Fills in tpi and returns header length to be pulled. */ | 63 | /* Fills in tpi and returns header length to be pulled. */ |
64 | int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, | 64 | int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, |
65 | bool *csum_err, __be16 proto) | 65 | bool *csum_err, __be16 proto, int nhs) |
66 | { | 66 | { |
67 | const struct gre_base_hdr *greh; | 67 | const struct gre_base_hdr *greh; |
68 | __be32 *options; | 68 | __be32 *options; |
69 | int hdr_len; | 69 | int hdr_len; |
70 | 70 | ||
71 | if (unlikely(!pskb_may_pull(skb, sizeof(struct gre_base_hdr)))) | 71 | if (unlikely(!pskb_may_pull(skb, nhs + sizeof(struct gre_base_hdr)))) |
72 | return -EINVAL; | 72 | return -EINVAL; |
73 | 73 | ||
74 | greh = (struct gre_base_hdr *)skb_transport_header(skb); | 74 | greh = (struct gre_base_hdr *)(skb->data + nhs); |
75 | if (unlikely(greh->flags & (GRE_VERSION | GRE_ROUTING))) | 75 | if (unlikely(greh->flags & (GRE_VERSION | GRE_ROUTING))) |
76 | return -EINVAL; | 76 | return -EINVAL; |
77 | 77 | ||
78 | tpi->flags = gre_flags_to_tnl_flags(greh->flags); | 78 | tpi->flags = gre_flags_to_tnl_flags(greh->flags); |
79 | hdr_len = gre_calc_hlen(tpi->flags); | 79 | hdr_len = gre_calc_hlen(tpi->flags); |
80 | 80 | ||
81 | if (!pskb_may_pull(skb, hdr_len)) | 81 | if (!pskb_may_pull(skb, nhs + hdr_len)) |
82 | return -EINVAL; | 82 | return -EINVAL; |
83 | 83 | ||
84 | greh = (struct gre_base_hdr *)skb_transport_header(skb); | 84 | greh = (struct gre_base_hdr *)(skb->data + nhs); |
85 | tpi->proto = greh->protocol; | 85 | tpi->proto = greh->protocol; |
86 | 86 | ||
87 | options = (__be32 *)(greh + 1); | 87 | options = (__be32 *)(greh + 1); |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 8eec78f53f9e..5b1481be0282 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -49,12 +49,6 @@ | |||
49 | #include <net/gre.h> | 49 | #include <net/gre.h> |
50 | #include <net/dst_metadata.h> | 50 | #include <net/dst_metadata.h> |
51 | 51 | ||
52 | #if IS_ENABLED(CONFIG_IPV6) | ||
53 | #include <net/ipv6.h> | ||
54 | #include <net/ip6_fib.h> | ||
55 | #include <net/ip6_route.h> | ||
56 | #endif | ||
57 | |||
58 | /* | 52 | /* |
59 | Problems & solutions | 53 | Problems & solutions |
60 | -------------------- | 54 | -------------------- |
@@ -226,12 +220,14 @@ static void gre_err(struct sk_buff *skb, u32 info) | |||
226 | * by themselves??? | 220 | * by themselves??? |
227 | */ | 221 | */ |
228 | 222 | ||
223 | const struct iphdr *iph = (struct iphdr *)skb->data; | ||
229 | const int type = icmp_hdr(skb)->type; | 224 | const int type = icmp_hdr(skb)->type; |
230 | const int code = icmp_hdr(skb)->code; | 225 | const int code = icmp_hdr(skb)->code; |
231 | struct tnl_ptk_info tpi; | 226 | struct tnl_ptk_info tpi; |
232 | bool csum_err = false; | 227 | bool csum_err = false; |
233 | 228 | ||
234 | if (gre_parse_header(skb, &tpi, &csum_err, htons(ETH_P_IP)) < 0) { | 229 | if (gre_parse_header(skb, &tpi, &csum_err, htons(ETH_P_IP), |
230 | iph->ihl * 4) < 0) { | ||
235 | if (!csum_err) /* ignore csum errors. */ | 231 | if (!csum_err) /* ignore csum errors. */ |
236 | return; | 232 | return; |
237 | } | 233 | } |
@@ -347,7 +343,7 @@ static int gre_rcv(struct sk_buff *skb) | |||
347 | } | 343 | } |
348 | #endif | 344 | #endif |
349 | 345 | ||
350 | hdr_len = gre_parse_header(skb, &tpi, &csum_err, htons(ETH_P_IP)); | 346 | hdr_len = gre_parse_header(skb, &tpi, &csum_err, htons(ETH_P_IP), 0); |
351 | if (hdr_len < 0) | 347 | if (hdr_len < 0) |
352 | goto drop; | 348 | goto drop; |
353 | 349 | ||
@@ -1154,6 +1150,7 @@ struct net_device *gretap_fb_dev_create(struct net *net, const char *name, | |||
1154 | { | 1150 | { |
1155 | struct nlattr *tb[IFLA_MAX + 1]; | 1151 | struct nlattr *tb[IFLA_MAX + 1]; |
1156 | struct net_device *dev; | 1152 | struct net_device *dev; |
1153 | LIST_HEAD(list_kill); | ||
1157 | struct ip_tunnel *t; | 1154 | struct ip_tunnel *t; |
1158 | int err; | 1155 | int err; |
1159 | 1156 | ||
@@ -1169,8 +1166,10 @@ struct net_device *gretap_fb_dev_create(struct net *net, const char *name, | |||
1169 | t->collect_md = true; | 1166 | t->collect_md = true; |
1170 | 1167 | ||
1171 | err = ipgre_newlink(net, dev, tb, NULL); | 1168 | err = ipgre_newlink(net, dev, tb, NULL); |
1172 | if (err < 0) | 1169 | if (err < 0) { |
1173 | goto out; | 1170 | free_netdev(dev); |
1171 | return ERR_PTR(err); | ||
1172 | } | ||
1174 | 1173 | ||
1175 | /* openvswitch users expect packet sizes to be unrestricted, | 1174 | /* openvswitch users expect packet sizes to be unrestricted, |
1176 | * so set the largest MTU we can. | 1175 | * so set the largest MTU we can. |
@@ -1179,9 +1178,14 @@ struct net_device *gretap_fb_dev_create(struct net *net, const char *name, | |||
1179 | if (err) | 1178 | if (err) |
1180 | goto out; | 1179 | goto out; |
1181 | 1180 | ||
1181 | err = rtnl_configure_link(dev, NULL); | ||
1182 | if (err < 0) | ||
1183 | goto out; | ||
1184 | |||
1182 | return dev; | 1185 | return dev; |
1183 | out: | 1186 | out: |
1184 | free_netdev(dev); | 1187 | ip_tunnel_dellink(dev, &list_kill); |
1188 | unregister_netdevice_many(&list_kill); | ||
1185 | return ERR_PTR(err); | 1189 | return ERR_PTR(err); |
1186 | } | 1190 | } |
1187 | EXPORT_SYMBOL_GPL(gretap_fb_dev_create); | 1191 | EXPORT_SYMBOL_GPL(gretap_fb_dev_create); |
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 2ed9dd2b5f2f..1d71c40eaaf3 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c | |||
@@ -127,7 +127,9 @@ __be32 ic_myaddr = NONE; /* My IP address */ | |||
127 | static __be32 ic_netmask = NONE; /* Netmask for local subnet */ | 127 | static __be32 ic_netmask = NONE; /* Netmask for local subnet */ |
128 | __be32 ic_gateway = NONE; /* Gateway IP address */ | 128 | __be32 ic_gateway = NONE; /* Gateway IP address */ |
129 | 129 | ||
130 | __be32 ic_addrservaddr = NONE; /* IP Address of the IP addresses'server */ | 130 | #ifdef IPCONFIG_DYNAMIC |
131 | static __be32 ic_addrservaddr = NONE; /* IP Address of the IP addresses'server */ | ||
132 | #endif | ||
131 | 133 | ||
132 | __be32 ic_servaddr = NONE; /* Boot server IP address */ | 134 | __be32 ic_servaddr = NONE; /* Boot server IP address */ |
133 | 135 | ||
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 21a38e296fe2..5ad48ec77710 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -891,8 +891,10 @@ static struct mfc_cache *ipmr_cache_alloc(void) | |||
891 | { | 891 | { |
892 | struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL); | 892 | struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL); |
893 | 893 | ||
894 | if (c) | 894 | if (c) { |
895 | c->mfc_un.res.last_assert = jiffies - MFC_ASSERT_THRESH - 1; | ||
895 | c->mfc_un.res.minvif = MAXVIFS; | 896 | c->mfc_un.res.minvif = MAXVIFS; |
897 | } | ||
896 | return c; | 898 | return c; |
897 | } | 899 | } |
898 | 900 | ||
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index b1bcba0563f2..b26aa870adc0 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -2753,7 +2753,7 @@ void tcp_xmit_retransmit_queue(struct sock *sk) | |||
2753 | struct tcp_sock *tp = tcp_sk(sk); | 2753 | struct tcp_sock *tp = tcp_sk(sk); |
2754 | struct sk_buff *skb; | 2754 | struct sk_buff *skb; |
2755 | struct sk_buff *hole = NULL; | 2755 | struct sk_buff *hole = NULL; |
2756 | u32 last_lost; | 2756 | u32 max_segs, last_lost; |
2757 | int mib_idx; | 2757 | int mib_idx; |
2758 | int fwd_rexmitting = 0; | 2758 | int fwd_rexmitting = 0; |
2759 | 2759 | ||
@@ -2773,6 +2773,7 @@ void tcp_xmit_retransmit_queue(struct sock *sk) | |||
2773 | last_lost = tp->snd_una; | 2773 | last_lost = tp->snd_una; |
2774 | } | 2774 | } |
2775 | 2775 | ||
2776 | max_segs = tcp_tso_autosize(sk, tcp_current_mss(sk)); | ||
2776 | tcp_for_write_queue_from(skb, sk) { | 2777 | tcp_for_write_queue_from(skb, sk) { |
2777 | __u8 sacked = TCP_SKB_CB(skb)->sacked; | 2778 | __u8 sacked = TCP_SKB_CB(skb)->sacked; |
2778 | int segs; | 2779 | int segs; |
@@ -2786,6 +2787,10 @@ void tcp_xmit_retransmit_queue(struct sock *sk) | |||
2786 | segs = tp->snd_cwnd - tcp_packets_in_flight(tp); | 2787 | segs = tp->snd_cwnd - tcp_packets_in_flight(tp); |
2787 | if (segs <= 0) | 2788 | if (segs <= 0) |
2788 | return; | 2789 | return; |
2790 | /* In case tcp_shift_skb_data() have aggregated large skbs, | ||
2791 | * we need to make sure not sending too bigs TSO packets | ||
2792 | */ | ||
2793 | segs = min_t(int, segs, max_segs); | ||
2789 | 2794 | ||
2790 | if (fwd_rexmitting) { | 2795 | if (fwd_rexmitting) { |
2791 | begin_fwd: | 2796 | begin_fwd: |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 0ff31d97d485..ca5e8ea29538 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -391,9 +391,9 @@ int udp_v4_get_port(struct sock *sk, unsigned short snum) | |||
391 | return udp_lib_get_port(sk, snum, ipv4_rcv_saddr_equal, hash2_nulladdr); | 391 | return udp_lib_get_port(sk, snum, ipv4_rcv_saddr_equal, hash2_nulladdr); |
392 | } | 392 | } |
393 | 393 | ||
394 | static inline int compute_score(struct sock *sk, struct net *net, | 394 | static int compute_score(struct sock *sk, struct net *net, |
395 | __be32 saddr, unsigned short hnum, __be16 sport, | 395 | __be32 saddr, __be16 sport, |
396 | __be32 daddr, __be16 dport, int dif) | 396 | __be32 daddr, unsigned short hnum, int dif) |
397 | { | 397 | { |
398 | int score; | 398 | int score; |
399 | struct inet_sock *inet; | 399 | struct inet_sock *inet; |
@@ -434,52 +434,6 @@ static inline int compute_score(struct sock *sk, struct net *net, | |||
434 | return score; | 434 | return score; |
435 | } | 435 | } |
436 | 436 | ||
437 | /* | ||
438 | * In this second variant, we check (daddr, dport) matches (inet_rcv_sadd, inet_num) | ||
439 | */ | ||
440 | static inline int compute_score2(struct sock *sk, struct net *net, | ||
441 | __be32 saddr, __be16 sport, | ||
442 | __be32 daddr, unsigned int hnum, int dif) | ||
443 | { | ||
444 | int score; | ||
445 | struct inet_sock *inet; | ||
446 | |||
447 | if (!net_eq(sock_net(sk), net) || | ||
448 | ipv6_only_sock(sk)) | ||
449 | return -1; | ||
450 | |||
451 | inet = inet_sk(sk); | ||
452 | |||
453 | if (inet->inet_rcv_saddr != daddr || | ||
454 | inet->inet_num != hnum) | ||
455 | return -1; | ||
456 | |||
457 | score = (sk->sk_family == PF_INET) ? 2 : 1; | ||
458 | |||
459 | if (inet->inet_daddr) { | ||
460 | if (inet->inet_daddr != saddr) | ||
461 | return -1; | ||
462 | score += 4; | ||
463 | } | ||
464 | |||
465 | if (inet->inet_dport) { | ||
466 | if (inet->inet_dport != sport) | ||
467 | return -1; | ||
468 | score += 4; | ||
469 | } | ||
470 | |||
471 | if (sk->sk_bound_dev_if) { | ||
472 | if (sk->sk_bound_dev_if != dif) | ||
473 | return -1; | ||
474 | score += 4; | ||
475 | } | ||
476 | |||
477 | if (sk->sk_incoming_cpu == raw_smp_processor_id()) | ||
478 | score++; | ||
479 | |||
480 | return score; | ||
481 | } | ||
482 | |||
483 | static u32 udp_ehashfn(const struct net *net, const __be32 laddr, | 437 | static u32 udp_ehashfn(const struct net *net, const __be32 laddr, |
484 | const __u16 lport, const __be32 faddr, | 438 | const __u16 lport, const __be32 faddr, |
485 | const __be16 fport) | 439 | const __be16 fport) |
@@ -492,11 +446,11 @@ static u32 udp_ehashfn(const struct net *net, const __be32 laddr, | |||
492 | udp_ehash_secret + net_hash_mix(net)); | 446 | udp_ehash_secret + net_hash_mix(net)); |
493 | } | 447 | } |
494 | 448 | ||
495 | /* called with read_rcu_lock() */ | 449 | /* called with rcu_read_lock() */ |
496 | static struct sock *udp4_lib_lookup2(struct net *net, | 450 | static struct sock *udp4_lib_lookup2(struct net *net, |
497 | __be32 saddr, __be16 sport, | 451 | __be32 saddr, __be16 sport, |
498 | __be32 daddr, unsigned int hnum, int dif, | 452 | __be32 daddr, unsigned int hnum, int dif, |
499 | struct udp_hslot *hslot2, unsigned int slot2, | 453 | struct udp_hslot *hslot2, |
500 | struct sk_buff *skb) | 454 | struct sk_buff *skb) |
501 | { | 455 | { |
502 | struct sock *sk, *result; | 456 | struct sock *sk, *result; |
@@ -506,7 +460,7 @@ static struct sock *udp4_lib_lookup2(struct net *net, | |||
506 | result = NULL; | 460 | result = NULL; |
507 | badness = 0; | 461 | badness = 0; |
508 | udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) { | 462 | udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) { |
509 | score = compute_score2(sk, net, saddr, sport, | 463 | score = compute_score(sk, net, saddr, sport, |
510 | daddr, hnum, dif); | 464 | daddr, hnum, dif); |
511 | if (score > badness) { | 465 | if (score > badness) { |
512 | reuseport = sk->sk_reuseport; | 466 | reuseport = sk->sk_reuseport; |
@@ -554,17 +508,22 @@ struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr, | |||
554 | 508 | ||
555 | result = udp4_lib_lookup2(net, saddr, sport, | 509 | result = udp4_lib_lookup2(net, saddr, sport, |
556 | daddr, hnum, dif, | 510 | daddr, hnum, dif, |
557 | hslot2, slot2, skb); | 511 | hslot2, skb); |
558 | if (!result) { | 512 | if (!result) { |
513 | unsigned int old_slot2 = slot2; | ||
559 | hash2 = udp4_portaddr_hash(net, htonl(INADDR_ANY), hnum); | 514 | hash2 = udp4_portaddr_hash(net, htonl(INADDR_ANY), hnum); |
560 | slot2 = hash2 & udptable->mask; | 515 | slot2 = hash2 & udptable->mask; |
516 | /* avoid searching the same slot again. */ | ||
517 | if (unlikely(slot2 == old_slot2)) | ||
518 | return result; | ||
519 | |||
561 | hslot2 = &udptable->hash2[slot2]; | 520 | hslot2 = &udptable->hash2[slot2]; |
562 | if (hslot->count < hslot2->count) | 521 | if (hslot->count < hslot2->count) |
563 | goto begin; | 522 | goto begin; |
564 | 523 | ||
565 | result = udp4_lib_lookup2(net, saddr, sport, | 524 | result = udp4_lib_lookup2(net, saddr, sport, |
566 | htonl(INADDR_ANY), hnum, dif, | 525 | daddr, hnum, dif, |
567 | hslot2, slot2, skb); | 526 | hslot2, skb); |
568 | } | 527 | } |
569 | return result; | 528 | return result; |
570 | } | 529 | } |
@@ -572,8 +531,8 @@ begin: | |||
572 | result = NULL; | 531 | result = NULL; |
573 | badness = 0; | 532 | badness = 0; |
574 | sk_for_each_rcu(sk, &hslot->head) { | 533 | sk_for_each_rcu(sk, &hslot->head) { |
575 | score = compute_score(sk, net, saddr, hnum, sport, | 534 | score = compute_score(sk, net, saddr, sport, |
576 | daddr, dport, dif); | 535 | daddr, hnum, dif); |
577 | if (score > badness) { | 536 | if (score > badness) { |
578 | reuseport = sk->sk_reuseport; | 537 | reuseport = sk->sk_reuseport; |
579 | if (reuseport) { | 538 | if (reuseport) { |
@@ -1755,8 +1714,11 @@ static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh, | |||
1755 | return err; | 1714 | return err; |
1756 | } | 1715 | } |
1757 | 1716 | ||
1758 | return skb_checksum_init_zero_check(skb, proto, uh->check, | 1717 | /* Note, we are only interested in != 0 or == 0, thus the |
1759 | inet_compute_pseudo); | 1718 | * force to int. |
1719 | */ | ||
1720 | return (__force int)skb_checksum_init_zero_check(skb, proto, uh->check, | ||
1721 | inet_compute_pseudo); | ||
1760 | } | 1722 | } |
1761 | 1723 | ||
1762 | /* | 1724 | /* |