Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 84b7187c authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'mlxsw-Support-for-IPv6-UC-router'



Jiri Pirko says:

====================
mlxsw: Support for IPv6 UC router

Ido says:

This set adds support for IPv6 unicast routes offload. The first four
patches make the FIB notification chain generic so that it could be used
by address families other than IPv4. This is done by having each address
family register its callbacks with the common code, so that its FIB tables
and rules could be dumped upon registration to the chain, while ensuring
the integrity of the dump. The exact mechanics are explained in detail in
the first patch.

The next six patches build upon this work and add the necessary callbacks
in IPv6 code. This allows listeners of the chain to receive notifications
about IPv6 routes addition, deletion and replacement as well as FIB rules
notifications.

Unlike user space notifications for IPv6 multipath routes, the FIB
notification chain notifies these on a per-nexthop basis. This allows
us to keep the common code lean and is also unnecessary, as notifications
are serialized by each table's lock whereas applications maintaining
netlink caches may suffer from concurrent dumps and deletions / additions
of routes.

The next five patches audit the different code paths reading the route's
reference count (rt6i_ref) and remove assumptions regarding its meaning.
This is needed since non-FIB users need to be able to hold a reference on
the route and a non-zero reference count no longer means the route is in
the FIB.

The last six patches enable the mlxsw driver to offload IPv6 unicast
routes to the Spectrum ASIC. Without resorting to ACLs, lookup is done
solely based on the destination IP, so the abort mechanism is invoked
upon the addition of source-specific routes.

Follow-up patch sets will increase the scale of gatewayed routes by
consolidating identical nexthop groups to one adjacency entry in the
device's adjacency table (as in IPv4), as well as add support for
NH_{ADD,DEL} events which enable support for the
'ignore_routes_with_linkdown' sysctl.

Changes in v2:
* Provide offload indication for individual nexthops (David Ahern).
* Use existing route reference count instead of adding another one.
  This resulted in several new patches to remove assumptions regarding
  current semantics of the existing reference count (David Ahern).
* Add helpers to allow non-FIB users to take a reference on route.
* Remove use of tb6_lock in mlxsw (David Ahern).
* Add IPv6 dependency to mlxsw.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 80cf0b45 65e65ec1
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -75,6 +75,7 @@ config MLXSW_SPECTRUM
	depends on MLXSW_CORE && MLXSW_PCI && NET_SWITCHDEV && VLAN_8021Q
	depends on MLXSW_CORE && MLXSW_PCI && NET_SWITCHDEV && VLAN_8021Q
	depends on PSAMPLE || PSAMPLE=n
	depends on PSAMPLE || PSAMPLE=n
	depends on BRIDGE || BRIDGE=n
	depends on BRIDGE || BRIDGE=n
	depends on IPV6 || IPV6=n
	select PARMAN
	select PARMAN
	select MLXFW
	select MLXFW
	default m
	default m
+831 −24

File changed.

Preview size limit exceeded, changes collapsed.

+5 −0
Original line number Original line Diff line number Diff line
@@ -34,6 +34,7 @@
#include <net/netevent.h>
#include <net/netevent.h>
#include <net/arp.h>
#include <net/arp.h>
#include <net/fib_rules.h>
#include <net/fib_rules.h>
#include <net/fib_notifier.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <generated/utsrelease.h>
#include <generated/utsrelease.h>


@@ -2191,6 +2192,10 @@ static int rocker_router_fib_event(struct notifier_block *nb,
{
{
	struct rocker *rocker = container_of(nb, struct rocker, fib_nb);
	struct rocker *rocker = container_of(nb, struct rocker, fib_nb);
	struct rocker_fib_event_work *fib_work;
	struct rocker_fib_event_work *fib_work;
	struct fib_notifier_info *info = ptr;

	if (info->family != AF_INET)
		return NOTIFY_DONE;


	fib_work = kzalloc(sizeof(*fib_work), GFP_ATOMIC);
	fib_work = kzalloc(sizeof(*fib_work), GFP_ATOMIC);
	if (WARN_ON(!fib_work))
	if (WARN_ON(!fib_work))
+44 −0
Original line number Original line Diff line number Diff line
#ifndef __NET_FIB_NOTIFIER_H
#define __NET_FIB_NOTIFIER_H

#include <linux/types.h>
#include <linux/notifier.h>
#include <net/net_namespace.h>

struct fib_notifier_info {
	struct net *net;
	int family;
};

enum fib_event_type {
	FIB_EVENT_ENTRY_REPLACE,
	FIB_EVENT_ENTRY_APPEND,
	FIB_EVENT_ENTRY_ADD,
	FIB_EVENT_ENTRY_DEL,
	FIB_EVENT_RULE_ADD,
	FIB_EVENT_RULE_DEL,
	FIB_EVENT_NH_ADD,
	FIB_EVENT_NH_DEL,
};

struct fib_notifier_ops {
	int family;
	struct list_head list;
	unsigned int (*fib_seq_read)(struct net *net);
	int (*fib_dump)(struct net *net, struct notifier_block *nb);
	struct rcu_head rcu;
};

int call_fib_notifier(struct notifier_block *nb, struct net *net,
		      enum fib_event_type event_type,
		      struct fib_notifier_info *info);
int call_fib_notifiers(struct net *net, enum fib_event_type event_type,
		       struct fib_notifier_info *info);
int register_fib_notifier(struct notifier_block *nb,
			  void (*cb)(struct notifier_block *nb));
int unregister_fib_notifier(struct notifier_block *nb);
struct fib_notifier_ops *
fib_notifier_ops_register(const struct fib_notifier_ops *tmpl, struct net *net);
void fib_notifier_ops_unregister(struct fib_notifier_ops *ops);

#endif
+9 −0
Original line number Original line Diff line number Diff line
@@ -8,6 +8,7 @@
#include <linux/refcount.h>
#include <linux/refcount.h>
#include <net/flow.h>
#include <net/flow.h>
#include <net/rtnetlink.h>
#include <net/rtnetlink.h>
#include <net/fib_notifier.h>


struct fib_kuid_range {
struct fib_kuid_range {
	kuid_t start;
	kuid_t start;
@@ -57,6 +58,7 @@ struct fib_rules_ops {
	int			addr_size;
	int			addr_size;
	int			unresolved_rules;
	int			unresolved_rules;
	int			nr_goto_rules;
	int			nr_goto_rules;
	unsigned int		fib_rules_seq;


	int			(*action)(struct fib_rule *,
	int			(*action)(struct fib_rule *,
					  struct flowi *, int,
					  struct flowi *, int,
@@ -89,6 +91,11 @@ struct fib_rules_ops {
	struct rcu_head		rcu;
	struct rcu_head		rcu;
};
};


struct fib_rule_notifier_info {
	struct fib_notifier_info info; /* must be first */
	struct fib_rule *rule;
};

#define FRA_GENERIC_POLICY \
#define FRA_GENERIC_POLICY \
	[FRA_IIFNAME]	= { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \
	[FRA_IIFNAME]	= { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \
	[FRA_OIFNAME]	= { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \
	[FRA_OIFNAME]	= { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \
@@ -143,6 +150,8 @@ int fib_rules_lookup(struct fib_rules_ops *, struct flowi *, int flags,
int fib_default_rule_add(struct fib_rules_ops *, u32 pref, u32 table,
int fib_default_rule_add(struct fib_rules_ops *, u32 pref, u32 table,
			 u32 flags);
			 u32 flags);
bool fib_rule_matchall(const struct fib_rule *rule);
bool fib_rule_matchall(const struct fib_rule *rule);
int fib_rules_dump(struct net *net, struct notifier_block *nb, int family);
unsigned int fib_rules_seq_read(struct net *net, int family);


int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh,
int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh,
		   struct netlink_ext_ack *extack);
		   struct netlink_ext_ack *extack);
Loading