Thread (16 messages) 16 messages, 6 authors, 2018-03-07

[RFC net-next 1/6] drivers: net: bonding: add tc offload infastructure to bond

flat view
STALE3154d

From: John Hurley <hidden>
Date: 2018-03-05 13:28:44
Subsystem: bonding driver, networking drivers, networking [general], the rest · Maintainers: Jay Vosburgh, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

Register an ndo and callback for linux bonds to offload TC block ingress
rules. Enable tc-hw-offload to be set by the user (defaults to off). When
on, the flag cannot be turned off if rules are offloaded.

Signed-off-by: John Hurley <redacted>
---
 drivers/net/bonding/bond_main.c | 64 +++++++++++++++++++++++++++++++++++++++++
 include/net/bonding.h           |  2 ++
 2 files changed, 66 insertions(+)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 4c19d23..e6415f6 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -325,6 +325,55 @@ static int bond_vlan_rx_kill_vid(struct net_device *bond_dev,
 	return 0;
 }
 
+/*------------------------------ TC HW Offload ------------------------------*/
+
+static inline unsigned int bond_get_offload_cnt(struct bonding *bond)
+{
+	if (!bond->tc_block)
+		return 0;
+
+	return bond->tc_block->offloadcnt;
+}
+
+static int bond_tc_relay_cb(enum tc_setup_type type, void *type_data,
+			    void *cb_priv)
+{
+	return 0;
+}
+
+static int bond_setup_tc_block(struct net_device *netdev,
+			       struct tc_block_offload *f)
+{
+	struct bonding *bond = netdev_priv(netdev);
+
+	if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
+		return -EOPNOTSUPP;
+
+	switch (f->command) {
+	case TC_BLOCK_BIND:
+		bond->tc_block = f->block;
+		return tcf_block_cb_register(f->block, bond_tc_relay_cb,
+					     netdev, netdev);
+	case TC_BLOCK_UNBIND:
+		bond->tc_block = NULL;
+		tcf_block_cb_unregister(f->block, bond_tc_relay_cb, netdev);
+		return 0;
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int bond_setup_tc(struct net_device *netdev, enum tc_setup_type type,
+			 void *type_data)
+{
+	switch (type) {
+	case TC_SETUP_BLOCK:
+		return bond_setup_tc_block(netdev, type_data);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
 /*------------------------------- Link status -------------------------------*/
 
 /* Set the carrier state for the master according to the state of its
@@ -1065,6 +1114,17 @@ static netdev_features_t bond_fix_features(struct net_device *dev,
 	return features;
 }
 
+int bond_set_features(struct net_device *netdev, netdev_features_t features)
+{
+	if ((features & NETIF_F_HW_TC) <
+	    !!bond_get_offload_cnt(netdev_priv(netdev))) {
+		netdev_err(netdev, "Cannot disable TC offload while active\n");
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
 #define BOND_VLAN_FEATURES	(NETIF_F_HW_CSUM | NETIF_F_SG | \
 				 NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \
 				 NETIF_F_HIGHDMA | NETIF_F_LRO)
@@ -4198,7 +4258,9 @@ static const struct net_device_ops bond_netdev_ops = {
 	.ndo_add_slave		= bond_enslave,
 	.ndo_del_slave		= bond_release,
 	.ndo_fix_features	= bond_fix_features,
+	.ndo_set_features	= bond_set_features,
 	.ndo_features_check	= passthru_features_check,
+	.ndo_setup_tc		= bond_setup_tc,
 };
 
 static const struct device_type bond_type = {
@@ -4259,6 +4321,8 @@ void bond_setup(struct net_device *bond_dev)
 
 	bond_dev->hw_features |= NETIF_F_GSO_ENCAP_ALL;
 	bond_dev->features |= bond_dev->hw_features;
+	/* Disable hw tc offload by default. */
+	bond_dev->hw_features |= NETIF_F_HW_TC;
 }
 
 /* Destroy a bonding device.
diff --git a/include/net/bonding.h b/include/net/bonding.h
index f801fc9..424b9ea 100644
--- a/include/net/bonding.h
+++ b/include/net/bonding.h
@@ -29,6 +29,7 @@
 #include <net/bond_3ad.h>
 #include <net/bond_alb.h>
 #include <net/bond_options.h>
+#include <net/pkt_cls.h>
 
 #define BOND_MAX_ARP_TARGETS	16
 
@@ -199,6 +200,7 @@ struct bonding {
 	struct   bond_up_slave __rcu *slave_arr; /* Array of usable slaves */
 	bool     force_primary;
 	s32      slave_cnt; /* never change this value outside the attach/detach wrappers */
+	struct   tcf_block *tc_block;
 	int     (*recv_probe)(const struct sk_buff *, struct bonding *,
 			      struct slave *);
 	/* mode_lock is used for mode-specific locking needs, currently used by:
-- 
2.7.4
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help