mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-03 04:46:56 +07:00
1b2a444085
Unlike the routing tables, the FIB rules share a common core, so instead of replicating the same logic for each address family we can simply dump the rules and send notifications from the core itself. To protect the integrity of the dump, a rules-specific sequence counter is added for each address family and incremented whenever a rule is added or deleted (under RTNL). Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
72 lines
1.5 KiB
C
72 lines
1.5 KiB
C
#include <linux/rtnetlink.h>
|
|
#include <linux/notifier.h>
|
|
#include <linux/socket.h>
|
|
#include <linux/kernel.h>
|
|
#include <net/net_namespace.h>
|
|
#include <net/fib_notifier.h>
|
|
#include <net/netns/ipv4.h>
|
|
#include <net/ip_fib.h>
|
|
|
|
int call_fib4_notifier(struct notifier_block *nb, struct net *net,
|
|
enum fib_event_type event_type,
|
|
struct fib_notifier_info *info)
|
|
{
|
|
info->family = AF_INET;
|
|
return call_fib_notifier(nb, net, event_type, info);
|
|
}
|
|
|
|
int call_fib4_notifiers(struct net *net, enum fib_event_type event_type,
|
|
struct fib_notifier_info *info)
|
|
{
|
|
ASSERT_RTNL();
|
|
|
|
info->family = AF_INET;
|
|
net->ipv4.fib_seq++;
|
|
return call_fib_notifiers(net, event_type, info);
|
|
}
|
|
|
|
static unsigned int fib4_seq_read(struct net *net)
|
|
{
|
|
ASSERT_RTNL();
|
|
|
|
return net->ipv4.fib_seq + fib4_rules_seq_read(net);
|
|
}
|
|
|
|
static int fib4_dump(struct net *net, struct notifier_block *nb)
|
|
{
|
|
int err;
|
|
|
|
err = fib4_rules_dump(net, nb);
|
|
if (err)
|
|
return err;
|
|
|
|
fib_notify(net, nb);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const struct fib_notifier_ops fib4_notifier_ops_template = {
|
|
.family = AF_INET,
|
|
.fib_seq_read = fib4_seq_read,
|
|
.fib_dump = fib4_dump,
|
|
};
|
|
|
|
int __net_init fib4_notifier_init(struct net *net)
|
|
{
|
|
struct fib_notifier_ops *ops;
|
|
|
|
net->ipv4.fib_seq = 0;
|
|
|
|
ops = fib_notifier_ops_register(&fib4_notifier_ops_template, net);
|
|
if (IS_ERR(ops))
|
|
return PTR_ERR(ops);
|
|
net->ipv4.notifier_ops = ops;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void __net_exit fib4_notifier_exit(struct net *net)
|
|
{
|
|
fib_notifier_ops_unregister(net->ipv4.notifier_ops);
|
|
}
|