swconfig: implement uci loading support
SVN-Revision: 15315
This commit is contained in:
parent
70bf92d03c
commit
2fe29deb90
@ -17,7 +17,7 @@ include $(INCLUDE_DIR)/package.mk
|
|||||||
define Package/swconfig
|
define Package/swconfig
|
||||||
SECTION:=base
|
SECTION:=base
|
||||||
CATEGORY:=Base system
|
CATEGORY:=Base system
|
||||||
DEPENDS:=@LINUX_2_6_26||LINUX_2_6_27||LINUX_2_6_28||LINUX_2_6_29
|
DEPENDS:=@LINUX_2_6_26||LINUX_2_6_27||LINUX_2_6_28||LINUX_2_6_29 +libuci
|
||||||
TITLE:=Switch configuration utility
|
TITLE:=Switch configuration utility
|
||||||
endef
|
endef
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ define Build/Compile
|
|||||||
CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS)" \
|
CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS)" \
|
||||||
$(MAKE) -C $(PKG_BUILD_DIR) \
|
$(MAKE) -C $(PKG_BUILD_DIR) \
|
||||||
$(TARGET_CONFIGURE_OPTS) \
|
$(TARGET_CONFIGURE_OPTS) \
|
||||||
LIBS="$(STAGING_DIR)/usr/lib/libnl.a -lm"
|
LIBS="-L$(STAGING_DIR)/usr/lib $(STAGING_DIR)/usr/lib/libnl.a -lm -luci"
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/swconfig/install
|
define Package/swconfig/install
|
||||||
|
@ -8,5 +8,5 @@ all: swconfig
|
|||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(CC) $(CFLAGS) -c -o $@ $^
|
$(CC) $(CFLAGS) -c -o $@ $^
|
||||||
|
|
||||||
swconfig: cli.o swlib.o
|
swconfig: cli.o swlib.o uci.o
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <uci.h>
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/netlink.h>
|
#include <linux/netlink.h>
|
||||||
@ -32,10 +33,14 @@
|
|||||||
#include <linux/switch.h>
|
#include <linux/switch.h>
|
||||||
#include "swlib.h"
|
#include "swlib.h"
|
||||||
|
|
||||||
#define GET 1
|
enum {
|
||||||
#define SET 2
|
GET,
|
||||||
|
SET,
|
||||||
|
LOAD
|
||||||
|
};
|
||||||
|
|
||||||
void print_attrs(struct switch_attr *attr)
|
static void
|
||||||
|
print_attrs(const struct switch_attr *attr)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (attr) {
|
while (attr) {
|
||||||
@ -62,7 +67,8 @@ void print_attrs(struct switch_attr *attr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void list_attributes(struct switch_dev *dev)
|
static void
|
||||||
|
list_attributes(struct switch_dev *dev)
|
||||||
{
|
{
|
||||||
printf("Switch %d: %s(%s), ports: %d, vlans: %d\n", dev->id, dev->dev_name, dev->name, dev->ports, dev->vlans);
|
printf("Switch %d: %s(%s), ports: %d, vlans: %d\n", dev->id, dev->dev_name, dev->name, dev->ports, dev->vlans);
|
||||||
printf(" --switch\n");
|
printf(" --switch\n");
|
||||||
@ -73,10 +79,38 @@ void list_attributes(struct switch_dev *dev)
|
|||||||
print_attrs(dev->port_ops);
|
print_attrs(dev->port_ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_usage(void)
|
static void
|
||||||
|
print_usage(void)
|
||||||
{
|
{
|
||||||
printf("swconfig dev <dev> [port <port>|vlan <vlan>] (help|set <key> <value>|get <key>)\n");
|
printf("swconfig dev <dev> [port <port>|vlan <vlan>] (help|set <key> <value>|get <key>|load <config>)\n");
|
||||||
exit(0);
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swconfig_load_uci(struct switch_dev *dev, const char *name)
|
||||||
|
{
|
||||||
|
struct uci_context *ctx;
|
||||||
|
struct uci_package *p = NULL;
|
||||||
|
struct uci_element *e;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
ctx = uci_alloc_context();
|
||||||
|
if (!ctx)
|
||||||
|
return;
|
||||||
|
|
||||||
|
uci_load(ctx, name, &p);
|
||||||
|
if (!p) {
|
||||||
|
uci_perror(ctx, "Failed to load config file: ");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = swlib_apply_from_uci(dev, p);
|
||||||
|
if (ret < 0)
|
||||||
|
fprintf(stderr, "Failed to apply configuration for switch '%s'\n", dev->dev_name);
|
||||||
|
|
||||||
|
out:
|
||||||
|
uci_free_context(ctx);
|
||||||
|
exit(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
@ -109,22 +143,18 @@ int main(int argc, char **argv)
|
|||||||
for(i = 3; i < argc; i++)
|
for(i = 3; i < argc; i++)
|
||||||
{
|
{
|
||||||
int p;
|
int p;
|
||||||
if(!strcmp(argv[i], "help"))
|
if (!strcmp(argv[i], "help")) {
|
||||||
{
|
|
||||||
chelp = 1;
|
chelp = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(i + 1 >= argc)
|
if( i + 1 >= argc)
|
||||||
print_usage();
|
print_usage();
|
||||||
p = atoi(argv[i + 1]);
|
p = atoi(argv[i + 1]);
|
||||||
if(!strcmp(argv[i], "port"))
|
if (!strcmp(argv[i], "port")) {
|
||||||
{
|
|
||||||
cport = p;
|
cport = p;
|
||||||
} else if(!strcmp(argv[i], "vlan"))
|
} else if (!strcmp(argv[i], "vlan")) {
|
||||||
{
|
|
||||||
cvlan = p;
|
cvlan = p;
|
||||||
} else if(!strcmp(argv[i], "set"))
|
} else if (!strcmp(argv[i], "set")) {
|
||||||
{
|
|
||||||
if(argc <= i + 1)
|
if(argc <= i + 1)
|
||||||
print_usage();
|
print_usage();
|
||||||
cmd = SET;
|
cmd = SET;
|
||||||
@ -134,11 +164,16 @@ int main(int argc, char **argv)
|
|||||||
else
|
else
|
||||||
cvalue = NULL;
|
cvalue = NULL;
|
||||||
i++;
|
i++;
|
||||||
} else if(!strcmp(argv[i], "get"))
|
} else if (!strcmp(argv[i], "get")) {
|
||||||
{
|
|
||||||
cmd = GET;
|
cmd = GET;
|
||||||
ckey = argv[i + 1];
|
ckey = argv[i + 1];
|
||||||
} else{
|
} else if (!strcmp(argv[i], "load")) {
|
||||||
|
if ((cport >= 0) || (cvlan >= 0))
|
||||||
|
print_usage();
|
||||||
|
|
||||||
|
ckey = argv[i + 1];
|
||||||
|
cmd = LOAD;
|
||||||
|
} else {
|
||||||
print_usage();
|
print_usage();
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
@ -163,17 +198,19 @@ int main(int argc, char **argv)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cport > -1)
|
if (cmd != LOAD) {
|
||||||
a = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_PORT, ckey);
|
if(cport > -1)
|
||||||
else if(cvlan > -1)
|
a = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_PORT, ckey);
|
||||||
a = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_VLAN, ckey);
|
else if(cvlan > -1)
|
||||||
else
|
a = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_VLAN, ckey);
|
||||||
a = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_GLOBAL, ckey);
|
else
|
||||||
|
a = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_GLOBAL, ckey);
|
||||||
|
|
||||||
if(!a)
|
if(!a)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Unknown attribute \"%s\"\n", ckey);
|
fprintf(stderr, "Unknown attribute \"%s\"\n", ckey);
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(cmd)
|
switch(cmd)
|
||||||
@ -183,38 +220,10 @@ int main(int argc, char **argv)
|
|||||||
(cvalue == NULL))
|
(cvalue == NULL))
|
||||||
print_usage();
|
print_usage();
|
||||||
|
|
||||||
switch(a->type) {
|
|
||||||
case SWITCH_TYPE_INT:
|
|
||||||
val.value.i = atoi(cvalue);
|
|
||||||
break;
|
|
||||||
case SWITCH_TYPE_STRING:
|
|
||||||
val.value.s = cvalue;
|
|
||||||
break;
|
|
||||||
case SWITCH_TYPE_PORTS:
|
|
||||||
val.len = 0;
|
|
||||||
while(cvalue && *cvalue)
|
|
||||||
{
|
|
||||||
ports[val.len].flags = 0;
|
|
||||||
ports[val.len].id = strtol(cvalue, &cvalue, 10);
|
|
||||||
while(*cvalue && !isspace(*cvalue)) {
|
|
||||||
if (*cvalue == 't')
|
|
||||||
ports[val.len].flags |= SWLIB_PORT_FLAG_TAGGED;
|
|
||||||
cvalue++;
|
|
||||||
}
|
|
||||||
if (*cvalue)
|
|
||||||
cvalue++;
|
|
||||||
val.len++;
|
|
||||||
}
|
|
||||||
val.value.ports = ports;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(cvlan > -1)
|
if(cvlan > -1)
|
||||||
val.port_vlan = cvlan;
|
cport = cvlan;
|
||||||
if(cport > -1)
|
|
||||||
val.port_vlan = cport;
|
if(swlib_set_attr_string(dev, a, cport, cvalue) < 0)
|
||||||
if(swlib_set_attr(dev, a, &val) < 0)
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "failed\n");
|
fprintf(stderr, "failed\n");
|
||||||
retval = -1;
|
retval = -1;
|
||||||
@ -245,6 +254,10 @@ int main(int argc, char **argv)
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case LOAD:
|
||||||
|
swconfig_load_uci(dev, ckey);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -343,6 +343,49 @@ swlib_set_attr(struct switch_dev *dev, struct switch_attr *attr, struct switch_v
|
|||||||
return swlib_call(cmd, NULL, send_attr_val, val);
|
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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
if (*ptr)
|
||||||
|
ptr++;
|
||||||
|
val.len++;
|
||||||
|
}
|
||||||
|
val.value.ports = ports;
|
||||||
|
break;
|
||||||
|
case SWITCH_TYPE_NOVAL:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return swlib_set_attr(dev, a, &val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct attrlist_arg {
|
struct attrlist_arg {
|
||||||
int id;
|
int id;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* swlib.h: Switch configuration API (user space part)
|
* swlib.h: Switch configuration API (user space part)
|
||||||
*
|
*
|
||||||
* Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
|
* Copyright (C) 2008-2009 Felix Fietkau <nbd@openwrt.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
@ -110,6 +110,7 @@ struct switch_dev;
|
|||||||
struct switch_attr;
|
struct switch_attr;
|
||||||
struct switch_port;
|
struct switch_port;
|
||||||
struct switch_val;
|
struct switch_val;
|
||||||
|
struct uci_package;
|
||||||
|
|
||||||
struct switch_dev {
|
struct switch_dev {
|
||||||
int id;
|
int id;
|
||||||
@ -199,6 +200,17 @@ struct switch_attr *swlib_lookup_attr(struct switch_dev *dev,
|
|||||||
int swlib_set_attr(struct switch_dev *dev, struct switch_attr *attr,
|
int swlib_set_attr(struct switch_dev *dev, struct switch_attr *attr,
|
||||||
struct switch_val *val);
|
struct switch_val *val);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* swlib_set_attr_string: set the value for an attribute with type conversion
|
||||||
|
* @dev: switch device struct
|
||||||
|
* @attr: switch attribute struct
|
||||||
|
* @port_vlan: port or vlan (if applicable)
|
||||||
|
* @str: string value
|
||||||
|
* returns 0 on success
|
||||||
|
*/
|
||||||
|
int swlib_set_attr_string(struct switch_dev *dev, struct switch_attr *attr,
|
||||||
|
int port_vlan, const char *str);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* swlib_get_attr: get the value for an attribute
|
* swlib_get_attr: get the value for an attribute
|
||||||
* @dev: switch device struct
|
* @dev: switch device struct
|
||||||
@ -210,4 +222,11 @@ int swlib_set_attr(struct switch_dev *dev, struct switch_attr *attr,
|
|||||||
int swlib_get_attr(struct switch_dev *dev, struct switch_attr *attr,
|
int swlib_get_attr(struct switch_dev *dev, struct switch_attr *attr,
|
||||||
struct switch_val *val);
|
struct switch_val *val);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* swlib_apply_from_uci: set up the switch from a uci configuration
|
||||||
|
* @dev: switch device struct
|
||||||
|
* @p: uci package which contains the desired global config
|
||||||
|
*/
|
||||||
|
int swlib_apply_from_uci(struct switch_dev *dev, struct uci_package *p);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
224
package/swconfig/src/uci.c
Normal file
224
package/swconfig/src/uci.c
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
/*
|
||||||
|
* uci.c: UCI binding for the switch configuration utility
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* version 2 as published by the Free Software Foundatio.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <uci.h>
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/netlink.h>
|
||||||
|
#include <linux/genetlink.h>
|
||||||
|
#include <netlink/netlink.h>
|
||||||
|
#include <netlink/genl/genl.h>
|
||||||
|
#include <netlink/genl/ctrl.h>
|
||||||
|
#include <linux/switch.h>
|
||||||
|
#include "swlib.h"
|
||||||
|
|
||||||
|
#ifndef ARRAY_SIZE
|
||||||
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct swlib_setting {
|
||||||
|
struct switch_attr *attr;
|
||||||
|
const char *name;
|
||||||
|
int port_vlan;
|
||||||
|
const char *val;
|
||||||
|
struct swlib_setting *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct swlib_setting early_settings[] = {
|
||||||
|
{ .name = "reset" },
|
||||||
|
{ .name = "enable_vlan" },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct swlib_setting *settings;
|
||||||
|
static struct swlib_setting **head;
|
||||||
|
|
||||||
|
static int
|
||||||
|
swlib_map_settings(struct switch_dev *dev, int type, int port_vlan, struct uci_section *s)
|
||||||
|
{
|
||||||
|
struct swlib_setting *setting;
|
||||||
|
struct switch_attr *attr;
|
||||||
|
struct uci_element *e;
|
||||||
|
struct uci_option *o;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
uci_foreach_element(&s->options, e) {
|
||||||
|
o = uci_to_option(e);
|
||||||
|
|
||||||
|
if (o->type != UCI_TYPE_STRING)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!strcmp(e->name, "device"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* map early settings */
|
||||||
|
if (type == SWLIB_ATTR_GROUP_GLOBAL) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(early_settings); i++) {
|
||||||
|
if (strcmp(e->name, early_settings[i].name) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
early_settings[i].val = o->v.string;
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
attr = swlib_lookup_attr(dev, type, e->name);
|
||||||
|
if (!attr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
setting = malloc(sizeof(struct swlib_setting));
|
||||||
|
memset(setting, 0, sizeof(struct swlib_setting));
|
||||||
|
setting->attr = attr;
|
||||||
|
setting->port_vlan = port_vlan;
|
||||||
|
setting->val = o->v.string;
|
||||||
|
*head = setting;
|
||||||
|
head = &setting->next;
|
||||||
|
skip:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int swlib_apply_from_uci(struct switch_dev *dev, struct uci_package *p)
|
||||||
|
{
|
||||||
|
struct switch_attr *attr;
|
||||||
|
struct uci_context *ctx = p->ctx;
|
||||||
|
struct uci_element *e;
|
||||||
|
struct uci_section *s;
|
||||||
|
struct uci_option *o;
|
||||||
|
struct switch_val val;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
settings = NULL;
|
||||||
|
head = &settings;
|
||||||
|
|
||||||
|
uci_foreach_element(&p->sections, e) {
|
||||||
|
s = uci_to_section(e);
|
||||||
|
|
||||||
|
if (strcmp(s->type, "switch") != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strcmp(e->name, dev->dev_name) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* not found */
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
found:
|
||||||
|
/* look up available early options, which need to be taken care
|
||||||
|
* of in the correct order */
|
||||||
|
for (i = 0; i < ARRAY_SIZE(early_settings); i++) {
|
||||||
|
early_settings[i].attr = swlib_lookup_attr(dev,
|
||||||
|
SWLIB_ATTR_GROUP_GLOBAL, early_settings[i].name);
|
||||||
|
}
|
||||||
|
swlib_map_settings(dev, SWLIB_ATTR_GROUP_GLOBAL, 0, s);
|
||||||
|
|
||||||
|
/* look for port or vlan sections */
|
||||||
|
uci_foreach_element(&p->sections, e) {
|
||||||
|
struct uci_element *os;
|
||||||
|
s = uci_to_section(e);
|
||||||
|
|
||||||
|
if (!strcmp(s->type, "switch_port")) {
|
||||||
|
char *devn, *port, *port_err = NULL;
|
||||||
|
int port_n;
|
||||||
|
|
||||||
|
uci_foreach_element(&s->options, os) {
|
||||||
|
o = uci_to_option(os);
|
||||||
|
if (o->type != UCI_TYPE_STRING)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!strcmp(os->name, "device")) {
|
||||||
|
devn = o->v.string;
|
||||||
|
if (strcmp(devn, dev->dev_name) != 0)
|
||||||
|
devn = NULL;
|
||||||
|
} else if (!strcmp(os->name, "port")) {
|
||||||
|
port = o->v.string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!dev || !port || !port[0])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
port_n = strtoul(port, &port_err, 0);
|
||||||
|
if (port_err && port_err[0])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
swlib_map_settings(dev, SWLIB_ATTR_GROUP_PORT, port_n, s);
|
||||||
|
} else if (!strcmp(s->type, "switch_vlan")) {
|
||||||
|
char *devn, *vlan, *vlan_err = NULL;
|
||||||
|
int vlan_n;
|
||||||
|
|
||||||
|
uci_foreach_element(&s->options, os) {
|
||||||
|
o = uci_to_option(os);
|
||||||
|
if (o->type != UCI_TYPE_STRING)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!strcmp(os->name, "device")) {
|
||||||
|
devn = o->v.string;
|
||||||
|
if (strcmp(devn, dev->dev_name) != 0)
|
||||||
|
devn = NULL;
|
||||||
|
} else if (!strcmp(os->name, "vlan")) {
|
||||||
|
vlan = o->v.string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!dev || !vlan || !vlan[0])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
vlan_n = strtoul(vlan, &vlan_err, 0);
|
||||||
|
if (vlan_err && vlan_err[0])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
swlib_map_settings(dev, SWLIB_ATTR_GROUP_VLAN, vlan_n, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(early_settings); i++) {
|
||||||
|
struct swlib_setting *st = &early_settings[i];
|
||||||
|
if (!st->attr || !st->val)
|
||||||
|
continue;
|
||||||
|
swlib_set_attr_string(dev, st->attr, st->port_vlan, st->val);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
while (settings) {
|
||||||
|
struct swlib_setting *st = settings;
|
||||||
|
|
||||||
|
swlib_set_attr_string(dev, st->attr, st->port_vlan, st->val);
|
||||||
|
st = st->next;
|
||||||
|
free(settings);
|
||||||
|
settings = st;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Apply the config */
|
||||||
|
attr = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_GLOBAL, "apply");
|
||||||
|
if (!attr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
memset(&val, 0, sizeof(val));
|
||||||
|
swlib_set_attr(dev, attr, &val);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user