statd: add ipv6 data to operational datastore

Modify existing IPv4 code to also add IPv6 address data to the
operational datastore. Also add support for handling link-layer IPv6
address.

IPv6 LL addresses generated with eui64 has "link-layer" origin
and random/secure generated LL addresses has "random" origin.

Signed-off-by: Richard Alpe <richard@bit42.se>
This commit is contained in:
Richard Alpe
2023-09-20 11:33:35 +02:00
committed by Joachim Wiberg
parent b05d220fa4
commit cf0c99bd78
+62 -32
View File
@@ -166,6 +166,7 @@ static const char *get_yang_origin(const char *protocol)
const char *yang;
} map[] = {
{"kernel_ll", "link-layer"},
{"static", "static"},
{"dhcp", "dhcp"},
};
@@ -473,8 +474,8 @@ static int ly_add_ip_link_data(const struct ly_ctx *ctx, struct lyd_node **paren
return SR_ERR_OK;
}
static int ly_add_mtu(const struct ly_ctx *ctx, struct lyd_node *node,
char *xpath, json_t *j_iface, char *ifname)
static int ly_add_ip_mtu(const struct ly_ctx *ctx, struct lyd_node *node,
char *xpath, json_t *j_iface, char *ifname)
{
json_t *j_val;
int err;
@@ -502,28 +503,45 @@ static int ly_add_mtu(const struct ly_ctx *ctx, struct lyd_node *node,
return SR_ERR_OK;
}
static int ly_add_ipv4_address_origin(const struct ly_ctx *ctx, struct lyd_node *addr_node,
char *addr_xpath, json_t *j_proto)
static int ly_add_ip_addr_origin(const struct ly_ctx *ctx, struct lyd_node *addr_node,
char *addr_xpath, json_t *j_addr)
{
const char *origin;
json_t *j_val;
int err;
if (!json_is_string(j_proto)) {
ERROR("Expected a JSON string for ipv4 'protocol'");
/* It's okey not to have an origin */
j_val = json_object_get(j_addr, "protocol");
if (!j_val)
return SR_ERR_OK;
if (!json_is_string(j_val)) {
ERROR("Expected a JSON string for ip 'protocol'");
return SR_ERR_SYS;
}
origin = get_yang_origin(json_string_value(j_proto));
origin = get_yang_origin(json_string_value(j_val));
/**
* kernel_ll/link-layer only has a link-layer origin if its address is
* based on the link layer address (addrgenmode eui64).
*/
if (strcmp(origin, "link-layer") == 0) {
j_val = json_object_get(j_addr, "stable-privacy");
if (j_val && json_is_boolean(j_val) && json_boolean_value(j_val))
origin = "random";
}
err = lydx_new_path(ctx, &addr_node, addr_xpath, "origin", "%s", origin);
if (err) {
ERROR("Error, adding ipv4 'origin' to data tree, libyang error %d", err);
ERROR("Error, adding ip 'origin' to data tree, libyang error %d", err);
return SR_ERR_LY;
}
return SR_ERR_OK;
}
static int ly_add_ipv4_address(const struct ly_ctx *ctx, struct lyd_node *ipv4_node,
static int ly_add_ip_addr_info(const struct ly_ctx *ctx, struct lyd_node *node,
char *xpath, json_t *j_addr)
{
struct lyd_node *addr_node = NULL;
@@ -534,7 +552,7 @@ static int ly_add_ipv4_address(const struct ly_ctx *ctx, struct lyd_node *ipv4_n
j_val = json_object_get(j_addr, "local");
if (!json_is_string(j_val)) {
ERROR("Expected a JSON string for ipv4 'local'");
ERROR("Expected a JSON string for ip 'local'");
return SR_ERR_SYS;
}
ip = json_string_value(j_val);
@@ -545,9 +563,9 @@ static int ly_add_ipv4_address(const struct ly_ctx *ctx, struct lyd_node *ipv4_n
return SR_ERR_SYS;
}
err = lyd_new_path(ipv4_node, ctx, addr_xpath, NULL, 0, &addr_node);
err = lyd_new_path(node, ctx, addr_xpath, NULL, 0, &addr_node);
if (err) {
ERROR("Failed adding ipv4 'address' node (%s), libyang error %d: %s",
ERROR("Failed adding ip 'address' node (%s), libyang error %d: %s",
addr_xpath, err, ly_errmsg(ctx));
free(addr_xpath);
return SR_ERR_LY;
@@ -555,7 +573,7 @@ static int ly_add_ipv4_address(const struct ly_ctx *ctx, struct lyd_node *ipv4_n
j_val = json_object_get(j_addr, "prefixlen");
if (!json_is_integer(j_val)) {
ERROR("Expected a JSON integer for ipv4 'prefixlen'");
ERROR("Expected a JSON integer for ip 'prefixlen'");
free(addr_xpath);
return SR_ERR_SYS;
}
@@ -563,41 +581,37 @@ static int ly_add_ipv4_address(const struct ly_ctx *ctx, struct lyd_node *ipv4_n
err = lydx_new_path(ctx, &addr_node, addr_xpath, "prefix-length",
"%lld", json_integer_value(j_val));
if (err) {
ERROR("Error, adding ipv4 'prefix-length' to data tree, libyang error %d", err);
ERROR("Error, adding ip 'prefix-length' to data tree, libyang error %d", err);
free(addr_xpath);
return SR_ERR_LY;
}
j_val = json_object_get(j_addr, "protocol");
if (j_val)
err = ly_add_ipv4_address_origin(ctx, addr_node, addr_xpath, j_val);
else
err = SR_ERR_OK;
err = ly_add_ip_addr_origin(ctx, addr_node, addr_xpath, j_addr);
free(addr_xpath);
return err;
}
static int ly_add_ipv4_addr_data(const struct ly_ctx *ctx, struct lyd_node **parent,
char *xpath, json_t *j_iface, char *ifname)
static int ly_add_ip_data(const struct ly_ctx *ctx, struct lyd_node **parent,
char *xpath, int version, json_t *j_iface, char *ifname)
{
struct lyd_node *ipv4_node = NULL;
struct lyd_node *node = NULL;
json_t *j_val;
json_t *j_addr;
size_t index;
int err;
err = lyd_new_path(*parent, ctx, xpath, NULL, 0, &ipv4_node);
err = lyd_new_path(*parent, ctx, xpath, NULL, 0, &node);
if (err) {
ERROR("Failed adding 'ipv4' node (%s), libyang error %d: %s",
ERROR("Failed adding 'ip' node (%s), libyang error %d: %s",
xpath, err, ly_errmsg(ctx));
return SR_ERR_LY;
}
err = ly_add_mtu(ctx, ipv4_node, xpath, j_iface, ifname);
err = ly_add_ip_mtu(ctx, node, xpath, j_iface, ifname);
if (err) {
ERROR("Error, adding ipv4 MTU");
ERROR("Error, adding ip MTU");
return err;
}
@@ -612,14 +626,20 @@ static int ly_add_ipv4_addr_data(const struct ly_ctx *ctx, struct lyd_node **par
j_family = json_object_get(j_addr, "family");
if (!json_is_string(j_family)) {
ERROR("Expected a JSON string for ipv4 'family'");
ERROR("Expected a JSON string for ip 'family'");
return SR_ERR_SYS;
}
if (strcmp(json_string_value(j_family), "inet") == 0) {
err = ly_add_ipv4_address(ctx, ipv4_node, xpath, j_addr);
if (version == 4 && (strcmp(json_string_value(j_family), "inet") == 0)) {
err = ly_add_ip_addr_info(ctx, node, xpath, j_addr);
if (err) {
ERROR("Error, adding ipv4 address");
ERROR("Error, adding address");
return err;
}
} else if (version == 6 && (strcmp(json_string_value(j_family), "inet6") == 0)) {
err = ly_add_ip_addr_info(ctx, node, xpath, j_addr);
if (err) {
ERROR("Error, adding address");
return err;
}
}
@@ -686,9 +706,19 @@ static int ly_add_ip_addr(const struct ly_ctx *ctx, struct lyd_node **parent, ch
snprintf(xpath, sizeof(xpath), "%s/interface[name='%s']/ietf-ip:ipv4",
XPATH_IFACE_BASE, ifname);
err = ly_add_ipv4_addr_data(ctx, parent, xpath, j_iface, ifname);
err = ly_add_ip_data(ctx, parent, xpath, 4, j_iface, ifname);
if (err) {
ERROR("Error, adding ip-addr info for %s", ifname);
ERROR("Error, adding ipv4 addr info for %s", ifname);
json_decref(j_root);
return err;
}
snprintf(xpath, sizeof(xpath), "%s/interface[name='%s']/ietf-ip:ipv6",
XPATH_IFACE_BASE, ifname);
err = ly_add_ip_data(ctx, parent, xpath, 6, j_iface, ifname);
if (err) {
ERROR("Error, adding ipv6 addr info for %s", ifname);
json_decref(j_root);
return err;
}