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 /net/dcb | |
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>
Diffstat (limited to 'net/dcb')
-rw-r--r-- | net/dcb/dcbnl.c | 90 |
1 files changed, 88 insertions, 2 deletions
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; |