hostapd: add a workaround for driver issues in various android devices with texas...
[openwrt.git] / package / swconfig / src / swlib.c
index 3fde816..531a23a 100644 (file)
@@ -24,6 +24,9 @@
 #include <sys/socket.h>
 #include <linux/switch.h>
 #include "swlib.h"
+#include <netlink/netlink.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
 
 //#define DEBUG 1
 #ifdef DEBUG
@@ -32,7 +35,7 @@
 #define DPRINTF(fmt, ...) do {} while (0)
 #endif
 
-static struct nl_handle *handle;
+static struct nl_sock *handle;
 static struct nl_cache *cache;
 static struct genl_family *family;
 static struct nlattr *tb[SWITCH_ATTR_MAX];
@@ -343,6 +346,67 @@ swlib_set_attr(struct switch_dev *dev, struct switch_attr *attr, struct switch_v
        return swlib_call(cmd, NULL, send_attr_val, val);
 }
 
+int swlib_set_attr_string(struct switch_dev *dev, struct switch_attr *a, int port_vlan, const char *str)
+{
+       struct switch_port *ports;
+       struct switch_val val;
+       char *ptr;
+
+       memset(&val, 0, sizeof(val));
+       val.port_vlan = port_vlan;
+       switch(a->type) {
+       case SWITCH_TYPE_INT:
+               val.value.i = atoi(str);
+               break;
+       case SWITCH_TYPE_STRING:
+               val.value.s = str;
+               break;
+       case SWITCH_TYPE_PORTS:
+               ports = alloca(sizeof(struct switch_port) * dev->ports);
+               memset(ports, 0, sizeof(struct switch_port) * dev->ports);
+               val.len = 0;
+               ptr = (char *)str;
+               while(ptr && *ptr)
+               {
+                       while(*ptr && isspace(*ptr))
+                               ptr++;
+
+                       if (!*ptr)
+                               break;
+
+                       if (!isdigit(*ptr))
+                               return -1;
+
+                       if (val.len >= dev->ports)
+                               return -1;
+
+                       ports[val.len].flags = 0;
+                       ports[val.len].id = strtoul(ptr, &ptr, 10);
+                       while(*ptr && !isspace(*ptr)) {
+                               if (*ptr == 't')
+                                       ports[val.len].flags |= SWLIB_PORT_FLAG_TAGGED;
+                               else
+                                       return -1;
+
+                               ptr++;
+                       }
+                       if (*ptr)
+                               ptr++;
+                       val.len++;
+               }
+               val.value.ports = ports;
+               break;
+       case SWITCH_TYPE_NOVAL:
+               if (str && !strcmp(str, "0"))
+                       return 0;
+
+               break;
+       default:
+               return -1;
+       }
+       return swlib_set_attr(dev, a, &val);
+}
+
 
 struct attrlist_arg {
        int id;
@@ -464,7 +528,7 @@ swlib_priv_free(void)
        if (cache)
                nl_cache_free(cache);
        if (handle)
-               nl_handle_destroy(handle);
+               nl_socket_free(handle);
        handle = NULL;
        cache = NULL;
 }
@@ -472,7 +536,9 @@ swlib_priv_free(void)
 static int
 swlib_priv_init(void)
 {
-       handle = nl_handle_alloc();
+       int ret;
+
+       handle = nl_socket_alloc();
        if (!handle) {
                DPRINTF("Failed to create handle\n");
                goto err;
@@ -483,8 +549,8 @@ swlib_priv_init(void)
                goto err;
        }
 
-       cache = genl_ctrl_alloc_cache(handle);
-       if (!cache) {
+       ret = genl_ctrl_alloc_cache(handle, &cache);
+       if (ret < 0) {
                DPRINTF("Failed to allocate netlink cache\n");
                goto err;
        }
@@ -514,6 +580,7 @@ add_switch(struct nl_msg *msg, void *arg)
        struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
        struct switch_dev *dev;
        const char *name;
+       const char *alias;
 
        if (nla_parse(tb, SWITCH_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL) < 0)
                goto done;
@@ -522,22 +589,27 @@ add_switch(struct nl_msg *msg, void *arg)
                goto done;
 
        name = nla_get_string(tb[SWITCH_ATTR_DEV_NAME]);
-       if (sa->name && (strcmp(name, sa->name) != 0))
+       alias = nla_get_string(tb[SWITCH_ATTR_ALIAS]);
+
+       if (sa->name && (strcmp(name, sa->name) != 0) && (strcmp(alias, sa->name) != 0))
                goto done;
 
        dev = swlib_alloc(sizeof(struct switch_dev));
        if (!dev)
                goto done;
 
-       dev->dev_name = strdup(name);
+       strncpy(dev->dev_name, name, IFNAMSIZ - 1);
+       dev->alias = strdup(alias);
        if (tb[SWITCH_ATTR_ID])
                dev->id = nla_get_u32(tb[SWITCH_ATTR_ID]);
        if (tb[SWITCH_ATTR_NAME])
-               dev->name = strdup(nla_get_string(tb[SWITCH_ATTR_DEV_NAME]));
+               dev->name = strdup(nla_get_string(tb[SWITCH_ATTR_NAME]));
        if (tb[SWITCH_ATTR_PORTS])
                dev->ports = nla_get_u32(tb[SWITCH_ATTR_PORTS]);
        if (tb[SWITCH_ATTR_VLANS])
                dev->vlans = nla_get_u32(tb[SWITCH_ATTR_VLANS]);
+       if (tb[SWITCH_ATTR_CPU_PORT])
+               dev->cpu_port = nla_get_u32(tb[SWITCH_ATTR_CPU_PORT]);
 
        if (!sa->head) {
                sa->head = dev;
This page took 0.02464 seconds and 4 git commands to generate.