From 5585bed07962f4c05e37efd7e90df09af1434fed Mon Sep 17 00:00:00 2001 From: Feten Besbes Date: Mon, 26 Feb 2018 09:50:57 +0100 Subject: [PATCH] Ticket refs #13739: icwmp: adapt to new way of creating VLANs --- dm/dmcommon.h | 1 + dm/dmtree/tr098/layer_2_bridging.c | 393 ++++++++++++++++++++--------- dm/dmtree/tr098/layer_2_bridging.h | 5 +- dm/dmtree/tr098/wandevice.c | 56 ++-- dm/dmtree/tr181/bridging.c | 281 ++++++++++++--------- dm/dmtree/tr181/bridging.h | 2 + 6 files changed, 464 insertions(+), 274 deletions(-) diff --git a/dm/dmcommon.h b/dm/dmcommon.h index 3375ab6..80d66a8 100644 --- a/dm/dmcommon.h +++ b/dm/dmcommon.h @@ -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); diff --git a/dm/dmtree/tr098/layer_2_bridging.c b/dm/dmtree/tr098/layer_2_bridging.c index 3945b26..a86583f 100644 --- a/dm/dmtree/tr098/layer_2_bridging.c +++ b/dm/dmtree/tr098/layer_2_bridging.c @@ -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; diff --git a/dm/dmtree/tr098/layer_2_bridging.h b/dm/dmtree/tr098/layer_2_bridging.h index 8dc82a6..a96de53 100644 --- a/dm/dmtree/tr098/layer_2_bridging.h +++ b/dm/dmtree/tr098/layer_2_bridging.h @@ -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 diff --git a/dm/dmtree/tr098/wandevice.c b/dm/dmtree/tr098/wandevice.c index 69ba4d4..bb46814 100644 --- a/dm/dmtree/tr098/wandevice.c +++ b/dm/dmtree/tr098/wandevice.c @@ -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; diff --git a/dm/dmtree/tr181/bridging.c b/dm/dmtree/tr181/bridging.c index 472f2ba..07be0d1 100644 --- a/dm/dmtree/tr181/bridging.c +++ b/dm/dmtree/tr181/bridging.c @@ -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; } diff --git a/dm/dmtree/tr181/bridging.h b/dm/dmtree/tr181/bridging.h index 91cf4bd..e5c1499 100644 --- a/dm/dmtree/tr181/bridging.h +++ b/dm/dmtree/tr181/bridging.h @@ -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);