From 52db14f866057e2e7a9c0cef5fefed0f34cd93cf Mon Sep 17 00:00:00 2001 From: Meng Date: Fri, 21 Dec 2018 13:43:05 +0100 Subject: [PATCH] Update for IP.Interface.LowerLayers for bridge interface The lowerlayer of Ip.Interface of bridge type is changed to the "Etherent.Link". --- dm/dmcommon.c | 75 ++++++++++++++++++++++-- dm/dmcommon.h | 3 + dm/dmtree/tr181/ethernet.c | 115 +++++++++++++++++-------------------- dm/dmtree/tr181/ip.c | 21 +++++-- 4 files changed, 141 insertions(+), 73 deletions(-) diff --git a/dm/dmcommon.c b/dm/dmcommon.c index ce7db83..4b7d6e7 100644 --- a/dm/dmcommon.c +++ b/dm/dmcommon.c @@ -23,11 +23,18 @@ #include #include #include +#include +#include +#include +#include +#include + #include "dmcwmp.h" #include "dmuci.h" #include "dmubus.h" #include "dmcommon.h" #include "dmjson.h" +#include "log.h" char *array_notifcation_char[__MAX_notification] = { [notification_none] = "0", @@ -270,7 +277,7 @@ int set_interface_enable_ubus(char *iface, char *refparam, struct dmctx *ctx, in { bool b; char *ubus_object; - + switch (action) { case VALUECHECK: if (string_to_bool(value, &b)) @@ -286,7 +293,7 @@ int set_interface_enable_ubus(char *iface, char *refparam, struct dmctx *ctx, in dmubus_call_set(ubus_object, "down", UBUS_ARGS{}, 0); dmfree(ubus_object); return 0; - } + } return 0; } @@ -644,7 +651,7 @@ void update_section_option_list(char *config, char *section, char *option, char dmuci_delete_by_section(prev_s, NULL, NULL); } if (add_sec) { - dmuci_add_section_and_rename(config, section, &s, &add_value); + dmuci_add_section(config, section, &s, &add_value); dmuci_set_value_by_section(s, option, val); dmuci_set_value_by_section(s, option_2, val_2); } @@ -711,7 +718,7 @@ void update_section_list(char *config, char *section, char *option, int number, } } while (i < number) { - dmuci_add_section_and_rename(config, section, &s, &add_value); + dmuci_add_section(config, section, &s, &add_value); if (option)dmuci_set_value_by_section(s, option, filter); if (option1)dmuci_set_value_by_section(s, option1, val1); if (option2)dmuci_set_value_by_section(s, option2, val2); @@ -787,7 +794,7 @@ int wan_remove_dev_interface(struct uci_section *interface_setion, char *dev) return 0; } -int filter_lan_device_interface(struct uci_section *s) +int filter_lan_device_interface(struct uci_section *s, void *v) { char *ifname = NULL; char *phy_itf = NULL, *phy_itf_local; @@ -1052,7 +1059,7 @@ void synchronize_specific_config_sections_with_dmmap(char *package, char *sectio uci_path_foreach_sections_safe(icwmpd, 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_icwmpd(s, NULL, NULL); + dmuci_delete_by_section(s, NULL, NULL); } } } @@ -1423,3 +1430,59 @@ char **strsplit(const char* str, const char* delim, size_t* numtokens) { free(s); return tokens; } + +char *get_macaddr(char *ifname) +{ + struct ifreq s; + int fd; + char macaddr[18]; + + fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); + if (fd < 0) { + CWMP_LOG(ERROR, "socket failed %s", ifname); + return NULL; + } + + memset(&s, 0, sizeof(s)); + strcpy(s.ifr_name, ifname); + if (0 != ioctl(fd, SIOCGIFHWADDR, &s)) { + CWMP_LOG(ERROR, "ioctl failed %s", ifname); + close(fd); + return NULL; + } + + close(fd); + + unsigned char *p = (unsigned char*)s.ifr_addr.sa_data; + snprintf(macaddr, sizeof(macaddr), "%02x:%02x:%02x:%02x:%02x:%02x", p[0], p[1], p[2], p[3], p[4], p[5]); + + return dmstrdup(macaddr); +} + +int set_macaddr(char *ifname, char *macaddr) +{ + struct ifreq s; + int fd; + + CWMP_LOG(ERROR, "set_macaddr %s, %s", ifname, macaddr) + + fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); + if (fd < 0) { + CWMP_LOG(ERROR, "socket failed %s", ifname); + return -1; + } + + memset(&s, 0, sizeof(s)); + strcpy(s.ifr_name, ifname); + s.ifr_hwaddr.sa_family = ARPHRD_ETHER; + unsigned char *p = (unsigned char*)s.ifr_addr.sa_data; + sscanf(macaddr, "%02x:%02x:%02x:%02x:%02x:%02x", &p[0], &p[1], &p[2], &p[3], &p[4], &p[5]); + if (0 != ioctl(fd, SIOCSIFHWADDR, &s)) { + CWMP_LOG(ERROR, "ioctl failed %s", ifname); + close(fd); + return -1; + } + + close(fd); + return 0; +} \ No newline at end of file diff --git a/dm/dmcommon.h b/dm/dmcommon.h index 7a68c34..a6113f2 100644 --- a/dm/dmcommon.h +++ b/dm/dmcommon.h @@ -179,4 +179,7 @@ void update_dmmap_sections(struct list_head *dup_list, char *instancename, char* 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 *get_macaddr(char *ifname); +int set_macaddr(char *ifname, char *macaddr); + #endif diff --git a/dm/dmtree/tr181/ethernet.c b/dm/dmtree/tr181/ethernet.c index 6b6a8ae..57ab90a 100644 --- a/dm/dmtree/tr181/ethernet.c +++ b/dm/dmtree/tr181/ethernet.c @@ -8,12 +8,6 @@ * Author: Anis Ellouze * */ -#include -#include -#include -#include -#include - #include #include #include @@ -587,62 +581,6 @@ int get_vlan_term_name(char *refparam, struct dmctx *ctx, void *data, char *inst return 0; } -static char *get_macaddr(char *ifname) -{ - struct ifreq s; - int fd; - char macaddr[18]; - - fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); - if (fd < 0) { - CWMP_LOG(ERROR, "socket failed %s", ifname); - return NULL; - } - - memset(&s, 0, sizeof(s)); - strcpy(s.ifr_name, ifname); - if (0 != ioctl(fd, SIOCGIFHWADDR, &s)) { - CWMP_LOG(ERROR, "ioctl failed %s", ifname); - close(fd); - return NULL; - } - - close(fd); - - unsigned char *p = (unsigned char*)s.ifr_addr.sa_data; - snprintf(macaddr, sizeof(macaddr), "%02x:%02x:%02x:%02x:%02x:%02x", p[0], p[1], p[2], p[3], p[4], p[5]); - - return dmstrdup(macaddr); -} - -static int set_macaddr(char *ifname, char *macaddr) -{ - struct ifreq s; - int fd; - - CWMP_LOG(ERROR, "set_macaddr %s, %s", ifname, macaddr) - - fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); - if (fd < 0) { - CWMP_LOG(ERROR, "socket failed %s", ifname); - return -1; - } - - memset(&s, 0, sizeof(s)); - strcpy(s.ifr_name, ifname); - s.ifr_hwaddr.sa_family = ARPHRD_ETHER; - unsigned char *p = (unsigned char*)s.ifr_addr.sa_data; - sscanf(macaddr, "%02x:%02x:%02x:%02x:%02x:%02x", &p[0], &p[1], &p[2], &p[3], &p[4], &p[5]); - if (0 != ioctl(fd, SIOCSIFHWADDR, &s)) { - CWMP_LOG(ERROR, "ioctl failed %s", ifname); - close(fd); - return -1; - } - - close(fd); - return 0; -} - /************************************************************************** * SET & GET Lowerlayers ***************************************************************************/ @@ -847,6 +785,59 @@ int get_link_name(char *refparam, struct dmctx *ctx, void *data, char *instance, int get_link_lowerlayers(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { + struct uci_section *s = NULL; + char * link_mac; + dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "mac", &link_mac); + + uci_foreach_sections("network", "interface", s) { + char *type, *ifname; + char *mac; + dmuci_get_value_by_section_string(s, "type", &type); + if (strcmp(type, "alias") == 0 || strcmp(section_name(s), "loopback") == 0) + continue; + + if (strcmp(type, "bridge") == 0) + dmasprintf(&ifname, "br-%s", section_name(s)); + else + dmuci_get_value_by_section_string(s, "ifname", &ifname); + + if (*ifname == '\0' || *ifname == '@') + continue; + + mac = get_macaddr(ifname); + if (mac == NULL || strcasecmp(mac, link_mac) != 0) + continue; + + if (strcmp(type, "bridge") == 0) { + struct uci_section *dmmap_section; + char *br_inst, *mg; + struct uci_section *port; + char linker[64] = ""; + get_dmmap_section_of_config_section("dmmap_network", "interface", section_name(s), &dmmap_section); + dmuci_get_value_by_section_string(dmmap_section, "bridge_instance", &br_inst); + uci_path_foreach_option_eq(icwmpd, "dmmap_bridge_port", "bridge_port", "bridge_key", br_inst, port) { + dmuci_get_value_by_section_string(port, "mg_port", &mg); + if (strcmp(mg, "true") == 0) + sprintf(linker, "%s+", section_name(port)); + 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 = ""; + } + } + else { + /* for upstream interface, set the lowerlayer to wan port of Ethernet.Interface */ + char * p = strchr(ifname, '.'); + if (p) { + /*linker of wan port of interface is eth0.1*/ + *(p+1) = '1'; + *(p+2) = '\0'; + adm_entry_get_linker_param(ctx, dm_print_path("%s%cEthernet%cInterface%c", dmroot, dm_delim, dm_delim, dm_delim), ifname, value); + } + } + + break; + } + return 0; } diff --git a/dm/dmtree/tr181/ip.c b/dm/dmtree/tr181/ip.c index 78bf570..96ade74 100644 --- a/dm/dmtree/tr181/ip.c +++ b/dm/dmtree/tr181/ip.c @@ -19,6 +19,7 @@ #include "ip.h" #include "diagnostic.h" #include "dmjson.h" +#include "log.h" struct dm_forced_inform_s IPv4INFRM = {0, get_ipv4_finform}; struct dm_forced_inform_s IPv6INFRM = {0, get_ipv6_finform}; @@ -503,6 +504,16 @@ int get_ip_int_lower_layer(char *refparam, struct dmctx *ctx, void *data, char * dmuci_get_value_by_section_string(((struct ip_args *)data)->ip_sec, "type", &wtype); if (strcmp(wtype, "bridge") == 0) { + char *ifname, *mac; + dmasprintf(&ifname, "br-%s", section_name(((struct ip_args *)data)->ip_sec)); + mac = get_macaddr(ifname); + CWMP_LOG(ERROR, "get_ip_int_lower_layer, mac:%s", mac) + if (mac != NULL) { + /* Expect the Ethernet.Link to be the lowerlayer*/ + adm_entry_get_linker_param(ctx, dm_print_path("%s%cEthernet%cLink%c", dmroot, dm_delim, dm_delim, dm_delim), mac, value); + CWMP_LOG(ERROR, "get_ip_int_lower_layer, lowerlay:%s", *value) + return 0; + } get_dmmap_section_of_config_section("dmmap_network", "interface", section_name(((struct ip_args *)data)->ip_sec), &dmmap_section); dmuci_get_value_by_section_string(dmmap_section, "bridge_instance", &br_inst); uci_path_foreach_option_eq(icwmpd, "dmmap_bridge_port", "bridge_port", "bridge_key", br_inst, port) { @@ -535,19 +546,19 @@ int get_ip_int_lower_layer(char *refparam, struct dmctx *ctx, void *data, char * adm_entry_get_linker_param(ctx, dm_print_path("%s%cATM%cLink%c", dmroot, dm_delim, dm_delim, dm_delim), linker, value); if (*value == NULL) adm_entry_get_linker_param(ctx, dm_print_path("%s%cPTM%cLink%c", dmroot, dm_delim, dm_delim, dm_delim), linker, value); - + if (*value == NULL) adm_entry_get_linker_param(ctx, dm_print_path("%s%cEthernet%cVLANTermination%c", dmroot, dm_delim, dm_delim, dm_delim), linker, value); - + if (*value == NULL) adm_entry_get_linker_param(ctx, dm_print_path("%s%cEthernet%cInterface%c", dmroot, dm_delim, dm_delim, dm_delim), linker, value); - + if (*value == NULL) adm_entry_get_linker_param(ctx, dm_print_path("%s%cWiFi%cSSID%c", dmroot, dm_delim, dm_delim, dm_delim), linker, value); - + if (*value == NULL) adm_entry_get_linker_param(ctx, dm_print_path("%s%cPPP%cInterface%c", dmroot, dm_delim, dm_delim, dm_delim), linker, value); - + if (*value == NULL) *value = ""; return 0;