From 69f5df491e0becb75d2d795add7481a35218d657 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 24 Sep 2015 10:02:40 +0200 Subject: switchdev: rename "trans" to "trans_ph". This is temporary, name "trans" will be used for something else and "trans_ph" will eventually disappear. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- net/switchdev/switchdev.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'net/switchdev/switchdev.c') diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index fda38f830a10..df5a5446ff4c 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -163,7 +163,7 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr) * but should not commit the attr. */ - attr->trans = SWITCHDEV_TRANS_PREPARE; + attr->trans_ph = SWITCHDEV_TRANS_PREPARE; err = __switchdev_port_attr_set(dev, attr); if (err) { /* Prepare phase failed: abort the transaction. Any @@ -172,7 +172,7 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr) */ if (err != -EOPNOTSUPP) { - attr->trans = SWITCHDEV_TRANS_ABORT; + attr->trans_ph = SWITCHDEV_TRANS_ABORT; __switchdev_port_attr_set(dev, attr); } @@ -184,7 +184,7 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr) * because the driver said everythings was OK in phase I. */ - attr->trans = SWITCHDEV_TRANS_COMMIT; + attr->trans_ph = SWITCHDEV_TRANS_COMMIT; err = __switchdev_port_attr_set(dev, attr); WARN(err, "%s: Commit of attribute (id=%d) failed.\n", dev->name, attr->id); @@ -243,7 +243,7 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj) * but should not commit the obj. */ - obj->trans = SWITCHDEV_TRANS_PREPARE; + obj->trans_ph = SWITCHDEV_TRANS_PREPARE; err = __switchdev_port_obj_add(dev, obj); if (err) { /* Prepare phase failed: abort the transaction. Any @@ -252,7 +252,7 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj) */ if (err != -EOPNOTSUPP) { - obj->trans = SWITCHDEV_TRANS_ABORT; + obj->trans_ph = SWITCHDEV_TRANS_ABORT; __switchdev_port_obj_add(dev, obj); } @@ -264,7 +264,7 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj) * because the driver said everythings was OK in phase I. */ - obj->trans = SWITCHDEV_TRANS_COMMIT; + obj->trans_ph = SWITCHDEV_TRANS_COMMIT; err = __switchdev_port_obj_add(dev, obj); WARN(err, "%s: Commit of object (id=%d) failed.\n", dev->name, obj->id); -- cgit From 7ea6eb3f56f45cf4babae8b9a7421868e5005f17 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 24 Sep 2015 10:02:41 +0200 Subject: switchdev: introduce transaction item queue for attr_set and obj_add Now, the memory allocation in prepare/commit state is done separatelly in each driver (rocker). Introduce the similar mechanism in generic switchdev code, in form of queue. That can be used not only for memory allocations, but also for different items. Abort item destruction is handled as well. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- net/switchdev/switchdev.c | 111 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 98 insertions(+), 13 deletions(-) (limited to 'net/switchdev/switchdev.c') diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index df5a5446ff4c..35e2967ffa18 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -1,6 +1,6 @@ /* * net/switchdev/switchdev.c - Switch device API - * Copyright (c) 2014 Jiri Pirko + * Copyright (c) 2014-2015 Jiri Pirko * Copyright (c) 2014-2015 Scott Feldman * * This program is free software; you can redistribute it and/or modify @@ -16,9 +16,82 @@ #include #include #include +#include #include #include +/** + * switchdev_trans_item_enqueue - Enqueue data item to transaction queue + * + * @trans: transaction + * @data: pointer to data being queued + * @destructor: data destructor + * @tritem: transaction item being queued + * + * Enqeueue data item to transaction queue. tritem is typically placed in + * cointainter pointed at by data pointer. Destructor is called on + * transaction abort and after successful commit phase in case + * the caller did not dequeue the item before. + */ +void switchdev_trans_item_enqueue(struct switchdev_trans *trans, + void *data, void (*destructor)(void const *), + struct switchdev_trans_item *tritem) +{ + tritem->data = data; + tritem->destructor = destructor; + list_add_tail(&tritem->list, &trans->item_list); +} +EXPORT_SYMBOL_GPL(switchdev_trans_item_enqueue); + +static struct switchdev_trans_item * +__switchdev_trans_item_dequeue(struct switchdev_trans *trans) +{ + struct switchdev_trans_item *tritem; + + if (list_empty(&trans->item_list)) + return NULL; + tritem = list_first_entry(&trans->item_list, + struct switchdev_trans_item, list); + list_del(&tritem->list); + return tritem; +} + +/** + * switchdev_trans_item_dequeue - Dequeue data item from transaction queue + * + * @trans: transaction + */ +void *switchdev_trans_item_dequeue(struct switchdev_trans *trans) +{ + struct switchdev_trans_item *tritem; + + tritem = __switchdev_trans_item_dequeue(trans); + BUG_ON(!tritem); + return tritem->data; +} +EXPORT_SYMBOL_GPL(switchdev_trans_item_dequeue); + +static void switchdev_trans_init(struct switchdev_trans *trans) +{ + INIT_LIST_HEAD(&trans->item_list); +} + +static void switchdev_trans_items_destroy(struct switchdev_trans *trans) +{ + struct switchdev_trans_item *tritem; + + while ((tritem = __switchdev_trans_item_dequeue(trans))) + tritem->destructor(tritem->data); +} + +static void switchdev_trans_items_warn_destroy(struct net_device *dev, + struct switchdev_trans *trans) +{ + WARN(!list_empty(&trans->item_list), "%s: transaction item queue is not empty.\n", + dev->name); + switchdev_trans_items_destroy(trans); +} + /** * switchdev_port_attr_get - Get port attribute * @@ -62,7 +135,8 @@ int switchdev_port_attr_get(struct net_device *dev, struct switchdev_attr *attr) EXPORT_SYMBOL_GPL(switchdev_port_attr_get); static int __switchdev_port_attr_set(struct net_device *dev, - struct switchdev_attr *attr) + struct switchdev_attr *attr, + struct switchdev_trans *trans) { const struct switchdev_ops *ops = dev->switchdev_ops; struct net_device *lower_dev; @@ -70,7 +144,7 @@ static int __switchdev_port_attr_set(struct net_device *dev, int err = -EOPNOTSUPP; if (ops && ops->switchdev_port_attr_set) - return ops->switchdev_port_attr_set(dev, attr); + return ops->switchdev_port_attr_set(dev, attr, trans); if (attr->flags & SWITCHDEV_F_NO_RECURSE) return err; @@ -81,7 +155,7 @@ static int __switchdev_port_attr_set(struct net_device *dev, */ netdev_for_each_lower_dev(dev, lower_dev, iter) { - err = __switchdev_port_attr_set(lower_dev, attr); + err = __switchdev_port_attr_set(lower_dev, attr, trans); if (err) break; } @@ -144,6 +218,7 @@ static int switchdev_port_attr_set_defer(struct net_device *dev, */ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr) { + struct switchdev_trans trans; int err; if (!rtnl_is_locked()) { @@ -156,6 +231,8 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr) return switchdev_port_attr_set_defer(dev, attr); } + switchdev_trans_init(&trans); + /* Phase I: prepare for attr set. Driver/device should fail * here if there are going to be issues in the commit phase, * such as lack of resources or support. The driver/device @@ -164,7 +241,7 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr) */ attr->trans_ph = SWITCHDEV_TRANS_PREPARE; - err = __switchdev_port_attr_set(dev, attr); + err = __switchdev_port_attr_set(dev, attr, &trans); if (err) { /* Prepare phase failed: abort the transaction. Any * resources reserved in the prepare phase are @@ -173,7 +250,8 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr) if (err != -EOPNOTSUPP) { attr->trans_ph = SWITCHDEV_TRANS_ABORT; - __switchdev_port_attr_set(dev, attr); + __switchdev_port_attr_set(dev, attr, &trans); + switchdev_trans_items_destroy(&trans); } return err; @@ -185,16 +263,18 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr) */ attr->trans_ph = SWITCHDEV_TRANS_COMMIT; - err = __switchdev_port_attr_set(dev, attr); + err = __switchdev_port_attr_set(dev, attr, &trans); WARN(err, "%s: Commit of attribute (id=%d) failed.\n", dev->name, attr->id); + switchdev_trans_items_warn_destroy(dev, &trans); return err; } EXPORT_SYMBOL_GPL(switchdev_port_attr_set); static int __switchdev_port_obj_add(struct net_device *dev, - struct switchdev_obj *obj) + struct switchdev_obj *obj, + struct switchdev_trans *trans) { const struct switchdev_ops *ops = dev->switchdev_ops; struct net_device *lower_dev; @@ -202,7 +282,7 @@ static int __switchdev_port_obj_add(struct net_device *dev, int err = -EOPNOTSUPP; if (ops && ops->switchdev_port_obj_add) - return ops->switchdev_port_obj_add(dev, obj); + return ops->switchdev_port_obj_add(dev, obj, trans); /* Switch device port(s) may be stacked under * bond/team/vlan dev, so recurse down to add object on @@ -210,7 +290,7 @@ static int __switchdev_port_obj_add(struct net_device *dev, */ netdev_for_each_lower_dev(dev, lower_dev, iter) { - err = __switchdev_port_obj_add(lower_dev, obj); + err = __switchdev_port_obj_add(lower_dev, obj, trans); if (err) break; } @@ -232,10 +312,13 @@ static int __switchdev_port_obj_add(struct net_device *dev, */ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj) { + struct switchdev_trans trans; int err; ASSERT_RTNL(); + switchdev_trans_init(&trans); + /* Phase I: prepare for obj add. Driver/device should fail * here if there are going to be issues in the commit phase, * such as lack of resources or support. The driver/device @@ -244,7 +327,7 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj) */ obj->trans_ph = SWITCHDEV_TRANS_PREPARE; - err = __switchdev_port_obj_add(dev, obj); + err = __switchdev_port_obj_add(dev, obj, &trans); if (err) { /* Prepare phase failed: abort the transaction. Any * resources reserved in the prepare phase are @@ -253,7 +336,8 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj) if (err != -EOPNOTSUPP) { obj->trans_ph = SWITCHDEV_TRANS_ABORT; - __switchdev_port_obj_add(dev, obj); + __switchdev_port_obj_add(dev, obj, &trans); + switchdev_trans_items_destroy(&trans); } return err; @@ -265,8 +349,9 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj) */ obj->trans_ph = SWITCHDEV_TRANS_COMMIT; - err = __switchdev_port_obj_add(dev, obj); + err = __switchdev_port_obj_add(dev, obj, &trans); WARN(err, "%s: Commit of object (id=%d) failed.\n", dev->name, obj->id); + switchdev_trans_items_warn_destroy(dev, &trans); return err; } -- cgit From f8db83486e316ff50f97961a82b614985645508e Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 24 Sep 2015 10:02:42 +0200 Subject: switchdev: move transaction phase enum under transaction structure Before it disappears completely, move transaction phase enum under transaction structure and make attr/obj structures a bit cleaner. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- net/switchdev/switchdev.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'net/switchdev/switchdev.c') diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 35e2967ffa18..d1c7d51620b1 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -240,7 +240,7 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr) * but should not commit the attr. */ - attr->trans_ph = SWITCHDEV_TRANS_PREPARE; + trans.ph = SWITCHDEV_TRANS_PREPARE; err = __switchdev_port_attr_set(dev, attr, &trans); if (err) { /* Prepare phase failed: abort the transaction. Any @@ -249,7 +249,7 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr) */ if (err != -EOPNOTSUPP) { - attr->trans_ph = SWITCHDEV_TRANS_ABORT; + trans.ph = SWITCHDEV_TRANS_ABORT; __switchdev_port_attr_set(dev, attr, &trans); switchdev_trans_items_destroy(&trans); } @@ -262,7 +262,7 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr) * because the driver said everythings was OK in phase I. */ - attr->trans_ph = SWITCHDEV_TRANS_COMMIT; + trans.ph = SWITCHDEV_TRANS_COMMIT; err = __switchdev_port_attr_set(dev, attr, &trans); WARN(err, "%s: Commit of attribute (id=%d) failed.\n", dev->name, attr->id); @@ -326,7 +326,7 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj) * but should not commit the obj. */ - obj->trans_ph = SWITCHDEV_TRANS_PREPARE; + trans.ph = SWITCHDEV_TRANS_PREPARE; err = __switchdev_port_obj_add(dev, obj, &trans); if (err) { /* Prepare phase failed: abort the transaction. Any @@ -335,7 +335,7 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj) */ if (err != -EOPNOTSUPP) { - obj->trans_ph = SWITCHDEV_TRANS_ABORT; + trans.ph = SWITCHDEV_TRANS_ABORT; __switchdev_port_obj_add(dev, obj, &trans); switchdev_trans_items_destroy(&trans); } @@ -348,7 +348,7 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj) * because the driver said everythings was OK in phase I. */ - obj->trans_ph = SWITCHDEV_TRANS_COMMIT; + trans.ph = SWITCHDEV_TRANS_COMMIT; err = __switchdev_port_obj_add(dev, obj, &trans); WARN(err, "%s: Commit of object (id=%d) failed.\n", dev->name, obj->id); switchdev_trans_items_warn_destroy(dev, &trans); -- cgit From 9f6467cf229a0e8a7580401b07de2a76e4c8618d Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 24 Sep 2015 10:02:47 +0200 Subject: switchdev: remove "ABORT" transaction phase No longer used by drivers, as transaction queue with item destructors takes care of abort phase internally in switchdev code. So kill it. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- net/switchdev/switchdev.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'net/switchdev/switchdev.c') diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index d1c7d51620b1..1adeedade0fb 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -248,11 +248,8 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr) * released. */ - if (err != -EOPNOTSUPP) { - trans.ph = SWITCHDEV_TRANS_ABORT; - __switchdev_port_attr_set(dev, attr, &trans); + if (err != -EOPNOTSUPP) switchdev_trans_items_destroy(&trans); - } return err; } @@ -334,11 +331,8 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj) * released. */ - if (err != -EOPNOTSUPP) { - trans.ph = SWITCHDEV_TRANS_ABORT; - __switchdev_port_obj_add(dev, obj, &trans); + if (err != -EOPNOTSUPP) switchdev_trans_items_destroy(&trans); - } return err; } -- cgit From f623ab7f51b1bfb523c9cd492747392abf3c4421 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 24 Sep 2015 10:02:49 +0200 Subject: switchdev: reduce transaction phase enum down to a boolean Now, since we have only 2 values for transaction phase, just use bool. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- net/switchdev/switchdev.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'net/switchdev/switchdev.c') diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 1adeedade0fb..00ee547ba45b 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -240,7 +240,7 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr) * but should not commit the attr. */ - trans.ph = SWITCHDEV_TRANS_PREPARE; + trans.ph_prepare = true; err = __switchdev_port_attr_set(dev, attr, &trans); if (err) { /* Prepare phase failed: abort the transaction. Any @@ -259,7 +259,7 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr) * because the driver said everythings was OK in phase I. */ - trans.ph = SWITCHDEV_TRANS_COMMIT; + trans.ph_prepare = false; err = __switchdev_port_attr_set(dev, attr, &trans); WARN(err, "%s: Commit of attribute (id=%d) failed.\n", dev->name, attr->id); @@ -323,7 +323,7 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj) * but should not commit the obj. */ - trans.ph = SWITCHDEV_TRANS_PREPARE; + trans.ph_prepare = true; err = __switchdev_port_obj_add(dev, obj, &trans); if (err) { /* Prepare phase failed: abort the transaction. Any @@ -342,7 +342,7 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj) * because the driver said everythings was OK in phase I. */ - trans.ph = SWITCHDEV_TRANS_COMMIT; + trans.ph_prepare = false; err = __switchdev_port_obj_add(dev, obj, &trans); WARN(err, "%s: Commit of object (id=%d) failed.\n", dev->name, obj->id); switchdev_trans_items_warn_destroy(dev, &trans); -- cgit From e23b002b23dfdcd12ca982fbc57dcb071a1fee62 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Tue, 29 Sep 2015 12:07:13 -0400 Subject: net: switchdev: remove dev in port_vlan_dump_put The static switchdev_port_vlan_dump_put function does not need the net_device parameter, so remove it. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- net/switchdev/switchdev.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'net/switchdev/switchdev.c') diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 00ee547ba45b..56d34edc7442 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -484,8 +484,7 @@ struct switchdev_vlan_dump { u16 end; }; -static int switchdev_port_vlan_dump_put(struct net_device *dev, - struct switchdev_vlan_dump *dump) +static int switchdev_port_vlan_dump_put(struct switchdev_vlan_dump *dump) { struct bridge_vlan_info vinfo; @@ -531,7 +530,7 @@ static int switchdev_port_vlan_dump_cb(struct net_device *dev, for (dump->begin = dump->end = vlan->vid_begin; dump->begin <= vlan->vid_end; dump->begin++, dump->end++) { - err = switchdev_port_vlan_dump_put(dev, dump); + err = switchdev_port_vlan_dump_put(dump); if (err) return err; } @@ -543,7 +542,7 @@ static int switchdev_port_vlan_dump_cb(struct net_device *dev, /* prepend */ dump->begin = vlan->vid_begin; } else { - err = switchdev_port_vlan_dump_put(dev, dump); + err = switchdev_port_vlan_dump_put(dump); dump->flags = vlan->flags; dump->begin = vlan->vid_begin; dump->end = vlan->vid_end; @@ -555,7 +554,7 @@ static int switchdev_port_vlan_dump_cb(struct net_device *dev, /* append */ dump->end = vlan->vid_end; } else { - err = switchdev_port_vlan_dump_put(dev, dump); + err = switchdev_port_vlan_dump_put(dump); dump->flags = vlan->flags; dump->begin = vlan->vid_begin; dump->end = vlan->vid_end; @@ -588,7 +587,7 @@ static int switchdev_port_vlan_fill(struct sk_buff *skb, struct net_device *dev, goto err_out; if (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED) /* last one */ - err = switchdev_port_vlan_dump_put(dev, &dump); + err = switchdev_port_vlan_dump_put(&dump); } err_out: -- cgit From e02a06b2a7c6e8b43c60ed8e0181172231af13d7 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Tue, 29 Sep 2015 12:07:14 -0400 Subject: net: switchdev: move dev in switchdev_fdb_dump The FDB dump callback requires the related net_device so move it to the struct switchdev_fdb_dump superset instead of using a callback param. With this done, it'll be simpler to change the dump function signature. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- net/switchdev/switchdev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'net/switchdev/switchdev.c') diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 56d34edc7442..c0e2047f8984 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -858,6 +858,7 @@ EXPORT_SYMBOL_GPL(switchdev_port_fdb_del); struct switchdev_fdb_dump { struct switchdev_obj obj; + struct net_device *dev; struct sk_buff *skb; struct netlink_callback *cb; int idx; @@ -887,7 +888,7 @@ static int switchdev_port_fdb_dump_cb(struct net_device *dev, ndm->ndm_pad2 = 0; ndm->ndm_flags = NTF_SELF; ndm->ndm_type = 0; - ndm->ndm_ifindex = dev->ifindex; + ndm->ndm_ifindex = dump->dev->ifindex; ndm->ndm_state = obj->u.fdb.ndm_state; if (nla_put(dump->skb, NDA_LLADDR, ETH_ALEN, obj->u.fdb.addr)) @@ -927,6 +928,7 @@ int switchdev_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, .id = SWITCHDEV_OBJ_PORT_FDB, .cb = switchdev_port_fdb_dump_cb, }, + .dev = dev, .skb = skb, .cb = cb, .idx = idx, -- cgit From 03d5fb18626aff95426a380aef0d1c6904cac7c9 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Tue, 29 Sep 2015 12:07:15 -0400 Subject: net: switchdev: remove dev from switchdev_obj cb The net_device associated to a dump operation does not have to be passed to the callback. switchdev stores it in a superset struct, if needed. Also some drivers (such as DSA drivers) may not have easy access to it. This will simplify pushing the callback function down to the drivers. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- net/switchdev/switchdev.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'net/switchdev/switchdev.c') diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index c0e2047f8984..93f4971e68db 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -514,8 +514,7 @@ static int switchdev_port_vlan_dump_put(struct switchdev_vlan_dump *dump) return 0; } -static int switchdev_port_vlan_dump_cb(struct net_device *dev, - struct switchdev_obj *obj) +static int switchdev_port_vlan_dump_cb(struct switchdev_obj *obj) { struct switchdev_vlan_dump *dump = container_of(obj, struct switchdev_vlan_dump, obj); @@ -864,8 +863,7 @@ struct switchdev_fdb_dump { int idx; }; -static int switchdev_port_fdb_dump_cb(struct net_device *dev, - struct switchdev_obj *obj) +static int switchdev_port_fdb_dump_cb(struct switchdev_obj *obj) { struct switchdev_fdb_dump *dump = container_of(obj, struct switchdev_fdb_dump, obj); -- cgit From 25f07adc473f05f850efc9414b9da3374563015f Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Tue, 29 Sep 2015 12:07:16 -0400 Subject: net: switchdev: pass callback to dump operation Similar to the notifier_call callback of a notifier_block, change the function signature of switchdev dump operation to: int switchdev_port_obj_dump(struct net_device *dev, enum switchdev_obj_id id, void *obj, int (*cb)(void *obj)); This allows the caller to pass and expect back a specific switchdev_obj_* structure instead of the generic switchdev_obj one. Drivers implementation of dump operation can now expect this specific structure and call the callback with it. Drivers have been changed accordingly. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- net/switchdev/switchdev.c | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) (limited to 'net/switchdev/switchdev.c') diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 93f4971e68db..2ef863c96359 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -386,9 +386,12 @@ EXPORT_SYMBOL_GPL(switchdev_port_obj_del); * switchdev_port_obj_dump - Dump port objects * * @dev: port device + * @id: object ID * @obj: object to dump + * @cb: function to call with a filled object */ -int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj) +int switchdev_port_obj_dump(struct net_device *dev, enum switchdev_obj_id id, + void *obj, int (*cb)(void *obj)) { const struct switchdev_ops *ops = dev->switchdev_ops; struct net_device *lower_dev; @@ -396,7 +399,7 @@ int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj) int err = -EOPNOTSUPP; if (ops && ops->switchdev_port_obj_dump) - return ops->switchdev_port_obj_dump(dev, obj); + return ops->switchdev_port_obj_dump(dev, id, obj, cb); /* Switch device port(s) may be stacked under * bond/team/vlan dev, so recurse down to dump objects on @@ -404,7 +407,7 @@ int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj) */ netdev_for_each_lower_dev(dev, lower_dev, iter) { - err = switchdev_port_obj_dump(lower_dev, obj); + err = switchdev_port_obj_dump(lower_dev, id, obj, cb); break; } @@ -476,7 +479,7 @@ int call_switchdev_notifiers(unsigned long val, struct net_device *dev, EXPORT_SYMBOL_GPL(call_switchdev_notifiers); struct switchdev_vlan_dump { - struct switchdev_obj obj; + struct switchdev_obj_vlan vlan; struct sk_buff *skb; u32 filter_mask; u16 flags; @@ -514,11 +517,11 @@ static int switchdev_port_vlan_dump_put(struct switchdev_vlan_dump *dump) return 0; } -static int switchdev_port_vlan_dump_cb(struct switchdev_obj *obj) +static int switchdev_port_vlan_dump_cb(void *obj) { + struct switchdev_obj_vlan *vlan = obj; struct switchdev_vlan_dump *dump = - container_of(obj, struct switchdev_vlan_dump, obj); - struct switchdev_obj_vlan *vlan = &dump->obj.u.vlan; + container_of(vlan, struct switchdev_vlan_dump, vlan); int err = 0; if (vlan->vid_begin > vlan->vid_end) @@ -570,10 +573,6 @@ static int switchdev_port_vlan_fill(struct sk_buff *skb, struct net_device *dev, u32 filter_mask) { struct switchdev_vlan_dump dump = { - .obj = { - .id = SWITCHDEV_OBJ_PORT_VLAN, - .cb = switchdev_port_vlan_dump_cb, - }, .skb = skb, .filter_mask = filter_mask, }; @@ -581,7 +580,9 @@ static int switchdev_port_vlan_fill(struct sk_buff *skb, struct net_device *dev, if ((filter_mask & RTEXT_FILTER_BRVLAN) || (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED)) { - err = switchdev_port_obj_dump(dev, &dump.obj); + err = switchdev_port_obj_dump(dev, SWITCHDEV_OBJ_PORT_VLAN, + &dump.vlan, + switchdev_port_vlan_dump_cb); if (err) goto err_out; if (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED) @@ -856,17 +857,18 @@ int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], EXPORT_SYMBOL_GPL(switchdev_port_fdb_del); struct switchdev_fdb_dump { - struct switchdev_obj obj; + struct switchdev_obj_fdb fdb; struct net_device *dev; struct sk_buff *skb; struct netlink_callback *cb; int idx; }; -static int switchdev_port_fdb_dump_cb(struct switchdev_obj *obj) +static int switchdev_port_fdb_dump_cb(void *obj) { + struct switchdev_obj_fdb *fdb = obj; struct switchdev_fdb_dump *dump = - container_of(obj, struct switchdev_fdb_dump, obj); + container_of(fdb, struct switchdev_fdb_dump, fdb); u32 portid = NETLINK_CB(dump->cb->skb).portid; u32 seq = dump->cb->nlh->nlmsg_seq; struct nlmsghdr *nlh; @@ -887,12 +889,12 @@ static int switchdev_port_fdb_dump_cb(struct switchdev_obj *obj) ndm->ndm_flags = NTF_SELF; ndm->ndm_type = 0; ndm->ndm_ifindex = dump->dev->ifindex; - ndm->ndm_state = obj->u.fdb.ndm_state; + ndm->ndm_state = fdb->ndm_state; - if (nla_put(dump->skb, NDA_LLADDR, ETH_ALEN, obj->u.fdb.addr)) + if (nla_put(dump->skb, NDA_LLADDR, ETH_ALEN, fdb->addr)) goto nla_put_failure; - if (obj->u.fdb.vid && nla_put_u16(dump->skb, NDA_VLAN, obj->u.fdb.vid)) + if (fdb->vid && nla_put_u16(dump->skb, NDA_VLAN, fdb->vid)) goto nla_put_failure; nlmsg_end(dump->skb, nlh); @@ -922,17 +924,14 @@ int switchdev_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, struct net_device *filter_dev, int idx) { struct switchdev_fdb_dump dump = { - .obj = { - .id = SWITCHDEV_OBJ_PORT_FDB, - .cb = switchdev_port_fdb_dump_cb, - }, .dev = dev, .skb = skb, .cb = cb, .idx = idx, }; - switchdev_port_obj_dump(dev, &dump.obj); + switchdev_port_obj_dump(dev, SWITCHDEV_OBJ_PORT_FDB, &dump.fdb, + switchdev_port_fdb_dump_cb); return dump.idx; } EXPORT_SYMBOL_GPL(switchdev_port_fdb_dump); -- cgit From ab06900230181b5a717b1e1a39c44e96f6292e71 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Tue, 29 Sep 2015 12:07:17 -0400 Subject: net: switchdev: abstract object in add/del ops Similar to the notifier_call callback of a notifier_block, change the function signature of switchdev add and del operations to: int switchdev_port_obj_add/del(struct net_device *dev, enum switchdev_obj_id id, void *obj); This allows the caller to pass a specific switchdev_obj_* structure instead of the generic switchdev_obj one. Drivers implementation of these operations and switchdev have been changed accordingly. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- net/switchdev/switchdev.c | 122 +++++++++++++++++++++------------------------- 1 file changed, 56 insertions(+), 66 deletions(-) (limited to 'net/switchdev/switchdev.c') diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 2ef863c96359..fe82fab1d55c 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -270,7 +270,7 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr) EXPORT_SYMBOL_GPL(switchdev_port_attr_set); static int __switchdev_port_obj_add(struct net_device *dev, - struct switchdev_obj *obj, + enum switchdev_obj_id id, const void *obj, struct switchdev_trans *trans) { const struct switchdev_ops *ops = dev->switchdev_ops; @@ -279,7 +279,7 @@ static int __switchdev_port_obj_add(struct net_device *dev, int err = -EOPNOTSUPP; if (ops && ops->switchdev_port_obj_add) - return ops->switchdev_port_obj_add(dev, obj, trans); + return ops->switchdev_port_obj_add(dev, id, obj, trans); /* Switch device port(s) may be stacked under * bond/team/vlan dev, so recurse down to add object on @@ -287,7 +287,7 @@ static int __switchdev_port_obj_add(struct net_device *dev, */ netdev_for_each_lower_dev(dev, lower_dev, iter) { - err = __switchdev_port_obj_add(lower_dev, obj, trans); + err = __switchdev_port_obj_add(lower_dev, id, obj, trans); if (err) break; } @@ -299,6 +299,7 @@ static int __switchdev_port_obj_add(struct net_device *dev, * switchdev_port_obj_add - Add port object * * @dev: port device + * @id: object ID * @obj: object to add * * Use a 2-phase prepare-commit transaction model to ensure @@ -307,7 +308,8 @@ static int __switchdev_port_obj_add(struct net_device *dev, * * rtnl_lock must be held. */ -int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj) +int switchdev_port_obj_add(struct net_device *dev, enum switchdev_obj_id id, + const void *obj) { struct switchdev_trans trans; int err; @@ -324,7 +326,7 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj) */ trans.ph_prepare = true; - err = __switchdev_port_obj_add(dev, obj, &trans); + err = __switchdev_port_obj_add(dev, id, obj, &trans); if (err) { /* Prepare phase failed: abort the transaction. Any * resources reserved in the prepare phase are @@ -343,8 +345,8 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj) */ trans.ph_prepare = false; - err = __switchdev_port_obj_add(dev, obj, &trans); - WARN(err, "%s: Commit of object (id=%d) failed.\n", dev->name, obj->id); + err = __switchdev_port_obj_add(dev, id, obj, &trans); + WARN(err, "%s: Commit of object (id=%d) failed.\n", dev->name, id); switchdev_trans_items_warn_destroy(dev, &trans); return err; @@ -355,9 +357,11 @@ EXPORT_SYMBOL_GPL(switchdev_port_obj_add); * switchdev_port_obj_del - Delete port object * * @dev: port device + * @id: object ID * @obj: object to delete */ -int switchdev_port_obj_del(struct net_device *dev, struct switchdev_obj *obj) +int switchdev_port_obj_del(struct net_device *dev, enum switchdev_obj_id id, + const void *obj) { const struct switchdev_ops *ops = dev->switchdev_ops; struct net_device *lower_dev; @@ -365,7 +369,7 @@ int switchdev_port_obj_del(struct net_device *dev, struct switchdev_obj *obj) int err = -EOPNOTSUPP; if (ops && ops->switchdev_port_obj_del) - return ops->switchdev_port_obj_del(dev, obj); + return ops->switchdev_port_obj_del(dev, id, obj); /* Switch device port(s) may be stacked under * bond/team/vlan dev, so recurse down to delete object on @@ -373,7 +377,7 @@ int switchdev_port_obj_del(struct net_device *dev, struct switchdev_obj *obj) */ netdev_for_each_lower_dev(dev, lower_dev, iter) { - err = switchdev_port_obj_del(lower_dev, obj); + err = switchdev_port_obj_del(lower_dev, id, obj); if (err) break; } @@ -695,14 +699,12 @@ static int switchdev_port_br_setlink_protinfo(struct net_device *dev, static int switchdev_port_br_afspec(struct net_device *dev, struct nlattr *afspec, int (*f)(struct net_device *dev, - struct switchdev_obj *obj)) + enum switchdev_obj_id id, + const void *obj)) { struct nlattr *attr; struct bridge_vlan_info *vinfo; - struct switchdev_obj obj = { - .id = SWITCHDEV_OBJ_PORT_VLAN, - }; - struct switchdev_obj_vlan *vlan = &obj.u.vlan; + struct switchdev_obj_vlan vlan = { 0 }; int rem; int err; @@ -712,30 +714,30 @@ static int switchdev_port_br_afspec(struct net_device *dev, if (nla_len(attr) != sizeof(struct bridge_vlan_info)) return -EINVAL; vinfo = nla_data(attr); - vlan->flags = vinfo->flags; + vlan.flags = vinfo->flags; if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) { - if (vlan->vid_begin) + if (vlan.vid_begin) return -EINVAL; - vlan->vid_begin = vinfo->vid; + vlan.vid_begin = vinfo->vid; } else if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END) { - if (!vlan->vid_begin) + if (!vlan.vid_begin) return -EINVAL; - vlan->vid_end = vinfo->vid; - if (vlan->vid_end <= vlan->vid_begin) + vlan.vid_end = vinfo->vid; + if (vlan.vid_end <= vlan.vid_begin) return -EINVAL; - err = f(dev, &obj); + err = f(dev, SWITCHDEV_OBJ_PORT_VLAN, &vlan); if (err) return err; - memset(vlan, 0, sizeof(*vlan)); + memset(&vlan, 0, sizeof(vlan)); } else { - if (vlan->vid_begin) + if (vlan.vid_begin) return -EINVAL; - vlan->vid_begin = vinfo->vid; - vlan->vid_end = vinfo->vid; - err = f(dev, &obj); + vlan.vid_begin = vinfo->vid; + vlan.vid_end = vinfo->vid; + err = f(dev, SWITCHDEV_OBJ_PORT_VLAN, &vlan); if (err) return err; - memset(vlan, 0, sizeof(*vlan)); + memset(&vlan, 0, sizeof(vlan)); } } @@ -817,15 +819,12 @@ int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], struct net_device *dev, const unsigned char *addr, u16 vid, u16 nlm_flags) { - struct switchdev_obj obj = { - .id = SWITCHDEV_OBJ_PORT_FDB, - .u.fdb = { - .addr = addr, - .vid = vid, - }, + struct switchdev_obj_fdb fdb = { + .addr = addr, + .vid = vid, }; - return switchdev_port_obj_add(dev, &obj); + return switchdev_port_obj_add(dev, SWITCHDEV_OBJ_PORT_FDB, &fdb); } EXPORT_SYMBOL_GPL(switchdev_port_fdb_add); @@ -844,15 +843,12 @@ int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], struct net_device *dev, const unsigned char *addr, u16 vid) { - struct switchdev_obj obj = { - .id = SWITCHDEV_OBJ_PORT_FDB, - .u.fdb = { - .addr = addr, - .vid = vid, - }, + struct switchdev_obj_fdb fdb = { + .addr = addr, + .vid = vid, }; - return switchdev_port_obj_del(dev, &obj); + return switchdev_port_obj_del(dev, SWITCHDEV_OBJ_PORT_FDB, &fdb); } EXPORT_SYMBOL_GPL(switchdev_port_fdb_del); @@ -1009,17 +1005,14 @@ static struct net_device *switchdev_get_dev_by_nhs(struct fib_info *fi) int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, u8 tos, u8 type, u32 nlflags, u32 tb_id) { - struct switchdev_obj fib_obj = { - .id = SWITCHDEV_OBJ_IPV4_FIB, - .u.ipv4_fib = { - .dst = dst, - .dst_len = dst_len, - .fi = fi, - .tos = tos, - .type = type, - .nlflags = nlflags, - .tb_id = tb_id, - }, + struct switchdev_obj_ipv4_fib ipv4_fib = { + .dst = dst, + .dst_len = dst_len, + .fi = fi, + .tos = tos, + .type = type, + .nlflags = nlflags, + .tb_id = tb_id, }; struct net_device *dev; int err = 0; @@ -1040,7 +1033,7 @@ int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, if (!dev) return 0; - err = switchdev_port_obj_add(dev, &fib_obj); + err = switchdev_port_obj_add(dev, SWITCHDEV_OBJ_IPV4_FIB, &ipv4_fib); if (!err) fi->fib_flags |= RTNH_F_OFFLOAD; @@ -1063,17 +1056,14 @@ EXPORT_SYMBOL_GPL(switchdev_fib_ipv4_add); int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, u8 tos, u8 type, u32 tb_id) { - struct switchdev_obj fib_obj = { - .id = SWITCHDEV_OBJ_IPV4_FIB, - .u.ipv4_fib = { - .dst = dst, - .dst_len = dst_len, - .fi = fi, - .tos = tos, - .type = type, - .nlflags = 0, - .tb_id = tb_id, - }, + struct switchdev_obj_ipv4_fib ipv4_fib = { + .dst = dst, + .dst_len = dst_len, + .fi = fi, + .tos = tos, + .type = type, + .nlflags = 0, + .tb_id = tb_id, }; struct net_device *dev; int err = 0; @@ -1085,7 +1075,7 @@ int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, if (!dev) return 0; - err = switchdev_port_obj_del(dev, &fib_obj); + err = switchdev_port_obj_del(dev, SWITCHDEV_OBJ_IPV4_FIB, &ipv4_fib); if (!err) fi->fib_flags &= ~RTNH_F_OFFLOAD; -- cgit From 57d80838dae55c1bc6ca629e471c84100513079a Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 1 Oct 2015 11:03:41 +0200 Subject: switchdev: rename SWITCHDEV_OBJ_* enum values to SWITCHDEV_OBJ_ID_* Suggested-by: Vivien Didelot Signed-off-by: Jiri Pirko Acked-by: Scott Feldman Reviewed-by: Vivien Didelot Signed-off-by: David S. Miller --- net/switchdev/switchdev.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'net/switchdev/switchdev.c') diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index fe82fab1d55c..5b1aa9f6f261 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -584,7 +584,7 @@ static int switchdev_port_vlan_fill(struct sk_buff *skb, struct net_device *dev, if ((filter_mask & RTEXT_FILTER_BRVLAN) || (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED)) { - err = switchdev_port_obj_dump(dev, SWITCHDEV_OBJ_PORT_VLAN, + err = switchdev_port_obj_dump(dev, SWITCHDEV_OBJ_ID_PORT_VLAN, &dump.vlan, switchdev_port_vlan_dump_cb); if (err) @@ -725,7 +725,7 @@ static int switchdev_port_br_afspec(struct net_device *dev, vlan.vid_end = vinfo->vid; if (vlan.vid_end <= vlan.vid_begin) return -EINVAL; - err = f(dev, SWITCHDEV_OBJ_PORT_VLAN, &vlan); + err = f(dev, SWITCHDEV_OBJ_ID_PORT_VLAN, &vlan); if (err) return err; memset(&vlan, 0, sizeof(vlan)); @@ -734,7 +734,7 @@ static int switchdev_port_br_afspec(struct net_device *dev, return -EINVAL; vlan.vid_begin = vinfo->vid; vlan.vid_end = vinfo->vid; - err = f(dev, SWITCHDEV_OBJ_PORT_VLAN, &vlan); + err = f(dev, SWITCHDEV_OBJ_ID_PORT_VLAN, &vlan); if (err) return err; memset(&vlan, 0, sizeof(vlan)); @@ -824,7 +824,7 @@ int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], .vid = vid, }; - return switchdev_port_obj_add(dev, SWITCHDEV_OBJ_PORT_FDB, &fdb); + return switchdev_port_obj_add(dev, SWITCHDEV_OBJ_ID_PORT_FDB, &fdb); } EXPORT_SYMBOL_GPL(switchdev_port_fdb_add); @@ -848,7 +848,7 @@ int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], .vid = vid, }; - return switchdev_port_obj_del(dev, SWITCHDEV_OBJ_PORT_FDB, &fdb); + return switchdev_port_obj_del(dev, SWITCHDEV_OBJ_ID_PORT_FDB, &fdb); } EXPORT_SYMBOL_GPL(switchdev_port_fdb_del); @@ -926,7 +926,7 @@ int switchdev_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, .idx = idx, }; - switchdev_port_obj_dump(dev, SWITCHDEV_OBJ_PORT_FDB, &dump.fdb, + switchdev_port_obj_dump(dev, SWITCHDEV_OBJ_ID_PORT_FDB, &dump.fdb, switchdev_port_fdb_dump_cb); return dump.idx; } @@ -1033,7 +1033,7 @@ int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, if (!dev) return 0; - err = switchdev_port_obj_add(dev, SWITCHDEV_OBJ_IPV4_FIB, &ipv4_fib); + err = switchdev_port_obj_add(dev, SWITCHDEV_OBJ_ID_IPV4_FIB, &ipv4_fib); if (!err) fi->fib_flags |= RTNH_F_OFFLOAD; @@ -1075,7 +1075,7 @@ int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, if (!dev) return 0; - err = switchdev_port_obj_del(dev, SWITCHDEV_OBJ_IPV4_FIB, &ipv4_fib); + err = switchdev_port_obj_del(dev, SWITCHDEV_OBJ_ID_IPV4_FIB, &ipv4_fib); if (!err) fi->fib_flags &= ~RTNH_F_OFFLOAD; -- cgit From 1f86839874a50c9ee2009567d2f312b1e1949e24 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 1 Oct 2015 11:03:42 +0200 Subject: switchdev: rename SWITCHDEV_ATTR_* enum values to SWITCHDEV_ATTR_ID_* To be aligned with obj. Signed-off-by: Jiri Pirko Acked-by: Scott Feldman Reviewed-by: Vivien Didelot Signed-off-by: David S. Miller --- net/switchdev/switchdev.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'net/switchdev/switchdev.c') diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 5b1aa9f6f261..c457c1f73d35 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -104,7 +104,7 @@ int switchdev_port_attr_get(struct net_device *dev, struct switchdev_attr *attr) struct net_device *lower_dev; struct list_head *iter; struct switchdev_attr first = { - .id = SWITCHDEV_ATTR_UNDEFINED + .id = SWITCHDEV_ATTR_ID_UNDEFINED }; int err = -EOPNOTSUPP; @@ -124,7 +124,7 @@ int switchdev_port_attr_get(struct net_device *dev, struct switchdev_attr *attr) err = switchdev_port_attr_get(lower_dev, attr); if (err) break; - if (first.id == SWITCHDEV_ATTR_UNDEFINED) + if (first.id == SWITCHDEV_ATTR_ID_UNDEFINED) first = *attr; else if (memcmp(&first, attr, sizeof(*attr))) return -ENODATA; @@ -611,7 +611,7 @@ int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, int nlflags) { struct switchdev_attr attr = { - .id = SWITCHDEV_ATTR_PORT_BRIDGE_FLAGS, + .id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS, }; u16 mode = BRIDGE_MODE_UNDEF; u32 mask = BR_LEARNING | BR_LEARNING_SYNC; @@ -632,7 +632,7 @@ static int switchdev_port_br_setflag(struct net_device *dev, unsigned long brport_flag) { struct switchdev_attr attr = { - .id = SWITCHDEV_ATTR_PORT_BRIDGE_FLAGS, + .id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS, }; u8 flag = nla_get_u8(nlattr); int err; @@ -958,7 +958,7 @@ static struct net_device *switchdev_get_lowest_dev(struct net_device *dev) static struct net_device *switchdev_get_dev_by_nhs(struct fib_info *fi) { struct switchdev_attr attr = { - .id = SWITCHDEV_ATTR_PORT_PARENT_ID, + .id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID, }; struct switchdev_attr prev_attr; struct net_device *dev = NULL; @@ -1107,11 +1107,11 @@ static bool switchdev_port_same_parent_id(struct net_device *a, struct net_device *b) { struct switchdev_attr a_attr = { - .id = SWITCHDEV_ATTR_PORT_PARENT_ID, + .id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID, .flags = SWITCHDEV_F_NO_RECURSE, }; struct switchdev_attr b_attr = { - .id = SWITCHDEV_ATTR_PORT_PARENT_ID, + .id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID, .flags = SWITCHDEV_F_NO_RECURSE, }; -- cgit From 8f24f3095dcedaa4eb4719eee2bed738fe2ce4a0 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 1 Oct 2015 11:03:43 +0200 Subject: switchdev: rename switchdev_obj_vlan to switchdev_obj_port_vlan Make the struct name in sync with object id name. Suggested-by: Vivien Didelot Signed-off-by: Jiri Pirko Acked-by: Scott Feldman Reviewed-by: Vivien Didelot Signed-off-by: David S. Miller --- net/switchdev/switchdev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'net/switchdev/switchdev.c') diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index c457c1f73d35..02ee926ebde6 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -483,7 +483,7 @@ int call_switchdev_notifiers(unsigned long val, struct net_device *dev, EXPORT_SYMBOL_GPL(call_switchdev_notifiers); struct switchdev_vlan_dump { - struct switchdev_obj_vlan vlan; + struct switchdev_obj_port_vlan vlan; struct sk_buff *skb; u32 filter_mask; u16 flags; @@ -523,7 +523,7 @@ static int switchdev_port_vlan_dump_put(struct switchdev_vlan_dump *dump) static int switchdev_port_vlan_dump_cb(void *obj) { - struct switchdev_obj_vlan *vlan = obj; + struct switchdev_obj_port_vlan *vlan = obj; struct switchdev_vlan_dump *dump = container_of(vlan, struct switchdev_vlan_dump, vlan); int err = 0; @@ -704,7 +704,7 @@ static int switchdev_port_br_afspec(struct net_device *dev, { struct nlattr *attr; struct bridge_vlan_info *vinfo; - struct switchdev_obj_vlan vlan = { 0 }; + struct switchdev_obj_port_vlan vlan = { 0 }; int rem; int err; -- cgit From 52ba57cfdc4c90da3bf996dfbe0c5feb731eb477 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 1 Oct 2015 11:03:44 +0200 Subject: switchdev: rename switchdev_obj_fdb to switchdev_obj_port_fdb Make the struct name in sync with object id name. Suggested-by: Vivien Didelot Signed-off-by: Jiri Pirko Acked-by: Scott Feldman Reviewed-by: Vivien Didelot Signed-off-by: David S. Miller --- net/switchdev/switchdev.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'net/switchdev/switchdev.c') diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 02ee926ebde6..250d013d64c6 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -819,7 +819,7 @@ int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], struct net_device *dev, const unsigned char *addr, u16 vid, u16 nlm_flags) { - struct switchdev_obj_fdb fdb = { + struct switchdev_obj_port_fdb fdb = { .addr = addr, .vid = vid, }; @@ -843,7 +843,7 @@ int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], struct net_device *dev, const unsigned char *addr, u16 vid) { - struct switchdev_obj_fdb fdb = { + struct switchdev_obj_port_fdb fdb = { .addr = addr, .vid = vid, }; @@ -853,7 +853,7 @@ int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], EXPORT_SYMBOL_GPL(switchdev_port_fdb_del); struct switchdev_fdb_dump { - struct switchdev_obj_fdb fdb; + struct switchdev_obj_port_fdb fdb; struct net_device *dev; struct sk_buff *skb; struct netlink_callback *cb; @@ -862,7 +862,7 @@ struct switchdev_fdb_dump { static int switchdev_port_fdb_dump_cb(void *obj) { - struct switchdev_obj_fdb *fdb = obj; + struct switchdev_obj_port_fdb *fdb = obj; struct switchdev_fdb_dump *dump = container_of(fdb, struct switchdev_fdb_dump, fdb); u32 portid = NETLINK_CB(dump->cb->skb).portid; -- cgit From 648b4a995a057187ddd77cdb181e6a0b24ab2959 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 1 Oct 2015 11:03:45 +0200 Subject: switchdev: bring back switchdev_obj and use it as a generic object param Replace "void *obj" with a generic structure. Introduce couple of helpers along that. Signed-off-by: Jiri Pirko Acked-by: Scott Feldman Reviewed-by: Vivien Didelot Signed-off-by: David S. Miller --- net/switchdev/switchdev.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) (limited to 'net/switchdev/switchdev.c') diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 250d013d64c6..0402b3633100 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -270,7 +270,8 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr) EXPORT_SYMBOL_GPL(switchdev_port_attr_set); static int __switchdev_port_obj_add(struct net_device *dev, - enum switchdev_obj_id id, const void *obj, + enum switchdev_obj_id id, + const struct switchdev_obj *obj, struct switchdev_trans *trans) { const struct switchdev_ops *ops = dev->switchdev_ops; @@ -309,7 +310,7 @@ static int __switchdev_port_obj_add(struct net_device *dev, * rtnl_lock must be held. */ int switchdev_port_obj_add(struct net_device *dev, enum switchdev_obj_id id, - const void *obj) + const struct switchdev_obj *obj) { struct switchdev_trans trans; int err; @@ -361,7 +362,7 @@ EXPORT_SYMBOL_GPL(switchdev_port_obj_add); * @obj: object to delete */ int switchdev_port_obj_del(struct net_device *dev, enum switchdev_obj_id id, - const void *obj) + const struct switchdev_obj *obj) { const struct switchdev_ops *ops = dev->switchdev_ops; struct net_device *lower_dev; @@ -395,7 +396,8 @@ EXPORT_SYMBOL_GPL(switchdev_port_obj_del); * @cb: function to call with a filled object */ int switchdev_port_obj_dump(struct net_device *dev, enum switchdev_obj_id id, - void *obj, int (*cb)(void *obj)) + struct switchdev_obj *obj, + switchdev_obj_dump_cb_t *cb) { const struct switchdev_ops *ops = dev->switchdev_ops; struct net_device *lower_dev; @@ -521,9 +523,9 @@ static int switchdev_port_vlan_dump_put(struct switchdev_vlan_dump *dump) return 0; } -static int switchdev_port_vlan_dump_cb(void *obj) +static int switchdev_port_vlan_dump_cb(struct switchdev_obj *obj) { - struct switchdev_obj_port_vlan *vlan = obj; + struct switchdev_obj_port_vlan *vlan = SWITCHDEV_OBJ_PORT_VLAN(obj); struct switchdev_vlan_dump *dump = container_of(vlan, struct switchdev_vlan_dump, vlan); int err = 0; @@ -585,7 +587,7 @@ static int switchdev_port_vlan_fill(struct sk_buff *skb, struct net_device *dev, if ((filter_mask & RTEXT_FILTER_BRVLAN) || (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED)) { err = switchdev_port_obj_dump(dev, SWITCHDEV_OBJ_ID_PORT_VLAN, - &dump.vlan, + &dump.vlan.obj, switchdev_port_vlan_dump_cb); if (err) goto err_out; @@ -700,11 +702,11 @@ static int switchdev_port_br_afspec(struct net_device *dev, struct nlattr *afspec, int (*f)(struct net_device *dev, enum switchdev_obj_id id, - const void *obj)) + const struct switchdev_obj *obj)) { struct nlattr *attr; struct bridge_vlan_info *vinfo; - struct switchdev_obj_port_vlan vlan = { 0 }; + struct switchdev_obj_port_vlan vlan = { {}, 0 }; int rem; int err; @@ -725,7 +727,7 @@ static int switchdev_port_br_afspec(struct net_device *dev, vlan.vid_end = vinfo->vid; if (vlan.vid_end <= vlan.vid_begin) return -EINVAL; - err = f(dev, SWITCHDEV_OBJ_ID_PORT_VLAN, &vlan); + err = f(dev, SWITCHDEV_OBJ_ID_PORT_VLAN, &vlan.obj); if (err) return err; memset(&vlan, 0, sizeof(vlan)); @@ -734,7 +736,7 @@ static int switchdev_port_br_afspec(struct net_device *dev, return -EINVAL; vlan.vid_begin = vinfo->vid; vlan.vid_end = vinfo->vid; - err = f(dev, SWITCHDEV_OBJ_ID_PORT_VLAN, &vlan); + err = f(dev, SWITCHDEV_OBJ_ID_PORT_VLAN, &vlan.obj); if (err) return err; memset(&vlan, 0, sizeof(vlan)); @@ -824,7 +826,7 @@ int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], .vid = vid, }; - return switchdev_port_obj_add(dev, SWITCHDEV_OBJ_ID_PORT_FDB, &fdb); + return switchdev_port_obj_add(dev, SWITCHDEV_OBJ_ID_PORT_FDB, &fdb.obj); } EXPORT_SYMBOL_GPL(switchdev_port_fdb_add); @@ -848,7 +850,7 @@ int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], .vid = vid, }; - return switchdev_port_obj_del(dev, SWITCHDEV_OBJ_ID_PORT_FDB, &fdb); + return switchdev_port_obj_del(dev, SWITCHDEV_OBJ_ID_PORT_FDB, &fdb.obj); } EXPORT_SYMBOL_GPL(switchdev_port_fdb_del); @@ -860,9 +862,9 @@ struct switchdev_fdb_dump { int idx; }; -static int switchdev_port_fdb_dump_cb(void *obj) +static int switchdev_port_fdb_dump_cb(struct switchdev_obj *obj) { - struct switchdev_obj_port_fdb *fdb = obj; + struct switchdev_obj_port_fdb *fdb = SWITCHDEV_OBJ_PORT_FDB(obj); struct switchdev_fdb_dump *dump = container_of(fdb, struct switchdev_fdb_dump, fdb); u32 portid = NETLINK_CB(dump->cb->skb).portid; @@ -926,7 +928,7 @@ int switchdev_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, .idx = idx, }; - switchdev_port_obj_dump(dev, SWITCHDEV_OBJ_ID_PORT_FDB, &dump.fdb, + switchdev_port_obj_dump(dev, SWITCHDEV_OBJ_ID_PORT_FDB, &dump.fdb.obj, switchdev_port_fdb_dump_cb); return dump.idx; } @@ -1033,7 +1035,8 @@ int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, if (!dev) return 0; - err = switchdev_port_obj_add(dev, SWITCHDEV_OBJ_ID_IPV4_FIB, &ipv4_fib); + err = switchdev_port_obj_add(dev, SWITCHDEV_OBJ_ID_IPV4_FIB, + &ipv4_fib.obj); if (!err) fi->fib_flags |= RTNH_F_OFFLOAD; @@ -1075,7 +1078,8 @@ int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, if (!dev) return 0; - err = switchdev_port_obj_del(dev, SWITCHDEV_OBJ_ID_IPV4_FIB, &ipv4_fib); + err = switchdev_port_obj_del(dev, SWITCHDEV_OBJ_ID_IPV4_FIB, + &ipv4_fib.obj); if (!err) fi->fib_flags &= ~RTNH_F_OFFLOAD; -- cgit From 9e8f4a548ab4710002c23c94c4b1bbde91b5e335 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 1 Oct 2015 11:03:46 +0200 Subject: switchdev: push object ID back to object structure Suggested-by: Scott Feldman Signed-off-by: Jiri Pirko Acked-by: Scott Feldman Reviewed-by: Vivien Didelot Signed-off-by: David S. Miller --- net/switchdev/switchdev.c | 57 ++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 28 deletions(-) (limited to 'net/switchdev/switchdev.c') diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 0402b3633100..6e4a4f9ad927 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -270,7 +270,6 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr) EXPORT_SYMBOL_GPL(switchdev_port_attr_set); static int __switchdev_port_obj_add(struct net_device *dev, - enum switchdev_obj_id id, const struct switchdev_obj *obj, struct switchdev_trans *trans) { @@ -280,7 +279,7 @@ static int __switchdev_port_obj_add(struct net_device *dev, int err = -EOPNOTSUPP; if (ops && ops->switchdev_port_obj_add) - return ops->switchdev_port_obj_add(dev, id, obj, trans); + return ops->switchdev_port_obj_add(dev, obj, trans); /* Switch device port(s) may be stacked under * bond/team/vlan dev, so recurse down to add object on @@ -288,7 +287,7 @@ static int __switchdev_port_obj_add(struct net_device *dev, */ netdev_for_each_lower_dev(dev, lower_dev, iter) { - err = __switchdev_port_obj_add(lower_dev, id, obj, trans); + err = __switchdev_port_obj_add(lower_dev, obj, trans); if (err) break; } @@ -309,7 +308,7 @@ static int __switchdev_port_obj_add(struct net_device *dev, * * rtnl_lock must be held. */ -int switchdev_port_obj_add(struct net_device *dev, enum switchdev_obj_id id, +int switchdev_port_obj_add(struct net_device *dev, const struct switchdev_obj *obj) { struct switchdev_trans trans; @@ -327,7 +326,7 @@ int switchdev_port_obj_add(struct net_device *dev, enum switchdev_obj_id id, */ trans.ph_prepare = true; - err = __switchdev_port_obj_add(dev, id, obj, &trans); + err = __switchdev_port_obj_add(dev, obj, &trans); if (err) { /* Prepare phase failed: abort the transaction. Any * resources reserved in the prepare phase are @@ -346,8 +345,8 @@ int switchdev_port_obj_add(struct net_device *dev, enum switchdev_obj_id id, */ trans.ph_prepare = false; - err = __switchdev_port_obj_add(dev, id, obj, &trans); - WARN(err, "%s: Commit of object (id=%d) failed.\n", dev->name, id); + err = __switchdev_port_obj_add(dev, obj, &trans); + WARN(err, "%s: Commit of object (id=%d) failed.\n", dev->name, obj->id); switchdev_trans_items_warn_destroy(dev, &trans); return err; @@ -361,7 +360,7 @@ EXPORT_SYMBOL_GPL(switchdev_port_obj_add); * @id: object ID * @obj: object to delete */ -int switchdev_port_obj_del(struct net_device *dev, enum switchdev_obj_id id, +int switchdev_port_obj_del(struct net_device *dev, const struct switchdev_obj *obj) { const struct switchdev_ops *ops = dev->switchdev_ops; @@ -370,7 +369,7 @@ int switchdev_port_obj_del(struct net_device *dev, enum switchdev_obj_id id, int err = -EOPNOTSUPP; if (ops && ops->switchdev_port_obj_del) - return ops->switchdev_port_obj_del(dev, id, obj); + return ops->switchdev_port_obj_del(dev, obj); /* Switch device port(s) may be stacked under * bond/team/vlan dev, so recurse down to delete object on @@ -378,7 +377,7 @@ int switchdev_port_obj_del(struct net_device *dev, enum switchdev_obj_id id, */ netdev_for_each_lower_dev(dev, lower_dev, iter) { - err = switchdev_port_obj_del(lower_dev, id, obj); + err = switchdev_port_obj_del(lower_dev, obj); if (err) break; } @@ -395,8 +394,7 @@ EXPORT_SYMBOL_GPL(switchdev_port_obj_del); * @obj: object to dump * @cb: function to call with a filled object */ -int switchdev_port_obj_dump(struct net_device *dev, enum switchdev_obj_id id, - struct switchdev_obj *obj, +int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj, switchdev_obj_dump_cb_t *cb) { const struct switchdev_ops *ops = dev->switchdev_ops; @@ -405,7 +403,7 @@ int switchdev_port_obj_dump(struct net_device *dev, enum switchdev_obj_id id, int err = -EOPNOTSUPP; if (ops && ops->switchdev_port_obj_dump) - return ops->switchdev_port_obj_dump(dev, id, obj, cb); + return ops->switchdev_port_obj_dump(dev, obj, cb); /* Switch device port(s) may be stacked under * bond/team/vlan dev, so recurse down to dump objects on @@ -413,7 +411,7 @@ int switchdev_port_obj_dump(struct net_device *dev, enum switchdev_obj_id id, */ netdev_for_each_lower_dev(dev, lower_dev, iter) { - err = switchdev_port_obj_dump(lower_dev, id, obj, cb); + err = switchdev_port_obj_dump(lower_dev, obj, cb); break; } @@ -579,6 +577,7 @@ static int switchdev_port_vlan_fill(struct sk_buff *skb, struct net_device *dev, u32 filter_mask) { struct switchdev_vlan_dump dump = { + .vlan.obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN, .skb = skb, .filter_mask = filter_mask, }; @@ -586,8 +585,7 @@ static int switchdev_port_vlan_fill(struct sk_buff *skb, struct net_device *dev, if ((filter_mask & RTEXT_FILTER_BRVLAN) || (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED)) { - err = switchdev_port_obj_dump(dev, SWITCHDEV_OBJ_ID_PORT_VLAN, - &dump.vlan.obj, + err = switchdev_port_obj_dump(dev, &dump.vlan.obj, switchdev_port_vlan_dump_cb); if (err) goto err_out; @@ -701,12 +699,13 @@ static int switchdev_port_br_setlink_protinfo(struct net_device *dev, static int switchdev_port_br_afspec(struct net_device *dev, struct nlattr *afspec, int (*f)(struct net_device *dev, - enum switchdev_obj_id id, const struct switchdev_obj *obj)) { struct nlattr *attr; struct bridge_vlan_info *vinfo; - struct switchdev_obj_port_vlan vlan = { {}, 0 }; + struct switchdev_obj_port_vlan vlan = { + .obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN, + }; int rem; int err; @@ -727,7 +726,7 @@ static int switchdev_port_br_afspec(struct net_device *dev, vlan.vid_end = vinfo->vid; if (vlan.vid_end <= vlan.vid_begin) return -EINVAL; - err = f(dev, SWITCHDEV_OBJ_ID_PORT_VLAN, &vlan.obj); + err = f(dev, &vlan.obj); if (err) return err; memset(&vlan, 0, sizeof(vlan)); @@ -736,7 +735,7 @@ static int switchdev_port_br_afspec(struct net_device *dev, return -EINVAL; vlan.vid_begin = vinfo->vid; vlan.vid_end = vinfo->vid; - err = f(dev, SWITCHDEV_OBJ_ID_PORT_VLAN, &vlan.obj); + err = f(dev, &vlan.obj); if (err) return err; memset(&vlan, 0, sizeof(vlan)); @@ -822,11 +821,12 @@ int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], u16 vid, u16 nlm_flags) { struct switchdev_obj_port_fdb fdb = { + .obj.id = SWITCHDEV_OBJ_ID_PORT_FDB, .addr = addr, .vid = vid, }; - return switchdev_port_obj_add(dev, SWITCHDEV_OBJ_ID_PORT_FDB, &fdb.obj); + return switchdev_port_obj_add(dev, &fdb.obj); } EXPORT_SYMBOL_GPL(switchdev_port_fdb_add); @@ -846,11 +846,12 @@ int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], u16 vid) { struct switchdev_obj_port_fdb fdb = { + .obj.id = SWITCHDEV_OBJ_ID_PORT_FDB, .addr = addr, .vid = vid, }; - return switchdev_port_obj_del(dev, SWITCHDEV_OBJ_ID_PORT_FDB, &fdb.obj); + return switchdev_port_obj_del(dev, &fdb.obj); } EXPORT_SYMBOL_GPL(switchdev_port_fdb_del); @@ -922,14 +923,14 @@ int switchdev_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, struct net_device *filter_dev, int idx) { struct switchdev_fdb_dump dump = { + .fdb.obj.id = SWITCHDEV_OBJ_ID_PORT_FDB, .dev = dev, .skb = skb, .cb = cb, .idx = idx, }; - switchdev_port_obj_dump(dev, SWITCHDEV_OBJ_ID_PORT_FDB, &dump.fdb.obj, - switchdev_port_fdb_dump_cb); + switchdev_port_obj_dump(dev, &dump.fdb.obj, switchdev_port_fdb_dump_cb); return dump.idx; } EXPORT_SYMBOL_GPL(switchdev_port_fdb_dump); @@ -1008,6 +1009,7 @@ int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, u8 tos, u8 type, u32 nlflags, u32 tb_id) { struct switchdev_obj_ipv4_fib ipv4_fib = { + .obj.id = SWITCHDEV_OBJ_ID_IPV4_FIB, .dst = dst, .dst_len = dst_len, .fi = fi, @@ -1035,8 +1037,7 @@ int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, if (!dev) return 0; - err = switchdev_port_obj_add(dev, SWITCHDEV_OBJ_ID_IPV4_FIB, - &ipv4_fib.obj); + err = switchdev_port_obj_add(dev, &ipv4_fib.obj); if (!err) fi->fib_flags |= RTNH_F_OFFLOAD; @@ -1060,6 +1061,7 @@ int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, u8 tos, u8 type, u32 tb_id) { struct switchdev_obj_ipv4_fib ipv4_fib = { + .obj.id = SWITCHDEV_OBJ_ID_IPV4_FIB, .dst = dst, .dst_len = dst_len, .fi = fi, @@ -1078,8 +1080,7 @@ int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, if (!dev) return 0; - err = switchdev_port_obj_del(dev, SWITCHDEV_OBJ_ID_IPV4_FIB, - &ipv4_fib.obj); + err = switchdev_port_obj_del(dev, &ipv4_fib.obj); if (!err) fi->fib_flags &= ~RTNH_F_OFFLOAD; -- cgit From 464314ea6c119ebc22ee78453e63814453c31611 Mon Sep 17 00:00:00 2001 From: Scott Feldman Date: Thu, 8 Oct 2015 19:23:18 -0700 Subject: switchdev: skip over ports returning -EOPNOTSUPP when recursing ports This allows us to recurse over all the ports, skipping over unsupporting ports. Without the change, the recursion would stop at first unsupported port. Signed-off-by: Scott Feldman Acked-by: Jiri Pirko Signed-off-by: David S. Miller --- net/switchdev/switchdev.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'net/switchdev/switchdev.c') diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 6e4a4f9ad927..7a9ab90363be 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -147,7 +147,7 @@ static int __switchdev_port_attr_set(struct net_device *dev, return ops->switchdev_port_attr_set(dev, attr, trans); if (attr->flags & SWITCHDEV_F_NO_RECURSE) - return err; + goto done; /* Switch device port(s) may be stacked under * bond/team/vlan dev, so recurse down to set attr on @@ -156,10 +156,17 @@ static int __switchdev_port_attr_set(struct net_device *dev, netdev_for_each_lower_dev(dev, lower_dev, iter) { err = __switchdev_port_attr_set(lower_dev, attr, trans); + if (err == -EOPNOTSUPP && + attr->flags & SWITCHDEV_F_SKIP_EOPNOTSUPP) + continue; if (err) break; } +done: + if (err == -EOPNOTSUPP && attr->flags & SWITCHDEV_F_SKIP_EOPNOTSUPP) + err = 0; + return err; } -- cgit