X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv6%2Fip6_fib.c;h=1816b81ae4543b9fc2e652484415f74015899901;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=65a137241777e61d328f0ae0e1af20f58446f609;hpb=a2c21200f1c81b08cb55e417b68150bba439b646;p=linux-2.6.git diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 65a137241..1816b81ae 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -449,9 +449,10 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, * Same priority level */ - if ((iter->rt6i_dev == rt->rt6i_dev) && - (ipv6_addr_cmp(&iter->rt6i_gateway, - &rt->rt6i_gateway) == 0)) { + if (iter->rt6i_dev == rt->rt6i_dev && + iter->rt6i_idev == rt->rt6i_idev && + ipv6_addr_cmp(&iter->rt6i_gateway, + &rt->rt6i_gateway) == 0) { if (!(iter->rt6i_flags&RTF_EXPIRES)) return -EEXIST; iter->rt6i_expires = rt->rt6i_expires; @@ -514,7 +515,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nlmsghdr *nlh, int err = -ENOMEM; fn = fib6_add_1(root, &rt->rt6i_dst.addr, sizeof(struct in6_addr), - rt->rt6i_dst.plen, (u8*) &rt->rt6i_dst - (u8*) rt); + rt->rt6i_dst.plen, offsetof(struct rt6_info, rt6i_dst)); if (fn == NULL) goto out; @@ -550,7 +551,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nlmsghdr *nlh, sn = fib6_add_1(sfn, &rt->rt6i_src.addr, sizeof(struct in6_addr), rt->rt6i_src.plen, - (u8*) &rt->rt6i_src - (u8*) rt); + offsetof(struct rt6_info, rt6i_src)); if (sn == NULL) { /* If it is failed, discard just allocated @@ -571,7 +572,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nlmsghdr *nlh, } else { sn = fib6_add_1(fn->subtree, &rt->rt6i_src.addr, sizeof(struct in6_addr), rt->rt6i_src.plen, - (u8*) &rt->rt6i_src - (u8*) rt); + offsetof(struct rt6_info, rt6i_src)); if (sn == NULL) goto st_failure; @@ -680,14 +681,13 @@ struct fib6_node * fib6_lookup(struct fib6_node *root, struct in6_addr *daddr, struct in6_addr *saddr) { struct lookup_args args[2]; - struct rt6_info *rt = NULL; struct fib6_node *fn; - args[0].offset = (u8*) &rt->rt6i_dst - (u8*) rt; + args[0].offset = offsetof(struct rt6_info, rt6i_dst); args[0].addr = daddr; #ifdef CONFIG_IPV6_SUBTREES - args[1].offset = (u8*) &rt->rt6i_src - (u8*) rt; + args[1].offset = offsetof(struct rt6_info, rt6i_src); args[1].addr = saddr; #endif @@ -739,11 +739,10 @@ struct fib6_node * fib6_locate(struct fib6_node *root, struct in6_addr *daddr, int dst_len, struct in6_addr *saddr, int src_len) { - struct rt6_info *rt = NULL; struct fib6_node *fn; fn = fib6_locate_1(root, daddr, dst_len, - (u8*) &rt->rt6i_dst - (u8*) rt); + offsetof(struct rt6_info, rt6i_dst)); #ifdef CONFIG_IPV6_SUBTREES if (src_len) { @@ -752,7 +751,7 @@ struct fib6_node * fib6_locate(struct fib6_node *root, fn = fn->subtree; if (fn) fn = fib6_locate_1(fn, saddr, src_len, - (u8*) &rt->rt6i_src - (u8*) rt); + offsetof(struct rt6_info, rt6i_src)); } #endif @@ -1185,6 +1184,7 @@ static int fib6_age(struct rt6_info *rt, void *arg) if (rt->rt6i_flags&RTF_EXPIRES && rt->rt6i_expires) { if (time_after(now, rt->rt6i_expires)) { RT6_TRACE("expiring %p\n", rt); + rt6_reset_dflt_pointer(rt); return -1; } gc_args.more++; @@ -1193,6 +1193,11 @@ static int fib6_age(struct rt6_info *rt, void *arg) time_after_eq(now, rt->u.dst.lastuse + gc_args.timeout)) { RT6_TRACE("aging clone %p\n", rt); return -1; + } else if ((rt->rt6i_flags & RTF_GATEWAY) && + (!(rt->rt6i_nexthop->flags & NTF_ROUTER))) { + RT6_TRACE("purging route %p via non-router but gateway\n", + rt); + return -1; } gc_args.more++; }