IP.Interface: interface proto can't be set to static if it is dhcp by default

This commit is contained in:
Amin Ben Ramdhane 2021-01-12 16:56:30 +01:00
parent e6e4ab1353
commit cced3a7f8d

View file

@ -81,6 +81,31 @@ static void create_firewall_zone_config(char *iface)
dmuci_set_value_by_section(s, "network", iface);
}
static struct uci_section *check_dmmap_network_interface_ipv4(char *dmmap_file_name, char *dmmap_sec_name, char *parent_section, char *section_name)
{
struct uci_section *dmmap_section = NULL;
char *sec_name;
uci_path_foreach_option_eq(bbfdm, dmmap_file_name, dmmap_sec_name, "parent_section", parent_section, dmmap_section) {
dmuci_get_value_by_section_string(dmmap_section, "section_name", &sec_name);
if (strcmp(sec_name, section_name) == 0)
return dmmap_section;
}
return NULL;
}
static struct uci_section *add_dmmap_network_interface_ipv4(char *dmmap_file_name, char *dmmap_sec_name, char *parent_section, char *section_name)
{
struct uci_section *dmmap_section = NULL;
dmuci_add_section_bbfdm(dmmap_file_name, dmmap_sec_name, &dmmap_section);
dmuci_set_value_by_section_bbfdm(dmmap_section, "parent_section", parent_section);
dmuci_set_value_by_section_bbfdm(dmmap_section, "section_name", section_name);
return dmmap_section;
}
static struct uci_section *update_dmmap_network_interface(char *dmmap_file_name, char *dmmap_sec_name, char *parent_section, char *section_name, char *option, char *value, bool assign)
{
struct uci_section *dmmap_section = NULL;
@ -104,42 +129,6 @@ static struct uci_section *update_dmmap_network_interface(char *dmmap_file_name,
return dmmap_section;
}
static void synchronize_intf_ipv4_sections_with_dmmap(void)
{
json_object *res = NULL, *ipv4_obj = NULL, *arrobj = NULL;
struct uci_section *s = NULL, *ss = NULL, *stmp = NULL;
char *dmmap_intf_s, *dmmap_address, *ipaddr = NULL;
bool found = false;
int i = 0;
uci_path_foreach_sections_safe(bbfdm, "dmmap_network_ipv4", "intf_ipv4", stmp, s) {
dmuci_get_value_by_section_string(s, "section_name", &dmmap_intf_s);
dmuci_get_value_by_section_string(s, "address", &dmmap_address);
found = false;
ss = get_origin_section_from_config("network", "interface", dmmap_intf_s);
dmuci_get_value_by_section_string(ss, "ipaddr", &ipaddr);
if (ipaddr && *ipaddr != '\0' && strcmp(ipaddr, dmmap_address) == 0)
continue;
dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", dmmap_intf_s, String}}, 1, &res);
dmjson_foreach_obj_in_array(res, arrobj, ipv4_obj, i, 1, "ipv4-address") {
char *address = dmjson_get_value(ipv4_obj, 1, "address");
if (address && *address && strcmp(address, dmmap_address) == 0) {
found = true;
break;
}
}
if (!found)
dmuci_delete_by_section(s, NULL, NULL);
}
}
static void synchronize_intf_ipv6_sections_with_dmmap(void)
{
json_object *res = NULL, *ipv6_obj = NULL, *arrobj = NULL;
@ -381,13 +370,18 @@ static bool interface_section_with_dhcpv6_exists(const char *sec_name)
return false;
}
static void set_ip_interface_ifname_option(struct uci_section *section, char *linker, char *instance)
static void set_ip_interface_ifname_option(struct uci_section *section, char *linker, char *instance, bool is_br_sec)
{
struct uci_section *s = NULL;
bool device_exists = false;
char ifname[64];
snprintf(ifname, sizeof(ifname), "%s.1", linker);
if (is_br_sec) {
snprintf(ifname, sizeof(ifname), "%s", linker);
goto end;
} else {
snprintf(ifname, sizeof(ifname), "%s.1", linker);
}
// Check if device exists
uci_foreach_option_eq("network", "device", "name", ifname, s) {
@ -408,6 +402,7 @@ static void set_ip_interface_ifname_option(struct uci_section *section, char *li
dmuci_set_value_by_section(s, "name", ifname);
}
end:
dmuci_set_value_by_section(section, "ifname", ifname);
}
@ -496,67 +491,47 @@ static int browseIPInterfaceInst(struct dmctx *dmctx, DMNODE *parent_node, void
static int browseIPInterfaceIPv4AddressInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
{
struct uci_section *parent_sec = (struct uci_section *)prev_data, *intf_s = NULL, *dmmap_s = NULL;
char *inst = NULL, *max_inst = NULL, *ipaddr, *ifname, buf[32] = {0};
json_object *res = NULL, *ipv4_obj = NULL, *arrobj = NULL;
char *inst = NULL, *max_inst = NULL, *ipaddr, *added_by_user = NULL, *ifname, buf[32] = {0};
json_object *res = NULL, *ipv4_obj = NULL;
struct intf_ip_args curr_intf_ip_args = {0};
struct browse_args browse_args = {0};
int i = 0;
snprintf(buf, sizeof(buf), "@%s", section_name(parent_sec));
synchronize_intf_ipv4_sections_with_dmmap();
uci_foreach_sections("network", "interface", intf_s) {
dmuci_get_value_by_section_string(intf_s, "ifname", &ifname);
if (strcmp(section_name(intf_s), section_name(parent_sec)) != 0 && strcmp(ifname, buf) != 0)
continue;
dmmap_s = check_dmmap_network_interface_ipv4("dmmap_network_ipv4", "intf_ipv4", section_name(parent_sec), section_name(intf_s));
dmuci_get_value_by_section_string(dmmap_s, "added_by_user", &added_by_user);
dmuci_get_value_by_section_string(intf_s, "ipaddr", &ipaddr);
if (*ipaddr == '\0') {
dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", section_name(intf_s), String}}, 1, &res);
dmjson_foreach_obj_in_array(res, arrobj, ipv4_obj, i, 1, "ipv4-address") {
char *address = dmjson_get_value(ipv4_obj, 1, "address");
if (*address == '\0')
continue;
dmmap_s = update_dmmap_network_interface("dmmap_network_ipv4", "intf_ipv4", section_name(parent_sec), section_name(intf_s), "address", address, false);
init_interface_ip_args(&curr_intf_ip_args, intf_s, dmmap_s, ipv4_obj);
browse_args.option = "parent_section";
browse_args.value = section_name(parent_sec);
inst = handle_update_instance(2, dmctx, &max_inst, update_instance_alias, 5,
dmmap_s, "ipv4_instance", "ipv4_alias",
check_browse_section, (void *)&browse_args);
if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_intf_ip_args, inst) == DM_STOP)
goto end;
}
} else {
dmmap_s = update_dmmap_network_interface("dmmap_network_ipv4", "intf_ipv4", section_name(parent_sec), section_name(intf_s), "address", ipaddr, false);
init_interface_ip_args(&curr_intf_ip_args, intf_s, dmmap_s, NULL);
browse_args.option = "parent_section";
browse_args.value = section_name(parent_sec);
inst = handle_update_instance(2, dmctx, &max_inst, update_instance_alias, 5,
dmmap_s, "ipv4_instance", "ipv4_alias",
check_browse_section, (void *)&browse_args);
if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_intf_ip_args, inst) == DM_STOP)
goto end;
ipv4_obj = dmjson_select_obj_in_array_idx(res, 0, 1, "ipv4-address");
ipaddr = dmjson_get_value(ipv4_obj, 1, "address");
}
}
end:
if (*ipaddr == '\0' && added_by_user && strcmp(added_by_user, "1") != 0)
continue;
if (dmmap_s == NULL)
dmmap_s = add_dmmap_network_interface_ipv4("dmmap_network_ipv4", "intf_ipv4", section_name(parent_sec), section_name(intf_s));
init_interface_ip_args(&curr_intf_ip_args, intf_s, dmmap_s, res);
browse_args.option = "parent_section";
browse_args.value = section_name(parent_sec);
inst = handle_update_instance(2, dmctx, &max_inst, update_instance_alias, 5,
dmmap_s, "ipv4_instance", "ipv4_alias",
check_browse_section, (void *)&browse_args);
if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_intf_ip_args, inst) == DM_STOP)
break;
}
return 0;
}
@ -754,7 +729,7 @@ static int addObjIPInterface(char *refparam, struct dmctx *ctx, void *data, char
snprintf(ip_name, sizeof(ip_name), "ip_interface_%d", last_inst ? atoi(last_inst) + 1 : 1);
dmuci_set_value("network", ip_name, "", "interface");
dmuci_set_value("network", ip_name, "proto", "static");
dmuci_set_value("network", ip_name, "proto", "none");
dmuci_add_section_bbfdm("dmmap_network", "interface", &dmmap_ip_interface);
dmuci_set_value_by_section(dmmap_ip_interface, "section_name", ip_name);
@ -790,12 +765,6 @@ static int delObjIPInterface(char *refparam, struct dmctx *ctx, void *data, char
static int addObjIPInterfaceIPv4Address(char *refparam, struct dmctx *ctx, void *data, char **instance)
{
// check the proto option from the interface section parent, if proto="static" ==> we can add a new object, else return 9001 error
char *proto;
dmuci_get_value_by_section_string((struct uci_section *)data, "proto", &proto);
if (strcmp(proto, "static") != 0)
return FAULT_9001;
char *last_inst = NULL, *ip_inst, ipv4_name[64] = {0}, buf[32] = {0};
struct uci_section *dmmap_ip_interface = NULL, *dmmap_ip_interface_ipv4;
struct browse_args browse_args = {0};
@ -812,11 +781,11 @@ static int addObjIPInterfaceIPv4Address(char *refparam, struct dmctx *ctx, void
dmuci_set_value("network", ipv4_name, "", "interface");
dmuci_set_value("network", ipv4_name, "ifname", buf);
dmuci_set_value("network", ipv4_name, "proto", "static");
dmuci_set_value("network", ipv4_name, "ipaddr", "0.0.0.0");
dmuci_set_value("network", ipv4_name, "netmask", "0.0.0.0");
} else {
dmuci_set_value_by_section((struct uci_section *)data, "ipaddr", "0.0.0.0");
dmuci_set_value_by_section((struct uci_section *)data, "netmask", "0.0.0.0");
char *proto;
dmuci_get_value_by_section_string((struct uci_section *)data, "proto", &proto);
dmuci_set_value_by_section((struct uci_section *)data, "proto", strcmp(proto, "dhcp") == 0 ? proto : "static");
}
browse_args.option = "parent_section";
@ -825,7 +794,7 @@ static int addObjIPInterfaceIPv4Address(char *refparam, struct dmctx *ctx, void
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", last_inst ? ipv4_name : section_name((struct uci_section *)data));
dmuci_set_value_by_section(dmmap_ip_interface_ipv4, "address", "0.0.0.0");
dmuci_set_value_by_section(dmmap_ip_interface_ipv4, "added_by_user", "1");
*instance = update_instance(last_inst, 5, dmmap_ip_interface_ipv4, "ipv4_instance", NULL, check_browse_section, (void *)&browse_args);
return 0;
@ -885,12 +854,6 @@ static int delObjIPInterfaceIPv4Address(char *refparam, struct dmctx *ctx, void
static int addObjIPInterfaceIPv6Address(char *refparam, struct dmctx *ctx, void *data, char **instance)
{
// check the proto option from the interface section parent, if proto="static" ==> you can add a new object, else return 9001 error
char *proto;
dmuci_get_value_by_section_string((struct uci_section *)data, "proto", &proto);
if (strcmp(proto, "static") != 0 || (strcmp(proto, "static") == 0 && interface_section_with_dhcpv6_exists(section_name((struct uci_section *)data))))
return FAULT_9001;
char *last_inst = NULL, *ip_inst, ipv6_name[64] = {0}, buf[32] = {0};
struct uci_section *dmmap_ip_interface = NULL, *dmmap_ip_interface_ipv6;
struct browse_args browse_args = {0};
@ -926,12 +889,6 @@ static int delObjIPInterfaceIPv6Address(char *refparam, struct dmctx *ctx, void
static int addObjIPInterfaceIPv6Prefix(char *refparam, struct dmctx *ctx, void *data, char **instance)
{
// check the proto option from the interface section parent, if proto="static" ==> you can add a new object, else return 9001 error
char *proto;
dmuci_get_value_by_section_string((struct uci_section *)data, "proto", &proto);
if (strcmp(proto, "static") != 0 || (strcmp(proto, "static") == 0 && interface_section_with_dhcpv6_exists(section_name((struct uci_section *)data))))
return FAULT_9001;
char *last_inst = NULL, *ip_inst, ipv6_prefix_name[64] = {0}, buf[32] = {0};
struct uci_section *dmmap_ip_interface = NULL, *dmmap_ip_interface_ipv6_prefix;
struct browse_args browse_args = {0};
@ -1369,18 +1326,20 @@ static int set_IPInterface_LowerLayers(char *refparam, struct dmctx *ctx, void *
if (!interface) {
bool ip_interface_s = false;
// Update the new interface section with proto=dhcp if its proto is empty
bool is_br_sec = false;
// Update the new interface section with proto=none if its proto is empty
uci_foreach_sections("network", "interface", s) {
if (strcmp(section_name(s), interface_list) == 0) {
char *proto, *type;
dmuci_get_value_by_section_string(s, "proto", &proto);
dmuci_get_value_by_section_string(s, "type", &type);
if (*proto == '\0') {
dmuci_set_value_by_section(s, "proto", "dhcp");
dmuci_set_value_by_section(s, "proto", "none");
if (strcmp(type, "bridge") != 0)
set_ip_interface_ifname_option(s, ip_linker, instance);
set_ip_interface_ifname_option(s, ip_linker, instance, false);
} else {
ip_interface_s = true;
is_br_sec = (strcmp(type, "bridge") == 0) ? true : false;
}
break;
}
@ -1406,10 +1365,10 @@ static int set_IPInterface_LowerLayers(char *refparam, struct dmctx *ctx, void *
// remove the current interface section
dmuci_delete_by_section((struct uci_section *)data, NULL, NULL);
} else {
set_ip_interface_ifname_option((struct uci_section *)data, ip_linker, instance);
set_ip_interface_ifname_option((struct uci_section *)data, ip_linker, instance, is_br_sec);
}
} else {
set_ip_interface_ifname_option((struct uci_section *)data, ip_linker, instance);
set_ip_interface_ifname_option((struct uci_section *)data, ip_linker, instance, false);
}
}
break;
@ -1514,7 +1473,6 @@ static int get_IPInterface_IPv4AddressNumberOfEntries(char *refparam, struct dmc
struct uci_section *s = NULL;
int cnt = 0;
synchronize_intf_ipv4_sections_with_dmmap();
uci_path_foreach_option_eq(bbfdm, "dmmap_network_ipv4", "intf_ipv4", "parent_section", section_name((struct uci_section *)data), s) {
cnt++;
}
@ -1548,6 +1506,40 @@ static int get_IPInterface_IPv6PrefixNumberOfEntries(char *refparam, struct dmct
return 0;
}
/*#Device.IP.Interface.{i}.AutoIPEnable!UCI:network/interface,@i-1/proto*/
static int get_IPInterface_AutoIPEnable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
char *proto = NULL;
dmuci_get_value_by_section_string((struct uci_section *)data, "proto", &proto);
*value = (proto && strcmp(proto, "dhcp") == 0) ? "1" : "0";
return 0;
}
static int set_IPInterface_AutoIPEnable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
char *ip_addr = NULL;
bool b;
switch (action) {
case VALUECHECK:
if (dm_validate_boolean(value))
return FAULT_9007;
break;
case VALUESET:
string_to_bool(value, &b);
dmuci_get_value_by_section_string((struct uci_section *)data, "ipaddr", &ip_addr);
if (b) {
dmuci_set_value_by_section((struct uci_section *)data, "proto", "dhcp");
dmuci_set_value_by_section((struct uci_section *)data, "ipaddr", "");
} else {
dmuci_set_value_by_section((struct uci_section *)data, "proto", (ip_addr && *ip_addr) ? "static" : "none");
dmuci_set_value_by_section((struct uci_section *)data, "ipaddr", (ip_addr && *ip_addr) ? ip_addr : "");
}
break;
}
return 0;
}
static int get_IPInterface_TWAMPReflectorNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *s = NULL;
@ -1563,14 +1555,23 @@ static int get_IPInterface_TWAMPReflectorNumberOfEntries(char *refparam, struct
/*#Device.IP.Interface.{i}.IPv4Address.{i}.Enable!UCI:network/interface,@i-1/disabled*/
static int get_IPInterfaceIPv4Address_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
char *disabled = NULL;
dmuci_get_value_by_section_string(((struct intf_ip_args *)data)->interface_sec, "disabled", &disabled);
*value = (disabled && *disabled == '1') ? "0" : "1";
char *proto = NULL;
dmuci_get_value_by_section_string(((struct intf_ip_args *)data)->interface_sec, "proto", &proto);
if (strcmp(proto, "none") != 0) {
char *disabled = NULL;
dmuci_get_value_by_section_string(((struct intf_ip_args *)data)->interface_sec, "disabled", &disabled);
*value = (disabled && *disabled == '1') ? "0" : "1";
} else {
*value = "0";
}
return 0;
}
static int set_IPInterfaceIPv4Address_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
char *proto;
bool b;
switch (action) {
@ -1580,7 +1581,15 @@ static int set_IPInterfaceIPv4Address_Enable(char *refparam, struct dmctx *ctx,
break;
case VALUESET:
string_to_bool(value, &b);
dmuci_get_value_by_section_string(((struct intf_ip_args *)data)->interface_sec, "proto", &proto);
if (strcmp(proto, "none") == 0) {
char *ip_addr;
dmuci_get_value_by_section_string(((struct intf_ip_args *)data)->interface_sec, "ipaddr", &ip_addr);
dmuci_set_value_by_section(((struct intf_ip_args *)data)->interface_sec, "proto", b ? (*ip_addr == '\0' ? "dhcp" : "static") : "none");
}
dmuci_set_value_by_section(((struct intf_ip_args *)data)->interface_sec, "disabled", b ? "0" : "1");
break;
}
return 0;
@ -1605,13 +1614,17 @@ static int get_IPInterfaceIPv4Address_Alias(char *refparam, struct dmctx *ctx, v
static int set_IPInterfaceIPv4Address_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
char *proto = NULL;
switch (action) {
case VALUECHECK:
if (dm_validate_string(value, -1, 64, NULL, 0, NULL, 0))
return FAULT_9007;
break;
case VALUESET:
dmuci_set_value_by_section(((struct intf_ip_args *)data)->dmmap_sec, "ipv4_alias", value);
dmuci_get_value_by_section_string(((struct intf_ip_args *)data)->interface_sec, "proto", &proto);
if (proto && strcmp(proto, "static") == 0)
dmuci_set_value_by_section(((struct intf_ip_args *)data)->dmmap_sec, "ipv4_alias", value);
break;
}
return 0;
@ -1624,10 +1637,12 @@ static int get_IPInterfaceIPv4Address_IPAddress(char *refparam, struct dmctx *ct
dmuci_get_value_by_section_string(((struct intf_ip_args *)data)->interface_sec, "ipaddr", &ip_addr);
if (ip_addr[0] == '\0')
ip_addr = dmjson_get_value(((struct intf_ip_args *)data)->interface_obj, 1, "address");
if (ip_addr[0] == '\0') {
json_object *ipv4_obj = dmjson_select_obj_in_array_idx(((struct intf_ip_args *)data)->interface_obj, 0, 1, "ipv4-address");
ip_addr = dmjson_get_value(ipv4_obj, 1, "address");
}
*value = ip_addr;
*value = (ip_addr && *ip_addr) ? ip_addr : "0.0.0.0";
return 0;
}
@ -1642,10 +1657,8 @@ static int set_IPInterfaceIPv4Address_IPAddress(char *refparam, struct dmctx *ct
break;
case VALUESET:
dmuci_get_value_by_section_string(((struct intf_ip_args *)data)->interface_sec, "proto", &proto_intf);
if (proto_intf && strcmp(proto_intf, "static") == 0) {
if (proto_intf && strcmp(proto_intf, "static") == 0)
dmuci_set_value_by_section(((struct intf_ip_args *)data)->interface_sec, "ipaddr", value);
dmuci_set_value_by_section(((struct intf_ip_args *)data)->dmmap_sec, "address", value);
}
break;
}
return 0;
@ -1659,11 +1672,12 @@ static int get_IPInterfaceIPv4Address_SubnetMask(char *refparam, struct dmctx *c
dmuci_get_value_by_section_string(((struct intf_ip_args *)data)->interface_sec, "netmask", &mask);
if (mask[0] == '\0') {
mask = dmjson_get_value(((struct intf_ip_args *)data)->interface_obj, 1, "mask");
json_object *ipv4_obj = dmjson_select_obj_in_array_idx(((struct intf_ip_args *)data)->interface_obj, 0, 1, "ipv4-address");
mask = dmjson_get_value(ipv4_obj, 1, "mask");
mask = (mask && *mask) ? dmstrdup(cidr2netmask(atoi(mask))) : "";
}
*value = mask;
*value = (mask && *mask) ? mask : "0.0.0.0";
return 0;
}
@ -1689,7 +1703,7 @@ static int set_IPInterfaceIPv4Address_SubnetMask(char *refparam, struct dmctx *c
static int get_IPInterfaceIPv4Address_AddressingType(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
dmuci_get_value_by_section_string(((struct intf_ip_args *)data)->interface_sec, "proto", value);
*value = (strcmp(*value, "dhcp") == 0) ? "DHCP" : "Static";
*value = (strcmp(*value, "static") == 0) ? "Static" : "DHCP";
return 0;
}
@ -2263,7 +2277,7 @@ DMLEAF tIPInterfaceParams[] = {
{"IPv4AddressNumberOfEntries", &DMREAD, DMT_UNINT, get_IPInterface_IPv4AddressNumberOfEntries, NULL, BBFDM_BOTH},
{"IPv6AddressNumberOfEntries", &DMREAD, DMT_UNINT, get_IPInterface_IPv6AddressNumberOfEntries, NULL, BBFDM_BOTH},
{"IPv6PrefixNumberOfEntries", &DMREAD, DMT_UNINT, get_IPInterface_IPv6PrefixNumberOfEntries, NULL, BBFDM_BOTH},
//{"AutoIPEnable", &DMWRITE, DMT_BOOL, get_IPInterface_AutoIPEnable, set_IPInterface_AutoIPEnable, BBFDM_BOTH},
{"AutoIPEnable", &DMWRITE, DMT_BOOL, get_IPInterface_AutoIPEnable, set_IPInterface_AutoIPEnable, BBFDM_BOTH},
{"TWAMPReflectorNumberOfEntries", &DMREAD, DMT_UNINT, get_IPInterface_TWAMPReflectorNumberOfEntries, NULL, BBFDM_BOTH},
{0}
};