diff --git a/src/statd/statd.c b/src/statd/statd.c index 66644ec5..158013bb 100644 --- a/src/statd/statd.c +++ b/src/statd/statd.c @@ -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; }