mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	fib: introduce FIB notification infrastructure
This allows to pass information about added/deleted FIB entries/rules to whoever is interested. This is done in a very similar way as devinet notifies address additions/removals. Signed-off-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									eb523f42d7
								
							
						
					
					
						commit
						b90eb75494
					
				
					 4 changed files with 108 additions and 14 deletions
				
			
		| 
						 | 
					@ -22,6 +22,7 @@
 | 
				
			||||||
#include <net/fib_rules.h>
 | 
					#include <net/fib_rules.h>
 | 
				
			||||||
#include <net/inetpeer.h>
 | 
					#include <net/inetpeer.h>
 | 
				
			||||||
#include <linux/percpu.h>
 | 
					#include <linux/percpu.h>
 | 
				
			||||||
 | 
					#include <linux/notifier.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct fib_config {
 | 
					struct fib_config {
 | 
				
			||||||
	u8			fc_dst_len;
 | 
						u8			fc_dst_len;
 | 
				
			||||||
| 
						 | 
					@ -185,6 +186,33 @@ __be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh);
 | 
				
			||||||
#define FIB_RES_PREFSRC(net, res)	((res).fi->fib_prefsrc ? : \
 | 
					#define FIB_RES_PREFSRC(net, res)	((res).fi->fib_prefsrc ? : \
 | 
				
			||||||
					 FIB_RES_SADDR(net, res))
 | 
										 FIB_RES_SADDR(net, res))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fib_notifier_info {
 | 
				
			||||||
 | 
						struct net *net;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fib_entry_notifier_info {
 | 
				
			||||||
 | 
						struct fib_notifier_info info; /* must be first */
 | 
				
			||||||
 | 
						u32 dst;
 | 
				
			||||||
 | 
						int dst_len;
 | 
				
			||||||
 | 
						struct fib_info *fi;
 | 
				
			||||||
 | 
						u8 tos;
 | 
				
			||||||
 | 
						u8 type;
 | 
				
			||||||
 | 
						u32 tb_id;
 | 
				
			||||||
 | 
						u32 nlflags;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum fib_event_type {
 | 
				
			||||||
 | 
						FIB_EVENT_ENTRY_ADD,
 | 
				
			||||||
 | 
						FIB_EVENT_ENTRY_DEL,
 | 
				
			||||||
 | 
						FIB_EVENT_RULE_ADD,
 | 
				
			||||||
 | 
						FIB_EVENT_RULE_DEL,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int register_fib_notifier(struct notifier_block *nb);
 | 
				
			||||||
 | 
					int unregister_fib_notifier(struct notifier_block *nb);
 | 
				
			||||||
 | 
					int call_fib_notifiers(struct net *net, enum fib_event_type event_type,
 | 
				
			||||||
 | 
							       struct fib_notifier_info *info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct fib_table {
 | 
					struct fib_table {
 | 
				
			||||||
	struct hlist_node	tb_hlist;
 | 
						struct hlist_node	tb_hlist;
 | 
				
			||||||
	u32			tb_id;
 | 
						u32			tb_id;
 | 
				
			||||||
| 
						 | 
					@ -196,11 +224,11 @@ struct fib_table {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp,
 | 
					int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp,
 | 
				
			||||||
		     struct fib_result *res, int fib_flags);
 | 
							     struct fib_result *res, int fib_flags);
 | 
				
			||||||
int fib_table_insert(struct fib_table *, struct fib_config *);
 | 
					int fib_table_insert(struct net *, struct fib_table *, struct fib_config *);
 | 
				
			||||||
int fib_table_delete(struct fib_table *, struct fib_config *);
 | 
					int fib_table_delete(struct net *, struct fib_table *, struct fib_config *);
 | 
				
			||||||
int fib_table_dump(struct fib_table *table, struct sk_buff *skb,
 | 
					int fib_table_dump(struct fib_table *table, struct sk_buff *skb,
 | 
				
			||||||
		   struct netlink_callback *cb);
 | 
							   struct netlink_callback *cb);
 | 
				
			||||||
int fib_table_flush(struct fib_table *table);
 | 
					int fib_table_flush(struct net *net, struct fib_table *table);
 | 
				
			||||||
struct fib_table *fib_trie_unmerge(struct fib_table *main_tb);
 | 
					struct fib_table *fib_trie_unmerge(struct fib_table *main_tb);
 | 
				
			||||||
void fib_table_flush_external(struct fib_table *table);
 | 
					void fib_table_flush_external(struct fib_table *table);
 | 
				
			||||||
void fib_free_table(struct fib_table *tb);
 | 
					void fib_free_table(struct fib_table *tb);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -182,7 +182,7 @@ static void fib_flush(struct net *net)
 | 
				
			||||||
		struct fib_table *tb;
 | 
							struct fib_table *tb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		hlist_for_each_entry_safe(tb, tmp, head, tb_hlist)
 | 
							hlist_for_each_entry_safe(tb, tmp, head, tb_hlist)
 | 
				
			||||||
			flushed += fib_table_flush(tb);
 | 
								flushed += fib_table_flush(net, tb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (flushed)
 | 
						if (flushed)
 | 
				
			||||||
| 
						 | 
					@ -590,13 +590,13 @@ int ip_rt_ioctl(struct net *net, unsigned int cmd, void __user *arg)
 | 
				
			||||||
			if (cmd == SIOCDELRT) {
 | 
								if (cmd == SIOCDELRT) {
 | 
				
			||||||
				tb = fib_get_table(net, cfg.fc_table);
 | 
									tb = fib_get_table(net, cfg.fc_table);
 | 
				
			||||||
				if (tb)
 | 
									if (tb)
 | 
				
			||||||
					err = fib_table_delete(tb, &cfg);
 | 
										err = fib_table_delete(net, tb, &cfg);
 | 
				
			||||||
				else
 | 
									else
 | 
				
			||||||
					err = -ESRCH;
 | 
										err = -ESRCH;
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				tb = fib_new_table(net, cfg.fc_table);
 | 
									tb = fib_new_table(net, cfg.fc_table);
 | 
				
			||||||
				if (tb)
 | 
									if (tb)
 | 
				
			||||||
					err = fib_table_insert(tb, &cfg);
 | 
										err = fib_table_insert(net, tb, &cfg);
 | 
				
			||||||
				else
 | 
									else
 | 
				
			||||||
					err = -ENOBUFS;
 | 
										err = -ENOBUFS;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -719,7 +719,7 @@ static int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh)
 | 
				
			||||||
		goto errout;
 | 
							goto errout;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = fib_table_delete(tb, &cfg);
 | 
						err = fib_table_delete(net, tb, &cfg);
 | 
				
			||||||
errout:
 | 
					errout:
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -741,7 +741,7 @@ static int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh)
 | 
				
			||||||
		goto errout;
 | 
							goto errout;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = fib_table_insert(tb, &cfg);
 | 
						err = fib_table_insert(net, tb, &cfg);
 | 
				
			||||||
errout:
 | 
					errout:
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -828,9 +828,9 @@ static void fib_magic(int cmd, int type, __be32 dst, int dst_len, struct in_ifad
 | 
				
			||||||
		cfg.fc_scope = RT_SCOPE_HOST;
 | 
							cfg.fc_scope = RT_SCOPE_HOST;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (cmd == RTM_NEWROUTE)
 | 
						if (cmd == RTM_NEWROUTE)
 | 
				
			||||||
		fib_table_insert(tb, &cfg);
 | 
							fib_table_insert(net, tb, &cfg);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		fib_table_delete(tb, &cfg);
 | 
							fib_table_delete(net, tb, &cfg);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void fib_add_ifaddr(struct in_ifaddr *ifa)
 | 
					void fib_add_ifaddr(struct in_ifaddr *ifa)
 | 
				
			||||||
| 
						 | 
					@ -1254,7 +1254,7 @@ static void ip_fib_net_exit(struct net *net)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		hlist_for_each_entry_safe(tb, tmp, head, tb_hlist) {
 | 
							hlist_for_each_entry_safe(tb, tmp, head, tb_hlist) {
 | 
				
			||||||
			hlist_del(&tb->tb_hlist);
 | 
								hlist_del(&tb->tb_hlist);
 | 
				
			||||||
			fib_table_flush(tb);
 | 
								fib_table_flush(net, tb);
 | 
				
			||||||
			fib_free_table(tb);
 | 
								fib_free_table(tb);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -164,6 +164,14 @@ static struct fib_table *fib_empty_table(struct net *net)
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int call_fib_rule_notifiers(struct net *net,
 | 
				
			||||||
 | 
									   enum fib_event_type event_type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fib_notifier_info info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return call_fib_notifiers(net, event_type, &info);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct nla_policy fib4_rule_policy[FRA_MAX+1] = {
 | 
					static const struct nla_policy fib4_rule_policy[FRA_MAX+1] = {
 | 
				
			||||||
	FRA_GENERIC_POLICY,
 | 
						FRA_GENERIC_POLICY,
 | 
				
			||||||
	[FRA_FLOW]	= { .type = NLA_U32 },
 | 
						[FRA_FLOW]	= { .type = NLA_U32 },
 | 
				
			||||||
| 
						 | 
					@ -221,6 +229,7 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	net->ipv4.fib_has_custom_rules = true;
 | 
						net->ipv4.fib_has_custom_rules = true;
 | 
				
			||||||
	fib_flush_external(rule->fr_net);
 | 
						fib_flush_external(rule->fr_net);
 | 
				
			||||||
 | 
						call_fib_rule_notifiers(net, FIB_EVENT_RULE_ADD);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = 0;
 | 
						err = 0;
 | 
				
			||||||
errout:
 | 
					errout:
 | 
				
			||||||
| 
						 | 
					@ -243,6 +252,7 @@ static int fib4_rule_delete(struct fib_rule *rule)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	net->ipv4.fib_has_custom_rules = true;
 | 
						net->ipv4.fib_has_custom_rules = true;
 | 
				
			||||||
	fib_flush_external(rule->fr_net);
 | 
						fib_flush_external(rule->fr_net);
 | 
				
			||||||
 | 
						call_fib_rule_notifiers(net, FIB_EVENT_RULE_DEL);
 | 
				
			||||||
errout:
 | 
					errout:
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,6 +73,7 @@
 | 
				
			||||||
#include <linux/slab.h>
 | 
					#include <linux/slab.h>
 | 
				
			||||||
#include <linux/export.h>
 | 
					#include <linux/export.h>
 | 
				
			||||||
#include <linux/vmalloc.h>
 | 
					#include <linux/vmalloc.h>
 | 
				
			||||||
 | 
					#include <linux/notifier.h>
 | 
				
			||||||
#include <net/net_namespace.h>
 | 
					#include <net/net_namespace.h>
 | 
				
			||||||
#include <net/ip.h>
 | 
					#include <net/ip.h>
 | 
				
			||||||
#include <net/protocol.h>
 | 
					#include <net/protocol.h>
 | 
				
			||||||
| 
						 | 
					@ -84,6 +85,44 @@
 | 
				
			||||||
#include <trace/events/fib.h>
 | 
					#include <trace/events/fib.h>
 | 
				
			||||||
#include "fib_lookup.h"
 | 
					#include "fib_lookup.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static BLOCKING_NOTIFIER_HEAD(fib_chain);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int register_fib_notifier(struct notifier_block *nb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return blocking_notifier_chain_register(&fib_chain, nb);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(register_fib_notifier);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int unregister_fib_notifier(struct notifier_block *nb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return blocking_notifier_chain_unregister(&fib_chain, nb);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(unregister_fib_notifier);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int call_fib_notifiers(struct net *net, enum fib_event_type event_type,
 | 
				
			||||||
 | 
							       struct fib_notifier_info *info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						info->net = net;
 | 
				
			||||||
 | 
						return blocking_notifier_call_chain(&fib_chain, event_type, info);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int call_fib_entry_notifiers(struct net *net,
 | 
				
			||||||
 | 
									    enum fib_event_type event_type, u32 dst,
 | 
				
			||||||
 | 
									    int dst_len, struct fib_info *fi,
 | 
				
			||||||
 | 
									    u8 tos, u8 type, u32 tb_id, u32 nlflags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fib_entry_notifier_info info = {
 | 
				
			||||||
 | 
							.dst = dst,
 | 
				
			||||||
 | 
							.dst_len = dst_len,
 | 
				
			||||||
 | 
							.fi = fi,
 | 
				
			||||||
 | 
							.tos = tos,
 | 
				
			||||||
 | 
							.type = type,
 | 
				
			||||||
 | 
							.tb_id = tb_id,
 | 
				
			||||||
 | 
							.nlflags = nlflags,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						return call_fib_notifiers(net, event_type, &info.info);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MAX_STAT_DEPTH 32
 | 
					#define MAX_STAT_DEPTH 32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define KEYLENGTH	(8*sizeof(t_key))
 | 
					#define KEYLENGTH	(8*sizeof(t_key))
 | 
				
			||||||
| 
						 | 
					@ -1076,7 +1115,8 @@ static int fib_insert_alias(struct trie *t, struct key_vector *tp,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Caller must hold RTNL. */
 | 
					/* Caller must hold RTNL. */
 | 
				
			||||||
int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
 | 
					int fib_table_insert(struct net *net, struct fib_table *tb,
 | 
				
			||||||
 | 
							     struct fib_config *cfg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct trie *t = (struct trie *)tb->tb_data;
 | 
						struct trie *t = (struct trie *)tb->tb_data;
 | 
				
			||||||
	struct fib_alias *fa, *new_fa;
 | 
						struct fib_alias *fa, *new_fa;
 | 
				
			||||||
| 
						 | 
					@ -1193,6 +1233,11 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
 | 
				
			||||||
			fib_release_info(fi_drop);
 | 
								fib_release_info(fi_drop);
 | 
				
			||||||
			if (state & FA_S_ACCESSED)
 | 
								if (state & FA_S_ACCESSED)
 | 
				
			||||||
				rt_cache_flush(cfg->fc_nlinfo.nl_net);
 | 
									rt_cache_flush(cfg->fc_nlinfo.nl_net);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								call_fib_entry_notifiers(net, FIB_EVENT_ENTRY_ADD,
 | 
				
			||||||
 | 
											 key, plen, fi,
 | 
				
			||||||
 | 
											 new_fa->fa_tos, cfg->fc_type,
 | 
				
			||||||
 | 
											 tb->tb_id, cfg->fc_nlflags);
 | 
				
			||||||
			rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen,
 | 
								rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen,
 | 
				
			||||||
				tb->tb_id, &cfg->fc_nlinfo, nlflags);
 | 
									tb->tb_id, &cfg->fc_nlinfo, nlflags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1245,6 +1290,8 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
 | 
				
			||||||
		tb->tb_num_default++;
 | 
							tb->tb_num_default++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rt_cache_flush(cfg->fc_nlinfo.nl_net);
 | 
						rt_cache_flush(cfg->fc_nlinfo.nl_net);
 | 
				
			||||||
 | 
						call_fib_entry_notifiers(net, FIB_EVENT_ENTRY_ADD, key, plen, fi, tos,
 | 
				
			||||||
 | 
									 cfg->fc_type, tb->tb_id, cfg->fc_nlflags);
 | 
				
			||||||
	rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, new_fa->tb_id,
 | 
						rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, new_fa->tb_id,
 | 
				
			||||||
		  &cfg->fc_nlinfo, nlflags);
 | 
							  &cfg->fc_nlinfo, nlflags);
 | 
				
			||||||
succeeded:
 | 
					succeeded:
 | 
				
			||||||
| 
						 | 
					@ -1490,7 +1537,8 @@ static void fib_remove_alias(struct trie *t, struct key_vector *tp,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Caller must hold RTNL. */
 | 
					/* Caller must hold RTNL. */
 | 
				
			||||||
int fib_table_delete(struct fib_table *tb, struct fib_config *cfg)
 | 
					int fib_table_delete(struct net *net, struct fib_table *tb,
 | 
				
			||||||
 | 
							     struct fib_config *cfg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct trie *t = (struct trie *) tb->tb_data;
 | 
						struct trie *t = (struct trie *) tb->tb_data;
 | 
				
			||||||
	struct fib_alias *fa, *fa_to_delete;
 | 
						struct fib_alias *fa, *fa_to_delete;
 | 
				
			||||||
| 
						 | 
					@ -1546,6 +1594,9 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg)
 | 
				
			||||||
	switchdev_fib_ipv4_del(key, plen, fa_to_delete->fa_info, tos,
 | 
						switchdev_fib_ipv4_del(key, plen, fa_to_delete->fa_info, tos,
 | 
				
			||||||
			       cfg->fc_type, tb->tb_id);
 | 
								       cfg->fc_type, tb->tb_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						call_fib_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, key, plen,
 | 
				
			||||||
 | 
									 fa_to_delete->fa_info, tos, cfg->fc_type,
 | 
				
			||||||
 | 
									 tb->tb_id, 0);
 | 
				
			||||||
	rtmsg_fib(RTM_DELROUTE, htonl(key), fa_to_delete, plen, tb->tb_id,
 | 
						rtmsg_fib(RTM_DELROUTE, htonl(key), fa_to_delete, plen, tb->tb_id,
 | 
				
			||||||
		  &cfg->fc_nlinfo, 0);
 | 
							  &cfg->fc_nlinfo, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1809,7 +1860,7 @@ void fib_table_flush_external(struct fib_table *tb)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Caller must hold RTNL. */
 | 
					/* Caller must hold RTNL. */
 | 
				
			||||||
int fib_table_flush(struct fib_table *tb)
 | 
					int fib_table_flush(struct net *net, struct fib_table *tb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct trie *t = (struct trie *)tb->tb_data;
 | 
						struct trie *t = (struct trie *)tb->tb_data;
 | 
				
			||||||
	struct key_vector *pn = t->kv;
 | 
						struct key_vector *pn = t->kv;
 | 
				
			||||||
| 
						 | 
					@ -1861,6 +1912,11 @@ int fib_table_flush(struct fib_table *tb)
 | 
				
			||||||
			switchdev_fib_ipv4_del(n->key, KEYLENGTH - fa->fa_slen,
 | 
								switchdev_fib_ipv4_del(n->key, KEYLENGTH - fa->fa_slen,
 | 
				
			||||||
					       fi, fa->fa_tos, fa->fa_type,
 | 
										       fi, fa->fa_tos, fa->fa_type,
 | 
				
			||||||
					       tb->tb_id);
 | 
										       tb->tb_id);
 | 
				
			||||||
 | 
								call_fib_entry_notifiers(net, FIB_EVENT_ENTRY_DEL,
 | 
				
			||||||
 | 
											 n->key,
 | 
				
			||||||
 | 
											 KEYLENGTH - fa->fa_slen,
 | 
				
			||||||
 | 
											 fi, fa->fa_tos, fa->fa_type,
 | 
				
			||||||
 | 
											 tb->tb_id, 0);
 | 
				
			||||||
			hlist_del_rcu(&fa->fa_list);
 | 
								hlist_del_rcu(&fa->fa_list);
 | 
				
			||||||
			fib_release_info(fa->fa_info);
 | 
								fib_release_info(fa->fa_info);
 | 
				
			||||||
			alias_free_mem_rcu(fa);
 | 
								alias_free_mem_rcu(fa);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue