diff options
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/af_inet.c | 26 | ||||
-rw-r--r-- | net/ipv4/icmp.c | 9 | ||||
-rw-r--r-- | net/ipv4/ip_input.c | 5 | ||||
-rw-r--r-- | net/ipv4/protocol.c | 8 |
4 files changed, 21 insertions, 27 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index e4e8e00a2c91..85a3b1763136 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -242,20 +242,18 @@ void build_ehash_secret(void) | |||
242 | } | 242 | } |
243 | EXPORT_SYMBOL(build_ehash_secret); | 243 | EXPORT_SYMBOL(build_ehash_secret); |
244 | 244 | ||
245 | static inline int inet_netns_ok(struct net *net, int protocol) | 245 | static inline int inet_netns_ok(struct net *net, __u8 protocol) |
246 | { | 246 | { |
247 | int hash; | ||
248 | const struct net_protocol *ipprot; | 247 | const struct net_protocol *ipprot; |
249 | 248 | ||
250 | if (net_eq(net, &init_net)) | 249 | if (net_eq(net, &init_net)) |
251 | return 1; | 250 | return 1; |
252 | 251 | ||
253 | hash = protocol & (MAX_INET_PROTOS - 1); | 252 | ipprot = rcu_dereference(inet_protos[protocol]); |
254 | ipprot = rcu_dereference(inet_protos[hash]); | 253 | if (ipprot == NULL) { |
255 | |||
256 | if (ipprot == NULL) | ||
257 | /* raw IP is OK */ | 254 | /* raw IP is OK */ |
258 | return 1; | 255 | return 1; |
256 | } | ||
259 | return ipprot->netns_ok; | 257 | return ipprot->netns_ok; |
260 | } | 258 | } |
261 | 259 | ||
@@ -1216,8 +1214,8 @@ EXPORT_SYMBOL(inet_sk_rebuild_header); | |||
1216 | 1214 | ||
1217 | static int inet_gso_send_check(struct sk_buff *skb) | 1215 | static int inet_gso_send_check(struct sk_buff *skb) |
1218 | { | 1216 | { |
1219 | const struct iphdr *iph; | ||
1220 | const struct net_protocol *ops; | 1217 | const struct net_protocol *ops; |
1218 | const struct iphdr *iph; | ||
1221 | int proto; | 1219 | int proto; |
1222 | int ihl; | 1220 | int ihl; |
1223 | int err = -EINVAL; | 1221 | int err = -EINVAL; |
@@ -1236,7 +1234,7 @@ static int inet_gso_send_check(struct sk_buff *skb) | |||
1236 | __skb_pull(skb, ihl); | 1234 | __skb_pull(skb, ihl); |
1237 | skb_reset_transport_header(skb); | 1235 | skb_reset_transport_header(skb); |
1238 | iph = ip_hdr(skb); | 1236 | iph = ip_hdr(skb); |
1239 | proto = iph->protocol & (MAX_INET_PROTOS - 1); | 1237 | proto = iph->protocol; |
1240 | err = -EPROTONOSUPPORT; | 1238 | err = -EPROTONOSUPPORT; |
1241 | 1239 | ||
1242 | rcu_read_lock(); | 1240 | rcu_read_lock(); |
@@ -1253,8 +1251,8 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, | |||
1253 | netdev_features_t features) | 1251 | netdev_features_t features) |
1254 | { | 1252 | { |
1255 | struct sk_buff *segs = ERR_PTR(-EINVAL); | 1253 | struct sk_buff *segs = ERR_PTR(-EINVAL); |
1256 | struct iphdr *iph; | ||
1257 | const struct net_protocol *ops; | 1254 | const struct net_protocol *ops; |
1255 | struct iphdr *iph; | ||
1258 | int proto; | 1256 | int proto; |
1259 | int ihl; | 1257 | int ihl; |
1260 | int id; | 1258 | int id; |
@@ -1286,7 +1284,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, | |||
1286 | skb_reset_transport_header(skb); | 1284 | skb_reset_transport_header(skb); |
1287 | iph = ip_hdr(skb); | 1285 | iph = ip_hdr(skb); |
1288 | id = ntohs(iph->id); | 1286 | id = ntohs(iph->id); |
1289 | proto = iph->protocol & (MAX_INET_PROTOS - 1); | 1287 | proto = iph->protocol; |
1290 | segs = ERR_PTR(-EPROTONOSUPPORT); | 1288 | segs = ERR_PTR(-EPROTONOSUPPORT); |
1291 | 1289 | ||
1292 | rcu_read_lock(); | 1290 | rcu_read_lock(); |
@@ -1340,7 +1338,7 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head, | |||
1340 | goto out; | 1338 | goto out; |
1341 | } | 1339 | } |
1342 | 1340 | ||
1343 | proto = iph->protocol & (MAX_INET_PROTOS - 1); | 1341 | proto = iph->protocol; |
1344 | 1342 | ||
1345 | rcu_read_lock(); | 1343 | rcu_read_lock(); |
1346 | ops = rcu_dereference(inet_protos[proto]); | 1344 | ops = rcu_dereference(inet_protos[proto]); |
@@ -1398,11 +1396,11 @@ out: | |||
1398 | 1396 | ||
1399 | static int inet_gro_complete(struct sk_buff *skb) | 1397 | static int inet_gro_complete(struct sk_buff *skb) |
1400 | { | 1398 | { |
1401 | const struct net_protocol *ops; | 1399 | __be16 newlen = htons(skb->len - skb_network_offset(skb)); |
1402 | struct iphdr *iph = ip_hdr(skb); | 1400 | struct iphdr *iph = ip_hdr(skb); |
1403 | int proto = iph->protocol & (MAX_INET_PROTOS - 1); | 1401 | const struct net_protocol *ops; |
1402 | int proto = iph->protocol; | ||
1404 | int err = -ENOSYS; | 1403 | int err = -ENOSYS; |
1405 | __be16 newlen = htons(skb->len - skb_network_offset(skb)); | ||
1406 | 1404 | ||
1407 | csum_replace2(&iph->check, iph->tot_len, newlen); | 1405 | csum_replace2(&iph->check, iph->tot_len, newlen); |
1408 | iph->tot_len = newlen; | 1406 | iph->tot_len = newlen; |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index e1caa1abe5d1..49a74cc79dc8 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
@@ -637,12 +637,12 @@ EXPORT_SYMBOL(icmp_send); | |||
637 | 637 | ||
638 | static void icmp_unreach(struct sk_buff *skb) | 638 | static void icmp_unreach(struct sk_buff *skb) |
639 | { | 639 | { |
640 | const struct net_protocol *ipprot; | ||
640 | const struct iphdr *iph; | 641 | const struct iphdr *iph; |
641 | struct icmphdr *icmph; | 642 | struct icmphdr *icmph; |
642 | int hash, protocol; | ||
643 | const struct net_protocol *ipprot; | ||
644 | u32 info = 0; | ||
645 | struct net *net; | 643 | struct net *net; |
644 | u32 info = 0; | ||
645 | int protocol; | ||
646 | 646 | ||
647 | net = dev_net(skb_dst(skb)->dev); | 647 | net = dev_net(skb_dst(skb)->dev); |
648 | 648 | ||
@@ -731,9 +731,8 @@ static void icmp_unreach(struct sk_buff *skb) | |||
731 | */ | 731 | */ |
732 | raw_icmp_error(skb, protocol, info); | 732 | raw_icmp_error(skb, protocol, info); |
733 | 733 | ||
734 | hash = protocol & (MAX_INET_PROTOS - 1); | ||
735 | rcu_read_lock(); | 734 | rcu_read_lock(); |
736 | ipprot = rcu_dereference(inet_protos[hash]); | 735 | ipprot = rcu_dereference(inet_protos[protocol]); |
737 | if (ipprot && ipprot->err_handler) | 736 | if (ipprot && ipprot->err_handler) |
738 | ipprot->err_handler(skb, info); | 737 | ipprot->err_handler(skb, info); |
739 | rcu_read_unlock(); | 738 | rcu_read_unlock(); |
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 8590144ca330..c4fe1d271131 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c | |||
@@ -198,14 +198,13 @@ static int ip_local_deliver_finish(struct sk_buff *skb) | |||
198 | rcu_read_lock(); | 198 | rcu_read_lock(); |
199 | { | 199 | { |
200 | int protocol = ip_hdr(skb)->protocol; | 200 | int protocol = ip_hdr(skb)->protocol; |
201 | int hash, raw; | ||
202 | const struct net_protocol *ipprot; | 201 | const struct net_protocol *ipprot; |
202 | int raw; | ||
203 | 203 | ||
204 | resubmit: | 204 | resubmit: |
205 | raw = raw_local_deliver(skb, protocol); | 205 | raw = raw_local_deliver(skb, protocol); |
206 | 206 | ||
207 | hash = protocol & (MAX_INET_PROTOS - 1); | 207 | ipprot = rcu_dereference(inet_protos[protocol]); |
208 | ipprot = rcu_dereference(inet_protos[hash]); | ||
209 | if (ipprot != NULL) { | 208 | if (ipprot != NULL) { |
210 | int ret; | 209 | int ret; |
211 | 210 | ||
diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c index 9ae5c01cd0b2..8918eff1426d 100644 --- a/net/ipv4/protocol.c +++ b/net/ipv4/protocol.c | |||
@@ -36,9 +36,7 @@ const struct net_protocol __rcu *inet_protos[MAX_INET_PROTOS] __read_mostly; | |||
36 | 36 | ||
37 | int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol) | 37 | int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol) |
38 | { | 38 | { |
39 | int hash = protocol & (MAX_INET_PROTOS - 1); | 39 | return !cmpxchg((const struct net_protocol **)&inet_protos[protocol], |
40 | |||
41 | return !cmpxchg((const struct net_protocol **)&inet_protos[hash], | ||
42 | NULL, prot) ? 0 : -1; | 40 | NULL, prot) ? 0 : -1; |
43 | } | 41 | } |
44 | EXPORT_SYMBOL(inet_add_protocol); | 42 | EXPORT_SYMBOL(inet_add_protocol); |
@@ -49,9 +47,9 @@ EXPORT_SYMBOL(inet_add_protocol); | |||
49 | 47 | ||
50 | int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol) | 48 | int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol) |
51 | { | 49 | { |
52 | int ret, hash = protocol & (MAX_INET_PROTOS - 1); | 50 | int ret; |
53 | 51 | ||
54 | ret = (cmpxchg((const struct net_protocol **)&inet_protos[hash], | 52 | ret = (cmpxchg((const struct net_protocol **)&inet_protos[protocol], |
55 | prot, NULL) == prot) ? 0 : -1; | 53 | prot, NULL) == prot) ? 0 : -1; |
56 | 54 | ||
57 | synchronize_net(); | 55 | synchronize_net(); |