diff options
| author | John Fastabend <john.r.fastabend@intel.com> | 2011-06-21 03:34:48 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2011-06-21 19:06:11 -0400 |
| commit | f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25 (patch) | |
| tree | cb8bd9dee3075be4a9278ba4f5f5eb0eb41e32b0 | |
| parent | b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3 (diff) | |
dcb: Add ieee_dcb_delapp() and dcb op to delete app entry
Now that we allow multiple IEEE App entries we need a way
to remove specific entries. To do this add the ieee_dcb_delapp()
routine.
Additionaly drivers may need to remove the APP entry from
their firmware tables. Add dcb ops routine to handle this.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | include/linux/dcbnl.h | 2 | ||||
| -rw-r--r-- | include/net/dcbnl.h | 2 | ||||
| -rw-r--r-- | net/dcb/dcbnl.c | 90 |
3 files changed, 92 insertions, 2 deletions
diff --git a/include/linux/dcbnl.h b/include/linux/dcbnl.h index c52280047e2c..66a67235e729 100644 --- a/include/linux/dcbnl.h +++ b/include/linux/dcbnl.h | |||
| @@ -203,6 +203,7 @@ struct dcbmsg { | |||
| 203 | * @DCB_CMD_GFEATCFG: get DCBX features flags | 203 | * @DCB_CMD_GFEATCFG: get DCBX features flags |
| 204 | * @DCB_CMD_SFEATCFG: set DCBX features negotiation flags | 204 | * @DCB_CMD_SFEATCFG: set DCBX features negotiation flags |
| 205 | * @DCB_CMD_CEE_GET: get CEE aggregated configuration | 205 | * @DCB_CMD_CEE_GET: get CEE aggregated configuration |
| 206 | * @DCB_CMD_IEEE_DEL: delete IEEE 802.1Qaz configuration | ||
| 206 | */ | 207 | */ |
| 207 | enum dcbnl_commands { | 208 | enum dcbnl_commands { |
| 208 | DCB_CMD_UNDEFINED, | 209 | DCB_CMD_UNDEFINED, |
| @@ -246,6 +247,7 @@ enum dcbnl_commands { | |||
| 246 | DCB_CMD_SFEATCFG, | 247 | DCB_CMD_SFEATCFG, |
| 247 | 248 | ||
| 248 | DCB_CMD_CEE_GET, | 249 | DCB_CMD_CEE_GET, |
| 250 | DCB_CMD_IEEE_DEL, | ||
| 249 | 251 | ||
| 250 | __DCB_CMD_ENUM_MAX, | 252 | __DCB_CMD_ENUM_MAX, |
| 251 | DCB_CMD_MAX = __DCB_CMD_ENUM_MAX - 1, | 253 | DCB_CMD_MAX = __DCB_CMD_ENUM_MAX - 1, |
diff --git a/include/net/dcbnl.h b/include/net/dcbnl.h index c53a4e06a16a..62a268531d4a 100644 --- a/include/net/dcbnl.h +++ b/include/net/dcbnl.h | |||
| @@ -31,6 +31,7 @@ struct dcb_app_type { | |||
| 31 | u8 dcb_setapp(struct net_device *, struct dcb_app *); | 31 | u8 dcb_setapp(struct net_device *, struct dcb_app *); |
| 32 | u8 dcb_getapp(struct net_device *, struct dcb_app *); | 32 | u8 dcb_getapp(struct net_device *, struct dcb_app *); |
| 33 | int dcb_ieee_setapp(struct net_device *, struct dcb_app *); | 33 | int dcb_ieee_setapp(struct net_device *, struct dcb_app *); |
| 34 | int dcb_ieee_delapp(struct net_device *, struct dcb_app *); | ||
| 34 | 35 | ||
| 35 | int dcbnl_notify(struct net_device *dev, int event, int cmd, u32 seq, u32 pid); | 36 | int dcbnl_notify(struct net_device *dev, int event, int cmd, u32 seq, u32 pid); |
| 36 | 37 | ||
| @@ -46,6 +47,7 @@ struct dcbnl_rtnl_ops { | |||
| 46 | int (*ieee_setpfc) (struct net_device *, struct ieee_pfc *); | 47 | int (*ieee_setpfc) (struct net_device *, struct ieee_pfc *); |
| 47 | int (*ieee_getapp) (struct net_device *, struct dcb_app *); | 48 | int (*ieee_getapp) (struct net_device *, struct dcb_app *); |
| 48 | int (*ieee_setapp) (struct net_device *, struct dcb_app *); | 49 | int (*ieee_setapp) (struct net_device *, struct dcb_app *); |
| 50 | int (*ieee_delapp) (struct net_device *, struct dcb_app *); | ||
| 49 | int (*ieee_peer_getets) (struct net_device *, struct ieee_ets *); | 51 | int (*ieee_peer_getets) (struct net_device *, struct ieee_ets *); |
| 50 | int (*ieee_peer_getpfc) (struct net_device *, struct ieee_pfc *); | 52 | int (*ieee_peer_getpfc) (struct net_device *, struct ieee_pfc *); |
| 51 | 53 | ||
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 3e3b51c4a84a..196084f310d2 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c | |||
| @@ -1451,6 +1451,52 @@ static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb, | |||
| 1451 | 1451 | ||
| 1452 | return err; | 1452 | return err; |
| 1453 | } | 1453 | } |
| 1454 | |||
| 1455 | static int dcbnl_ieee_del(struct net_device *netdev, struct nlattr **tb, | ||
| 1456 | u32 pid, u32 seq, u16 flags) | ||
| 1457 | { | ||
| 1458 | const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; | ||
| 1459 | struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1]; | ||
| 1460 | int err = -EOPNOTSUPP; | ||
| 1461 | |||
| 1462 | if (!ops) | ||
| 1463 | return -EOPNOTSUPP; | ||
| 1464 | |||
| 1465 | if (!tb[DCB_ATTR_IEEE]) | ||
| 1466 | return -EINVAL; | ||
| 1467 | |||
| 1468 | err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX, | ||
| 1469 | tb[DCB_ATTR_IEEE], dcbnl_ieee_policy); | ||
| 1470 | if (err) | ||
| 1471 | return err; | ||
| 1472 | |||
| 1473 | if (ieee[DCB_ATTR_IEEE_APP_TABLE]) { | ||
| 1474 | struct nlattr *attr; | ||
| 1475 | int rem; | ||
| 1476 | |||
| 1477 | nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) { | ||
| 1478 | struct dcb_app *app_data; | ||
| 1479 | |||
| 1480 | if (nla_type(attr) != DCB_ATTR_IEEE_APP) | ||
| 1481 | continue; | ||
| 1482 | app_data = nla_data(attr); | ||
| 1483 | if (ops->ieee_delapp) | ||
| 1484 | err = ops->ieee_delapp(netdev, app_data); | ||
| 1485 | else | ||
| 1486 | err = dcb_ieee_delapp(netdev, app_data); | ||
| 1487 | if (err) | ||
| 1488 | goto err; | ||
| 1489 | } | ||
| 1490 | } | ||
| 1491 | |||
| 1492 | err: | ||
| 1493 | dcbnl_reply(err, RTM_SETDCB, DCB_CMD_IEEE_DEL, DCB_ATTR_IEEE, | ||
| 1494 | pid, seq, flags); | ||
| 1495 | dcbnl_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_DEL, seq, 0); | ||
| 1496 | return err; | ||
| 1497 | } | ||
| 1498 | |||
| 1499 | |||
| 1454 | /* DCBX configuration */ | 1500 | /* DCBX configuration */ |
| 1455 | static int dcbnl_getdcbx(struct net_device *netdev, struct nlattr **tb, | 1501 | static int dcbnl_getdcbx(struct net_device *netdev, struct nlattr **tb, |
| 1456 | u32 pid, u32 seq, u16 flags) | 1502 | u32 pid, u32 seq, u16 flags) |
| @@ -1765,11 +1811,15 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
| 1765 | goto out; | 1811 | goto out; |
| 1766 | case DCB_CMD_IEEE_SET: | 1812 | case DCB_CMD_IEEE_SET: |
| 1767 | ret = dcbnl_ieee_set(netdev, tb, pid, nlh->nlmsg_seq, | 1813 | ret = dcbnl_ieee_set(netdev, tb, pid, nlh->nlmsg_seq, |
| 1768 | nlh->nlmsg_flags); | 1814 | nlh->nlmsg_flags); |
| 1769 | goto out; | 1815 | goto out; |
| 1770 | case DCB_CMD_IEEE_GET: | 1816 | case DCB_CMD_IEEE_GET: |
| 1771 | ret = dcbnl_ieee_get(netdev, tb, pid, nlh->nlmsg_seq, | 1817 | ret = dcbnl_ieee_get(netdev, tb, pid, nlh->nlmsg_seq, |
| 1772 | nlh->nlmsg_flags); | 1818 | nlh->nlmsg_flags); |
| 1819 | goto out; | ||
| 1820 | case DCB_CMD_IEEE_DEL: | ||
| 1821 | ret = dcbnl_ieee_del(netdev, tb, pid, nlh->nlmsg_seq, | ||
| 1822 | nlh->nlmsg_flags); | ||
| 1773 | goto out; | 1823 | goto out; |
| 1774 | case DCB_CMD_GDCBX: | 1824 | case DCB_CMD_GDCBX: |
| 1775 | ret = dcbnl_getdcbx(netdev, tb, pid, nlh->nlmsg_seq, | 1825 | ret = dcbnl_getdcbx(netdev, tb, pid, nlh->nlmsg_seq, |
| @@ -1924,6 +1974,42 @@ out: | |||
| 1924 | } | 1974 | } |
| 1925 | EXPORT_SYMBOL(dcb_ieee_setapp); | 1975 | EXPORT_SYMBOL(dcb_ieee_setapp); |
| 1926 | 1976 | ||
| 1977 | /** | ||
| 1978 | * dcb_ieee_delapp - delete IEEE dcb application data from list | ||
| 1979 | * | ||
| 1980 | * This removes a matching APP data from the APP list | ||
| 1981 | */ | ||
| 1982 | int dcb_ieee_delapp(struct net_device *dev, struct dcb_app *del) | ||
| 1983 | { | ||
| 1984 | struct dcb_app_type *itr; | ||
| 1985 | struct dcb_app_type event; | ||
| 1986 | int err = -ENOENT; | ||
| 1987 | |||
| 1988 | memcpy(&event.name, dev->name, sizeof(event.name)); | ||
| 1989 | memcpy(&event.app, del, sizeof(event.app)); | ||
| 1990 | |||
| 1991 | spin_lock(&dcb_lock); | ||
| 1992 | /* Search for existing match and remove it. */ | ||
| 1993 | list_for_each_entry(itr, &dcb_app_list, list) { | ||
| 1994 | if (itr->app.selector == del->selector && | ||
| 1995 | itr->app.protocol == del->protocol && | ||
| 1996 | itr->app.priority == del->priority && | ||
| 1997 | (strncmp(itr->name, dev->name, IFNAMSIZ) == 0)) { | ||
| 1998 | list_del(&itr->list); | ||
| 1999 | kfree(itr); | ||
| 2000 | err = 0; | ||
| 2001 | goto out; | ||
| 2002 | } | ||
| 2003 | } | ||
| 2004 | |||
| 2005 | out: | ||
| 2006 | spin_unlock(&dcb_lock); | ||
| 2007 | if (!err) | ||
| 2008 | call_dcbevent_notifiers(DCB_APP_EVENT, &event); | ||
| 2009 | return err; | ||
| 2010 | } | ||
| 2011 | EXPORT_SYMBOL(dcb_ieee_delapp); | ||
| 2012 | |||
| 1927 | static void dcb_flushapp(void) | 2013 | static void dcb_flushapp(void) |
| 1928 | { | 2014 | { |
| 1929 | struct dcb_app_type *app; | 2015 | struct dcb_app_type *app; |
