diff options
Diffstat (limited to 'net/ipv6/ip6_output.c')
-rw-r--r-- | net/ipv6/ip6_output.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 48cdce9c696c..6407c64ea4a5 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -5,8 +5,6 @@ | |||
5 | * Authors: | 5 | * Authors: |
6 | * Pedro Roque <roque@di.fc.ul.pt> | 6 | * Pedro Roque <roque@di.fc.ul.pt> |
7 | * | 7 | * |
8 | * $Id: ip6_output.c,v 1.34 2002/02/01 22:01:04 davem Exp $ | ||
9 | * | ||
10 | * Based on linux/net/ipv4/ip_output.c | 8 | * Based on linux/net/ipv4/ip_output.c |
11 | * | 9 | * |
12 | * This program is free software; you can redistribute it and/or | 10 | * This program is free software; you can redistribute it and/or |
@@ -175,6 +173,13 @@ static inline int ip6_skb_dst_mtu(struct sk_buff *skb) | |||
175 | 173 | ||
176 | int ip6_output(struct sk_buff *skb) | 174 | int ip6_output(struct sk_buff *skb) |
177 | { | 175 | { |
176 | struct inet6_dev *idev = ip6_dst_idev(skb->dst); | ||
177 | if (unlikely(idev->cnf.disable_ipv6)) { | ||
178 | IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS); | ||
179 | kfree_skb(skb); | ||
180 | return 0; | ||
181 | } | ||
182 | |||
178 | if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || | 183 | if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || |
179 | dst_allfrag(skb->dst)) | 184 | dst_allfrag(skb->dst)) |
180 | return ip6_fragment(skb, ip6_output2); | 185 | return ip6_fragment(skb, ip6_output2); |
@@ -406,9 +411,12 @@ int ip6_forward(struct sk_buff *skb) | |||
406 | struct inet6_skb_parm *opt = IP6CB(skb); | 411 | struct inet6_skb_parm *opt = IP6CB(skb); |
407 | struct net *net = dev_net(dst->dev); | 412 | struct net *net = dev_net(dst->dev); |
408 | 413 | ||
409 | if (ipv6_devconf.forwarding == 0) | 414 | if (net->ipv6.devconf_all->forwarding == 0) |
410 | goto error; | 415 | goto error; |
411 | 416 | ||
417 | if (skb_warn_if_lro(skb)) | ||
418 | goto drop; | ||
419 | |||
412 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) { | 420 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) { |
413 | IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); | 421 | IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); |
414 | goto drop; | 422 | goto drop; |
@@ -450,7 +458,7 @@ int ip6_forward(struct sk_buff *skb) | |||
450 | } | 458 | } |
451 | 459 | ||
452 | /* XXX: idev->cnf.proxy_ndp? */ | 460 | /* XXX: idev->cnf.proxy_ndp? */ |
453 | if (ipv6_devconf.proxy_ndp && | 461 | if (net->ipv6.devconf_all->proxy_ndp && |
454 | pneigh_lookup(&nd_tbl, net, &hdr->daddr, skb->dev, 0)) { | 462 | pneigh_lookup(&nd_tbl, net, &hdr->daddr, skb->dev, 0)) { |
455 | int proxied = ip6_forward_proxy_check(skb); | 463 | int proxied = ip6_forward_proxy_check(skb); |
456 | if (proxied > 0) | 464 | if (proxied > 0) |
@@ -497,7 +505,8 @@ int ip6_forward(struct sk_buff *skb) | |||
497 | int addrtype = ipv6_addr_type(&hdr->saddr); | 505 | int addrtype = ipv6_addr_type(&hdr->saddr); |
498 | 506 | ||
499 | /* This check is security critical. */ | 507 | /* This check is security critical. */ |
500 | if (addrtype & (IPV6_ADDR_MULTICAST|IPV6_ADDR_LOOPBACK)) | 508 | if (addrtype == IPV6_ADDR_ANY || |
509 | addrtype & (IPV6_ADDR_MULTICAST | IPV6_ADDR_LOOPBACK)) | ||
501 | goto error; | 510 | goto error; |
502 | if (addrtype & IPV6_ADDR_LINKLOCAL) { | 511 | if (addrtype & IPV6_ADDR_LINKLOCAL) { |
503 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, | 512 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, |