History

net: fib_notifier: make FIB notifier per-netns

Currently all users of FIB notifier only cares about events in init_net. Later in this patchset, users get interested in other namespaces too. However, for every registered block user is interested only about one namespace. Make the FIB notifier registration per-netns and avoid unnecessary calls of notifier block for other namespaces.

Jiri Pirko committed 7 years ago

Commit 7c550da1 parent a5facc415 files · +78 −105Browse files

Unified · Split

15 files
  1. drivers/net/ethernet/mellanox/mlx5/core/lag_mp.c +2 −5
  2. drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +4 −5
  3. drivers/net/ethernet/rocker/rocker_main.c +3 −6
  4. drivers/net/netdevsim/fib.c +3 −5
  5. include/linux/mroute_base.h +2 −8
  6. include/net/fib_notifier.h +3 −4
  7. include/net/ip6_fib.h +1 −1
  8. include/net/ip_fib.h +1 −1
  9. net/core/fib_notifier.c +39 −48
  10. net/core/fib_rules.c +3 −4
  11. net/ipv4/fib_notifier.c +2 −2
  12. net/ipv4/fib_trie.c +8 −9
  13. net/ipv4/ipmr_base.c +2 −2
  14. net/ipv6/fib6_notifier.c +2 −2
  15. net/ipv6/ip6_fib.c +3 −3
drivers/net/ethernet/mellanox/mlx5/core/lag_mp.c+2−5
@@ -248,9 +248,6 @@ static int mlx5_lag_fib_event(struct notifier_block *nb, · 247 unmodified lines
248 struct net_device *fib_dev;248 struct net_device *fib_dev;
249 struct fib_info *fi;249 struct fib_info *fi;
250 250
251 if (!net_eq(info->net, &init_net))
252 return NOTIFY_DONE;
253
254 if (info->family != AF_INET)251 if (info->family != AF_INET)
255 return NOTIFY_DONE;252 return NOTIFY_DONE;
256 253
@@ -311,7 +308,7 @@ int mlx5_lag_mp_init(struct mlx5_lag *ldev) · 54 unmodified lines
311 return 0;308 return 0;
312 309
313 mp->fib_nb.notifier_call = mlx5_lag_fib_event;310 mp->fib_nb.notifier_call = mlx5_lag_fib_event;
314 err = register_fib_notifier(&mp->fib_nb,311 err = register_fib_notifier(&init_net, &mp->fib_nb,
315 mlx5_lag_fib_event_flush);312 mlx5_lag_fib_event_flush);
316 if (err)313 if (err)
317 mp->fib_nb.notifier_call = NULL;314 mp->fib_nb.notifier_call = NULL;
@@ -326,6 +323,6 @@ void mlx5_lag_mp_cleanup(struct mlx5_lag *ldev) · 8 unmodified lines
326 if (!mp->fib_nb.notifier_call)323 if (!mp->fib_nb.notifier_call)
327 return;324 return;
328 325
329 unregister_fib_notifier(&mp->fib_nb);326 unregister_fib_notifier(&init_net, &mp->fib_nb);
330 mp->fib_nb.notifier_call = NULL;327 mp->fib_nb.notifier_call = NULL;
331}328}
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c+4−5
@@ -6213,7 +6213,7 @@ static int mlxsw_sp_router_fib_rule_event(unsigned long event, · 6212 unmodified lines
6213 rule = fr_info->rule;6213 rule = fr_info->rule;
6214 6214
6215 /* Rule only affects locally generated traffic */6215 /* Rule only affects locally generated traffic */
6216 if (rule->iifindex == info->net->loopback_dev->ifindex)6216 if (rule->iifindex == init_net.loopback_dev->ifindex)
6217 return 0;6217 return 0;
6218 6218
6219 switch (info->family) {6219 switch (info->family) {
@@ -6250,8 +6250,7 @@ static int mlxsw_sp_router_fib_event(struct notifier_block *nb, · 30 unmodified lines
6250 struct mlxsw_sp_router *router;6250 struct mlxsw_sp_router *router;
6251 int err;6251 int err;
6252 6252
6253 if (!net_eq(info->net, &init_net) ||6253 if ((info->family != AF_INET && info->family != AF_INET6 &&
6254 (info->family != AF_INET && info->family != AF_INET6 &&
6255 info->family != RTNL_FAMILY_IPMR &&6254 info->family != RTNL_FAMILY_IPMR &&
6256 info->family != RTNL_FAMILY_IP6MR))6255 info->family != RTNL_FAMILY_IP6MR))
6257 return NOTIFY_DONE;6256 return NOTIFY_DONE;
@@ -8155,7 +8154,7 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp) · 1897 unmodified lines
8155 goto err_dscp_init;8154 goto err_dscp_init;
8156 8155
8157 mlxsw_sp->router->fib_nb.notifier_call = mlxsw_sp_router_fib_event;8156 mlxsw_sp->router->fib_nb.notifier_call = mlxsw_sp_router_fib_event;
8158 err = register_fib_notifier(&mlxsw_sp->router->fib_nb,8157 err = register_fib_notifier(&init_net, &mlxsw_sp->router->fib_nb,
8159 mlxsw_sp_router_fib_dump_flush);8158 mlxsw_sp_router_fib_dump_flush);
8160 if (err)8159 if (err)
8161 goto err_register_fib_notifier;8160 goto err_register_fib_notifier;
@@ -8195,7 +8194,7 @@ err_register_inetaddr_notifier: · 33 unmodified lines
8195 8194
8196void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp)8195void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp)
8197{8196{
8198 unregister_fib_notifier(&mlxsw_sp->router->fib_nb);8197 unregister_fib_notifier(&init_net, &mlxsw_sp->router->fib_nb);
8199 unregister_netevent_notifier(&mlxsw_sp->router->netevent_nb);8198 unregister_netevent_notifier(&mlxsw_sp->router->netevent_nb);
8200 mlxsw_sp_neigh_fini(mlxsw_sp);8199 mlxsw_sp_neigh_fini(mlxsw_sp);
8201 mlxsw_sp_vrs_fini(mlxsw_sp);8200 mlxsw_sp_vrs_fini(mlxsw_sp);
drivers/net/ethernet/rocker/rocker_main.c+3−6
@@ -2189,9 +2189,6 @@ static int rocker_router_fib_event(struct notifier_block *nb, · 2188 unmodified lines
2189 struct rocker_fib_event_work *fib_work;2189 struct rocker_fib_event_work *fib_work;
2190 struct fib_notifier_info *info = ptr;2190 struct fib_notifier_info *info = ptr;
2191 2191
2192 if (!net_eq(info->net, &init_net))
2193 return NOTIFY_DONE;
2194
2195 if (info->family != AF_INET)2192 if (info->family != AF_INET)
2196 return NOTIFY_DONE;2193 return NOTIFY_DONE;
2197 2194
@@ -2994,7 +2991,7 @@ static int rocker_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 796 unmodified lines
2994 * the device, so no need to pass a callback.2991 * the device, so no need to pass a callback.
2995 */2992 */
2996 rocker->fib_nb.notifier_call = rocker_router_fib_event;2993 rocker->fib_nb.notifier_call = rocker_router_fib_event;
2997 err = register_fib_notifier(&rocker->fib_nb, NULL);2994 err = register_fib_notifier(&init_net, &rocker->fib_nb, NULL);
2998 if (err)2995 if (err)
2999 goto err_register_fib_notifier;2996 goto err_register_fib_notifier;
3000 2997
@@ -3021,7 +3018,7 @@ static int rocker_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 20 unmodified lines
3021err_register_switchdev_blocking_notifier:3018err_register_switchdev_blocking_notifier:
3022 unregister_switchdev_notifier(&rocker_switchdev_notifier);3019 unregister_switchdev_notifier(&rocker_switchdev_notifier);
3023err_register_switchdev_notifier:3020err_register_switchdev_notifier:
3024 unregister_fib_notifier(&rocker->fib_nb);3021 unregister_fib_notifier(&init_net, &rocker->fib_nb);
3025err_register_fib_notifier:3022err_register_fib_notifier:
3026 rocker_remove_ports(rocker);3023 rocker_remove_ports(rocker);
3027err_probe_ports:3024err_probe_ports:
@@ -3057,7 +3054,7 @@ static void rocker_remove(struct pci_dev *pdev) · 29 unmodified lines
3057 unregister_switchdev_blocking_notifier(nb);3054 unregister_switchdev_blocking_notifier(nb);
3058 3055
3059 unregister_switchdev_notifier(&rocker_switchdev_notifier);3056 unregister_switchdev_notifier(&rocker_switchdev_notifier);
3060 unregister_fib_notifier(&rocker->fib_nb);3057 unregister_fib_notifier(&init_net, &rocker->fib_nb);
3061 rocker_remove_ports(rocker);3058 rocker_remove_ports(rocker);
3062 rocker_write32(rocker, CONTROL, ROCKER_CONTROL_RESET);3059 rocker_write32(rocker, CONTROL, ROCKER_CONTROL_RESET);
3063 destroy_workqueue(rocker->rocker_owq);3060 destroy_workqueue(rocker->rocker_owq);
drivers/net/netdevsim/fib.c+3−5
@@ -182,9 +182,6 @@ static int nsim_fib_event_nb(struct notifier_block *nb, unsigned long event, · 181 unmodified lines
182 struct fib_notifier_info *info = ptr;182 struct fib_notifier_info *info = ptr;
183 int err = 0;183 int err = 0;
184 184
185 if (!net_eq(info->net, &init_net))
186 return NOTIFY_DONE;
187
188 switch (event) {185 switch (event) {
189 case FIB_EVENT_RULE_ADD: /* fall through */186 case FIB_EVENT_RULE_ADD: /* fall through */
190 case FIB_EVENT_RULE_DEL:187 case FIB_EVENT_RULE_DEL:
@@ -258,7 +255,8 @@ struct nsim_fib_data *nsim_fib_create(struct devlink *devlink) · 67 unmodified lines
258 data->ipv6.rules.max = (u64)-1;255 data->ipv6.rules.max = (u64)-1;
259 256
260 data->fib_nb.notifier_call = nsim_fib_event_nb;257 data->fib_nb.notifier_call = nsim_fib_event_nb;
261 err = register_fib_notifier(&data->fib_nb, nsim_fib_dump_inconsistent);258 err = register_fib_notifier(&init_net, &data->fib_nb,
259 nsim_fib_dump_inconsistent);
262 if (err) {260 if (err) {
263 pr_err("Failed to register fib notifier\n");261 pr_err("Failed to register fib notifier\n");
264 goto err_out;262 goto err_out;
@@ -297,6 +295,6 @@ void nsim_fib_destroy(struct devlink *devlink, struct nsim_fib_data *data) · 32 unmodified lines
297 NSIM_RESOURCE_IPV4_FIB_RULES);295 NSIM_RESOURCE_IPV4_FIB_RULES);
298 devlink_resource_occ_get_unregister(devlink,296 devlink_resource_occ_get_unregister(devlink,
299 NSIM_RESOURCE_IPV4_FIB);297 NSIM_RESOURCE_IPV4_FIB);
300 unregister_fib_notifier(&data->fib_nb);298 unregister_fib_notifier(&init_net, &data->fib_nb);
301 kfree(data);299 kfree(data);
302}300}
include/linux/mroute_base.h+2−8
@@ -47,7 +47,6 @@ struct vif_entry_notifier_info { · 46 unmodified lines
47};47};
48 48
49static inline int mr_call_vif_notifier(struct notifier_block *nb,49static inline int mr_call_vif_notifier(struct notifier_block *nb,
50 struct net *net,
51 unsigned short family,50 unsigned short family,
52 enum fib_event_type event_type,51 enum fib_event_type event_type,
53 struct vif_device *vif,52 struct vif_device *vif,
@@ -56,7 +55,6 @@ static inline int mr_call_vif_notifier(struct notifier_block *nb, · 2 unmodified lines
56 struct vif_entry_notifier_info info = {55 struct vif_entry_notifier_info info = {
57 .info = {56 .info = {
58 .family = family,57 .family = family,
59 .net = net,
60 },58 },
61 .dev = vif->dev,59 .dev = vif->dev,
62 .vif_index = vif_index,60 .vif_index = vif_index,
@@ -64,7 +62,7 @@ static inline int mr_call_vif_notifier(struct notifier_block *nb, · 1 unmodified line
64 .tb_id = tb_id,62 .tb_id = tb_id,
65 };63 };
66 64
67 return call_fib_notifier(nb, net, event_type, &info.info);65 return call_fib_notifier(nb, event_type, &info.info);
68}66}
69 67
70static inline int mr_call_vif_notifiers(struct net *net,68static inline int mr_call_vif_notifiers(struct net *net,
@@ -77,7 +75,6 @@ static inline int mr_call_vif_notifiers(struct net *net, · 6 unmodified lines
77 struct vif_entry_notifier_info info = {75 struct vif_entry_notifier_info info = {
78 .info = {76 .info = {
79 .family = family,77 .family = family,
80 .net = net,
81 },78 },
82 .dev = vif->dev,79 .dev = vif->dev,
83 .vif_index = vif_index,80 .vif_index = vif_index,
@@ -173,7 +170,6 @@ struct mfc_entry_notifier_info { · 89 unmodified lines
173};170};
174 171
175static inline int mr_call_mfc_notifier(struct notifier_block *nb,172static inline int mr_call_mfc_notifier(struct notifier_block *nb,
176 struct net *net,
177 unsigned short family,173 unsigned short family,
178 enum fib_event_type event_type,174 enum fib_event_type event_type,
179 struct mr_mfc *mfc, u32 tb_id)175 struct mr_mfc *mfc, u32 tb_id)
@@ -181,13 +177,12 @@ static inline int mr_call_mfc_notifier(struct notifier_block *nb, · 1 unmodified line
181 struct mfc_entry_notifier_info info = {177 struct mfc_entry_notifier_info info = {
182 .info = {178 .info = {
183 .family = family,179 .family = family,
184 .net = net,
185 },180 },
186 .mfc = mfc,181 .mfc = mfc,
187 .tb_id = tb_id182 .tb_id = tb_id
188 };183 };
189 184
190 return call_fib_notifier(nb, net, event_type, &info.info);185 return call_fib_notifier(nb, event_type, &info.info);
191}186}
192 187
193static inline int mr_call_mfc_notifiers(struct net *net,188static inline int mr_call_mfc_notifiers(struct net *net,
@@ -199,7 +194,6 @@ static inline int mr_call_mfc_notifiers(struct net *net, · 5 unmodified lines
199 struct mfc_entry_notifier_info info = {194 struct mfc_entry_notifier_info info = {
200 .info = {195 .info = {
201 .family = family,196 .family = family,
202 .net = net,
203 },197 },
204 .mfc = mfc,198 .mfc = mfc,
205 .tb_id = tb_id199 .tb_id = tb_id
include/net/fib_notifier.h+3−4
@@ -8,7 +8,6 @@ · 7 unmodified lines
8struct module;8struct module;
9 9
10struct fib_notifier_info {10struct fib_notifier_info {
11 struct net *net;
12 int family;11 int family;
13 struct netlink_ext_ack *extack;12 struct netlink_ext_ack *extack;
14};13};
@@ -35,14 +34,14 @@ struct fib_notifier_ops { · 20 unmodified lines
35 struct rcu_head rcu;34 struct rcu_head rcu;
36};35};
37 36
38int call_fib_notifier(struct notifier_block *nb, struct net *net,37int call_fib_notifier(struct notifier_block *nb,
39 enum fib_event_type event_type,38 enum fib_event_type event_type,
40 struct fib_notifier_info *info);39 struct fib_notifier_info *info);
41int call_fib_notifiers(struct net *net, enum fib_event_type event_type,40int call_fib_notifiers(struct net *net, enum fib_event_type event_type,
42 struct fib_notifier_info *info);41 struct fib_notifier_info *info);
43int register_fib_notifier(struct notifier_block *nb,42int register_fib_notifier(struct net *net, struct notifier_block *nb,
44 void (*cb)(struct notifier_block *nb));43 void (*cb)(struct notifier_block *nb));
45int unregister_fib_notifier(struct notifier_block *nb);44int unregister_fib_notifier(struct net *net, struct notifier_block *nb);
46struct fib_notifier_ops *45struct fib_notifier_ops *
47fib_notifier_ops_register(const struct fib_notifier_ops *tmpl, struct net *net);46fib_notifier_ops_register(const struct fib_notifier_ops *tmpl, struct net *net);
48void fib_notifier_ops_unregister(struct fib_notifier_ops *ops);47void fib_notifier_ops_unregister(struct fib_notifier_ops *ops);
include/net/ip6_fib.h+1−1
@@ -478,7 +478,7 @@ struct ipv6_route_iter { · 477 unmodified lines
478 478
479extern const struct seq_operations ipv6_route_seq_ops;479extern const struct seq_operations ipv6_route_seq_ops;
480 480
481int call_fib6_notifier(struct notifier_block *nb, struct net *net,481int call_fib6_notifier(struct notifier_block *nb,
482 enum fib_event_type event_type,482 enum fib_event_type event_type,
483 struct fib_notifier_info *info);483 struct fib_notifier_info *info);
484int call_fib6_notifiers(struct net *net, enum fib_event_type event_type,484int call_fib6_notifiers(struct net *net, enum fib_event_type event_type,
include/net/ip_fib.h+1−1
@@ -219,7 +219,7 @@ struct fib_nh_notifier_info { · 218 unmodified lines
219 struct fib_nh *fib_nh;219 struct fib_nh *fib_nh;
220};220};
221 221
222int call_fib4_notifier(struct notifier_block *nb, struct net *net,222int call_fib4_notifier(struct notifier_block *nb,
223 enum fib_event_type event_type,223 enum fib_event_type event_type,
224 struct fib_notifier_info *info);224 struct fib_notifier_info *info);
225int call_fib4_notifiers(struct net *net, enum fib_event_type event_type,225int call_fib4_notifiers(struct net *net, enum fib_event_type event_type,
net/core/fib_notifier.c+39−48
@@ -12,17 +12,15 @@ static unsigned int fib_notifier_net_id; · 11 unmodified lines
12 12
13struct fib_notifier_net {13struct fib_notifier_net {
14 struct list_head fib_notifier_ops;14 struct list_head fib_notifier_ops;
15 struct atomic_notifier_head fib_chain;
15};16};
16 17
17static ATOMIC_NOTIFIER_HEAD(fib_chain);18int call_fib_notifier(struct notifier_block *nb,
18
19int call_fib_notifier(struct notifier_block *nb, struct net *net,
20 enum fib_event_type event_type,19 enum fib_event_type event_type,
21 struct fib_notifier_info *info)20 struct fib_notifier_info *info)
22{21{
23 int err;22 int err;
24 23
25 info->net = net;
26 err = nb->notifier_call(nb, event_type, info);24 err = nb->notifier_call(nb, event_type, info);
27 return notifier_to_errno(err);25 return notifier_to_errno(err);
28}26}
@@ -31,35 +29,29 @@ EXPORT_SYMBOL(call_fib_notifier); · 2 unmodified lines
31int call_fib_notifiers(struct net *net, enum fib_event_type event_type,29int call_fib_notifiers(struct net *net, enum fib_event_type event_type,
32 struct fib_notifier_info *info)30 struct fib_notifier_info *info)
33{31{
32 struct fib_notifier_net *fn_net = net_generic(net, fib_notifier_net_id);
34 int err;33 int err;
35 34
36 info->net = net;35 err = atomic_notifier_call_chain(&fn_net->fib_chain, event_type, info);
37 err = atomic_notifier_call_chain(&fib_chain, event_type, info);
38 return notifier_to_errno(err);36 return notifier_to_errno(err);
39}37}
40EXPORT_SYMBOL(call_fib_notifiers);38EXPORT_SYMBOL(call_fib_notifiers);
41 39
42static unsigned int fib_seq_sum(void)40static unsigned int fib_seq_sum(struct net *net)
43{41{
44 struct fib_notifier_net *fn_net;42 struct fib_notifier_net *fn_net = net_generic(net, fib_notifier_net_id);
45 struct fib_notifier_ops *ops;43 struct fib_notifier_ops *ops;
46 unsigned int fib_seq = 0;44 unsigned int fib_seq = 0;
47 struct net *net;
48 45
49 rtnl_lock();46 rtnl_lock();
50 down_read(&net_rwsem);47 rcu_read_lock();
51 for_each_net(net) {48 list_for_each_entry_rcu(ops, &fn_net->fib_notifier_ops, list) {
52 fn_net = net_generic(net, fib_notifier_net_id);49 if (!try_module_get(ops->owner))
53 rcu_read_lock();50 continue;
54 list_for_each_entry_rcu(ops, &fn_net->fib_notifier_ops, list) {51 fib_seq += ops->fib_seq_read(net);
55 if (!try_module_get(ops->owner))52 module_put(ops->owner);
56 continue;
57 fib_seq += ops->fib_seq_read(net);
58 module_put(ops->owner);
59 }
60 rcu_read_unlock();
61 }53 }
62 up_read(&net_rwsem);54 rcu_read_unlock();
63 rtnl_unlock();55 rtnl_unlock();
64 56
65 return fib_seq;57 return fib_seq;
@@ -69,68 +61,66 @@ static int fib_net_dump(struct net *net, struct notifier_block *nb) · 3 unmodified lines
69{61{
70 struct fib_notifier_net *fn_net = net_generic(net, fib_notifier_net_id);62 struct fib_notifier_net *fn_net = net_generic(net, fib_notifier_net_id);
71 struct fib_notifier_ops *ops;63 struct fib_notifier_ops *ops;
64 int err = 0;
72 65
66 rcu_read_lock();
73 list_for_each_entry_rcu(ops, &fn_net->fib_notifier_ops, list) {67 list_for_each_entry_rcu(ops, &fn_net->fib_notifier_ops, list) {
74 int err;
75
76 if (!try_module_get(ops->owner))68 if (!try_module_get(ops->owner))
77 continue;69 continue;
78 err = ops->fib_dump(net, nb);70 err = ops->fib_dump(net, nb);
79 module_put(ops->owner);71 module_put(ops->owner);
80 if (err)72 if (err)
81 return err;73 goto unlock;
82 }74 }
83 75
84 return 0;76unlock:
77 rcu_read_unlock();
78
79 return err;
85}80}
86 81
87static bool fib_dump_is_consistent(struct notifier_block *nb,82static bool fib_dump_is_consistent(struct net *net, struct notifier_block *nb,
88 void (*cb)(struct notifier_block *nb),83 void (*cb)(struct notifier_block *nb),
89 unsigned int fib_seq)84 unsigned int fib_seq)
90{85{
91 atomic_notifier_chain_register(&fib_chain, nb);86 struct fib_notifier_net *fn_net = net_generic(net, fib_notifier_net_id);
92 if (fib_seq == fib_seq_sum())87
88 atomic_notifier_chain_register(&fn_net->fib_chain, nb);
89 if (fib_seq == fib_seq_sum(net))
93 return true;90 return true;
94 atomic_notifier_chain_unregister(&fib_chain, nb);91 atomic_notifier_chain_unregister(&fn_net->fib_chain, nb);
95 if (cb)92 if (cb)
96 cb(nb);93 cb(nb);
97 return false;94 return false;
98}95}
99 96
100#define FIB_DUMP_MAX_RETRIES 597#define FIB_DUMP_MAX_RETRIES 5
101int register_fib_notifier(struct notifier_block *nb,98int register_fib_notifier(struct net *net, struct notifier_block *nb,
102 void (*cb)(struct notifier_block *nb))99 void (*cb)(struct notifier_block *nb))
103{100{
104 int retries = 0;101 int retries = 0;
105 int err;102 int err;
106 103
107 do {104 do {
108 unsigned int fib_seq = fib_seq_sum();105 unsigned int fib_seq = fib_seq_sum(net);
109 struct net *net;106
110 107 err = fib_net_dump(net, nb);
111 rcu_read_lock();108 if (err)
112 for_each_net_rcu(net) {109 return err;
113 err = fib_net_dump(net, nb);110
114 if (err)111 if (fib_dump_is_consistent(net, nb, cb, fib_seq))
115 goto err_fib_net_dump;
116 }
117 rcu_read_unlock();
118
119 if (fib_dump_is_consistent(nb, cb, fib_seq))
120 return 0;112 return 0;
121 } while (++retries < FIB_DUMP_MAX_RETRIES);113 } while (++retries < FIB_DUMP_MAX_RETRIES);
122 114
123 return -EBUSY;115 return -EBUSY;
124
125err_fib_net_dump:
126 rcu_read_unlock();
127 return err;
128}116}
129EXPORT_SYMBOL(register_fib_notifier);117EXPORT_SYMBOL(register_fib_notifier);
130 118
131int unregister_fib_notifier(struct notifier_block *nb)119int unregister_fib_notifier(struct net *net, struct notifier_block *nb)
132{120{
133 return atomic_notifier_chain_unregister(&fib_chain, nb);121 struct fib_notifier_net *fn_net = net_generic(net, fib_notifier_net_id);
122
123 return atomic_notifier_chain_unregister(&fn_net->fib_chain, nb);
134}124}
135EXPORT_SYMBOL(unregister_fib_notifier);125EXPORT_SYMBOL(unregister_fib_notifier);
136 126
@@ -181,6 +171,7 @@ static int __net_init fib_notifier_net_init(struct net *net) · 44 unmodified lines
181 struct fib_notifier_net *fn_net = net_generic(net, fib_notifier_net_id);171 struct fib_notifier_net *fn_net = net_generic(net, fib_notifier_net_id);
182 172
183 INIT_LIST_HEAD(&fn_net->fib_notifier_ops);173 INIT_LIST_HEAD(&fn_net->fib_notifier_ops);
174 ATOMIC_INIT_NOTIFIER_HEAD(&fn_net->fib_chain);
184 return 0;175 return 0;
185}176}
186 177
net/core/fib_rules.c+3−4
@@ -321,7 +321,7 @@ out: · 320 unmodified lines
321}321}
322EXPORT_SYMBOL_GPL(fib_rules_lookup);322EXPORT_SYMBOL_GPL(fib_rules_lookup);
323 323
324static int call_fib_rule_notifier(struct notifier_block *nb, struct net *net,324static int call_fib_rule_notifier(struct notifier_block *nb,
325 enum fib_event_type event_type,325 enum fib_event_type event_type,
326 struct fib_rule *rule, int family)326 struct fib_rule *rule, int family)
327{327{
@@ -330,7 +330,7 @@ static int call_fib_rule_notifier(struct notifier_block *nb, struct net *net, · 2 unmodified lines
330 .rule = rule,330 .rule = rule,
331 };331 };
332 332
333 return call_fib_notifier(nb, net, event_type, &info.info);333 return call_fib_notifier(nb, event_type, &info.info);
334}334}
335 335
336static int call_fib_rule_notifiers(struct net *net,336static int call_fib_rule_notifiers(struct net *net,
@@ -359,8 +359,7 @@ int fib_rules_dump(struct net *net, struct notifier_block *nb, int family) · 22 unmodified lines
359 if (!ops)359 if (!ops)
360 return -EAFNOSUPPORT;360 return -EAFNOSUPPORT;
361 list_for_each_entry_rcu(rule, &ops->rules_list, list)361 list_for_each_entry_rcu(rule, &ops->rules_list, list)
362 call_fib_rule_notifier(nb, net, FIB_EVENT_RULE_ADD, rule,362 call_fib_rule_notifier(nb, FIB_EVENT_RULE_ADD, rule, family);
363 family);
364 rules_ops_put(ops);363 rules_ops_put(ops);
365 364
366 return 0;365 return 0;
net/ipv4/fib_notifier.c+2−2
@@ -9,12 +9,12 @@ · 8 unmodified lines
9#include <net/netns/ipv4.h>9#include <net/netns/ipv4.h>
10#include <net/ip_fib.h>10#include <net/ip_fib.h>
11 11
12int call_fib4_notifier(struct notifier_block *nb, struct net *net,12int call_fib4_notifier(struct notifier_block *nb,
13 enum fib_event_type event_type,13 enum fib_event_type event_type,
14 struct fib_notifier_info *info)14 struct fib_notifier_info *info)
15{15{
16 info->family = AF_INET;16 info->family = AF_INET;
17 return call_fib_notifier(nb, net, event_type, info);17 return call_fib_notifier(nb, event_type, info);
18}18}
19 19
20int call_fib4_notifiers(struct net *net, enum fib_event_type event_type,20int call_fib4_notifiers(struct net *net, enum fib_event_type event_type,
net/ipv4/fib_trie.c+8−9
@@ -74,7 +74,7 @@ · 73 unmodified lines
74#include <trace/events/fib.h>74#include <trace/events/fib.h>
75#include "fib_lookup.h"75#include "fib_lookup.h"
76 76
77static int call_fib_entry_notifier(struct notifier_block *nb, struct net *net,77static int call_fib_entry_notifier(struct notifier_block *nb,
78 enum fib_event_type event_type, u32 dst,78 enum fib_event_type event_type, u32 dst,
79 int dst_len, struct fib_alias *fa)79 int dst_len, struct fib_alias *fa)
80{80{
@@ -86,7 +86,7 @@ static int call_fib_entry_notifier(struct notifier_block *nb, struct net *net, · 5 unmodified lines
86 .type = fa->fa_type,86 .type = fa->fa_type,
87 .tb_id = fa->tb_id,87 .tb_id = fa->tb_id,
88 };88 };
89 return call_fib4_notifier(nb, net, event_type, &info.info);89 return call_fib4_notifier(nb, event_type, &info.info);
90}90}
91 91
92static int call_fib_entry_notifiers(struct net *net,92static int call_fib_entry_notifiers(struct net *net,
@@ -2015,8 +2015,8 @@ void fib_info_notify_update(struct net *net, struct nl_info *info) · 1922 unmodified lines
2015 }2015 }
2016}2016}
2017 2017
2018static void fib_leaf_notify(struct net *net, struct key_vector *l,2018static void fib_leaf_notify(struct key_vector *l, struct fib_table *tb,
2019 struct fib_table *tb, struct notifier_block *nb)2019 struct notifier_block *nb)
2020{2020{
2021 struct fib_alias *fa;2021 struct fib_alias *fa;
2022 2022
@@ -2032,20 +2032,19 @@ static void fib_leaf_notify(struct net *net, struct key_vector *l, · 9 unmodified lines
2032 if (tb->tb_id != fa->tb_id)2032 if (tb->tb_id != fa->tb_id)
2033 continue;2033 continue;
2034 2034
2035 call_fib_entry_notifier(nb, net, FIB_EVENT_ENTRY_ADD, l->key,2035 call_fib_entry_notifier(nb, FIB_EVENT_ENTRY_ADD, l->key,
2036 KEYLENGTH - fa->fa_slen, fa);2036 KEYLENGTH - fa->fa_slen, fa);
2037 }2037 }
2038}2038}
2039 2039
2040static void fib_table_notify(struct net *net, struct fib_table *tb,2040static void fib_table_notify(struct fib_table *tb, struct notifier_block *nb)
2041 struct notifier_block *nb)
2042{2041{
2043 struct trie *t = (struct trie *)tb->tb_data;2042 struct trie *t = (struct trie *)tb->tb_data;
2044 struct key_vector *l, *tp = t->kv;2043 struct key_vector *l, *tp = t->kv;
2045 t_key key = 0;2044 t_key key = 0;
2046 2045
2047 while ((l = leaf_walk_rcu(&tp, key)) != NULL) {2046 while ((l = leaf_walk_rcu(&tp, key)) != NULL) {
2048 fib_leaf_notify(net, l, tb, nb);2047 fib_leaf_notify(l, tb, nb);
2049 2048
2050 key = l->key + 1;2049 key = l->key + 1;
2051 /* stop in case of wrap around */2050 /* stop in case of wrap around */
@@ -2063,7 +2062,7 @@ void fib_notify(struct net *net, struct notifier_block *nb) · 11 unmodified lines
2063 struct fib_table *tb;2062 struct fib_table *tb;
2064 2063
2065 hlist_for_each_entry_rcu(tb, head, tb_hlist)2064 hlist_for_each_entry_rcu(tb, head, tb_hlist)
2066 fib_table_notify(net, tb, nb);2065 fib_table_notify(tb, nb);
2067 }2066 }
2068}2067}
2069 2068
net/ipv4/ipmr_base.c+2−2
@@ -409,7 +409,7 @@ int mr_dump(struct net *net, struct notifier_block *nb, unsigned short family, · 408 unmodified lines
409 if (!v->dev)409 if (!v->dev)
410 continue;410 continue;
411 411
412 mr_call_vif_notifier(nb, net, family,412 mr_call_vif_notifier(nb, family,
413 FIB_EVENT_VIF_ADD,413 FIB_EVENT_VIF_ADD,
414 v, vifi, mrt->id);414 v, vifi, mrt->id);
415 }415 }
@@ -417,7 +417,7 @@ int mr_dump(struct net *net, struct notifier_block *nb, unsigned short family, · 1 unmodified line
417 417
418 /* Notify on table MFC entries */418 /* Notify on table MFC entries */
419 list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list)419 list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list)
420 mr_call_mfc_notifier(nb, net, family,420 mr_call_mfc_notifier(nb, family,
421 FIB_EVENT_ENTRY_ADD,421 FIB_EVENT_ENTRY_ADD,
422 mfc, mrt->id);422 mfc, mrt->id);
423 }423 }
net/ipv6/fib6_notifier.c+2−2
@@ -7,12 +7,12 @@ · 6 unmodified lines
7#include <net/netns/ipv6.h>7#include <net/netns/ipv6.h>
8#include <net/ip6_fib.h>8#include <net/ip6_fib.h>
9 9
10int call_fib6_notifier(struct notifier_block *nb, struct net *net,10int call_fib6_notifier(struct notifier_block *nb,
11 enum fib_event_type event_type,11 enum fib_event_type event_type,
12 struct fib_notifier_info *info)12 struct fib_notifier_info *info)
13{13{
14 info->family = AF_INET6;14 info->family = AF_INET6;
15 return call_fib_notifier(nb, net, event_type, info);15 return call_fib_notifier(nb, event_type, info);
16}16}
17 17
18int call_fib6_notifiers(struct net *net, enum fib_event_type event_type,18int call_fib6_notifiers(struct net *net, enum fib_event_type event_type,
net/ipv6/ip6_fib.c+3−3
@@ -357,7 +357,7 @@ unsigned int fib6_tables_seq_read(struct net *net) · 356 unmodified lines
357 return fib_seq;357 return fib_seq;
358}358}
359 359
360static int call_fib6_entry_notifier(struct notifier_block *nb, struct net *net,360static int call_fib6_entry_notifier(struct notifier_block *nb,
361 enum fib_event_type event_type,361 enum fib_event_type event_type,
362 struct fib6_info *rt)362 struct fib6_info *rt)
363{363{
@@ -365,7 +365,7 @@ static int call_fib6_entry_notifier(struct notifier_block *nb, struct net *net, · 1 unmodified line
365 .rt = rt,365 .rt = rt,
366 };366 };
367 367
368 return call_fib6_notifier(nb, net, event_type, &info.info);368 return call_fib6_notifier(nb, event_type, &info.info);
369}369}
370 370
371int call_fib6_entry_notifiers(struct net *net,371int call_fib6_entry_notifiers(struct net *net,
@@ -407,7 +407,7 @@ static void fib6_rt_dump(struct fib6_info *rt, struct fib6_dump_arg *arg) · 35 unmodified lines
407{407{
408 if (rt == arg->net->ipv6.fib6_null_entry)408 if (rt == arg->net->ipv6.fib6_null_entry)
409 return;409 return;
410 call_fib6_entry_notifier(arg->nb, arg->net, FIB_EVENT_ENTRY_ADD, rt);410 call_fib6_entry_notifier(arg->nb, FIB_EVENT_ENTRY_ADD, rt);
411}411}
412 412
413static int fib6_node_dump(struct fib6_walker *w)413static int fib6_node_dump(struct fib6_walker *w)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t