diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 2 | ||||
-rw-r--r-- | net/ipv6/icmp.c | 4 | ||||
-rw-r--r-- | net/ipv6/ip6_flowlabel.c | 8 | ||||
-rw-r--r-- | net/ipv6/ip6_input.c | 2 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 67 | ||||
-rw-r--r-- | net/ipv6/ip6_tunnel.c | 2 | ||||
-rw-r--r-- | net/ipv6/ip6mr.c | 24 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 25 | ||||
-rw-r--r-- | net/ipv6/route.c | 2 |
9 files changed, 106 insertions, 30 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index e92ad8455c63..f9afb452249c 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -4250,7 +4250,7 @@ static struct addrconf_sysctl_table | |||
4250 | .procname = "mc_forwarding", | 4250 | .procname = "mc_forwarding", |
4251 | .data = &ipv6_devconf.mc_forwarding, | 4251 | .data = &ipv6_devconf.mc_forwarding, |
4252 | .maxlen = sizeof(int), | 4252 | .maxlen = sizeof(int), |
4253 | .mode = 0644, | 4253 | .mode = 0444, |
4254 | .proc_handler = proc_dointvec, | 4254 | .proc_handler = proc_dointvec, |
4255 | }, | 4255 | }, |
4256 | #endif | 4256 | #endif |
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 4f433847d95f..36dff8807183 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -443,10 +443,10 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, | |||
443 | if (xfrm_decode_session_reverse(skb, &fl2, AF_INET6)) | 443 | if (xfrm_decode_session_reverse(skb, &fl2, AF_INET6)) |
444 | goto relookup_failed; | 444 | goto relookup_failed; |
445 | 445 | ||
446 | if (ip6_dst_lookup(sk, &dst2, &fl)) | 446 | if (ip6_dst_lookup(sk, &dst2, &fl2)) |
447 | goto relookup_failed; | 447 | goto relookup_failed; |
448 | 448 | ||
449 | err = xfrm_lookup(net, &dst2, &fl, sk, XFRM_LOOKUP_ICMP); | 449 | err = xfrm_lookup(net, &dst2, &fl2, sk, XFRM_LOOKUP_ICMP); |
450 | switch (err) { | 450 | switch (err) { |
451 | case 0: | 451 | case 0: |
452 | dst_release(dst); | 452 | dst_release(dst); |
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index c62dd247774f..7712578bdc66 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c | |||
@@ -323,17 +323,21 @@ static struct ip6_flowlabel * | |||
323 | fl_create(struct net *net, struct in6_flowlabel_req *freq, char __user *optval, | 323 | fl_create(struct net *net, struct in6_flowlabel_req *freq, char __user *optval, |
324 | int optlen, int *err_p) | 324 | int optlen, int *err_p) |
325 | { | 325 | { |
326 | struct ip6_flowlabel *fl; | 326 | struct ip6_flowlabel *fl = NULL; |
327 | int olen; | 327 | int olen; |
328 | int addr_type; | 328 | int addr_type; |
329 | int err; | 329 | int err; |
330 | 330 | ||
331 | olen = optlen - CMSG_ALIGN(sizeof(*freq)); | ||
332 | err = -EINVAL; | ||
333 | if (olen > 64 * 1024) | ||
334 | goto done; | ||
335 | |||
331 | err = -ENOMEM; | 336 | err = -ENOMEM; |
332 | fl = kzalloc(sizeof(*fl), GFP_KERNEL); | 337 | fl = kzalloc(sizeof(*fl), GFP_KERNEL); |
333 | if (fl == NULL) | 338 | if (fl == NULL) |
334 | goto done; | 339 | goto done; |
335 | 340 | ||
336 | olen = optlen - CMSG_ALIGN(sizeof(*freq)); | ||
337 | if (olen > 0) { | 341 | if (olen > 0) { |
338 | struct msghdr msg; | 342 | struct msghdr msg; |
339 | struct flowi flowi; | 343 | struct flowi flowi; |
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index 936f48946e20..f171e8dbac91 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c | |||
@@ -255,6 +255,7 @@ int ip6_mc_input(struct sk_buff *skb) | |||
255 | * IPv6 multicast router mode is now supported ;) | 255 | * IPv6 multicast router mode is now supported ;) |
256 | */ | 256 | */ |
257 | if (dev_net(skb->dev)->ipv6.devconf_all->mc_forwarding && | 257 | if (dev_net(skb->dev)->ipv6.devconf_all->mc_forwarding && |
258 | !(ipv6_addr_type(&hdr->daddr) & IPV6_ADDR_LINKLOCAL) && | ||
258 | likely(!(IP6CB(skb)->flags & IP6SKB_FORWARDED))) { | 259 | likely(!(IP6CB(skb)->flags & IP6SKB_FORWARDED))) { |
259 | /* | 260 | /* |
260 | * Okay, we try to forward - split and duplicate | 261 | * Okay, we try to forward - split and duplicate |
@@ -316,7 +317,6 @@ int ip6_mc_input(struct sk_buff *skb) | |||
316 | } | 317 | } |
317 | 318 | ||
318 | if (skb2) { | 319 | if (skb2) { |
319 | skb2->dev = skb2->dst->dev; | ||
320 | ip6_mr_input(skb2); | 320 | ip6_mr_input(skb2); |
321 | } | 321 | } |
322 | } | 322 | } |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 4b15938bef4d..9fb49c3b518a 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -1105,6 +1105,18 @@ static inline int ip6_ufo_append_data(struct sock *sk, | |||
1105 | return err; | 1105 | return err; |
1106 | } | 1106 | } |
1107 | 1107 | ||
1108 | static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src, | ||
1109 | gfp_t gfp) | ||
1110 | { | ||
1111 | return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL; | ||
1112 | } | ||
1113 | |||
1114 | static inline struct ipv6_rt_hdr *ip6_rthdr_dup(struct ipv6_rt_hdr *src, | ||
1115 | gfp_t gfp) | ||
1116 | { | ||
1117 | return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL; | ||
1118 | } | ||
1119 | |||
1108 | int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | 1120 | int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, |
1109 | int offset, int len, int odd, struct sk_buff *skb), | 1121 | int offset, int len, int odd, struct sk_buff *skb), |
1110 | void *from, int length, int transhdrlen, | 1122 | void *from, int length, int transhdrlen, |
@@ -1130,17 +1142,37 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1130 | * setup for corking | 1142 | * setup for corking |
1131 | */ | 1143 | */ |
1132 | if (opt) { | 1144 | if (opt) { |
1133 | if (np->cork.opt == NULL) { | 1145 | if (WARN_ON(np->cork.opt)) |
1134 | np->cork.opt = kmalloc(opt->tot_len, | ||
1135 | sk->sk_allocation); | ||
1136 | if (unlikely(np->cork.opt == NULL)) | ||
1137 | return -ENOBUFS; | ||
1138 | } else if (np->cork.opt->tot_len < opt->tot_len) { | ||
1139 | printk(KERN_DEBUG "ip6_append_data: invalid option length\n"); | ||
1140 | return -EINVAL; | 1146 | return -EINVAL; |
1141 | } | 1147 | |
1142 | memcpy(np->cork.opt, opt, opt->tot_len); | 1148 | np->cork.opt = kmalloc(opt->tot_len, sk->sk_allocation); |
1143 | inet->cork.flags |= IPCORK_OPT; | 1149 | if (unlikely(np->cork.opt == NULL)) |
1150 | return -ENOBUFS; | ||
1151 | |||
1152 | np->cork.opt->tot_len = opt->tot_len; | ||
1153 | np->cork.opt->opt_flen = opt->opt_flen; | ||
1154 | np->cork.opt->opt_nflen = opt->opt_nflen; | ||
1155 | |||
1156 | np->cork.opt->dst0opt = ip6_opt_dup(opt->dst0opt, | ||
1157 | sk->sk_allocation); | ||
1158 | if (opt->dst0opt && !np->cork.opt->dst0opt) | ||
1159 | return -ENOBUFS; | ||
1160 | |||
1161 | np->cork.opt->dst1opt = ip6_opt_dup(opt->dst1opt, | ||
1162 | sk->sk_allocation); | ||
1163 | if (opt->dst1opt && !np->cork.opt->dst1opt) | ||
1164 | return -ENOBUFS; | ||
1165 | |||
1166 | np->cork.opt->hopopt = ip6_opt_dup(opt->hopopt, | ||
1167 | sk->sk_allocation); | ||
1168 | if (opt->hopopt && !np->cork.opt->hopopt) | ||
1169 | return -ENOBUFS; | ||
1170 | |||
1171 | np->cork.opt->srcrt = ip6_rthdr_dup(opt->srcrt, | ||
1172 | sk->sk_allocation); | ||
1173 | if (opt->srcrt && !np->cork.opt->srcrt) | ||
1174 | return -ENOBUFS; | ||
1175 | |||
1144 | /* need source address above miyazawa*/ | 1176 | /* need source address above miyazawa*/ |
1145 | } | 1177 | } |
1146 | dst_hold(&rt->u.dst); | 1178 | dst_hold(&rt->u.dst); |
@@ -1167,8 +1199,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1167 | } else { | 1199 | } else { |
1168 | rt = (struct rt6_info *)inet->cork.dst; | 1200 | rt = (struct rt6_info *)inet->cork.dst; |
1169 | fl = &inet->cork.fl; | 1201 | fl = &inet->cork.fl; |
1170 | if (inet->cork.flags & IPCORK_OPT) | 1202 | opt = np->cork.opt; |
1171 | opt = np->cork.opt; | ||
1172 | transhdrlen = 0; | 1203 | transhdrlen = 0; |
1173 | exthdrlen = 0; | 1204 | exthdrlen = 0; |
1174 | mtu = inet->cork.fragsize; | 1205 | mtu = inet->cork.fragsize; |
@@ -1407,9 +1438,15 @@ error: | |||
1407 | 1438 | ||
1408 | static void ip6_cork_release(struct inet_sock *inet, struct ipv6_pinfo *np) | 1439 | static void ip6_cork_release(struct inet_sock *inet, struct ipv6_pinfo *np) |
1409 | { | 1440 | { |
1410 | inet->cork.flags &= ~IPCORK_OPT; | 1441 | if (np->cork.opt) { |
1411 | kfree(np->cork.opt); | 1442 | kfree(np->cork.opt->dst0opt); |
1412 | np->cork.opt = NULL; | 1443 | kfree(np->cork.opt->dst1opt); |
1444 | kfree(np->cork.opt->hopopt); | ||
1445 | kfree(np->cork.opt->srcrt); | ||
1446 | kfree(np->cork.opt); | ||
1447 | np->cork.opt = NULL; | ||
1448 | } | ||
1449 | |||
1413 | if (inet->cork.dst) { | 1450 | if (inet->cork.dst) { |
1414 | dst_release(inet->cork.dst); | 1451 | dst_release(inet->cork.dst); |
1415 | inet->cork.dst = NULL; | 1452 | inet->cork.dst = NULL; |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 58e2b0d93758..d994c55a5b16 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -249,8 +249,8 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct ip6_tnl_parm *p) | |||
249 | } | 249 | } |
250 | 250 | ||
251 | t = netdev_priv(dev); | 251 | t = netdev_priv(dev); |
252 | ip6_tnl_dev_init(dev); | ||
253 | t->parms = *p; | 252 | t->parms = *p; |
253 | ip6_tnl_dev_init(dev); | ||
254 | 254 | ||
255 | if ((err = register_netdevice(dev)) < 0) | 255 | if ((err = register_netdevice(dev)) < 0) |
256 | goto failed_free; | 256 | goto failed_free; |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 3c51b2d827f4..228be551e9c1 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include <linux/pim.h> | 48 | #include <linux/pim.h> |
49 | #include <net/addrconf.h> | 49 | #include <net/addrconf.h> |
50 | #include <linux/netfilter_ipv6.h> | 50 | #include <linux/netfilter_ipv6.h> |
51 | #include <net/ip6_checksum.h> | ||
51 | 52 | ||
52 | /* Big lock, protecting vif table, mrt cache and mroute socket state. | 53 | /* Big lock, protecting vif table, mrt cache and mroute socket state. |
53 | Note that the changes are semaphored via rtnl_lock. | 54 | Note that the changes are semaphored via rtnl_lock. |
@@ -365,7 +366,9 @@ static int pim6_rcv(struct sk_buff *skb) | |||
365 | pim = (struct pimreghdr *)skb_transport_header(skb); | 366 | pim = (struct pimreghdr *)skb_transport_header(skb); |
366 | if (pim->type != ((PIM_VERSION << 4) | PIM_REGISTER) || | 367 | if (pim->type != ((PIM_VERSION << 4) | PIM_REGISTER) || |
367 | (pim->flags & PIM_NULL_REGISTER) || | 368 | (pim->flags & PIM_NULL_REGISTER) || |
368 | (ip_compute_csum((void *)pim, sizeof(*pim)) != 0 && | 369 | (csum_ipv6_magic(&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, |
370 | sizeof(*pim), IPPROTO_PIM, | ||
371 | csum_partial((void *)pim, sizeof(*pim), 0)) && | ||
369 | csum_fold(skb_checksum(skb, 0, skb->len, 0)))) | 372 | csum_fold(skb_checksum(skb, 0, skb->len, 0)))) |
370 | goto drop; | 373 | goto drop; |
371 | 374 | ||
@@ -392,7 +395,7 @@ static int pim6_rcv(struct sk_buff *skb) | |||
392 | skb_pull(skb, (u8 *)encap - skb->data); | 395 | skb_pull(skb, (u8 *)encap - skb->data); |
393 | skb_reset_network_header(skb); | 396 | skb_reset_network_header(skb); |
394 | skb->dev = reg_dev; | 397 | skb->dev = reg_dev; |
395 | skb->protocol = htons(ETH_P_IP); | 398 | skb->protocol = htons(ETH_P_IPV6); |
396 | skb->ip_summed = 0; | 399 | skb->ip_summed = 0; |
397 | skb->pkt_type = PACKET_HOST; | 400 | skb->pkt_type = PACKET_HOST; |
398 | dst_release(skb->dst); | 401 | dst_release(skb->dst); |
@@ -481,6 +484,7 @@ static int mif6_delete(struct net *net, int vifi) | |||
481 | { | 484 | { |
482 | struct mif_device *v; | 485 | struct mif_device *v; |
483 | struct net_device *dev; | 486 | struct net_device *dev; |
487 | struct inet6_dev *in6_dev; | ||
484 | if (vifi < 0 || vifi >= net->ipv6.maxvif) | 488 | if (vifi < 0 || vifi >= net->ipv6.maxvif) |
485 | return -EADDRNOTAVAIL; | 489 | return -EADDRNOTAVAIL; |
486 | 490 | ||
@@ -513,6 +517,10 @@ static int mif6_delete(struct net *net, int vifi) | |||
513 | 517 | ||
514 | dev_set_allmulti(dev, -1); | 518 | dev_set_allmulti(dev, -1); |
515 | 519 | ||
520 | in6_dev = __in6_dev_get(dev); | ||
521 | if (in6_dev) | ||
522 | in6_dev->cnf.mc_forwarding--; | ||
523 | |||
516 | if (v->flags & MIFF_REGISTER) | 524 | if (v->flags & MIFF_REGISTER) |
517 | unregister_netdevice(dev); | 525 | unregister_netdevice(dev); |
518 | 526 | ||
@@ -622,6 +630,7 @@ static int mif6_add(struct net *net, struct mif6ctl *vifc, int mrtsock) | |||
622 | int vifi = vifc->mif6c_mifi; | 630 | int vifi = vifc->mif6c_mifi; |
623 | struct mif_device *v = &net->ipv6.vif6_table[vifi]; | 631 | struct mif_device *v = &net->ipv6.vif6_table[vifi]; |
624 | struct net_device *dev; | 632 | struct net_device *dev; |
633 | struct inet6_dev *in6_dev; | ||
625 | int err; | 634 | int err; |
626 | 635 | ||
627 | /* Is vif busy ? */ | 636 | /* Is vif busy ? */ |
@@ -662,6 +671,10 @@ static int mif6_add(struct net *net, struct mif6ctl *vifc, int mrtsock) | |||
662 | return -EINVAL; | 671 | return -EINVAL; |
663 | } | 672 | } |
664 | 673 | ||
674 | in6_dev = __in6_dev_get(dev); | ||
675 | if (in6_dev) | ||
676 | in6_dev->cnf.mc_forwarding++; | ||
677 | |||
665 | /* | 678 | /* |
666 | * Fill in the VIF structures | 679 | * Fill in the VIF structures |
667 | */ | 680 | */ |
@@ -838,8 +851,6 @@ static int ip6mr_cache_report(struct net *net, struct sk_buff *pkt, mifi_t mifi, | |||
838 | 851 | ||
839 | skb->dst = dst_clone(pkt->dst); | 852 | skb->dst = dst_clone(pkt->dst); |
840 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 853 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
841 | |||
842 | skb_pull(skb, sizeof(struct ipv6hdr)); | ||
843 | } | 854 | } |
844 | 855 | ||
845 | if (net->ipv6.mroute6_sk == NULL) { | 856 | if (net->ipv6.mroute6_sk == NULL) { |
@@ -1222,8 +1233,10 @@ static int ip6mr_sk_init(struct sock *sk) | |||
1222 | 1233 | ||
1223 | rtnl_lock(); | 1234 | rtnl_lock(); |
1224 | write_lock_bh(&mrt_lock); | 1235 | write_lock_bh(&mrt_lock); |
1225 | if (likely(net->ipv6.mroute6_sk == NULL)) | 1236 | if (likely(net->ipv6.mroute6_sk == NULL)) { |
1226 | net->ipv6.mroute6_sk = sk; | 1237 | net->ipv6.mroute6_sk = sk; |
1238 | net->ipv6.devconf_all->mc_forwarding++; | ||
1239 | } | ||
1227 | else | 1240 | else |
1228 | err = -EADDRINUSE; | 1241 | err = -EADDRINUSE; |
1229 | write_unlock_bh(&mrt_lock); | 1242 | write_unlock_bh(&mrt_lock); |
@@ -1242,6 +1255,7 @@ int ip6mr_sk_done(struct sock *sk) | |||
1242 | if (sk == net->ipv6.mroute6_sk) { | 1255 | if (sk == net->ipv6.mroute6_sk) { |
1243 | write_lock_bh(&mrt_lock); | 1256 | write_lock_bh(&mrt_lock); |
1244 | net->ipv6.mroute6_sk = NULL; | 1257 | net->ipv6.mroute6_sk = NULL; |
1258 | net->ipv6.devconf_all->mc_forwarding--; | ||
1245 | write_unlock_bh(&mrt_lock); | 1259 | write_unlock_bh(&mrt_lock); |
1246 | 1260 | ||
1247 | mroute_clean_tables(net); | 1261 | mroute_clean_tables(net); |
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index c455cf4ee756..c323643ffcf9 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | |||
@@ -49,8 +49,19 @@ static bool icmpv6_pkt_to_tuple(const struct sk_buff *skb, | |||
49 | static const u_int8_t invmap[] = { | 49 | static const u_int8_t invmap[] = { |
50 | [ICMPV6_ECHO_REQUEST - 128] = ICMPV6_ECHO_REPLY + 1, | 50 | [ICMPV6_ECHO_REQUEST - 128] = ICMPV6_ECHO_REPLY + 1, |
51 | [ICMPV6_ECHO_REPLY - 128] = ICMPV6_ECHO_REQUEST + 1, | 51 | [ICMPV6_ECHO_REPLY - 128] = ICMPV6_ECHO_REQUEST + 1, |
52 | [ICMPV6_NI_QUERY - 128] = ICMPV6_NI_QUERY + 1, | 52 | [ICMPV6_NI_QUERY - 128] = ICMPV6_NI_REPLY + 1, |
53 | [ICMPV6_NI_REPLY - 128] = ICMPV6_NI_REPLY +1 | 53 | [ICMPV6_NI_REPLY - 128] = ICMPV6_NI_QUERY +1 |
54 | }; | ||
55 | |||
56 | static const u_int8_t noct_valid_new[] = { | ||
57 | [ICMPV6_MGM_QUERY - 130] = 1, | ||
58 | [ICMPV6_MGM_REPORT -130] = 1, | ||
59 | [ICMPV6_MGM_REDUCTION - 130] = 1, | ||
60 | [NDISC_ROUTER_SOLICITATION - 130] = 1, | ||
61 | [NDISC_ROUTER_ADVERTISEMENT - 130] = 1, | ||
62 | [NDISC_NEIGHBOUR_SOLICITATION - 130] = 1, | ||
63 | [NDISC_NEIGHBOUR_ADVERTISEMENT - 130] = 1, | ||
64 | [ICMPV6_MLD2_REPORT - 130] = 1 | ||
54 | }; | 65 | }; |
55 | 66 | ||
56 | static bool icmpv6_invert_tuple(struct nf_conntrack_tuple *tuple, | 67 | static bool icmpv6_invert_tuple(struct nf_conntrack_tuple *tuple, |
@@ -178,6 +189,7 @@ icmpv6_error(struct net *net, struct sk_buff *skb, unsigned int dataoff, | |||
178 | { | 189 | { |
179 | const struct icmp6hdr *icmp6h; | 190 | const struct icmp6hdr *icmp6h; |
180 | struct icmp6hdr _ih; | 191 | struct icmp6hdr _ih; |
192 | int type; | ||
181 | 193 | ||
182 | icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih); | 194 | icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih); |
183 | if (icmp6h == NULL) { | 195 | if (icmp6h == NULL) { |
@@ -194,6 +206,15 @@ icmpv6_error(struct net *net, struct sk_buff *skb, unsigned int dataoff, | |||
194 | return -NF_ACCEPT; | 206 | return -NF_ACCEPT; |
195 | } | 207 | } |
196 | 208 | ||
209 | type = icmp6h->icmp6_type - 130; | ||
210 | if (type >= 0 && type < sizeof(noct_valid_new) && | ||
211 | noct_valid_new[type]) { | ||
212 | skb->nfct = &nf_conntrack_untracked.ct_general; | ||
213 | skb->nfctinfo = IP_CT_NEW; | ||
214 | nf_conntrack_get(skb->nfct); | ||
215 | return NF_ACCEPT; | ||
216 | } | ||
217 | |||
197 | /* is not error message ? */ | 218 | /* is not error message ? */ |
198 | if (icmp6h->icmp6_type >= 128) | 219 | if (icmp6h->icmp6_type >= 128) |
199 | return NF_ACCEPT; | 220 | return NF_ACCEPT; |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index c4a59824ac2c..9c574235c905 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -794,7 +794,7 @@ void ip6_route_input(struct sk_buff *skb) | |||
794 | .proto = iph->nexthdr, | 794 | .proto = iph->nexthdr, |
795 | }; | 795 | }; |
796 | 796 | ||
797 | if (rt6_need_strict(&iph->daddr)) | 797 | if (rt6_need_strict(&iph->daddr) && skb->dev->type != ARPHRD_PIMREG) |
798 | flags |= RT6_LOOKUP_F_IFACE; | 798 | flags |= RT6_LOOKUP_F_IFACE; |
799 | 799 | ||
800 | skb->dst = fib6_rule_lookup(net, &fl, flags, ip6_pol_route_input); | 800 | skb->dst = fib6_rule_lookup(net, &fl, flags, ip6_pol_route_input); |