diff --git a/board/aarch64/linux_defconfig b/board/aarch64/linux_defconfig index ca1ab4c2b..3ad3f1315 100644 --- a/board/aarch64/linux_defconfig +++ b/board/aarch64/linux_defconfig @@ -67,28 +67,32 @@ CONFIG_CMA=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y +CONFIG_XDP_SOCKETS=y +CONFIG_XDP_SOCKETS_DIAG=y CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_NET_IPIP=y -CONFIG_NET_IPGRE_DEMUX=y -CONFIG_NET_IPGRE=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IPGRE=m CONFIG_NET_IPGRE_BROADCAST=y CONFIG_IP_MROUTE=y CONFIG_IP_MROUTE_MULTIPLE_TABLES=y CONFIG_IP_PIMSM_V1=y CONFIG_IP_PIMSM_V2=y -CONFIG_NET_IPVTI=y +CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_IPV6_SIT=m +CONFIG_IPV6_GRE=m CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MROUTE=y CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y CONFIG_IPV6_PIMSM_V2=y +CONFIG_NETWORK_PHY_TIMESTAMPING=y CONFIG_NETFILTER=y CONFIG_BRIDGE_NETFILTER=y CONFIG_NETFILTER_NETLINK_QUEUE=y @@ -98,6 +102,26 @@ CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CONNTRACK_FTP=y CONFIG_NF_TABLES=y CONFIG_NF_TABLES_INET=y +CONFIG_NF_TABLES_NETDEV=y +CONFIG_NFT_CT=m +CONFIG_NFT_CONNLIMIT=m +CONFIG_NFT_LOG=m +CONFIG_NFT_LIMIT=m +CONFIG_NFT_MASQ=m +CONFIG_NFT_REDIR=m +CONFIG_NFT_NAT=m +CONFIG_NFT_TUNNEL=m +CONFIG_NFT_OBJREF=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_REJECT=m +CONFIG_NFT_COMPAT=m +CONFIG_NFT_HASH=m +CONFIG_NFT_XFRM=m +CONFIG_NFT_SOCKET=m +CONFIG_NFT_OSF=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m +CONFIG_NFT_REJECT_NETDEV=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m @@ -108,7 +132,37 @@ CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_NAT=m CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_MANGLE=m -CONFIG_NF_LOG_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_NAT=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m +CONFIG_NF_TABLES_BRIDGE=m +CONFIG_NFT_BRIDGE_META=m +CONFIG_NF_CONNTRACK_BRIDGE=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_NFLOG=m CONFIG_BRIDGE=y CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_BRIDGE_MRP=y @@ -117,9 +171,16 @@ CONFIG_NET_DSA=y CONFIG_VLAN_8021Q=y CONFIG_VLAN_8021Q_GVRP=y CONFIG_VLAN_8021Q_MVRP=y -CONFIG_NET_L3_MASTER_DEV=y +CONFIG_NETLINK_DIAG=y +CONFIG_MPLS=y +CONFIG_NET_MPLS_GSO=y +CONFIG_MPLS_ROUTING=m +CONFIG_MPLS_IPTUNNEL=m +CONFIG_NET_PKTGEN=y +# CONFIG_WIRELESS is not set CONFIG_NET_9P=y CONFIG_NET_9P_VIRTIO=y +CONFIG_LWTUNNEL=y CONFIG_PCI=y CONFIG_PCIEPORTBUS=y CONFIG_PCI_IOV=y @@ -163,21 +224,21 @@ CONFIG_DM_INIT=y CONFIG_DM_VERITY=y CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y CONFIG_NETDEVICES=y -CONFIG_BONDING=y -CONFIG_DUMMY=y -CONFIG_NET_TEAM=y -CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=y -CONFIG_NET_TEAM_MODE_LOADBALANCE=y -CONFIG_MACVLAN=y -CONFIG_MACVTAP=y -CONFIG_IPVLAN=y -CONFIG_IPVTAP=y -CONFIG_VXLAN=y -CONFIG_GENEVE=y -CONFIG_BAREUDP=y -CONFIG_MACSEC=y -CONFIG_TUN=y -CONFIG_VETH=y +CONFIG_BONDING=m +CONFIG_DUMMY=m +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_IPVLAN=m +CONFIG_IPVTAP=m +CONFIG_VXLAN=m +CONFIG_GENEVE=m +CONFIG_BAREUDP=m +CONFIG_MACSEC=m +CONFIG_TUN=m +CONFIG_VETH=m CONFIG_VIRTIO_NET=y CONFIG_NLMON=y CONFIG_NET_VRF=y diff --git a/board/amd64/linux_defconfig b/board/amd64/linux_defconfig index 423675b5c..bc141589a 100644 --- a/board/amd64/linux_defconfig +++ b/board/amd64/linux_defconfig @@ -38,25 +38,32 @@ CONFIG_MODULE_UNLOAD=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y +CONFIG_XDP_SOCKETS=y +CONFIG_XDP_SOCKETS_DIAG=y CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_NET_IPIP=y -CONFIG_NET_IPGRE_DEMUX=y -CONFIG_NET_IPGRE=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IPGRE=m CONFIG_NET_IPGRE_BROADCAST=y CONFIG_IP_MROUTE=y CONFIG_IP_MROUTE_MULTIPLE_TABLES=y CONFIG_IP_PIMSM_V1=y CONFIG_IP_PIMSM_V2=y -CONFIG_NET_IPVTI=y +CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_IPV6_SIT=m +CONFIG_IPV6_GRE=m CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MROUTE=y CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y CONFIG_IPV6_PIMSM_V2=y +CONFIG_NETWORK_PHY_TIMESTAMPING=y CONFIG_NETFILTER=y CONFIG_BRIDGE_NETFILTER=y CONFIG_NETFILTER_NETLINK_QUEUE=y @@ -66,6 +73,26 @@ CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CONNTRACK_FTP=y CONFIG_NF_TABLES=y CONFIG_NF_TABLES_INET=y +CONFIG_NF_TABLES_NETDEV=y +CONFIG_NFT_CT=m +CONFIG_NFT_CONNLIMIT=m +CONFIG_NFT_LOG=m +CONFIG_NFT_LIMIT=m +CONFIG_NFT_MASQ=m +CONFIG_NFT_REDIR=m +CONFIG_NFT_NAT=m +CONFIG_NFT_TUNNEL=m +CONFIG_NFT_OBJREF=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_REJECT=m +CONFIG_NFT_COMPAT=m +CONFIG_NFT_HASH=m +CONFIG_NFT_XFRM=m +CONFIG_NFT_SOCKET=m +CONFIG_NFT_OSF=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m +CONFIG_NFT_REJECT_NETDEV=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m @@ -76,7 +103,37 @@ CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_NAT=m CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_MANGLE=m -CONFIG_NF_LOG_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_NAT=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m +CONFIG_NF_TABLES_BRIDGE=m +CONFIG_NFT_BRIDGE_META=m +CONFIG_NF_CONNTRACK_BRIDGE=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_NFLOG=m CONFIG_BRIDGE=y CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_BRIDGE_MRP=y @@ -84,8 +141,16 @@ CONFIG_BRIDGE_CFM=y CONFIG_VLAN_8021Q=y CONFIG_VLAN_8021Q_GVRP=y CONFIG_VLAN_8021Q_MVRP=y +CONFIG_NETLINK_DIAG=y +CONFIG_MPLS=y +CONFIG_NET_MPLS_GSO=y +CONFIG_MPLS_ROUTING=m +CONFIG_MPLS_IPTUNNEL=m +CONFIG_NET_PKTGEN=y +# CONFIG_WIRELESS is not set CONFIG_NET_9P=y CONFIG_NET_9P_VIRTIO=y +CONFIG_LWTUNNEL=y CONFIG_PCI=y CONFIG_UEVENT_HELPER=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" @@ -107,21 +172,21 @@ CONFIG_BLK_DEV_DM=y CONFIG_DM_VERITY=y CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y CONFIG_NETDEVICES=y -CONFIG_BONDING=y -CONFIG_DUMMY=y -CONFIG_NET_TEAM=y -CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=y -CONFIG_NET_TEAM_MODE_LOADBALANCE=y -CONFIG_MACVLAN=y -CONFIG_MACVTAP=y -CONFIG_IPVLAN=y -CONFIG_IPVTAP=y -CONFIG_VXLAN=y -CONFIG_GENEVE=y -CONFIG_BAREUDP=y -CONFIG_MACSEC=y -CONFIG_TUN=y -CONFIG_VETH=y +CONFIG_BONDING=m +CONFIG_DUMMY=m +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_IPVLAN=m +CONFIG_IPVTAP=m +CONFIG_VXLAN=m +CONFIG_GENEVE=m +CONFIG_BAREUDP=m +CONFIG_MACSEC=m +CONFIG_TUN=m +CONFIG_VETH=m CONFIG_VIRTIO_NET=y CONFIG_NLMON=y CONFIG_NET_VRF=y @@ -134,24 +199,18 @@ CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_VIRTIO_CONSOLE=y CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_I2C=y CONFIG_WATCHDOG=y CONFIG_WATCHDOG_SYSFS=y CONFIG_SOFT_WATCHDOG=y CONFIG_I6300ESB_WDT=y -CONFIG_DRM=y -CONFIG_DRM_QXL=y -CONFIG_DRM_VIRTIO_GPU=y -CONFIG_DRM_BOCHS=y -CONFIG_SOUND=y -CONFIG_SND=y -CONFIG_SND_HDA_INTEL=y -CONFIG_SND_HDA_GENERIC=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_UHCI_HCD=y CONFIG_USB_STORAGE=y CONFIG_RTC_CLASS=y +CONFIG_SYNC_FILE=y CONFIG_VIRTIO_PCI=y CONFIG_VIRTIO_BALLOON=y CONFIG_VIRTIO_INPUT=y @@ -172,7 +231,9 @@ CONFIG_SQUASHFS_ZSTD=y CONFIG_9P_FS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y +CONFIG_CRYPTO_GCM=y CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_AES=y CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_FS=y diff --git a/board/common/rootfs/etc/modprobe.d/bonding.conf b/board/common/rootfs/etc/modprobe.d/bonding.conf new file mode 100644 index 000000000..88f138543 --- /dev/null +++ b/board/common/rootfs/etc/modprobe.d/bonding.conf @@ -0,0 +1,2 @@ +options bonding max_bonds=0 + diff --git a/board/common/rootfs/etc/modprobe.d/dummy.conf b/board/common/rootfs/etc/modprobe.d/dummy.conf new file mode 100644 index 000000000..022ea0773 --- /dev/null +++ b/board/common/rootfs/etc/modprobe.d/dummy.conf @@ -0,0 +1,2 @@ +options dummy numdummies=0 + diff --git a/board/common/rootfs/etc/sysctl.d/forwarding.conf b/board/common/rootfs/etc/sysctl.d/forwarding.conf new file mode 100644 index 000000000..c24ade969 --- /dev/null +++ b/board/common/rootfs/etc/sysctl.d/forwarding.conf @@ -0,0 +1,2 @@ +net.ipv4.ip_forward=1 +net.ipv6.conf.all.forwarding=1 diff --git a/board/common/rootfs/etc/sysctl.d/system.conf b/board/common/rootfs/etc/sysctl.d/system.conf new file mode 100644 index 000000000..cca845303 --- /dev/null +++ b/board/common/rootfs/etc/sysctl.d/system.conf @@ -0,0 +1 @@ +net.core.fb_tunnels_only_for_init_net=2 diff --git a/src/confd/configure.ac b/src/confd/configure.ac index fe2923ee6..e3d46a948 100644 --- a/src/confd/configure.ac +++ b/src/confd/configure.ac @@ -15,12 +15,17 @@ AC_CONFIG_FILES([ AC_PROG_CC AC_PROG_INSTALL +AC_CONFIG_LIBOBJ_DIR(lib) +AC_REPLACE_FUNCS(vasprintf) +AC_REPLACE_FUNCS(asprintf) + # Check for pkg-config first, warn if it's not installed PKG_PROG_PKG_CONFIG -PKG_CHECK_MODULES([sysrepo], [sysrepo >= 2.2.36]) PKG_CHECK_MODULES([augeas], [augeas >= 1.12.0]) PKG_CHECK_MODULES([jansson], [jansson >= 2.0.0]) +PKG_CHECK_MODULES([libite], [libite >= 2.5.0]) +PKG_CHECK_MODULES([sysrepo], [sysrepo >= 2.2.36]) # Plugin installation path for sysrepo-plugind PKG_CHECK_VAR([srpdplugindir], [sysrepo], [SRPD_PLUGINS_PATH]) diff --git a/src/confd/lib/asprintf.c b/src/confd/lib/asprintf.c new file mode 100644 index 000000000..18b4fe34f --- /dev/null +++ b/src/confd/lib/asprintf.c @@ -0,0 +1,18 @@ +#include +#include +#include + +#ifndef HAVE_VASPRINTF +int vasprintf(char **strp, const char *fmt, va_list ap); +#endif + +int asprintf(char **strp, const char *fmt, ...) +{ + va_list ap; + int len; + + va_start(ap, fmt); + len = vasprintf(strp, fmt, ap); + va_end(ap); + return len; +} diff --git a/src/confd/lib/vasprintf.c b/src/confd/lib/vasprintf.c new file mode 100644 index 000000000..b79bdfc11 --- /dev/null +++ b/src/confd/lib/vasprintf.c @@ -0,0 +1,25 @@ +#include +#include +#include + +int vasprintf(char **strp, const char *fmt, va_list ap) +{ + va_list apdup; + char *str; + int len; + + va_copy(apdup, ap); + len = vsnprintf(0, 0, fmt, apdup); + va_end(apdup); + + if (len < 0) + return -1; + + len++; + str = malloc(len); + if (!str) + return -1; + + *strp = str; + return vsnprintf(str, len, fmt, ap); +} diff --git a/src/confd/src/Makefile.am b/src/confd/src/Makefile.am index 49083c9a0..1c4609f7f 100644 --- a/src/confd/src/Makefile.am +++ b/src/confd/src/Makefile.am @@ -1,10 +1,11 @@ CFLAGS = -Wall -Wextra -Werror -Wno-unused-parameter -AM_CPPFLAGS = -D_DEFAULT_SOURCE -D_XOPEN_SOURCE -DYANG_PATH_=\"$(YANGDIR)/\" +AM_CPPFLAGS = -D_DEFAULT_SOURCE -D_XOPEN_SOURCE -D_GNU_SOURCE -DYANG_PATH_=\"$(YANGDIR)\" plugindir = $(srpdplugindir) plugin_LTLIBRARIES = confd-plugin.la -confd_plugin_la_CFLAGS = $(augeas_CFLAGS) $(sysrepo_CFLAGS) $(CFLAGS) -confd_plugin_la_LIBADD = $(augeas_LIBS) $(sysrepo_LIBS) +confd_plugin_la_CFLAGS = $(augeas_CFLAGS) $(libite_CFLAGS) $(sysrepo_CFLAGS) $(CFLAGS) +confd_plugin_la_LIBADD = $(augeas_LIBS) $(libite_LIBS) $(sysrepo_LIBS) confd_plugin_la_LDFLAGS = -module -avoid-version -shared -confd_plugin_la_SOURCES = core.c core.h run.c ietf-system.c ietf-interfaces.c +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 diff --git a/src/confd/src/core.c b/src/confd/src/core.c index 8c2708aa7..042bd943e 100644 --- a/src/confd/src/core.c +++ b/src/confd/src/core.c @@ -7,7 +7,7 @@ static struct confd confd; static int startup_save_hook(sr_session_ctx_t *session, uint32_t sub_id, const char *module, const char *xpath, sr_event_t event, unsigned request_id, void *priv) { - if (run("sysrepocfg -X/cfg/startup-config.cfg -d startup -f json")) + if (systemf("sysrepocfg -X/cfg/startup-config.cfg -d startup -f json")) return SR_ERR_SYS; return SR_ERR_OK; @@ -70,7 +70,7 @@ int sr_plugin_init_cb(sr_session_ctx_t *session, void **priv) goto err; } - rc = sr_install_module(confd.conn, YANG_PATH_"kernelkit-infix-deviations.yang", NULL, NULL); + rc = sr_install_module(confd.conn, YANG_PATH_"/kernelkit-infix-deviations.yang", NULL, NULL); if (rc) goto err; diff --git a/src/confd/src/core.h b/src/confd/src/core.h index 4dd130fcf..fcc277cf1 100644 --- a/src/confd/src/core.h +++ b/src/confd/src/core.h @@ -1,4 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause */ + #ifndef CONFD_CORE_H_ #define CONFD_CORE_H_ @@ -12,18 +13,26 @@ #include #include +#include +#include #include #include #include #include +#include "helpers.h" -#define NELEMS(arr) (sizeof(arr) / sizeof(arr[0])) +#ifndef HAVE_VASPRINTF +int vasprintf(char **strp, const char *fmt, va_list ap); +#endif +#ifndef HAVE_ASPRINTF +int asprintf(char **strp, const char *fmt, ...); +#endif -#define DEBUG(frmt, ...) -//#define DEBUG(frmt, ...) syslog(LOG_DEBUG, "%s: "frmt, __func__, ##__VA_ARGS__) -#define ERROR(frmt, ...) syslog(LOG_ERR, "%s: " frmt, __func__, ##__VA_ARGS__) -#define ERRNO(frmt, ...) syslog(LOG_ERR, "%s: " frmt ": %s", __func__, ##__VA_ARGS__, strerror(errno)) +#define DEBUG(fmt, ...) +//#define DEBUG(fmt, ...) syslog(LOG_DEBUG, "%s: "fmt, __func__, ##__VA_ARGS__) +#define ERROR(fmt, ...) syslog(LOG_ERR, "%s: " fmt, __func__, ##__VA_ARGS__) +#define ERRNO(fmt, ...) syslog(LOG_ERR, "%s: " fmt ": %s", __func__, ##__VA_ARGS__, strerror(errno)) static inline void print_val(sr_val_t *val) { @@ -37,11 +46,15 @@ static inline void print_val(sr_val_t *val) #define REGISTER_CHANGE(s,m,x,f,c,a,u) \ if ((rc = register_change(s, m, x, f, c, a, u))) \ - goto err + goto fail + +#define REGISTER_OPER(s,m,x,c,a,f,u) \ + if ((rc = register_oper(s, m, x, c, a, f, u))) \ + goto fail #define REGISTER_RPC(s,x,c,a,u) \ if ((rc = register_rpc(s, x, c, a, u))) \ - goto err + goto fail struct confd { sr_session_ctx_t *session; @@ -60,6 +73,15 @@ static inline int register_change(sr_session_ctx_t *session, const char *module, return rc; } +static inline int register_oper(sr_session_ctx_t *session, const char *module, const char *xpath, + sr_oper_get_items_cb cb, void *arg, int flags, sr_subscription_ctx_t **sub) +{ + int rc = sr_oper_get_subscribe(session, module, xpath, cb, arg, flags | SR_SUBSCR_DEFAULT, sub); + if (rc) + ERROR("failed subscribing to %s oper: %s", xpath, sr_strerror(rc)); + return rc; +} + static inline int register_rpc(sr_session_ctx_t *session, const char *xpath, sr_rpc_cb cb, void *arg, sr_subscription_ctx_t **sub) { @@ -69,10 +91,6 @@ static inline int register_rpc(sr_session_ctx_t *session, const char *xpath, return rc; } - -/* core.c */ -int run(const char *fmt, ...); - /* ietf-interfaces.c */ int ietf_interfaces_init(struct confd *confd); diff --git a/src/confd/src/helpers.c b/src/confd/src/helpers.c new file mode 100644 index 000000000..d61488b13 --- /dev/null +++ b/src/confd/src/helpers.c @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#include +#include "core.h" + +static FILE *open_file(const char *mode, const char *fmt, va_list ap) +{ + va_list apc; + char *file; + int len; + + va_copy(apc, ap); + len = vsnprintf(NULL, 0, fmt, apc); + va_end(apc); + + file = alloca(len + 1); + if (!file) { + errno = ENOMEM; + return NULL; + } + + va_copy(apc, ap); + vsnprintf(file, len + 1, fmt, apc); + va_end(apc); + + return fopen(file, mode); +} + +/* + * Write interger value to a file composed from fmt and optional args. + */ +int writedf(int value, const char *fmt, ...) +{ + va_list ap; + FILE *fp; + + va_start(ap, fmt); + fp = open_file("r+", fmt, ap); + va_end(ap); + if (!fp) + return -1; + + fprintf(fp, "%d\n", value); + return fclose(fp); +} + +/* + * Write str to a file composed from fmt and optional args. + */ +int writesf(const char *str, const char *fmt, ...) +{ + va_list ap; + FILE *fp; + + va_start(ap, fmt); + fp = open_file("r+", fmt, ap); + va_end(ap); + if (!fp) + return -1; + + fprintf(fp, "%s\n", str); + return fclose(fp); +} + diff --git a/src/confd/src/helpers.h b/src/confd/src/helpers.h new file mode 100644 index 000000000..87ea93c6c --- /dev/null +++ b/src/confd/src/helpers.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#ifndef CONFD_HELPERS_H_ +#define CONFD_HELPERS_H_ + +int writedf(int value, const char *fmt, ...); +int writesf(const char *str, const char *fmt, ...); + +#endif /* CONFD_HELPERS_H_ */ diff --git a/src/confd/src/ietf-interfaces.c b/src/confd/src/ietf-interfaces.c index d2052a4b8..3d56e1d3c 100644 --- a/src/confd/src/ietf-interfaces.c +++ b/src/confd/src/ietf-interfaces.c @@ -1,8 +1,332 @@ /* SPDX-License-Identifier: BSD-3-Clause */ +#include + #include "core.h" +#include "srx_module.h" +#include "srx_val.h" + +struct iface { + TAILQ_ENTRY(iface) link; + + int ifindex; + char ifname[IFNAMSIZ]; + char hwaddr[18]; + short flags; + uint64_t speed; + short vid; + short pvid; + char upper[IFNAMSIZ]; +}; + +static const char *iffeat[] = { + "if-mib", + NULL +}; + +static const char *ipfeat[] = { + "ipv4-non-contiguous-netmasks", + NULL +}; + +static const struct srx_module_requirement ietf_if_reqs[] = { + { .dir = YANG_PATH_, .name = "ietf-interfaces", .rev = "2018-02-20", .features = iffeat }, + { .dir = YANG_PATH_, .name = "iana-if-type", .rev = "2023-01-26" }, + { .dir = YANG_PATH_, .name = "ietf-ip", .rev = "2018-02-22", .features = ipfeat }, + + { NULL } +}; + +static TAILQ_HEAD(iflist, iface) iface_list = TAILQ_HEAD_INITIALIZER(iface_list); + +static int inet_mask2len(char *netmask) +{ + struct in_addr ina; + int len = 0; + + if (inet_pton(AF_INET, netmask, &ina) != 1) + return 0; + + while (ina.s_addr) { + ina.s_addr >>= 1; + len++; + } + + return len; +} + +static void ifprobe(void) +{ + struct if_nameindex *if_list, *i; + + if_list = if_nameindex(); + if (!if_list) { + ERROR("failed if_nameindex(): %s", strerror(errno)); + return; + } + + for (i = if_list; !(i->if_index == 0 && i->if_name == NULL); i++) { + struct iface *iface; + + if (!i->if_name || i->if_index == 0) + continue; + + iface = calloc(1, sizeof(struct iface)); + if (!iface) { + ERROR("out of memory"); + return; + } + + iface->ifindex = i->if_index; + strlcpy(iface->ifname, i->if_name, sizeof(iface->ifname)); + + /* XXX: add other data */ + TAILQ_INSERT_TAIL(&iface_list, iface, link); + } + + if_freenameindex(if_list); +} + +#define INTERFACE_XPATH "/ietf-interfaces:interfaces/interface[name='%s']" + +static void ifpopul(sr_session_ctx_t *session) +{ + struct iface *iface; + int rc = 0; + + TAILQ_FOREACH(iface, &iface_list, link) { + char xpath[sizeof(INTERFACE_XPATH) + IFNAMSIZ + 42]; + sr_val_t val = { 0 }; + + snprintf(xpath, sizeof(xpath), INTERFACE_XPATH "/if-index", iface->ifname); + val.data.int32_val = iface->ifindex; + val.type = SR_INT32_T; + rc = sr_set_item(session, xpath, &val, 0); + if (rc) + ERROR("failed setting item %s", xpath); + snprintf(xpath, sizeof(xpath), INTERFACE_XPATH "/admin-status", iface->ifname); + val.data.enum_val = "up"; + val.type = SR_ENUM_T; + rc = sr_set_item(session, xpath, &val, 0); + if (rc) + ERROR("failed setting item %s", xpath); + + if (!iface->hwaddr[0]) /* e.g., loopback */ + continue; + + snprintf(xpath, sizeof(xpath), INTERFACE_XPATH "/phys-address", iface->ifname); + rc = sr_set_item_str(session, xpath, iface->hwaddr, NULL, 0); + if (rc) + ERROR("failed setting item %s", xpath); + } + + rc = sr_apply_changes(session, 0); + if (rc) + ERROR("faled: %s", sr_strerror(rc)); +} + +static void ifinit(sr_session_ctx_t *session) +{ + struct iface *iface; + int rc = 0; + + TAILQ_FOREACH(iface, &iface_list, link) { + char xpath[sizeof(INTERFACE_XPATH) + IFNAMSIZ + 128]; + sr_val_t val; + + snprintf(xpath, sizeof(xpath), INTERFACE_XPATH "/type", iface->ifname); + if (!strcmp("lo", iface->ifname)) + val.data.string_val = "iana-if-type:softwareLoopback"; + else if (!strncmp("eth", iface->ifname, 3)) + val.data.string_val = "iana-if-type:ethernetCsmacd"; + else + continue; + + val.type = SR_IDENTITYREF_T; + if ((rc = sr_set_item(session, xpath, &val, 0))) + goto fail; + + if (strcmp(iface->ifname, "lo")) + continue; + + snprintf(xpath, sizeof(xpath), INTERFACE_XPATH + "/ietf-ip:ipv4/address[ip='%s']/prefix-length", iface->ifname, "127.0.0.1"); + if ((rc = sr_set_item_str(session, xpath, "8", NULL, 0))) + goto fail; + + snprintf(xpath, sizeof(xpath), INTERFACE_XPATH + "/ietf-ip:ipv6/address[ip='%s']/prefix-length", iface->ifname, "::1"); + rc = sr_set_item_str(session, xpath, "128", NULL, 0); + if (rc) { + fail: + ERROR("failed setting item %s", xpath); + continue; + } + } + + rc = sr_apply_changes(session, 0); + if (rc) + ERROR("faled: %s", sr_strerror(rc)); +} + +static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *module, + const char *xpath, sr_event_t event, unsigned request_id, void *priv) +{ + sr_val_t *val; + size_t cnt; + int rc; + + if (event != SR_EV_DONE) + return SR_ERR_OK; + + rc = sr_get_items(session, "/ietf-interfaces:interfaces/interface", 0, 0, &val, &cnt); + if (rc) + goto fail; + + for (size_t i = 0; i < cnt; i++) { + const char *xpath = val[i].xpath; + char path[strlen(xpath) + 64]; + int dad_xmit = 1; + sr_val_t *addr; + size_t addrcnt; + char *ifname; + char *ptr; + + ifname = srx_get_str(session, "%s/name", xpath); + ptr = srx_get_str(session, "%s/description", xpath); + if (ptr) + writesf(ptr, "/sys/class/net/%s/ifalias", ifname); + free(ptr); + + writedf(srx_enabled(session, "%s/ietf-ip:ipv4/forwarding", xpath), + "/proc/sys/net/ipv4/conf/%s/forwarding", ifname); + + systemf("ip addr flush dev %s", ifname); + if (!srx_enabled(session, "%s/ietf-ip:ipv4/enabled", xpath)) + goto ipv6; + + snprintf(path, sizeof(path), "%s/ietf-ip:ipv4/address", xpath); + rc = sr_get_items(session, path, 0, 0, &addr, &addrcnt); + for (size_t j = 0; j < addrcnt; j++) { + char *address, *netmask; + int plen = 0; + + address = srx_get_str(session, "%s/ip", addr[j].xpath); + SRX_GET_UINT8(session, plen, "%s/prefix-length", addr[j].xpath); + if (!plen) { + netmask = srx_get_str(session, "%s/netmask", addr[j].xpath); + if (netmask) { + plen = inet_mask2len(netmask); + free(netmask); + } + } + + if (plen == 0) + ERROR("%s: missing netmask or invalid prefix-length", address); + else + systemf("ip addr add %s/%d dev %s", address, plen, ifname); + free(address); + } + ipv6: + writedf(srx_enabled(session, "%s/ietf-ip:ipv6/forwarding", xpath), + "/proc/sys/net/ipv6/conf/%s/forwarding", ifname); + + SRX_GET_UINT32(session, dad_xmit, "%s/ietf-ip:ipv6/dup-addr-detect-transmits", xpath); + writedf(dad_xmit, "/proc/sys/net/ipv6/conf/%s/dad_transmits", ifname); + + if (!srx_enabled(session, "%s/ietf-ip:ipv6/enabled", xpath)) { + writedf(1, "/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifname); + goto done; + + } + writedf(0, "/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifname); + + writedf(srx_enabled(session, "%s/ietf-ip:ipv6/autoconf/create-global-addresses", xpath), + "/proc/sys/net/ipv6/conf/%s/autoconf", ifname); + + snprintf(path, sizeof(path), "%s/ietf-ip:ipv6/address", xpath); + rc = sr_get_items(session, path, 0, 0, &addr, &addrcnt); + for (size_t j = 0; j < addrcnt; j++) { + char *address; + int plen = 0; + + address = srx_get_str(session, "%s/ip", addr[j].xpath); + SRX_GET_UINT8(session, plen, "%s/prefix-length", addr[j].xpath); + if (plen == 0) + ERROR("%s: missing netmask or invalid prefix-length", address); + else + systemf("ip addr add %s/%d dev %s", address, plen, ifname); + free(address); + } + done: + systemf("ip link set %s %s", ifname, srx_enabled(session, "%s/enabled", xpath) ? "up" : "down"); + free(ifname); + } + sr_free_values(val, cnt); + + rc = SR_ERR_OK; +fail: + return rc; +} + +static int ifoper(sr_session_ctx_t *session, uint32_t sub_id, const char *module, + const char *path, const char *request_path, uint32_t request_id, + struct lyd_node **parent, void *priv) +{ + char xpath[sizeof(INTERFACE_XPATH) + IFNAMSIZ + 42]; + const struct ly_ctx *ctx; + struct iface *iface; + int first = 1; + int rc = 0; + + ctx = sr_acquire_context(sr_session_get_connection(session)); + + TAILQ_FOREACH(iface, &iface_list, link) { + snprintf(xpath, sizeof(xpath), INTERFACE_XPATH, iface->ifname); + + if ((rc = srx_set_item(ctx, parent, &first, xpath, "if-index", "%d", iface->ifindex))) + goto fail; + + if ((rc = srx_set_item(ctx, parent, &first, xpath, "admin-status", "up"))) + goto fail; + + if ((rc = srx_set_item(ctx, parent, &first, xpath, "oper-status", "up"))) + goto fail; + + if (rc) { + fail: + ERROR("Failed building data tree, libyang error %d", rc); + sr_release_context(sr_session_get_connection(session)); + return SR_ERR_INTERNAL; + } + } + + sr_release_context(sr_session_get_connection(session)); + return SR_ERR_OK; +} int ietf_interfaces_init(struct confd *confd) { + int rc; + + rc = srx_require_modules(confd->conn, ietf_if_reqs); + if (rc) + goto fail; + + ifprobe(); + + REGISTER_CHANGE(confd->session, "ietf-interfaces", "/ietf-interfaces:interfaces", 0, ifchange, confd, &confd->sub); + REGISTER_OPER(confd->session, "ietf-interfaces", "/ietf-interfaces:interfaces", ifoper, NULL, 0, &confd->sub); + + sr_session_switch_ds(confd->session, SR_DS_OPERATIONAL); + ifpopul(confd->session); + sr_session_switch_ds(confd->session, SR_DS_RUNNING); + ifinit(confd->session); + return SR_ERR_OK; +fail: + ERROR("init failed: %s", sr_strerror(rc)); + sr_unsubscribe(confd->sub); + + return rc; } diff --git a/src/confd/src/ietf-system.c b/src/confd/src/ietf-system.c index 7c7841c42..aa259d2eb 100644 --- a/src/confd/src/ietf-system.c +++ b/src/confd/src/ietf-system.c @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: BSD-3-Clause */ #include "core.h" +#include "srx_val.h" + #include #include #include @@ -99,22 +101,11 @@ static int clock_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *modu const struct ly_ctx *ctx; char curtime[64]; time_t now, boot; - char *buf; + int first = 1; int rc; - DEBUG("path=%s, request_path=%s", path, request_path); ctx = sr_acquire_context(sr_session_get_connection(session)); - rc = lyd_new_path(NULL, ctx, CLOCK_PATH_, NULL, 0, parent); - if (rc) { - fail: - ERROR("Failed building data tree, libyang error %d", rc); - return SR_ERR_INTERNAL; - } - - lyd_print_mem(&buf, *parent, LYD_XML, 0); - DEBUG("%s", buf); - now = time(NULL); if (!boottime[0]) { struct sysinfo si; @@ -123,20 +114,21 @@ static int clock_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *modu boot = now - si.uptime; fmtime(boot, boottime, sizeof(boottime)); } + fmtime(now, curtime, sizeof(curtime)); - rc = lyd_new_path(*parent, NULL, CLOCK_PATH_ "/boot-datetime", boottime, 0, NULL); - if (rc) + if ((rc = srx_set_item(ctx, parent, &first, CLOCK_PATH_, "boot-datetime", boottime))) goto fail; - - fmtime(now, curtime, sizeof(curtime)); - rc = lyd_new_path(*parent, NULL, CLOCK_PATH_ "/current-datetime", curtime, 0, NULL); - if (rc) + if ((rc = srx_set_item(ctx, parent, &first, CLOCK_PATH_, "current-datetime", curtime))) goto fail; - lyd_print_mem(&buf, *parent, LYD_XML, 0); - DEBUG("%s", buf); + if (rc) { + fail: + ERROR("Failed building data tree, libyang error %d", rc); + rc = SR_ERR_INTERNAL; + } - return SR_ERR_OK; + sr_release_context(sr_session_get_connection(session)); + return rc; } static int platform_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *module, @@ -144,39 +136,28 @@ static int platform_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *m struct lyd_node **parent, void *priv) { const struct ly_ctx *ctx; - char *buf; + int first = 1; int rc; - DEBUG("path=%s request_path=%s", path, request_path); ctx = sr_acquire_context(sr_session_get_connection(session)); - rc = lyd_new_path(NULL, ctx, PLATFORM_PATH_, NULL, 0, parent); - if (rc) { - fail: - ERROR("Failed building data tree, libyang error %d", rc); - return SR_ERR_INTERNAL; - } - - lyd_print_mem(&buf, *parent, LYD_XML, 0); - DEBUG("%s", buf); - - rc = lyd_new_path(*parent, NULL, PLATFORM_PATH_"/os-name", os, 0, NULL); - if (rc) + if ((rc = srx_set_item(ctx, parent, &first, PLATFORM_PATH_, "os-name", os))) goto fail; - rc = lyd_new_path(*parent, NULL, PLATFORM_PATH_"/os-release", rel, 0, NULL); - if (rc) + if ((rc = srx_set_item(ctx, parent, &first, PLATFORM_PATH_, "os-release", rel))) goto fail; - rc = lyd_new_path(*parent, NULL, PLATFORM_PATH_"/os-version", ver, 0, NULL); - if (rc) + if ((rc = srx_set_item(ctx, parent, &first, PLATFORM_PATH_, "os-version", ver))) goto fail; - rc = lyd_new_path(*parent, NULL, PLATFORM_PATH_"/machine", sys, 0, NULL); - if (rc) + if ((rc = srx_set_item(ctx, parent, &first, PLATFORM_PATH_, "machine", sys))) goto fail; - lyd_print_mem(&buf, *parent, LYD_XML, 0); - DEBUG("%s", buf); + if (rc) { + fail: + ERROR("Failed building data tree, libyang error %d", rc); + rc = SR_ERR_INTERNAL; + } - return SR_ERR_OK; + sr_release_context(sr_session_get_connection(session)); + return rc; } static int rpc_exec(sr_session_ctx_t *session, uint32_t sub_id, const char *path, @@ -187,7 +168,7 @@ static int rpc_exec(sr_session_ctx_t *session, uint32_t sub_id, const char *path { DEBUG("path: %s", path); - if (run(priv)) + if (systemf(priv)) return SR_ERR_INTERNAL; return SR_ERR_OK; @@ -246,131 +227,7 @@ static int rpc_set_datetime(sr_session_ctx_t *session, uint32_t sub_id, static int sys_reload_services(void) { - return run("initctl -nbq touch sysklogd lldpd"); -} - -int sr_get_int(sr_session_ctx_t *session, const char *fmt, ...) -{ - sr_val_t *val = NULL; - char *xpath; - va_list ap; - int rc = 0; - int len; - - va_start(ap, fmt); - len = vsnprintf(NULL, 0, fmt, ap) + 1; - va_end(ap); - - xpath = alloca(len); - if (!xpath) - goto fail; - - va_start(ap, fmt); - vsnprintf(xpath, len, fmt, ap); - va_end(ap); - - if (sr_get_item(session, xpath, 0, &val) || !val) - goto fail; - - switch (val->type) { - case SR_INT8_T: - rc = val->data.int8_val; - break; - case SR_UINT8_T: - rc = val->data.uint8_val; - break; - case SR_INT16_T: - rc = val->data.int16_val; - break; - case SR_UINT16_T: - rc = val->data.uint16_val; - break; - case SR_INT32_T: - rc = val->data.int32_val; - break; - case SR_UINT32_T: - rc = val->data.uint32_val; - break; - case SR_INT64_T: - rc = val->data.int64_val; - break; - case SR_UINT64_T: - rc = val->data.uint64_val; - break; - default: - goto fail; - } - -fail: - if (val) - sr_free_val(val); - return rc; -} - -int sr_get_bool(sr_session_ctx_t *session, const char *fmt, ...) -{ - sr_val_t *val = NULL; - char *xpath; - va_list ap; - int rc = 0; - int len; - - va_start(ap, fmt); - len = vsnprintf(NULL, 0, fmt, ap) + 1; - va_end(ap); - - xpath = alloca(len); - if (!xpath) - goto fail; - - va_start(ap, fmt); - vsnprintf(xpath, len, fmt, ap); - va_end(ap); - - if (sr_get_item(session, xpath, 0, &val)) - goto fail; - if (!val || val->type != SR_BOOL_T) - goto fail; - - rc = val->data.bool_val; -fail: - if (val) - sr_free_val(val); - return rc; -} - -char *sr_get_str(sr_session_ctx_t *session, const char *fmt, ...) -{ - char *str = NULL; - sr_val_t *val; - char *xpath; - va_list ap; - int len; - - va_start(ap, fmt); - len = vsnprintf(NULL, 0, fmt, ap) + 1; - va_end(ap); - - xpath = alloca(len); - if (!xpath) - return NULL; - - va_start(ap, fmt); - vsnprintf(xpath, len, fmt, ap); - va_end(ap); - - if (sr_get_item(session, xpath, 0, &val)) { - ERROR("Failed reading string value from xpath %s", xpath); - goto fail; - } - if (!val || val->type != SR_STRING_T) - goto fail; - - str = strdup(val->data.string_val); -fail: - if (val) - sr_free_val(val); - return str; + return systemf("initctl -nbq touch sysklogd lldpd"); } #define TIMEZONE_CONF "/etc/timezone" @@ -381,7 +238,6 @@ static int change_clock(sr_session_ctx_t *session, uint32_t sub_id, const char * const char *xpath, sr_event_t event, unsigned request_id, void *priv) { char *timezone; - FILE *fp; switch (event) { case SR_EV_ENABLED: /* first time, on register. */ @@ -413,25 +269,22 @@ static int change_clock(sr_session_ctx_t *session, uint32_t sub_id, const char * } /* XXX: add support also for /ietf-system:system/clock/timezone-utc-offset (deviation) */ - timezone = sr_get_str(session, "/ietf-system:system/clock/timezone-name"); + timezone = srx_get_str(session, "/ietf-system:system/clock/timezone-name"); if (!timezone) { ERROR("Failed reading timezone-name"); return SR_ERR_VALIDATION_FAILED; } remove("/etc/localtime+"); - if (run("ln -s /usr/share/zoneinfo/%s /etc/localtime+", timezone)) { + if (systemf("ln -s /usr/share/zoneinfo/%s /etc/localtime+", timezone)) { ERROR("No such timezone %s", timezone); return SR_ERR_VALIDATION_FAILED; } - fp = fopen(TIMEZONE_NEXT, "w"); - if (!fp) { + if (writesf(timezone, TIMEZONE_NEXT)) { ERRNO("Failed preparing %s", TIMEZONE_NEXT); return SR_ERR_SYS; } - fprintf(fp, "%s\n", timezone); - fclose(fp); return SR_ERR_OK; } @@ -468,16 +321,16 @@ static int change_ntp(sr_session_ctx_t *session, uint32_t sub_id, const char *mo remove(CHRONY_PREV); rename(CHRONY_CONF, CHRONY_PREV); rename(CHRONY_NEXT, CHRONY_CONF); - if (!sr_get_bool(session, "/ietf-system:system/ntp/enabled")) { - run("initctl -nbq disable chronyd"); + if (srx_enabled(session, "/ietf-system:system/ntp/enabled")) { + systemf("initctl -nbq disable chronyd"); return SR_ERR_OK; } /* * If chrony is alrady enabled we tell Finit it's been * modified , so Finit restarts it, otherwise enable it. */ - run("initctl -nbq touch chronyd"); - run("initctl -nbq enable chronyd"); + systemf("initctl -nbq touch chronyd"); + systemf("initctl -nbq enable chronyd"); return SR_ERR_OK; default: @@ -510,16 +363,16 @@ static int change_ntp(sr_session_ctx_t *session, uint32_t sub_id, const char *mo valid = 0; /* Get /ietf-system:system/ntp/server[name='foo'] */ - ptr = sr_get_str(session, "%s/udp/address", xpath); + ptr = srx_get_str(session, "%s/udp/address", xpath); if (ptr) { - type = sr_get_str(session, "%s/association-type", xpath); + type = srx_get_str(session, "%s/association-type", xpath); fprintf(fp, "%s %s", type ?: "server", ptr); server++; if (type) free(type); free(ptr); - ptr = sr_get_str(session, "%s/udp/port", xpath); + ptr = srx_get_str(session, "%s/udp/port", xpath); if (ptr) { fprintf(fp, " port %s", ptr); free(ptr); @@ -527,9 +380,9 @@ static int change_ntp(sr_session_ctx_t *session, uint32_t sub_id, const char *mo } if (server) { - if (sr_get_bool(session, "%s/iburst", xpath)) + if (srx_enabled(session, "%s/iburst", xpath) > 0) fprintf(fp, " iburst"); - if (sr_get_bool(session, "%s/prefer", xpath)) + if (srx_enabled(session, "%s/prefer", xpath) > 0) fprintf(fp, " prefer"); fprintf(fp, "\n"); @@ -561,7 +414,7 @@ static int change_dns(sr_session_ctx_t *session, uint32_t sub_id, const char *mo const char *xpath, sr_event_t event, unsigned request_id, void *priv) { const char *fn = RESOLV_NEXT; - int timeout, attempts; + int timeout = 0, attempts = 0; int rc = SR_ERR_SYS; sr_val_t *val; size_t cnt; @@ -587,10 +440,10 @@ static int change_dns(sr_session_ctx_t *session, uint32_t sub_id, const char *mo rename(RESOLV_NEXT, RESOLV_CONF); /* in bootstrap, another resolvconf will soon take your call */ - if (run("initctl cond get hook/sys/up")) + if (systemf("initctl cond get hook/sys/up")) return 0; - run("resolvconf -u"); + systemf("resolvconf -u"); return SR_ERR_OK; default: @@ -604,8 +457,8 @@ static int change_dns(sr_session_ctx_t *session, uint32_t sub_id, const char *mo return SR_ERR_SYS; } - timeout = sr_get_int(session, "/ietf-system:system/dns-resolver/options/timeout"); - attempts = sr_get_int(session, "/ietf-system:system/dns-resolver/options/attempts"); + SRX_GET_UINT8(session, timeout, "/ietf-system:system/dns-resolver/options/timeout"); + SRX_GET_UINT8(session, timeout, "/ietf-system:system/dns-resolver/options/attempts"); if (timeout || attempts) { fprintf(fp, "options"); if (timeout) @@ -636,7 +489,7 @@ static int change_dns(sr_session_ctx_t *session, uint32_t sub_id, const char *mo char *ptr; /* Get /ietf-system:system/dns-resolver/server[name='foo'] */ - ptr = sr_get_str(session, "%s/udp-and-tcp/address", xpath); + ptr = srx_get_str(session, "%s/udp-and-tcp/address", xpath); if (ptr) /* XXX: add support also for udp-and-tcp/port */ fprintf(fp, "nameserver %s\n", ptr); @@ -655,26 +508,26 @@ static int change_dns(sr_session_ctx_t *session, uint32_t sub_id, const char *mo static int change_motd(sr_session_ctx_t *session, uint32_t sub_id, const char *module, const char *xpath, sr_event_t event, unsigned request_id, void *priv) { - char *nm; - FILE *fp; + /* XXX: derive from global "options.h" or /usr/share/factory/ */ + const char *msg = "\033[1;90mNote:\033[0m" + "\033[0;90m use help, show, and setup commands to set up and diagnose the system\033[0m"; + char *str; + int rc; /* Ignore all events except SR_EV_DONE */ if (event != SR_EV_DONE) return SR_ERR_OK; - fp = fopen("/etc/motd", "w"); - if (!fp) - return SR_ERR_SYS; - - nm = sr_get_str(session, xpath); - if (nm) { - fprintf(fp, "%s\n", nm); + str = srx_get_str(session, xpath); + if (str) { + rc = writesf(str, "/etc/motd"); + free(str); } else { - /* XXX: derive from global "options.h" or /usr/share/factory/ */ - fprintf(fp, "\033[1;90mNote:\033[0m "); - fprintf(fp, "\033[0;90m use help, show, and setup commands to set up and diagnose the system\033[0m\n"); + rc = writesf(msg, "/etc/motd"); } - fclose(fp); + + if (rc) + return SR_ERR_SYS; return SR_ERR_OK; } @@ -691,7 +544,7 @@ static int change_hostname(sr_session_ctx_t *session, uint32_t sub_id, const cha if (event != SR_EV_DONE) return SR_ERR_OK; - nm = sr_get_str(session, xpath); + nm = srx_get_str(session, xpath); if (!nm) { /* XXX: derive from global "options.h" or /usr/share/factory/ */ nm = strdup("infix"); @@ -732,7 +585,6 @@ static int change_hostname(sr_session_ctx_t *session, uint32_t sub_id, const cha return err; } - ERROR("Reload hostname-dependent services ..."); err = err ? : aug_save(confd->aug); if (sys_reload_services()) return SR_ERR_SYS; @@ -755,26 +607,16 @@ int ietf_system_init(struct confd *confd) if (aug_load_file(confd->aug, "/etc/hostname") || aug_load_file(confd->aug, "/etc/hosts")) { ERROR("ietf-system: Augeas initialization failed"); - goto err; + goto fail; } - rc = sr_install_module(confd->conn, YANG_PATH_"ietf-system@2014-08-06.yang", NULL, features); + rc = sr_install_module(confd->conn, YANG_PATH_"/ietf-system@2014-08-06.yang", NULL, features); if (rc) - goto err; + goto fail; /* Augment to ietf-systems */ - rc = sr_install_module(confd->conn, YANG_PATH_"infix-system@2014-08-06.yang", NULL, NULL); + rc = sr_install_module(confd->conn, YANG_PATH_"/infix-system@2014-08-06.yang", NULL, NULL); if (rc) - goto err; - - rc = sr_oper_get_subscribe(confd->session, "ietf-system", CLOCK_PATH_, - clock_cb, NULL, SR_SUBSCR_DEFAULT, &confd->sub); - if (rc != SR_ERR_OK) - goto err; - - rc = sr_oper_get_subscribe(confd->session, "ietf-system", PLATFORM_PATH_, - platform_cb, NULL, SR_SUBSCR_DEFAULT, &confd->sub); - if (rc != SR_ERR_OK) - goto err; + goto fail; REGISTER_CHANGE(confd->session, "ietf-system", "/ietf-system:system/hostname", 0, change_hostname, confd, &confd->sub); REGISTER_CHANGE(confd->session, "ietf-system", "/ietf-system:system/infix-system:motd", 0, change_motd, confd, &confd->sub); @@ -782,12 +624,15 @@ int ietf_system_init(struct confd *confd) REGISTER_CHANGE(confd->session, "ietf-system", "/ietf-system:system/ntp", 0, change_ntp, confd, &confd->sub); REGISTER_CHANGE(confd->session, "ietf-system", "/ietf-system:system/dns-resolver", 0, change_dns, confd, &confd->sub); + REGISTER_OPER(confd->session, "ietf-system", CLOCK_PATH_, clock_cb, NULL, 0, &confd->sub); + REGISTER_OPER(confd->session, "ietf-system", PLATFORM_PATH_, platform_cb, NULL, 0, &confd->sub); + REGISTER_RPC(confd->session, "/ietf-system:system-restart", rpc_exec, "reboot", &confd->sub); REGISTER_RPC(confd->session, "/ietf-system:system-shutdown", rpc_exec, "poweroff", &confd->sub); REGISTER_RPC(confd->session, "/ietf-system:set-current-datetime", rpc_set_datetime, NULL, &confd->sub); return SR_ERR_OK; -err: +fail: ERROR("init failed: %s", sr_strerror(rc)); sr_unsubscribe(confd->sub); diff --git a/src/confd/src/run.c b/src/confd/src/run.c deleted file mode 100644 index 1a809c681..000000000 --- a/src/confd/src/run.c +++ /dev/null @@ -1,52 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ - -#include "core.h" - -/** - * Like system(), but takes a formatted string as argument. - * @param fmt printf style format list to command to run - * - * This system() wrapper greatly simplifies operations that usually - * consist of composing a command from parts into a dynamic buffer - * before calling it. The return value from system() is also parsed, - * checking for proper exit and signals. - * - * @returns If the command exits normally, the return code of the command - * is returned. Otherwise, if the command is signalled, the return code - * is -1 and @a errno is set to @c EINTR. - */ -int run(const char *fmt, ...) -{ - va_list ap; - char *cmd; - int len; - int rc; - - va_start(ap, fmt); - len = vsnprintf(NULL, 0, fmt, ap); - va_end(ap); - - cmd = alloca(++len); - if (!cmd) { - errno = ENOMEM; - return -1; - } - - va_start(ap, fmt); - vsnprintf(cmd, len, fmt, ap); - va_end(ap); - - rc = system(cmd); - if (rc == -1) - return -1; - - if (WIFEXITED(rc)) { - errno = 0; - rc = WEXITSTATUS(rc); - } else if (WIFSIGNALED(rc)) { - errno = EINTR; - rc = -1; - } - - return rc; -} diff --git a/src/confd/src/srx_module.c b/src/confd/src/srx_module.c new file mode 100644 index 000000000..63de9cdd2 --- /dev/null +++ b/src/confd/src/srx_module.c @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#include + +#include "core.h" +#include "srx_module.h" + +sr_error_t srx_require_module(sr_conn_ctx_t *conn, + const struct srx_module_requirement *mr) +{ + sr_error_t err = SR_ERR_OK; + const struct ly_ctx *ly; + struct lys_module *mod; + const char **f; + char *path; + + ly = sr_acquire_context(conn); + if (!ly) + return SR_ERR_INVAL_ARG; + + mod = ly_ctx_get_module(ly, mr->name, mr->rev); + sr_release_context(conn); + + if (mod && mod->implemented) { + if (!mr->features) + return SR_ERR_OK; + + for (f = mr->features; *f; f++) { + switch (lys_feature_value(mod, *f)) { + case LY_SUCCESS: + continue; + case LY_ENOT: + err = sr_enable_module_feature(conn, mr->name, *f); + if (err) + return err; + break; + default: + return SR_ERR_UNSUPPORTED; + } + } + } else { + /* `search_dirs` argument is ignored by sysrepo 2.2.60, + * so we supply the full path instead. + */ + asprintf(&path, "%s/%s%s%s.yang", mr->dir ? : "", mr->name, + mr->rev ? "@" : "", mr->rev ? : ""); + err = sr_install_module(conn, path, NULL, mr->features); + free(path); + } + + return err; +} + +sr_error_t srx_require_modules(sr_conn_ctx_t *conn, + const struct srx_module_requirement *mrs) +{ + sr_error_t err = SR_ERR_OK; + + for (; mrs->name && !err; mrs++) + err = srx_require_module(conn, mrs); + + return err; +} diff --git a/src/confd/src/srx_module.h b/src/confd/src/srx_module.h new file mode 100644 index 000000000..a544e209d --- /dev/null +++ b/src/confd/src/srx_module.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#ifndef CONFD_SR_EXT_H_ +#define CONFD_SR_EXT_H_ + +#include + +struct srx_module_requirement { + const char *dir; + const char *name; + const char *rev; + const char **features; +}; + +sr_error_t srx_require_module(sr_conn_ctx_t *conn, + const struct srx_module_requirement *mr); +sr_error_t srx_require_modules(sr_conn_ctx_t *conn, + const struct srx_module_requirement *mrs); + +#endif /* CONFD_SR_EXT_H_ */ diff --git a/src/confd/src/srx_val.c b/src/confd/src/srx_val.c new file mode 100644 index 000000000..a74d494ec --- /dev/null +++ b/src/confd/src/srx_val.c @@ -0,0 +1,197 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#include +#include "core.h" + +int srx_set_item(const struct ly_ctx *ctx, struct lyd_node **parent, int *first, + char *xpath_base, char *node, const char *fmt, ...) +{ + char xpath[strlen(xpath_base) + strlen(node) + 2]; + va_list ap; + size_t len; + char *val; + int rc; + + va_start(ap, fmt); + len = vsnprintf(NULL, 0, fmt, ap) + 1; + va_end(ap); + + val = alloca(len); + if (!val) + return -1; + + snprintf(xpath, sizeof(xpath), "%s/%s", xpath_base, node); + va_start(ap, fmt); + vsnprintf(val, len, fmt, ap); + va_end(ap); + + DEBUG("Setting first:%d xpath %s to %s", *first, xpath, val); + + if (*first) + rc = lyd_new_path(NULL, ctx, xpath, val, 0, parent); + else + rc = lyd_new_path(*parent, NULL, xpath, val, 0, NULL); + + *first = 0; + if (rc) + ERROR("Failed building data tree, xpath %s, libyang error %d: %s", + xpath, rc, ly_errmsg(ctx)); + + return rc; +} + +static int srx_vaget(sr_session_ctx_t *session, const char *fmt, va_list ap, sr_val_type_t type, sr_val_t **val, size_t *cnt) +{ + va_list apdup; + char *xpath; + int len; + int rc; + + va_copy(apdup, ap); + len = vsnprintf(NULL, 0, fmt, apdup) + 1; + va_end(apdup); + + xpath = alloca(len); + if (!xpath) + return -1; + + va_copy(apdup, ap); + vsnprintf(xpath, len, fmt, apdup); + va_end(apdup); + + rc = sr_get_items(session, xpath, 0, 0, val, cnt); + if (rc) { + ERROR("Failed reading xpath %s: %s", xpath, sr_strerror(rc)); + return -1; + } + + if (*cnt == 0) { + errno = ENODATA; + return -1; + } else if (*cnt > 1) { + sr_free_values(*val, *cnt); + errno = EOVERFLOW; + return -1; + } + + if (type != SR_UNKNOWN_T && val[0]->type != type) { + sr_free_values(*val, *cnt); + errno = EINVAL; + return -1; + } + + return 0; +} + +static int get_vabool(sr_session_ctx_t *session, int *result, const char *fmt, va_list ap) +{ + sr_val_t *val = NULL; + size_t cnt = 0; + va_list apdup; + int rc; + + va_copy(apdup, ap); + rc = srx_vaget(session, fmt, apdup, SR_BOOL_T, &val, &cnt); + va_end(apdup); + + if (rc) + return rc; + + *result = val->data.bool_val; + sr_free_values(val, cnt); + + return 0; +} + +int srx_get_bool(sr_session_ctx_t *session, int *result, const char *fmt, ...) +{ + va_list ap; + int rc; + + va_start(ap, fmt); + rc = get_vabool(session, result, fmt, ap); + va_end(ap); + + return rc; +} + +int srx_enabled(sr_session_ctx_t *session, const char *fmt, ...) +{ + va_list ap; + int v = 0; + int rc; + + va_start(ap, fmt); + rc = get_vabool(session, &v, fmt, ap); + va_end(ap); + + return rc ? 0 : v; +} + +int srx_get_int(sr_session_ctx_t *session, int *result, sr_val_type_t type, const char *fmt, ...) +{ + sr_val_t *val = NULL; + size_t cnt = 0; + va_list ap; + int rc; + + va_start(ap, fmt); + rc = srx_vaget(session, fmt, ap, type, &val, &cnt); + va_end(ap); + + if (rc) + return rc; + rc = -1; + + switch (val->type) { + case SR_INT8_T: + *result = val->data.int8_val; + break; + case SR_UINT8_T: + *result = val->data.uint8_val; + break; + case SR_INT16_T: + *result = val->data.int16_val; + break; + case SR_UINT16_T: + *result = val->data.uint16_val; + break; + case SR_INT32_T: + *result = val->data.int32_val; + break; + case SR_UINT32_T: + *result = val->data.uint32_val; + break; + case SR_INT64_T: + *result = val->data.int64_val; + break; + case SR_UINT64_T: + *result = val->data.uint64_val; + break; + default: + goto fail; + } + + rc = 0; +fail: + sr_free_values(val, cnt); + return rc; +} + +char *srx_get_str(sr_session_ctx_t *session, const char *fmt, ...) +{ + sr_val_t *val = NULL; + char *str = NULL; + size_t cnt = 0; + va_list ap; + + va_start(ap, fmt); + if (srx_vaget(session, fmt, ap, SR_UNKNOWN_T, &val, &cnt)) + goto fail; + + str = sr_val_to_str(val); + sr_free_values(val, cnt); +fail: + va_end(ap); + return str; +} diff --git a/src/confd/src/srx_val.h b/src/confd/src/srx_val.h new file mode 100644 index 000000000..669644e2b --- /dev/null +++ b/src/confd/src/srx_val.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#ifndef CONFD_SRX_VAL_H_ +#define CONFD_SRX_VAL_H_ + +#include "core.h" + +#define SRX_GET_UINT8(s,v,fmt,...) srx_get_int(s, &v, SR_UINT8_T, fmt, ##__VA_ARGS__) +#define SRX_GET_UINT32(s,v,fmt,...) srx_get_int(s, &v, SR_UINT32_T, fmt, ##__VA_ARGS__) + +int srx_set_item(const struct ly_ctx *ctx, struct lyd_node **parent, int *first, char *xpath_base, + char *node, const char *fmt, ...); + +char *srx_get_str (sr_session_ctx_t *session, const char *fmt, ...); +int srx_get_int (sr_session_ctx_t *session, int *result, sr_val_type_t type, const char *fmt, ...); +int srx_get_bool (sr_session_ctx_t *session, const char *fmt, ...); +int srx_enabled (sr_session_ctx_t *session, const char *fmt, ...); + +#endif /* CONFD_SRX_VAL_H_ */ diff --git a/src/confd/yang/iana-if-type@2017-01-19.yang b/src/confd/yang/iana-if-type@2023-01-26.yang similarity index 88% rename from src/confd/yang/iana-if-type@2017-01-19.yang rename to src/confd/yang/iana-if-type@2023-01-26.yang index 7bfee3647..fea9330bf 100644 --- a/src/confd/yang/iana-if-type@2017-01-19.yang +++ b/src/confd/yang/iana-if-type@2023-01-26.yang @@ -16,7 +16,7 @@ module iana-if-type { United States Tel: +1 310 301 5800 - "; + "; description "This YANG module defines YANG identities for IANA-registered interface types. @@ -28,7 +28,7 @@ module iana-if-type { the IANA web site. Requests for new values should be made to IANA via - email (iana&iana.org). + email (iana@iana.org). Copyright (c) 2014 IETF Trust and the persons identified as authors of the code. All rights reserved. @@ -46,6 +46,124 @@ module iana-if-type { "IANA 'ifType definitions' registry. "; + revision 2023-01-26 { + description + "Fix incorrect quotation for previous 3 revision statements."; + } + + revision 2022-08-24 { + description + "Updated reference for ifType 303."; + } + + revision 2022-08-17 { + description + "Changed gpon description to refer to G.984."; + } + + revision 2022-03-07 { + description + "Coalesced revision history entries for 2018-06-28."; + } + + revision 2021-06-21 { + description + "Corrected reference for ifType 303."; + } + + revision 2021-05-17 { + description + "Registered ifType 303."; + } + + revision 2021-04-22 { + description + "Registered ifType 302."; + } + + revision 2021-04-01 { + description + "Updated reference for 301."; + } + + revision 2021-02-18 { + description + "Registered ifType 301."; + } + + revision 2020-08-27 { + description + "Added missing references."; + } + + revision 2020-07-13 { + description + "Added identity cpri."; + } + + revision 2020-07-10 { + description + "Registered ifType 300."; + } + + revision 2020-01-10 { + description + "Registered ifType 299."; + } + + revision 2019-10-16 { + description + "Registered ifType 298."; + } + revision 2019-07-16 { + description + "Registered ifType 297."; + } + revision 2019-06-21 { + description + "Updated reference associated with ifTypes 295-296."; + } + + revision 2019-02-08 { + description + "Corrected formatting issue."; + } + + revision 2019-01-31 { + description + "Registered ifTypes 295-296."; + } + + revision 2018-07-03 { + description + "Corrected revision date."; + } + + revision 2018-06-29 { + description + "Corrected formatting issue."; + } + + revision 2018-06-28 { + description + "Registered ifTypes 293 and 294."; + } + + revision 2018-06-22 { + description + "Registered ifType 292."; + } + + revision 2018-06-21 { + description + "Registered ifType 291."; + } + + revision 2017-03-30 { + description + "Registered ifType 290."; + } + revision 2017-01-19 { description "Registered ifType 289."; @@ -1410,7 +1528,7 @@ module iana-if-type { base iana-interface-type; description "Gigabit-capable passive optical networks (G-PON) as per - ITU-T G.948."; + ITU-T G.984."; } identity vdsl2 { base iana-interface-type; @@ -1549,11 +1667,17 @@ module iana-if-type { base iana-interface-type; description "CATV Downstream OFDM interface."; + reference + "Cable Modem Operations Support System Interface + Specification"; } identity docsOfdmaUpstream { base iana-interface-type; description "CATV Upstream OFDMA interface."; + reference + "Cable Modem Operations Support System Interface + Specification"; } identity gfast { base iana-interface-type; @@ -1585,21 +1709,29 @@ module iana-if-type { base iana-interface-type; description "Cable SCTE 55-1 OOB Forward Channel."; + reference + "ANSI/SCTE 55-1 2009"; } identity docsCableScte55d1RetOob { base iana-interface-type; description "Cable SCTE 55-1 OOB Return Channel."; + reference + "ANSI/SCTE 55-1 2009"; } identity docsCableScte55d2DsOob { base iana-interface-type; description "Cable SCTE 55-2 OOB Downstream Channel."; + reference + "ANSI/SCTE 55-2 2008"; } identity docsCableScte55d2UsOob { base iana-interface-type; description "Cable SCTE 55-2 OOB Upstream Channel."; + reference + "ANSI/SCTE 55-2 2008"; } identity docsCableNdf { base iana-interface-type; @@ -1615,5 +1747,105 @@ module iana-if-type { base iana-interface-type; description "Packet Transfer Mode."; + reference + "IEEE G.993.1, Annex H; IEEE G.993.2; IEEE G.9701"; + } + identity ghn { + base iana-interface-type; + description + "G.hn port."; + reference + "IEEE G.9961"; + } + identity otnOtsi { + base iana-interface-type; + description + "Optical Tributary Signal."; + reference + "ITU-T G.959.1"; + } + identity otnOtuc { + base iana-interface-type; + description + "OTN OTUCn."; + reference + "ITU-T G.709/Y.1331"; + } + identity otnOduc { + base iana-interface-type; + description + "OTN ODUC."; + reference + "ITU-T G.709"; + } + identity otnOtsig { + base iana-interface-type; + description + "OTN OTUC Signal."; + reference + "ITU-T G.709"; + } + identity microwaveCarrierTermination { + base iana-interface-type; + description + "air interface of a single microwave carrier."; + reference + "RFC 8561 - A YANG Data Model for Microwave Radio Link"; + } + identity microwaveRadioLinkTerminal { + base iana-interface-type; + description + "radio link interface for one or several aggregated microwave carriers."; + reference + "RFC 8561 - A YANG Data Model for Microwave Radio Link"; + } + identity ieee8021axDrni { + base iana-interface-type; + description + "IEEE 802.1AX Distributed Resilient Network Interface."; + reference + "IEEE 802.1AX-Rev-d2-0"; + } + identity ax25 { + base iana-interface-type; + description + "AX.25 network interfaces."; + reference + "AX.25 Link Access Protocol for Amateur Packet Radio version 2.2"; + } + identity ieee19061nanocom { + base iana-interface-type; + description + "Nanoscale and Molecular Communication."; + reference + "IEEE 1906.1-2015"; + } + identity cpri { + base iana-interface-type; + description + "Common Public Radio Interface."; + reference + "CPRI v7.0"; + } + identity omni { + base iana-interface-type; + description + "Overlay Multilink Network Interface (OMNI)."; + reference + "draft-templin-6man-omni-00"; + } + identity roe { + base iana-interface-type; + description + "Radio over Ethernet Interface."; + reference + "1914.3-2018 - IEEE Standard for Radio over Ethernet Encapsulations and Mappings"; + } + identity p2pOverLan { + base iana-interface-type; + description + "Point to Point over LAN interface."; + reference + "RFC 9296 - ifStackTable for the Point-to-Point (P2P) Interface over a LAN Type: Definition and Examples"; } }