]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
dcb: Add ieee_dcb_delapp() and dcb op to delete app entry
authorJoe Jin <joe.jin@oracle.com>
Wed, 16 May 2012 08:27:49 +0000 (16:27 +0800)
committerJoe Jin <joe.jin@oracle.com>
Wed, 16 May 2012 08:27:49 +0000 (16:27 +0800)
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>
(cherry picked from commit f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25)

Signed-off-by: Joe Jin <joe.jin@oracle.com>
include/linux/dcbnl.h
include/net/dcbnl.h
net/dcb/dcbnl.c

index c52280047e2c60835b3013fe27672ca64b4fe57e..66a67235e72911b173d3f6e00358bcd5fbd02685 100644 (file)
@@ -203,6 +203,7 @@ struct dcbmsg {
  * @DCB_CMD_GFEATCFG: get DCBX features flags
  * @DCB_CMD_SFEATCFG: set DCBX features negotiation flags
  * @DCB_CMD_CEE_GET: get CEE aggregated configuration
+ * @DCB_CMD_IEEE_DEL: delete IEEE 802.1Qaz configuration
  */
 enum dcbnl_commands {
        DCB_CMD_UNDEFINED,
@@ -246,6 +247,7 @@ enum dcbnl_commands {
        DCB_CMD_SFEATCFG,
 
        DCB_CMD_CEE_GET,
+       DCB_CMD_IEEE_DEL,
 
        __DCB_CMD_ENUM_MAX,
        DCB_CMD_MAX = __DCB_CMD_ENUM_MAX - 1,
index c53a4e06a16af09268d6c7e8a044028bb0ca5daf..7f6599718a82e0677fd51a3ece0f851a57857a95 100644 (file)
@@ -31,6 +31,7 @@ struct dcb_app_type {
 u8 dcb_setapp(struct net_device *, struct dcb_app *);
 u8 dcb_getapp(struct net_device *, struct dcb_app *);
 int dcb_ieee_setapp(struct net_device *, struct dcb_app *);
+int dcb_ieee_delapp(struct net_device *, struct dcb_app *);
 
 int dcbnl_notify(struct net_device *dev, int event, int cmd, u32 seq, u32 pid);
 
index 48b1926c1506effc4df702a91846d756eb57001e..a2453ce3492e627d5eb5f226ff43f22399e70480 100644 (file)
@@ -1451,6 +1451,49 @@ static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb,
 
        return err;
 }
+
+static int dcbnl_ieee_del(struct net_device *netdev, struct nlattr **tb,
+                         u32 pid, u32 seq, u16 flags)
+{
+       const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
+       struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1];
+       int err = -EOPNOTSUPP;
+
+       if (!ops)
+               return -EOPNOTSUPP;
+
+       if (!tb[DCB_ATTR_IEEE])
+               return -EINVAL;
+
+       err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX,
+                              tb[DCB_ATTR_IEEE], dcbnl_ieee_policy);
+       if (err)
+               return err;
+
+       if (ieee[DCB_ATTR_IEEE_APP_TABLE]) {
+               struct nlattr *attr;
+               int rem;
+
+               nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) {
+                       struct dcb_app *app_data;
+
+                       if (nla_type(attr) != DCB_ATTR_IEEE_APP)
+                               continue;
+                       app_data = nla_data(attr);
+                       err = dcb_ieee_delapp(netdev, app_data);
+                       if (err)
+                               goto err;
+               }
+       }
+
+err:
+       dcbnl_reply(err, RTM_SETDCB, DCB_CMD_IEEE_DEL, DCB_ATTR_IEEE,
+                   pid, seq, flags);
+       dcbnl_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_DEL, seq, 0);
+       return err;
+}
+
+
 /* DCBX configuration */
 static int dcbnl_getdcbx(struct net_device *netdev, struct nlattr **tb,
                         u32 pid, u32 seq, u16 flags)
@@ -1765,11 +1808,15 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
                goto out;
        case DCB_CMD_IEEE_SET:
                ret = dcbnl_ieee_set(netdev, tb, pid, nlh->nlmsg_seq,
-                                nlh->nlmsg_flags);
+                                    nlh->nlmsg_flags);
                goto out;
        case DCB_CMD_IEEE_GET:
                ret = dcbnl_ieee_get(netdev, tb, pid, nlh->nlmsg_seq,
-                                nlh->nlmsg_flags);
+                                    nlh->nlmsg_flags);
+               goto out;
+       case DCB_CMD_IEEE_DEL:
+               ret = dcbnl_ieee_del(netdev, tb, pid, nlh->nlmsg_seq,
+                                    nlh->nlmsg_flags);
                goto out;
        case DCB_CMD_GDCBX:
                ret = dcbnl_getdcbx(netdev, tb, pid, nlh->nlmsg_seq,
@@ -1924,6 +1971,42 @@ out:
 }
 EXPORT_SYMBOL(dcb_ieee_setapp);
 
+/**
+ * dcb_ieee_delapp - delete IEEE dcb application data from list
+ *
+ * This removes a matching APP data from the APP list
+ */
+int dcb_ieee_delapp(struct net_device *dev, struct dcb_app *del)
+{
+       struct dcb_app_type *itr;
+       struct dcb_app_type event;
+       int err = -ENOENT;
+
+       memcpy(&event.name, dev->name, sizeof(event.name));
+       memcpy(&event.app, del, sizeof(event.app));
+
+       spin_lock(&dcb_lock);
+       /* Search for existing match and remove it. */
+       list_for_each_entry(itr, &dcb_app_list, list) {
+               if (itr->app.selector == del->selector &&
+                   itr->app.protocol == del->protocol &&
+                   itr->app.priority == del->priority &&
+                   (strncmp(itr->name, dev->name, IFNAMSIZ) == 0)) {
+                       list_del(&itr->list);
+                       kfree(itr);
+                       err = 0;
+                       goto out;
+               }
+       }
+
+out:
+       spin_unlock(&dcb_lock);
+       if (!err)
+               call_dcbevent_notifiers(DCB_APP_EVENT, &event);
+       return err;
+}
+EXPORT_SYMBOL(dcb_ieee_delapp);
+
 static void dcb_flushapp(void)
 {
        struct dcb_app_type *app;