All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 0/9] Simplify IPv6 route offload API
@ 2019-12-23 13:28 Ido Schimmel
  2019-12-23 13:28 ` [PATCH net-next 1/9] net: fib_notifier: Add temporary events to the FIB notification chain Ido Schimmel
                   ` (9 more replies)
  0 siblings, 10 replies; 20+ messages in thread
From: Ido Schimmel @ 2019-12-23 13:28 UTC (permalink / raw)
  To: netdev; +Cc: davem, dsahern, roopa, jakub.kicinski, jiri, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

Motivation
==========

This is the IPv6 counterpart of "Simplify IPv4 route offload API" [1].
The aim of this patch set is to simplify the IPv6 route offload API by
making the stack a bit smarter about the notifications it is generating.
This allows driver authors to focus on programming the underlying device
instead of having to duplicate the IPv6 route insertion logic in their
driver, which is error-prone.

Details
=======

Today, whenever an IPv6 route is added or deleted a notification is sent
in the FIB notification chain and it is up to offload drivers to decide
if the route should be programmed to the hardware or not. This is not an
easy task as in hardware routes are keyed by {prefix, prefix length,
table id}, whereas the kernel can store multiple such routes that only
differ in metric / nexthop info.

This series makes sure that only routes that are actually used in the
data path are notified to offload drivers. This greatly simplifies the
work these drivers need to do, as they are now only concerned with
programming the hardware and do not need to replicate the IPv6 route
insertion logic and store multiple identical routes.

The route that is notified is the first route in the IPv6 FIB node,
which represents a single prefix and length in a given table. In case
the route is deleted and there is another route with the same key, a
replace notification is emitted. Otherwise, a delete notification is
emitted.

Unlike IPv4, in IPv6 it is possible to append individual nexthops to an
existing multipath route. Therefore, in addition to the replace and
delete notifications present in IPv4, an append notification is also
used.

Testing
=======

To ensure there is no degradation in route insertion rates, I averaged
the insertion rate of 512k routes (/64 and /128) over 50 runs. Did not
observe any degradation.

Functional tests are available here [2]. They rely on route trap
indication, which is added in a subsequent patch set.

In addition, I have been running syzkaller for the past couple of weeks
with debug options enabled. Did not observe any problems.

Patch set overview
==================

Patches #1-#7 gradually introduce the new FIB notifications
Patch #8 converts mlxsw to use the new notifications
Patch #9 remove the old notifications

[1] https://patchwork.ozlabs.org/cover/1209738/
[2] https://github.com/idosch/linux/tree/fib-notifier

Ido Schimmel (9):
  net: fib_notifier: Add temporary events to the FIB notification chain
  ipv6: Notify newly added route if should be offloaded
  ipv6: Notify route if replacing currently offloaded one
  ipv6: Notify multipath route if should be offloaded
  ipv6: Only Replay routes of interest to new listeners
  ipv6: Handle route deletion notification
  ipv6: Handle multipath route deletion notification
  mlxsw: spectrum_router: Start using new IPv6 route notifications
  ipv6: Remove old route notifications and convert listeners

 .../ethernet/mellanox/mlxsw/spectrum_router.c | 218 ++++++------------
 drivers/net/netdevsim/fib.c                   |   1 -
 include/net/ip6_fib.h                         |   1 +
 net/ipv6/ip6_fib.c                            | 108 +++++++--
 net/ipv6/route.c                              |  86 +++++--
 5 files changed, 238 insertions(+), 176 deletions(-)

-- 
2.24.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH net-next 1/9] net: fib_notifier: Add temporary events to the FIB notification chain
  2019-12-23 13:28 [PATCH net-next 0/9] Simplify IPv6 route offload API Ido Schimmel
@ 2019-12-23 13:28 ` Ido Schimmel
  2019-12-24 16:40   ` David Ahern
  2019-12-23 13:28 ` [PATCH net-next 2/9] ipv6: Notify newly added route if should be offloaded Ido Schimmel
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: Ido Schimmel @ 2019-12-23 13:28 UTC (permalink / raw)
  To: netdev; +Cc: davem, dsahern, roopa, jakub.kicinski, jiri, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

Subsequent patches are going to simplify the IPv6 route offload API,
which will only use three events - replace, delete and append.

Introduce a temporary version of replace and delete in order to make the
conversion easier to review. Note that append does not need a temporary
version, as it is currently not used.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
---
 include/net/fib_notifier.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/net/fib_notifier.h b/include/net/fib_notifier.h
index 6d59221ff05a..b3c54325caec 100644
--- a/include/net/fib_notifier.h
+++ b/include/net/fib_notifier.h
@@ -23,6 +23,8 @@ enum fib_event_type {
 	FIB_EVENT_NH_DEL,
 	FIB_EVENT_VIF_ADD,
 	FIB_EVENT_VIF_DEL,
+	FIB_EVENT_ENTRY_REPLACE_TMP,
+	FIB_EVENT_ENTRY_DEL_TMP,
 };
 
 struct fib_notifier_ops {
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next 2/9] ipv6: Notify newly added route if should be offloaded
  2019-12-23 13:28 [PATCH net-next 0/9] Simplify IPv6 route offload API Ido Schimmel
  2019-12-23 13:28 ` [PATCH net-next 1/9] net: fib_notifier: Add temporary events to the FIB notification chain Ido Schimmel
@ 2019-12-23 13:28 ` Ido Schimmel
  2019-12-24 16:40   ` David Ahern
  2019-12-23 13:28 ` [PATCH net-next 3/9] ipv6: Notify route if replacing currently offloaded one Ido Schimmel
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: Ido Schimmel @ 2019-12-23 13:28 UTC (permalink / raw)
  To: netdev; +Cc: davem, dsahern, roopa, jakub.kicinski, jiri, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

fib6_add_rt2node() takes care of adding a single route ('struct
fib6_info') to a FIB node. The route in question should only be notified
in case it is added as the first route in the node (lowest metric) or if
it is added as a sibling route to the first route in the node.

The first criterion can be tested by checking if the route is pointed to
by 'fn->leaf'. The second criterion can be tested by checking the new
'notify_sibling_rt' variable that is set when the route is added as a
sibling to the first route in the node.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
---
 net/ipv6/ip6_fib.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 7bae6a91b487..045bcaf5e770 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -1039,6 +1039,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
 		   (info->nlh->nlmsg_flags & NLM_F_CREATE));
 	int found = 0;
 	bool rt_can_ecmp = rt6_qualify_for_ecmp(rt);
+	bool notify_sibling_rt = false;
 	u16 nlflags = NLM_F_EXCL;
 	int err;
 
@@ -1130,6 +1131,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
 
 		/* Find the first route that have the same metric */
 		sibling = leaf;
+		notify_sibling_rt = true;
 		while (sibling) {
 			if (sibling->fib6_metric == rt->fib6_metric &&
 			    rt6_qualify_for_ecmp(sibling)) {
@@ -1139,6 +1141,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
 			}
 			sibling = rcu_dereference_protected(sibling->fib6_next,
 				    lockdep_is_held(&rt->fib6_table->tb6_lock));
+			notify_sibling_rt = false;
 		}
 		/* For each sibling in the list, increment the counter of
 		 * siblings. BUG() if counters does not match, list of siblings
@@ -1166,6 +1169,21 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
 		nlflags |= NLM_F_CREATE;
 
 		if (!info->skip_notify_kernel) {
+			enum fib_event_type fib_event;
+
+			if (notify_sibling_rt)
+				fib_event = FIB_EVENT_ENTRY_APPEND;
+			else
+				fib_event = FIB_EVENT_ENTRY_REPLACE_TMP;
+			/* The route should only be notified if it is the first
+			 * route in the node or if it is added as a sibling
+			 * route to the first route in the node.
+			 */
+			if (notify_sibling_rt || ins == &fn->leaf)
+				err = call_fib6_entry_notifiers(info->nl_net,
+								fib_event, rt,
+								extack);
+
 			err = call_fib6_entry_notifiers(info->nl_net,
 							FIB_EVENT_ENTRY_ADD,
 							rt, extack);
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next 3/9] ipv6: Notify route if replacing currently offloaded one
  2019-12-23 13:28 [PATCH net-next 0/9] Simplify IPv6 route offload API Ido Schimmel
  2019-12-23 13:28 ` [PATCH net-next 1/9] net: fib_notifier: Add temporary events to the FIB notification chain Ido Schimmel
  2019-12-23 13:28 ` [PATCH net-next 2/9] ipv6: Notify newly added route if should be offloaded Ido Schimmel
@ 2019-12-23 13:28 ` Ido Schimmel
  2019-12-24 16:44   ` David Ahern
  2019-12-23 13:28 ` [PATCH net-next 4/9] ipv6: Notify multipath route if should be offloaded Ido Schimmel
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: Ido Schimmel @ 2019-12-23 13:28 UTC (permalink / raw)
  To: netdev; +Cc: davem, dsahern, roopa, jakub.kicinski, jiri, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

Similar to the corresponding IPv4 patch, only notify the new route if it
is replacing the currently offloaded one. Meaning, the one pointed to by
'fn->leaf'.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
---
 net/ipv6/ip6_fib.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 045bcaf5e770..7cf9554888b0 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -1231,6 +1231,13 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
 		}
 
 		if (!info->skip_notify_kernel) {
+			enum fib_event_type fib_event;
+
+			fib_event = FIB_EVENT_ENTRY_REPLACE_TMP;
+			if (ins == &fn->leaf)
+				err = call_fib6_entry_notifiers(info->nl_net,
+								fib_event, rt,
+								extack);
 			err = call_fib6_entry_notifiers(info->nl_net,
 							FIB_EVENT_ENTRY_REPLACE,
 							rt, extack);
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next 4/9] ipv6: Notify multipath route if should be offloaded
  2019-12-23 13:28 [PATCH net-next 0/9] Simplify IPv6 route offload API Ido Schimmel
                   ` (2 preceding siblings ...)
  2019-12-23 13:28 ` [PATCH net-next 3/9] ipv6: Notify route if replacing currently offloaded one Ido Schimmel
@ 2019-12-23 13:28 ` Ido Schimmel
  2019-12-24 16:49   ` David Ahern
  2019-12-23 13:28 ` [PATCH net-next 5/9] ipv6: Only Replay routes of interest to new listeners Ido Schimmel
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: Ido Schimmel @ 2019-12-23 13:28 UTC (permalink / raw)
  To: netdev; +Cc: davem, dsahern, roopa, jakub.kicinski, jiri, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

In a similar fashion to previous patches, only notify the new multipath
route if it is the first route in the node or if it was appended to such
route.

The type of the notification (replace vs. append) is determined based on
the number of routes added ('nhn') and the number of sibling routes. If
the two do not match, then an append notification should be sent.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
---
 net/ipv6/route.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index b59940416cb5..c0809f52f9ef 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -5017,6 +5017,32 @@ static void ip6_route_mpath_notify(struct fib6_info *rt,
 		inet6_rt_notify(RTM_NEWROUTE, rt, info, nlflags);
 }
 
+static bool ip6_route_mpath_should_notify(const struct fib6_info *rt)
+{
+	bool rt_can_ecmp = rt6_qualify_for_ecmp(rt);
+	bool should_notify = false;
+	struct fib6_info *leaf;
+	struct fib6_node *fn;
+
+	rcu_read_lock();
+	fn = rcu_dereference(rt->fib6_node);
+	if (!fn)
+		goto out;
+
+	leaf = rcu_dereference(fn->leaf);
+	if (!leaf)
+		goto out;
+
+	if (rt == leaf ||
+	    (rt_can_ecmp && rt->fib6_metric == leaf->fib6_metric &&
+	     rt6_qualify_for_ecmp(leaf)))
+		should_notify = true;
+out:
+	rcu_read_unlock();
+
+	return should_notify;
+}
+
 static int ip6_route_multipath_add(struct fib6_config *cfg,
 				   struct netlink_ext_ack *extack)
 {
@@ -5147,6 +5173,28 @@ static int ip6_route_multipath_add(struct fib6_config *cfg,
 		nhn++;
 	}
 
+	/* An in-kernel notification should only be sent in case the new
+	 * multipath route is added as the first route in the node, or if
+	 * it was appended to it. We pass 'rt_notif' since it is the first
+	 * sibling and might allow us to skip some checks in the replace case.
+	 */
+	if (ip6_route_mpath_should_notify(rt_notif)) {
+		enum fib_event_type fib_event;
+
+		if (rt_notif->fib6_nsiblings != nhn - 1)
+			fib_event = FIB_EVENT_ENTRY_APPEND;
+		else
+			fib_event = FIB_EVENT_ENTRY_REPLACE_TMP;
+
+		err = call_fib6_multipath_entry_notifiers(info->nl_net,
+							  fib_event, rt_notif,
+							  nhn - 1, extack);
+		if (err) {
+			/* Delete all the siblings that were just added */
+			err_nh = NULL;
+			goto add_errout;
+		}
+	}
 	event_type = replace ? FIB_EVENT_ENTRY_REPLACE : FIB_EVENT_ENTRY_ADD;
 	err = call_fib6_multipath_entry_notifiers(info->nl_net, event_type,
 						  rt_notif, nhn - 1, extack);
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next 5/9] ipv6: Only Replay routes of interest to new listeners
  2019-12-23 13:28 [PATCH net-next 0/9] Simplify IPv6 route offload API Ido Schimmel
                   ` (3 preceding siblings ...)
  2019-12-23 13:28 ` [PATCH net-next 4/9] ipv6: Notify multipath route if should be offloaded Ido Schimmel
@ 2019-12-23 13:28 ` Ido Schimmel
  2019-12-24 16:58   ` David Ahern
  2019-12-23 13:28 ` [PATCH net-next 6/9] ipv6: Handle route deletion notification Ido Schimmel
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: Ido Schimmel @ 2019-12-23 13:28 UTC (permalink / raw)
  To: netdev; +Cc: davem, dsahern, roopa, jakub.kicinski, jiri, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

When a new listener is registered to the FIB notification chain it
receives a dump of all the available routes in the system. Instead, make
sure to only replay the IPv6 routes that are actually used in the data
path and are of any interest to the new listener.

This is done by iterating over all the routing tables in the given
namespace, but from each traversed node only the first route ('leaf') is
notified. Multipath routes are notified in a single notification instead
of one for each nexthop.

Add fib6_rt_dump_tmp() to do that. Later on in the patch set it will be
renamed to fib6_rt_dump() instead of the existing one.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
---
 net/ipv6/ip6_fib.c | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 7cf9554888b0..51cf848e38f0 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -370,6 +370,21 @@ static int call_fib6_entry_notifier(struct notifier_block *nb,
 	return call_fib6_notifier(nb, event_type, &info.info);
 }
 
+static int call_fib6_multipath_entry_notifier(struct notifier_block *nb,
+					      enum fib_event_type event_type,
+					      struct fib6_info *rt,
+					      unsigned int nsiblings,
+					      struct netlink_ext_ack *extack)
+{
+	struct fib6_entry_notifier_info info = {
+		.info.extack = extack,
+		.rt = rt,
+		.nsiblings = nsiblings,
+	};
+
+	return call_fib6_notifier(nb, event_type, &info.info);
+}
+
 int call_fib6_entry_notifiers(struct net *net,
 			      enum fib_event_type event_type,
 			      struct fib6_info *rt,
@@ -414,16 +429,41 @@ static int fib6_rt_dump(struct fib6_info *rt, struct fib6_dump_arg *arg)
 					rt, arg->extack);
 }
 
+static int fib6_rt_dump_tmp(struct fib6_info *rt, struct fib6_dump_arg *arg)
+{
+	enum fib_event_type fib_event = FIB_EVENT_ENTRY_REPLACE_TMP;
+	int err;
+
+	if (!rt || rt == arg->net->ipv6.fib6_null_entry)
+		return 0;
+
+	if (rt->fib6_nsiblings)
+		err = call_fib6_multipath_entry_notifier(arg->nb, fib_event,
+							 rt,
+							 rt->fib6_nsiblings,
+							 arg->extack);
+	else
+		err = call_fib6_entry_notifier(arg->nb, fib_event, rt,
+					       arg->extack);
+
+	return err;
+}
+
 static int fib6_node_dump(struct fib6_walker *w)
 {
 	struct fib6_info *rt;
 	int err = 0;
 
+	err = fib6_rt_dump_tmp(w->leaf, w->args);
+	if (err)
+		goto out;
+
 	for_each_fib6_walker_rt(w) {
 		err = fib6_rt_dump(rt, w->args);
 		if (err)
 			break;
 	}
+out:
 	w->leaf = NULL;
 	return err;
 }
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next 6/9] ipv6: Handle route deletion notification
  2019-12-23 13:28 [PATCH net-next 0/9] Simplify IPv6 route offload API Ido Schimmel
                   ` (4 preceding siblings ...)
  2019-12-23 13:28 ` [PATCH net-next 5/9] ipv6: Only Replay routes of interest to new listeners Ido Schimmel
@ 2019-12-23 13:28 ` Ido Schimmel
  2019-12-24 17:03   ` David Ahern
  2019-12-23 13:28 ` [PATCH net-next 7/9] ipv6: Handle multipath " Ido Schimmel
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: Ido Schimmel @ 2019-12-23 13:28 UTC (permalink / raw)
  To: netdev; +Cc: davem, dsahern, roopa, jakub.kicinski, jiri, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

For the purpose of route offload, when a single route is deleted, it is
only of interest if it is the first route in the node or if it is
sibling to such a route.

In the first case, distinguish between several possibilities:

1. Route is the last route in the node. Emit a delete notification

2. Route is followed by a non-multipath route. Emit a replace
notification for the non-multipath route.

3. Route is followed by a multipath route. Emit a replace notification
for the multipath route.

In the second case, only emit a delete notification to ensure the route
is no longer used as a valid nexthop.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
---
 include/net/ip6_fib.h |  1 +
 net/ipv6/ip6_fib.c    | 44 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index f1535f172935..b579faea41e9 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -487,6 +487,7 @@ int call_fib6_multipath_entry_notifiers(struct net *net,
 					struct fib6_info *rt,
 					unsigned int 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,
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 51cf848e38f0..67ddee539f77 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -415,6 +415,18 @@ int call_fib6_multipath_entry_notifiers(struct net *net,
 	return call_fib6_notifiers(net, event_type, &info.info);
 }
 
+int call_fib6_entry_notifiers_replace(struct net *net, struct fib6_info *rt)
+{
+	struct fib6_entry_notifier_info info = {
+		.rt = rt,
+		.nsiblings = rt->fib6_nsiblings,
+	};
+
+	rt->fib6_table->fib_seq++;
+	return call_fib6_notifiers(net, FIB_EVENT_ENTRY_REPLACE_TMP,
+				   &info.info);
+}
+
 struct fib6_dump_arg {
 	struct net *net;
 	struct notifier_block *nb;
@@ -1910,13 +1922,29 @@ static struct fib6_node *fib6_repair_tree(struct net *net,
 static void fib6_del_route(struct fib6_table *table, struct fib6_node *fn,
 			   struct fib6_info __rcu **rtp, struct nl_info *info)
 {
+	struct fib6_info *leaf, *replace_rt = NULL;
 	struct fib6_walker *w;
 	struct fib6_info *rt = rcu_dereference_protected(*rtp,
 				    lockdep_is_held(&table->tb6_lock));
 	struct net *net = info->nl_net;
+	bool notify_del = false;
 
 	RT6_TRACE("fib6_del_route\n");
 
+	/* If the deleted route is the first in the node and it is not part of
+	 * a multipath route, then we need to replace it with the next route
+	 * in the node, if exists.
+	 */
+	leaf = rcu_dereference_protected(fn->leaf,
+					 lockdep_is_held(&table->tb6_lock));
+	if (leaf == rt && !rt->fib6_nsiblings) {
+		if (rcu_access_pointer(rt->fib6_next))
+			replace_rt = rcu_dereference_protected(rt->fib6_next,
+					    lockdep_is_held(&table->tb6_lock));
+		else
+			notify_del = true;
+	}
+
 	/* Unlink it */
 	*rtp = rt->fib6_next;
 	rt->fib6_node = NULL;
@@ -1934,6 +1962,14 @@ static void fib6_del_route(struct fib6_table *table, struct fib6_node *fn,
 	if (rt->fib6_nsiblings) {
 		struct fib6_info *sibling, *next_sibling;
 
+		/* The route is deleted from a multipath route. If this
+		 * multipath route is the first route in the node, then we need
+		 * to emit a delete notification. Otherwise, we need to skip
+		 * the notification.
+		 */
+		if (rt->fib6_metric == leaf->fib6_metric &&
+		    rt6_qualify_for_ecmp(leaf))
+			notify_del = true;
 		list_for_each_entry_safe(sibling, next_sibling,
 					 &rt->fib6_siblings, fib6_siblings)
 			sibling->fib6_nsiblings--;
@@ -1969,8 +2005,14 @@ static void fib6_del_route(struct fib6_table *table, struct fib6_node *fn,
 
 	fib6_purge_rt(rt, fn, net);
 
-	if (!info->skip_notify_kernel)
+	if (!info->skip_notify_kernel) {
+		if (notify_del)
+			call_fib6_entry_notifiers(net, FIB_EVENT_ENTRY_DEL_TMP,
+						  rt, NULL);
+		else if (replace_rt)
+			call_fib6_entry_notifiers_replace(net, replace_rt);
 		call_fib6_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, rt, NULL);
+	}
 	if (!info->skip_notify)
 		inet6_rt_notify(RTM_DELROUTE, rt, info, 0);
 
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next 7/9] ipv6: Handle multipath route deletion notification
  2019-12-23 13:28 [PATCH net-next 0/9] Simplify IPv6 route offload API Ido Schimmel
                   ` (5 preceding siblings ...)
  2019-12-23 13:28 ` [PATCH net-next 6/9] ipv6: Handle route deletion notification Ido Schimmel
@ 2019-12-23 13:28 ` Ido Schimmel
  2019-12-24 17:09   ` David Ahern
  2019-12-23 13:28 ` [PATCH net-next 8/9] mlxsw: spectrum_router: Start using new IPv6 route notifications Ido Schimmel
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: Ido Schimmel @ 2019-12-23 13:28 UTC (permalink / raw)
  To: netdev; +Cc: davem, dsahern, roopa, jakub.kicinski, jiri, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

When an entire multipath route is deleted, only emit a notification if
it is the first route in the node. Emit a replace notification in case
the last sibling is followed by another route. Otherwise, emit a delete
notification.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
---
 net/ipv6/route.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index c0809f52f9ef..646716a47cc9 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -3749,6 +3749,7 @@ static int __ip6_del_rt_siblings(struct fib6_info *rt, struct fib6_config *cfg)
 
 	if (rt->fib6_nsiblings && cfg->fc_delete_all_nh) {
 		struct fib6_info *sibling, *next_sibling;
+		struct fib6_node *fn;
 
 		/* prefer to send a single notification with all hops */
 		skb = nlmsg_new(rt6_nlmsg_size(rt), gfp_any());
@@ -3764,7 +3765,32 @@ static int __ip6_del_rt_siblings(struct fib6_info *rt, struct fib6_config *cfg)
 				info->skip_notify = 1;
 		}
 
+		/* 'rt' points to the first sibling route. If it is not the
+		 * leaf, then we do not need to send a notification. Otherwise,
+		 * we need to check if the last sibling has a next route or not
+		 * and emit a replace or delete notification, respectively.
+		 */
 		info->skip_notify_kernel = 1;
+		fn = rcu_dereference_protected(rt->fib6_node,
+					    lockdep_is_held(&table->tb6_lock));
+		if (rcu_access_pointer(fn->leaf) == rt) {
+			struct fib6_info *last_sibling, *replace_rt;
+
+			last_sibling = list_last_entry(&rt->fib6_siblings,
+						       struct fib6_info,
+						       fib6_siblings);
+			replace_rt = rcu_dereference_protected(
+					    last_sibling->fib6_next,
+					    lockdep_is_held(&table->tb6_lock));
+			if (replace_rt)
+				call_fib6_entry_notifiers_replace(net,
+								  replace_rt);
+			else
+				call_fib6_multipath_entry_notifiers(net,
+						       FIB_EVENT_ENTRY_DEL_TMP,
+						       rt, rt->fib6_nsiblings,
+						       NULL);
+		}
 		call_fib6_multipath_entry_notifiers(net,
 						    FIB_EVENT_ENTRY_DEL,
 						    rt,
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next 8/9] mlxsw: spectrum_router: Start using new IPv6 route notifications
  2019-12-23 13:28 [PATCH net-next 0/9] Simplify IPv6 route offload API Ido Schimmel
                   ` (6 preceding siblings ...)
  2019-12-23 13:28 ` [PATCH net-next 7/9] ipv6: Handle multipath " Ido Schimmel
@ 2019-12-23 13:28 ` Ido Schimmel
  2019-12-23 13:28 ` [PATCH net-next 9/9] ipv6: Remove old route notifications and convert listeners Ido Schimmel
  2019-12-25  6:38 ` [PATCH net-next 0/9] Simplify IPv6 route offload API David Miller
  9 siblings, 0 replies; 20+ messages in thread
From: Ido Schimmel @ 2019-12-23 13:28 UTC (permalink / raw)
  To: netdev; +Cc: davem, dsahern, roopa, jakub.kicinski, jiri, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

With the new notifications mlxsw does not need to handle identical
routes itself, as this is taken care of by the core IPv6 code.

Instead, mlxsw only needs to take care of inserting and removing routes
from the device.

Convert mlxsw to use the new IPv6 route notifications and simplify the
code.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
---
 .../ethernet/mellanox/mlxsw/spectrum_router.c | 225 ++++++------------
 1 file changed, 76 insertions(+), 149 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 0678815efbf3..295cdcb1c4c0 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -4989,13 +4989,6 @@ static void mlxsw_sp_rt6_destroy(struct mlxsw_sp_rt6 *mlxsw_sp_rt6)
 	kfree(mlxsw_sp_rt6);
 }
 
-static bool mlxsw_sp_fib6_rt_can_mp(const struct fib6_info *rt)
-{
-	/* RTF_CACHE routes are ignored */
-	return !(rt->fib6_flags & RTF_ADDRCONF) &&
-		rt->fib6_nh->fib_nh_gw_family;
-}
-
 static struct fib6_info *
 mlxsw_sp_fib6_entry_rt(const struct mlxsw_sp_fib6_entry *fib6_entry)
 {
@@ -5003,37 +4996,6 @@ mlxsw_sp_fib6_entry_rt(const struct mlxsw_sp_fib6_entry *fib6_entry)
 				list)->rt;
 }
 
-static struct mlxsw_sp_fib6_entry *
-mlxsw_sp_fib6_node_mp_entry_find(const struct mlxsw_sp_fib_node *fib_node,
-				 const struct fib6_info *nrt, bool replace)
-{
-	struct mlxsw_sp_fib6_entry *fib6_entry;
-
-	if (!mlxsw_sp_fib6_rt_can_mp(nrt) || replace)
-		return NULL;
-
-	list_for_each_entry(fib6_entry, &fib_node->entry_list, common.list) {
-		struct fib6_info *rt = mlxsw_sp_fib6_entry_rt(fib6_entry);
-
-		/* RT6_TABLE_LOCAL and RT6_TABLE_MAIN share the same
-		 * virtual router.
-		 */
-		if (rt->fib6_table->tb6_id > nrt->fib6_table->tb6_id)
-			continue;
-		if (rt->fib6_table->tb6_id != nrt->fib6_table->tb6_id)
-			break;
-		if (rt->fib6_metric < nrt->fib6_metric)
-			continue;
-		if (rt->fib6_metric == nrt->fib6_metric &&
-		    mlxsw_sp_fib6_rt_can_mp(rt))
-			return fib6_entry;
-		if (rt->fib6_metric > nrt->fib6_metric)
-			break;
-	}
-
-	return NULL;
-}
-
 static struct mlxsw_sp_rt6 *
 mlxsw_sp_fib6_entry_rt_find(const struct mlxsw_sp_fib6_entry *fib6_entry,
 			    const struct fib6_info *rt)
@@ -5424,86 +5386,13 @@ static void mlxsw_sp_fib6_entry_destroy(struct mlxsw_sp *mlxsw_sp,
 	kfree(fib6_entry);
 }
 
-static struct mlxsw_sp_fib6_entry *
-mlxsw_sp_fib6_node_entry_find(const struct mlxsw_sp_fib_node *fib_node,
-			      const struct fib6_info *nrt, bool replace)
-{
-	struct mlxsw_sp_fib6_entry *fib6_entry, *fallback = NULL;
-
-	list_for_each_entry(fib6_entry, &fib_node->entry_list, common.list) {
-		struct fib6_info *rt = mlxsw_sp_fib6_entry_rt(fib6_entry);
-
-		if (rt->fib6_table->tb6_id > nrt->fib6_table->tb6_id)
-			continue;
-		if (rt->fib6_table->tb6_id != nrt->fib6_table->tb6_id)
-			break;
-		if (replace && rt->fib6_metric == nrt->fib6_metric) {
-			if (mlxsw_sp_fib6_rt_can_mp(rt) ==
-			    mlxsw_sp_fib6_rt_can_mp(nrt))
-				return fib6_entry;
-			if (mlxsw_sp_fib6_rt_can_mp(nrt))
-				fallback = fallback ?: fib6_entry;
-		}
-		if (rt->fib6_metric > nrt->fib6_metric)
-			return fallback ?: fib6_entry;
-	}
-
-	return fallback;
-}
-
-static int
-mlxsw_sp_fib6_node_list_insert(struct mlxsw_sp_fib6_entry *new6_entry,
-			       bool *p_replace)
-{
-	struct mlxsw_sp_fib_node *fib_node = new6_entry->common.fib_node;
-	struct fib6_info *nrt = mlxsw_sp_fib6_entry_rt(new6_entry);
-	struct mlxsw_sp_fib6_entry *fib6_entry;
-
-	fib6_entry = mlxsw_sp_fib6_node_entry_find(fib_node, nrt, *p_replace);
-
-	if (*p_replace && !fib6_entry)
-		*p_replace = false;
-
-	if (fib6_entry) {
-		list_add_tail(&new6_entry->common.list,
-			      &fib6_entry->common.list);
-	} else {
-		struct mlxsw_sp_fib6_entry *last;
-
-		list_for_each_entry(last, &fib_node->entry_list, common.list) {
-			struct fib6_info *rt = mlxsw_sp_fib6_entry_rt(last);
-
-			if (nrt->fib6_table->tb6_id > rt->fib6_table->tb6_id)
-				break;
-			fib6_entry = last;
-		}
-
-		if (fib6_entry)
-			list_add(&new6_entry->common.list,
-				 &fib6_entry->common.list);
-		else
-			list_add(&new6_entry->common.list,
-				 &fib_node->entry_list);
-	}
-
-	return 0;
-}
-
-static void
-mlxsw_sp_fib6_node_list_remove(struct mlxsw_sp_fib6_entry *fib6_entry)
-{
-	list_del(&fib6_entry->common.list);
-}
-
 static int mlxsw_sp_fib6_node_entry_link(struct mlxsw_sp *mlxsw_sp,
-					 struct mlxsw_sp_fib6_entry *fib6_entry,
-					 bool *p_replace)
+					 struct mlxsw_sp_fib6_entry *fib6_entry)
 {
+	struct mlxsw_sp_fib_node *fib_node = fib6_entry->common.fib_node;
 	int err;
 
-	err = mlxsw_sp_fib6_node_list_insert(fib6_entry, p_replace);
-	if (err)
-		return err;
+	list_add(&fib6_entry->common.list, &fib_node->entry_list);
 
 	err = mlxsw_sp_fib_node_entry_add(mlxsw_sp, &fib6_entry->common);
 	if (err)
@@ -5512,7 +5401,7 @@ static int mlxsw_sp_fib6_node_entry_link(struct mlxsw_sp *mlxsw_sp,
 	return 0;
 
 err_fib_node_entry_add:
-	mlxsw_sp_fib6_node_list_remove(fib6_entry);
+	list_del(&fib6_entry->common.list);
 	return err;
 }
 
@@ -5521,7 +5410,7 @@ mlxsw_sp_fib6_node_entry_unlink(struct mlxsw_sp *mlxsw_sp,
 				struct mlxsw_sp_fib6_entry *fib6_entry)
 {
 	mlxsw_sp_fib_node_entry_del(mlxsw_sp, &fib6_entry->common);
-	mlxsw_sp_fib6_node_list_remove(fib6_entry);
+	list_del(&fib6_entry->common.list);
 }
 
 static struct mlxsw_sp_fib6_entry *
@@ -5557,15 +5446,15 @@ mlxsw_sp_fib6_entry_lookup(struct mlxsw_sp *mlxsw_sp,
 }
 
 static void mlxsw_sp_fib6_entry_replace(struct mlxsw_sp *mlxsw_sp,
-					struct mlxsw_sp_fib6_entry *fib6_entry,
-					bool replace)
+					struct mlxsw_sp_fib6_entry *fib6_entry)
 {
 	struct mlxsw_sp_fib_node *fib_node = fib6_entry->common.fib_node;
 	struct mlxsw_sp_fib6_entry *replaced;
 
-	if (!replace)
+	if (list_is_singular(&fib_node->entry_list))
 		return;
 
+	/* We inserted the new entry before replaced one */
 	replaced = list_next_entry(fib6_entry, common.list);
 
 	mlxsw_sp_fib6_node_entry_unlink(mlxsw_sp, replaced);
@@ -5573,9 +5462,9 @@ static void mlxsw_sp_fib6_entry_replace(struct mlxsw_sp *mlxsw_sp,
 	mlxsw_sp_fib_node_put(mlxsw_sp, fib_node);
 }
 
-static int mlxsw_sp_router_fib6_add(struct mlxsw_sp *mlxsw_sp,
-				    struct fib6_info **rt_arr,
-				    unsigned int nrt6, bool replace)
+static int mlxsw_sp_router_fib6_replace(struct mlxsw_sp *mlxsw_sp,
+					struct fib6_info **rt_arr,
+					unsigned int nrt6)
 {
 	struct mlxsw_sp_fib6_entry *fib6_entry;
 	struct mlxsw_sp_fib_node *fib_node;
@@ -5599,18 +5488,6 @@ static int mlxsw_sp_router_fib6_add(struct mlxsw_sp *mlxsw_sp,
 	if (IS_ERR(fib_node))
 		return PTR_ERR(fib_node);
 
-	/* Before creating a new entry, try to append route to an existing
-	 * multipath entry.
-	 */
-	fib6_entry = mlxsw_sp_fib6_node_mp_entry_find(fib_node, rt, replace);
-	if (fib6_entry) {
-		err = mlxsw_sp_fib6_entry_nexthop_add(mlxsw_sp, fib6_entry,
-						      rt_arr, nrt6);
-		if (err)
-			goto err_fib6_entry_nexthop_add;
-		return 0;
-	}
-
 	fib6_entry = mlxsw_sp_fib6_entry_create(mlxsw_sp, fib_node, rt_arr,
 						nrt6);
 	if (IS_ERR(fib6_entry)) {
@@ -5618,17 +5495,61 @@ static int mlxsw_sp_router_fib6_add(struct mlxsw_sp *mlxsw_sp,
 		goto err_fib6_entry_create;
 	}
 
-	err = mlxsw_sp_fib6_node_entry_link(mlxsw_sp, fib6_entry, &replace);
+	err = mlxsw_sp_fib6_node_entry_link(mlxsw_sp, fib6_entry);
 	if (err)
 		goto err_fib6_node_entry_link;
 
-	mlxsw_sp_fib6_entry_replace(mlxsw_sp, fib6_entry, replace);
+	mlxsw_sp_fib6_entry_replace(mlxsw_sp, fib6_entry);
 
 	return 0;
 
 err_fib6_node_entry_link:
 	mlxsw_sp_fib6_entry_destroy(mlxsw_sp, fib6_entry);
 err_fib6_entry_create:
+	mlxsw_sp_fib_node_put(mlxsw_sp, fib_node);
+	return err;
+}
+
+static int mlxsw_sp_router_fib6_append(struct mlxsw_sp *mlxsw_sp,
+				       struct fib6_info **rt_arr,
+				       unsigned int nrt6)
+{
+	struct mlxsw_sp_fib6_entry *fib6_entry;
+	struct mlxsw_sp_fib_node *fib_node;
+	struct fib6_info *rt = rt_arr[0];
+	int err;
+
+	if (mlxsw_sp->router->aborted)
+		return 0;
+
+	if (rt->fib6_src.plen)
+		return -EINVAL;
+
+	if (mlxsw_sp_fib6_rt_should_ignore(rt))
+		return 0;
+
+	fib_node = mlxsw_sp_fib_node_get(mlxsw_sp, rt->fib6_table->tb6_id,
+					 &rt->fib6_dst.addr,
+					 sizeof(rt->fib6_dst.addr),
+					 rt->fib6_dst.plen,
+					 MLXSW_SP_L3_PROTO_IPV6);
+	if (IS_ERR(fib_node))
+		return PTR_ERR(fib_node);
+
+	if (WARN_ON_ONCE(list_empty(&fib_node->entry_list))) {
+		mlxsw_sp_fib_node_put(mlxsw_sp, fib_node);
+		return -EINVAL;
+	}
+
+	fib6_entry = list_first_entry(&fib_node->entry_list,
+				      struct mlxsw_sp_fib6_entry, common.list);
+	err = mlxsw_sp_fib6_entry_nexthop_add(mlxsw_sp, fib6_entry, rt_arr,
+					      nrt6);
+	if (err)
+		goto err_fib6_entry_nexthop_add;
+
+	return 0;
+
 err_fib6_entry_nexthop_add:
 	mlxsw_sp_fib_node_put(mlxsw_sp, fib_node);
 	return err;
@@ -6039,25 +5960,29 @@ static void mlxsw_sp_router_fib6_event_work(struct work_struct *work)
 	struct mlxsw_sp_fib_event_work *fib_work =
 		container_of(work, struct mlxsw_sp_fib_event_work, work);
 	struct mlxsw_sp *mlxsw_sp = fib_work->mlxsw_sp;
-	bool replace;
 	int err;
 
 	rtnl_lock();
 	mlxsw_sp_span_respin(mlxsw_sp);
 
 	switch (fib_work->event) {
-	case FIB_EVENT_ENTRY_REPLACE: /* fall through */
-	case FIB_EVENT_ENTRY_ADD:
-		replace = fib_work->event == FIB_EVENT_ENTRY_REPLACE;
-		err = mlxsw_sp_router_fib6_add(mlxsw_sp,
-					       fib_work->fib6_work.rt_arr,
-					       fib_work->fib6_work.nrt6,
-					       replace);
+	case FIB_EVENT_ENTRY_REPLACE_TMP:
+		err = mlxsw_sp_router_fib6_replace(mlxsw_sp,
+						   fib_work->fib6_work.rt_arr,
+						   fib_work->fib6_work.nrt6);
 		if (err)
 			mlxsw_sp_router_fib_abort(mlxsw_sp);
 		mlxsw_sp_router_fib6_work_fini(&fib_work->fib6_work);
 		break;
-	case FIB_EVENT_ENTRY_DEL:
+	case FIB_EVENT_ENTRY_APPEND:
+		err = mlxsw_sp_router_fib6_append(mlxsw_sp,
+						  fib_work->fib6_work.rt_arr,
+						  fib_work->fib6_work.nrt6);
+		if (err)
+			mlxsw_sp_router_fib_abort(mlxsw_sp);
+		mlxsw_sp_router_fib6_work_fini(&fib_work->fib6_work);
+		break;
+	case FIB_EVENT_ENTRY_DEL_TMP:
 		mlxsw_sp_router_fib6_del(mlxsw_sp,
 					 fib_work->fib6_work.rt_arr,
 					 fib_work->fib6_work.nrt6);
@@ -6143,9 +6068,9 @@ static int mlxsw_sp_router_fib6_event(struct mlxsw_sp_fib_event_work *fib_work,
 	int err;
 
 	switch (fib_work->event) {
-	case FIB_EVENT_ENTRY_REPLACE: /* fall through */
-	case FIB_EVENT_ENTRY_ADD: /* fall through */
-	case FIB_EVENT_ENTRY_DEL:
+	case FIB_EVENT_ENTRY_REPLACE_TMP: /* fall through */
+	case FIB_EVENT_ENTRY_APPEND: /* fall through */
+	case FIB_EVENT_ENTRY_DEL_TMP:
 		fen6_info = container_of(info, struct fib6_entry_notifier_info,
 					 info);
 		err = mlxsw_sp_router_fib6_work_init(&fib_work->fib6_work,
@@ -6248,7 +6173,9 @@ static int mlxsw_sp_router_fib_event(struct notifier_block *nb,
 						     router->mlxsw_sp);
 		return notifier_from_errno(err);
 	case FIB_EVENT_ENTRY_ADD: /* fall through */
-	case FIB_EVENT_ENTRY_REPLACE:
+	case FIB_EVENT_ENTRY_REPLACE: /* fall through */
+	case FIB_EVENT_ENTRY_REPLACE_TMP: /* fall through */
+	case FIB_EVENT_ENTRY_APPEND:
 		if (router->aborted) {
 			NL_SET_ERR_MSG_MOD(info->extack, "FIB offload was aborted. Not configuring route");
 			return notifier_from_errno(-EINVAL);
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next 9/9] ipv6: Remove old route notifications and convert listeners
  2019-12-23 13:28 [PATCH net-next 0/9] Simplify IPv6 route offload API Ido Schimmel
                   ` (7 preceding siblings ...)
  2019-12-23 13:28 ` [PATCH net-next 8/9] mlxsw: spectrum_router: Start using new IPv6 route notifications Ido Schimmel
@ 2019-12-23 13:28 ` Ido Schimmel
  2019-12-24 17:12   ` David Ahern
  2019-12-25  6:38 ` [PATCH net-next 0/9] Simplify IPv6 route offload API David Miller
  9 siblings, 1 reply; 20+ messages in thread
From: Ido Schimmel @ 2019-12-23 13:28 UTC (permalink / raw)
  To: netdev; +Cc: davem, dsahern, roopa, jakub.kicinski, jiri, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

Now that mlxsw is converted to use the new FIB notifications it is
possible to delete the old ones and use the new replace / append /
delete notifications.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
---
 .../ethernet/mellanox/mlxsw/spectrum_router.c |  9 ++-
 drivers/net/netdevsim/fib.c                   |  1 -
 include/net/fib_notifier.h                    |  2 -
 net/ipv6/ip6_fib.c                            | 61 +++++--------------
 net/ipv6/route.c                              | 18 +-----
 5 files changed, 21 insertions(+), 70 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 295cdcb1c4c0..f62e8d67348c 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -5966,7 +5966,7 @@ static void mlxsw_sp_router_fib6_event_work(struct work_struct *work)
 	mlxsw_sp_span_respin(mlxsw_sp);
 
 	switch (fib_work->event) {
-	case FIB_EVENT_ENTRY_REPLACE_TMP:
+	case FIB_EVENT_ENTRY_REPLACE:
 		err = mlxsw_sp_router_fib6_replace(mlxsw_sp,
 						   fib_work->fib6_work.rt_arr,
 						   fib_work->fib6_work.nrt6);
@@ -5982,7 +5982,7 @@ static void mlxsw_sp_router_fib6_event_work(struct work_struct *work)
 			mlxsw_sp_router_fib_abort(mlxsw_sp);
 		mlxsw_sp_router_fib6_work_fini(&fib_work->fib6_work);
 		break;
-	case FIB_EVENT_ENTRY_DEL_TMP:
+	case FIB_EVENT_ENTRY_DEL:
 		mlxsw_sp_router_fib6_del(mlxsw_sp,
 					 fib_work->fib6_work.rt_arr,
 					 fib_work->fib6_work.nrt6);
@@ -6068,9 +6068,9 @@ static int mlxsw_sp_router_fib6_event(struct mlxsw_sp_fib_event_work *fib_work,
 	int err;
 
 	switch (fib_work->event) {
-	case FIB_EVENT_ENTRY_REPLACE_TMP: /* fall through */
+	case FIB_EVENT_ENTRY_REPLACE: /* fall through */
 	case FIB_EVENT_ENTRY_APPEND: /* fall through */
-	case FIB_EVENT_ENTRY_DEL_TMP:
+	case FIB_EVENT_ENTRY_DEL:
 		fen6_info = container_of(info, struct fib6_entry_notifier_info,
 					 info);
 		err = mlxsw_sp_router_fib6_work_init(&fib_work->fib6_work,
@@ -6174,7 +6174,6 @@ static int mlxsw_sp_router_fib_event(struct notifier_block *nb,
 		return notifier_from_errno(err);
 	case FIB_EVENT_ENTRY_ADD: /* fall through */
 	case FIB_EVENT_ENTRY_REPLACE: /* fall through */
-	case FIB_EVENT_ENTRY_REPLACE_TMP: /* fall through */
 	case FIB_EVENT_ENTRY_APPEND:
 		if (router->aborted) {
 			NL_SET_ERR_MSG_MOD(info->extack, "FIB offload was aborted. Not configuring route");
diff --git a/drivers/net/netdevsim/fib.c b/drivers/net/netdevsim/fib.c
index 4e02a4231fcb..b5df308b4e33 100644
--- a/drivers/net/netdevsim/fib.c
+++ b/drivers/net/netdevsim/fib.c
@@ -178,7 +178,6 @@ static int nsim_fib_event_nb(struct notifier_block *nb, unsigned long event,
 		break;
 
 	case FIB_EVENT_ENTRY_REPLACE:  /* fall through */
-	case FIB_EVENT_ENTRY_ADD:  /* fall through */
 	case FIB_EVENT_ENTRY_DEL:
 		err = nsim_fib_event(data, info, event != FIB_EVENT_ENTRY_DEL);
 		break;
diff --git a/include/net/fib_notifier.h b/include/net/fib_notifier.h
index b3c54325caec..6d59221ff05a 100644
--- a/include/net/fib_notifier.h
+++ b/include/net/fib_notifier.h
@@ -23,8 +23,6 @@ enum fib_event_type {
 	FIB_EVENT_NH_DEL,
 	FIB_EVENT_VIF_ADD,
 	FIB_EVENT_VIF_DEL,
-	FIB_EVENT_ENTRY_REPLACE_TMP,
-	FIB_EVENT_ENTRY_DEL_TMP,
 };
 
 struct fib_notifier_ops {
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 67ddee539f77..b1e9a10e1133 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -423,8 +423,7 @@ int call_fib6_entry_notifiers_replace(struct net *net, struct fib6_info *rt)
 	};
 
 	rt->fib6_table->fib_seq++;
-	return call_fib6_notifiers(net, FIB_EVENT_ENTRY_REPLACE_TMP,
-				   &info.info);
+	return call_fib6_notifiers(net, FIB_EVENT_ENTRY_REPLACE, &info.info);
 }
 
 struct fib6_dump_arg {
@@ -435,15 +434,7 @@ struct fib6_dump_arg {
 
 static int fib6_rt_dump(struct fib6_info *rt, struct fib6_dump_arg *arg)
 {
-	if (rt == arg->net->ipv6.fib6_null_entry)
-		return 0;
-	return call_fib6_entry_notifier(arg->nb, FIB_EVENT_ENTRY_ADD,
-					rt, arg->extack);
-}
-
-static int fib6_rt_dump_tmp(struct fib6_info *rt, struct fib6_dump_arg *arg)
-{
-	enum fib_event_type fib_event = FIB_EVENT_ENTRY_REPLACE_TMP;
+	enum fib_event_type fib_event = FIB_EVENT_ENTRY_REPLACE;
 	int err;
 
 	if (!rt || rt == arg->net->ipv6.fib6_null_entry)
@@ -463,19 +454,9 @@ static int fib6_rt_dump_tmp(struct fib6_info *rt, struct fib6_dump_arg *arg)
 
 static int fib6_node_dump(struct fib6_walker *w)
 {
-	struct fib6_info *rt;
-	int err = 0;
-
-	err = fib6_rt_dump_tmp(w->leaf, w->args);
-	if (err)
-		goto out;
+	int err;
 
-	for_each_fib6_walker_rt(w) {
-		err = fib6_rt_dump(rt, w->args);
-		if (err)
-			break;
-	}
-out:
+	err = fib6_rt_dump(w->leaf, w->args);
 	w->leaf = NULL;
 	return err;
 }
@@ -1220,25 +1201,21 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
 add:
 		nlflags |= NLM_F_CREATE;
 
-		if (!info->skip_notify_kernel) {
+		/* The route should only be notified if it is the first
+		 * route in the node or if it is added as a sibling
+		 * route to the first route in the node.
+		 */
+		if (!info->skip_notify_kernel &&
+		    (notify_sibling_rt || ins == &fn->leaf)) {
 			enum fib_event_type fib_event;
 
 			if (notify_sibling_rt)
 				fib_event = FIB_EVENT_ENTRY_APPEND;
 			else
-				fib_event = FIB_EVENT_ENTRY_REPLACE_TMP;
-			/* The route should only be notified if it is the first
-			 * route in the node or if it is added as a sibling
-			 * route to the first route in the node.
-			 */
-			if (notify_sibling_rt || ins == &fn->leaf)
-				err = call_fib6_entry_notifiers(info->nl_net,
-								fib_event, rt,
-								extack);
-
+				fib_event = FIB_EVENT_ENTRY_REPLACE;
 			err = call_fib6_entry_notifiers(info->nl_net,
-							FIB_EVENT_ENTRY_ADD,
-							rt, extack);
+							fib_event, rt,
+							extack);
 			if (err) {
 				struct fib6_info *sibling, *next_sibling;
 
@@ -1282,14 +1259,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
 			return -ENOENT;
 		}
 
-		if (!info->skip_notify_kernel) {
-			enum fib_event_type fib_event;
-
-			fib_event = FIB_EVENT_ENTRY_REPLACE_TMP;
-			if (ins == &fn->leaf)
-				err = call_fib6_entry_notifiers(info->nl_net,
-								fib_event, rt,
-								extack);
+		if (!info->skip_notify_kernel && ins == &fn->leaf) {
 			err = call_fib6_entry_notifiers(info->nl_net,
 							FIB_EVENT_ENTRY_REPLACE,
 							rt, extack);
@@ -2007,11 +1977,10 @@ static void fib6_del_route(struct fib6_table *table, struct fib6_node *fn,
 
 	if (!info->skip_notify_kernel) {
 		if (notify_del)
-			call_fib6_entry_notifiers(net, FIB_EVENT_ENTRY_DEL_TMP,
+			call_fib6_entry_notifiers(net, FIB_EVENT_ENTRY_DEL,
 						  rt, NULL);
 		else if (replace_rt)
 			call_fib6_entry_notifiers_replace(net, replace_rt);
-		call_fib6_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, rt, NULL);
 	}
 	if (!info->skip_notify)
 		inet6_rt_notify(RTM_DELROUTE, rt, info, 0);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 646716a47cc9..4b8659e077d3 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -3787,15 +3787,10 @@ static int __ip6_del_rt_siblings(struct fib6_info *rt, struct fib6_config *cfg)
 								  replace_rt);
 			else
 				call_fib6_multipath_entry_notifiers(net,
-						       FIB_EVENT_ENTRY_DEL_TMP,
+						       FIB_EVENT_ENTRY_DEL,
 						       rt, rt->fib6_nsiblings,
 						       NULL);
 		}
-		call_fib6_multipath_entry_notifiers(net,
-						    FIB_EVENT_ENTRY_DEL,
-						    rt,
-						    rt->fib6_nsiblings,
-						    NULL);
 		list_for_each_entry_safe(sibling, next_sibling,
 					 &rt->fib6_siblings,
 					 fib6_siblings) {
@@ -5074,7 +5069,6 @@ static int ip6_route_multipath_add(struct fib6_config *cfg,
 {
 	struct fib6_info *rt_notif = NULL, *rt_last = NULL;
 	struct nl_info *info = &cfg->fc_nlinfo;
-	enum fib_event_type event_type;
 	struct fib6_config r_cfg;
 	struct rtnexthop *rtnh;
 	struct fib6_info *rt;
@@ -5210,7 +5204,7 @@ static int ip6_route_multipath_add(struct fib6_config *cfg,
 		if (rt_notif->fib6_nsiblings != nhn - 1)
 			fib_event = FIB_EVENT_ENTRY_APPEND;
 		else
-			fib_event = FIB_EVENT_ENTRY_REPLACE_TMP;
+			fib_event = FIB_EVENT_ENTRY_REPLACE;
 
 		err = call_fib6_multipath_entry_notifiers(info->nl_net,
 							  fib_event, rt_notif,
@@ -5221,14 +5215,6 @@ static int ip6_route_multipath_add(struct fib6_config *cfg,
 			goto add_errout;
 		}
 	}
-	event_type = replace ? FIB_EVENT_ENTRY_REPLACE : FIB_EVENT_ENTRY_ADD;
-	err = call_fib6_multipath_entry_notifiers(info->nl_net, event_type,
-						  rt_notif, nhn - 1, extack);
-	if (err) {
-		/* Delete all the siblings that were just added */
-		err_nh = NULL;
-		goto add_errout;
-	}
 
 	/* success ... tell user about new route */
 	ip6_route_mpath_notify(rt_notif, rt_last, info, nlflags);
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next 1/9] net: fib_notifier: Add temporary events to the FIB notification chain
  2019-12-23 13:28 ` [PATCH net-next 1/9] net: fib_notifier: Add temporary events to the FIB notification chain Ido Schimmel
@ 2019-12-24 16:40   ` David Ahern
  0 siblings, 0 replies; 20+ messages in thread
From: David Ahern @ 2019-12-24 16:40 UTC (permalink / raw)
  To: Ido Schimmel, netdev; +Cc: davem, roopa, jakub.kicinski, jiri, Ido Schimmel

On 12/23/19 6:28 AM, Ido Schimmel wrote:
> From: Ido Schimmel <idosch@mellanox.com>
> 
> Subsequent patches are going to simplify the IPv6 route offload API,
> which will only use three events - replace, delete and append.
> 
> Introduce a temporary version of replace and delete in order to make the
> conversion easier to review. Note that append does not need a temporary
> version, as it is currently not used.
> 
> Signed-off-by: Ido Schimmel <idosch@mellanox.com>
> Reviewed-by: Jiri Pirko <jiri@mellanox.com>
> ---
>  include/net/fib_notifier.h | 2 ++
>  1 file changed, 2 insertions(+)
> 

Reviewed-by: David Ahern <dsahern@gmail.com>



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next 2/9] ipv6: Notify newly added route if should be offloaded
  2019-12-23 13:28 ` [PATCH net-next 2/9] ipv6: Notify newly added route if should be offloaded Ido Schimmel
@ 2019-12-24 16:40   ` David Ahern
  0 siblings, 0 replies; 20+ messages in thread
From: David Ahern @ 2019-12-24 16:40 UTC (permalink / raw)
  To: Ido Schimmel, netdev; +Cc: davem, roopa, jakub.kicinski, jiri, Ido Schimmel

On 12/23/19 6:28 AM, Ido Schimmel wrote:
> From: Ido Schimmel <idosch@mellanox.com>
> 
> fib6_add_rt2node() takes care of adding a single route ('struct
> fib6_info') to a FIB node. The route in question should only be notified
> in case it is added as the first route in the node (lowest metric) or if
> it is added as a sibling route to the first route in the node.
> 
> The first criterion can be tested by checking if the route is pointed to
> by 'fn->leaf'. The second criterion can be tested by checking the new
> 'notify_sibling_rt' variable that is set when the route is added as a
> sibling to the first route in the node.
> 
> Signed-off-by: Ido Schimmel <idosch@mellanox.com>
> Reviewed-by: Jiri Pirko <jiri@mellanox.com>
> ---
>  net/ipv6/ip6_fib.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 

Reviewed-by: David Ahern <dsahern@gmail.com>



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next 3/9] ipv6: Notify route if replacing currently offloaded one
  2019-12-23 13:28 ` [PATCH net-next 3/9] ipv6: Notify route if replacing currently offloaded one Ido Schimmel
@ 2019-12-24 16:44   ` David Ahern
  0 siblings, 0 replies; 20+ messages in thread
From: David Ahern @ 2019-12-24 16:44 UTC (permalink / raw)
  To: Ido Schimmel, netdev; +Cc: davem, roopa, jakub.kicinski, jiri, Ido Schimmel

On 12/23/19 6:28 AM, Ido Schimmel wrote:
> From: Ido Schimmel <idosch@mellanox.com>
> 
> Similar to the corresponding IPv4 patch, only notify the new route if it
> is replacing the currently offloaded one. Meaning, the one pointed to by
> 'fn->leaf'.
> 
> Signed-off-by: Ido Schimmel <idosch@mellanox.com>
> Reviewed-by: Jiri Pirko <jiri@mellanox.com>
> ---
>  net/ipv6/ip6_fib.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 

Reviewed-by: David Ahern <dsahern@gmail.com>



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next 4/9] ipv6: Notify multipath route if should be offloaded
  2019-12-23 13:28 ` [PATCH net-next 4/9] ipv6: Notify multipath route if should be offloaded Ido Schimmel
@ 2019-12-24 16:49   ` David Ahern
  0 siblings, 0 replies; 20+ messages in thread
From: David Ahern @ 2019-12-24 16:49 UTC (permalink / raw)
  To: Ido Schimmel, netdev; +Cc: davem, roopa, jakub.kicinski, jiri, Ido Schimmel

On 12/23/19 6:28 AM, Ido Schimmel wrote:
> From: Ido Schimmel <idosch@mellanox.com>
> 
> In a similar fashion to previous patches, only notify the new multipath
> route if it is the first route in the node or if it was appended to such
> route.
> 
> The type of the notification (replace vs. append) is determined based on
> the number of routes added ('nhn') and the number of sibling routes. If
> the two do not match, then an append notification should be sent.
> 
> Signed-off-by: Ido Schimmel <idosch@mellanox.com>
> Reviewed-by: Jiri Pirko <jiri@mellanox.com>
> ---
>  net/ipv6/route.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 48 insertions(+)
> 

Reviewed-by: David Ahern <dsahern@gmail.com>



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next 5/9] ipv6: Only Replay routes of interest to new listeners
  2019-12-23 13:28 ` [PATCH net-next 5/9] ipv6: Only Replay routes of interest to new listeners Ido Schimmel
@ 2019-12-24 16:58   ` David Ahern
  0 siblings, 0 replies; 20+ messages in thread
From: David Ahern @ 2019-12-24 16:58 UTC (permalink / raw)
  To: Ido Schimmel, netdev; +Cc: davem, roopa, jakub.kicinski, jiri, Ido Schimmel

On 12/23/19 6:28 AM, Ido Schimmel wrote:
> From: Ido Schimmel <idosch@mellanox.com>
> 
> When a new listener is registered to the FIB notification chain it
> receives a dump of all the available routes in the system. Instead, make
> sure to only replay the IPv6 routes that are actually used in the data
> path and are of any interest to the new listener.
> 
> This is done by iterating over all the routing tables in the given
> namespace, but from each traversed node only the first route ('leaf') is
> notified. Multipath routes are notified in a single notification instead
> of one for each nexthop.
> 
> Add fib6_rt_dump_tmp() to do that. Later on in the patch set it will be
> renamed to fib6_rt_dump() instead of the existing one.
> 
> Signed-off-by: Ido Schimmel <idosch@mellanox.com>
> Reviewed-by: Jiri Pirko <jiri@mellanox.com>
> ---
>  net/ipv6/ip6_fib.c | 40 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 40 insertions(+)
> 

Reviewed-by: David Ahern <dsahern@gmail.com>



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next 6/9] ipv6: Handle route deletion notification
  2019-12-23 13:28 ` [PATCH net-next 6/9] ipv6: Handle route deletion notification Ido Schimmel
@ 2019-12-24 17:03   ` David Ahern
  0 siblings, 0 replies; 20+ messages in thread
From: David Ahern @ 2019-12-24 17:03 UTC (permalink / raw)
  To: Ido Schimmel, netdev; +Cc: davem, roopa, jakub.kicinski, jiri, Ido Schimmel

On 12/23/19 6:28 AM, Ido Schimmel wrote:
> From: Ido Schimmel <idosch@mellanox.com>
> 
> For the purpose of route offload, when a single route is deleted, it is
> only of interest if it is the first route in the node or if it is
> sibling to such a route.
> 
> In the first case, distinguish between several possibilities:
> 
> 1. Route is the last route in the node. Emit a delete notification
> 
> 2. Route is followed by a non-multipath route. Emit a replace
> notification for the non-multipath route.
> 
> 3. Route is followed by a multipath route. Emit a replace notification
> for the multipath route.
> 
> In the second case, only emit a delete notification to ensure the route
> is no longer used as a valid nexthop.
> 
> Signed-off-by: Ido Schimmel <idosch@mellanox.com>
> Reviewed-by: Jiri Pirko <jiri@mellanox.com>
> ---
>  include/net/ip6_fib.h |  1 +
>  net/ipv6/ip6_fib.c    | 44 ++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 44 insertions(+), 1 deletion(-)
> 

Reviewed-by: David Ahern <dsahern@gmail.com>



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next 7/9] ipv6: Handle multipath route deletion notification
  2019-12-23 13:28 ` [PATCH net-next 7/9] ipv6: Handle multipath " Ido Schimmel
@ 2019-12-24 17:09   ` David Ahern
  0 siblings, 0 replies; 20+ messages in thread
From: David Ahern @ 2019-12-24 17:09 UTC (permalink / raw)
  To: Ido Schimmel, netdev; +Cc: davem, roopa, jakub.kicinski, jiri, Ido Schimmel

On 12/23/19 6:28 AM, Ido Schimmel wrote:
> From: Ido Schimmel <idosch@mellanox.com>
> 
> When an entire multipath route is deleted, only emit a notification if
> it is the first route in the node. Emit a replace notification in case
> the last sibling is followed by another route. Otherwise, emit a delete
> notification.
> 
> Signed-off-by: Ido Schimmel <idosch@mellanox.com>
> Reviewed-by: Jiri Pirko <jiri@mellanox.com>
> ---
>  net/ipv6/route.c | 26 ++++++++++++++++++++++++++
>  1 file changed, 26 insertions(+)
> 

Reviewed-by: David Ahern <dsahern@gmail.com>



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next 9/9] ipv6: Remove old route notifications and convert listeners
  2019-12-23 13:28 ` [PATCH net-next 9/9] ipv6: Remove old route notifications and convert listeners Ido Schimmel
@ 2019-12-24 17:12   ` David Ahern
  0 siblings, 0 replies; 20+ messages in thread
From: David Ahern @ 2019-12-24 17:12 UTC (permalink / raw)
  To: Ido Schimmel, netdev; +Cc: davem, roopa, jakub.kicinski, jiri, Ido Schimmel

On 12/23/19 6:28 AM, Ido Schimmel wrote:
> From: Ido Schimmel <idosch@mellanox.com>
> 
> Now that mlxsw is converted to use the new FIB notifications it is
> possible to delete the old ones and use the new replace / append /
> delete notifications.
> 
> Signed-off-by: Ido Schimmel <idosch@mellanox.com>
> Reviewed-by: Jiri Pirko <jiri@mellanox.com>
> ---
>  .../ethernet/mellanox/mlxsw/spectrum_router.c |  9 ++-
>  drivers/net/netdevsim/fib.c                   |  1 -
>  include/net/fib_notifier.h                    |  2 -
>  net/ipv6/ip6_fib.c                            | 61 +++++--------------
>  net/ipv6/route.c                              | 18 +-----
>  5 files changed, 21 insertions(+), 70 deletions(-)
> 

Reviewed-by: David Ahern <dsahern@gmail.com>



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next 0/9] Simplify IPv6 route offload API
  2019-12-23 13:28 [PATCH net-next 0/9] Simplify IPv6 route offload API Ido Schimmel
                   ` (8 preceding siblings ...)
  2019-12-23 13:28 ` [PATCH net-next 9/9] ipv6: Remove old route notifications and convert listeners Ido Schimmel
@ 2019-12-25  6:38 ` David Miller
  9 siblings, 0 replies; 20+ messages in thread
From: David Miller @ 2019-12-25  6:38 UTC (permalink / raw)
  To: idosch; +Cc: netdev, dsahern, roopa, jakub.kicinski, jiri, idosch

From: Ido Schimmel <idosch@idosch.org>
Date: Mon, 23 Dec 2019 15:28:11 +0200

> This is the IPv6 counterpart of "Simplify IPv4 route offload API" [1].
 ...

Series applied, thanks Ido.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH net-next 1/9] net: fib_notifier: Add temporary events to the FIB notification chain
  2019-12-10 17:23 [PATCH net-next 0/9] Simplify IPv4 " Ido Schimmel
@ 2019-12-10 17:23 ` Ido Schimmel
  0 siblings, 0 replies; 20+ messages in thread
From: Ido Schimmel @ 2019-12-10 17:23 UTC (permalink / raw)
  To: netdev; +Cc: davem, jiri, dsahern, roopa, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

Subsequent patches are going to simplify the IPv4 route offload API,
which will only use two events - replace and delete.

Introduce a temporary version of these two events in order to make the
conversion easier to review.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 include/net/fib_notifier.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/net/fib_notifier.h b/include/net/fib_notifier.h
index 6d59221ff05a..b3c54325caec 100644
--- a/include/net/fib_notifier.h
+++ b/include/net/fib_notifier.h
@@ -23,6 +23,8 @@ enum fib_event_type {
 	FIB_EVENT_NH_DEL,
 	FIB_EVENT_VIF_ADD,
 	FIB_EVENT_VIF_DEL,
+	FIB_EVENT_ENTRY_REPLACE_TMP,
+	FIB_EVENT_ENTRY_DEL_TMP,
 };
 
 struct fib_notifier_ops {
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2019-12-25  6:38 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-23 13:28 [PATCH net-next 0/9] Simplify IPv6 route offload API Ido Schimmel
2019-12-23 13:28 ` [PATCH net-next 1/9] net: fib_notifier: Add temporary events to the FIB notification chain Ido Schimmel
2019-12-24 16:40   ` David Ahern
2019-12-23 13:28 ` [PATCH net-next 2/9] ipv6: Notify newly added route if should be offloaded Ido Schimmel
2019-12-24 16:40   ` David Ahern
2019-12-23 13:28 ` [PATCH net-next 3/9] ipv6: Notify route if replacing currently offloaded one Ido Schimmel
2019-12-24 16:44   ` David Ahern
2019-12-23 13:28 ` [PATCH net-next 4/9] ipv6: Notify multipath route if should be offloaded Ido Schimmel
2019-12-24 16:49   ` David Ahern
2019-12-23 13:28 ` [PATCH net-next 5/9] ipv6: Only Replay routes of interest to new listeners Ido Schimmel
2019-12-24 16:58   ` David Ahern
2019-12-23 13:28 ` [PATCH net-next 6/9] ipv6: Handle route deletion notification Ido Schimmel
2019-12-24 17:03   ` David Ahern
2019-12-23 13:28 ` [PATCH net-next 7/9] ipv6: Handle multipath " Ido Schimmel
2019-12-24 17:09   ` David Ahern
2019-12-23 13:28 ` [PATCH net-next 8/9] mlxsw: spectrum_router: Start using new IPv6 route notifications Ido Schimmel
2019-12-23 13:28 ` [PATCH net-next 9/9] ipv6: Remove old route notifications and convert listeners Ido Schimmel
2019-12-24 17:12   ` David Ahern
2019-12-25  6:38 ` [PATCH net-next 0/9] Simplify IPv6 route offload API David Miller
  -- strict thread matches above, loose matches on Subject: below --
2019-12-10 17:23 [PATCH net-next 0/9] Simplify IPv4 " Ido Schimmel
2019-12-10 17:23 ` [PATCH net-next 1/9] net: fib_notifier: Add temporary events to the FIB notification chain Ido Schimmel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.