xref: /openbmc/linux/net/ipv4/fib_notifier.c (revision 3d5f12d4)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2c0243892SIdo Schimmel #include <linux/rtnetlink.h>
3c0243892SIdo Schimmel #include <linux/notifier.h>
404b1d4e5SIdo Schimmel #include <linux/socket.h>
5c0243892SIdo Schimmel #include <linux/kernel.h>
6864150dfSIdo Schimmel #include <linux/export.h>
7c0243892SIdo Schimmel #include <net/net_namespace.h>
804b1d4e5SIdo Schimmel #include <net/fib_notifier.h>
9c0243892SIdo Schimmel #include <net/ip_fib.h>
10c0243892SIdo Schimmel 
call_fib4_notifier(struct notifier_block * nb,enum fib_event_type event_type,struct fib_notifier_info * info)117c550dafSJiri Pirko int call_fib4_notifier(struct notifier_block *nb,
12c0243892SIdo Schimmel 		       enum fib_event_type event_type,
13c0243892SIdo Schimmel 		       struct fib_notifier_info *info)
14c0243892SIdo Schimmel {
1504b1d4e5SIdo Schimmel 	info->family = AF_INET;
167c550dafSJiri Pirko 	return call_fib_notifier(nb, event_type, info);
17c0243892SIdo Schimmel }
18c0243892SIdo Schimmel 
call_fib4_notifiers(struct net * net,enum fib_event_type event_type,struct fib_notifier_info * info)1904b1d4e5SIdo Schimmel int call_fib4_notifiers(struct net *net, enum fib_event_type event_type,
20c0243892SIdo Schimmel 			struct fib_notifier_info *info)
21c0243892SIdo Schimmel {
2204b1d4e5SIdo Schimmel 	ASSERT_RTNL();
2304b1d4e5SIdo Schimmel 
2404b1d4e5SIdo Schimmel 	info->family = AF_INET;
25c0243892SIdo Schimmel 	net->ipv4.fib_seq++;
2604b1d4e5SIdo Schimmel 	return call_fib_notifiers(net, event_type, info);
27c0243892SIdo Schimmel }
28c0243892SIdo Schimmel 
fib4_seq_read(struct net * net)2904b1d4e5SIdo Schimmel static unsigned int fib4_seq_read(struct net *net)
30c0243892SIdo Schimmel {
3104b1d4e5SIdo Schimmel 	ASSERT_RTNL();
32c0243892SIdo Schimmel 
331b2a4440SIdo Schimmel 	return net->ipv4.fib_seq + fib4_rules_seq_read(net);
34c0243892SIdo Schimmel }
35c0243892SIdo Schimmel 
fib4_dump(struct net * net,struct notifier_block * nb,struct netlink_ext_ack * extack)36b7a59557SJiri Pirko static int fib4_dump(struct net *net, struct notifier_block *nb,
37b7a59557SJiri Pirko 		     struct netlink_ext_ack *extack)
38c0243892SIdo Schimmel {
391b2a4440SIdo Schimmel 	int err;
401b2a4440SIdo Schimmel 
41b7a59557SJiri Pirko 	err = fib4_rules_dump(net, nb, extack);
421b2a4440SIdo Schimmel 	if (err)
431b2a4440SIdo Schimmel 		return err;
441b2a4440SIdo Schimmel 
45b7a59557SJiri Pirko 	return fib_notify(net, nb, extack);
46c0243892SIdo Schimmel }
47c0243892SIdo Schimmel 
4804b1d4e5SIdo Schimmel static const struct fib_notifier_ops fib4_notifier_ops_template = {
4904b1d4e5SIdo Schimmel 	.family		= AF_INET,
5004b1d4e5SIdo Schimmel 	.fib_seq_read	= fib4_seq_read,
5104b1d4e5SIdo Schimmel 	.fib_dump	= fib4_dump,
52864150dfSIdo Schimmel 	.owner		= THIS_MODULE,
5304b1d4e5SIdo Schimmel };
5404b1d4e5SIdo Schimmel 
fib4_notifier_init(struct net * net)5504b1d4e5SIdo Schimmel int __net_init fib4_notifier_init(struct net *net)
56c0243892SIdo Schimmel {
5704b1d4e5SIdo Schimmel 	struct fib_notifier_ops *ops;
5804b1d4e5SIdo Schimmel 
5904b1d4e5SIdo Schimmel 	net->ipv4.fib_seq = 0;
6004b1d4e5SIdo Schimmel 
6104b1d4e5SIdo Schimmel 	ops = fib_notifier_ops_register(&fib4_notifier_ops_template, net);
6204b1d4e5SIdo Schimmel 	if (IS_ERR(ops))
6304b1d4e5SIdo Schimmel 		return PTR_ERR(ops);
6404b1d4e5SIdo Schimmel 	net->ipv4.notifier_ops = ops;
6504b1d4e5SIdo Schimmel 
6604b1d4e5SIdo Schimmel 	return 0;
67c0243892SIdo Schimmel }
6804b1d4e5SIdo Schimmel 
fib4_notifier_exit(struct net * net)6904b1d4e5SIdo Schimmel void __net_exit fib4_notifier_exit(struct net *net)
7004b1d4e5SIdo Schimmel {
7104b1d4e5SIdo Schimmel 	fib_notifier_ops_unregister(net->ipv4.notifier_ops);
7204b1d4e5SIdo Schimmel }
73