From 44cc27e43fa3b8977373915a8e7f515a9d263343 Mon Sep 17 00:00:00 2001 From: Ioana Ciornei Date: Tue, 28 May 2019 20:38:12 +0300 Subject: net: phylink: Add struct phylink_config to PHYLINK API The phylink_config structure will encapsulate a pointer to a struct device and the operation type requested for this instance of PHYLINK. This patch does not make any functional changes, it just transitions the PHYLINK internals and all its users to the new API. A pointer to a phylink_config structure will be passed to phylink_create() instead of the net_device directly. Also, the same phylink_config pointer will be passed back to all phylink_mac_ops callbacks instead of the net_device. Using this mechanism, a PHYLINK user can get the original net_device using a structure such as 'to_net_dev(config->dev)' or directly the structure containing the phylink_config using a container_of call. At the moment, only the PHYLINK_NETDEV is defined as a valid operation type for PHYLINK. In this mode, a valid reference to a struct device linked to the original net_device should be passed to PHYLINK through the phylink_config structure. This API changes is mainly driven by the necessity of adding a new operation type in PHYLINK that disconnects the phy_device from the net_device and also works when the net_device is lacking. Signed-off-by: Ioana Ciornei Signed-off-by: Vladimir Oltean Reviewed-by: Florian Fainelli Reviewed-by: Maxime Chevallier Tested-by: Maxime Chevallier Signed-off-by: David S. Miller --- net/dsa/slave.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'net/dsa/slave.c') diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 9892ca1f6859..48e017637d4f 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -1164,11 +1164,11 @@ static struct device_type dsa_type = { .name = "dsa", }; -static void dsa_slave_phylink_validate(struct net_device *dev, +static void dsa_slave_phylink_validate(struct phylink_config *config, unsigned long *supported, struct phylink_link_state *state) { - struct dsa_port *dp = dsa_slave_to_port(dev); + struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); struct dsa_switch *ds = dp->ds; if (!ds->ops->phylink_validate) @@ -1177,10 +1177,10 @@ static void dsa_slave_phylink_validate(struct net_device *dev, ds->ops->phylink_validate(ds, dp->index, supported, state); } -static int dsa_slave_phylink_mac_link_state(struct net_device *dev, +static int dsa_slave_phylink_mac_link_state(struct phylink_config *config, struct phylink_link_state *state) { - struct dsa_port *dp = dsa_slave_to_port(dev); + struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); struct dsa_switch *ds = dp->ds; /* Only called for SGMII and 802.3z */ @@ -1190,11 +1190,11 @@ static int dsa_slave_phylink_mac_link_state(struct net_device *dev, return ds->ops->phylink_mac_link_state(ds, dp->index, state); } -static void dsa_slave_phylink_mac_config(struct net_device *dev, +static void dsa_slave_phylink_mac_config(struct phylink_config *config, unsigned int mode, const struct phylink_link_state *state) { - struct dsa_port *dp = dsa_slave_to_port(dev); + struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); struct dsa_switch *ds = dp->ds; if (!ds->ops->phylink_mac_config) @@ -1203,9 +1203,9 @@ static void dsa_slave_phylink_mac_config(struct net_device *dev, ds->ops->phylink_mac_config(ds, dp->index, mode, state); } -static void dsa_slave_phylink_mac_an_restart(struct net_device *dev) +static void dsa_slave_phylink_mac_an_restart(struct phylink_config *config) { - struct dsa_port *dp = dsa_slave_to_port(dev); + struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); struct dsa_switch *ds = dp->ds; if (!ds->ops->phylink_mac_an_restart) @@ -1214,11 +1214,12 @@ static void dsa_slave_phylink_mac_an_restart(struct net_device *dev) ds->ops->phylink_mac_an_restart(ds, dp->index); } -static void dsa_slave_phylink_mac_link_down(struct net_device *dev, +static void dsa_slave_phylink_mac_link_down(struct phylink_config *config, unsigned int mode, phy_interface_t interface) { - struct dsa_port *dp = dsa_slave_to_port(dev); + struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); + struct net_device *dev = dp->slave; struct dsa_switch *ds = dp->ds; if (!ds->ops->phylink_mac_link_down) { @@ -1230,12 +1231,13 @@ static void dsa_slave_phylink_mac_link_down(struct net_device *dev, ds->ops->phylink_mac_link_down(ds, dp->index, mode, interface); } -static void dsa_slave_phylink_mac_link_up(struct net_device *dev, +static void dsa_slave_phylink_mac_link_up(struct phylink_config *config, unsigned int mode, phy_interface_t interface, struct phy_device *phydev) { - struct dsa_port *dp = dsa_slave_to_port(dev); + struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); + struct net_device *dev = dp->slave; struct dsa_switch *ds = dp->ds; if (!ds->ops->phylink_mac_link_up) { @@ -1303,7 +1305,10 @@ static int dsa_slave_phy_setup(struct net_device *slave_dev) if (mode < 0) mode = PHY_INTERFACE_MODE_NA; - dp->pl = phylink_create(slave_dev, of_fwnode_handle(port_dn), mode, + dp->pl_config.dev = &slave_dev->dev; + dp->pl_config.type = PHYLINK_NETDEV; + + dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(port_dn), mode, &dsa_slave_phylink_mac_ops); if (IS_ERR(dp->pl)) { netdev_err(slave_dev, -- cgit v1.2.3 From 77373d49de22e836cf58ddbe7689d6b4b5046539 Mon Sep 17 00:00:00 2001 From: Ioana Ciornei Date: Tue, 28 May 2019 20:38:15 +0300 Subject: net: dsa: Move the phylink driver calls into port.c In order to have a common handling of PHYLINK for the slave and non-user ports, the DSA core glue logic (between PHYLINK and the driver) must use an API that does not rely on a struct net_device. These will also be called by the CPU-port-handling code in a further patch. Signed-off-by: Ioana Ciornei Suggested-by: Vladimir Oltean Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- net/dsa/slave.c | 96 +-------------------------------------------------------- 1 file changed, 1 insertion(+), 95 deletions(-) (limited to 'net/dsa/slave.c') diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 48e017637d4f..1e2ae9d59b88 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -1164,100 +1164,6 @@ static struct device_type dsa_type = { .name = "dsa", }; -static void dsa_slave_phylink_validate(struct phylink_config *config, - unsigned long *supported, - struct phylink_link_state *state) -{ - struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); - struct dsa_switch *ds = dp->ds; - - if (!ds->ops->phylink_validate) - return; - - ds->ops->phylink_validate(ds, dp->index, supported, state); -} - -static int dsa_slave_phylink_mac_link_state(struct phylink_config *config, - struct phylink_link_state *state) -{ - struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); - struct dsa_switch *ds = dp->ds; - - /* Only called for SGMII and 802.3z */ - if (!ds->ops->phylink_mac_link_state) - return -EOPNOTSUPP; - - return ds->ops->phylink_mac_link_state(ds, dp->index, state); -} - -static void dsa_slave_phylink_mac_config(struct phylink_config *config, - unsigned int mode, - const struct phylink_link_state *state) -{ - struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); - struct dsa_switch *ds = dp->ds; - - if (!ds->ops->phylink_mac_config) - return; - - ds->ops->phylink_mac_config(ds, dp->index, mode, state); -} - -static void dsa_slave_phylink_mac_an_restart(struct phylink_config *config) -{ - struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); - struct dsa_switch *ds = dp->ds; - - if (!ds->ops->phylink_mac_an_restart) - return; - - ds->ops->phylink_mac_an_restart(ds, dp->index); -} - -static void dsa_slave_phylink_mac_link_down(struct phylink_config *config, - unsigned int mode, - phy_interface_t interface) -{ - struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); - struct net_device *dev = dp->slave; - struct dsa_switch *ds = dp->ds; - - if (!ds->ops->phylink_mac_link_down) { - if (ds->ops->adjust_link && dev->phydev) - ds->ops->adjust_link(ds, dp->index, dev->phydev); - return; - } - - ds->ops->phylink_mac_link_down(ds, dp->index, mode, interface); -} - -static void dsa_slave_phylink_mac_link_up(struct phylink_config *config, - unsigned int mode, - phy_interface_t interface, - struct phy_device *phydev) -{ - struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); - struct net_device *dev = dp->slave; - struct dsa_switch *ds = dp->ds; - - if (!ds->ops->phylink_mac_link_up) { - if (ds->ops->adjust_link && dev->phydev) - ds->ops->adjust_link(ds, dp->index, dev->phydev); - return; - } - - ds->ops->phylink_mac_link_up(ds, dp->index, mode, interface, phydev); -} - -static const struct phylink_mac_ops dsa_slave_phylink_mac_ops = { - .validate = dsa_slave_phylink_validate, - .mac_link_state = dsa_slave_phylink_mac_link_state, - .mac_config = dsa_slave_phylink_mac_config, - .mac_an_restart = dsa_slave_phylink_mac_an_restart, - .mac_link_down = dsa_slave_phylink_mac_link_down, - .mac_link_up = dsa_slave_phylink_mac_link_up, -}; - void dsa_port_phylink_mac_change(struct dsa_switch *ds, int port, bool up) { const struct dsa_port *dp = dsa_to_port(ds, port); @@ -1309,7 +1215,7 @@ static int dsa_slave_phy_setup(struct net_device *slave_dev) dp->pl_config.type = PHYLINK_NETDEV; dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(port_dn), mode, - &dsa_slave_phylink_mac_ops); + &dsa_port_phylink_mac_ops); if (IS_ERR(dp->pl)) { netdev_err(slave_dev, "error creating PHYLINK: %ld\n", PTR_ERR(dp->pl)); -- cgit v1.2.3 From 146d442c2357539589da14d374a25c9a82eb7f1e Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Sat, 8 Jun 2019 15:04:27 +0300 Subject: net: dsa: Keep a pointer to the skb clone for TX timestamping For drivers that use deferred_xmit for PTP frames (such as sja1105), there is no need to perform matching between PTP frames and their egress timestamps, since the sending process can be serialized. In that case, it makes sense to have the pointer to the skb clone that DSA made directly in the skb->cb. It will be used for pushing the egress timestamp back in the application socket's error queue. Signed-off-by: Vladimir Oltean Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- net/dsa/slave.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'net/dsa/slave.c') diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 5bab82d46f0c..289a6aa4b51c 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -423,6 +423,8 @@ static void dsa_skb_tx_timestamp(struct dsa_slave_priv *p, if (!clone) return; + DSA_SKB_CB(skb)->clone = clone; + if (ds->ops->port_txtstamp(ds, p->dp->index, clone, type)) return; @@ -460,6 +462,7 @@ static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev) u64_stats_update_end(&s->syncp); DSA_SKB_CB(skb)->deferred_xmit = false; + DSA_SKB_CB(skb)->clone = NULL; /* Identify PTP protocol packets, clone them, and pass them to the * switch driver -- cgit v1.2.3 From f3b78049d4629b4fc565e225dda4e3ffdf907a84 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Fri, 14 Jun 2019 13:49:21 -0400 Subject: net: dsa: make dsa_slave_dev_check use const The switchdev handle helpers make use of a device checking helper requiring a const net_device. Make dsa_slave_dev_check compliant to this. Signed-off-by: Vivien Didelot Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- net/dsa/slave.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net/dsa/slave.c') diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 289a6aa4b51c..cb436a05c9a8 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -22,7 +22,7 @@ #include "dsa_priv.h" -static bool dsa_slave_dev_check(struct net_device *dev); +static bool dsa_slave_dev_check(const struct net_device *dev); /* slave mii_bus handling ***************************************************/ static int dsa_slave_phy_read(struct mii_bus *bus, int addr, int reg) @@ -1408,7 +1408,7 @@ void dsa_slave_destroy(struct net_device *slave_dev) free_netdev(slave_dev); } -static bool dsa_slave_dev_check(struct net_device *dev) +static bool dsa_slave_dev_check(const struct net_device *dev) { return dev->netdev_ops == &dsa_slave_netdev_ops; } -- cgit v1.2.3 From 79b139f4bc4659016854115b9104cfb9ef598b31 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Fri, 14 Jun 2019 13:49:22 -0400 Subject: net: dsa: use switchdev handle helpers Get rid of the dsa_slave_switchdev_port_{attr_set,obj}_event functions in favor of the switchdev_handle_port_{attr_set,obj_add,obj_del} helpers which recurse into the lower devices of the target interface. This has the benefit of being aware of the operations made on the bridge device itself, where orig_dev is the bridge, and dev is the slave. This can be used later to configure the hardware switches. Only VLAN and (port) MDB objects not directly targeting the slave device are unsupported at the moment, so skip this case in their respective case statements. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- net/dsa/slave.c | 76 ++++++++++++++++++++++++--------------------------------- 1 file changed, 32 insertions(+), 44 deletions(-) (limited to 'net/dsa/slave.c') diff --git a/net/dsa/slave.c b/net/dsa/slave.c index cb436a05c9a8..99673f6b07f6 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -311,7 +311,8 @@ static int dsa_slave_port_attr_set(struct net_device *dev, static int dsa_slave_port_obj_add(struct net_device *dev, const struct switchdev_obj *obj, - struct switchdev_trans *trans) + struct switchdev_trans *trans, + struct netlink_ext_ack *extack) { struct dsa_port *dp = dsa_slave_to_port(dev); int err; @@ -323,6 +324,8 @@ static int dsa_slave_port_obj_add(struct net_device *dev, switch (obj->id) { case SWITCHDEV_OBJ_ID_PORT_MDB: + if (obj->orig_dev != dev) + return -EOPNOTSUPP; err = dsa_port_mdb_add(dp, SWITCHDEV_OBJ_PORT_MDB(obj), trans); break; case SWITCHDEV_OBJ_ID_HOST_MDB: @@ -333,6 +336,8 @@ static int dsa_slave_port_obj_add(struct net_device *dev, trans); break; case SWITCHDEV_OBJ_ID_PORT_VLAN: + if (obj->orig_dev != dev) + return -EOPNOTSUPP; err = dsa_port_vlan_add(dp, SWITCHDEV_OBJ_PORT_VLAN(obj), trans); break; @@ -352,6 +357,8 @@ static int dsa_slave_port_obj_del(struct net_device *dev, switch (obj->id) { case SWITCHDEV_OBJ_ID_PORT_MDB: + if (obj->orig_dev != dev) + return -EOPNOTSUPP; err = dsa_port_mdb_del(dp, SWITCHDEV_OBJ_PORT_MDB(obj)); break; case SWITCHDEV_OBJ_ID_HOST_MDB: @@ -361,6 +368,8 @@ static int dsa_slave_port_obj_del(struct net_device *dev, err = dsa_port_mdb_del(dp->cpu_dp, SWITCHDEV_OBJ_PORT_MDB(obj)); break; case SWITCHDEV_OBJ_ID_PORT_VLAN: + if (obj->orig_dev != dev) + return -EOPNOTSUPP; err = dsa_port_vlan_del(dp, SWITCHDEV_OBJ_PORT_VLAN(obj)); break; default: @@ -1479,19 +1488,6 @@ static int dsa_slave_netdevice_event(struct notifier_block *nb, return NOTIFY_DONE; } -static int -dsa_slave_switchdev_port_attr_set_event(struct net_device *netdev, - struct switchdev_notifier_port_attr_info *port_attr_info) -{ - int err; - - err = dsa_slave_port_attr_set(netdev, port_attr_info->attr, - port_attr_info->trans); - - port_attr_info->handled = true; - return notifier_from_errno(err); -} - struct dsa_switchdev_event_work { struct work_struct work; struct switchdev_notifier_fdb_info fdb_info; @@ -1566,13 +1562,18 @@ static int dsa_slave_switchdev_event(struct notifier_block *unused, { struct net_device *dev = switchdev_notifier_info_to_dev(ptr); struct dsa_switchdev_event_work *switchdev_work; + int err; + + if (event == SWITCHDEV_PORT_ATTR_SET) { + err = switchdev_handle_port_attr_set(dev, ptr, + dsa_slave_dev_check, + dsa_slave_port_attr_set); + return notifier_from_errno(err); + } if (!dsa_slave_dev_check(dev)) return NOTIFY_DONE; - if (event == SWITCHDEV_PORT_ATTR_SET) - return dsa_slave_switchdev_port_attr_set_event(dev, ptr); - switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC); if (!switchdev_work) return NOTIFY_BAD; @@ -1602,41 +1603,28 @@ err_fdb_work_init: return NOTIFY_BAD; } -static int -dsa_slave_switchdev_port_obj_event(unsigned long event, - struct net_device *netdev, - struct switchdev_notifier_port_obj_info *port_obj_info) -{ - int err = -EOPNOTSUPP; - - switch (event) { - case SWITCHDEV_PORT_OBJ_ADD: - err = dsa_slave_port_obj_add(netdev, port_obj_info->obj, - port_obj_info->trans); - break; - case SWITCHDEV_PORT_OBJ_DEL: - err = dsa_slave_port_obj_del(netdev, port_obj_info->obj); - break; - } - - port_obj_info->handled = true; - return notifier_from_errno(err); -} - static int dsa_slave_switchdev_blocking_event(struct notifier_block *unused, unsigned long event, void *ptr) { struct net_device *dev = switchdev_notifier_info_to_dev(ptr); - - if (!dsa_slave_dev_check(dev)) - return NOTIFY_DONE; + int err; switch (event) { - case SWITCHDEV_PORT_OBJ_ADD: /* fall through */ + case SWITCHDEV_PORT_OBJ_ADD: + err = switchdev_handle_port_obj_add(dev, ptr, + dsa_slave_dev_check, + dsa_slave_port_obj_add); + return notifier_from_errno(err); case SWITCHDEV_PORT_OBJ_DEL: - return dsa_slave_switchdev_port_obj_event(event, dev, ptr); + err = switchdev_handle_port_obj_del(dev, ptr, + dsa_slave_dev_check, + dsa_slave_port_obj_del); + return notifier_from_errno(err); case SWITCHDEV_PORT_ATTR_SET: - return dsa_slave_switchdev_port_attr_set_event(dev, ptr); + err = switchdev_handle_port_attr_set(dev, ptr, + dsa_slave_dev_check, + dsa_slave_port_attr_set); + return notifier_from_errno(err); } return NOTIFY_DONE; -- cgit v1.2.3 From 9c0e189ec988f306331036bc3f71085582b24fdc Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 9 Jul 2019 22:55:40 +0200 Subject: net: flow_offload: rename TC_BLOCK_{UN}BIND to FLOW_BLOCK_{UN}BIND Rename from TC_BLOCK_{UN}BIND to FLOW_BLOCK_{UN}BIND and remove temporary tc_block_command alias. Signed-off-by: Pablo Neira Ayuso Signed-off-by: David S. Miller --- net/dsa/slave.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net/dsa/slave.c') diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 99673f6b07f6..58a71ee0747a 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -955,9 +955,9 @@ static int dsa_slave_setup_tc_block(struct net_device *dev, return -EOPNOTSUPP; switch (f->command) { - case TC_BLOCK_BIND: + case FLOW_BLOCK_BIND: return tcf_block_cb_register(f->block, cb, dev, dev, f->extack); - case TC_BLOCK_UNBIND: + case FLOW_BLOCK_UNBIND: tcf_block_cb_unregister(f->block, cb, dev); return 0; default: -- cgit v1.2.3 From 32f8c4093ac353a5f1b36cfed0ce0138faf8e15f Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 9 Jul 2019 22:55:41 +0200 Subject: net: flow_offload: rename TCF_BLOCK_BINDER_TYPE_* to FLOW_BLOCK_BINDER_TYPE_* Rename from TCF_BLOCK_BINDER_TYPE_* to FLOW_BLOCK_BINDER_TYPE_* and remove temporary tcf_block_binder_type alias. Signed-off-by: Pablo Neira Ayuso Signed-off-by: David S. Miller --- net/dsa/slave.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net/dsa/slave.c') diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 58a71ee0747a..9b5e202c255e 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -947,9 +947,9 @@ static int dsa_slave_setup_tc_block(struct net_device *dev, { tc_setup_cb_t *cb; - if (f->binder_type == TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) + if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) cb = dsa_slave_setup_tc_block_cb_ig; - else if (f->binder_type == TCF_BLOCK_BINDER_TYPE_CLSACT_EGRESS) + else if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS) cb = dsa_slave_setup_tc_block_cb_eg; else return -EOPNOTSUPP; -- cgit v1.2.3 From 955bcb6ea0df0d9ace89ac475405f1295ced5962 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 9 Jul 2019 22:55:46 +0200 Subject: drivers: net: use flow block API This patch updates flow_block_cb_setup_simple() to use the flow block API. Several drivers are also adjusted to use it. This patch introduces the per-driver list of flow blocks to account for blocks that are already in use. Remove tc_block_offload alias. Signed-off-by: Pablo Neira Ayuso Signed-off-by: David S. Miller --- net/dsa/slave.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'net/dsa/slave.c') diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 9b5e202c255e..90c32fd680db 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -942,9 +942,12 @@ static int dsa_slave_setup_tc_block_cb_eg(enum tc_setup_type type, return dsa_slave_setup_tc_block_cb(type, type_data, cb_priv, false); } +static LIST_HEAD(dsa_slave_block_cb_list); + static int dsa_slave_setup_tc_block(struct net_device *dev, - struct tc_block_offload *f) + struct flow_block_offload *f) { + struct flow_block_cb *block_cb; tc_setup_cb_t *cb; if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) @@ -954,11 +957,24 @@ static int dsa_slave_setup_tc_block(struct net_device *dev, else return -EOPNOTSUPP; + f->driver_block_list = &dsa_slave_block_cb_list; + switch (f->command) { case FLOW_BLOCK_BIND: - return tcf_block_cb_register(f->block, cb, dev, dev, f->extack); + block_cb = flow_block_cb_alloc(f->net, cb, dev, dev, NULL); + if (IS_ERR(block_cb)) + return PTR_ERR(block_cb); + + flow_block_cb_add(block_cb, f); + list_add_tail(&block_cb->driver_list, &dsa_slave_block_cb_list); + return 0; case FLOW_BLOCK_UNBIND: - tcf_block_cb_unregister(f->block, cb, dev); + block_cb = flow_block_cb_lookup(f, cb, dev); + if (!block_cb) + return -ENOENT; + + flow_block_cb_remove(block_cb, f); + list_del(&block_cb->driver_list); return 0; default: return -EOPNOTSUPP; -- cgit v1.2.3 From 0d4fd02e7199fbf57c0d175dd1890c82cd4a6f4f Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 9 Jul 2019 22:55:48 +0200 Subject: net: flow_offload: add flow_block_cb_is_busy() and use it This patch adds a function to check if flow block callback is already in use. Call this new function from flow_block_cb_setup_simple() and from drivers. Signed-off-by: Pablo Neira Ayuso Signed-off-by: David S. Miller --- net/dsa/slave.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'net/dsa/slave.c') diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 90c32fd680db..9bcb598fc840 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -961,6 +961,9 @@ static int dsa_slave_setup_tc_block(struct net_device *dev, switch (f->command) { case FLOW_BLOCK_BIND: + if (flow_block_cb_is_busy(cb, dev, &dsa_slave_block_cb_list)) + return -EBUSY; + block_cb = flow_block_cb_alloc(f->net, cb, dev, dev, NULL); if (IS_ERR(block_cb)) return PTR_ERR(block_cb); -- cgit v1.2.3 From 08cc83cc7fd8e6c3670ff545ef2bbfbc01a02d87 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 8 Jul 2019 23:31:13 -0400 Subject: net: dsa: add support for BRIDGE_MROUTER attribute This patch adds support for enabling or disabling the flooding of unknown multicast traffic on the CPU ports, depending on the value of the switchdev SWITCHDEV_ATTR_ID_BRIDGE_MROUTER attribute. The current behavior is kept unchanged but a user can now prevent the CPU conduit to be flooded with a lot of unregistered traffic that the network stack needs to filter in software with e.g.: echo 0 > /sys/class/net/br0/multicast_router Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- net/dsa/slave.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'net/dsa/slave.c') diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 9bcb598fc840..614c38ece104 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -301,6 +301,9 @@ static int dsa_slave_port_attr_set(struct net_device *dev, case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS: ret = dsa_port_bridge_flags(dp, attr->u.brport_flags, trans); break; + case SWITCHDEV_ATTR_ID_BRIDGE_MROUTER: + ret = dsa_port_mrouter(dp->cpu_dp, attr->u.mrouter, trans); + break; default: ret = -EOPNOTSUPP; break; -- cgit v1.2.3