cregit-Linux how code gets into the kernel

Release 4.15 net/core/fib_notifier.c

Directory: net/core
#include <linux/rtnetlink.h>
#include <linux/notifier.h>
#include <linux/rcupdate.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <net/net_namespace.h>
#include <net/fib_notifier.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); }

Contributors

PersonTokensPropCommitsCommitProp
Ido Schimmel42100.00%1100.00%
Total42100.00%1100.00%

EXPORT_SYMBOL(call_fib_notifier);
int call_fib_notifiers(struct net *net, enum fib_event_type event_type, struct fib_notifier_info *info) { info->net = net; return atomic_notifier_call_chain(&fib_chain, event_type, info); }

Contributors

PersonTokensPropCommitsCommitProp
Ido Schimmel36100.00%1100.00%
Total36100.00%1100.00%

EXPORT_SYMBOL(call_fib_notifiers);
static unsigned int fib_seq_sum(void) { struct fib_notifier_ops *ops; unsigned int fib_seq = 0; struct net *net; rtnl_lock(); for_each_net(net) { rcu_read_lock(); list_for_each_entry_rcu(ops, &net->fib_notifier_ops, list) { if (!try_module_get(ops->owner)) continue; fib_seq += ops->fib_seq_read(net); module_put(ops->owner); } rcu_read_unlock(); } rtnl_unlock(); return fib_seq; }

Contributors

PersonTokensPropCommitsCommitProp
Ido Schimmel7691.57%266.67%
Kirill Tkhai78.43%133.33%
Total83100.00%3100.00%


static int fib_net_dump(struct net *net, struct notifier_block *nb) { struct fib_notifier_ops *ops; list_for_each_entry_rcu(ops, &net->fib_notifier_ops, list) { int err; if (!try_module_get(ops->owner)) continue; err = ops->fib_dump(net, nb); module_put(ops->owner); if (err) return err; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Ido Schimmel73100.00%2100.00%
Total73100.00%2100.00%


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; }

Contributors

PersonTokensPropCommitsCommitProp
Ido Schimmel65100.00%1100.00%
Total65100.00%1100.00%

#define FIB_DUMP_MAX_RETRIES 5
int register_fib_notifier(struct notifier_block *nb, void (*cb)(struct notifier_block *nb)) { int retries = 0; int err; do { unsigned int fib_seq = fib_seq_sum(); struct net *net; rcu_read_lock(); for_each_net_rcu(net) { err = fib_net_dump(net, nb); if (err) goto err_fib_net_dump; } rcu_read_unlock(); if (fib_dump_is_consistent(nb, cb, fib_seq)) return 0; } while (++retries < FIB_DUMP_MAX_RETRIES); return -EBUSY; err_fib_net_dump: rcu_read_unlock(); return err; }

Contributors

PersonTokensPropCommitsCommitProp
Ido Schimmel107100.00%1100.00%
Total107100.00%1100.00%

EXPORT_SYMBOL(register_fib_notifier);
int unregister_fib_notifier(struct notifier_block *nb) { return atomic_notifier_chain_unregister(&fib_chain, nb); }

Contributors

PersonTokensPropCommitsCommitProp
Ido Schimmel19100.00%1100.00%
Total19100.00%1100.00%

EXPORT_SYMBOL(unregister_fib_notifier);
static int __fib_notifier_ops_register(struct fib_notifier_ops *ops, struct net *net) { struct fib_notifier_ops *o; list_for_each_entry(o, &net->fib_notifier_ops, list) if (ops->family == o->family) return -EEXIST; list_add_tail_rcu(&ops->list, &net->fib_notifier_ops); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Ido Schimmel59100.00%1100.00%
Total59100.00%1100.00%


struct fib_notifier_ops * fib_notifier_ops_register(const struct fib_notifier_ops *tmpl, struct net *net) { struct fib_notifier_ops *ops; int err; ops = kmemdup(tmpl, sizeof(*ops), GFP_KERNEL); if (!ops) return ERR_PTR(-ENOMEM); err = __fib_notifier_ops_register(ops, net); if (err) goto err_register; return ops; err_register: kfree(ops); return ERR_PTR(err); }

Contributors

PersonTokensPropCommitsCommitProp
Ido Schimmel85100.00%1100.00%
Total85100.00%1100.00%

EXPORT_SYMBOL(fib_notifier_ops_register);
void fib_notifier_ops_unregister(struct fib_notifier_ops *ops) { list_del_rcu(&ops->list); kfree_rcu(ops, rcu); }

Contributors

PersonTokensPropCommitsCommitProp
Ido Schimmel25100.00%1100.00%
Total25100.00%1100.00%

EXPORT_SYMBOL(fib_notifier_ops_unregister);
static int __net_init fib_notifier_net_init(struct net *net) { INIT_LIST_HEAD(&net->fib_notifier_ops); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Ido Schimmel23100.00%1100.00%
Total23100.00%1100.00%


static void __net_exit fib_notifier_net_exit(struct net *net) { WARN_ON_ONCE(!list_empty(&net->fib_notifier_ops)); }

Contributors

PersonTokensPropCommitsCommitProp
Vasily Averin24100.00%1100.00%
Total24100.00%1100.00%

static struct pernet_operations fib_notifier_net_ops = { .init = fib_notifier_net_init, .exit = fib_notifier_net_exit, };
static int __init fib_notifier_init(void) { return register_pernet_subsys(&fib_notifier_net_ops); }

Contributors

PersonTokensPropCommitsCommitProp
Ido Schimmel16100.00%1100.00%
Total16100.00%1100.00%

subsys_initcall(fib_notifier_init);

Overall Contributors

PersonTokensPropCommitsCommitProp
Ido Schimmel70795.15%250.00%
Vasily Averin293.90%125.00%
Kirill Tkhai70.94%125.00%
Total743100.00%4100.00%
Directory: net/core
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.