/* * 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 * as published by the Free Software Foundation * * Author: Amin Ben Ramdhane */ #include "dmentry.h" #include "interfacestack.h" struct interfacestack_data { char *lowerlayer; char *higherlayer; char *loweralias; char *higheralias; }; /************************************************************* * ENTRY METHOD **************************************************************/ static char *get_instance_by_section(int mode, char *dmmap_config, char *section, char *option, char *value, char *instance_option, char *alias_option) { struct uci_section *dmmap_section; char *instance = ""; get_dmmap_section_of_config_section_eq(dmmap_config, section, option, value, &dmmap_section); if (mode == INSTANCE_MODE_NUMBER) dmuci_get_value_by_section_string(dmmap_section, instance_option, &instance); else dmuci_get_value_by_section_string(dmmap_section, alias_option, &instance); return instance; } static char *get_instance_by_section_option_condition(int mode, char *dmmap_config, char *section, struct uci_section *s, char *option, char *value, char *instance_option, char *alias_option) { struct uci_section *dmmap_section; char *instance = ""; get_dmmap_section_of_config_section_cont(dmmap_config, section, option, value, &dmmap_section); if (mode == INSTANCE_MODE_NUMBER) dmuci_get_value_by_section_string(dmmap_section, instance_option, &instance); else dmuci_get_value_by_section_string(dmmap_section, alias_option, &instance); return instance; } static char *get_alias_by_section(char *dmmap_config, char *section, struct uci_section *s, char *alias_option) { struct uci_section *dmmap_section; char *alias = ""; get_dmmap_section_of_config_section(dmmap_config, section, section_name(s), &dmmap_section); dmuci_get_value_by_section_string(dmmap_section, alias_option, &alias); return alias; } static char *get_alias_by_section_option_condition(char *dmmap_config, char *section, char *option, char *value, char *alias_option) { struct uci_section *dmmap_section; char *alias = ""; get_dmmap_section_of_config_section_cont(dmmap_config, section, option, value, &dmmap_section); dmuci_get_value_by_section_string(dmmap_section, alias_option, &alias); return alias; } static struct uci_section *create_dmmap_interface_stack_section(char *curr_inst) { struct uci_section *s = NULL; uci_path_foreach_option_eq(bbfdm, "dmmap_interface_stack", "interface_stack", "interface_stack_instance", curr_inst, s) { return s; } if (!s) { dmuci_add_section_bbfdm("dmmap_interface_stack", "interface_stack", &s); dmuci_set_value_by_section_bbfdm(s, "interface_stack_instance", curr_inst); } return s; } int browseInterfaceStackInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) { struct interfacestack_data intf_stack_data = {0}; struct uci_section *s = NULL, *dmmap_s = NULL; char *layer_inst = "", *loweralias = "", *higheralias = ""; char *inst = NULL, *max_inst = NULL; char buf_lowerlayer[128] = {0}; char buf_higherlayer[128] = {0}; char buf_higheralias[64] = {0}; char buf_loweralias[64] = {0}; char buf_instance[16] = {0}; int instance = 0; /* Higher layers are Device.IP.Interface.{i}. */ uci_foreach_sections("network", "interface", s) { char *proto, *ifname; dmuci_get_value_by_section_string(s, "proto", &proto); dmuci_get_value_by_section_string(s, "ifname", &ifname); if (strcmp(section_name(s), "loopback") == 0 || *proto == '\0' || strchr(ifname, '@')) continue; // The higher layer is Device.IP.Interface.{i}. layer_inst = get_instance_by_section(dmctx->instance_mode, "dmmap_network", "interface", "section_name", section_name(s), "ip_int_instance", "ip_int_alias"); if (*layer_inst == '\0') continue; snprintf(buf_higherlayer, sizeof(buf_higherlayer), "Device.IP.Interface.%s", layer_inst); higheralias = get_alias_by_section("dmmap_network", "interface", s, "ip_int_alias"); if (*higheralias == '\0') if (*layer_inst == '\0') snprintf(buf_higheralias, sizeof(buf_higheralias), "%s", ""); else snprintf(buf_higheralias, sizeof(buf_higheralias), "cpe-%s", layer_inst); else snprintf(buf_higheralias, sizeof(buf_higheralias), "%s", higheralias); if (strstr(proto, "ppp")) { // The lower layer is Device.PPP.Interface.{i}. layer_inst = get_instance_by_section(dmctx->instance_mode, "dmmap_network", "interface", "section_name", section_name(s), "ppp_int_instance", "ppp_int_alias"); if (*layer_inst == '\0') continue; snprintf(buf_lowerlayer, sizeof(buf_lowerlayer), "Device.PPP.Interface.%s", layer_inst); loweralias = get_alias_by_section("dmmap_network", "interface", s, "ppp_int_alias"); if (*loweralias == '\0') snprintf(buf_loweralias, sizeof(buf_loweralias), "cpe-%s", layer_inst); else snprintf(buf_loweralias, sizeof(buf_loweralias), "%s", loweralias); } else { // The lower layer is Device.Ethernet.VLANTermination.{i}. char *value = NULL; int found = 0; char *device = get_device(section_name(s)); if (device[0] != '\0') { struct uci_section *vlan_sect = NULL; adm_entry_get_linker_param(dmctx, dm_print_path("%s%cEthernet%cVLANTermination%c", dmroot, dm_delim, dm_delim, dm_delim), device, &value); uci_foreach_option_eq("network", "device", "name", device, vlan_sect) { loweralias = get_alias_by_section("dmmap_network", "device", vlan_sect, "vlan_term_alias"); layer_inst = get_instance_by_section(dmctx->instance_mode, "dmmap_network", "device", "section_name", section_name(vlan_sect), "vlan_term_instance", "vlan_term_alias"); break; } if (value != NULL) found = 1; } if (device[0] != '\0' && found == 0) { // The lower layer is Device.Ethernet.Link.{i}. char linker[32] = {0}; strncpy(linker, device, sizeof(linker) - 1); char *vid = strchr(linker, '.'); if (vid) *vid = '\0'; adm_entry_get_linker_param(dmctx, dm_print_path("%s%cEthernet%cLink%c", dmroot, dm_delim, dm_delim, dm_delim), linker, &value); loweralias = get_alias_by_section_option_condition("dmmap", "link", "section_name", section_name(s), "link_alias"); layer_inst = get_instance_by_section_option_condition(dmctx->instance_mode, "dmmap", "link", s, "section_name", section_name(s), "link_instance", "link_alias"); if (value == NULL) value = ""; } snprintf(buf_lowerlayer, sizeof(buf_lowerlayer), "%s", value?value:""); if (*loweralias == '\0') if (*layer_inst == '\0') snprintf(buf_loweralias, sizeof(buf_loweralias), "%s", ""); else snprintf(buf_loweralias, sizeof(buf_loweralias), "cpe-%s", layer_inst); else snprintf(buf_loweralias, sizeof(buf_loweralias), "%s", loweralias); } // fill interface stack data intf_stack_data.higherlayer = buf_higherlayer; intf_stack_data.lowerlayer = buf_lowerlayer; intf_stack_data.higheralias = buf_higheralias; intf_stack_data.loweralias = buf_loweralias; // create dmmap section snprintf(buf_instance, sizeof(buf_instance), "%d", ++instance); dmmap_s = create_dmmap_interface_stack_section(buf_instance); // link instance to interface stack data inst = handle_update_instance(1, dmctx, &max_inst, update_instance_alias, 5, dmmap_s, "interface_stack_instance", "interface_stack_alias", "dmmap_interface_stack", "interface_stack"); if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&intf_stack_data, inst) == DM_STOP) goto end; } /* Higher layers are Device.PPP.Interface.{i}. */ uci_foreach_sections("network", "interface", s) { char *proto; dmuci_get_value_by_section_string(s, "proto", &proto); if (!strstr(proto, "ppp")) continue; // The higher layer is Device.PPP.Interface.{i}. layer_inst = get_instance_by_section(dmctx->instance_mode, "dmmap_network", "interface", "section_name", section_name(s), "ppp_int_instance", "ppp_int_alias"); if (*layer_inst == '\0') continue; snprintf(buf_higherlayer, sizeof(buf_higherlayer), "Device.PPP.Interface.%s", layer_inst); higheralias = get_alias_by_section("dmmap_network", "interface", s, "ppp_int_alias"); if (*higheralias == '\0') if (*layer_inst == '\0') snprintf(buf_higheralias, sizeof(buf_higheralias), "%s", ""); else snprintf(buf_higheralias, sizeof(buf_higheralias), "cpe-%s", layer_inst); else snprintf(buf_higheralias, sizeof(buf_higheralias), "%s", higheralias); char *value = NULL; int found = 0; // The lower layer is Device.Ethernet.VLANTermination.{i}. char *device = get_device(section_name(s)); if (device[0] != '\0') { struct uci_section *vlan_sect = NULL; adm_entry_get_linker_param(dmctx, dm_print_path("%s%cEthernet%cVLANTermination%c", dmroot, dm_delim, dm_delim, dm_delim), device, &value); uci_foreach_option_eq("network", "device", "name", device, vlan_sect) { loweralias = get_alias_by_section("dmmap_network", "device", vlan_sect, "vlan_term_alias"); layer_inst = get_instance_by_section(dmctx->instance_mode, "dmmap_network", "device", "section_name", section_name(vlan_sect), "vlan_term_instance", "vlan_term_alias"); break; } if (value != NULL) found = 1; } if (found == 0) { // The lower layer is Device.Ethernet.Link.{i}. char linker[32] = {0}; strncpy(linker, device, sizeof(linker) - 1); char *vid = strchr(linker, '.'); if (vid) *vid = '\0'; adm_entry_get_linker_param(dmctx, dm_print_path("%s%cEthernet%cLink%c", dmroot, dm_delim, dm_delim, dm_delim), linker, &value); loweralias = get_alias_by_section("dmmap", "link", s, "link_alias"); layer_inst = get_instance_by_section_option_condition(dmctx->instance_mode, "dmmap", "link", s, "section_name", section_name(s), "link_instance", "link_alias"); if (value == NULL) value = ""; } snprintf(buf_lowerlayer, sizeof(buf_lowerlayer), "%s", value); if (*loweralias == '\0') if (*layer_inst == '\0') snprintf(buf_loweralias, sizeof(buf_loweralias), "%s", ""); else snprintf(buf_loweralias, sizeof(buf_loweralias), "cpe-%s", layer_inst); else snprintf(buf_loweralias, sizeof(buf_loweralias), "%s", loweralias); // fill interface stack data intf_stack_data.higherlayer = buf_higherlayer; intf_stack_data.lowerlayer = buf_lowerlayer; intf_stack_data.higheralias = buf_higheralias; intf_stack_data.loweralias = buf_loweralias; // create dmmap section snprintf(buf_instance, sizeof(buf_instance), "%d", ++instance); dmmap_s = create_dmmap_interface_stack_section(buf_instance); // link instance to interface stack data inst = handle_update_instance(1, dmctx, &max_inst, update_instance_alias, 5, dmmap_s, "interface_stack_instance", "interface_stack_alias", "dmmap_interface_stack", "interface_stack"); if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&intf_stack_data, inst) == DM_STOP) goto end; } /* Higher layers are Device.Ethernet.VLANTermination.{i}. */ uci_foreach_sections("network", "device", s) { char *type, *name, *value = NULL; dmuci_get_value_by_section_string(s, "type", &type); dmuci_get_value_by_section_string(s, "name", &name); if (strcmp(type, "untagged") == 0 || (*name != '\0' && !is_vlan_termination_section(name))) continue; // The higher layer is Device.Ethernet.VLANTermination.{i}. layer_inst = get_instance_by_section(dmctx->instance_mode, "dmmap_network", "device", "section_name", section_name(s), "vlan_term_instance", "vlan_term_alias"); if (*layer_inst == '\0') continue; snprintf(buf_higherlayer, sizeof(buf_higherlayer), "Device.Ethernet.VLANTermination.%s", layer_inst); higheralias = get_alias_by_section("dmmap_network", "device", s, "vlan_term_alias"); if (*higheralias == '\0') if (*layer_inst == '\0') snprintf(buf_higheralias, sizeof(buf_higheralias), "%s", ""); else snprintf(buf_higheralias, sizeof(buf_higheralias), "cpe-%s", layer_inst); else snprintf(buf_higheralias, sizeof(buf_higheralias), "%s", higheralias); // The lower layer is Device.Ethernet.Link.{i}. char *vid = strchr(name, '.'); if (vid) *vid = '\0'; adm_entry_get_linker_param(dmctx, dm_print_path("%s%cEthernet%cLink%c", dmroot, dm_delim, dm_delim, dm_delim), name, &value); if (value == NULL) value = ""; struct uci_section *link_s = NULL; get_dmmap_section_of_config_section_eq("dmmap", "link", "device", name, &link_s); dmuci_get_value_by_section_string(link_s, "link_instance", &layer_inst); dmuci_get_value_by_section_string(link_s, "link_alias", &loweralias); snprintf(buf_lowerlayer, sizeof(buf_lowerlayer), "%s", value); if (*loweralias == '\0') if (*layer_inst == '\0') snprintf(buf_loweralias, sizeof(buf_loweralias), "%s", ""); else snprintf(buf_loweralias, sizeof(buf_loweralias), "cpe-%s", layer_inst); else snprintf(buf_loweralias, sizeof(buf_loweralias), "%s", loweralias); // fill interface stack data intf_stack_data.higherlayer = buf_higherlayer; intf_stack_data.lowerlayer = buf_lowerlayer; intf_stack_data.higheralias = buf_higheralias; intf_stack_data.loweralias = buf_loweralias; // create dmmap section snprintf(buf_instance, sizeof(buf_instance), "%d", ++instance); dmmap_s = create_dmmap_interface_stack_section(buf_instance); // link instance to interface stack data inst = handle_update_instance(1, dmctx, &max_inst, update_instance_alias, 5, dmmap_s, "interface_stack_instance", "interface_stack_alias", "dmmap_interface_stack", "interface_stack"); if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&intf_stack_data, inst) == DM_STOP) goto end; } /* Higher layers are Device.Ethernet.Link.{i}. */ uci_path_foreach_sections(bbfdm, DMMAP, "link", s) { // The higher layer is Device.Ethernet.Link.{i}. dmuci_get_value_by_section_string(s, "link_instance", &layer_inst); if (*layer_inst == '\0') continue; snprintf(buf_higherlayer, sizeof(buf_higherlayer), "Device.Ethernet.Link.%s", layer_inst); dmuci_get_value_by_section_string(s, "link_alias", &higheralias); if (*higheralias == '\0') if (*layer_inst == '\0') snprintf(buf_higheralias, sizeof(buf_higheralias), "%s", ""); else snprintf(buf_higheralias, sizeof(buf_higheralias), "cpe-%s", layer_inst); else snprintf(buf_higheralias, sizeof(buf_higheralias), "%s", higheralias); char *linker, *value = NULL; dmuci_get_value_by_section_string(s, "device", &linker); char *bridge = strstr(linker, "br-"); if (bridge) { // The lower layer is Device.Bridging.Bridge.{i}.Port.{i}. char *int_name; dmuci_get_value_by_section_string(s, "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(dmctx, dm_print_path("%s%cBridging%cBridge%c", dmroot, dm_delim, dm_delim, dm_delim), linker, &value); dmuci_get_value_by_section_string(port, "bridge_port_alias", &loweralias); dmuci_get_value_by_section_string(port, "bridge_port_instance", &layer_inst); break; } } } } else { // The lower layer is Device.Ethernet.Interface.{i}. char *vid = strchr(linker, '.'); if (vid) *vid = '\0'; char *macvlan = strchr(linker, '_'); if (macvlan) *macvlan = '\0'; struct uci_section *eth_port_sect = NULL, *eth_port_dmms = NULL; uci_foreach_option_eq("ports", "ethport", "ifname", linker, eth_port_sect) { break; } if (eth_port_sect != NULL) { get_dmmap_section_of_config_section_eq("dmmap_ports", "ethport", "section_name", section_name(eth_port_sect), ð_port_dmms); if (eth_port_dmms) { dmuci_get_value_by_section_string(eth_port_dmms, "eth_port_alias", &loweralias); dmuci_get_value_by_section_string(eth_port_dmms, "eth_port_instance", &layer_inst); } } adm_entry_get_linker_param(dmctx, dm_print_path("%s%cEthernet%cInterface%c", dmroot, dm_delim, dm_delim, dm_delim), linker, &value); } if (value == NULL) value = ""; snprintf(buf_lowerlayer, sizeof(buf_lowerlayer), "%s", value); if (*loweralias == '\0') if (*layer_inst == '\0') snprintf(buf_loweralias, sizeof(buf_loweralias), "%s", ""); else snprintf(buf_loweralias, sizeof(buf_loweralias), "cpe-%s", layer_inst); else snprintf(buf_loweralias, sizeof(buf_loweralias), "%s", loweralias); // fill interface stack data intf_stack_data.higherlayer = buf_higherlayer; intf_stack_data.lowerlayer = buf_lowerlayer; intf_stack_data.higheralias = buf_higheralias; intf_stack_data.loweralias = buf_loweralias; // create dmmap section snprintf(buf_instance, sizeof(buf_instance), "%d", ++instance); dmmap_s = create_dmmap_interface_stack_section(buf_instance); // link instance to interface stack data inst = handle_update_instance(1, dmctx, &max_inst, update_instance_alias, 5, dmmap_s, "interface_stack_instance", "interface_stack_alias", "dmmap_interface_stack", "interface_stack"); if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&intf_stack_data, inst) == DM_STOP) goto end; } /* Higher layers are Device.Bridging.Bridge.{i}.Port.{i}.*/ uci_foreach_sections("network", "interface", s) { char *type; dmuci_get_value_by_section_string(s, "type", &type); if (strcmp(type, "bridge") != 0) continue; char *br_inst = get_instance_by_section(dmctx->instance_mode, "dmmap_network", "interface", "section_name", section_name(s), "bridge_instance", "bridge_alias"); if (*br_inst == '\0') continue; // The higher layer is Device.Bridging.Bridge.{i}.Port.{i}. char *bridge_port_inst, *mg_value = NULL,*value = NULL; char buf_mngr[64] = {0}; struct uci_section *port = NULL; uci_path_foreach_option_eq(bbfdm, "dmmap_bridge_port", "bridge_port", "br_inst", br_inst, port) { char *mg; dmuci_get_value_by_section_string(port, "management", &mg); if (strcmp(mg, "1") == 0) { char *device, linker[512] = {0}; 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(dmctx, dm_print_path("%s%cBridging%cBridge%c", dmroot, dm_delim, dm_delim, dm_delim), linker, &mg_value); dmuci_get_value_by_section_string(port, "bridge_port_alias", &higheralias); dmuci_get_value_by_section_string(port, "bridge_port_instance", &bridge_port_inst); if (*higheralias == '\0') if (*bridge_port_inst == '\0') snprintf(buf_mngr, sizeof(buf_mngr), "%s", ""); else snprintf(buf_mngr, sizeof(buf_mngr), "cpe-%s", bridge_port_inst); else snprintf(buf_mngr, sizeof(buf_mngr), "%s", higheralias); if (mg_value == NULL) mg_value = ""; break; } } struct uci_section *sd = NULL; uci_path_foreach_option_eq(bbfdm, "dmmap_bridge_port", "bridge_port", "br_inst", br_inst, sd) { char *mg; dmuci_get_value_by_section_string(sd, "management", &mg); if (strcmp(mg, "1") == 0) continue; char *vb = NULL, *device, linker[512] = {0}; dmuci_get_value_by_section_string(sd, "device", &device); // The lower layer is Device.Bridging.Bridge.{i}.Port.{i}. snprintf(linker, sizeof(linker), "br_%s:%s+%s", br_inst, section_name(sd), device); adm_entry_get_linker_param(dmctx, dm_print_path("%s%cBridging%cBridge%c", dmroot, dm_delim, dm_delim, dm_delim), linker, &vb); if (vb == NULL) vb = ""; dmuci_get_value_by_section_string(sd, "bridge_port_alias", &loweralias); dmuci_get_value_by_section_string(sd, "bridge_port_instance", &bridge_port_inst); if (*loweralias == '\0') if (*bridge_port_inst == '\0') snprintf(buf_loweralias, sizeof(buf_loweralias), "%s", ""); else snprintf(buf_loweralias, sizeof(buf_loweralias), "cpe-%s", bridge_port_inst); else snprintf(buf_loweralias, sizeof(buf_loweralias), "%s", loweralias); // fill interface stack data intf_stack_data.higherlayer = mg_value; intf_stack_data.lowerlayer = vb; intf_stack_data.higheralias = buf_mngr; intf_stack_data.loweralias = buf_loweralias; // create dmmap section snprintf(buf_instance, sizeof(buf_instance), "%d", ++instance); dmmap_s = create_dmmap_interface_stack_section(buf_instance); // link instance to interface stack data inst = handle_update_instance(1, dmctx, &max_inst, update_instance_alias, 5, dmmap_s, "interface_stack_instance", "interface_stack_alias", "dmmap_interface_stack", "interface_stack"); if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&intf_stack_data, inst) == DM_STOP) goto end; if (*loweralias == '\0') if (*bridge_port_inst == '\0') snprintf(buf_higheralias, sizeof(buf_higheralias), "%s", ""); else snprintf(buf_higheralias, sizeof(buf_higheralias), "cpe-%s", bridge_port_inst); else snprintf(buf_higheralias, sizeof(buf_higheralias), "%s", loweralias); char package[32] = {0}; int found = 0; // The lower layer is Device.Ethernet.Interface.{i}. adm_entry_get_linker_param(dmctx, dm_print_path("%s%cEthernet%cInterface%c", dmroot, dm_delim, dm_delim, dm_delim), device, &value); if (value != NULL) { strncpy(package, "ports", sizeof(package) - 1); struct uci_section *port_s = NULL; uci_foreach_option_eq("ports", "ethport", "ifname", device, port_s) { loweralias = get_alias_by_section("dmmap_ports", "ethport", port_s, "eth_port_alias"); bridge_port_inst = get_instance_by_section(dmctx->instance_mode, "dmmap_ports", "ethport", "section_name", section_name(port_s), "eth_port_instance", "eth_port_alias"); break; } found = 1; } // The lower layer is Device.WiFi.SSID.{i}. if (!found && value == NULL) adm_entry_get_linker_param(dmctx,dm_print_path("%s%cWiFi%cSSID%c", dmroot, dm_delim, dm_delim, dm_delim), device, &value); if (!found && value != NULL) { strncpy(package, "wireless", sizeof(package) - 1); struct uci_section *wl_s = NULL; uci_foreach_option_eq("wireless", "wifi-iface", "ifname", device, wl_s) { loweralias = get_alias_by_section("dmmap_wireless", "wifi-iface", wl_s, "ssidalias"); bridge_port_inst = get_instance_by_section(dmctx->instance_mode, "dmmap_wireless", "wifi-iface", "section_name", section_name(wl_s), "ssidinstance", "ssidalias"); break; } found = 1; } // The lower layer is Device.ATM.Link.{i}. if (!found && value == NULL) { char *tag = strchr(device, '.'); if (tag) *tag = '\0'; adm_entry_get_linker_param(dmctx,dm_print_path("%s%cATM%cLink%c", dmroot, dm_delim, dm_delim, dm_delim), device, &value); } if (!found && value != NULL) { strncpy(package, "dsl:atm", sizeof(package) - 1); struct uci_section *dsl_s = NULL; uci_foreach_option_eq("dsl", "atm-device", "device", device, dsl_s) { loweralias = get_alias_by_section("dmmap_dsl", "atm-device", dsl_s, "atmlinkalias"); bridge_port_inst = get_instance_by_section(dmctx->instance_mode, "dmmap_dsl", "atm-device", "section_name", section_name(dsl_s), "atmlinkinstance", "atmlinkalias"); break; } found = 1; } // The lower layer is Device.PTM.Link.{i}. if (!found && value == NULL) { char *tag = strchr(device, '.'); if (tag) *tag = '\0'; adm_entry_get_linker_param(dmctx,dm_print_path("%s%cPTM%cLink%c", dmroot, dm_delim, dm_delim, dm_delim), device, &value); } if (!found && value != NULL) { strncpy(package, "dsl:ptm", sizeof(package) - 1); struct uci_section *dsl_s = NULL; uci_foreach_option_eq("dsl", "ptm-device", "device", device, dsl_s) { loweralias = get_alias_by_section("dmmap_dsl", "ptm-device", dsl_s, "ptmlinkalias"); bridge_port_inst = get_instance_by_section(dmctx->instance_mode, "dmmap_dsl", "ptm-device", "section_name", section_name(dsl_s), "ptmlinkinstance", "ptmlinkalias"); break; } found = 1; } // The lower layer is Device.Ethernet.Interface.{i}. if (!found && value == NULL) { char *tag = strchr(device, '.'); if (tag) *tag = '\0'; adm_entry_get_linker_param(dmctx, dm_print_path("%s%cEthernet%cInterface%c", dmroot, dm_delim, dm_delim, dm_delim), device, &value); } if (!found && value != NULL) { strncpy(package, "ports", sizeof(package) - 1); struct uci_section *port_s = NULL; uci_foreach_option_eq("ports", "ethport", "ifname", device, port_s) { loweralias = get_alias_by_section("dmmap_ports", "ethport", port_s, "eth_port_alias"); bridge_port_inst = get_instance_by_section(dmctx->instance_mode, "dmmap_ports", "ethport", "section_name", section_name(port_s), "eth_port_instance", "eth_port_alias"); break; } } if (*loweralias == '\0') if (*bridge_port_inst == '\0') snprintf(buf_loweralias, sizeof(buf_loweralias), "%s", ""); else snprintf(buf_loweralias, sizeof(buf_loweralias), "cpe-%s", bridge_port_inst); else snprintf(buf_loweralias, sizeof(buf_loweralias), "%s", loweralias); if (value == NULL) value = ""; // fill interface stack data intf_stack_data.higherlayer = vb; intf_stack_data.lowerlayer = value; intf_stack_data.higheralias = buf_higheralias; intf_stack_data.loweralias = buf_loweralias; // create dmmap section snprintf(buf_instance, sizeof(buf_instance), "%d", ++instance); dmmap_s = create_dmmap_interface_stack_section(buf_instance); // link instance to interface stack data inst = handle_update_instance(1, dmctx, &max_inst, update_instance_alias, 5, dmmap_s, "interface_stack_instance", "interface_stack_alias", "dmmap_interface_stack", "interface_stack"); if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&intf_stack_data, inst) == DM_STOP) goto end; // The lower layer is Device.WiFi.Radio.{i}. if(strcmp(package, "wireless") == 0) { if (*loweralias == '\0') if (*bridge_port_inst == '\0') snprintf(buf_higheralias, sizeof(buf_higheralias), "%s", ""); else snprintf(buf_higheralias, sizeof(buf_higheralias), "cpe-%s", bridge_port_inst); else snprintf(buf_higheralias, sizeof(buf_higheralias), "%s", loweralias); struct uci_section *wl_s = NULL; char *wl_device; uci_foreach_option_eq("wireless", "wifi-iface", "ifname", device, wl_s) { dmuci_get_value_by_section_string(wl_s, "device", &wl_device); break; } if (wl_device[0] != '\0') { adm_entry_get_linker_param(dmctx, dm_print_path("%s%cWiFi%cRadio%c", dmroot, dm_delim, dm_delim, dm_delim), wl_device, &vb); struct uci_section *ss = NULL; uci_foreach_sections("wireless", "wifi-device", ss) { if(strcmp(section_name(ss), device) == 0) { loweralias = get_alias_by_section("dmmap_wireless", "wifi-device", ss, "radioalias"); bridge_port_inst = get_instance_by_section(dmctx->instance_mode, "dmmap_wireless", "wifi-device", "section_name", section_name(ss), "radioinstance", "radioalias"); break; } } } if (vb == NULL) vb = ""; if (*loweralias == '\0') if (*bridge_port_inst == '\0') snprintf(buf_loweralias, sizeof(buf_loweralias), "%s", ""); else snprintf(buf_loweralias, sizeof(buf_loweralias), "cpe-%s", bridge_port_inst); else snprintf(buf_loweralias, sizeof(buf_loweralias), "%s", loweralias); // fill interface stack data intf_stack_data.higherlayer = value; intf_stack_data.lowerlayer = vb; intf_stack_data.higheralias = buf_higheralias; intf_stack_data.loweralias = buf_loweralias; // create dmmap section snprintf(buf_instance, sizeof(buf_instance), "%d", ++instance); dmmap_s = create_dmmap_interface_stack_section(buf_instance); // link instance to interface stack data inst = handle_update_instance(1, dmctx, &max_inst, update_instance_alias, 5, dmmap_s, "interface_stack_instance", "interface_stack_alias", "dmmap_interface_stack", "interface_stack"); if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&intf_stack_data, inst) == DM_STOP) goto end; } // The lower layer is Device.DSL.Channel.{i}. if(strcmp(package, "dsl:atm") == 0) { if (*loweralias == '\0') if (*bridge_port_inst == '\0') snprintf(buf_higheralias, sizeof(buf_higheralias), "%s", ""); else snprintf(buf_higheralias, sizeof(buf_higheralias), "cpe-%s", bridge_port_inst); else snprintf(buf_higheralias, sizeof(buf_higheralias), "%s", loweralias); char *link_channel = "channel_0"; adm_entry_get_linker_param(dmctx, dm_print_path("%s%cDSL%cChannel%c", dmroot, dm_delim, dm_delim, dm_delim), link_channel, &vb); if (vb == NULL) vb = ""; struct uci_section *dsl_s = NULL; uci_path_foreach_sections(bbfdm, "dmmap", "dsl_channel", dsl_s) { dmuci_get_value_by_section_string(dsl_s, "dsl_channel_alias", &loweralias); bridge_port_inst = get_instance_by_section(dmctx->instance_mode, "dmmap", "dsl_channel", "section_name", section_name(dsl_s), "dsl_channel_instance", "dsl_channel_alias"); } if (*loweralias == '\0') if (*bridge_port_inst == '\0') snprintf(buf_loweralias, sizeof(buf_loweralias), "%s", ""); else snprintf(buf_loweralias, sizeof(buf_loweralias), "cpe-%s", bridge_port_inst); else snprintf(buf_loweralias, sizeof(buf_loweralias), "%s", loweralias); // fill interface stack data intf_stack_data.higherlayer = value; intf_stack_data.lowerlayer = vb; intf_stack_data.higheralias = buf_higheralias; intf_stack_data.loweralias = buf_loweralias; // create dmmap section snprintf(buf_instance, sizeof(buf_instance), "%d", ++instance); dmmap_s = create_dmmap_interface_stack_section(buf_instance); // link instance to interface stack data inst = handle_update_instance(1, dmctx, &max_inst, update_instance_alias, 5, dmmap_s, "interface_stack_instance", "interface_stack_alias", "dmmap_interface_stack", "interface_stack"); if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&intf_stack_data, inst) == DM_STOP) goto end; } // The lower layer is Device.DSL.Line.{i}. if(strcmp(package, "dsl:ptm") == 0) { if (*loweralias == '\0') if (*bridge_port_inst == '\0') snprintf(buf_higheralias, sizeof(buf_higheralias), "%s", ""); else snprintf(buf_higheralias, sizeof(buf_higheralias), "cpe-%s", bridge_port_inst); else snprintf(buf_higheralias, sizeof(buf_higheralias), "%s", loweralias); char *link_line = "line_0"; adm_entry_get_linker_param(dmctx, dm_print_path("%s%cDSL%cLine%c", dmroot, dm_delim, dm_delim, dm_delim), link_line, &value); if (value == NULL) value = ""; struct uci_section *dsl_s = NULL; uci_path_foreach_sections(bbfdm, "dmmap", "dsl_line", dsl_s) { dmuci_get_value_by_section_string(dsl_s, "dsl_line_alias", &loweralias); bridge_port_inst = get_instance_by_section(dmctx->instance_mode, "dmmap", "dsl_line", "id", "0", "dsl_line_instance", "dsl_line_alias"); } if (*loweralias == '\0') if (*bridge_port_inst == '\0') snprintf(buf_loweralias, sizeof(buf_loweralias), "%s", ""); else snprintf(buf_loweralias, sizeof(buf_loweralias), "cpe-%s", bridge_port_inst); else snprintf(buf_loweralias, sizeof(buf_loweralias), "%s", loweralias); // fill interface stack data intf_stack_data.higherlayer = vb; intf_stack_data.lowerlayer = value; intf_stack_data.higheralias = buf_higheralias; intf_stack_data.loweralias = buf_loweralias; // create dmmap section snprintf(buf_instance, sizeof(buf_instance), "%d", ++instance); dmmap_s = create_dmmap_interface_stack_section(buf_instance); // link instance to interface stack data inst = handle_update_instance(1, dmctx, &max_inst, update_instance_alias, 5, dmmap_s, "interface_stack_instance", "interface_stack_alias", "dmmap_interface_stack", "interface_stack"); if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&intf_stack_data, inst) == DM_STOP) goto end; } } } end: return 0; } /************************************************************* * GET & SET PARAM **************************************************************/ int get_Device_InterfaceStackNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { struct uci_section *s = NULL; int cnt = 0; uci_path_foreach_sections(bbfdm, "dmmap_interface_stack", "interface_stack", s) { cnt++; } dmasprintf(value, "%d", cnt); return 0; } static int get_InterfaceStack_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { struct uci_section *s = NULL; uci_path_foreach_option_eq(bbfdm, "dmmap_interface_stack", "interface_stack", "interface_stack_instance", instance, s) { dmuci_get_value_by_section_string(s, "interface_stack_alias", value); if ((*value)[0] == '\0') dmasprintf(value, "cpe-%s", instance); } return 0; } static int set_InterfaceStack_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { struct uci_section *s = NULL; switch (action) { case VALUECHECK: if (dm_validate_string(value, -1, 64, NULL, 0, NULL, 0)) return FAULT_9007; break; case VALUESET: uci_path_foreach_option_eq(bbfdm, "dmmap_interface_stack", "interface_stack", "interface_stack_instance", instance, s) dmuci_set_value_by_section(s, "interface_stack_alias", value); break; } return 0; } static int get_InterfaceStack_HigherLayer(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { *value = dmstrdup(((struct interfacestack_data *)data)->higherlayer); return 0; } static int get_InterfaceStack_LowerLayer(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { *value = dmstrdup(((struct interfacestack_data *)data)->lowerlayer); return 0; } static int get_InterfaceStack_HigherAlias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { *value = dmstrdup(((struct interfacestack_data *)data)->higheralias); return 0; } static int get_InterfaceStack_LowerAlias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { *value = dmstrdup(((struct interfacestack_data *)data)->loweralias); return 0; } /* *** Device.InterfaceStack.{i}. *** */ DMLEAF tInterfaceStackParams[] = { /* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/ {"Alias", &DMWRITE, DMT_STRING, get_InterfaceStack_Alias, set_InterfaceStack_Alias, BBFDM_BOTH}, {"HigherLayer", &DMREAD, DMT_STRING, get_InterfaceStack_HigherLayer, NULL, BBFDM_BOTH}, {"LowerLayer", &DMREAD, DMT_STRING, get_InterfaceStack_LowerLayer, NULL, BBFDM_BOTH}, {"HigherAlias", &DMREAD, DMT_STRING, get_InterfaceStack_HigherAlias, NULL, BBFDM_BOTH}, {"LowerAlias", &DMREAD, DMT_STRING, get_InterfaceStack_LowerAlias, NULL, BBFDM_BOTH}, {0} };