Bug #11637: TR181 is broken for ports that have '.' in their device name

This commit is contained in:
Amin Ben Romdhane 2023-08-03 13:56:33 +00:00
parent 58fab6623f
commit ae04d7a5b7
6 changed files with 86 additions and 55 deletions

View file

@ -10,6 +10,7 @@
*
*/
#include "ethernet.h"
#include "bridging.h"
struct bridge_args
@ -660,7 +661,7 @@ static void dmmap_synchronizeBridgingBridgeVLAN(struct dmctx *dmctx, DMNODE *par
dmuci_get_value_by_section_string(s, "vid", &vid);
if (vid && vid[0] == '\0') {
char *ifname = DM_STRCHR(e->name, '.');
char *ifname = (!ethernet___is_ethernet_interface_inst(e->name)) ? DM_STRRCHR(e->name, '.') : NULL;
if (ifname) vid = dmstrdup(ifname+1);
}
@ -923,7 +924,7 @@ static void remove_vlanid_from_bridge_secions(struct uci_section *bridge_sec, st
return;
uci_foreach_element_safe(device_ports, tmp, e) {
char *vid = DM_STRCHR(e->name, '.');
char *vid = (!ethernet___is_ethernet_interface_inst(e->name)) ? DM_STRRCHR(e->name, '.') : NULL;
if (vid && curr_vid && DM_STRCMP(vid+1, curr_vid) == 0) {
struct uci_section *s = NULL;
@ -983,24 +984,26 @@ static void remove_vlanport_section(struct uci_section *bridge_vlanport_sec, str
dmuci_get_value_by_section_string(port_s, "enabled", &enable);
dmuci_get_value_by_section_string(port_s, "port", &port);
char *vid = port ? DM_STRCHR(port, '.') : NULL;
if (vid) {
if (DM_STRLEN(port)) {
char *vid = (!ethernet___is_ethernet_interface_inst(port)) ? DM_STRRCHR(port, '.') : NULL;
if (vid) {
if (DM_STRCMP(enable, "1") == 0) {
/* Remove port from port list */
remove_port_from_bridge_sections(bridge_sec, bridge_dmmap_sec, port);
if (DM_STRCMP(enable, "1") == 0) {
/* Remove port from port list */
remove_port_from_bridge_sections(bridge_sec, bridge_dmmap_sec, port);
}
/* Remove vid from port */
vid[0] = '\0';
if (DM_STRCMP(enable, "1") == 0) {
/* Add new port to port list */
add_port_to_bridge_sections(bridge_sec, bridge_dmmap_sec, port);
}
// dmmap_bridge_port: Update port option
dmuci_set_value_by_section(port_s, "port", port);
}
/* Remove vid from port */
vid[0] = '\0';
if (DM_STRCMP(enable, "1") == 0) {
/* Add new port to port list */
add_port_to_bridge_sections(bridge_sec, bridge_dmmap_sec, port);
}
// dmmap_bridge_port: Update port option
dmuci_set_value_by_section(port_s, "port", port);
}
}
}
@ -1999,7 +2002,7 @@ static int get_BridgingBridgePort_LowerLayers(char *refparam, struct dmctx *ctx,
if (DM_LSTRCMP(config, "network") == 0) {
adm_entry_get_linker_param(ctx, "Device.Ethernet.Interface.", port, value);
if (!(*value) || (*value)[0] == 0) {
char *tag = DM_STRCHR(port, '.');
char *tag = DM_STRRCHR(port, '.');
if (tag) tag[0] = '\0';
} else {
return 0;
@ -2089,12 +2092,12 @@ static int set_BridgingBridgePort_LowerLayers(char *refparam, struct dmctx *ctx,
remove_port_from_bridge_sections(args->bridge_sec, args->bridge_dmmap_sec, port_device);
}
char *tag = DM_STRCHR(port_device, '.');
char *tag = (!ethernet___is_ethernet_interface_inst(port_device)) ? DM_STRRCHR(port_device, '.') : NULL;
if (tag && !is_wireless_config) {
char *cur_vid = dmstrdup(tag+1);
char new_name[32] = {0};
snprintf(new_name, sizeof(new_name), "%s.%s", linker, cur_vid);
snprintf(new_name, sizeof(new_name), "%s.%s", linker, tag + 1);
if (DM_STRCMP(port_enabled, "1") == 0) {
// Add port to ports list
@ -2105,12 +2108,12 @@ static int set_BridgingBridgePort_LowerLayers(char *refparam, struct dmctx *ctx,
dmuci_set_value_by_section(args->bridge_port_dmmap_sec, "port", new_name);
// Check if there is a vlan port maps to this port
if (args->bridge_sec) {
if (args->bridge_port_sec) {
struct uci_section *s = NULL;
dmuci_set_value_by_section(args->bridge_sec, "ifname", linker);
dmuci_set_value_by_section(args->bridge_sec, "name", new_name);
s = get_dup_section_in_dmmap("dmmap_bridge_vlanport", "bridge_vlanport", section_name(args->bridge_sec));
dmuci_set_value_by_section(args->bridge_port_sec, "ifname", linker);
dmuci_set_value_by_section(args->bridge_port_sec, "name", new_name);
s = get_dup_section_in_dmmap("dmmap_bridge_vlanport", "bridge_vlanport", section_name(args->bridge_port_sec));
dmuci_set_value_by_section(s, "name", new_name);
}
} else {
@ -2504,7 +2507,8 @@ static int set_BridgingBridgeVLAN_VLANID(char *refparam, struct dmctx *ctx, void
return 0;
uci_foreach_element_safe(device_ports, tmp, e) {
char *vid = DM_STRCHR(e->name, '.');
char *vid = (!ethernet___is_ethernet_interface_inst(e->name)) ? DM_STRRCHR(e->name, '.') : NULL;
if (vid && curr_vid && DM_STRCMP(vid+1, curr_vid) == 0) {
struct uci_section *s = NULL;
@ -2749,11 +2753,11 @@ static int set_BridgingBridgeVLANPort_Port(char *refparam, struct dmctx *ctx, vo
if (DM_STRLEN(vid) == 0) {
/* Update device section */
dmuci_set_value_by_section(args->bridge_vlanport_sec, "name", port);
dmuci_set_value_by_section(args->bridge_vlanport_sec, "ifname", port);
dmuci_set_value_by_section(args->bridge_vlanport_sec, "name", port);
dmuci_set_value_by_section(args->bridge_vlanport_sec, "ifname", port);
/* Update dmmap vlanport section */
dmuci_set_value_by_section(args->bridge_vlanport_dmmap_sec, "name", port);
/* Update dmmap vlanport section */
dmuci_set_value_by_section(args->bridge_vlanport_dmmap_sec, "name", port);
} else {
char port_name[32] = {0};
@ -2763,8 +2767,10 @@ static int set_BridgingBridgeVLANPort_Port(char *refparam, struct dmctx *ctx, vo
}
if (DM_STRCMP(type, "34984") != 0) { // type:34984=>'8021ad'
char *tag = DM_STRCHR(port, '.');
if (tag) tag[0] = '\0';
if (!ethernet___is_ethernet_interface_inst(port)) {
char *tag = DM_STRRCHR(port, '.');
if (tag) tag[0] = '\0';
}
} else {
dmuci_set_value_by_section(args->bridge_vlanport_sec, "type", "8021ad");
}

View file

@ -1232,7 +1232,7 @@ static int operate_DeviceInfoVendorLogFile_Upload(char *refparam, struct dmctx *
char upload_command[32] = {'\0'};
char *vlf_file_path = NULL;
char *ret = strrchr(refparam, '.');
char *ret = DM_STRRCHR(refparam, '.');
strncpy(upload_path, refparam, ret - refparam +1);
DM_STRNCPY(upload_command, ret+1, sizeof(upload_command));
@ -1281,7 +1281,7 @@ static int operate_DeviceInfoVendorConfigFile_Backup(char *refparam, struct dmct
char backup_command[32] = {'\0'};
char *vcf_name = NULL;
char *ret = strrchr(refparam, '.');
char *ret = DM_STRRCHR(refparam, '.');
strncpy(backup_path, refparam, ret - refparam +1);
DM_STRNCPY(backup_command, ret+1, sizeof(backup_command));
@ -1323,7 +1323,7 @@ static int operate_DeviceInfoVendorConfigFile_Restore(char *refparam, struct dmc
char restore_path[256] = {'\0'};
char restore_command[32] = {'\0'};
char *ret = strrchr(refparam, '.');
char *ret = DM_STRRCHR(refparam, '.');
DM_STRNCPY(restore_path, refparam, ret - refparam + 2);
DM_STRNCPY(restore_command, ret+1, sizeof(restore_command));
@ -1367,7 +1367,7 @@ static int operate_DeviceInfoFirmwareImage_Download(char *refparam, struct dmctx
char obj_path[256] = {'\0'};
char command[32] = {'\0'};
char *ret = strrchr(refparam, '.');
char *ret = DM_STRRCHR(refparam, '.');
DM_STRNCPY(obj_path, refparam, ret - refparam + 2);
DM_STRNCPY(command, ret+1, sizeof(command));

View file

@ -63,6 +63,22 @@ bool ethernet___check_vlan_termination_section(const char *name)
return true;
}
bool ethernet___is_ethernet_interface_inst(const char *device_name)
{
struct uci_section *s = NULL;
uci_foreach_sections("ports", "ethport", s) {
char *ifname = NULL;
dmuci_get_value_by_section_string(s, "ifname", &ifname);
if (DM_STRCMP(ifname, device_name) == 0)
return true;
}
return false;
}
static int eth_iface_sysfs(const struct uci_section *data, const char *name, char **value)
{
char *device;
@ -90,7 +106,7 @@ static struct uci_section *is_ethernet_link_exist(char *device)
return NULL;
}
bool ethernet___name_exists_in_devices(char *name)
static bool name_exists_in_devices(char *name)
{
struct uci_section *s = NULL;
@ -161,9 +177,11 @@ static void dmmap_synchronizeEthernetLink(struct dmctx *dmctx, DMNODE *parent_no
DM_STRNCPY(dev_name, device, sizeof(dev_name));
char *has_vid = DM_STRRCHR(dev_name, '.');
if (has_vid)
*has_vid = '\0';
if (!ethernet___is_ethernet_interface_inst(dev_name)) {
char *has_vid = DM_STRRCHR(dev_name, '.');
if (has_vid)
*has_vid = '\0';
}
if (is_mac_vlan_interface(dev_name)) {
char *p = DM_STRRCHR(dev_name, '_');
@ -997,9 +1015,11 @@ static int get_EthernetLink_FlowControl(char *refparam, struct dmctx *ctx, void
DM_STRNCPY(buf, e->name, sizeof(buf));
char *is_tagged = DM_STRCHR(buf, '.');
if (is_tagged)
*is_tagged = 0;
if (!ethernet___is_ethernet_interface_inst(buf)) {
char *is_tagged = DM_STRRCHR(buf, '.');
if (is_tagged)
*is_tagged = 0;
}
port_s = get_dup_section_in_config_opt("ports", "ethport", "ifname", buf);
char *pause = port_s ? dmuci_get_value_by_section_fallback_def(port_s, "pause", "0") : "0";
@ -1067,9 +1087,11 @@ static int set_EthernetLink_FlowControl(char *refparam, struct dmctx *ctx, void
DM_STRNCPY(buf, e->name, sizeof(buf));
char *is_tagged = DM_STRCHR(buf, '.');
if (is_tagged)
*is_tagged = 0;
if (!ethernet___is_ethernet_interface_inst(buf)) {
char *is_tagged = DM_STRRCHR(buf, '.');
if (is_tagged)
*is_tagged = 0;
}
port_s = get_dup_section_in_config_opt("ports", "ethport", "ifname", buf);
if (port_s)
@ -1291,7 +1313,7 @@ static int set_EthernetVLANTermination_LowerLayers(char *refparam, struct dmctx
snprintf(new_name, sizeof(new_name), "%s%s%s", vlan_linker, DM_STRLEN(vid) ? "." : "", DM_STRLEN(vid) ? vid : "");
if (ethernet___name_exists_in_devices(new_name))
if (name_exists_in_devices(new_name))
return -1;
if (DM_STRLEN(old_name)) {
@ -1343,7 +1365,7 @@ static int set_EthernetVLANTermination_LowerLayers(char *refparam, struct dmctx
snprintf(new_name, sizeof(new_name), "%s%s%s", vlan_linker, DM_STRLEN(vid) ? "." : "", DM_STRLEN(vid) ? vid : "");
if (ethernet___name_exists_in_devices(new_name))
if (name_exists_in_devices(new_name))
return -1;
dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "ifname", vlan_linker);
@ -1385,7 +1407,7 @@ static int set_EthernetVLANTermination_VLANID(char *refparam, struct dmctx *ctx,
snprintf(old_name, sizeof(old_name), "%s.%s", ifname, vid);
snprintf(new_name, sizeof(new_name), "%s.%s", ifname, value);
if (ethernet___name_exists_in_devices(new_name))
if (name_exists_in_devices(new_name))
return 0;
dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "name", &name);

View file

@ -29,5 +29,6 @@ extern DMLEAF tEthernetVLANTerminationStatsParams[];
extern DMLEAF tEthernetRMONStatsParams[];
bool ethernet___check_vlan_termination_section(const char *name);
bool ethernet___is_ethernet_interface_inst(const char *device_name);
#endif //__ETHERNET_H

View file

@ -468,7 +468,7 @@ int browseInterfaceStackInst(struct dmctx *dmctx, DMNODE *parent_node, void *pre
// The lower layer is Device.ATM.Link.{i}.
if (!found && value == NULL) {
char *tag = DM_STRCHR(device, '.');
char *tag = DM_STRRCHR(device, '.');
if (tag) *tag = '\0';
adm_entry_get_linker_param(dmctx, "Device.ATM.Link.", device, &value);
}
@ -486,7 +486,7 @@ int browseInterfaceStackInst(struct dmctx *dmctx, DMNODE *parent_node, void *pre
// The lower layer is Device.PTM.Link.{i}.
if (!found && value == NULL) {
char *tag = DM_STRCHR(device, '.');
char *tag = DM_STRRCHR(device, '.');
if (tag) *tag = '\0';
adm_entry_get_linker_param(dmctx, "Device.PTM.Link.", device, &value);
}
@ -504,7 +504,7 @@ int browseInterfaceStackInst(struct dmctx *dmctx, DMNODE *parent_node, void *pre
// The lower layer is Device.Ethernet.Interface.{i}.
if (!found && value == NULL) {
char *tag = DM_STRCHR(device, '.');
char *tag = DM_STRRCHR(device, '.');
if (tag) *tag = '\0';
adm_entry_get_linker_param(dmctx, "Device.Ethernet.Interface.", device, &value);
}

View file

@ -193,8 +193,10 @@ static int set_EthernetMACVLAN_LowerLayers(char *refparam, struct dmctx *ctx, vo
dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "ifname", linker);
char *vid = DM_STRCHR(linker, '.');
if (vid) *vid = 0;
if (DM_STRNCMP(value, allowed_objects[0], strlen(allowed_objects[0])) == 0) {
char *vid = DM_STRRCHR(linker, '.');
if (vid) *vid = 0;
}
snprintf(name, sizeof(name), "%s_%s", linker, instance);