diff options
Diffstat (limited to 'net/ipv6/ip6_output.c')
-rw-r--r-- | net/ipv6/ip6_output.c | 54 |
1 files changed, 6 insertions, 48 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index ae652ca14bc9..01ef94f7c7f1 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -153,51 +153,6 @@ int ip6_output(struct sk_buff *skb) | |||
153 | return ip6_output2(skb); | 153 | return ip6_output2(skb); |
154 | } | 154 | } |
155 | 155 | ||
156 | #ifdef CONFIG_NETFILTER | ||
157 | int ip6_route_me_harder(struct sk_buff *skb) | ||
158 | { | ||
159 | struct ipv6hdr *iph = skb->nh.ipv6h; | ||
160 | struct dst_entry *dst; | ||
161 | struct flowi fl = { | ||
162 | .oif = skb->sk ? skb->sk->sk_bound_dev_if : 0, | ||
163 | .nl_u = | ||
164 | { .ip6_u = | ||
165 | { .daddr = iph->daddr, | ||
166 | .saddr = iph->saddr, } }, | ||
167 | .proto = iph->nexthdr, | ||
168 | }; | ||
169 | |||
170 | dst = ip6_route_output(skb->sk, &fl); | ||
171 | |||
172 | if (dst->error) { | ||
173 | IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES); | ||
174 | LIMIT_NETDEBUG( | ||
175 | printk(KERN_DEBUG "ip6_route_me_harder: No more route.\n")); | ||
176 | dst_release(dst); | ||
177 | return -EINVAL; | ||
178 | } | ||
179 | |||
180 | /* Drop old route. */ | ||
181 | dst_release(skb->dst); | ||
182 | |||
183 | skb->dst = dst; | ||
184 | return 0; | ||
185 | } | ||
186 | #endif | ||
187 | |||
188 | static inline int ip6_maybe_reroute(struct sk_buff *skb) | ||
189 | { | ||
190 | #ifdef CONFIG_NETFILTER | ||
191 | if (skb->nfcache & NFC_ALTERED){ | ||
192 | if (ip6_route_me_harder(skb) != 0){ | ||
193 | kfree_skb(skb); | ||
194 | return -EINVAL; | ||
195 | } | ||
196 | } | ||
197 | #endif /* CONFIG_NETFILTER */ | ||
198 | return dst_output(skb); | ||
199 | } | ||
200 | |||
201 | /* | 156 | /* |
202 | * xmit an sk_buff (used by TCP) | 157 | * xmit an sk_buff (used by TCP) |
203 | */ | 158 | */ |
@@ -266,7 +221,8 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | |||
266 | mtu = dst_mtu(dst); | 221 | mtu = dst_mtu(dst); |
267 | if ((skb->len <= mtu) || ipfragok) { | 222 | if ((skb->len <= mtu) || ipfragok) { |
268 | IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); | 223 | IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); |
269 | return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute); | 224 | return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, |
225 | dst_output); | ||
270 | } | 226 | } |
271 | 227 | ||
272 | if (net_ratelimit()) | 228 | if (net_ratelimit()) |
@@ -321,7 +277,9 @@ static int ip6_call_ra_chain(struct sk_buff *skb, int sel) | |||
321 | read_lock(&ip6_ra_lock); | 277 | read_lock(&ip6_ra_lock); |
322 | for (ra = ip6_ra_chain; ra; ra = ra->next) { | 278 | for (ra = ip6_ra_chain; ra; ra = ra->next) { |
323 | struct sock *sk = ra->sk; | 279 | struct sock *sk = ra->sk; |
324 | if (sk && ra->sel == sel) { | 280 | if (sk && ra->sel == sel && |
281 | (!sk->sk_bound_dev_if || | ||
282 | sk->sk_bound_dev_if == skb->dev->ifindex)) { | ||
325 | if (last) { | 283 | if (last) { |
326 | struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); | 284 | struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); |
327 | if (skb2) | 285 | if (skb2) |
@@ -667,7 +625,7 @@ slow_path: | |||
667 | */ | 625 | */ |
668 | 626 | ||
669 | if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) { | 627 | if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) { |
670 | NETDEBUG(printk(KERN_INFO "IPv6: frag: no memory for new fragment!\n")); | 628 | NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n"); |
671 | IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS); | 629 | IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS); |
672 | err = -ENOMEM; | 630 | err = -ENOMEM; |
673 | goto fail; | 631 | goto fail; |