-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ipv4: fib: Move FIB notification code to a separate file
Most of the code concerned with the FIB notification chain currently resides in fib_trie.c, but this isn't really appropriate, as the FIB notification chain is also used for FIB rules. Therefore, it makes sense to move the common FIB notification code to a separate file and have it export the relevant functions, which can be invoked by its different users (e.g., fib_trie.c, fib_rules.c). Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: Jiri Pirko <jiri@mellanox.com> Acked-by: David Ahern <dsa@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
- Loading branch information
Ido Schimmel
authored and
David S. Miller
committed
Mar 10, 2017
1 parent
71e8727
commit c024389
Showing
5 changed files
with
113 additions
and
96 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
#include <linux/rtnetlink.h> | ||
#include <linux/notifier.h> | ||
#include <linux/rcupdate.h> | ||
#include <linux/kernel.h> | ||
#include <net/net_namespace.h> | ||
#include <net/netns/ipv4.h> | ||
#include <net/ip_fib.h> | ||
|
||
static ATOMIC_NOTIFIER_HEAD(fib_chain); | ||
|
||
int call_fib_notifier(struct notifier_block *nb, struct net *net, | ||
enum fib_event_type event_type, | ||
struct fib_notifier_info *info) | ||
{ | ||
info->net = net; | ||
return nb->notifier_call(nb, event_type, info); | ||
} | ||
|
||
int call_fib_notifiers(struct net *net, enum fib_event_type event_type, | ||
struct fib_notifier_info *info) | ||
{ | ||
net->ipv4.fib_seq++; | ||
info->net = net; | ||
return atomic_notifier_call_chain(&fib_chain, event_type, info); | ||
} | ||
|
||
static unsigned int fib_seq_sum(void) | ||
{ | ||
unsigned int fib_seq = 0; | ||
struct net *net; | ||
|
||
rtnl_lock(); | ||
for_each_net(net) | ||
fib_seq += net->ipv4.fib_seq; | ||
rtnl_unlock(); | ||
|
||
return fib_seq; | ||
} | ||
|
||
static bool fib_dump_is_consistent(struct notifier_block *nb, | ||
void (*cb)(struct notifier_block *nb), | ||
unsigned int fib_seq) | ||
{ | ||
atomic_notifier_chain_register(&fib_chain, nb); | ||
if (fib_seq == fib_seq_sum()) | ||
return true; | ||
atomic_notifier_chain_unregister(&fib_chain, nb); | ||
if (cb) | ||
cb(nb); | ||
return false; | ||
} | ||
|
||
#define FIB_DUMP_MAX_RETRIES 5 | ||
int register_fib_notifier(struct notifier_block *nb, | ||
void (*cb)(struct notifier_block *nb)) | ||
{ | ||
int retries = 0; | ||
|
||
do { | ||
unsigned int fib_seq = fib_seq_sum(); | ||
struct net *net; | ||
|
||
/* Mutex semantics guarantee that every change done to | ||
* FIB tries before we read the change sequence counter | ||
* is now visible to us. | ||
*/ | ||
rcu_read_lock(); | ||
for_each_net_rcu(net) { | ||
fib_rules_notify(net, nb, FIB_EVENT_RULE_ADD); | ||
fib_notify(net, nb, FIB_EVENT_ENTRY_ADD); | ||
} | ||
rcu_read_unlock(); | ||
|
||
if (fib_dump_is_consistent(nb, cb, fib_seq)) | ||
return 0; | ||
} while (++retries < FIB_DUMP_MAX_RETRIES); | ||
|
||
return -EBUSY; | ||
} | ||
EXPORT_SYMBOL(register_fib_notifier); | ||
|
||
int unregister_fib_notifier(struct notifier_block *nb) | ||
{ | ||
return atomic_notifier_chain_unregister(&fib_chain, nb); | ||
} | ||
EXPORT_SYMBOL(unregister_fib_notifier); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters