/* The callers should hold f6i->fib6_table->tb6_lock if a route has ever *beenaddedtoatablebefore.
*/ staticinlinevoid fib6_clean_expires(struct fib6_info *f6i)
{
f6i->fib6_flags &= ~RTF_EXPIRES;
f6i->expires = 0;
}
/* The callers should hold f6i->fib6_table->tb6_lock if a route has ever *beenaddedtoatablebefore.
*/ staticinlinevoid fib6_set_expires(struct fib6_info *f6i, unsignedlong expires)
{
f6i->expires = expires;
f6i->fib6_flags |= RTF_EXPIRES;
}
/* Function to safely get fn->fn_sernum for passed in rt *andstoreresultinpassedincookie. *Returntrueifwecangetcookiesafely *Returnfalseifnot
*/ staticinlinebool fib6_get_cookie_safe(conststruct fib6_info *f6i,
u32 *cookie)
{ struct fib6_node *fn; bool status = false;
fn = rcu_dereference(f6i->fib6_node);
if (fn) {
*cookie = READ_ONCE(fn->fn_sernum); /* pairs with smp_wmb() in __fib6_update_sernum_upto_root() */
smp_rmb();
status = true;
}
struct fib6_entry_notifier_info { struct fib_notifier_info info; /* must be first */ struct fib6_info *rt; unsignedint nsiblings;
};
/* *exportedfunctions
*/
struct fib6_table *fib6_get_table(struct net *net, u32 id); struct fib6_table *fib6_new_table(struct net *net, u32 id); struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6, conststruct sk_buff *skb, int flags, pol_lookup_t lookup);
/* called with rcu lock held; can return error pointer *callerneedstoselectpath
*/ int fib6_lookup(struct net *net, int oif, struct flowi6 *fl6, struct fib6_result *res, int flags);
/* called with rcu lock held; caller needs to select path */ int fib6_table_lookup(struct net *net, struct fib6_table *table, int oif, struct flowi6 *fl6, struct fib6_result *res, int strict);
void fib6_select_path(conststruct net *net, struct fib6_result *res, struct flowi6 *fl6, int oif, bool have_oif_match, conststruct sk_buff *skb, int strict); struct fib6_node *fib6_node_lookup(struct fib6_node *root, conststruct in6_addr *daddr, conststruct in6_addr *saddr);
struct fib6_node *fib6_locate(struct fib6_node *root, conststruct in6_addr *daddr, int dst_len, conststruct in6_addr *saddr, int src_len, bool exact_match);
void fib6_clean_all(struct net *net, int (*func)(struct fib6_info *, void *arg), void *arg); void fib6_clean_all_skip_notify(struct net *net, int (*func)(struct fib6_info *, void *arg), void *arg);
int fib6_add(struct fib6_node *root, struct fib6_info *rt, struct nl_info *info, struct netlink_ext_ack *extack); int fib6_del(struct fib6_info *rt, struct nl_info *info);
int call_fib6_entry_notifiers(struct net *net, enum fib_event_type event_type, struct fib6_info *rt, struct netlink_ext_ack *extack); int call_fib6_multipath_entry_notifiers(struct net *net, enum fib_event_type event_type, struct fib6_info *rt, unsignedint nsiblings, struct netlink_ext_ack *extack); int call_fib6_entry_notifiers_replace(struct net *net, struct fib6_info *rt); void fib6_rt_update(struct net *net, struct fib6_info *rt, struct nl_info *info); void inet6_rt_notify(int event, struct fib6_info *rt, struct nl_info *info, unsignedint flags);
void fib6_run_gc(unsignedlong expires, struct net *net, bool force);
void fib6_gc_cleanup(void);
int fib6_init(void);
/* Add the route to the gc list if it is not already there * *Thecallersshouldholdf6i->fib6_table->tb6_lock.
*/ staticinlinevoid fib6_add_gc_list(struct fib6_info *f6i)
{ /* If fib6_node is null, the f6i is not in (or removed from) the *table. * *Thereisagapbetweenfindingthef6ifromthetableand *callingthisfunctionwithouttheprotectionofthetb6_lock. *Thischeckmakessurethef6iisnotaddedtothegclistwhen *itisnotonthetable.
*/ if (!rcu_dereference_protected(f6i->fib6_node,
lockdep_is_held(&f6i->fib6_table->tb6_lock))) return;
if (hlist_unhashed(&f6i->gc_link))
hlist_add_head(&f6i->gc_link, &f6i->fib6_table->tb6_gc_hlist);
}
/* Remove the route from the gc list if it is on the list. * *Thecallersshouldholdf6i->fib6_table->tb6_lock.
*/ staticinlinevoid fib6_remove_gc_list(struct fib6_info *f6i)
{ if (!hlist_unhashed(&f6i->gc_link))
hlist_del_init(&f6i->gc_link);
}
int call_fib6_notifier(struct notifier_block *nb, enum fib_event_type event_type, struct fib_notifier_info *info); int call_fib6_notifiers(struct net *net, enum fib_event_type event_type, struct fib_notifier_info *info);
int __net_init fib6_notifier_init(struct net *net); void __net_exit fib6_notifier_exit(struct net *net);
unsignedint fib6_tables_seq_read(conststruct net *net); int fib6_tables_dump(struct net *net, struct notifier_block *nb, struct netlink_ext_ack *extack);
void fib6_update_sernum(struct net *net, struct fib6_info *rt); void fib6_update_sernum_upto_root(struct net *net, struct fib6_info *rt); void fib6_update_sernum_stub(struct net *net, struct fib6_info *f6i);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.