mirror of
https://github.com/kernelkit/infix.git
synced 2026-08-06 23:43:20 +02:00
statd: add operational ipv4 address data
Add IPv4 address info from "ip addr" json to sysrepo operational datastore. This patch adds: MTU and ip with prefix-length. Signed-off-by: Richard Alpe <richard@bit42.se>
This commit is contained in:
committed by
Tobias Waldekranz
parent
d34908a0e5
commit
2656f17f58
+176
-8
@@ -104,19 +104,12 @@ static void sub_delete(struct ev_loop *loop, struct sub_head *subs, struct sub *
|
||||
free(sub);
|
||||
}
|
||||
|
||||
|
||||
static json_t *json_get_ip_link(char *ifname)
|
||||
static json_t *_json_get_ip_output(const char *cmd)
|
||||
{
|
||||
char cmd[512] = {}; /* Size is arbitrary */
|
||||
json_error_t j_err;
|
||||
json_t *j_root;
|
||||
FILE *proc;
|
||||
|
||||
if (ifname)
|
||||
snprintf(cmd, sizeof(cmd), "ip -s -d -j link show dev %s 2>/dev/null", ifname);
|
||||
else
|
||||
snprintf(cmd, sizeof(cmd), "ip -s -d -j link show 2>/dev/null");
|
||||
|
||||
proc = popenf("re", cmd);
|
||||
if (!proc) {
|
||||
ERROR("Error, running ip link command");
|
||||
@@ -139,6 +132,30 @@ static json_t *json_get_ip_link(char *ifname)
|
||||
return j_root;
|
||||
}
|
||||
|
||||
static json_t *json_get_ip_link(const char *ifname)
|
||||
{
|
||||
char cmd[512] = {}; /* Size is arbitrary */
|
||||
|
||||
if (ifname)
|
||||
snprintf(cmd, sizeof(cmd), "ip -s -d -j link show dev %s 2>/dev/null", ifname);
|
||||
else
|
||||
snprintf(cmd, sizeof(cmd), "ip -s -d -j link show 2>/dev/null");
|
||||
|
||||
return _json_get_ip_output(cmd);
|
||||
}
|
||||
|
||||
static json_t *json_get_ip_addr(const char *ifname)
|
||||
{
|
||||
char cmd[512] = {}; /* Size is arbitrary */
|
||||
|
||||
if (ifname)
|
||||
snprintf(cmd, sizeof(cmd), "ip -j addr show dev %s 2>/dev/null", ifname);
|
||||
else
|
||||
snprintf(cmd, sizeof(cmd), "ip -j addr show 2>/dev/null");
|
||||
|
||||
return _json_get_ip_output(cmd);
|
||||
}
|
||||
|
||||
static const char *get_yang_operstate(const char *operstate)
|
||||
{
|
||||
size_t i;
|
||||
@@ -350,6 +367,117 @@ static int ly_add_ip_link_data(const struct ly_ctx *ctx, struct lyd_node **paren
|
||||
return SR_ERR_LY;
|
||||
}
|
||||
|
||||
j_val = json_object_get(iface, "address");
|
||||
if (!json_is_string(j_val)) {
|
||||
ERROR("Expected a JSON string for 'address'");
|
||||
return SR_ERR_SYS;
|
||||
}
|
||||
|
||||
err = lydx_new_path(ctx, parent, xpath, "phys-address", json_string_value(j_val));
|
||||
if (err) {
|
||||
ERROR("Error, adding 'phys-address' to data tree, libyang error %d", err);
|
||||
return SR_ERR_LY;
|
||||
}
|
||||
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
static int ly_add_ip_addr_data(const struct ly_ctx *ctx, struct lyd_node **parent,
|
||||
char *xpath, json_t *j_iface, char *ifname)
|
||||
{
|
||||
struct lyd_node *ipv4_node = NULL;
|
||||
json_t *j_val;
|
||||
json_t *j_arr;
|
||||
size_t index;
|
||||
int err;
|
||||
|
||||
err = lyd_new_path(*parent, ctx, xpath, NULL, 0, &ipv4_node);
|
||||
if (err) {
|
||||
ERROR("Failed adding 'ipv4' node (%s), libyang error %d: %s",
|
||||
xpath, err, ly_errmsg(ctx));
|
||||
return SR_ERR_LY;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Not sure how to handle loopback MTU (65536) which is
|
||||
* out of bounds for both YANG and uint16_t. For now, we skip it.
|
||||
*/
|
||||
if (strcmp(ifname, "lo") != 0) {
|
||||
j_val = json_object_get(j_iface, "mtu");
|
||||
if (!json_is_integer(j_val)) {
|
||||
ERROR("Expected a JSON integer for 'mtu'");
|
||||
return SR_ERR_SYS;
|
||||
}
|
||||
|
||||
err = lydx_new_path(ctx, &ipv4_node, xpath, "mtu", "%lld",
|
||||
json_integer_value(j_val));
|
||||
if (err) {
|
||||
ERROR("Error, adding 'mtu' to data tree, libyang error %d", err);
|
||||
return SR_ERR_LY;
|
||||
}
|
||||
}
|
||||
|
||||
j_arr = json_object_get(j_iface, "addr_info");
|
||||
if (!json_is_array(j_arr)) {
|
||||
ERROR("Expected a JSON array for 'addr_info'");
|
||||
return SR_ERR_SYS;
|
||||
}
|
||||
|
||||
json_array_foreach(j_arr, index, j_val) {
|
||||
struct lyd_node *addr_node = NULL;
|
||||
char *addr_xpath;
|
||||
json_t *j_family;
|
||||
json_t *j_local;
|
||||
json_t *j_prefix;
|
||||
const char *ip;
|
||||
|
||||
j_family = json_object_get(j_val, "family");
|
||||
if (!json_is_string(j_family)) {
|
||||
ERROR("Expected a JSON string for ipv4 'family'");
|
||||
return SR_ERR_SYS;
|
||||
}
|
||||
/* TODO: We only handle ipv4 for now */
|
||||
if (strcmp(json_string_value(j_family), "inet") != 0)
|
||||
continue;
|
||||
|
||||
j_local = json_object_get(j_val, "local");
|
||||
if (!json_is_string(j_local)) {
|
||||
ERROR("Expected a JSON string for ipv4 'local'");
|
||||
return SR_ERR_SYS;
|
||||
}
|
||||
ip = json_string_value(j_local);
|
||||
|
||||
err = asprintf(&addr_xpath, "%s/address[ip='%s']", xpath, ip);
|
||||
if (err == -1) {
|
||||
ERROR("Error, creating address xpath");
|
||||
return SR_ERR_SYS;
|
||||
}
|
||||
|
||||
err = lyd_new_path(ipv4_node, ctx, addr_xpath, NULL, 0, &addr_node);
|
||||
if (err) {
|
||||
ERROR("Failed adding ipv4 'address' node (%s), libyang error %d: %s",
|
||||
addr_xpath, err, ly_errmsg(ctx));
|
||||
free(addr_xpath);
|
||||
return SR_ERR_LY;
|
||||
}
|
||||
|
||||
j_prefix = json_object_get(j_val, "prefixlen");
|
||||
if (!json_is_integer(j_prefix)) {
|
||||
ERROR("Expected a JSON integer for ipv4 'prefixlen'");
|
||||
free(addr_xpath);
|
||||
return SR_ERR_SYS;
|
||||
}
|
||||
|
||||
err = lydx_new_path(ctx, &addr_node, addr_xpath, "prefix-length",
|
||||
"%lld", json_integer_value(j_prefix));
|
||||
if (err) {
|
||||
ERROR("Error, adding ipv4 'prefix-length' to data tree, libyang error %d", err);
|
||||
free(addr_xpath);
|
||||
return SR_ERR_LY;
|
||||
}
|
||||
free(addr_xpath);
|
||||
}
|
||||
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
@@ -382,6 +510,42 @@ static int ly_add_ip_link(const struct ly_ctx *ctx, struct lyd_node **parent, ch
|
||||
json_decref(j_root);
|
||||
return err;
|
||||
}
|
||||
|
||||
json_decref(j_root);
|
||||
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
static int ly_add_ip_addr(const struct ly_ctx *ctx, struct lyd_node **parent, char *ifname)
|
||||
{
|
||||
char xpath[XPATH_MAX] = {};
|
||||
json_t *j_root;
|
||||
json_t *j_iface;
|
||||
int err;
|
||||
|
||||
j_root = json_get_ip_addr(ifname);
|
||||
if (!j_root) {
|
||||
ERROR("Error, parsing ip-addr JSON");
|
||||
return SR_ERR_SYS;
|
||||
}
|
||||
if (json_array_size(j_root) != 1) {
|
||||
ERROR("Error, expected JSON array of single iface");
|
||||
json_decref(j_root);
|
||||
return SR_ERR_SYS;
|
||||
}
|
||||
|
||||
j_iface = json_array_get(j_root, 0);
|
||||
|
||||
snprintf(xpath, sizeof(xpath), "%s/interface[name='%s']/ietf-ip:ipv4",
|
||||
XPATH_IFACE_BASE, ifname);
|
||||
|
||||
err = ly_add_ip_addr_data(ctx, parent, xpath, j_iface, ifname);
|
||||
if (err) {
|
||||
ERROR("Error, adding ip-addr info for %s", ifname);
|
||||
json_decref(j_root);
|
||||
return err;
|
||||
}
|
||||
|
||||
json_decref(j_root);
|
||||
|
||||
return SR_ERR_OK;
|
||||
@@ -414,6 +578,10 @@ static int sr_ifaces_cb(sr_session_ctx_t *session, uint32_t, const char *path,
|
||||
if (err)
|
||||
ERROR("Error, adding ip link info");
|
||||
|
||||
err = ly_add_ip_addr(ctx, parent, sub->ifname);
|
||||
if (err)
|
||||
ERROR("Error, adding ip link info");
|
||||
|
||||
sr_release_context(con);
|
||||
|
||||
return err;
|
||||
|
||||
Reference in New Issue
Block a user