diff --git a/dmtree/tr181/bridging.c b/dmtree/tr181/bridging.c index 4e081cae..e1c0b8ec 100644 --- a/dmtree/tr181/bridging.c +++ b/dmtree/tr181/bridging.c @@ -187,6 +187,22 @@ void bridging_set_vlan_tvid(char *uci_opt_name, void *data, char *value) dmuci_set_value_by_section(((struct bridge_vlan_args *)data)->bridge_vlan_sec, uci_opt_name, !strcmp(value, "0") ? "" : value); } +static void bridge_remove_related_device_section(struct uci_list *br_ports_list) +{ + struct uci_element *e = NULL; + + if (!br_ports_list) + return; + + uci_foreach_element(br_ports_list, e) { + struct uci_section *s = NULL, *stmp = NULL; + + uci_foreach_option_eq_safe("network", "device", "name", e->name, stmp, s) { + dmuci_delete_by_section(s, NULL, NULL); + } + } +} + static int get_last_inst(char *config, char *section, char *option1, char *option2, char *br_inst) { struct uci_section *s = NULL; @@ -1527,6 +1543,9 @@ static int delObjBridgingBridge(char *refparam, struct dmctx *ctx, void *data, c switch (del_action) { case DEL_INST: + // Remove all related device bridge section + bridge_remove_related_device_section(((struct bridge_args *)data)->br_ports_list); + // Remove all bridge sections related to this device bridge section remove_bridge_sections("dmmap_bridge", "device", "bridge_instance", ((struct bridge_args *)data)->br_inst); @@ -1547,11 +1566,16 @@ static int delObjBridgingBridge(char *refparam, struct dmctx *ctx, void *data, c break; case DEL_ALL: uci_foreach_option_eq_safe("network", "device", "type", "bridge", stmp, s) { + struct uci_list *br_ports_list = NULL; struct uci_section *dmmap_section = NULL; char *bridge_inst = NULL; get_dmmap_section_of_config_section("dmmap_bridge", "device", section_name(s), &dmmap_section); dmuci_get_value_by_section_string(dmmap_section, "bridge_instance", &bridge_inst); + dmuci_get_value_by_section_list(dmmap_section, "ports", &br_ports_list); + + // Remove all related device bridge section + bridge_remove_related_device_section(br_ports_list); // Remove all bridge port sections related to this interface bridge section remove_bridge_sections("dmmap_bridge_port", "bridge_port", "br_inst", bridge_inst); @@ -1565,6 +1589,9 @@ static int delObjBridgingBridge(char *refparam, struct dmctx *ctx, void *data, c // Remove cvlan/svaln from dmmap_provider_bridge section if this bridge instance is a part of it remove_bridge_from_provider_bridge(bridge_inst); + // Remove dmmap device bridge section + dmuci_delete_by_section(dmmap_section, NULL, NULL); + // Remove device bridge section dmuci_delete_by_section(s, NULL, NULL); } diff --git a/dmtree/tr181/ethernet.c b/dmtree/tr181/ethernet.c index 3ded5f9b..b0739a7b 100644 --- a/dmtree/tr181/ethernet.c +++ b/dmtree/tr181/ethernet.c @@ -45,6 +45,25 @@ static inline int init_eth_rmon(struct eth_rmon_args *args, struct dmmap_dup *s, /************************************************************* * COMMON FUNCTIONS **************************************************************/ +bool ethernet___check_vlan_termination_section(const char *name) +{ + struct uci_section *s = NULL; + + uci_foreach_option_eq("network", "device", "type", "bridge", s) { + struct uci_list *uci_list = NULL; + + dmuci_get_value_by_section_list(s, "ports", &uci_list); + + if (uci_list == NULL) + continue; + + if (value_exists_in_uci_list(uci_list, name)) + return false; + } + + return true; +} + struct uci_section *ethernet___get_device_section(char *dev_name) { struct uci_section *s = NULL; @@ -278,7 +297,7 @@ static int browseEthernetVLANTerminationInst(struct dmctx *dmctx, DMNODE *parent 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, "bridge") == 0 || strcmp(type, "untagged") == 0) + if (strcmp(type, "bridge") == 0 || strcmp(type, "untagged") == 0 || (*name != 0 && !ethernet___check_vlan_termination_section(name))) continue; inst = handle_instance(dmctx, parent_node, p->dmmap_section, "vlan_term_instance", "vlan_term_alias"); @@ -437,7 +456,7 @@ static int delObjEthernetVLANTermination(char *refparam, struct dmctx *ctx, void dmuci_get_value_by_section_string(s_dev, "type", &type); dmuci_get_value_by_section_string(s_dev, "name", &name); - if (strcmp(type, "bridge") == 0 || strcmp(type, "untagged") == 0) + if (strcmp(type, "bridge") == 0 || strcmp(type, "untagged") == 0 || (*name != 0 && !ethernet___check_vlan_termination_section(name))) continue; // Remove device section in dmmap_network file diff --git a/dmtree/tr181/ethernet.h b/dmtree/tr181/ethernet.h index 1e1b92d4..21f65c48 100644 --- a/dmtree/tr181/ethernet.h +++ b/dmtree/tr181/ethernet.h @@ -29,6 +29,7 @@ extern DMLEAF tEthernetVLANTerminationStatsParams[]; extern DMLEAF tEthernetRMONStatsParams[]; struct uci_section *ethernet___get_device_section(char *dev_name); +bool ethernet___check_vlan_termination_section(const char *name); bool ethernet___check_section_in_curr_section(const char *curr_section, const char *section); bool ethernet___name_exists_in_devices(char *name); diff --git a/dmtree/tr181/interfacestack.c b/dmtree/tr181/interfacestack.c index 1a249392..193b1273 100644 --- a/dmtree/tr181/interfacestack.c +++ b/dmtree/tr181/interfacestack.c @@ -266,7 +266,7 @@ int browseInterfaceStackInst(struct dmctx *dmctx, DMNODE *parent_node, void *pre char *type, *name, *value = NULL; dmuci_get_value_by_section_string(s, "type", &type); dmuci_get_value_by_section_string(s, "name", &name); - if (strcmp(type, "bridge") == 0 || strcmp(type, "untagged") == 0) + if (strcmp(type, "bridge") == 0 || strcmp(type, "untagged") == 0 || (*name != 0 && !ethernet___check_vlan_termination_section(name))) continue; // The higher layer is Device.Ethernet.VLANTermination.{i}.