diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 35 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 1 | ||||
-rw-r--r-- | net/ipv6/ah6.c | 2 | ||||
-rw-r--r-- | net/ipv6/datagram.c | 8 | ||||
-rw-r--r-- | net/ipv6/exthdrs.c | 16 | ||||
-rw-r--r-- | net/ipv6/ip6_fib.c | 9 | ||||
-rw-r--r-- | net/ipv6/ip6_input.c | 2 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 13 | ||||
-rw-r--r-- | net/ipv6/netfilter/Kconfig | 2 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6table_filter.c | 70 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6table_mangle.c | 96 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6table_raw.c | 52 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 3 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 3 | ||||
-rw-r--r-- | net/ipv6/raw.c | 8 | ||||
-rw-r--r-- | net/ipv6/route.c | 63 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 8 | ||||
-rw-r--r-- | net/ipv6/udp.c | 29 | ||||
-rw-r--r-- | net/ipv6/udp_impl.h | 2 | ||||
-rw-r--r-- | net/ipv6/udplite.c | 2 | ||||
-rw-r--r-- | net/ipv6/xfrm6_input.c | 6 | ||||
-rw-r--r-- | net/ipv6/xfrm6_mode_tunnel.c | 1 |
22 files changed, 220 insertions, 211 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index d02685c6bc69..329de679ac38 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -2154,15 +2154,6 @@ static void addrconf_dev_config(struct net_device *dev) | |||
2154 | 2154 | ||
2155 | ASSERT_RTNL(); | 2155 | ASSERT_RTNL(); |
2156 | 2156 | ||
2157 | if ((dev->type != ARPHRD_ETHER) && | ||
2158 | (dev->type != ARPHRD_FDDI) && | ||
2159 | (dev->type != ARPHRD_IEEE802_TR) && | ||
2160 | (dev->type != ARPHRD_ARCNET) && | ||
2161 | (dev->type != ARPHRD_INFINIBAND)) { | ||
2162 | /* Alas, we support only Ethernet autoconfiguration. */ | ||
2163 | return; | ||
2164 | } | ||
2165 | |||
2166 | idev = addrconf_add_dev(dev); | 2157 | idev = addrconf_add_dev(dev); |
2167 | if (idev == NULL) | 2158 | if (idev == NULL) |
2168 | return; | 2159 | return; |
@@ -2250,13 +2241,33 @@ static void addrconf_ip6_tnl_config(struct net_device *dev) | |||
2250 | ip6_tnl_add_linklocal(idev); | 2241 | ip6_tnl_add_linklocal(idev); |
2251 | } | 2242 | } |
2252 | 2243 | ||
2244 | static int ipv6_hwtype(struct net_device *dev) | ||
2245 | { | ||
2246 | if ((dev->type == ARPHRD_ETHER) || | ||
2247 | (dev->type == ARPHRD_LOOPBACK) || | ||
2248 | (dev->type == ARPHRD_SIT) || | ||
2249 | (dev->type == ARPHRD_TUNNEL6) || | ||
2250 | (dev->type == ARPHRD_FDDI) || | ||
2251 | (dev->type == ARPHRD_IEEE802_TR) || | ||
2252 | (dev->type == ARPHRD_ARCNET) || | ||
2253 | (dev->type == ARPHRD_INFINIBAND)) | ||
2254 | return 1; | ||
2255 | |||
2256 | return 0; | ||
2257 | } | ||
2258 | |||
2253 | static int addrconf_notify(struct notifier_block *this, unsigned long event, | 2259 | static int addrconf_notify(struct notifier_block *this, unsigned long event, |
2254 | void * data) | 2260 | void * data) |
2255 | { | 2261 | { |
2256 | struct net_device *dev = (struct net_device *) data; | 2262 | struct net_device *dev = (struct net_device *) data; |
2257 | struct inet6_dev *idev = __in6_dev_get(dev); | 2263 | struct inet6_dev *idev; |
2258 | int run_pending = 0; | 2264 | int run_pending = 0; |
2259 | 2265 | ||
2266 | if (!ipv6_hwtype(dev)) | ||
2267 | return NOTIFY_OK; | ||
2268 | |||
2269 | idev = __in6_dev_get(dev); | ||
2270 | |||
2260 | switch(event) { | 2271 | switch(event) { |
2261 | case NETDEV_REGISTER: | 2272 | case NETDEV_REGISTER: |
2262 | if (!idev) { | 2273 | if (!idev) { |
@@ -4204,6 +4215,10 @@ int __init addrconf_init(void) | |||
4204 | return err; | 4215 | return err; |
4205 | 4216 | ||
4206 | ip6_null_entry.rt6i_idev = in6_dev_get(&loopback_dev); | 4217 | ip6_null_entry.rt6i_idev = in6_dev_get(&loopback_dev); |
4218 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | ||
4219 | ip6_prohibit_entry.rt6i_idev = in6_dev_get(&loopback_dev); | ||
4220 | ip6_blk_hole_entry.rt6i_idev = in6_dev_get(&loopback_dev); | ||
4221 | #endif | ||
4207 | 4222 | ||
4208 | register_netdevice_notifier(&ipv6_dev_notf); | 4223 | register_netdevice_notifier(&ipv6_dev_notf); |
4209 | 4224 | ||
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 18cb928c8d92..6dd377253cf7 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -42,7 +42,6 @@ | |||
42 | #include <linux/inet.h> | 42 | #include <linux/inet.h> |
43 | #include <linux/netdevice.h> | 43 | #include <linux/netdevice.h> |
44 | #include <linux/icmpv6.h> | 44 | #include <linux/icmpv6.h> |
45 | #include <linux/smp_lock.h> | ||
46 | #include <linux/netfilter_ipv6.h> | 45 | #include <linux/netfilter_ipv6.h> |
47 | 46 | ||
48 | #include <net/ip.h> | 47 | #include <net/ip.h> |
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index b696c8401200..128f94c79c64 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c | |||
@@ -247,7 +247,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb) | |||
247 | memcpy(tmp_base, top_iph, sizeof(tmp_base)); | 247 | memcpy(tmp_base, top_iph, sizeof(tmp_base)); |
248 | 248 | ||
249 | tmp_ext = NULL; | 249 | tmp_ext = NULL; |
250 | extlen = skb_transport_offset(skb) + sizeof(struct ipv6hdr); | 250 | extlen = skb_transport_offset(skb) - sizeof(struct ipv6hdr); |
251 | if (extlen) { | 251 | if (extlen) { |
252 | extlen += sizeof(*tmp_ext); | 252 | extlen += sizeof(*tmp_ext); |
253 | tmp_ext = kmalloc(extlen, GFP_ATOMIC); | 253 | tmp_ext = kmalloc(extlen, GFP_ATOMIC); |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 403eee66b9c5..b1fe7ac5dc90 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -177,8 +177,12 @@ ipv4_connected: | |||
177 | if (final_p) | 177 | if (final_p) |
178 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 178 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
179 | 179 | ||
180 | if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0) | 180 | if ((err = __xfrm_lookup(&dst, &fl, sk, 1)) < 0) { |
181 | goto out; | 181 | if (err == -EREMOTE) |
182 | err = ip6_dst_blackhole(sk, &dst, &fl); | ||
183 | if (err < 0) | ||
184 | goto out; | ||
185 | } | ||
182 | 186 | ||
183 | /* source address lookup done in ip6_dst_lookup */ | 187 | /* source address lookup done in ip6_dst_lookup */ |
184 | 188 | ||
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 6d8e4ac7bdad..14be0b9b77a5 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
@@ -660,6 +660,14 @@ EXPORT_SYMBOL_GPL(ipv6_invert_rthdr); | |||
660 | Hop-by-hop options. | 660 | Hop-by-hop options. |
661 | **********************************/ | 661 | **********************************/ |
662 | 662 | ||
663 | /* | ||
664 | * Note: we cannot rely on skb->dst before we assign it in ip6_route_input(). | ||
665 | */ | ||
666 | static inline struct inet6_dev *ipv6_skb_idev(struct sk_buff *skb) | ||
667 | { | ||
668 | return skb->dst ? ip6_dst_idev(skb->dst) : __in6_dev_get(skb->dev); | ||
669 | } | ||
670 | |||
663 | /* Router Alert as of RFC 2711 */ | 671 | /* Router Alert as of RFC 2711 */ |
664 | 672 | ||
665 | static int ipv6_hop_ra(struct sk_buff **skbp, int optoff) | 673 | static int ipv6_hop_ra(struct sk_buff **skbp, int optoff) |
@@ -688,25 +696,25 @@ static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff) | |||
688 | if (nh[optoff + 1] != 4 || (optoff & 3) != 2) { | 696 | if (nh[optoff + 1] != 4 || (optoff & 3) != 2) { |
689 | LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", | 697 | LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", |
690 | nh[optoff+1]); | 698 | nh[optoff+1]); |
691 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | 699 | IP6_INC_STATS_BH(ipv6_skb_idev(skb), |
692 | IPSTATS_MIB_INHDRERRORS); | 700 | IPSTATS_MIB_INHDRERRORS); |
693 | goto drop; | 701 | goto drop; |
694 | } | 702 | } |
695 | 703 | ||
696 | pkt_len = ntohl(*(__be32 *)(nh + optoff + 2)); | 704 | pkt_len = ntohl(*(__be32 *)(nh + optoff + 2)); |
697 | if (pkt_len <= IPV6_MAXPLEN) { | 705 | if (pkt_len <= IPV6_MAXPLEN) { |
698 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); | 706 | IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS); |
699 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2); | 707 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2); |
700 | return 0; | 708 | return 0; |
701 | } | 709 | } |
702 | if (ipv6_hdr(skb)->payload_len) { | 710 | if (ipv6_hdr(skb)->payload_len) { |
703 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); | 711 | IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS); |
704 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff); | 712 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff); |
705 | return 0; | 713 | return 0; |
706 | } | 714 | } |
707 | 715 | ||
708 | if (pkt_len > skb->len - sizeof(struct ipv6hdr)) { | 716 | if (pkt_len > skb->len - sizeof(struct ipv6hdr)) { |
709 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INTRUNCATEDPKTS); | 717 | IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INTRUNCATEDPKTS); |
710 | goto drop; | 718 | goto drop; |
711 | } | 719 | } |
712 | 720 | ||
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index ca08ee88d07f..662a7d9681fd 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -619,14 +619,6 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, | |||
619 | 619 | ||
620 | ins = &fn->leaf; | 620 | ins = &fn->leaf; |
621 | 621 | ||
622 | if (fn->fn_flags&RTN_TL_ROOT && | ||
623 | fn->leaf == &ip6_null_entry && | ||
624 | !(rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) ){ | ||
625 | fn->leaf = rt; | ||
626 | rt->u.dst.rt6_next = NULL; | ||
627 | goto out; | ||
628 | } | ||
629 | |||
630 | for (iter = fn->leaf; iter; iter=iter->u.dst.rt6_next) { | 622 | for (iter = fn->leaf; iter; iter=iter->u.dst.rt6_next) { |
631 | /* | 623 | /* |
632 | * Search for duplicates | 624 | * Search for duplicates |
@@ -666,7 +658,6 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, | |||
666 | * insert node | 658 | * insert node |
667 | */ | 659 | */ |
668 | 660 | ||
669 | out: | ||
670 | rt->u.dst.rt6_next = iter; | 661 | rt->u.dst.rt6_next = iter; |
671 | *ins = rt; | 662 | *ins = rt; |
672 | rt->rt6i_node = fn; | 663 | rt->rt6i_node = fn; |
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index be0ee8a34f9b..30a5cb1b203e 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c | |||
@@ -235,7 +235,7 @@ int ip6_mc_input(struct sk_buff *skb) | |||
235 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS); | 235 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS); |
236 | 236 | ||
237 | hdr = ipv6_hdr(skb); | 237 | hdr = ipv6_hdr(skb); |
238 | deliver = likely(!(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI))) || | 238 | deliver = unlikely(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI)) || |
239 | ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL); | 239 | ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL); |
240 | 240 | ||
241 | /* | 241 | /* |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index f508171bab73..4704b5fc3085 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -463,10 +463,17 @@ int ip6_forward(struct sk_buff *skb) | |||
463 | */ | 463 | */ |
464 | if (xrlim_allow(dst, 1*HZ)) | 464 | if (xrlim_allow(dst, 1*HZ)) |
465 | ndisc_send_redirect(skb, n, target); | 465 | ndisc_send_redirect(skb, n, target); |
466 | } else if (ipv6_addr_type(&hdr->saddr)&(IPV6_ADDR_MULTICAST|IPV6_ADDR_LOOPBACK | 466 | } else { |
467 | |IPV6_ADDR_LINKLOCAL)) { | 467 | int addrtype = ipv6_addr_type(&hdr->saddr); |
468 | |||
468 | /* This check is security critical. */ | 469 | /* This check is security critical. */ |
469 | goto error; | 470 | if (addrtype & (IPV6_ADDR_MULTICAST|IPV6_ADDR_LOOPBACK)) |
471 | goto error; | ||
472 | if (addrtype & IPV6_ADDR_LINKLOCAL) { | ||
473 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, | ||
474 | ICMPV6_NOT_NEIGHBOUR, 0, skb->dev); | ||
475 | goto error; | ||
476 | } | ||
470 | } | 477 | } |
471 | 478 | ||
472 | if (skb->len > dst_mtu(dst)) { | 479 | if (skb->len > dst_mtu(dst)) { |
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index bbe99f842f9f..838b8ddee8c0 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig | |||
@@ -28,7 +28,7 @@ config IP6_NF_QUEUE | |||
28 | packets which enables users to receive the filtered packets | 28 | packets which enables users to receive the filtered packets |
29 | with QUEUE target using libipq. | 29 | with QUEUE target using libipq. |
30 | 30 | ||
31 | THis option enables the old IPv6-only "ip6_queue" implementation | 31 | This option enables the old IPv6-only "ip6_queue" implementation |
32 | which has been obsoleted by the new "nfnetlink_queue" code (see | 32 | which has been obsoleted by the new "nfnetlink_queue" code (see |
33 | CONFIG_NETFILTER_NETLINK_QUEUE). | 33 | CONFIG_NETFILTER_NETLINK_QUEUE). |
34 | 34 | ||
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c index 76f0cf66f95c..7e32e2aaf7f7 100644 --- a/net/ipv6/netfilter/ip6table_filter.c +++ b/net/ipv6/netfilter/ip6table_filter.c | |||
@@ -24,53 +24,29 @@ static struct | |||
24 | struct ip6t_replace repl; | 24 | struct ip6t_replace repl; |
25 | struct ip6t_standard entries[3]; | 25 | struct ip6t_standard entries[3]; |
26 | struct ip6t_error term; | 26 | struct ip6t_error term; |
27 | } initial_table __initdata | 27 | } initial_table __initdata = { |
28 | = { { "filter", FILTER_VALID_HOOKS, 4, | 28 | .repl = { |
29 | sizeof(struct ip6t_standard) * 3 + sizeof(struct ip6t_error), | 29 | .name = "filter", |
30 | { [NF_IP6_LOCAL_IN] = 0, | 30 | .valid_hooks = FILTER_VALID_HOOKS, |
31 | [NF_IP6_FORWARD] = sizeof(struct ip6t_standard), | 31 | .num_entries = 4, |
32 | [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2 }, | 32 | .size = sizeof(struct ip6t_standard) * 3 + sizeof(struct ip6t_error), |
33 | { [NF_IP6_LOCAL_IN] = 0, | 33 | .hook_entry = { |
34 | [NF_IP6_FORWARD] = sizeof(struct ip6t_standard), | 34 | [NF_IP6_LOCAL_IN] = 0, |
35 | [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2 }, | 35 | [NF_IP6_FORWARD] = sizeof(struct ip6t_standard), |
36 | 0, NULL, { } }, | 36 | [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2 |
37 | { | 37 | }, |
38 | /* LOCAL_IN */ | 38 | .underflow = { |
39 | { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | 39 | [NF_IP6_LOCAL_IN] = 0, |
40 | 0, | 40 | [NF_IP6_FORWARD] = sizeof(struct ip6t_standard), |
41 | sizeof(struct ip6t_entry), | 41 | [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2 |
42 | sizeof(struct ip6t_standard), | 42 | }, |
43 | 0, { 0, 0 }, { } }, | 43 | }, |
44 | { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, | 44 | .entries = { |
45 | -NF_ACCEPT - 1 } }, | 45 | IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */ |
46 | /* FORWARD */ | 46 | IP6T_STANDARD_INIT(NF_ACCEPT), /* FORWARD */ |
47 | { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | 47 | IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */ |
48 | 0, | 48 | }, |
49 | sizeof(struct ip6t_entry), | 49 | .term = IP6T_ERROR_INIT, /* ERROR */ |
50 | sizeof(struct ip6t_standard), | ||
51 | 0, { 0, 0 }, { } }, | ||
52 | { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, | ||
53 | -NF_ACCEPT - 1 } }, | ||
54 | /* LOCAL_OUT */ | ||
55 | { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
56 | 0, | ||
57 | sizeof(struct ip6t_entry), | ||
58 | sizeof(struct ip6t_standard), | ||
59 | 0, { 0, 0 }, { } }, | ||
60 | { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, | ||
61 | -NF_ACCEPT - 1 } } | ||
62 | }, | ||
63 | /* ERROR */ | ||
64 | { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
65 | 0, | ||
66 | sizeof(struct ip6t_entry), | ||
67 | sizeof(struct ip6t_error), | ||
68 | 0, { 0, 0 }, { } }, | ||
69 | { { { { IP6T_ALIGN(sizeof(struct ip6t_error_target)), IP6T_ERROR_TARGET } }, | ||
70 | { } }, | ||
71 | "ERROR" | ||
72 | } | ||
73 | } | ||
74 | }; | 50 | }; |
75 | 51 | ||
76 | static struct xt_table packet_filter = { | 52 | static struct xt_table packet_filter = { |
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c index a9f10e32c163..f2d26495f413 100644 --- a/net/ipv6/netfilter/ip6table_mangle.c +++ b/net/ipv6/netfilter/ip6table_mangle.c | |||
@@ -32,73 +32,35 @@ static struct | |||
32 | struct ip6t_replace repl; | 32 | struct ip6t_replace repl; |
33 | struct ip6t_standard entries[5]; | 33 | struct ip6t_standard entries[5]; |
34 | struct ip6t_error term; | 34 | struct ip6t_error term; |
35 | } initial_table __initdata | 35 | } initial_table __initdata = { |
36 | = { { "mangle", MANGLE_VALID_HOOKS, 6, | 36 | .repl = { |
37 | sizeof(struct ip6t_standard) * 5 + sizeof(struct ip6t_error), | 37 | .name = "mangle", |
38 | { [NF_IP6_PRE_ROUTING] = 0, | 38 | .valid_hooks = MANGLE_VALID_HOOKS, |
39 | [NF_IP6_LOCAL_IN] = sizeof(struct ip6t_standard), | 39 | .num_entries = 6, |
40 | [NF_IP6_FORWARD] = sizeof(struct ip6t_standard) * 2, | 40 | .size = sizeof(struct ip6t_standard) * 5 + sizeof(struct ip6t_error), |
41 | [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 3, | 41 | .hook_entry = { |
42 | [NF_IP6_POST_ROUTING] = sizeof(struct ip6t_standard) * 4}, | 42 | [NF_IP6_PRE_ROUTING] = 0, |
43 | { [NF_IP6_PRE_ROUTING] = 0, | 43 | [NF_IP6_LOCAL_IN] = sizeof(struct ip6t_standard), |
44 | [NF_IP6_LOCAL_IN] = sizeof(struct ip6t_standard), | 44 | [NF_IP6_FORWARD] = sizeof(struct ip6t_standard) * 2, |
45 | [NF_IP6_FORWARD] = sizeof(struct ip6t_standard) * 2, | 45 | [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 3, |
46 | [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 3, | 46 | [NF_IP6_POST_ROUTING] = sizeof(struct ip6t_standard) * 4, |
47 | [NF_IP6_POST_ROUTING] = sizeof(struct ip6t_standard) * 4}, | 47 | }, |
48 | 0, NULL, { } }, | 48 | .underflow = { |
49 | { | 49 | [NF_IP6_PRE_ROUTING] = 0, |
50 | /* PRE_ROUTING */ | 50 | [NF_IP6_LOCAL_IN] = sizeof(struct ip6t_standard), |
51 | { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | 51 | [NF_IP6_FORWARD] = sizeof(struct ip6t_standard) * 2, |
52 | 0, | 52 | [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 3, |
53 | sizeof(struct ip6t_entry), | 53 | [NF_IP6_POST_ROUTING] = sizeof(struct ip6t_standard) * 4, |
54 | sizeof(struct ip6t_standard), | 54 | }, |
55 | 0, { 0, 0 }, { } }, | 55 | }, |
56 | { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, | 56 | .entries = { |
57 | -NF_ACCEPT - 1 } }, | 57 | IP6T_STANDARD_INIT(NF_ACCEPT), /* PRE_ROUTING */ |
58 | /* LOCAL_IN */ | 58 | IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */ |
59 | { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | 59 | IP6T_STANDARD_INIT(NF_ACCEPT), /* FORWARD */ |
60 | 0, | 60 | IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */ |
61 | sizeof(struct ip6t_entry), | 61 | IP6T_STANDARD_INIT(NF_ACCEPT), /* POST_ROUTING */ |
62 | sizeof(struct ip6t_standard), | 62 | }, |
63 | 0, { 0, 0 }, { } }, | 63 | .term = IP6T_ERROR_INIT, /* ERROR */ |
64 | { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, | ||
65 | -NF_ACCEPT - 1 } }, | ||
66 | /* FORWARD */ | ||
67 | { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
68 | 0, | ||
69 | sizeof(struct ip6t_entry), | ||
70 | sizeof(struct ip6t_standard), | ||
71 | 0, { 0, 0 }, { } }, | ||
72 | { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, | ||
73 | -NF_ACCEPT - 1 } }, | ||
74 | /* LOCAL_OUT */ | ||
75 | { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
76 | 0, | ||
77 | sizeof(struct ip6t_entry), | ||
78 | sizeof(struct ip6t_standard), | ||
79 | 0, { 0, 0 }, { } }, | ||
80 | { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, | ||
81 | -NF_ACCEPT - 1 } }, | ||
82 | /* POST_ROUTING */ | ||
83 | { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
84 | 0, | ||
85 | sizeof(struct ip6t_entry), | ||
86 | sizeof(struct ip6t_standard), | ||
87 | 0, { 0, 0 }, { } }, | ||
88 | { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, | ||
89 | -NF_ACCEPT - 1 } } | ||
90 | }, | ||
91 | /* ERROR */ | ||
92 | { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
93 | 0, | ||
94 | sizeof(struct ip6t_entry), | ||
95 | sizeof(struct ip6t_error), | ||
96 | 0, { 0, 0 }, { } }, | ||
97 | { { { { IP6T_ALIGN(sizeof(struct ip6t_error_target)), IP6T_ERROR_TARGET } }, | ||
98 | { } }, | ||
99 | "ERROR" | ||
100 | } | ||
101 | } | ||
102 | }; | 64 | }; |
103 | 65 | ||
104 | static struct xt_table packet_mangler = { | 66 | static struct xt_table packet_mangler = { |
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c index a3eb5b8ce18d..0acda45d455d 100644 --- a/net/ipv6/netfilter/ip6table_raw.c +++ b/net/ipv6/netfilter/ip6table_raw.c | |||
@@ -35,56 +35,10 @@ static struct | |||
35 | }, | 35 | }, |
36 | }, | 36 | }, |
37 | .entries = { | 37 | .entries = { |
38 | /* PRE_ROUTING */ | 38 | IP6T_STANDARD_INIT(NF_ACCEPT), /* PRE_ROUTING */ |
39 | { | 39 | IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */ |
40 | .entry = { | ||
41 | .target_offset = sizeof(struct ip6t_entry), | ||
42 | .next_offset = sizeof(struct ip6t_standard), | ||
43 | }, | ||
44 | .target = { | ||
45 | .target = { | ||
46 | .u = { | ||
47 | .target_size = IP6T_ALIGN(sizeof(struct ip6t_standard_target)), | ||
48 | }, | ||
49 | }, | ||
50 | .verdict = -NF_ACCEPT - 1, | ||
51 | }, | ||
52 | }, | ||
53 | |||
54 | /* LOCAL_OUT */ | ||
55 | { | ||
56 | .entry = { | ||
57 | .target_offset = sizeof(struct ip6t_entry), | ||
58 | .next_offset = sizeof(struct ip6t_standard), | ||
59 | }, | ||
60 | .target = { | ||
61 | .target = { | ||
62 | .u = { | ||
63 | .target_size = IP6T_ALIGN(sizeof(struct ip6t_standard_target)), | ||
64 | }, | ||
65 | }, | ||
66 | .verdict = -NF_ACCEPT - 1, | ||
67 | }, | ||
68 | }, | ||
69 | }, | 40 | }, |
70 | /* ERROR */ | 41 | .term = IP6T_ERROR_INIT, /* ERROR */ |
71 | .term = { | ||
72 | .entry = { | ||
73 | .target_offset = sizeof(struct ip6t_entry), | ||
74 | .next_offset = sizeof(struct ip6t_error), | ||
75 | }, | ||
76 | .target = { | ||
77 | .target = { | ||
78 | .u = { | ||
79 | .user = { | ||
80 | .target_size = IP6T_ALIGN(sizeof(struct ip6t_error_target)), | ||
81 | .name = IP6T_ERROR_TARGET, | ||
82 | }, | ||
83 | }, | ||
84 | }, | ||
85 | .errorname = "ERROR", | ||
86 | }, | ||
87 | } | ||
88 | }; | 42 | }; |
89 | 43 | ||
90 | static struct xt_table packet_raw = { | 44 | static struct xt_table packet_raw = { |
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index 6d2a08205111..dc442fb791b0 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | |||
@@ -177,8 +177,7 @@ static unsigned int ipv6_confirm(unsigned int hooknum, | |||
177 | 177 | ||
178 | protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum, | 178 | protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum, |
179 | (*pskb)->len - extoff); | 179 | (*pskb)->len - extoff); |
180 | if (protoff < 0 || protoff > (*pskb)->len || | 180 | if (protoff > (*pskb)->len || pnum == NEXTHDR_FRAGMENT) { |
181 | pnum == NEXTHDR_FRAGMENT) { | ||
182 | DEBUGP("proto header not found\n"); | 181 | DEBUGP("proto header not found\n"); |
183 | return NF_ACCEPT; | 182 | return NF_ACCEPT; |
184 | } | 183 | } |
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index 0be790d250f9..8814b95b2326 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | |||
@@ -168,8 +168,7 @@ icmpv6_error_message(struct sk_buff *skb, | |||
168 | skb->len - inip6off | 168 | skb->len - inip6off |
169 | - sizeof(struct ipv6hdr)); | 169 | - sizeof(struct ipv6hdr)); |
170 | 170 | ||
171 | if ((inprotoff < 0) || (inprotoff > skb->len) || | 171 | if ((inprotoff > skb->len) || (inprotonum == NEXTHDR_FRAGMENT)) { |
172 | (inprotonum == NEXTHDR_FRAGMENT)) { | ||
173 | DEBUGP("icmpv6_error: Can't get protocol header in ICMPv6 payload.\n"); | 172 | DEBUGP("icmpv6_error: Can't get protocol header in ICMPv6 payload.\n"); |
174 | return -NF_ACCEPT; | 173 | return -NF_ACCEPT; |
175 | } | 174 | } |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 009a1047fc3f..a58459a76684 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -818,8 +818,12 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
818 | if (final_p) | 818 | if (final_p) |
819 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 819 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
820 | 820 | ||
821 | if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0) | 821 | if ((err = __xfrm_lookup(&dst, &fl, sk, 1)) < 0) { |
822 | goto out; | 822 | if (err == -EREMOTE) |
823 | err = ip6_dst_blackhole(sk, &dst, &fl); | ||
824 | if (err < 0) | ||
825 | goto out; | ||
826 | } | ||
823 | 827 | ||
824 | if (hlimit < 0) { | 828 | if (hlimit < 0) { |
825 | if (ipv6_addr_is_multicast(&fl.fl6_dst)) | 829 | if (ipv6_addr_is_multicast(&fl.fl6_dst)) |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index b46ad53044ba..1324b06796c0 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -119,6 +119,19 @@ static struct dst_ops ip6_dst_ops = { | |||
119 | .entry_size = sizeof(struct rt6_info), | 119 | .entry_size = sizeof(struct rt6_info), |
120 | }; | 120 | }; |
121 | 121 | ||
122 | static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) | ||
123 | { | ||
124 | } | ||
125 | |||
126 | static struct dst_ops ip6_dst_blackhole_ops = { | ||
127 | .family = AF_INET6, | ||
128 | .protocol = __constant_htons(ETH_P_IPV6), | ||
129 | .destroy = ip6_dst_destroy, | ||
130 | .check = ip6_dst_check, | ||
131 | .update_pmtu = ip6_rt_blackhole_update_pmtu, | ||
132 | .entry_size = sizeof(struct rt6_info), | ||
133 | }; | ||
134 | |||
122 | struct rt6_info ip6_null_entry = { | 135 | struct rt6_info ip6_null_entry = { |
123 | .u = { | 136 | .u = { |
124 | .dst = { | 137 | .dst = { |
@@ -833,6 +846,54 @@ struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl) | |||
833 | 846 | ||
834 | EXPORT_SYMBOL(ip6_route_output); | 847 | EXPORT_SYMBOL(ip6_route_output); |
835 | 848 | ||
849 | static int ip6_blackhole_output(struct sk_buff *skb) | ||
850 | { | ||
851 | kfree_skb(skb); | ||
852 | return 0; | ||
853 | } | ||
854 | |||
855 | int ip6_dst_blackhole(struct sock *sk, struct dst_entry **dstp, struct flowi *fl) | ||
856 | { | ||
857 | struct rt6_info *ort = (struct rt6_info *) *dstp; | ||
858 | struct rt6_info *rt = (struct rt6_info *) | ||
859 | dst_alloc(&ip6_dst_blackhole_ops); | ||
860 | struct dst_entry *new = NULL; | ||
861 | |||
862 | if (rt) { | ||
863 | new = &rt->u.dst; | ||
864 | |||
865 | atomic_set(&new->__refcnt, 1); | ||
866 | new->__use = 1; | ||
867 | new->input = ip6_blackhole_output; | ||
868 | new->output = ip6_blackhole_output; | ||
869 | |||
870 | memcpy(new->metrics, ort->u.dst.metrics, RTAX_MAX*sizeof(u32)); | ||
871 | new->dev = ort->u.dst.dev; | ||
872 | if (new->dev) | ||
873 | dev_hold(new->dev); | ||
874 | rt->rt6i_idev = ort->rt6i_idev; | ||
875 | if (rt->rt6i_idev) | ||
876 | in6_dev_hold(rt->rt6i_idev); | ||
877 | rt->rt6i_expires = 0; | ||
878 | |||
879 | ipv6_addr_copy(&rt->rt6i_gateway, &ort->rt6i_gateway); | ||
880 | rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES; | ||
881 | rt->rt6i_metric = 0; | ||
882 | |||
883 | memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key)); | ||
884 | #ifdef CONFIG_IPV6_SUBTREES | ||
885 | memcpy(&rt->rt6i_src, &ort->rt6i_src, sizeof(struct rt6key)); | ||
886 | #endif | ||
887 | |||
888 | dst_free(new); | ||
889 | } | ||
890 | |||
891 | dst_release(*dstp); | ||
892 | *dstp = new; | ||
893 | return (new ? 0 : -ENOMEM); | ||
894 | } | ||
895 | EXPORT_SYMBOL_GPL(ip6_dst_blackhole); | ||
896 | |||
836 | /* | 897 | /* |
837 | * Destination cache support functions | 898 | * Destination cache support functions |
838 | */ | 899 | */ |
@@ -2495,6 +2556,8 @@ void __init ip6_route_init(void) | |||
2495 | ip6_dst_ops.kmem_cachep = | 2556 | ip6_dst_ops.kmem_cachep = |
2496 | kmem_cache_create("ip6_dst_cache", sizeof(struct rt6_info), 0, | 2557 | kmem_cache_create("ip6_dst_cache", sizeof(struct rt6_info), 0, |
2497 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); | 2558 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); |
2559 | ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops.kmem_cachep; | ||
2560 | |||
2498 | fib6_init(); | 2561 | fib6_init(); |
2499 | #ifdef CONFIG_PROC_FS | 2562 | #ifdef CONFIG_PROC_FS |
2500 | p = proc_net_create("ipv6_route", 0, rt6_proc_info); | 2563 | p = proc_net_create("ipv6_route", 0, rt6_proc_info); |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index e2f25ea43b68..4f06a51ad4fd 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -265,8 +265,12 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
265 | if (final_p) | 265 | if (final_p) |
266 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 266 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
267 | 267 | ||
268 | if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0) | 268 | if ((err = __xfrm_lookup(&dst, &fl, sk, 1)) < 0) { |
269 | goto failure; | 269 | if (err == -EREMOTE) |
270 | err = ip6_dst_blackhole(sk, &dst, &fl); | ||
271 | if (err < 0) | ||
272 | goto failure; | ||
273 | } | ||
270 | 274 | ||
271 | if (saddr == NULL) { | 275 | if (saddr == NULL) { |
272 | saddr = &fl.fl6_src; | 276 | saddr = &fl.fl6_src; |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index b083c09e3d2d..d1fbddd172e7 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -52,9 +52,28 @@ | |||
52 | 52 | ||
53 | DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly; | 53 | DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly; |
54 | 54 | ||
55 | static int ipv6_rcv_saddr_any(const struct sock *sk) | ||
56 | { | ||
57 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
58 | |||
59 | return ipv6_addr_any(&np->rcv_saddr); | ||
60 | } | ||
61 | |||
62 | static unsigned int ipv6_hash_port_and_rcv_saddr(__u16 port, | ||
63 | const struct sock *sk) | ||
64 | { | ||
65 | return port; | ||
66 | } | ||
67 | |||
68 | const struct udp_get_port_ops udp_ipv6_ops = { | ||
69 | .saddr_cmp = ipv6_rcv_saddr_equal, | ||
70 | .saddr_any = ipv6_rcv_saddr_any, | ||
71 | .hash_port_and_rcv_saddr = ipv6_hash_port_and_rcv_saddr, | ||
72 | }; | ||
73 | |||
55 | static inline int udp_v6_get_port(struct sock *sk, unsigned short snum) | 74 | static inline int udp_v6_get_port(struct sock *sk, unsigned short snum) |
56 | { | 75 | { |
57 | return udp_get_port(sk, snum, ipv6_rcv_saddr_equal); | 76 | return udp_get_port(sk, snum, &udp_ipv6_ops); |
58 | } | 77 | } |
59 | 78 | ||
60 | static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport, | 79 | static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport, |
@@ -748,8 +767,12 @@ do_udp_sendmsg: | |||
748 | if (final_p) | 767 | if (final_p) |
749 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 768 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
750 | 769 | ||
751 | if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0) | 770 | if ((err = __xfrm_lookup(&dst, &fl, sk, 1)) < 0) { |
752 | goto out; | 771 | if (err == -EREMOTE) |
772 | err = ip6_dst_blackhole(sk, &dst, &fl); | ||
773 | if (err < 0) | ||
774 | goto out; | ||
775 | } | ||
753 | 776 | ||
754 | if (hlimit < 0) { | 777 | if (hlimit < 0) { |
755 | if (ipv6_addr_is_multicast(&fl.fl6_dst)) | 778 | if (ipv6_addr_is_multicast(&fl.fl6_dst)) |
diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h index 6e252f318f7c..36b0c11a28a3 100644 --- a/net/ipv6/udp_impl.h +++ b/net/ipv6/udp_impl.h | |||
@@ -6,6 +6,8 @@ | |||
6 | #include <net/addrconf.h> | 6 | #include <net/addrconf.h> |
7 | #include <net/inet_common.h> | 7 | #include <net/inet_common.h> |
8 | 8 | ||
9 | extern const struct udp_get_port_ops udp_ipv6_ops; | ||
10 | |||
9 | extern int __udp6_lib_rcv(struct sk_buff **, struct hlist_head [], int ); | 11 | extern int __udp6_lib_rcv(struct sk_buff **, struct hlist_head [], int ); |
10 | extern void __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *, | 12 | extern void __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *, |
11 | int , int , int , __be32 , struct hlist_head []); | 13 | int , int , int , __be32 , struct hlist_head []); |
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c index f54016a55004..c40a51362f89 100644 --- a/net/ipv6/udplite.c +++ b/net/ipv6/udplite.c | |||
@@ -37,7 +37,7 @@ static struct inet6_protocol udplitev6_protocol = { | |||
37 | 37 | ||
38 | static int udplite_v6_get_port(struct sock *sk, unsigned short snum) | 38 | static int udplite_v6_get_port(struct sock *sk, unsigned short snum) |
39 | { | 39 | { |
40 | return udplite_get_port(sk, snum, ipv6_rcv_saddr_equal); | 40 | return udplite_get_port(sk, snum, &udp_ipv6_ops); |
41 | } | 41 | } |
42 | 42 | ||
43 | struct proto udplitev6_prot = { | 43 | struct proto udplitev6_prot = { |
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c index d7ed8aa56ec1..c858537cec4b 100644 --- a/net/ipv6/xfrm6_input.c +++ b/net/ipv6/xfrm6_input.c | |||
@@ -104,10 +104,8 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi) | |||
104 | nf_reset(skb); | 104 | nf_reset(skb); |
105 | 105 | ||
106 | if (decaps) { | 106 | if (decaps) { |
107 | if (!(skb->dev->flags&IFF_LOOPBACK)) { | 107 | dst_release(skb->dst); |
108 | dst_release(skb->dst); | 108 | skb->dst = NULL; |
109 | skb->dst = NULL; | ||
110 | } | ||
111 | netif_rx(skb); | 109 | netif_rx(skb); |
112 | return -1; | 110 | return -1; |
113 | } else { | 111 | } else { |
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c index a6c0cdf46ad6..9fc95bc6509f 100644 --- a/net/ipv6/xfrm6_mode_tunnel.c +++ b/net/ipv6/xfrm6_mode_tunnel.c | |||
@@ -80,6 +80,7 @@ static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) | |||
80 | top_iph->hop_limit = dst_metric(dst->child, RTAX_HOPLIMIT); | 80 | top_iph->hop_limit = dst_metric(dst->child, RTAX_HOPLIMIT); |
81 | ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr); | 81 | ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr); |
82 | ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr); | 82 | ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr); |
83 | skb->protocol = htons(ETH_P_IPV6); | ||
83 | return 0; | 84 | return 0; |
84 | } | 85 | } |
85 | 86 | ||