[DCB_ATTR_IEEE_APP]         = {.len = sizeof(struct dcb_app)},
 };
 
+static LIST_HEAD(dcb_app_list);
+static DEFINE_SPINLOCK(dcb_lock);
+
 /* standard netlink reply call */
 static int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid,
                        u32 seq, u16 flags)
 static int dcbnl_setapp(struct net_device *netdev, struct nlattr **tb,
                         u32 pid, u32 seq, u16 flags)
 {
-       int ret = -EINVAL;
+       int err, ret = -EINVAL;
        u16 id;
        u8 up, idtype;
        struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1];
 
-       if (!tb[DCB_ATTR_APP] || !netdev->dcbnl_ops->setapp)
+       if (!tb[DCB_ATTR_APP])
                goto out;
 
        ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP],
        id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]);
        up = nla_get_u8(app_tb[DCB_APP_ATTR_PRIORITY]);
 
-       ret = dcbnl_reply(netdev->dcbnl_ops->setapp(netdev, idtype, id, up),
-                         RTM_SETDCB, DCB_CMD_SAPP, DCB_ATTR_APP,
-                         pid, seq, flags);
+       if (netdev->dcbnl_ops->setapp) {
+               err = netdev->dcbnl_ops->setapp(netdev, idtype, id, up);
+       } else {
+               struct dcb_app app;
+               app.selector = idtype;
+               app.protocol = id;
+               app.priority = up;
+               err = dcb_setapp(netdev, &app);
+       }
+
+       ret = dcbnl_reply(err, RTM_SETDCB, DCB_CMD_SAPP, DCB_ATTR_APP,
+                         pid, seq, flags);
 out:
        return ret;
 }
                        goto err;
        }
 
-       if (ieee[DCB_ATTR_IEEE_APP_TABLE] && ops->ieee_setapp) {
+       if (ieee[DCB_ATTR_IEEE_APP_TABLE]) {
                struct nlattr *attr;
                int rem;
 
                        if (nla_type(attr) != DCB_ATTR_IEEE_APP)
                                continue;
                        app_data = nla_data(attr);
-                       err = ops->ieee_setapp(netdev, app_data);
+                       if (ops->ieee_setapp)
+                               err = ops->ieee_setapp(netdev, app_data);
+                       else
+                               err = dcb_setapp(netdev, app_data);
                        if (err)
                                goto err;
                }
        struct sk_buff *skb;
        struct nlmsghdr *nlh;
        struct dcbmsg *dcb;
-       struct nlattr *ieee;
+       struct nlattr *ieee, *app;
+       struct dcb_app_type *itr;
        const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
        int err;
 
                        NLA_PUT(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc);
        }
 
+       app = nla_nest_start(skb, DCB_ATTR_IEEE_APP_TABLE);
+       if (!app)
+               goto nla_put_failure;
+
+       spin_lock(&dcb_lock);
+       list_for_each_entry(itr, &dcb_app_list, list) {
+               if (strncmp(itr->name, netdev->name, IFNAMSIZ) == 0)
+                       NLA_PUT(skb, DCB_ATTR_IEEE_APP,
+                               sizeof(itr->app), &itr->app);
+       }
+       spin_unlock(&dcb_lock);
+       nla_nest_end(skb, app);
+
        nla_nest_end(skb, ieee);
        nlmsg_end(skb, nlh);
 
        return ret;
 }
 
+/**
+ * dcb_getapp - retrieve the DCBX application user priority
+ *
+ * On success returns a non-zero 802.1p user priority bitmap
+ * otherwise returns 0 as the invalid user priority bitmap to
+ * indicate an error.
+ */
+u8 dcb_getapp(struct net_device *dev, struct dcb_app *app)
+{
+       struct dcb_app_type *itr;
+       u8 prio = 0;
+
+       spin_lock(&dcb_lock);
+       list_for_each_entry(itr, &dcb_app_list, list) {
+               if (itr->app.selector == app->selector &&
+                   itr->app.protocol == app->protocol &&
+                   (strncmp(itr->name, dev->name, IFNAMSIZ) == 0)) {
+                       prio = itr->app.priority;
+                       break;
+               }
+       }
+       spin_unlock(&dcb_lock);
+
+       return prio;
+}
+EXPORT_SYMBOL(dcb_getapp);
+
+/**
+ * ixgbe_dcbnl_setapp - add dcb application data to app list
+ *
+ * Priority 0 is the default priority this removes applications
+ * from the app list if the priority is set to zero.
+ */
+u8 dcb_setapp(struct net_device *dev, struct dcb_app *new)
+{
+       struct dcb_app_type *itr;
+
+       spin_lock(&dcb_lock);
+       /* Search for existing match and replace */
+       list_for_each_entry(itr, &dcb_app_list, list) {
+               if (itr->app.selector == new->selector &&
+                   itr->app.protocol == new->protocol &&
+                   (strncmp(itr->name, dev->name, IFNAMSIZ) == 0)) {
+                       if (new->priority)
+                               itr->app.priority = new->priority;
+                       else {
+                               list_del(&itr->list);
+                               kfree(itr);
+                       }
+                       goto out;
+               }
+       }
+       /* App type does not exist add new application type */
+       if (new->priority) {
+               struct dcb_app_type *entry;
+               entry = kmalloc(sizeof(struct dcb_app_type), GFP_ATOMIC);
+               if (!entry) {
+                       spin_unlock(&dcb_lock);
+                       return -ENOMEM;
+               }
+
+               memcpy(&entry->app, new, sizeof(*new));
+               strncpy(entry->name, dev->name, IFNAMSIZ);
+               list_add(&entry->list, &dcb_app_list);
+       }
+out:
+       spin_unlock(&dcb_lock);
+       return 0;
+}
+EXPORT_SYMBOL(dcb_setapp);
+
+void dcb_flushapp(void)
+{
+       struct dcb_app_type *app;
+
+       spin_lock(&dcb_lock);
+       list_for_each_entry(app, &dcb_app_list, list) {
+               list_del(&app->list);
+               kfree(app);
+       }
+       spin_unlock(&dcb_lock);
+}
+
 static int __init dcbnl_init(void)
 {
+       INIT_LIST_HEAD(&dcb_app_list);
+
        rtnl_register(PF_UNSPEC, RTM_GETDCB, dcb_doit, NULL);
        rtnl_register(PF_UNSPEC, RTM_SETDCB, dcb_doit, NULL);
 
 {
        rtnl_unregister(PF_UNSPEC, RTM_GETDCB);
        rtnl_unregister(PF_UNSPEC, RTM_SETDCB);
+       dcb_flushapp();
 }
 module_exit(dcbnl_exit);
-
-