diff --git a/docs/guide/ip_interface.md b/docs/guide/ip_interface.md new file mode 100644 index 00000000..73f1b9bb --- /dev/null +++ b/docs/guide/ip_interface.md @@ -0,0 +1,175 @@ +# TR181 IP.Interface. Object + +The purpose of this document is to describe what are the problems and limitation we have in managing IP.Interface. with their sub-objects and what is the best way for the customer to avoid these problems/limitations and can easily configure IP.Interface. with different IPv4/v6 addresses using static or dhcp server. + +In fact, many TR181 objects are not mapped 1-to-1 with uci config which makes managing these objects so difficult and one of the important objects is IP.Interface. + +# Problematics: + +Actually, we find a lot of problems with the current implementation of IP.Interface object such as: + + - If IP.Interface instance and IP.Interface.X.IPv4Address instance map to the same interface section, so there is no way to disable IPv4Address instance without affecting IP.Interface since both maps to the same interface section. + +``` +config interface 'wan' ---> used by Device.IP.Interface.X. and Device.IP.Interface.X.IPv4Address.X. instances + option disabled '0' ---> Disabling this IPv4Address.X. instance using Enable parameter(Device.IP.Interface.X.IPv4Address.X.Enable) will impact on IP.Interface.X. instance + option device 'ethx' + option proto 'static' + option ipaddr '10.100.17.39' + option netmask '255.255.255.0' + +``` + + - Currently, each IP.Interface instance can be configured with either dhcpv4 or dhcpv6. So there is no way to configure it with both DHCPv4 and DHCPv6 server at the same time as shown below. + + ``` +config interface 'wan' + option device 'ethx' + option proto 'dhcp' + +config interface 'wan6' + option device 'ethx' + option proto 'dhcpv6' + +``` + + - If someone try to create a static route and bind it to an IP.Interface. instance which has an IPv4Address instance defined there so disabling IPv4Addres will cause IP.Interface instance to be disabled and therefore the static route will be automatically disabled from the system. + +``` +config interface 'wan' ---> used by Device.IP.Interface.1. and Device.IP.Interface.1.IPv4Address.1. instances + option disabled '1' ---> Disabling this IPv4Address.1. instance using Enable parameter(Device.IP.Interface.1.IPv4Address.1.Enable) will disable IP.Interface.1. and route section even if there are others section use the same device(wan_2) + option device 'ethx' + option proto 'dhcp' + +config interface 'wan_2' ---> used by Device.IP.Interface.1.IPv4Address.2. instance + option disabled '0' + option device 'ethx' + option proto 'static' + option ipaddr '10.100.17.39' + option netmask '255.255.255.0' + +config route + option interface 'wan' + option target '0.0.0.0/0' + option gateway '10.72.197.110' + +``` + + - There is no way to handle config interface section which is created by luci or cli commands as below: + +``` +config interface 'wan' + option disabled '0' + option device 'ethx' + option proto 'static' + list ipaddr '10.100.17.39' + list ipaddr '10.100.18.39' + list ipaddr '10.100.19.39' + option netmask '255.255.255.0' + +``` + +# Limitations: + +1. If the network uci defines IPv4 address with the primary config interface secion, then its only allowed to have one IPv4 address with the mapped IP.Interface. instance, any addition of IPv4Address in the same section will result into a fault <9001>. + +2. If the network uci defines IPv6 address with the primary config interface secion, then its only allowed to have one IPv6 address with the mapped IP.Interface. instance, any addition of IPv6Address in the same section will result into a fault <9001> + +3. If Data Model shows IP.Interface.{i}.IPv4Address.{i}. instance with DHCP type, then its not allowed to disable this IP.Interface.{i}.IPv4Address.{i}. instance. + +4. If Data Model shows IP.Interface.{i}.IPv6Address.{i}. instance with DHCP type, then its not allowed to disable this IP.Interface.{i}.IPv6Address.{i}. instance. + + +# Solutions: + +1. If someone wants to configure IP.Interface. instance with different IPv4/6 addresses, it should **remove** the default IP.Interface. instance and trying to define their IP.Interface. instance with needed IPv4Address or IPv6Address instances. + +> Note1: Before setting LowerLayers of new IP.Interface. instance, please make sure there is no other IP.Interface instance links to the same object that you want to set. Otherwise, the new IP.Interface. instance will be disappered. + +> Note2: We have supported now both alias and device name. + +2. Each data model object which maps to uci network interface section should create its network section. + +3. We need to have an internal migration mechanism in bbfdm to migrate everything added by other apps to be alligned with new design. + +``` +config interface 'wan config interface 'wan' + option proto 'dhcp' option proto 'dhcp' + option device 'ethx' option device 'ethx' + ==========> +config interface 'wan6' config interface 'wan6' + option proto 'dhcpv6' option proto 'dhcpv6' + option device 'ethx' option device 'ethx' + + config interface 'ip_iface_x' + option proto 'none' + option device 'ethx' + +``` + +# Explaination with uci network config: + +### Adding an IP.Interface. instance + +``` +config interface 'iface_x' ---> Device.IP.Interface.X.Name + option proto 'none' + option disabled '1' ---> Device.IP.Interface.X.Enable + option device 'iface_x' ---> Device.IP.Interface.X.LowerLayers + option ula '' ---> Device.IP.Interface.X.ULAEnable + option mtu '' ---> Device.IP.Interface.X.MaxMTUSize + +``` + +### Adding a static IP.Interface.X.IPv4Address. instance + +``` +config interface 'iface_x_ipv4_x' + option proto 'static' ---> Device.IP.Interface.X.IPv4Address.X.AddressingType + option disabled '1' ---> Device.IP.Interface.X.IPv4Address.X.Enable + option device '@iface_x' + option ipaddr '' ---> Device.IP.Interface.X.IPv4Address.X.IPAddress + option netmask '' ---> Device.IP.Interface.X.IPv4Address.X.SubnetMask + +``` + +### Adding a static IP.Interface.X.IPv6Address. instance + +``` +config interface 'iface_x_ipv6_x' + option proto 'static' ---> Device.IP.Interface.X.IPv6Address.X.Origin + option disabled '1' ---> Device.IP.Interface.X.IPv6Address.X.Enable + option device '@iface_x' + option ipaddr '' ---> Device.IP.Interface.X.IPv6Address.X.IPAddress + +``` + +### Adding a DHCPv4.Client. instance + +``` +config interface 'dhcpv4_x' + option proto 'dhcp' + option disabled '1' ---> Device.DHCPv4.Client.X.Enable + option device '' ---> Device.DHCPv4.Client.X.Interface + +``` + +### Adding a DHCPv6.Client. instance + +``` +config interface 'dhcpv6_x' + option proto 'dhcpv6' + option disabled '1' ---> Device.DHCPv6.Client.X.Enable + option device '' ---> Device.DHCPv6.Client.X.Interface + +``` + +### Adding a PPP.Interface. instance + +``` +config interface 'ppp_x' ---> Device.PPP.Interface.X.Name + option proto 'ppp' + option disabled '1' ---> Device.PPP.Interface.X.Enable + option device '' ---> Device.PPP.Interface.X.LowerLayers + +``` diff --git a/libbbfdm/dmtree/tr181/dhcpv4.c b/libbbfdm/dmtree/tr181/dhcpv4.c index 6d8d3887..94cdf542 100644 --- a/libbbfdm/dmtree/tr181/dhcpv4.c +++ b/libbbfdm/dmtree/tr181/dhcpv4.c @@ -46,11 +46,6 @@ struct client_options_args { char *value; }; -struct dhcp_client_args { - struct uci_section *iface_s; - struct uci_section *dmmap_s; -}; - struct dhcp_client_option_args { struct uci_section *client_sect; struct uci_section *dmmap_sect; @@ -173,92 +168,6 @@ int get_value_in_mac_format(struct uci_section *s, char *option_name, bool type, return 0; } -static bool is_dhcp_section_exist(char *dmmap_file, char *sec_name) -{ - struct uci_section *s = NULL; - - uci_path_foreach_option_eq(bbfdm, dmmap_file, "interface", "iface_name", sec_name, s) { - return true; - } - - return false; -} - -static void dmmap_synchronizeDHCPv4Client(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_dhcp_client", "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 (DM_LSTRCMP(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 (DM_LSTRCMP(proto, "dhcp") != 0) - continue; - - if (is_dhcp_section_exist("dmmap_dhcp_client", section_name(s))) - continue; - - dmuci_add_section_bbfdm("dmmap_dhcp_client", "interface", &ppp_s); - dmuci_set_value_by_section(ppp_s, "iface_name", section_name(s)); - dmuci_set_value_by_section(ppp_s, "dhcp_client_key", section_name(s)); - } -} - -static void dmmap_synchronizeDHCPv4RelayForwarding(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_dhcp_relay", "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 (DM_LSTRCMP(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 (DM_LSTRCMP(proto, "relay") != 0) - continue; - - if (is_dhcp_section_exist("dmmap_dhcp_relay", section_name(s))) - continue; - - dmuci_add_section_bbfdm("dmmap_dhcp_relay", "interface", &ppp_s); - dmuci_set_value_by_section(ppp_s, "iface_name", section_name(s)); - } -} - static void dhcp_leases_load(struct list_head *head) { FILE *f = fopen(DHCP_LEASES_FILE, "r"); @@ -716,39 +625,31 @@ static int browseDHCPv4ServerPoolClientOptionInst(struct dmctx *dmctx, DMNODE *p /*#Device.DHCPv4.Client.{i}.!UCI:network/interface/dmmap_dhcp_client*/ static int browseDHCPv4ClientInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) { - struct dhcp_client_args curr_dhcp_client_args = {0}; - struct uci_section *s = NULL; + struct dmmap_dup *p = NULL; char *inst = NULL; + LIST_HEAD(dup_list); - dmmap_synchronizeDHCPv4Client(dmctx, parent_node, prev_data, prev_instance); - uci_path_foreach_sections(bbfdm, "dmmap_dhcp_client", "interface", s) { - struct uci_section *iface_s = NULL; - char *iface_name = NULL; + synchronize_specific_config_sections_with_dmmap_eq("network", "interface", "dmmap_dhcp_client", "proto", "dhcp", &dup_list); + list_for_each_entry(p, &dup_list, list) { - 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); + inst = handle_instance(dmctx, parent_node, p->dmmap_section, "bbf_dhcpv4client_instance", "bbf_dhcpv4client_alias"); - curr_dhcp_client_args.iface_s = iface_s; - curr_dhcp_client_args.dmmap_s = s; - - inst = handle_instance(dmctx, parent_node, s, "bbf_dhcpv4client_instance", "bbf_dhcpv4client_alias"); - - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_dhcp_client_args, inst) == DM_STOP) + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)p, inst) == DM_STOP) break; } + free_dmmap_config_dup_list(&dup_list); return 0; } static int browseDHCPv4ClientSentOptionInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) { - struct uci_section *dhcp_client_s = ((struct dhcp_client_args *)prev_data)->iface_s; + struct uci_section *dhcp_client_s = ((struct dmmap_dup *)prev_data)->config_section; struct dhcp_client_option_args dhcp_client_opt_args = {0}; struct uci_section *dhcp_client_dmmap_s = NULL; char *dhcp_client_key = NULL; char *inst = NULL; - dmuci_get_value_by_section_string(((struct dhcp_client_args *)prev_data)->dmmap_s, "dhcp_client_key", &dhcp_client_key); + dmuci_get_value_by_section_string(((struct dmmap_dup *)prev_data)->dmmap_section, "dhcp_client_key", &dhcp_client_key); if (dhcp_client_s) { size_t length = 0, length2 = 0; @@ -837,13 +738,13 @@ static int browseDHCPv4ClientSentOptionInst(struct dmctx *dmctx, DMNODE *parent_ static int browseDHCPv4ClientReqOptionInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) { - struct uci_section *dhcp_client_s = ((struct dhcp_client_args *)prev_data)->iface_s; + struct uci_section *dhcp_client_s = ((struct dmmap_dup *)prev_data)->config_section; struct uci_section *dhcp_client_dmmap_s = NULL; struct dhcp_client_option_args dhcp_client_opt_args = {0}; char *dhcp_client_key = NULL; char *inst = NULL; - dmuci_get_value_by_section_string(((struct dhcp_client_args *)prev_data)->dmmap_s, "dhcp_client_key", &dhcp_client_key); + dmuci_get_value_by_section_string(((struct dmmap_dup *)prev_data)->dmmap_section, "dhcp_client_key", &dhcp_client_key); if (dhcp_client_s) { char **reqtopts = NULL; @@ -936,27 +837,19 @@ static int browseDHCPv4ServerPoolOptionInst(struct dmctx *dmctx, DMNODE *parent_ /*#Device.DHCPv4.Relay.Forwarding.{i}.!UCI:network/interface/dmmap_dhcp_relay*/ static int browseDHCPv4RelayForwardingInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) { - struct dhcp_client_args curr_dhcp_relay_args = {0}; - struct uci_section *dmmap_s = NULL; + struct dmmap_dup *p = NULL; char *inst = NULL; + LIST_HEAD(dup_list); - dmmap_synchronizeDHCPv4RelayForwarding(dmctx, parent_node, prev_data, prev_instance); - uci_path_foreach_sections(bbfdm, "dmmap_dhcp_relay", "interface", dmmap_s) { - struct uci_section *iface_s = NULL; - char *iface_name = NULL; + synchronize_specific_config_sections_with_dmmap_eq("network", "interface", "dmmap_dhcp_relay", "proto", "relay", &dup_list); + list_for_each_entry(p, &dup_list, list) { - dmuci_get_value_by_section_string(dmmap_s, "iface_name", &iface_name); - if (DM_STRLEN(iface_name)) - get_config_section_of_dmmap_section("network", "interface", iface_name, &iface_s); + inst = handle_instance(dmctx, parent_node, p->dmmap_section, "bbf_dhcpv4relay_instance", "bbf_dhcpv4relay_alias"); - curr_dhcp_relay_args.iface_s = iface_s; - curr_dhcp_relay_args.dmmap_s = dmmap_s; - - inst = handle_instance(dmctx, parent_node, dmmap_s, "bbf_dhcpv4relay_instance", "bbf_dhcpv4relay_alias"); - - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_dhcp_relay_args, inst) == DM_STOP) + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)p, inst) == DM_STOP) break; } + free_dmmap_config_dup_list(&dup_list); return 0; } @@ -1052,16 +945,18 @@ static int delObjDHCPv4ServerPoolStaticAddress(char *refparam, struct dmctx *ctx static int addObjDHCPv4Client(char *refparam, struct dmctx *ctx, void *data, char **instance) { - struct uci_section *dmmap_sect = NULL; + struct uci_section *s = NULL, *dmmap_sect = NULL; char dhcp_client_key[32] = {0}; snprintf(dhcp_client_key, sizeof(dhcp_client_key), "dhcp_client_%s", *instance); + dmuci_add_section("network", "interface", &s); + dmuci_rename_section_by_section(s, dhcp_client_key); + dmuci_set_value_by_section(s, "disabled", "1"); + dmuci_set_value_by_section(s, "proto", "dhcp"); + dmuci_add_section_bbfdm("dmmap_dhcp_client", "interface", &dmmap_sect); - dmuci_set_value_by_section(dmmap_sect, "proto", "dhcp"); - dmuci_set_value_by_section(dmmap_sect, "disabled", "1"); - dmuci_set_value_by_section(dmmap_sect, "dhcp_client_key", dhcp_client_key); - dmuci_set_value_by_section(dmmap_sect, "added_by_controller", "1"); + dmuci_set_value_by_section(dmmap_sect, "section_name", dhcp_client_key); dmuci_set_value_by_section(dmmap_sect, "bbf_dhcpv4client_instance", *instance); return 0; } @@ -1073,16 +968,7 @@ static int delObjDHCPv4Client(char *refparam, struct dmctx *ctx, void *data, cha switch (del_action) { case DEL_INST: - dmuci_get_value_by_section_string(((struct dhcp_client_args *)data)->dmmap_s, "dhcp_client_key", &dhcp_client_key); - - if (((struct dhcp_client_args *)data)->iface_s) { - dmuci_set_value_by_section(((struct dhcp_client_args *)data)->iface_s, "proto", "none"); - dmuci_set_value_by_section(((struct dhcp_client_args *)data)->iface_s, "clientid", ""); - dmuci_set_value_by_section(((struct dhcp_client_args *)data)->iface_s, "vendorid", ""); - dmuci_set_value_by_section(((struct dhcp_client_args *)data)->iface_s, "hostname", ""); - dmuci_set_value_by_section(((struct dhcp_client_args *)data)->iface_s, "sendopts", ""); - dmuci_set_value_by_section(((struct dhcp_client_args *)data)->iface_s, "reqopts", ""); - } + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->dmmap_section, "dhcp_client_key", &dhcp_client_key); uci_path_foreach_option_eq_safe(bbfdm, "dmmap_dhcp_client", "send_option", "dhcp_client_key", dhcp_client_key, stmp, s) { dmuci_delete_by_section(s, NULL, NULL); @@ -1092,27 +978,16 @@ static int delObjDHCPv4Client(char *refparam, struct dmctx *ctx, void *data, cha dmuci_delete_by_section(s, NULL, NULL); } - dmuci_delete_by_section(((struct dhcp_client_args *)data)->dmmap_s, NULL, NULL); + dmuci_delete_by_section(((struct dmmap_dup *)data)->config_section, NULL, NULL); + dmuci_delete_by_section(((struct dmmap_dup *)data)->dmmap_section, NULL, NULL); break; case DEL_ALL: - uci_path_foreach_sections_safe(bbfdm, "dmmap_dhcp_client", "interface", stmp, s) { + uci_foreach_option_eq_safe("network", "interface", "proto", "dhcp", stmp, s) { struct uci_section *ss = NULL, *sstmp = NULL; - struct uci_section *iface_s = NULL; - char *iface_name = NULL; + struct uci_section *dmmap_s = NULL; - dmuci_get_value_by_section_string(s, "dhcp_client_key", &dhcp_client_key); - 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_set_value_by_section(iface_s, "proto", "none"); - dmuci_set_value_by_section(s, "clientid", ""); - dmuci_set_value_by_section(s, "vendorid", ""); - dmuci_set_value_by_section(s, "hostname", ""); - dmuci_set_value_by_section(s, "sendopts", ""); - dmuci_set_value_by_section(s, "reqopts", ""); - } + get_dmmap_section_of_config_section("dmmap_dhcp_client", "interface", section_name(s), &dmmap_s); + dmuci_get_value_by_section_string(dmmap_s, "dhcp_client_key", &dhcp_client_key); uci_path_foreach_option_eq_safe(bbfdm, "dmmap_dhcp_client", "send_option", "dhcp_client_key", dhcp_client_key, sstmp, ss) { dmuci_delete_by_section(ss, NULL, NULL); @@ -1123,6 +998,7 @@ static int delObjDHCPv4Client(char *refparam, struct dmctx *ctx, void *data, cha } dmuci_delete_by_section(s, NULL, NULL); + dmuci_delete_by_section(dmmap_s, NULL, NULL); } break; } @@ -1131,11 +1007,10 @@ static int delObjDHCPv4Client(char *refparam, struct dmctx *ctx, void *data, cha static int addObjDHCPv4ClientSentOption(char *refparam, struct dmctx *ctx, void *data, char **instance) { - struct dhcp_client_args *dhcp_client_args = (struct dhcp_client_args *)data; struct uci_section *dmmap_sect = NULL; char *dhcp_client_key = NULL; - dmuci_get_value_by_section_string(dhcp_client_args->dmmap_s, "dhcp_client_key", &dhcp_client_key); + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->dmmap_section, "dhcp_client_key", &dhcp_client_key); char *option_tag = generate_tag_option("dmmap_dhcp_client", "send_option", "dhcp_client_key", dhcp_client_key, "option_tag"); dmuci_add_section_bbfdm("dmmap_dhcp_client", "send_option", &dmmap_sect); @@ -1149,40 +1024,36 @@ static int addObjDHCPv4ClientSentOption(char *refparam, struct dmctx *ctx, void static int delObjDHCPv4ClientSentOption(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action) { struct uci_section *s = NULL, *stmp = NULL; - char *dhcp_client_key = NULL; + char *dhcp_client_key = NULL, *option_name = NULL; switch (del_action) { case DEL_INST: - if (((struct dhcp_client_option_args *)data)->client_sect) { - char *option_name = get_dhcp_option_name(DM_STRTOL(((struct dhcp_client_option_args *)data)->option_tag)); + option_name = get_dhcp_option_name(DM_STRTOL(((struct dhcp_client_option_args *)data)->option_tag)); - if (DM_LSTRCMP(option_name, "sendopts") == 0) { - char *sendopts = NULL; + if (DM_LSTRCMP(option_name, "sendopts") == 0) { + char *sendopts = NULL; - dmuci_get_value_by_section_string(((struct dhcp_client_option_args *)data)->client_sect, "sendopts", &sendopts); - if (sendopts && *sendopts) { - char tag_value[128] = {0}; + dmuci_get_value_by_section_string(((struct dhcp_client_option_args *)data)->client_sect, "sendopts", &sendopts); + if (sendopts && *sendopts) { + char tag_value[128] = {0}; - snprintf(tag_value, sizeof(tag_value), "%s:%s", ((struct dhcp_client_option_args *)data)->option_tag, ((struct dhcp_client_option_args *)data)->value); - remove_elt_from_str_list(&sendopts, tag_value); - dmuci_set_value_by_section(((struct dhcp_client_option_args *)data)->client_sect, "sendopts", sendopts); - } - } else { - dmuci_set_value_by_section(((struct dhcp_client_option_args*) data)->client_sect, option_name, ""); + snprintf(tag_value, sizeof(tag_value), "%s:%s", ((struct dhcp_client_option_args *)data)->option_tag, ((struct dhcp_client_option_args *)data)->value); + remove_elt_from_str_list(&sendopts, tag_value); + dmuci_set_value_by_section(((struct dhcp_client_option_args *)data)->client_sect, "sendopts", sendopts); } + } else { + dmuci_set_value_by_section(((struct dhcp_client_option_args*) data)->client_sect, option_name, ""); } dmuci_delete_by_section(((struct dhcp_client_option_args *)data)->dmmap_sect, NULL, NULL); break; case DEL_ALL: - if (((struct dhcp_client_args *)data)->iface_s) { - dmuci_set_value_by_section(((struct dhcp_client_args *)data)->iface_s, "clientid", ""); - dmuci_set_value_by_section(((struct dhcp_client_args *)data)->iface_s, "vendorid", ""); - dmuci_set_value_by_section(((struct dhcp_client_args *)data)->iface_s, "hostname", ""); - dmuci_set_value_by_section(((struct dhcp_client_args *)data)->iface_s, "sendopts", ""); - } + dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "clientid", ""); + dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "vendorid", ""); + dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "hostname", ""); + dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "sendopts", ""); - dmuci_get_value_by_section_string(((struct dhcp_client_args *)data)->dmmap_s, "dhcp_client_key", &dhcp_client_key); + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->dmmap_section, "dhcp_client_key", &dhcp_client_key); uci_path_foreach_option_eq_safe(bbfdm, "dmmap_dhcp_client", "send_option", "dhcp_client_key", dhcp_client_key, stmp, s) { dmuci_delete_by_section(s, NULL, NULL); @@ -1194,11 +1065,10 @@ static int delObjDHCPv4ClientSentOption(char *refparam, struct dmctx *ctx, void static int addObjDHCPv4ClientReqOption(char *refparam, struct dmctx *ctx, void *data, char **instance) { - struct dhcp_client_args *dhcp_client_args = (struct dhcp_client_args *)data; struct uci_section *dmmap_sect = NULL; char *dhcp_client_key = NULL; - dmuci_get_value_by_section_string(dhcp_client_args->dmmap_s, "dhcp_client_key", &dhcp_client_key); + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->dmmap_section, "dhcp_client_key", &dhcp_client_key); char *option_tag = generate_tag_option("dmmap_dhcp_client", "req_option", "dhcp_client_key", dhcp_client_key, "option_tag"); dmuci_add_section_bbfdm("dmmap_dhcp_client", "req_option", &dmmap_sect); @@ -1212,27 +1082,21 @@ static int addObjDHCPv4ClientReqOption(char *refparam, struct dmctx *ctx, void * static int delObjDHCPv4ClientReqOption(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action) { struct uci_section *s = NULL, *stmp = NULL; - char *dhcp_client_key = NULL; + char *reqopts = NULL, *dhcp_client_key = NULL; switch (del_action) { case DEL_INST: - if (((struct dhcp_client_option_args *)data)->client_sect) { - char *reqopts = NULL; - - dmuci_get_value_by_section_string(((struct dhcp_client_option_args *)data)->client_sect, "reqopts", &reqopts); - if (reqopts && *reqopts) { - remove_elt_from_str_list(&reqopts, ((struct dhcp_client_option_args*) data)->option_tag); - dmuci_set_value_by_section(((struct dhcp_client_option_args *)data)->client_sect, "reqopts", reqopts); - } + dmuci_get_value_by_section_string(((struct dhcp_client_option_args *)data)->client_sect, "reqopts", &reqopts); + if (reqopts && *reqopts) { + remove_elt_from_str_list(&reqopts, ((struct dhcp_client_option_args*) data)->option_tag); + dmuci_set_value_by_section(((struct dhcp_client_option_args *)data)->client_sect, "reqopts", reqopts); } dmuci_delete_by_section(((struct dhcp_client_option_args *)data)->dmmap_sect, NULL, NULL); break; case DEL_ALL: - if (((struct dhcp_client_args *)data)->iface_s) - dmuci_set_value_by_section(((struct dhcp_client_args *)data)->iface_s, "reqopts", ""); - - dmuci_get_value_by_section_string(((struct dhcp_client_args *)data)->dmmap_s, "dhcp_client_key", &dhcp_client_key); + dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "reqopts", ""); + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->dmmap_section, "dhcp_client_key", &dhcp_client_key); uci_path_foreach_option_eq_safe(bbfdm, "dmmap_dhcp_client", "req_option", "dhcp_client_key", dhcp_client_key, stmp, s) { dmuci_delete_by_section(s, NULL, NULL); @@ -1284,12 +1148,18 @@ static int delObjDHCPv4ServerPoolOption(char *refparam, struct dmctx *ctx, void static int addObjDHCPv4RelayForwarding(char *refparam, struct dmctx *ctx, void *data, char **instance) { - struct uci_section *dmmap_sect = NULL; + struct uci_section *s = NULL, *dmmap_sect = NULL; + char dhcp_relay_key[32] = {0}; + + snprintf(dhcp_relay_key, sizeof(dhcp_relay_key), "dhcp_relay_%s", *instance); + + dmuci_add_section("network", "interface", &s); + dmuci_rename_section_by_section(s, dhcp_relay_key); + dmuci_set_value_by_section(s, "disabled", "1"); + dmuci_set_value_by_section(s, "proto", "relay"); dmuci_add_section_bbfdm("dmmap_dhcp_relay", "interface", &dmmap_sect); - dmuci_set_value_by_section(dmmap_sect, "proto", "relay"); - dmuci_set_value_by_section(dmmap_sect, "disabled", "1"); - dmuci_set_value_by_section(dmmap_sect, "added_by_controller", "1"); + dmuci_set_value_by_section(dmmap_sect, "section_name", dhcp_relay_key); dmuci_set_value_by_section(dmmap_sect, "bbf_dhcpv4relay_instance", *instance); return 0; } @@ -1300,24 +1170,17 @@ static int delObjDHCPv4RelayForwarding(char *refparam, struct dmctx *ctx, void * switch (del_action) { case DEL_INST: - dmuci_delete_by_section(((struct dhcp_client_args *)data)->dmmap_s, NULL, NULL); - - if (((struct dhcp_client_args *)data)->iface_s) - dmuci_set_value_by_section(((struct dhcp_client_args *)data)->iface_s, "proto", "none"); + dmuci_delete_by_section(((struct dmmap_dup *)data)->config_section, NULL, NULL); + dmuci_delete_by_section(((struct dmmap_dup *)data)->dmmap_section, NULL, NULL); break; case DEL_ALL: - uci_path_foreach_sections_safe(bbfdm, "dmmap_dhcp_relay", "interface", stmp, s) { - struct uci_section *iface_s = NULL; - char *iface_name = NULL; + uci_foreach_option_eq_safe("network", "interface", "proto", "relay", stmp, s) { + struct uci_section *dmmap_s = 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); + get_dmmap_section_of_config_section("dmmap_dhcp_relay", "interface", section_name(s), &dmmap_s); + dmuci_delete_by_section(dmmap_s, NULL, NULL); dmuci_delete_by_section(s, NULL, NULL); - - if (iface_s) - dmuci_set_value_by_section(iface_s, "proto", "none"); } break; } @@ -2107,17 +1970,15 @@ static int get_DHCPv4_ClientNumberOfEntries(char *refparam, struct dmctx *ctx, v /*#Device.DHCPv4.Client.{i}.Enable!UCI:network/interface,@i-1/disabled*/ static int get_DHCPv4Client_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - struct dhcp_client_args *dhcpv4_client = (struct dhcp_client_args *)data; char *disabled = NULL; - dmuci_get_value_by_section_string(dhcpv4_client->iface_s ? dhcpv4_client->iface_s : dhcpv4_client->dmmap_s, "disabled", &disabled); + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "disabled", &disabled); *value = (disabled[0] == '1') ? "0" : "1"; return 0; } static int set_DHCPv4Client_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - struct dhcp_client_args *dhcpv4_client = (struct dhcp_client_args *)data; bool b; switch (action) { @@ -2127,9 +1988,7 @@ static int set_DHCPv4Client_Enable(char *refparam, struct dmctx *ctx, void *data return 0; case VALUESET: string_to_bool(value, &b); - dmuci_set_value_by_section(dhcpv4_client->dmmap_s, "disabled", b ? "0" : "1"); - if (dhcpv4_client->iface_s) - dmuci_set_value_by_section(dhcpv4_client->iface_s, "disabled", b ? "0" : "1"); + dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "disabled", b ? "0" : "1"); return 0; } return 0; @@ -2137,7 +1996,7 @@ static int set_DHCPv4Client_Enable(char *refparam, struct dmctx *ctx, void *data static int get_DHCPv4Client_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - dmuci_get_value_by_section_string(((struct dhcp_client_args *)data)->dmmap_s, "bbf_dhcpv4client_alias", value); + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->dmmap_section, "bbf_dhcpv4client_alias", value); if ((*value)[0] == '\0') dmasprintf(value, "cpe-%s", instance); return 0; @@ -2151,7 +2010,7 @@ static int set_DHCPv4Client_Alias(char *refparam, struct dmctx *ctx, void *data, return FAULT_9007; break; case VALUESET: - dmuci_set_value_by_section(((struct dhcp_client_args *)data)->dmmap_s, "bbf_dhcpv4client_alias", value); + dmuci_set_value_by_section(((struct dmmap_dup *)data)->dmmap_section, "bbf_dhcpv4client_alias", value); break; } return 0; @@ -2159,19 +2018,16 @@ static int set_DHCPv4Client_Alias(char *refparam, struct dmctx *ctx, void *data, static int get_DHCPv4Client_Interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - struct dhcp_client_args *dhcpv4_client = (struct dhcp_client_args *)data; - char *iface_name = NULL; + char *device = NULL; - dmuci_get_value_by_section_string(dhcpv4_client->dmmap_s, "iface_name", &iface_name); - adm_entry_get_linker_param(ctx, "Device.IP.Interface.", iface_name, value); + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "device", &device); + if (DM_STRLEN(device) == 0) + return 0; - if (DM_STRLEN(*value) == 0 && dhcpv4_client->iface_s) { + if (device[0] == '@') { + adm_entry_get_linker_param(ctx, "Device.IP.Interface.", device + 1, value); + } else { struct uci_section *s = NULL; - char *device = NULL; - - dmuci_get_value_by_section_string(dhcpv4_client->iface_s, "device", &device); - if (DM_STRLEN(device) == 0) - return 0; uci_foreach_option_eq("network", "interface", "device", device, s) { adm_entry_get_linker_param(ctx, "Device.IP.Interface.", section_name(s), value); @@ -2179,17 +2035,13 @@ static int get_DHCPv4Client_Interface(char *refparam, struct dmctx *ctx, void *d return 0; } } + return 0; } static int set_DHCPv4Client_Interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - struct dhcp_client_args *dhcpv4_client = (struct dhcp_client_args *)data; char *allowed_objects[] = {"Device.IP.Interface.", NULL}; - struct uci_section *interface_s = NULL; - struct uci_section *option_s = NULL; - char *curr_iface_name = NULL; - char *dhcp_client_key = NULL; char *linker = NULL; switch (action) { @@ -2205,98 +2057,13 @@ static int set_DHCPv4Client_Interface(char *refparam, struct dmctx *ctx, void *d // Get linker adm_entry_get_linker_value(ctx, value, &linker); - dmuci_get_value_by_section_string(dhcpv4_client->dmmap_s, "dhcp_client_key", &dhcp_client_key); - dmuci_get_value_by_section_string(dhcpv4_client->dmmap_s, "iface_name", &curr_iface_name); - - // Get the corresponding network config - if (DM_STRLEN(linker)) - get_config_section_of_dmmap_section("network", "interface", linker, &interface_s); - - // break if interface section is not found - if (interface_s && (strcmp(section_name(interface_s), curr_iface_name) == 0)) - break; - - if (dhcpv4_client->iface_s) { - dmuci_set_value_by_section(dhcpv4_client->iface_s, "proto", "none"); - dmuci_set_value_by_section(dhcpv4_client->iface_s, "clientid", ""); - dmuci_set_value_by_section(dhcpv4_client->iface_s, "vendorid", ""); - dmuci_set_value_by_section(dhcpv4_client->iface_s, "hostname", ""); - dmuci_set_value_by_section(dhcpv4_client->iface_s, "sendopts", ""); - dmuci_set_value_by_section(dhcpv4_client->iface_s, "reqopts", ""); - } - if (!linker || *linker == 0) { - dmuci_set_value_by_section_bbfdm(dhcpv4_client->dmmap_s, "added_by_controller", "1"); - dmuci_set_value_by_section_bbfdm(dhcpv4_client->dmmap_s, "iface_name", ""); + dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "device", ""); } else { + char device[32] = {0}; - if (interface_s) { - struct uci_section *iface_s = NULL; - char iface_name[32]; - char buf[128] = {0}; - unsigned pos = 0; - char *proto = NULL; - - dmuci_get_value_by_section_string(interface_s, "proto", &proto); - if (DM_LSTRNCMP(proto, "dhcp", 4) == 0) { - char *dev_name = NULL; - - snprintf(iface_name, sizeof(iface_name), "%s_4", linker); - - dmuci_get_value_by_section_string(interface_s, "device", &dev_name); - - // Create a new interface section - dmuci_add_section("network", "interface", &iface_s); - dmuci_rename_section_by_section(iface_s, iface_name); - dmuci_set_value_by_section(iface_s, "device", dev_name); - } - - // Update proto option of config section - dmuci_set_value_by_section(iface_s ? iface_s : interface_s, "proto", "dhcp"); - - // Added the enabled options for sendopts - uci_path_foreach_option_eq(bbfdm, "dmmap_dhcp_client", "send_option", "dhcp_client_key", dhcp_client_key, option_s) { - char *enable = NULL; - - - dmuci_get_value_by_section_string(option_s, "enable", &enable); - if (DM_LSTRCMP(enable, "1") == 0) { - char *opt_tag = NULL; - char *opt_value = NULL; - - dmuci_get_value_by_section_string(option_s, "option_tag", &opt_tag); - dmuci_get_value_by_section_string(option_s, "option_value", &opt_value); - pos += snprintf(&buf[pos], sizeof(buf) - pos, "%s:%s ", opt_tag, opt_value); - } - } - - if (pos) { - buf[pos - 1] = 0; - dmuci_set_value_by_section(iface_s ? iface_s : interface_s, "sendopts", buf); - } - - // Added the enabled options for reqopts - pos = 0; - uci_path_foreach_option_eq(bbfdm, "dmmap_dhcp_client", "req_option", "dhcp_client_key", dhcp_client_key, option_s) { - char *enable = NULL; - - dmuci_get_value_by_section_string(option_s, "enable", &enable); - if (DM_LSTRCMP(enable, "1") == 0) { - char *opt_tag = NULL; - - dmuci_get_value_by_section_string(option_s, "option_tag", &opt_tag); - pos += snprintf(&buf[pos], sizeof(buf) - pos, "%s ", opt_tag); - } - } - - if (pos) { - buf[pos - 1] = 0; - dmuci_set_value_by_section(iface_s ? iface_s : interface_s, "reqopts", buf); - } - - // Update dmmap section - dmuci_set_value_by_section_bbfdm(dhcpv4_client->dmmap_s, "iface_name", iface_s ? iface_name : linker); - } + snprintf(device, sizeof(device), "@%s", linker); + dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "device", device); } break; } @@ -2314,20 +2081,14 @@ static int get_DHCPv4Client_Status(char *refparam, struct dmctx *ctx, void *data /*#Device.DHCPv4.Client.{i}.DHCPStatus!UBUS:network.interface/status/interface,@Name/ipv4-address[@i-1].address*/ static int get_DHCPv4Client_DHCPStatus(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - struct uci_section *dhcpv4_s = ((struct dhcp_client_args *)data)->iface_s; + char *iface_name = section_name(((struct dmmap_dup *)data)->config_section); + json_object *res = NULL; - if (dhcpv4_s) { - json_object *res = NULL; - - char *if_name = section_name(dhcpv4_s); - dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", if_name, String}}, 1, &res); - DM_ASSERT(res, *value = "Requesting"); - json_object *jobj = dmjson_select_obj_in_array_idx(res, 0, 1, "ipv4-address"); - char *ipaddr = dmjson_get_value(jobj, 1, "address"); - *value = (ipaddr[0] == '\0') ? "Requesting" : "Bound"; - } else { - *value = "Requesting"; - } + dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", iface_name, String}}, 1, &res); + DM_ASSERT(res, *value = "Requesting"); + json_object *jobj = dmjson_select_obj_in_array_idx(res, 0, 1, "ipv4-address"); + char *ipaddr = dmjson_get_value(jobj, 1, "address"); + *value = (ipaddr[0] == '\0') ? "Requesting" : "Bound"; return 0; } @@ -2339,7 +2100,7 @@ static int get_DHCPv4Client_Renew(char *refparam, struct dmctx *ctx, void *data, static int set_DHCPv4Client_Renew(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - struct uci_section *dhcpv4_s = ((struct dhcp_client_args *)data)->iface_s; + char *iface_name = NULL; bool b; switch (action) { @@ -2349,11 +2110,11 @@ static int set_DHCPv4Client_Renew(char *refparam, struct dmctx *ctx, void *data, break; case VALUESET: string_to_bool(value, &b); - if (!b) break; - if (dhcpv4_s) { - char *if_name = section_name(dhcpv4_s); - dmubus_call_set("network.interface", "renew", UBUS_ARGS{{"interface", if_name, String}}, 1); - } + if (!b) + break; + + iface_name = section_name(((struct dmmap_dup *)data)->config_section); + dmubus_call_set("network.interface", "renew", UBUS_ARGS{{"interface", iface_name, String}}, 1); break; } return 0; @@ -2361,46 +2122,39 @@ static int set_DHCPv4Client_Renew(char *refparam, struct dmctx *ctx, void *data, static int get_DHCPv4Client_IPAddress(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - struct uci_section *dhcpv4_s = ((struct dhcp_client_args *)data)->iface_s; char *ipaddr = ""; - if (dhcpv4_s) { + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "ipaddr", &ipaddr); + if (!ipaddr || *ipaddr == 0) { + json_object *res = NULL; - dmuci_get_value_by_section_string(((struct dhcp_client_args *)data)->iface_s, "ipaddr", &ipaddr); - if (!ipaddr || *ipaddr == 0) { - json_object *res = NULL; - - char *if_name = section_name(dhcpv4_s); - dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", if_name, String}}, 1, &res); - if (res) { - json_object *jobj = dmjson_select_obj_in_array_idx(res, 0, 1, "ipv4-address"); - ipaddr = dmjson_get_value(jobj, 1, "address"); - } + char *iface_name = section_name(((struct dmmap_dup *)data)->config_section); + dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", iface_name, String}}, 1, &res); + if (res) { + json_object *jobj = dmjson_select_obj_in_array_idx(res, 0, 1, "ipv4-address"); + ipaddr = dmjson_get_value(jobj, 1, "address"); } } + *value = ipaddr; return 0; } static int get_DHCPv4Client_SubnetMask(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - struct uci_section *dhcpv4_s = ((struct dhcp_client_args *)data)->iface_s; char *mask = ""; - if (dhcpv4_s) { + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "netmask", &mask); + if (!mask || *mask == 0) { + json_object *res = NULL; - dmuci_get_value_by_section_string(((struct dhcp_client_args *)data)->iface_s, "netmask", &mask); - if (!mask || *mask == 0) { - json_object *res = NULL; - - char *if_name = section_name(dhcpv4_s); - dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", if_name, String}}, 1, &res); - if (res) { - json_object *jobj = dmjson_select_obj_in_array_idx(res, 0, 1, "ipv4-address"); - mask = dmjson_get_value(jobj, 1, "mask"); - mask = (mask && *mask) ? cidr2netmask(DM_STRTOL(mask)) : ""; - } + char *iface_name = section_name(((struct dmmap_dup *)data)->config_section); + dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", iface_name, String}}, 1, &res); + if (res) { + json_object *jobj = dmjson_select_obj_in_array_idx(res, 0, 1, "ipv4-address"); + mask = dmjson_get_value(jobj, 1, "mask"); + mask = (mask && *mask) ? cidr2netmask(DM_STRTOL(mask)) : ""; } } @@ -2411,61 +2165,49 @@ static int get_DHCPv4Client_SubnetMask(char *refparam, struct dmctx *ctx, void * /*#Device.DHCPv4.Client.{i}.IPRouters!UBUS:network.interface/status/interface,@Name/route[@i-1].nexthop*/ static int get_DHCPv4Client_IPRouters(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - struct uci_section *dhcpv4_s = ((struct dhcp_client_args *)data)->iface_s; + json_object *res = NULL, *route = NULL, *arrobj = NULL; + unsigned pos = 0, idx = 0; + char list_ip[256] = {0}; - if (dhcpv4_s) { - json_object *res = NULL, *route = NULL, *arrobj = NULL; - unsigned pos = 0, idx = 0; - char list_ip[256] = {0}; + char *iface_name = section_name(((struct dmmap_dup *)data)->config_section); + dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", iface_name, String}}, 1, &res); + DM_ASSERT(res, *value = ""); - char *if_name = section_name(dhcpv4_s); - dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", if_name, String}}, 1, &res); - DM_ASSERT(res, *value = ""); - - list_ip[0] = 0; - dmjson_foreach_obj_in_array(res, arrobj, route, idx, 1, "route") { - char *nexthop = dmjson_get_value(route, 1, "nexthop"); - pos += snprintf(&list_ip[pos], sizeof(list_ip) - pos, "%s,", nexthop); - } - - /* cut tailing ',' */ - if (pos) - list_ip[pos - 1] = 0; - - *value = dmstrdup(list_ip); + list_ip[0] = 0; + dmjson_foreach_obj_in_array(res, arrobj, route, idx, 1, "route") { + char *nexthop = dmjson_get_value(route, 1, "nexthop"); + pos += snprintf(&list_ip[pos], sizeof(list_ip) - pos, "%s,", nexthop); } + + /* cut tailing ',' */ + if (pos) + list_ip[pos - 1] = 0; + + *value = dmstrdup(list_ip); return 0; } /*#Device.DHCPv4.Client.{i}.DNSServers!UBUS:network.interface/status/interface,@Name/dns-server*/ static int get_DHCPv4Client_DNSServers(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - struct uci_section *dhcpv4_s = ((struct dhcp_client_args *)data)->iface_s; + json_object *res = NULL; - if (dhcpv4_s) { - json_object *res = NULL; - - char *if_name = section_name(dhcpv4_s); - dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", if_name, String}}, 1, &res); - DM_ASSERT(res, *value = ""); - *value = dmjson_get_value_array_all(res, ",", 1, "dns-server"); - } + char *if_name = section_name(((struct dmmap_dup *)data)->config_section); + dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", if_name, String}}, 1, &res); + DM_ASSERT(res, *value = ""); + *value = dmjson_get_value_array_all(res, ",", 1, "dns-server"); return 0; } /*#Device.DHCPv4.Client.{i}.LeaseTimeRemaining!UBUS:network.interface/status/interface,@Name/data.leasetime*/ static int get_DHCPv4Client_LeaseTimeRemaining(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - struct uci_section *dhcpv4_s = ((struct dhcp_client_args *)data)->iface_s; + json_object *res = NULL; - if (dhcpv4_s) { - json_object *res = NULL; - - char *if_name = section_name(dhcpv4_s); - dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", if_name, String}}, 1, &res); - DM_ASSERT(res, *value = "0"); - *value = dmjson_get_value(res, 2, "data", "leasetime"); - } + char *if_name = section_name(((struct dmmap_dup *)data)->config_section); + dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", if_name, String}}, 1, &res); + DM_ASSERT(res, *value = "0"); + *value = dmjson_get_value(res, 2, "data", "leasetime"); return 0; } @@ -3090,17 +2832,15 @@ static int get_DHCPv4Relay_ForwardingNumberOfEntries(char *refparam, struct dmct /*#Device.DHCPv4.Relay.Forwarding.{i}.Enable!UCI:network/interface,@i-1/disabled*/ static int get_DHCPv4RelayForwarding_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - struct dhcp_client_args *dhcp_relay = (struct dhcp_client_args *)data; char *disabled = NULL; - dmuci_get_value_by_section_string(dhcp_relay->iface_s ? dhcp_relay->iface_s : dhcp_relay->dmmap_s, "disabled", &disabled); + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "disabled", &disabled); *value = (disabled[0] == '1') ? "0" : "1"; return 0; } static int set_DHCPv4RelayForwarding_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - struct dhcp_client_args *dhcp_relay = (struct dhcp_client_args *)data; bool b; switch (action) { @@ -3110,9 +2850,7 @@ static int set_DHCPv4RelayForwarding_Enable(char *refparam, struct dmctx *ctx, v return 0; case VALUESET: string_to_bool(value, &b); - dmuci_set_value_by_section(dhcp_relay->dmmap_s, "disabled", b ? "0" : "1"); - if (dhcp_relay->iface_s) - dmuci_set_value_by_section(dhcp_relay->iface_s, "disabled", b ? "0" : "1"); + dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "disabled", b ? "0" : "1"); break; } return 0; @@ -3128,7 +2866,7 @@ static int get_DHCPv4RelayForwarding_Status(char *refparam, struct dmctx *ctx, v static int get_DHCPv4RelayForwarding_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - dmuci_get_value_by_section_string(((struct dhcp_client_args *)data)->dmmap_s, "bbf_dhcpv4relay_alias", value); + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->dmmap_section, "bbf_dhcpv4relay_alias", value); if ((*value)[0] == '\0') dmasprintf(value, "cpe-%s", instance); return 0; @@ -3142,7 +2880,7 @@ static int set_DHCPv4RelayForwarding_Alias(char *refparam, struct dmctx *ctx, vo return FAULT_9007; break; case VALUESET: - dmuci_set_value_by_section(((struct dhcp_client_args *)data)->dmmap_s, "bbf_dhcpv4relay_alias", value); + dmuci_set_value_by_section(((struct dmmap_dup *)data)->dmmap_section, "bbf_dhcpv4relay_alias", value); break; } return 0; @@ -3150,19 +2888,30 @@ static int set_DHCPv4RelayForwarding_Alias(char *refparam, struct dmctx *ctx, vo static int get_DHCPv4RelayForwarding_Interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - char *iface_name = NULL; + char *device = NULL; + + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "device", &device); + if (DM_STRLEN(device) == 0) + return 0; + + if (device[0] == '@') { + adm_entry_get_linker_param(ctx, "Device.IP.Interface.", device + 1, value); + } else { + struct uci_section *s = NULL; + + uci_foreach_option_eq("network", "interface", "device", device, s) { + adm_entry_get_linker_param(ctx, "Device.IP.Interface.", section_name(s), value); + if (DM_STRLEN(*value)) + return 0; + } + } - dmuci_get_value_by_section_string(((struct dhcp_client_args *)data)->dmmap_s, "iface_name", &iface_name); - adm_entry_get_linker_param(ctx, "Device.IP.Interface.", iface_name, value); return 0; } static int set_DHCPv4RelayForwarding_Interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - struct dhcp_client_args *dhcp_relay = (struct dhcp_client_args *)data; char *allowed_objects[] = {"Device.IP.Interface.", NULL}; - struct uci_section *interface_s = NULL; - char *curr_iface_name = NULL; char *linker = NULL; switch (action) { @@ -3178,27 +2927,13 @@ static int set_DHCPv4RelayForwarding_Interface(char *refparam, struct dmctx *ctx // Get linker adm_entry_get_linker_value(ctx, value, &linker); - dmuci_get_value_by_section_string(dhcp_relay->dmmap_s, "iface_name", &curr_iface_name); - - // Get the corresponding network config - if (linker && *linker != 0) - get_config_section_of_dmmap_section("network", "interface", linker, &interface_s); - - // break if interface section is not found - if (interface_s && (strcmp(section_name(interface_s), curr_iface_name) == 0)) - break; - - dmuci_set_value_by_section(dhcp_relay->iface_s, "proto", "none"); - if (!linker || *linker == 0) { - dmuci_set_value_by_section_bbfdm(dhcp_relay->dmmap_s, "added_by_controller", "1"); - dmuci_set_value_by_section_bbfdm(dhcp_relay->dmmap_s, "iface_name", ""); + dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "device", ""); } else { - // Update proto option of config section - dmuci_set_value_by_section(interface_s, "proto", "relay"); + char device[32] = {0}; - // Update dmmap section - dmuci_set_value_by_section_bbfdm(dhcp_relay->dmmap_s, "iface_name", linker); + snprintf(device, sizeof(device), "@%s", linker); + dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "device", device); } break; } @@ -3208,24 +2943,21 @@ static int set_DHCPv4RelayForwarding_Interface(char *refparam, struct dmctx *ctx /*#Device.DHCPv4.Relay.Forwarding.{i}.VendorClassID!UCI:network/interface,@i-1/vendorclass*/ static int get_DHCPv4RelayForwarding_VendorClassID(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - struct uci_section *dhcp_relay_s = ((struct dhcp_client_args *)data)->iface_s; + char *relay_network = NULL; - if (dhcp_relay_s) { - char *relay_network = NULL; + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "network", &relay_network); + char *dhcp_network = (DM_STRLEN(relay_network)) ? get_dhcp_network_from_relay_list(relay_network) : NULL; + struct uci_section *ven_class_s = (DM_STRLEN(dhcp_network)) ? get_dhcp_classifier("vendorclass", dhcp_network) : NULL; - dmuci_get_value_by_section_string(dhcp_relay_s, "network", &relay_network); - char *dhcp_network = (DM_STRLEN(relay_network)) ? get_dhcp_network_from_relay_list(relay_network) : NULL; - struct uci_section *ven_class_s = (DM_STRLEN(dhcp_network)) ? get_dhcp_classifier("vendorclass", dhcp_network) : NULL; + if (ven_class_s) + dmuci_get_value_by_section_string(ven_class_s, "vendorclass", value); - if (ven_class_s) - dmuci_get_value_by_section_string(ven_class_s, "vendorclass", value); - } return 0; } static int set_DHCPv4RelayForwarding_VendorClassID(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - struct uci_section *dhcp_relay_s = ((struct dhcp_client_args *)data)->iface_s; + char *relay_network = NULL; switch (action) { case VALUECHECK: @@ -3233,16 +2965,13 @@ static int set_DHCPv4RelayForwarding_VendorClassID(char *refparam, struct dmctx return FAULT_9007; break; case VALUESET: - if (dhcp_relay_s) { - char *relay_network = NULL; + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "network", &relay_network); + char *dhcp_network = (DM_STRLEN(relay_network)) ? get_dhcp_network_from_relay_list(relay_network) : NULL; + struct uci_section *ven_class_s = (DM_STRLEN(dhcp_network)) ? get_dhcp_classifier("vendorclass", dhcp_network) : NULL; - dmuci_get_value_by_section_string(dhcp_relay_s, "network", &relay_network); - char *dhcp_network = (DM_STRLEN(relay_network)) ? get_dhcp_network_from_relay_list(relay_network) : NULL; - struct uci_section *ven_class_s = (DM_STRLEN(dhcp_network)) ? get_dhcp_classifier("vendorclass", dhcp_network) : NULL; + if (ven_class_s) + dmuci_set_value_by_section(ven_class_s, "vendorclass", value); - if (ven_class_s) - dmuci_set_value_by_section(ven_class_s, "vendorclass", value); - } break; } return 0; @@ -3251,18 +2980,15 @@ static int set_DHCPv4RelayForwarding_VendorClassID(char *refparam, struct dmctx /*#Device.DHCPv4.Relay.Forwarding.{i}.Chaddr!UCI:network/interface,@i-1/mac*/ static int get_DHCPv4RelayForwarding_Chaddr(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - struct uci_section *dhcp_relay_s = ((struct dhcp_client_args *)data)->iface_s; + char *relay_network = NULL; - if (dhcp_relay_s) { - char *relay_network = NULL; + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "network", &relay_network); + char *dhcp_network = (DM_STRLEN(relay_network)) ? get_dhcp_network_from_relay_list(relay_network) : NULL; + struct uci_section *mac_s = (DM_STRLEN(dhcp_network)) ? get_dhcp_classifier("mac", dhcp_network) : NULL; - dmuci_get_value_by_section_string(dhcp_relay_s, "network", &relay_network); - char *dhcp_network = (DM_STRLEN(relay_network)) ? get_dhcp_network_from_relay_list(relay_network) : NULL; - struct uci_section *mac_s = (DM_STRLEN(dhcp_network)) ? get_dhcp_classifier("mac", dhcp_network) : NULL; + if (mac_s) + dmuci_get_value_by_section_string(mac_s, "mac", value); - if (mac_s) - dmuci_get_value_by_section_string(mac_s, "mac", value); - } return 0; } @@ -3282,33 +3008,29 @@ static int set_DHCPv4RelayForwarding_Chaddr(char *refparam, struct dmctx *ctx, v /*#Device.DHCPv4.Relay.Forwarding.{i}.UserClassID!UCI:network/interface,@i-1/userclass*/ static int get_DHCPv4RelayForwarding_UserClassID(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - struct uci_section *dhcp_relay_s = ((struct dhcp_client_args *)data)->iface_s; + char *relay_network = NULL; - if (dhcp_relay_s) { - char *relay_network = NULL; + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "network", &relay_network); + char *dhcp_network = (DM_STRLEN(relay_network)) ? get_dhcp_network_from_relay_list(relay_network) : NULL; + struct uci_section *user_class_s = (DM_STRLEN(dhcp_network)) ? get_dhcp_classifier("userclass", dhcp_network) : NULL; - dmuci_get_value_by_section_string(dhcp_relay_s, "network", &relay_network); - char *dhcp_network = (DM_STRLEN(relay_network)) ? get_dhcp_network_from_relay_list(relay_network) : NULL; - struct uci_section *user_class_s = (DM_STRLEN(dhcp_network)) ? get_dhcp_classifier("userclass", dhcp_network) : NULL; + if (user_class_s) { + char hex[256] = {0}, *ucid = NULL; - if (user_class_s) { - char hex[256] = {0}, *ucid = NULL; + dmuci_get_value_by_section_string(user_class_s, "userclass", &ucid); - dmuci_get_value_by_section_string(user_class_s, "userclass", &ucid); + if (DM_STRLEN(ucid)) + convert_str_option_to_hex(77, ucid, hex, sizeof(hex)); - if (DM_STRLEN(ucid)) - convert_str_option_to_hex(77, ucid, hex, sizeof(hex)); - - *value = (*hex) ? dmstrdup(hex) : ""; - } + *value = (*hex) ? dmstrdup(hex) : ""; } + return 0; } static int set_DHCPv4RelayForwarding_UserClassID(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - struct uci_section *dhcp_relay_s = ((struct dhcp_client_args *)data)->iface_s; - + char *relay_network = NULL; switch (action) { case VALUECHECK: @@ -3316,19 +3038,15 @@ static int set_DHCPv4RelayForwarding_UserClassID(char *refparam, struct dmctx *c return FAULT_9007; break; case VALUESET: - if (dhcp_relay_s) { - char *relay_network = NULL; + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "network", &relay_network); + char *dhcp_network = (DM_STRLEN(relay_network)) ? get_dhcp_network_from_relay_list(relay_network) : NULL; + struct uci_section *user_class_s = (DM_STRLEN(dhcp_network)) ? get_dhcp_classifier("userclass", dhcp_network) : NULL; - dmuci_get_value_by_section_string(dhcp_relay_s, "network", &relay_network); - char *dhcp_network = (DM_STRLEN(relay_network)) ? get_dhcp_network_from_relay_list(relay_network) : NULL; - struct uci_section *user_class_s = (DM_STRLEN(dhcp_network)) ? get_dhcp_classifier("userclass", dhcp_network) : NULL; + if (user_class_s) { + char res[256] = {0}; - if (user_class_s) { - char res[256] = {0}; - - convert_hex_option_to_string(77, value, res, sizeof(res)); - dmuci_set_value_by_section(user_class_s, "userclass", res); - } + convert_hex_option_to_string(77, value, res, sizeof(res)); + dmuci_set_value_by_section(user_class_s, "userclass", res); } break; } @@ -3340,13 +3058,8 @@ static int set_DHCPv4RelayForwarding_UserClassID(char *refparam, struct dmctx *c *************************************************************/ static int operate_DHCPv4Client_Renew(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - struct uci_section *dhcpv4_s = ((struct dhcp_client_args *)data)->iface_s; - - if (dhcpv4_s) { - char *if_name = section_name(dhcpv4_s); - dmubus_call_set("network.interface", "renew", UBUS_ARGS{{"interface", if_name, String}}, 1); - } - + char *iface_name = section_name(((struct dmmap_dup *)data)->config_section); + dmubus_call_set("network.interface", "renew", UBUS_ARGS{{"interface", iface_name, String}}, 1); return 0; } diff --git a/libbbfdm/dmtree/tr181/dhcpv6.c b/libbbfdm/dmtree/tr181/dhcpv6.c index 82c3859f..cfd16955 100644 --- a/libbbfdm/dmtree/tr181/dhcpv6.c +++ b/libbbfdm/dmtree/tr181/dhcpv6.c @@ -12,13 +12,6 @@ #include "dhcpv4.h" #include "dhcpv6.h" - -struct dhcpv6_client_args -{ - struct uci_section *iface_s; - struct uci_section *dmmap_s; -}; - struct dhcpv6_args { struct dmmap_dup *dhcp_sections; @@ -42,54 +35,6 @@ struct dhcpv6_client_option_args { /************************************************************* * COMMON FUNCTIONS **************************************************************/ -static bool is_dhcpv6_client_section_exist(char *sec_name) -{ - struct uci_section *s = NULL; - - uci_path_foreach_option_eq(bbfdm, "dmmap_dhcpv6", "interface", "iface_name", sec_name, s) { - return true; - } - - return false; -} - -static void dmmap_synchronizeDHCPv6Client(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_dhcpv6", "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 (DM_LSTRCMP(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 (DM_LSTRCMP(proto, "dhcpv6") != 0) - continue; - - if (is_dhcpv6_client_section_exist(section_name(s))) - continue; - - dmuci_add_section_bbfdm("dmmap_dhcpv6", "interface", &ppp_s); - dmuci_set_value_by_section(ppp_s, "iface_name", section_name(s)); - } -} - static struct uci_section *get_dhcpv6_classifier(char *classifier_name, const char *network) { struct uci_section *s = NULL; @@ -140,27 +85,19 @@ static inline int init_dhcpv6_args(struct dhcpv6_args *args, struct dmmap_dup *s /*#Device.DHCPv6.Client.{i}.!UCI:network/interface/dmmap_dhcpv6*/ static int browseDHCPv6ClientInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) { - struct dhcpv6_client_args curr_dhcpv6_client_args = {0}; - struct uci_section *dmmap_s = NULL; + struct dmmap_dup *p = NULL; char *inst = NULL; + LIST_HEAD(dup_list); - dmmap_synchronizeDHCPv6Client(dmctx, parent_node, prev_data, prev_instance); - uci_path_foreach_sections(bbfdm, "dmmap_dhcpv6", "interface", dmmap_s) { - struct uci_section *iface_s = NULL; - char *iface_name = NULL; + synchronize_specific_config_sections_with_dmmap_eq("network", "interface", "dmmap_dhcpv6", "proto", "dhcpv6", &dup_list); + list_for_each_entry(p, &dup_list, list) { - dmuci_get_value_by_section_string(dmmap_s, "iface_name", &iface_name); - if (DM_STRLEN(iface_name)) - get_config_section_of_dmmap_section("network", "interface", iface_name, &iface_s); + inst = handle_instance(dmctx, parent_node, p->dmmap_section, "bbf_dhcpv6client_instance", "bbf_dhcpv6client_alias"); - curr_dhcpv6_client_args.iface_s = iface_s; - curr_dhcpv6_client_args.dmmap_s = dmmap_s; - - inst = handle_instance(dmctx, parent_node, dmmap_s, "bbf_dhcpv6client_instance", "bbf_dhcpv6client_alias"); - - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_dhcpv6_client_args, inst) == DM_STOP) + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)p, inst) == DM_STOP) break; } + free_dmmap_config_dup_list(&dup_list); return 0; } @@ -322,14 +259,18 @@ static int browseDHCPv6ServerPoolClientIPv6PrefixInst(struct dmctx *dmctx, DMNOD **************************************************************/ static int addObjDHCPv6Client(char *refparam, struct dmctx *ctx, void *data, char **instance) { - struct uci_section *dmmap_sect = NULL; + struct uci_section *s = NULL, *dmmap_sect = NULL; + char dhcpv6_client_key[32] = {0}; + + snprintf(dhcpv6_client_key, sizeof(dhcpv6_client_key), "dhcpv6_client_%s", *instance); + + dmuci_add_section("network", "interface", &s); + dmuci_rename_section_by_section(s, dhcpv6_client_key); + dmuci_set_value_by_section(s, "disabled", "1"); + dmuci_set_value_by_section(s, "proto", "dhcpv6"); dmuci_add_section_bbfdm("dmmap_dhcpv6", "interface", &dmmap_sect); - dmuci_set_value_by_section(dmmap_sect, "proto", "dhcpv6"); - dmuci_set_value_by_section(dmmap_sect, "disabled", "1"); - dmuci_set_value_by_section(dmmap_sect, "reqaddress", "force"); - dmuci_set_value_by_section(dmmap_sect, "reqprefix", "no"); - dmuci_set_value_by_section(dmmap_sect, "added_by_controller", "1"); + dmuci_set_value_by_section(dmmap_sect, "section_name", dhcpv6_client_key); dmuci_set_value_by_section(dmmap_sect, "bbf_dhcpv6client_instance", *instance); return 0; } @@ -340,30 +281,15 @@ static int delObjDHCPv6Client(char *refparam, struct dmctx *ctx, void *data, cha switch (del_action) { case DEL_INST: - dmuci_delete_by_section(((struct dhcpv6_client_args *)data)->dmmap_s, NULL, NULL); - - if (((struct dhcpv6_client_args *)data)->iface_s) { - dmuci_set_value_by_section(((struct dhcpv6_client_args *)data)->iface_s, "proto", "none"); - dmuci_set_value_by_section(((struct dhcpv6_client_args *)data)->iface_s, "reqaddress", ""); - dmuci_set_value_by_section(((struct dhcpv6_client_args *)data)->iface_s, "reqprefix", ""); - dmuci_set_value_by_section(((struct dhcpv6_client_args *)data)->iface_s, "reqopts", ""); - } + dmuci_delete_by_section(((struct dmmap_dup *)data)->config_section, NULL, NULL); + dmuci_delete_by_section(((struct dmmap_dup *)data)->dmmap_section, NULL, NULL); break; case DEL_ALL: - uci_path_foreach_sections_safe(bbfdm, "dmmap_dhcpv6", "interface", stmp, s) { - struct uci_section *iface_s = NULL; - char *iface_name = NULL; + uci_foreach_option_eq_safe("network", "interface", "proto", "dhcp", stmp, s) { + struct uci_section *dmmap_s = 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); - - if (iface_s) { - dmuci_set_value_by_section(iface_s, "proto", "none"); - dmuci_set_value_by_section(iface_s, "reqaddress", ""); - dmuci_set_value_by_section(iface_s, "reqprefix", ""); - dmuci_set_value_by_section(iface_s, "reqopts", ""); - } + get_dmmap_section_of_config_section("dmmap_dhcpv6", "interface", section_name(s), &dmmap_s); + dmuci_delete_by_section(dmmap_s, NULL, NULL); dmuci_delete_by_section(s, NULL, NULL); } @@ -471,17 +397,15 @@ static int get_DHCPv6_ClientNumberOfEntries(char *refparam, struct dmctx *ctx, v /*#Device.DHCPv6.Client.{i}.Enable!UCI:network/interface,@i-1/disabled*/ static int get_DHCPv6Client_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - struct dhcpv6_client_args *dhcpv6_client = (struct dhcpv6_client_args *)data; char *disabled = NULL; - dmuci_get_value_by_section_string(dhcpv6_client->iface_s ? dhcpv6_client->iface_s : dhcpv6_client->dmmap_s, "disabled", &disabled); + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "disabled", &disabled); *value = (disabled[0] == '1') ? "0" : "1"; return 0; } static int set_DHCPv6Client_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - struct dhcpv6_client_args *dhcpv6_client = (struct dhcpv6_client_args *)data; bool b; switch (action) { @@ -491,9 +415,7 @@ static int set_DHCPv6Client_Enable(char *refparam, struct dmctx *ctx, void *data return 0; case VALUESET: string_to_bool(value, &b); - dmuci_set_value_by_section(dhcpv6_client->dmmap_s, "disabled", b ? "0" : "1"); - if (dhcpv6_client->iface_s) - dmuci_set_value_by_section(dhcpv6_client->iface_s, "disabled", b ? "0" : "1"); + dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "disabled", b ? "0" : "1"); return 0; } return 0; @@ -501,7 +423,7 @@ static int set_DHCPv6Client_Enable(char *refparam, struct dmctx *ctx, void *data static int get_DHCPv6Client_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - dmuci_get_value_by_section_string(((struct dhcpv6_client_args *)data)->dmmap_s, "bbf_dhcpv6client_alias", value); + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->dmmap_section, "bbf_dhcpv6client_alias", value); if ((*value)[0] == '\0') dmasprintf(value, "cpe-%s", instance); return 0; @@ -515,7 +437,7 @@ static int set_DHCPv6Client_Alias(char *refparam, struct dmctx *ctx, void *data, return FAULT_9007; break; case VALUESET: - dmuci_set_value_by_section(((struct dhcpv6_client_args *)data)->dmmap_s, "bbf_dhcpv6client_alias", value); + dmuci_set_value_by_section(((struct dmmap_dup *)data)->dmmap_section, "bbf_dhcpv6client_alias", value); break; } return 0; @@ -523,19 +445,16 @@ static int set_DHCPv6Client_Alias(char *refparam, struct dmctx *ctx, void *data, static int get_DHCPv6Client_Interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - struct dhcpv6_client_args *dhcpv6_client = (struct dhcpv6_client_args *)data; - char *iface_name = NULL; + char *device = NULL; - dmuci_get_value_by_section_string(dhcpv6_client->dmmap_s, "iface_name", &iface_name); - adm_entry_get_linker_param(ctx, "Device.IP.Interface.", iface_name, value); + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "device", &device); + if (DM_STRLEN(device) == 0) + return 0; - if (DM_STRLEN(*value) == 0 && dhcpv6_client->iface_s) { + if (device[0] == '@') { + adm_entry_get_linker_param(ctx, "Device.IP.Interface.", device + 1, value); + } else { struct uci_section *s = NULL; - char *device = NULL; - - dmuci_get_value_by_section_string(dhcpv6_client->iface_s, "device", &device); - if (DM_STRLEN(device) == 0) - return 0; uci_foreach_option_eq("network", "interface", "device", device, s) { adm_entry_get_linker_param(ctx, "Device.IP.Interface.", section_name(s), value); @@ -543,15 +462,13 @@ static int get_DHCPv6Client_Interface(char *refparam, struct dmctx *ctx, void *d return 0; } } + return 0; } static int set_DHCPv6Client_Interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - struct dhcpv6_client_args *dhcpv6_client = (struct dhcpv6_client_args *)data; char *allowed_objects[] = {"Device.IP.Interface.", NULL}; - struct uci_section *interface_s = NULL; - char *curr_iface_name = NULL; char *linker = NULL; switch (action) { @@ -567,64 +484,13 @@ static int set_DHCPv6Client_Interface(char *refparam, struct dmctx *ctx, void *d // Get linker adm_entry_get_linker_value(ctx, value, &linker); - dmuci_get_value_by_section_string(dhcpv6_client->dmmap_s, "iface_name", &curr_iface_name); - - // Get the corresponding network config - if (linker && *linker != 0) - get_config_section_of_dmmap_section("network", "interface", linker, &interface_s); - - // break if interface section is not found - if (interface_s && (strcmp(section_name(interface_s), curr_iface_name) == 0)) - break; - - if (dhcpv6_client->iface_s) { - dmuci_set_value_by_section(dhcpv6_client->iface_s, "proto", "none"); - dmuci_set_value_by_section(dhcpv6_client->iface_s, "reqaddress", ""); - dmuci_set_value_by_section(dhcpv6_client->iface_s, "reqprefix", ""); - dmuci_set_value_by_section(dhcpv6_client->iface_s, "reqopts", ""); - } - if (!linker || *linker == 0) { - dmuci_set_value_by_section_bbfdm(dhcpv6_client->dmmap_s, "added_by_controller", "1"); - dmuci_set_value_by_section_bbfdm(dhcpv6_client->dmmap_s, "iface_name", ""); + dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "device", ""); } else { - char *reqaddress = NULL; - char *reqprefix = NULL; - char *reqopts = NULL; + char device[32] = {0}; - // Get the current value of requested parameters - dmuci_get_value_by_section_string(dhcpv6_client->dmmap_s, "reqaddress", &reqaddress); - dmuci_get_value_by_section_string(dhcpv6_client->dmmap_s, "reqprefix", &reqprefix); - dmuci_get_value_by_section_string(dhcpv6_client->dmmap_s, "reqopts", &reqopts); - - if (interface_s) { - struct uci_section *iface_s = NULL; - char iface_name[32]; - char *proto = NULL; - - dmuci_get_value_by_section_string(interface_s, "proto", &proto); - if (DM_LSTRNCMP(proto, "dhcp", 4) == 0) { - char *dev_name = NULL; - - snprintf(iface_name, sizeof(iface_name), "%s_6", linker); - - dmuci_get_value_by_section_string(interface_s, "device", &dev_name); - - // Create a new interface section - dmuci_add_section("network", "interface", &iface_s); - dmuci_rename_section_by_section(iface_s, iface_name); - dmuci_set_value_by_section(iface_s, "device", dev_name); - } - - // Update proto option of config section - dmuci_set_value_by_section(iface_s ? iface_s : interface_s, "proto", "dhcpv6"); - dmuci_set_value_by_section(iface_s ? iface_s : interface_s, "reqaddress", reqaddress); - dmuci_set_value_by_section(iface_s ? iface_s : interface_s, "reqprefix", reqprefix); - dmuci_set_value_by_section(iface_s ? iface_s : interface_s, "reqopts", reqopts); - - // Update dmmap section - dmuci_set_value_by_section_bbfdm(dhcpv6_client->dmmap_s, "iface_name", iface_s ? iface_name : linker); - } + snprintf(device, sizeof(device), "@%s", linker); + dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "device", device); } break; } @@ -642,31 +508,26 @@ static int get_DHCPv6Client_Status(char *refparam, struct dmctx *ctx, void *data /*#Device.DHCPv6.Client.{i}.DUID!UBUS:network.interface/status/interface,@Name/data.passthru*/ static int get_DHCPv6Client_DUID(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - struct uci_section *dhcpv6_s = ((struct dhcpv6_client_args *)data)->iface_s; - if (dhcpv6_s) { - json_object *res = NULL; + json_object *res = NULL; - char *if_name = section_name(dhcpv6_s); - dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", if_name, String}}, 1, &res); - *value = res ? dmjson_get_value(res, 2, "data", "passthru") : ""; - } + char *iface_name = section_name(((struct dmmap_dup *)data)->config_section); + dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", iface_name, String}}, 1, &res); + *value = res ? dmjson_get_value(res, 2, "data", "passthru") : ""; return 0; } /*#Device.DHCPv6.Client.{i}.RequestAddresses!UCI:network/interface,@i-1/reqaddress*/ static int get_DHCPv6Client_RequestAddresses(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - struct dhcpv6_client_args *dhcpv6_client = (struct dhcpv6_client_args *)data; char *reqaddress = NULL; - dmuci_get_value_by_section_string(dhcpv6_client->iface_s ? dhcpv6_client->iface_s : dhcpv6_client->dmmap_s, "reqaddress", &reqaddress); - *value = (reqaddress && DM_LSTRCMP(reqaddress, "none") == 0) ? "0" : "1"; + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "reqaddress", &reqaddress); + *value = DM_LSTRCMP(reqaddress, "none") == 0 ? "0" : "1"; return 0; } static int set_DHCPv6Client_RequestAddresses(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - struct dhcpv6_client_args *dhcpv6_client = (struct dhcpv6_client_args *)data; bool b; switch (action) { @@ -676,9 +537,7 @@ static int set_DHCPv6Client_RequestAddresses(char *refparam, struct dmctx *ctx, return 0; case VALUESET: string_to_bool(value, &b); - dmuci_set_value_by_section(dhcpv6_client->dmmap_s, "reqaddress", b ? "force" : "none"); - if (dhcpv6_client->iface_s) - dmuci_set_value_by_section(dhcpv6_client->iface_s, "reqaddress", b ? "force" : "none"); + dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "reqaddress", b ? "force" : "none"); break; } return 0; @@ -687,17 +546,15 @@ static int set_DHCPv6Client_RequestAddresses(char *refparam, struct dmctx *ctx, /*#Device.DHCPv6.Client.{i}.RequestPrefixes!UCI:network/interface,@i-1/reqprefix*/ static int get_DHCPv6Client_RequestPrefixes(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - struct dhcpv6_client_args *dhcpv6_client = (struct dhcpv6_client_args *)data; char *reqprefix = NULL; - dmuci_get_value_by_section_string(dhcpv6_client->iface_s ? dhcpv6_client->iface_s : dhcpv6_client->dmmap_s, "reqprefix", &reqprefix); + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "reqprefix", &reqprefix); *value = (reqprefix && DM_LSTRCMP(reqprefix, "auto") == 0) ? "1" : "0"; return 0; } static int set_DHCPv6Client_RequestPrefixes(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - struct dhcpv6_client_args *dhcpv6_client = (struct dhcpv6_client_args *)data; bool b; switch (action) { @@ -707,9 +564,7 @@ static int set_DHCPv6Client_RequestPrefixes(char *refparam, struct dmctx *ctx, v return 0; case VALUESET: string_to_bool(value, &b); - dmuci_set_value_by_section(dhcpv6_client->dmmap_s, "reqprefix", b ? "auto" : "no"); - if (dhcpv6_client->iface_s) - dmuci_set_value_by_section(dhcpv6_client->iface_s, "reqprefix", b ? "auto" : "no"); + dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "reqprefix", b ? "auto" : "no"); return 0; } return 0; @@ -723,7 +578,7 @@ static int get_DHCPv6Client_Renew(char *refparam, struct dmctx *ctx, void *data, static int set_DHCPv6Client_Renew(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - struct uci_section *dhcpv6_s = ((struct dhcpv6_client_args *)data)->iface_s; + char *iface_name = NULL; bool b; switch (action) { @@ -733,11 +588,11 @@ static int set_DHCPv6Client_Renew(char *refparam, struct dmctx *ctx, void *data, break; case VALUESET: string_to_bool(value, &b); - if (!b) break; - if (dhcpv6_s) { - char *if_name = section_name(dhcpv6_s); - dmubus_call_set("network.interface", "renew", UBUS_ARGS{{"interface", if_name, String}}, 1); - } + if (!b) + break; + + iface_name = section_name(((struct dmmap_dup *)data)->config_section); + dmubus_call_set("network.interface", "renew", UBUS_ARGS{{"interface", iface_name, String}}, 1); break; } return 0; @@ -746,25 +601,19 @@ static int set_DHCPv6Client_Renew(char *refparam, struct dmctx *ctx, void *data, /*#Device.DHCPv6.Client.{i}.RequestedOptions!UCI:network/interface,@i-1/reqopts*/ static int get_DHCPv6Client_RequestedOptions(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - struct dhcpv6_client_args *dhcpv6_client = (struct dhcpv6_client_args *)data; - - dmuci_get_value_by_section_string(dhcpv6_client->iface_s ? dhcpv6_client->iface_s : dhcpv6_client->dmmap_s, "reqopts", value); + dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "reqopts", value); return 0; } static int set_DHCPv6Client_RequestedOptions(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - struct dhcpv6_client_args *dhcpv6_client = (struct dhcpv6_client_args *)data; - switch (action) { case VALUECHECK: if (dm_validate_unsignedInt_list(value, -1, -1, -1, RANGE_ARGS{{NULL,NULL}}, 1)) return FAULT_9007; break; case VALUESET: - dmuci_set_value_by_section(dhcpv6_client->dmmap_s, "reqopts", value); - if (dhcpv6_client->iface_s) - dmuci_set_value_by_section(dhcpv6_client->iface_s, "reqopts", value); + dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "reqopts", value); break; } return 0; @@ -1359,13 +1208,8 @@ static int set_DHCPv6ServerPoolOption_Value(char *refparam, struct dmctx *ctx, v *************************************************************/ static int operate_DHCPv6Client_Renew(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - struct uci_section *dhcpv6_s = ((struct dhcpv6_client_args *)data)->iface_s; - - if (dhcpv6_s) { - char *if_name = section_name(dhcpv6_s); - dmubus_call_set("network.interface", "renew", UBUS_ARGS{{"interface", if_name, String}}, 1); - } - + char *iface_name = section_name(((struct dmmap_dup *)data)->config_section); + dmubus_call_set("network.interface", "renew", UBUS_ARGS{{"interface", iface_name, String}}, 1); return 0; } diff --git a/libbbfdm/dmtree/tr181/interfacestack.c b/libbbfdm/dmtree/tr181/interfacestack.c index 79b8cc05..2cd08f29 100644 --- a/libbbfdm/dmtree/tr181/interfacestack.c +++ b/libbbfdm/dmtree/tr181/interfacestack.c @@ -124,19 +124,11 @@ int browseInterfaceStackInst(struct dmctx *dmctx, DMNODE *parent_node, void *pre /* Higher layers are Device.IP.Interface.{i}. */ uci_foreach_sections("network", "interface", s) { - char *proto = NULL; - char *device_s = NULL; char *value = NULL; bool found = false; char *device = get_device(section_name(s)); - dmuci_get_value_by_section_string(s, "proto", &proto); - dmuci_get_value_by_section_string(s, "device", &device_s); - - if (strcmp(section_name(s), "loopback") == 0 || - *proto == '\0' || - DM_STRCHR(device_s, '@') || - ip___is_ipinterface_exists(section_name(s), device_s)) + if (!ip___is_ipinterface_section(s)) continue; // The higher layer is Device.IP.Interface.{i}. @@ -150,7 +142,8 @@ int browseInterfaceStackInst(struct dmctx *dmctx, DMNODE *parent_node, void *pre snprintf(buf_higheralias, sizeof(buf_higheralias), "%s%s", *higheralias ? higheralias : *layer_inst ? "cpe-" : "", (*higheralias == '\0' && *layer_inst) ? layer_inst : ""); /* If the device value is empty, then get its value directly from device option */ - if (DM_STRLEN(device) == 0) device = device_s; + if (DM_STRLEN(device) == 0) + dmuci_get_value_by_section_string(s, "device", &device); if (DM_STRLEN(device) == 0) continue; diff --git a/libbbfdm/dmtree/tr181/ip.c b/libbbfdm/dmtree/tr181/ip.c index 28c1d4c6..b19bfe70 100644 --- a/libbbfdm/dmtree/tr181/ip.c +++ b/libbbfdm/dmtree/tr181/ip.c @@ -62,16 +62,12 @@ static int get_linker_ipv6_prefix(char *refparam, struct dmctx *dmctx, void *dat /************************************************************* * COMMON Functions **************************************************************/ -bool ip___is_ipinterface_exists(const char *sec_name, const char *device) +static bool ip___is_ipinterface_exists(const char *sec_name, const char *device) { struct uci_section *s = NULL; - char *curr_dev = NULL; - - if (DM_STRLEN(sec_name) == 0 || - DM_STRLEN(device) == 0) - return false; uci_foreach_sections("network", "interface", s) { + char *curr_dev = NULL; dmuci_get_value_by_section_string(s, "device", &curr_dev); if (DM_STRLEN(curr_dev) == 0 || @@ -93,6 +89,26 @@ bool ip___is_ipinterface_exists(const char *sec_name, const char *device) return false; } +bool ip___is_ipinterface_section(struct uci_section *iface_s) +{ + char *proto = NULL, *device = NULL; + + if (!iface_s) + return false; + + char *iface_name = section_name(iface_s); + if (DM_STRLEN(iface_name) == 0 || DM_STRCMP(iface_name, "loopback") == 0) + return false; + + dmuci_get_value_by_section_string(iface_s, "proto", &proto); + dmuci_get_value_by_section_string(iface_s, "device", &device); + + if (DM_STRLEN(device) == 0 || DM_STRLEN(proto) == 0 || *device == '@' || ip___is_ipinterface_exists(iface_name, device)) + return false; + + return true; +} + static int get_sysctl_disable_ipv6_per_device(const char *device, char **value) { char file[256]; @@ -465,38 +481,8 @@ static void delete_ip_intertace_instance(struct uci_section *s) dmuci_get_value_by_section_string(int_ss, "proto", &proto); - if (DM_LSTRCMP(proto, "dhcp") == 0) { - struct uci_section *dhcpv4_client_s = get_dup_section_in_dmmap_opt("dmmap_dhcp_client", "interface", "iface_name", section_name(int_ss)); - - if (dhcpv4_client_s) { - char *dhcp_client_key = NULL; - - dmuci_get_value_by_section_string(dhcpv4_client_s, "dhcp_client_key", &dhcp_client_key); - - /* Remove "DHCPv4.Client.{i}.ReqOption." sections related to this "IP.Interface." object */ - uci_path_foreach_option_eq_safe(bbfdm, "dmmap_dhcp_client", "req_option", "dhcp_client_key", dhcp_client_key, stmp, ss) { - dmuci_delete_by_section(ss, NULL, NULL); - } - - /* Remove "DHCPv4.Client.{i}.SentOption." sections related to this "IP.Interface." object */ - uci_path_foreach_option_eq_safe(bbfdm, "dmmap_dhcp_client", "send_option", "dhcp_client_key", dhcp_client_key, stmp, ss) { - dmuci_delete_by_section(ss, NULL, NULL); - } - - /* Remove "DHCPv4.Client." section related to this "IP.Interface." object */ - dmuci_delete_by_section(dhcpv4_client_s, NULL, NULL); - } - } - - if (DM_LSTRCMP(proto, "dhcpv6") == 0) { - struct uci_section *dhcpv6_client_s = get_dup_section_in_dmmap_opt("dmmap_dhcpv6", "interface", "iface_name", section_name(int_ss)); - - if (dhcpv6_client_s) { - - /* Remove "DHCPv6.Client." section related to this "IP.Interface." object */ - dmuci_delete_by_section(dhcpv6_client_s, NULL, NULL); - } - } + if (DM_LSTRNCMP(proto, "dhcp", 4) == 0) + dmuci_delete_by_section(int_ss, "device", NULL); if (DM_LSTRNCMP(proto, "ppp", 3) == 0) { struct uci_section *ppp_s = get_dup_section_in_dmmap_opt("dmmap_ppp", "interface", "iface_name", section_name(int_ss)); @@ -518,30 +504,7 @@ static void delete_ip_intertace_instance(struct uci_section *s) } } -static bool interface_section_with_dhcpv6_exists(struct uci_section *iface_s) -{ - struct uci_section *s = NULL; - char *iface_dev = NULL; - - dmuci_get_value_by_section_string(iface_s, "device", &iface_dev); - - uci_foreach_sections("network", "interface", s) { - char *device = NULL; - - dmuci_get_value_by_section_string(s, "device", &device); - if (DM_STRCMP(device, iface_dev) == 0) { - char *proto = NULL; - - dmuci_get_value_by_section_string(s, "proto", &proto); - if (DM_LSTRCMP(proto, "dhcpv6") == 0) - return true; - } - } - - return false; -} - -static int delObjIPInterfaceIPv6(void *data, unsigned char del_action, char *dmmap_file_name, char *section_type, char *option_name) +static int delObjIPInterfaceIPAddress(void *data, unsigned char del_action, char *dmmap_file_name, char *section_type, char *option_name) { struct uci_section *s = NULL, *stmp = NULL, *dmmap_s = NULL; char *proto, *device; @@ -550,11 +513,11 @@ static int delObjIPInterfaceIPv6(void *data, unsigned char del_action, char *dmm switch (del_action) { case DEL_INST: dmuci_get_value_by_section_string(((struct intf_ip_args *)data)->interface_sec, "proto", &proto); - if (DM_LSTRCMP(proto, "static") != 0 || interface_section_with_dhcpv6_exists(((struct intf_ip_args *)data)->interface_sec)) + if (DM_LSTRCMP(proto, "static") != 0) return FAULT_9001; dmuci_get_value_by_section_string(((struct intf_ip_args *)data)->dmmap_sec, "parent_section", &parent_section); - if (strcmp(parent_section, section_name(((struct intf_ip_args *)data)->interface_sec)) == 0) { + if (strcmp(parent_section, section_name(((struct intf_ip_args *)data)->interface_sec)) != 0) { dmuci_delete_by_section(((struct intf_ip_args *)data)->interface_sec, NULL, NULL); } else { dmuci_set_value_by_section(((struct intf_ip_args *)data)->interface_sec, option_name, ""); @@ -563,29 +526,26 @@ static int delObjIPInterfaceIPv6(void *data, unsigned char del_action, char *dmm dmuci_delete_by_section(((struct intf_ip_args *)data)->dmmap_sec, NULL, NULL); break; case DEL_ALL: - dmuci_get_value_by_section_string((struct uci_section *)data, "proto", &proto); - if (DM_LSTRCMP(proto, "static") != 0 || interface_section_with_dhcpv6_exists((struct uci_section *)data)) - return FAULT_9001; - dmuci_get_value_by_section_string((struct uci_section *)data, "device", &iface_dev); uci_foreach_sections_safe("network", "interface", stmp, s) { dmuci_get_value_by_section_string(s, "device", &device); + if (DM_STRCMP(device, iface_dev) != 0) + continue; + + dmuci_get_value_by_section_string(s, "proto", &proto); + if (DM_LSTRCMP(proto, "static") != 0) + return FAULT_9001; if (strcmp(section_name(s), section_name((struct uci_section *)data)) == 0) { - dmuci_set_value_by_section(s, option_name, ""); - - get_dmmap_section_of_config_section(dmmap_file_name, section_type, section_name(s), &dmmap_s); - dmuci_delete_by_section(dmmap_s, NULL, NULL); - } else if (DM_STRCMP(device, iface_dev) == 0) { - get_dmmap_section_of_config_section(dmmap_file_name, section_type, section_name(s), &dmmap_s); - dmuci_delete_by_section(dmmap_s, NULL, NULL); - dmuci_delete_by_section(s, NULL, NULL); } else { - continue; + dmuci_set_value_by_section(s, option_name, ""); } + + get_dmmap_section_of_config_section(dmmap_file_name, section_type, section_name(s), &dmmap_s); + dmuci_delete_by_section(dmmap_s, NULL, NULL); } break; } @@ -599,20 +559,13 @@ static int delObjIPInterfaceIPv6(void *data, unsigned char del_action, char *dmm static int browseIPInterfaceInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) { char *inst = NULL; - char *proto, *device; struct dmmap_dup *p = NULL; LIST_HEAD(dup_list); 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); - dmuci_get_value_by_section_string(p->config_section, "device", &device); - - if (strcmp(section_name(p->config_section), "loopback") == 0 || - *proto == '\0' || - DM_STRCHR(device, '@') || - ip___is_ipinterface_exists(section_name(p->config_section), device)) + if (!ip___is_ipinterface_section(p->config_section)) continue; inst = handle_instance(dmctx, parent_node, p->dmmap_section, "ip_int_instance", "ip_int_alias"); @@ -855,7 +808,7 @@ static int addObjIPInterface(char *refparam, struct dmctx *ctx, void *data, char // Network interface section dmuci_set_value("network", ip_name, "", "interface"); dmuci_set_value("network", ip_name, "proto", "none"); - dmuci_set_value("network", ip_name, "disabled", "1"); + dmuci_set_value("network", ip_name, "disabled", "0"); dmuci_set_value("network", ip_name, "device", ip_name); // Firewall zone section @@ -864,6 +817,7 @@ static int addObjIPInterface(char *refparam, struct dmctx *ctx, void *data, char dmuci_add_section_bbfdm("dmmap_network", "interface", &dmmap_ip_interface); dmuci_set_value_by_section(dmmap_ip_interface, "section_name", ip_name); dmuci_set_value_by_section(dmmap_ip_interface, "ip_int_instance", *instance); + dmuci_set_value_by_section(dmmap_ip_interface, "added_by_controller", "1"); return 0; } @@ -877,14 +831,8 @@ static int delObjIPInterface(char *refparam, struct dmctx *ctx, void *data, char break; case DEL_ALL: uci_foreach_sections_safe("network", "interface", stmp, s) { - char *proto, *device; - dmuci_get_value_by_section_string(s, "proto", &proto); - dmuci_get_value_by_section_string(s, "device", &device); - if (strcmp(section_name(s), "loopback") == 0 || - *proto == '\0' || - DM_STRCHR(device, '@') || - ip___is_ipinterface_exists(section_name(s), device)) + if (!ip___is_ipinterface_section(s)) continue; delete_ip_intertace_instance(s); @@ -896,37 +844,28 @@ static int delObjIPInterface(char *refparam, struct dmctx *ctx, void *data, char static int addObjIPInterfaceIPv4Address(char *refparam, struct dmctx *ctx, void *data, char **instance) { - char *ip_inst = NULL, ipv4_name[64] = {0}; + char *is_new_ip_int = NULL, *device = NULL, ipv4_name[64] = {0}; struct uci_section *dmmap_ip_interface = NULL, *dmmap_ip_interface_ipv4 = NULL; get_dmmap_section_of_config_section("dmmap_network", "interface", section_name((struct uci_section *)data), &dmmap_ip_interface); - dmuci_get_value_by_section_string(dmmap_ip_interface, "ip_int_instance", &ip_inst); + dmuci_get_value_by_section_string(dmmap_ip_interface, "added_by_controller", &is_new_ip_int); + if (DM_STRCMP(is_new_ip_int, "1") != 0) + return FAULT_9001; - if (DM_LSTRCMP(*instance, "1") != 0) { - struct uci_section *device_s = NULL; - char *device = NULL; - char *ipv6 = NULL; + snprintf(ipv4_name, sizeof(ipv4_name), "%s_ipv4_%s", section_name((struct uci_section *)data), *instance); + dmuci_get_value_by_section_string((struct uci_section *)data, "device", &device); - snprintf(ipv4_name, sizeof(ipv4_name), "iface%s_ipv4_%s", ip_inst, *instance); - dmuci_get_value_by_section_string((struct uci_section *)data, "device", &device); - dmuci_get_value_by_section_string((struct uci_section *)data, "ipv6", &ipv6); - device_s = get_dup_section_in_config_opt("network", "device", "name", device); + dmuci_set_value("network", ipv4_name, "", "interface"); + dmuci_set_value("network", ipv4_name, "device", device); + dmuci_set_value("network", ipv4_name, "proto", "static"); + dmuci_set_value("network", ipv4_name, "disabled", "1"); - dmuci_set_value("network", ipv4_name, "", "interface"); - dmuci_set_value("network", ipv4_name, "device", device); - dmuci_set_value("network", ipv4_name, "proto", "static"); - dmuci_set_value("network", ipv4_name, "disabled", "1"); - if (!device_s) dmuci_set_value("network", ipv4_name, "ipv6", ipv6); - - // Firewall : add this new interface to zone->network list - add_network_to_firewall_zone_network_list(section_name((struct uci_section *)data), ipv4_name); - } else { - dmuci_set_value_by_section((struct uci_section *)data, "proto", "static"); - } + // Firewall : add this new interface to zone->network list + add_network_to_firewall_zone_network_list(section_name((struct uci_section *)data), ipv4_name); dmuci_add_section_bbfdm("dmmap_network_ipv4", "intf_ipv4", &dmmap_ip_interface_ipv4); dmuci_set_value_by_section(dmmap_ip_interface_ipv4, "parent_section", section_name((struct uci_section *)data)); - dmuci_set_value_by_section(dmmap_ip_interface_ipv4, "section_name", (DM_LSTRCMP(*instance, "1") != 0) ? ipv4_name : section_name((struct uci_section *)data)); + dmuci_set_value_by_section(dmmap_ip_interface_ipv4, "section_name", ipv4_name); dmuci_set_value_by_section(dmmap_ip_interface_ipv4, "added_by_controller", "1"); dmuci_set_value_by_section(dmmap_ip_interface_ipv4, "ipv4_instance", *instance); return 0; @@ -934,76 +873,27 @@ static int addObjIPInterfaceIPv4Address(char *refparam, struct dmctx *ctx, void static int delObjIPInterfaceIPv4Address(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action) { - struct uci_section *s = NULL, *stmp = NULL, *dmmap_s = NULL; - char *proto, *parent_section, *device, *iface_dev; - - switch (del_action) { - case DEL_INST: - dmuci_get_value_by_section_string(((struct intf_ip_args *)data)->interface_sec, "proto", &proto); - if (DM_LSTRCMP(proto, "static") != 0) - return FAULT_9001; - - dmuci_get_value_by_section_string(((struct intf_ip_args *)data)->dmmap_sec, "parent_section", &parent_section); - if (strcmp(parent_section, section_name(((struct intf_ip_args *)data)->interface_sec)) != 0) { - dmuci_delete_by_section(((struct intf_ip_args *)data)->interface_sec, NULL, NULL); - } else { - dmuci_set_value_by_section(((struct intf_ip_args *)data)->interface_sec, "ipaddr", ""); - dmuci_set_value_by_section(((struct intf_ip_args *)data)->interface_sec, "netmask", ""); - } - - dmuci_delete_by_section(((struct intf_ip_args *)data)->dmmap_sec, NULL, NULL); - break; - case DEL_ALL: - dmuci_get_value_by_section_string((struct uci_section *)data, "proto", &proto); - if (DM_LSTRCMP(proto, "static") != 0) - return FAULT_9001; - - dmuci_get_value_by_section_string((struct uci_section *)data, "device", &iface_dev); - - uci_foreach_sections_safe("network", "interface", stmp, s) { - - dmuci_get_value_by_section_string(s, "device", &device); - - if (strcmp(section_name(s), section_name((struct uci_section *)data)) == 0) { - dmuci_set_value_by_section(s, "ipaddr", ""); - dmuci_set_value_by_section(s, "netmask", ""); - - get_dmmap_section_of_config_section("dmmap_network_ipv4", "intf_ipv4", section_name(s), &dmmap_s); - dmuci_delete_by_section(dmmap_s, NULL, NULL); - } else if (DM_STRCMP(device, iface_dev) == 0) { - get_dmmap_section_of_config_section("dmmap_network_ipv4", "intf_ipv4", section_name(s), &dmmap_s); - dmuci_delete_by_section(dmmap_s, NULL, NULL); - - dmuci_delete_by_section(s, NULL, NULL); - } else { - continue; - } - } - break; - } - return 0; + return delObjIPInterfaceIPAddress(data, del_action, "dmmap_network_ipv4", "intf_ipv4", "ipaddr"); } static int addObjIPInterfaceIPv6Address(char *refparam, struct dmctx *ctx, void *data, char **instance) { - char *ip_inst = NULL, *device = NULL, ipv6_name[64] = {0}; - struct uci_section *dmmap_ip_interface = NULL, *dmmap_ip_interface_ipv6 = NULL, *device_s = NULL; - char *ipv6 = NULL; + char *is_new_ip_int = NULL, *device = NULL, ipv6_name[64] = {0}; + struct uci_section *dmmap_ip_interface = NULL, *dmmap_ip_interface_ipv6 = NULL; get_dmmap_section_of_config_section("dmmap_network", "interface", section_name((struct uci_section *)data), &dmmap_ip_interface); - dmuci_get_value_by_section_string(dmmap_ip_interface, "ip_int_instance", &ip_inst); + dmuci_get_value_by_section_string(dmmap_ip_interface, "added_by_controller", &is_new_ip_int); + if (DM_STRCMP(is_new_ip_int, "1") != 0) + return FAULT_9001; - snprintf(ipv6_name, sizeof(ipv6_name), "iface%s_ipv6_%s", ip_inst, *instance); - dmuci_get_value_by_section_string((struct uci_section *)data, "ipv6", &ipv6); + snprintf(ipv6_name, sizeof(ipv6_name), "%s_ipv6_%s", section_name((struct uci_section *)data), *instance); dmuci_get_value_by_section_string((struct uci_section *)data, "device", &device); - device_s = get_dup_section_in_config_opt("network", "device", "name", device); dmuci_set_value("network", ipv6_name, "", "interface"); dmuci_set_value("network", ipv6_name, "device", device); dmuci_set_value("network", ipv6_name, "proto", "static"); dmuci_set_value("network", ipv6_name, "ip6addr", "::"); dmuci_set_value("network", ipv6_name, "disabled", "1"); - if (!device_s) dmuci_set_value("network", ipv6_name, "ipv6", ipv6); // Firewall : add this new interface to zone->network list add_network_to_firewall_zone_network_list(section_name((struct uci_section *)data), ipv6_name); @@ -1018,29 +908,27 @@ static int addObjIPInterfaceIPv6Address(char *refparam, struct dmctx *ctx, void static int delObjIPInterfaceIPv6Address(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action) { - return delObjIPInterfaceIPv6(data, del_action, "dmmap_network_ipv6", "intf_ipv6", "ip6addr"); + return delObjIPInterfaceIPAddress(data, del_action, "dmmap_network_ipv6", "intf_ipv6", "ip6addr"); } static int addObjIPInterfaceIPv6Prefix(char *refparam, struct dmctx *ctx, void *data, char **instance) { - char *ip_inst = NULL, *device = NULL, ipv6_prefix_name[64] = {0}; - struct uci_section *dmmap_ip_interface = NULL, *dmmap_ip_interface_ipv6_prefix = NULL, *device_s = NULL; - char *ipv6 = NULL; + char *is_new_ip_int = NULL, *device = NULL, ipv6_prefix_name[64] = {0}; + struct uci_section *dmmap_ip_interface = NULL, *dmmap_ip_interface_ipv6_prefix = NULL; get_dmmap_section_of_config_section("dmmap_network", "interface", section_name((struct uci_section *)data), &dmmap_ip_interface); - dmuci_get_value_by_section_string(dmmap_ip_interface, "ip_int_instance", &ip_inst); + dmuci_get_value_by_section_string(dmmap_ip_interface, "added_by_controller", &is_new_ip_int); + if (DM_STRCMP(is_new_ip_int, "1") != 0) + return FAULT_9001; - snprintf(ipv6_prefix_name, sizeof(ipv6_prefix_name), "iface%s_ipv6_prefix_%s", ip_inst, *instance); + snprintf(ipv6_prefix_name, sizeof(ipv6_prefix_name), "%s_ipv6_prefix_%s", section_name((struct uci_section *)data), *instance); dmuci_get_value_by_section_string((struct uci_section *)data, "device", &device); - dmuci_get_value_by_section_string((struct uci_section *)data, "ipv6", &ipv6); - device_s = get_dup_section_in_config_opt("network", "device", "name", device); dmuci_set_value("network", ipv6_prefix_name, "", "interface"); dmuci_set_value("network", ipv6_prefix_name, "device", device); dmuci_set_value("network", ipv6_prefix_name, "proto", "static"); dmuci_set_value("network", ipv6_prefix_name, "ip6prefix", "::/64"); dmuci_set_value("network", ipv6_prefix_name, "disabled", "1"); - if (!device_s) dmuci_set_value("network", ipv6_prefix_name, "ipv6", ipv6); // Firewall : add this new interface to zone->network list add_network_to_firewall_zone_network_list(section_name((struct uci_section *)data), ipv6_prefix_name); @@ -1055,7 +943,7 @@ static int addObjIPInterfaceIPv6Prefix(char *refparam, struct dmctx *ctx, void * static int delObjIPInterfaceIPv6Prefix(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action) { - return delObjIPInterfaceIPv6(data, del_action, "dmmap_network_ipv6_prefix", "intf_ipv6_prefix", "ip6prefix"); + return delObjIPInterfaceIPAddress(data, del_action, "dmmap_network_ipv6_prefix", "intf_ipv6_prefix", "ip6prefix"); } /************************************************************* @@ -1552,12 +1440,18 @@ static int get_IPInterfaceIPv4Address_Enable(char *refparam, struct dmctx *ctx, static int set_IPInterfaceIPv4Address_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { + char *proto = NULL; bool b; switch (action) { case VALUECHECK: if (dm_validate_boolean(value)) return FAULT_9007; + + dmuci_get_value_by_section_string(((struct intf_ip_args *)data)->interface_sec, "proto", &proto); + if (DM_LSTRCMP(proto, "static") != 0) + return FAULT_9007; + break; case VALUESET: string_to_bool(value, &b); diff --git a/libbbfdm/dmtree/tr181/ip.h b/libbbfdm/dmtree/tr181/ip.h index cb27e41b..7e709a0e 100644 --- a/libbbfdm/dmtree/tr181/ip.h +++ b/libbbfdm/dmtree/tr181/ip.h @@ -24,7 +24,7 @@ extern DMLEAF tIPInterfaceIPv6AddressParams[]; extern DMLEAF tIPInterfaceIPv6PrefixParams[]; extern DMLEAF tIPInterfaceStatsParams[]; -bool ip___is_ipinterface_exists(const char *sec_name, const char *device); +bool ip___is_ipinterface_section(struct uci_section *iface_s); #endif //__IP_H diff --git a/libbbfdm/dmtree/tr181/routing.c b/libbbfdm/dmtree/tr181/routing.c index 8f40e63b..4f28cf8c 100644 --- a/libbbfdm/dmtree/tr181/routing.c +++ b/libbbfdm/dmtree/tr181/routing.c @@ -376,22 +376,16 @@ static void create_routing_route_section(char *rt_table) static int browseRouterInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) { struct uci_section *s = NULL; - char *inst = NULL, *idx = NULL, *device = NULL, *proto = NULL; + char *inst = NULL, *idx = NULL; struct uci_section *dmmap_route = NULL; create_routing_route_section("254"); uci_foreach_sections("network", "interface", s) { - dmuci_get_value_by_section_string(s, "proto", &proto); - dmuci_get_value_by_section_string(s, "device", &device); - dmuci_get_value_by_section_string(s, "ip4table", &idx); - - if (strcmp(section_name(s), "loopback") == 0 || - *proto == '\0' || - DM_STRCHR(device, '@') || - ip___is_ipinterface_exists(section_name(s), device)) + if (!ip___is_ipinterface_section(s)) continue; + dmuci_get_value_by_section_string(s, "ip4table", &idx); if (DM_STRLEN(idx)) create_routing_route_section(idx); }