diff --git a/dmtree/tr181/ethernet.c b/dmtree/tr181/ethernet.c index a3821eba..fb662e7c 100644 --- a/dmtree/tr181/ethernet.c +++ b/dmtree/tr181/ethernet.c @@ -167,6 +167,7 @@ static void add_new_dmmap_section(char *macaddr, char*interface, char *section_n dmuci_add_section_bbfdm(DMMAP, "link", &dmmap); dmuci_set_value_by_section(dmmap, "mac", macaddr); dmuci_set_value_by_section(dmmap, "device", interface); + dmuci_set_value_by_section(dmmap, "is_eth", (!strncmp(interface, "atm", 3) || !strncmp(interface, "ptm", 3)) ? "0" : "1"); dmuci_set_value_by_section(dmmap, "section_name", section_name); } @@ -975,6 +976,14 @@ static int get_EthernetLink_LowerLayers(char *refparam, struct dmctx *ctx, void if (!linker || *linker == '\0') return 0; + adm_entry_get_linker_param(ctx, "Device.ATM.Link.", linker, value); + if (*value != NULL && (*value)[0] != 0) + return 0; + + adm_entry_get_linker_param(ctx, "Device.PTM.Link.", linker, value); + if (*value != NULL && (*value)[0] != 0) + return 0; + // get device section mapped to this device name struct uci_section *br_device_s = ethernet___get_device_section(linker); @@ -1028,18 +1037,39 @@ static int set_EthernetLink_LowerLayers(char *refparam, struct dmctx *ctx, void if (!link_linker || link_linker[0] == 0) { dmuci_set_value_by_section((struct uci_section *)data, "device", ""); - } else if (strncmp(value, eth_interface, strlen(eth_interface)) == 0) { - struct uci_section *s = NULL; - char *int_name = NULL; + } else if (strncmp(value, eth_interface, strlen(eth_interface)) == 0 || + strncmp(value, atm_link, strlen(atm_link)) == 0 || + strncmp(value, ptm_link, strlen(ptm_link)) == 0) { + + char *iface_name = NULL; dmuci_set_value_by_section((struct uci_section *)data, "device", link_linker); - dmuci_get_value_by_section_string((struct uci_section *)data, "section_name", &int_name); + dmuci_set_value_by_section((struct uci_section *)data, "is_eth", !strncmp(value, eth_interface, strlen(eth_interface)) ? "1" : "0"); - uci_foreach_sections("network", "interface", s) { - if (strcmp(section_name(s), int_name) == 0) { + // Check if there is a IP.Interface linked to this Ethernet.Link + dmuci_get_value_by_section_string((struct uci_section *)data, "section_name", &iface_name); + if (DM_STRLEN(iface_name)) { + struct uci_section *s = get_origin_section_from_config("network", "interface", iface_name); + dmuci_set_value_by_section(s, "device", link_linker); + } + + // Check if there is a PPP.Interface linked to this Ethernet.Link + struct uci_section *ppp_s = get_dup_section_in_dmmap_opt("dmmap_ppp", "interface", "device", link_linker); + if (ppp_s == NULL) { + char *default_linker = NULL; + + dmuci_get_value_by_section_string((struct uci_section *)data, "linker", &default_linker); + ppp_s = get_dup_section_in_dmmap_opt("dmmap_ppp", "interface", "eth_link_linker", default_linker); + } + + if (ppp_s) { + dmuci_get_value_by_section_string(ppp_s, "iface_name", &iface_name); + if (DM_STRLEN(iface_name)) { + struct uci_section *s = get_origin_section_from_config("network", "interface", iface_name); dmuci_set_value_by_section(s, "device", link_linker); - break; } + + dmuci_set_value_by_section(ppp_s, "device", link_linker); } } else if (strncmp(value, bridge_port, strlen(bridge_port)) == 0) { char br_linker[250] = {0}; @@ -1109,6 +1139,8 @@ static int set_EthernetLink_LowerLayers(char *refparam, struct dmctx *ctx, void dmuci_set_value_by_section((struct uci_section *)data, "device", device_name ? device_name : ""); } + + dmuci_set_value_by_section((struct uci_section *)data, "is_eth", "1"); } } break; @@ -1353,9 +1385,13 @@ static int set_EthernetVLANTermination_LowerLayers(char *refparam, struct dmctx } else if (strncmp(value, eth_link, strlen(eth_link)) == 0) { char new_name[16] = {0}, *type; char *iface_name = NULL; + char *old_name = NULL; + char *vid = NULL; - // Get type option from device section + // Get type, name and vid options from the current device section dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "type", &type); + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "name", &old_name); + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "vid", &vid); if ((strcmp(type, "macvlan") == 0)) { /* type == macvlan */ @@ -1382,10 +1418,7 @@ static int set_EthernetVLANTermination_LowerLayers(char *refparam, struct dmctx } else { /* type != macvlan */ struct uci_section *s = NULL; - char *vid = NULL, *old_name = NULL; - dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "name", &old_name); - dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "vid", &vid); if (vid && *vid != '\0') snprintf(new_name, sizeof(new_name), "%s.%s", vlan_linker, vid); else @@ -1404,7 +1437,7 @@ static int set_EthernetVLANTermination_LowerLayers(char *refparam, struct dmctx } } - // Update interface->device option linked to this VLANTermination if exists + // Check if there is an IP.Interface linked to this VLANTermination dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->dmmap_section, "iface_name", &iface_name); if (iface_name && *iface_name != 0) { struct uci_section *s = get_origin_section_from_config("network", "interface", iface_name); @@ -1412,6 +1445,27 @@ static int set_EthernetVLANTermination_LowerLayers(char *refparam, struct dmctx dmuci_set_value_by_section(((struct dmmap_dup *)data)->dmmap_section, "iface_name", ""); } + // Check if there is a PPP.Interface linked to this VLANTermination + if (old_name && *old_name != 0) { + struct uci_section *ppp_s = get_dup_section_in_dmmap_opt("dmmap_ppp", "interface", "device", old_name); + if (ppp_s == NULL) { + char *default_linker = NULL; + + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->dmmap_section, "default_linker", &default_linker); + ppp_s = get_dup_section_in_dmmap_opt("dmmap_ppp", "interface", "vlan_ter_linker", default_linker); + } + + if (ppp_s) { + dmuci_get_value_by_section_string(ppp_s, "iface_name", &iface_name); + if (DM_STRLEN(iface_name)) { + struct uci_section *s = get_origin_section_from_config("network", "interface", iface_name); + dmuci_set_value_by_section(s, "device", new_name); + } + + dmuci_set_value_by_section(ppp_s, "device", new_name); + } + } + // Set ifname and name options of device section dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "ifname", vlan_linker); dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "name", new_name); diff --git a/dmtree/tr181/ip.c b/dmtree/tr181/ip.c index 142dff49..6c216551 100644 --- a/dmtree/tr181/ip.c +++ b/dmtree/tr181/ip.c @@ -10,6 +10,7 @@ * */ +#include "ppp.h" #include "ip.h" #include "dmentry.h" #ifdef BBF_TR143 @@ -315,6 +316,7 @@ static int delete_ip_intertace_instance(struct uci_section *s) struct uci_section *ss = NULL; struct uci_section *stmp = NULL; char *int_device = NULL; + char *proto = NULL; dmuci_get_value_by_section_string(int_ss, "device", &int_device); if (strcmp(section_name(int_ss), int_sec_name) != 0 && strcmp(int_device, buf) != 0) @@ -364,20 +366,20 @@ static int delete_ip_intertace_instance(struct uci_section *s) dmuci_delete_by_section(ss, NULL, NULL); } - /* Remove "DHCPv4.Client.{i}.ReqOption." sections related to this "IP.Interface." object */ - uci_path_foreach_option_eq_safe(bbfdm, "dmmap_dhcp_client", "req_option", "section_name", section_name(int_ss), stmp, ss) { - dmuci_delete_by_section(ss, NULL, NULL); - } + dmuci_get_value_by_section_string(int_ss, "proto", &proto); - /* Remove "DHCPv4.Client.{i}.SentOption." sections related to this "IP.Interface." object */ - uci_path_foreach_option_eq_safe(bbfdm, "dmmap_dhcp_client", "send_option", "section_name", section_name(int_ss), stmp, ss) { - dmuci_delete_by_section(ss, NULL, NULL); + if (strncmp(proto, "ppp", 3) == 0) { + struct uci_section *ppp_s = get_dup_section_in_dmmap_opt("dmmap_ppp", "interface", "iface_name", section_name(int_ss)); + + if (ppp_s) { + + /* Remove "PPP.Interface." section related to this "IP.Interface." object */ + dmuci_delete_by_section(ppp_s, NULL, NULL); + } } /* remove interface section */ dmuci_delete_by_section(int_ss, NULL, NULL); - - } return 0; } @@ -1246,7 +1248,7 @@ static int get_IPInterface_LowerLayers(char *refparam, struct dmctx *ctx, void * char *proto; dmuci_get_value_by_section_string((struct uci_section *)data, "proto", &proto); - if (strstr(proto, "ppp")) { + if (strncmp(proto, "ppp", 3) == 0) { snprintf(linker, sizeof(linker), "%s", section_name((struct uci_section *)data)); adm_entry_get_linker_param(ctx, "Device.PPP.Interface.", linker, value); if (*value != NULL && (*value)[0] != 0) @@ -1293,9 +1295,11 @@ static int set_IPInterface_LowerLayers(char *refparam, struct dmctx *ctx, void * struct uci_section *dmmap_section = NULL; char eth_vlan_term[64] = "Device.Ethernet.VLANTermination."; char eth_link[32] = "Device.Ethernet.Link."; + char ppp_iface[32] = "Device.PPP.Interface."; char *allowed_objects[] = { eth_vlan_term, eth_link, + ppp_iface, NULL}; char linker_buf[32] = {0}; char *ip_linker = NULL; @@ -1317,8 +1321,21 @@ static int set_IPInterface_LowerLayers(char *refparam, struct dmctx *ctx, void * dmuci_set_value_by_section(dmmap_section, "LowerLayers", value); if (!ip_linker || *ip_linker == 0) { + char *curr_proto = NULL; + // Update device option dmuci_set_value_by_section((struct uci_section *)data, "device", ""); + + dmuci_get_value_by_section_string((struct uci_section *)data, "proto", &curr_proto); + if (strncmp(curr_proto, "ppp", 3) == 0) { + struct uci_section *ppp_s = NULL; + + ppp_s = get_dup_section_in_dmmap_opt("dmmap_ppp", "interface", "iface_name", section_name((struct uci_section *)data)); + dmuci_set_value_by_section_bbfdm(ppp_s, "iface_name", ""); + + dmuci_set_value_by_section((struct uci_section *)data, "proto", "none"); + ppp___reset_options((struct uci_section *)data); + } return 0; } @@ -1436,6 +1453,17 @@ static int set_IPInterface_LowerLayers(char *refparam, struct dmctx *ctx, void * set_ip_interface_device_option((struct uci_section *)data, linker_buf, instance, is_br_sec); } + } else if (strncmp(value, ppp_iface, strlen(ppp_iface)) == 0) { + struct uci_section *ppp_s = get_dup_section_in_dmmap_opt("dmmap_ppp", "interface", "name", linker_buf); + if (ppp_s == NULL) + ppp_s = get_dup_section_in_dmmap_opt("dmmap_ppp", "interface", "iface_name", linker_buf); + + if (ppp_s == NULL) + break; + + dmuci_set_value_by_section_bbfdm(ppp_s, "iface_name", section_name((struct uci_section *)data)); + + ppp___update_sections(ppp_s, (struct uci_section *)data); } break; } diff --git a/dmtree/tr181/ppp.c b/dmtree/tr181/ppp.c index bca13c47..3156aa10 100644 --- a/dmtree/tr181/ppp.c +++ b/dmtree/tr181/ppp.c @@ -12,28 +12,127 @@ #include "dmentry.h" #include "ppp.h" +struct ppp_args +{ + struct uci_section *iface_s; + struct uci_section *dmmap_s; +}; + +/************************************************************* +* COMMON FUNCTIONS +**************************************************************/ +void ppp___update_sections(struct uci_section *s_from, struct uci_section *s_to) +{ + char *proto = NULL; + char *device = NULL; + char *username = NULL; + char *password = NULL; + char *pppd_options = NULL; + char *service = NULL; + char *ac = NULL; + + dmuci_get_value_by_section_string(s_from, "proto", &proto); + dmuci_get_value_by_section_string(s_from, "device", &device); + dmuci_get_value_by_section_string(s_from, "username", &username); + dmuci_get_value_by_section_string(s_from, "password", &password); + dmuci_get_value_by_section_string(s_from, "pppd_options", &pppd_options); + dmuci_get_value_by_section_string(s_from, "service", &service); + dmuci_get_value_by_section_string(s_from, "ac", &ac); + + dmuci_set_value_by_section(s_to, "proto", proto); + dmuci_set_value_by_section(s_to, "device", device); + dmuci_set_value_by_section(s_to, "username", username); + dmuci_set_value_by_section(s_to, "password", password); + dmuci_set_value_by_section(s_to, "pppd_options", pppd_options); + dmuci_set_value_by_section(s_to, "service", service); + dmuci_set_value_by_section(s_to, "ac", ac); +} + +void ppp___reset_options(struct uci_section *ppp_s) +{ + dmuci_set_value_by_section(ppp_s, "device", ""); + dmuci_set_value_by_section(ppp_s, "username", ""); + dmuci_set_value_by_section(ppp_s, "password", ""); + dmuci_set_value_by_section(ppp_s, "pppd_options", ""); + dmuci_set_value_by_section(ppp_s, "service", ""); + dmuci_set_value_by_section(ppp_s, "ac", ""); +} + +static bool is_ppp_section_exist(char *sec_name) +{ + struct uci_section *s = NULL; + + uci_path_foreach_option_eq(bbfdm, "dmmap_ppp", "interface", "iface_name", sec_name, s) { + return true; + } + + return false; +} + +static void dmmap_synchronizePPPInterface(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) +{ + struct uci_section *s = NULL, *stmp = NULL; + + uci_path_foreach_sections_safe(bbfdm, "dmmap_ppp", "interface", stmp, s) { + struct uci_section *iface_s = NULL; + char *added_by_controller = NULL; + char *iface_name = NULL; + + dmuci_get_value_by_section_string(s, "added_by_controller", &added_by_controller); + if (strcmp(added_by_controller, "1") == 0) + continue; + + dmuci_get_value_by_section_string(s, "iface_name", &iface_name); + if (DM_STRLEN(iface_name)) + get_config_section_of_dmmap_section("network", "interface", iface_name, &iface_s); + + if (!iface_s) + dmuci_delete_by_section(s, NULL, NULL); + } + + uci_foreach_sections("network", "interface", s) { + struct uci_section *ppp_s = NULL; + char *proto = NULL; + + dmuci_get_value_by_section_string(s, "proto", &proto); + if (strncmp(proto, "ppp", 3) != 0) + continue; + + if (is_ppp_section_exist(section_name(s))) + continue; + + dmuci_add_section_bbfdm("dmmap_ppp", "interface", &ppp_s); + dmuci_set_value_by_section(ppp_s, "iface_name", section_name(s)); + ppp___update_sections(s, ppp_s); + } +} + /************************************************************* * ENTRY METHOD **************************************************************/ -/*#Device.PPP.Interface.{i}.!UCI:network/interface/dmmap_network*/ static int browseInterfaceInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) { - char *inst = NULL, *proto; - struct dmmap_dup *p = NULL; - LIST_HEAD(dup_list); + struct ppp_args curr_ppp_args = {0}; + struct uci_section *s = NULL; + char *inst = NULL; - synchronize_specific_config_sections_with_dmmap("network", "interface", "dmmap_network", &dup_list); - list_for_each_entry(p, &dup_list, list) { - dmuci_get_value_by_section_string(p->config_section, "proto", &proto); - if (!strstr(proto, "ppp")) - continue; + dmmap_synchronizePPPInterface(dmctx, parent_node, prev_data, prev_instance); + uci_path_foreach_sections(bbfdm, "dmmap_ppp", "interface", s) { + struct uci_section *iface_s = NULL; + char *iface_name = NULL; - inst = handle_instance(dmctx, parent_node, p->dmmap_section, "ppp_int_instance", "ppp_int_alias"); + dmuci_get_value_by_section_string(s, "iface_name", &iface_name); + if (DM_STRLEN(iface_name)) + get_config_section_of_dmmap_section("network", "interface", iface_name, &iface_s); - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)p, inst) == DM_STOP) + curr_ppp_args.iface_s = iface_s; + curr_ppp_args.dmmap_s = s; + + inst = handle_instance(dmctx, parent_node, s, "ppp_int_instance", "ppp_int_alias"); + + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_ppp_args, inst) == DM_STOP) break; } - free_dmmap_config_dup_list(&dup_list); return 0; } @@ -43,16 +142,15 @@ static int browseInterfaceInst(struct dmctx *dmctx, DMNODE *parent_node, void *p static int add_ppp_interface(char *refparam, struct dmctx *ctx, void *data, char **instance) { struct uci_section *dmmap_ppp = NULL; - char name[16] = {0}; + char name[8] = {0}; snprintf(name, sizeof(name), "ppp_%s", *instance); - dmuci_set_value("network", name, "", "interface"); - dmuci_set_value("network", name, "proto", "ppp"); - dmuci_set_value("network", name, "disabled", "1"); - - dmuci_add_section_bbfdm("dmmap_network", "interface", &dmmap_ppp); - dmuci_set_value_by_section(dmmap_ppp, "section_name", name); + dmuci_add_section_bbfdm("dmmap_ppp", "interface", &dmmap_ppp); + dmuci_set_value_by_section(dmmap_ppp, "name", name); + dmuci_set_value_by_section(dmmap_ppp, "proto", "ppp"); + dmuci_set_value_by_section(dmmap_ppp, "disabled", "1"); + dmuci_set_value_by_section(dmmap_ppp, "added_by_controller", "1"); dmuci_set_value_by_section(dmmap_ppp, "ppp_int_instance", *instance); return 0; } @@ -63,17 +161,28 @@ static int delete_ppp_interface(char *refparam, struct dmctx *ctx, void *data, c switch (del_action) { case DEL_INST: - dmuci_delete_by_section(((struct dmmap_dup *)data)->config_section, NULL, NULL); - dmuci_delete_by_section(((struct dmmap_dup *)data)->dmmap_section, NULL, NULL); + dmuci_delete_by_section(((struct ppp_args *)data)->dmmap_s, NULL, NULL); + + if (((struct ppp_args *)data)->iface_s) { + dmuci_set_value_by_section(((struct ppp_args *)data)->iface_s, "proto", "none"); + ppp___reset_options(((struct ppp_args *)data)->iface_s); + } break; case DEL_ALL: - uci_foreach_option_cont_safe("network", "interface", "proto", "ppp", stmp, s) { - struct uci_section *dmmap_section = NULL; + uci_path_foreach_sections_safe(bbfdm, "dmmap_ppp", "interface", stmp, s) { + struct uci_section *iface_s = NULL; + char *iface_name = NULL; - get_dmmap_section_of_config_section("dmmap_network", "interface", section_name(s), &dmmap_section); - dmuci_delete_by_section(dmmap_section, NULL, NULL); + dmuci_get_value_by_section_string(s, "iface_name", &iface_name); + if (DM_STRLEN(iface_name)) + get_config_section_of_dmmap_section("network", "interface", iface_name, &iface_s); dmuci_delete_by_section(s, NULL, NULL); + + if (iface_s) { + dmuci_set_value_by_section(iface_s, "proto", "none"); + ppp___reset_options(iface_s); + } } break; } @@ -83,20 +192,20 @@ static int delete_ppp_interface(char *refparam, struct dmctx *ctx, void *data, c /************************************************************* * GET & SET PARAM **************************************************************/ -/*#Device.PPP.Interface.{i}.Enable!UBUS:network.interface/status/interface,@Name/up*/ static int get_ppp_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - json_object *res; - dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", section_name(((struct dmmap_dup *)data)->config_section), String}}, 1, &res); - DM_ASSERT(res, *value = "false"); - *value = dmjson_get_value(res, 1, "up"); + struct ppp_args *ppp = (struct ppp_args *)data; + char *disabled = NULL; + + dmuci_get_value_by_section_string(ppp->iface_s ? ppp->iface_s : ppp->dmmap_s, "disabled", &disabled); + *value = (disabled && *disabled == '1') ? "0" : "1"; return 0; } static int set_ppp_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { + struct ppp_args *ppp = (struct ppp_args *)data; bool b; - char *ubus_object; switch (action) { case VALUECHECK: @@ -105,31 +214,25 @@ static int set_ppp_enable(char *refparam, struct dmctx *ctx, void *data, char *i break; case VALUESET: string_to_bool(value, &b); - dmastrcat(&ubus_object, "network.interface.", section_name(((struct dmmap_dup *)data)->config_section)); - dmubus_call_set(ubus_object, b ? "up" : "down", UBUS_ARGS{0}, 0); - dmfree(ubus_object); + dmuci_set_value_by_section(ppp->dmmap_s, "disabled", b ? "0" : "1"); + if (ppp->iface_s) + dmuci_set_value_by_section(ppp->iface_s, "disabled", b ? "0" : "1"); break; } return 0; } -/*#Device.PPP.Interface.{i}.Status!UBUS:network.interface/status/interface,@Name/up*/ static int get_PPPInterface_Status(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - json_object *res = NULL; - char *status; - - dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", section_name(((struct dmmap_dup *)data)->config_section), String}}, 1, &res); - DM_ASSERT(res, *value = "Down"); - status = dmjson_get_value(res, 1, "up"); - *value = (strcmp(status, "true") == 0) ? "Up" : "Down"; + get_ppp_enable(refparam, ctx, data, instance, value); + *value = (strcmp(*value, "1") == 0) ? "Up" : "Down"; return 0; } /*#Device.PPP.Interface.{i}.Alias!UCI:dmmap_network/interface,@i-1/ppp_int_alias*/ static int get_ppp_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->dmmap_section, "ppp_int_alias", value); + dmuci_get_value_by_section_string(((struct ppp_args *)data)->dmmap_s, "ppp_int_alias", value); if ((*value)[0] == '\0') dmasprintf(value, "cpe-%s", instance); return 0; @@ -143,7 +246,7 @@ static int set_ppp_alias(char *refparam, struct dmctx *ctx, void *data, char *in return FAULT_9007; return 0; case VALUESET: - dmuci_set_value_by_section(((struct dmmap_dup *)data)->dmmap_section, "ppp_int_alias", value); + dmuci_set_value_by_section(((struct ppp_args *)data)->dmmap_s, "ppp_int_alias", value); return 0; } return 0; @@ -152,10 +255,17 @@ static int set_ppp_alias(char *refparam, struct dmctx *ctx, void *data, char *in /*#Device.PPP.Interface.{i}.LastChange!UBUS:network.interface/status/interface,@Name/uptime*/ static int get_PPPInterface_LastChange(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - json_object *res; - dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", section_name(((struct dmmap_dup *)data)->config_section), String}}, 1, &res); - DM_ASSERT(res, *value = "0"); - *value = dmjson_get_value(res, 1, "uptime"); + struct uci_section *ppp_s = ((struct ppp_args *)data)->iface_s; + + if (ppp_s) { + json_object *res; + + dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", section_name(ppp_s), String}}, 1, &res); + DM_ASSERT(res, *value = "0"); + *value = dmjson_get_value(res, 1, "uptime"); + } else { + *value = "0"; + } return 0; } @@ -167,6 +277,7 @@ static int get_PPPInterface_Reset(char *refparam, struct dmctx *ctx, void *data, static int set_PPPInterface_Reset(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { + struct uci_section *ppp_s = ((struct ppp_args *)data)->iface_s; bool b; switch (action) { @@ -176,9 +287,9 @@ static int set_PPPInterface_Reset(char *refparam, struct dmctx *ctx, void *data, break; case VALUESET: string_to_bool(value, &b); - if (b) { + if (b && ppp_s) { char intf_obj[64] = {0}; - snprintf(intf_obj, sizeof(intf_obj), "network.interface.%s", section_name(((struct dmmap_dup *)data)->config_section)); + snprintf(intf_obj, sizeof(intf_obj), "network.interface.%s", section_name(ppp_s)); dmubus_call_set(intf_obj, "down", UBUS_ARGS{0}, 0); dmubus_call_set(intf_obj, "up", UBUS_ARGS{0}, 0); } @@ -189,96 +300,114 @@ static int set_PPPInterface_Reset(char *refparam, struct dmctx *ctx, void *data, static int get_ppp_name(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - *value = dmstrdup(section_name(((struct dmmap_dup *)data)->config_section)); + dmuci_get_value_by_section_string(((struct ppp_args *)data)->dmmap_s, "name", value); + if ((*value)[0] == '\0') + *value = dmstrdup(section_name(((struct ppp_args *)data)->iface_s)); return 0; } /*#Device.PPP.Interface.{i}.ConnectionStatus!UBUS:network.interface/status/interface,@Name/up*/ static int get_ppp_status(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - char *status = NULL, *uptime = NULL, *pending = NULL; - json_object *res = NULL, *jobj = NULL; - bool bstatus = false, bpend = false; + struct uci_section *ppp_s = ((struct ppp_args *)data)->iface_s; - dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", section_name(((struct dmmap_dup *)data)->config_section), String}}, 1, &res); - DM_ASSERT(res, *value = "Unconfigured"); - jobj = dmjson_get_obj(res, 1, "up"); - if (jobj) { - status = dmjson_get_value(res, 1, "up"); - string_to_bool(status, &bstatus); - if (bstatus) { - uptime = dmjson_get_value(res, 1, "uptime"); - pending = dmjson_get_value(res, 1, "pending"); - string_to_bool(pending, &bpend); + if (ppp_s) { + char *status = NULL, *uptime = NULL, *pending = NULL; + json_object *res = NULL, *jobj = NULL; + bool bstatus = false, bpend = false; + + dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", section_name(ppp_s), String}}, 1, &res); + DM_ASSERT(res, *value = "Unconfigured"); + jobj = dmjson_get_obj(res, 1, "up"); + if (jobj) { + status = dmjson_get_value(res, 1, "up"); + string_to_bool(status, &bstatus); + if (bstatus) { + uptime = dmjson_get_value(res, 1, "uptime"); + pending = dmjson_get_value(res, 1, "pending"); + string_to_bool(pending, &bpend); + } } + if (uptime && atoi(uptime) > 0) + *value = "Connected"; + else if (pending && bpend) + *value = "Pending Disconnect"; + else + *value = "Disconnected"; + } else { + *value = "Unconfigured"; } - if (uptime && atoi(uptime) > 0) - *value = "Connected"; - else if (pending && bpend) - *value = "Pending Disconnect"; - else - *value = "Disconnected"; return 0; } static int get_PPPInterface_LastConnectionError(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - json_object *res = NULL; - char *status; + struct uci_section *ppp_s = ((struct ppp_args *)data)->iface_s; - dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", section_name(((struct dmmap_dup *)data)->config_section), String}}, 1, &res); - DM_ASSERT(res, *value = "ERROR_NONE"); - status = dmjson_get_value(res, 2, "data", "lastconnectionerror"); + if (ppp_s) { + json_object *res = NULL; - switch (atoi(status)) { - case 0: - *value = "ERROR_NONE"; - break; - case 1: case 10: case 13: case 14: case 17: case 18: case 20: case 22: - *value = "ERROR_UNKNOWN"; - break; - case 2: case 3: case 4: case 6: case 7: case 9: - *value = "ERROR_COMMAND_ABORTED"; - break; - case 5: case 15: - *value = "ERROR_USER_DISCONNECT"; - break; - case 8: - *value = "ERROR_IP_CONFIGURATION"; - break; - case 11: case 19: case 21: - *value = "ERROR_AUTHENTICATION_FAILURE"; - break; - case 12: - *value = "ERROR_IDLE_DISCONNECT"; - break; - case 16: - *value = "ERROR_ISP_DISCONNECT"; - break; - default: - *value = "ERROR_NONE"; - break; - } + dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", section_name(ppp_s), String}}, 1, &res); + DM_ASSERT(res, *value = "ERROR_NONE"); + char *status = dmjson_get_value(res, 2, "data", "lastconnectionerror"); + switch (atoi(status)) { + case 0: + *value = "ERROR_NONE"; + break; + case 1: case 10: case 13: case 14: case 17: case 18: case 20: case 22: + *value = "ERROR_UNKNOWN"; + break; + case 2: case 3: case 4: case 6: case 7: case 9: + *value = "ERROR_COMMAND_ABORTED"; + break; + case 5: case 15: + *value = "ERROR_USER_DISCONNECT"; + break; + case 8: + *value = "ERROR_IP_CONFIGURATION"; + break; + case 11: case 19: case 21: + *value = "ERROR_AUTHENTICATION_FAILURE"; + break; + case 12: + *value = "ERROR_IDLE_DISCONNECT"; + break; + case 16: + *value = "ERROR_ISP_DISCONNECT"; + break; + default: + *value = "ERROR_NONE"; + break; + } + } else { + *value = "ERROR_NONE"; + } return 0; } /*#Device.PPP.Interface.{i}.Username!UCI:network/interface,@i-1/username*/ static int get_ppp_username(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "username", value); + struct ppp_args *ppp = (struct ppp_args *)data; + + dmuci_get_value_by_section_string(ppp->iface_s ? ppp->iface_s : ppp->dmmap_s, "username", value); return 0; } static int set_ppp_username(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { + struct ppp_args *ppp = (struct ppp_args *)data; + switch (action) { case VALUECHECK: if (dm_validate_string(value, -1, 64, NULL, NULL)) return FAULT_9007; return 0; case VALUESET: - dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "username", value); + dmuci_set_value_by_section(ppp->dmmap_s, "username", value); + if (ppp->iface_s) + dmuci_set_value_by_section(ppp->iface_s, "username", value); return 0; } return 0; @@ -287,13 +416,17 @@ static int set_ppp_username(char *refparam, struct dmctx *ctx, void *data, char /*#Device.PPP.Interface.{i}.Password!UCI:network/interface,@i-1/password*/ static int set_ppp_password(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { + struct ppp_args *ppp = (struct ppp_args *)data; + switch (action) { case VALUECHECK: if (dm_validate_string(value, -1, 64, NULL, NULL)) return FAULT_9007; return 0; case VALUESET: - dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "password", value); + dmuci_set_value_by_section(ppp->dmmap_s, "password", value); + if (ppp->iface_s) + dmuci_set_value_by_section(ppp->iface_s, "password", value); return 0; } return 0; @@ -301,8 +434,10 @@ static int set_ppp_password(char *refparam, struct dmctx *ctx, void *data, char static int get_PPPInterface_MaxMRUSize(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { + struct ppp_args *ppp = (struct ppp_args *)data; char *pppd_opt = NULL; - dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "pppd_options", &pppd_opt); + + dmuci_get_value_by_section_string(ppp->iface_s ? ppp->iface_s : ppp->dmmap_s, "pppd_options", &pppd_opt); if (pppd_opt && *pppd_opt == '\0') { *value = "1500"; return 0; @@ -330,7 +465,7 @@ static int get_PPPInterface_MaxMRUSize(char *refparam, struct dmctx *ctx, void * return 0; } -static int configure_pppd_mru(char *pppd_opt, char *mru_str, void *data, char *value) +static int configure_pppd_mru(char *pppd_opt, char *mru_str, struct uci_section *sec, char *value) { char *token = NULL, *end = NULL; char list_options[1024] = {0}, mru_opt[1024] = {0}; @@ -358,12 +493,13 @@ static int configure_pppd_mru(char *pppd_opt, char *mru_str, void *data, char *v if (found == false) snprintf(&list_options[pos], sizeof(list_options) - pos, "%s", mru_str); - dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "pppd_options", list_options); + dmuci_set_value_by_section(sec, "pppd_options", list_options); return 0; } static int set_PPPInterface_MaxMRUSize(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { + struct ppp_args *ppp = (struct ppp_args *)data; char mru_str[1024] = {0}; char *pppd_opt = NULL; @@ -374,13 +510,17 @@ static int set_PPPInterface_MaxMRUSize(char *refparam, struct dmctx *ctx, void * break; case VALUESET: snprintf(mru_str, sizeof(mru_str), "%s %s", "mru", value); - dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "pppd_options", &pppd_opt); + dmuci_get_value_by_section_string(ppp->iface_s ? ppp->iface_s : ppp->dmmap_s, "pppd_options", &pppd_opt); if (pppd_opt && *pppd_opt == '\0') { - dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "pppd_options", mru_str); + dmuci_set_value_by_section(ppp->dmmap_s, "pppd_options", mru_str); + if (ppp->iface_s) + dmuci_set_value_by_section(ppp->iface_s, "pppd_options", mru_str); } else { // If mru is specified then we need to replace and keep the rest of the options intact. - configure_pppd_mru(pppd_opt, mru_str, data, value); + configure_pppd_mru(pppd_opt, mru_str, ppp->dmmap_s, value); + if (ppp->iface_s) + configure_pppd_mru(pppd_opt, mru_str, ppp->iface_s, value); } break; } @@ -389,62 +529,62 @@ static int set_PPPInterface_MaxMRUSize(char *refparam, struct dmctx *ctx, void * static int get_PPPInterface_CurrentMRUSize(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - json_object *res = NULL; - char *status; + struct uci_section *ppp_s = ((struct ppp_args *)data)->iface_s; - dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", section_name(((struct dmmap_dup *)data)->config_section), String}}, 1, &res); - DM_ASSERT(res, *value = ""); - status = dmjson_get_value(res, 1, "up"); - if (0 != strcmp(status, "true")) { - *value = ""; - return 0; + if (ppp_s) { + char intf[64] = {0}; + + snprintf(intf, sizeof(intf), "%s-%s", "pppoe", section_name(ppp_s)); + get_net_device_sysfs(intf, "mtu", value); } - char intf[1024] = {0}; - snprintf(intf, sizeof(intf), "%s-%s", "pppoe", section_name(((struct dmmap_dup *)data)->config_section)); - get_net_device_sysfs(intf, "mtu", value); - return 0; } static int get_PPPInterface_LCPEcho(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - char *lcp_echo = NULL, *token = NULL; + struct uci_section *ppp_s = ((struct ppp_args *)data)->iface_s; - dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "keepalive", &lcp_echo); - if (lcp_echo && *lcp_echo == '\0') { - *value = "1"; - return 0; + if (ppp_s) { + char *lcp_echo = NULL, *token = NULL; + + dmuci_get_value_by_section_string(ppp_s, "keepalive", &lcp_echo); + if (lcp_echo && *lcp_echo == '\0') { + *value = "1"; + return 0; + } + + token = strtok(lcp_echo , " "); + if (NULL != token) { + char echo_val[50] = {0}; + + DM_STRNCPY(echo_val, token, sizeof(echo_val)); + *value = dmstrdup(echo_val); + } } - - token = strtok(lcp_echo , " "); - if (NULL != token) { - char echo_val[50] = {0}; - - DM_STRNCPY(echo_val, token, sizeof(echo_val)); - *value = dmstrdup(echo_val); - } - return 0; } static int get_PPPInterface_LCPEchoRetry(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - char *lcp_retry = NULL, *token = NULL; + struct uci_section *ppp_s = ((struct ppp_args *)data)->iface_s; - dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "keepalive", &lcp_retry); - if (!lcp_retry || *lcp_retry == '\0') { - *value = "5"; - } else { - token = strchr(lcp_retry , ' '); - if (NULL != token) { - char lcp_interval[50] = {0}; + if (ppp_s) { + char *lcp_retry = NULL, *token = NULL; - DM_STRNCPY(lcp_interval, token + 1, sizeof(lcp_interval)); - *value = dmstrdup(lcp_interval); + dmuci_get_value_by_section_string(ppp_s, "keepalive", &lcp_retry); + if (!lcp_retry || *lcp_retry == '\0') { + *value = "5"; + } else { + token = strchr(lcp_retry , ' '); + if (NULL != token) { + char lcp_interval[50] = {0}; + + DM_STRNCPY(lcp_interval, token + 1, sizeof(lcp_interval)); + *value = dmstrdup(lcp_interval); + } } } - return 0; } @@ -544,20 +684,27 @@ static int handle_supported_ncp_options(struct uci_section *s, char *instance, i static int get_PPPInterface_IPCPEnable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - int ret = handle_supported_ncp_options(((struct dmmap_dup *)data)->config_section, instance, IPCP); + struct ppp_args *ppp = (struct ppp_args *)data; + + int ret = handle_supported_ncp_options(ppp->iface_s ? ppp->iface_s : ppp->dmmap_s, instance, IPCP); *value = ret ? "0" : "1"; return 0; } static int set_PPPInterface_IPCPEnable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { + struct ppp_args *ppp = (struct ppp_args *)data; + switch (action) { case VALUECHECK: if (dm_validate_boolean(value)) return FAULT_9007; break; case VALUESET: - configure_supported_ncp_options(((struct dmmap_dup *)data)->config_section, value, "noip"); + configure_supported_ncp_options(ppp->dmmap_s, value, "noip"); + if (ppp->iface_s) + configure_supported_ncp_options(ppp->iface_s, value, "noip"); + break; } return 0; @@ -565,20 +712,26 @@ static int set_PPPInterface_IPCPEnable(char *refparam, struct dmctx *ctx, void * static int get_PPPInterface_IPv6CPEnable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - int ret = handle_supported_ncp_options(((struct dmmap_dup *)data)->config_section, instance, IPCPv6); + struct ppp_args *ppp = (struct ppp_args *)data; + + int ret = handle_supported_ncp_options(ppp->iface_s ? ppp->iface_s : ppp->dmmap_s, instance, IPCPv6); *value = ret ? "0" : "1"; return 0; } static int set_PPPInterface_IPv6CPEnable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { + struct ppp_args *ppp = (struct ppp_args *)data; + switch (action) { case VALUECHECK: if (dm_validate_boolean(value)) return FAULT_9007; break; case VALUESET: - configure_supported_ncp_options(((struct dmmap_dup *)data)->config_section, value, "noipv6"); + configure_supported_ncp_options(ppp->dmmap_s, value, "noipv6"); + if (ppp->iface_s) + configure_supported_ncp_options(ppp->iface_s, value, "noipv6"); break; } return 0; @@ -616,182 +769,206 @@ static int get_PPPInterfacePPPoE_SessionID(char *refparam, struct dmctx *ctx, vo static int get_PPPInterfaceIPCP_LocalIPAddress(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - json_object *res = NULL; + struct uci_section *ppp_s = ((struct ppp_args *)data)->iface_s; - dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", section_name(((struct dmmap_dup *)data)->config_section), String}}, 1, &res); - DM_ASSERT(res, *value = ""); - json_object *ipv4_obj = dmjson_select_obj_in_array_idx(res, 0, 1, "ipv4-address"); - *value = dmjson_get_value(ipv4_obj, 1, "address"); + if (ppp_s) { + json_object *res = NULL; + + dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", section_name(ppp_s), String}}, 1, &res); + DM_ASSERT(res, *value = ""); + json_object *ipv4_obj = dmjson_select_obj_in_array_idx(res, 0, 1, "ipv4-address"); + *value = dmjson_get_value(ipv4_obj, 1, "address"); + } return 0; } static int get_PPPInterfaceIPCP_RemoteIPAddress(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - json_object *res = NULL; + struct uci_section *ppp_s = ((struct ppp_args *)data)->iface_s; - dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", section_name(((struct dmmap_dup *)data)->config_section), String}}, 1, &res); - DM_ASSERT(res, *value = ""); - json_object *ipv4_obj = dmjson_select_obj_in_array_idx(res, 0, 1, "ipv4-address"); - *value = dmjson_get_value(ipv4_obj, 1, "ptpaddress"); - if (**value == '\0') { - json_object *route_obj = dmjson_select_obj_in_array_idx(res, 0, 1, "route"); - *value = dmjson_get_value(route_obj, 1, "nexthop"); + if (ppp_s) { + json_object *res = NULL; + + dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", section_name(ppp_s), String}}, 1, &res); + DM_ASSERT(res, *value = ""); + json_object *ipv4_obj = dmjson_select_obj_in_array_idx(res, 0, 1, "ipv4-address"); + *value = dmjson_get_value(ipv4_obj, 1, "ptpaddress"); + if (**value == '\0') { + json_object *route_obj = dmjson_select_obj_in_array_idx(res, 0, 1, "route"); + *value = dmjson_get_value(route_obj, 1, "nexthop"); + } } return 0; } static int get_PPPInterfaceIPCP_DNSServers(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - json_object *res = NULL; + struct uci_section *ppp_s = ((struct ppp_args *)data)->iface_s; - dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", section_name(((struct dmmap_dup *)data)->config_section), String}}, 1, &res); - DM_ASSERT(res, *value = ""); - *value = dmjson_get_value_array_all(res, ",", 1, "dns-server"); + if (ppp_s) { + json_object *res = NULL; + + dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", section_name(ppp_s), String}}, 1, &res); + DM_ASSERT(res, *value = ""); + *value = dmjson_get_value_array_all(res, ",", 1, "dns-server"); + } return 0; } static int get_PPPInterfaceIPv6CP_LocalInterfaceIdentifier(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - json_object *res = NULL; + struct uci_section *ppp_s = ((struct ppp_args *)data)->iface_s; - dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", section_name(((struct dmmap_dup *)data)->config_section), String}}, 1, &res); - DM_ASSERT(res, *value = ""); - json_object *ipv4_obj = dmjson_select_obj_in_array_idx(res, 0, 1, "ipv6-address"); - *value = dmjson_get_value(ipv4_obj, 1, "address"); + if (ppp_s) { + json_object *res = NULL; + + dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", section_name(ppp_s), String}}, 1, &res); + DM_ASSERT(res, *value = ""); + json_object *ipv4_obj = dmjson_select_obj_in_array_idx(res, 0, 1, "ipv6-address"); + *value = dmjson_get_value(ipv4_obj, 1, "address"); + } return 0; } static int get_PPPInterfaceIPv6CP_RemoteInterfaceIdentifier(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - json_object *res = NULL; + struct uci_section *ppp_s = ((struct ppp_args *)data)->iface_s; - dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", section_name(((struct dmmap_dup *)data)->config_section), String}}, 1, &res); - DM_ASSERT(res, *value = ""); - *value = dmjson_get_value(res, 2, "data", "llremote"); + if (ppp_s) { + json_object *res = NULL; + + dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", section_name(ppp_s), String}}, 1, &res); + DM_ASSERT(res, *value = ""); + *value = dmjson_get_value(res, 2, "data", "llremote"); + } return 0; } -static int ppp_read_sysfs(struct uci_section *sect, const char *name, char **value) +static int ppp_read_sysfs(void *data, const char *name, char **value) { - char *proto; - int rc = 0; + struct uci_section *ppp_s = ((struct ppp_args *)data)->iface_s; - dmuci_get_value_by_section_string(sect, "proto", &proto); - if (!strcmp(proto, "pppoe")) { - char *l3_device = get_l3_device(section_name(sect)); - rc = get_net_device_sysfs(l3_device, name, value); + if (ppp_s) { + char *proto; + + dmuci_get_value_by_section_string(ppp_s, "proto", &proto); + if (!strcmp(proto, "pppoe")) { + char *l3_device = get_l3_device(section_name(ppp_s)); + get_net_device_sysfs(l3_device, name, value); + } + } else { + *value = "0"; } - return rc; + + return 0; } /*#Device.PPP.Interface.{i}.Stats.BytesReceived!SYSFS:/sys/class/net/@Name/statistics/rx_bytes*/ static int get_ppp_eth_bytes_received(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - return ppp_read_sysfs(((struct dmmap_dup *)data)->config_section, "statistics/rx_bytes", value); + return ppp_read_sysfs(data, "statistics/rx_bytes", value); } /*#Device.PPP.Interface.{i}.Stats.BytesSent!SYSFS:/sys/class/net/@Name/statistics/tx_bytes*/ static int get_ppp_eth_bytes_sent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - return ppp_read_sysfs(((struct dmmap_dup *)data)->config_section, "statistics/tx_bytes", value); + return ppp_read_sysfs(data, "statistics/tx_bytes", value); } /*#Device.PPP.Interface.{i}.Stats.PacketsReceived!SYSFS:/sys/class/net/@Name/statistics/rx_packets*/ static int get_ppp_eth_pack_received(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - return ppp_read_sysfs(((struct dmmap_dup *)data)->config_section, "statistics/rx_packets", value); + return ppp_read_sysfs(data, "statistics/rx_packets", value); } /*#Device.PPP.Interface.{i}.Stats.PacketsSent!SYSFS:/sys/class/net/@Name/statistics/tx_packets*/ static int get_ppp_eth_pack_sent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - return ppp_read_sysfs(((struct dmmap_dup *)data)->config_section, "statistics/tx_packets", value); + return ppp_read_sysfs(data, "statistics/tx_packets", value); } /*#Device.PPP.Interface.{i}.Stats.ErrorsSent!SYSFS:/sys/class/net/@Name/statistics/tx_errors*/ static int get_PPPInterfaceStats_ErrorsSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - return ppp_read_sysfs(((struct dmmap_dup *)data)->config_section, "statistics/tx_errors", value); + return ppp_read_sysfs(data, "statistics/tx_errors", value); } /*#Device.PPP.Interface.{i}.Stats.ErrorsReceived!SYSFS:/sys/class/net/@Name/statistics/rx_errors*/ static int get_PPPInterfaceStats_ErrorsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - return ppp_read_sysfs(((struct dmmap_dup *)data)->config_section, "statistics/rx_errors", value); + return ppp_read_sysfs(data, "statistics/rx_errors", value); } /*#Device.PPP.Interface.{i}.Stats.DiscardPacketsSent!SYSFS:/sys/class/net/@Name/statistics/tx_dropped*/ static int get_PPPInterfaceStats_DiscardPacketsSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - return ppp_read_sysfs(((struct dmmap_dup *)data)->config_section, "statistics/tx_dropped", value); + return ppp_read_sysfs(data, "statistics/tx_dropped", value); } /*#Device.PPP.Interface.{i}.Stats.DiscardPacketsReceived!SYSFS:/sys/class/net/@Name/statistics/rx_dropped*/ static int get_PPPInterfaceStats_DiscardPacketsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - return ppp_read_sysfs(((struct dmmap_dup *)data)->config_section, "statistics/rx_dropped", value); + return ppp_read_sysfs(data, "statistics/rx_dropped", value); } /*#Device.PPP.Interface.{i}.Stats.MulticastPacketsReceived!SYSFS:/sys/class/net/@Name/statistics/multicast*/ static int get_PPPInterfaceStats_MulticastPacketsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - return ppp_read_sysfs(((struct dmmap_dup *)data)->config_section, "statistics/multicast", value); + return ppp_read_sysfs(data, "statistics/multicast", value); } static int get_ppp_lower_layer(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - char *linker, *ifname; - int ret = 0; - struct uci_section *ss = NULL; - char *dev = "0"; + struct ppp_args *ppp = (struct ppp_args *)data; - dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "device", &linker); + dmuci_get_value_by_section_string(ppp->dmmap_s, "LowerLayers", value); - // Get wan interface - dev = get_device(section_name(((struct dmmap_dup *)data)->config_section)); + if ((*value)[0] == '\0') { + char *device = NULL; - // Check if interface name is same as dev value. - char *token = NULL, *end = linker; - while ((token = strtok_r(end, " ", &end))) { - if (0 == strcmp(dev, token)) { - ret = 1; - break; + if (ppp->iface_s) { + device = get_device(section_name(ppp->iface_s)); + + /* If the device value is empty, then get its value directly from device option */ + if (*device == '\0') + dmuci_get_value_by_section_string(ppp->iface_s, "device", &device); + } else { + dmuci_get_value_by_section_string(ppp->dmmap_s, "device", &device); } - } - if (ret == 0 || !token) { - *value = ""; - return 0; - } + if (device[0] != '\0') { + adm_entry_get_linker_param(ctx, "Device.Ethernet.VLANTermination.", device, value); + if (*value != NULL && (*value)[0] != 0) + return 0; + } - // Check if the interface is untagged or tagged. - if (NULL != strchr(token, '.')) { - // Get the device section and the ifname corresponding to it - uci_foreach_option_eq("network", "device", "name", token, ss) { - dmuci_get_value_by_section_string(ss, "ifname", &ifname); - break; + if (device[0] != '\0') { + char linker[64] = {0}; + + DM_STRNCPY(linker, device, sizeof(linker)); + char *vid = strchr(linker, '.'); + if (vid) *vid = '\0'; + + adm_entry_get_linker_param(ctx, "Device.Ethernet.Link.", linker, value); } } else { - ifname = token; - } + char *linker = NULL; - adm_entry_get_linker_param(ctx, "Device.ATM.Link.", ifname, value); - if (!(*value) || (*value)[0] == 0) - adm_entry_get_linker_param(ctx, "Device.PTM.Link.", ifname, value); - if (!(*value) || (*value)[0] == 0) - adm_entry_get_linker_param(ctx, "Device.Ethernet.Interface.", ifname, value); - if (!(*value) || (*value)[0] == 0) - adm_entry_get_linker_param(ctx, "Device.WiFi.SSID.", ifname, value); + adm_entry_get_linker_value(ctx, *value, &linker); + if (!linker || *linker == 0) + *value = ""; + } return 0; } static int set_ppp_lower_layer(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { + struct ppp_args *ppp = (struct ppp_args *)data; + char eth_vlan_term[64] = "Device.Ethernet.VLANTermination."; + char eth_link[32] = "Device.Ethernet.Link."; char *allowed_objects[] = { - "Device.Ethernet.Interface.", - "Device.ATM.Link.", - "Device.PTM.Link.", - "Device.WiFi.SSID.", + eth_vlan_term, + eth_link, NULL}; char *ppp_linker = NULL; @@ -806,7 +983,58 @@ static int set_ppp_lower_layer(char *refparam, struct dmctx *ctx, void *data, ch return 0; case VALUESET: adm_entry_get_linker_value(ctx, value, &ppp_linker); - dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "device", ppp_linker ? ppp_linker : ""); + + // Store LowerLayers value under dmmap_ppp section + dmuci_set_value_by_section(ppp->dmmap_s, "LowerLayers", value); + + if (!ppp_linker || ppp_linker[0] == 0) { + dmuci_set_value_by_section(ppp->dmmap_s, "vlan_ter_linker", ""); + dmuci_set_value_by_section(ppp->dmmap_s, "eth_link_linker", ""); + + dmuci_set_value_by_section(ppp->dmmap_s, "device", ""); + if (ppp->iface_s) + dmuci_set_value_by_section(ppp->iface_s, "device", ""); + } else if (strncmp(value, eth_vlan_term, strlen(eth_vlan_term)) == 0) { + + // Check VLANTremination linker and required options + struct uci_section *vlan_ter_s = get_dup_section_in_config_opt("network", "device", "name", ppp_linker); + if (vlan_ter_s) { + dmuci_set_value_by_section(ppp->dmmap_s, "device", ppp_linker); + if (ppp->iface_s) + dmuci_set_value_by_section(ppp->iface_s, "device", ppp_linker); + } else { + dmuci_set_value_by_section(ppp->dmmap_s, "vlan_ter_linker", ppp_linker); + } + + // Update proto option + dmuci_set_value_by_section(ppp->dmmap_s, "proto", "pppoe"); + if (ppp->iface_s) + dmuci_set_value_by_section(ppp->iface_s, "proto", "pppoe"); + } else if (strncmp(value, eth_link, strlen(eth_link)) == 0) { + struct uci_section *eth_link_s = NULL; + + // Check Ethernet.Link linker and required options + get_dmmap_section_of_config_section_eq("dmmap", "link", "device", ppp_linker, ð_link_s); + if (eth_link_s) { + dmuci_set_value_by_section(ppp->dmmap_s, "device", ppp_linker); + if (ppp->iface_s) + dmuci_set_value_by_section(ppp->iface_s, "device", ppp_linker); + } else { + get_dmmap_section_of_config_section_eq("dmmap", "link", "linker", ppp_linker, ð_link_s); + dmuci_set_value_by_section(ppp->dmmap_s, "eth_link_linker", ppp_linker); + } + + if (eth_link_s) { + char *is_eth = NULL; + + dmuci_get_value_by_section_string(eth_link_s, "is_eth", &is_eth); + + // Update proto option + dmuci_set_value_by_section(ppp->dmmap_s, "proto", !strcmp(is_eth, "1") ? "pppoe" : "pppoa"); + if (ppp->iface_s) + dmuci_set_value_by_section(ppp->iface_s, "proto", !strcmp(is_eth, "1") ? "pppoe" : "pppoa"); + } + } return 0; } return 0; @@ -828,10 +1056,12 @@ static int get_PPP_SupportedNCPs(char *refparam, struct dmctx *ctx, void *data, /*#Device.PPP.Interface.{i}.PPPoE.ACName!UCI:network/interface,@i-1/ac*/ static int get_PPPInterfacePPPoE_ACName(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { + struct ppp_args *ppp = (struct ppp_args *)data; char *proto; - dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "proto", &proto); + + dmuci_get_value_by_section_string(ppp->iface_s ? ppp->iface_s : ppp->dmmap_s, "proto", &proto); if (strcmp(proto, "pppoe") == 0) { - dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "ac", value); + dmuci_get_value_by_section_string(ppp->iface_s ? ppp->iface_s : ppp->dmmap_s, "ac", value); return 0; } return 0; @@ -839,6 +1069,7 @@ static int get_PPPInterfacePPPoE_ACName(char *refparam, struct dmctx *ctx, void static int set_PPPInterfacePPPoE_ACName(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { + struct ppp_args *ppp = (struct ppp_args *)data; char *proto_intf; switch (action) { @@ -846,12 +1077,14 @@ static int set_PPPInterfacePPPoE_ACName(char *refparam, struct dmctx *ctx, void if (dm_validate_string(value, -1, 256, NULL, NULL)) return FAULT_9007; - dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "proto", &proto_intf); + dmuci_get_value_by_section_string(ppp->iface_s ? ppp->iface_s : ppp->dmmap_s, "proto", &proto_intf); if (strcmp(proto_intf, "pppoe") != 0) return FAULT_9001; break; case VALUESET: - dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "ac", value); + dmuci_set_value_by_section(ppp->dmmap_s, "ac", value); + if (ppp->iface_s) + dmuci_set_value_by_section(ppp->iface_s, "ac", value); break; } return 0; @@ -860,10 +1093,12 @@ static int set_PPPInterfacePPPoE_ACName(char *refparam, struct dmctx *ctx, void /*#Device.PPP.Interface.{i}.PPPoE.ServiceName!UCI:network/interface,@i-1/service*/ static int get_PPPInterfacePPPoE_ServiceName(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { + struct ppp_args *ppp = (struct ppp_args *)data; char *proto; - dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "proto", &proto); + + dmuci_get_value_by_section_string(ppp->iface_s ? ppp->iface_s : ppp->dmmap_s, "proto", &proto); if (strcmp(proto, "pppoe") == 0) { - dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "service", value); + dmuci_get_value_by_section_string(ppp->iface_s ? ppp->iface_s : ppp->dmmap_s, "service", value); return 0; } return 0; @@ -871,6 +1106,7 @@ static int get_PPPInterfacePPPoE_ServiceName(char *refparam, struct dmctx *ctx, static int set_PPPInterfacePPPoE_ServiceName(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { + struct ppp_args *ppp = (struct ppp_args *)data; char *proto; switch (action) { @@ -878,12 +1114,14 @@ static int set_PPPInterfacePPPoE_ServiceName(char *refparam, struct dmctx *ctx, if (dm_validate_string(value, -1, 256, NULL, NULL)) return FAULT_9007; - dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "proto", &proto); + dmuci_get_value_by_section_string(ppp->iface_s ? ppp->iface_s : ppp->dmmap_s, "proto", &proto); if (strcmp(proto, "pppoe") != 0) return FAULT_9001; break; case VALUESET: - dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "service", value); + dmuci_set_value_by_section(ppp->dmmap_s, "service", value); + if (ppp->iface_s) + dmuci_set_value_by_section(ppp->iface_s, "service", value); break; } return 0; @@ -894,7 +1132,12 @@ static int set_PPPInterfacePPPoE_ServiceName(char *refparam, struct dmctx *ctx, ***************************************************************************/ static int get_linker_ppp_interface(char *refparam, struct dmctx *dmctx, void *data, char *instance, char **linker) { - *linker = data ? dmstrdup(section_name(((struct dmmap_dup *)data)->config_section)) : ""; + struct ppp_args *ppp = (struct ppp_args *)data; + + if (ppp->iface_s) + *linker = dmstrdup(section_name(ppp->iface_s)); + else + dmuci_get_value_by_section_string(ppp->dmmap_s, "name", linker); return 0; } @@ -903,11 +1146,15 @@ static int get_linker_ppp_interface(char *refparam, struct dmctx *dmctx, void *d *************************************************************/ static int operate_PPPInterface_Reset(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - char interface_obj[64] = {0}; + struct uci_section *ppp_s = ((struct ppp_args *)data)->iface_s; - snprintf(interface_obj, sizeof(interface_obj), "network.interface.%s", section_name(((struct dmmap_dup *)data)->config_section)); - dmubus_call_set(interface_obj, "down", UBUS_ARGS{0}, 0); - dmubus_call_set(interface_obj, "up", UBUS_ARGS{0}, 0); + if (ppp_s) { + char interface_obj[64] = {0}; + + snprintf(interface_obj, sizeof(interface_obj), "network.interface.%s", section_name(ppp_s)); + dmubus_call_set(interface_obj, "down", UBUS_ARGS{0}, 0); + dmubus_call_set(interface_obj, "up", UBUS_ARGS{0}, 0); + } return CMD_SUCCESS; } diff --git a/dmtree/tr181/ppp.h b/dmtree/tr181/ppp.h index b5251425..2ddc793a 100644 --- a/dmtree/tr181/ppp.h +++ b/dmtree/tr181/ppp.h @@ -26,4 +26,7 @@ extern DMLEAF tPPPInterfaceIPCPParams[]; extern DMLEAF tPPPInterfaceIPv6CPParams[]; extern DMLEAF tPPPInterfaceStatsParams[]; +void ppp___update_sections(struct uci_section *s_from, struct uci_section *s_to); +void ppp___reset_options(struct uci_section *ppp_s); + #endif