190792Sgshapiro// SPDX-License-Identifier: GPL-2.0 2132943Sgshapiro#include <linux/rtnetlink.h> 390792Sgshapiro#include <linux/notifier.h> 490792Sgshapiro#include <linux/socket.h> 590792Sgshapiro#include <linux/kernel.h> 690792Sgshapiro#include <linux/export.h> 790792Sgshapiro#include <net/net_namespace.h> 890792Sgshapiro#include <net/fib_notifier.h> 990792Sgshapiro#include <net/ip_fib.h> 1090792Sgshapiro 1190792Sgshapiroint call_fib4_notifier(struct notifier_block *nb, 1290792Sgshapiro enum fib_event_type event_type, 1390792Sgshapiro struct fib_notifier_info *info) 1490792Sgshapiro{ 15157001Sgshapiro info->family = AF_INET; 1690792Sgshapiro return call_fib_notifier(nb, event_type, info); 1790792Sgshapiro} 1890792Sgshapiro 1990792Sgshapiroint call_fib4_notifiers(struct net *net, enum fib_event_type event_type, 20157001Sgshapiro struct fib_notifier_info *info) 2190792Sgshapiro{ 2290792Sgshapiro ASSERT_RTNL(); 2390792Sgshapiro 2490792Sgshapiro info->family = AF_INET; 2590792Sgshapiro net->ipv4.fib_seq++; 2690792Sgshapiro return call_fib_notifiers(net, event_type, info); 27120256Sgshapiro} 28120256Sgshapiro 29120256Sgshapirostatic unsigned int fib4_seq_read(struct net *net) 30120256Sgshapiro{ 31120256Sgshapiro ASSERT_RTNL(); 32120256Sgshapiro 3390792Sgshapiro return net->ipv4.fib_seq + fib4_rules_seq_read(net); 3490792Sgshapiro} 3590792Sgshapiro 3690792Sgshapirostatic int fib4_dump(struct net *net, struct notifier_block *nb, 3790792Sgshapiro struct netlink_ext_ack *extack) 3890792Sgshapiro{ 3990792Sgshapiro int err; 4090792Sgshapiro 4190792Sgshapiro err = fib4_rules_dump(net, nb, extack); 4290792Sgshapiro if (err) 4390792Sgshapiro return err; 4490792Sgshapiro 4590792Sgshapiro return fib_notify(net, nb, extack); 4690792Sgshapiro} 4790792Sgshapiro 4890792Sgshapirostatic const struct fib_notifier_ops fib4_notifier_ops_template = { 4990792Sgshapiro .family = AF_INET, 5090792Sgshapiro .fib_seq_read = fib4_seq_read, 5190792Sgshapiro .fib_dump = fib4_dump, 5290792Sgshapiro .owner = THIS_MODULE, 5390792Sgshapiro}; 5490792Sgshapiro 5590792Sgshapiroint __net_init fib4_notifier_init(struct net *net) 5690792Sgshapiro{ 5790792Sgshapiro struct fib_notifier_ops *ops; 5890792Sgshapiro 5990792Sgshapiro net->ipv4.fib_seq = 0; 6090792Sgshapiro 6190792Sgshapiro ops = fib_notifier_ops_register(&fib4_notifier_ops_template, net); 6290792Sgshapiro if (IS_ERR(ops)) 6390792Sgshapiro return PTR_ERR(ops); 6490792Sgshapiro net->ipv4.notifier_ops = ops; 6590792Sgshapiro 66141858Sgshapiro return 0; 6790792Sgshapiro} 6890792Sgshapiro 6990792Sgshapirovoid __net_exit fib4_notifier_exit(struct net *net) 7090792Sgshapiro{ 7190792Sgshapiro fib_notifier_ops_unregister(net->ipv4.notifier_ops); 7290792Sgshapiro} 7390792Sgshapiro