Lines Matching refs:nh

23 static void remove_nexthop(struct net *net, struct nexthop *nh,
101 const struct nexthop *nh) in nh_notifier_single_info_init() argument
103 struct nh_info *nhi = rtnl_dereference(nh->nh_info); in nh_notifier_single_info_init()
106 info->nh = kzalloc(sizeof(*info->nh), GFP_KERNEL); in nh_notifier_single_info_init()
107 if (!info->nh) in nh_notifier_single_info_init()
110 __nh_notifier_single_info_init(info->nh, nhi); in nh_notifier_single_info_init()
117 kfree(info->nh); in nh_notifier_single_info_fini()
139 nhi = rtnl_dereference(nhge->nh->nh_info); in nh_notifier_mpath_info_init()
140 info->nh_grp->nh_entries[i].id = nhge->nh->id; in nh_notifier_mpath_info_init()
142 __nh_notifier_single_info_init(&info->nh_grp->nh_entries[i].nh, in nh_notifier_mpath_info_init()
172 nhi = rtnl_dereference(nhge->nh->nh_info); in nh_notifier_res_table_info_init()
181 const struct nexthop *nh) in nh_notifier_grp_info_init() argument
183 struct nh_group *nhg = rtnl_dereference(nh->nh_grp); in nh_notifier_grp_info_init()
193 const struct nexthop *nh) in nh_notifier_grp_info_fini() argument
195 struct nh_group *nhg = rtnl_dereference(nh->nh_grp); in nh_notifier_grp_info_fini()
204 const struct nexthop *nh) in nh_notifier_info_init() argument
206 info->id = nh->id; in nh_notifier_info_init()
208 if (nh->is_group) in nh_notifier_info_init()
209 return nh_notifier_grp_info_init(info, nh); in nh_notifier_info_init()
211 return nh_notifier_single_info_init(info, nh); in nh_notifier_info_init()
215 const struct nexthop *nh) in nh_notifier_info_fini() argument
217 if (nh->is_group) in nh_notifier_info_fini()
218 nh_notifier_grp_info_fini(info, nh); in nh_notifier_info_fini()
225 struct nexthop *nh, in call_nexthop_notifiers() argument
239 err = nh_notifier_info_init(&info, nh); in call_nexthop_notifiers()
247 nh_notifier_info_fini(&info, nh); in call_nexthop_notifiers()
258 struct nexthop *nh; in nh_notifier_res_bucket_idle_timer_get() local
277 nh = nexthop_find_by_id(info->net, info->id); in nh_notifier_res_bucket_idle_timer_get()
278 if (!nh) { in nh_notifier_res_bucket_idle_timer_get()
283 nhg = rcu_dereference(nh->nh_grp); in nh_notifier_res_bucket_idle_timer_get()
390 static int call_nexthop_res_table_notifiers(struct net *net, struct nexthop *nh, in call_nexthop_res_table_notifiers() argument
409 nhg = rtnl_dereference(nh->nh_grp); in call_nexthop_res_table_notifiers()
426 struct nexthop *nh, in call_nexthop_notifier() argument
435 err = nh_notifier_info_init(&info, nh); in call_nexthop_notifier()
440 nh_notifier_info_fini(&info, nh); in call_nexthop_notifier()
467 static void nexthop_free_group(struct nexthop *nh) in nexthop_free_group() argument
472 nhg = rcu_dereference_raw(nh->nh_grp); in nexthop_free_group()
477 nexthop_put(nhge->nh); in nexthop_free_group()
489 static void nexthop_free_single(struct nexthop *nh) in nexthop_free_single() argument
493 nhi = rcu_dereference_raw(nh->nh_info); in nexthop_free_single()
496 fib_nh_release(nh->net, &nhi->fib_nh); in nexthop_free_single()
507 struct nexthop *nh = container_of(head, struct nexthop, rcu); in nexthop_free_rcu() local
509 if (nh->is_group) in nexthop_free_rcu()
510 nexthop_free_group(nh); in nexthop_free_rcu()
512 nexthop_free_single(nh); in nexthop_free_rcu()
514 kfree(nh); in nexthop_free_rcu()
520 struct nexthop *nh; in nexthop_alloc() local
522 nh = kzalloc(sizeof(struct nexthop), GFP_KERNEL); in nexthop_alloc()
523 if (nh) { in nexthop_alloc()
524 INIT_LIST_HEAD(&nh->fi_list); in nexthop_alloc()
525 INIT_LIST_HEAD(&nh->f6i_list); in nexthop_alloc()
526 INIT_LIST_HEAD(&nh->grp_list); in nexthop_alloc()
527 INIT_LIST_HEAD(&nh->fdb_list); in nexthop_alloc()
529 return nh; in nexthop_alloc()
580 struct nexthop *nh; in nexthop_find_by_id() local
587 nh = rb_entry(parent, struct nexthop, rb_node); in nexthop_find_by_id()
588 if (id < nh->id) in nexthop_find_by_id()
590 else if (id > nh->id) in nexthop_find_by_id()
593 return nh; in nexthop_find_by_id()
679 p->id = nhg->nh_entries[i].nh->id; in nla_put_nh_group()
693 static int nh_fill_node(struct sk_buff *skb, struct nexthop *nh, in nh_fill_node() argument
708 nhm->nh_flags = nh->nh_flags; in nh_fill_node()
709 nhm->nh_protocol = nh->protocol; in nh_fill_node()
713 if (nla_put_u32(skb, NHA_ID, nh->id)) in nh_fill_node()
716 if (nh->is_group) { in nh_fill_node()
717 struct nh_group *nhg = rtnl_dereference(nh->nh_grp); in nh_fill_node()
726 nhi = rtnl_dereference(nh->nh_info); in nh_fill_node()
783 static size_t nh_nlmsg_size_grp(struct nexthop *nh) in nh_nlmsg_size_grp() argument
785 struct nh_group *nhg = rtnl_dereference(nh->nh_grp); in nh_nlmsg_size_grp()
796 static size_t nh_nlmsg_size_single(struct nexthop *nh) in nh_nlmsg_size_single() argument
798 struct nh_info *nhi = rtnl_dereference(nh->nh_info); in nh_nlmsg_size_single()
827 static size_t nh_nlmsg_size(struct nexthop *nh) in nh_nlmsg_size() argument
833 if (nh->is_group) in nh_nlmsg_size()
834 sz += nh_nlmsg_size_grp(nh); in nh_nlmsg_size()
836 sz += nh_nlmsg_size_single(nh); in nh_nlmsg_size()
841 static void nexthop_notify(int event, struct nexthop *nh, struct nl_info *info) in nexthop_notify() argument
848 skb = nlmsg_new(nh_nlmsg_size(nh), gfp_any()); in nexthop_notify()
852 err = nh_fill_node(skb, nh, event, info->portid, seq, nlflags); in nexthop_notify()
914 static int nh_fill_res_bucket(struct sk_buff *skb, struct nexthop *nh, in nh_fill_res_bucket() argument
932 nhm->nh_protocol = nh->protocol; in nh_fill_res_bucket()
936 if (nla_put_u32(skb, NHA_ID, nh->id)) in nh_fill_res_bucket()
944 nla_put_u32(skb, NHA_RES_BUCKET_NH_ID, nhge->nh->id) || in nh_fill_res_bucket()
966 struct nexthop *nh = nhge->nh_parent; in nexthop_bucket_notify() local
974 err = nh_fill_res_bucket(skb, nh, bucket, bucket_index, in nexthop_bucket_notify()
982 rtnl_notify(skb, nh->net, 0, RTNLGRP_NEXTHOP, NULL, GFP_KERNEL); in nexthop_bucket_notify()
986 rtnl_set_sk_err(nh->net, RTNLGRP_NEXTHOP, err); in nexthop_bucket_notify()
989 static bool valid_group_nh(struct nexthop *nh, unsigned int npaths, in valid_group_nh() argument
992 if (nh->is_group) { in valid_group_nh()
993 struct nh_group *nhg = rtnl_dereference(nh->nh_grp); in valid_group_nh()
1008 struct nh_info *nhi = rtnl_dereference(nh->nh_info); in valid_group_nh()
1021 static int nh_check_attr_fdb_group(struct nexthop *nh, u8 *nh_family, in nh_check_attr_fdb_group() argument
1026 nhi = rtnl_dereference(nh->nh_info); in nh_check_attr_fdb_group()
1084 struct nexthop *nh; in nh_check_attr_group() local
1087 nh = nexthop_find_by_id(net, nhg[i].id); in nh_check_attr_group()
1088 if (!nh) { in nh_check_attr_group()
1092 if (!valid_group_nh(nh, len, &is_fdb_nh, extack)) in nh_check_attr_group()
1095 if (nhg_fdb && nh_check_attr_fdb_group(nh, &nh_family, extack)) in nh_check_attr_group()
1122 static bool ipv6_good_nh(const struct fib6_nh *nh) in ipv6_good_nh() argument
1129 n = __ipv6_neigh_lookup_noref_stub(nh->fib_nh_dev, &nh->fib_nh_gw6); in ipv6_good_nh()
1138 static bool ipv4_good_nh(const struct fib_nh *nh) in ipv4_good_nh() argument
1145 n = __ipv4_neigh_lookup_noref(nh->fib_nh_dev, in ipv4_good_nh()
1146 (__force u32)nh->fib_nh_gw4); in ipv4_good_nh()
1155 static bool nexthop_is_good_nh(const struct nexthop *nh) in nexthop_is_good_nh() argument
1157 struct nh_info *nhi = rcu_dereference(nh->nh_info); in nexthop_is_good_nh()
1179 return nhge->nh; in nexthop_select_path_fdb()
1200 if (!nexthop_is_good_nh(nhge->nh)) in nexthop_select_path_hthr()
1204 rc = nhge->nh; in nexthop_select_path_hthr()
1209 return nhge->nh; in nexthop_select_path_hthr()
1212 return rc ? : nhg->nh_entries[0].nh; in nexthop_select_path_hthr()
1228 return nhge->nh; in nexthop_select_path_res()
1231 struct nexthop *nexthop_select_path(struct nexthop *nh, int hash) in nexthop_select_path() argument
1235 if (!nh->is_group) in nexthop_select_path()
1236 return nh; in nexthop_select_path()
1238 nhg = rcu_dereference(nh->nh_grp); in nexthop_select_path()
1249 int nexthop_for_each_fib6_nh(struct nexthop *nh, in nexthop_for_each_fib6_nh() argument
1250 int (*cb)(struct fib6_nh *nh, void *arg), in nexthop_for_each_fib6_nh() argument
1256 if (nh->is_group) { in nexthop_for_each_fib6_nh()
1260 nhg = rcu_dereference_rtnl(nh->nh_grp); in nexthop_for_each_fib6_nh()
1264 nhi = rcu_dereference_rtnl(nhge->nh->nh_info); in nexthop_for_each_fib6_nh()
1270 nhi = rcu_dereference_rtnl(nh->nh_info); in nexthop_for_each_fib6_nh()
1290 int fib6_check_nexthop(struct nexthop *nh, struct fib6_config *cfg, in fib6_check_nexthop() argument
1305 if (nh->is_group) { in fib6_check_nexthop()
1308 nhg = rtnl_dereference(nh->nh_grp); in fib6_check_nexthop()
1313 nhi = rtnl_dereference(nh->nh_info); in fib6_check_nexthop()
1371 int fib_check_nexthop(struct nexthop *nh, u8 scope, in fib_check_nexthop() argument
1377 if (nh->is_group) { in fib_check_nexthop()
1380 nhg = rtnl_dereference(nh->nh_grp); in fib_check_nexthop()
1394 nhi = rtnl_dereference(nhg->nh_entries[0].nh->nh_info); in fib_check_nexthop()
1397 nhi = rtnl_dereference(nh->nh_info); in fib_check_nexthop()
1551 old_nhge->nh, in nh_res_bucket_migrate()
1552 new_nhge->nh, &extack); in nh_res_bucket_migrate()
1697 u32 id = rtnl_dereference(bucket->nh_entry)->nh->id; in nh_res_table_migrate_buckets()
1704 if (nhge->nh->id == id) { in nh_res_table_migrate_buckets()
1762 struct nexthop *nh = nhge->nh; in remove_nh_grp_entry() local
1766 WARN_ON(!nh); in remove_nh_grp_entry()
1791 if (nhg->nh_entries[i].nh == nh) { in remove_nh_grp_entry()
1796 nhi = rtnl_dereference(nhges[i].nh->nh_info); in remove_nh_grp_entry()
1802 new_nhges[j].nh = nhges[i].nh; in remove_nh_grp_entry()
1804 list_add(&new_nhges[j].nh_list, &new_nhges[j].nh->grp_list); in remove_nh_grp_entry()
1816 nexthop_put(nhge->nh); in remove_nh_grp_entry()
1832 static void remove_nexthop_from_groups(struct net *net, struct nexthop *nh, in remove_nexthop_from_groups() argument
1837 list_for_each_entry_safe(nhge, tmp, &nh->grp_list, nh_list) in remove_nexthop_from_groups()
1844 static void remove_nexthop_group(struct nexthop *nh, struct nl_info *nlinfo) in remove_nexthop_group() argument
1846 struct nh_group *nhg = rcu_dereference_rtnl(nh->nh_grp); in remove_nexthop_group()
1853 if (WARN_ON(!nhge->nh)) in remove_nexthop_group()
1866 static void __remove_nexthop_fib(struct net *net, struct nexthop *nh) in __remove_nexthop_fib() argument
1872 list_for_each_entry(fi, &nh->fi_list, nh_list) { in __remove_nexthop_fib()
1880 list_for_each_entry_safe(f6i, tmp, &nh->f6i_list, nh_list) { in __remove_nexthop_fib()
1888 static void __remove_nexthop(struct net *net, struct nexthop *nh, in __remove_nexthop() argument
1891 __remove_nexthop_fib(net, nh); in __remove_nexthop()
1893 if (nh->is_group) { in __remove_nexthop()
1894 remove_nexthop_group(nh, nlinfo); in __remove_nexthop()
1898 nhi = rtnl_dereference(nh->nh_info); in __remove_nexthop()
1902 remove_nexthop_from_groups(net, nh, nlinfo); in __remove_nexthop()
1906 static void remove_nexthop(struct net *net, struct nexthop *nh, in remove_nexthop() argument
1909 call_nexthop_notifiers(net, NEXTHOP_EVENT_DEL, nh, NULL); in remove_nexthop()
1912 rb_erase(&nh->rb_node, &net->nexthop.rb_root); in remove_nexthop()
1915 nexthop_notify(RTM_DELNEXTHOP, nh, nlinfo); in remove_nexthop()
1917 __remove_nexthop(net, nh, nlinfo); in remove_nexthop()
1920 nexthop_put(nh); in remove_nexthop()
1926 static void nh_rt_cache_flush(struct net *net, struct nexthop *nh, in nh_rt_cache_flush() argument
1933 if (!list_empty(&nh->fi_list)) in nh_rt_cache_flush()
1936 list_for_each_entry(f6i, &nh->f6i_list, nh_list) in nh_rt_cache_flush()
1948 struct nh_info *nhi = rtnl_dereference(nhge->nh->nh_info); in nh_rt_cache_flush()
2052 nhi = rtnl_dereference(nhges[i].nh->nh_info); in nh_group_v4_update()
2075 if (nhge->nh == old) { in replace_nexthop_single_notify_res()
2093 if (nhge->nh == old) in replace_nexthop_single_notify_res()
2203 static void __nexthop_replace_notify(struct net *net, struct nexthop *nh, in __nexthop_replace_notify() argument
2208 if (!list_empty(&nh->fi_list)) { in __nexthop_replace_notify()
2215 list_for_each_entry(fi, &nh->fi_list, nh_list) in __nexthop_replace_notify()
2220 list_for_each_entry(fi, &nh->fi_list, nh_list) in __nexthop_replace_notify()
2224 list_for_each_entry(f6i, &nh->f6i_list, nh_list) in __nexthop_replace_notify()
2232 static void nexthop_replace_notify(struct net *net, struct nexthop *nh, in nexthop_replace_notify() argument
2237 __nexthop_replace_notify(net, nh, info); in nexthop_replace_notify()
2239 list_for_each_entry(nhge, &nh->grp_list, nh_list) in nexthop_replace_notify()
2316 struct nexthop *nh; in insert_nexthop() local
2324 nh = rb_entry(parent, struct nexthop, rb_node); in insert_nexthop()
2325 if (new_id < nh->id) { in insert_nexthop()
2327 } else if (new_id > nh->id) { in insert_nexthop()
2330 rc = replace_nexthop(net, nh, new_nh, cfg, extack); in insert_nexthop()
2332 new_nh = nh; /* send notification with old nh */ in insert_nexthop()
2422 struct nexthop *nh; in flush_all_nexthops() local
2425 nh = rb_entry(node, struct nexthop, rb_node); in flush_all_nexthops()
2426 remove_nexthop(net, nh, NULL); in flush_all_nexthops()
2438 struct nexthop *nh; in nexthop_create_group() local
2445 nh = nexthop_alloc(); in nexthop_create_group()
2446 if (!nh) in nexthop_create_group()
2449 nh->is_group = 1; in nexthop_create_group()
2453 kfree(nh); in nexthop_create_group()
2461 kfree(nh); in nexthop_create_group()
2480 nhg->nh_entries[i].nh = nhe; in nexthop_create_group()
2483 nhg->nh_entries[i].nh_parent = nh; in nexthop_create_group()
2512 rcu_assign_pointer(nh->nh_grp, nhg); in nexthop_create_group()
2514 return nh; in nexthop_create_group()
2519 nexthop_put(nhg->nh_entries[i].nh); in nexthop_create_group()
2524 kfree(nh); in nexthop_create_group()
2529 static int nh_create_ipv4(struct net *net, struct nexthop *nh, in nh_create_ipv4() argument
2558 nh->nh_flags = fib_nh->fib_nh_flags; in nh_create_ipv4()
2568 static int nh_create_ipv6(struct net *net, struct nexthop *nh, in nh_create_ipv6() argument
2597 nh->nh_flags = fib6_nh->fib_nh_flags; in nh_create_ipv6()
2607 struct nexthop *nh; in nexthop_create() local
2610 nh = nexthop_alloc(); in nexthop_create()
2611 if (!nh) in nexthop_create()
2616 kfree(nh); in nexthop_create()
2620 nh->nh_flags = cfg->nh_flags; in nexthop_create()
2621 nh->net = net; in nexthop_create()
2623 nhi->nh_parent = nh; in nexthop_create()
2637 err = nh_create_ipv4(net, nh, nhi, cfg, extack); in nexthop_create()
2640 err = nh_create_ipv6(net, nh, nhi, cfg, extack); in nexthop_create()
2646 kfree(nh); in nexthop_create()
2654 rcu_assign_pointer(nh->nh_info, nhi); in nexthop_create()
2656 return nh; in nexthop_create()
2663 struct nexthop *nh; in nexthop_add() local
2680 nh = nexthop_create_group(net, cfg); in nexthop_add()
2682 nh = nexthop_create(net, cfg, extack); in nexthop_add()
2684 if (IS_ERR(nh)) in nexthop_add()
2685 return nh; in nexthop_add()
2687 refcount_set(&nh->refcnt, 1); in nexthop_add()
2688 nh->id = cfg->nh_id; in nexthop_add()
2689 nh->protocol = cfg->nh_protocol; in nexthop_add()
2690 nh->net = net; in nexthop_add()
2692 err = insert_nexthop(net, nh, cfg, extack); in nexthop_add()
2694 __remove_nexthop(net, nh, NULL); in nexthop_add()
2695 nexthop_put(nh); in nexthop_add()
2696 nh = ERR_PTR(err); in nexthop_add()
2699 return nh; in nexthop_add()
2956 struct nexthop *nh; in rtm_new_nexthop() local
2961 nh = nexthop_add(net, &cfg, extack); in rtm_new_nexthop()
2962 if (IS_ERR(nh)) in rtm_new_nexthop()
2963 err = PTR_ERR(nh); in rtm_new_nexthop()
3019 struct nexthop *nh; in rtm_del_nexthop() local
3027 nh = nexthop_find_by_id(net, id); in rtm_del_nexthop()
3028 if (!nh) in rtm_del_nexthop()
3031 remove_nexthop(net, nh, &nlinfo); in rtm_del_nexthop()
3042 struct nexthop *nh; in rtm_get_nexthop() local
3056 nh = nexthop_find_by_id(net, id); in rtm_get_nexthop()
3057 if (!nh) in rtm_get_nexthop()
3060 err = nh_fill_node(skb, nh, RTM_NEWNEXTHOP, NETLINK_CB(in_skb).portid, in rtm_get_nexthop()
3084 static bool nh_dump_filtered(struct nexthop *nh, in nh_dump_filtered() argument
3090 if (filter->group_filter && !nh->is_group) in nh_dump_filtered()
3096 if (nh->is_group) in nh_dump_filtered()
3099 nhi = rtnl_dereference(nh->nh_info); in nh_dump_filtered()
3191 struct nexthop *nh, void *data), in rtm_dump_walk_nexthops() argument
3200 struct nexthop *nh; in rtm_dump_walk_nexthops() local
3202 nh = rb_entry(node, struct nexthop, rb_node); in rtm_dump_walk_nexthops()
3203 if (nh->id < s_idx) in rtm_dump_walk_nexthops()
3206 ctx->idx = nh->id; in rtm_dump_walk_nexthops()
3207 err = nh_cb(skb, cb, nh, data); in rtm_dump_walk_nexthops()
3216 struct nexthop *nh, void *data) in rtm_dump_nexthop_cb() argument
3221 if (nh_dump_filtered(nh, filter, nhm->nh_family)) in rtm_dump_nexthop_cb()
3224 return nh_fill_node(skb, nh, RTM_NEWNEXTHOP, in rtm_dump_nexthop_cb()
3259 struct nexthop *nh; in nexthop_find_group_resilient() local
3261 nh = nexthop_find_by_id(net, id); in nexthop_find_group_resilient()
3262 if (!nh) in nexthop_find_group_resilient()
3265 if (!nh->is_group) { in nexthop_find_group_resilient()
3270 nhg = rtnl_dereference(nh->nh_grp); in nexthop_find_group_resilient()
3276 return nh; in nexthop_find_group_resilient()
3337 struct rtm_dump_nh_ctx nh; member
3357 struct nexthop *nh, in rtm_dump_nexthop_bucket_nh() argument
3367 nhg = rtnl_dereference(nh->nh_grp); in rtm_dump_nexthop_bucket_nh()
3377 if (nh_dump_filtered(nhge->nh, &dd->filter, nhm->nh_family)) in rtm_dump_nexthop_bucket_nh()
3381 dd->filter.res_bucket_nh_id != nhge->nh->id) in rtm_dump_nexthop_bucket_nh()
3385 err = nh_fill_res_bucket(skb, nh, bucket, bucket_index, in rtm_dump_nexthop_bucket_nh()
3400 struct nexthop *nh, void *data) in rtm_dump_nexthop_bucket_cb() argument
3405 if (!nh->is_group) in rtm_dump_nexthop_bucket_cb()
3408 nhg = rtnl_dereference(nh->nh_grp); in rtm_dump_nexthop_bucket_cb()
3412 return rtm_dump_nexthop_bucket_nh(skb, cb, nh, dd); in rtm_dump_nexthop_bucket_cb()
3422 struct nexthop *nh; in rtm_dump_nexthop_bucket() local
3430 nh = nexthop_find_group_resilient(net, dd.filter.nh_id, in rtm_dump_nexthop_bucket()
3432 if (IS_ERR(nh)) in rtm_dump_nexthop_bucket()
3433 return PTR_ERR(nh); in rtm_dump_nexthop_bucket()
3434 err = rtm_dump_nexthop_bucket_nh(skb, cb, nh, &dd); in rtm_dump_nexthop_bucket()
3438 err = rtm_dump_walk_nexthops(skb, cb, root, &ctx->nh, in rtm_dump_nexthop_bucket()
3511 struct nexthop *nh; in rtm_get_nexthop_bucket() local
3520 nh = nexthop_find_group_resilient(net, id, extack); in rtm_get_nexthop_bucket()
3521 if (IS_ERR(nh)) in rtm_get_nexthop_bucket()
3522 return PTR_ERR(nh); in rtm_get_nexthop_bucket()
3524 nhg = rtnl_dereference(nh->nh_grp); in rtm_get_nexthop_bucket()
3535 err = nh_fill_res_bucket(skb, nh, &res_table->nh_buckets[bucket_index], in rtm_get_nexthop_bucket()
3606 struct nexthop *nh; in nexthops_dump() local
3608 nh = rb_entry(node, struct nexthop, rb_node); in nexthops_dump()
3609 err = call_nexthop_notifier(nb, net, event_type, nh, extack); in nexthops_dump()