Lines Matching refs:nh

19 static void remove_nexthop(struct net *net, struct nexthop *nh,
41 struct nexthop *nh) in call_nexthop_notifiers() argument
46 event_type, nh); in call_nexthop_notifiers()
72 static void nexthop_free_mpath(struct nexthop *nh) in nexthop_free_mpath() argument
77 nhg = rcu_dereference_raw(nh->nh_grp); in nexthop_free_mpath()
82 nexthop_put(nhge->nh); in nexthop_free_mpath()
91 static void nexthop_free_single(struct nexthop *nh) in nexthop_free_single() argument
95 nhi = rcu_dereference_raw(nh->nh_info); in nexthop_free_single()
98 fib_nh_release(nh->net, &nhi->fib_nh); in nexthop_free_single()
109 struct nexthop *nh = container_of(head, struct nexthop, rcu); in nexthop_free_rcu() local
111 if (nh->is_group) in nexthop_free_rcu()
112 nexthop_free_mpath(nh); in nexthop_free_rcu()
114 nexthop_free_single(nh); in nexthop_free_rcu()
116 kfree(nh); in nexthop_free_rcu()
122 struct nexthop *nh; in nexthop_alloc() local
124 nh = kzalloc(sizeof(struct nexthop), GFP_KERNEL); in nexthop_alloc()
125 if (nh) { in nexthop_alloc()
126 INIT_LIST_HEAD(&nh->fi_list); in nexthop_alloc()
127 INIT_LIST_HEAD(&nh->f6i_list); in nexthop_alloc()
128 INIT_LIST_HEAD(&nh->grp_list); in nexthop_alloc()
129 INIT_LIST_HEAD(&nh->fdb_list); in nexthop_alloc()
131 return nh; in nexthop_alloc()
158 struct nexthop *nh; in nexthop_find_by_id() local
165 nh = rb_entry(parent, struct nexthop, rb_node); in nexthop_find_by_id()
166 if (id < nh->id) in nexthop_find_by_id()
168 else if (id > nh->id) in nexthop_find_by_id()
171 return nh; in nexthop_find_by_id()
213 p->id = nhg->nh_entries[i].nh->id; in nla_put_nh_group()
224 static int nh_fill_node(struct sk_buff *skb, struct nexthop *nh, in nh_fill_node() argument
239 nhm->nh_flags = nh->nh_flags; in nh_fill_node()
240 nhm->nh_protocol = nh->protocol; in nh_fill_node()
244 if (nla_put_u32(skb, NHA_ID, nh->id)) in nh_fill_node()
247 if (nh->is_group) { in nh_fill_node()
248 struct nh_group *nhg = rtnl_dereference(nh->nh_grp); in nh_fill_node()
257 nhi = rtnl_dereference(nh->nh_info); in nh_fill_node()
305 static size_t nh_nlmsg_size_grp(struct nexthop *nh) in nh_nlmsg_size_grp() argument
307 struct nh_group *nhg = rtnl_dereference(nh->nh_grp); in nh_nlmsg_size_grp()
314 static size_t nh_nlmsg_size_single(struct nexthop *nh) in nh_nlmsg_size_single() argument
316 struct nh_info *nhi = rtnl_dereference(nh->nh_info); in nh_nlmsg_size_single()
345 static size_t nh_nlmsg_size(struct nexthop *nh) in nh_nlmsg_size() argument
351 if (nh->is_group) in nh_nlmsg_size()
352 sz += nh_nlmsg_size_grp(nh); in nh_nlmsg_size()
354 sz += nh_nlmsg_size_single(nh); in nh_nlmsg_size()
359 static void nexthop_notify(int event, struct nexthop *nh, struct nl_info *info) in nexthop_notify() argument
366 skb = nlmsg_new(nh_nlmsg_size(nh), gfp_any()); in nexthop_notify()
370 err = nh_fill_node(skb, nh, event, info->portid, seq, nlflags); in nexthop_notify()
386 static bool valid_group_nh(struct nexthop *nh, unsigned int npaths, in valid_group_nh() argument
389 if (nh->is_group) { in valid_group_nh()
390 struct nh_group *nhg = rtnl_dereference(nh->nh_grp); in valid_group_nh()
402 struct nh_info *nhi = rtnl_dereference(nh->nh_info); in valid_group_nh()
415 static int nh_check_attr_fdb_group(struct nexthop *nh, u8 *nh_family, in nh_check_attr_fdb_group() argument
420 nhi = rtnl_dereference(nh->nh_info); in nh_check_attr_fdb_group()
477 struct nexthop *nh; in nh_check_attr_group() local
480 nh = nexthop_find_by_id(net, nhg[i].id); in nh_check_attr_group()
481 if (!nh) { in nh_check_attr_group()
485 if (!valid_group_nh(nh, len, &is_fdb_nh, extack)) in nh_check_attr_group()
488 if (nhg_fdb && nh_check_attr_fdb_group(nh, &nh_family, extack)) in nh_check_attr_group()
509 static bool ipv6_good_nh(const struct fib6_nh *nh) in ipv6_good_nh() argument
516 n = __ipv6_neigh_lookup_noref_stub(nh->fib_nh_dev, &nh->fib_nh_gw6); in ipv6_good_nh()
525 static bool ipv4_good_nh(const struct fib_nh *nh) in ipv4_good_nh() argument
532 n = __ipv4_neigh_lookup_noref(nh->fib_nh_dev, in ipv4_good_nh()
533 (__force u32)nh->fib_nh_gw4); in ipv4_good_nh()
542 struct nexthop *nexthop_select_path(struct nexthop *nh, int hash) in nexthop_select_path() argument
548 if (!nh->is_group) in nexthop_select_path()
549 return nh; in nexthop_select_path()
551 nhg = rcu_dereference(nh->nh_grp); in nexthop_select_path()
559 nhi = rcu_dereference(nhge->nh->nh_info); in nexthop_select_path()
561 return nhge->nh; in nexthop_select_path()
569 return nhge->nh; in nexthop_select_path()
573 return nhge->nh; in nexthop_select_path()
578 rc = nhge->nh; in nexthop_select_path()
585 int nexthop_for_each_fib6_nh(struct nexthop *nh, in nexthop_for_each_fib6_nh() argument
586 int (*cb)(struct fib6_nh *nh, void *arg), in nexthop_for_each_fib6_nh() argument
592 if (nh->is_group) { in nexthop_for_each_fib6_nh()
596 nhg = rcu_dereference_rtnl(nh->nh_grp); in nexthop_for_each_fib6_nh()
600 nhi = rcu_dereference_rtnl(nhge->nh->nh_info); in nexthop_for_each_fib6_nh()
606 nhi = rcu_dereference_rtnl(nh->nh_info); in nexthop_for_each_fib6_nh()
626 int fib6_check_nexthop(struct nexthop *nh, struct fib6_config *cfg, in fib6_check_nexthop() argument
641 if (nh->is_group) { in fib6_check_nexthop()
644 nhg = rtnl_dereference(nh->nh_grp); in fib6_check_nexthop()
649 nhi = rtnl_dereference(nh->nh_info); in fib6_check_nexthop()
707 int fib_check_nexthop(struct nexthop *nh, u8 scope, in fib_check_nexthop() argument
713 if (nh->is_group) { in fib_check_nexthop()
716 nhg = rtnl_dereference(nh->nh_grp); in fib_check_nexthop()
730 nhi = rtnl_dereference(nhg->nh_entries[0].nh->nh_info); in fib_check_nexthop()
733 nhi = rtnl_dereference(nh->nh_info); in fib_check_nexthop()
785 struct nexthop *nh = nhge->nh; in remove_nh_grp_entry() local
789 WARN_ON(!nh); in remove_nh_grp_entry()
812 if (nhg->nh_entries[i].nh == nh) { in remove_nh_grp_entry()
817 nhi = rtnl_dereference(nhges[i].nh->nh_info); in remove_nh_grp_entry()
823 new_nhges[j].nh = nhges[i].nh; in remove_nh_grp_entry()
825 list_add(&new_nhges[j].nh_list, &new_nhges[j].nh->grp_list); in remove_nh_grp_entry()
833 nexthop_put(nhge->nh); in remove_nh_grp_entry()
839 static void remove_nexthop_from_groups(struct net *net, struct nexthop *nh, in remove_nexthop_from_groups() argument
844 list_for_each_entry_safe(nhge, tmp, &nh->grp_list, nh_list) in remove_nexthop_from_groups()
851 static void remove_nexthop_group(struct nexthop *nh, struct nl_info *nlinfo) in remove_nexthop_group() argument
853 struct nh_group *nhg = rcu_dereference_rtnl(nh->nh_grp); in remove_nexthop_group()
859 if (WARN_ON(!nhge->nh)) in remove_nexthop_group()
867 static void __remove_nexthop_fib(struct net *net, struct nexthop *nh) in __remove_nexthop_fib() argument
873 list_for_each_entry(fi, &nh->fi_list, nh_list) { in __remove_nexthop_fib()
881 list_for_each_entry_safe(f6i, tmp, &nh->f6i_list, nh_list) { in __remove_nexthop_fib()
889 static void __remove_nexthop(struct net *net, struct nexthop *nh, in __remove_nexthop() argument
892 __remove_nexthop_fib(net, nh); in __remove_nexthop()
894 if (nh->is_group) { in __remove_nexthop()
895 remove_nexthop_group(nh, nlinfo); in __remove_nexthop()
899 nhi = rtnl_dereference(nh->nh_info); in __remove_nexthop()
903 remove_nexthop_from_groups(net, nh, nlinfo); in __remove_nexthop()
907 static void remove_nexthop(struct net *net, struct nexthop *nh, in remove_nexthop() argument
910 call_nexthop_notifiers(net, NEXTHOP_EVENT_DEL, nh); in remove_nexthop()
913 rb_erase(&nh->rb_node, &net->nexthop.rb_root); in remove_nexthop()
916 nexthop_notify(RTM_DELNEXTHOP, nh, nlinfo); in remove_nexthop()
918 __remove_nexthop(net, nh, nlinfo); in remove_nexthop()
921 nexthop_put(nh); in remove_nexthop()
927 static void nh_rt_cache_flush(struct net *net, struct nexthop *nh) in nh_rt_cache_flush() argument
931 if (!list_empty(&nh->fi_list)) in nh_rt_cache_flush()
934 list_for_each_entry(f6i, &nh->f6i_list, nh_list) in nh_rt_cache_flush()
977 nhi = rtnl_dereference(nhges[i].nh->nh_info); in nh_group_v4_update()
1025 static void __nexthop_replace_notify(struct net *net, struct nexthop *nh, in __nexthop_replace_notify() argument
1030 if (!list_empty(&nh->fi_list)) { in __nexthop_replace_notify()
1037 list_for_each_entry(fi, &nh->fi_list, nh_list) in __nexthop_replace_notify()
1042 list_for_each_entry(fi, &nh->fi_list, nh_list) in __nexthop_replace_notify()
1046 list_for_each_entry(f6i, &nh->f6i_list, nh_list) in __nexthop_replace_notify()
1054 static void nexthop_replace_notify(struct net *net, struct nexthop *nh, in nexthop_replace_notify() argument
1059 __nexthop_replace_notify(net, nh, info); in nexthop_replace_notify()
1061 list_for_each_entry(nhge, &nh->grp_list, nh_list) in nexthop_replace_notify()
1137 struct nexthop *nh; in insert_nexthop() local
1145 nh = rb_entry(parent, struct nexthop, rb_node); in insert_nexthop()
1146 if (new_id < nh->id) { in insert_nexthop()
1148 } else if (new_id > nh->id) { in insert_nexthop()
1151 rc = replace_nexthop(net, nh, new_nh, extack); in insert_nexthop()
1153 new_nh = nh; /* send notification with old nh */ in insert_nexthop()
1211 struct nexthop *nh; in flush_all_nexthops() local
1214 nh = rb_entry(node, struct nexthop, rb_node); in flush_all_nexthops()
1215 remove_nexthop(net, nh, NULL); in flush_all_nexthops()
1227 struct nexthop *nh; in nexthop_create_group() local
1233 nh = nexthop_alloc(); in nexthop_create_group()
1234 if (!nh) in nexthop_create_group()
1237 nh->is_group = 1; in nexthop_create_group()
1241 kfree(nh); in nexthop_create_group()
1249 kfree(nh); in nexthop_create_group()
1266 nhg->nh_entries[i].nh = nhe; in nexthop_create_group()
1269 nhg->nh_entries[i].nh_parent = nh; in nexthop_create_group()
1280 rcu_assign_pointer(nh->nh_grp, nhg); in nexthop_create_group()
1282 return nh; in nexthop_create_group()
1287 nexthop_put(nhg->nh_entries[i].nh); in nexthop_create_group()
1292 kfree(nh); in nexthop_create_group()
1297 static int nh_create_ipv4(struct net *net, struct nexthop *nh, in nh_create_ipv4() argument
1326 nh->nh_flags = fib_nh->fib_nh_flags; in nh_create_ipv4()
1336 static int nh_create_ipv6(struct net *net, struct nexthop *nh, in nh_create_ipv6() argument
1365 nh->nh_flags = fib6_nh->fib_nh_flags; in nh_create_ipv6()
1375 struct nexthop *nh; in nexthop_create() local
1378 nh = nexthop_alloc(); in nexthop_create()
1379 if (!nh) in nexthop_create()
1384 kfree(nh); in nexthop_create()
1388 nh->nh_flags = cfg->nh_flags; in nexthop_create()
1389 nh->net = net; in nexthop_create()
1391 nhi->nh_parent = nh; in nexthop_create()
1405 err = nh_create_ipv4(net, nh, nhi, cfg, extack); in nexthop_create()
1408 err = nh_create_ipv6(net, nh, nhi, cfg, extack); in nexthop_create()
1414 kfree(nh); in nexthop_create()
1422 rcu_assign_pointer(nh->nh_info, nhi); in nexthop_create()
1424 return nh; in nexthop_create()
1431 struct nexthop *nh; in nexthop_add() local
1448 nh = nexthop_create_group(net, cfg); in nexthop_add()
1450 nh = nexthop_create(net, cfg, extack); in nexthop_add()
1452 if (IS_ERR(nh)) in nexthop_add()
1453 return nh; in nexthop_add()
1455 refcount_set(&nh->refcnt, 1); in nexthop_add()
1456 nh->id = cfg->nh_id; in nexthop_add()
1457 nh->protocol = cfg->nh_protocol; in nexthop_add()
1458 nh->net = net; in nexthop_add()
1460 err = insert_nexthop(net, nh, cfg, extack); in nexthop_add()
1462 __remove_nexthop(net, nh, NULL); in nexthop_add()
1463 nexthop_put(nh); in nexthop_add()
1464 nh = ERR_PTR(err); in nexthop_add()
1467 return nh; in nexthop_add()
1657 struct nexthop *nh; in rtm_new_nexthop() local
1662 nh = nexthop_add(net, &cfg, extack); in rtm_new_nexthop()
1663 if (IS_ERR(nh)) in rtm_new_nexthop()
1664 err = PTR_ERR(nh); in rtm_new_nexthop()
1725 struct nexthop *nh; in rtm_del_nexthop() local
1733 nh = nexthop_find_by_id(net, id); in rtm_del_nexthop()
1734 if (!nh) in rtm_del_nexthop()
1737 remove_nexthop(net, nh, &nlinfo); in rtm_del_nexthop()
1748 struct nexthop *nh; in rtm_get_nexthop() local
1762 nh = nexthop_find_by_id(net, id); in rtm_get_nexthop()
1763 if (!nh) in rtm_get_nexthop()
1766 err = nh_fill_node(skb, nh, RTM_NEWNEXTHOP, NETLINK_CB(in_skb).portid, in rtm_get_nexthop()
1781 static bool nh_dump_filtered(struct nexthop *nh, int dev_idx, int master_idx, in nh_dump_filtered() argument
1787 if (group_filter && !nh->is_group) in nh_dump_filtered()
1793 if (nh->is_group) in nh_dump_filtered()
1796 nhi = rtnl_dereference(nh->nh_info); in nh_dump_filtered()
1894 struct nexthop *nh; in rtm_dump_nexthop() local
1899 nh = rb_entry(node, struct nexthop, rb_node); in rtm_dump_nexthop()
1900 if (nh_dump_filtered(nh, dev_filter_idx, master_idx, in rtm_dump_nexthop()
1904 err = nh_fill_node(skb, nh, RTM_NEWNEXTHOP, in rtm_dump_nexthop()