Update for IP.Interface.LowerLayers for bridge interface

The lowerlayer of Ip.Interface of bridge type is changed to the "Etherent.Link".
This commit is contained in:
Meng 2018-12-21 13:43:05 +01:00 committed by Omar Kallel
parent e642ddd383
commit 52db14f866
4 changed files with 141 additions and 73 deletions

View file

@ -23,11 +23,18 @@
#include <sys/wait.h>
#include <uci.h>
#include <ctype.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/if_arp.h>
#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;
}

View file

@ -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

View file

@ -8,12 +8,6 @@
* Author: Anis Ellouze <anis.ellouze@pivasoftware.com>
*
*/
#include <netdb.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <uci.h>
#include <stdio.h>
#include <ctype.h>
@ -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;
}

View file

@ -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;