Ticket refs #13739: icwmp: adapt to new way of creating VLANs

This commit is contained in:
Feten Besbes 2018-02-26 09:50:57 +01:00
parent 61efda6831
commit 5585bed079
6 changed files with 464 additions and 274 deletions

View file

@ -131,6 +131,7 @@ int reset_wlan(struct uci_section *s);
int get_cfg_layer2idx(char *pack, char *section_type, char *option, int shift);
int wan_remove_dev_interface(struct uci_section *interface_setion, char *dev);
int filter_lan_device_interface(struct uci_section *s, void *v);
void remove_vlan_from_bridge_interface(char *bridge_key, struct uci_section *vb);
void update_remove_vlan_from_bridge_interface(char *bridge_key, struct uci_section *vb);
int filter_lan_ip_interface(struct uci_section *ss, void *v);
void remove_interface_from_ifname(char *iface, char *ifname, char *new_ifname);

View file

@ -91,19 +91,33 @@ int browselayer2_availableinterfaceInst(struct dmctx *dmctx, DMNODE *parent_node
int i = 0;
char *oface, *phy_interface, *ch_ptr, *saveptr, *waninstance = NULL, *phy_interface_dup = NULL;
char *base_ifname, *available_inst = NULL;
struct uci_section *wifi_s , *wan_s, *ai_s;
struct uci_section *wifi_s , *wan_s, *ai_s, *s;
char *instance_last = NULL;
struct args_layer2 curr_args = {0};
#ifndef EX400
for (i=0; i<3; i++) {
uci_foreach_sections(wan_interface_tab[i].package, wan_interface_tab[i].section, wan_s) {
waninstance = update_instance(wan_s, waninstance, "waninstance");
dmasprintf(&oface, "%s%cWANDevice%c%s%cWANConnectionDevice%c%s%c", DMROOT, dm_delim, dm_delim, wan_interface_tab[i].instance, dm_delim, dm_delim, waninstance, dm_delim); // MEM WILL BE FREED IN DMMEMCLEAN
dmuci_get_value_by_section_string(wan_s, "device", &base_ifname);
ai_s = update_availableinterface_list(dmctx, base_ifname, &available_inst, &instance_last);
init_args_layer2(&curr_args, ai_s, NULL, instance_last, NULL, "WANInterface", oface);
if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_args, available_inst) == DM_STOP)
goto end;
if(i==0){
uci_foreach_sections("ports", "ethport", wan_s) {
if(!strcmp(wan_s->e.name, "WAN")){
waninstance = update_instance(wan_s, waninstance, "waninstance");
dmasprintf(&oface, "%s%cWANDevice%c%s%cWANConnectionDevice%c%s%c", DMROOT, dm_delim, dm_delim, wan_interface_tab[i].instance, dm_delim, dm_delim, waninstance, dm_delim); // MEM WILL BE FREED IN DMMEMCLEAN
dmuci_get_value_by_section_string(wan_s, "ifname", &base_ifname);
ai_s = update_availableinterface_list(dmctx, base_ifname, &available_inst, &instance_last);
init_args_layer2(&curr_args, ai_s, NULL, instance_last, NULL, "WANInterface", oface);
if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_args, available_inst) == DM_STOP)
goto end;
}
}
}else{
uci_foreach_sections(wan_interface_tab[i].package, wan_interface_tab[i].section, wan_s) {
waninstance = update_instance(wan_s, waninstance, "waninstance");
dmasprintf(&oface, "%s%cWANDevice%c%s%cWANConnectionDevice%c%s%c", DMROOT, dm_delim, dm_delim, wan_interface_tab[i].instance, dm_delim, dm_delim, waninstance, dm_delim); // MEM WILL BE FREED IN DMMEMCLEAN
dmuci_get_value_by_section_string(wan_s, "device", &base_ifname);
ai_s = update_availableinterface_list(dmctx, base_ifname, &available_inst, &instance_last);
init_args_layer2(&curr_args, ai_s, NULL, instance_last, NULL, "WANInterface", oface);
if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_args, available_inst) == DM_STOP)
goto end;
}
}
}
#else
@ -179,16 +193,20 @@ int browselayer2_markingInst(struct dmctx *dmctx, DMNODE *parent_node, void *pre
int browsebridge_vlanInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
{
struct uci_section *ss = NULL;
char *vlan_instance = NULL, *vlan_instance_last = NULL;
char *vlan_instance = NULL, *vlan_instance_last = NULL, *is_lan=NULL;
struct args_layer2 *curr_args = (struct args_layer2 *)prev_data;
update_bridge_all_vlan_config_bybridge(dmctx, curr_args);
uci_path_foreach_option_eq(icwmpd, "dmmap", "vlan_bridge", "bridgekey", curr_args->bridge_instance, ss) {
vlan_instance = handle_update_instance(2, dmctx, &vlan_instance_last, update_instance_alias, 3, ss, "vlan_instance", "vlan_alias");
init_args_layer2_vlan(curr_args, ss);
if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)curr_args, vlan_instance) == DM_STOP)
break;
dmuci_get_value_by_section_string(curr_args->layer2section, "is_lan", &is_lan);
if(is_lan==NULL || strcmp(is_lan, "1")!=0){
update_bridge_all_vlan_config_bybridge(dmctx, curr_args);
uci_path_foreach_option_eq(icwmpd, "dmmap", "vlan_bridge", "bridgekey", curr_args->bridge_instance, ss){
vlan_instance = handle_update_instance(2, dmctx, &vlan_instance_last, update_instance_alias, 3, ss, "vlan_instance", "vlan_alias");
init_args_layer2_vlan(curr_args, ss);
if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)curr_args, vlan_instance) == DM_STOP)
goto end;
}
}
end:
return 0;
}
@ -280,120 +298,123 @@ char *layer2_get_last_section_instance(char *package, char *section, char *opt_i
return inst;
}
int update_bridge_vlan_config(char *vid, char *bridge_key)
int update_bridge_vlan_config(char *vid, char *bridge_key, char* ifname)
{
struct uci_section *s, *ss;
char *add_value, *instance, *p;
char *name;
uci_path_foreach_option_eq(icwmpd, "dmmap", "vlan_bridge", "vid", vid, s)
{
return 0;
}
instance = get_last_instance_lev2(DMMAP, "vlan_bridge", "vlan_instance", "bridgekey", bridge_key);
instance = get_last_instance_lev2(DMMAP, "vlan_bridge", "vlan_instance","bridgekey", bridge_key);
DMUCI_ADD_SECTION(icwmpd, "dmmap", "vlan_bridge", &ss, &add_value);
instance = update_instance_icwmpd(ss, instance, "vlan_instance");
dmasprintf(&name, "vlan_%s.%s", bridge_key, instance);
DMUCI_SET_VALUE_BY_SECTION(icwmpd, ss, "bridgekey", bridge_key);
DMUCI_SET_VALUE_BY_SECTION(icwmpd, ss, "name", name);
DMUCI_SET_VALUE_BY_SECTION(icwmpd, ss, "vid", vid);
DMUCI_SET_VALUE_BY_SECTION(icwmpd, ss, "ifname", ifname);
dmfree(name);
return 0;
}
int update_bridge_all_vlan_config_bybridge(struct dmctx *ctx, struct args_layer2 *curr_args)
{
char *ifname, *ifname_tmp, *pch, *spch, *vid;
char *ifname, *pch, *spch, *vid, *type;
struct uci_section *s, *ss;
dmuci_get_value_by_section_string(curr_args->layer2section, "ifname", &ifname);
ifname_tmp = dmstrdup(ifname);
for (pch = strtok_r(ifname_tmp, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch)) {
if (strncmp(pch, wan_baseifname, 4) == 0
|| strncmp(pch, "ptm", 3) == 0
|| strncmp(pch, "atm", 3) == 0) {
uci_foreach_option_eq("layer2_interface_vlan", "vlan_interface", "ifname", pch, s) {
vid = strchr(pch, '.') + 1;
update_bridge_vlan_config(vid, curr_args->bridge_instance);
break;
uci_foreach_sections("network", "device", s) {
if(!s)
break;
dmuci_get_value_by_section_string(s, "ifname", &ifname);
if (strncmp(ifname, wan_baseifname, 4) == 0 || strncmp(ifname, "ptm", 3) == 0 || strncmp(ifname, "atm", 3) == 0) {
dmuci_get_value_by_section_string(s, "type", &type);
if (strcmp(type, "untagged")) {
dmuci_get_value_by_section_string(s, "vid", &vid);
update_bridge_vlan_config(vid, curr_args->bridge_instance, ifname);
}
}
}
dmfree(ifname_tmp);
return 0;
}
void update_add_vlan_interfaces(char *bridge_key, char *vid)
{
char *baseifname, *add_value;
char baseifname_dup[16];
char *p;
char *ifname, *add_value, *dev_name, *v_name;
bool found;
struct uci_section *s, *vlan_interface_s, *vi_sec;
uci_path_foreach_option_eq(icwmpd, "dmmap", "marking-bridge", "bridgekey", bridge_key, s) {
dmuci_get_value_by_section_string(s, "baseifname", &baseifname);
p = baseifname_dup;
dmstrappendstr(p, baseifname);
dmstrappendchr(p, '.');
dmstrappendstr(p, vid);
dmstrappendend(p);
uci_path_foreach_option_eq(icwmpd, "dmmap", "vlan_bridge", "bridgekey", bridge_key, s)
{
dmuci_get_value_by_section_string(s, "ifname", &ifname);
found = false;
uci_foreach_option_eq("layer2_interface_vlan", "vlan_interface", "ifname", baseifname_dup, vi_sec) {
uci_foreach_option_eq("network", "device", "name", ifname, vi_sec) {
found = true;
break;
}
if(found)
if (found)
continue;
if(strncmp(baseifname, wan_baseifname, 4) == 0 ||
strncmp(baseifname, "ptm", 3) == 0 ||
strncmp(baseifname, "atm", 3) == 0) {
dmuci_add_section("layer2_interface_vlan", "vlan_interface", &vlan_interface_s, &add_value);
dmuci_set_value_by_section(vlan_interface_s, "baseifname", baseifname);
dmuci_set_value_by_section(vlan_interface_s, "bridge", bridge_key);
dmuci_set_value_by_section(vlan_interface_s, "ifname", baseifname_dup);
dmuci_set_value_by_section(vlan_interface_s, "name", baseifname_dup);
dmuci_set_value_by_section(vlan_interface_s, "vlan8021q", vid);
if (strncmp(ifname, wan_baseifname, 4) == 0
|| strncmp(ifname, "ptm", 3) == 0
|| strncmp(ifname, "atm", 3) == 0) {
dmasprintf(&v_name, "vlan_%s.%s", bridge_key, vid);
dmasprintf(&dev_name, "%s.%s", ifname, vid);
//Add new section to network.device
dmuci_set_value("network", v_name, "", "device");
dmuci_set_value("network", v_name, "priority", "0");
dmuci_set_value("network", v_name, "type", "8021q");
dmuci_set_value("network", v_name, "vid", vid);
dmuci_set_value("network", v_name, "ifname", wan_baseifname);
dmuci_set_value("network", v_name, "name", dev_name);
return;
}
}
}
void update_remove_vlan_interface(char *bridge_key, char* vid)
{
char *ifname, *vid_section;
struct uci_section *s, *vi_sec = NULL;
uci_path_foreach_option_eq(icwmpd, "dmmap", "vlan_bridge", "bridgekey", bridge_key, s){
dmuci_get_value_by_section_string(s, "ifname", &ifname);
uci_foreach_option_eq("network", "device", "name", ifname, vi_sec)
{
if (strncmp(ifname, wan_baseifname, 4) == 0
|| strncmp(ifname, "ptm", 3) == 0
|| strncmp(ifname, "atm", 3) == 0) {
dmuci_get_value_by_section_string(vi_sec, "vid", &vid_section);
if (strcmp(vid_section, vid) == 0) {
dmuci_delete_by_section(vi_sec, NULL, NULL);
return;
}
}
}
}
return;
}
void update_add_vlan_to_bridge_interface(char *bridge_key, struct uci_section *dmmap_s)
{
char *vid, *ifname, *baseifname;
char *ifname, *baseifname;
struct uci_section *interface_s, *marking_bridge_s;
char baseifname_dup[16];
char *p;
char ifname_dup[128];
char *ptr;
dmuci_get_value_by_section_string(dmmap_s, "vid", &vid);
if(vid[0] == '\0')
return ;
uci_foreach_option_eq("network", "interface", "bridge_instance", bridge_key, interface_s)
{
uci_foreach_option_eq("network", "interface", "bridge_instance", bridge_key, interface_s) {
dmuci_get_value_by_section_string(interface_s, "ifname", &ifname);
ifname_dup[0] = '\0';
ptr = ifname_dup;
dmstrappendstr(ptr, ifname);
dmstrappendend(ptr);
uci_path_foreach_option_eq(icwmpd, "dmmap", "marking-bridge", "bridgekey", bridge_key, marking_bridge_s)
{
dmuci_get_value_by_section_string(marking_bridge_s, "baseifname", &baseifname);
uci_path_foreach_option_eq(icwmpd, "dmmap", "vlan_bridge", "bridgekey", bridge_key, marking_bridge_s) {
dmuci_get_value_by_section_string(marking_bridge_s, "ifname", &baseifname);
if (strncmp(baseifname, wan_baseifname, 4) == 0
|| strncmp(baseifname, "ptm", 3) == 0
|| strncmp(baseifname, "atm", 3) == 0) {
p = baseifname_dup;
dmstrappendstr(p, baseifname);
dmstrappendchr(p, '.');
dmstrappendstr(p, vid);
dmstrappendend(p);
if (is_strword_in_optionvalue(ifname_dup, baseifname_dup)) continue;
if (ifname_dup[0] != '\0')
dmstrappendchr(ptr, ' ');
dmstrappendstr(ptr, baseifname_dup);
if (is_strword_in_optionvalue(ifname_dup, baseifname)) continue;
if (ifname_dup[0] != '\0') dmstrappendchr(ptr, ' ');
dmstrappendstr(ptr, baseifname);
dmstrappendend(ptr);
}
}
@ -694,10 +715,35 @@ int set_marking_interface_key_sub(char *refparam, struct dmctx *ctx, void *data,
return 0;
}
int get_bridge_vlan_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
static int is_bridge_vlan_enabled(char *bkey, char* ifname) {
struct uci_section *br_sec;
char *br_ifname;
uci_foreach_option_eq("network", "interface", "bridge_instance", bkey, br_sec) {
dmuci_get_value_by_section_string(br_sec, "ifname", &br_ifname);
if (is_strword_in_optionvalue(br_ifname, ifname))
return 1;
}
return 0;
}
int get_bridge_vlan_enable(char *refparam, struct dmctx *ctx, void *data,char *instance, char **value)
{
struct args_layer2 *args = (struct args_layer2 *)data;
dmuci_get_value_by_section_string(args->layer2sectionlev2, "enable", value);
char *ifname, *brkey, *vid, *str;
struct args_layer2 *args = (struct args_layer2 *) data;
struct uci_section *s;
int is_enabled = 0;
dmuci_get_value_by_section_string(args->layer2sectionlev2, "ifname", &ifname);
dmuci_get_value_by_section_string(args->layer2sectionlev2, "vid", &vid);
dmasprintf(&str, "%s.%s", ifname, vid);
dmuci_get_value_by_section_string(args->layer2sectionlev2, "bridgekey", &brkey);
is_enabled = is_bridge_vlan_enabled(brkey, str);
if(is_enabled){
*value = "1";
return 0;
}
*value = "0";
return 0;
}
@ -717,28 +763,68 @@ int set_bridge_vlan_enable(char *refparam, struct dmctx *ctx, void *data, char *
return 0;
}
int update_br_vlan_ifname(struct uci_section* br_sec, char* ifname, char* baseifname, int status)
{
char ifname_dup[128], *ptr, *start, *end;
int pos=0;
ptr = ifname_dup;
dmstrappendstr(ptr, ifname);
dmstrappendend(ptr);
if(status!=0){
if (is_strword_in_optionvalue(ifname_dup, baseifname)) return 0;
if (ifname_dup[0] != '\0') dmstrappendchr(ptr, ' ');
dmstrappendstr(ptr, baseifname);
dmstrappendend(ptr);
}else{
if (is_strword_in_optionvalue(ifname_dup, baseifname)){
start = strstr(ifname_dup, baseifname);
end = start + strlen(baseifname);
if(start != ifname_dup){
start--;
pos=1;
}
memmove(start, start + strlen(baseifname)+pos, strlen(end) + 1);
}
}
dmuci_set_value_by_section(br_sec, "ifname", ifname_dup);
return 0;
}
int set_bridge_vlan_enable_sub(char *refparam, struct dmctx *ctx, void *data, char *instance, bool b)
{
char *value, *vid, *bkey, *cval;
struct uci_section *vb;
bool bcval;
char *value, *vid, *bkey, *ifname, *baseifname, ifname_dup[128], *ptr, *br_ifname;
struct uci_section *vb, *br_sec;
int is_enabled;
struct args_layer2 *args = (struct args_layer2 *)data;
vb = args->layer2sectionlev2;
vb = args->layer2sectionlev2; //vb : /etc/icwmpd/dmmap
dmuci_get_value_by_section_string(vb, "ifname", &ifname);
dmuci_get_value_by_section_string(vb, "vid", &vid);
dmuci_get_value_by_section_string(vb, "bridgekey", &bkey);
dmuci_get_value_by_section_string(vb, "enable", &cval);
string_to_bool(cval, &bcval);
if (b && !bcval) {
DMUCI_SET_VALUE_BY_SECTION(icwmpd, vb, "enable", "1");
if (vid[0] == '\0') return 0;
update_add_vlan_interfaces(bkey, vid);
update_add_vlan_to_bridge_interface(bkey, vb);
dmasprintf(&baseifname, "%s.%s",ifname, vid);
is_enabled = is_bridge_vlan_enabled(bkey, baseifname);
uci_foreach_option_eq("network", "interface", "bridge_instance", bkey, br_sec) {
if(br_sec)
break;
}
else if (!b && bcval) {
DMUCI_SET_VALUE_BY_SECTION(icwmpd, vb, "enable", "0");
if (vid[0] == '\0') return 0;
update_remove_vlan_from_bridge_interface(bkey, vb);
dmuci_get_value_by_section_string(br_sec, "ifname", &br_ifname);
if (b && !is_enabled) {
if (vid[0] == '\0')
return 0;
ifname_dup[0] = '\0';
ptr = ifname_dup;
dmstrappendstr(ptr, br_ifname);
if (ifname_dup[0] != '\0') dmstrappendchr(ptr, ' ');
dmstrappendstr(ptr, baseifname);
dmstrappendend(ptr);
dmuci_set_value_by_section(br_sec, "ifname", ifname_dup);
}
else if (!b && is_enabled) {
if (vid[0] == '\0')
return 0;
update_br_vlan_ifname(br_sec, br_ifname, baseifname, 0);
}
return 0;
}
@ -773,7 +859,7 @@ int get_bridge_vlan_vid(char *refparam, struct dmctx *ctx, void *data, char *ins
int set_bridge_vlan_vid(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
struct uci_section *vb;
struct uci_section *vb, *br_sec;
struct args_layer2 *args;
switch (action) {
@ -782,29 +868,51 @@ int set_bridge_vlan_vid(char *refparam, struct dmctx *ctx, void *data, char *ins
case VALUESET:
args = (struct args_layer2 *)data;
vb = args->layer2sectionlev2;
set_bridge_vlan_vid_sub(vb, value);
br_sec = args->layer2section;
set_bridge_vlan_vid_sub(br_sec, vb, value);
return 0;
}
return 0;
}
int set_bridge_vlan_vid_sub(struct uci_section *vb, char *value)
int set_bridge_vlan_vid_sub(struct uci_section *br_sec, struct uci_section *vb, char *value)
{
char *enable, *bkey, *cval;
char *enable, *bkey, *cval, *ifname, *baseifname, *br_ifname, *new_baseifname;
struct uci_section *s, *vs;
int v;
int is_enabled;
v=atoi(value);
if(v==1 ||v==0)
return 0; //
uci_path_foreach_option_eq(icwmpd, "dmmap", "vlan_bridge", "vid", value, s){
if(s)
return 0; //UID
}
dmuci_get_value_by_section_string(vb, "vid", &cval);
if (strcmp(cval, value) == 0) return 0;
dmuci_get_value_by_section_string(vb, "enable", &enable);
if (enable[0] == '1') {
dmuci_get_value_by_section_string(vb, "bridgekey", &bkey);
update_remove_vlan_from_bridge_interface(bkey, vb);
DMUCI_SET_VALUE_BY_SECTION(icwmpd, vb, "vid", value);
update_add_vlan_interfaces(bkey, value);
update_add_vlan_to_bridge_interface(bkey, vb);
dmuci_get_value_by_section_string(vb, "ifname", &ifname);
dmuci_get_value_by_section_string(vb, "bridgekey", &bkey);
dmasprintf(&baseifname, "%s.%s", ifname, cval);
dmasprintf(&new_baseifname, "%s.%s", ifname, value);
is_enabled = is_bridge_vlan_enabled(bkey, baseifname);
uci_foreach_option_eq("network", "device", "vid", cval, vs){
if(vs)
break;
}
if (is_enabled) {
dmuci_get_value_by_section_string(br_sec, "ifname", &br_ifname);//update interfaces ifname
update_br_vlan_ifname(br_sec, br_ifname, baseifname, 0);
dmuci_get_value_by_section_string(br_sec, "ifname", &br_ifname);
update_br_vlan_ifname(br_sec, br_ifname, new_baseifname, 1);
DMUCI_SET_VALUE_BY_SECTION(icwmpd, vb, "vid", value); //update dmmap vid
dmuci_set_value_by_section(vs, "vid", value); //update network device vid, name
dmuci_set_value_by_section(vs, "name", new_baseifname);
}
else {
DMUCI_SET_VALUE_BY_SECTION(icwmpd, vb, "vid", value);
dmuci_set_value_by_section(vs, "vid", value); //update network device vid, name
dmuci_set_value_by_section(vs, "name", new_baseifname);
}
return 0;
}
@ -903,9 +1011,10 @@ int set_bridge_vlanid(char *refparam, struct dmctx *ctx, void *data, char *insta
int set_bridge_vlanid_sub(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value)
{
char *add_value, *name, *instce;
struct uci_section *s = NULL, *vb;;
char *add_value, *name, *instce, *baseifname, *devname;
struct uci_section *s = NULL, *vb;
struct args_layer2 *args = (struct args_layer2 *)data;
struct uci_section *br_sec = args->layer2section;
uci_path_foreach_option_eq(icwmpd, "dmmap", "vlan_bridge", "bridgekey", args->bridge_instance, s)
{
@ -916,14 +1025,25 @@ int set_bridge_vlanid_sub(char *refparam, struct dmctx *ctx, void *data, char *i
DMUCI_ADD_SECTION(icwmpd, "dmmap", "vlan_bridge", &vb, &add_value);
instce = update_instance_icwmpd(vb, instce, "vlan_instance");
dmasprintf(&name, "vlan_%s.%s", args->bridge_instance, instce);
dmasprintf(&devname, "vlan_%s_%s", args->bridge_instance, instce);
dmasprintf(&baseifname, "%s.%s", wan_baseifname, value);
DMUCI_SET_VALUE_BY_SECTION(icwmpd, vb, "bridgekey", args->bridge_instance);
DMUCI_SET_VALUE_BY_SECTION(icwmpd, vb, "name", name);
DMUCI_SET_VALUE_BY_SECTION(icwmpd, vb, "enable", "0");
DMUCI_SET_VALUE_BY_SECTION(icwmpd, vb, "vid", value);
DMUCI_SET_VALUE_BY_SECTION(icwmpd, vb, "ifname", wan_baseifname);
dmuci_set_value("network", devname, "", "device");
dmuci_set_value("network", devname, "priority", "0");
dmuci_set_value("network", devname, "type", "8021q");
dmuci_set_value("network", devname, "vid", value);
dmuci_set_value("network", devname, "ifname", wan_baseifname);
dmuci_set_value("network", devname, "name", baseifname);
dmfree(name);
dmfree(devname);
dmfree(baseifname);
}
else {
set_bridge_vlan_vid_sub(s, value);
set_bridge_vlan_vid_sub(br_sec,s, value);
}
return 0;
}
@ -1152,30 +1272,47 @@ int delete_layer2bridging_marking(char *refparam, struct dmctx *ctx, void *data,
int add_layer2bridging_bridge_vlan(char *refparam, struct dmctx *ctx, void *data, char **instance)
{
struct args_layer2 *args_bridge = (struct args_layer2 *)data;
char *value, *last_instance ;
struct uci_section *vlan_s;
char *value, *v_value, *last_instance, *vid_n, *new_vid, *dev_name, *s_name ;
struct uci_section *vlan_s, *s, *ss;
char buf[16];
char *v_name = buf;
int v1, v2=2;
last_instance = get_last_instance_lev2(DMMAP, "vlan_bridge", "vlan_instance", "bridgekey", args_bridge->bridge_instance);
//Add new section to icwmpd.dmmap.vlan_bridge
DMUCI_ADD_SECTION(icwmpd, "dmmap", "vlan_bridge", &vlan_s, &value);
*instance = update_instance_icwmpd(vlan_s, last_instance, "vlan_instance");
dmasprintf(&v_name, "vlan_%s.%s", args_bridge->bridge_instance, *instance);
dmasprintf(&s_name, "vlan_%s_%s", args_bridge->bridge_instance, *instance);
uci_foreach_sections("network", "device", s){
dmuci_get_value_by_section_string(s, "vid", &vid_n);
v1=atoi(vid_n);
if(v2 < v1)
v2=v1;
}
v2++;
dmasprintf(&new_vid, "%d", v2);
dmasprintf(&dev_name, "%s.%s", wan_baseifname, new_vid);
//Add new section to network.device
dmuci_set_value("network", s_name, "", "device");
dmuci_set_value("network", s_name, "priority", "0");
dmuci_set_value("network", s_name, "type", "8021q");
dmuci_set_value("network", s_name, "vid", new_vid);
dmuci_set_value("network", s_name, "ifname", wan_baseifname);
dmuci_set_value("network", s_name, "name", dev_name);
//Add new section to icwmpd.dmmap.vlan_bridge
DMUCI_SET_VALUE_BY_SECTION(icwmpd, vlan_s, "bridgekey", args_bridge->bridge_instance);
DMUCI_SET_VALUE_BY_SECTION(icwmpd, vlan_s, "enable", "0");
*instance = update_instance_icwmpd(vlan_s, last_instance, "vlan_instance");
dmstrappendstr(v_name, "vlan_");
dmstrappendstr(v_name, args_bridge->bridge_instance);
dmstrappendchr(v_name, '.');
dmstrappendstr(v_name, *instance);
dmstrappendend(v_name);
DMUCI_SET_VALUE_BY_SECTION(icwmpd, vlan_s, "name", v_name);
DMUCI_SET_VALUE_BY_SECTION(icwmpd, vlan_s, "ifname", wan_baseifname);
DMUCI_SET_VALUE_BY_SECTION(icwmpd, vlan_s, "vid", new_vid);
return 0;
}
int delete_layer2bridging_bridge_vlan(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action)
{
char *vid, *ifname;
char *vid, *ifname, *type;
char new_ifname[128];
struct uci_section *vlan_s, *prev_s = NULL ;
struct uci_section *vlan_s, *prev_s = NULL, *s ;
struct args_layer2 *args_bridge = (struct args_layer2 *)data;
switch (del_action) {
@ -1185,6 +1322,10 @@ int delete_layer2bridging_bridge_vlan(char *refparam, struct dmctx *ctx, void *d
remove_vid_interfaces_from_ifname(vid, ifname, new_ifname);
dmuci_set_value_by_section(args_bridge->layer2section, "ifname", new_ifname);
DMUCI_DELETE_BY_SECTION(icwmpd, args_bridge->layer2sectionlev2, NULL, NULL);
uci_foreach_option_eq("network", "device", "vid", vid, vlan_s) {
dmuci_delete_by_section(vlan_s, NULL, NULL);
break;
}
break;
case DEL_ALL:
uci_path_foreach_option_eq(icwmpd, "dmmap", "vlan_bridge", "bridgekey", args_bridge->bridge_instance, vlan_s) {
@ -1198,6 +1339,18 @@ int delete_layer2bridging_bridge_vlan(char *refparam, struct dmctx *ctx, void *d
}
if (prev_s != NULL)
DMUCI_DELETE_BY_SECTION(icwmpd, prev_s, NULL, NULL);
prev_s=NULL;
uci_foreach_sections("network", "device", s){
dmuci_get_value_by_section_string(s, "type", &type);
//If VLAN
if(strcmp(type, "untagged")){
if (prev_s != NULL)
dmuci_delete_by_section(prev_s, NULL, NULL);
prev_s = s;
}
}
if (prev_s != NULL)
dmuci_delete_by_section(prev_s, NULL, NULL);
break;
}
return 0;

View file

@ -85,9 +85,10 @@ int get_available_interface_key(char *refparam, struct dmctx *ctx, void *data, c
int get_interface_reference(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value);
int get_interfaces_type(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value);
char *layer2_get_last_section_instance(char *package, char *section, char *opt_inst);
int update_bridge_vlan_config(char *vid, char *bridge_key);
int update_bridge_vlan_config(char *vid, char *bridge_key, char* ifname);
int update_bridge_all_vlan_config_bybridge(struct dmctx *ctx, struct args_layer2 *curr_args);
void update_add_vlan_interfaces(char *bridge_key, char *vid);
void update_remove_vlan_interfaces(char *bridge_key, char *vid);
void update_add_vlan_to_bridge_interface(char *bridge_key, struct uci_section *dmmap_s);
int get_marking_bridge_reference(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value);
void get_baseifname_from_ifname(char *ifname, char *baseifname);
@ -97,5 +98,5 @@ int set_marking_alias(char *refparam, struct dmctx *ctx, void *data, char *insta
int get_brvlan_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value);
int set_brvlan_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action);
int get_marking_interface_key(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value);
int set_bridge_vlan_vid_sub(struct uci_section *vb, char *value);
int set_bridge_vlan_vid_sub(struct uci_section *br_sec, struct uci_section *vb, char *value);
#endif

View file

@ -263,20 +263,20 @@ inline int add_wvlan(char *baseifname, char *ifname, char *vid, char *prioprity,
struct uci_section *ss = NULL, *vlan_interface_s;
char *add_value;
uci_foreach_option_eq("layer2_interface_vlan", "vlan_interface", "wan_name", wan_name, ss) {
uci_foreach_option_eq("network", "device", "name", wan_name, ss) {
dmuci_set_value_by_section(ss, "wan_name", wan_name);
dmuci_set_value_by_section(ss, "baseifname", baseifname);
dmuci_set_value_by_section(ss, "ifname", ifname);
dmuci_set_value_by_section(ss, "vlan8021q", vid);
dmuci_set_value_by_section(ss, "vlan8021p", prioprity);
dmuci_set_value_by_section(ss, "ifname", baseifname);
dmuci_set_value_by_section(ss, "name", ifname);
dmuci_set_value_by_section(ss, "vid", vid);
dmuci_set_value_by_section(ss, "priority", prioprity);
return 0;
}
dmuci_add_section("layer2_interface_vlan", "vlan_interface", &vlan_interface_s, &add_value);
dmuci_set_value_by_section(vlan_interface_s, "wan_name", wan_name);
dmuci_set_value_by_section(vlan_interface_s, "baseifname", baseifname);
dmuci_set_value_by_section(vlan_interface_s, "ifname", ifname);
dmuci_set_value_by_section(vlan_interface_s, "vlan8021q", vid);
dmuci_set_value_by_section(vlan_interface_s, "vlan8021p", prioprity);
dmuci_add_section("network", "device", &vlan_interface_s, &add_value);
dmuci_set_value_by_section(ss, "type", "8021q");
dmuci_set_value_by_section(ss, "ifname", baseifname);
dmuci_set_value_by_section(ss, "name", ifname);
dmuci_set_value_by_section(ss, "vid", vid);
dmuci_set_value_by_section(ss, "priority", prioprity);
return 0;
}
@ -290,7 +290,7 @@ void set_bridge_layer2(struct dmctx *ctx, char *bridge, struct wanargs *wandcpro
for (pch = strtok_r(dup, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch))
{
if (atoi(pch + 5) > 1) {
uci_foreach_option_eq("layer2_interface_vlan", "vlan_interface", "ifname", pch, s)
uci_foreach_option_eq("network", "device", "ifname", pch, s)
{
dmuci_set_value_by_section(s, "bridge", bridge);
}
@ -1883,7 +1883,7 @@ int set_wan_ip_link_connection_vid(char *refparam, struct dmctx *ctx, void *data
struct uci_section *ss = NULL, *w_vlan, *s_last = NULL;
struct wanargs *wandcprotoargs = (struct wanargs *)data;
char *add_value, *ifname, *vid, *prio;
char *wan_name = section_name(wandcprotoargs->wancprotosection);
char *wan_name = section_name(wandcprotoargs->wancprotosection); //wanprotosection is dmmap wan_dev section
bool found = false;
char *p, *q, *wifname, *baseifname="", *type="";
char r_new_wifname[128] = "";
@ -1900,8 +1900,8 @@ int set_wan_ip_link_connection_vid(char *refparam, struct dmctx *ctx, void *data
dmuci_get_value_by_section_string(wandcprotoargs->wancprotosection, "type", &type);
if (ifname[0] != '\0')
{
uci_foreach_option_eq("layer2_interface_vlan", "vlan_interface", "wan_name", wan_name, ss) {
dmuci_get_value_by_section_string(ss, "vlan8021q", &vid);
uci_foreach_option_eq("network", "device", "name", ifname, ss) {
dmuci_get_value_by_section_string(ss, "vid", &vid);
if (strcmp(vid, value) == 0)
return 0;
dmuci_get_option_value_string("network", wan_name, "ifname", &wifname);
@ -1909,7 +1909,7 @@ int set_wan_ip_link_connection_vid(char *refparam, struct dmctx *ctx, void *data
return 0;
remove_vid_interfaces_from_ifname(vid, wifname, r_new_wifname);
sprintf(r1_new_wifname, "%s", r_new_wifname);
dmuci_get_value_by_section_string(ss, "baseifname", &baseifname);
dmuci_get_value_by_section_string(ss, "ifname", &baseifname);
if (strcmp(type, "bridge") != 0 || strcmp(value, "1") == 0)
{
sprintf(v1_baseifname, "%s.1", baseifname);
@ -1917,7 +1917,7 @@ int set_wan_ip_link_connection_vid(char *refparam, struct dmctx *ctx, void *data
}
p = a_new_wifname;
q = v_ifname;
dmuci_get_value_by_section_string(ss, "vlan8021q", &vid);
dmuci_get_value_by_section_string(ss, "vid", &vid);
dmstrappendstr(q, baseifname);
dmstrappendchr(q, '.');
dmstrappendstr(q, value);
@ -1927,8 +1927,8 @@ int set_wan_ip_link_connection_vid(char *refparam, struct dmctx *ctx, void *data
dmstrappendchr(p, ' ');
dmstrappendstr(p, r_new_wifname);
dmstrappendend(p);
dmuci_set_value_by_section(ss, "ifname", v_ifname);
dmuci_set_value_by_section(ss, "vlan8021q", value);
dmuci_set_value_by_section(ss, "name", v_ifname);
dmuci_set_value_by_section(ss, "vid", value);
dmuci_set_value_by_section(wandcprotoargs->wancprotosection, "ifname", a_new_wifname);
DMUCI_SET_VALUE(icwmpd, "dmmap", wan_name, "vid", value);
}
@ -1990,9 +1990,9 @@ int get_wan_ip_link_connection_vpriority(char *refparam, struct dmctx *ctx, void
}
return 0;
}
uci_foreach_option_eq("layer2_interface_vlan", "vlan_interface", "ifname", ifname, ss)
uci_foreach_option_eq("network", "device", "name", ifname, ss)
{
dmuci_get_value_by_section_string(ss, "vlan8021p", value);
dmuci_get_value_by_section_string(ss, "priority", value);
}
return 0;
}
@ -2016,9 +2016,9 @@ int set_wan_ip_link_connection_vpriority(char *refparam, struct dmctx *ctx, void
}
return 0;
}
uci_foreach_option_eq("layer2_interface_vlan", "vlan_interface", "ifname", ifname, ss)
uci_foreach_option_eq("network", "device", "name", ifname, ss)
{
dmuci_set_value_by_section(ss, "vlan8021p", value);
dmuci_set_value_by_section(ss, "priority", value);
}
return 0;
}
@ -2066,14 +2066,14 @@ int set_wan_ip_link_connection_layer2_interface(char *refparam, struct dmctx *ct
get_layer2_interface(wan_name, &ifname);
if (ifname[0] != '\0')
{
uci_foreach_option_eq("layer2_interface_vlan", "vlan_interface", "ifname", ifname, ss) {
dmuci_get_value_by_section_string(ss, "baseifname", &baseifname);
uci_foreach_option_eq("network", "device", "name", ifname, ss) {
dmuci_get_value_by_section_string(ss, "ifname", &baseifname);
if (strcmp(baseifname, value) == 0)
return 0;
dmuci_get_option_value_string("network", wan_name, "ifname", &wifname);
if (wifname[0] == '\0')
return 0;
dmuci_get_value_by_section_string(ss, "vlan8021q", &vid);
dmuci_get_value_by_section_string(ss, "vid", &vid);
remove_vid_interfaces_from_ifname(vid, wifname, r_new_wifname);
p = a_new_wifname;
q = ifname_buf;
@ -2086,8 +2086,8 @@ int set_wan_ip_link_connection_layer2_interface(char *refparam, struct dmctx *ct
dmstrappendchr(p, ' ');
dmstrappendstr(p, r_new_wifname);
dmstrappendend(p);
dmuci_set_value_by_section(ss, "baseifname", value);
dmuci_set_value_by_section(ss, "ifname", ifname_buf);
dmuci_set_value_by_section(ss, "ifname", value);
dmuci_set_value_by_section(ss, "name", ifname_buf);
dmuci_set_value_by_section(wandcprotoargs->wancprotosection, "ifname", a_new_wifname);
}
return 0;

View file

@ -207,7 +207,7 @@ int get_br_port_last_inst(char *br_key)
buf[4] = atoi(tmp);
if(buf[4]>max) max=buf[4];
}
uci_foreach_option_eq("layer2_interface_vlan", "vlan_interface", "bridge_key", br_key, s) {
uci_foreach_option_eq("network", "device", "bridge_key", br_key, s) {
dmuci_get_value_by_section_string(s, "bridge_port_instance", &tmp);
if (tmp[0] == '\0')
break;
@ -332,7 +332,7 @@ int reset_br_port(char *br_key)
dmuci_set_value_by_section(s, "bridge_key", "");
dmuci_set_value_by_section(s, "penable", "0");
}
uci_foreach_option_eq("layer2_interface_vlan", "vlan_interface", "bridge_key", br_key, s) {
uci_foreach_option_eq("network", "device", "bridge_key", br_key, s) {
if (prev_s)
dmuci_delete_by_section(prev_s, NULL, NULL);
prev_s = s;
@ -357,7 +357,7 @@ int update_port_parameters(char *linker, char *br_key, char *br_pt_inst, char *m
{
struct uci_section *s;
if (check_ifname_is_vlan(linker)) {
uci_foreach_option_eq("layer2_interface_vlan", "vlan_interface", "ifname", linker, s) {
uci_foreach_option_eq("network", "device", "ifname", linker, s) {
dmuci_set_value_by_section(s, "bridge_key", br_key);
dmuci_set_value_by_section(s, "bridge_port_instance", br_pt_inst);
dmuci_set_value_by_section(s, "mg_port", mg_port);
@ -548,14 +548,57 @@ int get_br_port_stats_rx_packets(char *refparam, struct dmctx *ctx, void *data,
return 0;
}
int is_bridge_vlan_enabled(struct bridging_vlan_args *curr_arg)
{
struct uci_section *vlan_sec = curr_arg->bridge_vlan_sec, *br_sec = curr_arg->bridge_sec;
char *ifname, *br_ifname, *ifname_dup, *pch, *spch;
dmuci_get_value_by_section_string(br_sec, "ifname", &br_ifname);
dmuci_get_value_by_section_string(vlan_sec, "name", &ifname);
ifname_dup = dmstrdup(br_ifname);
if(ifname!=NULL && ifname[0]!='\0'){
if (is_strword_in_optionvalue(ifname_dup, ifname))
return 1;
}
return 0;
}
int update_br_vlan_ifname(struct bridging_vlan_args *curr_arg, int status)
{
char ifname_dup[128], *ptr, *baseifname, *ifname, *start, *end;
struct uci_section *vlan_sec = curr_arg->bridge_vlan_sec, *br_sec = curr_arg->bridge_sec;
int pos=0;
dmuci_get_value_by_section_string(br_sec, "ifname", &ifname);
dmuci_get_value_by_section_string(vlan_sec, "name", &baseifname);
ptr = ifname_dup;
dmstrappendstr(ptr, ifname);
dmstrappendend(ptr);
if(status){
if (is_strword_in_optionvalue(ifname_dup, baseifname)) return 0;
if (ifname_dup[0] != '\0') dmstrappendchr(ptr, ' ');
dmstrappendstr(ptr, baseifname);
dmstrappendend(ptr);
}else{
if (is_strword_in_optionvalue(ifname_dup, baseifname)){
start = strstr(ifname_dup, baseifname);
end = start + strlen(baseifname);
if(start != ifname_dup){
start--;
pos=1;
}
memmove(start, start + strlen(baseifname)+pos, strlen(end) + 1);
}
}
dmuci_set_value_by_section(br_sec, "ifname", ifname_dup);
return 0;
}
int get_br_vlan_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = "false";
char *tmp;
dmuci_get_value_by_section_string(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "penable", &tmp);
if (tmp[0] == '0' || tmp[0] == '\0')
*value = "false";
else if (tmp[0] == '1')
int status;
status = is_bridge_vlan_enabled((struct bridging_vlan_args *)data);
if (status)
*value = "true";
return 0;
}
@ -566,6 +609,7 @@ int set_br_vlan_enable(char *refparam, struct dmctx *ctx, void *data, char *inst
char *vlan_ifname, *br_ifname, *vid, *p;
char new_ifname[256];
char pr_linker[32];
int is_enabled;
switch (action) {
case VALUECHECK:
if (string_to_bool(value, &b))
@ -573,35 +617,12 @@ int set_br_vlan_enable(char *refparam, struct dmctx *ctx, void *data, char *inst
return 0;
case VALUESET:
string_to_bool(value, &b);
if (b)
dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "penable", "1");
else {
dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "penable", "0");
dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "bridge_port_instance", "");
dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "bridge_port_alias", "");
dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "br_port_linker", "");
is_enabled = is_bridge_vlan_enabled((struct bridging_vlan_args *)data);
if (b && !is_enabled) {
update_br_vlan_ifname((struct bridging_vlan_args *)data, 1);
}
dmuci_get_value_by_section_string(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "ifname", &vlan_ifname);
if (vlan_ifname[0] == '\0')
return 0;
dmuci_get_value_by_section_string(((struct bridging_vlan_args *)data)->bridge_sec, "ifname", &br_ifname);
if (b) {
//add vlan ifname to br ifname list
p = new_ifname;
if (br_ifname[0] != '\0') {
dmstrappendstr(p, br_ifname);
dmstrappendchr(p, ' ');
}
dmstrappendstr(p, vlan_ifname);
dmstrappendend(p);
dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_sec, "ifname", new_ifname);
sprintf(pr_linker,"%s+%s", section_name(((struct bridging_vlan_args *)data)->bridge_vlan_sec), vlan_ifname);
dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "br_port_linker", pr_linker);
} else {
//delete vlan ifname from br ifname list
remove_interface_from_ifname(vlan_ifname, br_ifname, new_ifname);
//remove_vid_interfaces_from_ifname(vid, br_ifname, new_ifname);
dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_sec, "ifname", new_ifname);
if (!b && is_enabled){
update_br_vlan_ifname((struct bridging_vlan_args *)data, 0);
}
return 0;
}
@ -611,7 +632,7 @@ int set_br_vlan_enable(char *refparam, struct dmctx *ctx, void *data, char *inst
int get_br_vlan_name(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = "0";
dmuci_get_value_by_section_string(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "name", value);
*value = dmstrdup(section_name(((struct bridging_vlan_args *)data)->bridge_vlan_sec));
return 0;
}
@ -621,7 +642,7 @@ int set_br_vlan_name(char *refparam, struct dmctx *ctx, void *data, char *instan
case VALUECHECK:
return 0;
case VALUESET:
dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "name", value);
dmuci_rename_section_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec,value);
return 0;
}
return 0;
@ -630,45 +651,28 @@ int set_br_vlan_name(char *refparam, struct dmctx *ctx, void *data, char *instan
int get_br_vlan_vid(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = "0";
dmuci_get_value_by_section_string(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "vlan8021q", value);
dmuci_get_value_by_section_string(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "vid", value);
return 0;
}
int set_br_vlan_vid(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
char *ifname, *p, *vifname, *linker, *n_ifname;
char buf[256];
char tmp[8];
char *name, *br_ifname, *ifname;
int is_enabled;
switch (action) {
case VALUECHECK:
return 0;
case VALUESET:
dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "vlan8021q", value);
dmuci_get_value_by_section_string(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "ifname", &vifname);
if (vifname[0] != '\0') {
strncpy(tmp, vifname, 5);
tmp[5] = '\0';
strcat(tmp, value);// concat new vid
dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "ifname", tmp);
//update br ifname
dmuci_get_value_by_section_string(((struct bridging_vlan_args *)data)->bridge_sec, "ifname", &ifname);
remove_interface_from_ifname(vifname, ifname, buf);
p = buf;
if (buf[0] != '\0') {
dmstrappendstr(p, buf);
dmstrappendchr(p, ' ');
}
dmstrappendstr(p, tmp);
dmstrappendend(p);
dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_sec, "ifname", buf);
dmuci_get_value_by_section_string(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "br_port_linker", &linker);
strcpy(buf,linker);
p = strchr(buf, '+') + 1;
dmstrappendstr(p, tmp);
dmstrappendend(p);
dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "br_port_linker", buf);
}
dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "vid", value);
dmuci_get_value_by_section_string(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "ifname", &ifname);
dmasprintf(&name, "%s.%s", ifname, value);
is_enabled = is_bridge_vlan_enabled((struct bridging_vlan_args *)data);
if(is_enabled)
update_br_vlan_ifname((struct bridging_vlan_args *)data, 0);
dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "name", name);
if(is_enabled)
update_br_vlan_ifname((struct bridging_vlan_args *)data, 1);
return 0;
}
return 0;
@ -677,7 +681,7 @@ int set_br_vlan_vid(char *refparam, struct dmctx *ctx, void *data, char *instanc
int get_br_vlan_priority(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = "0";
dmuci_get_value_by_section_string(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "vlan8021p", value);
dmuci_get_value_by_section_string(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "priority", value);
return 0;
}
@ -691,7 +695,7 @@ int set_br_vlan_priority(char *refparam, struct dmctx *ctx, void *data, char *in
case VALUECHECK:
return 0;
case VALUESET:
dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "vlan8021p", value);
dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "priority", value);
return 0;
}
return 0;
@ -826,40 +830,39 @@ int add_br_vlan(char *refparam, struct dmctx *ctx, void *data, char **instance)
struct uci_section *vlan_s;
char buf[16];
char *v_name = buf;
char *vid;
int x;
char *val_name;
last_instance = get_last_instance_lev2("layer2_interface_vlan", "vlan_interface", "bridge_vlan_instance", "bridge_key", ((struct bridging_args *)data)->br_key);
dmuci_add_section("layer2_interface_vlan", "vlan_interface", &vlan_s, &value);
last_instance = get_last_instance_lev2("network", "device", "bridge_vlan_instance", "bridge_key", ((struct bridging_args *)data)->br_key);
dmasprintf(&vlan_name, "vlan%d", last_instance ? atoi(last_instance)+ 1 : 0);
dmuci_add_section("network", "device", &vlan_s, &value);
dmuci_rename_section_by_section(vlan_s, vlan_name);
dmuci_set_value_by_section(vlan_s, "bridge_key", ((struct bridging_args *)data)->br_key);
*instance = update_instance(vlan_s, last_instance, "bridge_vlan_instance");
dmstrappendstr(v_name, "vlan_");
dmstrappendstr(v_name, ((struct bridging_args *)data)->br_key);
dmstrappendchr(v_name, '.');
dmstrappendstr(v_name, *instance);
dmstrappendend(v_name);
dmuci_set_value_by_section(vlan_s, "name", v_name);
dmuci_set_value_by_section(vlan_s, "penable", "0");
dmuci_set_value_by_section(vlan_s, "priority", "0");
dmuci_set_value_by_section(vlan_s, "type", "8021q");
dmuci_set_value_by_section(vlan_s, "ifname", wan_baseifname);
return 0;
}
int delete_br_vlan(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action)
{
char *vid, *ifname;
char *vid, *ifname, *br_ifname, *vl_ifname, *type;
struct uci_section *prev_s = NULL, *vlan_s=NULL;
char new_ifname[128];
struct uci_section *vlan_s, *prev_s = NULL ;
int is_enabled;
switch (del_action) {
case DEL_INST:
dmuci_get_value_by_section_string(((struct bridging_vlan_args *)data)->bridge_sec, "ifname", &ifname);
dmuci_get_value_by_section_string(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "vlan8021q", &vid);
if(ifname[0] != '\0' && vid[0] != '\0'){
remove_vid_interfaces_from_ifname(vid, ifname, new_ifname);
dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_sec, "ifname", new_ifname);
}
is_enabled = is_bridge_vlan_enabled((struct bridging_vlan_args *)data);
if(is_enabled)
update_br_vlan_ifname((struct bridging_vlan_args *)data, 0);
dmuci_delete_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec, NULL, NULL);
break;
case DEL_ALL:
uci_foreach_option_eq("layer2_interface_vlan", "vlan_interface", "bridge_key", ((struct bridging_args *)data)->br_key, vlan_s) {
dmuci_get_value_by_section_string(vlan_s, "vlan8021q", &vid);
uci_foreach_option_eq("network", "device", "bridge_key", ((struct bridging_args *)data)->br_key, vlan_s) {
dmuci_get_value_by_section_string(vlan_s, "vid", &vid);
dmuci_get_value_by_section_string(((struct bridging_args *)data)->bridge_sec, "ifname", &ifname);
if(ifname[0] != '\0' && vid[0] != '\0'){
remove_vid_interfaces_from_ifname(vid, ifname, new_ifname);
@ -911,7 +914,7 @@ int delete_br_port(char *refparam, struct dmctx *ctx, void *data, char *instance
return 0;
}
dmasprintf(&linker, "%s+%s", section_name(((struct bridging_port_args *)data)->bridge_port_sec), ((struct bridging_port_args *)data)->ifname);
uci_foreach_option_eq("layer2_interface_vlan", "vlan_interface", "br_port_linker", linker, vlan_s) {
uci_foreach_option_eq("network", "device", "br_port_linker", linker, vlan_s) {
dmuci_set_value_by_section(vlan_s, "br_port_linker", "");
}
DMUCI_DELETE_BY_SECTION(icwmpd, ((struct bridging_port_args *)data)->bridge_port_sec, NULL, NULL);//del port from dmmap
@ -1046,7 +1049,7 @@ int set_port_lower_layer(char *refparam, struct dmctx *ctx, void *data, char *in
}
// check if the current port is already linked with VLAN
sprintf(pr_linker,"%s+%s", section_name(((struct bridging_port_args *)data)->bridge_port_sec), ((struct bridging_port_args *)data)->ifname);
uci_foreach_option_eq("layer2_interface_vlan", "vlan_interface", "br_port_linker", pr_linker, s) {
uci_foreach_option_eq("network", "device", "br_port_linker", pr_linker, s) {
dmuci_get_value_by_section_string(s, "vlan8021q", &vid);
break;
}
@ -1063,7 +1066,7 @@ int set_port_lower_layer(char *refparam, struct dmctx *ctx, void *data, char *in
linker = tmp;
dmstrappendstr(p, tmp);
dmstrappendend(p);
uci_foreach_option_eq("layer2_interface_vlan", "vlan_interface", "br_port_linker", pr_linker, s) {
uci_foreach_option_eq("network", "device", "br_port_linker", pr_linker, s) {
sprintf(pr_linker,"%s+%s", section_name(s), linker);
dmuci_set_value_by_section(s, "br_port_linker", pr_linker);
dmuci_set_value_by_section(s, "ifname", linker);
@ -1131,14 +1134,14 @@ int set_vlan_port_port_ref(char *refparam, struct dmctx *ctx, void *data, char *
if (strstr(pch, "atm") || strstr(pch, "ptm") || strstr(pch, wan_baseifname)) {
strncpy(tmp, pch, 4);
tmp[4] ='\0';
dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "baseifname", tmp);
dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "ifname", tmp);
}
} else {
if (strstr(pch, "atm") || strstr(pch, "ptm") || strstr(pch, wan_baseifname)) {
p = new_ifname;
strncpy(tmp, pch, 4);
tmp[4] ='\0';
dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "baseifname", tmp);
dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "ifname", tmp);
dmstrappendstr(p, tmp);
dmstrappendchr(p, '.');
dmstrappendstr(p, vid);
@ -1190,9 +1193,9 @@ int browseBridgeInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data,
int browseBridgePortInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
{
struct uci_section *eth_s = NULL, *atm_s = NULL, *ptm_s = NULL, *wl_s = NULL, *vlan_s = NULL, *w_eth_s = NULL, *new_port = NULL;
struct uci_section *s, *eth_s = NULL, *atm_s = NULL, *ptm_s = NULL, *wl_s = NULL, *vlan_s = NULL, *w_eth_s = NULL, *new_port = NULL;
char *port = NULL, *port_last = NULL, *vlan = NULL, *vlan_last = NULL;
char *ifname_dup = NULL, *pch, *spch;
char *ifname_dup = NULL, *pch, *spch, *type;
bool find_max = true;
struct bridging_port_args curr_bridging_port_args = {0};
bool found = false;
@ -1280,15 +1283,21 @@ int browseBridgePortInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_da
}
#ifndef EX400
if(!found) {
uci_foreach_option_eq("layer2_interface_vlan", "vlan_interface", "ifname", pch, vlan_s) {
dmuci_set_value_by_section(vlan_s, "bridge_key", ((struct bridging_args *)prev_data)->br_key);
dmuci_set_value_by_section(vlan_s, "mg_port", "false");
dmuci_set_value_by_section(vlan_s, "penable", "1");
init_bridging_port_args(&curr_bridging_port_args, vlan_s, ((struct bridging_args *)prev_data)->bridge_sec, true, pch);
port = handle_update_instance(2, dmctx, &port_last, br_port_update_instance_alias, 5, vlan_s, "bridge_port_instance", "bridge_port_alias", &find_max, ((struct bridging_args *)prev_data)->br_key);
if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_bridging_port_args, port) == DM_STOP)
goto end;
break;
if (strncmp(pch, wan_baseifname, 4) == 0 || strncmp(pch, "ptm", 3) == 0 || strncmp(pch, "atm", 3) == 0) {
uci_foreach_option_eq("network", "device", "name", pch, vlan_s) {
dmuci_get_value_by_section_string(vlan_s, "type", &type);
//Check if VLAN or NOT
if (strcmp(type, "untagged")!=0) {
dmuci_set_value_by_section(vlan_s, "bridge_key", ((struct bridging_args *)prev_data)->br_key);
dmuci_set_value_by_section(vlan_s, "mg_port", "false");
dmuci_set_value_by_section(vlan_s, "penable", "1");
init_bridging_port_args(&curr_bridging_port_args, vlan_s, ((struct bridging_args *)prev_data)->bridge_sec, true, pch);
port = handle_update_instance(2, dmctx, &port_last, br_port_update_instance_alias, 5, vlan_s, "bridge_port_instance", "bridge_port_alias", &find_max, ((struct bridging_args *)prev_data)->br_key);
if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_bridging_port_args, port) == DM_STOP)
goto end;
break;
}
}
}
}
#endif
@ -1300,32 +1309,56 @@ end:
int browseBridgeVlanInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
{
struct uci_section *vlan_s = NULL;
char *vlan = NULL, *vlan_last = NULL;
char *type, *ipv4 ;
struct bridging_vlan_args curr_bridging_vlan_args = {0};
struct uci_section *vlan_s;
char *vlan = NULL, *vlan_last = NULL, *type, *ifname, *is_lan= NULL;
uci_foreach_option_eq("layer2_interface_vlan", "vlan_interface", "bridge_key", ((struct bridging_args *)prev_data)->br_key, vlan_s) {
vlan = handle_update_instance(2, dmctx, &vlan_last, update_instance_alias, 3, vlan_s, "bridge_vlan_instance", "bridge_vlan_alias");
init_bridging_vlan_args(&curr_bridging_vlan_args, vlan_s, ((struct bridging_args *)prev_data)->bridge_sec, vlan_last, ((struct bridging_args *)prev_data)->br_key);
if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_bridging_vlan_args, vlan) == DM_STOP)
break;
struct bridging_vlan_args curr_bridging_vlan_args = {0};
struct bridging_args *br_args = (struct bridging_args *)prev_data;
bool find_max = true;
dmuci_get_value_by_section_string(br_args->bridge_sec, "is_lan", &is_lan);
if(is_lan==NULL || strcmp(is_lan, "1")!=0){
uci_foreach_sections("network", "device", vlan_s) {
if(!vlan_s)
goto end;
//Check if VLAN or NOT
dmuci_get_value_by_section_string(vlan_s, "type", &type);
if (strcmp(type, "untagged")!=0) {
vlan = handle_update_instance(2, dmctx, &vlan_last, update_instance_alias, 3, vlan_s, "bridge_vlan_instance", "bridge_vlan_alias");
init_bridging_vlan_args(&curr_bridging_vlan_args, vlan_s, br_args->bridge_sec, vlan_last, br_args->br_key);
if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_bridging_vlan_args, vlan) == DM_STOP)
goto end;
}
}
}
end:
return 0;
}
int browseBridgeVlanPortInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
{
struct uci_section *vlan_s = NULL;
char *vlan = NULL, *vlan_last = NULL;
char *type, *ipv4 ;
struct bridging_vlan_args curr_bridging_vlan_args = {0};
struct uci_section *vlan_s;
char *vlan = NULL, *vlan_last = NULL, *type, *ifname, *is_lan= NULL;
uci_foreach_option_eq("layer2_interface_vlan", "vlan_interface", "bridge_key", ((struct bridging_args *)prev_data)->br_key, vlan_s) {
vlan = handle_update_instance(2, dmctx, &vlan_last, update_instance_alias, 3, vlan_s, "bridge_vlan_instance", "bridge_vlan_alias");
init_bridging_vlan_args(&curr_bridging_vlan_args, vlan_s, ((struct bridging_args *)prev_data)->bridge_sec, vlan_last, ((struct bridging_args *)prev_data)->br_key);
if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_bridging_vlan_args, vlan) == DM_STOP)
break;
}
return 0;
struct bridging_vlan_args curr_bridging_vlan_args = {0};
struct bridging_args *br_args = (struct bridging_args *)prev_data;
bool find_max = true;
dmuci_get_value_by_section_string(br_args->bridge_sec, "is_lan", &is_lan);
if(is_lan==NULL || strcmp(is_lan, "1")!=0){
uci_foreach_sections("network", "device", vlan_s) {
if(!vlan_s)
goto end;
//Check if VLAN or NOT
dmuci_get_value_by_section_string(vlan_s, "type", &type);
if (strcmp(type, "untagged")!=0) {
vlan = handle_update_instance(2, dmctx, &vlan_last, update_instance_alias, 3, vlan_s, "bridge_vlan_instance", "bridge_vlan_alias");
init_bridging_vlan_args(&curr_bridging_vlan_args, vlan_s, br_args->bridge_sec, vlan_last, br_args->br_key);
if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_bridging_vlan_args, vlan) == DM_STOP)
goto end;
}
}
}
end:
return 0;
}

View file

@ -47,6 +47,8 @@ extern DMLEAF tBridgeVlanPortParams[];
extern DMOBJ tBridgePortObj[];
extern DMLEAF tBridgePortStatParams[];
int update_br_vlan_ifname(struct bridging_vlan_args *curr_arg, int status);
int browseBridgeVlanPortInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance);
int browseBridgeVlanInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance);
int browseBridgePortInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance);