X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=net%2Fipv4%2Froute.c;h=29ca63e81ced23877fe568573b8522e0ce16d8a1;hb=74235a25c673f80147c1f975304888e8212a14d5;hp=df9fe4f2e8cc5df95fc43c3fe1c271d8d480ac89;hpb=f6c5d736af6bc71cebc017e4001ec5efff1ee116;p=safe%2Fjmp%2Flinux-2.6 diff --git a/net/ipv4/route.c b/net/ipv4/route.c index df9fe4f..29ca63e 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1636,7 +1636,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, atomic_set(&rth->u.dst.__refcnt, 1); rth->u.dst.flags= DST_HOST; - if (in_dev->cnf.no_policy) + if (IN_DEV_CONF_GET(in_dev, NOPOLICY)) rth->u.dst.flags |= DST_NOPOLICY; rth->fl.fl4_dst = daddr; rth->rt_dst = daddr; @@ -1778,9 +1778,9 @@ static inline int __mkroute_input(struct sk_buff *skb, if (res->fi->fib_nhs > 1) rth->u.dst.flags |= DST_BALANCED; #endif - if (in_dev->cnf.no_policy) + if (IN_DEV_CONF_GET(in_dev, NOPOLICY)) rth->u.dst.flags |= DST_NOPOLICY; - if (out_dev->cnf.no_xfrm) + if (IN_DEV_CONF_GET(out_dev, NOXFRM)) rth->u.dst.flags |= DST_NOXFRM; rth->fl.fl4_dst = daddr; rth->rt_dst = daddr; @@ -2021,7 +2021,7 @@ local_input: atomic_set(&rth->u.dst.__refcnt, 1); rth->u.dst.flags= DST_HOST; - if (in_dev->cnf.no_policy) + if (IN_DEV_CONF_GET(in_dev, NOPOLICY)) rth->u.dst.flags |= DST_NOPOLICY; rth->fl.fl4_dst = daddr; rth->rt_dst = daddr; @@ -2218,9 +2218,9 @@ static inline int __mkroute_output(struct rtable **result, rth->u.dst.flags |= DST_BALANCED; } #endif - if (in_dev->cnf.no_xfrm) + if (IN_DEV_CONF_GET(in_dev, NOXFRM)) rth->u.dst.flags |= DST_NOXFRM; - if (in_dev->cnf.no_policy) + if (IN_DEV_CONF_GET(in_dev, NOPOLICY)) rth->u.dst.flags |= DST_NOPOLICY; rth->fl.fl4_dst = oldflp->fl4_dst; @@ -2598,6 +2598,69 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp) EXPORT_SYMBOL_GPL(__ip_route_output_key); +static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) +{ +} + +static struct dst_ops ipv4_dst_blackhole_ops = { + .family = AF_INET, + .protocol = __constant_htons(ETH_P_IP), + .destroy = ipv4_dst_destroy, + .check = ipv4_dst_check, + .update_pmtu = ipv4_rt_blackhole_update_pmtu, + .entry_size = sizeof(struct rtable), +}; + + +static int ipv4_blackhole_output(struct sk_buff *skb) +{ + kfree_skb(skb); + return 0; +} + +static int ipv4_dst_blackhole(struct rtable **rp, struct flowi *flp, struct sock *sk) +{ + struct rtable *ort = *rp; + struct rtable *rt = (struct rtable *) + dst_alloc(&ipv4_dst_blackhole_ops); + + if (rt) { + struct dst_entry *new = &rt->u.dst; + + atomic_set(&new->__refcnt, 1); + new->__use = 1; + new->input = ipv4_blackhole_output; + new->output = ipv4_blackhole_output; + memcpy(new->metrics, ort->u.dst.metrics, RTAX_MAX*sizeof(u32)); + + new->dev = ort->u.dst.dev; + if (new->dev) + dev_hold(new->dev); + + rt->fl = ort->fl; + + rt->idev = ort->idev; + if (rt->idev) + in_dev_hold(rt->idev); + rt->rt_flags = ort->rt_flags; + rt->rt_type = ort->rt_type; + rt->rt_dst = ort->rt_dst; + rt->rt_src = ort->rt_src; + rt->rt_iif = ort->rt_iif; + rt->rt_gateway = ort->rt_gateway; + rt->rt_spec_dst = ort->rt_spec_dst; + rt->peer = ort->peer; + if (rt->peer) + atomic_inc(&rt->peer->refcnt); + + dst_free(new); + } + + dst_release(&(*rp)->u.dst); + *rp = rt; + return (rt ? 0 : -ENOMEM); +} + int ip_route_output_flow(struct rtable **rp, struct flowi *flp, struct sock *sk, int flags) { int err; @@ -2610,7 +2673,11 @@ int ip_route_output_flow(struct rtable **rp, struct flowi *flp, struct sock *sk, flp->fl4_src = (*rp)->rt_src; if (!flp->fl4_dst) flp->fl4_dst = (*rp)->rt_dst; - return xfrm_lookup((struct dst_entry **)rp, flp, sk, flags); + err = __xfrm_lookup((struct dst_entry **)rp, flp, sk, flags); + if (err == -EREMOTE) + err = ipv4_dst_blackhole(rp, flp, sk); + + return err; } return 0; @@ -2692,7 +2759,7 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event, __be32 dst = rt->rt_dst; if (MULTICAST(dst) && !LOCAL_MCAST(dst) && - ipv4_devconf.mc_forwarding) { + IPV4_DEVCONF_ALL(MC_FORWARDING)) { int err = ipmr_get_route(skb, r, nowait); if (err <= 0) { if (!nowait) { @@ -3139,6 +3206,8 @@ int __init ip_rt_init(void) kmem_cache_create("ip_dst_cache", sizeof(struct rtable), 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); + ipv4_dst_blackhole_ops.kmem_cachep = ipv4_dst_ops.kmem_cachep; + rt_hash_table = (struct rt_hash_bucket *) alloc_large_system_hash("IP route cache", sizeof(struct rt_hash_bucket),