mirror of
https://dev.iopsys.eu/bbf/bbfdm.git
synced 2025-12-10 07:44:39 +01:00
Ticket refs #2582: libbbf: add support for handling macvlan interfaces
This commit is contained in:
parent
4354aa2117
commit
6acb70c71c
4 changed files with 401 additions and 495 deletions
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2019 iopsys Software Solutions AB
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License version 2.1
|
||||
|
|
@ -45,93 +45,126 @@ static int eth_port_sysfs(const struct eth_port_args *args, const char *name, ch
|
|||
return get_net_device_sysfs(args->ifname, name, value);
|
||||
}
|
||||
|
||||
static int is_device_exist(char *device)
|
||||
static struct uci_section *is_device_section_exist(char *device)
|
||||
{
|
||||
struct uci_section *s = NULL;
|
||||
char *dev;
|
||||
|
||||
uci_path_foreach_sections(bbfdm, DMMAP, "link", s) {
|
||||
dmuci_get_value_by_section_string(s, "device", &dev);
|
||||
char *p = strtok(dev, ".");
|
||||
if (p != NULL) {
|
||||
if (strcmp(p, device) == 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (strcmp(dev, device) == 0)
|
||||
return s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
static int check_section_in_curr_section(char *curr_section, char *section)
|
||||
{
|
||||
char *pch = NULL, *pchr = NULL, section_list[256] = {0};
|
||||
|
||||
strncpy(section_list, curr_section, sizeof(section_list) - 1);
|
||||
for (pch = strtok_r(section_list, ",", &pchr); pch != NULL; pch = strtok_r(NULL, ",", &pchr)) {
|
||||
if (strcmp(pch, section) == 0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void create_link(char *ifname)
|
||||
static void add_section_in_curr_section(struct uci_section *dmmap_section, char *curr_section, char *section)
|
||||
{
|
||||
char *macaddr, *v, *device;
|
||||
struct uci_section *dmmap = NULL;
|
||||
char section_list[128] = {0}, *p = section_list;
|
||||
dmstrappendstr(p, curr_section);
|
||||
dmstrappendchr(p, ',');
|
||||
dmstrappendstr(p, section);
|
||||
dmstrappendend(p);
|
||||
|
||||
macaddr = get_macaddr(ifname);
|
||||
dmuci_set_value_by_section(dmmap_section, "section_name", section_list);
|
||||
}
|
||||
|
||||
static int is_name_exist_in_devices(char *name)
|
||||
{
|
||||
struct uci_section *s = NULL;
|
||||
|
||||
uci_foreach_option_eq("network", "device", "name", name, s) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void add_new_dmmap_section(char *macaddr, char*interface, char *section_name)
|
||||
{
|
||||
struct uci_section *dmmap = NULL;
|
||||
char *v;
|
||||
dmuci_add_section_bbfdm(DMMAP, "link", &dmmap, &v);
|
||||
dmuci_set_value_by_section(dmmap, "mac", macaddr);
|
||||
dmuci_set_value_by_section(dmmap, "device", interface);
|
||||
dmuci_set_value_by_section(dmmap, "section_name", section_name);
|
||||
}
|
||||
|
||||
static void create_link(char *sec_name, char *mac_addr)
|
||||
{
|
||||
char *macaddr = (*mac_addr != '\0') ? mac_addr : get_macaddr(sec_name);
|
||||
if (macaddr[0] == '\0')
|
||||
return;
|
||||
|
||||
device = get_device(ifname);
|
||||
char *device = get_device(sec_name);
|
||||
if (device[0] == '\0')
|
||||
return;
|
||||
|
||||
/* Interfaces might share the same mac address */
|
||||
if (is_mac_exist(macaddr))
|
||||
return;
|
||||
|
||||
/* For all the Ethernet link objects pointing to same Ethernet Interface,
|
||||
* we can omit creating multiple Ethernet link entries.*/
|
||||
char intf[250] = {0};
|
||||
/* For all the Ethernet link objects pointing to same Ethernet Interface, only one ethernet link */
|
||||
char intf[32] = {0};
|
||||
strncpy(intf, device, sizeof(intf) - 1);
|
||||
char *p = strtok(intf, ".");
|
||||
char *p = strchr(intf, '.');
|
||||
if (p != NULL) {
|
||||
if (is_device_exist(p))
|
||||
return;
|
||||
*p = '\0';
|
||||
struct uci_section *dmmap_section = is_device_section_exist(intf);
|
||||
if (dmmap_section) {
|
||||
char *section_name;
|
||||
dmuci_get_value_by_section_string(dmmap_section, "section_name", §ion_name);
|
||||
|
||||
/* Check section name exist => if yes, return*/
|
||||
if (check_section_in_curr_section(section_name, sec_name))
|
||||
return;
|
||||
|
||||
/* Update only section name */
|
||||
add_section_in_curr_section(dmmap_section, section_name, sec_name);
|
||||
|
||||
} else {
|
||||
/* Add new dmmap section */
|
||||
add_new_dmmap_section(macaddr, intf, sec_name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if section_name exists or not, if yes then do not add section just update
|
||||
* the params else add section and update the params. */
|
||||
struct uci_section *s = NULL;
|
||||
char *sec_name;
|
||||
int ret = 1;
|
||||
|
||||
char *dev_sec_name;
|
||||
uci_path_foreach_sections(bbfdm, DMMAP, "link", s) {
|
||||
dmuci_get_value_by_section_string(s, "section_name", &sec_name);
|
||||
if (strcmp(ifname, sec_name) == 0) {
|
||||
dmuci_get_value_by_section_string(s, "section_name", &dev_sec_name);
|
||||
if (strcmp(sec_name, dev_sec_name) == 0) {
|
||||
dmuci_set_value_by_section(s, "mac", macaddr);
|
||||
dmuci_set_value_by_section(s, "device", device);
|
||||
dmuci_set_value_by_section(s, "section_name", ifname);
|
||||
ret = 0;
|
||||
break;
|
||||
} else {
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 1 ) {
|
||||
dmuci_add_section_bbfdm(DMMAP, "link", &dmmap, &v);
|
||||
dmuci_set_value_by_section(dmmap, "mac", macaddr);
|
||||
dmuci_set_value_by_section(dmmap, "device", device);
|
||||
dmuci_set_value_by_section(dmmap, "section_name", ifname);
|
||||
}
|
||||
/* Add new dmmap section */
|
||||
add_new_dmmap_section(macaddr, intf, sec_name);
|
||||
}
|
||||
|
||||
static int dmmap_synchronizeEthernetLink(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
|
||||
{
|
||||
struct uci_section *s = NULL;
|
||||
char *ifname, *proto;
|
||||
char *ifname, *macaddr;
|
||||
|
||||
uci_foreach_sections("network", "interface", s) {
|
||||
dmuci_get_value_by_section_string(s, "proto", &proto);
|
||||
|
||||
if (strcmp(section_name(s), "loopback") == 0 || *proto == '\0')
|
||||
if (strcmp(section_name(s), "loopback") == 0)
|
||||
continue;
|
||||
|
||||
dmuci_get_value_by_section_string(s, "ifname", &ifname);
|
||||
if (*ifname == '\0' || *ifname == '@')
|
||||
if (*ifname == '\0')
|
||||
continue;
|
||||
|
||||
create_link(section_name(s));
|
||||
dmuci_get_value_by_section_string(s, "macaddr", &macaddr);
|
||||
create_link(section_name(s), macaddr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -234,7 +267,7 @@ static int get_linker_interface(char *refparam, struct dmctx *dmctx, void *data,
|
|||
|
||||
static int get_linker_link(char *refparam, struct dmctx *dmctx, void *data, char *instance, char **linker)
|
||||
{
|
||||
dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "mac", linker);
|
||||
dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "device", linker);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -252,88 +285,63 @@ static int get_linker_vlan_term(char *refparam, struct dmctx *dmctx, void *data,
|
|||
**************************************************************/
|
||||
static int addObjEthernetLink(char *refparam, struct dmctx *ctx, void *data, char **instance)
|
||||
{
|
||||
char *inst, *v;
|
||||
struct uci_section *dmmap_network= NULL;
|
||||
char *inst, *v, *val, *interface_name;
|
||||
struct uci_section *s = NULL, *dmmap_link = NULL;
|
||||
|
||||
inst = get_last_instance_bbfdm(DMMAP, "link", "link_instance");
|
||||
dmuci_add_section_bbfdm(DMMAP, "link", &dmmap_network, &v);
|
||||
*instance = update_instance_bbfdm(dmmap_network, inst, "link_instance");
|
||||
return 0;
|
||||
}
|
||||
dmasprintf(&interface_name, "link_%d", inst ? atoi(inst)+1 : 1);
|
||||
|
||||
static int del_ethernet_link_instance(char *sect_name)
|
||||
{
|
||||
char intf_tag[50] = {0};
|
||||
struct uci_section *s = NULL, *intf_s = NULL, *prev_s = NULL, *dev_s = NULL;
|
||||
int ret = 0;
|
||||
|
||||
/* Get the upstream interface. */
|
||||
get_upstream_interface(intf_tag, sizeof(intf_tag));
|
||||
|
||||
/* Create untagged upstream interface. */
|
||||
if (intf_tag[0] != '\0')
|
||||
strcat(intf_tag, ".1");
|
||||
|
||||
/* 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);
|
||||
|
||||
/* If ifname is same as of WAN port then delete the interface
|
||||
* section and the device section.*/
|
||||
if (strncmp(intf_tag, intf, sizeof(intf_tag)) == 0) {
|
||||
prev_s = intf_s;
|
||||
ret = 1;
|
||||
} else {
|
||||
char *proto;
|
||||
dmuci_get_value_by_section_string(intf_s, "proto", &proto);
|
||||
dmuci_delete_by_section(intf_s, "proto", proto);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 1) {
|
||||
/* Remove the section from UCI. */
|
||||
if (prev_s) dmuci_delete_by_section(prev_s, NULL, NULL);
|
||||
|
||||
/* Remove the device section from the UCI. */
|
||||
uci_foreach_option_eq("network", "device", "name", intf_tag, s) {
|
||||
dev_s = s;
|
||||
break;
|
||||
}
|
||||
if (dev_s) dmuci_delete_by_section(dev_s, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Remove the Link section from dmmap. */
|
||||
struct uci_section *dmmap_section = NULL;
|
||||
get_dmmap_section_of_config_section("dmmap", "link", sect_name, &dmmap_section);
|
||||
if (dmmap_section) dmuci_delete_by_section(dmmap_section, NULL, NULL);
|
||||
/* Add device section */
|
||||
dmuci_add_section("network", "interface", &s, &val);
|
||||
dmuci_rename_section_by_section(s, interface_name);
|
||||
|
||||
/* Add link section in dmmap file */
|
||||
dmuci_add_section_bbfdm(DMMAP, "link", &dmmap_link, &v);
|
||||
dmuci_set_value_by_section(dmmap_link, "section_name", interface_name);
|
||||
*instance = update_instance_bbfdm(dmmap_link, inst, "link_instance");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int delObjEthernetLink(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action)
|
||||
{
|
||||
char *sect_name = NULL;
|
||||
struct uci_section *s = NULL;
|
||||
struct uci_section *s = NULL, *stmp = NULL, *ss = NULL, *sstmp = NULL;
|
||||
char *sect_name = NULL, *section_list = NULL, *pch = NULL, *pchr = NULL;
|
||||
|
||||
switch (del_action) {
|
||||
case DEL_INST:
|
||||
/* Deletion of EthernetLink to support L2 VLAN deployments. */
|
||||
dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "section_name", §_name);
|
||||
get_config_section_of_dmmap_section("network", "interface", sect_name, &s);
|
||||
if(!s) {
|
||||
dmuci_delete_by_section(((struct dm_args *)data)->section, NULL, NULL);
|
||||
} else {
|
||||
del_ethernet_link_instance(sect_name);
|
||||
// Remove dmmap section
|
||||
dmuci_delete_by_section(((struct dm_args *)data)->section, NULL, NULL);
|
||||
|
||||
// Check each network section in the list of sections
|
||||
if (*sect_name == '\0')
|
||||
return -1;
|
||||
|
||||
section_list = dmstrdup(sect_name);
|
||||
for (pch = strtok_r(section_list, ",", &pchr); pch != NULL; pch = strtok_r(NULL, ",", &pchr)) {
|
||||
// Remove network and device section
|
||||
uci_foreach_sections_safe("network", "interface", stmp, s) {
|
||||
if (strcmp(section_name(s), pch) == 0) {
|
||||
// Remove the device section corresponding to this interface if exists
|
||||
char *device = get_device(pch);
|
||||
uci_foreach_option_eq_safe("network", "device", "name", device, sstmp, ss) {
|
||||
char *type;
|
||||
dmuci_get_value_by_section_string(s, "type", &type);
|
||||
if (strcmp(type, "untagged") == 0) dmuci_delete_by_section(ss, NULL, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
// Remove network section
|
||||
dmuci_delete_by_section(s, NULL, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
dmfree(section_list);
|
||||
return 0;
|
||||
case DEL_ALL:
|
||||
return FAULT_9005;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -376,7 +384,7 @@ static int delObjEthernetVLANTermination(char *refparam, struct dmctx *ctx, void
|
|||
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 || (name && !is_vlan_termination_section(name)))
|
||||
if (strcmp(type, "untagged") == 0 || (*name != '\0' && !is_vlan_termination_section(name)))
|
||||
continue;
|
||||
|
||||
// Remove device section in dmmap_network file
|
||||
|
|
@ -430,7 +438,7 @@ static int get_Ethernet_VLANTerminationNumberOfEntries(char *refparam, struct dm
|
|||
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))
|
||||
if (strcmp(type, "untagged") == 0 || (*name != '\0' && !is_vlan_termination_section(name)))
|
||||
continue;
|
||||
cnt++;
|
||||
}
|
||||
|
|
@ -819,276 +827,42 @@ 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, *proto, *type, *ifname, *mac;
|
||||
|
||||
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, "proto", &proto);
|
||||
if (strcmp(section_name(s), "loopback") == 0 || *proto == '\0')
|
||||
continue;
|
||||
|
||||
dmuci_get_value_by_section_string(s, "ifname", &ifname);
|
||||
if (*ifname == '\0' || *ifname == '@')
|
||||
continue;
|
||||
|
||||
mac = get_macaddr(section_name(s));
|
||||
if (mac[0] == '\0' || strcasecmp(mac, link_mac) != 0)
|
||||
continue;
|
||||
|
||||
dmuci_get_value_by_section_string(s, "type", &type);
|
||||
if (strcmp(type, "bridge") == 0) {
|
||||
struct uci_section *dmmap_section, *port;
|
||||
get_dmmap_section_of_config_section("dmmap_network", "interface", section_name(s), &dmmap_section);
|
||||
if (dmmap_section != NULL) {
|
||||
char *br_inst, *mg;
|
||||
dmuci_get_value_by_section_string(dmmap_section, "bridge_instance", &br_inst);
|
||||
uci_path_foreach_option_eq(bbfdm, "dmmap_bridge_port", "bridge_port", "br_inst", br_inst, port) {
|
||||
dmuci_get_value_by_section_string(port, "management", &mg);
|
||||
if (strcmp(mg, "1") == 0) {
|
||||
char *device, linker[512] = "";
|
||||
dmuci_get_value_by_section_string(port, "device", &device);
|
||||
snprintf(linker, sizeof(linker), "br_%s:%s+%s", br_inst, section_name(port), device);
|
||||
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 = "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* For upstream interface, set the lowerlayer to wan port of Ethernet.Interface */
|
||||
char intf_tag[50] = {0};
|
||||
|
||||
/* Get the upstream interface. */
|
||||
get_upstream_interface(intf_tag, sizeof(intf_tag));
|
||||
|
||||
if (intf_tag[0] != '\0') {
|
||||
adm_entry_get_linker_param(ctx, dm_print_path("%s%cEthernet%cInterface%c", dmroot, dm_delim, dm_delim, dm_delim), intf_tag, value);
|
||||
if (*value == NULL)
|
||||
*value = "";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_ethlink_lowerlayer_bridge(char *lower_layer, char *instance)
|
||||
{
|
||||
int len = 0, i = 0;
|
||||
char new_if[250] = {0}, key[10] = {0};
|
||||
struct uci_section *s = NULL, *intf_s = NULL;
|
||||
char *sec_name;
|
||||
char *p = strstr(lower_layer, "Port");
|
||||
if (p) {
|
||||
/* Get the bridge_key. */
|
||||
len = strlen(p);
|
||||
for (i = 0; i < strlen(lower_layer) - len; i++) {
|
||||
new_if[i] = lower_layer[i];
|
||||
}
|
||||
|
||||
char br_key = new_if[strlen(new_if) - 2];
|
||||
snprintf(key, sizeof(key), "%c", br_key);
|
||||
|
||||
/* Find out bridge section name using bridge key. */
|
||||
uci_path_foreach_option_eq(bbfdm, "dmmap_network", "interface", "bridge_instance", key, s) {
|
||||
dmuci_get_value_by_section_string(s, "section_name", &sec_name);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if section name is present in network UCI wd type as bridge
|
||||
* and ifname not empty, if yes then update
|
||||
* the section with proto 'dhcp' else do nothing. */
|
||||
uci_foreach_sections("network", "interface", intf_s) {
|
||||
char sec[20] = {0};
|
||||
strncpy(sec, section_name(intf_s), sizeof(sec) - 1);
|
||||
|
||||
if (strncmp(sec, sec_name, sizeof(sec)) == 0) {
|
||||
char *type, *ifname;
|
||||
dmuci_get_value_by_section_string(intf_s, "type", &type);
|
||||
if (*type == '\0' || strcmp(type, "bridge") != 0)
|
||||
return -1;
|
||||
|
||||
dmuci_get_value_by_section_string(intf_s, "ifname", &ifname);
|
||||
if (*ifname == '\0')
|
||||
return -1;
|
||||
|
||||
/* Add ethernet link params to dmmap link section. */
|
||||
uci_path_foreach_sections(bbfdm, DMMAP, "link", s) {
|
||||
char *inst;
|
||||
char link_inst[10] = {0};
|
||||
dmuci_get_value_by_section_string(s, "link_instance", &inst);
|
||||
strncpy(link_inst, instance, sizeof(link_inst) - 1);
|
||||
|
||||
/* Check if the link instance are same or not. */
|
||||
if (strncmp(link_inst, inst, sizeof(link_inst)) == 0) {
|
||||
dmuci_set_value_by_section(s, "section_name", section_name(intf_s));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the value of proto to the section. */
|
||||
dmuci_set_value_by_section(intf_s, "proto", "dhcp");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_set_linker_in_uci(char *intf, char *instance, char *mac_addr)
|
||||
{
|
||||
struct uci_section *s = NULL, *link_s = NULL, *mac_s = NULL, *prev_s = NULL;
|
||||
int mac_present = 0;
|
||||
uci_foreach_option_eq("network", "interface", "ifname", intf, s) {
|
||||
/* Fetch the mac address of the interface. */
|
||||
char *macaddr = get_macaddr(section_name(s));
|
||||
|
||||
/* Check if mac is present in dmmap link section. */
|
||||
uci_path_foreach_option_eq(bbfdm, DMMAP, "link", "mac", macaddr, mac_s) {
|
||||
/* Get the link instance of the section. */
|
||||
char *link;
|
||||
dmuci_get_value_by_section_string(mac_s, "link_instance", &link);
|
||||
|
||||
/* Check if the link instance are same or not. */
|
||||
if (strcmp(link, instance) != 0) {
|
||||
/* Delete the new link inst as mac already exists. */
|
||||
uci_path_foreach_option_eq(bbfdm, DMMAP, "link", "link_instance", instance, link_s) {
|
||||
prev_s = link_s;
|
||||
}
|
||||
if (prev_s) dmuci_delete_by_section(prev_s, NULL, NULL);
|
||||
}
|
||||
mac_present = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (mac_present == 1) {
|
||||
dmuci_set_value_by_section(s, "proto", "dhcp");
|
||||
return 1;
|
||||
} else {
|
||||
/* Add section name and mac in dmmap link section if
|
||||
* link instances are same. */
|
||||
uci_path_foreach_sections(bbfdm, DMMAP, "link", link_s) {
|
||||
char *inst;
|
||||
char link_inst[10] = {0};
|
||||
dmuci_get_value_by_section_string(link_s, "link_instance", &inst);
|
||||
strncpy(link_inst, instance, sizeof(link_inst) - 1);
|
||||
|
||||
/* Check if the link instance are same or not. */
|
||||
if (strncmp(link_inst, inst, sizeof(link_inst)) == 0) {
|
||||
dmuci_set_value_by_section(link_s, "section_name", section_name(s));
|
||||
dmuci_set_value_by_section(link_s, "mac", mac_addr);
|
||||
char *linker;
|
||||
dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "device", &linker);
|
||||
char *bridge = strstr(linker, "br-");
|
||||
if (bridge) {
|
||||
char *int_name;
|
||||
dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "section_name", &int_name);
|
||||
struct uci_section *dmmap_section, *port;
|
||||
get_dmmap_section_of_config_section("dmmap_network", "interface", int_name, &dmmap_section);
|
||||
if (dmmap_section != NULL) {
|
||||
char *br_inst, *mg;
|
||||
dmuci_get_value_by_section_string(dmmap_section, "bridge_instance", &br_inst);
|
||||
uci_path_foreach_option_eq(bbfdm, "dmmap_bridge_port", "bridge_port", "br_inst", br_inst, port) {
|
||||
dmuci_get_value_by_section_string(port, "management", &mg);
|
||||
if (strcmp(mg, "1") == 0) {
|
||||
char *device, linker[512] = "";
|
||||
dmuci_get_value_by_section_string(port, "device", &device);
|
||||
snprintf(linker, sizeof(linker), "br_%s:%s+%s", br_inst, section_name(port), device);
|
||||
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 = "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
dmuci_set_value_by_section(s, "proto", "dhcp");
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
char *vid = strchr(linker, '.');
|
||||
if (vid) *vid = '\0';
|
||||
char *macvlan = strchr(linker, '_');
|
||||
if (macvlan) *macvlan = '\0';
|
||||
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)
|
||||
*value = "";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_lowerlayer_in_uci(char *mac_addr, char *instance, char *intf, char *linker)
|
||||
{
|
||||
int val_present = 0;
|
||||
char *val;
|
||||
struct uci_section *s = NULL, *link_s = NULL, *mac_s = NULL, *prev_s = NULL;
|
||||
|
||||
dmuci_add_section_and_rename("network", "interface", &s, &val);
|
||||
|
||||
/* Check if mac is present in dmmap link section. */
|
||||
uci_path_foreach_option_eq(bbfdm, DMMAP, "link", "mac", mac_addr, mac_s) {
|
||||
/* Get the link instance of the section. */
|
||||
char *link;
|
||||
dmuci_get_value_by_section_string(mac_s, "link_instance", &link);
|
||||
|
||||
/* Check if the link instance are same or not. */
|
||||
if (strcmp(link, instance) != 0) {
|
||||
/* Delete the new link inst as mac already exists. */
|
||||
uci_path_foreach_option_eq(bbfdm, DMMAP, "link", "link_instance", instance, link_s) {
|
||||
prev_s = link_s;
|
||||
}
|
||||
if (prev_s) dmuci_delete_by_section(prev_s, NULL, NULL);
|
||||
}
|
||||
val_present = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (val_present == 0) {
|
||||
/* Add ethernet link params to dmmap link section. */
|
||||
uci_path_foreach_sections(bbfdm, DMMAP, "link", link_s) {
|
||||
char *inst;
|
||||
char link_inst[10] = {0};
|
||||
dmuci_get_value_by_section_string(link_s, "link_instance", &inst);
|
||||
strncpy(link_inst, instance, sizeof(link_inst) - 1);
|
||||
|
||||
/* Check if the link instance are same or not. */
|
||||
if (strncmp(link_inst, inst, sizeof(link_inst)) == 0) {
|
||||
dmuci_set_value_by_section(link_s, "section_name", section_name(s));
|
||||
dmuci_set_value_by_section(link_s, "mac", mac_addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dmuci_set_value_by_section(s, "proto", "dhcp");
|
||||
dmuci_set_value_by_section(s, "ifname", intf);
|
||||
|
||||
/* Add config device section. */
|
||||
struct uci_section *dev_s;
|
||||
dmuci_add_section_and_rename("network", "device", &dev_s, &val);
|
||||
dmuci_set_value_by_section(dev_s, "type", "untagged");
|
||||
char *tok = strtok(linker, ".");
|
||||
dmuci_set_value_by_section(dev_s, "ifname", tok);
|
||||
dmuci_set_value_by_section(dev_s, "name", intf);
|
||||
dmuci_set_value_by_section(dev_s, "macaddr", mac_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_ethlink_lowerlayer_eth_intf(char *lower_layer, char *instance, char *linker)
|
||||
{
|
||||
|
||||
/* Get the upstream interface. */
|
||||
char intf_tag[50] = {0};
|
||||
|
||||
/* Get the upstream interface. */
|
||||
get_upstream_interface(intf_tag, sizeof(intf_tag));
|
||||
|
||||
/* Fetch the macaddress of upstream interface. */
|
||||
char *mac = get_macaddr_from_device(intf_tag);
|
||||
|
||||
/* 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));
|
||||
|
||||
/* Create untagged upstream interface. */
|
||||
if (intf_tag[0] != '\0')
|
||||
strcat(intf_tag, ".1");
|
||||
|
||||
char intf[20] = {0};
|
||||
if (strcmp(linker, intf_tag) == 0)
|
||||
strncpy(intf, linker, sizeof(intf) - 1);
|
||||
else {
|
||||
snprintf(intf, sizeof(intf), "%s.%s", linker, "1");
|
||||
if (strcmp(intf, intf_tag) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check if linker is present in network UCI, if yes the update
|
||||
* the proto, else create a interface and device section. */
|
||||
int ret = check_set_linker_in_uci(intf, instance, mac_addr);
|
||||
|
||||
/* Linker is not present in the UCI. */
|
||||
if (ret == 0) {
|
||||
set_lowerlayer_in_uci(mac_addr, instance, intf, linker);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_EthernetLink_LowerLayers(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
||||
{
|
||||
char lower_layer[250] = {0};
|
||||
|
|
@ -1104,14 +878,22 @@ static int set_EthernetLink_LowerLayers(char *refparam, struct dmctx *ctx, void
|
|||
else
|
||||
strncpy(lower_layer, value, sizeof(lower_layer) - 1);
|
||||
|
||||
/* Check if the value is valid or not. */
|
||||
if (strncmp(lower_layer, "Device.Bridging.Bridge.", 23) == 0) {
|
||||
set_ethlink_lowerlayer_bridge(lower_layer, instance);
|
||||
} else if (strncmp(lower_layer, "Device.Ethernet.Interface.", 26) == 0) {
|
||||
/* Find the linker of the lowerlayer value to be set. */
|
||||
char *linker;
|
||||
if (strncmp(lower_layer, "Device.Ethernet.Interface.", 26) == 0) {
|
||||
char *linker, *int_name;
|
||||
adm_entry_get_linker_value(ctx, lower_layer, &linker);
|
||||
set_ethlink_lowerlayer_eth_intf(lower_layer, instance, linker);
|
||||
|
||||
if (linker == NULL || *linker == '\0')
|
||||
return -1;
|
||||
|
||||
dmuci_set_value_by_section(((struct dm_args *)data)->section, "device", linker);
|
||||
dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "section_name", &int_name);
|
||||
struct uci_section *s;
|
||||
uci_foreach_sections("network", "interface", s) {
|
||||
if (strcmp(section_name(s), int_name) == 0) {
|
||||
dmuci_set_value_by_section(s, "ifname", linker);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -1251,28 +1033,15 @@ static int get_EthernetVLANTermination_LastChange(char *refparam, struct dmctx *
|
|||
|
||||
static int get_EthernetVLANTermination_LowerLayers(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
char *macaddr, *devname, *linker = "";
|
||||
char *name;
|
||||
|
||||
dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "name", &devname);
|
||||
if (*devname != '\0') {
|
||||
macaddr = get_macaddr_from_device(devname);
|
||||
if (macaddr[0] != '\0' && 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);
|
||||
}
|
||||
}
|
||||
dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "name", &name);
|
||||
char *vid = strchr(name, '.');
|
||||
if (vid) *vid = '\0';
|
||||
|
||||
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 = "";
|
||||
}
|
||||
}
|
||||
adm_entry_get_linker_param(ctx, dm_print_path("%s%cEthernet%cLink%c", dmroot, dm_delim, dm_delim, dm_delim), name, value);
|
||||
if (*value == NULL)
|
||||
*value = "";
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1292,36 +1061,55 @@ static int set_EthernetVLANTermination_LowerLayers(char *refparam, struct dmctx
|
|||
strncpy(lower_layer, value, sizeof(lower_layer) - 1);
|
||||
|
||||
if (strncmp(lower_layer, "Device.Ethernet.Link.", 21) == 0) {
|
||||
char new_name[16] = {0}, *linker = NULL, *device, *vid, *curr_name;
|
||||
char new_name[16] = {0}, *linker = NULL, *type;
|
||||
|
||||
adm_entry_get_linker_value(ctx, lower_layer, &linker);
|
||||
if (linker == NULL || *linker == '\0')
|
||||
return -1;
|
||||
|
||||
struct uci_section *dmmap_s = NULL;
|
||||
get_dmmap_section_of_config_section_eq("dmmap", "link", "mac", linker, &dmmap_s);
|
||||
dmuci_get_value_by_section_string(dmmap_s, "device", &device);
|
||||
dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "name", &curr_name);
|
||||
// Get type option from device section
|
||||
dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "type", &type);
|
||||
|
||||
if (*device != '\0') {
|
||||
char *p = strtok(device, ".");
|
||||
if ((strcmp(type, "macvlan") == 0)) {
|
||||
/* type == macvlan */
|
||||
|
||||
struct uci_section *s = NULL, *dmmap_s = NULL;
|
||||
char link_inst[8] = {0}, sec_name[32] = {0};
|
||||
|
||||
snprintf(link_inst, sizeof(link_inst), "%c", lower_layer[strlen(lower_layer)-2]);
|
||||
snprintf(new_name, sizeof(new_name), "%s_%s", linker, link_inst);
|
||||
|
||||
if (is_name_exist_in_devices(new_name))
|
||||
return -1;
|
||||
|
||||
uci_foreach_option_eq("network", "interface", "ifname", linker, s) {
|
||||
dmuci_set_value_by_section(s, "ifname", new_name);
|
||||
strncpy(sec_name, section_name(s), sizeof(sec_name) - 1);
|
||||
break;
|
||||
}
|
||||
|
||||
get_dmmap_section_of_config_section_eq("dmmap", "link", "link_instance", link_inst, &dmmap_s);
|
||||
dmuci_set_value_by_section(dmmap_s, "device", new_name);
|
||||
dmuci_set_value_by_section(dmmap_s, "section_name", sec_name);
|
||||
|
||||
|
||||
} else {
|
||||
/* type != macvlan */
|
||||
|
||||
char *vid;
|
||||
dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "vid", &vid);
|
||||
if (*vid != '\0')
|
||||
snprintf(new_name, sizeof(new_name), "%s.%s", (p)?p:device, vid);
|
||||
snprintf(new_name, sizeof(new_name), "%s.%s", linker, vid);
|
||||
else
|
||||
snprintf(new_name, sizeof(new_name), "%s", (p)?p:device);
|
||||
snprintf(new_name, sizeof(new_name), "%s", linker);
|
||||
|
||||
dmuci_set_value_by_section(((struct dm_args *)data)->section, "ifname", (p)?p:device);
|
||||
dmuci_set_value_by_section(((struct dm_args *)data)->section, "name", new_name);
|
||||
if (is_name_exist_in_devices(new_name))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*curr_name != '\0') {
|
||||
// Update interface section corresponding to this device if it exists
|
||||
struct uci_section *s = NULL;
|
||||
uci_foreach_option_eq("network", "interface", "ifname", curr_name, s) {
|
||||
dmuci_set_value_by_section(s, "ifname", new_name);
|
||||
}
|
||||
}
|
||||
// Set ifname and name options of device section
|
||||
dmuci_set_value_by_section(((struct dm_args *)data)->section, "ifname", linker);
|
||||
dmuci_set_value_by_section(((struct dm_args *)data)->section, "name", new_name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -1338,7 +1126,7 @@ static int get_EthernetVLANTermination_VLANID(char *refparam, struct dmctx *ctx,
|
|||
|
||||
static int set_EthernetVLANTermination_VLANID(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
||||
{
|
||||
char *ifname, *name, *curr_ifname;
|
||||
char *ifname, *name, *curr_ifname, *type;
|
||||
struct uci_section *s = NULL;
|
||||
|
||||
switch (action) {
|
||||
|
|
@ -1347,19 +1135,29 @@ static int set_EthernetVLANTermination_VLANID(char *refparam, struct dmctx *ctx,
|
|||
return FAULT_9007;
|
||||
return 0;
|
||||
case VALUESET:
|
||||
dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "ifname", &ifname);
|
||||
if (*ifname != '\0') {
|
||||
dmasprintf(&name, "%s.%s", ifname, value);
|
||||
// Get type option from device section
|
||||
dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "type", &type);
|
||||
|
||||
// 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);
|
||||
if (strcmp(type, "macvlan") != 0) {
|
||||
/* only when type != macvlan */
|
||||
|
||||
dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "ifname", &ifname);
|
||||
if (*ifname != '\0') {
|
||||
dmasprintf(&name, "%s.%s", ifname, value);
|
||||
|
||||
if (is_name_exist_in_devices(name))
|
||||
return -1;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// set name option of the device section
|
||||
dmuci_set_value_by_section(((struct dm_args *)data)->section, "name", name);
|
||||
dmfree(name);
|
||||
}
|
||||
|
||||
// set name option of the device section
|
||||
dmuci_set_value_by_section(((struct dm_args *)data)->section, "name", name);
|
||||
dmfree(name);
|
||||
}
|
||||
|
||||
// set vid option of the device section
|
||||
|
|
@ -1399,6 +1197,108 @@ static int set_EthernetVLANTermination_TPID(char *refparam, struct dmctx *ctx, v
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int get_EthernetVLANTermination_MACVLAN(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "type", value);
|
||||
*value = (strcmp(*value, "macvlan") == 0) ? "1" : "0";
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_EthernetVLANTermination_MACVLAN(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
||||
{
|
||||
char *name, *ifname;
|
||||
bool b;
|
||||
|
||||
switch (action) {
|
||||
case VALUECHECK:
|
||||
if (dm_validate_boolean(value))
|
||||
return FAULT_9007;
|
||||
break;
|
||||
case VALUESET:
|
||||
string_to_bool(value, &b);
|
||||
dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "ifname", &ifname);
|
||||
dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "name", &name);
|
||||
struct uci_section *s = NULL, *dmmap_s = NULL;
|
||||
char *link_instance, new_name[16] = {0};
|
||||
if (b && *name != '\0') {
|
||||
int name_found = 0;
|
||||
|
||||
uci_foreach_option_eq("network", "interface", "ifname", name, s) {
|
||||
|
||||
get_dmmap_section_of_config_section_eq("dmmap", "link", "device", ifname, &dmmap_s);
|
||||
if (dmmap_s) {
|
||||
dmuci_get_value_by_section_string(dmmap_s, "link_instance", &link_instance);
|
||||
snprintf(new_name, sizeof(new_name), "%s_%s", ifname, link_instance);
|
||||
|
||||
if (is_name_exist_in_devices(new_name))
|
||||
return -1;
|
||||
|
||||
dmuci_set_value_by_section(dmmap_s, "device", new_name);
|
||||
dmuci_set_value_by_section(dmmap_s, "section_name", section_name(s));
|
||||
|
||||
}
|
||||
|
||||
dmuci_set_value_by_section(s, "ifname", new_name);
|
||||
|
||||
name_found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (name_found == 0) {
|
||||
int ifname_found = 0;
|
||||
struct uci_section *ss = NULL;
|
||||
|
||||
uci_foreach_option_eq("network", "interface", "ifname", ifname, ss) {
|
||||
|
||||
uci_path_foreach_option_eq(bbfdm, "dmmap", "link", "device", ifname, dmmap_s) {
|
||||
char *sec_name;
|
||||
dmuci_get_value_by_section_string(dmmap_s, "section_name", &sec_name);
|
||||
/* Check section name exist => if yes, continue*/
|
||||
if (!check_section_in_curr_section(sec_name, section_name(ss)))
|
||||
continue;
|
||||
|
||||
dmuci_get_value_by_section_string(dmmap_s, "link_instance", &link_instance);
|
||||
snprintf(new_name, sizeof(new_name), "%s_%s", ifname, link_instance);
|
||||
|
||||
if (is_name_exist_in_devices(new_name))
|
||||
return -1;
|
||||
|
||||
dmuci_set_value_by_section(dmmap_s, "device", new_name);
|
||||
dmuci_set_value_by_section(dmmap_s, "section_name", section_name(ss));
|
||||
}
|
||||
|
||||
dmuci_set_value_by_section(ss, "ifname", new_name);
|
||||
|
||||
ifname_found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ifname_found == 0) {
|
||||
get_dmmap_section_of_config_section_eq("dmmap", "link", "device", ifname, &dmmap_s);
|
||||
if (dmmap_s) {
|
||||
dmuci_get_value_by_section_string(dmmap_s, "link_instance", &link_instance);
|
||||
snprintf(new_name, sizeof(new_name), "%s_%s", ifname, link_instance);
|
||||
|
||||
if (is_name_exist_in_devices(new_name))
|
||||
return -1;
|
||||
|
||||
dmuci_set_value_by_section(dmmap_s, "device", new_name);
|
||||
dmuci_set_value_by_section(dmmap_s, "section_name", "");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dmuci_set_value_by_section(((struct dm_args *)data)->section, "name", new_name);
|
||||
dmuci_set_value_by_section(((struct dm_args *)data)->section, "type", "macvlan");
|
||||
} else {
|
||||
dmuci_set_value_by_section(((struct dm_args *)data)->section, "type", b ? "macvlan" : "8021q");
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*#Device.Ethernet.VLANTermination.{i}.Stats.BytesSent!SYSFS:/sys/class/net/@Name/statistics/tx_bytes*/
|
||||
static int get_EthernetVLANTerminationStats_BytesSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
|
|
@ -1573,6 +1473,7 @@ DMLEAF tEthernetVLANTerminationParams[] = {
|
|||
{"LowerLayers", &DMWRITE, DMT_STRING, get_EthernetVLANTermination_LowerLayers, set_EthernetVLANTermination_LowerLayers, NULL, NULL, BBFDM_BOTH},
|
||||
{"VLANID", &DMWRITE, DMT_UNINT, get_EthernetVLANTermination_VLANID, set_EthernetVLANTermination_VLANID, NULL, NULL, BBFDM_BOTH},
|
||||
{"TPID", &DMWRITE, DMT_UNINT, get_EthernetVLANTermination_TPID, set_EthernetVLANTermination_TPID, NULL, NULL, BBFDM_BOTH},
|
||||
{CUSTOM_PREFIX"MACVLAN", &DMWRITE, DMT_BOOL, get_EthernetVLANTermination_MACVLAN, set_EthernetVLANTermination_MACVLAN, NULL, NULL, BBFDM_BOTH},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -233,9 +233,11 @@ static int get_IP_InterfaceNumberOfEntries(char *refparam, struct dmctx *ctx, vo
|
|||
{
|
||||
struct uci_section *s = NULL;
|
||||
int cnt = 0;
|
||||
char *proto;
|
||||
|
||||
uci_foreach_sections("network", "interface", s) {
|
||||
if (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;
|
||||
cnt++;
|
||||
}
|
||||
|
|
@ -645,7 +647,7 @@ 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 *proto, *device, *mac, linker[64] = {0};
|
||||
char *proto, *device, linker[64] = {0};
|
||||
|
||||
dmuci_get_value_by_section_string(((struct ip_args *)data)->ip_sec, "proto", &proto);
|
||||
if (strstr(proto, "ppp")) {
|
||||
|
|
@ -662,9 +664,12 @@ static int get_IPInterface_LowerLayers(char *refparam, struct dmctx *ctx, void *
|
|||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
if (device[0] != '\0') {
|
||||
char linker[32] = {0};
|
||||
strncpy(linker, device, sizeof(linker) - 1);
|
||||
char *vid = strchr(linker, '.');
|
||||
if (vid) *vid = '\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)
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -685,7 +690,6 @@ static int set_IPInterface_LowerLayers(char *refparam, struct dmctx *ctx, void *
|
|||
return FAULT_9007;
|
||||
return 0;
|
||||
case VALUESET:
|
||||
|
||||
if (value[strlen(value)-1] != '.')
|
||||
snprintf(lower_layer, sizeof(lower_layer), "%s.", value);
|
||||
else
|
||||
|
|
@ -693,12 +697,48 @@ static int set_IPInterface_LowerLayers(char *refparam, struct dmctx *ctx, void *
|
|||
|
||||
if (strncmp(lower_layer, "Device.Ethernet.VLANTermination.", 32) == 0) {
|
||||
adm_entry_get_linker_value(ctx, lower_layer, &linker);
|
||||
if (linker) {
|
||||
// Update ifname list
|
||||
dmuci_set_value_by_section(((struct ip_args *)data)->ip_sec, "ifname", linker);
|
||||
|
||||
if (linker == NULL || *linker == '\0')
|
||||
return -1;
|
||||
|
||||
struct uci_section *s = NULL, *stmp = NULL;
|
||||
|
||||
// Remove the device section corresponding to this interface if exists
|
||||
char *device = get_device(section_name(((struct ip_args *)data)->ip_sec));
|
||||
uci_foreach_option_eq_safe("network", "device", "name", device, stmp, s) {
|
||||
char *type;
|
||||
dmuci_get_value_by_section_string(s, "type", &type);
|
||||
if (strcmp(type, "untagged") == 0) dmuci_delete_by_section(s, NULL, NULL);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
return FAULT_9005;
|
||||
|
||||
char *mac_vlan = strchr(linker, '_');
|
||||
if (mac_vlan) {
|
||||
// Check if there is an interface that has the same ifname ==> if yes, remove it
|
||||
uci_foreach_option_eq_safe("network", "interface", "ifname", linker, stmp, s) {
|
||||
dmuci_delete_by_section(s, NULL, NULL);
|
||||
}
|
||||
|
||||
// Check if there is an dmmap link section that has the same device ==> if yes, update section name
|
||||
get_dmmap_section_of_config_section_eq("dmmap", "link", "device", linker, &s);
|
||||
dmuci_set_value_by_section_bbfdm(s, "section_name", section_name(((struct ip_args *)data)->ip_sec));
|
||||
|
||||
} else {
|
||||
// Check if there is an interface that has the same name of device ==> if yes, remove it
|
||||
char device[32] = {0};
|
||||
strncpy(device, linker, sizeof(device) - 1);
|
||||
char *vid = strchr(device, '.');
|
||||
if (vid) {
|
||||
*vid = '\0';
|
||||
uci_foreach_option_eq_safe("network", "interface", "ifname", device, stmp, s) {
|
||||
dmuci_delete_by_section(s, NULL, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update ifname list
|
||||
dmuci_set_value_by_section(((struct ip_args *)data)->ip_sec, "ifname", linker);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -1515,8 +1555,17 @@ static int delete_ip_interface(char *refparam, struct dmctx *ctx, void *data, ch
|
|||
dmuci_set_value_by_section(dmmap_section, "ip_int_instance", "");
|
||||
dmuci_set_value_by_section(dmmap_section, "ipv4_instance", "");
|
||||
} else {
|
||||
/* type is not bridge ==> remove interface and dmmap section */
|
||||
/* Remove the device section corresponding to this interface if exists */
|
||||
char *device = get_device(section_name(((struct ip_args *)data)->ip_sec));
|
||||
struct uci_section *s = NULL, *stmp = NULL;
|
||||
uci_foreach_option_eq_safe("network", "device", "name", device, stmp, s) {
|
||||
char *type;
|
||||
dmuci_get_value_by_section_string(s, "type", &type);
|
||||
if (strcmp(type, "untagged") == 0) dmuci_delete_by_section(s, NULL, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
/* type is not bridge ==> remove interface and dmmap section */
|
||||
dmuci_delete_by_section(((struct ip_args *)data)->ip_sec, NULL, NULL);
|
||||
dmuci_delete_by_section(dmmap_section, NULL, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1877,12 +1877,11 @@ int is_vlan_termination_section(char *name)
|
|||
|
||||
// check if ifname list contains the device name
|
||||
if (strstr(ifname, name)) {
|
||||
char *type, *proto;
|
||||
dmuci_get_value_by_section_string(s, "type", &type);
|
||||
dmuci_get_value_by_section_string(s, "proto", &proto);
|
||||
char *type;
|
||||
// check type is not bridge
|
||||
|
||||
// check type is not bridge and proto is not empty
|
||||
if (strcmp(type, "bridge") == 0 || *proto == '\0')
|
||||
dmuci_get_value_by_section_string(s, "type", &type);
|
||||
if (strcmp(type, "bridge") == 0)
|
||||
return 0;
|
||||
|
||||
break;
|
||||
|
|
@ -1891,46 +1890,6 @@ int is_vlan_termination_section(char *name)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int get_upstream_interface(char *intf_tag, int len)
|
||||
{
|
||||
/* Get the upstream interface. */
|
||||
struct uci_section *port_s = NULL;
|
||||
uci_foreach_option_eq("ports", "ethport", "uplink", "1", port_s) {
|
||||
char *iface;
|
||||
dmuci_get_value_by_section_string(port_s, "ifname", &iface);
|
||||
if (*iface != '\0') {
|
||||
strncpy(intf_tag, iface, len - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int create_mac_addr_upstream_intf(char *mac_addr, char *mac, int mac_len)
|
||||
{
|
||||
int num = 0;
|
||||
char macaddr[25] = {0};
|
||||
|
||||
if (*mac != '\0') {
|
||||
strncpy(macaddr, mac, sizeof(macaddr) - 1);
|
||||
int len = strlen(macaddr);
|
||||
|
||||
/* Fetch the last octect of base mac address in integer variable. */
|
||||
if (sscanf(&macaddr[len - 2], "%02x", &num) > 0) {
|
||||
num += 1;
|
||||
snprintf(&macaddr[len - 2], sizeof(macaddr), "%02x", num);
|
||||
}
|
||||
|
||||
if (macaddr[0] != '\0') {
|
||||
strncpy(mac_addr, macaddr, mac_len);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void del_dmmap_sec_with_opt_eq(char *dmmap_file, char *section, char *option, char *value)
|
||||
{
|
||||
struct uci_section *d_sec = NULL;
|
||||
|
|
|
|||
|
|
@ -324,11 +324,8 @@ int is_regular_file(const char *path);
|
|||
char *stringToHex(char *text, int length);
|
||||
char *replace_char(char *str, char find, char replace);
|
||||
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);
|
||||
int get_br_key_from_lower_layer(char *lower_layer, char *key, size_t s_key);
|
||||
int get_igmp_snooping_interface_val(char *value, char *ifname, size_t s_ifname);
|
||||
void sync_dmmap_bool_to_uci_list(struct uci_section *s, char *section,
|
||||
char *value, bool b);
|
||||
void sync_dmmap_bool_to_uci_list(struct uci_section *s, char *section, char *value, bool b);
|
||||
void del_dmmap_sec_with_opt_eq(char *dmmap_file, char *section, char *option, char *value);
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue