Layer2 Deployment : Changes done to support VLAN deployments for layer 2

- Changes done in Bridging.Bridge.X.Port, Bridging.Bridge.X.VLAN Objects
- Changes done in IP.Interface Objects
- Changes done in Ethernet Objects

TODO : Few more deployments needs to be covered. Also to add supoort for
	VLANPort and VLANTermination.
This commit is contained in:
jjoseph 2020-02-18 16:00:01 +05:30
parent 4f8a100d7a
commit 1f3e1d8744
4 changed files with 203 additions and 32 deletions

View file

@ -488,7 +488,8 @@ int get_br_vlan_number_of_entries(char *refparam, struct dmctx *ctx, void *data,
struct uci_section *s = NULL;
int cnt = 0;
uci_path_foreach_option_eq(bbfdm, "dmmap_network", "device", "bridge_key", instance, s) {
/* Fix: Interface section needs to be browsed to get the vlan entries. */
uci_path_foreach_option_eq(bbfdm, "dmmap_network", "interface", "bridge_key", instance, s) {
cnt++;
}
dmasprintf(value, "%d", cnt);
@ -1131,7 +1132,8 @@ int get_br_vlan_alias(char *refparam, struct dmctx *ctx, void *data, char *insta
{
struct uci_section *dmmap_section;
get_dmmap_section_of_config_section("dmmap_network", "device", section_name(((struct bridging_vlan_args *)data)->bridge_vlan_sec), &dmmap_section);
/* Fix: Interface section needs to be browsed to get the value for vlan alias. */
get_dmmap_section_of_config_section("dmmap_network", "interface", section_name(((struct bridging_vlan_args *)data)->bridge_vlan_sec), &dmmap_section);
if (dmmap_section) dmuci_get_value_by_section_string(dmmap_section, "bridge_vlan_alias", value);
return 0;
}
@ -1346,7 +1348,7 @@ int delete_br_port(char *refparam, struct dmctx *ctx, void *data, char *instance
/*************************************************************
* LOWER LAYER
**************************************************************/
int check_port_with_ifname (char *ifname, struct uci_section **ss)
int check_port_with_ifname (char *ifname, struct uci_section **ss, int *is_tag)
{
struct uci_section *sss, *s;
char *file_config_name;
@ -1385,7 +1387,7 @@ int check_port_with_ifname (char *ifname, struct uci_section **ss)
}
}
}
} else if (strncmp(ifname, wan_baseifname, strlen(wan_baseifname)) == 0) {
} else if (strncmp(ifname, wan_baseifname, strlen(ifname)) == 0) {
uci_foreach_option_eq("network", "device", "name", ifname, s) {
*ss = s;
break;
@ -1396,10 +1398,37 @@ int check_port_with_ifname (char *ifname, struct uci_section **ss)
break;
}
} else {
uci_foreach_option_eq("ports", "ethport", "ifname", ifname, s) {
*ss = s;
break;
/* Fix : Add support for untagged interfaces(vlan id =1) in lower layer. */
char intf[50] = {0};
strncpy(intf, ifname, sizeof(intf));
char *p = strstr(intf, ".");
if(p) {
char *token , *end= NULL;
token = strtok_r(intf, ".", &end);
if (NULL != token) {
char tag[50] = {0};
strncpy(tag, end, sizeof(tag));
if (strncmp(tag, "1", sizeof(tag)) == 0) {
uci_foreach_option_eq("network", "device", "name", ifname, s) {
*ss = s;
break;
}
} else {
/* Fix : Add support for tagged interfaces in lower layer. */
uci_foreach_option_eq("ports", "ethport", "ifname", token, s) {
*is_tag = 1;
*ss = s;
break;
}
}
}
} else {
uci_foreach_option_eq("ports", "ethport", "ifname", ifname, s) {
*ss = s;
break;
}
}
}
return 0;
}
@ -1416,7 +1445,9 @@ int get_port_lower_layer(char *refparam, struct dmctx *ctx, void *data, char *in
ifname_dup = dmstrdup(ifname);
p = lbuf;
for (pch = strtok_r(ifname_dup, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch)) {
check_port_with_ifname(pch, &s);
/* Fix: Added support for tagged and untagged interfaces. */
int is_tag = 0;
check_port_with_ifname(pch, &s, &is_tag);
if(s == NULL)
continue;
snprintf(plinker, sizeof(plinker), "%s+%s", section_name(s), pch);
@ -1703,11 +1734,34 @@ int browseBridgePortInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_da
if (((struct bridging_args *)prev_data)->ifname[0] == '\0')
return 0;
ifname_dup = dmstrdup(((struct bridging_args *)prev_data)->ifname);
char tagged_intf[250] = {0};
strncpy(tagged_intf, ifname_dup, sizeof(tagged_intf));
for (pch = strtok_r(ifname_dup, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch)) {
found = false;
if (!found)
found= synchronize_multi_config_sections_with_dmmap_eq("ports", "ethport", "dmmap_bridge_port", "bridge_port", "ifname", pch, pch, &dup_list);
if (!found) {
/* Fix : Add support for untagged interfaces.*/
char val[50] = {0};
strncpy(val, pch, sizeof(val));
char *p = strstr(val, ".");
if (p) {
char *tok, *tok_end;
tok = strtok_r(val, ".", &tok_end);
if (tok != NULL) {
char tag[20] = {0};
strncpy(tag, tok_end, sizeof(tag));
if (strncmp(tag, "1", sizeof(tag)) == 0) {
found= synchronize_multi_config_sections_with_dmmap_eq("network", "device", "dmmap_bridge_port", "bridge_port", "name", pch, pch, &dup_list);
} else {
/* Fix : Add support for tagged interfaces(eth0.100, eth1.200 etc).*/
found= synchronize_multi_config_sections_with_dmmap_eq("ports", "ethport", "dmmap_bridge_port", "bridge_port", "ifname", tok, pch, &dup_list);
}
}
} else {
/* Add support for interfaces eth0, eth1, eth2.....etc.*/
found= synchronize_multi_config_sections_with_dmmap_eq("ports", "ethport", "dmmap_bridge_port", "bridge_port", "ifname", pch, pch, &dup_list);
}
}
if (!found)
found= synchronize_multi_config_sections_with_dmmap_eq("wireless", "wifi-iface", "dmmap_bridge_port", "bridge_port", "ifname", pch, pch, &dup_list);
@ -1763,30 +1817,24 @@ end:
/*#Device.Bridging.Bridge.{i}.VLAN.!UCI:network/device/dmmap_network*/
int browseBridgeVlanInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
{
char *vlan = NULL, *vlan_last = NULL, *type, *is_lan = NULL;
char *vlan = NULL, *vlan_last = NULL;
struct bridging_vlan_args curr_bridging_vlan_args = {0};
struct bridging_args *br_args = (struct bridging_args *)prev_data;
struct dmmap_dup *p;
LIST_HEAD(dup_list);
dmuci_get_value_by_section_string(br_args->bridge_sec, "is_lan", &is_lan);
if (is_lan == NULL || strcmp(is_lan, "1") != 0) {
synchronize_specific_config_sections_with_dmmap("network", "device", "dmmap_network", &dup_list);
list_for_each_entry(p, &dup_list, list) {
if(!p->config_section)
synchronize_specific_config_sections_with_dmmap_vlan("network", "interface", "dmmap_network", br_args->ifname, &dup_list);
list_for_each_entry(p, &dup_list, list) {
if(!p->config_section)
goto end;
dmuci_set_value_by_section(p->dmmap_section, "bridge_key", br_args->br_key);
vlan = handle_update_instance(2, dmctx, &vlan_last, update_instance_alias, 3, p->dmmap_section, "bridge_vlan_instance", "bridge_vlan_alias");
init_bridging_vlan_args(&curr_bridging_vlan_args, p->config_section, br_args->bridge_sec, vlan_last, br_args->br_key);
if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_bridging_vlan_args, vlan) == DM_STOP)
goto end;
//Check if VLAN or NOT
dmuci_get_value_by_section_string(p->config_section, "type", &type);
if (strcmp(type, "untagged") != 0) {
dmuci_set_value_by_section(p->dmmap_section, "bridge_key", br_args->br_key);
vlan = handle_update_instance(2, dmctx, &vlan_last, update_instance_alias, 3, p->dmmap_section, "bridge_vlan_instance", "bridge_vlan_alias");
init_bridging_vlan_args(&curr_bridging_vlan_args, p->config_section, br_args->bridge_sec, vlan_last, br_args->br_key);
if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_bridging_vlan_args, vlan) == DM_STOP)
goto end;
}
}
free_dmmap_config_dup_list(&dup_list);
}
free_dmmap_config_dup_list(&dup_list);
end:
return 0;
}

View file

@ -171,6 +171,24 @@ inline int init_eth_port(struct eth_port_args *args, struct uci_section *s, char
/*************************************************************
* COMMON Functions
**************************************************************/
static int is_device_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;
}
}
}
return 0;
}
static int is_mac_exist(char *macaddr)
{
struct uci_section *s = NULL;
@ -201,6 +219,17 @@ static void create_link(char *ifname)
if (is_mac_exist(macaddr))
return;
/* Fix: For all the Ethernet link objects pointing to same Ethernet Interface,
* we can omit creating multiple Ethernet link entries.*/
char intf[250] = {0};
strncpy(intf, device, sizeof(intf));
char *p = strtok(intf, ".");
if (p != NULL) {
if (is_device_exist(p)) {
return;
}
}
dmuci_add_section_bbfdm(DMMAP, "link", &dmmap, &v);
dmuci_set_value_by_section(dmmap, "mac", macaddr);
dmuci_set_value_by_section(dmmap, "device", device);
@ -210,12 +239,16 @@ static void create_link(char *ifname)
static int dmmap_synchronizeEthernetLink(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
{
struct uci_section *s = NULL;
char *type, *ifname;
char *type, *ifname, *proto;
uci_foreach_sections("network", "interface", s) {
dmuci_get_value_by_section_string(s, "type", &type);
if (strcmp(type, "alias") == 0 || strcmp(section_name(s), "loopback") == 0)
/* Fix: The creating of multiple ethernet links.*/
dmuci_get_value_by_section_string(s, "proto", &proto);
if (strcmp(type, "alias") == 0 || strcmp(section_name(s), "loopback") == 0 ||
*proto == '\0') {
continue;
}
dmuci_get_value_by_section_string(s, "ifname", &ifname);
if (*ifname == '\0' || *ifname == '@')
@ -314,7 +347,8 @@ int get_linker_interface(char *refparam, struct dmctx *dmctx, void *data, char *
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, "section_name", linker);
/* Fix: for get linker link */
dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "mac", linker);
return 0;
}
@ -1207,7 +1241,7 @@ int get_EthernetVLANTermination_LastChange(char *refparam, struct dmctx *ctx, vo
int get_EthernetVLANTermination_LowerLayers(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
char *pch, *spch, *devifname, *ifname, *dupifname;
char *pch, *spch, *devifname, *ifname, *dupifname, *mac;
struct uci_section *section;
dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "name", &devifname);
@ -1216,7 +1250,11 @@ int get_EthernetVLANTermination_LowerLayers(char *refparam, struct dmctx *ctx, v
dupifname = dmstrdup(ifname);
for (pch = strtok_r(dupifname, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch)) {
if(strcmp(pch, devifname) == 0){
adm_entry_get_linker_param(ctx, dm_print_path("%s%cEthernet%cLink%c", dmroot, dm_delim, dm_delim, dm_delim), section_name(section), value);
/* Fix: Use mac address instead of section name for lower layer. */
mac = get_macaddr(section_name(section));
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);
}
break;
}
}

View file

@ -821,6 +821,78 @@ struct uci_section *get_dup_section_in_dmmap_eq(char *dmmap_package, char* secti
return NULL;
}
void synchronize_specific_config_sections_with_dmmap_vlan(char *package, char *section_type, char *dmmap_package, char *ifname, struct list_head *dup_list)
{
struct uci_section *s, *stmp, *dmmap_sect;
FILE *fp;
char *v, *dmmap_file_path;
dmasprintf(&dmmap_file_path, "/etc/bbfdm/%s", dmmap_package);
if (access(dmmap_file_path, F_OK)) {
/*
*File does not exist
**/
fp = fopen(dmmap_file_path, "w"); // new empty file
fclose(fp);
}
uci_foreach_sections(package, section_type, s) {
/*
* create/update corresponding dmmap section that have same config_section link and using param_value_array
*/
if ((dmmap_sect = get_dup_section_in_dmmap(dmmap_package, section_type, section_name(s))) == NULL) {
dmuci_add_section_bbfdm(dmmap_package, section_type, &dmmap_sect, &v);
DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_sect, "section_name", section_name(s));
}
/* Fix : Entry for only VLANS. */
if (strcmp(package, "network") == 0 &&
strcmp(section_type, "interface") == 0 &&
strcmp(dmmap_package, "dmmap_network") == 0) {
char *type, *intf;
dmuci_get_value_by_section_string(s, "type", &type);
dmuci_get_value_by_section_string(s, "ifname", &intf);
if (strcmp(type,"bridge") != 0 || strcmp(intf, ifname) != 0){
continue;
}
}
/* Fix: Vlan object should not be created for transparent bridges. */
int tag = 0;
char name[250] = {0};
strncpy(name, ifname, sizeof(name));
char *p = strtok(name, " ");
while (p != NULL) {
char intf[250] = {0};
strncpy(intf, p, sizeof(intf));
char *find = strstr(intf, ".");
if (find) {
tag = 1;
break;
}
p = strtok(NULL, "");
}
if (tag == 0) {
continue;
}
/*
* Add system and dmmap sections to the list
*/
add_sectons_list_paramameter(dup_list, s, dmmap_sect, NULL);
}
/*
* Delete unused dmmap sections
*/
uci_path_foreach_sections_safe(bbfdm, 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_bbfdm(s, NULL, NULL);
}
}
}
void synchronize_specific_config_sections_with_dmmap(char *package, char *section_type, char *dmmap_package, struct list_head *dup_list)
{
struct uci_section *s, *stmp, *dmmap_sect;
@ -844,6 +916,18 @@ void synchronize_specific_config_sections_with_dmmap(char *package, char *sectio
DMUCI_SET_VALUE_BY_SECTION(bbfdm, dmmap_sect, "section_name", section_name(s));
}
/* Fix : Change to fix multiple IP interface creation. */
if (strcmp(package, "network") == 0 &&
strcmp(section_type, "interface") == 0 &&
strcmp(dmmap_package, "dmmap_network") == 0) {
char *value;
char *type;
dmuci_get_value_by_section_string(s, "proto", &value);
if (*value == '\0') {
continue;
}
}
/*
* Add system and dmmap sections to the list
*/

View file

@ -220,6 +220,7 @@ void hex_to_ip(char *address, char *ret);
void ip_to_hex(char *address, char *ret);
void free_dmmap_config_dup_list(struct list_head *dup_list);
void synchronize_specific_config_sections_with_dmmap(char *package, char *section_type, char *dmmap_package, struct list_head *dup_list);
void synchronize_specific_config_sections_with_dmmap_vlan(char *package, char *section_type, char *dmmap_package, char *ifname, struct list_head *dup_list);
void synchronize_specific_config_sections_with_dmmap_eq(char *package, char *section_type, char *dmmap_package,char* option_name, char* option_value, struct list_head *dup_list);
void synchronize_specific_config_sections_with_dmmap_eq_no_delete(char *package, char *section_type, char *dmmap_package,char* option_name, char* option_value, struct list_head *dup_list);
void synchronize_specific_config_sections_with_dmmap_cont(char *package, char *section_type, char *dmmap_package,char* option_name, char* option_value, struct list_head *dup_list);