xref: /linux/net/ipv6/fib6_notifier.c (revision 91a4855d6c03e770e42f17c798a36a3c46e63de2) !
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/notifier.h>
3 #include <linux/socket.h>
4 #include <linux/kernel.h>
5 #include <linux/export.h>
6 #include <net/net_namespace.h>
7 #include <net/fib_notifier.h>
8 #include <net/netns/ipv6.h>
9 #include <net/ip6_fib.h>
10 
11 int call_fib6_notifier(struct notifier_block *nb,
12 		       enum fib_event_type event_type,
13 		       struct fib_notifier_info *info)
14 {
15 	info->family = AF_INET6;
16 	return call_fib_notifier(nb, event_type, info);
17 }
18 
19 int call_fib6_notifiers(struct net *net, enum fib_event_type event_type,
20 			struct fib_notifier_info *info)
21 {
22 	info->family = AF_INET6;
23 	return call_fib_notifiers(net, event_type, info);
24 }
25 
26 static unsigned int fib6_seq_read(const struct net *net)
27 {
28 	return fib6_tables_seq_read(net) + fib6_rules_seq_read(net);
29 }
30 
31 static int fib6_dump(struct net *net, struct notifier_block *nb,
32 		     struct netlink_ext_ack *extack)
33 {
34 	int err;
35 
36 	err = fib6_rules_dump(net, nb, extack);
37 	if (err)
38 		return err;
39 
40 	return fib6_tables_dump(net, nb, extack);
41 }
42 
43 static const struct fib_notifier_ops fib6_notifier_ops_template = {
44 	.family		= AF_INET6,
45 	.fib_seq_read	= fib6_seq_read,
46 	.fib_dump	= fib6_dump,
47 	.owner		= THIS_MODULE,
48 };
49 
50 int __net_init fib6_notifier_init(struct net *net)
51 {
52 	struct fib_notifier_ops *ops;
53 
54 	ops = fib_notifier_ops_register(&fib6_notifier_ops_template, net);
55 	if (IS_ERR(ops))
56 		return PTR_ERR(ops);
57 	net->ipv6.notifier_ops = ops;
58 
59 	return 0;
60 }
61 
62 void __net_exit fib6_notifier_exit(struct net *net)
63 {
64 	fib_notifier_ops_unregister(net->ipv6.notifier_ops);
65 }
66