void *arg;
};
-rwlock_t fib6_walker_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(fib6_walker_lock);
#ifdef CONFIG_IPV6_SUBTREES
static struct timer_list ip6_fib_timer = TIMER_INITIALIZER(fib6_run_gc, 0, 0);
-static struct fib6_walker_t fib6_walker_list = {
+struct fib6_walker_t fib6_walker_list = {
.prev = &fib6_walker_list,
.next = &fib6_walker_list,
};
* 64bit processors)
*/
-/*
- * compare "prefix length" bits of an address
- */
-
-static __inline__ int addr_match(void *token1, void *token2, int prefixlen)
-{
- __u32 *a1 = token1;
- __u32 *a2 = token2;
- int pdw;
- int pbi;
-
- pdw = prefixlen >> 5; /* num of whole __u32 in prefix */
- pbi = prefixlen & 0x1f; /* num of bits in incomplete u32 in prefix */
-
- if (pdw)
- if (memcmp(a1, a2, pdw << 2))
- return 0;
-
- if (pbi) {
- __u32 mask;
-
- mask = htonl((0xffffffff) << (32 - pbi));
-
- if ((a1[pdw] ^ a2[pdw]) & mask)
- return 0;
- }
-
- return 1;
-}
-
/*
* test bit
*/
* Prefix match
*/
if (plen < fn->fn_bit ||
- !addr_match(&key->addr, addr, fn->fn_bit))
+ !ipv6_prefix_equal(&key->addr, addr, fn->fn_bit))
goto insert_above;
/*
if (fn->fn_flags&RTN_TL_ROOT &&
fn->leaf == &ip6_null_entry &&
- !(rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF | RTF_ALLONLINK)) ){
+ !(rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) ){
fn->leaf = rt;
rt->u.next = NULL;
goto out;
* 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_equal(&iter->rt6i_gateway,
+ &rt->rt6i_gateway)) {
if (!(iter->rt6i_flags&RTF_EXPIRES))
return -EEXIST;
iter->rt6i_expires = rt->rt6i_expires;
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;
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
} 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;
key = (struct rt6key *) ((u8 *) fn->leaf +
args->offset);
- if (addr_match(&key->addr, args->addr, key->plen))
+ if (ipv6_prefix_equal(&key->addr, args->addr, key->plen))
return fn;
}
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
* Prefix match
*/
if (plen < fn->fn_bit ||
- !addr_match(&key->addr, addr, fn->fn_bit))
+ !ipv6_prefix_equal(&key->addr, addr, fn->fn_bit))
return NULL;
if (plen == fn->fn_bit)
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) {
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
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++;
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++;
}
return 0;
}
-static spinlock_t fib6_gc_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(fib6_gc_lock);
void fib6_run_gc(unsigned long dummy)
{
if (dummy != ~0UL) {
spin_lock_bh(&fib6_gc_lock);
- gc_args.timeout = (int)dummy;
+ gc_args.timeout = dummy ? (int)dummy : ip6_rt_gc_interval;
} else {
local_bh_disable();
if (!spin_trylock(&fib6_gc_lock)) {
panic("cannot create fib6_nodes cache");
}
-void __exit fib6_gc_cleanup(void)
+void fib6_gc_cleanup(void)
{
del_timer(&ip6_fib_timer);
kmem_cache_destroy(fib6_node_kmem);