void fib_release_info(struct fib_info *fi) { spin_lock_bh(&fib_info_lock); if (fi && --fi->fib_treeref == 0) { hlist_del(&fi->fib_hash); if (fi->fib_prefsrc) hlist_del(&fi->fib_lhash); change_nexthops(fi) { if (!nh->nh_dev) continue; hlist_del(&nh->nh_hash); } endfor_nexthops(fi) fi->fib_dead = 1; fib_info_put(fi); }
void free_fib_info(struct fib_info *fi) { if (fi->fib_dead == 0) { printk("Freeing alive fib_info %p\n", fi); return; } change_nexthops(fi) { if (nh->nh_dev) dev_put(nh->nh_dev); nh->nh_dev = NULL; } endfor_nexthops(fi); fib_info_cnt--; kfree(fi); }
void free_fib_info(struct fib_info *fi) { if (fi->fib_dead == 0) { pr_warning("Freeing alive fib_info %p\n", fi); return; } change_nexthops(fi) { if (nexthop_nh->nh_dev) dev_put(nexthop_nh->nh_dev); nexthop_nh->nh_dev = NULL; } endfor_nexthops(fi); fib_info_cnt--; release_net(fi->fib_net); call_rcu(&fi->rcu, free_fib_info_rcu); }
void free_fib_info(struct fib_info *fi) { if (fi->fib_dead == 0) { pr_warn("Freeing alive fib_info %p\n", fi); return; } fib_info_cnt--; #ifdef CONFIG_IP_ROUTE_CLASSID change_nexthops(fi) { if (nexthop_nh->nh_tclassid) fi->fib_net->ipv4.fib_num_tclassid_users--; } endfor_nexthops(fi); #endif call_rcu(&fi->rcu, free_fib_info_rcu); }
static inline int dn_fib_nh_comp(const struct dn_fib_info *fi, const struct dn_fib_info *ofi) { const struct dn_fib_nh *onh = ofi->fib_nh; for_nexthops(fi) { if (nh->nh_oif != onh->nh_oif || nh->nh_gw != onh->nh_gw || nh->nh_scope != onh->nh_scope || nh->nh_weight != onh->nh_weight || ((nh->nh_flags^onh->nh_flags)&~RTNH_F_DEAD)) return -1; onh++; } endfor_nexthops(fi); return 0; }
static __inline__ int nh_comp(const struct fib_info *fi, const struct fib_info *ofi) { const struct fib_nh *onh = ofi->fib_nh; for_nexthops(fi) { if (nh->nh_oif != onh->nh_oif || nh->nh_gw != onh->nh_gw || nh->nh_scope != onh->nh_scope || #ifdef CONFIG_IP_ROUTE_MULTIPATH nh->nh_weight != onh->nh_weight || #endif #ifdef CONFIG_NET_CLS_ROUTE nh->nh_tclassid != onh->nh_tclassid || #endif ((nh->nh_flags^onh->nh_flags)&~RTNH_F_DEAD)) return -1; onh++; } endfor_nexthops(fi); return 0; }
/* Release a nexthop info record */ static void free_fib_info_rcu(struct rcu_head *head) { struct fib_info *fi = container_of(head, struct fib_info, rcu); change_nexthops(fi) { if (nexthop_nh->nh_dev) dev_put(nexthop_nh->nh_dev); if (nexthop_nh->nh_exceptions) free_nh_exceptions(nexthop_nh); if (nexthop_nh->nh_rth_output) dst_release(&nexthop_nh->nh_rth_output->dst); if (nexthop_nh->nh_rth_input) dst_release(&nexthop_nh->nh_rth_input->dst); } endfor_nexthops(fi); release_net(fi->fib_net); if (fi->fib_metrics != (u32 *) dst_default_metrics) kfree(fi->fib_metrics); kfree(fi); }