Ticket refs #3629: TR-181: Device.DHCPv4.Server.Pool.{i}.StaticAddress. implementation has incorrect behavior

Fix multiple issues in StaticAddress implementation

 - "StaticAddress.{i}.Yiaddr" accepting any IP address -> According to standard, It should accept IP address from DHCP IP pool
 - Same IP address can be assigned to multiple MAC address -> According to standard, Once a IP got bind to a MAC, it should not get bind to other MAC
 - Able to create multiple entry for same MAC -> According to standard, It should accept only one entry for one MAC
 - Able to create multiple object with same Alias -> According to standard, Alias should be unique
This commit is contained in:
Amin Ben Ramdhane 2020-11-26 11:06:56 +01:00
parent 09d21a9d51
commit da60243b30
3 changed files with 285 additions and 208 deletions

View file

@ -28,8 +28,10 @@ struct dhcp_args {
unsigned n_leases;
};
struct dhcp_static_args {
struct uci_section *dhcpsection;
struct dhcp_host_args {
struct uci_section *dhcp_sec;
struct uci_section *host_sec;
char *dhcp_interface;
};
struct client_args {
@ -80,9 +82,11 @@ static inline void init_dhcp_args(struct dhcp_args *args, struct uci_section *s,
args->n_leases = 0;
}
static inline void init_args_dhcp_host(struct dhcp_static_args *args, struct uci_section *s)
static inline void init_args_dhcp_host(struct dhcp_host_args *args, struct uci_section *dhcp_s, struct uci_section *host_s, char *interface)
{
args->dhcpsection = s;
args->dhcp_sec = dhcp_s;
args->host_sec = host_s;
args->dhcp_interface = interface;
}
static inline void init_dhcp_client_args(struct client_args *args, const struct dhcp_lease *lease)
@ -97,9 +101,9 @@ static inline void init_client_options_args(struct client_options_args *args, ch
}
/*************************************************************
* Other functions
* COMMON Functions
**************************************************************/
struct uci_section* exist_other_section_same_order(struct uci_section *dmmap_sect, char * package, char* sect_type, char *order)
static struct uci_section *exist_other_section_same_order(struct uci_section *dmmap_sect, char * package, char* sect_type, char *order)
{
struct uci_section *s;
uci_path_foreach_option_eq(bbfdm, package, sect_type, "order", order, s) {
@ -110,7 +114,7 @@ struct uci_section* exist_other_section_same_order(struct uci_section *dmmap_sec
return NULL;
}
int set_section_order(char *package, char *dmpackage, char* sect_type, struct uci_section *dmmap_sect, struct uci_section *conf, int set_force, char* order)
int set_section_order(char *package, char *dmpackage, char *sect_type, struct uci_section *dmmap_sect, struct uci_section *conf, int set_force, char *order)
{
char *v = NULL, *sect_name, *incrorder;
struct uci_section *s, *dm;
@ -143,10 +147,187 @@ int set_section_order(char *package, char *dmpackage, char* sect_type, struct uc
set_section_order(package, dmpackage, sect_type, dm, s, set_force, incrorder);
}
return 0;
}
/*******************ADD-DEL OBJECT*********************/
static void dhcp_leases_load(struct list_head *head)
{
FILE *f = fopen(DHCP_LEASES_FILE, "r");
char line[128];
if (f == NULL)
return;
while (fgets(line, sizeof(line) - 1, f)) {
struct dhcp_lease *lease;
if (line[0] == '\n')
continue;
lease = dmcalloc(1, sizeof(*lease));
if (lease == NULL)
break;
sscanf(line, "%" PRId64 "%19s %15s",
&lease->ts, lease->hwaddr, lease->ipaddr);
list_add_tail(&lease->list, head);
}
fclose(f);
}
static int interface_get_ipv4(const char *iface, uint32_t *addr, unsigned *bits)
{
json_object *res;
const char *addr_str = NULL;
int addr_cidr = -1;
dmubus_call("network.interface", "status", UBUS_ARGS {{"interface", iface, String}}, 1, &res);
if (res) {
json_object *jobj;
jobj = dmjson_select_obj_in_array_idx(res, 0, 1, "ipv4-address");
if (jobj == NULL)
return -1;
json_object_object_foreach(jobj, key, val) {
if (!strcmp(key, "address"))
addr_str = json_object_get_string(val);
else if (!strcmp(key, "mask"))
addr_cidr = json_object_get_int(val);
}
}
if (addr_str == NULL || addr_cidr == -1)
return -1;
if (inet_pton(AF_INET, addr_str, addr) != 1)
return -1;
*bits = addr_cidr;
return 0;
}
static void dhcp_leases_assign_to_interface(struct dhcp_args *dhcp,
struct list_head *src,
const char *iface)
{
struct dhcp_lease *lease, *tmp;
unsigned iface_addr;
unsigned iface_cidr;
unsigned iface_net;
unsigned iface_bits;
if (interface_get_ipv4(iface, &iface_addr, &iface_cidr))
return;
iface_bits = 32 - iface_cidr;
iface_net = ntohl(iface_addr) >> iface_bits;
list_for_each_entry_safe(lease, tmp, src, list) {
unsigned addr, net;
inet_pton(AF_INET, lease->ipaddr, &addr);
net = ntohl(addr) >> iface_bits;
if (net == iface_net) {
list_move_tail(&lease->list, &dhcp->leases);
dhcp->n_leases += 1;
}
}
}
static bool check_dhcp_host_alias_exists(char *dhcp_interface, char *option, char *value)
{
struct uci_section *s = NULL;
char *opt_value;
uci_path_foreach_option_eq(bbfdm, "dmmap_dhcp", "host", "dhcp", dhcp_interface, s) {
dmuci_get_value_by_section_string(s, option, &opt_value);
if (strcmp(opt_value, value) == 0)
return true;
}
return false;
}
static bool check_dhcp_host_option_exists(char *dhcp_interface, char *option, char *value)
{
struct uci_section *s = NULL;
char *opt_value;
uci_foreach_option_eq("dhcp", "host", "dhcp", dhcp_interface, s) {
dmuci_get_value_by_section_string(s, option, &opt_value);
if (strcmp(opt_value, value) == 0)
return true;
}
return false;
}
static int check_ipv4_in_dhcp_pool(struct uci_section *dhcp_sec, char *interface, char *ip)
{
unsigned iface_addr, iface_cidr, addr;
char *start = NULL, *limit = NULL;
dmuci_get_value_by_section_string(dhcp_sec, "start", &start);
dmuci_get_value_by_section_string(dhcp_sec, "limit", &limit);
if (!start || *start == '\0' || !limit || *limit == '\0')
return -1;
if (interface_get_ipv4(interface, &iface_addr, &iface_cidr))
return -1;
unsigned iface_bits = ~((1 << (32 - iface_cidr)) - 1);
unsigned iface_net_start = (ntohl(iface_addr) & iface_bits) + atoi(start);
unsigned iface_net_end = (ntohl(iface_addr) & iface_bits) + atoi(start) + atoi(limit) - 1;
inet_pton(AF_INET, ip, &addr);
unsigned net = ntohl(addr);
if (net > iface_net_end || net < iface_net_start)
return -1;
return 0;
}
static char *get_dhcp_network_from_relay_list(char *net_list)
{
struct uci_section *s;
char **net_list_arr, *v;
int i;
size_t length;
net_list_arr = strsplit(net_list, " ", &length);
uci_foreach_sections("network", "interface", s) {
dmuci_get_value_by_section_string(s, "proto", &v);
for (i = 0; i < length; i++) {
if (strcmp(net_list_arr[i], section_name(s)) == 0 && strcmp(v, "dhcp") == 0)
return net_list_arr[i];
}
}
return "";
}
static struct uci_section *get_dhcp_classifier(char *classifier_name, char *network)
{
struct uci_section* s = NULL;
char *v;
uci_foreach_sections("dhcp", classifier_name, s) {
dmuci_get_value_by_section_string(s, "networkid", &v);
if (strcmp(v, network) == 0)
return s;
}
return NULL;
}
/*************************************************************
* ADD & DEL OBJ
**************************************************************/
static int add_dhcp_server(char *refparam, struct dmctx *ctx, void *data, char **instancepara)
{
struct uci_section *s = NULL, *dmmap_dhcp = NULL;
@ -206,59 +387,52 @@ static int delete_dhcp_server(char *refparam, struct dmctx *ctx, void *data, cha
return 0;
}
static int add_dhcp_staticaddress(char *refparam, struct dmctx *ctx, void *data, char **instancepara)
static int addObjDHCPv4ServerPoolStaticAddress(char *refparam, struct dmctx *ctx, void *data, char **instancepara)
{
struct uci_section *s = NULL, *dmmap_dhcp_host = NULL;
struct browse_args browse_args = {0};
char host_name[32];
char *instance = get_last_instance_lev2_bbfdm("dhcp", "host", "dmmap_dhcp", "ldhcpinstance", "dhcp", ((struct dhcp_args *)data)->interface);
char *instance = get_last_instance_lev2_bbfdm("dhcp", "host", "dmmap_dhcp", "dhcp_host_instance", "dhcp", ((struct dhcp_args *)data)->interface);
snprintf(host_name, sizeof(host_name), "host_%d", instance ? atoi(instance) + 1 : 1);
dmuci_add_section("dhcp", "host", &s);
dmuci_set_value_by_section(s, "name", host_name);
dmuci_set_value_by_section(s, "dhcp", ((struct dhcp_args *)data)->interface);
browse_args.option = "dhcp";
browse_args.value = ((struct dhcp_args *)data)->interface;
dmuci_add_section_bbfdm("dmmap_dhcp", "host", &dmmap_dhcp_host);
dmuci_set_value_by_section(dmmap_dhcp_host, "section_name", section_name(s));
dmuci_set_value_by_section(dmmap_dhcp_host, "dhcp", ((struct dhcp_args *)data)->interface);
*instancepara = update_instance(instance, 4, dmmap_dhcp_host, "ldhcpinstance", "dmmap_dhcp", "host");
*instancepara = update_instance(instance, 6, dmmap_dhcp_host, "dhcp_host_instance", "dmmap_dhcp", "host", check_browse_section, (void *)&browse_args);
return 0;
}
static int delete_dhcp_staticaddress(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action)
static int delObjDHCPv4ServerPoolStaticAddress(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action)
{
int found = 0;
struct uci_section *s = NULL, *ss = NULL, *dmmap_section = NULL;
struct dhcp_static_args *dhcpargs = (struct dhcp_static_args *)data;
struct uci_section *s = NULL, *stmp = NULL, *dmmap_section = NULL;
struct dhcp_host_args *host_args = (struct dhcp_host_args *)data;
switch (del_action) {
case DEL_INST:
if (is_section_unnamed(section_name(dhcpargs->dhcpsection))) {
if (is_section_unnamed(section_name(host_args->host_sec))) {
LIST_HEAD(dup_list);
delete_sections_save_next_sections("dmmap_dhcp", "host", "ldhcpinstance", section_name(dhcpargs->dhcpsection), atoi(instance), &dup_list);
update_dmmap_sections(&dup_list, "ldhcpinstance", "dmmap_dhcp", "host");
dmuci_delete_by_section_unnamed(dhcpargs->dhcpsection, NULL, NULL);
delete_sections_save_next_sections("dmmap_dhcp", "host", "dhcp_host_instance", section_name(host_args->host_sec), atoi(instance), &dup_list);
update_dmmap_sections(&dup_list, "dhcp_host_instance", "dmmap_dhcp", "host");
dmuci_delete_by_section_unnamed(host_args->host_sec, NULL, NULL);
} else {
get_dmmap_section_of_config_section("dmmap_dhcp", "host", section_name(dhcpargs->dhcpsection), &dmmap_section);
if (dmmap_section != NULL)
dmuci_delete_by_section(dmmap_section, NULL, NULL);
dmuci_delete_by_section(dhcpargs->dhcpsection, NULL, NULL);
get_dmmap_section_of_config_section("dmmap_dhcp", "host", section_name((struct uci_section *)data), &dmmap_section);
dmuci_delete_by_section(dmmap_section, NULL, NULL);
dmuci_delete_by_section(host_args->host_sec, NULL, NULL);
}
break;
case DEL_ALL:
uci_foreach_option_eq("dhcp", "host", "dhcp", ((struct dhcp_args *)data)->interface, s) {
if (found != 0) {
get_dmmap_section_of_config_section("dmmap_dhcp", "host", section_name(ss), &dmmap_section);
if (dmmap_section != NULL)
dmuci_delete_by_section(dmmap_section, NULL, NULL);
dmuci_delete_by_section(ss, NULL, NULL);
}
ss = s;
found++;
}
if (ss != NULL) {
get_dmmap_section_of_config_section("dmmap_dhcp", "host", section_name(ss), &dmmap_section);
if (dmmap_section != NULL)
dmuci_delete_by_section(dmmap_section, NULL, NULL);
dmuci_delete_by_section(ss, NULL, NULL);
uci_foreach_option_eq_safe("dhcp", "host", "dhcp", ((struct dhcp_args *)data)->interface, stmp, s) {
get_dmmap_section_of_config_section("dmmap_dhcp", "host", section_name(s), &dmmap_section);
dmuci_delete_by_section(dmmap_section, NULL, NULL);
dmuci_delete_by_section(s, NULL, NULL);
}
break;
}
@ -930,7 +1104,6 @@ static int set_dhcp_address_max(char *refparam, struct dmctx *ctx, void *data, c
return 0;
}
static int get_dhcp_reserved_addresses(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
char val[512] = {0}, *p;
@ -945,7 +1118,7 @@ static int get_dhcp_reserved_addresses(char *refparam, struct dmctx *ctx, void *
n_min = inet_network(min);
n_max = inet_network(max);
p = val;
uci_foreach_sections("dhcp", "host", s) {
uci_foreach_option_eq("dhcp", "host", "dhcp", ((struct dhcp_args *)data)->interface, s) {
dmuci_get_value_by_section_string(s, "ip", &ip);
if (ip[0] == '\0')
continue;
@ -983,10 +1156,7 @@ static int set_dhcp_reserved_addresses(char *refparam, struct dmctx *ctx, void *
bool host_exist = false;
// Check if host exists
struct uci_section *s = NULL;
uci_foreach_option_eq("dhcp", "host", "ip", pch, s) {
host_exist = true;
}
host_exist = check_dhcp_host_option_exists(((struct dhcp_args *)data)->interface, "ip", pch);
// host exists -> skip it
if (host_exist)
@ -1258,13 +1428,13 @@ end:
}
/*#Device.DHCPv4.Server.Pool.{i}.StaticAddress.{i}.Enable!UCI:dhcp/host,@i-1/enable*/
static int get_dhcp_static_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
static int get_DHCPv4ServerPoolStaticAddress_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = dmuci_get_value_by_section_fallback_def(((struct dhcp_static_args *)data)->dhcpsection, "enable", "1");
*value = dmuci_get_value_by_section_fallback_def(((struct dhcp_host_args *)data)->host_sec, "enable", "1");
return 0;
}
static int set_dhcp_static_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
static int set_DHCPv4ServerPoolStaticAddress_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
bool b;
@ -1275,89 +1445,116 @@ static int set_dhcp_static_enable(char *refparam, struct dmctx *ctx, void *data,
return 0;
case VALUESET:
string_to_bool(value, &b);
dmuci_set_value_by_section(((struct dhcp_static_args *)data)->dhcpsection, "enable", b ? "1" : "0");
dmuci_set_value_by_section(((struct dhcp_host_args *)data)->host_sec, "enable", b ? "1" : "0");
return 0;
}
return 0;
}
/*#Device.DHCPv4.Server.Pool.{i}.StaticAddress.{i}.Alias!UCI:dmmap_dhcp/host,@i-1/ldhcpalias*/
static int get_dhcp_static_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
/*#Device.DHCPv4.Server.Pool.{i}.StaticAddress.{i}.Alias!UCI:dmmap_dhcp/host,@i-1/dhcp_host_alias*/
static int get_DHCPv4ServerPoolStaticAddress_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_section = NULL;
get_dmmap_section_of_config_section("dmmap_dhcp", "host", section_name(((struct dhcp_static_args *)data)->dhcpsection), &dmmap_section);
dmuci_get_value_by_section_string(dmmap_section, "ldhcpalias", value);
get_dmmap_section_of_config_section("dmmap_dhcp", "host", section_name(((struct dhcp_host_args *)data)->host_sec), &dmmap_section);
dmuci_get_value_by_section_string(dmmap_section, "dhcp_host_alias", value);
if ((*value)[0] == '\0')
dmasprintf(value, "cpe-%s", instance);
return 0;
}
static int set_dhcp_static_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
static int set_DHCPv4ServerPoolStaticAddress_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
struct uci_section *dmmap_section = NULL;
char *curr_alias = NULL, *alias_assigned = NULL;
get_dmmap_section_of_config_section("dmmap_dhcp", "host", section_name(((struct dhcp_host_args *)data)->host_sec), &dmmap_section);
switch (action) {
case VALUECHECK:
// Validate value string -> length
if (dm_validate_string(value, -1, 64, NULL, 0, NULL, 0))
return FAULT_9007;
// Check if alias is assigned by user
dmuci_get_value_by_section_string(dmmap_section, "dhcp_host_alias_assigned", &alias_assigned);
if (alias_assigned && strcmp(alias_assigned, "1") == 0)
return FAULT_9007;
// Check if alias exists
dmuci_get_value_by_section_string(dmmap_section, "dhcp_host_alias", &curr_alias);
if (strcmp(curr_alias, value) != 0 && check_dhcp_host_alias_exists(((struct dhcp_host_args *)data)->dhcp_interface, "dhcp_host_alias", value))
return FAULT_9007;
return 0;
case VALUESET:
get_dmmap_section_of_config_section("dmmap_dhcp", "host", section_name(((struct dhcp_static_args *)data)->dhcpsection), &dmmap_section);
dmuci_set_value_by_section(dmmap_section, "ldhcpalias", value);
dmuci_set_value_by_section(dmmap_section, "dhcp_host_alias", value);
dmuci_set_value_by_section(dmmap_section, "dhcp_host_alias_assigned", "1");
return 0;
}
return 0;
}
/*#Device.DHCPv4.Server.Pool.{i}.StaticAddress.{i}.Chaddr!UCI:dhcp/host,@i-1/mac*/
static int get_dhcp_staticaddress_chaddr(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
static int get_DHCPv4ServerPoolStaticAddress_Chaddr(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
char *chaddr;
dmuci_get_value_by_section_string(((struct dhcp_static_args *)data)->dhcpsection, "mac", &chaddr);
if (strcmp(chaddr, DHCPSTATICADDRESS_DISABLED_CHADDR) == 0)
dmuci_get_value_by_section_string(((struct dhcp_static_args *)data)->dhcpsection, "mac_orig", value);
else
*value = chaddr;
dmuci_get_value_by_section_string(((struct dhcp_host_args *)data)->host_sec, "mac", value);
return 0;
}
static int set_dhcp_staticaddress_chaddr(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
char *chaddr;
static int set_DHCPv4ServerPoolStaticAddress_Chaddr(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
char *curr_mac = NULL;
switch (action) {
case VALUECHECK:
// Validate value string -> MAC Address
if (dm_validate_string(value, -1, 17, NULL, 0, MACAddress, 1))
return FAULT_9007;
// Check if mac exists
dmuci_get_value_by_section_string(((struct dhcp_host_args *)data)->host_sec, "mac", &curr_mac);
if (strcmp(curr_mac, value) != 0 && check_dhcp_host_option_exists(((struct dhcp_host_args *)data)->dhcp_interface, "mac", value))
return FAULT_9007;
return 0;
case VALUESET:
dmuci_get_value_by_section_string(((struct dhcp_static_args *)data)->dhcpsection, "mac", &chaddr);
if (strcmp(chaddr, DHCPSTATICADDRESS_DISABLED_CHADDR) == 0)
dmuci_set_value_by_section(((struct dhcp_static_args *)data)->dhcpsection, "mac_orig", value);
else
dmuci_set_value_by_section(((struct dhcp_static_args *)data)->dhcpsection, "mac", value);
dmuci_set_value_by_section(((struct dhcp_host_args *)data)->host_sec, "mac", value);
return 0;
}
return 0;
}
/*#Device.DHCPv4.Server.Pool.{i}.StaticAddress.{i}.Yiaddr!UCI:dhcp/host,@i-1/ip*/
static int get_dhcp_staticaddress_yiaddr(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
static int get_DHCPv4ServerPoolStaticAddress_Yiaddr(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
dmuci_get_value_by_section_string(((struct dhcp_static_args *)data)->dhcpsection, "ip", value);
dmuci_get_value_by_section_string(((struct dhcp_host_args *)data)->host_sec, "ip", value);
return 0;
}
static int set_dhcp_staticaddress_yiaddr(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
static int set_DHCPv4ServerPoolStaticAddress_Yiaddr(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
struct dhcp_host_args *host_args = (struct dhcp_host_args *)data;
char *curr_ip = NULL;
switch (action) {
case VALUECHECK:
// Validate value string -> IPv4 Address
if (dm_validate_string(value, -1, 15, NULL, 0, IPv4Address, 1))
return FAULT_9007;
// Check if ipv4 is out dhcp pool
if (check_ipv4_in_dhcp_pool(host_args->dhcp_sec, host_args->dhcp_interface, value))
return FAULT_9007;
// Check if ip exists
dmuci_get_value_by_section_string(host_args->host_sec, "ip", &curr_ip);
if (strcmp(curr_ip, value) != 0 && check_dhcp_host_option_exists(host_args->dhcp_interface, "ip", value))
return FAULT_9007;
return 0;
case VALUESET:
dmuci_set_value_by_section(((struct dhcp_static_args *)data)->dhcpsection, "ip", value);
dmuci_set_value_by_section(host_args->host_sec, "ip", value);
return 0;
}
return 0;
@ -2423,7 +2620,6 @@ static int set_DHCPv4RelayForwarding_ChaddrExclude(char *refparam, struct dmctx
return FAULT_9007;
break;
case VALUESET:
//TODO
break;
}
return 0;
@ -2524,93 +2720,6 @@ static int get_DHCPv4Relay_ForwardingNumberOfEntries(char *refparam, struct dmct
return 0;
}
static void dhcp_leases_load(struct list_head *head)
{
FILE *f = fopen(DHCP_LEASES_FILE, "r");
char line[128];
if (f == NULL)
return;
while (fgets(line, sizeof(line) - 1, f)) {
struct dhcp_lease *lease;
if (line[0] == '\n')
continue;
lease = dmcalloc(1, sizeof(*lease));
if (lease == NULL)
break;
sscanf(line, "%" PRId64 "%19s %15s",
&lease->ts, lease->hwaddr, lease->ipaddr);
list_add_tail(&lease->list, head);
}
fclose(f);
}
static int interface_get_ipv4(const char *iface, uint32_t *addr, unsigned *bits)
{
json_object *res;
const char *addr_str = NULL;
int addr_cidr = -1;
dmubus_call("network.interface", "status", UBUS_ARGS {{"interface", iface, String}}, 1, &res);
if (res) {
json_object *jobj;
jobj = dmjson_select_obj_in_array_idx(res, 0, 1, "ipv4-address");
if (jobj == NULL)
return -1;
json_object_object_foreach(jobj, key, val) {
if (!strcmp(key, "address"))
addr_str = json_object_get_string(val);
else if (!strcmp(key, "mask"))
addr_cidr = json_object_get_int(val);
}
}
if (addr_str == NULL || addr_cidr == -1)
return -1;
if (inet_pton(AF_INET, addr_str, addr) != 1)
return -1;
*bits = addr_cidr;
return 0;
}
static void dhcp_leases_assign_to_interface(struct dhcp_args *dhcp,
struct list_head *src,
const char *iface)
{
struct dhcp_lease *lease, *tmp;
unsigned iface_addr;
unsigned iface_cidr;
unsigned iface_net;
unsigned iface_bits;
if (interface_get_ipv4(iface, &iface_addr, &iface_cidr))
return;
iface_bits = 32 - iface_cidr;
iface_net = ntohl(iface_addr) >> iface_bits;
list_for_each_entry_safe(lease, tmp, src, list) {
unsigned addr, net;
inet_pton(AF_INET, lease->ipaddr, &addr);
net = ntohl(addr) >> iface_bits;
if (net == iface_net) {
list_move_tail(&lease->list, &dhcp->leases);
dhcp->n_leases += 1;
}
}
}
/*************************************************************
* ENTRY METHOD
**************************************************************/
@ -2649,10 +2758,10 @@ static int browseDhcpInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_d
}
/*#Device.DHCPv4.Server.Pool.{i}.StaticAddress.{i}.!UCI:dhcp/host/dmmap_dhcp*/
static int browseDhcpStaticInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
static int browseDHCPv4ServerPoolStaticAddressInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
{
char *inst = NULL, *max_inst = NULL;
struct dhcp_static_args curr_dhcp_staticargs = {0};
struct dhcp_host_args curr_dhcp_host_args = {0};
struct browse_args browse_args = {0};
struct dmmap_dup *p;
LIST_HEAD(dup_list);
@ -2661,16 +2770,16 @@ static int browseDhcpStaticInst(struct dmctx *dmctx, DMNODE *parent_node, void *
list_for_each_entry(p, &dup_list, list) {
dmuci_set_value_by_section(p->dmmap_section, "dhcp", ((struct dhcp_args *)prev_data)->interface);
init_args_dhcp_host(&curr_dhcp_staticargs, p->config_section);
init_args_dhcp_host(&curr_dhcp_host_args, ((struct dhcp_args *)prev_data)->dhcp_sec, p->config_section, ((struct dhcp_args *)prev_data)->interface);
browse_args.option = "dhcp";
browse_args.value = ((struct dhcp_args *)prev_data)->interface;
inst = handle_update_instance(2, dmctx, &max_inst, update_instance_alias, 7,
p->dmmap_section, "ldhcpinstance", "ldhcpalias", "dmmap_dhcp", "host",
p->dmmap_section, "dhcp_host_instance", "dhcp_host_alias", "dmmap_dhcp", "host",
check_browse_section, (void *)&browse_args);
if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_dhcp_staticargs, inst) == DM_STOP)
if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_dhcp_host_args, inst) == DM_STOP)
break;
}
free_dmmap_config_dup_list(&dup_list);
@ -2985,37 +3094,6 @@ static int browseDHCPv4ServerPoolOptionInst(struct dmctx *dmctx, DMNODE *parent_
return 0;
}
static char *get_dhcp_network_from_relay_list(char *net_list)
{
struct uci_section *s;
char **net_list_arr, *v;
int i;
size_t length;
net_list_arr = strsplit(net_list, " ", &length);
uci_foreach_sections("network", "interface", s) {
dmuci_get_value_by_section_string(s, "proto", &v);
for (i = 0; i < length; i++) {
if (strcmp(net_list_arr[i], section_name(s)) == 0 && strcmp(v, "dhcp") == 0)
return net_list_arr[i];
}
}
return "";
}
struct uci_section* get_dhcp_classifier(char *classifier_name, char *network)
{
struct uci_section* s = NULL;
char *v;
uci_foreach_sections("dhcp", classifier_name, s) {
dmuci_get_value_by_section_string(s, "networkid", &v);
if (strcmp(v, network) == 0)
return s;
}
return NULL;
}
/*#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)
{
@ -3183,7 +3261,7 @@ DMLEAF tDHCPv4ServerParams[] = {
/* *** Device.DHCPv4.Server.Pool.{i}. *** */
DMOBJ tDHCPv4ServerPoolObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/
{"StaticAddress", &DMWRITE, add_dhcp_staticaddress, delete_dhcp_staticaddress, NULL, browseDhcpStaticInst, NULL, NULL, tDHCPv4ServerPoolStaticAddressParams, NULL, BBFDM_BOTH, LIST_KEY{"Chaddr", "Alias", NULL}},
{"StaticAddress", &DMWRITE, addObjDHCPv4ServerPoolStaticAddress, delObjDHCPv4ServerPoolStaticAddress, NULL, browseDHCPv4ServerPoolStaticAddressInst, NULL, NULL, tDHCPv4ServerPoolStaticAddressParams, NULL, BBFDM_BOTH, LIST_KEY{"Alias", "Chaddr", NULL}},
{"Option", &DMWRITE, addObjDHCPv4ServerPoolOption, delObjDHCPv4ServerPoolOption, NULL, browseDHCPv4ServerPoolOptionInst, NULL, NULL, tDHCPv4ServerPoolOptionParams, NULL, BBFDM_BOTH, LIST_KEY{"Tag", "Alias", NULL}},
{"Client", &DMREAD, NULL, NULL, NULL, browseDhcpClientInst, NULL, tDHCPv4ServerPoolClientObj, tDHCPv4ServerPoolClientParams, get_dhcp_client_linker, BBFDM_BOTH, LIST_KEY{"Chaddr", "Alias", NULL}},
{0}
@ -3213,10 +3291,10 @@ DMLEAF tDHCPv4ServerPoolParams[] = {
/* *** Device.DHCPv4.Server.Pool.{i}.StaticAddress.{i}. *** */
DMLEAF tDHCPv4ServerPoolStaticAddressParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
{"Enable", &DMWRITE, DMT_BOOL, get_dhcp_static_enable, set_dhcp_static_enable, BBFDM_BOTH},
{"Alias", &DMWRITE, DMT_STRING, get_dhcp_static_alias, set_dhcp_static_alias, BBFDM_BOTH},
{"Chaddr", &DMWRITE, DMT_STRING, get_dhcp_staticaddress_chaddr, set_dhcp_staticaddress_chaddr, BBFDM_BOTH},
{"Yiaddr", &DMWRITE, DMT_STRING, get_dhcp_staticaddress_yiaddr, set_dhcp_staticaddress_yiaddr, BBFDM_BOTH},
{"Enable", &DMWRITE, DMT_BOOL, get_DHCPv4ServerPoolStaticAddress_Enable, set_DHCPv4ServerPoolStaticAddress_Enable, BBFDM_BOTH},
{"Alias", &DMWRITE, DMT_STRING, get_DHCPv4ServerPoolStaticAddress_Alias, set_DHCPv4ServerPoolStaticAddress_Alias, BBFDM_BOTH},
{"Chaddr", &DMWRITE, DMT_STRING, get_DHCPv4ServerPoolStaticAddress_Chaddr, set_DHCPv4ServerPoolStaticAddress_Chaddr, BBFDM_BOTH},
{"Yiaddr", &DMWRITE, DMT_STRING, get_DHCPv4ServerPoolStaticAddress_Yiaddr, set_DHCPv4ServerPoolStaticAddress_Yiaddr, BBFDM_BOTH},
{0}
};

View file

@ -58724,7 +58724,7 @@
"index": "@i-1"
},
"option": {
"name": "ldhcpalias"
"name": "dhcp_host_alias"
}
}
}

View file

@ -118,7 +118,6 @@ extern char *SupportedFrequencyBands[];
#define DHCP_LEASES_FILE "/tmp/dhcp.leases"
#define DHCP_CLIENT_OPTIONS_FILE "/var/dhcp.client.options"
#define DMMAP "dmmap"
#define DHCPSTATICADDRESS_DISABLED_CHADDR "00:00:00:00:00:01"
#define RANGE_ARGS (struct range_args[])
#define LIST_KEY (const char *[])
#define IS_BIG_ENDIAN (*(uint16_t *)"\0\xff" < 0x100)