netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: sfeldma@gmail.com
To: netdev@vger.kernel.org, davem@davemloft.net, jiri@resnulli.us,
	roopa@cumulusnetworks.com, alexander.h.duyck@redhat.com
Subject: [PATCH net-next v4 5/8] switchdev: implement IPv4 fib ndo wrappers
Date: Thu,  5 Mar 2015 21:21:17 -0800	[thread overview]
Message-ID: <1425619280-27492-6-git-send-email-sfeldma@gmail.com> (raw)
In-Reply-To: <1425619280-27492-1-git-send-email-sfeldma@gmail.com>

From: Scott Feldman <sfeldma@gmail.com>

Flesh out ndo wrappers to call into device driver.  To call into device driver,
the wrapper must interate over route's nexthops to ensure all nexthop devs
belong to the same switch device.  Currently, there is no support for route's
nexthops spanning offloaded and non-offloaded devices, or spanning ports of
multiple offload devices.

Since switch device ports may be stacked under virtual interfaces (bonds and/or
bridges), and the route's nexthop may be on the virtual interface, the wrapper
will traverse the nexthop dev down to the base dev.  It's the base dev that's
passed to the switchdev driver's ndo ops.

Signed-off-by: Scott Feldman <sfeldma@gmail.com>
---
 net/switchdev/switchdev.c |   98 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 96 insertions(+), 2 deletions(-)

diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index 81c4c02..99907d8 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -227,6 +227,65 @@ int ndo_dflt_netdev_switch_port_bridge_dellink(struct net_device *dev,
 }
 EXPORT_SYMBOL(ndo_dflt_netdev_switch_port_bridge_dellink);
 
+static struct net_device *netdev_switch_get_lowest_dev(struct net_device *dev)
+{
+	const struct net_device_ops *ops = dev->netdev_ops;
+	struct net_device *lower_dev;
+	struct net_device *port_dev;
+	struct list_head *iter;
+
+	/* Recusively search down until we find a sw port dev.
+	 * (A sw port dev supports ndo_switch_parent_id_get).
+	 */
+
+	if (dev->features & NETIF_F_HW_SWITCH_OFFLOAD &&
+	    ops->ndo_switch_parent_id_get)
+		return dev;
+
+	netdev_for_each_lower_dev(dev, lower_dev, iter) {
+		port_dev = netdev_switch_get_lowest_dev(lower_dev);
+		if (port_dev)
+			return port_dev;
+	}
+
+	return NULL;
+}
+
+static struct net_device *netdev_switch_get_dev_by_nhs(struct fib_info *fi)
+{
+	struct netdev_phys_item_id psid;
+	struct netdev_phys_item_id prev_psid;
+	struct net_device *dev = NULL;
+	int nhsel;
+
+	/* For this route, all nexthop devs must be on the same switch. */
+
+	for (nhsel = 0; nhsel < fi->fib_nhs; nhsel++) {
+		const struct fib_nh *nh = &fi->fib_nh[nhsel];
+
+		if (!nh->nh_dev)
+			return NULL;
+
+		dev = netdev_switch_get_lowest_dev(nh->nh_dev);
+		if (!dev)
+			return NULL;
+
+		if (netdev_switch_parent_id_get(dev, &psid))
+			return NULL;
+
+		if (nhsel > 0) {
+			if (prev_psid.id_len != psid.id_len)
+				return NULL;
+			if (memcmp(prev_psid.id, psid.id, psid.id_len))
+				return NULL;
+		}
+
+		prev_psid = psid;
+	}
+
+	return dev;
+}
+
 /**
  *	netdev_switch_fib_ipv4_add - Add IPv4 route entry to switch
  *
@@ -242,11 +301,27 @@ EXPORT_SYMBOL(ndo_dflt_netdev_switch_port_bridge_dellink);
 int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
 			       u8 tos, u8 type, u32 tb_id)
 {
+	struct net_device *dev;
+	const struct net_device_ops *ops;
+	int err = 0;
+
 	/* Don't offload route if using custom ip rules */
 	if (fi->fib_net->ipv4.fib_has_custom_rules)
 		return 0;
 
-	return 0;
+	dev = netdev_switch_get_dev_by_nhs(fi);
+	if (!dev)
+		return 0;
+	ops = dev->netdev_ops;
+
+	if (ops->ndo_switch_fib_ipv4_add) {
+		err = ops->ndo_switch_fib_ipv4_add(dev, htonl(dst), dst_len,
+						   fi, tos, type, tb_id);
+		if (!err)
+			fi->fib_flags |= RTNH_F_EXTERNAL;
+	}
+
+	return err;
 }
 EXPORT_SYMBOL(netdev_switch_fib_ipv4_add);
 
@@ -265,6 +340,25 @@ EXPORT_SYMBOL(netdev_switch_fib_ipv4_add);
 int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
 			       u8 tos, u8 type, u32 tb_id)
 {
-	return 0;
+	struct net_device *dev;
+	const struct net_device_ops *ops;
+	int err = 0;
+
+	if (!(fi->fib_flags & RTNH_F_EXTERNAL))
+		return 0;
+
+	dev = netdev_switch_get_dev_by_nhs(fi);
+	if (!dev)
+		return 0;
+	ops = dev->netdev_ops;
+
+	if (ops->ndo_switch_fib_ipv4_del) {
+		err = ops->ndo_switch_fib_ipv4_del(dev, htonl(dst), dst_len,
+						   fi, tos, type, tb_id);
+		if (!err)
+			fi->fib_flags &= ~RTNH_F_EXTERNAL;
+	}
+
+	return err;
 }
 EXPORT_SYMBOL(netdev_switch_fib_ipv4_del);
-- 
1.7.10.4

  parent reply	other threads:[~2015-03-06  5:20 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-06  5:21 [PATCH net-next v4 0/8] switchdev: add IPv4 routing offload sfeldma
2015-03-06  5:21 ` [PATCH net-next v4 1/8] rtnetlink: add RTNH_F_EXTERNAL flag for fib offload sfeldma
2015-03-06  5:21 ` [PATCH net-next v4 2/8] netdevice: add IPv4 fib add/del ops sfeldma
2015-03-06 14:55   ` Jamal Hadi Salim
2015-03-06 19:59     ` Scott Feldman
2015-03-08 14:31       ` roopa
2015-03-08 22:16         ` Scott Feldman
2015-03-09  6:22           ` roopa
2015-03-09  8:38             ` Scott Feldman
2015-03-09 13:47       ` Jamal Hadi Salim
2015-03-09 18:07         ` Scott Feldman
2015-03-06  5:21 ` [PATCH net-next v4 3/8] switchdev: add IPv4 fib ndo ops wrappers sfeldma
2015-03-06  5:21 ` [PATCH net-next v4 4/8] switchdev: don't support custom ip rules, for now sfeldma
2015-03-06  5:21 ` sfeldma [this message]
2015-03-06  7:24   ` [PATCH net-next v4 5/8] switchdev: implement IPv4 fib ndo wrappers Jiri Pirko
2015-03-06  9:38     ` Scott Feldman
2015-03-06 11:53       ` Jiri Pirko
2015-03-06  5:21 ` [PATCH net-next v4 6/8] ipv4: add net bool fib_offload_disabled sfeldma
2015-03-06  5:21 ` [PATCH net-next v4 7/8] fib: hook IPv4 fib for hardware offload sfeldma
2015-03-06  5:21 ` [PATCH net-next v4 8/8] rocker: implement IPv4 fib offloading sfeldma
2015-03-06  5:27 ` [PATCH net-next v4 0/8] switchdev: add IPv4 routing offload David Miller
2015-03-06 15:43 ` Alexander Duyck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1425619280-27492-6-git-send-email-sfeldma@gmail.com \
    --to=sfeldma@gmail.com \
    --cc=alexander.h.duyck@redhat.com \
    --cc=davem@davemloft.net \
    --cc=jiri@resnulli.us \
    --cc=netdev@vger.kernel.org \
    --cc=roopa@cumulusnetworks.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).