Lines Matching refs:rt
158 static void rt6_rcu_free(struct rt6_info *rt) in rt6_rcu_free() argument
160 call_rcu(&rt->dst.rcu_head, dst_rcu_free); in rt6_rcu_free()
185 static void rt6_release(struct rt6_info *rt) in rt6_release() argument
187 if (atomic_dec_and_test(&rt->rt6i_ref)) { in rt6_release()
188 rt6_free_pcpu(rt); in rt6_release()
189 rt6_rcu_free(rt); in rt6_release()
289 struct rt6_info *rt; in fib6_rule_lookup() local
291 rt = lookup(net, net->ipv6.fib6_main_tbl, fl6, flags); in fib6_rule_lookup()
292 if (rt->rt6i_flags & RTF_REJECT && in fib6_rule_lookup()
293 rt->dst.error == -EAGAIN) { in fib6_rule_lookup()
294 ip6_rt_put(rt); in fib6_rule_lookup()
295 rt = net->ipv6.ip6_null_entry; in fib6_rule_lookup()
296 dst_hold(&rt->dst); in fib6_rule_lookup()
299 return &rt->dst; in fib6_rule_lookup()
312 struct rt6_info *rt; in fib6_dump_node() local
314 for (rt = w->leaf; rt; rt = rt->dst.rt6_next) { in fib6_dump_node()
315 res = rt6_dump_route(rt, w->args); in fib6_dump_node()
318 w->leaf = rt; in fib6_dump_node()
667 static bool rt6_qualify_for_ecmp(struct rt6_info *rt) in rt6_qualify_for_ecmp() argument
669 return (rt->rt6i_flags & (RTF_GATEWAY|RTF_ADDRCONF|RTF_DYNAMIC)) == in rt6_qualify_for_ecmp()
705 static void fib6_purge_rt(struct rt6_info *rt, struct fib6_node *fn, in fib6_purge_rt() argument
708 if (atomic_read(&rt->rt6i_ref) != 1) { in fib6_purge_rt()
716 if (!(fn->fn_flags & RTN_RTINFO) && fn->leaf == rt) { in fib6_purge_rt()
719 rt6_release(rt); in fib6_purge_rt()
724 BUG_ON(atomic_read(&rt->rt6i_ref) != 1); in fib6_purge_rt()
732 static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, in fib6_add_rt2node() argument
743 bool rt_can_ecmp = rt6_qualify_for_ecmp(rt); in fib6_add_rt2node()
753 if (iter->rt6i_metric == rt->rt6i_metric) { in fib6_add_rt2node()
770 if (iter->dst.dev == rt->dst.dev && in fib6_add_rt2node()
771 iter->rt6i_idev == rt->rt6i_idev && in fib6_add_rt2node()
773 &rt->rt6i_gateway)) { in fib6_add_rt2node()
774 if (rt->rt6i_nsiblings) in fib6_add_rt2node()
775 rt->rt6i_nsiblings = 0; in fib6_add_rt2node()
778 if (!(rt->rt6i_flags & RTF_EXPIRES)) in fib6_add_rt2node()
781 rt6_set_expires(iter, rt->dst.expires); in fib6_add_rt2node()
782 iter->rt6i_pmtu = rt->rt6i_pmtu; in fib6_add_rt2node()
798 rt->rt6i_nsiblings++; in fib6_add_rt2node()
801 if (iter->rt6i_metric > rt->rt6i_metric) in fib6_add_rt2node()
820 if (rt->rt6i_nsiblings) { in fib6_add_rt2node()
827 if (sibling->rt6i_metric == rt->rt6i_metric && in fib6_add_rt2node()
829 list_add_tail(&rt->rt6i_siblings, in fib6_add_rt2node()
841 &rt->rt6i_siblings, rt6i_siblings) { in fib6_add_rt2node()
843 BUG_ON(sibling->rt6i_nsiblings != rt->rt6i_nsiblings); in fib6_add_rt2node()
846 BUG_ON(rt6i_nsiblings != rt->rt6i_nsiblings); in fib6_add_rt2node()
857 err = fib6_commit_metrics(&rt->dst, mxc); in fib6_add_rt2node()
861 rt->dst.rt6_next = iter; in fib6_add_rt2node()
862 *ins = rt; in fib6_add_rt2node()
863 rt->rt6i_node = fn; in fib6_add_rt2node()
864 atomic_inc(&rt->rt6i_ref); in fib6_add_rt2node()
865 inet6_rt_notify(RTM_NEWROUTE, rt, info, 0); in fib6_add_rt2node()
883 err = fib6_commit_metrics(&rt->dst, mxc); in fib6_add_rt2node()
887 *ins = rt; in fib6_add_rt2node()
888 rt->rt6i_node = fn; in fib6_add_rt2node()
889 rt->dst.rt6_next = iter->dst.rt6_next; in fib6_add_rt2node()
890 atomic_inc(&rt->rt6i_ref); in fib6_add_rt2node()
891 inet6_rt_notify(RTM_NEWROUTE, rt, info, NLM_F_REPLACE); in fib6_add_rt2node()
902 ins = &rt->dst.rt6_next; in fib6_add_rt2node()
922 static void fib6_start_gc(struct net *net, struct rt6_info *rt) in fib6_start_gc() argument
925 (rt->rt6i_flags & (RTF_EXPIRES | RTF_CACHE))) in fib6_start_gc()
943 int fib6_add(struct fib6_node *root, struct rt6_info *rt, in fib6_add() argument
952 if (WARN_ON_ONCE((rt->dst.flags & DST_NOCACHE) && in fib6_add()
953 !atomic_read(&rt->dst.__refcnt))) in fib6_add()
965 fn = fib6_add_1(root, &rt->rt6i_dst.addr, rt->rt6i_dst.plen, in fib6_add()
977 if (rt->rt6i_src.plen) { in fib6_add()
1005 sn = fib6_add_1(sfn, &rt->rt6i_src.addr, in fib6_add()
1006 rt->rt6i_src.plen, in fib6_add()
1024 sn = fib6_add_1(fn->subtree, &rt->rt6i_src.addr, in fib6_add()
1025 rt->rt6i_src.plen, in fib6_add()
1036 fn->leaf = rt; in fib6_add()
1037 atomic_inc(&rt->rt6i_ref); in fib6_add()
1043 err = fib6_add_rt2node(fn, rt, info, mxc); in fib6_add()
1045 fib6_start_gc(info->nl_net, rt); in fib6_add()
1046 if (!(rt->rt6i_flags & RTF_CACHE)) in fib6_add()
1048 rt->dst.flags &= ~DST_NOCACHE; in fib6_add()
1058 if (pn != fn && pn->leaf == rt) { in fib6_add()
1060 atomic_dec(&rt->rt6i_ref); in fib6_add()
1073 if (!(rt->dst.flags & DST_NOCACHE)) in fib6_add()
1074 dst_free(&rt->dst); in fib6_add()
1085 if (!(rt->dst.flags & DST_NOCACHE)) in fib6_add()
1086 dst_free(&rt->dst); in fib6_add()
1387 struct rt6_info *rt = *rtp; in fib6_del_route() local
1393 *rtp = rt->dst.rt6_next; in fib6_del_route()
1394 rt->rt6i_node = NULL; in fib6_del_route()
1399 if (fn->rr_ptr == rt) in fib6_del_route()
1403 if (rt->rt6i_nsiblings) { in fib6_del_route()
1407 &rt->rt6i_siblings, rt6i_siblings) in fib6_del_route()
1409 rt->rt6i_nsiblings = 0; in fib6_del_route()
1410 list_del_init(&rt->rt6i_siblings); in fib6_del_route()
1416 if (w->state == FWS_C && w->leaf == rt) { in fib6_del_route()
1418 w->leaf = rt->dst.rt6_next; in fib6_del_route()
1425 rt->dst.rt6_next = NULL; in fib6_del_route()
1434 fib6_purge_rt(rt, fn, net); in fib6_del_route()
1436 inet6_rt_notify(RTM_DELROUTE, rt, info, 0); in fib6_del_route()
1437 rt6_release(rt); in fib6_del_route()
1440 int fib6_del(struct rt6_info *rt, struct nl_info *info) in fib6_del() argument
1443 struct fib6_node *fn = rt->rt6i_node; in fib6_del()
1447 if (rt->dst.obsolete > 0) { in fib6_del()
1452 if (!fn || rt == net->ipv6.ip6_null_entry) in fib6_del()
1457 if (!(rt->rt6i_flags & RTF_CACHE)) { in fib6_del()
1461 if (rt->rt6i_src.plen) { in fib6_del()
1475 if (*rtp == rt) { in fib6_del()
1608 struct rt6_info *rt; in fib6_clean_node() local
1624 for (rt = w->leaf; rt; rt = rt->dst.rt6_next) { in fib6_clean_node()
1625 res = c->func(rt, c->arg); in fib6_clean_node()
1627 w->leaf = rt; in fib6_clean_node()
1628 res = fib6_del(rt, &info); in fib6_clean_node()
1632 __func__, rt, rt->rt6i_node, res); in fib6_clean_node()
1640 w->leaf = rt; in fib6_clean_node()
1701 static int fib6_prune_clone(struct rt6_info *rt, void *arg) in fib6_prune_clone() argument
1703 if (rt->rt6i_flags & RTF_CACHE) { in fib6_prune_clone()
1704 RT6_TRACE("pruning clone %p\n", rt); in fib6_prune_clone()
1734 static int fib6_age(struct rt6_info *rt, void *arg) in fib6_age() argument
1746 if (rt->rt6i_flags & RTF_EXPIRES && rt->dst.expires) { in fib6_age()
1747 if (time_after(now, rt->dst.expires)) { in fib6_age()
1748 RT6_TRACE("expiring %p\n", rt); in fib6_age()
1752 } else if (rt->rt6i_flags & RTF_CACHE) { in fib6_age()
1753 if (atomic_read(&rt->dst.__refcnt) == 0 && in fib6_age()
1754 time_after_eq(now, rt->dst.lastuse + gc_args.timeout)) { in fib6_age()
1755 RT6_TRACE("aging clone %p\n", rt); in fib6_age()
1757 } else if (rt->rt6i_flags & RTF_GATEWAY) { in fib6_age()
1761 neigh = dst_neigh_lookup(&rt->dst, &rt->rt6i_gateway); in fib6_age()
1768 rt); in fib6_age()
1937 struct rt6_info *rt = v; in ipv6_route_seq_show() local
1940 seq_printf(seq, "%pi6 %02x ", &rt->rt6i_dst.addr, rt->rt6i_dst.plen); in ipv6_route_seq_show()
1943 seq_printf(seq, "%pi6 %02x ", &rt->rt6i_src.addr, rt->rt6i_src.plen); in ipv6_route_seq_show()
1947 if (rt->rt6i_flags & RTF_GATEWAY) in ipv6_route_seq_show()
1948 seq_printf(seq, "%pi6", &rt->rt6i_gateway); in ipv6_route_seq_show()
1953 rt->rt6i_metric, atomic_read(&rt->dst.__refcnt), in ipv6_route_seq_show()
1954 rt->dst.__use, rt->rt6i_flags, in ipv6_route_seq_show()
1955 rt->dst.dev ? rt->dst.dev->name : ""); in ipv6_route_seq_show()