confd: Infer type when configuring physical interfaces

This commit is contained in:
Tobias Waldekranz
2023-05-12 14:24:41 +02:00
committed by Joachim Wiberg
parent ed41b621d9
commit 80d9312e36
4 changed files with 67 additions and 3 deletions
+2 -2
View File
@@ -4,8 +4,8 @@ AM_CPPFLAGS = -D_DEFAULT_SOURCE -D_XOPEN_SOURCE -D_GNU_SOURCE -DYANG
plugindir = $(srpdplugindir)
plugin_LTLIBRARIES = confd-plugin.la
confd_plugin_la_CFLAGS = $(augeas_CFLAGS) $(libite_CFLAGS) $(sysrepo_CFLAGS) $(CFLAGS)
confd_plugin_la_LIBADD = $(augeas_LIBS) $(libite_LIBS) $(sysrepo_LIBS)
confd_plugin_la_CFLAGS = $(augeas_CFLAGS) $(jansson_CFLAGS) $(libite_CFLAGS) $(sysrepo_CFLAGS) $(CFLAGS)
confd_plugin_la_LIBADD = $(augeas_LIBS) $(jansson_LIBS) $(libite_LIBS) $(sysrepo_LIBS)
confd_plugin_la_LDFLAGS = -module -avoid-version -shared
confd_plugin_la_SOURCES = core.c core.h helpers.c helpers.h srx_module.c srx_module.h srx_val.c srx_val.h \
ietf-system.c ietf-interfaces.c systemv.c systemv.h
+22
View File
@@ -1,8 +1,30 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#include <errno.h>
#include <stdarg.h>
#include "core.h"
FILE *popenf(const char *type, const char *cmdf, ...)
{
va_list ap;
char *cmd;
FILE *fp;
int len;
va_start(ap, cmdf);
len = vasprintf(&cmd, cmdf, ap);
va_end(ap);
if (len < 0) {
errno = ENOMEM;
return NULL;
}
fp = popen(cmd, type);
free(cmd);
return fp;
}
static FILE *open_file(const char *mode, const char *fmt, va_list ap)
{
va_list apc;
+2
View File
@@ -3,6 +3,8 @@
#ifndef CONFD_HELPERS_H_
#define CONFD_HELPERS_H_
FILE *popenf(const char *type, const char *cmdf, ...);
int writedf(int value, const char *fmt, ...);
int writesf(const char *str, const char *fmt, ...);
+41 -1
View File
@@ -1,6 +1,9 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#include <fnmatch.h>
#include <stdbool.h>
#include <jansson.h>
#include <net/if.h>
@@ -172,6 +175,41 @@ static void ifinit(sr_session_ctx_t *session)
ERROR("failed: %s", sr_strerror(rc));
}
static bool iface_is_phys(const char *ifname)
{
bool is_phys = false;
json_error_t jerr;
const char *attr;
json_t *link;
FILE *proc;
proc = popenf("re", "ip -d -j link show dev %s", ifname);
if (!proc)
goto out;
link = json_loadf(proc, 0, &jerr);
pclose(proc);
if (!link)
goto out;
if (json_unpack(link, "[{s:s}]", "link_type", &attr))
goto out_free;
if (strcmp(attr, "ether"))
goto out_free;
if (!json_unpack(link, "[{s: { s:s }}]", "linkinfo", "info_kind", &attr))
goto out_free;
is_phys = true;
out_free:
json_decref(link);
out:
return is_phys;
}
static int ifchange_cand_infer_type(sr_session_ctx_t *session, const char *xpath)
{
sr_val_t inferred = { .type = SR_STRING_T };
@@ -188,7 +226,9 @@ static int ifchange_cand_infer_type(sr_session_ctx_t *session, const char *xpath
if (!ifname)
return SR_ERR_INTERNAL;
if (!fnmatch("br+([0-9])", ifname, FNM_EXTMATCH))
if (iface_is_phys(ifname))
inferred.data.string_val = "iana-if-type:ethernetCsmacd";
else if (!fnmatch("br+([0-9])", ifname, FNM_EXTMATCH))
inferred.data.string_val = "iana-if-type:bridge";
else if (!fnmatch("lag+([0-9])", ifname, FNM_EXTMATCH))
inferred.data.string_val = "iana-if-type:ieee8023adLag";