From cd391b939be693c9ff1f18b52b68b49cdd64f0b7 Mon Sep 17 00:00:00 2001 From: Amin Ben Ramdhane Date: Wed, 8 Apr 2020 21:51:23 +0100 Subject: [PATCH] Ticket refs#2344: TR-181: Correct implementation of Device.Ethernet.VLANTermination --- dmtree/tr181/bridging.c | 92 ++++++--- dmtree/tr181/ethernet.c | 375 +++++++++++++++------------------- dmtree/tr181/firewall.c | 11 +- dmtree/tr181/interfacestack.c | 68 +++--- dmtree/tr181/ip.c | 26 ++- libbbf_api/dmcommon.c | 120 +++++------ libbbf_api/dmcommon.h | 4 +- libbbf_api/dmuci.h | 8 +- 8 files changed, 361 insertions(+), 343 deletions(-) diff --git a/dmtree/tr181/bridging.c b/dmtree/tr181/bridging.c index 8a2bd5a7..b1ac09a3 100644 --- a/dmtree/tr181/bridging.c +++ b/dmtree/tr181/bridging.c @@ -363,48 +363,79 @@ static int get_br_vlan_port_number_of_entries(char *refparam, struct dmctx *ctx, 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 = NULL; - dmuci_get_value_by_section_string(((struct bridging_port_args *)data)->bridge_port_sec, "ifname", value); + + // wifi-iface wireless section if(strncmp(*value, "wl", 2) == 0 || strncmp(*value, "ra", 2) == 0 || strncmp(*value, "apclii", 6) == 0) { + struct uci_section *wifi_device_s = NULL; + char *val; + uci_foreach_option_eq("wireless", "wifi-iface", "ifname", *value, wifi_device_s) { dmuci_get_value_by_section_string(wifi_device_s, "disabled", &val); - if ((val[0] == '\0') || (val[0] == '0')) - *value = "true"; - else - *value = "false"; + *value = (val[0] == '1') ? "0" : "1"; return 0; } } - dmubus_call("network.device", "status", UBUS_ARGS{{"name", *value, String}}, 1, &res); - DM_ASSERT(res, *value = "false"); - speed = dmjson_get_value(res, 1, "speed"); - if(*speed != '\0') - *value = "true"; - else - *value = "false"; + + // ethport ports section + char *type; + dmuci_get_value_by_section_string(((struct bridging_port_args *)data)->bridge_port_sec, "type", &type); + if (*type == '\0') { + dmuci_get_value_by_section_string(((struct bridging_port_args *)data)->bridge_port_sec, "enabled", value); + } else { + struct uci_section *s = NULL; + uci_foreach_option_eq("ports", "ethport", "ifname", *value, s) { + dmuci_get_value_by_section_string(s, "enabled", value); + break; + } + } + if ((*value)[0] == '\0') *value = "1"; return 0; } static int set_br_port_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { + bool b; + char *ifname; + switch (action) { case VALUECHECK: if (dm_validate_boolean(value)) return FAULT_9007; return 0; case VALUESET: + string_to_bool(value, &b); + dmuci_get_value_by_section_string(((struct bridging_port_args *)data)->bridge_port_sec, "ifname", &ifname); + + // wifi-iface wireless section + if(strncmp(ifname, "wl", 2) == 0 || strncmp(ifname, "ra", 2) == 0 || strncmp(ifname, "apclii", 6) == 0) { + struct uci_section *wifi_device_s = NULL; + + uci_foreach_option_eq("wireless", "wifi-iface", "ifname", ifname, wifi_device_s) { + dmuci_set_value_by_section(wifi_device_s, "disabled", b ? "0" : "1"); + return 0; + } + } + + // ethport ports section + char *type; + dmuci_get_value_by_section_string(((struct bridging_port_args *)data)->bridge_port_sec, "type", &type); + if (*type == '\0') { + dmuci_set_value_by_section(((struct bridging_port_args *)data)->bridge_port_sec, "enabled", b ? "1" : "0"); + } else { + struct uci_section *s = NULL; + uci_foreach_option_eq("ports", "ethport", "ifname", ifname, s) { + dmuci_set_value_by_section(s, "enabled", b ? "1" : "0"); + break; + } + } return 0; } return 0; } -/*#Device.Bridging.Bridge.{i}.Port.{i}.Status!UBUS:network.device/status/name,@Name/speed*/ static int get_br_port_status(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { bool b; @@ -494,7 +525,7 @@ static int get_br_port_default_user_priority(char *refparam, struct dmctx *ctx, struct uci_section *s = NULL; char *name, *type; - *value = ""; + *value = "0"; dmuci_get_value_by_section_string(((struct bridging_port_args *)data)->bridge_port_sec, "name", &name); s = check_if_ifname_is_tagged(name); if (s != NULL) { @@ -989,8 +1020,20 @@ static int get_br_port_alias(char *refparam, struct dmctx *ctx, void *data, char 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, "bridge_port_alias", value); - if ((*value)[0] == '\0') - dmuci_get_value_by_section_string(((struct bridging_port_args *)data)->bridge_port_sec, "name", value); + if ((*value)[0] == '\0') { + char *type; + dmuci_get_value_by_section_string(((struct bridging_port_args *)data)->bridge_port_sec, "type", &type); + if (*type == '\0') { + dmuci_get_value_by_section_string(((struct bridging_port_args *)data)->bridge_port_sec, "name", value); + } else { + struct uci_section *s = NULL; + dmuci_get_value_by_section_string(((struct bridging_port_args *)data)->bridge_port_sec, "ifname", value); + uci_foreach_option_eq("ports", "ethport", "ifname", *value, s) { + dmuci_get_value_by_section_string(s, "name", value); + break; + } + } + } return 0; } @@ -1529,12 +1572,7 @@ static int check_port_with_ifname (char *ifname, struct uci_section **ss, int *i struct uci_section *sss = NULL, *s = NULL; char *atm_device, *ptm_device; - if (check_ifname_is_vlan(ifname)) { - uci_foreach_option_eq("network", "device", "name", ifname, s) { - *ss = s; - break; - } - } else if (strncmp(ifname, "ptm", 3) == 0) { + if (strncmp(ifname, "ptm", 3) == 0) { if (access("/etc/config/dsl", F_OK) != -1) { uci_foreach_sections("dsl", "ptm-device", sss) { dmuci_get_value_by_section_string(sss, "device", &ptm_device); @@ -1622,7 +1660,7 @@ static int get_port_lower_layer(char *refparam, struct dmctx *ctx, void *data, c /* Added support for tagged and untagged interfaces. */ int is_tag = 0; check_port_with_ifname(pch, &s, &is_tag); - if(s == NULL) + 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); diff --git a/dmtree/tr181/ethernet.c b/dmtree/tr181/ethernet.c index d920ffcf..c74461e0 100644 --- a/dmtree/tr181/ethernet.c +++ b/dmtree/tr181/ethernet.c @@ -62,19 +62,6 @@ static int is_device_exist(char *device) return 0; } -static int is_mac_exist(char *macaddr) -{ - struct uci_section *s = NULL; - char *mac; - - uci_path_foreach_sections(bbfdm, DMMAP, "link", s) { - dmuci_get_value_by_section_string(s, "mac", &mac); - if (strcmp(mac, macaddr) == 0) - return 1; - } - return 0; -} - static void create_link(char *ifname) { char *macaddr, *v, *device; @@ -132,13 +119,12 @@ static void create_link(char *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, *proto; + char *ifname, *proto; uci_foreach_sections("network", "interface", s) { - dmuci_get_value_by_section_string(s, "type", &type); dmuci_get_value_by_section_string(s, "proto", &proto); - if (strcmp(type, "alias") == 0 || strcmp(section_name(s), "loopback") == 0 || *proto == '\0') + if (strcmp(section_name(s), "loopback") == 0 || *proto == '\0') continue; dmuci_get_value_by_section_string(s, "ifname", &ifname); @@ -153,53 +139,19 @@ static int dmmap_synchronizeEthernetLink(struct dmctx *dmctx, DMNODE *parent_nod static char *get_vlan_last_instance_bbfdm(char *package, char *section, char *opt_inst) { struct uci_section *s, *confsect; - char *inst = NULL, *last_inst = NULL, *sect_name; + char *inst = NULL, *last_inst = NULL, *type, *sect_name, *name; 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", "interface", sect_name, &confsect); - - char *proto; - dmuci_get_value_by_section_string(confsect, "proto", &proto); - if (*proto == '\0') + get_config_section_of_dmmap_section("network", "device", sect_name, &confsect); + dmuci_get_value_by_section_string(confsect, "type", &type); + dmuci_get_value_by_section_string(confsect, "name", &name); + if (strcmp(type, "untagged") == 0 || !is_vlan_termination_section(name)) 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) - 1); - - /* Only tagged interfaces should be considered. */ - int ret = 0; - char *tok, *end; - tok = strtok_r(ifname, " ", &end); - if (tok == NULL) { - char *tag; - strtok_r(tok, ".", &tag); - if (tag != NULL) { - char tag_if[10] = {0}; - strncpy(tag_if, tag, sizeof(tag_if) - 1); - 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); - } + inst = update_instance_bbfdm(s, last_inst, opt_inst); + if(last_inst) + dmfree(last_inst); + last_inst = dmstrdup(inst); } return inst; } @@ -237,24 +189,25 @@ static int browseEthernetLinkInst(struct dmctx *dmctx, DMNODE *parent_node, void uci_path_foreach_sections(bbfdm, DMMAP, "link", s) { args.section = s; id = handle_update_instance(1, dmctx, &id_last, update_instance_alias_bbfdm, 3, s, "link_instance", "link_alias"); - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&args, id) == DM_STOP) { + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&args, id) == DM_STOP) break; - } } return 0; } -/*#Device.Ethernet.VLANTermination.{i}.!UCI:network/interface/dmmap_network*/ +/*#Device.Ethernet.VLANTermination.{i}.!UCI:network/device/dmmap_network*/ static int browseEthernetVLANTerminationInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) { - char *vlan_term = NULL, *vlan_term_last = NULL; + char *type, *name, *vlan_term = NULL, *vlan_term_last = NULL; struct dm_args curr_vlan_term_args = {0}; struct dmmap_dup *p = NULL; LIST_HEAD(dup_list); - synchronize_specific_config_sections_with_dmmap("network", "interface", "dmmap_network", &dup_list); + synchronize_specific_config_sections_with_dmmap("network", "device", "dmmap_network", &dup_list); list_for_each_entry(p, &dup_list, list) { - if (!is_vlan_termination_section(p->config_section)) + dmuci_get_value_by_section_string(p->config_section, "type", &type); + dmuci_get_value_by_section_string(p->config_section, "name", &name); + if (strcmp(type, "untagged") == 0 || !is_vlan_termination_section(name)) continue; curr_vlan_term_args.section = p->config_section; vlan_term = handle_update_instance(1, dmctx, &vlan_term_last, update_instance_alias, 3, p->dmmap_section, "vlan_term_instance", "vlan_term_alias"); @@ -292,7 +245,7 @@ static int get_linker_link(char *refparam, struct dmctx *dmctx, void *data, char static int get_linker_vlan_term(char *refparam, struct dmctx *dmctx, void *data, char *instance, char **linker) { if(data && ((struct dm_args *)data)->section) - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "ifname", linker); + dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "name", linker); else *linker = ""; return 0; @@ -328,7 +281,6 @@ static int del_ethernet_link_instance(char *sect_name) /* Get section from section_name.*/ uci_foreach_sections("network", "interface", intf_s) { if (strcmp(section_name(intf_s), sect_name) == 0) { - char *intf; dmuci_get_value_by_section_string(intf_s, "ifname", &intf); @@ -337,13 +289,12 @@ static int del_ethernet_link_instance(char *sect_name) if (strncmp(intf_tag, intf, sizeof(intf_tag)) == 0) { prev_s = intf_s; ret = 1; - break; } else { char *proto; dmuci_get_value_by_section_string(intf_s, "proto", &proto); dmuci_delete_by_section(intf_s, "proto", proto); - break; } + break; } } @@ -360,9 +311,9 @@ static int del_ethernet_link_instance(char *sect_name) } /* Remove the Link section from dmmap. */ - struct uci_section *dmmap_section; + struct uci_section *dmmap_section = NULL; get_dmmap_section_of_config_section("dmmap", "link", sect_name, &dmmap_section); - dmuci_delete_by_section(dmmap_section, NULL, NULL); + if (dmmap_section) dmuci_delete_by_section(dmmap_section, NULL, NULL); return 0; } @@ -392,73 +343,81 @@ 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, *eth_wan, *vid, *name, *vlan_name, *val, *v; + char intf_tag[64] = {0}, *inst, *vid, *name, *device_name, *interface_name, *val, *v; struct uci_section *s = NULL, *dmmap_network = NULL; check_create_dmmap_package("dmmap_network"); - inst = get_vlan_last_instance_bbfdm("dmmap_network", "interface", "vlan_term_instance"); + inst = get_vlan_last_instance_bbfdm("dmmap_network", "device", "vlan_term_instance"); - dmuci_get_option_value_string("ports", "WAN", "ifname", ð_wan); - dmasprintf(&vid, "%d", inst?atoi(inst)+5:4); - dmasprintf(&vlan_name, "vlan_%s", vid); - dmuci_add_section_and_rename("network", "interface", &s, &val); + get_upstream_interface(intf_tag, sizeof(intf_tag)); + dmasprintf(&vid, "%d", inst ? atoi(inst)+1 : 2); + dmasprintf(&interface_name, "%s_%s", intf_tag, vid); + dmasprintf(&device_name, "vlan_%s", vid); + dmasprintf(&name, "%s.%s", intf_tag, vid); + + // Add network section + dmuci_add_section("network", "interface", &s, &val); + dmuci_rename_section_by_section(s, interface_name); 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_by_section(s, "ifname", name); - /* Get the upstream interface. */ - char *mac; - char intf_tag[50] = {0}; - /* Get the upstream interface. */ - get_upstream_interface(intf_tag, sizeof(intf_tag)); + // Add device section + dmuci_add_section("network", "device", &s, &val); + dmuci_rename_section_by_section(s, device_name); + dmuci_set_value_by_section(s, "type", "8021q"); + dmuci_set_value_by_section(s, "ifname", intf_tag); + dmuci_set_value_by_section(s, "vid", vid); + dmuci_set_value_by_section(s, "name", name); - /* Fetch the macaddress of upstream interface. */ - if (intf_tag[0] != '\0') { - char file[128]; - char val[32]; - - snprintf(file, sizeof(file), "/sys/class/net/%s/address", intf_tag); - dm_read_sysfs_file(file, val, sizeof(val)); - mac = dmstrdup(val); - } else { - mac = ""; - } - - /* Create a mac address for the tagged upstream interfaces - * using the base mac address. */ - char mac_addr[25] = {0}; - create_mac_addr_upstream_intf(mac_addr, mac, sizeof(mac_addr)); - - if (mac_addr[0] != '\0') - dmuci_set_value_by_section(s, "macaddr", mac_addr); - - dmuci_add_section_bbfdm("dmmap_network", "interface", &dmmap_network, &v); - dmuci_set_value_by_section(dmmap_network, "section_name", vlan_name); + // Add device section in dmmap_network file + dmuci_add_section_bbfdm("dmmap_network", "device", &dmmap_network, &v); + dmuci_set_value_by_section(dmmap_network, "section_name", device_name); *instance = update_instance_bbfdm(dmmap_network, inst, "vlan_term_instance"); return 0; } static int delObjEthernetVLANTermination(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action) { - struct uci_section *dmmap_section = NULL; + struct uci_section *s = NULL, *stmp = NULL, *dmmap_section = NULL, *s_dev = NULL, *sdevtmp = NULL; + char *name, *type; switch (del_action) { case DEL_INST: - if(is_section_unnamed(section_name(((struct dm_args *)data)->section))) { - LIST_HEAD(dup_list); - delete_sections_save_next_sections("dmmap_network", "interface", "vlan_term_instance", section_name(((struct dm_args *)data)->section), atoi(instance), &dup_list); - update_dmmap_sections(&dup_list, "vlan_term_instance", "dmmap_network", "interface"); - dmuci_delete_by_section_unnamed(((struct dm_args *)data)->section, NULL, NULL); - } else { - get_dmmap_section_of_config_section("dmmap_network", "interface", section_name(((struct dm_args *)data)->section), &dmmap_section); - if (dmmap_section != NULL) - dmuci_delete_by_section_unnamed_bbfdm(dmmap_section, NULL, NULL); - dmuci_delete_by_section(((struct dm_args *)data)->section, NULL, NULL); + // Remove network section + dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "name", &name); + uci_foreach_option_eq_safe("network", "interface", "ifname", name, stmp, s) { + dmuci_delete_by_section(s, NULL, NULL); } + + // Remove device section in dmmap_network file + get_dmmap_section_of_config_section("dmmap_network", "device", section_name(((struct dm_args *)data)->section), &dmmap_section); + if (dmmap_section) + dmuci_delete_by_section(dmmap_section, NULL, NULL); + + // Remove device section + dmuci_delete_by_section(((struct dm_args *)data)->section, NULL, NULL); break; case DEL_ALL: - return FAULT_9005; + uci_foreach_sections_safe("network", "device", sdevtmp, s_dev) { + dmuci_get_value_by_section_string(s_dev, "type", &type); + dmuci_get_value_by_section_string(s_dev, "name", &name); + if (strcmp(type, "untagged") == 0 || !is_vlan_termination_section(name)) + continue; + + // Remove network section + uci_foreach_option_eq_safe("network", "interface", "ifname", name, stmp, s) { + dmuci_delete_by_section(s, NULL, NULL); + } + + // Remove device section in dmmap_network file + get_dmmap_section_of_config_section("dmmap_network", "device", section_name(s_dev), &dmmap_section); + if (dmmap_section) + dmuci_delete_by_section(dmmap_section, NULL, NULL); + + // Remove device section + dmuci_delete_by_section(s_dev, NULL, NULL); + } + break; } return 0; } @@ -496,10 +455,13 @@ static int get_Ethernet_LinkNumberOfEntries(char *refparam, struct dmctx *ctx, v static int get_Ethernet_VLANTerminationNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { struct uci_section *s = NULL; + char *type, *name; int cnt = 0; - uci_foreach_sections("network", "interface", s) { - if (!is_vlan_termination_section(s)) + uci_foreach_sections("network", "device", s) { + dmuci_get_value_by_section_string(s, "type", &type); + dmuci_get_value_by_section_string(s, "name", &name); + if (strcmp(type, "untagged") == 0 || !is_vlan_termination_section(name)) continue; cnt++; } @@ -872,13 +834,13 @@ static int get_EthernetLink_LastChange(char *refparam, struct dmctx *ctx, void * static int get_EthernetLink_LowerLayers(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { struct uci_section *s = NULL; - char *link_mac, *type, *ifname, *mac, *br_inst, *mg, linker[64] = ""; + char *link_mac, *proto, *type, *ifname, *mac, *br_inst, *mg, linker[64] = ""; struct uci_section *dmmap_section, *port; dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "mac", &link_mac); 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) + dmuci_get_value_by_section_string(s, "proto", &proto); + if (strcmp(section_name(s), "loopback") == 0 || *proto == '\0') continue; dmuci_get_value_by_section_string(s, "ifname", &ifname); @@ -889,6 +851,7 @@ static int get_EthernetLink_LowerLayers(char *refparam, struct dmctx *ctx, void if (mac[0] == '\0' || strcasecmp(mac, link_mac) != 0) continue; + dmuci_get_value_by_section_string(s, "type", &type); if (strcmp(type, "bridge") == 0) { get_dmmap_section_of_config_section("dmmap_network", "interface", section_name(s), &dmmap_section); if (dmmap_section != NULL) { @@ -1104,16 +1067,7 @@ static int set_ethlink_lowerlayer_eth_intf(char *lower_layer, char *instance, ch get_upstream_interface(intf_tag, sizeof(intf_tag)); /* Fetch the macaddress of upstream interface. */ - char *mac; - if (intf_tag[0] != '\0') { - char file[128]; - char val[32]; - snprintf(file, sizeof(file), "/sys/class/net/%s/address", intf_tag); - dm_read_sysfs_file(file, val, sizeof(val)); - mac = dmstrdup(val); - } else { - mac = ""; - } + char *mac = get_macaddr_from_device(intf_tag); /* Create a mac address for the tagged upstream interfaces * using the base mac address. */ @@ -1148,6 +1102,7 @@ static int set_ethlink_lowerlayer_eth_intf(char *lower_layer, char *instance, ch 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)) @@ -1167,13 +1122,9 @@ static int set_EthernetLink_LowerLayers(char *refparam, struct dmctx *ctx, void char *linker; adm_entry_get_linker_value(ctx, lower_layer, &linker); set_ethlink_lowerlayer_eth_intf(lower_layer, instance, linker); - - } else { - return -1; } break; } - return 0; } @@ -1257,7 +1208,7 @@ static int get_EthernetVLANTermination_Alias(char *refparam, struct dmctx *ctx, { struct uci_section *dmmap_section = NULL; - get_dmmap_section_of_config_section("dmmap_network", "interface", section_name(((struct dm_args *)data)->section), &dmmap_section); + get_dmmap_section_of_config_section("dmmap_network", "device", section_name(((struct dm_args *)data)->section), &dmmap_section); dmuci_get_value_by_section_string(dmmap_section, "vlan_term_alias", value); return 0; } @@ -1272,7 +1223,7 @@ 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", "interface", section_name(((struct dm_args *)data)->section), &dmmap_section); + get_dmmap_section_of_config_section("dmmap_network", "device", section_name(((struct dm_args *)data)->section), &dmmap_section); if(dmmap_section) dmuci_set_value_by_section(dmmap_section, "vlan_term_alias", value); return 0; @@ -1289,117 +1240,130 @@ static int get_EthernetVLANTermination_Name(char *refparam, struct dmctx *ctx, v /*#Device.Ethernet.VLANTermination.{i}.LastChange!UBUS:network.interface/status/interface,@Name/uptime*/ static int get_EthernetVLANTermination_LastChange(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - json_object *res; + json_object *res = NULL; struct uci_section *s = NULL; - char *ifname, *devifname; + char *devname; - *value ="0"; - 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)) { - dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", section_name(s), String}}, 1, &res); - DM_ASSERT(res, *value = "0"); - *value = dmjson_get_value(res, 1, "uptime"); - if((*value)[0] == '\0') - *value = "0"; - break; - } + *value = "0"; + dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "name", &devname); + uci_foreach_option_eq("network", "interface", "ifname", devname, s) { + dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", section_name(s), String}}, 1, &res); + DM_ASSERT(res, *value = "0"); + *value = dmjson_get_value(res, 1, "uptime"); + if((*value)[0] == '\0') + *value = "0"; + break; } return 0; } static int get_EthernetVLANTermination_LowerLayers(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - char *pch, *spch, *devifname, *ifname, *dupifname, *mac; - struct uci_section *section = NULL; + char *macaddr, *devname, *linker = ""; - 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) { - 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; + dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "name", &devname); + macaddr = get_macaddr_from_device(devname); + if (macaddr[0] != '\0') { + if (is_mac_exist(macaddr)) { + linker = macaddr; + } else { + char intf_tag[64] = {0}; + get_upstream_interface(intf_tag, sizeof(intf_tag)); + if (intf_tag[0] != '\0') { + strcat(intf_tag, ".1"); + linker = get_macaddr_from_device(intf_tag); } } } + if (linker[0] != '\0') { + adm_entry_get_linker_param(ctx, dm_print_path("%s%cEthernet%cLink%c", dmroot, dm_delim, dm_delim, dm_delim), linker, value); + if (*value == NULL) + *value = ""; + } return 0; } static int set_EthernetVLANTermination_LowerLayers(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - char *iface_list, *linker = NULL, *newvalue = NULL, *vlan_name = NULL; - struct uci_section *s = NULL; + char lower_layer[256] = {0}; switch (action) { case VALUECHECK: if (dm_validate_string_list(value, -1, -1, 1024, -1, -1, NULL, 0, NULL, 0)) return FAULT_9007; - return 0; + break; 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); + if (value[strlen(value)-1] != '.') + snprintf(lower_layer, sizeof(lower_layer), "%s.", value); + else + strncpy(lower_layer, value, sizeof(lower_layer) - 1); - if (linker == NULL || *linker == '\0') - return -1; + if (strncmp(lower_layer, "Device.Ethernet.Link.", 21) == 0) { + char *linker = NULL, *section_name, *devname, *iface_list, *mac; - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "name", &vlan_name); - uci_foreach_sections("network", "interface", s) { - dmuci_get_value_by_section_string(s, "ifname", &iface_list); - if(strcmp(section_name(s), linker) != 0 && is_elt_exit_in_str_list(iface_list, vlan_name)) { - remove_elt_from_str_list(&iface_list, vlan_name); - dmuci_set_value_by_section(s, "ifname", iface_list); - } else if (strcmp(section_name(s), linker) == 0 && !is_elt_exit_in_str_list(iface_list, vlan_name)) { - add_elt_to_str_list(&iface_list, vlan_name); - dmuci_set_value_by_section(s, "ifname", iface_list); + adm_entry_get_linker_value(ctx, lower_layer, &linker); + if (linker == NULL || *linker == '\0') + return -1; + + struct uci_section *s = NULL, *dmmap_s = NULL; + get_dmmap_section_of_config_section_eq("dmmap", "link", "mac", linker, &dmmap_s); + if (dmmap_s) + dmuci_get_value_by_section_string(dmmap_s, "section_name", §ion_name); + + dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "name", &devname); + uci_foreach_sections("network", "interface", s) { + dmuci_get_value_by_section_string(s, "ifname", &iface_list); + mac = get_macaddr(section_name(s)); + if (strcmp(mac, linker) != 0 && is_elt_exit_in_str_list(iface_list, devname)) { + remove_elt_from_str_list(&iface_list, devname); + dmuci_set_value_by_section(s, "ifname", (*iface_list == '\0') ? iface_list : ""); + } else if (strcmp(mac, linker) == 0 && !is_elt_exit_in_str_list(iface_list, devname)) { + add_elt_to_str_list(&iface_list, devname); + dmuci_set_value_by_section(s, "ifname", iface_list); + } } } + break; } return 0; } -/*#Device.Ethernet.VLANTermination.{i}.LastChange!UCI:network/device,@i-1/vid*/ +/*#Device.Ethernet.VLANTermination.{i}.VLANID!UCI:network/device,@i-1/vid*/ static int get_EthernetVLANTermination_VLANID(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { *value = "0"; - char *ifname, *tag; - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "ifname", &ifname); - strtok_r(ifname, ".", &tag); - if (tag != NULL) { - *value = tag; - } + dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "vid", value); return 0; } static int set_EthernetVLANTermination_VLANID(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - char *ifname, *name; + char *ifname, *name, *curr_ifname; + struct uci_section *s = NULL; switch (action) { case VALUECHECK: if (dm_validate_unsignedInt(value, RANGE_ARGS{{"1","4094"}}, 1)) return FAULT_9007; return 0; - case VALUESET: { + case VALUESET: dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "ifname", &ifname); - char *tok, *tag; - tok = strtok_r(ifname, ".", &tag); - if (tok != NULL) { - dmasprintf(&name, "%s.%s", tok, value); + dmasprintf(&name, "%s.%s", ifname, value); + + // set ifname option of the corresponding interface section + dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "name", &curr_ifname); + uci_foreach_option_eq("network", "interface", "ifname", curr_ifname, s) { + dmuci_set_value_by_section(s, "ifname", name); } - dmuci_set_value_by_section(((struct dm_args *)data)->section, "ifname", name); + + // set name option of the device section + dmuci_set_value_by_section(((struct dm_args *)data)->section, "name", name); + + // set vid option of the device section + dmuci_set_value_by_section(((struct dm_args *)data)->section, "vid", value); + dmfree(name); return 0; - } } return 0; } @@ -1407,11 +1371,10 @@ static int set_EthernetVLANTermination_VLANID(char *refparam, struct dmctx *ctx, /*#Device.Ethernet.VLANTermination.{i}.TPID!UCI:network/device,@i-1/type*/ static int get_EthernetVLANTermination_TPID(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - char *type; - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "type", &type); - if (strcmp(type, "8021q") == 0 || strcmp(type, "untagged") == 0) + dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "type", value); + if (strcmp(*value, "8021q") == 0) *value = "33024"; - else if (strcmp(type, "8021ad") == 0) + else if (strcmp(*value, "8021ad") == 0) *value = "34984"; else *value = "37120"; @@ -1430,8 +1393,6 @@ static int set_EthernetVLANTermination_TPID(char *refparam, struct dmctx *ctx, v dmuci_set_value_by_section(((struct dm_args *)data)->section, "type", "8021q"); else if (strcmp(value, "34984") == 0) dmuci_set_value_by_section(((struct dm_args *)data)->section, "type", "8021ad"); - else - return -1; return 0; } return 0; diff --git a/dmtree/tr181/firewall.c b/dmtree/tr181/firewall.c index 870ab017..c641a812 100644 --- a/dmtree/tr181/firewall.c +++ b/dmtree/tr181/firewall.c @@ -293,7 +293,7 @@ static int get_rule_source_interface(char *refparam, struct dmctx *ctx, void *da { struct uci_list *v = NULL, *v1 = NULL; struct uci_element *e; - char *vallink, *zone, buf[256] = "", *val; + char *vallink = NULL, *zone, buf[256] = "", *val; struct uci_section *s = NULL; dmuci_get_value_by_section_string((struct uci_section *)data, "src", &zone); @@ -320,7 +320,7 @@ static int get_rule_source_interface(char *refparam, struct dmctx *ctx, void *da if (v != NULL) { uci_foreach_element(v, e) { adm_entry_get_linker_param(ctx, dm_print_path("%s%cIP%cInterface%c", dmroot, dm_delim, dm_delim, dm_delim), e->name, &vallink); - if (*vallink == '\0') + if (vallink == NULL) continue; if (*buf != '\0') strcat(buf, ","); @@ -328,7 +328,8 @@ static int get_rule_source_interface(char *refparam, struct dmctx *ctx, void *da } } else { adm_entry_get_linker_param(ctx, dm_print_path("%s%cIP%cInterface%c", dmroot, dm_delim, dm_delim, dm_delim), zone, &vallink); - strcpy(buf, vallink); + if (vallink) + strcpy(buf, vallink); } *value = dmstrdup(buf); @@ -339,7 +340,7 @@ static int get_rule_dest_interface(char *refparam, struct dmctx *ctx, void *data { struct uci_list *v = NULL; struct uci_element *e; - char *zone, *ifaceobj, buf[256] = "", *val; + char *zone, *ifaceobj = NULL, buf[256] = "", *val; struct uci_section *s = NULL; dmuci_get_value_by_section_string((struct uci_section *)data, "dest", &zone); @@ -353,7 +354,7 @@ static int get_rule_dest_interface(char *refparam, struct dmctx *ctx, void *data if (v != NULL) { uci_foreach_element(v, e) { adm_entry_get_linker_param(ctx, dm_print_path("%s%cIP%cInterface%c", dmroot, dm_delim, dm_delim, dm_delim), e->name, &ifaceobj); - if (*ifaceobj == '\0') + if (ifaceobj == NULL) continue; if (*buf != '\0') strcat(buf, ","); diff --git a/dmtree/tr181/interfacestack.c b/dmtree/tr181/interfacestack.c index 46678fb6..315a4a64 100644 --- a/dmtree/tr181/interfacestack.c +++ b/dmtree/tr181/interfacestack.c @@ -72,21 +72,21 @@ int browseInterfaceStackInst(struct dmctx *dmctx, DMNODE *parent_node, void *pre { struct interfacestack_data ifdata = {0}; struct uci_section *s = NULL, *sd = NULL, *port, *port_s, *ss, *dmmap_s = NULL; - char *proto, *type, *pch, *spch, *layer_inst, *v, *vb, *higheralias, *loweralias, *ifname, *br_inst, *mg, *value, *device, *name; + char *proto, *type, *pch, *layer_inst, *v, *vb, *higheralias, *loweralias, *ifname, *br_inst, *mg, *value, *device, *name; char *interface_stack_int = NULL, *interface_stack_int_last = NULL, *wanifname, *wanlinker, *mac, *sectionname, *package, *section; - char buf_lowerlayer[128] = ""; - char buf_higherlayer[128] = ""; - char buf_higheralias[64] = ""; - char buf_loweralias[64] = ""; - char buf_instance[32] = ""; - char linker[64] = ""; - char buf_tmp[64] = ""; + char buf_lowerlayer[128] = {0}; + char buf_higherlayer[128] = {0}; + char buf_higheralias[64] = {0}; + char buf_loweralias[64] = {0}; + char buf_instance[32] = {0}; + char linker[64] = {0}; + char buf_tmp[64] = {0}; int instance = 0, found = 0; /* Higher layers are Device.IP.Interface.{i}. */ 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) + dmuci_get_value_by_section_string(s, "proto", &proto); + if (strcmp(section_name(s), "loopback") == 0 || *proto == '\0') continue; layer_inst = get_instance_by_section(dmctx, dmctx->instance_mode, "dmmap_network", "interface", s, "ip_int_instance", "ip_int_alias"); if (*layer_inst == '\0') @@ -94,7 +94,6 @@ int browseInterfaceStackInst(struct dmctx *dmctx, DMNODE *parent_node, void *pre snprintf(buf_higherlayer, sizeof(buf_higherlayer), "Device.IP.Interface.%s.", layer_inst); higheralias = get_alias_by_section("dmmap_network", "interface", s, "ip_int_alias"); snprintf(buf_higheralias, sizeof(buf_higheralias), "%s", higheralias); - dmuci_get_value_by_section_string(s, "proto", &proto); if (strstr(proto, "ppp")) { layer_inst = get_instance_by_section(dmctx, dmctx->instance_mode, "dmmap_network", "interface", s, "ppp_int_instance", "ppp_int_alias"); if (*layer_inst == '\0') @@ -102,8 +101,7 @@ int browseInterfaceStackInst(struct dmctx *dmctx, DMNODE *parent_node, void *pre snprintf(buf_lowerlayer, sizeof(buf_lowerlayer), "Device.PPP.Interface.%s.", layer_inst); loweralias = get_alias_by_section("dmmap_network", "interface", s, "ppp_int_alias"); snprintf(buf_loweralias, sizeof(buf_loweralias), "%s", loweralias); - } - else { + } else { device = get_device(section_name(s)); if (device[0] != '\0') { adm_entry_get_linker_param(dmctx, dm_print_path("%s%cEthernet%cVLANTermination%c", dmroot, dm_delim, dm_delim, dm_delim), device, &v); @@ -172,30 +170,38 @@ int browseInterfaceStackInst(struct dmctx *dmctx, DMNODE *parent_node, void *pre } /* Higher layers are Device.Ethernet.VLANTermination.{i}. */ - uci_foreach_sections("network", "interface", s) { - if (!is_vlan_termination_section(s)) + uci_foreach_sections("network", "device", s) { + dmuci_get_value_by_section_string(s, "type", &type); + dmuci_get_value_by_section_string(s, "name", &name); + if (strcmp(type, "untagged") == 0 || !is_vlan_termination_section(name)) continue; - layer_inst = get_instance_by_section(dmctx, dmctx->instance_mode, "dmmap_network", "interface", s, "vlan_term_instance", "vlan_term_alias"); + layer_inst = get_instance_by_section(dmctx, dmctx->instance_mode, "dmmap_network", "device", s, "vlan_term_instance", "vlan_term_alias"); if (*layer_inst == '\0') continue; snprintf(buf_higherlayer, sizeof(buf_higherlayer), "Device.Ethernet.VLANTermination.%s.", layer_inst); higheralias = get_alias_by_section("dmmap_network", "device", s, "vlan_term_alias"); snprintf(buf_higheralias, sizeof(buf_higheralias), "%s", higheralias); - - dmuci_get_value_by_section_string(s, "name", &value); + char *macaddr = get_macaddr_from_device(name); + if (macaddr[0] != '\0') { + if (is_mac_exist(macaddr)) { + pch = macaddr; + } else { + char intf_tag[64] = {0}; + dmuci_get_value_by_section_string(s, "ifname", &ifname); + snprintf(intf_tag, sizeof(intf_tag), "%s.1", ifname); + pch = get_macaddr_from_device(intf_tag); + } + } + if (pch[0] != '\0') { + adm_entry_get_linker_param(dmctx, dm_print_path("%s%cEthernet%cLink%c", dmroot, dm_delim, dm_delim, dm_delim), pch, &v); + if (v == NULL) + v = ""; + } uci_foreach_sections("network", "interface", ss) { - dmuci_get_value_by_section_string(ss, "ifname", &ifname); - for (pch = strtok_r(ifname, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch)) { - if(strcmp(pch, value) == 0) { - mac = get_macaddr(section_name(ss)); - if (mac[0] != '\0') { - adm_entry_get_linker_param(dmctx, dm_print_path("%s%cEthernet%cLink%c", dmroot, dm_delim, dm_delim, dm_delim), mac, &v); - loweralias = get_alias_by_section("dmmap", "link", ss, "link_alias"); - if (v == NULL) - v = ""; - break; - } - } + mac = get_macaddr(section_name(ss)); + if (strcmp(pch, mac) == 0) { + loweralias = get_alias_by_section("dmmap", "link", ss, "link_alias"); + break; } } snprintf(buf_lowerlayer, sizeof(buf_lowerlayer), "%s", v); @@ -215,7 +221,7 @@ int browseInterfaceStackInst(struct dmctx *dmctx, DMNODE *parent_node, void *pre uci_foreach_sections("network", "interface", s) { dmuci_get_value_by_section_string(s, "type", &type); dmuci_get_value_by_section_string(s, "proto", &proto); - if (strcmp(type, "alias") == 0 || strcmp(section_name(s), "loopback") == 0 || *proto == '\0') + if (strcmp(section_name(s), "loopback") == 0 || *proto == '\0') continue; dmuci_get_value_by_section_string(s, "ifname", &ifname); if (*ifname == '\0' || *ifname == '@') diff --git a/dmtree/tr181/ip.c b/dmtree/tr181/ip.c index 2ee3b4fd..df3f7ee1 100644 --- a/dmtree/tr181/ip.c +++ b/dmtree/tr181/ip.c @@ -645,32 +645,30 @@ static int get_ipv4_addressing_type(char *refparam, struct dmctx *ctx, void *dat static int get_IPInterface_LowerLayers(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - char linker[64] = "", *proto, *device, *mac; - const struct ip_args *ip = data; - char *section; + char *proto, *device, *mac, linker[64] = {0}; - dmuci_get_value_by_section_string(ip->ip_sec, "proto", &proto); + dmuci_get_value_by_section_string(((struct ip_args *)data)->ip_sec, "proto", &proto); if (strstr(proto, "ppp")) { snprintf(linker, sizeof(linker), "%s", section_name(((struct ip_args *)data)->ip_sec)); adm_entry_get_linker_param(ctx, dm_print_path("%s%cPPP%cInterface%c", dmroot, dm_delim, dm_delim, dm_delim), linker, value); - goto end; + if (*value != NULL) + return 0; } - section = section_name(ip->ip_sec); - device = get_device(section); + device = get_device(section_name(((struct ip_args *)data)->ip_sec)); if (device[0] != '\0') { adm_entry_get_linker_param(ctx, dm_print_path("%s%cEthernet%cVLANTermination%c", dmroot, dm_delim, dm_delim, dm_delim), device, value); if (*value != NULL) return 0; } - mac = get_macaddr(section); + mac = get_macaddr(section_name(((struct ip_args *)data)->ip_sec)); 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); - goto end; + if (*value != NULL) + return 0; } -end: if (*value == NULL) *value = ""; return 0; @@ -686,7 +684,7 @@ static int set_IPInterface_LowerLayers(char *refparam, struct dmctx *ctx, void * return FAULT_9007; return 0; case VALUESET: - if (value[strlen(value)-1]!='.') { + if (value[strlen(value)-1] != '.') { dmasprintf(&newvalue, "%s.", value); adm_entry_get_linker_value(ctx, newvalue, &linker); } else @@ -1721,15 +1719,15 @@ static int get_linker_ipv6_prefix(char *refparam, struct dmctx *dmctx, void *dat static int browseIPIfaceInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) { char *ip_int = NULL, *ip_int_last = NULL; - char *type, *ipv4addr = ""; + char *proto, *ipv4addr = ""; struct ip_args curr_ip_args = {0}; struct dmmap_dup *p; LIST_HEAD(dup_list); 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); - if (strcmp(type, "alias") == 0 || strcmp(section_name(p->config_section), "loopback")==0) + dmuci_get_value_by_section_string(p->config_section, "proto", &proto); + if (strcmp(section_name(p->config_section), "loopback") == 0 || *proto == '\0') continue; /* IPv4 address */ diff --git a/libbbf_api/dmcommon.c b/libbbf_api/dmcommon.c index 9b98d717..b2a5d786 100644 --- a/libbbf_api/dmcommon.c +++ b/libbbf_api/dmcommon.c @@ -1238,7 +1238,7 @@ void get_dmmap_section_of_config_section_eq(char* dmmap_package, char* section_t { struct uci_section* s; - uci_path_foreach_option_eq(bbfdm, dmmap_package, section_type, opt, value, s){ + uci_path_foreach_option_eq(bbfdm, dmmap_package, section_type, opt, value, s) { *dmmap_section = s; return; } @@ -1255,7 +1255,7 @@ void get_config_section_of_dmmap_section(char* package, char* section_type, char return; } } - *config_section= NULL; + *config_section = NULL; } void check_create_dmmap_package(char *dmmap_package) @@ -1457,12 +1457,29 @@ char **strsplit_by_str(const char str[], char *delim) return tokens; } +char *get_macaddr_from_device(char *device_name) +{ + char *mac; + + if (device_name[0]) { + char file[128]; + char val[32]; + + snprintf(file, sizeof(file), "/sys/class/net/%s/address", device_name); + dm_read_sysfs_file(file, val, sizeof(val)); + mac = dmstrdup(val); + } else { + mac = ""; + } + return mac; +} + char *get_macaddr(char *interface_name) { char *device = get_device(interface_name); char *mac; - if(device[0]) { + if (device[0]) { char file[128]; char val[32]; @@ -1534,41 +1551,40 @@ int is_elt_exit_in_str_list(char *str_list, char *elt) void add_elt_to_str_list(char **str_list, char *elt) { - char *list= NULL; - if(*str_list == NULL || strlen(*str_list) == 0){ + if (*str_list == NULL || strlen(*str_list) == 0) { dmasprintf(str_list, "%s", elt); return; } - list= dmstrdup(*str_list); + char *list = dmstrdup(*str_list); dmfree(*str_list); - *str_list= NULL; + *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; + char *list = NULL, *tmp = NULL, *pch, *spch; + if (*iface_list == NULL || strlen(*iface_list) == 0) return; - list= dmstrdup(*iface_list); + list = dmstrdup(*iface_list); dmfree(*iface_list); - *iface_list= NULL; + *iface_list = NULL; for (pch = strtok_r(list, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch)) { - if(strcmp(pch, ifname) == 0) + if (strcmp(pch, ifname) == 0) continue; - if(tmp == NULL) + if (tmp == NULL) dmasprintf(iface_list, "%s", pch); else dmasprintf(iface_list, "%s %s", tmp, pch); - if(tmp){ + if (tmp) { dmfree(tmp); - tmp= NULL; + tmp = NULL; } if(*iface_list){ - tmp= dmstrdup(*iface_list); + tmp = dmstrdup(*iface_list); dmfree(*iface_list); - *iface_list= NULL; + *iface_list = NULL; } } dmasprintf(iface_list, "%s", tmp); @@ -1764,6 +1780,19 @@ int dm_time_format(time_t ts, char **dst) return 0; } +int is_mac_exist(char *macaddr) +{ + struct uci_section *s = NULL; + char *mac; + + uci_path_foreach_sections(bbfdm, DMMAP, "link", s) { + dmuci_get_value_by_section_string(s, "mac", &mac); + if (strcmp(mac, macaddr) == 0) + return 1; + } + return 0; +} + bool match(const char *string, const char *pattern) { regex_t re; @@ -2154,51 +2183,28 @@ char *replace_char(char *str, char find, char replace) return str; } -int is_vlan_termination_section(struct uci_section *s) +int is_vlan_termination_section(char *name) { - char *proto, *ifname; + struct uci_section *s; - dmuci_get_value_by_section_string(s, "proto", &proto); - if (*proto == '\0') - return 0; + uci_foreach_sections("network", "interface", s) { + // check proto is not empty + char *proto; + dmuci_get_value_by_section_string(s, "proto", &proto); + if (*proto == '\0') + continue; - dmuci_get_value_by_section_string(s, "ifname", &ifname); - if (*ifname == '\0') - return 0; + // check ifname is not empty + char *ifname; + dmuci_get_value_by_section_string(s, "ifname", &ifname); + if (*ifname == '\0') + continue; - char intf[250] = {0}; - strncpy(intf, ifname, sizeof(intf) - 1); - char *if_name = strtok(intf, " "); - if (NULL != if_name) { - char name[250] = {0}; - strncpy(name, if_name, sizeof(name) - 1); - int macvlan = 0; - char *p = strstr(name, "."); - if (!p) { - char *t = strstr(name, "_"); - if (t) - macvlan = 1; - else - return 0; - } - char *end; - if (macvlan == 1) - strtok_r(name, "_", &end); - else - strtok_r(name, ".", &end); - - if (end == NULL) - return 0; - - if (macvlan == 0) { - char tag[20] = {0}; - strncpy(tag, end, sizeof(tag) - 1); - if (strncmp(tag, "1", sizeof(tag)) == 0) - return 0; - } + // check if name exist in the list ifname + if (strcmp(ifname, name) == 0) + return 1; } - - return 1; + return 0; } int get_upstream_interface(char *intf_tag, int len) diff --git a/libbbf_api/dmcommon.h b/libbbf_api/dmcommon.h index 054ad31c..daef29ef 100644 --- a/libbbf_api/dmcommon.h +++ b/libbbf_api/dmcommon.h @@ -288,6 +288,7 @@ unsigned char isdigit_str(char *str); char *dm_strword(char *src, char *str); char **strsplit(const char* str, const char* delim, size_t* numtokens); char **strsplit_by_str(const char str[], char *delim); +char *get_macaddr_from_device(char *device_name); char *get_macaddr(char *ifname); char *get_device(char *ifname); int is_elt_exit_in_str_list(char *str_list, char *elt); @@ -310,6 +311,7 @@ int get_net_iface_sysfs(const char *uci_iface, const char *name, char **value); int get_net_device_sysfs(const char *uci_iface, const char *name, char **value); char *get_device_from_wifi_iface(const char *wifi_iface, const char *wifi_section); int dm_time_format(time_t ts, char **dst); +int is_mac_exist(char *macaddr); bool match(const char *string, const char *pattern); int dm_validate_string(char *value, int min_length, int max_length, char *enumeration[], int enumeration_size, char *pattern[], int pattern_size); int dm_validate_boolean(char *value); @@ -325,7 +327,7 @@ char **get_all_iop_certificates(int *length); char *decode64 (char *enc); char *stringToHex(char *text, int length); char *replace_char(char *str, char find, char replace); -int is_vlan_termination_section(struct uci_section *s); +int is_vlan_termination_section(char *name); int get_upstream_interface(char *intf_tag, int len); int create_mac_addr_upstream_intf(char *mac_addr, char *mac, int len); #endif diff --git a/libbbf_api/dmuci.h b/libbbf_api/dmuci.h index 1873a046..83ca4cb9 100644 --- a/libbbf_api/dmuci.h +++ b/libbbf_api/dmuci.h @@ -86,6 +86,12 @@ struct package_change section != NULL; \ section = dmuci_walk_section(package, stype, NULL, NULL, CMP_SECTION, NULL, section, GET_NEXT_SECTION)) +#define uci_foreach_sections_safe(package, stype, _tmp, section) \ + for (section = dmuci_walk_section(package, stype, NULL, NULL, CMP_SECTION, NULL, NULL, GET_FIRST_SECTION), \ + _tmp = (section) ? dmuci_walk_section(package, stype, NULL, NULL, CMP_SECTION, NULL, section, GET_NEXT_SECTION) : NULL; \ + section != NULL; \ + section = _tmp, _tmp = (section) ? dmuci_walk_section(package, stype, NULL, NULL, CMP_SECTION, NULL, section, GET_NEXT_SECTION) : NULL) + #define uci_foreach_option_eq(package, stype, option, val, section) \ for (section = dmuci_walk_section(package, stype, option, val, CMP_OPTION_EQUAL, NULL, NULL, GET_FIRST_SECTION); \ section != NULL; \ @@ -95,7 +101,7 @@ struct package_change for (section = dmuci_walk_section(package, stype, option, val, CMP_OPTION_EQUAL, NULL, NULL, GET_FIRST_SECTION), \ _tmp = (section) ? dmuci_walk_section(package, stype, option, val, CMP_OPTION_EQUAL, NULL, section, GET_NEXT_SECTION) : NULL; \ section != NULL; \ - section = _tmp, _tmp = (section) ? dmuci_walk_section(package, stype, option, val, CMP_OPTION_EQUAL, NULL, section, GET_NEXT_SECTION) : NULL) + section = _tmp, _tmp = (section) ? dmuci_walk_section(package, stype, option, val, CMP_OPTION_EQUAL, NULL, section, GET_NEXT_SECTION) : NULL) #define uci_foreach_option_cont(package, stype, option, val, section) \ for (section = dmuci_walk_section(package, stype, option, val, CMP_OPTION_CONTAINING, NULL, NULL, GET_FIRST_SECTION); \