aboutsummaryrefslogtreecommitdiffstats
path: root/net/switchdev
diff options
context:
space:
mode:
authorVivien Didelot <vivien.didelot@savoirfairelinux.com>2015-09-29 12:07:16 -0400
committerDavid S. Miller <davem@davemloft.net>2015-09-30 00:31:59 -0400
commit25f07adc473f05f850efc9414b9da3374563015f (patch)
treeff62d9a8e9c63c48abd034b61156c55c6437a36e /net/switchdev
parent03d5fb18626aff95426a380aef0d1c6904cac7c9 (diff)
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 <vivien.didelot@savoirfairelinux.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/switchdev')
-rw-r--r--net/switchdev/switchdev.c45
1 files changed, 22 insertions, 23 deletions
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);
386 * switchdev_port_obj_dump - Dump port objects 386 * switchdev_port_obj_dump - Dump port objects
387 * 387 *
388 * @dev: port device 388 * @dev: port device
389 * @id: object ID
389 * @obj: object to dump 390 * @obj: object to dump
391 * @cb: function to call with a filled object
390 */ 392 */
391int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj) 393int switchdev_port_obj_dump(struct net_device *dev, enum switchdev_obj_id id,
394 void *obj, int (*cb)(void *obj))
392{ 395{
393 const struct switchdev_ops *ops = dev->switchdev_ops; 396 const struct switchdev_ops *ops = dev->switchdev_ops;
394 struct net_device *lower_dev; 397 struct net_device *lower_dev;
@@ -396,7 +399,7 @@ int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj)
396 int err = -EOPNOTSUPP; 399 int err = -EOPNOTSUPP;
397 400
398 if (ops && ops->switchdev_port_obj_dump) 401 if (ops && ops->switchdev_port_obj_dump)
399 return ops->switchdev_port_obj_dump(dev, obj); 402 return ops->switchdev_port_obj_dump(dev, id, obj, cb);
400 403
401 /* Switch device port(s) may be stacked under 404 /* Switch device port(s) may be stacked under
402 * bond/team/vlan dev, so recurse down to dump objects on 405 * 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)
404 */ 407 */
405 408
406 netdev_for_each_lower_dev(dev, lower_dev, iter) { 409 netdev_for_each_lower_dev(dev, lower_dev, iter) {
407 err = switchdev_port_obj_dump(lower_dev, obj); 410 err = switchdev_port_obj_dump(lower_dev, id, obj, cb);
408 break; 411 break;
409 } 412 }
410 413
@@ -476,7 +479,7 @@ int call_switchdev_notifiers(unsigned long val, struct net_device *dev,
476EXPORT_SYMBOL_GPL(call_switchdev_notifiers); 479EXPORT_SYMBOL_GPL(call_switchdev_notifiers);
477 480
478struct switchdev_vlan_dump { 481struct switchdev_vlan_dump {
479 struct switchdev_obj obj; 482 struct switchdev_obj_vlan vlan;
480 struct sk_buff *skb; 483 struct sk_buff *skb;
481 u32 filter_mask; 484 u32 filter_mask;
482 u16 flags; 485 u16 flags;
@@ -514,11 +517,11 @@ static int switchdev_port_vlan_dump_put(struct switchdev_vlan_dump *dump)
514 return 0; 517 return 0;
515} 518}
516 519
517static int switchdev_port_vlan_dump_cb(struct switchdev_obj *obj) 520static int switchdev_port_vlan_dump_cb(void *obj)
518{ 521{
522 struct switchdev_obj_vlan *vlan = obj;
519 struct switchdev_vlan_dump *dump = 523 struct switchdev_vlan_dump *dump =
520 container_of(obj, struct switchdev_vlan_dump, obj); 524 container_of(vlan, struct switchdev_vlan_dump, vlan);
521 struct switchdev_obj_vlan *vlan = &dump->obj.u.vlan;
522 int err = 0; 525 int err = 0;
523 526
524 if (vlan->vid_begin > vlan->vid_end) 527 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,
570 u32 filter_mask) 573 u32 filter_mask)
571{ 574{
572 struct switchdev_vlan_dump dump = { 575 struct switchdev_vlan_dump dump = {
573 .obj = {
574 .id = SWITCHDEV_OBJ_PORT_VLAN,
575 .cb = switchdev_port_vlan_dump_cb,
576 },
577 .skb = skb, 576 .skb = skb,
578 .filter_mask = filter_mask, 577 .filter_mask = filter_mask,
579 }; 578 };
@@ -581,7 +580,9 @@ static int switchdev_port_vlan_fill(struct sk_buff *skb, struct net_device *dev,
581 580
582 if ((filter_mask & RTEXT_FILTER_BRVLAN) || 581 if ((filter_mask & RTEXT_FILTER_BRVLAN) ||
583 (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED)) { 582 (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED)) {
584 err = switchdev_port_obj_dump(dev, &dump.obj); 583 err = switchdev_port_obj_dump(dev, SWITCHDEV_OBJ_PORT_VLAN,
584 &dump.vlan,
585 switchdev_port_vlan_dump_cb);
585 if (err) 586 if (err)
586 goto err_out; 587 goto err_out;
587 if (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED) 588 if (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED)
@@ -856,17 +857,18 @@ int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
856EXPORT_SYMBOL_GPL(switchdev_port_fdb_del); 857EXPORT_SYMBOL_GPL(switchdev_port_fdb_del);
857 858
858struct switchdev_fdb_dump { 859struct switchdev_fdb_dump {
859 struct switchdev_obj obj; 860 struct switchdev_obj_fdb fdb;
860 struct net_device *dev; 861 struct net_device *dev;
861 struct sk_buff *skb; 862 struct sk_buff *skb;
862 struct netlink_callback *cb; 863 struct netlink_callback *cb;
863 int idx; 864 int idx;
864}; 865};
865 866
866static int switchdev_port_fdb_dump_cb(struct switchdev_obj *obj) 867static int switchdev_port_fdb_dump_cb(void *obj)
867{ 868{
869 struct switchdev_obj_fdb *fdb = obj;
868 struct switchdev_fdb_dump *dump = 870 struct switchdev_fdb_dump *dump =
869 container_of(obj, struct switchdev_fdb_dump, obj); 871 container_of(fdb, struct switchdev_fdb_dump, fdb);
870 u32 portid = NETLINK_CB(dump->cb->skb).portid; 872 u32 portid = NETLINK_CB(dump->cb->skb).portid;
871 u32 seq = dump->cb->nlh->nlmsg_seq; 873 u32 seq = dump->cb->nlh->nlmsg_seq;
872 struct nlmsghdr *nlh; 874 struct nlmsghdr *nlh;
@@ -887,12 +889,12 @@ static int switchdev_port_fdb_dump_cb(struct switchdev_obj *obj)
887 ndm->ndm_flags = NTF_SELF; 889 ndm->ndm_flags = NTF_SELF;
888 ndm->ndm_type = 0; 890 ndm->ndm_type = 0;
889 ndm->ndm_ifindex = dump->dev->ifindex; 891 ndm->ndm_ifindex = dump->dev->ifindex;
890 ndm->ndm_state = obj->u.fdb.ndm_state; 892 ndm->ndm_state = fdb->ndm_state;
891 893
892 if (nla_put(dump->skb, NDA_LLADDR, ETH_ALEN, obj->u.fdb.addr)) 894 if (nla_put(dump->skb, NDA_LLADDR, ETH_ALEN, fdb->addr))
893 goto nla_put_failure; 895 goto nla_put_failure;
894 896
895 if (obj->u.fdb.vid && nla_put_u16(dump->skb, NDA_VLAN, obj->u.fdb.vid)) 897 if (fdb->vid && nla_put_u16(dump->skb, NDA_VLAN, fdb->vid))
896 goto nla_put_failure; 898 goto nla_put_failure;
897 899
898 nlmsg_end(dump->skb, nlh); 900 nlmsg_end(dump->skb, nlh);
@@ -922,17 +924,14 @@ int switchdev_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
922 struct net_device *filter_dev, int idx) 924 struct net_device *filter_dev, int idx)
923{ 925{
924 struct switchdev_fdb_dump dump = { 926 struct switchdev_fdb_dump dump = {
925 .obj = {
926 .id = SWITCHDEV_OBJ_PORT_FDB,
927 .cb = switchdev_port_fdb_dump_cb,
928 },
929 .dev = dev, 927 .dev = dev,
930 .skb = skb, 928 .skb = skb,
931 .cb = cb, 929 .cb = cb,
932 .idx = idx, 930 .idx = idx,
933 }; 931 };
934 932
935 switchdev_port_obj_dump(dev, &dump.obj); 933 switchdev_port_obj_dump(dev, SWITCHDEV_OBJ_PORT_FDB, &dump.fdb,
934 switchdev_port_fdb_dump_cb);
936 return dump.idx; 935 return dump.idx;
937} 936}
938EXPORT_SYMBOL_GPL(switchdev_port_fdb_dump); 937EXPORT_SYMBOL_GPL(switchdev_port_fdb_dump);