diff --git a/dmtree/tr181/bridging.c b/dmtree/tr181/bridging.c index 3bb9ad32..85708287 100644 --- a/dmtree/tr181/bridging.c +++ b/dmtree/tr181/bridging.c @@ -96,6 +96,7 @@ static inline int init_bridging_vlan_args(struct bridging_vlan_args *args, struc /************************************************************************** * INSTANCE MG ***************************************************************************/ +#if 0 static char *get_last_vid(void) { struct uci_section *vlan_s; @@ -115,22 +116,37 @@ static char *get_last_vid(void) } return vid; } +#endif -static int check_ifname_exist_in_br_ifname_list(char *ifname) +static int check_ifname_exist_in_br_ifname_list(char *ifname, char *section) { char *br_ifname_list, *br_ifname_dup, *pch, *spch; - struct uci_section *s; + struct uci_section *s = NULL; uci_foreach_option_eq("network", "interface", "type", "bridge", s) { + + /* Check if both the section names are same or not, if same fetch the interface + * name else continue with the next section. */ + char br_sec[250] = {0}; + strncpy(br_sec, section, sizeof(br_sec)); + + if (strncmp(br_sec, section_name(s), sizeof(br_sec)) != 0) { + continue; + } + dmuci_get_value_by_section_string(s, "ifname", &br_ifname_list); if (br_ifname_list[0] == '\0') return 0; + br_ifname_dup = dmstrdup(br_ifname_list); for (pch = strtok_r(br_ifname_dup, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch)) { - if (strcmp(pch, ifname) == 0) + /* Fix : Check to support tagged and untagged interfaces. */ + if (strncmp(ifname, pch, 4) == 0) { return 1; + } } } + return 0; } @@ -138,7 +154,7 @@ static int get_br_port_last_inst(char *br_key) { char *tmp; int instance, max = 1; - struct uci_section *s; + struct uci_section *s = NULL; uci_path_foreach_option_eq(bbfdm, "dmmap_bridge_port", "bridge_port", "bridge_key", br_key, s) { dmuci_get_value_by_section_string(s, "bridge_port_instance", &tmp); @@ -152,7 +168,7 @@ static int get_br_port_last_inst(char *br_key) static int reset_br_port(char *br_key) { - struct uci_section *s, *prev_s = NULL; + struct uci_section *s = NULL, *prev_s = NULL; uci_path_foreach_option_eq(bbfdm, "dmmap_bridge_port", "bridge_port", "bridge_key", br_key, s) { if (prev_s) @@ -163,6 +179,7 @@ static int reset_br_port(char *br_key) return 0; } +#if 0 static int check_ifname_is_not_lan_port(char *ifname) { struct uci_section *s; @@ -230,6 +247,7 @@ static int update_port_parameters(char *linker, char *br_key, char *br_pt_inst, } return 0; } +#endif static int is_br_port_enabled(struct bridging_port_args *curr_arg) { @@ -406,7 +424,8 @@ static int get_br_vlan_number_of_entries(char *refparam, struct dmctx *ctx, void struct uci_section *s = NULL; int cnt = 0; - uci_path_foreach_option_eq(bbfdm, "dmmap_network", "device", "bridge_key", instance, s) { + /* Fix: Interface section needs to be browsed to get the vlan entries. */ + uci_path_foreach_option_eq(bbfdm, "dmmap_network", "interface", "bridge_key", instance, s) { cnt++; } dmasprintf(value, "%d", cnt); @@ -415,42 +434,36 @@ static int get_br_vlan_number_of_entries(char *refparam, struct dmctx *ctx, void static int get_br_vlan_port_number_of_entries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - struct uci_section *s = NULL; int cnt = 0; + char *br_ifname_list, *br_ifname_dup, *pch, *spch; - uci_path_foreach_option_eq(bbfdm, "dmmap_network", "device", "bridge_key", instance, s) { - cnt++; + dmuci_get_value_by_section_string(((struct bridging_args *)data)->bridge_sec, "ifname", &br_ifname_list); + + if(br_ifname_list[0] == '\0') { + dmasprintf(value, "%d", cnt); + return 0; } + + br_ifname_dup = dmstrdup(br_ifname_list); + + for (pch = strtok_r(br_ifname_dup, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch)) { + // Bridge has vlan's defined as ethx.y where y is the vlan id, so, the presence + // of '.' in the string confirms vlan port. + if (strstr(pch, ".") != NULL) { + cnt++; + } + } + dmasprintf(value, "%d", cnt); return 0; } -static int get_br_associated_interfaces(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - dmuci_get_value_by_section_string(((struct bridging_args *)data)->bridge_sec, "ifname", value); - return 0; -} - -static int set_br_associated_interfaces(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) -{ - switch (action) { - case VALUECHECK: - if (dm_validate_string(value, -1, 256, NULL, 0, NULL, 0)) - return FAULT_9007; - return 0; - case VALUESET: - dmuci_set_value_by_section(((struct bridging_args *)data)->bridge_sec, "ifname", value); - return 0; - } - return 0; -} - /*#Device.Bridging.Bridge.{i}.Port.{i}.Enable!UBUS:network.device/status/name,@Name/speed*/ static int get_br_port_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { json_object *res; char *speed, *val; - struct uci_section *wifi_device_s; + struct uci_section *wifi_device_s = NULL; dmuci_get_value_by_section_string(((struct bridging_port_args *)data)->bridge_port_sec, "ifname", value); if(strncmp(*value, "wl", 2) == 0 || strncmp(*value, "ra", 2) == 0 || strncmp(*value, "apclii", 6) == 0) { @@ -540,7 +553,7 @@ static int set_br_port_management(char *refparam, struct dmctx *ctx, void *data, static struct uci_section *check_if_ifname_is_tagged(char *ifname) { - struct uci_section *s; + struct uci_section *s = NULL; uci_foreach_option_eq("network", "device", "name", ifname, s) { return s; } @@ -811,6 +824,7 @@ static int update_br_vlan_ifname(struct bridging_vlan_args *curr_arg, int status 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, ' '); @@ -886,14 +900,33 @@ static int set_br_vlan_name(char *refparam, struct dmctx *ctx, void *data, char static int get_br_vlan_vid(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - dmuci_get_value_by_section_string(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "vid", value); + /* Fix : Fetch the vlan id from the ifname option of "network", "interface" section. */ + char *ifname; + dmuci_get_value_by_section_string(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "ifname", &ifname); + char tag[20] = {0}; + char *tok = strtok(ifname, " "); + while (tok != NULL) { + char intf[250] = {0}; + strncpy(intf, tok, sizeof(intf)); + char *p, *end; + p = strtok_r(intf, ".", &end); + if (end != NULL) { + strncpy(tag, end, sizeof(tag)); + *value = dmstrdup(tag); + break; + } + + tok = strtok(NULL, " "); + } + return 0; } static int set_br_vlan_vid(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { char *name, *ifname; - int is_enabled; + struct uci_section *sec; + struct bridging_vlan_args *vlan_args = (struct bridging_vlan_args *)data; switch (action) { case VALUECHECK: @@ -901,17 +934,87 @@ static int set_br_vlan_vid(char *refparam, struct dmctx *ctx, void *data, char * return FAULT_9007; return 0; case VALUESET: - 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); - dmfree(name); - return 0; + /* Fix : Set the value of vid in Bridging.Bridge.x.VLAN object. */ + dmuci_get_value_by_section_string(vlan_args->bridge_sec, "ifname", &ifname); + char intf_name[250] = {0}; + if (*ifname == '\0') { + char *intf = "eth0 eth1 eth2 eth3 eth4 eth5"; + strncpy(intf_name, intf, sizeof(intf_name)); + } else { + strncpy(intf_name, ifname, sizeof(intf_name)); + } + + struct uci_section *s; + char *val; + char intf_tag[250] = {0}; + + /* If vid is 1 then add config device section in /etc/config/network file also. */ + char vid[50] = {0}; + strncpy(vid, value, sizeof(vid)); + + char *end; + char *token = strtok_r(intf_name, " ", &end); + while (token != NULL) { + char intf[50] = {0}; + strncpy(intf, token, sizeof(intf)); + char *tok, *tag; + tok = strtok_r(intf, ".", &tag); + + /* Remove all the config device section before setting the vlan id. */ + if (tag != NULL ) { + char vlan_id[20] = {0}; + strncpy(vlan_id, tag, sizeof(vlan_id)); + if (strncmp(vlan_id, "1", sizeof(vlan_id)) == 0) { + uci_foreach_option_eq("network", "device", "name", token, sec) { + dmuci_delete_by_section(sec, "name", token); + dmuci_delete_by_section(sec, "type", "untagged"); + dmuci_delete_by_section(sec, "ifname", tok); + } + } + } + dmasprintf(&name, "%s.%s", intf, vid); + + if (strncmp(vid, "1", sizeof(vid)) == 0 ) { + /* Create config device section. */ + dmuci_add_section_and_rename("network", "device", &s, &val); + dmuci_set_value_by_section(s, "type", "untagged"); + if (tag != NULL) { + dmuci_set_value_by_section(s, "ifname", tag); + } else { + dmuci_set_value_by_section(s, "ifname", intf); + } + dmuci_set_value_by_section(s, "name", name); + } + + if (intf_tag[0] != '\0') { + strcat(intf_tag, " "); + } + strcat(intf_tag, name); + + /* Remove vlanport section from dmmap_network file. */ + struct uci_section *s = NULL, *dmmap_section = NULL; + char *tmp; + int ret = 0; + uci_path_foreach_option_eq(bbfdm, "dmmap_network", "vlanport", "ifname", token, s) { + dmuci_get_value_by_section_string(s, "section_name", &tmp); + ret = 1; + break; + } + + if (ret == 1) { + get_dmmap_section_of_config_section("dmmap_network", "vlanport", tmp, &dmmap_section); + dmuci_delete_by_section(dmmap_section, NULL, NULL); + } + + token = strtok_r(NULL, " ", &end); + } + + dmuci_set_value_by_section(vlan_args->bridge_sec, "ifname", intf_tag); + + + uci_path_foreach_option_eq(bbfdm, "dmmap_network", "interface", "section_name", section_name(vlan_args->bridge_sec), sec) { + dmuci_set_value_by_section(sec, "vlan_id", value); + } } return 0; } @@ -999,9 +1102,9 @@ static int get_br_vlan_alias(char *refparam, struct dmctx *ctx, void *data, char { struct uci_section *dmmap_section = NULL; - get_dmmap_section_of_config_section("dmmap_network", "device", section_name(((struct bridging_vlan_args *)data)->bridge_vlan_sec), &dmmap_section); - if (dmmap_section) - dmuci_get_value_by_section_string(dmmap_section, "bridge_vlan_alias", value); + /* Fix: Interface section needs to be browsed to get the value for vlan alias. */ + get_dmmap_section_of_config_section("dmmap_network", "interface", section_name(((struct bridging_vlan_args *)data)->bridge_vlan_sec), &dmmap_section); + if (dmmap_section) dmuci_get_value_by_section_string(dmmap_section, "bridge_vlan_alias", value); return 0; } @@ -1040,7 +1143,7 @@ static int add_bridge(char *refparam, struct dmctx *ctx, void *data, char **inst dmstrappendend(p); dmuci_set_value("network", bridge_name, "", "interface"); dmuci_set_value("network", bridge_name, "type", "bridge"); - dmuci_set_value("network", bridge_name, "proto", "dhcp"); + /* Fix : Bridge should be created without specifying the proto.*/ dmuci_add_section_bbfdm("dmmap_network", "interface", &dmmap_bridge, &v); dmuci_set_value_by_section(dmmap_bridge, "section_name", bridge_name); @@ -1093,75 +1196,374 @@ static int delete_bridge(char *refparam, struct dmctx *ctx, void *data, char *in return 0; } +static int get_vlanport_last_inst(char *br_key) +{ + char *tmp; + int instance, max = 0; + struct uci_section *s = NULL; + + uci_path_foreach_option_eq(bbfdm, "dmmap_network", "vlanport", "bridge_key", br_key, s) { + dmuci_get_value_by_section_string(s, "vport_inst", &tmp); + if (tmp[0] == '\0') + continue; + instance = atoi(tmp); + if (instance > max) max = instance; + } + return max; +} + +static int add_br_vlanport(char *refparam, struct dmctx *ctx, void *data, char **instance) +{ + char *v, *name; + + /* Fix: To add Bridge.VLANPort object from the management methods. */ + struct bridging_args *br_args = (struct bridging_args *)data; + char *br_ifname_list, *br_ifname_dup, *pch, *spch; + + /* Check if the section name has tagged ifname or not. */ + dmuci_get_value_by_section_string(br_args->bridge_sec, "ifname", &br_ifname_list); + + + if(br_ifname_list[0] != '\0') { + /* Check if the ifname is tagged or not , if not tagged replace it with a tag of 1. */ + br_ifname_dup = dmstrdup(br_ifname_list); + for (pch = strtok_r(br_ifname_dup, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch)) { + int is_present = 0; + if (strstr(pch, ".") == NULL) { + continue; + } else { + /* Check if the vlanport section is not present for the interface. */ + struct uci_section *s = NULL; + uci_path_foreach_option_eq(bbfdm, "dmmap_network", "vlanport", "ifname", pch, s) { + is_present = 1; + break; + } + + if (is_present == 0) { + /* Add vlanport section in dmmap_network. */ + struct uci_section *dmmap_port; + dmuci_add_section_bbfdm("dmmap_network", "vlanport", &dmmap_port, &v); + dmuci_set_value_by_section(dmmap_port, "bridge_key", br_args->br_key); + /* Get the last vlan_instance and add one. */ + int m = get_vlanport_last_inst(br_args->br_key); + char instance[10]; + sprintf(instance, "%d", m+1); + dmuci_set_value_by_section(dmmap_port, "vport_inst", instance); + dmasprintf(&name, "%s_%d", "vlanport", m); + dmuci_set_value_by_section(dmmap_port, "section_name", name); + dmuci_set_value_by_section(dmmap_port, "ifname", pch); + } + } + } + } + + /* Add vlanport section in dmmap_network. */ + struct uci_section *dmmap_port; + dmuci_add_section_bbfdm("dmmap_network", "vlanport", &dmmap_port, &v); + dmuci_set_value_by_section(dmmap_port, "bridge_key", br_args->br_key); + /* Get the vlan port instance. */ + int m = get_vlanport_last_inst(br_args->br_key); + char inst[10]; + sprintf(inst, "%d", m+1); + dmuci_set_value_by_section(dmmap_port, "vport_inst", inst); + dmasprintf(&name, "%s_%d", "vlanport", m); + dmuci_set_value_by_section(dmmap_port, "section_name", name); + dmasprintf(instance, "%d", m+1); + + return 0; +} + +static int remove_ifname_from_uci(char *ifname, void *data, char *nontag_name) +{ + struct bridging_args *br_args = (struct bridging_args *)data; + char *br_ifname_list; + char new_ifname[250] = {0}; + char intf[50] = {0}; + + dmuci_get_value_by_section_string(br_args->bridge_sec, "ifname", &br_ifname_list); + + strncpy(intf, ifname, sizeof(intf)); + + char *tok = strtok(br_ifname_list, " "); + while (tok != NULL) { + if (strncmp(intf, tok, sizeof(intf)) != 0) { + if (new_ifname[0] != '\0') { + strcat(new_ifname, " "); + } + strcat(new_ifname, tok); + } else { + if (new_ifname[0] != '\0') { + strcat(new_ifname, " "); + } + strcat(new_ifname, nontag_name); + + } + tok = strtok(NULL, " "); + } + + dmuci_set_value_by_section(br_args->bridge_sec, "ifname", new_ifname); + + return 0; +} + +static int delete_br_vlanport(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action) +{ + /* Fix: To delete Bridge.VLANPort object from the management methods. */ + struct bridging_args *br_args = (struct bridging_args *)data; + char *br_ifname_list = NULL, *br_ifname_dup = NULL, *pch = NULL, *spch = NULL; + struct uci_section *sec, *s, *vport_sec; + char new_ifname[250] = {0}; + int inst_found = 0; + char *name; + + + switch (del_action) { + case DEL_INST: + /* Get the Port associated with it. */ + uci_path_foreach_option_eq(bbfdm, "dmmap_network", "vlanport", "bridge_key", br_args->br_inst, s) { + + /* Fetch and compare the vlan port instance with the instance we got. */ + char *inst; + dmuci_get_value_by_section_string(s, "vport_inst", &inst); + char v_instance[10] = {0}; + strncpy(v_instance, instance, sizeof(v_instance)); + if (strncmp(v_instance, inst, sizeof(v_instance)) != 0) { + continue; + } + + inst_found = 1; + + /* Check if ifname is present or not. */ + char *ifname; + dmuci_get_value_by_section_string(s, "ifname", &ifname); + if (*ifname != '\0') { + char intf[250] = {0}; + strncpy(intf, ifname, sizeof(intf)); + + char *tok, *tag; + tok = strtok_r(intf, ".", &tag); + if (tag != NULL) { + /* Remove the tag in ifname from UCI file.*/ + remove_ifname_from_uci(ifname, data, intf); + + /* Check if the tag is 1 or not. */ + char vid[10] = {0}; + strncpy(vid, tag, sizeof(vid)); + + if (strncmp(vid, "1", sizeof(vid)) == 0) { + /* Remove the config device section. */ + uci_foreach_option_eq("network", "device", "name", ifname, sec) { + dmuci_delete_by_section(sec, "name", ifname); + dmuci_delete_by_section(sec, "type", "untagged"); + dmuci_delete_by_section(sec, "ifname", tok); + } + } + } + } + } + /* Remove the vlan port dmmap section. */ + if (inst_found == 1) { + int id = atoi(instance); + dmasprintf(&name, "%s_%d", "vlanport", (id - 1)); + get_dmmap_section_of_config_section("dmmap_network", "vlanport", name, &vport_sec); + dmuci_delete_by_section(vport_sec, NULL, NULL); + } + /* JOmily add. */ + int v_last = get_vlanport_last_inst(br_args->br_inst); + int j = 0; + int val = atoi(instance) + 1; + for (j = val; j <= v_last; j++) { + dmasprintf(&name, "%s_%d", "vlanport", (j - 1)); + get_dmmap_section_of_config_section("dmmap_network", "vlanport", name, &vport_sec); + char inst_val[10]; + sprintf(inst_val, "%d", (j-1)); + dmuci_set_value_by_section(vport_sec, "vport_inst", inst_val); + char *v_name; + dmasprintf(&v_name, "%s_%d", "vlanport", (j - 2)); + dmuci_set_value_by_section(vport_sec, "section_name", v_name); + } + + break; + case DEL_ALL: + /* Check if the section name has tagged ifname or not. */ + dmuci_get_value_by_section_string(br_args->bridge_sec, "ifname", &br_ifname_list); + + if(br_ifname_list[0] != '\0') { + br_ifname_dup = dmstrdup(br_ifname_list); + } + + if (*br_ifname_dup == '\0') { + return -1; + } + + /* Check if the ifname is tagged or not, if yes then remove the tag. */ + for (pch = strtok_r(br_ifname_dup, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch)) { + char pch_tag[20] = {0}; + strncpy(pch_tag, pch, sizeof(pch_tag)); + + if (strstr(pch_tag, ".") == NULL) { + if( new_ifname[0] != '\0') { + strcat(new_ifname, " "); + } + strcat(new_ifname, pch); + } else { + /* Remove the tag. */ + char name[50] = {0}; + strncpy(name, pch, sizeof(name)); + char *tag_id; + char *tag = strtok_r(name, ".", &tag_id); + if (tag != NULL) { + if( new_ifname[0] != '\0') { + strcat(new_ifname, " "); + } + strcat(new_ifname, tag); + } + if (tag_id != NULL) { + /* Check if the tag_id is 1, then remove the device section. */ + char if_tag[20] = {0}; + strncpy(if_tag, tag_id, sizeof(if_tag)); + + if(strncmp(if_tag, "1", sizeof(if_tag)) == 0) { + uci_foreach_option_eq("network", "device", "name", pch, sec) { + dmuci_delete_by_section(sec, "name", pch); + dmuci_delete_by_section(sec, "type", "untagged"); + dmuci_delete_by_section(sec, "ifname", name); + } + + } + } + } + } + dmuci_set_value_by_section(br_args->bridge_sec, "ifname", new_ifname); + + /* Remove all dmmap VLANPort section. */ + int m = get_vlanport_last_inst(br_args->br_key); + struct uci_section *s; + int i; + for (i = 0; i < m; i++) { + dmasprintf(&name, "%s_%d", "vlanport", i); + get_dmmap_section_of_config_section("dmmap_network", "vlanport", name, &s); + dmuci_delete_by_section(s, NULL, NULL); + } + break; + } + + return 0; +} + static int add_br_vlan(char *refparam, struct dmctx *ctx, void *data, char **instance) { - char *value, *last_instance, *v, *vlan_name, *name, *last_vid, *vid; - struct uci_section *vlan_s, *dmmap_bridge_vlan; + /* Fix: To add Bridge.VLAN object from the management methods. */ + char *v, *name; + struct uci_section *sec = NULL, *dmmap_bridge_vlan = NULL; check_create_dmmap_package("dmmap_network"); - last_instance = get_last_instance_lev2_bbfdm_dmmap_opt("dmmap_network", "device", "bridge_vlan_instance", "bridge_key", ((struct bridging_args *)data)->br_key); - dmasprintf(&vlan_name, "vlan%d", last_instance ? atoi(last_instance)+ 1 : 1); - last_vid = get_last_vid(); - dmasprintf(&name, "%s.%d", wan_baseifname, last_vid ? atoi(last_vid)+ 1 : 1001); - dmasprintf(&vid, "%d", last_vid ? atoi(last_vid)+ 1 : 1001); - dmuci_add_section_and_rename("network", "device", &vlan_s, &value); - dmuci_rename_section_by_section(vlan_s, vlan_name); - 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, "vid", vid); - dmuci_set_value_by_section(vlan_s, "name", name); - dmuci_set_value_by_section(vlan_s, "ifname", wan_baseifname); - dmfree(name); - dmfree(vid); - dmuci_add_section_bbfdm("dmmap_network", "device", &dmmap_bridge_vlan, &v); - dmuci_set_value_by_section(dmmap_bridge_vlan, "section_name", vlan_name); - dmuci_set_value_by_section(dmmap_bridge_vlan, "bridge_key", ((struct bridging_args *)data)->br_key); - *instance = update_instance_bbfdm(dmmap_bridge_vlan, last_instance, "bridge_vlan_instance"); + /* Check if section_name exists with specified bridge_key. */ + uci_path_foreach_option_eq(bbfdm, "dmmap_network", "interface", "section_name", section_name(((struct bridging_args *)data)->bridge_sec), sec) { + /* If section exists, create new vlan instance. */ + dmuci_add_section_bbfdm("dmmap_network", "vlan", &dmmap_bridge_vlan, &v); + dmasprintf(&name, "%s_%s", "vlan", ((struct bridging_args *)data)->br_inst ); + dmuci_set_value_by_section(dmmap_bridge_vlan, "section_name", name); + dmuci_set_value_by_section(dmmap_bridge_vlan, "bridge_instance", ((struct bridging_args *)data)->br_inst); + dmuci_set_value_by_section(dmmap_bridge_vlan, "bridge_key", ((struct bridging_args *)data)->br_key); + } return 0; } static int delete_br_vlan(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action) { + /* Fix: To delete Bridge.VLAN object from the management methods. */ char *vid, *ifname, *type; - struct uci_section *prev_s = NULL, *vlan_s=NULL, *dmmap_section; - char new_ifname[128]; + struct uci_section *prev_s = NULL, *vlan_s=NULL, *dmmap_section, *vid_sec; int is_enabled; switch (del_action) { case DEL_INST: is_enabled = is_bridge_vlan_enabled((struct bridging_vlan_args *)data); - if(is_enabled) + if(is_enabled) { update_br_vlan_ifname((struct bridging_vlan_args *)data, 0); - get_dmmap_section_of_config_section("dmmap_network", "device", section_name(((struct bridging_vlan_args *)data)->bridge_vlan_sec), &dmmap_section); - dmuci_delete_by_section(dmmap_section, NULL, NULL); - dmuci_delete_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec, NULL, NULL); + } + get_dmmap_section_of_config_section("dmmap_network", "interface", section_name(((struct bridging_vlan_args *)data)->bridge_vlan_sec), &dmmap_section); + dmuci_delete_by_section(dmmap_section, "bridge_vlan_instance", NULL); break; case DEL_ALL: - uci_foreach_sections("network", "device", vlan_s) { + uci_foreach_sections("network", "interface", vlan_s) { dmuci_get_value_by_section_string(vlan_s, "type", &type); - if (strcmp(type, "untagged")==0) + if (*type == '\0' || strcmp(type, "untagged")==0) continue; - dmuci_get_value_by_section_string(vlan_s, "vid", &vid); + + get_dmmap_section_of_config_section("dmmap_network", "interface", section_name(((struct bridging_args *)data)->bridge_sec), &vid_sec); + dmuci_get_value_by_section_string(vid_sec, "vlan_id", &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); - dmuci_set_value_by_section(((struct bridging_args *)data)->bridge_sec, "ifname", new_ifname); - } if (prev_s != NULL){ - get_dmmap_section_of_config_section("dmmap_network", "device", section_name(prev_s), &dmmap_section); - dmuci_delete_by_section(dmmap_section, NULL, NULL); - dmuci_delete_by_section(prev_s, NULL, NULL); + get_dmmap_section_of_config_section("dmmap_network", "interface", section_name(prev_s), &dmmap_section); + dmuci_delete_by_section(dmmap_section, "bridge_vlan_instance", NULL); } prev_s = vlan_s; } if (prev_s != NULL){ - get_dmmap_section_of_config_section("dmmap_network", "device", section_name(prev_s), &dmmap_section); - dmuci_delete_by_section(dmmap_section, NULL, NULL); - dmuci_delete_by_section(prev_s, NULL, NULL); + get_dmmap_section_of_config_section("dmmap_network", "interface", section_name(prev_s), &dmmap_section); + dmuci_delete_by_section(dmmap_section, "bridge_vlan_instance", NULL); } break; } + + /* Update the ifname section in network file. */ + char *br_ifname_list; + char final_list[250] = {0}; + dmuci_get_value_by_section_string(((struct bridging_args *)data)->bridge_sec, "ifname", &br_ifname_list); + char *end; + char *tok = strtok_r(br_ifname_list, " ", &end); + while (tok != NULL) { + char intf[20] = {0}; + strncpy(intf, tok, sizeof(intf)); + char *end2; + char *tag = strtok_r(tok, ".", &end2); + if (tag != NULL) { + char vid[10] = {0}; + strncpy(vid, end2, sizeof(vid)); + if (strncmp(vid, "1", sizeof(vid)) == 0) { + /* Remove the config device section. */ + struct uci_section *sec = NULL; + uci_foreach_option_eq("network", "device", "name", intf, sec) { + dmuci_delete_by_section(sec, "name", intf); + dmuci_delete_by_section(sec, "type", "untagged"); + dmuci_delete_by_section(sec, "ifname", tag); + } + } + + /* Remove the vlanport instance from the dmmap_network file. */ + struct uci_section *vport_s = NULL; + char *sec_name; + int ret = 0; + uci_path_foreach_option_eq(bbfdm, "dmmap_network", "vlanport", "ifname", intf, vport_s) { + dmuci_get_value_by_section_string(vport_s, "section_name", &sec_name); + ret = 1; + break; + } + + if (ret == 1) { + get_dmmap_section_of_config_section("dmmap_network", "vlanport", sec_name, &vport_s); + dmuci_delete_by_section(vport_s, NULL, NULL); + } + + if (final_list[0] != '\0') { + strcat(final_list, " "); + } + strcat(final_list, tag); + } + tok = strtok_r(NULL, " ", &end); + } + dmuci_set_value_by_section(((struct bridging_args *)data)->bridge_sec, "ifname", final_list); + + /* Remove the vlan instance from the dmmap_network file. */ + char *name; + dmasprintf(&name, "%s_%s", "vlan", ((struct bridging_vlan_args *)data)->br_inst); + get_dmmap_section_of_config_section("dmmap_network", "vlan", name, &dmmap_section); + dmuci_delete_by_section(dmmap_section, NULL, NULL); + return 0; } @@ -1196,7 +1598,7 @@ static int delete_br_port(char *refparam, struct dmctx *ctx, void *data, char *i if (ifname[0] != '\0') { remove_interface_from_ifname(((struct bridging_port_args *)data)->ifname, ifname, new_ifname); dmuci_set_value_by_section(((struct bridging_port_args *)data)->bridge_sec, "ifname", new_ifname); - } +} get_dmmap_section_of_config_section("dmmap_bridge_port", "bridge_port", section_name(((struct bridging_port_args *)data)->bridge_port_sec), &dmmap_section); dmuci_delete_by_section_unnamed_bbfdm(dmmap_section, NULL, NULL); } @@ -1218,9 +1620,9 @@ static int delete_br_port(char *refparam, struct dmctx *ctx, void *data, char *i /************************************************************* * LOWER LAYER **************************************************************/ -static int check_port_with_ifname (char *ifname, struct uci_section **ss) +static int check_port_with_ifname (char *ifname, struct uci_section **ss, int *is_tag) { - struct uci_section *sss, *s; + struct uci_section *sss = NULL, *s = NULL; char *file_config_name; char *atm_device, *ptm_device; @@ -1257,8 +1659,10 @@ static int check_port_with_ifname (char *ifname, struct uci_section **ss) } } } - } else if (strncmp(ifname, wan_baseifname, strlen(wan_baseifname)) == 0) { - uci_foreach_option_eq("network", "device", "name", ifname, s) { + } else if (strncmp(ifname, wan_baseifname, strlen(ifname)) == 0) { + /* Fix: For eth4, not entry will be found in "network", "device". + * Entry for untagged interfaces would be there. */ + uci_foreach_option_eq("ports", "ethport", "ifname", ifname, s) { *ss = s; break; } @@ -1268,10 +1672,37 @@ static int check_port_with_ifname (char *ifname, struct uci_section **ss) break; } } else { - uci_foreach_option_eq("ports", "ethport", "ifname", ifname, s) { - *ss = s; - break; + /* Fix : Add support for untagged interfaces(vlan id =1) in lower layer. */ + char intf[50] = {0}; + strncpy(intf, ifname, sizeof(intf)); + char *p = strstr(intf, "."); + if(p) { + char *token , *end= NULL; + token = strtok_r(intf, ".", &end); + if (NULL != token) { + char tag[50] = {0}; + strncpy(tag, end, sizeof(tag)); + if (strncmp(tag, "1", sizeof(tag)) == 0) { + uci_foreach_option_eq("network", "device", "name", ifname, s) { + *ss = s; + break; + } + } else { + /* Fix : Add support for tagged interfaces in lower layer. */ + uci_foreach_option_eq("ports", "ethport", "ifname", token, s) { + *is_tag = 1; + *ss = s; + break; + } + } + } + } else { + uci_foreach_option_eq("ports", "ethport", "ifname", ifname, s) { + *ss = s; + break; + } } + } return 0; } @@ -1288,7 +1719,9 @@ static int get_port_lower_layer(char *refparam, struct dmctx *ctx, void *data, c ifname_dup = dmstrdup(ifname); p = lbuf; for (pch = strtok_r(ifname_dup, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch)) { - check_port_with_ifname(pch, &s); + /* Fix: Added support for tagged and untagged interfaces. */ + int is_tag = 0; + check_port_with_ifname(pch, &s, &is_tag); if(s == NULL) continue; snprintf(plinker, sizeof(plinker), "%s+%s", section_name(s), pch); @@ -1327,93 +1760,85 @@ static int get_port_lower_layer(char *refparam, struct dmctx *ctx, void *data, c return 0; } +static void set_bridge_port_parameters(struct uci_section *dmmap_section, char* bridge_key) +{ + DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_section, "bridge_key", bridge_key); + DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_section, "mg_port", "false"); + DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_section, "penable", "1"); + DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_section, "is_dmmap", "false"); +} + static int set_port_lower_layer(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - char *linker, *ifname, *p, *br_key, *br_pt_inst = "", *mg_port = "false", *vid = NULL; - char *newvalue= NULL; - char new_ifname[256]; - char tmp[16]; - char pr_linker[32]; - struct uci_section *s; - struct uci_section *dmmap_section= NULL; + /* Fix : Set lower layer value from management methods. */ + char *linker_intf, *br_key; + char *newvalue = NULL; switch (action) { case VALUECHECK: - if (dm_validate_string_list(value, -1, -1, 1024, -1, -1, NULL, 0, NULL, 0)) - return FAULT_9007; - get_dmmap_section_of_config_section("dmmap_bridge_port", "bridge_port", section_name(((struct bridging_port_args *)data)->bridge_port_sec), &dmmap_section); - dmuci_get_value_by_section_string(dmmap_section, "mg_port", &mg_port); - if (value[strlen(value)-1]!='.') { - dmasprintf(&newvalue, "%s.", value); - adm_entry_get_linker_value(ctx, newvalue, &linker); - } else - adm_entry_get_linker_value(ctx, value, &linker); - if (strcmp(mg_port, "false")!=0 && linker && !check_ifname_exist_in_br_ifname_list(linker)) - return FAULT_9001; + /* Fix : adding of lower layer. */ return 0; case VALUESET: if (value[strlen(value)-1]!='.') { dmasprintf(&newvalue, "%s.", value); - adm_entry_get_linker_value(ctx, newvalue, &linker); - } else - adm_entry_get_linker_value(ctx, value, &linker); - //check ifname(linker) doesn't exit in bridges - if (linker && check_ifname_exist_in_br_ifname_list(linker)) { - //save param of current port and copy it to new port - dmuci_get_value_by_section_string(((struct bridging_port_args *)data)->bridge_port_sec, "bridge_key", &br_key); - dmuci_get_value_by_section_string(((struct bridging_port_args *)data)->bridge_port_sec, "bridge_port_instance", &br_pt_inst); - dmuci_get_value_by_section_string(((struct bridging_port_args *)data)->bridge_port_sec, "mg_port", &mg_port); - //remove old port (ifname) from bridge - if (((struct bridging_port_args *)data)->ifname[0] != 0 && strcmp(((struct bridging_port_args *)data)->ifname, linker) != 0) { - delete_br_port(NULL, ctx, data, instance, DEL_INST); - } - // check if the current port is already linked with VLAN - snprintf(pr_linker, sizeof(pr_linker), "%s+%s", section_name(((struct bridging_port_args *)data)->bridge_port_sec), ((struct bridging_port_args *)data)->ifname); - uci_foreach_option_eq("network", "device", "br_port_linker", pr_linker, s) { - dmuci_get_value_by_section_string(s, "vlan8021q", &vid); - break; - } - dmuci_get_value_by_section_string(((struct bridging_port_args *)data)->bridge_sec, "ifname", &ifname); - p = new_ifname; - if (ifname[0] != '\0') { - dmstrappendstr(p, ifname); - dmstrappendchr(p, ' '); - } - if(vid && check_ifname_is_not_lan_port(linker) && !strstr (linker, "wl")) { - strncpy(tmp, linker, 5); - tmp[5] = '\0'; - strcat(tmp, vid); - linker = tmp; - dmstrappendstr(p, tmp); - dmstrappendend(p); - uci_foreach_option_eq("network", "device", "br_port_linker", pr_linker, s) { - snprintf(pr_linker, sizeof(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); - dmuci_set_value_by_section(s, "penable", "1"); - } - } else { - dmstrappendstr(p, linker); - dmstrappendend(p); - } - dmuci_set_value_by_section(((struct bridging_port_args *)data)->bridge_sec, "ifname", new_ifname); - //remove old br_port param to the new one - update_port_parameters(linker, br_key, br_pt_inst, mg_port); - if(((struct bridging_port_args *)data)->ifname[0] == '\0') - DMUCI_DELETE_BY_SECTION(bbfdm,((struct bridging_port_args *)data)->bridge_port_sec, NULL, NULL);// delete dmmap section after remove br_port_instance to adequate config + adm_entry_get_linker_value(ctx, newvalue, &linker_intf); } else { - return FAULT_9005; + adm_entry_get_linker_value(ctx, value, &linker_intf); } - return 0; - } + + /* If linker value is eth5.1, then change it to eth5. */ + char *linker = NULL; + char if_name[20] = {0}; + char intf[20] = {0}; + strncpy(intf, linker_intf, sizeof(intf)); + + if (strncmp(intf, "eth5.1", sizeof(intf)) == 0) { + char *tok = strtok(intf, "."); + if (tok != NULL) { + strncpy(if_name, tok, sizeof(if_name)); + linker = if_name; + } + } else { + strncpy(if_name, linker_intf, sizeof(if_name)); + linker = if_name; + } + + /* Check if the ifname is present in the network UCI file under the bridge section name + * obtained from the refparam. */ + if (linker && check_ifname_exist_in_br_ifname_list(linker, section_name(((struct bridging_port_args *)data)->bridge_sec))) { + // Do nothing + } else { + /* Fetch the value of ifname from the UCI. */ + char *name; + + dmuci_get_value_by_section_string(((struct bridging_port_args *)data)->bridge_sec, "ifname", &name); + + /* Fetch the bridge key associated with the ifname. */ + dmuci_get_value_by_section_string(((struct bridging_port_args *)data)->bridge_port_sec, "bridge_key", &br_key); + + char intf_name[250] = {0}; + strncpy(intf_name, name, sizeof(intf_name)); + /* Append the interface name to it. */ + if (intf_name[0] != '\0') { + strcat(intf_name, " "); + } + strcat(intf_name, linker); + + synchronize_multi_config_sections_with_dmmap_set("ports", "ethport", "dmmap_bridge_port", "bridge_port", "ifname", linker, instance, br_key); + + dmuci_set_value_by_section(((struct bridging_port_args *)data)->bridge_sec, "ifname", intf_name); + + } + } return 0; } static int get_vlan_port_vlan_ref(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { + int cnt = 1; // For now this will only work for Bridges with 1 VLAN only char linker[8]; - snprintf(linker, sizeof(linker), "vlan%s_%s", ((struct bridging_vlan_args *)data)->vlan_port, ((struct bridging_vlan_args *)data)->br_inst); - adm_entry_get_linker_param(ctx, dm_print_path("%s%cBridging%cBridge%c", dmroot, dm_delim, dm_delim, dm_delim), linker, value); // MEM WILL BE FREED IN DMMEMCLEAN + snprintf(linker, sizeof(linker),"vlan%d_%s", cnt, ((struct bridging_vlan_args *)data)->br_inst); + adm_entry_get_linker_param(ctx, dm_print_path("%s%cBridging%cBridge%c", dmroot, dm_delim, dm_delim, dm_delim), linker, value); if (*value == NULL) *value = ""; return 0; @@ -1434,74 +1859,179 @@ static int set_vlan_port_vlan_ref(char *refparam, struct dmctx *ctx, void *data, static int get_vlan_port_port_ref(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - char linker[16], *name; - dmuci_get_value_by_section_string(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "name", &name); - snprintf(linker, sizeof(linker), "%s+%s", section_name(((struct bridging_vlan_args *)data)->bridge_vlan_sec), name); - adm_entry_get_linker_param(ctx, dm_print_path("%s%cBridging%cBridge%c", dmroot, dm_delim, dm_delim, dm_delim), linker, value); // MEM WILL BE FREED IN DMMEMCLEAN - if (*value == NULL) + int cnt = 1; + char *pch, *spch, *ifname, *ifname_dup; + char plinker[32]; + struct uci_section *s = NULL; + + + dmuci_get_value_by_section_string(((struct bridging_port_args *)data)->bridge_sec, "ifname", &ifname); + + if (ifname[0] != '\0') { + ifname_dup = dmstrdup(ifname); + for (pch = strtok_r(ifname_dup, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch)) { + if (cnt == atoi(instance)) { + + /* Fix: Added support for tagged and untagged interfaces. */ + int is_tag = 0; + check_port_with_ifname(pch, &s, &is_tag); + if(s == NULL) { + continue; + } + + snprintf(plinker, sizeof(plinker), "%s+%s", section_name(s), pch); + adm_entry_get_linker_param(ctx, dm_print_path("%s%cBridging%cBridge%c", dmroot, dm_delim, dm_delim, dm_delim), plinker, value); + + if (*value == NULL) + *value = ""; + + break; + } else { + cnt++; + } + } + } else { *value = ""; + } + return 0; } static int set_vlan_port_port_ref(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - char *linker = NULL, *vid, *enable, *vifname, *pch, *p, *br_ifname, tmp[8], new_ifname[16]; + char *linker = NULL, *newvalue; + struct bridging_args *br_args = (struct bridging_args *)data; + struct uci_section *s, *sec; switch (action) { case VALUECHECK: - if (dm_validate_string(value, -1, 256, NULL, 0, NULL, 0)) - return FAULT_9007; return 0; case VALUESET: - adm_entry_get_linker_value(ctx, value, &linker); - if (!linker) { - dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "br_port_linker", ""); - set_br_vlan_enable(refparam, ctx, data, instance, "false", action); - return 0; - } - dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "br_port_linker", linker); - dmuci_get_value_by_section_string(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "vlan8021q", &vid); - pch = strchr(linker, '+') + 1; - if (pch[0] == '\0') { - dmfree(linker); - return 0; - } - if (vid[0] == '\0') { - 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, "ifname", tmp); - } + if (value[strlen(value)-1]!='.') { + dmasprintf(&newvalue, "%s.", value); + adm_entry_get_linker_value(ctx, newvalue, &linker); } 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, "ifname", tmp); - dmstrappendstr(p, tmp); - dmstrappendchr(p, '.'); - dmstrappendstr(p, vid); - dmstrappendend(p); - dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "ifname", new_ifname); - dmuci_get_value_by_section_string(((struct bridging_vlan_args *)data)->bridge_vlan_sec, "penable", &enable);///TO CHECK - // add to bridge ifname if enable = 1 - if (enable[0] == '1') { - vifname = dmstrdup(new_ifname); - dmuci_get_value_by_section_string(((struct bridging_vlan_args *)data)->bridge_sec, "ifname", &br_ifname); - p = new_ifname; - if (br_ifname[0] != '\0') { - dmstrappendstr(p, br_ifname); - dmstrappendchr(p, ' '); - } - dmstrappendstr(p, vifname); - dmstrappendend(p); - dmuci_set_value_by_section(((struct bridging_vlan_args *)data)->bridge_sec, "ifname", new_ifname); - dmfree(vifname); - } + adm_entry_get_linker_value(ctx, value, &linker); + } + + if (!linker) { + return -1; + } + + /* Get the interface name from linker. */ + char intf[50] = {0}; + char *p = strstr(linker, "+"); + if (p) { + strncpy(intf, p+1, sizeof(intf)); + } else { + return -1; + } + + /* Using bridge key, check if vlan port instance exists in vlan port dmmap. */ + int ret = 0; + uci_path_foreach_option_eq(bbfdm, "dmmap_network", "vlanport", "bridge_key", br_args->br_inst, s) { + char *tmp; + dmuci_get_value_by_section_string(s, "vport_inst", &tmp); + + char inst[10] = {0}; + strncpy(inst, instance, sizeof(inst)); + + if (strncmp(inst, tmp, sizeof(inst)) == 0) { + ret = 1; + break; } } - dmfree(linker); - return 0; + + if (ret == 0) { + return -1; + } + + /* Get vlan_id from interface section using bridge_key. */ + char *vlan_id; + uci_path_foreach_option_eq(bbfdm, "dmmap_network", "interface", "bridge_key", br_args->br_inst, sec) { + dmuci_get_value_by_section_string(sec, "vlan_id", &vlan_id); + } + + if (*vlan_id == '\0') { + return -1; + } + + /* Combine vid wd linker. */ + char new_if[50] = {0}; + snprintf(new_if, sizeof(new_if), "%s.%s", intf, vlan_id); + + /* Check if the new name is present in UCI. If yes do nothing, if no + * then update vlanport and UCI wd new ifname.*/ + char *br_ifname; + dmuci_get_value_by_section_string(((struct bridging_args *)data)->bridge_sec, "ifname", &br_ifname); + + char new_ifname[250] = {0}; + char *tok, *end; + tok = strtok_r(br_ifname, " ", &end); + while (tok != NULL) { + /* check if intf matches with tok. */ + if (strncmp(intf, tok, sizeof(intf)) == 0) { + /* Check if tok and new_if are same or not. */ + if (strncmp(new_if, tok, sizeof(new_if)) == 0) { + /* Do nothing. */ + } else { + /* Check the vid of existing ifname, and remove + * the config device section if vid is one. + * Also update the ifname wd new name. */ + char if_tag[10] = {0}; + strncpy(if_tag, tok, sizeof(if_tag)); + + char *token, *tag; + token = strtok_r(if_tag, ".", &tag); + if (tag != NULL) { + char vid[10] = {0}; + strncpy(vid, tag, sizeof(vid)); + + if (strncmp(vid, "1", sizeof(vid)) == 0) { + /* remove device section. */ + struct uci_section *sec = NULL; + uci_foreach_option_eq("network", "device", "name", tok, sec) { + dmuci_delete_by_section(sec, "name", tok); + dmuci_delete_by_section(sec, "type", "untagged"); + dmuci_delete_by_section(sec, "ifname", if_tag); + } + } + } + if (new_ifname[0] != '\0') { + strcat(new_ifname, " "); + } + strcat(new_ifname, new_if); + + /* Add ifname to vlanport section in dmmap. */ + uci_path_foreach_option_eq(bbfdm, "dmmap_network", "vlanport", "vport_inst", instance, sec) { + dmuci_set_value_by_section(sec, "ifname", new_if); + } + + /* IF vlan id fro the new ifname is 1, then add device section.*/ + char vd[10] = {0}; + char *val; + strncpy(vd, vlan_id, sizeof(vd)); + + if (strncmp(vd, "1", sizeof(vd)) == 0) { + dmuci_add_section_and_rename("network", "device", &sec, &val); + dmuci_set_value_by_section(sec, "name", new_if); + dmuci_set_value_by_section(sec, "type", "untagged"); + dmuci_set_value_by_section(sec, "ifname", intf); + + + } + } + } else { + if (new_ifname[0] != '\0') { + strcat(new_ifname, " "); + } + strcat(new_ifname, tok); + } + tok = strtok_r(NULL, " ", &end); + } + + dmuci_set_value_by_section(((struct bridging_args *)data)->bridge_sec, "ifname", new_ifname); + break; } return 0; } @@ -1533,7 +2063,7 @@ static int browseBridgeInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev { char *br_inst = NULL, *br_inst_last = NULL, *ifname; struct bridging_args curr_bridging_args = {0}; - struct dmmap_dup *p; + struct dmmap_dup *p = NULL; LIST_HEAD(dup_list); dmuci_get_option_value_string("ports", "WAN", "ifname", &wan_baseifname); @@ -1550,20 +2080,13 @@ static int browseBridgeInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev return 0; } -static void set_bridge_port_parameters(struct uci_section *dmmap_section, char* bridge_key) -{ - DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_section, "bridge_key", bridge_key); - DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_section, "mg_port", "false"); - DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_section, "penable", "1"); - DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_section, "is_dmmap", "false"); -} static int browseBridgePortInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance){ struct uci_section *new_port = NULL, *ss_atm = NULL, *ss_ptm = NULL; char *port = NULL, *port_last = NULL, *ifname_dup = NULL, *pch, *spch, *is_dmmap, *file_config_name, *deviceatm, *deviceptm, *atm_device, *ptm_device; bool find_max = true, found = false; struct bridging_port_args curr_bridging_port_args = {0}; - struct dmmap_dup *p; + struct dmmap_dup *p = NULL; LIST_HEAD(dup_list); dmasprintf(&file_config_name, "%s","/etc/config/dsl"); @@ -1581,12 +2104,36 @@ static int browseBridgePortInst(struct dmctx *dmctx, DMNODE *parent_node, void * if (((struct bridging_args *)prev_data)->ifname[0] == '\0') return 0; + ifname_dup = dmstrdup(((struct bridging_args *)prev_data)->ifname); + char tagged_intf[250] = {0}; + strncpy(tagged_intf, ifname_dup, sizeof(tagged_intf)); for (pch = strtok_r(ifname_dup, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch)) { found = false; - if (!found) - found= synchronize_multi_config_sections_with_dmmap_eq("ports", "ethport", "dmmap_bridge_port", "bridge_port", "ifname", pch, pch, &dup_list); + if (!found) { + /* Fix : Add support for untagged interfaces.*/ + char val[50] = {0}; + strncpy(val, pch, sizeof(val)); + char *p = strstr(val, "."); + if (p) { + char *tok, *tok_end; + tok = strtok_r(val, ".", &tok_end); + if (tok != NULL) { + char tag[20] = {0}; + strncpy(tag, tok_end, sizeof(tag)); + if (strncmp(tag, "1", sizeof(tag)) == 0) { + found= synchronize_multi_config_sections_with_dmmap_eq("network", "device", "dmmap_bridge_port", "bridge_port", "name", pch, pch, &dup_list); + } else { + /* Fix : Add support for tagged interfaces(eth0.100, eth1.200 etc).*/ + found= synchronize_multi_config_sections_with_dmmap_eq("ports", "ethport", "dmmap_bridge_port", "bridge_port", "ifname", tok, pch, &dup_list); + } + } + } else { + /* Add support for interfaces eth0, eth1, eth2.....etc.*/ + found= synchronize_multi_config_sections_with_dmmap_eq("ports", "ethport", "dmmap_bridge_port", "bridge_port", "ifname", pch, pch, &dup_list); + } + } if (!found) found= synchronize_multi_config_sections_with_dmmap_eq("wireless", "wifi-iface", "dmmap_bridge_port", "bridge_port", "ifname", pch, pch, &dup_list); @@ -1642,29 +2189,42 @@ end: /*#Device.Bridging.Bridge.{i}.VLAN.!UCI:network/device/dmmap_network*/ static int browseBridgeVlanInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) { - char *vlan = NULL, *vlan_last = NULL, *type, *is_lan = NULL; + char *vlan = NULL, *vlan_last = NULL; struct bridging_vlan_args curr_bridging_vlan_args = {0}; struct bridging_args *br_args = (struct bridging_args *)prev_data; - struct dmmap_dup *p; + struct dmmap_dup *p = NULL; + struct uci_section *sec = NULL, *section = NULL; + int count = 0; + char id; LIST_HEAD(dup_list); - dmuci_get_value_by_section_string(br_args->bridge_sec, "is_lan", &is_lan); - if (is_lan == NULL || strcmp(is_lan, "1") != 0) { - synchronize_specific_config_sections_with_dmmap("network", "device", "dmmap_network", &dup_list); + synchronize_specific_config_sections_with_dmmap_vlan("network", "interface", "dmmap_network", br_args->ifname, &dup_list, &count, &id); + /* Fix : TO add bridge object and lower layer through management method. */ + if (count != 0) { list_for_each_entry(p, &dup_list, list) { if(!p->config_section) goto end; - //Check if VLAN or NOT - dmuci_get_value_by_section_string(p->config_section, "type", &type); - if (strcmp(type, "untagged") != 0) { - dmuci_set_value_by_section(p->dmmap_section, "bridge_key", br_args->br_key); - vlan = handle_update_instance(2, dmctx, &vlan_last, update_instance_alias, 3, p->dmmap_section, "bridge_vlan_instance", "bridge_vlan_alias"); - init_bridging_vlan_args(&curr_bridging_vlan_args, p->config_section, 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) + + dmuci_set_value_by_section(p->dmmap_section, "bridge_key", br_args->br_key); + dmuci_set_value_by_section(p->dmmap_section, "vlan_id", &id); + vlan = handle_update_instance(2, dmctx, &vlan_last, update_instance_alias, 3, p->dmmap_section, "bridge_vlan_instance", "bridge_vlan_alias"); + init_bridging_vlan_args(&curr_bridging_vlan_args, p->config_section, 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; + } + + free_dmmap_config_dup_list(&dup_list); + } else { + /* Check if config vlan section is present in the dmmap_network. */ + uci_path_foreach_option_eq(bbfdm, "dmmap_network", "vlan", "bridge_instance", br_args->br_inst, sec) { + uci_path_foreach_option_eq(bbfdm, "dmmap_network", "interface", "bridge_instance", br_args->br_inst, section) { + dmuci_set_value_by_section(section, "bridge_key", br_args->br_key); + vlan = handle_update_instance(2, dmctx, &vlan_last, update_instance_alias, 3, section, "bridge_vlan_instance", "bridge_vlan_alias"); + init_bridging_vlan_args(&curr_bridging_vlan_args, section, 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; } } - free_dmmap_config_dup_list(&dup_list); } end: return 0; @@ -1673,29 +2233,90 @@ end: /*#Device.Bridging.Bridge.{i}.VLANPort.!UCI:network/device/dmmap_network*/ static int browseBridgeVlanPortInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) { - char *vlan = NULL, *vlan_last = NULL, *type, *is_lan = NULL; + int cnt = 1; + char *vlan; + char *br_ifname_list, *br_ifname_dup, *pch, *spch; struct bridging_vlan_args curr_bridging_vlan_args = {0}; struct bridging_args *br_args = (struct bridging_args *)prev_data; - struct dmmap_dup *p; - LIST_HEAD(dup_list); + struct uci_section *sec = NULL; + + dmuci_get_value_by_section_string(br_args->bridge_sec, "ifname", &br_ifname_list); + + if(br_ifname_list[0] == '\0') { + /* Check if dmmap vlanport section is present. If present create link for it + * with empty fileds. */ + uci_path_foreach_option_eq(bbfdm, "dmmap_network", "vlanport", "bridge_key", br_args->br_key, sec) { + char *tmp; + dmuci_get_value_by_section_string(sec, "ifname", &tmp); + if (*tmp == '\0') { + dmasprintf(&vlan, "%d", cnt); + init_bridging_vlan_args(&curr_bridging_vlan_args, br_args->bridge_sec, br_args->bridge_sec, NULL, br_args->br_key); - dmuci_get_value_by_section_string(br_args->bridge_sec, "is_lan", &is_lan); - if (is_lan == NULL || strcmp(is_lan, "1") != 0) { - synchronize_specific_config_sections_with_dmmap("network", "device", "dmmap_network", &dup_list); - list_for_each_entry(p, &dup_list, list) { - if(!p->config_section) - goto end; - //Check if VLAN or NOT - dmuci_get_value_by_section_string(p->config_section, "type", &type); - if (strcmp(type, "untagged") != 0) { - dmuci_set_value_by_section(p->dmmap_section, "bridge_key", br_args->br_key); - vlan = handle_update_instance(2, dmctx, &vlan_last, update_instance_alias, 3, p->dmmap_section, "bridge_vlan_instance", "bridge_vlan_alias"); - init_bridging_vlan_args(&curr_bridging_vlan_args, p->config_section, 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; + + cnt++; + + } + } + + } else { + + br_ifname_dup = dmstrdup(br_ifname_list); + for (pch = strtok_r(br_ifname_dup, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch)) { + int ret = 0; + if (strstr(pch, ".") == NULL) { + continue; + } + + dmasprintf(&vlan, "%d", cnt); + init_bridging_vlan_args(&curr_bridging_vlan_args, br_args->bridge_sec, br_args->bridge_sec, NULL, br_args->br_key); + + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_bridging_vlan_args, vlan) == DM_STOP) + goto end; + + cnt++; + + /* Check if the vlanport section is not present for the interface. */ + struct uci_section *s = NULL; + uci_path_foreach_option_eq(bbfdm, "dmmap_network", "vlanport", "ifname", pch, s) { + ret = 1; + break; + } + + if (ret == 0) { + /* Add vlanport section in dmmap_network. */ + struct uci_section *dmmap_port = NULL; + char *v, *name; + dmuci_add_section_bbfdm("dmmap_network", "vlanport", &dmmap_port, &v); + dmuci_set_value_by_section(dmmap_port, "bridge_key", br_args->br_key); + /* Get the last vlan_instance and add one. */ + int m = get_vlanport_last_inst(br_args->br_key); + char instance[10]; + sprintf(instance, "%d", m+1); + dmuci_set_value_by_section(dmmap_port, "vport_inst", instance); + dmasprintf(&name, "%s_%d", "vlanport", m); + dmuci_set_value_by_section(dmmap_port, "section_name", name); + dmuci_set_value_by_section(dmmap_port, "ifname", pch); + } + } + + /* Also check if any dmmap vlanport section is present without ifname. + * If present, then create the link. */ + uci_path_foreach_option_eq(bbfdm, "dmmap_network", "vlanport", "bridge_key", br_args->br_key, sec) { + char *tmp; + dmuci_get_value_by_section_string(sec, "ifname", &tmp); + if (*tmp == '\0') { + dmasprintf(&vlan, "%d", cnt); + init_bridging_vlan_args(&curr_bridging_vlan_args, br_args->bridge_sec, br_args->bridge_sec, NULL, br_args->br_key); + + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_bridging_vlan_args, vlan) == DM_STOP) + goto end; + + cnt++; + } } - free_dmmap_config_dup_list(&dup_list); } end: return 0; @@ -1725,7 +2346,7 @@ DMOBJ tBridgingBridgeObj[] = { /* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Port", &DMWRITE, add_br_port, delete_br_port, NULL, browseBridgePortInst, NULL, NULL, NULL, tBridgingBridgePortObj, tBridgingBridgePortParams, get_linker_br_port, BBFDM_BOTH}, {"VLAN", &DMWRITE, add_br_vlan, delete_br_vlan, NULL, browseBridgeVlanInst, NULL, NULL, NULL, NULL, tBridgingBridgeVLANParams, get_linker_br_vlan, BBFDM_BOTH}, -{"VLANPort", &DMREAD, NULL, NULL, NULL, browseBridgeVlanPortInst, NULL, NULL, NULL, NULL, tBridgingBridgeVLANPortParams, NULL, BBFDM_BOTH}, +{"VLANPort", &DMWRITE, add_br_vlanport, delete_br_vlanport, NULL, browseBridgeVlanPortInst, NULL, NULL, NULL, NULL, tBridgingBridgeVLANPortParams, NULL, BBFDM_BOTH}, {0} }; @@ -1738,7 +2359,6 @@ DMLEAF tBridgingBridgeParams[] = { {"PortNumberOfEntries", &DMREAD, DMT_UNINT, get_br_port_number_of_entries, NULL, NULL, NULL, BBFDM_BOTH}, {"VLANNumberOfEntries", &DMREAD, DMT_UNINT, get_br_vlan_number_of_entries, NULL, NULL, NULL, BBFDM_BOTH}, {"VLANPortNumberOfEntries", &DMREAD, DMT_UNINT, get_br_vlan_port_number_of_entries, NULL, NULL, NULL, BBFDM_BOTH}, -{CUSTOM_PREFIX"AssociatedInterfaces", &DMWRITE, DMT_STRING, get_br_associated_interfaces, set_br_associated_interfaces, NULL, NULL, BBFDM_BOTH}, {0} }; @@ -1794,7 +2414,7 @@ DMLEAF tBridgingBridgeVLANParams[] = { {"Enable", &DMWRITE, DMT_BOOL, get_br_vlan_enable, set_br_vlan_enable, NULL, NULL, BBFDM_BOTH}, {"Alias", &DMWRITE, DMT_STRING,get_br_vlan_alias, set_br_vlan_alias, NULL, NULL, BBFDM_BOTH}, {"Name", &DMWRITE, DMT_STRING, get_br_vlan_name, set_br_vlan_name, NULL, NULL, BBFDM_BOTH}, -{"VLANID", &DMWRITE, DMT_INT, get_br_vlan_vid, set_br_vlan_vid, NULL, NULL, BBFDM_BOTH}, +{"VLANID", &DMWRITE, DMT_STRING, get_br_vlan_vid, set_br_vlan_vid, NULL, NULL, BBFDM_BOTH}, {CUSTOM_PREFIX"VLANPriority", &DMWRITE, DMT_STRING, get_br_vlan_priority, set_br_vlan_priority, NULL, NULL, BBFDM_BOTH}, {0} }; diff --git a/dmtree/tr181/ethernet.c b/dmtree/tr181/ethernet.c index ddd2d100..5dde0418 100644 --- a/dmtree/tr181/ethernet.c +++ b/dmtree/tr181/ethernet.c @@ -47,6 +47,24 @@ static int eth_port_sysfs(const struct eth_port_args *args, const char *name, ch return get_net_device_sysfs(args->ifname, name, value); } +static int is_device_exist(char *device) +{ + struct uci_section *s = NULL; + char *dev; + + uci_path_foreach_sections(bbfdm, DMMAP, "link", s) { + dmuci_get_value_by_section_string(s, "device", &dev); + + char *p = strtok(dev, "."); + if (p != NULL) { + if (strcmp(p, device) == 0) { + return 1; + } + } + } + return 0; +} + static int is_mac_exist(char *macaddr) { struct uci_section *s = NULL; @@ -74,24 +92,63 @@ static void create_link(char *ifname) return; /* Interfaces might share the same mac address */ - if (is_mac_exist(macaddr)) + if (is_mac_exist(macaddr)) { return; + } - dmuci_add_section_bbfdm(DMMAP, "link", &dmmap, &v); - dmuci_set_value_by_section(dmmap, "mac", macaddr); - dmuci_set_value_by_section(dmmap, "device", device); - dmuci_set_value_by_section(dmmap, "section_name", ifname); + /* Fix: For all the Ethernet link objects pointing to same Ethernet Interface, + * we can omit creating multiple Ethernet link entries.*/ + char intf[250] = {0}; + strncpy(intf, device, sizeof(intf)); + char *p = strtok(intf, "."); + if (p != NULL) { + if (is_device_exist(p)) { + return; + } + } + + /* Check if section_name exists or not, if yes then do not add section just update + * the params else add section and update the params. */ + + struct uci_section *s = NULL; + char *sec_name; + int ret = 1; + + uci_path_foreach_sections(bbfdm, DMMAP, "link", s) { + dmuci_get_value_by_section_string(s, "section_name", &sec_name); + if (strcmp(ifname, sec_name) == 0) { + dmuci_set_value_by_section(s, "mac", macaddr); + dmuci_set_value_by_section(s, "device", device); + dmuci_set_value_by_section(s, "section_name", ifname); + ret = 0; + break; + + } else { + ret = 1; + } + } + + if (ret == 1 ) { + dmuci_add_section_bbfdm(DMMAP, "link", &dmmap, &v); + dmuci_set_value_by_section(dmmap, "mac", macaddr); + dmuci_set_value_by_section(dmmap, "device", device); + dmuci_set_value_by_section(dmmap, "section_name", ifname); + } } static int dmmap_synchronizeEthernetLink(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) { struct uci_section *s = NULL; - char *type, *ifname; + char *type, *ifname, *proto; uci_foreach_sections("network", "interface", s) { dmuci_get_value_by_section_string(s, "type", &type); - if (strcmp(type, "alias") == 0 || strcmp(section_name(s), "loopback") == 0) + /* Fix: The creating of multiple ethernet links.*/ + dmuci_get_value_by_section_string(s, "proto", &proto); + if (strcmp(type, "alias") == 0 || strcmp(section_name(s), "loopback") == 0 || + *proto == '\0') { continue; + } dmuci_get_value_by_section_string(s, "ifname", &ifname); if (*ifname == '\0' || *ifname == '@') @@ -110,7 +167,7 @@ static int browseEthernetInterfaceInst(struct dmctx *dmctx, DMNODE *parent_node, { char *int_num = NULL, *int_num_last = NULL, *ifname; struct eth_port_args curr_eth_port_args = {0}; - struct dmmap_dup *p; + struct dmmap_dup *p = NULL; LIST_HEAD(dup_list); synchronize_specific_config_sections_with_dmmap("ports", "ethport", "dmmap_ports", &dup_list); @@ -152,15 +209,72 @@ static int browseEthernetVLANTerminationInst(struct dmctx *dmctx, DMNODE *parent { char *vlan_term = NULL, *vlan_term_last = NULL, *type= NULL, *vlan_method= NULL; struct dm_args curr_vlan_term_args = {0}; - struct dmmap_dup *p; + struct dmmap_dup *p = NULL; LIST_HEAD(dup_list); - synchronize_specific_config_sections_with_dmmap("network", "device", "dmmap_network", &dup_list); + /* Fix : Creating of vlan instance for only upstream interface with proto defined. */ + synchronize_specific_config_sections_with_dmmap("network", "interface", "dmmap_network", &dup_list); list_for_each_entry(p, &dup_list, list) { dmuci_get_value_by_section_string(p->config_section, "type", &type); dmuci_get_option_value_string("cwmp", "cpe", "vlan_method", &vlan_method); if ((strcmp(vlan_method, "2") != 0 && strcmp(vlan_method, "1") != 0) || (strcmp(vlan_method, "1") == 0 && strcmp(type, "untagged") == 0) ) continue; + + char *proto; + dmuci_get_value_by_section_string(p->config_section, "proto", &proto); + if (*proto == '\0') { + continue; + } + + char *ifname; + dmuci_get_value_by_section_string(p->config_section, "ifname", &ifname); + if (*ifname == '\0') { + continue; + } + + char intf[250] = {0}; + strncpy(intf, ifname, sizeof(intf)); + + char *if_name = strtok(intf, " "); + if (NULL != if_name) { + + char name[250] = {0}; + strncpy(name, if_name, sizeof(name)); + + /* Support for both vlans and macvlans. */ + int macvlan = 0; + char *p = strstr(name, "."); + if (!p) { + char *t = strstr(name, "_"); + if (t) { + macvlan = 1; + } else { + continue; + } + } + + char *tok, *end; + if (macvlan == 1) { + tok = strtok_r(name, "_", &end); + } else { + tok = strtok_r(name, ".", &end); + } + + if (end == NULL) { + continue; + } + + if (macvlan == 0) { + char tag[20] = {0}; + strncpy(tag, end, sizeof(tag)); + + + if (strncmp(tag, "1", sizeof(tag)) == 0) { + continue; + } + } + } + curr_vlan_term_args.section = p->config_section; if(strcmp(vlan_method, "2") == 0) vlan_term = handle_update_instance(1, dmctx, &vlan_term_last, update_instance_alias, 3, p->dmmap_section, "all_vlan_term_instance", "all_vlan_term_alias"); @@ -190,14 +304,16 @@ static int get_linker_interface(char *refparam, struct dmctx *dmctx, void *data, static int get_linker_link(char *refparam, struct dmctx *dmctx, void *data, char *instance, char **linker) { - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "section_name", linker); + /* Fix: for get linker link */ + dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "mac", linker); return 0; } static int get_linker_vlan_term(char *refparam, struct dmctx *dmctx, void *data, char *instance, char **linker) { + /* Fix: linker should be fetched using ifname. */ if(((struct dm_args *)data)->section) { - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "name", linker); + dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "ifname", linker); return 0; } else { *linker = ""; @@ -226,11 +342,29 @@ static int delObjEthernetLink(char *refparam, struct dmctx *ctx, void *data, cha struct uci_section *s = NULL; switch (del_action) { case DEL_INST: + /* Fix : Deletion of EthernetLink to support L2 VLAN deployments. */ dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "section_name", §_name); get_config_section_of_dmmap_section("network", "interface", sect_name, &s); if(!s) { dmuci_delete_by_section(((struct dm_args *)data)->section, NULL, NULL); return 0; + } else { + /* Get section from section_name.*/ + struct uci_section *intf_s = NULL; + uci_foreach_sections("network", "interface", intf_s) { + if (strcmp(section_name(intf_s), sect_name) == 0) { + char *proto; + dmuci_get_value_by_section_string(intf_s, "proto", &proto); + dmuci_delete_by_section(intf_s, "proto", proto); + break; + + } + } + /* Remove the Link section from dmmap. */ + struct uci_section *dmmap_section; + get_dmmap_section_of_config_section("dmmap", "link", sect_name, &dmmap_section); + dmuci_delete_by_section(dmmap_section, NULL, NULL); + return 0; } return FAULT_9005; break; @@ -244,27 +378,28 @@ static int delObjEthernetLink(char *refparam, struct dmctx *ctx, void *data, cha static int addObjEthernetVLANTermination(char *refparam, struct dmctx *ctx, void *data, char **instance) { - char *inst, *v, *eth_wan, *vid, *name, *vlan_name, *vlan_method = NULL; - struct uci_section *dmmap_network= NULL; + char *inst, *v, *eth_wan, *vid, *name, *vlan_name, *val, *vlan_method = NULL; + struct uci_section *dmmap_network= NULL, *s; check_create_dmmap_package("dmmap_network"); dmuci_get_option_value_string("cwmp", "cpe", "vlan_method", &vlan_method); if(strcmp(vlan_method, "2") == 0) - inst = get_vlan_last_instance_bbfdm("dmmap_network", "device", "all_vlan_term_instance", vlan_method); + inst = get_vlan_last_instance_bbfdm("dmmap_network", "interface", "all_vlan_term_instance", vlan_method); else - inst = get_vlan_last_instance_bbfdm("dmmap_network", "device", "only_tagged_vlan_term_instance", vlan_method); + inst = get_vlan_last_instance_bbfdm("dmmap_network", "interface", "only_tagged_vlan_term_instance", vlan_method); dmuci_get_option_value_string("ports", "WAN", "ifname", ð_wan); - dmasprintf(&vid, "%d", inst?atoi(inst)+4:4); + dmasprintf(&vid, "%d", inst?atoi(inst)+5:4); dmasprintf(&vlan_name, "vlan_%s", vid); - dmuci_set_value("network", vlan_name, "", "device"); - dmuci_set_value("network", vlan_name, "ifname", eth_wan); - dmuci_set_value("network", vlan_name, "type", "8021q"); - dmuci_set_value("network", vlan_name, "vid", vid); + dmuci_add_section_and_rename("network", "interface", &s, &val); + dmuci_set_value_by_section(s, "proto", "dhcp"); + dmuci_set_value_by_section(s, "section_name", vlan_name); dmasprintf(&name, "%s.%s", eth_wan, vid); - dmuci_set_value("network", vlan_name, "name", name); + dmuci_set_value_by_section(s, "ifname", name); + char mac[100] = "02:10:18:01:CC:05"; + dmuci_set_value_by_section(s, "macaddr", mac); - dmuci_add_section_bbfdm("dmmap_network", "device", &dmmap_network, &v); + dmuci_add_section_bbfdm("dmmap_network", "interface", &dmmap_network, &v); dmuci_set_value_by_section(dmmap_network, "section_name", vlan_name); if(strcmp(vlan_method, "2") == 0) *instance = update_instance_bbfdm(dmmap_network, inst, "all_vlan_term_instance"); @@ -276,22 +411,23 @@ static int addObjEthernetVLANTermination(char *refparam, struct dmctx *ctx, void static int delObjEthernetVLANTermination(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action) { - int found = 0; - struct uci_section *s = NULL, *ss = NULL, *dmmap_section = NULL; + struct uci_section *dmmap_section = NULL; char *vlan_method = NULL; switch (del_action) { case DEL_INST: dmuci_get_option_value_string("cwmp", "cpe", "vlan_method", &vlan_method); + if(is_section_unnamed(section_name(((struct dm_args *)data)->section))) { + LIST_HEAD(dup_list); if(strcmp(vlan_method, "2") == 0) { - delete_sections_save_next_sections("dmmap_network", "device", "all_vlan_term_instance", section_name((struct uci_section *)data), atoi(instance), &dup_list); - update_dmmap_sections(&dup_list, "all_vlan_term_instance", "dmmap_network", "device"); + delete_sections_save_next_sections("dmmap_network", "interface", "all_vlan_term_instance", section_name(((struct dm_args *)data)->section), atoi(instance), &dup_list); + update_dmmap_sections(&dup_list, "all_vlan_term_instance", "dmmap_network", "interface"); } else { - delete_sections_save_next_sections("dmmap_network", "device", "only_tagged_vlan_term_instance", section_name((struct uci_section *)data), atoi(instance), &dup_list); - update_dmmap_sections(&dup_list, "only_tagged_vlan_term_instance", "dmmap_network", "device"); + delete_sections_save_next_sections("dmmap_network", "interface", "only_tagged_vlan_term_instance", section_name(((struct dm_args *)data)->section), atoi(instance), &dup_list); + update_dmmap_sections(&dup_list, "only_tagged_vlan_term_instance", "dmmap_network", "interface"); } dmuci_delete_by_section_unnamed(((struct dm_args *)data)->section, NULL, NULL); } else { @@ -302,23 +438,8 @@ static int delObjEthernetVLANTermination(char *refparam, struct dmctx *ctx, void } break; case DEL_ALL: - uci_foreach_sections("network", "device", s) { - if (found != 0){ - get_dmmap_section_of_config_section("dmmap_network", "device", section_name(s), &dmmap_section); - if (dmmap_section != NULL) - dmuci_delete_by_section(dmmap_section, NULL, NULL); - dmuci_delete_by_section(ss, NULL, NULL); - } - ss = s; - found++; - } - if (ss != NULL){ - get_dmmap_section_of_config_section("dmmap_network", "device", section_name(ss), &dmmap_section); - if (dmmap_section != NULL) - dmuci_delete_by_section(dmmap_section, NULL, NULL); - dmuci_delete_by_section(ss, NULL, NULL); - } - break; + return FAULT_9005; + break; } return 0; } @@ -359,11 +480,69 @@ static int get_Ethernet_VLANTerminationNumberOfEntries(char *refparam, struct dm char *type, *vlan_method; int cnt = 0; - uci_foreach_sections("network", "device", s) { + /* Fix: Browse interface to find the no of vlan termination entries. */ + uci_foreach_sections("network", "interface", s) + { dmuci_get_value_by_section_string(s, "type", &type); dmuci_get_option_value_string("cwmp", "cpe", "vlan_method", &vlan_method); if ((strcmp(vlan_method, "2") != 0 && strcmp(vlan_method, "1") != 0) || (strcmp(vlan_method, "1") == 0 && strcmp(type, "untagged") == 0)) continue; + + char *proto; + dmuci_get_value_by_section_string(s, "proto", &proto); + if (*proto == '\0') { + continue; + } + + char *ifname; + dmuci_get_value_by_section_string(s, "ifname", &ifname); + if (*ifname == '\0') { + continue; + } + + char intf[250] = {0}; + strncpy(intf, ifname, sizeof(intf)); + + char *if_name = strtok(intf, " "); + if (NULL != if_name) { + + char name[250] = {0}; + strncpy(name, if_name, sizeof(name)); + + /* Support for both vlans and macvlans. */ + int macvlan = 0; + char *p = strstr(name, "."); + if (!p) { + char *t = strstr(name, "_"); + if (t) { + macvlan = 1; + } else { + continue; + } + } + + + char *tok, *end; + if (macvlan == 1) { + tok = strtok_r(name, "_", &end); + } else { + tok = strtok_r(name, ".", &end); + } + + if (end == NULL) { + continue; + } + + if (macvlan == 0) { + char tag[20] = {0}; + strncpy(tag, end, sizeof(tag)); + + if (strncmp(tag, "1", sizeof(tag)) == 0) { + continue; + } + } + } + cnt++; } dmasprintf(value, "%d", cnt); @@ -797,8 +976,7 @@ static int get_EthernetLink_LowerLayers(char *refparam, struct dmctx *ctx, void *value = ""; } } - } - else { + } else { /* for upstream interface, set the lowerlayer to wan port of Ethernet.Interface */ p = strchr(ifname, '.'); if (p) { @@ -815,12 +993,151 @@ static int get_EthernetLink_LowerLayers(char *refparam, struct dmctx *ctx, void static int set_EthernetLink_LowerLayers(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { + char lower_layer[250] = {0}; switch (action) { case VALUECHECK: if (dm_validate_string_list(value, -1, -1, 1024, -1, -1, NULL, 0, NULL, 0)) return FAULT_9007; break; case VALUESET: + if (value[strlen(value)-1]!='.') { + snprintf(lower_layer, sizeof(lower_layer), "%s.", value); + } else { + strncpy(lower_layer, value, sizeof(lower_layer)); + } + + /* Check if the value is valid or not. */ + if (strncmp(lower_layer, "Device.Bridging.Bridge.", 23) == 0) { + char *p = strstr(lower_layer, "Port"); + if (p) { + /* Get the bridge_key. */ + int len = strlen(p); + char new_if[250] = {0}; + int i; + for (i = 0; i < strlen(lower_layer) - len; i++) { + new_if[i] = lower_layer[i]; + } + + char br_key = new_if[strlen(new_if) - 2]; + + char key[10] = {0}; + snprintf(key, sizeof(key), "%c", br_key); + + /* Find out bridge section name using bridge key. */ + struct uci_section *s = NULL; + char *sec_name; + uci_path_foreach_option_eq(bbfdm, "dmmap_network", "interface", "bridge_instance", key, s) { + dmuci_get_value_by_section_string(s, "section_name", &sec_name); + break; + } + + /* Check if section name is present in network UCI wd type as bridge + * and ifname not empty, if yes then update + * the section with proto 'dhcp' else do nothing. */ + struct uci_section *intf_s = NULL; + uci_foreach_sections("network", "interface", intf_s) { + struct uci_section *s = NULL; + char sec[20] = {0}; + strncpy(sec, section_name(intf_s), sizeof(sec)); + if (strncmp(sec, sec_name, sizeof(sec)) == 0) { + char *type, *ifname; + dmuci_get_value_by_section_string(intf_s, "type", &type); + if (*type == '\0' || strcmp(type, "bridge") != 0) { + return -1; + } + + dmuci_get_value_by_section_string(intf_s, "ifname", &ifname); + if (*ifname == '\0') { + return -1; + } + + /* Add ethernet link params to dmmap link section. */ + uci_path_foreach_sections(bbfdm, DMMAP, "link", s) { + char *inst; + char link_inst[10] = {0}; + dmuci_get_value_by_section_string(s, "link_instance", &inst); + strncpy(link_inst, instance, sizeof(link_inst)); + + /* Check if the link instance are same or not. */ + if (strncmp(link_inst, inst, sizeof(link_inst)) == 0) { + dmuci_set_value_by_section(s, "section_name", section_name(intf_s)); + break; + } + } + + /* Set the value of proto to the section. */ + dmuci_set_value_by_section(intf_s, "proto", "dhcp"); + + } + } + } + } else if (strncmp(lower_layer, "Device.Ethernet.Interface.", 26) == 0) { + /* Find the linker of the lowerlayer value to be set. */ + char *linker; + adm_entry_get_linker_value(ctx, lower_layer, &linker); + + /* Check if linker is present in network UCI, if yes the update + * the proto, else create a interface and device section. */ + char intf[20] = {0}; + if (strcmp(linker, "eth5.1") == 0) { + strncpy(intf, linker, sizeof(intf)); + } else { + snprintf(intf, sizeof(intf), "%s.%s", linker, "1"); + } + + struct uci_section *s = NULL, *link_s = NULL; + char *val; + int ret = 0; + uci_foreach_option_eq("network", "interface", "ifname", intf, s) { + /* Add ethernet link params to dmmap link section. */ + uci_path_foreach_sections(bbfdm, DMMAP, "link", link_s) { + char *inst; + char link_inst[10] = {0}; + dmuci_get_value_by_section_string(link_s, "link_instance", &inst); + strncpy(link_inst, instance, sizeof(link_inst)); + + /* Check if the link instance are same or not. */ + if (strncmp(link_inst, inst, sizeof(link_inst)) == 0) { + dmuci_set_value_by_section(link_s, "section_name", section_name(s)); + break; + } + } + + dmuci_set_value_by_section(s, "proto", "dhcp"); + ret = 1; + } + + if (ret == 0) { + dmuci_add_section_and_rename("network", "interface", &s, &val); + + /* Add ethernet link params to dmmap link section. */ + uci_path_foreach_sections(bbfdm, DMMAP, "link", link_s) { + char *inst; + char link_inst[10] = {0}; + dmuci_get_value_by_section_string(link_s, "link_instance", &inst); + strncpy(link_inst, instance, sizeof(link_inst)); + + /* Check if the link instance are same or not. */ + if (strncmp(link_inst, inst, sizeof(link_inst)) == 0) { + dmuci_set_value_by_section(link_s, "section_name", section_name(s)); + break; + } + } + + dmuci_set_value_by_section(s, "proto", "dhcp"); + dmuci_set_value_by_section(s, "ifname", intf); + + /* Add config device section. */ + struct uci_section *dev_s; + dmuci_add_section_and_rename("network", "device", &dev_s, &val); + dmuci_set_value_by_section(dev_s, "type", "untagged"); + char *tok = strtok(linker, "."); + dmuci_set_value_by_section(dev_s, "ifname", tok); + dmuci_set_value_by_section(dev_s, "name", intf); + } + } else { + return -1; + } break; } return 0; @@ -907,7 +1224,8 @@ static int get_EthernetVLANTermination_Alias(char *refparam, struct dmctx *ctx, struct uci_section *dmmap_section = NULL; char *vlan_method = NULL; - get_dmmap_section_of_config_section("dmmap_network", "device", section_name(((struct dm_args *)data)->section), &dmmap_section); + /* Fix: Browse interface in dmmap_network to fetch the value. */ + get_dmmap_section_of_config_section("dmmap_network", "interface", section_name(((struct dm_args *)data)->section), &dmmap_section); if (dmmap_section) { dmuci_get_option_value_string("cwmp", "cpe", "vlan_method", &vlan_method); if(strcmp(vlan_method, "2") == 0) @@ -915,6 +1233,7 @@ static int get_EthernetVLANTermination_Alias(char *refparam, struct dmctx *ctx, else dmuci_get_value_by_section_string(dmmap_section, "vlan_term_alias", value); } + return 0; } @@ -929,15 +1248,15 @@ static int set_EthernetVLANTermination_Alias(char *refparam, struct dmctx *ctx, return FAULT_9007; return 0; case VALUESET: - get_dmmap_section_of_config_section("dmmap_network", "device", section_name(((struct dm_args *)data)->section), &dmmap_section); - if (dmmap_section) { + /* Fix: Browse interface in dmmap_network to fetch the value. */ + get_dmmap_section_of_config_section("dmmap_network", "interface", section_name(((struct dm_args *)data)->section), &dmmap_section); + if(dmmap_section) { dmuci_get_option_value_string("cwmp", "cpe", "vlan_method", &vlan_method); if(strcmp(vlan_method, "2") == 0) dmuci_set_value_by_section(dmmap_section, "all_vlan_term_alias", value); else dmuci_set_value_by_section(dmmap_section, "vlan_term_alias", value); } - return 0; } return 0; } @@ -955,8 +1274,9 @@ static int get_EthernetVLANTermination_LastChange(char *refparam, struct dmctx * struct uci_section *s = NULL; char *ifname, *devifname; + /* Fix : Use section_name and ifname to find the value of interface. */ *value ="0"; - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "name", &devifname); + dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "ifname", &devifname); uci_foreach_sections("network", "interface", s) { dmuci_get_value_by_section_string(s, "ifname", &ifname); if (strstr(ifname, devifname)) { @@ -973,16 +1293,23 @@ static int get_EthernetVLANTermination_LastChange(char *refparam, struct dmctx * static int get_EthernetVLANTermination_LowerLayers(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - char *pch, *spch, *devifname, *ifname, *dupifname; - struct uci_section *section; - - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "name", &devifname); + char *pch, *spch, *devifname, *ifname, *dupifname, *mac; + struct uci_section *section = NULL; + + /* Fix : Use ifname paramter to find the name of the interface in specified section. */ + //dmuci_get_value_by_section_string(section_name(((struct dm_args *)data)->section), "ifname", &devifname); + dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "ifname", &devifname); + uci_foreach_sections("network", "interface", section) { dmuci_get_value_by_section_string(section, "ifname", &ifname); dupifname = dmstrdup(ifname); for (pch = strtok_r(dupifname, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch)) { - if(strcmp(pch, devifname) == 0){ - adm_entry_get_linker_param(ctx, dm_print_path("%s%cEthernet%cLink%c", dmroot, dm_delim, dm_delim, dm_delim), section_name(section), value); + if(strcmp(pch, devifname) == 0) { + /* Fix: Use mac address instead of section name for lower layer. */ + mac = get_macaddr(section_name(section)); + if (mac[0] != '\0') { + adm_entry_get_linker_param(ctx, dm_print_path("%s%cEthernet%cLink%c", dmroot, dm_delim, dm_delim, dm_delim), mac, value); + } break; } } @@ -1029,14 +1356,18 @@ static int set_EthernetVLANTermination_LowerLayers(char *refparam, struct dmctx static int get_EthernetVLANTermination_VLANID(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { *value = "0"; - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "vid", value); + char *ifname, *tag, *tok; + dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "ifname", &ifname); + tok = strtok_r(ifname, ".", &tag); + if (tag != NULL) { + *value = tag; + } return 0; } static int set_EthernetVLANTermination_VLANID(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - char *ifname, *name, *vid, *curr_ifname; - struct uci_section *s; + char *ifname, *name; switch (action) { case VALUECHECK: @@ -1045,16 +1376,13 @@ static int set_EthernetVLANTermination_VLANID(char *refparam, struct dmctx *ctx, return 0; case VALUESET: { dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "ifname", &ifname); - dmasprintf(&name, "%s.%s", ifname, value); - dmuci_set_value_by_section(((struct dm_args *)data)->section, "name", name); - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "vid", &vid); - dmuci_set_value_by_section(((struct dm_args *)data)->section, "vid", value); - dmasprintf(&curr_ifname, "%s.%s", ifname, vid); - uci_foreach_option_eq("network", "interface", "ifname", curr_ifname, s) { - dmuci_set_value_by_section(s, "ifname", name); + char *tok, *tag; + tok = strtok_r(ifname, ".", &tag); + if (tok != NULL) { + dmasprintf(&name, "%s.%s", tok, value); } + dmuci_set_value_by_section(((struct dm_args *)data)->section, "ifname", name); dmfree(name); - dmfree(curr_ifname); return 0; } } diff --git a/libbbf_api/dmbbf.c b/libbbf_api/dmbbf.c index f8f6caba..546a6735 100644 --- a/libbbf_api/dmbbf.c +++ b/libbbf_api/dmbbf.c @@ -619,14 +619,57 @@ char *get_vlan_last_instance_bbfdm(char *package, char *section, char *opt_inst, uci_path_foreach_sections(bbfdm, package, section, s) { dmuci_get_value_by_section_string(s, "section_name", §_name); - get_config_section_of_dmmap_section("network", "device", sect_name, &confsect); + get_config_section_of_dmmap_section("network", "interface", sect_name, &confsect); dmuci_get_value_by_section_string(confsect, "type", &type); if ((strcmp(vlan_method, "2") != 0 && strcmp(vlan_method, "1") != 0) || (strcmp(vlan_method, "1") == 0 && strcmp(type, "untagged") == 0) ) continue; - inst = update_instance_bbfdm(s, last_inst, opt_inst); - if(last_inst) - dmfree(last_inst); - last_inst = dmstrdup(inst); + + char *proto; + dmuci_get_value_by_section_string(confsect, "proto", &proto); + if (*proto == '\0') { + continue; + } + + char *ifname; + dmuci_get_value_by_section_string(confsect, "ifname", &ifname); + if (*ifname == '\0') { + continue; + } + + char interface[250] = {0}; + strncpy(interface, ifname, sizeof(interface)); + + /* Only tagged interfaces should be considered. */ + int ret = 0; + char *tok, *end; + tok = strtok_r(ifname, " ", &end); + if (tok == NULL) { + char *intf, *tag; + intf = strtok_r(tok, ".", &tag); + if (tag != NULL) { + char tag_if[10] = {0}; + strncpy(tag_if, tag, sizeof(tag_if)); + if (strncmp(tag_if, "1", sizeof(tag_if)) != 0) { + ret = 1; + } else { + ret = 0; + } + } else { + ret = 0; + } + } else { + char *p = strstr(interface, "."); + if (p) { + ret = 1; + } + } + + if (ret == 1) { + inst = update_instance_bbfdm(s, last_inst, opt_inst); + if(last_inst) + dmfree(last_inst); + last_inst = dmstrdup(inst); + } } return inst; } diff --git a/libbbf_api/dmcommon.c b/libbbf_api/dmcommon.c index d61d88f1..ad866dd8 100644 --- a/libbbf_api/dmcommon.c +++ b/libbbf_api/dmcommon.c @@ -888,6 +888,80 @@ struct uci_section *get_dup_section_in_dmmap_eq(char *dmmap_package, char* secti return NULL; } +void synchronize_specific_config_sections_with_dmmap_vlan(char *package, char *section_type, char *dmmap_package, char *ifname, struct list_head *dup_list, int *count, char *id) +{ + struct uci_section *s, *stmp, *dmmap_sect; + FILE *fp; + char *v, *dmmap_file_path; + + dmasprintf(&dmmap_file_path, "/etc/bbfdm/%s", dmmap_package); + if (access(dmmap_file_path, F_OK)) { + /* + *File does not exist + **/ + fp = fopen(dmmap_file_path, "w"); // new empty file + fclose(fp); + } + uci_foreach_sections(package, section_type, s) { + /* + * create/update corresponding dmmap section that have same config_section link and using param_value_array + */ + if ((dmmap_sect = get_dup_section_in_dmmap(dmmap_package, section_type, section_name(s))) == NULL) { + dmuci_add_section_bbfdm(dmmap_package, section_type, &dmmap_sect, &v); + DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_sect, "section_name", section_name(s)); + } + + /* Fix : Entry for only VLANS. */ + if (strcmp(package, "network") == 0 && + strcmp(section_type, "interface") == 0 && + strcmp(dmmap_package, "dmmap_network") == 0) { + char *type, *intf; + dmuci_get_value_by_section_string(s, "type", &type); + dmuci_get_value_by_section_string(s, "ifname", &intf); + if (strcmp(type,"bridge") != 0 || strcmp(intf, ifname) != 0){ + continue; + } + } + + /* Fix: Vlan object should not be created for transparent bridges. */ + int tag = 0; + char name[250] = {0}; + strncpy(name, ifname, sizeof(name)); + char *p = strtok(name, " "); + while (p != NULL) { + char intf[250] = {0}; + strncpy(intf, p, sizeof(intf)); + char *find = strstr(intf, "."); + if (find) { + tag = 1; + *id = find[strlen(find) - 1]; + break; + } + p = strtok(NULL, " "); + } + + if (tag == 0) { + continue; + } + + /* + * Add system and dmmap sections to the list + */ + add_sectons_list_paramameter(dup_list, s, dmmap_sect, NULL); + *count = *count + 1; + } + + /* + * Delete unused dmmap sections + */ + uci_path_foreach_sections_safe(bbfdm, dmmap_package, section_type, stmp, s) { + dmuci_get_value_by_section_string(s, "section_name", &v); + if(get_origin_section_from_config(package, section_type, v) == NULL){ + dmuci_delete_by_section_unnamed_bbfdm(s, NULL, NULL); + } + } +} + void synchronize_specific_config_sections_with_dmmap(char *package, char *section_type, char *dmmap_package, struct list_head *dup_list) { struct uci_section *s, *stmp, *dmmap_sect; @@ -904,6 +978,17 @@ void synchronize_specific_config_sections_with_dmmap(char *package, char *sectio DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_sect, "section_name", section_name(s)); } + /* Fix : Change to fix multiple IP interface creation. */ + if (strcmp(package, "network") == 0 && + strcmp(section_type, "interface") == 0 && + strcmp(dmmap_package, "dmmap_network") == 0) { + char *value; + dmuci_get_value_by_section_string(s, "proto", &value); + if (*value == '\0') { + continue; + } + } + /* * Add system and dmmap sections to the list */ @@ -1014,6 +1099,42 @@ void synchronize_specific_config_sections_with_dmmap_cont(char *package, char *s } } +void synchronize_multi_config_sections_with_dmmap_set(char *package, char *section_type, char *dmmap_package, char* dmmap_section, char* option_name, char* option_value, char *instance, char *br_key) +{ + /* Fix : Dmmap set for configuring the lower layer of Bridge.Port object. */ + struct uci_section *s; + FILE *fp; + char *dmmap_file_path, *key; + + dmasprintf(&dmmap_file_path, "/etc/bbfdm/%s", dmmap_package); + if (access(dmmap_file_path, F_OK)) { + /* + *File does not exist + **/ + fp = fopen(dmmap_file_path, "w"); // new empty file + fclose(fp); + } + + uci_foreach_option_eq(package, section_type, option_name, option_value, s) { + + /* Check if bridge_port_instance is present in dmmap_bridge_port.*/ + struct uci_section *sec; + uci_path_foreach_option_eq(bbfdm, "dmmap_bridge_port", "bridge_port", "bridge_port_instance", instance, sec) { + + dmuci_get_value_by_section_string(sec, "bridge_key", &key); + char bridge_key[10] = {0}; + strncpy(bridge_key, br_key, sizeof(bridge_key)); + + char bridge_key_1[10] = {0}; + strncpy(bridge_key_1, key, sizeof(bridge_key_1)); + + if (strncmp(bridge_key, bridge_key_1, sizeof(bridge_key)) == 0) { + DMUCI_SET_VALUE_BY_SECTION(bbfdm, sec, "section_name", section_name(s)); + } + } + } +} + bool synchronize_multi_config_sections_with_dmmap_eq(char *package, char *section_type, char *dmmap_package, char* dmmap_section, char* option_name, char* option_value, void* additional_attribute, struct list_head *dup_list) { struct uci_section *s, *stmp, *dmmap_sect; @@ -1032,6 +1153,11 @@ bool synchronize_multi_config_sections_with_dmmap_eq(char *package, char *sectio DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_sect, "section_name", section_name(s)); DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_sect, "package", package); DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_sect, "section", section_type); + } else { + /* Fix : Dmmap set for configuring the lower layer of Bridge.Port object. */ + DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_sect, "section_name", section_name(s)); + DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_sect, "package", package); + DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_sect, "section", section_type); } /* @@ -1040,175 +1166,175 @@ bool synchronize_multi_config_sections_with_dmmap_eq(char *package, char *sectio add_sectons_list_paramameter(dup_list, s, dmmap_sect, additional_attribute); } - /* - * Delete unused dmmap sections - */ - uci_path_foreach_sections_safe(bbfdm, dmmap_package, dmmap_section, stmp, s) { - dmuci_get_value_by_section_string(s, "section_name", &v); - dmuci_get_value_by_section_string(s, "package", &pack); - dmuci_get_value_by_section_string(s, "section", §); - if (v!=NULL && strlen(v)>0 && strcmp(package, pack)==0 && strcmp(section_type, sect)== 0) { - if(get_origin_section_from_config(package, section_type, v) == NULL){ - dmuci_delete_by_section(s, NULL, NULL); - } - } - } + /* + * Delete unused dmmap sections + */ + uci_path_foreach_sections_safe(bbfdm, dmmap_package, dmmap_section, stmp, s) { + dmuci_get_value_by_section_string(s, "section_name", &v); + dmuci_get_value_by_section_string(s, "package", &pack); + dmuci_get_value_by_section_string(s, "section", §); + if (v!=NULL && strlen(v)>0 && strcmp(package, pack)==0 && strcmp(section_type, sect)== 0) { + if(get_origin_section_from_config(package, section_type, v) == NULL){ + dmuci_delete_by_section(s, NULL, NULL); + } + } + } - return found; + return found; } bool synchronize_multi_config_sections_with_dmmap_eq_diff(char *package, char *section_type, char *dmmap_package, char* dmmap_section, char* option_name, char* option_value, char* opt_diff_name, char* opt_diff_value, void* additional_attribute, struct list_head *dup_list) { - struct uci_section *s, *stmp, *dmmap_sect; - char *v, *pack, *sect, *optval; - bool found= false; + struct uci_section *s, *stmp, *dmmap_sect; + char *v, *pack, *sect, *optval; + bool found= false; - dmmap_file_path_get(dmmap_package); + dmmap_file_path_get(dmmap_package); - uci_foreach_option_eq(package, section_type, option_name, option_value, s) { - found = true; - dmuci_get_value_by_section_string(s, opt_diff_name, &optval); - if (strcmp(optval, opt_diff_value) != 0) { - /* - * create/update corresponding dmmap section that have same config_section link and using param_value_array - */ - if ((dmmap_sect = get_dup_section_in_dmmap(dmmap_package, dmmap_section, section_name(s))) == NULL) { - dmuci_add_section_bbfdm(dmmap_package, dmmap_section, &dmmap_sect, &v); - DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_sect, "section_name", section_name(s)); - DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_sect, "package", package); - DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_sect, "section", section_type); - } + uci_foreach_option_eq(package, section_type, option_name, option_value, s) { + found = true; + dmuci_get_value_by_section_string(s, opt_diff_name, &optval); + if (strcmp(optval, opt_diff_value) != 0) { + /* + * create/update corresponding dmmap section that have same config_section link and using param_value_array + */ + if ((dmmap_sect = get_dup_section_in_dmmap(dmmap_package, dmmap_section, section_name(s))) == NULL) { + dmuci_add_section_bbfdm(dmmap_package, dmmap_section, &dmmap_sect, &v); + DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_sect, "section_name", section_name(s)); + DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_sect, "package", package); + DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_sect, "section", section_type); + } - /* - * Add system and dmmap sections to the list - */ - add_sectons_list_paramameter(dup_list, s, dmmap_sect, additional_attribute); - } - } + /* + * Add system and dmmap sections to the list + */ + add_sectons_list_paramameter(dup_list, s, dmmap_sect, additional_attribute); + } + } - /* - * Delete unused dmmap sections - */ - uci_path_foreach_sections_safe(bbfdm, dmmap_package, dmmap_section, stmp, s) { - dmuci_get_value_by_section_string(s, "section_name", &v); - dmuci_get_value_by_section_string(s, "package", &pack); - dmuci_get_value_by_section_string(s, "section", §); - if(v!=NULL && strlen(v)>0 && strcmp(package, pack)==0 && strcmp(section_type, sect)== 0){ - if(get_origin_section_from_config(package, section_type, v) == NULL){ - dmuci_delete_by_section(s, NULL, NULL); - } - } - } + /* + * Delete unused dmmap sections + */ + uci_path_foreach_sections_safe(bbfdm, dmmap_package, dmmap_section, stmp, s) { + dmuci_get_value_by_section_string(s, "section_name", &v); + dmuci_get_value_by_section_string(s, "package", &pack); + dmuci_get_value_by_section_string(s, "section", §); + if(v!=NULL && strlen(v)>0 && strcmp(package, pack)==0 && strcmp(section_type, sect)== 0){ + if(get_origin_section_from_config(package, section_type, v) == NULL){ + dmuci_delete_by_section(s, NULL, NULL); + } + } + } - return found; + return found; } void add_sysfs_sectons_list_paramameter(struct list_head *dup_list, struct uci_section *dmmap_section, char *file_name, char* filepath) { - struct sysfs_dmsection *dmmap_sysfs; + struct sysfs_dmsection *dmmap_sysfs; - dmmap_sysfs = dmcalloc(1, sizeof(struct sysfs_dmsection)); - list_add_tail(&dmmap_sysfs->list, dup_list); - dmmap_sysfs->dm = dmmap_section; - dmmap_sysfs->sysfs_folder_name= dmstrdup(file_name); - dmmap_sysfs->sysfs_folder_path= dmstrdup(filepath); + dmmap_sysfs = dmcalloc(1, sizeof(struct sysfs_dmsection)); + list_add_tail(&dmmap_sysfs->list, dup_list); + dmmap_sysfs->dm = dmmap_section; + dmmap_sysfs->sysfs_folder_name= dmstrdup(file_name); + dmmap_sysfs->sysfs_folder_path= dmstrdup(filepath); } int synchronize_system_folders_with_dmmap_opt(char *sysfsrep, char *dmmap_package, char *dmmap_section, char *opt_name, char* inst_opt, struct list_head *dup_list) { - struct uci_section *s, *stmp, *dmmap_sect; - DIR *dir; - struct dirent *ent; - char *v, *sysfs_rep_path, *instance= NULL; - struct sysfs_dmsection *p, *tmp; - LIST_HEAD(dup_list_no_inst); + struct uci_section *s, *stmp, *dmmap_sect; + DIR *dir; + struct dirent *ent; + char *v, *sysfs_rep_path, *instance= NULL; + struct sysfs_dmsection *p, *tmp; + LIST_HEAD(dup_list_no_inst); - dmmap_file_path_get(dmmap_package); + dmmap_file_path_get(dmmap_package); - sysfs_foreach_file(sysfsrep, dir, ent) { - if(strcmp(ent->d_name, ".")==0 || strcmp(ent->d_name, "..")==0) - continue; + sysfs_foreach_file(sysfsrep, dir, ent) { + if(strcmp(ent->d_name, ".")==0 || strcmp(ent->d_name, "..")==0) + continue; - /* - * create/update corresponding dmmap section that have same config_section link and using param_value_array - */ - dmasprintf(&sysfs_rep_path, "%s/%s", sysfsrep, ent->d_name); - if ((dmmap_sect = get_dup_section_in_dmmap_opt(dmmap_package, dmmap_section, opt_name, sysfs_rep_path)) == NULL) { - dmuci_add_section_bbfdm(dmmap_package, dmmap_section, &dmmap_sect, &v); - DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_sect, opt_name, sysfs_rep_path); - } + /* + * create/update corresponding dmmap section that have same config_section link and using param_value_array + */ + dmasprintf(&sysfs_rep_path, "%s/%s", sysfsrep, ent->d_name); + if ((dmmap_sect = get_dup_section_in_dmmap_opt(dmmap_package, dmmap_section, opt_name, sysfs_rep_path)) == NULL) { + dmuci_add_section_bbfdm(dmmap_package, dmmap_section, &dmmap_sect, &v); + DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_sect, opt_name, sysfs_rep_path); + } - dmuci_get_value_by_section_string(dmmap_sect, inst_opt, &instance); + dmuci_get_value_by_section_string(dmmap_sect, inst_opt, &instance); - /* - * Add system and dmmap sections to the list - */ + /* + * Add system and dmmap sections to the list + */ - if(instance == NULL || strlen(instance) <= 0) - add_sysfs_sectons_list_paramameter(&dup_list_no_inst, dmmap_sect, ent->d_name, sysfs_rep_path); - else - add_sysfs_sectons_list_paramameter(dup_list, dmmap_sect, ent->d_name, sysfs_rep_path); - } - if (dir) - closedir(dir); + if(instance == NULL || strlen(instance) <= 0) + add_sysfs_sectons_list_paramameter(&dup_list_no_inst, dmmap_sect, ent->d_name, sysfs_rep_path); + else + add_sysfs_sectons_list_paramameter(dup_list, dmmap_sect, ent->d_name, sysfs_rep_path); + } + if (dir) + closedir(dir); - /* - * fusion two lists - */ - list_for_each_entry_safe(p, tmp, &dup_list_no_inst, list) - list_move_tail(&p->list, dup_list); + /* + * fusion two lists + */ + list_for_each_entry_safe(p, tmp, &dup_list_no_inst, list) + list_move_tail(&p->list, dup_list); - /* - * Delete unused dmmap sections - */ - uci_path_foreach_sections_safe(bbfdm, dmmap_package, dmmap_section, stmp, s) { - dmuci_get_value_by_section_string(s, opt_name, &v); - if(isfolderexist(v) == 0){ - dmuci_delete_by_section_unnamed_bbfdm(s, NULL, NULL); - } - } - return 0; + /* + * Delete unused dmmap sections + */ + uci_path_foreach_sections_safe(bbfdm, dmmap_package, dmmap_section, stmp, s) { + dmuci_get_value_by_section_string(s, opt_name, &v); + if(isfolderexist(v) == 0){ + dmuci_delete_by_section_unnamed_bbfdm(s, NULL, NULL); + } + } + return 0; } void get_dmmap_section_of_config_section(char* dmmap_package, char* section_type, char *section_name, struct uci_section **dmmap_section) { - struct uci_section* s; + struct uci_section* s; - uci_path_foreach_option_eq(bbfdm, dmmap_package, section_type, "section_name", section_name, s) { - *dmmap_section = s; - return; - } - *dmmap_section = NULL; + uci_path_foreach_option_eq(bbfdm, dmmap_package, section_type, "section_name", section_name, s) { + *dmmap_section = s; + return; + } + *dmmap_section = NULL; } void get_dmmap_section_of_config_section_eq(char* dmmap_package, char* section_type, char *opt, char* value, struct uci_section **dmmap_section) { - struct uci_section* s; + struct uci_section* s; - uci_path_foreach_option_eq(bbfdm, dmmap_package, section_type, opt, value, s){ - *dmmap_section = s; - return; - } - *dmmap_section = NULL; + uci_path_foreach_option_eq(bbfdm, dmmap_package, section_type, opt, value, s){ + *dmmap_section = s; + return; + } + *dmmap_section = NULL; } void get_config_section_of_dmmap_section(char* package, char* section_type, char *section_name, struct uci_section **config_section) { - struct uci_section* s; + struct uci_section* s; - uci_foreach_sections(package, section_type, s) { - if (strcmp(section_name(s), section_name) == 0) { - *config_section = s; - return; - } - } - *config_section= NULL; + uci_foreach_sections(package, section_type, s) { + if (strcmp(section_name(s), section_name) == 0) { + *config_section = s; + return; + } + } + *config_section= NULL; } void check_create_dmmap_package(char *dmmap_package) { - char *dmmap_file_path = dmmap_file_path_get(dmmap_package); - dmfree(dmmap_file_path); + char *dmmap_file_path = dmmap_file_path_get(dmmap_package); + dmfree(dmmap_file_path); } int is_section_unnamed(char *section_name) @@ -1228,241 +1354,241 @@ int is_section_unnamed(char *section_name) void add_dmmap_list_section(struct list_head *dup_list, char* section_name, char* instance) { - struct dmmap_sect *dmsect; + struct dmmap_sect *dmsect; - dmsect = dmcalloc(1, sizeof(struct dmmap_sect)); - list_add_tail(&dmsect->list, dup_list); - dmasprintf(&dmsect->section_name, "%s", section_name); - dmasprintf(&dmsect->instance, "%s", instance); + dmsect = dmcalloc(1, sizeof(struct dmmap_sect)); + list_add_tail(&dmsect->list, dup_list); + dmasprintf(&dmsect->section_name, "%s", section_name); + dmasprintf(&dmsect->instance, "%s", instance); } -void delete_sections_save_next_sections(char* dmmap_package, char *section_type, char *instancename, char *section_name, int instance, struct list_head *dup_list) +void delete_sections_save_next_sections(char* dmmap_package, char *section_type, char *instancename, char *section_name, int instance, struct list_head *dup_list) { - struct uci_section *s, *stmp; - char *v=NULL, *lsectname= NULL, *tmp= NULL; - int inst; + struct uci_section *s, *stmp; + char *v=NULL, *lsectname= NULL, *tmp= NULL; + int inst; - dmasprintf(&lsectname, "%s", section_name); + dmasprintf(&lsectname, "%s", section_name); - uci_path_foreach_sections(bbfdm, dmmap_package, section_type, s) { - dmuci_get_value_by_section_string(s, instancename, &v); - inst= atoi(v); - if(inst>instance){ - dmuci_get_value_by_section_string(s, "section_name", &tmp); - add_dmmap_list_section(dup_list, lsectname, v); - dmfree(lsectname); - lsectname= NULL; - dmasprintf(&lsectname, "%s", tmp); - dmfree(tmp); - tmp= NULL; - } - } + uci_path_foreach_sections(bbfdm, dmmap_package, section_type, s) { + dmuci_get_value_by_section_string(s, instancename, &v); + inst= atoi(v); + if(inst>instance){ + dmuci_get_value_by_section_string(s, "section_name", &tmp); + add_dmmap_list_section(dup_list, lsectname, v); + dmfree(lsectname); + lsectname= NULL; + dmasprintf(&lsectname, "%s", tmp); + dmfree(tmp); + tmp= NULL; + } + } - if(lsectname != NULL) dmfree(lsectname); + if(lsectname != NULL) dmfree(lsectname); - uci_path_foreach_sections_safe(bbfdm, dmmap_package, section_type, stmp, s) { - dmuci_get_value_by_section_string(s, instancename, &v); - inst= atoi(v); - if(inst>=instance) - dmuci_delete_by_section_unnamed_bbfdm(s, NULL, NULL); - } + uci_path_foreach_sections_safe(bbfdm, dmmap_package, section_type, stmp, s) { + dmuci_get_value_by_section_string(s, instancename, &v); + inst= atoi(v); + if(inst>=instance) + dmuci_delete_by_section_unnamed_bbfdm(s, NULL, NULL); + } } void update_dmmap_sections(struct list_head *dup_list, char *instancename, char* dmmap_package, char *section_type) { - struct uci_section *dm_sect; - char *v; - struct dmmap_sect *p; + struct uci_section *dm_sect; + char *v; + struct dmmap_sect *p = NULL; - list_for_each_entry(p, dup_list, list) { - dmuci_add_section_bbfdm(dmmap_package, section_type, &dm_sect, &v); - dmuci_set_value_by_section(dm_sect, "section_name", p->section_name); - dmuci_set_value_by_section(dm_sect, instancename, p->instance); - } + list_for_each_entry(p, dup_list, list) { + dmuci_add_section_bbfdm(dmmap_package, section_type, &dm_sect, &v); + dmuci_set_value_by_section(dm_sect, "section_name", p->section_name); + dmuci_set_value_by_section(dm_sect, instancename, p->instance); + } } struct uci_section *is_dmmap_section_exist(char* package, char* section) { - struct uci_section *s; + struct uci_section *s; - uci_path_foreach_sections(bbfdm, package, section, s) { - return s; - } - return NULL; + uci_path_foreach_sections(bbfdm, package, section, s) { + return s; + } + return NULL; } struct uci_section *is_dmmap_section_exist_eq(char* package, char* section, char* opt, char* value) { - struct uci_section *s; + struct uci_section *s; - uci_path_foreach_option_eq(bbfdm, package, section, opt, value, s) { - return s; - } - return NULL; + uci_path_foreach_option_eq(bbfdm, package, section, opt, value, s) { + return s; + } + return NULL; } unsigned char isdigit_str(char *str) { - if (!(*str)) return 0; - while(isdigit(*str++)); - return ((*(str-1)) ? 0 : 1); + if (!(*str)) return 0; + while(isdigit(*str++)); + return ((*(str-1)) ? 0 : 1); } static inline int isword_delim(char c) { - if (c == ' ' || - c == ',' || - c == '\t' || - c == '\v' || - c == '\r' || - c == '\n' || - c == '\0') - return 1; - return 0; + if (c == ' ' || + c == ',' || + c == '\t' || + c == '\v' || + c == '\r' || + c == '\n' || + c == '\0') + return 1; + return 0; } char *dm_strword(char *src, char *str) { - char *ret = src; - int len; - if (src[0] == '\0') - return NULL; - len = strlen(str); - while ((ret = strstr(ret, str)) != NULL) { - if ((ret == src && isword_delim(ret[len])) || - (ret != src && isword_delim(ret[len]) && isword_delim(*(ret - 1)))) - return ret; - ret++; - } - return NULL; + char *ret = src; + int len; + if (src[0] == '\0') + return NULL; + len = strlen(str); + while ((ret = strstr(ret, str)) != NULL) { + if ((ret == src && isword_delim(ret[len])) || + (ret != src && isword_delim(ret[len]) && isword_delim(*(ret - 1)))) + return ret; + ret++; + } + return NULL; } char **strsplit(const char* str, const char* delim, size_t* numtokens) { - char *s = strdup(str); - size_t tokens_alloc = 1; - size_t tokens_used = 0; - char **tokens = dmcalloc(tokens_alloc, sizeof(char*)); - char *token, *strtok_ctx; + char *s = strdup(str); + size_t tokens_alloc = 1; + size_t tokens_used = 0; + char **tokens = dmcalloc(tokens_alloc, sizeof(char*)); + char *token, *strtok_ctx; - for (token = strtok_r(s, delim, &strtok_ctx); - token != NULL; - token = strtok_r(NULL, delim, &strtok_ctx)) { + for (token = strtok_r(s, delim, &strtok_ctx); + token != NULL; + token = strtok_r(NULL, delim, &strtok_ctx)) { - if (tokens_used == tokens_alloc) { - tokens_alloc *= 2; - tokens = dmrealloc(tokens, tokens_alloc * sizeof(char*)); - } - tokens[tokens_used++] = dmstrdup(token); - } - if (tokens_used == 0) { - dmfree(tokens); - tokens = NULL; - } else { - tokens = dmrealloc(tokens, tokens_used * sizeof(char*)); - } - *numtokens = tokens_used; - FREE(s); - return tokens; + if (tokens_used == tokens_alloc) { + tokens_alloc *= 2; + tokens = dmrealloc(tokens, tokens_alloc * sizeof(char*)); + } + tokens[tokens_used++] = dmstrdup(token); + } + if (tokens_used == 0) { + dmfree(tokens); + tokens = NULL; + } else { + tokens = dmrealloc(tokens, tokens_used * sizeof(char*)); + } + *numtokens = tokens_used; + FREE(s); + return tokens; } char **strsplit_by_str(const char str[], char *delim) { - char *substr = NULL; - size_t tokens_alloc = 1; - size_t tokens_used = 0; - char **tokens = dmcalloc(tokens_alloc, sizeof(char*)); - char *strparse = strdup(str); - do { - substr = strstr(strparse, delim); - if (substr == NULL && (strparse == NULL || strparse[0] == '\0')) - break; + char *substr = NULL; + size_t tokens_alloc = 1; + size_t tokens_used = 0; + char **tokens = dmcalloc(tokens_alloc, sizeof(char*)); + char *strparse = strdup(str); + do { + substr = strstr(strparse, delim); + if (substr == NULL && (strparse == NULL || strparse[0] == '\0')) + break; - if (substr == NULL) { - substr = strdup(strparse); - tokens[tokens_used] = dmcalloc(strlen(substr)+1, sizeof(char)); - strncpy(tokens[tokens_used], strparse, strlen(strparse)); - FREE(strparse); - break; - } + if (substr == NULL) { + substr = strdup(strparse); + tokens[tokens_used] = dmcalloc(strlen(substr)+1, sizeof(char)); + strncpy(tokens[tokens_used], strparse, strlen(strparse)); + FREE(strparse); + break; + } - if (tokens_used == tokens_alloc) { - if (strparse == NULL) - tokens_alloc++; - else - tokens_alloc += 2; - tokens = dmrealloc(tokens, tokens_alloc * sizeof(char*)); - } + if (tokens_used == tokens_alloc) { + if (strparse == NULL) + tokens_alloc++; + else + tokens_alloc += 2; + tokens = dmrealloc(tokens, tokens_alloc * sizeof(char*)); + } - tokens[tokens_used] = dmcalloc(substr-strparse+1, sizeof(char)); - strncpy(tokens[tokens_used], strparse, substr-strparse); - tokens_used++; - FREE(strparse); - strparse = strdup(substr+strlen(delim)); - } while (substr != NULL); - FREE(strparse); - return tokens; + tokens[tokens_used] = dmcalloc(substr-strparse+1, sizeof(char)); + strncpy(tokens[tokens_used], strparse, substr-strparse); + tokens_used++; + FREE(strparse); + strparse = strdup(substr+strlen(delim)); + } while (substr != NULL); + FREE(strparse); + return tokens; } char *get_macaddr(char *interface_name) { - char *device = get_device(interface_name); - char *mac; + char *device = get_device(interface_name); + char *mac; - if(device[0]) { - char file[128]; - char val[32]; + if(device[0]) { + char file[128]; + char val[32]; - snprintf(file, sizeof(file), "/sys/class/net/%s/address", device); - dm_read_sysfs_file(file, val, sizeof(val)); - mac = dmstrdup(val); - } else { - mac = ""; - } - return mac; + snprintf(file, sizeof(file), "/sys/class/net/%s/address", device); + dm_read_sysfs_file(file, val, sizeof(val)); + mac = dmstrdup(val); + } else { + mac = ""; + } + return mac; } char *get_device(char *interface_name) { - json_object *res; + json_object *res; - dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", interface_name, String}}, 1, &res); - return dmjson_get_value(res, 1, "device"); + dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", interface_name, String}}, 1, &res); + return dmjson_get_value(res, 1, "device"); } char *get_device_from_wifi_iface(const char *wifi_iface, const char *wifi_section) { - json_object *jobj; - array_list *jarr; - unsigned n = 0, i; - const char *ifname = ""; + json_object *jobj; + array_list *jarr; + unsigned n = 0, i; + const char *ifname = ""; - if (wifi_iface[0] == 0 || wifi_section[0] == 0) - return ""; + if (wifi_iface[0] == 0 || wifi_section[0] == 0) + return ""; - dmubus_call("network.wireless", "status", UBUS_ARGS{{}}, 0, &jobj); - if (jobj == NULL) - return ""; + dmubus_call("network.wireless", "status", UBUS_ARGS{{}}, 0, &jobj); + if (jobj == NULL) + return ""; - json_object_object_get_ex(jobj, wifi_iface, &jobj); - json_object_object_get_ex(jobj, "interfaces", &jobj); + json_object_object_get_ex(jobj, wifi_iface, &jobj); + json_object_object_get_ex(jobj, "interfaces", &jobj); - jarr = json_object_get_array(jobj); - if (jarr) - n = array_list_length(jarr); + jarr = json_object_get_array(jobj); + if (jarr) + n = array_list_length(jarr); - for (i = 0; i < n; i++) { - json_object *j_e = jarr->array[i]; - const char *sect; + for (i = 0; i < n; i++) { + json_object *j_e = jarr->array[i]; + const char *sect; - sect = __dmjson_get_string(j_e, "section"); - if (!strcmp(sect, wifi_section)) { - ifname = __dmjson_get_string(j_e, "ifname"); - break; - } - } - return (char *)ifname; + sect = __dmjson_get_string(j_e, "section"); + if (!strcmp(sect, wifi_section)) { + ifname = __dmjson_get_string(j_e, "ifname"); + break; + } + } + return (char *)ifname; } /* @@ -1471,82 +1597,82 @@ char *get_device_from_wifi_iface(const char *wifi_iface, const char *wifi_sectio int is_elt_exit_in_str_list(char *str_list, char *elt) { - char *pch, *spch, *list; - list= dmstrdup(str_list); - for (pch = strtok_r(list, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch)) { - if(strcmp(pch, elt) == 0) - return 1; - } - return 0; + char *pch, *spch, *list; + list= dmstrdup(str_list); + for (pch = strtok_r(list, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch)) { + if(strcmp(pch, elt) == 0) + return 1; + } + return 0; } void add_elt_to_str_list(char **str_list, char *elt) { - char *list= NULL; - if(*str_list == NULL || strlen(*str_list) == 0){ - dmasprintf(str_list, "%s", elt); - return; - } - list= dmstrdup(*str_list); - dmfree(*str_list); - *str_list= NULL; - dmasprintf(str_list, "%s %s", list, elt); + char *list= NULL; + if(*str_list == NULL || strlen(*str_list) == 0){ + dmasprintf(str_list, "%s", elt); + return; + } + list= dmstrdup(*str_list); + dmfree(*str_list); + *str_list= NULL; + dmasprintf(str_list, "%s %s", list, elt); } void remove_elt_from_str_list(char **iface_list, char *ifname) { - char *list= NULL, *tmp=NULL; - char *pch, *spch; - if (*iface_list == NULL || strlen(*iface_list) == 0) - return; - list= dmstrdup(*iface_list); - dmfree(*iface_list); - *iface_list= NULL; - for (pch = strtok_r(list, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch)) { - if(strcmp(pch, ifname) == 0) - continue; - if(tmp == NULL) - dmasprintf(iface_list, "%s", pch); - else - dmasprintf(iface_list, "%s %s", tmp, pch); - if(tmp){ - dmfree(tmp); - tmp= NULL; - } - if(*iface_list){ - tmp= dmstrdup(*iface_list); - dmfree(*iface_list); - *iface_list= NULL; - } - } - dmasprintf(iface_list, "%s", tmp); + char *list= NULL, *tmp=NULL; + char *pch, *spch; + if (*iface_list == NULL || strlen(*iface_list) == 0) + return; + list= dmstrdup(*iface_list); + dmfree(*iface_list); + *iface_list= NULL; + for (pch = strtok_r(list, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch)) { + if(strcmp(pch, ifname) == 0) + continue; + if(tmp == NULL) + dmasprintf(iface_list, "%s", pch); + else + dmasprintf(iface_list, "%s %s", tmp, pch); + if(tmp){ + dmfree(tmp); + tmp= NULL; + } + if(*iface_list){ + tmp= dmstrdup(*iface_list); + dmfree(*iface_list); + *iface_list= NULL; + } + } + dmasprintf(iface_list, "%s", tmp); } int is_array_elt_exist(char **str_array, char *str, int length) { - int i; + int i; - for (i = 0; i < length; i++){ - if (strcmp(str_array[i], str) == 0) - return 1; - } - return 0; + for (i = 0; i < length; i++){ + if (strcmp(str_array[i], str) == 0) + return 1; + } + return 0; } int get_shift_time_time(int shift_time, char *local_time, int size) { - time_t t_time; - struct tm *t_tm; + time_t t_time; + struct tm *t_tm; - t_time = time(NULL) + shift_time; - t_tm = localtime(&t_time); - if (t_tm == NULL) - return -1; + t_time = time(NULL) + shift_time; + t_tm = localtime(&t_time); + if (t_tm == NULL) + return -1; - if (strftime(local_time, size, "%Y-%m-%dT%H:%M:%SZ", t_tm) == 0) - return -1; + if (strftime(local_time, size, "%Y-%m-%dT%H:%M:%SZ", t_tm) == 0) + return -1; - return 0; + return 0; } int get_shift_time_shift(char *local_time, char *shift) @@ -1701,15 +1827,15 @@ int dm_time_format(time_t ts, char **dst) *dst = "0001-01-01T00:00:00Z"; - t_tm = localtime(&ts); - if (t_tm == NULL) - return -1; + t_tm = localtime(&ts); + if (t_tm == NULL) + return -1; - if(strftime(time_buf, sizeof(time_buf), "%Y-%m-%dT%H:%M:%SZ", t_tm) == 0) - return -1; + if(strftime(time_buf, sizeof(time_buf), "%Y-%m-%dT%H:%M:%SZ", t_tm) == 0) + return -1; - *dst = dmstrdup(time_buf); - return 0; + *dst = dmstrdup(time_buf); + return 0; } bool match(const char *string, const char *pattern) diff --git a/libbbf_api/dmcommon.h b/libbbf_api/dmcommon.h index bc39f5ef..c2672a40 100644 --- a/libbbf_api/dmcommon.h +++ b/libbbf_api/dmcommon.h @@ -273,6 +273,8 @@ void hex_to_ip(char *address, char *ret); void ip_to_hex(char *address, char *ret); void free_dmmap_config_dup_list(struct list_head *dup_list); void synchronize_specific_config_sections_with_dmmap(char *package, char *section_type, char *dmmap_package, struct list_head *dup_list); +void synchronize_specific_config_sections_with_dmmap_vlan(char *package, char *section_type, char *dmmap_package, char *ifname, struct list_head *dup_list, int *count, char *id); +void synchronize_multi_config_sections_with_dmmap_set(char *package, char *section_type, char *dmmap_package, char* dmmap_section, char* option_name, char* option_value, char *instance, char *br_key); void synchronize_specific_config_sections_with_dmmap_eq(char *package, char *section_type, char *dmmap_package,char* option_name, char* option_value, struct list_head *dup_list); void synchronize_specific_config_sections_with_dmmap_eq_no_delete(char *package, char *section_type, char *dmmap_package,char* option_name, char* option_value, struct list_head *dup_list); void synchronize_specific_config_sections_with_dmmap_cont(char *package, char *section_type, char *dmmap_package,char* option_name, char* option_value, struct list_head *dup_list);