confd: add sloppy inference of container-network type

"Sloppy" because, for some reason, we don't get sysrepo update callbacks
for presence containers.  I.e., when calling 'set container-network'
compared to 'edit container-network'.

Yes, I've gone over klish-plugins-sysrepo with a fine-toothed comb to
see if it's the culprit, but no, it seems to be sysrepo.  Hence the
defaulting of the type also in the change path.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg
2024-02-25 19:49:27 +01:00
parent e4aa36dfe7
commit a05a3609c5
+79
View File
@@ -270,6 +270,29 @@ static int iface_gen_cni(const char *ifname, struct lyd_node *cif)
struct lyd_node *net = lydx_get_child(cif, "container-network");
const char *type = lydx_get_cattr(net, "type");
/*
* klish/sysrepo does not seem to call update callbacks for
* presence containers, so we have to be prepared for the
* worst here and perform late type inference. What works:
*
* edit container-network # callback called
*
* What doesn't work:
*
* set container-network # callback not called
*
* Funnily enough, "show running-config" shows the empty
* "container-network": {}, so someone does their job.
*/
if (!type) {
const char *iftype = lydx_get_cattr(cif, "type");
if (iftype && !strcmp(iftype, "infix-if-type:bridge"))
type = "bridge";
else
type = "host";
}
if (!strcmp(type, "host"))
return cni_host(net, ifname);
@@ -470,6 +493,54 @@ out:
return err;
}
static int ifchange_cand_infer_cni_type(sr_session_ctx_t *session, const char *path)
{
sr_val_t inferred = { .type = SR_STRING_T };
struct lyd_node *node, *net;
sr_error_t err = SR_ERR_OK;
char *xpath, *iftype;
sr_data_t *cfg;
xpath = iface_xpath(path);
if (!xpath)
return SR_ERR_SYS;
err = sr_get_data(session, path, 0, 0, 0, &cfg);
if (err)
goto err;
node = lydx_get_descendant(cfg->tree, "interfaces", "interface", NULL);
if (!node)
goto out;
net = lydx_get_child(node, "container-network");
if (!net)
goto out;
if (lydx_get_cattr(net, "type"))
goto out; /* CNI type is already set */
/* Infer from ietf-interface type, reduces typing */
iftype = srx_get_str(session, "%s/type", xpath);
if (iftype && !strcmp(iftype, "infix-if-type:bridge"))
inferred.data.string_val = "bridge";
else
inferred.data.string_val = "host";
err = srx_set_item(session, &inferred, 0, "%s/type", path);
if (err)
ERROR("failed setting container-network type %s, err %d: %s",
inferred.data.string_val, err, sr_strerror(err));
if (iftype)
free(iftype);
out:
sr_release_data(cfg);
err:
free(xpath);
return err;
}
static int ifchange_cand_infer_type(sr_session_ctx_t *session, const char *path)
{
sr_val_t inferred = { .type = SR_STRING_T };
@@ -496,6 +567,10 @@ static int ifchange_cand_infer_type(sr_session_ctx_t *session, const char *path)
inferred.data.string_val = "infix-if-type:ethernet";
else if (!fnmatch("br+([0-9])", ifname, FNM_EXTMATCH))
inferred.data.string_val = "infix-if-type:bridge";
else if (!fnmatch("docker+([0-9])", ifname, FNM_EXTMATCH))
inferred.data.string_val = "infix-if-type:bridge";
else if (!fnmatch("podman+([0-9])", ifname, FNM_EXTMATCH))
inferred.data.string_val = "infix-if-type:bridge";
else if (!fnmatch("lag+([0-9])", ifname, FNM_EXTMATCH))
inferred.data.string_val = "infix-if-type:lag";
else if (!fnmatch("veth+([0-9a-z_-])", ifname, FNM_EXTMATCH))
@@ -555,6 +630,10 @@ static int ifchange_cand(sr_session_ctx_t *session, uint32_t sub_id, const char
err = ifchange_cand_infer_vlan(session, new->xpath);
if (err)
break;
err = ifchange_cand_infer_cni_type(session, new->xpath);
if (err)
break;
}
sr_free_change_iter(iter);