#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
#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];
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;
if (cache)
nl_cache_free(cache);
if (handle)
- nl_handle_destroy(handle);
+ nl_socket_free(handle);
handle = NULL;
cache = NULL;
}
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;
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;
}
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;
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;