diff options
Diffstat (limited to 'net/ipv4')
46 files changed, 621 insertions, 497 deletions
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 5b919f7b45db..70491d9035eb 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig | |||
@@ -273,29 +273,20 @@ config IP_PIMSM_V2 | |||
273 | you want to play with it. | 273 | you want to play with it. |
274 | 274 | ||
275 | config ARPD | 275 | config ARPD |
276 | bool "IP: ARP daemon support (EXPERIMENTAL)" | 276 | bool "IP: ARP daemon support" |
277 | depends on EXPERIMENTAL | ||
278 | ---help--- | 277 | ---help--- |
279 | Normally, the kernel maintains an internal cache which maps IP | 278 | The kernel maintains an internal cache which maps IP addresses to |
280 | addresses to hardware addresses on the local network, so that | 279 | hardware addresses on the local network, so that Ethernet/Token Ring/ |
281 | Ethernet/Token Ring/ etc. frames are sent to the proper address on | 280 | etc. frames are sent to the proper address on the physical networking |
282 | the physical networking layer. For small networks having a few | 281 | layer. Normally, kernel uses the ARP protocol to resolve these |
283 | hundred directly connected hosts or less, keeping this address | 282 | mappings. |
284 | resolution (ARP) cache inside the kernel works well. However, | 283 | |
285 | maintaining an internal ARP cache does not work well for very large | 284 | Saying Y here adds support to have an user space daemon to do this |
286 | switched networks, and will use a lot of kernel memory if TCP/IP | 285 | resolution instead. This is useful for implementing an alternate |
287 | connections are made to many machines on the network. | 286 | address resolution protocol (e.g. NHRP on mGRE tunnels) and also for |
288 | 287 | testing purposes. | |
289 | If you say Y here, the kernel's internal ARP cache will never grow | 288 | |
290 | to more than 256 entries (the oldest entries are expired in a LIFO | 289 | If unsure, say N. |
291 | manner) and communication will be attempted with the user space ARP | ||
292 | daemon arpd. Arpd then answers the address resolution request either | ||
293 | from its own cache or by asking the net. | ||
294 | |||
295 | This code is experimental and also obsolete. If you want to use it, | ||
296 | you need to find a version of the daemon arpd on the net somewhere, | ||
297 | and you should also say Y to "Kernel/User network link driver", | ||
298 | below. If unsure, say N. | ||
299 | 290 | ||
300 | config SYN_COOKIES | 291 | config SYN_COOKIES |
301 | bool "IP: TCP syncookie support (disabled per default)" | 292 | bool "IP: TCP syncookie support (disabled per default)" |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 7f03373b8c07..566ea6c4321d 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -116,7 +116,6 @@ | |||
116 | #include <linux/mroute.h> | 116 | #include <linux/mroute.h> |
117 | #endif | 117 | #endif |
118 | 118 | ||
119 | extern void ip_mc_drop_socket(struct sock *sk); | ||
120 | 119 | ||
121 | /* The inetsw table contains everything that inet_create needs to | 120 | /* The inetsw table contains everything that inet_create needs to |
122 | * build a new socket. | 121 | * build a new socket. |
@@ -375,6 +374,7 @@ lookup_protocol: | |||
375 | inet->uc_ttl = -1; | 374 | inet->uc_ttl = -1; |
376 | inet->mc_loop = 1; | 375 | inet->mc_loop = 1; |
377 | inet->mc_ttl = 1; | 376 | inet->mc_ttl = 1; |
377 | inet->mc_all = 1; | ||
378 | inet->mc_index = 0; | 378 | inet->mc_index = 0; |
379 | inet->mc_list = NULL; | 379 | inet->mc_list = NULL; |
380 | 380 | ||
@@ -1003,8 +1003,6 @@ void inet_register_protosw(struct inet_protosw *p) | |||
1003 | out: | 1003 | out: |
1004 | spin_unlock_bh(&inetsw_lock); | 1004 | spin_unlock_bh(&inetsw_lock); |
1005 | 1005 | ||
1006 | synchronize_net(); | ||
1007 | |||
1008 | return; | 1006 | return; |
1009 | 1007 | ||
1010 | out_permanent: | 1008 | out_permanent: |
@@ -1248,13 +1246,20 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head, | |||
1248 | struct sk_buff **pp = NULL; | 1246 | struct sk_buff **pp = NULL; |
1249 | struct sk_buff *p; | 1247 | struct sk_buff *p; |
1250 | struct iphdr *iph; | 1248 | struct iphdr *iph; |
1249 | unsigned int hlen; | ||
1250 | unsigned int off; | ||
1251 | unsigned int id; | ||
1251 | int flush = 1; | 1252 | int flush = 1; |
1252 | int proto; | 1253 | int proto; |
1253 | int id; | ||
1254 | 1254 | ||
1255 | iph = skb_gro_header(skb, sizeof(*iph)); | 1255 | off = skb_gro_offset(skb); |
1256 | if (unlikely(!iph)) | 1256 | hlen = off + sizeof(*iph); |
1257 | goto out; | 1257 | iph = skb_gro_header_fast(skb, off); |
1258 | if (skb_gro_header_hard(skb, hlen)) { | ||
1259 | iph = skb_gro_header_slow(skb, hlen, off); | ||
1260 | if (unlikely(!iph)) | ||
1261 | goto out; | ||
1262 | } | ||
1258 | 1263 | ||
1259 | proto = iph->protocol & (MAX_INET_PROTOS - 1); | 1264 | proto = iph->protocol & (MAX_INET_PROTOS - 1); |
1260 | 1265 | ||
@@ -1269,9 +1274,9 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head, | |||
1269 | if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl))) | 1274 | if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl))) |
1270 | goto out_unlock; | 1275 | goto out_unlock; |
1271 | 1276 | ||
1272 | flush = ntohs(iph->tot_len) != skb_gro_len(skb) || | 1277 | id = ntohl(*(u32 *)&iph->id); |
1273 | iph->frag_off != htons(IP_DF); | 1278 | flush = (u16)((ntohl(*(u32 *)iph) ^ skb_gro_len(skb)) | (id ^ IP_DF)); |
1274 | id = ntohs(iph->id); | 1279 | id >>= 16; |
1275 | 1280 | ||
1276 | for (p = *head; p; p = p->next) { | 1281 | for (p = *head; p; p = p->next) { |
1277 | struct iphdr *iph2; | 1282 | struct iphdr *iph2; |
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index f11931c18381..8a3881e28aca 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -468,13 +468,13 @@ int arp_find(unsigned char *haddr, struct sk_buff *skb) | |||
468 | __be32 paddr; | 468 | __be32 paddr; |
469 | struct neighbour *n; | 469 | struct neighbour *n; |
470 | 470 | ||
471 | if (!skb->dst) { | 471 | if (!skb_dst(skb)) { |
472 | printk(KERN_DEBUG "arp_find is called with dst==NULL\n"); | 472 | printk(KERN_DEBUG "arp_find is called with dst==NULL\n"); |
473 | kfree_skb(skb); | 473 | kfree_skb(skb); |
474 | return 1; | 474 | return 1; |
475 | } | 475 | } |
476 | 476 | ||
477 | paddr = skb->rtable->rt_gateway; | 477 | paddr = skb_rtable(skb)->rt_gateway; |
478 | 478 | ||
479 | if (arp_set_predefined(inet_addr_type(dev_net(dev), paddr), haddr, paddr, dev)) | 479 | if (arp_set_predefined(inet_addr_type(dev_net(dev), paddr), haddr, paddr, dev)) |
480 | return 0; | 480 | return 0; |
@@ -817,7 +817,7 @@ static int arp_process(struct sk_buff *skb) | |||
817 | if (arp->ar_op == htons(ARPOP_REQUEST) && | 817 | if (arp->ar_op == htons(ARPOP_REQUEST) && |
818 | ip_route_input(skb, tip, sip, 0, dev) == 0) { | 818 | ip_route_input(skb, tip, sip, 0, dev) == 0) { |
819 | 819 | ||
820 | rt = skb->rtable; | 820 | rt = skb_rtable(skb); |
821 | addr_type = rt->rt_type; | 821 | addr_type = rt->rt_type; |
822 | 822 | ||
823 | if (addr_type == RTN_LOCAL) { | 823 | if (addr_type == RTN_LOCAL) { |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 126bb911880f..3863c3a4223f 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -1347,7 +1347,8 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write, | |||
1347 | struct net *net = ctl->extra2; | 1347 | struct net *net = ctl->extra2; |
1348 | 1348 | ||
1349 | if (valp != &IPV4_DEVCONF_DFLT(net, FORWARDING)) { | 1349 | if (valp != &IPV4_DEVCONF_DFLT(net, FORWARDING)) { |
1350 | rtnl_lock(); | 1350 | if (!rtnl_trylock()) |
1351 | return restart_syscall(); | ||
1351 | if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING)) { | 1352 | if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING)) { |
1352 | inet_forward_change(net); | 1353 | inet_forward_change(net); |
1353 | } else if (*valp) { | 1354 | } else if (*valp) { |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index cafcc49d0993..e2f950592566 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include <net/route.h> | 40 | #include <net/route.h> |
41 | #include <net/tcp.h> | 41 | #include <net/tcp.h> |
42 | #include <net/sock.h> | 42 | #include <net/sock.h> |
43 | #include <net/icmp.h> | ||
44 | #include <net/arp.h> | 43 | #include <net/arp.h> |
45 | #include <net/ip_fib.h> | 44 | #include <net/ip_fib.h> |
46 | #include <net/rtnetlink.h> | 45 | #include <net/rtnetlink.h> |
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index ded8c44fb848..ecd39454235c 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c | |||
@@ -263,7 +263,6 @@ fn_hash_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result | |||
263 | 263 | ||
264 | err = fib_semantic_match(&f->fn_alias, | 264 | err = fib_semantic_match(&f->fn_alias, |
265 | flp, res, | 265 | flp, res, |
266 | f->fn_key, fz->fz_mask, | ||
267 | fz->fz_order); | 266 | fz->fz_order); |
268 | if (err <= 0) | 267 | if (err <= 0) |
269 | goto out; | 268 | goto out; |
diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h index 2c1623d2768b..637b133973bd 100644 --- a/net/ipv4/fib_lookup.h +++ b/net/ipv4/fib_lookup.h | |||
@@ -22,8 +22,7 @@ struct fib_alias { | |||
22 | /* Exported by fib_semantics.c */ | 22 | /* Exported by fib_semantics.c */ |
23 | extern int fib_semantic_match(struct list_head *head, | 23 | extern int fib_semantic_match(struct list_head *head, |
24 | const struct flowi *flp, | 24 | const struct flowi *flp, |
25 | struct fib_result *res, __be32 zone, __be32 mask, | 25 | struct fib_result *res, int prefixlen); |
26 | int prefixlen); | ||
27 | extern void fib_release_info(struct fib_info *); | 26 | extern void fib_release_info(struct fib_info *); |
28 | extern struct fib_info *fib_create_info(struct fib_config *cfg); | 27 | extern struct fib_info *fib_create_info(struct fib_config *cfg); |
29 | extern int fib_nh_match(struct fib_config *cfg, struct fib_info *fi); | 28 | extern int fib_nh_match(struct fib_config *cfg, struct fib_info *fi); |
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 6080d7120821..92d9d97ec5e3 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
@@ -134,7 +134,7 @@ static const struct nla_policy fib4_rule_policy[FRA_MAX+1] = { | |||
134 | }; | 134 | }; |
135 | 135 | ||
136 | static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | 136 | static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, |
137 | struct nlmsghdr *nlh, struct fib_rule_hdr *frh, | 137 | struct fib_rule_hdr *frh, |
138 | struct nlattr **tb) | 138 | struct nlattr **tb) |
139 | { | 139 | { |
140 | struct net *net = sock_net(skb->sk); | 140 | struct net *net = sock_net(skb->sk); |
@@ -209,7 +209,7 @@ static int fib4_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, | |||
209 | } | 209 | } |
210 | 210 | ||
211 | static int fib4_rule_fill(struct fib_rule *rule, struct sk_buff *skb, | 211 | static int fib4_rule_fill(struct fib_rule *rule, struct sk_buff *skb, |
212 | struct nlmsghdr *nlh, struct fib_rule_hdr *frh) | 212 | struct fib_rule_hdr *frh) |
213 | { | 213 | { |
214 | struct fib4_rule *rule4 = (struct fib4_rule *) rule; | 214 | struct fib4_rule *rule4 = (struct fib4_rule *) rule; |
215 | 215 | ||
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index f831df500907..9b096d6ff3f2 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
@@ -866,8 +866,7 @@ failure: | |||
866 | 866 | ||
867 | /* Note! fib_semantic_match intentionally uses RCU list functions. */ | 867 | /* Note! fib_semantic_match intentionally uses RCU list functions. */ |
868 | int fib_semantic_match(struct list_head *head, const struct flowi *flp, | 868 | int fib_semantic_match(struct list_head *head, const struct flowi *flp, |
869 | struct fib_result *res, __be32 zone, __be32 mask, | 869 | struct fib_result *res, int prefixlen) |
870 | int prefixlen) | ||
871 | { | 870 | { |
872 | struct fib_alias *fa; | 871 | struct fib_alias *fa; |
873 | int nh_sel = 0; | 872 | int nh_sel = 0; |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 33c7c85dfe40..d1a39b1277d6 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -123,6 +123,7 @@ struct tnode { | |||
123 | union { | 123 | union { |
124 | struct rcu_head rcu; | 124 | struct rcu_head rcu; |
125 | struct work_struct work; | 125 | struct work_struct work; |
126 | struct tnode *tnode_free; | ||
126 | }; | 127 | }; |
127 | struct node *child[0]; | 128 | struct node *child[0]; |
128 | }; | 129 | }; |
@@ -161,6 +162,8 @@ static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, | |||
161 | static struct node *resize(struct trie *t, struct tnode *tn); | 162 | static struct node *resize(struct trie *t, struct tnode *tn); |
162 | static struct tnode *inflate(struct trie *t, struct tnode *tn); | 163 | static struct tnode *inflate(struct trie *t, struct tnode *tn); |
163 | static struct tnode *halve(struct trie *t, struct tnode *tn); | 164 | static struct tnode *halve(struct trie *t, struct tnode *tn); |
165 | /* tnodes to free after resize(); protected by RTNL */ | ||
166 | static struct tnode *tnode_free_head; | ||
164 | 167 | ||
165 | static struct kmem_cache *fn_alias_kmem __read_mostly; | 168 | static struct kmem_cache *fn_alias_kmem __read_mostly; |
166 | static struct kmem_cache *trie_leaf_kmem __read_mostly; | 169 | static struct kmem_cache *trie_leaf_kmem __read_mostly; |
@@ -385,6 +388,29 @@ static inline void tnode_free(struct tnode *tn) | |||
385 | call_rcu(&tn->rcu, __tnode_free_rcu); | 388 | call_rcu(&tn->rcu, __tnode_free_rcu); |
386 | } | 389 | } |
387 | 390 | ||
391 | static void tnode_free_safe(struct tnode *tn) | ||
392 | { | ||
393 | BUG_ON(IS_LEAF(tn)); | ||
394 | |||
395 | if (node_parent((struct node *) tn)) { | ||
396 | tn->tnode_free = tnode_free_head; | ||
397 | tnode_free_head = tn; | ||
398 | } else { | ||
399 | tnode_free(tn); | ||
400 | } | ||
401 | } | ||
402 | |||
403 | static void tnode_free_flush(void) | ||
404 | { | ||
405 | struct tnode *tn; | ||
406 | |||
407 | while ((tn = tnode_free_head)) { | ||
408 | tnode_free_head = tn->tnode_free; | ||
409 | tn->tnode_free = NULL; | ||
410 | tnode_free(tn); | ||
411 | } | ||
412 | } | ||
413 | |||
388 | static struct leaf *leaf_new(void) | 414 | static struct leaf *leaf_new(void) |
389 | { | 415 | { |
390 | struct leaf *l = kmem_cache_alloc(trie_leaf_kmem, GFP_KERNEL); | 416 | struct leaf *l = kmem_cache_alloc(trie_leaf_kmem, GFP_KERNEL); |
@@ -495,7 +521,7 @@ static struct node *resize(struct trie *t, struct tnode *tn) | |||
495 | 521 | ||
496 | /* No children */ | 522 | /* No children */ |
497 | if (tn->empty_children == tnode_child_length(tn)) { | 523 | if (tn->empty_children == tnode_child_length(tn)) { |
498 | tnode_free(tn); | 524 | tnode_free_safe(tn); |
499 | return NULL; | 525 | return NULL; |
500 | } | 526 | } |
501 | /* One child */ | 527 | /* One child */ |
@@ -509,7 +535,7 @@ static struct node *resize(struct trie *t, struct tnode *tn) | |||
509 | 535 | ||
510 | /* compress one level */ | 536 | /* compress one level */ |
511 | node_set_parent(n, NULL); | 537 | node_set_parent(n, NULL); |
512 | tnode_free(tn); | 538 | tnode_free_safe(tn); |
513 | return n; | 539 | return n; |
514 | } | 540 | } |
515 | /* | 541 | /* |
@@ -670,7 +696,7 @@ static struct node *resize(struct trie *t, struct tnode *tn) | |||
670 | /* compress one level */ | 696 | /* compress one level */ |
671 | 697 | ||
672 | node_set_parent(n, NULL); | 698 | node_set_parent(n, NULL); |
673 | tnode_free(tn); | 699 | tnode_free_safe(tn); |
674 | return n; | 700 | return n; |
675 | } | 701 | } |
676 | 702 | ||
@@ -756,7 +782,7 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn) | |||
756 | put_child(t, tn, 2*i, inode->child[0]); | 782 | put_child(t, tn, 2*i, inode->child[0]); |
757 | put_child(t, tn, 2*i+1, inode->child[1]); | 783 | put_child(t, tn, 2*i+1, inode->child[1]); |
758 | 784 | ||
759 | tnode_free(inode); | 785 | tnode_free_safe(inode); |
760 | continue; | 786 | continue; |
761 | } | 787 | } |
762 | 788 | ||
@@ -801,9 +827,9 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn) | |||
801 | put_child(t, tn, 2*i, resize(t, left)); | 827 | put_child(t, tn, 2*i, resize(t, left)); |
802 | put_child(t, tn, 2*i+1, resize(t, right)); | 828 | put_child(t, tn, 2*i+1, resize(t, right)); |
803 | 829 | ||
804 | tnode_free(inode); | 830 | tnode_free_safe(inode); |
805 | } | 831 | } |
806 | tnode_free(oldtnode); | 832 | tnode_free_safe(oldtnode); |
807 | return tn; | 833 | return tn; |
808 | nomem: | 834 | nomem: |
809 | { | 835 | { |
@@ -885,7 +911,7 @@ static struct tnode *halve(struct trie *t, struct tnode *tn) | |||
885 | put_child(t, newBinNode, 1, right); | 911 | put_child(t, newBinNode, 1, right); |
886 | put_child(t, tn, i/2, resize(t, newBinNode)); | 912 | put_child(t, tn, i/2, resize(t, newBinNode)); |
887 | } | 913 | } |
888 | tnode_free(oldtnode); | 914 | tnode_free_safe(oldtnode); |
889 | return tn; | 915 | return tn; |
890 | nomem: | 916 | nomem: |
891 | { | 917 | { |
@@ -989,7 +1015,6 @@ static struct node *trie_rebalance(struct trie *t, struct tnode *tn) | |||
989 | t_key cindex, key; | 1015 | t_key cindex, key; |
990 | struct tnode *tp; | 1016 | struct tnode *tp; |
991 | 1017 | ||
992 | preempt_disable(); | ||
993 | key = tn->key; | 1018 | key = tn->key; |
994 | 1019 | ||
995 | while (tn != NULL && (tp = node_parent((struct node *)tn)) != NULL) { | 1020 | while (tn != NULL && (tp = node_parent((struct node *)tn)) != NULL) { |
@@ -1001,16 +1026,18 @@ static struct node *trie_rebalance(struct trie *t, struct tnode *tn) | |||
1001 | (struct node *)tn, wasfull); | 1026 | (struct node *)tn, wasfull); |
1002 | 1027 | ||
1003 | tp = node_parent((struct node *) tn); | 1028 | tp = node_parent((struct node *) tn); |
1029 | tnode_free_flush(); | ||
1004 | if (!tp) | 1030 | if (!tp) |
1005 | break; | 1031 | break; |
1006 | tn = tp; | 1032 | tn = tp; |
1007 | } | 1033 | } |
1008 | 1034 | ||
1009 | /* Handle last (top) tnode */ | 1035 | /* Handle last (top) tnode */ |
1010 | if (IS_TNODE(tn)) | 1036 | if (IS_TNODE(tn)) { |
1011 | tn = (struct tnode *)resize(t, (struct tnode *)tn); | 1037 | tn = (struct tnode *)resize(t, (struct tnode *)tn); |
1038 | tnode_free_flush(); | ||
1039 | } | ||
1012 | 1040 | ||
1013 | preempt_enable(); | ||
1014 | return (struct node *)tn; | 1041 | return (struct node *)tn; |
1015 | } | 1042 | } |
1016 | 1043 | ||
@@ -1351,8 +1378,7 @@ static int check_leaf(struct trie *t, struct leaf *l, | |||
1351 | if (l->key != (key & ntohl(mask))) | 1378 | if (l->key != (key & ntohl(mask))) |
1352 | continue; | 1379 | continue; |
1353 | 1380 | ||
1354 | err = fib_semantic_match(&li->falh, flp, res, | 1381 | err = fib_semantic_match(&li->falh, flp, res, plen); |
1355 | htonl(l->key), mask, plen); | ||
1356 | 1382 | ||
1357 | #ifdef CONFIG_IP_FIB_TRIE_STATS | 1383 | #ifdef CONFIG_IP_FIB_TRIE_STATS |
1358 | if (err <= 0) | 1384 | if (err <= 0) |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 3f50807237e0..97c410e84388 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
@@ -356,7 +356,7 @@ static void icmp_push_reply(struct icmp_bxm *icmp_param, | |||
356 | static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) | 356 | static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) |
357 | { | 357 | { |
358 | struct ipcm_cookie ipc; | 358 | struct ipcm_cookie ipc; |
359 | struct rtable *rt = skb->rtable; | 359 | struct rtable *rt = skb_rtable(skb); |
360 | struct net *net = dev_net(rt->u.dst.dev); | 360 | struct net *net = dev_net(rt->u.dst.dev); |
361 | struct sock *sk; | 361 | struct sock *sk; |
362 | struct inet_sock *inet; | 362 | struct inet_sock *inet; |
@@ -416,7 +416,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
416 | struct iphdr *iph; | 416 | struct iphdr *iph; |
417 | int room; | 417 | int room; |
418 | struct icmp_bxm icmp_param; | 418 | struct icmp_bxm icmp_param; |
419 | struct rtable *rt = skb_in->rtable; | 419 | struct rtable *rt = skb_rtable(skb_in); |
420 | struct ipcm_cookie ipc; | 420 | struct ipcm_cookie ipc; |
421 | __be32 saddr; | 421 | __be32 saddr; |
422 | u8 tos; | 422 | u8 tos; |
@@ -591,13 +591,13 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
591 | goto relookup_failed; | 591 | goto relookup_failed; |
592 | 592 | ||
593 | /* Ugh! */ | 593 | /* Ugh! */ |
594 | odst = skb_in->dst; | 594 | odst = skb_dst(skb_in); |
595 | err = ip_route_input(skb_in, fl.fl4_dst, fl.fl4_src, | 595 | err = ip_route_input(skb_in, fl.fl4_dst, fl.fl4_src, |
596 | RT_TOS(tos), rt2->u.dst.dev); | 596 | RT_TOS(tos), rt2->u.dst.dev); |
597 | 597 | ||
598 | dst_release(&rt2->u.dst); | 598 | dst_release(&rt2->u.dst); |
599 | rt2 = skb_in->rtable; | 599 | rt2 = skb_rtable(skb_in); |
600 | skb_in->dst = odst; | 600 | skb_dst_set(skb_in, odst); |
601 | } | 601 | } |
602 | 602 | ||
603 | if (err) | 603 | if (err) |
@@ -659,7 +659,7 @@ static void icmp_unreach(struct sk_buff *skb) | |||
659 | u32 info = 0; | 659 | u32 info = 0; |
660 | struct net *net; | 660 | struct net *net; |
661 | 661 | ||
662 | net = dev_net(skb->dst->dev); | 662 | net = dev_net(skb_dst(skb)->dev); |
663 | 663 | ||
664 | /* | 664 | /* |
665 | * Incomplete header ? | 665 | * Incomplete header ? |
@@ -822,7 +822,7 @@ static void icmp_echo(struct sk_buff *skb) | |||
822 | { | 822 | { |
823 | struct net *net; | 823 | struct net *net; |
824 | 824 | ||
825 | net = dev_net(skb->dst->dev); | 825 | net = dev_net(skb_dst(skb)->dev); |
826 | if (!net->ipv4.sysctl_icmp_echo_ignore_all) { | 826 | if (!net->ipv4.sysctl_icmp_echo_ignore_all) { |
827 | struct icmp_bxm icmp_param; | 827 | struct icmp_bxm icmp_param; |
828 | 828 | ||
@@ -873,7 +873,7 @@ static void icmp_timestamp(struct sk_buff *skb) | |||
873 | out: | 873 | out: |
874 | return; | 874 | return; |
875 | out_err: | 875 | out_err: |
876 | ICMP_INC_STATS_BH(dev_net(skb->dst->dev), ICMP_MIB_INERRORS); | 876 | ICMP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), ICMP_MIB_INERRORS); |
877 | goto out; | 877 | goto out; |
878 | } | 878 | } |
879 | 879 | ||
@@ -926,7 +926,7 @@ static void icmp_address(struct sk_buff *skb) | |||
926 | 926 | ||
927 | static void icmp_address_reply(struct sk_buff *skb) | 927 | static void icmp_address_reply(struct sk_buff *skb) |
928 | { | 928 | { |
929 | struct rtable *rt = skb->rtable; | 929 | struct rtable *rt = skb_rtable(skb); |
930 | struct net_device *dev = skb->dev; | 930 | struct net_device *dev = skb->dev; |
931 | struct in_device *in_dev; | 931 | struct in_device *in_dev; |
932 | struct in_ifaddr *ifa; | 932 | struct in_ifaddr *ifa; |
@@ -970,7 +970,7 @@ static void icmp_discard(struct sk_buff *skb) | |||
970 | int icmp_rcv(struct sk_buff *skb) | 970 | int icmp_rcv(struct sk_buff *skb) |
971 | { | 971 | { |
972 | struct icmphdr *icmph; | 972 | struct icmphdr *icmph; |
973 | struct rtable *rt = skb->rtable; | 973 | struct rtable *rt = skb_rtable(skb); |
974 | struct net *net = dev_net(rt->u.dst.dev); | 974 | struct net *net = dev_net(rt->u.dst.dev); |
975 | 975 | ||
976 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { | 976 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 9eb6219af615..01b4284ed694 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -311,7 +311,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) | |||
311 | return NULL; | 311 | return NULL; |
312 | } | 312 | } |
313 | 313 | ||
314 | skb->dst = &rt->u.dst; | 314 | skb_dst_set(skb, &rt->u.dst); |
315 | skb->dev = dev; | 315 | skb->dev = dev; |
316 | 316 | ||
317 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 317 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); |
@@ -659,7 +659,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, | |||
659 | return -1; | 659 | return -1; |
660 | } | 660 | } |
661 | 661 | ||
662 | skb->dst = &rt->u.dst; | 662 | skb_dst_set(skb, &rt->u.dst); |
663 | 663 | ||
664 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 664 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); |
665 | 665 | ||
@@ -948,7 +948,7 @@ int igmp_rcv(struct sk_buff *skb) | |||
948 | case IGMPV2_HOST_MEMBERSHIP_REPORT: | 948 | case IGMPV2_HOST_MEMBERSHIP_REPORT: |
949 | case IGMPV3_HOST_MEMBERSHIP_REPORT: | 949 | case IGMPV3_HOST_MEMBERSHIP_REPORT: |
950 | /* Is it our report looped back? */ | 950 | /* Is it our report looped back? */ |
951 | if (skb->rtable->fl.iif == 0) | 951 | if (skb_rtable(skb)->fl.iif == 0) |
952 | break; | 952 | break; |
953 | /* don't rely on MC router hearing unicast reports */ | 953 | /* don't rely on MC router hearing unicast reports */ |
954 | if (skb->pkt_type == PACKET_MULTICAST || | 954 | if (skb->pkt_type == PACKET_MULTICAST || |
@@ -2196,7 +2196,7 @@ int ip_mc_sf_allow(struct sock *sk, __be32 loc_addr, __be32 rmt_addr, int dif) | |||
2196 | break; | 2196 | break; |
2197 | } | 2197 | } |
2198 | if (!pmc) | 2198 | if (!pmc) |
2199 | return 1; | 2199 | return inet->mc_all; |
2200 | psl = pmc->sflist; | 2200 | psl = pmc->sflist; |
2201 | if (!psl) | 2201 | if (!psl) |
2202 | return pmc->sfmode == MCAST_EXCLUDE; | 2202 | return pmc->sfmode == MCAST_EXCLUDE; |
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 588a7796e3e3..b0b273503e2a 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
@@ -198,8 +198,6 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, | |||
198 | tmo = 0; | 198 | tmo = 0; |
199 | 199 | ||
200 | r->idiag_family = tw->tw_family; | 200 | r->idiag_family = tw->tw_family; |
201 | r->idiag_state = tw->tw_state; | ||
202 | r->idiag_timer = 0; | ||
203 | r->idiag_retrans = 0; | 201 | r->idiag_retrans = 0; |
204 | r->id.idiag_if = tw->tw_bound_dev_if; | 202 | r->id.idiag_if = tw->tw_bound_dev_if; |
205 | r->id.idiag_cookie[0] = (u32)(unsigned long)tw; | 203 | r->id.idiag_cookie[0] = (u32)(unsigned long)tw; |
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c index 03169fc84877..61283f928825 100644 --- a/net/ipv4/inet_timewait_sock.c +++ b/net/ipv4/inet_timewait_sock.c | |||
@@ -50,19 +50,22 @@ static void __inet_twsk_kill(struct inet_timewait_sock *tw, | |||
50 | inet_twsk_put(tw); | 50 | inet_twsk_put(tw); |
51 | } | 51 | } |
52 | 52 | ||
53 | void inet_twsk_put(struct inet_timewait_sock *tw) | 53 | static noinline void inet_twsk_free(struct inet_timewait_sock *tw) |
54 | { | 54 | { |
55 | if (atomic_dec_and_test(&tw->tw_refcnt)) { | 55 | struct module *owner = tw->tw_prot->owner; |
56 | struct module *owner = tw->tw_prot->owner; | 56 | twsk_destructor((struct sock *)tw); |
57 | twsk_destructor((struct sock *)tw); | ||
58 | #ifdef SOCK_REFCNT_DEBUG | 57 | #ifdef SOCK_REFCNT_DEBUG |
59 | printk(KERN_DEBUG "%s timewait_sock %p released\n", | 58 | pr_debug("%s timewait_sock %p released\n", tw->tw_prot->name, tw); |
60 | tw->tw_prot->name, tw); | ||
61 | #endif | 59 | #endif |
62 | release_net(twsk_net(tw)); | 60 | release_net(twsk_net(tw)); |
63 | kmem_cache_free(tw->tw_prot->twsk_prot->twsk_slab, tw); | 61 | kmem_cache_free(tw->tw_prot->twsk_prot->twsk_slab, tw); |
64 | module_put(owner); | 62 | module_put(owner); |
65 | } | 63 | } |
64 | |||
65 | void inet_twsk_put(struct inet_timewait_sock *tw) | ||
66 | { | ||
67 | if (atomic_dec_and_test(&tw->tw_refcnt)) | ||
68 | inet_twsk_free(tw); | ||
66 | } | 69 | } |
67 | EXPORT_SYMBOL_GPL(inet_twsk_put); | 70 | EXPORT_SYMBOL_GPL(inet_twsk_put); |
68 | 71 | ||
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c index df3fe50bbf0d..a2991bc8e32e 100644 --- a/net/ipv4/ip_forward.c +++ b/net/ipv4/ip_forward.c | |||
@@ -42,7 +42,7 @@ static int ip_forward_finish(struct sk_buff *skb) | |||
42 | { | 42 | { |
43 | struct ip_options * opt = &(IPCB(skb)->opt); | 43 | struct ip_options * opt = &(IPCB(skb)->opt); |
44 | 44 | ||
45 | IP_INC_STATS_BH(dev_net(skb->dst->dev), IPSTATS_MIB_OUTFORWDATAGRAMS); | 45 | IP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTFORWDATAGRAMS); |
46 | 46 | ||
47 | if (unlikely(opt->optlen)) | 47 | if (unlikely(opt->optlen)) |
48 | ip_forward_options(skb); | 48 | ip_forward_options(skb); |
@@ -81,7 +81,7 @@ int ip_forward(struct sk_buff *skb) | |||
81 | if (!xfrm4_route_forward(skb)) | 81 | if (!xfrm4_route_forward(skb)) |
82 | goto drop; | 82 | goto drop; |
83 | 83 | ||
84 | rt = skb->rtable; | 84 | rt = skb_rtable(skb); |
85 | 85 | ||
86 | if (opt->is_strictroute && rt->rt_dst != rt->rt_gateway) | 86 | if (opt->is_strictroute && rt->rt_dst != rt->rt_gateway) |
87 | goto sr_failed; | 87 | goto sr_failed; |
@@ -123,7 +123,7 @@ sr_failed: | |||
123 | 123 | ||
124 | too_many_hops: | 124 | too_many_hops: |
125 | /* Tell the sender its packet died... */ | 125 | /* Tell the sender its packet died... */ |
126 | IP_INC_STATS_BH(dev_net(skb->dst->dev), IPSTATS_MIB_INHDRERRORS); | 126 | IP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_INHDRERRORS); |
127 | icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0); | 127 | icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0); |
128 | drop: | 128 | drop: |
129 | kfree_skb(skb); | 129 | kfree_skb(skb); |
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 7985346653bd..575f9bd51ccd 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
@@ -507,7 +507,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, | |||
507 | /* If the first fragment is fragmented itself, we split | 507 | /* If the first fragment is fragmented itself, we split |
508 | * it to two chunks: the first with data and paged part | 508 | * it to two chunks: the first with data and paged part |
509 | * and the second, holding only fragments. */ | 509 | * and the second, holding only fragments. */ |
510 | if (skb_shinfo(head)->frag_list) { | 510 | if (skb_has_frags(head)) { |
511 | struct sk_buff *clone; | 511 | struct sk_buff *clone; |
512 | int i, plen = 0; | 512 | int i, plen = 0; |
513 | 513 | ||
@@ -516,7 +516,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, | |||
516 | clone->next = head->next; | 516 | clone->next = head->next; |
517 | head->next = clone; | 517 | head->next = clone; |
518 | skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list; | 518 | skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list; |
519 | skb_shinfo(head)->frag_list = NULL; | 519 | skb_frag_list_init(head); |
520 | for (i=0; i<skb_shinfo(head)->nr_frags; i++) | 520 | for (i=0; i<skb_shinfo(head)->nr_frags; i++) |
521 | plen += skb_shinfo(head)->frags[i].size; | 521 | plen += skb_shinfo(head)->frags[i].size; |
522 | clone->len = clone->data_len = head->data_len - plen; | 522 | clone->len = clone->data_len = head->data_len - plen; |
@@ -573,7 +573,7 @@ int ip_defrag(struct sk_buff *skb, u32 user) | |||
573 | struct ipq *qp; | 573 | struct ipq *qp; |
574 | struct net *net; | 574 | struct net *net; |
575 | 575 | ||
576 | net = skb->dev ? dev_net(skb->dev) : dev_net(skb->dst->dev); | 576 | net = skb->dev ? dev_net(skb->dev) : dev_net(skb_dst(skb)->dev); |
577 | IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS); | 577 | IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS); |
578 | 578 | ||
579 | /* Start by cleaning up the memory. */ | 579 | /* Start by cleaning up the memory. */ |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index e62510d5ea5a..44e2a3d2359a 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -602,7 +602,7 @@ static int ipgre_rcv(struct sk_buff *skb) | |||
602 | #ifdef CONFIG_NET_IPGRE_BROADCAST | 602 | #ifdef CONFIG_NET_IPGRE_BROADCAST |
603 | if (ipv4_is_multicast(iph->daddr)) { | 603 | if (ipv4_is_multicast(iph->daddr)) { |
604 | /* Looped back packet, drop it! */ | 604 | /* Looped back packet, drop it! */ |
605 | if (skb->rtable->fl.iif == 0) | 605 | if (skb_rtable(skb)->fl.iif == 0) |
606 | goto drop; | 606 | goto drop; |
607 | stats->multicast++; | 607 | stats->multicast++; |
608 | skb->pkt_type = PACKET_BROADCAST; | 608 | skb->pkt_type = PACKET_BROADCAST; |
@@ -643,8 +643,7 @@ static int ipgre_rcv(struct sk_buff *skb) | |||
643 | stats->rx_packets++; | 643 | stats->rx_packets++; |
644 | stats->rx_bytes += len; | 644 | stats->rx_bytes += len; |
645 | skb->dev = tunnel->dev; | 645 | skb->dev = tunnel->dev; |
646 | dst_release(skb->dst); | 646 | skb_dst_drop(skb); |
647 | skb->dst = NULL; | ||
648 | nf_reset(skb); | 647 | nf_reset(skb); |
649 | 648 | ||
650 | skb_reset_network_header(skb); | 649 | skb_reset_network_header(skb); |
@@ -698,13 +697,13 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
698 | if ((dst = tiph->daddr) == 0) { | 697 | if ((dst = tiph->daddr) == 0) { |
699 | /* NBMA tunnel */ | 698 | /* NBMA tunnel */ |
700 | 699 | ||
701 | if (skb->dst == NULL) { | 700 | if (skb_dst(skb) == NULL) { |
702 | stats->tx_fifo_errors++; | 701 | stats->tx_fifo_errors++; |
703 | goto tx_error; | 702 | goto tx_error; |
704 | } | 703 | } |
705 | 704 | ||
706 | if (skb->protocol == htons(ETH_P_IP)) { | 705 | if (skb->protocol == htons(ETH_P_IP)) { |
707 | rt = skb->rtable; | 706 | rt = skb_rtable(skb); |
708 | if ((dst = rt->rt_gateway) == 0) | 707 | if ((dst = rt->rt_gateway) == 0) |
709 | goto tx_error_icmp; | 708 | goto tx_error_icmp; |
710 | } | 709 | } |
@@ -712,7 +711,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
712 | else if (skb->protocol == htons(ETH_P_IPV6)) { | 711 | else if (skb->protocol == htons(ETH_P_IPV6)) { |
713 | struct in6_addr *addr6; | 712 | struct in6_addr *addr6; |
714 | int addr_type; | 713 | int addr_type; |
715 | struct neighbour *neigh = skb->dst->neighbour; | 714 | struct neighbour *neigh = skb_dst(skb)->neighbour; |
716 | 715 | ||
717 | if (neigh == NULL) | 716 | if (neigh == NULL) |
718 | goto tx_error; | 717 | goto tx_error; |
@@ -766,10 +765,10 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
766 | if (df) | 765 | if (df) |
767 | mtu = dst_mtu(&rt->u.dst) - dev->hard_header_len - tunnel->hlen; | 766 | mtu = dst_mtu(&rt->u.dst) - dev->hard_header_len - tunnel->hlen; |
768 | else | 767 | else |
769 | mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu; | 768 | mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; |
770 | 769 | ||
771 | if (skb->dst) | 770 | if (skb_dst(skb)) |
772 | skb->dst->ops->update_pmtu(skb->dst, mtu); | 771 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); |
773 | 772 | ||
774 | if (skb->protocol == htons(ETH_P_IP)) { | 773 | if (skb->protocol == htons(ETH_P_IP)) { |
775 | df |= (old_iph->frag_off&htons(IP_DF)); | 774 | df |= (old_iph->frag_off&htons(IP_DF)); |
@@ -783,14 +782,14 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
783 | } | 782 | } |
784 | #ifdef CONFIG_IPV6 | 783 | #ifdef CONFIG_IPV6 |
785 | else if (skb->protocol == htons(ETH_P_IPV6)) { | 784 | else if (skb->protocol == htons(ETH_P_IPV6)) { |
786 | struct rt6_info *rt6 = (struct rt6_info *)skb->dst; | 785 | struct rt6_info *rt6 = (struct rt6_info *)skb_dst(skb); |
787 | 786 | ||
788 | if (rt6 && mtu < dst_mtu(skb->dst) && mtu >= IPV6_MIN_MTU) { | 787 | if (rt6 && mtu < dst_mtu(skb_dst(skb)) && mtu >= IPV6_MIN_MTU) { |
789 | if ((tunnel->parms.iph.daddr && | 788 | if ((tunnel->parms.iph.daddr && |
790 | !ipv4_is_multicast(tunnel->parms.iph.daddr)) || | 789 | !ipv4_is_multicast(tunnel->parms.iph.daddr)) || |
791 | rt6->rt6i_dst.plen == 128) { | 790 | rt6->rt6i_dst.plen == 128) { |
792 | rt6->rt6i_flags |= RTF_MODIFIED; | 791 | rt6->rt6i_flags |= RTF_MODIFIED; |
793 | skb->dst->metrics[RTAX_MTU-1] = mtu; | 792 | skb_dst(skb)->metrics[RTAX_MTU-1] = mtu; |
794 | } | 793 | } |
795 | } | 794 | } |
796 | 795 | ||
@@ -837,8 +836,8 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
837 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); | 836 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
838 | IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | | 837 | IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | |
839 | IPSKB_REROUTED); | 838 | IPSKB_REROUTED); |
840 | dst_release(skb->dst); | 839 | skb_dst_drop(skb); |
841 | skb->dst = &rt->u.dst; | 840 | skb_dst_set(skb, &rt->u.dst); |
842 | 841 | ||
843 | /* | 842 | /* |
844 | * Push down and install the IPIP header. | 843 | * Push down and install the IPIP header. |
@@ -1238,6 +1237,7 @@ static void ipgre_tunnel_setup(struct net_device *dev) | |||
1238 | dev->iflink = 0; | 1237 | dev->iflink = 0; |
1239 | dev->addr_len = 4; | 1238 | dev->addr_len = 4; |
1240 | dev->features |= NETIF_F_NETNS_LOCAL; | 1239 | dev->features |= NETIF_F_NETNS_LOCAL; |
1240 | dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; | ||
1241 | } | 1241 | } |
1242 | 1242 | ||
1243 | static int ipgre_tunnel_init(struct net_device *dev) | 1243 | static int ipgre_tunnel_init(struct net_device *dev) |
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 1a58a6fa1dc0..490ce20faf38 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c | |||
@@ -329,7 +329,7 @@ static int ip_rcv_finish(struct sk_buff *skb) | |||
329 | * Initialise the virtual path cache for the packet. It describes | 329 | * Initialise the virtual path cache for the packet. It describes |
330 | * how the packet travels inside Linux networking. | 330 | * how the packet travels inside Linux networking. |
331 | */ | 331 | */ |
332 | if (skb->dst == NULL) { | 332 | if (skb_dst(skb) == NULL) { |
333 | int err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, | 333 | int err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, |
334 | skb->dev); | 334 | skb->dev); |
335 | if (unlikely(err)) { | 335 | if (unlikely(err)) { |
@@ -344,9 +344,9 @@ static int ip_rcv_finish(struct sk_buff *skb) | |||
344 | } | 344 | } |
345 | 345 | ||
346 | #ifdef CONFIG_NET_CLS_ROUTE | 346 | #ifdef CONFIG_NET_CLS_ROUTE |
347 | if (unlikely(skb->dst->tclassid)) { | 347 | if (unlikely(skb_dst(skb)->tclassid)) { |
348 | struct ip_rt_acct *st = per_cpu_ptr(ip_rt_acct, smp_processor_id()); | 348 | struct ip_rt_acct *st = per_cpu_ptr(ip_rt_acct, smp_processor_id()); |
349 | u32 idx = skb->dst->tclassid; | 349 | u32 idx = skb_dst(skb)->tclassid; |
350 | st[idx&0xFF].o_packets++; | 350 | st[idx&0xFF].o_packets++; |
351 | st[idx&0xFF].o_bytes += skb->len; | 351 | st[idx&0xFF].o_bytes += skb->len; |
352 | st[(idx>>16)&0xFF].i_packets++; | 352 | st[(idx>>16)&0xFF].i_packets++; |
@@ -357,11 +357,13 @@ static int ip_rcv_finish(struct sk_buff *skb) | |||
357 | if (iph->ihl > 5 && ip_rcv_options(skb)) | 357 | if (iph->ihl > 5 && ip_rcv_options(skb)) |
358 | goto drop; | 358 | goto drop; |
359 | 359 | ||
360 | rt = skb->rtable; | 360 | rt = skb_rtable(skb); |
361 | if (rt->rt_type == RTN_MULTICAST) | 361 | if (rt->rt_type == RTN_MULTICAST) { |
362 | IP_INC_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INMCASTPKTS); | 362 | IP_UPD_PO_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INMCAST, |
363 | else if (rt->rt_type == RTN_BROADCAST) | 363 | skb->len); |
364 | IP_INC_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INBCASTPKTS); | 364 | } else if (rt->rt_type == RTN_BROADCAST) |
365 | IP_UPD_PO_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INBCAST, | ||
366 | skb->len); | ||
365 | 367 | ||
366 | return dst_input(skb); | 368 | return dst_input(skb); |
367 | 369 | ||
@@ -384,7 +386,8 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, | |||
384 | if (skb->pkt_type == PACKET_OTHERHOST) | 386 | if (skb->pkt_type == PACKET_OTHERHOST) |
385 | goto drop; | 387 | goto drop; |
386 | 388 | ||
387 | IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INRECEIVES); | 389 | |
390 | IP_UPD_PO_STATS_BH(dev_net(dev), IPSTATS_MIB_IN, skb->len); | ||
388 | 391 | ||
389 | if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { | 392 | if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { |
390 | IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INDISCARDS); | 393 | IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INDISCARDS); |
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index 2c88da6e7862..94bf105ef3c9 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c | |||
@@ -102,7 +102,7 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb) | |||
102 | sptr = skb_network_header(skb); | 102 | sptr = skb_network_header(skb); |
103 | dptr = dopt->__data; | 103 | dptr = dopt->__data; |
104 | 104 | ||
105 | daddr = skb->rtable->rt_spec_dst; | 105 | daddr = skb_rtable(skb)->rt_spec_dst; |
106 | 106 | ||
107 | if (sopt->rr) { | 107 | if (sopt->rr) { |
108 | optlen = sptr[sopt->rr+1]; | 108 | optlen = sptr[sopt->rr+1]; |
@@ -143,7 +143,7 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb) | |||
143 | __be32 addr; | 143 | __be32 addr; |
144 | 144 | ||
145 | memcpy(&addr, sptr+soffset-1, 4); | 145 | memcpy(&addr, sptr+soffset-1, 4); |
146 | if (inet_addr_type(dev_net(skb->dst->dev), addr) != RTN_LOCAL) { | 146 | if (inet_addr_type(dev_net(skb_dst(skb)->dev), addr) != RTN_LOCAL) { |
147 | dopt->ts_needtime = 1; | 147 | dopt->ts_needtime = 1; |
148 | soffset += 8; | 148 | soffset += 8; |
149 | } | 149 | } |
@@ -257,7 +257,7 @@ int ip_options_compile(struct net *net, | |||
257 | struct rtable *rt = NULL; | 257 | struct rtable *rt = NULL; |
258 | 258 | ||
259 | if (skb != NULL) { | 259 | if (skb != NULL) { |
260 | rt = skb->rtable; | 260 | rt = skb_rtable(skb); |
261 | optptr = (unsigned char *)&(ip_hdr(skb)[1]); | 261 | optptr = (unsigned char *)&(ip_hdr(skb)[1]); |
262 | } else | 262 | } else |
263 | optptr = opt->__data; | 263 | optptr = opt->__data; |
@@ -550,7 +550,7 @@ void ip_forward_options(struct sk_buff *skb) | |||
550 | { | 550 | { |
551 | struct ip_options * opt = &(IPCB(skb)->opt); | 551 | struct ip_options * opt = &(IPCB(skb)->opt); |
552 | unsigned char * optptr; | 552 | unsigned char * optptr; |
553 | struct rtable *rt = skb->rtable; | 553 | struct rtable *rt = skb_rtable(skb); |
554 | unsigned char *raw = skb_network_header(skb); | 554 | unsigned char *raw = skb_network_header(skb); |
555 | 555 | ||
556 | if (opt->rr_needaddr) { | 556 | if (opt->rr_needaddr) { |
@@ -598,7 +598,7 @@ int ip_options_rcv_srr(struct sk_buff *skb) | |||
598 | __be32 nexthop; | 598 | __be32 nexthop; |
599 | struct iphdr *iph = ip_hdr(skb); | 599 | struct iphdr *iph = ip_hdr(skb); |
600 | unsigned char *optptr = skb_network_header(skb) + opt->srr; | 600 | unsigned char *optptr = skb_network_header(skb) + opt->srr; |
601 | struct rtable *rt = skb->rtable; | 601 | struct rtable *rt = skb_rtable(skb); |
602 | struct rtable *rt2; | 602 | struct rtable *rt2; |
603 | int err; | 603 | int err; |
604 | 604 | ||
@@ -623,13 +623,13 @@ int ip_options_rcv_srr(struct sk_buff *skb) | |||
623 | } | 623 | } |
624 | memcpy(&nexthop, &optptr[srrptr-1], 4); | 624 | memcpy(&nexthop, &optptr[srrptr-1], 4); |
625 | 625 | ||
626 | rt = skb->rtable; | 626 | rt = skb_rtable(skb); |
627 | skb->rtable = NULL; | 627 | skb_dst_set(skb, NULL); |
628 | err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, skb->dev); | 628 | err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, skb->dev); |
629 | rt2 = skb->rtable; | 629 | rt2 = skb_rtable(skb); |
630 | if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) { | 630 | if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) { |
631 | ip_rt_put(rt2); | 631 | ip_rt_put(rt2); |
632 | skb->rtable = rt; | 632 | skb_dst_set(skb, &rt->u.dst); |
633 | return -EINVAL; | 633 | return -EINVAL; |
634 | } | 634 | } |
635 | ip_rt_put(rt); | 635 | ip_rt_put(rt); |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 3e7e910c7c0f..247026282669 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -95,7 +95,7 @@ int __ip_local_out(struct sk_buff *skb) | |||
95 | 95 | ||
96 | iph->tot_len = htons(skb->len); | 96 | iph->tot_len = htons(skb->len); |
97 | ip_send_check(iph); | 97 | ip_send_check(iph); |
98 | return nf_hook(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, skb->dst->dev, | 98 | return nf_hook(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, skb_dst(skb)->dev, |
99 | dst_output); | 99 | dst_output); |
100 | } | 100 | } |
101 | 101 | ||
@@ -118,7 +118,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb) | |||
118 | __skb_pull(newskb, skb_network_offset(newskb)); | 118 | __skb_pull(newskb, skb_network_offset(newskb)); |
119 | newskb->pkt_type = PACKET_LOOPBACK; | 119 | newskb->pkt_type = PACKET_LOOPBACK; |
120 | newskb->ip_summed = CHECKSUM_UNNECESSARY; | 120 | newskb->ip_summed = CHECKSUM_UNNECESSARY; |
121 | WARN_ON(!newskb->dst); | 121 | WARN_ON(!skb_dst(newskb)); |
122 | netif_rx(newskb); | 122 | netif_rx(newskb); |
123 | return 0; | 123 | return 0; |
124 | } | 124 | } |
@@ -140,7 +140,7 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk, | |||
140 | __be32 saddr, __be32 daddr, struct ip_options *opt) | 140 | __be32 saddr, __be32 daddr, struct ip_options *opt) |
141 | { | 141 | { |
142 | struct inet_sock *inet = inet_sk(sk); | 142 | struct inet_sock *inet = inet_sk(sk); |
143 | struct rtable *rt = skb->rtable; | 143 | struct rtable *rt = skb_rtable(skb); |
144 | struct iphdr *iph; | 144 | struct iphdr *iph; |
145 | 145 | ||
146 | /* Build the IP header. */ | 146 | /* Build the IP header. */ |
@@ -176,15 +176,15 @@ EXPORT_SYMBOL_GPL(ip_build_and_send_pkt); | |||
176 | 176 | ||
177 | static inline int ip_finish_output2(struct sk_buff *skb) | 177 | static inline int ip_finish_output2(struct sk_buff *skb) |
178 | { | 178 | { |
179 | struct dst_entry *dst = skb->dst; | 179 | struct dst_entry *dst = skb_dst(skb); |
180 | struct rtable *rt = (struct rtable *)dst; | 180 | struct rtable *rt = (struct rtable *)dst; |
181 | struct net_device *dev = dst->dev; | 181 | struct net_device *dev = dst->dev; |
182 | unsigned int hh_len = LL_RESERVED_SPACE(dev); | 182 | unsigned int hh_len = LL_RESERVED_SPACE(dev); |
183 | 183 | ||
184 | if (rt->rt_type == RTN_MULTICAST) | 184 | if (rt->rt_type == RTN_MULTICAST) { |
185 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTMCASTPKTS); | 185 | IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUTMCAST, skb->len); |
186 | else if (rt->rt_type == RTN_BROADCAST) | 186 | } else if (rt->rt_type == RTN_BROADCAST) |
187 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTBCASTPKTS); | 187 | IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUTBCAST, skb->len); |
188 | 188 | ||
189 | /* Be paranoid, rather than too clever. */ | 189 | /* Be paranoid, rather than too clever. */ |
190 | if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) { | 190 | if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) { |
@@ -217,14 +217,14 @@ static inline int ip_skb_dst_mtu(struct sk_buff *skb) | |||
217 | struct inet_sock *inet = skb->sk ? inet_sk(skb->sk) : NULL; | 217 | struct inet_sock *inet = skb->sk ? inet_sk(skb->sk) : NULL; |
218 | 218 | ||
219 | return (inet && inet->pmtudisc == IP_PMTUDISC_PROBE) ? | 219 | return (inet && inet->pmtudisc == IP_PMTUDISC_PROBE) ? |
220 | skb->dst->dev->mtu : dst_mtu(skb->dst); | 220 | skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb)); |
221 | } | 221 | } |
222 | 222 | ||
223 | static int ip_finish_output(struct sk_buff *skb) | 223 | static int ip_finish_output(struct sk_buff *skb) |
224 | { | 224 | { |
225 | #if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM) | 225 | #if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM) |
226 | /* Policy lookup after SNAT yielded a new policy */ | 226 | /* Policy lookup after SNAT yielded a new policy */ |
227 | if (skb->dst->xfrm != NULL) { | 227 | if (skb_dst(skb)->xfrm != NULL) { |
228 | IPCB(skb)->flags |= IPSKB_REROUTED; | 228 | IPCB(skb)->flags |= IPSKB_REROUTED; |
229 | return dst_output(skb); | 229 | return dst_output(skb); |
230 | } | 230 | } |
@@ -238,13 +238,13 @@ static int ip_finish_output(struct sk_buff *skb) | |||
238 | int ip_mc_output(struct sk_buff *skb) | 238 | int ip_mc_output(struct sk_buff *skb) |
239 | { | 239 | { |
240 | struct sock *sk = skb->sk; | 240 | struct sock *sk = skb->sk; |
241 | struct rtable *rt = skb->rtable; | 241 | struct rtable *rt = skb_rtable(skb); |
242 | struct net_device *dev = rt->u.dst.dev; | 242 | struct net_device *dev = rt->u.dst.dev; |
243 | 243 | ||
244 | /* | 244 | /* |
245 | * If the indicated interface is up and running, send the packet. | 245 | * If the indicated interface is up and running, send the packet. |
246 | */ | 246 | */ |
247 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTREQUESTS); | 247 | IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUT, skb->len); |
248 | 248 | ||
249 | skb->dev = dev; | 249 | skb->dev = dev; |
250 | skb->protocol = htons(ETH_P_IP); | 250 | skb->protocol = htons(ETH_P_IP); |
@@ -296,9 +296,9 @@ int ip_mc_output(struct sk_buff *skb) | |||
296 | 296 | ||
297 | int ip_output(struct sk_buff *skb) | 297 | int ip_output(struct sk_buff *skb) |
298 | { | 298 | { |
299 | struct net_device *dev = skb->dst->dev; | 299 | struct net_device *dev = skb_dst(skb)->dev; |
300 | 300 | ||
301 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTREQUESTS); | 301 | IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUT, skb->len); |
302 | 302 | ||
303 | skb->dev = dev; | 303 | skb->dev = dev; |
304 | skb->protocol = htons(ETH_P_IP); | 304 | skb->protocol = htons(ETH_P_IP); |
@@ -319,7 +319,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok) | |||
319 | /* Skip all of this if the packet is already routed, | 319 | /* Skip all of this if the packet is already routed, |
320 | * f.e. by something like SCTP. | 320 | * f.e. by something like SCTP. |
321 | */ | 321 | */ |
322 | rt = skb->rtable; | 322 | rt = skb_rtable(skb); |
323 | if (rt != NULL) | 323 | if (rt != NULL) |
324 | goto packet_routed; | 324 | goto packet_routed; |
325 | 325 | ||
@@ -355,7 +355,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok) | |||
355 | } | 355 | } |
356 | sk_setup_caps(sk, &rt->u.dst); | 356 | sk_setup_caps(sk, &rt->u.dst); |
357 | } | 357 | } |
358 | skb->dst = dst_clone(&rt->u.dst); | 358 | skb_dst_set(skb, dst_clone(&rt->u.dst)); |
359 | 359 | ||
360 | packet_routed: | 360 | packet_routed: |
361 | if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway) | 361 | if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway) |
@@ -401,8 +401,8 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from) | |||
401 | to->pkt_type = from->pkt_type; | 401 | to->pkt_type = from->pkt_type; |
402 | to->priority = from->priority; | 402 | to->priority = from->priority; |
403 | to->protocol = from->protocol; | 403 | to->protocol = from->protocol; |
404 | dst_release(to->dst); | 404 | skb_dst_drop(to); |
405 | to->dst = dst_clone(from->dst); | 405 | skb_dst_set(to, dst_clone(skb_dst(from))); |
406 | to->dev = from->dev; | 406 | to->dev = from->dev; |
407 | to->mark = from->mark; | 407 | to->mark = from->mark; |
408 | 408 | ||
@@ -440,7 +440,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
440 | unsigned int mtu, hlen, left, len, ll_rs, pad; | 440 | unsigned int mtu, hlen, left, len, ll_rs, pad; |
441 | int offset; | 441 | int offset; |
442 | __be16 not_last_frag; | 442 | __be16 not_last_frag; |
443 | struct rtable *rt = skb->rtable; | 443 | struct rtable *rt = skb_rtable(skb); |
444 | int err = 0; | 444 | int err = 0; |
445 | 445 | ||
446 | dev = rt->u.dst.dev; | 446 | dev = rt->u.dst.dev; |
@@ -474,7 +474,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
474 | * LATER: this step can be merged to real generation of fragments, | 474 | * LATER: this step can be merged to real generation of fragments, |
475 | * we can switch to copy when see the first bad fragment. | 475 | * we can switch to copy when see the first bad fragment. |
476 | */ | 476 | */ |
477 | if (skb_shinfo(skb)->frag_list) { | 477 | if (skb_has_frags(skb)) { |
478 | struct sk_buff *frag; | 478 | struct sk_buff *frag; |
479 | int first_len = skb_pagelen(skb); | 479 | int first_len = skb_pagelen(skb); |
480 | int truesizes = 0; | 480 | int truesizes = 0; |
@@ -485,7 +485,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
485 | skb_cloned(skb)) | 485 | skb_cloned(skb)) |
486 | goto slow_path; | 486 | goto slow_path; |
487 | 487 | ||
488 | for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { | 488 | skb_walk_frags(skb, frag) { |
489 | /* Correct geometry. */ | 489 | /* Correct geometry. */ |
490 | if (frag->len > mtu || | 490 | if (frag->len > mtu || |
491 | ((frag->len & 7) && frag->next) || | 491 | ((frag->len & 7) && frag->next) || |
@@ -498,7 +498,6 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
498 | 498 | ||
499 | BUG_ON(frag->sk); | 499 | BUG_ON(frag->sk); |
500 | if (skb->sk) { | 500 | if (skb->sk) { |
501 | sock_hold(skb->sk); | ||
502 | frag->sk = skb->sk; | 501 | frag->sk = skb->sk; |
503 | frag->destructor = sock_wfree; | 502 | frag->destructor = sock_wfree; |
504 | truesizes += frag->truesize; | 503 | truesizes += frag->truesize; |
@@ -510,7 +509,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
510 | err = 0; | 509 | err = 0; |
511 | offset = 0; | 510 | offset = 0; |
512 | frag = skb_shinfo(skb)->frag_list; | 511 | frag = skb_shinfo(skb)->frag_list; |
513 | skb_shinfo(skb)->frag_list = NULL; | 512 | skb_frag_list_init(skb); |
514 | skb->data_len = first_len - skb_headlen(skb); | 513 | skb->data_len = first_len - skb_headlen(skb); |
515 | skb->truesize -= truesizes; | 514 | skb->truesize -= truesizes; |
516 | skb->len = first_len; | 515 | skb->len = first_len; |
@@ -1294,7 +1293,7 @@ int ip_push_pending_frames(struct sock *sk) | |||
1294 | * on dst refcount | 1293 | * on dst refcount |
1295 | */ | 1294 | */ |
1296 | inet->cork.dst = NULL; | 1295 | inet->cork.dst = NULL; |
1297 | skb->dst = &rt->u.dst; | 1296 | skb_dst_set(skb, &rt->u.dst); |
1298 | 1297 | ||
1299 | if (iph->protocol == IPPROTO_ICMP) | 1298 | if (iph->protocol == IPPROTO_ICMP) |
1300 | icmp_out_count(net, ((struct icmphdr *) | 1299 | icmp_out_count(net, ((struct icmphdr *) |
@@ -1362,7 +1361,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar | |||
1362 | } replyopts; | 1361 | } replyopts; |
1363 | struct ipcm_cookie ipc; | 1362 | struct ipcm_cookie ipc; |
1364 | __be32 daddr; | 1363 | __be32 daddr; |
1365 | struct rtable *rt = skb->rtable; | 1364 | struct rtable *rt = skb_rtable(skb); |
1366 | 1365 | ||
1367 | if (ip_options_echo(&replyopts.opt, skb)) | 1366 | if (ip_options_echo(&replyopts.opt, skb)) |
1368 | return; | 1367 | return; |
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 43c05854d752..fc7993e9061f 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
@@ -57,7 +57,7 @@ | |||
57 | static void ip_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb) | 57 | static void ip_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb) |
58 | { | 58 | { |
59 | struct in_pktinfo info; | 59 | struct in_pktinfo info; |
60 | struct rtable *rt = skb->rtable; | 60 | struct rtable *rt = skb_rtable(skb); |
61 | 61 | ||
62 | info.ipi_addr.s_addr = ip_hdr(skb)->daddr; | 62 | info.ipi_addr.s_addr = ip_hdr(skb)->daddr; |
63 | if (rt) { | 63 | if (rt) { |
@@ -157,38 +157,39 @@ void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb) | |||
157 | /* Ordered by supposed usage frequency */ | 157 | /* Ordered by supposed usage frequency */ |
158 | if (flags & 1) | 158 | if (flags & 1) |
159 | ip_cmsg_recv_pktinfo(msg, skb); | 159 | ip_cmsg_recv_pktinfo(msg, skb); |
160 | if ((flags>>=1) == 0) | 160 | if ((flags >>= 1) == 0) |
161 | return; | 161 | return; |
162 | 162 | ||
163 | if (flags & 1) | 163 | if (flags & 1) |
164 | ip_cmsg_recv_ttl(msg, skb); | 164 | ip_cmsg_recv_ttl(msg, skb); |
165 | if ((flags>>=1) == 0) | 165 | if ((flags >>= 1) == 0) |
166 | return; | 166 | return; |
167 | 167 | ||
168 | if (flags & 1) | 168 | if (flags & 1) |
169 | ip_cmsg_recv_tos(msg, skb); | 169 | ip_cmsg_recv_tos(msg, skb); |
170 | if ((flags>>=1) == 0) | 170 | if ((flags >>= 1) == 0) |
171 | return; | 171 | return; |
172 | 172 | ||
173 | if (flags & 1) | 173 | if (flags & 1) |
174 | ip_cmsg_recv_opts(msg, skb); | 174 | ip_cmsg_recv_opts(msg, skb); |
175 | if ((flags>>=1) == 0) | 175 | if ((flags >>= 1) == 0) |
176 | return; | 176 | return; |
177 | 177 | ||
178 | if (flags & 1) | 178 | if (flags & 1) |
179 | ip_cmsg_recv_retopts(msg, skb); | 179 | ip_cmsg_recv_retopts(msg, skb); |
180 | if ((flags>>=1) == 0) | 180 | if ((flags >>= 1) == 0) |
181 | return; | 181 | return; |
182 | 182 | ||
183 | if (flags & 1) | 183 | if (flags & 1) |
184 | ip_cmsg_recv_security(msg, skb); | 184 | ip_cmsg_recv_security(msg, skb); |
185 | 185 | ||
186 | if ((flags>>=1) == 0) | 186 | if ((flags >>= 1) == 0) |
187 | return; | 187 | return; |
188 | if (flags & 1) | 188 | if (flags & 1) |
189 | ip_cmsg_recv_dstaddr(msg, skb); | 189 | ip_cmsg_recv_dstaddr(msg, skb); |
190 | 190 | ||
191 | } | 191 | } |
192 | EXPORT_SYMBOL(ip_cmsg_recv); | ||
192 | 193 | ||
193 | int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc) | 194 | int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc) |
194 | { | 195 | { |
@@ -203,7 +204,8 @@ int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc) | |||
203 | switch (cmsg->cmsg_type) { | 204 | switch (cmsg->cmsg_type) { |
204 | case IP_RETOPTS: | 205 | case IP_RETOPTS: |
205 | err = cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr)); | 206 | err = cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr)); |
206 | err = ip_options_get(net, &ipc->opt, CMSG_DATA(cmsg), err < 40 ? err : 40); | 207 | err = ip_options_get(net, &ipc->opt, CMSG_DATA(cmsg), |
208 | err < 40 ? err : 40); | ||
207 | if (err) | 209 | if (err) |
208 | return err; | 210 | return err; |
209 | break; | 211 | break; |
@@ -238,7 +240,8 @@ int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc) | |||
238 | struct ip_ra_chain *ip_ra_chain; | 240 | struct ip_ra_chain *ip_ra_chain; |
239 | DEFINE_RWLOCK(ip_ra_lock); | 241 | DEFINE_RWLOCK(ip_ra_lock); |
240 | 242 | ||
241 | int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *)) | 243 | int ip_ra_control(struct sock *sk, unsigned char on, |
244 | void (*destructor)(struct sock *)) | ||
242 | { | 245 | { |
243 | struct ip_ra_chain *ra, *new_ra, **rap; | 246 | struct ip_ra_chain *ra, *new_ra, **rap; |
244 | 247 | ||
@@ -248,7 +251,7 @@ int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct s | |||
248 | new_ra = on ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; | 251 | new_ra = on ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; |
249 | 252 | ||
250 | write_lock_bh(&ip_ra_lock); | 253 | write_lock_bh(&ip_ra_lock); |
251 | for (rap = &ip_ra_chain; (ra=*rap) != NULL; rap = &ra->next) { | 254 | for (rap = &ip_ra_chain; (ra = *rap) != NULL; rap = &ra->next) { |
252 | if (ra->sk == sk) { | 255 | if (ra->sk == sk) { |
253 | if (on) { | 256 | if (on) { |
254 | write_unlock_bh(&ip_ra_lock); | 257 | write_unlock_bh(&ip_ra_lock); |
@@ -416,7 +419,8 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len) | |||
416 | /* Reset and regenerate socket error */ | 419 | /* Reset and regenerate socket error */ |
417 | spin_lock_bh(&sk->sk_error_queue.lock); | 420 | spin_lock_bh(&sk->sk_error_queue.lock); |
418 | sk->sk_err = 0; | 421 | sk->sk_err = 0; |
419 | if ((skb2 = skb_peek(&sk->sk_error_queue)) != NULL) { | 422 | skb2 = skb_peek(&sk->sk_error_queue); |
423 | if (skb2 != NULL) { | ||
420 | sk->sk_err = SKB_EXT_ERR(skb2)->ee.ee_errno; | 424 | sk->sk_err = SKB_EXT_ERR(skb2)->ee.ee_errno; |
421 | spin_unlock_bh(&sk->sk_error_queue.lock); | 425 | spin_unlock_bh(&sk->sk_error_queue.lock); |
422 | sk->sk_error_report(sk); | 426 | sk->sk_error_report(sk); |
@@ -431,8 +435,8 @@ out: | |||
431 | 435 | ||
432 | 436 | ||
433 | /* | 437 | /* |
434 | * Socket option code for IP. This is the end of the line after any TCP,UDP etc options on | 438 | * Socket option code for IP. This is the end of the line after any |
435 | * an IP socket. | 439 | * TCP,UDP etc options on an IP socket. |
436 | */ | 440 | */ |
437 | 441 | ||
438 | static int do_ip_setsockopt(struct sock *sk, int level, | 442 | static int do_ip_setsockopt(struct sock *sk, int level, |
@@ -449,6 +453,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
449 | (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) | | 453 | (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) | |
450 | (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT))) || | 454 | (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT))) || |
451 | optname == IP_MULTICAST_TTL || | 455 | optname == IP_MULTICAST_TTL || |
456 | optname == IP_MULTICAST_ALL || | ||
452 | optname == IP_MULTICAST_LOOP || | 457 | optname == IP_MULTICAST_LOOP || |
453 | optname == IP_RECVORIGDSTADDR) { | 458 | optname == IP_RECVORIGDSTADDR) { |
454 | if (optlen >= sizeof(int)) { | 459 | if (optlen >= sizeof(int)) { |
@@ -474,7 +479,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
474 | switch (optname) { | 479 | switch (optname) { |
475 | case IP_OPTIONS: | 480 | case IP_OPTIONS: |
476 | { | 481 | { |
477 | struct ip_options * opt = NULL; | 482 | struct ip_options *opt = NULL; |
478 | if (optlen > 40 || optlen < 0) | 483 | if (optlen > 40 || optlen < 0) |
479 | goto e_inval; | 484 | goto e_inval; |
480 | err = ip_options_get_from_user(sock_net(sk), &opt, | 485 | err = ip_options_get_from_user(sock_net(sk), &opt, |
@@ -556,9 +561,9 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
556 | } | 561 | } |
557 | break; | 562 | break; |
558 | case IP_TTL: | 563 | case IP_TTL: |
559 | if (optlen<1) | 564 | if (optlen < 1) |
560 | goto e_inval; | 565 | goto e_inval; |
561 | if (val != -1 && (val < 1 || val>255)) | 566 | if (val != -1 && (val < 0 || val > 255)) |
562 | goto e_inval; | 567 | goto e_inval; |
563 | inet->uc_ttl = val; | 568 | inet->uc_ttl = val; |
564 | break; | 569 | break; |
@@ -570,7 +575,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
570 | inet->hdrincl = val ? 1 : 0; | 575 | inet->hdrincl = val ? 1 : 0; |
571 | break; | 576 | break; |
572 | case IP_MTU_DISCOVER: | 577 | case IP_MTU_DISCOVER: |
573 | if (val<0 || val>3) | 578 | if (val < 0 || val > 3) |
574 | goto e_inval; | 579 | goto e_inval; |
575 | inet->pmtudisc = val; | 580 | inet->pmtudisc = val; |
576 | break; | 581 | break; |
@@ -582,7 +587,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
582 | case IP_MULTICAST_TTL: | 587 | case IP_MULTICAST_TTL: |
583 | if (sk->sk_type == SOCK_STREAM) | 588 | if (sk->sk_type == SOCK_STREAM) |
584 | goto e_inval; | 589 | goto e_inval; |
585 | if (optlen<1) | 590 | if (optlen < 1) |
586 | goto e_inval; | 591 | goto e_inval; |
587 | if (val == -1) | 592 | if (val == -1) |
588 | val = 1; | 593 | val = 1; |
@@ -591,7 +596,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
591 | inet->mc_ttl = val; | 596 | inet->mc_ttl = val; |
592 | break; | 597 | break; |
593 | case IP_MULTICAST_LOOP: | 598 | case IP_MULTICAST_LOOP: |
594 | if (optlen<1) | 599 | if (optlen < 1) |
595 | goto e_inval; | 600 | goto e_inval; |
596 | inet->mc_loop = !!val; | 601 | inet->mc_loop = !!val; |
597 | break; | 602 | break; |
@@ -613,7 +618,8 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
613 | } else { | 618 | } else { |
614 | memset(&mreq, 0, sizeof(mreq)); | 619 | memset(&mreq, 0, sizeof(mreq)); |
615 | if (optlen >= sizeof(struct in_addr) && | 620 | if (optlen >= sizeof(struct in_addr) && |
616 | copy_from_user(&mreq.imr_address, optval, sizeof(struct in_addr))) | 621 | copy_from_user(&mreq.imr_address, optval, |
622 | sizeof(struct in_addr))) | ||
617 | break; | 623 | break; |
618 | } | 624 | } |
619 | 625 | ||
@@ -677,7 +683,6 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
677 | } | 683 | } |
678 | case IP_MSFILTER: | 684 | case IP_MSFILTER: |
679 | { | 685 | { |
680 | extern int sysctl_igmp_max_msf; | ||
681 | struct ip_msfilter *msf; | 686 | struct ip_msfilter *msf; |
682 | 687 | ||
683 | if (optlen < IP_MSFILTER_SIZE(0)) | 688 | if (optlen < IP_MSFILTER_SIZE(0)) |
@@ -831,7 +836,6 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
831 | } | 836 | } |
832 | case MCAST_MSFILTER: | 837 | case MCAST_MSFILTER: |
833 | { | 838 | { |
834 | extern int sysctl_igmp_max_msf; | ||
835 | struct sockaddr_in *psin; | 839 | struct sockaddr_in *psin; |
836 | struct ip_msfilter *msf = NULL; | 840 | struct ip_msfilter *msf = NULL; |
837 | struct group_filter *gsf = NULL; | 841 | struct group_filter *gsf = NULL; |
@@ -849,9 +853,9 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
849 | break; | 853 | break; |
850 | } | 854 | } |
851 | err = -EFAULT; | 855 | err = -EFAULT; |
852 | if (copy_from_user(gsf, optval, optlen)) { | 856 | if (copy_from_user(gsf, optval, optlen)) |
853 | goto mc_msf_out; | 857 | goto mc_msf_out; |
854 | } | 858 | |
855 | /* numsrc >= (4G-140)/128 overflow in 32 bits */ | 859 | /* numsrc >= (4G-140)/128 overflow in 32 bits */ |
856 | if (gsf->gf_numsrc >= 0x1ffffff || | 860 | if (gsf->gf_numsrc >= 0x1ffffff || |
857 | gsf->gf_numsrc > sysctl_igmp_max_msf) { | 861 | gsf->gf_numsrc > sysctl_igmp_max_msf) { |
@@ -879,7 +883,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
879 | msf->imsf_fmode = gsf->gf_fmode; | 883 | msf->imsf_fmode = gsf->gf_fmode; |
880 | msf->imsf_numsrc = gsf->gf_numsrc; | 884 | msf->imsf_numsrc = gsf->gf_numsrc; |
881 | err = -EADDRNOTAVAIL; | 885 | err = -EADDRNOTAVAIL; |
882 | for (i=0; i<gsf->gf_numsrc; ++i) { | 886 | for (i = 0; i < gsf->gf_numsrc; ++i) { |
883 | psin = (struct sockaddr_in *)&gsf->gf_slist[i]; | 887 | psin = (struct sockaddr_in *)&gsf->gf_slist[i]; |
884 | 888 | ||
885 | if (psin->sin_family != AF_INET) | 889 | if (psin->sin_family != AF_INET) |
@@ -890,17 +894,24 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
890 | gsf = NULL; | 894 | gsf = NULL; |
891 | 895 | ||
892 | err = ip_mc_msfilter(sk, msf, ifindex); | 896 | err = ip_mc_msfilter(sk, msf, ifindex); |
893 | mc_msf_out: | 897 | mc_msf_out: |
894 | kfree(msf); | 898 | kfree(msf); |
895 | kfree(gsf); | 899 | kfree(gsf); |
896 | break; | 900 | break; |
897 | } | 901 | } |
902 | case IP_MULTICAST_ALL: | ||
903 | if (optlen < 1) | ||
904 | goto e_inval; | ||
905 | if (val != 0 && val != 1) | ||
906 | goto e_inval; | ||
907 | inet->mc_all = val; | ||
908 | break; | ||
898 | case IP_ROUTER_ALERT: | 909 | case IP_ROUTER_ALERT: |
899 | err = ip_ra_control(sk, val ? 1 : 0, NULL); | 910 | err = ip_ra_control(sk, val ? 1 : 0, NULL); |
900 | break; | 911 | break; |
901 | 912 | ||
902 | case IP_FREEBIND: | 913 | case IP_FREEBIND: |
903 | if (optlen<1) | 914 | if (optlen < 1) |
904 | goto e_inval; | 915 | goto e_inval; |
905 | inet->freebind = !!val; | 916 | inet->freebind = !!val; |
906 | break; | 917 | break; |
@@ -957,6 +968,7 @@ int ip_setsockopt(struct sock *sk, int level, | |||
957 | #endif | 968 | #endif |
958 | return err; | 969 | return err; |
959 | } | 970 | } |
971 | EXPORT_SYMBOL(ip_setsockopt); | ||
960 | 972 | ||
961 | #ifdef CONFIG_COMPAT | 973 | #ifdef CONFIG_COMPAT |
962 | int compat_ip_setsockopt(struct sock *sk, int level, int optname, | 974 | int compat_ip_setsockopt(struct sock *sk, int level, int optname, |
@@ -986,13 +998,12 @@ int compat_ip_setsockopt(struct sock *sk, int level, int optname, | |||
986 | #endif | 998 | #endif |
987 | return err; | 999 | return err; |
988 | } | 1000 | } |
989 | |||
990 | EXPORT_SYMBOL(compat_ip_setsockopt); | 1001 | EXPORT_SYMBOL(compat_ip_setsockopt); |
991 | #endif | 1002 | #endif |
992 | 1003 | ||
993 | /* | 1004 | /* |
994 | * Get the options. Note for future reference. The GET of IP options gets the | 1005 | * Get the options. Note for future reference. The GET of IP options gets |
995 | * _received_ ones. The set sets the _sent_ ones. | 1006 | * the _received_ ones. The set sets the _sent_ ones. |
996 | */ | 1007 | */ |
997 | 1008 | ||
998 | static int do_ip_getsockopt(struct sock *sk, int level, int optname, | 1009 | static int do_ip_getsockopt(struct sock *sk, int level, int optname, |
@@ -1143,10 +1154,14 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname, | |||
1143 | return -EFAULT; | 1154 | return -EFAULT; |
1144 | } | 1155 | } |
1145 | err = ip_mc_gsfget(sk, &gsf, | 1156 | err = ip_mc_gsfget(sk, &gsf, |
1146 | (struct group_filter __user *)optval, optlen); | 1157 | (struct group_filter __user *)optval, |
1158 | optlen); | ||
1147 | release_sock(sk); | 1159 | release_sock(sk); |
1148 | return err; | 1160 | return err; |
1149 | } | 1161 | } |
1162 | case IP_MULTICAST_ALL: | ||
1163 | val = inet->mc_all; | ||
1164 | break; | ||
1150 | case IP_PKTOPTIONS: | 1165 | case IP_PKTOPTIONS: |
1151 | { | 1166 | { |
1152 | struct msghdr msg; | 1167 | struct msghdr msg; |
@@ -1187,7 +1202,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname, | |||
1187 | } | 1202 | } |
1188 | release_sock(sk); | 1203 | release_sock(sk); |
1189 | 1204 | ||
1190 | if (len < sizeof(int) && len > 0 && val>=0 && val<=255) { | 1205 | if (len < sizeof(int) && len > 0 && val >= 0 && val <= 255) { |
1191 | unsigned char ucval = (unsigned char)val; | 1206 | unsigned char ucval = (unsigned char)val; |
1192 | len = 1; | 1207 | len = 1; |
1193 | if (put_user(len, optlen)) | 1208 | if (put_user(len, optlen)) |
@@ -1230,6 +1245,7 @@ int ip_getsockopt(struct sock *sk, int level, | |||
1230 | #endif | 1245 | #endif |
1231 | return err; | 1246 | return err; |
1232 | } | 1247 | } |
1248 | EXPORT_SYMBOL(ip_getsockopt); | ||
1233 | 1249 | ||
1234 | #ifdef CONFIG_COMPAT | 1250 | #ifdef CONFIG_COMPAT |
1235 | int compat_ip_getsockopt(struct sock *sk, int level, int optname, | 1251 | int compat_ip_getsockopt(struct sock *sk, int level, int optname, |
@@ -1262,11 +1278,5 @@ int compat_ip_getsockopt(struct sock *sk, int level, int optname, | |||
1262 | #endif | 1278 | #endif |
1263 | return err; | 1279 | return err; |
1264 | } | 1280 | } |
1265 | |||
1266 | EXPORT_SYMBOL(compat_ip_getsockopt); | 1281 | EXPORT_SYMBOL(compat_ip_getsockopt); |
1267 | #endif | 1282 | #endif |
1268 | |||
1269 | EXPORT_SYMBOL(ip_cmsg_recv); | ||
1270 | |||
1271 | EXPORT_SYMBOL(ip_getsockopt); | ||
1272 | EXPORT_SYMBOL(ip_setsockopt); | ||
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 88bf051d0cbb..f8d04c256454 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c | |||
@@ -160,6 +160,9 @@ static char user_dev_name[IFNAMSIZ] __initdata = { 0, }; | |||
160 | /* Protocols supported by available interfaces */ | 160 | /* Protocols supported by available interfaces */ |
161 | static int ic_proto_have_if __initdata = 0; | 161 | static int ic_proto_have_if __initdata = 0; |
162 | 162 | ||
163 | /* MTU for boot device */ | ||
164 | static int ic_dev_mtu __initdata = 0; | ||
165 | |||
163 | #ifdef IPCONFIG_DYNAMIC | 166 | #ifdef IPCONFIG_DYNAMIC |
164 | static DEFINE_SPINLOCK(ic_recv_lock); | 167 | static DEFINE_SPINLOCK(ic_recv_lock); |
165 | static volatile int ic_got_reply __initdata = 0; /* Proto(s) that replied */ | 168 | static volatile int ic_got_reply __initdata = 0; /* Proto(s) that replied */ |
@@ -286,7 +289,7 @@ set_sockaddr(struct sockaddr_in *sin, __be32 addr, __be16 port) | |||
286 | sin->sin_port = port; | 289 | sin->sin_port = port; |
287 | } | 290 | } |
288 | 291 | ||
289 | static int __init ic_dev_ioctl(unsigned int cmd, struct ifreq *arg) | 292 | static int __init ic_devinet_ioctl(unsigned int cmd, struct ifreq *arg) |
290 | { | 293 | { |
291 | int res; | 294 | int res; |
292 | 295 | ||
@@ -297,6 +300,17 @@ static int __init ic_dev_ioctl(unsigned int cmd, struct ifreq *arg) | |||
297 | return res; | 300 | return res; |
298 | } | 301 | } |
299 | 302 | ||
303 | static int __init ic_dev_ioctl(unsigned int cmd, struct ifreq *arg) | ||
304 | { | ||
305 | int res; | ||
306 | |||
307 | mm_segment_t oldfs = get_fs(); | ||
308 | set_fs(get_ds()); | ||
309 | res = dev_ioctl(&init_net, cmd, (struct ifreq __user *) arg); | ||
310 | set_fs(oldfs); | ||
311 | return res; | ||
312 | } | ||
313 | |||
300 | static int __init ic_route_ioctl(unsigned int cmd, struct rtentry *arg) | 314 | static int __init ic_route_ioctl(unsigned int cmd, struct rtentry *arg) |
301 | { | 315 | { |
302 | int res; | 316 | int res; |
@@ -321,20 +335,31 @@ static int __init ic_setup_if(void) | |||
321 | memset(&ir, 0, sizeof(ir)); | 335 | memset(&ir, 0, sizeof(ir)); |
322 | strcpy(ir.ifr_ifrn.ifrn_name, ic_dev->name); | 336 | strcpy(ir.ifr_ifrn.ifrn_name, ic_dev->name); |
323 | set_sockaddr(sin, ic_myaddr, 0); | 337 | set_sockaddr(sin, ic_myaddr, 0); |
324 | if ((err = ic_dev_ioctl(SIOCSIFADDR, &ir)) < 0) { | 338 | if ((err = ic_devinet_ioctl(SIOCSIFADDR, &ir)) < 0) { |
325 | printk(KERN_ERR "IP-Config: Unable to set interface address (%d).\n", err); | 339 | printk(KERN_ERR "IP-Config: Unable to set interface address (%d).\n", err); |
326 | return -1; | 340 | return -1; |
327 | } | 341 | } |
328 | set_sockaddr(sin, ic_netmask, 0); | 342 | set_sockaddr(sin, ic_netmask, 0); |
329 | if ((err = ic_dev_ioctl(SIOCSIFNETMASK, &ir)) < 0) { | 343 | if ((err = ic_devinet_ioctl(SIOCSIFNETMASK, &ir)) < 0) { |
330 | printk(KERN_ERR "IP-Config: Unable to set interface netmask (%d).\n", err); | 344 | printk(KERN_ERR "IP-Config: Unable to set interface netmask (%d).\n", err); |
331 | return -1; | 345 | return -1; |
332 | } | 346 | } |
333 | set_sockaddr(sin, ic_myaddr | ~ic_netmask, 0); | 347 | set_sockaddr(sin, ic_myaddr | ~ic_netmask, 0); |
334 | if ((err = ic_dev_ioctl(SIOCSIFBRDADDR, &ir)) < 0) { | 348 | if ((err = ic_devinet_ioctl(SIOCSIFBRDADDR, &ir)) < 0) { |
335 | printk(KERN_ERR "IP-Config: Unable to set interface broadcast address (%d).\n", err); | 349 | printk(KERN_ERR "IP-Config: Unable to set interface broadcast address (%d).\n", err); |
336 | return -1; | 350 | return -1; |
337 | } | 351 | } |
352 | /* Handle the case where we need non-standard MTU on the boot link (a network | ||
353 | * using jumbo frames, for instance). If we can't set the mtu, don't error | ||
354 | * out, we'll try to muddle along. | ||
355 | */ | ||
356 | if (ic_dev_mtu != 0) { | ||
357 | strcpy(ir.ifr_name, ic_dev->name); | ||
358 | ir.ifr_mtu = ic_dev_mtu; | ||
359 | if ((err = ic_dev_ioctl(SIOCSIFMTU, &ir)) < 0) | ||
360 | printk(KERN_ERR "IP-Config: Unable to set interface mtu to %d (%d).\n", | ||
361 | ic_dev_mtu, err); | ||
362 | } | ||
338 | return 0; | 363 | return 0; |
339 | } | 364 | } |
340 | 365 | ||
@@ -623,6 +648,7 @@ ic_dhcp_init_options(u8 *options) | |||
623 | 12, /* Host name */ | 648 | 12, /* Host name */ |
624 | 15, /* Domain name */ | 649 | 15, /* Domain name */ |
625 | 17, /* Boot path */ | 650 | 17, /* Boot path */ |
651 | 26, /* MTU */ | ||
626 | 40, /* NIS domain name */ | 652 | 40, /* NIS domain name */ |
627 | }; | 653 | }; |
628 | 654 | ||
@@ -798,6 +824,7 @@ static void __init ic_do_bootp_ext(u8 *ext) | |||
798 | { | 824 | { |
799 | u8 servers; | 825 | u8 servers; |
800 | int i; | 826 | int i; |
827 | u16 mtu; | ||
801 | 828 | ||
802 | #ifdef IPCONFIG_DEBUG | 829 | #ifdef IPCONFIG_DEBUG |
803 | u8 *c; | 830 | u8 *c; |
@@ -837,6 +864,10 @@ static void __init ic_do_bootp_ext(u8 *ext) | |||
837 | if (!root_server_path[0]) | 864 | if (!root_server_path[0]) |
838 | ic_bootp_string(root_server_path, ext+1, *ext, sizeof(root_server_path)); | 865 | ic_bootp_string(root_server_path, ext+1, *ext, sizeof(root_server_path)); |
839 | break; | 866 | break; |
867 | case 26: /* Interface MTU */ | ||
868 | memcpy(&mtu, ext+1, sizeof(mtu)); | ||
869 | ic_dev_mtu = ntohs(mtu); | ||
870 | break; | ||
840 | case 40: /* NIS Domain name (_not_ DNS) */ | 871 | case 40: /* NIS Domain name (_not_ DNS) */ |
841 | ic_bootp_string(utsname()->domainname, ext+1, *ext, __NEW_UTS_LEN); | 872 | ic_bootp_string(utsname()->domainname, ext+1, *ext, __NEW_UTS_LEN); |
842 | break; | 873 | break; |
@@ -1403,6 +1434,8 @@ static int __init ip_auto_config(void) | |||
1403 | printk(",\n bootserver=%pI4", &ic_servaddr); | 1434 | printk(",\n bootserver=%pI4", &ic_servaddr); |
1404 | printk(", rootserver=%pI4", &root_server_addr); | 1435 | printk(", rootserver=%pI4", &root_server_addr); |
1405 | printk(", rootpath=%s", root_server_path); | 1436 | printk(", rootpath=%s", root_server_path); |
1437 | if (ic_dev_mtu) | ||
1438 | printk(", mtu=%d", ic_dev_mtu); | ||
1406 | printk("\n"); | 1439 | printk("\n"); |
1407 | #endif /* !SILENT */ | 1440 | #endif /* !SILENT */ |
1408 | 1441 | ||
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 9054139795af..93e2b787da20 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
@@ -370,8 +370,7 @@ static int ipip_rcv(struct sk_buff *skb) | |||
370 | tunnel->dev->stats.rx_packets++; | 370 | tunnel->dev->stats.rx_packets++; |
371 | tunnel->dev->stats.rx_bytes += skb->len; | 371 | tunnel->dev->stats.rx_bytes += skb->len; |
372 | skb->dev = tunnel->dev; | 372 | skb->dev = tunnel->dev; |
373 | dst_release(skb->dst); | 373 | skb_dst_drop(skb); |
374 | skb->dst = NULL; | ||
375 | nf_reset(skb); | 374 | nf_reset(skb); |
376 | ipip_ecn_decapsulate(iph, skb); | 375 | ipip_ecn_decapsulate(iph, skb); |
377 | netif_rx(skb); | 376 | netif_rx(skb); |
@@ -416,7 +415,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
416 | 415 | ||
417 | if (!dst) { | 416 | if (!dst) { |
418 | /* NBMA tunnel */ | 417 | /* NBMA tunnel */ |
419 | if ((rt = skb->rtable) == NULL) { | 418 | if ((rt = skb_rtable(skb)) == NULL) { |
420 | stats->tx_fifo_errors++; | 419 | stats->tx_fifo_errors++; |
421 | goto tx_error; | 420 | goto tx_error; |
422 | } | 421 | } |
@@ -447,15 +446,15 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
447 | if (tiph->frag_off) | 446 | if (tiph->frag_off) |
448 | mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr); | 447 | mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr); |
449 | else | 448 | else |
450 | mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu; | 449 | mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; |
451 | 450 | ||
452 | if (mtu < 68) { | 451 | if (mtu < 68) { |
453 | stats->collisions++; | 452 | stats->collisions++; |
454 | ip_rt_put(rt); | 453 | ip_rt_put(rt); |
455 | goto tx_error; | 454 | goto tx_error; |
456 | } | 455 | } |
457 | if (skb->dst) | 456 | if (skb_dst(skb)) |
458 | skb->dst->ops->update_pmtu(skb->dst, mtu); | 457 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); |
459 | 458 | ||
460 | df |= (old_iph->frag_off&htons(IP_DF)); | 459 | df |= (old_iph->frag_off&htons(IP_DF)); |
461 | 460 | ||
@@ -502,8 +501,8 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
502 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); | 501 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
503 | IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | | 502 | IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | |
504 | IPSKB_REROUTED); | 503 | IPSKB_REROUTED); |
505 | dst_release(skb->dst); | 504 | skb_dst_drop(skb); |
506 | skb->dst = &rt->u.dst; | 505 | skb_dst_set(skb, &rt->u.dst); |
507 | 506 | ||
508 | /* | 507 | /* |
509 | * Push down and install the IPIP header. | 508 | * Push down and install the IPIP header. |
@@ -713,6 +712,7 @@ static void ipip_tunnel_setup(struct net_device *dev) | |||
713 | dev->iflink = 0; | 712 | dev->iflink = 0; |
714 | dev->addr_len = 4; | 713 | dev->addr_len = 4; |
715 | dev->features |= NETIF_F_NETNS_LOCAL; | 714 | dev->features |= NETIF_F_NETNS_LOCAL; |
715 | dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; | ||
716 | } | 716 | } |
717 | 717 | ||
718 | static void ipip_tunnel_init(struct net_device *dev) | 718 | static void ipip_tunnel_init(struct net_device *dev) |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 13e9dd3012b3..9a8da5ed92b7 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -226,9 +226,10 @@ static void reg_vif_setup(struct net_device *dev) | |||
226 | dev->flags = IFF_NOARP; | 226 | dev->flags = IFF_NOARP; |
227 | dev->netdev_ops = ®_vif_netdev_ops, | 227 | dev->netdev_ops = ®_vif_netdev_ops, |
228 | dev->destructor = free_netdev; | 228 | dev->destructor = free_netdev; |
229 | dev->features |= NETIF_F_NETNS_LOCAL; | ||
229 | } | 230 | } |
230 | 231 | ||
231 | static struct net_device *ipmr_reg_vif(void) | 232 | static struct net_device *ipmr_reg_vif(struct net *net) |
232 | { | 233 | { |
233 | struct net_device *dev; | 234 | struct net_device *dev; |
234 | struct in_device *in_dev; | 235 | struct in_device *in_dev; |
@@ -238,6 +239,8 @@ static struct net_device *ipmr_reg_vif(void) | |||
238 | if (dev == NULL) | 239 | if (dev == NULL) |
239 | return NULL; | 240 | return NULL; |
240 | 241 | ||
242 | dev_net_set(dev, net); | ||
243 | |||
241 | if (register_netdevice(dev)) { | 244 | if (register_netdevice(dev)) { |
242 | free_netdev(dev); | 245 | free_netdev(dev); |
243 | return NULL; | 246 | return NULL; |
@@ -448,7 +451,7 @@ static int vif_add(struct net *net, struct vifctl *vifc, int mrtsock) | |||
448 | */ | 451 | */ |
449 | if (net->ipv4.mroute_reg_vif_num >= 0) | 452 | if (net->ipv4.mroute_reg_vif_num >= 0) |
450 | return -EADDRINUSE; | 453 | return -EADDRINUSE; |
451 | dev = ipmr_reg_vif(); | 454 | dev = ipmr_reg_vif(net); |
452 | if (!dev) | 455 | if (!dev) |
453 | return -ENOBUFS; | 456 | return -ENOBUFS; |
454 | err = dev_set_allmulti(dev, 1); | 457 | err = dev_set_allmulti(dev, 1); |
@@ -651,7 +654,7 @@ static int ipmr_cache_report(struct net *net, | |||
651 | ip_hdr(skb)->protocol = 0; /* Flag to the kernel this is a route add */ | 654 | ip_hdr(skb)->protocol = 0; /* Flag to the kernel this is a route add */ |
652 | msg = (struct igmpmsg *)skb_network_header(skb); | 655 | msg = (struct igmpmsg *)skb_network_header(skb); |
653 | msg->im_vif = vifi; | 656 | msg->im_vif = vifi; |
654 | skb->dst = dst_clone(pkt->dst); | 657 | skb_dst_set(skb, dst_clone(skb_dst(pkt))); |
655 | 658 | ||
656 | /* | 659 | /* |
657 | * Add our header | 660 | * Add our header |
@@ -1031,16 +1034,6 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int | |||
1031 | if (v != net->ipv4.mroute_do_pim) { | 1034 | if (v != net->ipv4.mroute_do_pim) { |
1032 | net->ipv4.mroute_do_pim = v; | 1035 | net->ipv4.mroute_do_pim = v; |
1033 | net->ipv4.mroute_do_assert = v; | 1036 | net->ipv4.mroute_do_assert = v; |
1034 | #ifdef CONFIG_IP_PIMSM_V2 | ||
1035 | if (net->ipv4.mroute_do_pim) | ||
1036 | ret = inet_add_protocol(&pim_protocol, | ||
1037 | IPPROTO_PIM); | ||
1038 | else | ||
1039 | ret = inet_del_protocol(&pim_protocol, | ||
1040 | IPPROTO_PIM); | ||
1041 | if (ret < 0) | ||
1042 | ret = -EAGAIN; | ||
1043 | #endif | ||
1044 | } | 1037 | } |
1045 | rtnl_unlock(); | 1038 | rtnl_unlock(); |
1046 | return ret; | 1039 | return ret; |
@@ -1201,7 +1194,7 @@ static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr) | |||
1201 | iph->protocol = IPPROTO_IPIP; | 1194 | iph->protocol = IPPROTO_IPIP; |
1202 | iph->ihl = 5; | 1195 | iph->ihl = 5; |
1203 | iph->tot_len = htons(skb->len); | 1196 | iph->tot_len = htons(skb->len); |
1204 | ip_select_ident(iph, skb->dst, NULL); | 1197 | ip_select_ident(iph, skb_dst(skb), NULL); |
1205 | ip_send_check(iph); | 1198 | ip_send_check(iph); |
1206 | 1199 | ||
1207 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); | 1200 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
@@ -1212,7 +1205,7 @@ static inline int ipmr_forward_finish(struct sk_buff *skb) | |||
1212 | { | 1205 | { |
1213 | struct ip_options * opt = &(IPCB(skb)->opt); | 1206 | struct ip_options * opt = &(IPCB(skb)->opt); |
1214 | 1207 | ||
1215 | IP_INC_STATS_BH(dev_net(skb->dst->dev), IPSTATS_MIB_OUTFORWDATAGRAMS); | 1208 | IP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTFORWDATAGRAMS); |
1216 | 1209 | ||
1217 | if (unlikely(opt->optlen)) | 1210 | if (unlikely(opt->optlen)) |
1218 | ip_forward_options(skb); | 1211 | ip_forward_options(skb); |
@@ -1290,8 +1283,8 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi) | |||
1290 | vif->pkt_out++; | 1283 | vif->pkt_out++; |
1291 | vif->bytes_out += skb->len; | 1284 | vif->bytes_out += skb->len; |
1292 | 1285 | ||
1293 | dst_release(skb->dst); | 1286 | skb_dst_drop(skb); |
1294 | skb->dst = &rt->u.dst; | 1287 | skb_dst_set(skb, &rt->u.dst); |
1295 | ip_decrease_ttl(ip_hdr(skb)); | 1288 | ip_decrease_ttl(ip_hdr(skb)); |
1296 | 1289 | ||
1297 | /* FIXME: forward and output firewalls used to be called here. | 1290 | /* FIXME: forward and output firewalls used to be called here. |
@@ -1354,7 +1347,7 @@ static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local | |||
1354 | if (net->ipv4.vif_table[vif].dev != skb->dev) { | 1347 | if (net->ipv4.vif_table[vif].dev != skb->dev) { |
1355 | int true_vifi; | 1348 | int true_vifi; |
1356 | 1349 | ||
1357 | if (skb->rtable->fl.iif == 0) { | 1350 | if (skb_rtable(skb)->fl.iif == 0) { |
1358 | /* It is our own packet, looped back. | 1351 | /* It is our own packet, looped back. |
1359 | Very complicated situation... | 1352 | Very complicated situation... |
1360 | 1353 | ||
@@ -1430,7 +1423,7 @@ int ip_mr_input(struct sk_buff *skb) | |||
1430 | { | 1423 | { |
1431 | struct mfc_cache *cache; | 1424 | struct mfc_cache *cache; |
1432 | struct net *net = dev_net(skb->dev); | 1425 | struct net *net = dev_net(skb->dev); |
1433 | int local = skb->rtable->rt_flags&RTCF_LOCAL; | 1426 | int local = skb_rtable(skb)->rt_flags & RTCF_LOCAL; |
1434 | 1427 | ||
1435 | /* Packet is looped back after forward, it should not be | 1428 | /* Packet is looped back after forward, it should not be |
1436 | forwarded second time, but still can be delivered locally. | 1429 | forwarded second time, but still can be delivered locally. |
@@ -1543,8 +1536,7 @@ static int __pim_rcv(struct sk_buff *skb, unsigned int pimlen) | |||
1543 | skb->protocol = htons(ETH_P_IP); | 1536 | skb->protocol = htons(ETH_P_IP); |
1544 | skb->ip_summed = 0; | 1537 | skb->ip_summed = 0; |
1545 | skb->pkt_type = PACKET_HOST; | 1538 | skb->pkt_type = PACKET_HOST; |
1546 | dst_release(skb->dst); | 1539 | skb_dst_drop(skb); |
1547 | skb->dst = NULL; | ||
1548 | reg_dev->stats.rx_bytes += skb->len; | 1540 | reg_dev->stats.rx_bytes += skb->len; |
1549 | reg_dev->stats.rx_packets++; | 1541 | reg_dev->stats.rx_packets++; |
1550 | nf_reset(skb); | 1542 | nf_reset(skb); |
@@ -1646,7 +1638,7 @@ int ipmr_get_route(struct net *net, | |||
1646 | { | 1638 | { |
1647 | int err; | 1639 | int err; |
1648 | struct mfc_cache *cache; | 1640 | struct mfc_cache *cache; |
1649 | struct rtable *rt = skb->rtable; | 1641 | struct rtable *rt = skb_rtable(skb); |
1650 | 1642 | ||
1651 | read_lock(&mrt_lock); | 1643 | read_lock(&mrt_lock); |
1652 | cache = ipmr_cache_find(net, rt->rt_src, rt->rt_dst); | 1644 | cache = ipmr_cache_find(net, rt->rt_src, rt->rt_dst); |
@@ -1955,6 +1947,7 @@ static const struct file_operations ipmr_mfc_fops = { | |||
1955 | #ifdef CONFIG_IP_PIMSM_V2 | 1947 | #ifdef CONFIG_IP_PIMSM_V2 |
1956 | static struct net_protocol pim_protocol = { | 1948 | static struct net_protocol pim_protocol = { |
1957 | .handler = pim_rcv, | 1949 | .handler = pim_rcv, |
1950 | .netns_ok = 1, | ||
1958 | }; | 1951 | }; |
1959 | #endif | 1952 | #endif |
1960 | 1953 | ||
@@ -2041,8 +2034,19 @@ int __init ip_mr_init(void) | |||
2041 | err = register_netdevice_notifier(&ip_mr_notifier); | 2034 | err = register_netdevice_notifier(&ip_mr_notifier); |
2042 | if (err) | 2035 | if (err) |
2043 | goto reg_notif_fail; | 2036 | goto reg_notif_fail; |
2037 | #ifdef CONFIG_IP_PIMSM_V2 | ||
2038 | if (inet_add_protocol(&pim_protocol, IPPROTO_PIM) < 0) { | ||
2039 | printk(KERN_ERR "ip_mr_init: can't add PIM protocol\n"); | ||
2040 | err = -EAGAIN; | ||
2041 | goto add_proto_fail; | ||
2042 | } | ||
2043 | #endif | ||
2044 | return 0; | 2044 | return 0; |
2045 | 2045 | ||
2046 | #ifdef CONFIG_IP_PIMSM_V2 | ||
2047 | add_proto_fail: | ||
2048 | unregister_netdevice_notifier(&ip_mr_notifier); | ||
2049 | #endif | ||
2046 | reg_notif_fail: | 2050 | reg_notif_fail: |
2047 | del_timer(&ipmr_expire_timer); | 2051 | del_timer(&ipmr_expire_timer); |
2048 | unregister_pernet_subsys(&ipmr_net_ops); | 2052 | unregister_pernet_subsys(&ipmr_net_ops); |
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index fdf6811c31a2..1725dc0ef688 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c | |||
@@ -12,7 +12,7 @@ | |||
12 | /* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */ | 12 | /* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */ |
13 | int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | 13 | int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) |
14 | { | 14 | { |
15 | struct net *net = dev_net(skb->dst->dev); | 15 | struct net *net = dev_net(skb_dst(skb)->dev); |
16 | const struct iphdr *iph = ip_hdr(skb); | 16 | const struct iphdr *iph = ip_hdr(skb); |
17 | struct rtable *rt; | 17 | struct rtable *rt; |
18 | struct flowi fl = {}; | 18 | struct flowi fl = {}; |
@@ -41,8 +41,8 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | |||
41 | return -1; | 41 | return -1; |
42 | 42 | ||
43 | /* Drop old route. */ | 43 | /* Drop old route. */ |
44 | dst_release(skb->dst); | 44 | skb_dst_drop(skb); |
45 | skb->dst = &rt->u.dst; | 45 | skb_dst_set(skb, &rt->u.dst); |
46 | } else { | 46 | } else { |
47 | /* non-local src, find valid iif to satisfy | 47 | /* non-local src, find valid iif to satisfy |
48 | * rp-filter when calling ip_route_input. */ | 48 | * rp-filter when calling ip_route_input. */ |
@@ -50,7 +50,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | |||
50 | if (ip_route_output_key(net, &rt, &fl) != 0) | 50 | if (ip_route_output_key(net, &rt, &fl) != 0) |
51 | return -1; | 51 | return -1; |
52 | 52 | ||
53 | odst = skb->dst; | 53 | odst = skb_dst(skb); |
54 | if (ip_route_input(skb, iph->daddr, iph->saddr, | 54 | if (ip_route_input(skb, iph->daddr, iph->saddr, |
55 | RT_TOS(iph->tos), rt->u.dst.dev) != 0) { | 55 | RT_TOS(iph->tos), rt->u.dst.dev) != 0) { |
56 | dst_release(&rt->u.dst); | 56 | dst_release(&rt->u.dst); |
@@ -60,18 +60,22 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | |||
60 | dst_release(odst); | 60 | dst_release(odst); |
61 | } | 61 | } |
62 | 62 | ||
63 | if (skb->dst->error) | 63 | if (skb_dst(skb)->error) |
64 | return -1; | 64 | return -1; |
65 | 65 | ||
66 | #ifdef CONFIG_XFRM | 66 | #ifdef CONFIG_XFRM |
67 | if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) && | 67 | if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) && |
68 | xfrm_decode_session(skb, &fl, AF_INET) == 0) | 68 | xfrm_decode_session(skb, &fl, AF_INET) == 0) { |
69 | if (xfrm_lookup(net, &skb->dst, &fl, skb->sk, 0)) | 69 | struct dst_entry *dst = skb_dst(skb); |
70 | skb_dst_set(skb, NULL); | ||
71 | if (xfrm_lookup(net, &dst, &fl, skb->sk, 0)) | ||
70 | return -1; | 72 | return -1; |
73 | skb_dst_set(skb, dst); | ||
74 | } | ||
71 | #endif | 75 | #endif |
72 | 76 | ||
73 | /* Change in oif may mean change in hh_len. */ | 77 | /* Change in oif may mean change in hh_len. */ |
74 | hh_len = skb->dst->dev->hard_header_len; | 78 | hh_len = skb_dst(skb)->dev->hard_header_len; |
75 | if (skb_headroom(skb) < hh_len && | 79 | if (skb_headroom(skb) < hh_len && |
76 | pskb_expand_head(skb, hh_len - skb_headroom(skb), 0, GFP_ATOMIC)) | 80 | pskb_expand_head(skb, hh_len - skb_headroom(skb), 0, GFP_ATOMIC)) |
77 | return -1; | 81 | return -1; |
@@ -92,7 +96,7 @@ int ip_xfrm_me_harder(struct sk_buff *skb) | |||
92 | if (xfrm_decode_session(skb, &fl, AF_INET) < 0) | 96 | if (xfrm_decode_session(skb, &fl, AF_INET) < 0) |
93 | return -1; | 97 | return -1; |
94 | 98 | ||
95 | dst = skb->dst; | 99 | dst = skb_dst(skb); |
96 | if (dst->xfrm) | 100 | if (dst->xfrm) |
97 | dst = ((struct xfrm_dst *)dst)->route; | 101 | dst = ((struct xfrm_dst *)dst)->route; |
98 | dst_hold(dst); | 102 | dst_hold(dst); |
@@ -100,11 +104,11 @@ int ip_xfrm_me_harder(struct sk_buff *skb) | |||
100 | if (xfrm_lookup(dev_net(dst->dev), &dst, &fl, skb->sk, 0) < 0) | 104 | if (xfrm_lookup(dev_net(dst->dev), &dst, &fl, skb->sk, 0) < 0) |
101 | return -1; | 105 | return -1; |
102 | 106 | ||
103 | dst_release(skb->dst); | 107 | skb_dst_drop(skb); |
104 | skb->dst = dst; | 108 | skb_dst_set(skb, dst); |
105 | 109 | ||
106 | /* Change in oif may mean change in hh_len. */ | 110 | /* Change in oif may mean change in hh_len. */ |
107 | hh_len = skb->dst->dev->hard_header_len; | 111 | hh_len = skb_dst(skb)->dev->hard_header_len; |
108 | if (skb_headroom(skb) < hh_len && | 112 | if (skb_headroom(skb) < hh_len && |
109 | pskb_expand_head(skb, hh_len - skb_headroom(skb), 0, GFP_ATOMIC)) | 113 | pskb_expand_head(skb, hh_len - skb_headroom(skb), 0, GFP_ATOMIC)) |
110 | return -1; | 114 | return -1; |
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 831fe1879dc0..7505dff4ffdf 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -231,6 +231,12 @@ static inline struct arpt_entry *get_entry(void *base, unsigned int offset) | |||
231 | return (struct arpt_entry *)(base + offset); | 231 | return (struct arpt_entry *)(base + offset); |
232 | } | 232 | } |
233 | 233 | ||
234 | static inline __pure | ||
235 | struct arpt_entry *arpt_next_entry(const struct arpt_entry *entry) | ||
236 | { | ||
237 | return (void *)entry + entry->next_offset; | ||
238 | } | ||
239 | |||
234 | unsigned int arpt_do_table(struct sk_buff *skb, | 240 | unsigned int arpt_do_table(struct sk_buff *skb, |
235 | unsigned int hook, | 241 | unsigned int hook, |
236 | const struct net_device *in, | 242 | const struct net_device *in, |
@@ -267,67 +273,64 @@ unsigned int arpt_do_table(struct sk_buff *skb, | |||
267 | 273 | ||
268 | arp = arp_hdr(skb); | 274 | arp = arp_hdr(skb); |
269 | do { | 275 | do { |
270 | if (arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) { | 276 | struct arpt_entry_target *t; |
271 | struct arpt_entry_target *t; | 277 | int hdr_len; |
272 | int hdr_len; | ||
273 | |||
274 | hdr_len = sizeof(*arp) + (2 * sizeof(struct in_addr)) + | ||
275 | (2 * skb->dev->addr_len); | ||
276 | 278 | ||
277 | ADD_COUNTER(e->counters, hdr_len, 1); | 279 | if (!arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) { |
280 | e = arpt_next_entry(e); | ||
281 | continue; | ||
282 | } | ||
278 | 283 | ||
279 | t = arpt_get_target(e); | 284 | hdr_len = sizeof(*arp) + (2 * sizeof(struct in_addr)) + |
285 | (2 * skb->dev->addr_len); | ||
286 | ADD_COUNTER(e->counters, hdr_len, 1); | ||
280 | 287 | ||
281 | /* Standard target? */ | 288 | t = arpt_get_target(e); |
282 | if (!t->u.kernel.target->target) { | ||
283 | int v; | ||
284 | 289 | ||
285 | v = ((struct arpt_standard_target *)t)->verdict; | 290 | /* Standard target? */ |
286 | if (v < 0) { | 291 | if (!t->u.kernel.target->target) { |
287 | /* Pop from stack? */ | 292 | int v; |
288 | if (v != ARPT_RETURN) { | ||
289 | verdict = (unsigned)(-v) - 1; | ||
290 | break; | ||
291 | } | ||
292 | e = back; | ||
293 | back = get_entry(table_base, | ||
294 | back->comefrom); | ||
295 | continue; | ||
296 | } | ||
297 | if (table_base + v | ||
298 | != (void *)e + e->next_offset) { | ||
299 | /* Save old back ptr in next entry */ | ||
300 | struct arpt_entry *next | ||
301 | = (void *)e + e->next_offset; | ||
302 | next->comefrom = | ||
303 | (void *)back - table_base; | ||
304 | |||
305 | /* set back pointer to next entry */ | ||
306 | back = next; | ||
307 | } | ||
308 | 293 | ||
309 | e = get_entry(table_base, v); | 294 | v = ((struct arpt_standard_target *)t)->verdict; |
310 | } else { | 295 | if (v < 0) { |
311 | /* Targets which reenter must return | 296 | /* Pop from stack? */ |
312 | * abs. verdicts | 297 | if (v != ARPT_RETURN) { |
313 | */ | 298 | verdict = (unsigned)(-v) - 1; |
314 | tgpar.target = t->u.kernel.target; | ||
315 | tgpar.targinfo = t->data; | ||
316 | verdict = t->u.kernel.target->target(skb, | ||
317 | &tgpar); | ||
318 | |||
319 | /* Target might have changed stuff. */ | ||
320 | arp = arp_hdr(skb); | ||
321 | |||
322 | if (verdict == ARPT_CONTINUE) | ||
323 | e = (void *)e + e->next_offset; | ||
324 | else | ||
325 | /* Verdict */ | ||
326 | break; | 299 | break; |
300 | } | ||
301 | e = back; | ||
302 | back = get_entry(table_base, back->comefrom); | ||
303 | continue; | ||
327 | } | 304 | } |
328 | } else { | 305 | if (table_base + v |
329 | e = (void *)e + e->next_offset; | 306 | != arpt_next_entry(e)) { |
307 | /* Save old back ptr in next entry */ | ||
308 | struct arpt_entry *next = arpt_next_entry(e); | ||
309 | next->comefrom = (void *)back - table_base; | ||
310 | |||
311 | /* set back pointer to next entry */ | ||
312 | back = next; | ||
313 | } | ||
314 | |||
315 | e = get_entry(table_base, v); | ||
316 | continue; | ||
330 | } | 317 | } |
318 | |||
319 | /* Targets which reenter must return | ||
320 | * abs. verdicts | ||
321 | */ | ||
322 | tgpar.target = t->u.kernel.target; | ||
323 | tgpar.targinfo = t->data; | ||
324 | verdict = t->u.kernel.target->target(skb, &tgpar); | ||
325 | |||
326 | /* Target might have changed stuff. */ | ||
327 | arp = arp_hdr(skb); | ||
328 | |||
329 | if (verdict == ARPT_CONTINUE) | ||
330 | e = arpt_next_entry(e); | ||
331 | else | ||
332 | /* Verdict */ | ||
333 | break; | ||
331 | } while (!hotdrop); | 334 | } while (!hotdrop); |
332 | xt_info_rdunlock_bh(); | 335 | xt_info_rdunlock_bh(); |
333 | 336 | ||
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 5f22c91c6e15..c156db215987 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
@@ -596,7 +596,7 @@ static int __init ip_queue_init(void) | |||
596 | #ifdef CONFIG_SYSCTL | 596 | #ifdef CONFIG_SYSCTL |
597 | ipq_sysctl_header = register_sysctl_paths(net_ipv4_ctl_path, ipq_table); | 597 | ipq_sysctl_header = register_sysctl_paths(net_ipv4_ctl_path, ipq_table); |
598 | #endif | 598 | #endif |
599 | status = nf_register_queue_handler(PF_INET, &nfqh); | 599 | status = nf_register_queue_handler(NFPROTO_IPV4, &nfqh); |
600 | if (status < 0) { | 600 | if (status < 0) { |
601 | printk(KERN_ERR "ip_queue: failed to register queue handler\n"); | 601 | printk(KERN_ERR "ip_queue: failed to register queue handler\n"); |
602 | goto cleanup_sysctl; | 602 | goto cleanup_sysctl; |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 2ec8d7290c40..fdefae6b5dfc 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -238,8 +238,8 @@ static struct nf_loginfo trace_loginfo = { | |||
238 | /* Mildly perf critical (only if packet tracing is on) */ | 238 | /* Mildly perf critical (only if packet tracing is on) */ |
239 | static inline int | 239 | static inline int |
240 | get_chainname_rulenum(struct ipt_entry *s, struct ipt_entry *e, | 240 | get_chainname_rulenum(struct ipt_entry *s, struct ipt_entry *e, |
241 | char *hookname, char **chainname, | 241 | const char *hookname, const char **chainname, |
242 | char **comment, unsigned int *rulenum) | 242 | const char **comment, unsigned int *rulenum) |
243 | { | 243 | { |
244 | struct ipt_standard_target *t = (void *)ipt_get_target(s); | 244 | struct ipt_standard_target *t = (void *)ipt_get_target(s); |
245 | 245 | ||
@@ -257,8 +257,8 @@ get_chainname_rulenum(struct ipt_entry *s, struct ipt_entry *e, | |||
257 | && unconditional(&s->ip)) { | 257 | && unconditional(&s->ip)) { |
258 | /* Tail of chains: STANDARD target (return/policy) */ | 258 | /* Tail of chains: STANDARD target (return/policy) */ |
259 | *comment = *chainname == hookname | 259 | *comment = *chainname == hookname |
260 | ? (char *)comments[NF_IP_TRACE_COMMENT_POLICY] | 260 | ? comments[NF_IP_TRACE_COMMENT_POLICY] |
261 | : (char *)comments[NF_IP_TRACE_COMMENT_RETURN]; | 261 | : comments[NF_IP_TRACE_COMMENT_RETURN]; |
262 | } | 262 | } |
263 | return 1; | 263 | return 1; |
264 | } else | 264 | } else |
@@ -277,14 +277,14 @@ static void trace_packet(struct sk_buff *skb, | |||
277 | { | 277 | { |
278 | void *table_base; | 278 | void *table_base; |
279 | const struct ipt_entry *root; | 279 | const struct ipt_entry *root; |
280 | char *hookname, *chainname, *comment; | 280 | const char *hookname, *chainname, *comment; |
281 | unsigned int rulenum = 0; | 281 | unsigned int rulenum = 0; |
282 | 282 | ||
283 | table_base = (void *)private->entries[smp_processor_id()]; | 283 | table_base = private->entries[smp_processor_id()]; |
284 | root = get_entry(table_base, private->hook_entry[hook]); | 284 | root = get_entry(table_base, private->hook_entry[hook]); |
285 | 285 | ||
286 | hookname = chainname = (char *)hooknames[hook]; | 286 | hookname = chainname = hooknames[hook]; |
287 | comment = (char *)comments[NF_IP_TRACE_COMMENT_RULE]; | 287 | comment = comments[NF_IP_TRACE_COMMENT_RULE]; |
288 | 288 | ||
289 | IPT_ENTRY_ITERATE(root, | 289 | IPT_ENTRY_ITERATE(root, |
290 | private->size - private->hook_entry[hook], | 290 | private->size - private->hook_entry[hook], |
@@ -297,6 +297,12 @@ static void trace_packet(struct sk_buff *skb, | |||
297 | } | 297 | } |
298 | #endif | 298 | #endif |
299 | 299 | ||
300 | static inline __pure | ||
301 | struct ipt_entry *ipt_next_entry(const struct ipt_entry *entry) | ||
302 | { | ||
303 | return (void *)entry + entry->next_offset; | ||
304 | } | ||
305 | |||
300 | /* Returns one of the generic firewall policies, like NF_ACCEPT. */ | 306 | /* Returns one of the generic firewall policies, like NF_ACCEPT. */ |
301 | unsigned int | 307 | unsigned int |
302 | ipt_do_table(struct sk_buff *skb, | 308 | ipt_do_table(struct sk_buff *skb, |
@@ -305,6 +311,8 @@ ipt_do_table(struct sk_buff *skb, | |||
305 | const struct net_device *out, | 311 | const struct net_device *out, |
306 | struct xt_table *table) | 312 | struct xt_table *table) |
307 | { | 313 | { |
314 | #define tb_comefrom ((struct ipt_entry *)table_base)->comefrom | ||
315 | |||
308 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); | 316 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); |
309 | const struct iphdr *ip; | 317 | const struct iphdr *ip; |
310 | u_int16_t datalen; | 318 | u_int16_t datalen; |
@@ -335,7 +343,7 @@ ipt_do_table(struct sk_buff *skb, | |||
335 | mtpar.in = tgpar.in = in; | 343 | mtpar.in = tgpar.in = in; |
336 | mtpar.out = tgpar.out = out; | 344 | mtpar.out = tgpar.out = out; |
337 | mtpar.family = tgpar.family = NFPROTO_IPV4; | 345 | mtpar.family = tgpar.family = NFPROTO_IPV4; |
338 | tgpar.hooknum = hook; | 346 | mtpar.hooknum = tgpar.hooknum = hook; |
339 | 347 | ||
340 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); | 348 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); |
341 | xt_info_rdlock_bh(); | 349 | xt_info_rdlock_bh(); |
@@ -348,92 +356,84 @@ ipt_do_table(struct sk_buff *skb, | |||
348 | back = get_entry(table_base, private->underflow[hook]); | 356 | back = get_entry(table_base, private->underflow[hook]); |
349 | 357 | ||
350 | do { | 358 | do { |
359 | struct ipt_entry_target *t; | ||
360 | |||
351 | IP_NF_ASSERT(e); | 361 | IP_NF_ASSERT(e); |
352 | IP_NF_ASSERT(back); | 362 | IP_NF_ASSERT(back); |
353 | if (ip_packet_match(ip, indev, outdev, | 363 | if (!ip_packet_match(ip, indev, outdev, |
354 | &e->ip, mtpar.fragoff)) { | 364 | &e->ip, mtpar.fragoff) || |
355 | struct ipt_entry_target *t; | 365 | IPT_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0) { |
356 | 366 | e = ipt_next_entry(e); | |
357 | if (IPT_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0) | 367 | continue; |
358 | goto no_match; | 368 | } |
359 | 369 | ||
360 | ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); | 370 | ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); |
361 | 371 | ||
362 | t = ipt_get_target(e); | 372 | t = ipt_get_target(e); |
363 | IP_NF_ASSERT(t->u.kernel.target); | 373 | IP_NF_ASSERT(t->u.kernel.target); |
364 | 374 | ||
365 | #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ | 375 | #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ |
366 | defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) | 376 | defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) |
367 | /* The packet is traced: log it */ | 377 | /* The packet is traced: log it */ |
368 | if (unlikely(skb->nf_trace)) | 378 | if (unlikely(skb->nf_trace)) |
369 | trace_packet(skb, hook, in, out, | 379 | trace_packet(skb, hook, in, out, |
370 | table->name, private, e); | 380 | table->name, private, e); |
371 | #endif | 381 | #endif |
372 | /* Standard target? */ | 382 | /* Standard target? */ |
373 | if (!t->u.kernel.target->target) { | 383 | if (!t->u.kernel.target->target) { |
374 | int v; | 384 | int v; |
375 | 385 | ||
376 | v = ((struct ipt_standard_target *)t)->verdict; | 386 | v = ((struct ipt_standard_target *)t)->verdict; |
377 | if (v < 0) { | 387 | if (v < 0) { |
378 | /* Pop from stack? */ | 388 | /* Pop from stack? */ |
379 | if (v != IPT_RETURN) { | 389 | if (v != IPT_RETURN) { |
380 | verdict = (unsigned)(-v) - 1; | 390 | verdict = (unsigned)(-v) - 1; |
381 | break; | 391 | break; |
382 | } | ||
383 | e = back; | ||
384 | back = get_entry(table_base, | ||
385 | back->comefrom); | ||
386 | continue; | ||
387 | } | ||
388 | if (table_base + v != (void *)e + e->next_offset | ||
389 | && !(e->ip.flags & IPT_F_GOTO)) { | ||
390 | /* Save old back ptr in next entry */ | ||
391 | struct ipt_entry *next | ||
392 | = (void *)e + e->next_offset; | ||
393 | next->comefrom | ||
394 | = (void *)back - table_base; | ||
395 | /* set back pointer to next entry */ | ||
396 | back = next; | ||
397 | } | 392 | } |
393 | e = back; | ||
394 | back = get_entry(table_base, back->comefrom); | ||
395 | continue; | ||
396 | } | ||
397 | if (table_base + v != ipt_next_entry(e) | ||
398 | && !(e->ip.flags & IPT_F_GOTO)) { | ||
399 | /* Save old back ptr in next entry */ | ||
400 | struct ipt_entry *next = ipt_next_entry(e); | ||
401 | next->comefrom = (void *)back - table_base; | ||
402 | /* set back pointer to next entry */ | ||
403 | back = next; | ||
404 | } | ||
405 | |||
406 | e = get_entry(table_base, v); | ||
407 | continue; | ||
408 | } | ||
409 | |||
410 | /* Targets which reenter must return | ||
411 | abs. verdicts */ | ||
412 | tgpar.target = t->u.kernel.target; | ||
413 | tgpar.targinfo = t->data; | ||
414 | |||
398 | 415 | ||
399 | e = get_entry(table_base, v); | ||
400 | } else { | ||
401 | /* Targets which reenter must return | ||
402 | abs. verdicts */ | ||
403 | tgpar.target = t->u.kernel.target; | ||
404 | tgpar.targinfo = t->data; | ||
405 | #ifdef CONFIG_NETFILTER_DEBUG | 416 | #ifdef CONFIG_NETFILTER_DEBUG |
406 | ((struct ipt_entry *)table_base)->comefrom | 417 | tb_comefrom = 0xeeeeeeec; |
407 | = 0xeeeeeeec; | ||
408 | #endif | 418 | #endif |
409 | verdict = t->u.kernel.target->target(skb, | 419 | verdict = t->u.kernel.target->target(skb, &tgpar); |
410 | &tgpar); | ||
411 | #ifdef CONFIG_NETFILTER_DEBUG | 420 | #ifdef CONFIG_NETFILTER_DEBUG |
412 | if (((struct ipt_entry *)table_base)->comefrom | 421 | if (tb_comefrom != 0xeeeeeeec && verdict == IPT_CONTINUE) { |
413 | != 0xeeeeeeec | 422 | printk("Target %s reentered!\n", |
414 | && verdict == IPT_CONTINUE) { | 423 | t->u.kernel.target->name); |
415 | printk("Target %s reentered!\n", | 424 | verdict = NF_DROP; |
416 | t->u.kernel.target->name); | 425 | } |
417 | verdict = NF_DROP; | 426 | tb_comefrom = 0x57acc001; |
418 | } | ||
419 | ((struct ipt_entry *)table_base)->comefrom | ||
420 | = 0x57acc001; | ||
421 | #endif | 427 | #endif |
422 | /* Target might have changed stuff. */ | 428 | /* Target might have changed stuff. */ |
423 | ip = ip_hdr(skb); | 429 | ip = ip_hdr(skb); |
424 | datalen = skb->len - ip->ihl * 4; | 430 | datalen = skb->len - ip->ihl * 4; |
425 | |||
426 | if (verdict == IPT_CONTINUE) | ||
427 | e = (void *)e + e->next_offset; | ||
428 | else | ||
429 | /* Verdict */ | ||
430 | break; | ||
431 | } | ||
432 | } else { | ||
433 | 431 | ||
434 | no_match: | 432 | if (verdict == IPT_CONTINUE) |
435 | e = (void *)e + e->next_offset; | 433 | e = ipt_next_entry(e); |
436 | } | 434 | else |
435 | /* Verdict */ | ||
436 | break; | ||
437 | } while (!hotdrop); | 437 | } while (!hotdrop); |
438 | xt_info_rdunlock_bh(); | 438 | xt_info_rdunlock_bh(); |
439 | 439 | ||
@@ -444,6 +444,8 @@ ipt_do_table(struct sk_buff *skb, | |||
444 | return NF_DROP; | 444 | return NF_DROP; |
445 | else return verdict; | 445 | else return verdict; |
446 | #endif | 446 | #endif |
447 | |||
448 | #undef tb_comefrom | ||
447 | } | 449 | } |
448 | 450 | ||
449 | /* Figures out from what hook each rule can be called: returns 0 if | 451 | /* Figures out from what hook each rule can be called: returns 0 if |
@@ -2158,7 +2160,7 @@ static bool icmp_checkentry(const struct xt_mtchk_param *par) | |||
2158 | static struct xt_target ipt_standard_target __read_mostly = { | 2160 | static struct xt_target ipt_standard_target __read_mostly = { |
2159 | .name = IPT_STANDARD_TARGET, | 2161 | .name = IPT_STANDARD_TARGET, |
2160 | .targetsize = sizeof(int), | 2162 | .targetsize = sizeof(int), |
2161 | .family = AF_INET, | 2163 | .family = NFPROTO_IPV4, |
2162 | #ifdef CONFIG_COMPAT | 2164 | #ifdef CONFIG_COMPAT |
2163 | .compatsize = sizeof(compat_int_t), | 2165 | .compatsize = sizeof(compat_int_t), |
2164 | .compat_from_user = compat_standard_from_user, | 2166 | .compat_from_user = compat_standard_from_user, |
@@ -2170,7 +2172,7 @@ static struct xt_target ipt_error_target __read_mostly = { | |||
2170 | .name = IPT_ERROR_TARGET, | 2172 | .name = IPT_ERROR_TARGET, |
2171 | .target = ipt_error, | 2173 | .target = ipt_error, |
2172 | .targetsize = IPT_FUNCTION_MAXNAMELEN, | 2174 | .targetsize = IPT_FUNCTION_MAXNAMELEN, |
2173 | .family = AF_INET, | 2175 | .family = NFPROTO_IPV4, |
2174 | }; | 2176 | }; |
2175 | 2177 | ||
2176 | static struct nf_sockopt_ops ipt_sockopts = { | 2178 | static struct nf_sockopt_ops ipt_sockopts = { |
@@ -2196,17 +2198,17 @@ static struct xt_match icmp_matchstruct __read_mostly = { | |||
2196 | .matchsize = sizeof(struct ipt_icmp), | 2198 | .matchsize = sizeof(struct ipt_icmp), |
2197 | .checkentry = icmp_checkentry, | 2199 | .checkentry = icmp_checkentry, |
2198 | .proto = IPPROTO_ICMP, | 2200 | .proto = IPPROTO_ICMP, |
2199 | .family = AF_INET, | 2201 | .family = NFPROTO_IPV4, |
2200 | }; | 2202 | }; |
2201 | 2203 | ||
2202 | static int __net_init ip_tables_net_init(struct net *net) | 2204 | static int __net_init ip_tables_net_init(struct net *net) |
2203 | { | 2205 | { |
2204 | return xt_proto_init(net, AF_INET); | 2206 | return xt_proto_init(net, NFPROTO_IPV4); |
2205 | } | 2207 | } |
2206 | 2208 | ||
2207 | static void __net_exit ip_tables_net_exit(struct net *net) | 2209 | static void __net_exit ip_tables_net_exit(struct net *net) |
2208 | { | 2210 | { |
2209 | xt_proto_fini(net, AF_INET); | 2211 | xt_proto_fini(net, NFPROTO_IPV4); |
2210 | } | 2212 | } |
2211 | 2213 | ||
2212 | static struct pernet_operations ip_tables_net_ops = { | 2214 | static struct pernet_operations ip_tables_net_ops = { |
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c index f389f60cb105..dada0863946d 100644 --- a/net/ipv4/netfilter/ipt_MASQUERADE.c +++ b/net/ipv4/netfilter/ipt_MASQUERADE.c | |||
@@ -27,9 +27,6 @@ MODULE_LICENSE("GPL"); | |||
27 | MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); | 27 | MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); |
28 | MODULE_DESCRIPTION("Xtables: automatic-address SNAT"); | 28 | MODULE_DESCRIPTION("Xtables: automatic-address SNAT"); |
29 | 29 | ||
30 | /* Lock protects masq region inside conntrack */ | ||
31 | static DEFINE_RWLOCK(masq_lock); | ||
32 | |||
33 | /* FIXME: Multiple targets. --RR */ | 30 | /* FIXME: Multiple targets. --RR */ |
34 | static bool masquerade_tg_check(const struct xt_tgchk_param *par) | 31 | static bool masquerade_tg_check(const struct xt_tgchk_param *par) |
35 | { | 32 | { |
@@ -72,16 +69,14 @@ masquerade_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
72 | return NF_ACCEPT; | 69 | return NF_ACCEPT; |
73 | 70 | ||
74 | mr = par->targinfo; | 71 | mr = par->targinfo; |
75 | rt = skb->rtable; | 72 | rt = skb_rtable(skb); |
76 | newsrc = inet_select_addr(par->out, rt->rt_gateway, RT_SCOPE_UNIVERSE); | 73 | newsrc = inet_select_addr(par->out, rt->rt_gateway, RT_SCOPE_UNIVERSE); |
77 | if (!newsrc) { | 74 | if (!newsrc) { |
78 | printk("MASQUERADE: %s ate my IP address\n", par->out->name); | 75 | printk("MASQUERADE: %s ate my IP address\n", par->out->name); |
79 | return NF_DROP; | 76 | return NF_DROP; |
80 | } | 77 | } |
81 | 78 | ||
82 | write_lock_bh(&masq_lock); | ||
83 | nat->masq_index = par->out->ifindex; | 79 | nat->masq_index = par->out->ifindex; |
84 | write_unlock_bh(&masq_lock); | ||
85 | 80 | ||
86 | /* Transfer from original range. */ | 81 | /* Transfer from original range. */ |
87 | newrange = ((struct nf_nat_range) | 82 | newrange = ((struct nf_nat_range) |
@@ -97,16 +92,11 @@ static int | |||
97 | device_cmp(struct nf_conn *i, void *ifindex) | 92 | device_cmp(struct nf_conn *i, void *ifindex) |
98 | { | 93 | { |
99 | const struct nf_conn_nat *nat = nfct_nat(i); | 94 | const struct nf_conn_nat *nat = nfct_nat(i); |
100 | int ret; | ||
101 | 95 | ||
102 | if (!nat) | 96 | if (!nat) |
103 | return 0; | 97 | return 0; |
104 | 98 | ||
105 | read_lock_bh(&masq_lock); | 99 | return nat->masq_index == (int)(long)ifindex; |
106 | ret = (nat->masq_index == (int)(long)ifindex); | ||
107 | read_unlock_bh(&masq_lock); | ||
108 | |||
109 | return ret; | ||
110 | } | 100 | } |
111 | 101 | ||
112 | static int masq_device_event(struct notifier_block *this, | 102 | static int masq_device_event(struct notifier_block *this, |
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index 0b4b6e0ff2b9..c93ae44bff2a 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c | |||
@@ -108,17 +108,16 @@ static void send_reset(struct sk_buff *oldskb, int hook) | |||
108 | addr_type = RTN_LOCAL; | 108 | addr_type = RTN_LOCAL; |
109 | 109 | ||
110 | /* ip_route_me_harder expects skb->dst to be set */ | 110 | /* ip_route_me_harder expects skb->dst to be set */ |
111 | dst_hold(oldskb->dst); | 111 | skb_dst_set(nskb, dst_clone(skb_dst(oldskb))); |
112 | nskb->dst = oldskb->dst; | ||
113 | 112 | ||
114 | if (ip_route_me_harder(nskb, addr_type)) | 113 | if (ip_route_me_harder(nskb, addr_type)) |
115 | goto free_nskb; | 114 | goto free_nskb; |
116 | 115 | ||
117 | niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT); | 116 | niph->ttl = dst_metric(skb_dst(nskb), RTAX_HOPLIMIT); |
118 | nskb->ip_summed = CHECKSUM_NONE; | 117 | nskb->ip_summed = CHECKSUM_NONE; |
119 | 118 | ||
120 | /* "Never happens" */ | 119 | /* "Never happens" */ |
121 | if (nskb->len > dst_mtu(nskb->dst)) | 120 | if (nskb->len > dst_mtu(skb_dst(nskb))) |
122 | goto free_nskb; | 121 | goto free_nskb; |
123 | 122 | ||
124 | nf_ct_attach(nskb, oldskb); | 123 | nf_ct_attach(nskb, oldskb); |
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index 23b2c2ee869a..d71ba7677344 100644 --- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c | |||
@@ -82,18 +82,10 @@ static int icmp_packet(struct nf_conn *ct, | |||
82 | u_int8_t pf, | 82 | u_int8_t pf, |
83 | unsigned int hooknum) | 83 | unsigned int hooknum) |
84 | { | 84 | { |
85 | /* Try to delete connection immediately after all replies: | 85 | /* Do not immediately delete the connection after the first |
86 | won't actually vanish as we still have skb, and del_timer | 86 | successful reply to avoid excessive conntrackd traffic |
87 | means this will only run once even if count hits zero twice | 87 | and also to handle correctly ICMP echo reply duplicates. */ |
88 | (theoretically possible with SMP) */ | 88 | nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout); |
89 | if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) { | ||
90 | if (atomic_dec_and_test(&ct->proto.icmp.count)) | ||
91 | nf_ct_kill_acct(ct, ctinfo, skb); | ||
92 | } else { | ||
93 | atomic_inc(&ct->proto.icmp.count); | ||
94 | nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, ct); | ||
95 | nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout); | ||
96 | } | ||
97 | 89 | ||
98 | return NF_ACCEPT; | 90 | return NF_ACCEPT; |
99 | } | 91 | } |
@@ -117,7 +109,6 @@ static bool icmp_new(struct nf_conn *ct, const struct sk_buff *skb, | |||
117 | nf_ct_dump_tuple_ip(&ct->tuplehash[0].tuple); | 109 | nf_ct_dump_tuple_ip(&ct->tuplehash[0].tuple); |
118 | return false; | 110 | return false; |
119 | } | 111 | } |
120 | atomic_set(&ct->proto.icmp.count, 0); | ||
121 | return true; | 112 | return true; |
122 | } | 113 | } |
123 | 114 | ||
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c index cf7a42bf9820..155c008626c8 100644 --- a/net/ipv4/netfilter/nf_nat_helper.c +++ b/net/ipv4/netfilter/nf_nat_helper.c | |||
@@ -140,7 +140,7 @@ nf_nat_mangle_tcp_packet(struct sk_buff *skb, | |||
140 | const char *rep_buffer, | 140 | const char *rep_buffer, |
141 | unsigned int rep_len) | 141 | unsigned int rep_len) |
142 | { | 142 | { |
143 | struct rtable *rt = skb->rtable; | 143 | struct rtable *rt = skb_rtable(skb); |
144 | struct iphdr *iph; | 144 | struct iphdr *iph; |
145 | struct tcphdr *tcph; | 145 | struct tcphdr *tcph; |
146 | int oldlen, datalen; | 146 | int oldlen, datalen; |
@@ -218,7 +218,7 @@ nf_nat_mangle_udp_packet(struct sk_buff *skb, | |||
218 | const char *rep_buffer, | 218 | const char *rep_buffer, |
219 | unsigned int rep_len) | 219 | unsigned int rep_len) |
220 | { | 220 | { |
221 | struct rtable *rt = skb->rtable; | 221 | struct rtable *rt = skb_rtable(skb); |
222 | struct iphdr *iph; | 222 | struct iphdr *iph; |
223 | struct udphdr *udph; | 223 | struct udphdr *udph; |
224 | int datalen, oldlen; | 224 | int datalen, oldlen; |
diff --git a/net/ipv4/netfilter/nf_nat_proto_sctp.c b/net/ipv4/netfilter/nf_nat_proto_sctp.c index 65e470bc6123..3fc598eeeb1a 100644 --- a/net/ipv4/netfilter/nf_nat_proto_sctp.c +++ b/net/ipv4/netfilter/nf_nat_proto_sctp.c | |||
@@ -33,6 +33,7 @@ sctp_manip_pkt(struct sk_buff *skb, | |||
33 | enum nf_nat_manip_type maniptype) | 33 | enum nf_nat_manip_type maniptype) |
34 | { | 34 | { |
35 | const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff); | 35 | const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff); |
36 | struct sk_buff *frag; | ||
36 | sctp_sctphdr_t *hdr; | 37 | sctp_sctphdr_t *hdr; |
37 | unsigned int hdroff = iphdroff + iph->ihl*4; | 38 | unsigned int hdroff = iphdroff + iph->ihl*4; |
38 | __be32 oldip, newip; | 39 | __be32 oldip, newip; |
@@ -57,8 +58,8 @@ sctp_manip_pkt(struct sk_buff *skb, | |||
57 | } | 58 | } |
58 | 59 | ||
59 | crc32 = sctp_start_cksum((u8 *)hdr, skb_headlen(skb) - hdroff); | 60 | crc32 = sctp_start_cksum((u8 *)hdr, skb_headlen(skb) - hdroff); |
60 | for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next) | 61 | skb_walk_frags(skb, frag) |
61 | crc32 = sctp_update_cksum((u8 *)skb->data, skb_headlen(skb), | 62 | crc32 = sctp_update_cksum((u8 *)frag->data, skb_headlen(frag), |
62 | crc32); | 63 | crc32); |
63 | crc32 = sctp_end_cksum(crc32); | 64 | crc32 = sctp_end_cksum(crc32); |
64 | hdr->checksum = crc32; | 65 | hdr->checksum = crc32; |
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c index b7dd695691a0..5567bd0d0750 100644 --- a/net/ipv4/netfilter/nf_nat_standalone.c +++ b/net/ipv4/netfilter/nf_nat_standalone.c | |||
@@ -167,10 +167,9 @@ nf_nat_in(unsigned int hooknum, | |||
167 | 167 | ||
168 | ret = nf_nat_fn(hooknum, skb, in, out, okfn); | 168 | ret = nf_nat_fn(hooknum, skb, in, out, okfn); |
169 | if (ret != NF_DROP && ret != NF_STOLEN && | 169 | if (ret != NF_DROP && ret != NF_STOLEN && |
170 | daddr != ip_hdr(skb)->daddr) { | 170 | daddr != ip_hdr(skb)->daddr) |
171 | dst_release(skb->dst); | 171 | skb_dst_drop(skb); |
172 | skb->dst = NULL; | 172 | |
173 | } | ||
174 | return ret; | 173 | return ret; |
175 | } | 174 | } |
176 | 175 | ||
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index cf0cdeeb1db0..f25542c48b7d 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
@@ -90,14 +90,14 @@ static const struct file_operations sockstat_seq_fops = { | |||
90 | 90 | ||
91 | /* snmp items */ | 91 | /* snmp items */ |
92 | static const struct snmp_mib snmp4_ipstats_list[] = { | 92 | static const struct snmp_mib snmp4_ipstats_list[] = { |
93 | SNMP_MIB_ITEM("InReceives", IPSTATS_MIB_INRECEIVES), | 93 | SNMP_MIB_ITEM("InReceives", IPSTATS_MIB_INPKTS), |
94 | SNMP_MIB_ITEM("InHdrErrors", IPSTATS_MIB_INHDRERRORS), | 94 | SNMP_MIB_ITEM("InHdrErrors", IPSTATS_MIB_INHDRERRORS), |
95 | SNMP_MIB_ITEM("InAddrErrors", IPSTATS_MIB_INADDRERRORS), | 95 | SNMP_MIB_ITEM("InAddrErrors", IPSTATS_MIB_INADDRERRORS), |
96 | SNMP_MIB_ITEM("ForwDatagrams", IPSTATS_MIB_OUTFORWDATAGRAMS), | 96 | SNMP_MIB_ITEM("ForwDatagrams", IPSTATS_MIB_OUTFORWDATAGRAMS), |
97 | SNMP_MIB_ITEM("InUnknownProtos", IPSTATS_MIB_INUNKNOWNPROTOS), | 97 | SNMP_MIB_ITEM("InUnknownProtos", IPSTATS_MIB_INUNKNOWNPROTOS), |
98 | SNMP_MIB_ITEM("InDiscards", IPSTATS_MIB_INDISCARDS), | 98 | SNMP_MIB_ITEM("InDiscards", IPSTATS_MIB_INDISCARDS), |
99 | SNMP_MIB_ITEM("InDelivers", IPSTATS_MIB_INDELIVERS), | 99 | SNMP_MIB_ITEM("InDelivers", IPSTATS_MIB_INDELIVERS), |
100 | SNMP_MIB_ITEM("OutRequests", IPSTATS_MIB_OUTREQUESTS), | 100 | SNMP_MIB_ITEM("OutRequests", IPSTATS_MIB_OUTPKTS), |
101 | SNMP_MIB_ITEM("OutDiscards", IPSTATS_MIB_OUTDISCARDS), | 101 | SNMP_MIB_ITEM("OutDiscards", IPSTATS_MIB_OUTDISCARDS), |
102 | SNMP_MIB_ITEM("OutNoRoutes", IPSTATS_MIB_OUTNOROUTES), | 102 | SNMP_MIB_ITEM("OutNoRoutes", IPSTATS_MIB_OUTNOROUTES), |
103 | SNMP_MIB_ITEM("ReasmTimeout", IPSTATS_MIB_REASMTIMEOUT), | 103 | SNMP_MIB_ITEM("ReasmTimeout", IPSTATS_MIB_REASMTIMEOUT), |
@@ -118,6 +118,12 @@ static const struct snmp_mib snmp4_ipextstats_list[] = { | |||
118 | SNMP_MIB_ITEM("OutMcastPkts", IPSTATS_MIB_OUTMCASTPKTS), | 118 | SNMP_MIB_ITEM("OutMcastPkts", IPSTATS_MIB_OUTMCASTPKTS), |
119 | SNMP_MIB_ITEM("InBcastPkts", IPSTATS_MIB_INBCASTPKTS), | 119 | SNMP_MIB_ITEM("InBcastPkts", IPSTATS_MIB_INBCASTPKTS), |
120 | SNMP_MIB_ITEM("OutBcastPkts", IPSTATS_MIB_OUTBCASTPKTS), | 120 | SNMP_MIB_ITEM("OutBcastPkts", IPSTATS_MIB_OUTBCASTPKTS), |
121 | SNMP_MIB_ITEM("InOctets", IPSTATS_MIB_INOCTETS), | ||
122 | SNMP_MIB_ITEM("OutOctets", IPSTATS_MIB_OUTOCTETS), | ||
123 | SNMP_MIB_ITEM("InMcastOctets", IPSTATS_MIB_INMCASTOCTETS), | ||
124 | SNMP_MIB_ITEM("OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS), | ||
125 | SNMP_MIB_ITEM("InBcastOctets", IPSTATS_MIB_INBCASTOCTETS), | ||
126 | SNMP_MIB_ITEM("OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS), | ||
121 | SNMP_MIB_SENTINEL | 127 | SNMP_MIB_SENTINEL |
122 | }; | 128 | }; |
123 | 129 | ||
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index f774651f0a47..3dc9171a272f 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -343,7 +343,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, | |||
343 | 343 | ||
344 | skb->priority = sk->sk_priority; | 344 | skb->priority = sk->sk_priority; |
345 | skb->mark = sk->sk_mark; | 345 | skb->mark = sk->sk_mark; |
346 | skb->dst = dst_clone(&rt->u.dst); | 346 | skb_dst_set(skb, dst_clone(&rt->u.dst)); |
347 | 347 | ||
348 | skb_reset_network_header(skb); | 348 | skb_reset_network_header(skb); |
349 | iph = ip_hdr(skb); | 349 | iph = ip_hdr(skb); |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 28205e5bfa9b..cd76b3cb7092 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -131,8 +131,8 @@ static int ip_rt_min_advmss __read_mostly = 256; | |||
131 | static int ip_rt_secret_interval __read_mostly = 10 * 60 * HZ; | 131 | static int ip_rt_secret_interval __read_mostly = 10 * 60 * HZ; |
132 | static int rt_chain_length_max __read_mostly = 20; | 132 | static int rt_chain_length_max __read_mostly = 20; |
133 | 133 | ||
134 | static void rt_worker_func(struct work_struct *work); | 134 | static struct delayed_work expires_work; |
135 | static DECLARE_DELAYED_WORK(expires_work, rt_worker_func); | 135 | static unsigned long expires_ljiffies; |
136 | 136 | ||
137 | /* | 137 | /* |
138 | * Interface to generic destination cache. | 138 | * Interface to generic destination cache. |
@@ -787,9 +787,12 @@ static void rt_check_expire(void) | |||
787 | struct rtable *rth, *aux, **rthp; | 787 | struct rtable *rth, *aux, **rthp; |
788 | unsigned long samples = 0; | 788 | unsigned long samples = 0; |
789 | unsigned long sum = 0, sum2 = 0; | 789 | unsigned long sum = 0, sum2 = 0; |
790 | unsigned long delta; | ||
790 | u64 mult; | 791 | u64 mult; |
791 | 792 | ||
792 | mult = ((u64)ip_rt_gc_interval) << rt_hash_log; | 793 | delta = jiffies - expires_ljiffies; |
794 | expires_ljiffies = jiffies; | ||
795 | mult = ((u64)delta) << rt_hash_log; | ||
793 | if (ip_rt_gc_timeout > 1) | 796 | if (ip_rt_gc_timeout > 1) |
794 | do_div(mult, ip_rt_gc_timeout); | 797 | do_div(mult, ip_rt_gc_timeout); |
795 | goal = (unsigned int)mult; | 798 | goal = (unsigned int)mult; |
@@ -1064,7 +1067,8 @@ work_done: | |||
1064 | out: return 0; | 1067 | out: return 0; |
1065 | } | 1068 | } |
1066 | 1069 | ||
1067 | static int rt_intern_hash(unsigned hash, struct rtable *rt, struct rtable **rp) | 1070 | static int rt_intern_hash(unsigned hash, struct rtable *rt, |
1071 | struct rtable **rp, struct sk_buff *skb) | ||
1068 | { | 1072 | { |
1069 | struct rtable *rth, **rthp; | 1073 | struct rtable *rth, **rthp; |
1070 | unsigned long now; | 1074 | unsigned long now; |
@@ -1114,7 +1118,10 @@ restart: | |||
1114 | spin_unlock_bh(rt_hash_lock_addr(hash)); | 1118 | spin_unlock_bh(rt_hash_lock_addr(hash)); |
1115 | 1119 | ||
1116 | rt_drop(rt); | 1120 | rt_drop(rt); |
1117 | *rp = rth; | 1121 | if (rp) |
1122 | *rp = rth; | ||
1123 | else | ||
1124 | skb_dst_set(skb, &rth->u.dst); | ||
1118 | return 0; | 1125 | return 0; |
1119 | } | 1126 | } |
1120 | 1127 | ||
@@ -1210,7 +1217,10 @@ restart: | |||
1210 | rcu_assign_pointer(rt_hash_table[hash].chain, rt); | 1217 | rcu_assign_pointer(rt_hash_table[hash].chain, rt); |
1211 | 1218 | ||
1212 | spin_unlock_bh(rt_hash_lock_addr(hash)); | 1219 | spin_unlock_bh(rt_hash_lock_addr(hash)); |
1213 | *rp = rt; | 1220 | if (rp) |
1221 | *rp = rt; | ||
1222 | else | ||
1223 | skb_dst_set(skb, &rt->u.dst); | ||
1214 | return 0; | 1224 | return 0; |
1215 | } | 1225 | } |
1216 | 1226 | ||
@@ -1407,7 +1417,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, | |||
1407 | &netevent); | 1417 | &netevent); |
1408 | 1418 | ||
1409 | rt_del(hash, rth); | 1419 | rt_del(hash, rth); |
1410 | if (!rt_intern_hash(hash, rt, &rt)) | 1420 | if (!rt_intern_hash(hash, rt, &rt, NULL)) |
1411 | ip_rt_put(rt); | 1421 | ip_rt_put(rt); |
1412 | goto do_next; | 1422 | goto do_next; |
1413 | } | 1423 | } |
@@ -1473,7 +1483,7 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) | |||
1473 | 1483 | ||
1474 | void ip_rt_send_redirect(struct sk_buff *skb) | 1484 | void ip_rt_send_redirect(struct sk_buff *skb) |
1475 | { | 1485 | { |
1476 | struct rtable *rt = skb->rtable; | 1486 | struct rtable *rt = skb_rtable(skb); |
1477 | struct in_device *in_dev = in_dev_get(rt->u.dst.dev); | 1487 | struct in_device *in_dev = in_dev_get(rt->u.dst.dev); |
1478 | 1488 | ||
1479 | if (!in_dev) | 1489 | if (!in_dev) |
@@ -1521,7 +1531,7 @@ out: | |||
1521 | 1531 | ||
1522 | static int ip_error(struct sk_buff *skb) | 1532 | static int ip_error(struct sk_buff *skb) |
1523 | { | 1533 | { |
1524 | struct rtable *rt = skb->rtable; | 1534 | struct rtable *rt = skb_rtable(skb); |
1525 | unsigned long now; | 1535 | unsigned long now; |
1526 | int code; | 1536 | int code; |
1527 | 1537 | ||
@@ -1698,7 +1708,7 @@ static void ipv4_link_failure(struct sk_buff *skb) | |||
1698 | 1708 | ||
1699 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); | 1709 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); |
1700 | 1710 | ||
1701 | rt = skb->rtable; | 1711 | rt = skb_rtable(skb); |
1702 | if (rt) | 1712 | if (rt) |
1703 | dst_set_expires(&rt->u.dst, 0); | 1713 | dst_set_expires(&rt->u.dst, 0); |
1704 | } | 1714 | } |
@@ -1858,7 +1868,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
1858 | 1868 | ||
1859 | in_dev_put(in_dev); | 1869 | in_dev_put(in_dev); |
1860 | hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); | 1870 | hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); |
1861 | return rt_intern_hash(hash, rth, &skb->rtable); | 1871 | return rt_intern_hash(hash, rth, NULL, skb); |
1862 | 1872 | ||
1863 | e_nobufs: | 1873 | e_nobufs: |
1864 | in_dev_put(in_dev); | 1874 | in_dev_put(in_dev); |
@@ -2019,7 +2029,7 @@ static int ip_mkroute_input(struct sk_buff *skb, | |||
2019 | /* put it into the cache */ | 2029 | /* put it into the cache */ |
2020 | hash = rt_hash(daddr, saddr, fl->iif, | 2030 | hash = rt_hash(daddr, saddr, fl->iif, |
2021 | rt_genid(dev_net(rth->u.dst.dev))); | 2031 | rt_genid(dev_net(rth->u.dst.dev))); |
2022 | return rt_intern_hash(hash, rth, &skb->rtable); | 2032 | return rt_intern_hash(hash, rth, NULL, skb); |
2023 | } | 2033 | } |
2024 | 2034 | ||
2025 | /* | 2035 | /* |
@@ -2175,7 +2185,7 @@ local_input: | |||
2175 | } | 2185 | } |
2176 | rth->rt_type = res.type; | 2186 | rth->rt_type = res.type; |
2177 | hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net)); | 2187 | hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net)); |
2178 | err = rt_intern_hash(hash, rth, &skb->rtable); | 2188 | err = rt_intern_hash(hash, rth, NULL, skb); |
2179 | goto done; | 2189 | goto done; |
2180 | 2190 | ||
2181 | no_route: | 2191 | no_route: |
@@ -2244,7 +2254,7 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
2244 | dst_use(&rth->u.dst, jiffies); | 2254 | dst_use(&rth->u.dst, jiffies); |
2245 | RT_CACHE_STAT_INC(in_hit); | 2255 | RT_CACHE_STAT_INC(in_hit); |
2246 | rcu_read_unlock(); | 2256 | rcu_read_unlock(); |
2247 | skb->rtable = rth; | 2257 | skb_dst_set(skb, &rth->u.dst); |
2248 | return 0; | 2258 | return 0; |
2249 | } | 2259 | } |
2250 | RT_CACHE_STAT_INC(in_hlist_search); | 2260 | RT_CACHE_STAT_INC(in_hlist_search); |
@@ -2420,7 +2430,7 @@ static int ip_mkroute_output(struct rtable **rp, | |||
2420 | if (err == 0) { | 2430 | if (err == 0) { |
2421 | hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif, | 2431 | hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif, |
2422 | rt_genid(dev_net(dev_out))); | 2432 | rt_genid(dev_net(dev_out))); |
2423 | err = rt_intern_hash(hash, rth, rp); | 2433 | err = rt_intern_hash(hash, rth, rp, NULL); |
2424 | } | 2434 | } |
2425 | 2435 | ||
2426 | return err; | 2436 | return err; |
@@ -2763,7 +2773,7 @@ static int rt_fill_info(struct net *net, | |||
2763 | struct sk_buff *skb, u32 pid, u32 seq, int event, | 2773 | struct sk_buff *skb, u32 pid, u32 seq, int event, |
2764 | int nowait, unsigned int flags) | 2774 | int nowait, unsigned int flags) |
2765 | { | 2775 | { |
2766 | struct rtable *rt = skb->rtable; | 2776 | struct rtable *rt = skb_rtable(skb); |
2767 | struct rtmsg *r; | 2777 | struct rtmsg *r; |
2768 | struct nlmsghdr *nlh; | 2778 | struct nlmsghdr *nlh; |
2769 | long expires; | 2779 | long expires; |
@@ -2907,7 +2917,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void | |||
2907 | err = ip_route_input(skb, dst, src, rtm->rtm_tos, dev); | 2917 | err = ip_route_input(skb, dst, src, rtm->rtm_tos, dev); |
2908 | local_bh_enable(); | 2918 | local_bh_enable(); |
2909 | 2919 | ||
2910 | rt = skb->rtable; | 2920 | rt = skb_rtable(skb); |
2911 | if (err == 0 && rt->u.dst.error) | 2921 | if (err == 0 && rt->u.dst.error) |
2912 | err = -rt->u.dst.error; | 2922 | err = -rt->u.dst.error; |
2913 | } else { | 2923 | } else { |
@@ -2927,7 +2937,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void | |||
2927 | if (err) | 2937 | if (err) |
2928 | goto errout_free; | 2938 | goto errout_free; |
2929 | 2939 | ||
2930 | skb->rtable = rt; | 2940 | skb_dst_set(skb, &rt->u.dst); |
2931 | if (rtm->rtm_flags & RTM_F_NOTIFY) | 2941 | if (rtm->rtm_flags & RTM_F_NOTIFY) |
2932 | rt->rt_flags |= RTCF_NOTIFY; | 2942 | rt->rt_flags |= RTCF_NOTIFY; |
2933 | 2943 | ||
@@ -2968,15 +2978,15 @@ int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
2968 | continue; | 2978 | continue; |
2969 | if (rt_is_expired(rt)) | 2979 | if (rt_is_expired(rt)) |
2970 | continue; | 2980 | continue; |
2971 | skb->dst = dst_clone(&rt->u.dst); | 2981 | skb_dst_set(skb, dst_clone(&rt->u.dst)); |
2972 | if (rt_fill_info(net, skb, NETLINK_CB(cb->skb).pid, | 2982 | if (rt_fill_info(net, skb, NETLINK_CB(cb->skb).pid, |
2973 | cb->nlh->nlmsg_seq, RTM_NEWROUTE, | 2983 | cb->nlh->nlmsg_seq, RTM_NEWROUTE, |
2974 | 1, NLM_F_MULTI) <= 0) { | 2984 | 1, NLM_F_MULTI) <= 0) { |
2975 | dst_release(xchg(&skb->dst, NULL)); | 2985 | skb_dst_drop(skb); |
2976 | rcu_read_unlock_bh(); | 2986 | rcu_read_unlock_bh(); |
2977 | goto done; | 2987 | goto done; |
2978 | } | 2988 | } |
2979 | dst_release(xchg(&skb->dst, NULL)); | 2989 | skb_dst_drop(skb); |
2980 | } | 2990 | } |
2981 | rcu_read_unlock_bh(); | 2991 | rcu_read_unlock_bh(); |
2982 | } | 2992 | } |
@@ -3390,6 +3400,8 @@ int __init ip_rt_init(void) | |||
3390 | /* All the timers, started at system startup tend | 3400 | /* All the timers, started at system startup tend |
3391 | to synchronize. Perturb it a bit. | 3401 | to synchronize. Perturb it a bit. |
3392 | */ | 3402 | */ |
3403 | INIT_DELAYED_WORK_DEFERRABLE(&expires_work, rt_worker_func); | ||
3404 | expires_ljiffies = jiffies; | ||
3393 | schedule_delayed_work(&expires_work, | 3405 | schedule_delayed_work(&expires_work, |
3394 | net_random() % ip_rt_gc_interval + ip_rt_gc_interval); | 3406 | net_random() % ip_rt_gc_interval + ip_rt_gc_interval); |
3395 | 3407 | ||
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index b35a950d2e06..cd2b97f1b6e1 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c | |||
@@ -161,13 +161,12 @@ static __u16 const msstab[] = { | |||
161 | */ | 161 | */ |
162 | __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp) | 162 | __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp) |
163 | { | 163 | { |
164 | struct tcp_sock *tp = tcp_sk(sk); | ||
165 | const struct iphdr *iph = ip_hdr(skb); | 164 | const struct iphdr *iph = ip_hdr(skb); |
166 | const struct tcphdr *th = tcp_hdr(skb); | 165 | const struct tcphdr *th = tcp_hdr(skb); |
167 | int mssind; | 166 | int mssind; |
168 | const __u16 mss = *mssp; | 167 | const __u16 mss = *mssp; |
169 | 168 | ||
170 | tp->last_synq_overflow = jiffies; | 169 | tcp_synq_overflow(sk); |
171 | 170 | ||
172 | /* XXX sort msstab[] by probability? Binary search? */ | 171 | /* XXX sort msstab[] by probability? Binary search? */ |
173 | for (mssind = 0; mss > msstab[mssind + 1]; mssind++) | 172 | for (mssind = 0; mss > msstab[mssind + 1]; mssind++) |
@@ -268,7 +267,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | |||
268 | if (!sysctl_tcp_syncookies || !th->ack) | 267 | if (!sysctl_tcp_syncookies || !th->ack) |
269 | goto out; | 268 | goto out; |
270 | 269 | ||
271 | if (time_after(jiffies, tp->last_synq_overflow + TCP_TIMEOUT_INIT) || | 270 | if (tcp_synq_no_recent_overflow(sk) || |
272 | (mss = cookie_check(skb, cookie)) == 0) { | 271 | (mss = cookie_check(skb, cookie)) == 0) { |
273 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESFAILED); | 272 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESFAILED); |
274 | goto out; | 273 | goto out; |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 7a0f0b27bf1f..17b89c523f9d 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -439,12 +439,14 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
439 | !tp->urg_data || | 439 | !tp->urg_data || |
440 | before(tp->urg_seq, tp->copied_seq) || | 440 | before(tp->urg_seq, tp->copied_seq) || |
441 | !before(tp->urg_seq, tp->rcv_nxt)) { | 441 | !before(tp->urg_seq, tp->rcv_nxt)) { |
442 | struct sk_buff *skb; | ||
443 | |||
442 | answ = tp->rcv_nxt - tp->copied_seq; | 444 | answ = tp->rcv_nxt - tp->copied_seq; |
443 | 445 | ||
444 | /* Subtract 1, if FIN is in queue. */ | 446 | /* Subtract 1, if FIN is in queue. */ |
445 | if (answ && !skb_queue_empty(&sk->sk_receive_queue)) | 447 | skb = skb_peek_tail(&sk->sk_receive_queue); |
446 | answ -= | 448 | if (answ && skb) |
447 | tcp_hdr((struct sk_buff *)sk->sk_receive_queue.prev)->fin; | 449 | answ -= tcp_hdr(skb)->fin; |
448 | } else | 450 | } else |
449 | answ = tp->urg_seq - tp->copied_seq; | 451 | answ = tp->urg_seq - tp->copied_seq; |
450 | release_sock(sk); | 452 | release_sock(sk); |
@@ -1382,11 +1384,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
1382 | 1384 | ||
1383 | /* Next get a buffer. */ | 1385 | /* Next get a buffer. */ |
1384 | 1386 | ||
1385 | skb = skb_peek(&sk->sk_receive_queue); | 1387 | skb_queue_walk(&sk->sk_receive_queue, skb) { |
1386 | do { | ||
1387 | if (!skb) | ||
1388 | break; | ||
1389 | |||
1390 | /* Now that we have two receive queues this | 1388 | /* Now that we have two receive queues this |
1391 | * shouldn't happen. | 1389 | * shouldn't happen. |
1392 | */ | 1390 | */ |
@@ -1403,8 +1401,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
1403 | if (tcp_hdr(skb)->fin) | 1401 | if (tcp_hdr(skb)->fin) |
1404 | goto found_fin_ok; | 1402 | goto found_fin_ok; |
1405 | WARN_ON(!(flags & MSG_PEEK)); | 1403 | WARN_ON(!(flags & MSG_PEEK)); |
1406 | skb = skb->next; | 1404 | } |
1407 | } while (skb != (struct sk_buff *)&sk->sk_receive_queue); | ||
1408 | 1405 | ||
1409 | /* Well, if we have backlog, try to process it now yet. */ | 1406 | /* Well, if we have backlog, try to process it now yet. */ |
1410 | 1407 | ||
@@ -2518,20 +2515,30 @@ struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
2518 | unsigned int thlen; | 2515 | unsigned int thlen; |
2519 | unsigned int flags; | 2516 | unsigned int flags; |
2520 | unsigned int mss = 1; | 2517 | unsigned int mss = 1; |
2518 | unsigned int hlen; | ||
2519 | unsigned int off; | ||
2521 | int flush = 1; | 2520 | int flush = 1; |
2522 | int i; | 2521 | int i; |
2523 | 2522 | ||
2524 | th = skb_gro_header(skb, sizeof(*th)); | 2523 | off = skb_gro_offset(skb); |
2525 | if (unlikely(!th)) | 2524 | hlen = off + sizeof(*th); |
2526 | goto out; | 2525 | th = skb_gro_header_fast(skb, off); |
2526 | if (skb_gro_header_hard(skb, hlen)) { | ||
2527 | th = skb_gro_header_slow(skb, hlen, off); | ||
2528 | if (unlikely(!th)) | ||
2529 | goto out; | ||
2530 | } | ||
2527 | 2531 | ||
2528 | thlen = th->doff * 4; | 2532 | thlen = th->doff * 4; |
2529 | if (thlen < sizeof(*th)) | 2533 | if (thlen < sizeof(*th)) |
2530 | goto out; | 2534 | goto out; |
2531 | 2535 | ||
2532 | th = skb_gro_header(skb, thlen); | 2536 | hlen = off + thlen; |
2533 | if (unlikely(!th)) | 2537 | if (skb_gro_header_hard(skb, hlen)) { |
2534 | goto out; | 2538 | th = skb_gro_header_slow(skb, hlen, off); |
2539 | if (unlikely(!th)) | ||
2540 | goto out; | ||
2541 | } | ||
2535 | 2542 | ||
2536 | skb_gro_pull(skb, thlen); | 2543 | skb_gro_pull(skb, thlen); |
2537 | 2544 | ||
@@ -2544,7 +2551,7 @@ struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
2544 | 2551 | ||
2545 | th2 = tcp_hdr(p); | 2552 | th2 = tcp_hdr(p); |
2546 | 2553 | ||
2547 | if ((th->source ^ th2->source) | (th->dest ^ th2->dest)) { | 2554 | if (*(u32 *)&th->source ^ *(u32 *)&th2->source) { |
2548 | NAPI_GRO_CB(p)->same_flow = 0; | 2555 | NAPI_GRO_CB(p)->same_flow = 0; |
2549 | continue; | 2556 | continue; |
2550 | } | 2557 | } |
@@ -2559,14 +2566,14 @@ found: | |||
2559 | flush |= flags & TCP_FLAG_CWR; | 2566 | flush |= flags & TCP_FLAG_CWR; |
2560 | flush |= (flags ^ tcp_flag_word(th2)) & | 2567 | flush |= (flags ^ tcp_flag_word(th2)) & |
2561 | ~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH); | 2568 | ~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH); |
2562 | flush |= (th->ack_seq ^ th2->ack_seq) | (th->window ^ th2->window); | 2569 | flush |= th->ack_seq ^ th2->ack_seq; |
2563 | for (i = sizeof(*th); !flush && i < thlen; i += 4) | 2570 | for (i = sizeof(*th); i < thlen; i += 4) |
2564 | flush |= *(u32 *)((u8 *)th + i) ^ | 2571 | flush |= *(u32 *)((u8 *)th + i) ^ |
2565 | *(u32 *)((u8 *)th2 + i); | 2572 | *(u32 *)((u8 *)th2 + i); |
2566 | 2573 | ||
2567 | mss = skb_shinfo(p)->gso_size; | 2574 | mss = skb_shinfo(p)->gso_size; |
2568 | 2575 | ||
2569 | flush |= (len > mss) | !len; | 2576 | flush |= (len - 1) >= mss; |
2570 | flush |= (ntohl(th2->seq) + skb_gro_len(p)) ^ ntohl(th->seq); | 2577 | flush |= (ntohl(th2->seq) + skb_gro_len(p)) ^ ntohl(th->seq); |
2571 | 2578 | ||
2572 | if (flush || skb_gro_receive(head, skb)) { | 2579 | if (flush || skb_gro_receive(head, skb)) { |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index eec3e6f9956c..2bdb0da237e6 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -77,7 +77,7 @@ int sysctl_tcp_window_scaling __read_mostly = 1; | |||
77 | int sysctl_tcp_sack __read_mostly = 1; | 77 | int sysctl_tcp_sack __read_mostly = 1; |
78 | int sysctl_tcp_fack __read_mostly = 1; | 78 | int sysctl_tcp_fack __read_mostly = 1; |
79 | int sysctl_tcp_reordering __read_mostly = TCP_FASTRETRANS_THRESH; | 79 | int sysctl_tcp_reordering __read_mostly = TCP_FASTRETRANS_THRESH; |
80 | int sysctl_tcp_ecn __read_mostly; | 80 | int sysctl_tcp_ecn __read_mostly = 2; |
81 | int sysctl_tcp_dsack __read_mostly = 1; | 81 | int sysctl_tcp_dsack __read_mostly = 1; |
82 | int sysctl_tcp_app_win __read_mostly = 31; | 82 | int sysctl_tcp_app_win __read_mostly = 31; |
83 | int sysctl_tcp_adv_win_scale __read_mostly = 2; | 83 | int sysctl_tcp_adv_win_scale __read_mostly = 2; |
@@ -4426,7 +4426,7 @@ drop: | |||
4426 | } | 4426 | } |
4427 | __skb_queue_head(&tp->out_of_order_queue, skb); | 4427 | __skb_queue_head(&tp->out_of_order_queue, skb); |
4428 | } else { | 4428 | } else { |
4429 | struct sk_buff *skb1 = tp->out_of_order_queue.prev; | 4429 | struct sk_buff *skb1 = skb_peek_tail(&tp->out_of_order_queue); |
4430 | u32 seq = TCP_SKB_CB(skb)->seq; | 4430 | u32 seq = TCP_SKB_CB(skb)->seq; |
4431 | u32 end_seq = TCP_SKB_CB(skb)->end_seq; | 4431 | u32 end_seq = TCP_SKB_CB(skb)->end_seq; |
4432 | 4432 | ||
@@ -4443,15 +4443,18 @@ drop: | |||
4443 | } | 4443 | } |
4444 | 4444 | ||
4445 | /* Find place to insert this segment. */ | 4445 | /* Find place to insert this segment. */ |
4446 | do { | 4446 | while (1) { |
4447 | if (!after(TCP_SKB_CB(skb1)->seq, seq)) | 4447 | if (!after(TCP_SKB_CB(skb1)->seq, seq)) |
4448 | break; | 4448 | break; |
4449 | } while ((skb1 = skb1->prev) != | 4449 | if (skb_queue_is_first(&tp->out_of_order_queue, skb1)) { |
4450 | (struct sk_buff *)&tp->out_of_order_queue); | 4450 | skb1 = NULL; |
4451 | break; | ||
4452 | } | ||
4453 | skb1 = skb_queue_prev(&tp->out_of_order_queue, skb1); | ||
4454 | } | ||
4451 | 4455 | ||
4452 | /* Do skb overlap to previous one? */ | 4456 | /* Do skb overlap to previous one? */ |
4453 | if (skb1 != (struct sk_buff *)&tp->out_of_order_queue && | 4457 | if (skb1 && before(seq, TCP_SKB_CB(skb1)->end_seq)) { |
4454 | before(seq, TCP_SKB_CB(skb1)->end_seq)) { | ||
4455 | if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) { | 4458 | if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) { |
4456 | /* All the bits are present. Drop. */ | 4459 | /* All the bits are present. Drop. */ |
4457 | __kfree_skb(skb); | 4460 | __kfree_skb(skb); |
@@ -4463,15 +4466,26 @@ drop: | |||
4463 | tcp_dsack_set(sk, seq, | 4466 | tcp_dsack_set(sk, seq, |
4464 | TCP_SKB_CB(skb1)->end_seq); | 4467 | TCP_SKB_CB(skb1)->end_seq); |
4465 | } else { | 4468 | } else { |
4466 | skb1 = skb1->prev; | 4469 | if (skb_queue_is_first(&tp->out_of_order_queue, |
4470 | skb1)) | ||
4471 | skb1 = NULL; | ||
4472 | else | ||
4473 | skb1 = skb_queue_prev( | ||
4474 | &tp->out_of_order_queue, | ||
4475 | skb1); | ||
4467 | } | 4476 | } |
4468 | } | 4477 | } |
4469 | __skb_queue_after(&tp->out_of_order_queue, skb1, skb); | 4478 | if (!skb1) |
4479 | __skb_queue_head(&tp->out_of_order_queue, skb); | ||
4480 | else | ||
4481 | __skb_queue_after(&tp->out_of_order_queue, skb1, skb); | ||
4470 | 4482 | ||
4471 | /* And clean segments covered by new one as whole. */ | 4483 | /* And clean segments covered by new one as whole. */ |
4472 | while ((skb1 = skb->next) != | 4484 | while (!skb_queue_is_last(&tp->out_of_order_queue, skb)) { |
4473 | (struct sk_buff *)&tp->out_of_order_queue && | 4485 | skb1 = skb_queue_next(&tp->out_of_order_queue, skb); |
4474 | after(end_seq, TCP_SKB_CB(skb1)->seq)) { | 4486 | |
4487 | if (!after(end_seq, TCP_SKB_CB(skb1)->seq)) | ||
4488 | break; | ||
4475 | if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) { | 4489 | if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) { |
4476 | tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq, | 4490 | tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq, |
4477 | end_seq); | 4491 | end_seq); |
@@ -4492,7 +4506,10 @@ add_sack: | |||
4492 | static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb, | 4506 | static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb, |
4493 | struct sk_buff_head *list) | 4507 | struct sk_buff_head *list) |
4494 | { | 4508 | { |
4495 | struct sk_buff *next = skb->next; | 4509 | struct sk_buff *next = NULL; |
4510 | |||
4511 | if (!skb_queue_is_last(list, skb)) | ||
4512 | next = skb_queue_next(list, skb); | ||
4496 | 4513 | ||
4497 | __skb_unlink(skb, list); | 4514 | __skb_unlink(skb, list); |
4498 | __kfree_skb(skb); | 4515 | __kfree_skb(skb); |
@@ -4503,6 +4520,9 @@ static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb, | |||
4503 | 4520 | ||
4504 | /* Collapse contiguous sequence of skbs head..tail with | 4521 | /* Collapse contiguous sequence of skbs head..tail with |
4505 | * sequence numbers start..end. | 4522 | * sequence numbers start..end. |
4523 | * | ||
4524 | * If tail is NULL, this means until the end of the list. | ||
4525 | * | ||
4506 | * Segments with FIN/SYN are not collapsed (only because this | 4526 | * Segments with FIN/SYN are not collapsed (only because this |
4507 | * simplifies code) | 4527 | * simplifies code) |
4508 | */ | 4528 | */ |
@@ -4511,15 +4531,23 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list, | |||
4511 | struct sk_buff *head, struct sk_buff *tail, | 4531 | struct sk_buff *head, struct sk_buff *tail, |
4512 | u32 start, u32 end) | 4532 | u32 start, u32 end) |
4513 | { | 4533 | { |
4514 | struct sk_buff *skb; | 4534 | struct sk_buff *skb, *n; |
4535 | bool end_of_skbs; | ||
4515 | 4536 | ||
4516 | /* First, check that queue is collapsible and find | 4537 | /* First, check that queue is collapsible and find |
4517 | * the point where collapsing can be useful. */ | 4538 | * the point where collapsing can be useful. */ |
4518 | for (skb = head; skb != tail;) { | 4539 | skb = head; |
4540 | restart: | ||
4541 | end_of_skbs = true; | ||
4542 | skb_queue_walk_from_safe(list, skb, n) { | ||
4543 | if (skb == tail) | ||
4544 | break; | ||
4519 | /* No new bits? It is possible on ofo queue. */ | 4545 | /* No new bits? It is possible on ofo queue. */ |
4520 | if (!before(start, TCP_SKB_CB(skb)->end_seq)) { | 4546 | if (!before(start, TCP_SKB_CB(skb)->end_seq)) { |
4521 | skb = tcp_collapse_one(sk, skb, list); | 4547 | skb = tcp_collapse_one(sk, skb, list); |
4522 | continue; | 4548 | if (!skb) |
4549 | break; | ||
4550 | goto restart; | ||
4523 | } | 4551 | } |
4524 | 4552 | ||
4525 | /* The first skb to collapse is: | 4553 | /* The first skb to collapse is: |
@@ -4529,16 +4557,24 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list, | |||
4529 | */ | 4557 | */ |
4530 | if (!tcp_hdr(skb)->syn && !tcp_hdr(skb)->fin && | 4558 | if (!tcp_hdr(skb)->syn && !tcp_hdr(skb)->fin && |
4531 | (tcp_win_from_space(skb->truesize) > skb->len || | 4559 | (tcp_win_from_space(skb->truesize) > skb->len || |
4532 | before(TCP_SKB_CB(skb)->seq, start) || | 4560 | before(TCP_SKB_CB(skb)->seq, start))) { |
4533 | (skb->next != tail && | 4561 | end_of_skbs = false; |
4534 | TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb->next)->seq))) | ||
4535 | break; | 4562 | break; |
4563 | } | ||
4564 | |||
4565 | if (!skb_queue_is_last(list, skb)) { | ||
4566 | struct sk_buff *next = skb_queue_next(list, skb); | ||
4567 | if (next != tail && | ||
4568 | TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(next)->seq) { | ||
4569 | end_of_skbs = false; | ||
4570 | break; | ||
4571 | } | ||
4572 | } | ||
4536 | 4573 | ||
4537 | /* Decided to skip this, advance start seq. */ | 4574 | /* Decided to skip this, advance start seq. */ |
4538 | start = TCP_SKB_CB(skb)->end_seq; | 4575 | start = TCP_SKB_CB(skb)->end_seq; |
4539 | skb = skb->next; | ||
4540 | } | 4576 | } |
4541 | if (skb == tail || tcp_hdr(skb)->syn || tcp_hdr(skb)->fin) | 4577 | if (end_of_skbs || tcp_hdr(skb)->syn || tcp_hdr(skb)->fin) |
4542 | return; | 4578 | return; |
4543 | 4579 | ||
4544 | while (before(start, end)) { | 4580 | while (before(start, end)) { |
@@ -4583,7 +4619,8 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list, | |||
4583 | } | 4619 | } |
4584 | if (!before(start, TCP_SKB_CB(skb)->end_seq)) { | 4620 | if (!before(start, TCP_SKB_CB(skb)->end_seq)) { |
4585 | skb = tcp_collapse_one(sk, skb, list); | 4621 | skb = tcp_collapse_one(sk, skb, list); |
4586 | if (skb == tail || | 4622 | if (!skb || |
4623 | skb == tail || | ||
4587 | tcp_hdr(skb)->syn || | 4624 | tcp_hdr(skb)->syn || |
4588 | tcp_hdr(skb)->fin) | 4625 | tcp_hdr(skb)->fin) |
4589 | return; | 4626 | return; |
@@ -4610,17 +4647,21 @@ static void tcp_collapse_ofo_queue(struct sock *sk) | |||
4610 | head = skb; | 4647 | head = skb; |
4611 | 4648 | ||
4612 | for (;;) { | 4649 | for (;;) { |
4613 | skb = skb->next; | 4650 | struct sk_buff *next = NULL; |
4651 | |||
4652 | if (!skb_queue_is_last(&tp->out_of_order_queue, skb)) | ||
4653 | next = skb_queue_next(&tp->out_of_order_queue, skb); | ||
4654 | skb = next; | ||
4614 | 4655 | ||
4615 | /* Segment is terminated when we see gap or when | 4656 | /* Segment is terminated when we see gap or when |
4616 | * we are at the end of all the queue. */ | 4657 | * we are at the end of all the queue. */ |
4617 | if (skb == (struct sk_buff *)&tp->out_of_order_queue || | 4658 | if (!skb || |
4618 | after(TCP_SKB_CB(skb)->seq, end) || | 4659 | after(TCP_SKB_CB(skb)->seq, end) || |
4619 | before(TCP_SKB_CB(skb)->end_seq, start)) { | 4660 | before(TCP_SKB_CB(skb)->end_seq, start)) { |
4620 | tcp_collapse(sk, &tp->out_of_order_queue, | 4661 | tcp_collapse(sk, &tp->out_of_order_queue, |
4621 | head, skb, start, end); | 4662 | head, skb, start, end); |
4622 | head = skb; | 4663 | head = skb; |
4623 | if (skb == (struct sk_buff *)&tp->out_of_order_queue) | 4664 | if (!skb) |
4624 | break; | 4665 | break; |
4625 | /* Start new segment */ | 4666 | /* Start new segment */ |
4626 | start = TCP_SKB_CB(skb)->seq; | 4667 | start = TCP_SKB_CB(skb)->seq; |
@@ -4681,10 +4722,11 @@ static int tcp_prune_queue(struct sock *sk) | |||
4681 | tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U * tp->advmss); | 4722 | tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U * tp->advmss); |
4682 | 4723 | ||
4683 | tcp_collapse_ofo_queue(sk); | 4724 | tcp_collapse_ofo_queue(sk); |
4684 | tcp_collapse(sk, &sk->sk_receive_queue, | 4725 | if (!skb_queue_empty(&sk->sk_receive_queue)) |
4685 | sk->sk_receive_queue.next, | 4726 | tcp_collapse(sk, &sk->sk_receive_queue, |
4686 | (struct sk_buff *)&sk->sk_receive_queue, | 4727 | skb_peek(&sk->sk_receive_queue), |
4687 | tp->copied_seq, tp->rcv_nxt); | 4728 | NULL, |
4729 | tp->copied_seq, tp->rcv_nxt); | ||
4688 | sk_mem_reclaim(sk); | 4730 | sk_mem_reclaim(sk); |
4689 | 4731 | ||
4690 | if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) | 4732 | if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 5d427f86b414..5a1ca2698c88 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -546,7 +546,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb) | |||
546 | if (th->rst) | 546 | if (th->rst) |
547 | return; | 547 | return; |
548 | 548 | ||
549 | if (skb->rtable->rt_type != RTN_LOCAL) | 549 | if (skb_rtable(skb)->rt_type != RTN_LOCAL) |
550 | return; | 550 | return; |
551 | 551 | ||
552 | /* Swap the send and the receive. */ | 552 | /* Swap the send and the receive. */ |
@@ -590,7 +590,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb) | |||
590 | arg.csumoffset = offsetof(struct tcphdr, check) / 2; | 590 | arg.csumoffset = offsetof(struct tcphdr, check) / 2; |
591 | arg.flags = (sk && inet_sk(sk)->transparent) ? IP_REPLY_ARG_NOSRCCHECK : 0; | 591 | arg.flags = (sk && inet_sk(sk)->transparent) ? IP_REPLY_ARG_NOSRCCHECK : 0; |
592 | 592 | ||
593 | net = dev_net(skb->dst->dev); | 593 | net = dev_net(skb_dst(skb)->dev); |
594 | ip_send_reply(net->ipv4.tcp_sock, skb, | 594 | ip_send_reply(net->ipv4.tcp_sock, skb, |
595 | &arg, arg.iov[0].iov_len); | 595 | &arg, arg.iov[0].iov_len); |
596 | 596 | ||
@@ -617,7 +617,7 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, | |||
617 | ]; | 617 | ]; |
618 | } rep; | 618 | } rep; |
619 | struct ip_reply_arg arg; | 619 | struct ip_reply_arg arg; |
620 | struct net *net = dev_net(skb->dst->dev); | 620 | struct net *net = dev_net(skb_dst(skb)->dev); |
621 | 621 | ||
622 | memset(&rep.th, 0, sizeof(struct tcphdr)); | 622 | memset(&rep.th, 0, sizeof(struct tcphdr)); |
623 | memset(&arg, 0, sizeof(arg)); | 623 | memset(&arg, 0, sizeof(arg)); |
@@ -1185,7 +1185,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1185 | #endif | 1185 | #endif |
1186 | 1186 | ||
1187 | /* Never answer to SYNs send to broadcast or multicast */ | 1187 | /* Never answer to SYNs send to broadcast or multicast */ |
1188 | if (skb->rtable->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) | 1188 | if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) |
1189 | goto drop; | 1189 | goto drop; |
1190 | 1190 | ||
1191 | /* TW buckets are converted to open requests without | 1191 | /* TW buckets are converted to open requests without |
@@ -1593,7 +1593,7 @@ process: | |||
1593 | #endif | 1593 | #endif |
1594 | { | 1594 | { |
1595 | if (!tcp_prequeue(sk, skb)) | 1595 | if (!tcp_prequeue(sk, skb)) |
1596 | ret = tcp_v4_do_rcv(sk, skb); | 1596 | ret = tcp_v4_do_rcv(sk, skb); |
1597 | } | 1597 | } |
1598 | } else | 1598 | } else |
1599 | sk_add_backlog(sk, skb); | 1599 | sk_add_backlog(sk, skb); |
@@ -2343,7 +2343,7 @@ void tcp4_proc_exit(void) | |||
2343 | 2343 | ||
2344 | struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *skb) | 2344 | struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *skb) |
2345 | { | 2345 | { |
2346 | struct iphdr *iph = ip_hdr(skb); | 2346 | struct iphdr *iph = skb_gro_network_header(skb); |
2347 | 2347 | ||
2348 | switch (skb->ip_summed) { | 2348 | switch (skb->ip_summed) { |
2349 | case CHECKSUM_COMPLETE: | 2349 | case CHECKSUM_COMPLETE: |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 59aec609cec6..416fc4c2e7eb 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -288,7 +288,7 @@ static inline void TCP_ECN_send_syn(struct sock *sk, struct sk_buff *skb) | |||
288 | struct tcp_sock *tp = tcp_sk(sk); | 288 | struct tcp_sock *tp = tcp_sk(sk); |
289 | 289 | ||
290 | tp->ecn_flags = 0; | 290 | tp->ecn_flags = 0; |
291 | if (sysctl_tcp_ecn) { | 291 | if (sysctl_tcp_ecn == 1) { |
292 | TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_ECE | TCPCB_FLAG_CWR; | 292 | TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_ECE | TCPCB_FLAG_CWR; |
293 | tp->ecn_flags = TCP_ECN_OK; | 293 | tp->ecn_flags = TCP_ECN_OK; |
294 | } | 294 | } |
@@ -2202,7 +2202,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
2202 | /* Reserve space for headers. */ | 2202 | /* Reserve space for headers. */ |
2203 | skb_reserve(skb, MAX_TCP_HEADER); | 2203 | skb_reserve(skb, MAX_TCP_HEADER); |
2204 | 2204 | ||
2205 | skb->dst = dst_clone(dst); | 2205 | skb_dst_set(skb, dst_clone(dst)); |
2206 | 2206 | ||
2207 | mss = dst_metric(dst, RTAX_ADVMSS); | 2207 | mss = dst_metric(dst, RTAX_ADVMSS); |
2208 | if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss) | 2208 | if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss) |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 7a1d1ce22e66..8f4158d7c9a6 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -328,7 +328,7 @@ static inline struct sock *__udp4_lib_lookup_skb(struct sk_buff *skb, | |||
328 | if (unlikely(sk = skb_steal_sock(skb))) | 328 | if (unlikely(sk = skb_steal_sock(skb))) |
329 | return sk; | 329 | return sk; |
330 | else | 330 | else |
331 | return __udp4_lib_lookup(dev_net(skb->dst->dev), iph->saddr, sport, | 331 | return __udp4_lib_lookup(dev_net(skb_dst(skb)->dev), iph->saddr, sport, |
332 | iph->daddr, dport, inet_iif(skb), | 332 | iph->daddr, dport, inet_iif(skb), |
333 | udptable); | 333 | udptable); |
334 | } | 334 | } |
@@ -1237,7 +1237,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, | |||
1237 | struct sock *sk; | 1237 | struct sock *sk; |
1238 | struct udphdr *uh; | 1238 | struct udphdr *uh; |
1239 | unsigned short ulen; | 1239 | unsigned short ulen; |
1240 | struct rtable *rt = (struct rtable*)skb->dst; | 1240 | struct rtable *rt = skb_rtable(skb); |
1241 | __be32 saddr, daddr; | 1241 | __be32 saddr, daddr; |
1242 | struct net *net = dev_net(skb->dev); | 1242 | struct net *net = dev_net(skb->dev); |
1243 | 1243 | ||
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c index 4ec2162a437e..f9f922a0ba88 100644 --- a/net/ipv4/xfrm4_input.c +++ b/net/ipv4/xfrm4_input.c | |||
@@ -23,7 +23,7 @@ int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb) | |||
23 | 23 | ||
24 | static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb) | 24 | static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb) |
25 | { | 25 | { |
26 | if (skb->dst == NULL) { | 26 | if (skb_dst(skb) == NULL) { |
27 | const struct iphdr *iph = ip_hdr(skb); | 27 | const struct iphdr *iph = ip_hdr(skb); |
28 | 28 | ||
29 | if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, | 29 | if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, |
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c index 7135279f3f84..3444f3b34eca 100644 --- a/net/ipv4/xfrm4_mode_tunnel.c +++ b/net/ipv4/xfrm4_mode_tunnel.c | |||
@@ -28,7 +28,7 @@ static inline void ipip_ecn_decapsulate(struct sk_buff *skb) | |||
28 | */ | 28 | */ |
29 | static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) | 29 | static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) |
30 | { | 30 | { |
31 | struct dst_entry *dst = skb->dst; | 31 | struct dst_entry *dst = skb_dst(skb); |
32 | struct iphdr *top_iph; | 32 | struct iphdr *top_iph; |
33 | int flags; | 33 | int flags; |
34 | 34 | ||
@@ -41,7 +41,7 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) | |||
41 | top_iph->ihl = 5; | 41 | top_iph->ihl = 5; |
42 | top_iph->version = 4; | 42 | top_iph->version = 4; |
43 | 43 | ||
44 | top_iph->protocol = xfrm_af2proto(skb->dst->ops->family); | 44 | top_iph->protocol = xfrm_af2proto(skb_dst(skb)->ops->family); |
45 | 45 | ||
46 | /* DS disclosed */ | 46 | /* DS disclosed */ |
47 | top_iph->tos = INET_ECN_encapsulate(XFRM_MODE_SKB_CB(skb)->tos, | 47 | top_iph->tos = INET_ECN_encapsulate(XFRM_MODE_SKB_CB(skb)->tos, |
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c index 8c3180adddbf..c908bd99bcba 100644 --- a/net/ipv4/xfrm4_output.c +++ b/net/ipv4/xfrm4_output.c | |||
@@ -29,7 +29,7 @@ static int xfrm4_tunnel_check_size(struct sk_buff *skb) | |||
29 | if (!(ip_hdr(skb)->frag_off & htons(IP_DF)) || skb->local_df) | 29 | if (!(ip_hdr(skb)->frag_off & htons(IP_DF)) || skb->local_df) |
30 | goto out; | 30 | goto out; |
31 | 31 | ||
32 | dst = skb->dst; | 32 | dst = skb_dst(skb); |
33 | mtu = dst_mtu(dst); | 33 | mtu = dst_mtu(dst); |
34 | if (skb->len > mtu) { | 34 | if (skb->len > mtu) { |
35 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); | 35 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); |
@@ -72,7 +72,7 @@ EXPORT_SYMBOL(xfrm4_prepare_output); | |||
72 | static int xfrm4_output_finish(struct sk_buff *skb) | 72 | static int xfrm4_output_finish(struct sk_buff *skb) |
73 | { | 73 | { |
74 | #ifdef CONFIG_NETFILTER | 74 | #ifdef CONFIG_NETFILTER |
75 | if (!skb->dst->xfrm) { | 75 | if (!skb_dst(skb)->xfrm) { |
76 | IPCB(skb)->flags |= IPSKB_REROUTED; | 76 | IPCB(skb)->flags |= IPSKB_REROUTED; |
77 | return dst_output(skb); | 77 | return dst_output(skb); |
78 | } | 78 | } |
@@ -87,6 +87,6 @@ static int xfrm4_output_finish(struct sk_buff *skb) | |||
87 | int xfrm4_output(struct sk_buff *skb) | 87 | int xfrm4_output(struct sk_buff *skb) |
88 | { | 88 | { |
89 | return NF_HOOK_COND(PF_INET, NF_INET_POST_ROUTING, skb, | 89 | return NF_HOOK_COND(PF_INET, NF_INET_POST_ROUTING, skb, |
90 | NULL, skb->dst->dev, xfrm4_output_finish, | 90 | NULL, skb_dst(skb)->dev, xfrm4_output_finish, |
91 | !(IPCB(skb)->flags & IPSKB_REROUTED)); | 91 | !(IPCB(skb)->flags & IPSKB_REROUTED)); |
92 | } | 92 | } |