diff options
| -rw-r--r-- | net/ipv6/ip6_output.c | 49 |
1 files changed, 23 insertions, 26 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 4535b7a0169b..236ac7813744 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
| @@ -82,22 +82,6 @@ int ip6_local_out(struct sk_buff *skb) | |||
| 82 | } | 82 | } |
| 83 | EXPORT_SYMBOL_GPL(ip6_local_out); | 83 | EXPORT_SYMBOL_GPL(ip6_local_out); |
| 84 | 84 | ||
| 85 | static int ip6_output_finish(struct sk_buff *skb) | ||
| 86 | { | ||
| 87 | struct dst_entry *dst = skb_dst(skb); | ||
| 88 | |||
| 89 | if (dst->hh) | ||
| 90 | return neigh_hh_output(dst->hh, skb); | ||
| 91 | else if (dst->neighbour) | ||
| 92 | return dst->neighbour->output(skb); | ||
| 93 | |||
| 94 | IP6_INC_STATS_BH(dev_net(dst->dev), | ||
| 95 | ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); | ||
| 96 | kfree_skb(skb); | ||
| 97 | return -EINVAL; | ||
| 98 | |||
| 99 | } | ||
| 100 | |||
| 101 | /* dev_loopback_xmit for use with netfilter. */ | 85 | /* dev_loopback_xmit for use with netfilter. */ |
| 102 | static int ip6_dev_loopback_xmit(struct sk_buff *newskb) | 86 | static int ip6_dev_loopback_xmit(struct sk_buff *newskb) |
| 103 | { | 87 | { |
| @@ -111,8 +95,7 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb) | |||
| 111 | return 0; | 95 | return 0; |
| 112 | } | 96 | } |
| 113 | 97 | ||
| 114 | 98 | static int ip6_finish_output2(struct sk_buff *skb) | |
| 115 | static int ip6_output2(struct sk_buff *skb) | ||
| 116 | { | 99 | { |
| 117 | struct dst_entry *dst = skb_dst(skb); | 100 | struct dst_entry *dst = skb_dst(skb); |
| 118 | struct net_device *dev = dst->dev; | 101 | struct net_device *dev = dst->dev; |
| @@ -150,8 +133,15 @@ static int ip6_output2(struct sk_buff *skb) | |||
| 150 | skb->len); | 133 | skb->len); |
| 151 | } | 134 | } |
| 152 | 135 | ||
| 153 | return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL, skb->dev, | 136 | if (dst->hh) |
| 154 | ip6_output_finish); | 137 | return neigh_hh_output(dst->hh, skb); |
| 138 | else if (dst->neighbour) | ||
| 139 | return dst->neighbour->output(skb); | ||
| 140 | |||
| 141 | IP6_INC_STATS_BH(dev_net(dst->dev), | ||
| 142 | ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); | ||
| 143 | kfree_skb(skb); | ||
| 144 | return -EINVAL; | ||
| 155 | } | 145 | } |
| 156 | 146 | ||
| 157 | static inline int ip6_skb_dst_mtu(struct sk_buff *skb) | 147 | static inline int ip6_skb_dst_mtu(struct sk_buff *skb) |
| @@ -162,21 +152,28 @@ static inline int ip6_skb_dst_mtu(struct sk_buff *skb) | |||
| 162 | skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb)); | 152 | skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb)); |
| 163 | } | 153 | } |
| 164 | 154 | ||
| 155 | static int ip6_finish_output(struct sk_buff *skb) | ||
| 156 | { | ||
| 157 | if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || | ||
| 158 | dst_allfrag(skb_dst(skb))) | ||
| 159 | return ip6_fragment(skb, ip6_finish_output2); | ||
| 160 | else | ||
| 161 | return ip6_finish_output2(skb); | ||
| 162 | } | ||
| 163 | |||
| 165 | int ip6_output(struct sk_buff *skb) | 164 | int ip6_output(struct sk_buff *skb) |
| 166 | { | 165 | { |
| 166 | struct net_device *dev = skb_dst(skb)->dev; | ||
| 167 | struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); | 167 | struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); |
| 168 | if (unlikely(idev->cnf.disable_ipv6)) { | 168 | if (unlikely(idev->cnf.disable_ipv6)) { |
| 169 | IP6_INC_STATS(dev_net(skb_dst(skb)->dev), idev, | 169 | IP6_INC_STATS(dev_net(dev), idev, |
| 170 | IPSTATS_MIB_OUTDISCARDS); | 170 | IPSTATS_MIB_OUTDISCARDS); |
| 171 | kfree_skb(skb); | 171 | kfree_skb(skb); |
| 172 | return 0; | 172 | return 0; |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || | 175 | return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL, dev, |
| 176 | dst_allfrag(skb_dst(skb))) | 176 | ip6_finish_output); |
| 177 | return ip6_fragment(skb, ip6_output2); | ||
| 178 | else | ||
| 179 | return ip6_output2(skb); | ||
| 180 | } | 177 | } |
| 181 | 178 | ||
| 182 | /* | 179 | /* |
