diff --git a/.gitmodules b/.gitmodules index 96a55b01..d3faed24 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,3 @@ [submodule "buildroot"] path = buildroot - url = https://github.com/buildroot/buildroot.git - branch = 2023.02.x + url = ../buildroot.git diff --git a/board/aarch64/linux_defconfig b/board/aarch64/linux_defconfig index b57529a0..ca1ab4c2 100644 --- a/board/aarch64/linux_defconfig +++ b/board/aarch64/linux_defconfig @@ -141,7 +141,6 @@ CONFIG_MTD_SPI_NOR=y CONFIG_OF_OVERLAY=y CONFIG_BLK_DEV_NULL_BLK=y CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_NBD=y CONFIG_BLK_DEV_RAM=y CONFIG_VIRTIO_BLK=y CONFIG_BLK_DEV_NVME=y diff --git a/board/amd64/linux_defconfig b/board/amd64/linux_defconfig index 7c3eca33..423675b5 100644 --- a/board/amd64/linux_defconfig +++ b/board/amd64/linux_defconfig @@ -95,7 +95,6 @@ CONFIG_FW_CFG_SYSFS=y CONFIG_FW_CFG_SYSFS_CMDLINE=y CONFIG_BLK_DEV_NULL_BLK=y CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_NBD=y CONFIG_BLK_DEV_RAM=y CONFIG_VIRTIO_BLK=y CONFIG_BLK_DEV_SD=y diff --git a/board/common/rootfs/etc/profile.d/convenience.sh b/board/common/rootfs/etc/profile.d/convenience.sh index 5393b2e5..e27fc5c5 100644 --- a/board/common/rootfs/etc/profile.d/convenience.sh +++ b/board/common/rootfs/etc/profile.d/convenience.sh @@ -16,4 +16,4 @@ alias ipaddr='ip addr' alias iplink='ip link' alias bridge='bridge --color=auto' alias setup='pdmenu; clear' -alias cli='clixon_cli' +alias cli='klish' diff --git a/buildroot b/buildroot index 8cca1e6d..58814174 160000 --- a/buildroot +++ b/buildroot @@ -1 +1 @@ -Subproject commit 8cca1e6de1c69a0a5e876116906bb3f6da4a5bd5 +Subproject commit 588141749e57c0edb4df2daaef8697f98800a8b2 diff --git a/configs/aarch64_defconfig b/configs/aarch64_defconfig index cfdaf484..0ded6949 100644 --- a/configs/aarch64_defconfig +++ b/configs/aarch64_defconfig @@ -48,6 +48,7 @@ BR2_PACKAGE_UBOOT_TOOLS_FIT_SUPPORT=y BR2_PACKAGE_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y BR2_PACKAGE_UBOOT_TOOLS_FIT_CHECK_SIGN=y BR2_PACKAGE_LIBCURL_CURL=y +BR2_PACKAGE_NETOPEER2_CLI=y BR2_PACKAGE_NSS_MDNS=y BR2_PACKAGE_ONIGURUMA=y BR2_PACKAGE_AVAHI=y @@ -74,10 +75,6 @@ BR2_PACKAGE_NETCALC=y BR2_PACKAGE_NETCAT_OPENBSD=y BR2_PACKAGE_NETSNMP=y BR2_PACKAGE_NFTABLES=y -BR2_PACKAGE_NGINX_HTTP_SSL_MODULE=y -BR2_PACKAGE_NGINX_HTTP_V2_MODULE=y -BR2_PACKAGE_NGINX_HTTP_GUNZIP_MODULE=y -BR2_PACKAGE_NGINX_HTTP_AUTH_REQUEST_MODULE=y BR2_PACKAGE_NMAP=y BR2_PACKAGE_NMAP_NCAT=y BR2_PACKAGE_NMAP_NMAP=y @@ -102,7 +99,6 @@ BR2_PACKAGE_PWGEN=y BR2_PACKAGE_RAUC=y BR2_PACKAGE_RAUC_GPT=y BR2_PACKAGE_RAUC_NETWORK=y -BR2_PACKAGE_RAUC_STREAMING=y BR2_PACKAGE_SYSKLOGD=y BR2_PACKAGE_SYSKLOGD_LOGGER=y BR2_PACKAGE_WATCHDOGD=y @@ -119,7 +115,7 @@ BR2_PACKAGE_HOST_RAUC=y BR2_PACKAGE_HOST_UBOOT_TOOLS=y BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y -BR2_PACKAGE_CLIXON_RESTCONF_FCGI=y +BR2_PACKAGE_CONFD=y BR2_PACKAGE_FACTORY=y BR2_PACKAGE_FINIT_SULOGIN=y BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y @@ -130,7 +126,7 @@ BR2_PACKAGE_FINIT_PLUGIN_RTC=y BR2_PACKAGE_FINIT_PLUGIN_TTY=y BR2_PACKAGE_FINIT_PLUGIN_URANDOM=y BR2_PACKAGE_IFUPDOWN_NG=y -BR2_PACKAGE_MECH=y +BR2_PACKAGE_KLINFIX=y BR2_PACKAGE_P_NET=y BR2_PACKAGE_P_NET_MAX_SUBSLOTS=12 BR2_PACKAGE_P_NET_MAX_PHYSICAL_PORTS=10 diff --git a/configs/amd64_defconfig b/configs/amd64_defconfig index d27a0540..87f9dd51 100644 --- a/configs/amd64_defconfig +++ b/configs/amd64_defconfig @@ -45,6 +45,7 @@ BR2_PACKAGE_UBOOT_TOOLS_FIT_SUPPORT=y BR2_PACKAGE_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y BR2_PACKAGE_UBOOT_TOOLS_FIT_CHECK_SIGN=y BR2_PACKAGE_LIBCURL_CURL=y +BR2_PACKAGE_NETOPEER2_CLI=y BR2_PACKAGE_NSS_MDNS=y BR2_PACKAGE_ONIGURUMA=y BR2_PACKAGE_AVAHI=y @@ -71,10 +72,6 @@ BR2_PACKAGE_NETCALC=y BR2_PACKAGE_NETCAT_OPENBSD=y BR2_PACKAGE_NETSNMP=y BR2_PACKAGE_NFTABLES=y -BR2_PACKAGE_NGINX_HTTP_SSL_MODULE=y -BR2_PACKAGE_NGINX_HTTP_V2_MODULE=y -BR2_PACKAGE_NGINX_HTTP_GUNZIP_MODULE=y -BR2_PACKAGE_NGINX_HTTP_AUTH_REQUEST_MODULE=y BR2_PACKAGE_NMAP=y BR2_PACKAGE_NMAP_NCAT=y BR2_PACKAGE_NMAP_NMAP=y @@ -99,7 +96,6 @@ BR2_PACKAGE_PWGEN=y BR2_PACKAGE_RAUC=y BR2_PACKAGE_RAUC_GPT=y BR2_PACKAGE_RAUC_NETWORK=y -BR2_PACKAGE_RAUC_STREAMING=y BR2_PACKAGE_SYSKLOGD=y BR2_PACKAGE_SYSKLOGD_LOGGER=y BR2_PACKAGE_WATCHDOGD=y @@ -114,15 +110,17 @@ BR2_TARGET_GRUB2_X86_64_EFI=y BR2_TARGET_GRUB2_BUILTIN_MODULES_EFI="boot linux ext2 fat squash4 part_gpt normal efi_gop configfile loadenv test terminfo terminal echo" BR2_TARGET_GRUB2_BUILTIN_CONFIG_EFI="${BR2_EXTERNAL_INFIX_PATH}/board/amd64/grub-embed.cfg" BR2_TARGET_GRUB2_INSTALL_TOOLS=y +BR2_PACKAGE_HOST_DOSFSTOOLS=y BR2_PACKAGE_HOST_E2FSPROGS=y BR2_PACKAGE_HOST_ENVIRONMENT_SETUP=y BR2_PACKAGE_HOST_GENEXT2FS=y BR2_PACKAGE_HOST_GENIMAGE=y +BR2_PACKAGE_HOST_MTOOLS=y BR2_PACKAGE_HOST_RAUC=y BR2_PACKAGE_HOST_UBOOT_TOOLS=y BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y -BR2_PACKAGE_CLIXON_RESTCONF_FCGI=y +BR2_PACKAGE_CONFD=y BR2_PACKAGE_FACTORY=y BR2_PACKAGE_FINIT_SULOGIN=y BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y @@ -133,7 +131,7 @@ BR2_PACKAGE_FINIT_PLUGIN_RTC=y BR2_PACKAGE_FINIT_PLUGIN_TTY=y BR2_PACKAGE_FINIT_PLUGIN_URANDOM=y BR2_PACKAGE_IFUPDOWN_NG=y -BR2_PACKAGE_MECH=y +BR2_PACKAGE_KLINFIX=y BR2_PACKAGE_P_NET=y BR2_PACKAGE_P_NET_MAX_SUBSLOTS=12 BR2_PACKAGE_P_NET_MAX_PHYSICAL_PORTS=10 diff --git a/package/Config.in b/package/Config.in index cd6e312e..f9e24aff 100644 --- a/package/Config.in +++ b/package/Config.in @@ -1,9 +1,14 @@ source "$BR2_EXTERNAL_INFIX_PATH/package/cligen/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/package/clixon/Config.in" +source "$BR2_EXTERNAL_INFIX_PATH/package/confd/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/package/factory/Config.in" +source "$BR2_EXTERNAL_INFIX_PATH/package/faux/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/package/finit/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/package/ifupdown2/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/package/ifupdown-ng/Config.in" +source "$BR2_EXTERNAL_INFIX_PATH/package/klinfix/Config.in" +source "$BR2_EXTERNAL_INFIX_PATH/package/klish/Config.in" +source "$BR2_EXTERNAL_INFIX_PATH/package/klish-plugin-sysrepo/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/package/mdnsd/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/package/mech/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/package/osal/Config.in" diff --git a/package/confd/Config.in b/package/confd/Config.in new file mode 100644 index 00000000..cb551a7a --- /dev/null +++ b/package/confd/Config.in @@ -0,0 +1,10 @@ +config BR2_PACKAGE_CONFD + bool "confd" + select BR2_PACKAGE_SYSREPO + select BR2_PACKAGE_NETOPEER2 + select BR2_PACKAGE_AUGEAS + select BR2_PACKAGE_JANSSON + help + A plugin to sysrepo that provides the core YANG models used to + manage an Infix based system. Configuration can be done using + either the on-system CLI or using NETCONF. diff --git a/package/confd/clean-etc b/package/confd/clean-etc new file mode 100755 index 00000000..342f47e4 --- /dev/null +++ b/package/confd/clean-etc @@ -0,0 +1,20 @@ +#!/bin/sh + +# This is an unmanaged node, leave /etc as-is +/lib/infix/use-etc && exit 0 + +# This is a managed node, ignore all default configuration ... +# ... except for some core services +reserved() +{ + for svc in dnsmasq getty klish lldpd nginx sysklogd sysrepo; do + [ "$1" = "${svc}.conf" ] && return 0 + done + + return 1 +} + +for file in /etc/finit.d/enabled/*.conf; do + reserved "$(basename "$file")" && continue + rm "$file" +done diff --git a/package/confd/confd.mk b/package/confd/confd.mk new file mode 100644 index 00000000..f707dfae --- /dev/null +++ b/package/confd/confd.mk @@ -0,0 +1,26 @@ +################################################################################ +# +# confd +# +################################################################################ + +CONFD_VERSION = 1.0 +CONFD_LICENSE = BSD-3-Clause +CONFD_SITE_METHOD = local +CONFD_SITE = $(BR2_EXTERNAL_INFIX_PATH)/src/confd +CONFD_DEPENDENCIES = augeas sysrepo +CONFD_AUTORECONF = YES + +define CONFD_INSTALL_EXTRA + cp $(CONFD_PKGDIR)/sysrepo.conf $(FINIT_D)/available/ + ln -sf ../available/sysrepo.conf $(FINIT_D)/enabled/sysrepo.conf + cp $(CONFD_PKGDIR)/tmpfiles.conf $(TARGET_DIR)/etc/tmpfiles.d/confd.conf + mkdir -p $(TARGET_DIR)/usr/share/factory/cfg + cp $(CONFD_PKGDIR)/factory.cfg $(TARGET_DIR)/usr/share/factory/cfg/startup-config.cfg + mkdir -p $(TARGET_DIR)/lib/infix + cp $(CONFD_PKGDIR)/prep-db $(TARGET_DIR)/lib/infix/ + cp $(CONFD_PKGDIR)/clean-etc $(TARGET_DIR)/lib/infix/ +endef +CONFD_TARGET_FINALIZE_HOOKS += CONFD_INSTALL_EXTRA + +$(eval $(autotools-package)) diff --git a/package/confd/factory.cfg b/package/confd/factory.cfg new file mode 100644 index 00000000..8711e168 --- /dev/null +++ b/package/confd/factory.cfg @@ -0,0 +1,5 @@ +{ + "ietf-system:system": { + "hostname": "default" + } +} diff --git a/package/confd/prep-db b/package/confd/prep-db new file mode 100755 index 00000000..541a41f5 --- /dev/null +++ b/package/confd/prep-db @@ -0,0 +1,4 @@ +#!/bin/sh +set -e + +exit 0 diff --git a/package/confd/sysrepo.conf b/package/confd/sysrepo.conf new file mode 100644 index 00000000..a78d4e56 --- /dev/null +++ b/package/confd/sysrepo.conf @@ -0,0 +1,8 @@ +run if: [S] /lib/infix/clean-etc -- +run if: [S] /lib/infix/prep-db -- + +service if: name:sysrepo [S12345789] sysrepo-plugind -p /run/sysrepo.pid -n -- Configuration daemon +run if: [S] log sysrepocfg -v4 -E/cfg/startup-config.cfg -f json -- +service if: name:netopeer [12345789] netopeer2-server -n -- NETCONF daemon + +task if: [12345789] resolvconf -u -- Update DNS configuration diff --git a/package/confd/tmpfiles.conf b/package/confd/tmpfiles.conf new file mode 100644 index 00000000..58cf1038 --- /dev/null +++ b/package/confd/tmpfiles.conf @@ -0,0 +1,2 @@ +d /run/resolvconf/interfaces - - - +C /cfg/startup-config.cfg - - - diff --git a/package/faux/Config.in b/package/faux/Config.in new file mode 100644 index 00000000..cdee852e --- /dev/null +++ b/package/faux/Config.in @@ -0,0 +1,7 @@ +config BR2_PACKAGE_FAUX + bool "faux" + depends on BR2_USE_MMU + help + The library contains a set of auxiliary functions. + + https://src.libcode.org/pkun/faux/ diff --git a/package/faux/faux.hash b/package/faux/faux.hash new file mode 100644 index 00000000..3059a197 --- /dev/null +++ b/package/faux/faux.hash @@ -0,0 +1,3 @@ +# Locally calculated +sha256 9d9d33b873917ca5d0bdcc47a36d2fd385971ab0c045d1472fcadf95ee5bcf5b LICENCE +sha256 8e369f54c2da317030ff4cad905e501303d0489b98e4b208d0ff611b4484c94e faux-tags_2.1.0-br1.tar.gz diff --git a/package/faux/faux.mk b/package/faux/faux.mk new file mode 100644 index 00000000..ff1e3cd6 --- /dev/null +++ b/package/faux/faux.mk @@ -0,0 +1,15 @@ +################################################################################ +# +# faux +# +################################################################################ + +FAUX_VERSION = tags/2.1.0 +FAUX_SITE = https://src.libcode.org/pkun/faux.git +FAUX_SITE_METHOD = git +FAUX_LICENSE = BSD-3 +FAUX_LICENSE_FILES = LICENSE +FAUX_INSTALL_STAGING = YES +FAUX_AUTORECONF = YES + +$(eval $(autotools-package)) diff --git a/package/finit/Config.in b/package/finit/Config.in index e0290304..94098312 100644 --- a/package/finit/Config.in +++ b/package/finit/Config.in @@ -150,6 +150,28 @@ config BR2_PACKAGE_FINIT_PLUGIN_RTC For lxc/docker application builds you do not need this. +if BR2_PACKAGE_FINIT_PLUGIN_RTC + +config BR2_PACKAGE_FINIT_RTC_DATE + string "Fallback RTC date" + help + On many embedded systems there is no RTC battery, maybe there + is a "supercap" but on first boot it is usually out of juice. + When this happens the RTC will return its default value, or + the driver will fail and report error. In these cases Linux + will detect a too old/invalid date set from userspace. Any + date prior to 2000-01-01 00:00 is denied. (Previously this + was the start of the UNIX epoch, Jan 1 1970.) + + This setting changes the default fallback date/time the RTC + plugin uses in case of such failures. Useful, e.g., for an + HTTPS certificate generated at first boot before any network + connection (DHCP/NTP) has been made to get the current time. + Ensuring the default system time to be closer to actual time + for a period after releasing a firmware image. + +endif + config BR2_PACKAGE_FINIT_PLUGIN_TTY bool "TTY plugin" help diff --git a/package/finit/finit.mk b/package/finit/finit.mk index 674acd7b..d67baf2e 100644 --- a/package/finit/finit.mk +++ b/package/finit/finit.mk @@ -89,6 +89,12 @@ else FINIT_CONF_OPTS += --disable-rtc-plugin endif +ifeq ($(BR2_PACKAGE_FINIT_RTC_DATE),y) +FINIT_CONF_OPTS += --with-rtc-date="$(BR2_PACKAGE_FINIT_RTC_DATE)" +else +FINIT_CONF_OPTS += --without-rtc-date +endif + ifeq ($(BR2_PACKAGE_FINIT_PLUGIN_TTY),y) FINIT_CONF_OPTS += --enable-tty-plugin else diff --git a/package/klinfix/Config.in b/package/klinfix/Config.in new file mode 100644 index 00000000..933d1289 --- /dev/null +++ b/package/klinfix/Config.in @@ -0,0 +1,8 @@ +config BR2_PACKAGE_KLINFIX + bool "klinfix" + select BR2_PACKAGE_KLISH + select BR2_PACKAGE_KLISH_PLUGIN_SYSREPO + select BR2_PACKAGE_SYSREPO + help + A plugin to klish with an opinionated config and some + command extensions, suitable for systems running Infix. diff --git a/package/klinfix/klinfix.mk b/package/klinfix/klinfix.mk new file mode 100644 index 00000000..d2f88539 --- /dev/null +++ b/package/klinfix/klinfix.mk @@ -0,0 +1,14 @@ +################################################################################ +# +# klinfix +# +################################################################################ + +KLINFIX_VERSION = 1.0 +KLINFIX_LICENSE = BSD-3-Clause +KLINFIX_SITE_METHOD = local +KLINFIX_SITE = $(BR2_EXTERNAL_INFIX_PATH)/src/klinfix +KLINFIX_DEPENDENCIES = klish-plugin-sysrepo +KLINFIX_AUTORECONF = YES + +$(eval $(autotools-package)) diff --git a/package/klish-plugin-sysrepo/Config.in b/package/klish-plugin-sysrepo/Config.in new file mode 100644 index 00000000..b9c735e8 --- /dev/null +++ b/package/klish-plugin-sysrepo/Config.in @@ -0,0 +1,22 @@ +config BR2_PACKAGE_KLISH_PLUGIN_SYSREPO + bool "klish-plugin-sysrepo" + depends on BR2_PACKAGE_KLISH + depends on BR2_PACKAGE_SYSREPO + help + This plugin allows klish framework to implement Juniper-like + interface for configuration. It uses sysrepo project as + background for datastores and libyang for yang files parsing + and configuration schemes. + + https://src.libcode.org/pkun/klish-plugin-sysrepo/ + +config BR2_PACKAGE_KLISH_PLUGIN_SYSREPO_XML + bool "install xml" + depends on BR2_PACKAGE_KLISH_PLUGIN_SYSREPO + depends on !BR2_PACKAGE_KLINFIX + default y + help + Install the default XML spec bundled with the project, which + exports the 'show' command, and the 'configure' view, etc. + + If unsure, say Y. diff --git a/package/klish-plugin-sysrepo/klish-plugin-sysrepo.hash b/package/klish-plugin-sysrepo/klish-plugin-sysrepo.hash new file mode 100644 index 00000000..ceb5ac66 --- /dev/null +++ b/package/klish-plugin-sysrepo/klish-plugin-sysrepo.hash @@ -0,0 +1,4 @@ +# Locally calculated +sha256 9d9d33b873917ca5d0bdcc47a36d2fd385971ab0c045d1472fcadf95ee5bcf5b LICENCE +sha256 515fa2a3c66b41d6ab5ec93d61cdd32097115b2f46e39c522659b84d555eebf5 klish-plugin-sysrepo-cdd3eb51a7f7ee0ed5bd925fa636061d3b1b85fb-br1.tar.gz + diff --git a/package/klish-plugin-sysrepo/klish-plugin-sysrepo.mk b/package/klish-plugin-sysrepo/klish-plugin-sysrepo.mk new file mode 100644 index 00000000..3f695c23 --- /dev/null +++ b/package/klish-plugin-sysrepo/klish-plugin-sysrepo.mk @@ -0,0 +1,25 @@ +################################################################################ +# +# klish-plugin-sysrepo +# +################################################################################ + +KLISH_PLUGIN_SYSREPO_VERSION = cdd3eb51a7f7ee0ed5bd925fa636061d3b1b85fb +KLISH_PLUGIN_SYSREPO_SITE = https://src.libcode.org/pkun/klish-plugin-sysrepo.git +KLISH_PLUGIN_SYSREPO_SITE_METHOD = git +KLISH_PLUGIN_SYSREPO_LICENSE = BSD-3 +KLISH_PLUGIN_SYSREPO_LICENSE_FILES = LICENSE +KLISH_PLUGIN_SYSREPO_DEPENDENCIES = klish sysrepo +KLISH_PLUGIN_SYSREPO_INSTALL_STAGING = YES +KLISH_PLUGIN_SYSREPO_AUTORECONF = YES + +ifeq ($(BR2_PACKAGE_KLISH_PLUGIN_SYSREPO_XML),y) +define KLISH_PLUGIN_SYSREPO_INSTALL_XML + $(INSTALL) -t $(TARGET_DIR)/etc/klish -D -m 0644 \ + $(@D)/xml/sysrepo.xml +endef +KLISH_PLUGIN_SYSREPO_POST_INSTALL_TARGET_HOOKS += \ + KLISH_PLUGIN_SYSREPO_INSTALL_XML +endif + +$(eval $(autotools-package)) diff --git a/package/klish/Config.in b/package/klish/Config.in new file mode 100644 index 00000000..e3f03e0e --- /dev/null +++ b/package/klish/Config.in @@ -0,0 +1,22 @@ +config BR2_PACKAGE_KLISH + bool "klish" + depends on BR2_USE_MMU + select BR2_PACKAGE_FAUX + select BR2_PACKAGE_LIBXML2 + help + Klish is a framework for implementing a CISCO-like or + Juniper-like CLI on a UNIX systems. + + https://src.libcode.org/pkun/klish/ + +config BR2_PACKAGE_KLISH_DEFAULT_XML + bool "install xml" + depends on BR2_PACKAGE_KLISH + depends on !BR2_PACKAGE_KLINFIX + default y + help + Install a small XML spec containing a definition of an + 'exit' command. This lets klish work out-of-the-box, even if + no other specs are available. + + If unsure, say Y. diff --git a/package/klish/default.xml b/package/klish/default.xml new file mode 100644 index 00000000..62e90d4c --- /dev/null +++ b/package/klish/default.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + %u@%h> + + + + + pop + Exiting klish session + + + + + + + diff --git a/package/klish/klish.hash b/package/klish/klish.hash new file mode 100644 index 00000000..ff5eb0a7 --- /dev/null +++ b/package/klish/klish.hash @@ -0,0 +1,3 @@ +# Locally calculated +sha256 9d9d33b873917ca5d0bdcc47a36d2fd385971ab0c045d1472fcadf95ee5bcf5b LICENCE +sha256 e7c09457ed0b030eddd8eaf7d9f7c9344c2fcd7ac2083f1d8ebeaafc4ed6dba6 klish-tags_3.0.0-br1.tar.gz diff --git a/package/klish/klish.mk b/package/klish/klish.mk new file mode 100644 index 00000000..99e2d6a2 --- /dev/null +++ b/package/klish/klish.mk @@ -0,0 +1,46 @@ +################################################################################ +# +# klish +# +################################################################################ + +KLISH_VERSION = tags/3.0.0 +KLISH_SITE = https://src.libcode.org/pkun/klish.git +KLISH_SITE_METHOD = git +KLISH_LICENSE = BSD-3 +KLISH_LICENSE_FILES = LICENSE +KLISH_DEPENDENCIES = libxml2 +KLISH_INSTALL_STAGING = YES +KLISH_AUTORECONF = YES + +KLISH_CONF_OPTS += --with-libxml2 + +define KLISH_INSTALL_CONFIG + $(INSTALL) -t $(TARGET_DIR)/etc/klish -D -m 0644 \ + $(@D)/klish.conf $(@D)/klishd.conf + +# klish's default pager settings assumes that less understands +# all GNU options, so we disable it. + sed -i -e 's/#UsePager=y/UsePager=n/' \ + $(TARGET_DIR)/etc/klish/klish.conf +endef +KLISH_POST_INSTALL_TARGET_HOOKS += KLISH_INSTALL_CONFIG + +ifeq ($(BR2_PACKAGE_KLISH_DEFAULT_XML),y) +define KLISH_INSTALL_XML + $(INSTALL) -t $(TARGET_DIR)/etc/klish -D -m 0644 \ + $(BR2_EXTERNAL_INFIX_PATH)/package/klish/default.xml +endef +KLISH_POST_INSTALL_TARGET_HOOKS += KLISH_INSTALL_XML +endif + +define KLISH_INSTALL_FINIT_SVC + $(INSTALL) -D -m 0644 $(BR2_EXTERNAL_INFIX_PATH)/package/klish/klish.svc \ + $(FINIT_D)/available/klish.conf + $(INSTALL) -d -m 0755 $(FINIT_D)/enabled + ln -sf ../available/klish.conf $(FINIT_D)/enabled/klish.conf +endef + +KLISH_POST_INSTALL_TARGET_HOOKS += KLISH_INSTALL_FINIT_SVC + +$(eval $(autotools-package)) diff --git a/package/klish/klish.svc b/package/klish/klish.svc new file mode 100644 index 00000000..a5bb2e6f --- /dev/null +++ b/package/klish/klish.svc @@ -0,0 +1 @@ +service [2345789] /usr/bin/klishd -d -- CLI backend diff --git a/board/common/rootfs/lib/infix/clean-etc b/package/mech/clean-etc similarity index 100% rename from board/common/rootfs/lib/infix/clean-etc rename to package/mech/clean-etc diff --git a/package/mech/mech.mk b/package/mech/mech.mk index 649bbb56..7c33ac9b 100644 --- a/package/mech/mech.mk +++ b/package/mech/mech.mk @@ -15,6 +15,9 @@ define MECH_INSTALL_EXTRA cp $(MECH_PKGDIR)/clixon.conf $(FINIT_D)/available/ ln -sf ../available/clixon.conf $(FINIT_D)/enabled/clixon.conf cp $(MECH_PKGDIR)/tmpfiles.conf $(TARGET_DIR)/etc/tmpfiles.d/mech.conf + mkdir -p $(TARGET_DIR)/lib/infix + cp $(MECH_PKGDIR)/prep-db $(TARGET_DIR)/lib/infix/ + cp $(MECH_PKGDIR)/clean-etc $(TARGET_DIR)/lib/infix/ endef MECH_TARGET_FINALIZE_HOOKS += MECH_INSTALL_EXTRA diff --git a/board/common/rootfs/lib/infix/prep-db b/package/mech/prep-db similarity index 100% rename from board/common/rootfs/lib/infix/prep-db rename to package/mech/prep-db diff --git a/package/sysrepo-plugin-system/sysrepo-plugin-system.mk b/package/sysrepo-plugin-system/sysrepo-plugin-system.mk index 5bd29954..044413b1 100644 --- a/package/sysrepo-plugin-system/sysrepo-plugin-system.mk +++ b/package/sysrepo-plugin-system/sysrepo-plugin-system.mk @@ -22,6 +22,8 @@ define SYSREPO_PLUGIN_SYSTEM_INSTALL_YANG_MODELS $(TARGET_DIR)/usr/share/yang/modules/sysrepo-plugin-system/iana-crypt-hash@2014-08-06.yang $(INSTALL) -D -m 0644 $(@D)/yang/ietf-system@2014-08-06.yang \ $(TARGET_DIR)/usr/share/yang/modules/sysrepo-plugin-system/ietf-system@2014-08-06.yang + $(INSTALL) -D -m 0644 $(@D)/yang/infix-system@2014-08-06.yang \ + $(TARGET_DIR)/usr/share/yang/modules/sysrepo-plugin-system/infix-system@2014-08-06.yang endef SYSREPO_PLUGIN_SYSTEM_POST_INSTALL_TARGET_HOOKS += SYSREPO_PLUGIN_SYSTEM_INSTALL_YANG_MODELS diff --git a/patches/netopeer2/netopeer2-server-foreground.patch b/patches/netopeer2/netopeer2-server-foreground.patch new file mode 100644 index 00000000..45a05388 --- /dev/null +++ b/patches/netopeer2/netopeer2-server-foreground.patch @@ -0,0 +1,60 @@ +commit 9e18bd10df1ac2aabd46a790ac6148c638a513b8 +Author: Joachim Wiberg +Date: Fri Mar 31 10:44:32 2023 +0200 + + netopeer2-server: add support for running in foreground with syslog + + Signed-off-by: Joachim Wiberg + +diff --git a/src/main.c b/src/main.c +index 6d054f5..c403000 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -1082,6 +1082,7 @@ print_usage(char *progname) + fprintf(stdout, " -f PATH Path to netopeer2 server files directory (default path is \"%s\")\n", SERVER_DIR); + fprintf(stdout, " -U[PATH] Listen on a local UNIX socket (default path is \"%s\").\n", NP2SRV_UNIX_SOCK_PATH); + fprintf(stdout, " -m MODE Set mode for the listening UNIX socket.\n"); ++ fprintf(stdout, " -n Run in foreground and log to syslog.\n"); + fprintf(stdout, " -u UID Set UID/user for the listening UNIX socket.\n"); + fprintf(stdout, " -g GID Set GID/group for the listening UNIX socket.\n"); + fprintf(stdout, " -t TIMEOUT Timeout in seconds of all sysrepo functions (applying edit-config, reading data, ...),\n"); +@@ -1112,7 +1113,7 @@ main(int argc, char *argv[]) + { + int ret = EXIT_SUCCESS; + int c, *idx, i; +- int daemonize = 1, verb = 0; ++ int daemonize = 1, verb = 0, use_syslog = 0; + int pidfd; + const char *pidfile = NP2SRV_PID_FILE_PATH; + char pid[8]; +@@ -1145,7 +1146,7 @@ main(int argc, char *argv[]) + np2srv.server_dir = SERVER_DIR; + + /* process command line options */ +- while ((c = getopt(argc, argv, "dhVp:f:U::m:u:g:t:x:v:c:")) != -1) { ++ while ((c = getopt(argc, argv, "dhVp:f:U::m:nu:g:t:x:v:c:")) != -1) { + switch (c) { + case 'd': + daemonize = 0; +@@ -1202,6 +1203,10 @@ main(int argc, char *argv[]) + return EXIT_FAILURE; + } + break; ++ case 'n': ++ daemonize = 0; ++ use_syslog = 1; ++ break; + case 'u': + np2srv.unix_uid = strtoul(optarg, &ptr, 10); + if (*ptr) { +@@ -1306,6 +1311,10 @@ main(int argc, char *argv[]) + np2_stderr_log = 0; + } + ++ /* use syslog even if running in foreground */ ++ if (use_syslog == 1) ++ np2_stderr_log = 0; ++ + /* make sure we are the only instance - lock the PID file and write the PID */ + pidfd = open(pidfile, O_RDWR | O_CREAT, 0640); + if (pidfd < 0) { diff --git a/patches/sysrepo/sysrepo-plugind-foreground.patch b/patches/sysrepo/sysrepo-plugind-foreground.patch new file mode 100644 index 00000000..827cfded --- /dev/null +++ b/patches/sysrepo/sysrepo-plugind-foreground.patch @@ -0,0 +1,64 @@ +commit 6fc440089353d76a9b8cb7c480402ee911a1387d +Author: Joachim Wiberg +Date: Tue Mar 28 10:37:53 2023 +0200 + + sysrepo-plugind: add support for running in foreground with syslog + + Signed-off-by: Joachim Wiberg + +diff --git a/src/executables/sysrepo-plugind.c b/src/executables/sysrepo-plugind.c +index bd584ed5..3079a855 100644 +--- a/src/executables/sysrepo-plugind.c ++++ b/src/executables/sysrepo-plugind.c +@@ -97,6 +97,7 @@ help_print(void) + " Change verbosity to a level (none, error, warning, info, debug) or\n" + " number (0, 1, 2, 3, 4).\n" + " -d, --debug Debug mode - is not daemonized and logs to stderr instead of syslog.\n" ++ " -n, --foreground Run in foreground and log to syslog.\n" + " -P, --plugin-install \n" + " Install a sysrepo-plugind plugin. The plugin is simply copied\n" + " to the designated plugin directory.\n" +@@ -200,6 +201,8 @@ daemon_init(int debug, sr_log_level_t log_level) + + if (debug) { + handle_signals(); ++ if (debug < 0) ++ goto done; + sr_log_stderr(log_level); + return; + } +@@ -240,6 +243,7 @@ daemon_init(int debug, sr_log_level_t log_level) + close(fd); + } + ++done: + /* set verbosity */ + sr_log_syslog("sysrepo-plugind", log_level); + } +@@ -459,6 +463,7 @@ main(int argc, char **argv) + {"version", no_argument, NULL, 'V'}, + {"verbosity", required_argument, NULL, 'v'}, + {"debug", no_argument, NULL, 'd'}, ++ {"foreground", no_argument, NULL, 'n'}, + {"plugin-install", required_argument, NULL, 'P'}, + {"pid-file", required_argument, NULL, 'p'}, + {"fatal-plugin-fail", no_argument, NULL, 'f'}, +@@ -467,7 +472,7 @@ main(int argc, char **argv) + + /* process options */ + opterr = 0; +- while ((opt = getopt_long(argc, argv, "hVv:dP:p:f", options, NULL)) != -1) { ++ while ((opt = getopt_long(argc, argv, "hVv:dnP:p:f", options, NULL)) != -1) { + switch (opt) { + case 'h': + version_print(); +@@ -499,6 +504,9 @@ main(int argc, char **argv) + case 'd': + debug = 1; + break; ++ case 'n': ++ debug = -1; ++ break; + case 'P': + /* plugin-install */ + if (get_plugins_dir(&plugins_dir)) { diff --git a/src/confd/.gitignore b/src/confd/.gitignore new file mode 100644 index 00000000..e9e8e747 --- /dev/null +++ b/src/confd/.gitignore @@ -0,0 +1,33 @@ +*~ +*.o +*.la +*.lo +*.so +.deps +.libs + +/aclocal.m4 +/autom4te.cache/ +/aux +/clixon.xml +/compile +/config.h +/config.h.in +/config.guess +/config.log +/config.status +/config.sub +/configure +/depcomp +/install-sh +/libtool +/ltmain.sh +/m4 +/missing + +GPATH +GRTAGS +GTAGS +Makefile +Makefile.in + diff --git a/src/confd/LICENSE b/src/confd/LICENSE new file mode 100644 index 00000000..0423839d --- /dev/null +++ b/src/confd/LICENSE @@ -0,0 +1,29 @@ +Copyright (c) 2020 Denis Kalashnikov +Copyright (c) 2023 The KernelKit Authors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of copyright holders nor the names of + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/src/confd/Makefile.am b/src/confd/Makefile.am new file mode 100644 index 00000000..a949b1fc --- /dev/null +++ b/src/confd/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = src yang +DISTCLEANFILES = *~ *.d +ACLOCAL_AMFLAGS = -I m4 diff --git a/src/confd/README.md b/src/confd/README.md new file mode 100644 index 00000000..02951ac8 --- /dev/null +++ b/src/confd/README.md @@ -0,0 +1,15 @@ +Configuration Daemon +==================== + +`confd` is the Infix configuration daemon that serves as the glue +between sysrepo and netopeer2 (NETCONF) and the UNIX system under +it all. + + +Origin & References +------------------- + +Based on the Open Source [dklibc/sysrepo_plugin_ietf_system][0] +project by Denis Kalashnikov. + +[0]: https://github.com/dklibc/sysrepo_plugin_ietf_system diff --git a/src/confd/autogen.sh b/src/confd/autogen.sh new file mode 100755 index 00000000..69ad0e18 --- /dev/null +++ b/src/confd/autogen.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +autoreconf -W portability -vifm diff --git a/src/confd/configure.ac b/src/confd/configure.ac new file mode 100644 index 00000000..fe2923ee --- /dev/null +++ b/src/confd/configure.ac @@ -0,0 +1,55 @@ +AC_PREREQ(2.61) +AC_INIT([confd], [1.0.0], + [https://github.com/kernelkit/infix/issues]) +AM_INIT_AUTOMAKE(1.11 foreign subdir-objects) +AM_SILENT_RULES(yes) + +LT_INIT + +AC_CONFIG_FILES([ + Makefile + src/Makefile + yang/Makefile +]) + +AC_PROG_CC +AC_PROG_INSTALL + +# 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]) + +# Plugin installation path for sysrepo-plugind +PKG_CHECK_VAR([srpdplugindir], [sysrepo], [SRPD_PLUGINS_PATH]) +AC_SUBST(srpdplugindir) + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DATAROOTDIR=`eval echo $datarootdir` +DATAROOTDIR=`eval echo $DATAROOTDIR` +AC_SUBST(DATAROOTDIR) + +YANGDIR=`eval echo $datarootdir/yang/modules/confd` +AC_SUBST(YANGDIR) + +LIBDIR=`eval echo $libdir` +LIBDIR=`eval echo $LIBDIR` +AC_SUBST(LIBDIR) + +LOCALSTATEDIR=`eval echo $localstatedir` +LOCALSTATEDIR=`eval echo $LOCALSTATEDIR` +AC_SUBST(LOCALSTATEDIR) + +RUNSTATEDIR=`eval echo $runstatedir` +RUNSTATEDIR=`eval echo $RUNSTATEDIR` +AC_SUBST(RUNSTATEDIR) + +SYSCONFDIR=`eval echo $sysconfdir` +SYSCONFDIR=`eval echo $SYSCONFDIR` +AC_SUBST(SYSCONFDIR) + +AC_OUTPUT diff --git a/src/confd/src/Makefile.am b/src/confd/src/Makefile.am new file mode 100644 index 00000000..49083c9a --- /dev/null +++ b/src/confd/src/Makefile.am @@ -0,0 +1,10 @@ +CFLAGS = -Wall -Wextra -Werror -Wno-unused-parameter +AM_CPPFLAGS = -D_DEFAULT_SOURCE -D_XOPEN_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_LDFLAGS = -module -avoid-version -shared +confd_plugin_la_SOURCES = core.c core.h run.c ietf-system.c ietf-interfaces.c diff --git a/src/confd/src/core.c b/src/confd/src/core.c new file mode 100644 index 00000000..8c2708aa --- /dev/null +++ b/src/confd/src/core.c @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#include "core.h" + +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")) + return SR_ERR_SYS; + + return SR_ERR_OK; +} + +static int commit_done_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 (system("initctl -nbq reload")) + return SR_ERR_SYS; + + return SR_ERR_OK; +} + +int sr_plugin_init_cb(sr_session_ctx_t *session, void **priv) +{ + sr_session_ctx_t *startup; + int rc = SR_ERR_SYS; + + openlog("confd", LOG_USER, 0); + + /* Save context with default running config datastore for all our models */ + *priv = (void *)&confd; + confd.session = session; + confd.conn = sr_session_get_connection(session); + confd.sub = NULL; + + if (!confd.conn) + goto err; + + confd.aug = aug_init(NULL, "", 0); + if (!confd.aug) + goto err; + + rc = ietf_interfaces_init(&confd); + if (rc) + goto err; + rc = ietf_system_init(&confd); + if (rc) + goto err; + + /* YOUR_INIT GOES HERE */ + + /* Set up hook to save startup-config to persisten backend store */ + rc = sr_session_start(confd.conn, SR_DS_STARTUP, &startup); + if (rc) + goto err; + + rc = sr_module_change_subscribe(startup, "ietf-system", "/ietf-system:system//.", + startup_save_hook, NULL, 0, SR_SUBSCR_PASSIVE | SR_SUBSCR_DONE_ONLY, &confd.sub); + if (rc) { + ERROR("failed setting up startup-config hook: %s", sr_strerror(rc)); + goto err; + } + + rc = sr_module_change_subscribe(session, "ietf-system", "/ietf-system:system//.", + commit_done_hook, NULL, 0, SR_SUBSCR_PASSIVE | SR_SUBSCR_DONE_ONLY, &confd.sub); + if (rc) { + ERROR("failed setting up startup-config hook: %s", sr_strerror(rc)); + goto err; + } + + rc = sr_install_module(confd.conn, YANG_PATH_"kernelkit-infix-deviations.yang", NULL, NULL); + if (rc) + goto err; + + return SR_ERR_OK; +err: + ERROR("init failed: %s", sr_strerror(rc)); + sr_unsubscribe(confd.sub); + + return rc; +} + +void sr_plugin_cleanup_cb(sr_session_ctx_t *session, void *priv) +{ + sr_unsubscribe((sr_subscription_ctx_t *)priv); + closelog(); +} diff --git a/src/confd/src/core.h b/src/confd/src/core.h new file mode 100644 index 00000000..4dd130fc --- /dev/null +++ b/src/confd/src/core.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +#ifndef CONFD_CORE_H_ +#define CONFD_CORE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +#define NELEMS(arr) (sizeof(arr) / sizeof(arr[0])) + +#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)) + +static inline void print_val(sr_val_t *val) +{ + char *str; + + if (sr_print_val_mem(&str, val)) + return; + ERROR("%s", str); + free(str); +} + +#define REGISTER_CHANGE(s,m,x,f,c,a,u) \ + if ((rc = register_change(s, m, x, f, c, a, u))) \ + goto err + +#define REGISTER_RPC(s,x,c,a,u) \ + if ((rc = register_rpc(s, x, c, a, u))) \ + goto err + +struct confd { + sr_session_ctx_t *session; + sr_conn_ctx_t *conn; + sr_subscription_ctx_t *sub; + + augeas *aug; +}; + +static inline int register_change(sr_session_ctx_t *session, const char *module, const char *xpath, + int flags, sr_module_change_cb cb, void *arg, sr_subscription_ctx_t **sub) +{ + int rc = sr_module_change_subscribe(session, module, xpath, cb, arg, 0, flags | SR_SUBSCR_DEFAULT, sub); + if (rc) + ERROR("failed subscribing to changes of %s: %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) +{ + int rc = sr_rpc_subscribe(session, xpath, cb, arg, 0, SR_SUBSCR_DEFAULT, sub); + if (rc) + ERROR("failed subscribing to %s rpc: %s", xpath, sr_strerror(rc)); + return rc; +} + + +/* core.c */ +int run(const char *fmt, ...); + +/* ietf-interfaces.c */ +int ietf_interfaces_init(struct confd *confd); + +/* ietf-system.c */ +int ietf_system_init(struct confd *confd); + +#endif /* CONFD_CORE_H_ */ diff --git a/src/confd/src/ietf-interfaces.c b/src/confd/src/ietf-interfaces.c new file mode 100644 index 00000000..d2052a4b --- /dev/null +++ b/src/confd/src/ietf-interfaces.c @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#include "core.h" + +int ietf_interfaces_init(struct confd *confd) +{ + return SR_ERR_OK; +} diff --git a/src/confd/src/ietf-system.c b/src/confd/src/ietf-system.c new file mode 100644 index 00000000..7c7841c4 --- /dev/null +++ b/src/confd/src/ietf-system.c @@ -0,0 +1,795 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#include "core.h" +#include +#include +#include + +#define CLOCK_PATH_ "/ietf-system:system-state/clock" +#define PLATFORM_PATH_ "/ietf-system:system-state/platform" + +static char *ver = NULL; +static char *rel = NULL; +static char *sys = NULL; +static char *os = NULL; + +static char *strip_quotes(char *str) +{ + char *ptr; + + while (*str && (isspace(*str) || *str == '"')) + str++; + + for (ptr = str + strlen(str); ptr > str; ptr--) { + if (*ptr != '"') + continue; + + *ptr = 0; + break; + } + + return str; +} + +static void setvar(char *line, const char *nm, char **var) +{ + char *ptr; + + if (!strncmp(line, nm, strlen(nm)) && (ptr = strchr(line, '='))) { + if (*var) + free(*var); + *var = strdup(strip_quotes(++ptr)); + } +} + +static void os_init(void) +{ + struct utsname uts; + char line[80]; + FILE *fp; + + if (!uname(&uts)) { + os = strdup(uts.sysname); + ver = strdup(uts.release); + rel = strdup(uts.release); + sys = strdup(uts.machine); + } + + fp = fopen("/etc/os-release", "r"); + if (!fp) { + fp = fopen("/usr/lib/os-release", "r"); + if (!fp) + return; + } + + while (fgets(line, sizeof(line), fp)) { + line[strlen(line) - 1] = 0; /* drop \n */ + setvar(line, "NAME", &os); + setvar(line, "VERSION_ID", &ver); + setvar(line, "BUILD_ID", &rel); + setvar(line, "ARCHITECTURE", &sys); + } + fclose(fp); +} + +static char *fmtime(time_t t, char *buf, size_t len) +{ + const char *isofmt = "%FT%T%z"; + struct tm tm; + size_t i, n; + + localtime_r(&t, &tm); + n = strftime(buf, len, isofmt, &tm); + i = n - 5; + if (buf[i] == '+' || buf[i] == '-') { + buf[i + 6] = buf[i + 5]; + buf[i + 5] = buf[i + 4]; + buf[i + 4] = buf[i + 3]; + buf[i + 3] = ':'; + } + + return buf; +} + +static int clock_cb(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) +{ + static char boottime[64] = { 0 }; + const struct ly_ctx *ctx; + char curtime[64]; + time_t now, boot; + char *buf; + 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; + + sysinfo(&si); + boot = now - si.uptime; + fmtime(boot, boottime, sizeof(boottime)); + } + + rc = lyd_new_path(*parent, NULL, CLOCK_PATH_ "/boot-datetime", boottime, 0, NULL); + if (rc) + goto fail; + + fmtime(now, curtime, sizeof(curtime)); + rc = lyd_new_path(*parent, NULL, CLOCK_PATH_ "/current-datetime", curtime, 0, NULL); + if (rc) + goto fail; + + lyd_print_mem(&buf, *parent, LYD_XML, 0); + DEBUG("%s", buf); + + return SR_ERR_OK; +} + +static int platform_cb(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) +{ + const struct ly_ctx *ctx; + char *buf; + 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) + goto fail; + rc = lyd_new_path(*parent, NULL, PLATFORM_PATH_"/os-release", rel, 0, NULL); + if (rc) + goto fail; + rc = lyd_new_path(*parent, NULL, PLATFORM_PATH_"/os-version", ver, 0, NULL); + if (rc) + goto fail; + rc = lyd_new_path(*parent, NULL, PLATFORM_PATH_"/machine", sys, 0, NULL); + if (rc) + goto fail; + + lyd_print_mem(&buf, *parent, LYD_XML, 0); + DEBUG("%s", buf); + + return SR_ERR_OK; +} + +static int rpc_exec(sr_session_ctx_t *session, uint32_t sub_id, const char *path, + const sr_val_t *input, const size_t input_cnt, + sr_event_t event, unsigned request_id, + sr_val_t **output, size_t *output_cnt, + void *priv) +{ + DEBUG("path: %s", path); + + if (run(priv)) + return SR_ERR_INTERNAL; + + return SR_ERR_OK; +} + +/* '/ietf-system:set-current-date-time' */ +static int rpc_set_datetime(sr_session_ctx_t *session, uint32_t sub_id, + const char *path, const sr_val_t *input, + const size_t input_cnt, sr_event_t event, + unsigned request_id, sr_val_t **output, + size_t *output_cnt, void *priv) +{ + const char *isofmt = "%FT%T%z"; + static int rc = SR_ERR_SYS; + struct timeval tv; + struct tm tm; + char tz[24]; + char *buf; + size_t n; + + buf = strdup(input->data.string_val); + if (!buf) + return SR_ERR_NO_MEMORY; + + n = strlen(buf); + if (buf[n - 3] == ':' && (buf[n - 6] == '+' || buf[n - 6] == '-')) { + buf[n - 3] = buf[n - 2]; + buf[n - 2] = buf[n - 1]; + buf[n - 1] = 0; + } else + isofmt = "%FT%TZ"; + + memset(&tm, 0, sizeof(tm)); + if (!strptime(buf, isofmt, &tm)) { + ERRNO("ietf-system:failed strptime: %s", strerror(errno)); + goto done; + } + + snprintf(tz, sizeof(tz), "UTC%s%ld", tm.tm_gmtoff > 0 ? "+" : "", tm.tm_gmtoff / 3600); + setenv("TZ", tz, 1); + + tv.tv_sec = mktime(&tm); + tv.tv_usec = 0; + if (settimeofday(&tv, NULL)) { + ERRNO("ietf-system:settimeofday() failed"); + goto done; + } + + rc = SR_ERR_OK; +done: + unsetenv("TZ"); + free(buf); + + return rc; +} + +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; +} + +#define TIMEZONE_CONF "/etc/timezone" +#define TIMEZONE_PREV TIMEZONE_CONF "-" +#define TIMEZONE_NEXT TIMEZONE_CONF "+" + +static int change_clock(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 *timezone; + FILE *fp; + + switch (event) { + case SR_EV_ENABLED: /* first time, on register. */ + case SR_EV_CHANGE: /* regular change (copy cand running) */ + /* Set up next timezone */ + break; + + case SR_EV_ABORT: /* User abort, or other plugin failed */ + remove(TIMEZONE_NEXT); + return SR_ERR_OK; + + case SR_EV_DONE: + /* Check if passed validation in previous event */ + if (access(TIMEZONE_NEXT, F_OK)) + return SR_ERR_OK; + + remove(TIMEZONE_PREV); + rename(TIMEZONE_CONF, TIMEZONE_PREV); + rename(TIMEZONE_NEXT, TIMEZONE_CONF); + + remove("/etc/localtime-"); + rename("/etc/localtime", "/etc/localtime-"); + rename("/etc/localtime+", "/etc/localtime"); + + return SR_ERR_OK; + + default: + return SR_ERR_OK; + } + + /* XXX: add support also for /ietf-system:system/clock/timezone-utc-offset (deviation) */ + timezone = sr_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)) { + ERROR("No such timezone %s", timezone); + return SR_ERR_VALIDATION_FAILED; + } + + fp = fopen(TIMEZONE_NEXT, "w"); + if (!fp) { + ERRNO("Failed preparing %s", TIMEZONE_NEXT); + return SR_ERR_SYS; + } + fprintf(fp, "%s\n", timezone); + fclose(fp); + + return SR_ERR_OK; +} + +#define CHRONY_CONF "/etc/chrony.conf" +#define CHRONY_PREV CHRONY_CONF "-" +#define CHRONY_NEXT CHRONY_CONF "+" + +static int change_ntp(sr_session_ctx_t *session, uint32_t sub_id, const char *module, + const char *xpath, sr_event_t event, unsigned request_id, void *priv) +{ + const char *fn = CHRONY_NEXT; + int valid = -1; + sr_val_t *val; + size_t cnt; + FILE *fp; + int rc; + + switch (event) { + case SR_EV_ENABLED: /* first time, on register. */ + case SR_EV_CHANGE: /* regular change (copy cand running) */ + /* Generate next config */ + break; + + case SR_EV_ABORT: /* User abort, or other plugin failed */ + remove(CHRONY_NEXT); + return SR_ERR_OK; + + case SR_EV_DONE: + /* Check if passed validation in previous event */ + if (access(CHRONY_NEXT, F_OK)) + return SR_ERR_OK; + + 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"); + 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"); + return SR_ERR_OK; + + default: + return SR_ERR_OK; + } + + rc = sr_get_items(session, "/ietf-system:system/ntp/server", 0, 0, &val, &cnt); + if (rc) { + remove(CHRONY_NEXT); + return rc; + } + + fp = fopen(fn, "w"); + if (!fp) { + ERROR("failed updating %s: %s", fn, strerror(errno)); + sr_free_values(val, cnt); + return SR_ERR_SYS; + } + + for (size_t i = 0; i < cnt; i++) { + const char *xpath = val[i].xpath; + char *type, *ptr; + int server = 0; + + /* + * Handle empty startup-config on SR_EV_ENABLED, + * prevents subscribe failure due to false invalid. + */ + if (i == 0) + valid = 0; + + /* Get /ietf-system:system/ntp/server[name='foo'] */ + ptr = sr_get_str(session, "%s/udp/address", xpath); + if (ptr) { + type = sr_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); + if (ptr) { + fprintf(fp, " port %s", ptr); + free(ptr); + } + } + + if (server) { + if (sr_get_bool(session, "%s/iburst", xpath)) + fprintf(fp, " iburst"); + if (sr_get_bool(session, "%s/prefer", xpath)) + fprintf(fp, " prefer"); + + fprintf(fp, "\n"); + valid++; + } + } + sr_free_values(val, cnt); + + fprintf(fp, "driftfile /var/lib/chrony/drift\n"); + fprintf(fp, "makestep 1.0 3\n"); + fprintf(fp, "maxupdateskew 100.0\n"); + fprintf(fp, "dumpdir /var/lib/chrony\n"); + fprintf(fp, "rtcfile /var/lib/chrony/rtc\n"); + fclose(fp); + + if (!valid) { + remove(fn); + return SR_ERR_VALIDATION_FAILED; + } + + return SR_ERR_OK; +} + +#define RESOLV_CONF "/etc/resolv.conf.head" +#define RESOLV_PREV RESOLV_CONF "-" +#define RESOLV_NEXT RESOLV_CONF "+" + +static int change_dns(sr_session_ctx_t *session, uint32_t sub_id, const char *module, + const char *xpath, sr_event_t event, unsigned request_id, void *priv) +{ + const char *fn = RESOLV_NEXT; + int timeout, attempts; + int rc = SR_ERR_SYS; + sr_val_t *val; + size_t cnt; + FILE *fp; + + switch (event) { + case SR_EV_ENABLED: /* first time, on register. */ + case SR_EV_CHANGE: /* regular change (copy cand running) */ + /* Generate next config */ + break; + + case SR_EV_ABORT: /* User abort, or other plugin failed */ + remove(RESOLV_NEXT); + return SR_ERR_OK; + + case SR_EV_DONE: + /* Check if passed validation in previous event */ + if (access(RESOLV_NEXT, F_OK)) + return SR_ERR_OK; + + remove(RESOLV_PREV); + rename(RESOLV_CONF, RESOLV_PREV); + rename(RESOLV_NEXT, RESOLV_CONF); + + /* in bootstrap, another resolvconf will soon take your call */ + if (run("initctl cond get hook/sys/up")) + return 0; + + run("resolvconf -u"); + return SR_ERR_OK; + + default: + return SR_ERR_OK; + } + + fp = fopen(fn, "w"); + if (!fp) { + ERROR("failed updating %s: %s", fn, strerror(errno)); + sr_free_values(val, cnt); + 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"); + if (timeout || attempts) { + fprintf(fp, "options"); + if (timeout) + fprintf(fp, " timeout:%d", timeout); + if (attempts) + fprintf(fp, " attempts:%d ", attempts); + fprintf(fp, "\n"); + } + + rc = sr_get_items(session, "/ietf-system:system/dns-resolver/search", 0, 0, &val, &cnt); + if (rc) + goto fail; + + if (cnt) { + fprintf(fp, "search "); + for (size_t i = 0; i < cnt; i++) + fprintf(fp, "%s ", val[i].data.string_val); + fprintf(fp, "\n"); + } + sr_free_values(val, cnt); + + rc = sr_get_items(session, "/ietf-system:system/dns-resolver/server", 0, 0, &val, &cnt); + if (rc) + goto fail; + + for (size_t i = 0; i < cnt; i++) { + const char *xpath = val[i].xpath; + char *ptr; + + /* Get /ietf-system:system/dns-resolver/server[name='foo'] */ + ptr = sr_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); + } + sr_free_values(val, cnt); + + rc = SR_ERR_OK; +fail: + fclose(fp); + if (rc) + remove(fn); + + return rc; +} + +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; + + /* 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); + } 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"); + } + fclose(fp); + + return SR_ERR_OK; +} + +static int change_hostname(sr_session_ctx_t *session, uint32_t sub_id, const char *module, + const char *xpath, sr_event_t event, unsigned request_id, void *priv) +{ + struct confd *confd = (struct confd *)priv; + const char *host, *tmp = NULL; + char **hosts, *current; + int err, i, nhosts; + char *nm; + + if (event != SR_EV_DONE) + return SR_ERR_OK; + + nm = sr_get_str(session, xpath); + if (!nm) { + /* XXX: derive from global "options.h" or /usr/share/factory/ */ + nm = strdup("infix"); + if (!nm) + goto err; + } + + if (aug_get(confd->aug, "etc/hostname/hostname", &tmp) <= 0) + goto err; + + current = strdup(tmp); + if (!current) + goto err; + + err = sethostname(nm, strlen(nm)); + err = err ? : aug_set(confd->aug, "etc/hostname/hostname", nm); + + nhosts = aug_match(confd->aug, "etc/hosts/*/canonical", &hosts); + for (i = 0; i < nhosts; i++) { + if (aug_get(confd->aug, hosts[i], &host) <= 0) + continue; + + if (!strcmp(host, current)) + err = err ? : aug_set(confd->aug, hosts[i], nm); + + free(hosts[i]); + } + + if (nhosts) + free(hosts); + free(current); +err: + if (nm) + free(nm); + + if (err) { + ERROR("Failed activating changes."); + return err; + } + + ERROR("Reload hostname-dependent services ..."); + err = err ? : aug_save(confd->aug); + if (sys_reload_services()) + return SR_ERR_SYS; + + return SR_ERR_OK; +} + +int ietf_system_init(struct confd *confd) +{ + const char *features[] = { + "ntp", + "ntp-udp-port", + "timezone-name", + NULL + }; + int rc; + + os_init(); + + if (aug_load_file(confd->aug, "/etc/hostname") || + aug_load_file(confd->aug, "/etc/hosts")) { + ERROR("ietf-system: Augeas initialization failed"); + goto err; + } + + rc = sr_install_module(confd->conn, YANG_PATH_"ietf-system@2014-08-06.yang", NULL, features); + if (rc) + goto err; + /* Augment to ietf-systems */ + 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; + + 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); + REGISTER_CHANGE(confd->session, "ietf-system", "/ietf-system:system/clock", 0, change_clock, confd, &confd->sub); + 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_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: + ERROR("init failed: %s", sr_strerror(rc)); + sr_unsubscribe(confd->sub); + + return rc; +} diff --git a/src/confd/src/run.c b/src/confd/src/run.c new file mode 100644 index 00000000..1a809c68 --- /dev/null +++ b/src/confd/src/run.c @@ -0,0 +1,52 @@ +/* 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/yang/Makefile.am b/src/confd/yang/Makefile.am new file mode 100644 index 00000000..3e287aca --- /dev/null +++ b/src/confd/yang/Makefile.am @@ -0,0 +1,2 @@ +yangdir = $(YANGDIR) +yang_DATA = $(wildcard *.yang) diff --git a/src/confd/yang/iana-crypt-hash@2014-08-06.yang b/src/confd/yang/iana-crypt-hash@2014-08-06.yang new file mode 100644 index 00000000..48dc50e3 --- /dev/null +++ b/src/confd/yang/iana-crypt-hash@2014-08-06.yang @@ -0,0 +1,120 @@ +module iana-crypt-hash { + namespace "urn:ietf:params:xml:ns:yang:iana-crypt-hash"; + prefix ianach; + + organization "IANA"; + contact + " Internet Assigned Numbers Authority + + Postal: ICANN + 12025 Waterfront Drive, Suite 300 + Los Angeles, CA 90094-2536 + United States + + Tel: +1 310 301 5800 + E-Mail: iana@iana.org>"; + description + "This YANG module defines a type for storing passwords + using a hash function and features to indicate which hash + functions are supported by an implementation. + + The latest revision of this YANG module can be obtained from + the IANA web site. + + Requests for new values should be made to IANA via + email (iana@iana.org). + + Copyright (c) 2014 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (http://trustee.ietf.org/license-info). + + The initial version of this YANG module is part of RFC 7317; + see the RFC itself for full legal notices."; + + revision 2014-08-06 { + description + "Initial revision."; + reference + "RFC 7317: A YANG Data Model for System Management"; + } + + typedef crypt-hash { + type string { + pattern + '$0$.*' + + '|$1$[a-zA-Z0-9./]{1,8}$[a-zA-Z0-9./]{22}' + + '|$5$(rounds=\d+$)?[a-zA-Z0-9./]{1,16}$[a-zA-Z0-9./]{43}' + + '|$6$(rounds=\d+$)?[a-zA-Z0-9./]{1,16}$[a-zA-Z0-9./]{86}'; + } + description + "The crypt-hash type is used to store passwords using + a hash function. The algorithms for applying the hash + function and encoding the result are implemented in + various UNIX systems as the function crypt(3). + + A value of this type matches one of the forms: + + $0$ + $$$ + $$$$ + + The '$0$' prefix signals that the value is clear text. When + such a value is received by the server, a hash value is + calculated, and the string '$$$' or + $$$$ is prepended to the result. This + value is stored in the configuration data store. + If a value starting with '$$', where is not '0', is + received, the server knows that the value already represents a + hashed value and stores it 'as is' in the data store. + + When a server needs to verify a password given by a user, it + finds the stored password hash string for that user, extracts + the salt, and calculates the hash with the salt and given + password as input. If the calculated hash value is the same + as the stored value, the password given by the client is + accepted. + + This type defines the following hash functions: + + id | hash function | feature + ---+---------------+------------------- + 1 | MD5 | crypt-hash-md5 + 5 | SHA-256 | crypt-hash-sha-256 + 6 | SHA-512 | crypt-hash-sha-512 + + The server indicates support for the different hash functions + by advertising the corresponding feature."; + reference + "IEEE Std 1003.1-2008 - crypt() function + RFC 1321: The MD5 Message-Digest Algorithm + FIPS.180-4.2012: Secure Hash Standard (SHS)"; + } + + feature crypt-hash-md5 { + description + "Indicates that the device supports the MD5 + hash function in 'crypt-hash' values."; + reference "RFC 1321: The MD5 Message-Digest Algorithm"; + } + + feature crypt-hash-sha-256 { + description + "Indicates that the device supports the SHA-256 + hash function in 'crypt-hash' values."; + reference "FIPS.180-4.2012: Secure Hash Standard (SHS)"; + } + + feature crypt-hash-sha-512 { + description + "Indicates that the device supports the SHA-512 + hash function in 'crypt-hash' values."; + reference "FIPS.180-4.2012: Secure Hash Standard (SHS)"; + } + +} \ No newline at end of file diff --git a/src/confd/yang/iana-if-type@2017-01-19.yang b/src/confd/yang/iana-if-type@2017-01-19.yang new file mode 100644 index 00000000..7bfee364 --- /dev/null +++ b/src/confd/yang/iana-if-type@2017-01-19.yang @@ -0,0 +1,1619 @@ +module iana-if-type { + namespace "urn:ietf:params:xml:ns:yang:iana-if-type"; + prefix ianaift; + + import ietf-interfaces { + prefix if; + } + + organization "IANA"; + contact + " Internet Assigned Numbers Authority + + Postal: ICANN + 12025 Waterfront Drive, Suite 300 + Los Angeles, CA 90094-2536 + United States + + Tel: +1 310 301 5800 + "; + description + "This YANG module defines YANG identities for IANA-registered + interface types. + + This YANG module is maintained by IANA and reflects the + 'ifType definitions' registry. + + The latest revision of this YANG module can be obtained from + the IANA web site. + + Requests for new values should be made to IANA via + email (iana&iana.org). + + Copyright (c) 2014 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (http://trustee.ietf.org/license-info). + + The initial version of this YANG module is part of RFC 7224; + see the RFC itself for full legal notices."; + reference + "IANA 'ifType definitions' registry. + "; + + revision 2017-01-19 { + description + "Registered ifType 289."; + } + + revision 2016-11-23 { + description + "Registered ifTypes 283-288."; + } + + revision 2016-06-09 { + description + "Registered ifType 282."; + } + revision 2016-05-03 { + description + "Registered ifType 281."; + } + revision 2015-06-12 { + description + "Corrected formatting issue."; + } + revision 2014-09-24 { + description + "Registered ifType 280."; + } + revision 2014-09-19 { + description + "Registered ifType 279."; + } + revision 2014-07-03 { + description + "Registered ifTypes 277-278."; + } + revision 2014-05-19 { + description + "Updated the contact address."; + } + revision 2014-05-08 { + description + "Initial revision."; + reference + "RFC 7224: IANA Interface Type YANG Module"; + } + + identity iana-interface-type { + base if:interface-type; + description + "This identity is used as a base for all interface types + defined in the 'ifType definitions' registry."; + } + + identity other { + base iana-interface-type; + } + identity regular1822 { + base iana-interface-type; + } + identity hdh1822 { + base iana-interface-type; + } + identity ddnX25 { + base iana-interface-type; + } + identity rfc877x25 { + base iana-interface-type; + reference + "RFC 1382 - SNMP MIB Extension for the X.25 Packet Layer"; + } + identity ethernetCsmacd { + base iana-interface-type; + description + "For all Ethernet-like interfaces, regardless of speed, + as per RFC 3635."; + reference + "RFC 3635 - Definitions of Managed Objects for the + Ethernet-like Interface Types"; + } + identity iso88023Csmacd { + base iana-interface-type; + status deprecated; + description + "Deprecated via RFC 3635. + Use ethernetCsmacd(6) instead."; + reference + "RFC 3635 - Definitions of Managed Objects for the + Ethernet-like Interface Types"; + } + identity iso88024TokenBus { + base iana-interface-type; + } + identity iso88025TokenRing { + base iana-interface-type; + } + identity iso88026Man { + base iana-interface-type; + } + identity starLan { + base iana-interface-type; + status deprecated; + description + "Deprecated via RFC 3635. + Use ethernetCsmacd(6) instead."; + reference + "RFC 3635 - Definitions of Managed Objects for the + Ethernet-like Interface Types"; + } + identity proteon10Mbit { + base iana-interface-type; + } + identity proteon80Mbit { + base iana-interface-type; + } + identity hyperchannel { + base iana-interface-type; + } + identity fddi { + base iana-interface-type; + reference + "RFC 1512 - FDDI Management Information Base"; + } + identity lapb { + base iana-interface-type; + reference + "RFC 1381 - SNMP MIB Extension for X.25 LAPB"; + } + identity sdlc { + base iana-interface-type; + } + identity ds1 { + base iana-interface-type; + description + "DS1-MIB."; + reference + "RFC 4805 - Definitions of Managed Objects for the + DS1, J1, E1, DS2, and E2 Interface Types"; + } + identity e1 { + base iana-interface-type; + status obsolete; + description + "Obsolete; see DS1-MIB."; + reference + "RFC 4805 - Definitions of Managed Objects for the + DS1, J1, E1, DS2, and E2 Interface Types"; + } + identity basicISDN { + base iana-interface-type; + description + "No longer used. See also RFC 2127."; + } + identity primaryISDN { + base iana-interface-type; + description + "No longer used. See also RFC 2127."; + } + identity propPointToPointSerial { + base iana-interface-type; + description + "Proprietary serial."; + } + identity ppp { + base iana-interface-type; + } + identity softwareLoopback { + base iana-interface-type; + } + identity eon { + base iana-interface-type; + description + "CLNP over IP."; + } + identity ethernet3Mbit { + base iana-interface-type; + } + identity nsip { + base iana-interface-type; + description + "XNS over IP."; + } + identity slip { + base iana-interface-type; + description + "Generic SLIP."; + } + identity ultra { + base iana-interface-type; + description + "Ultra Technologies."; + } + identity ds3 { + base iana-interface-type; + description + "DS3-MIB."; + reference + "RFC 3896 - Definitions of Managed Objects for the + DS3/E3 Interface Type"; + } + identity sip { + base iana-interface-type; + description + "SMDS, coffee."; + reference + "RFC 1694 - Definitions of Managed Objects for SMDS + Interfaces using SMIv2"; + } + identity frameRelay { + base iana-interface-type; + description + "DTE only."; + reference + "RFC 2115 - Management Information Base for Frame Relay + DTEs Using SMIv2"; + } + identity rs232 { + base iana-interface-type; + reference + "RFC 1659 - Definitions of Managed Objects for RS-232-like + Hardware Devices using SMIv2"; + } + identity para { + base iana-interface-type; + description + "Parallel-port."; + reference + "RFC 1660 - Definitions of Managed Objects for + Parallel-printer-like Hardware Devices using + SMIv2"; + } + identity arcnet { + base iana-interface-type; + description + "ARCnet."; + } + identity arcnetPlus { + base iana-interface-type; + description + "ARCnet Plus."; + } + identity atm { + base iana-interface-type; + description + "ATM cells."; + } + identity miox25 { + base iana-interface-type; + reference + "RFC 1461 - SNMP MIB extension for Multiprotocol + Interconnect over X.25"; + } + identity sonet { + base iana-interface-type; + description + "SONET or SDH."; + } + identity x25ple { + base iana-interface-type; + reference + "RFC 2127 - ISDN Management Information Base using SMIv2"; + } + identity iso88022llc { + base iana-interface-type; + } + identity localTalk { + base iana-interface-type; + } + identity smdsDxi { + base iana-interface-type; + } + identity frameRelayService { + base iana-interface-type; + description + "FRNETSERV-MIB."; + reference + "RFC 2954 - Definitions of Managed Objects for Frame + Relay Service"; + } + identity v35 { + base iana-interface-type; + } + identity hssi { + base iana-interface-type; + } + identity hippi { + base iana-interface-type; + } + identity modem { + base iana-interface-type; + description + "Generic modem."; + } + identity aal5 { + base iana-interface-type; + description + "AAL5 over ATM."; + } + identity sonetPath { + base iana-interface-type; + } + identity sonetVT { + base iana-interface-type; + } + identity smdsIcip { + base iana-interface-type; + description + "SMDS InterCarrier Interface."; + } + identity propVirtual { + base iana-interface-type; + description + "Proprietary virtual/internal."; + reference + "RFC 2863 - The Interfaces Group MIB"; + } + identity propMultiplexor { + base iana-interface-type; + description + "Proprietary multiplexing."; + reference + "RFC 2863 - The Interfaces Group MIB"; + } + identity ieee80212 { + base iana-interface-type; + description + "100BaseVG."; + } + identity fibreChannel { + base iana-interface-type; + description + "Fibre Channel."; + } + identity hippiInterface { + base iana-interface-type; + description + "HIPPI interfaces."; + } + identity frameRelayInterconnect { + base iana-interface-type; + status obsolete; + description + "Obsolete; use either + frameRelay(32) or frameRelayService(44)."; + } + identity aflane8023 { + base iana-interface-type; + description + "ATM Emulated LAN for 802.3."; + } + identity aflane8025 { + base iana-interface-type; + description + "ATM Emulated LAN for 802.5."; + } + identity cctEmul { + base iana-interface-type; + description + "ATM Emulated circuit."; + } + identity fastEther { + base iana-interface-type; + status deprecated; + description + "Obsoleted via RFC 3635. + ethernetCsmacd(6) should be used instead."; + reference + "RFC 3635 - Definitions of Managed Objects for the + Ethernet-like Interface Types"; + } + identity isdn { + base iana-interface-type; + description + "ISDN and X.25."; + reference + "RFC 1356 - Multiprotocol Interconnect on X.25 and ISDN + in the Packet Mode"; + } + identity v11 { + base iana-interface-type; + description + "CCITT V.11/X.21."; + } + identity v36 { + base iana-interface-type; + description + "CCITT V.36."; + } + identity g703at64k { + base iana-interface-type; + description + "CCITT G703 at 64Kbps."; + } + identity g703at2mb { + base iana-interface-type; + status obsolete; + description + "Obsolete; see DS1-MIB."; + } + identity qllc { + base iana-interface-type; + description + "SNA QLLC."; + } + identity fastEtherFX { + base iana-interface-type; + status deprecated; + description + "Obsoleted via RFC 3635. + ethernetCsmacd(6) should be used instead."; + reference + "RFC 3635 - Definitions of Managed Objects for the + Ethernet-like Interface Types"; + } + identity channel { + base iana-interface-type; + description + "Channel."; + } + identity ieee80211 { + base iana-interface-type; + description + "Radio spread spectrum."; + } + identity ibm370parChan { + base iana-interface-type; + description + "IBM System 360/370 OEMI Channel."; + } + identity escon { + base iana-interface-type; + description + "IBM Enterprise Systems Connection."; + } + identity dlsw { + base iana-interface-type; + description + "Data Link Switching."; + } + identity isdns { + base iana-interface-type; + description + "ISDN S/T interface."; + } + identity isdnu { + base iana-interface-type; + description + "ISDN U interface."; + } + identity lapd { + base iana-interface-type; + description + "Link Access Protocol D."; + } + identity ipSwitch { + base iana-interface-type; + description + "IP Switching Objects."; + } + identity rsrb { + base iana-interface-type; + description + "Remote Source Route Bridging."; + } + identity atmLogical { + base iana-interface-type; + description + "ATM Logical Port."; + reference + "RFC 3606 - Definitions of Supplemental Managed Objects + for ATM Interface"; + } + identity ds0 { + base iana-interface-type; + description + "Digital Signal Level 0."; + reference + "RFC 2494 - Definitions of Managed Objects for the DS0 + and DS0 Bundle Interface Type"; + } + identity ds0Bundle { + base iana-interface-type; + description + "Group of ds0s on the same ds1."; + reference + "RFC 2494 - Definitions of Managed Objects for the DS0 + and DS0 Bundle Interface Type"; + } + identity bsc { + base iana-interface-type; + description + "Bisynchronous Protocol."; + } + identity async { + base iana-interface-type; + description + "Asynchronous Protocol."; + } + identity cnr { + base iana-interface-type; + description + "Combat Net Radio."; + } + identity iso88025Dtr { + base iana-interface-type; + description + "ISO 802.5r DTR."; + } + identity eplrs { + base iana-interface-type; + description + "Ext Pos Loc Report Sys."; + } + identity arap { + base iana-interface-type; + description + "Appletalk Remote Access Protocol."; + } + identity propCnls { + base iana-interface-type; + description + "Proprietary Connectionless Protocol."; + } + identity hostPad { + base iana-interface-type; + description + "CCITT-ITU X.29 PAD Protocol."; + } + identity termPad { + base iana-interface-type; + description + "CCITT-ITU X.3 PAD Facility."; + } + identity frameRelayMPI { + base iana-interface-type; + description + "Multiproto Interconnect over FR."; + } + identity x213 { + base iana-interface-type; + description + "CCITT-ITU X213."; + } + identity adsl { + base iana-interface-type; + description + "Asymmetric Digital Subscriber Loop."; + } + identity radsl { + base iana-interface-type; + description + "Rate-Adapt. Digital Subscriber Loop."; + } + identity sdsl { + base iana-interface-type; + description + "Symmetric Digital Subscriber Loop."; + } + identity vdsl { + base iana-interface-type; + description + "Very H-Speed Digital Subscrib. Loop."; + } + identity iso88025CRFPInt { + base iana-interface-type; + description + "ISO 802.5 CRFP."; + } + identity myrinet { + base iana-interface-type; + description + "Myricom Myrinet."; + } + identity voiceEM { + base iana-interface-type; + description + "Voice recEive and transMit."; + } + identity voiceFXO { + base iana-interface-type; + description + "Voice Foreign Exchange Office."; + } + identity voiceFXS { + base iana-interface-type; + description + "Voice Foreign Exchange Station."; + } + identity voiceEncap { + base iana-interface-type; + description + "Voice encapsulation."; + } + identity voiceOverIp { + base iana-interface-type; + description + "Voice over IP encapsulation."; + } + identity atmDxi { + base iana-interface-type; + description + "ATM DXI."; + } + identity atmFuni { + base iana-interface-type; + description + "ATM FUNI."; + } + identity atmIma { + base iana-interface-type; + description + "ATM IMA."; + } + identity pppMultilinkBundle { + base iana-interface-type; + description + "PPP Multilink Bundle."; + } + identity ipOverCdlc { + base iana-interface-type; + description + "IBM ipOverCdlc."; + } + identity ipOverClaw { + base iana-interface-type; + description + "IBM Common Link Access to Workstn."; + } + identity stackToStack { + base iana-interface-type; + description + "IBM stackToStack."; + } + identity virtualIpAddress { + base iana-interface-type; + description + "IBM VIPA."; + } + identity mpc { + base iana-interface-type; + description + "IBM multi-protocol channel support."; + } + identity ipOverAtm { + base iana-interface-type; + description + "IBM ipOverAtm."; + reference + "RFC 2320 - Definitions of Managed Objects for Classical IP + and ARP Over ATM Using SMIv2 (IPOA-MIB)"; + } + identity iso88025Fiber { + base iana-interface-type; + description + "ISO 802.5j Fiber Token Ring."; + } + identity tdlc { + base iana-interface-type; + description + "IBM twinaxial data link control."; + } + identity gigabitEthernet { + base iana-interface-type; + status deprecated; + description + "Obsoleted via RFC 3635. + ethernetCsmacd(6) should be used instead."; + reference + "RFC 3635 - Definitions of Managed Objects for the + Ethernet-like Interface Types"; + } + identity hdlc { + base iana-interface-type; + description + "HDLC."; + } + identity lapf { + base iana-interface-type; + description + "LAP F."; + } + identity v37 { + base iana-interface-type; + description + "V.37."; + } + identity x25mlp { + base iana-interface-type; + description + "Multi-Link Protocol."; + } + identity x25huntGroup { + base iana-interface-type; + description + "X25 Hunt Group."; + } + identity transpHdlc { + base iana-interface-type; + description + "Transp HDLC."; + } + identity interleave { + base iana-interface-type; + description + "Interleave channel."; + } + identity fast { + base iana-interface-type; + description + "Fast channel."; + } + identity ip { + base iana-interface-type; + description + "IP (for APPN HPR in IP networks)."; + } + identity docsCableMaclayer { + base iana-interface-type; + description + "CATV Mac Layer."; + } + identity docsCableDownstream { + base iana-interface-type; + description + "CATV Downstream interface."; + } + identity docsCableUpstream { + base iana-interface-type; + description + "CATV Upstream interface."; + } + identity a12MppSwitch { + base iana-interface-type; + description + "Avalon Parallel Processor."; + } + identity tunnel { + base iana-interface-type; + description + "Encapsulation interface."; + } + identity coffee { + base iana-interface-type; + description + "Coffee pot."; + reference + "RFC 2325 - Coffee MIB"; + } + identity ces { + base iana-interface-type; + description + "Circuit Emulation Service."; + } + identity atmSubInterface { + base iana-interface-type; + description + "ATM Sub Interface."; + } + identity l2vlan { + base iana-interface-type; + description + "Layer 2 Virtual LAN using 802.1Q."; + } + identity l3ipvlan { + base iana-interface-type; + description + "Layer 3 Virtual LAN using IP."; + } + identity l3ipxvlan { + base iana-interface-type; + description + "Layer 3 Virtual LAN using IPX."; + } + identity digitalPowerline { + base iana-interface-type; + description + "IP over Power Lines."; + } + identity mediaMailOverIp { + base iana-interface-type; + description + "Multimedia Mail over IP."; + } + identity dtm { + base iana-interface-type; + description + "Dynamic synchronous Transfer Mode."; + } + identity dcn { + base iana-interface-type; + description + "Data Communications Network."; + } + identity ipForward { + base iana-interface-type; + description + "IP Forwarding Interface."; + } + identity msdsl { + base iana-interface-type; + description + "Multi-rate Symmetric DSL."; + } + identity ieee1394 { + base iana-interface-type; + + description + "IEEE1394 High Performance Serial Bus."; + } + identity if-gsn { + base iana-interface-type; + description + "HIPPI-6400."; + } + identity dvbRccMacLayer { + base iana-interface-type; + description + "DVB-RCC MAC Layer."; + } + identity dvbRccDownstream { + base iana-interface-type; + description + "DVB-RCC Downstream Channel."; + } + identity dvbRccUpstream { + base iana-interface-type; + description + "DVB-RCC Upstream Channel."; + } + identity atmVirtual { + base iana-interface-type; + description + "ATM Virtual Interface."; + } + identity mplsTunnel { + base iana-interface-type; + description + "MPLS Tunnel Virtual Interface."; + } + identity srp { + base iana-interface-type; + description + "Spatial Reuse Protocol."; + } + identity voiceOverAtm { + base iana-interface-type; + description + "Voice over ATM."; + } + identity voiceOverFrameRelay { + base iana-interface-type; + description + "Voice Over Frame Relay."; + } + identity idsl { + base iana-interface-type; + description + "Digital Subscriber Loop over ISDN."; + } + identity compositeLink { + base iana-interface-type; + description + "Avici Composite Link Interface."; + } + identity ss7SigLink { + base iana-interface-type; + description + "SS7 Signaling Link."; + } + identity propWirelessP2P { + base iana-interface-type; + description + "Prop. P2P wireless interface."; + } + identity frForward { + base iana-interface-type; + description + "Frame Forward Interface."; + } + identity rfc1483 { + base iana-interface-type; + description + "Multiprotocol over ATM AAL5."; + reference + "RFC 1483 - Multiprotocol Encapsulation over ATM + Adaptation Layer 5"; + } + identity usb { + base iana-interface-type; + description + "USB Interface."; + } + identity ieee8023adLag { + base iana-interface-type; + description + "IEEE 802.3ad Link Aggregate."; + } + identity bgppolicyaccounting { + base iana-interface-type; + description + "BGP Policy Accounting."; + } + identity frf16MfrBundle { + base iana-interface-type; + description + "FRF.16 Multilink Frame Relay."; + } + identity h323Gatekeeper { + base iana-interface-type; + description + "H323 Gatekeeper."; + } + identity h323Proxy { + base iana-interface-type; + description + "H323 Voice and Video Proxy."; + } + identity mpls { + base iana-interface-type; + description + "MPLS."; + } + identity mfSigLink { + base iana-interface-type; + description + "Multi-frequency signaling link."; + } + identity hdsl2 { + base iana-interface-type; + description + "High Bit-Rate DSL - 2nd generation."; + } + identity shdsl { + base iana-interface-type; + description + "Multirate HDSL2."; + } + identity ds1FDL { + base iana-interface-type; + description + "Facility Data Link (4Kbps) on a DS1."; + } + identity pos { + base iana-interface-type; + description + "Packet over SONET/SDH Interface."; + } + identity dvbAsiIn { + base iana-interface-type; + description + "DVB-ASI Input."; + } + identity dvbAsiOut { + base iana-interface-type; + description + "DVB-ASI Output."; + } + identity plc { + base iana-interface-type; + description + "Power Line Communications."; + } + identity nfas { + base iana-interface-type; + description + "Non-Facility Associated Signaling."; + } + identity tr008 { + base iana-interface-type; + description + "TR008."; + } + identity gr303RDT { + base iana-interface-type; + description + "Remote Digital Terminal."; + } + identity gr303IDT { + base iana-interface-type; + description + "Integrated Digital Terminal."; + } + identity isup { + base iana-interface-type; + description + "ISUP."; + } + identity propDocsWirelessMaclayer { + base iana-interface-type; + description + "Cisco proprietary Maclayer."; + } + identity propDocsWirelessDownstream { + base iana-interface-type; + description + "Cisco proprietary Downstream."; + } + identity propDocsWirelessUpstream { + base iana-interface-type; + description + "Cisco proprietary Upstream."; + } + identity hiperlan2 { + base iana-interface-type; + description + "HIPERLAN Type 2 Radio Interface."; + } + identity propBWAp2Mp { + base iana-interface-type; + description + "PropBroadbandWirelessAccesspt2Multipt (use of this value + for IEEE 802.16 WMAN interfaces as per IEEE Std 802.16f + is deprecated, and ieee80216WMAN(237) should be used + instead)."; + } + identity sonetOverheadChannel { + base iana-interface-type; + description + "SONET Overhead Channel."; + } + identity digitalWrapperOverheadChannel { + base iana-interface-type; + description + "Digital Wrapper."; + } + identity aal2 { + base iana-interface-type; + description + "ATM adaptation layer 2."; + } + identity radioMAC { + base iana-interface-type; + description + "MAC layer over radio links."; + } + identity atmRadio { + base iana-interface-type; + description + "ATM over radio links."; + } + identity imt { + base iana-interface-type; + description + "Inter-Machine Trunks."; + } + identity mvl { + base iana-interface-type; + description + "Multiple Virtual Lines DSL."; + } + identity reachDSL { + base iana-interface-type; + description + "Long Reach DSL."; + } + identity frDlciEndPt { + base iana-interface-type; + description + "Frame Relay DLCI End Point."; + } + identity atmVciEndPt { + base iana-interface-type; + description + "ATM VCI End Point."; + } + identity opticalChannel { + base iana-interface-type; + description + "Optical Channel."; + } + identity opticalTransport { + base iana-interface-type; + description + "Optical Transport."; + } + identity propAtm { + base iana-interface-type; + description + "Proprietary ATM."; + } + identity voiceOverCable { + base iana-interface-type; + description + "Voice Over Cable Interface."; + } + identity infiniband { + base iana-interface-type; + description + "Infiniband."; + } + identity teLink { + base iana-interface-type; + description + "TE Link."; + } + identity q2931 { + base iana-interface-type; + description + "Q.2931."; + } + identity virtualTg { + base iana-interface-type; + description + "Virtual Trunk Group."; + } + identity sipTg { + base iana-interface-type; + description + "SIP Trunk Group."; + } + identity sipSig { + base iana-interface-type; + description + "SIP Signaling."; + } + identity docsCableUpstreamChannel { + base iana-interface-type; + description + "CATV Upstream Channel."; + } + identity econet { + base iana-interface-type; + description + "Acorn Econet."; + } + identity pon155 { + base iana-interface-type; + description + "FSAN 155Mb Symetrical PON interface."; + } + identity pon622 { + base iana-interface-type; + description + "FSAN 622Mb Symetrical PON interface."; + } + identity bridge { + base iana-interface-type; + description + "Transparent bridge interface."; + } + identity linegroup { + base iana-interface-type; + description + "Interface common to multiple lines."; + } + identity voiceEMFGD { + base iana-interface-type; + description + "Voice E&M Feature Group D."; + } + identity voiceFGDEANA { + base iana-interface-type; + description + "Voice FGD Exchange Access North American."; + } + identity voiceDID { + base iana-interface-type; + description + "Voice Direct Inward Dialing."; + } + identity mpegTransport { + base iana-interface-type; + description + "MPEG transport interface."; + } + identity sixToFour { + base iana-interface-type; + status deprecated; + description + "6to4 interface (DEPRECATED)."; + reference + "RFC 4087 - IP Tunnel MIB"; + } + identity gtp { + base iana-interface-type; + description + "GTP (GPRS Tunneling Protocol)."; + } + identity pdnEtherLoop1 { + base iana-interface-type; + description + "Paradyne EtherLoop 1."; + } + identity pdnEtherLoop2 { + base iana-interface-type; + description + "Paradyne EtherLoop 2."; + } + identity opticalChannelGroup { + base iana-interface-type; + description + "Optical Channel Group."; + } + identity homepna { + base iana-interface-type; + description + "HomePNA ITU-T G.989."; + } + identity gfp { + base iana-interface-type; + description + "Generic Framing Procedure (GFP)."; + } + identity ciscoISLvlan { + base iana-interface-type; + description + "Layer 2 Virtual LAN using Cisco ISL."; + } + identity actelisMetaLOOP { + base iana-interface-type; + description + "Acteleis proprietary MetaLOOP High Speed Link."; + } + identity fcipLink { + base iana-interface-type; + description + "FCIP Link."; + } + identity rpr { + base iana-interface-type; + description + "Resilient Packet Ring Interface Type."; + } + identity qam { + base iana-interface-type; + description + "RF Qam Interface."; + } + identity lmp { + base iana-interface-type; + description + "Link Management Protocol."; + reference + "RFC 4327 - Link Management Protocol (LMP) Management + Information Base (MIB)"; + } + identity cblVectaStar { + base iana-interface-type; + description + "Cambridge Broadband Networks Limited VectaStar."; + } + identity docsCableMCmtsDownstream { + base iana-interface-type; + description + "CATV Modular CMTS Downstream Interface."; + } + identity adsl2 { + base iana-interface-type; + status deprecated; + description + "Asymmetric Digital Subscriber Loop Version 2 + (DEPRECATED/OBSOLETED - please use adsl2plus(238) + instead)."; + reference + "RFC 4706 - Definitions of Managed Objects for Asymmetric + Digital Subscriber Line 2 (ADSL2)"; + } + identity macSecControlledIF { + base iana-interface-type; + description + "MACSecControlled."; + } + identity macSecUncontrolledIF { + base iana-interface-type; + description + "MACSecUncontrolled."; + } + identity aviciOpticalEther { + base iana-interface-type; + description + "Avici Optical Ethernet Aggregate."; + } + identity atmbond { + base iana-interface-type; + description + "atmbond."; + } + identity voiceFGDOS { + base iana-interface-type; + description + "Voice FGD Operator Services."; + } + identity mocaVersion1 { + base iana-interface-type; + description + "MultiMedia over Coax Alliance (MoCA) Interface + as documented in information provided privately to IANA."; + } + identity ieee80216WMAN { + base iana-interface-type; + description + "IEEE 802.16 WMAN interface."; + } + identity adsl2plus { + base iana-interface-type; + description + "Asymmetric Digital Subscriber Loop Version 2 - + Version 2 Plus and all variants."; + } + identity dvbRcsMacLayer { + base iana-interface-type; + description + "DVB-RCS MAC Layer."; + reference + "RFC 5728 - The SatLabs Group DVB-RCS MIB"; + } + identity dvbTdm { + base iana-interface-type; + description + "DVB Satellite TDM."; + reference + "RFC 5728 - The SatLabs Group DVB-RCS MIB"; + } + identity dvbRcsTdma { + base iana-interface-type; + description + "DVB-RCS TDMA."; + reference + "RFC 5728 - The SatLabs Group DVB-RCS MIB"; + } + identity x86Laps { + base iana-interface-type; + description + "LAPS based on ITU-T X.86/Y.1323."; + } + identity wwanPP { + base iana-interface-type; + description + "3GPP WWAN."; + } + identity wwanPP2 { + base iana-interface-type; + description + "3GPP2 WWAN."; + } + identity voiceEBS { + base iana-interface-type; + description + "Voice P-phone EBS physical interface."; + } + identity ifPwType { + base iana-interface-type; + description + "Pseudowire interface type."; + reference + "RFC 5601 - Pseudowire (PW) Management Information Base (MIB)"; + } + identity ilan { + base iana-interface-type; + description + "Internal LAN on a bridge per IEEE 802.1ap."; + } + identity pip { + base iana-interface-type; + description + "Provider Instance Port on a bridge per IEEE 802.1ah PBB."; + } + identity aluELP { + base iana-interface-type; + description + "Alcatel-Lucent Ethernet Link Protection."; + } + identity gpon { + base iana-interface-type; + description + "Gigabit-capable passive optical networks (G-PON) as per + ITU-T G.948."; + } + identity vdsl2 { + base iana-interface-type; + description + "Very high speed digital subscriber line Version 2 + (as per ITU-T Recommendation G.993.2)."; + reference + "RFC 5650 - Definitions of Managed Objects for Very High + Speed Digital Subscriber Line 2 (VDSL2)"; + } + identity capwapDot11Profile { + base iana-interface-type; + description + "WLAN Profile Interface."; + reference + "RFC 5834 - Control and Provisioning of Wireless Access + Points (CAPWAP) Protocol Binding MIB for + IEEE 802.11"; + } + identity capwapDot11Bss { + base iana-interface-type; + description + "WLAN BSS Interface."; + reference + "RFC 5834 - Control and Provisioning of Wireless Access + Points (CAPWAP) Protocol Binding MIB for + IEEE 802.11"; + } + identity capwapWtpVirtualRadio { + base iana-interface-type; + description + "WTP Virtual Radio Interface."; + reference + "RFC 5833 - Control and Provisioning of Wireless Access + Points (CAPWAP) Protocol Base MIB"; + } + identity bits { + base iana-interface-type; + description + "bitsport."; + } + identity docsCableUpstreamRfPort { + base iana-interface-type; + description + "DOCSIS CATV Upstream RF Port."; + } + identity cableDownstreamRfPort { + base iana-interface-type; + description + "CATV downstream RF Port."; + } + identity vmwareVirtualNic { + base iana-interface-type; + description + "VMware Virtual Network Interface."; + } + identity ieee802154 { + base iana-interface-type; + description + "IEEE 802.15.4 WPAN interface."; + reference + "IEEE 802.15.4-2006"; + } + identity otnOdu { + base iana-interface-type; + description + "OTN Optical Data Unit."; + } + identity otnOtu { + base iana-interface-type; + description + "OTN Optical channel Transport Unit."; + } + identity ifVfiType { + base iana-interface-type; + description + "VPLS Forwarding Instance Interface Type."; + } + identity g9981 { + base iana-interface-type; + description + "G.998.1 bonded interface."; + } + identity g9982 { + base iana-interface-type; + description + "G.998.2 bonded interface."; + } + identity g9983 { + base iana-interface-type; + description + "G.998.3 bonded interface."; + } + + identity aluEpon { + base iana-interface-type; + description + "Ethernet Passive Optical Networks (E-PON)."; + } + identity aluEponOnu { + base iana-interface-type; + description + "EPON Optical Network Unit."; + } + identity aluEponPhysicalUni { + base iana-interface-type; + description + "EPON physical User to Network interface."; + } + identity aluEponLogicalLink { + base iana-interface-type; + description + "The emulation of a point-to-point link over the EPON + layer."; + } + identity aluGponOnu { + base iana-interface-type; + description + "GPON Optical Network Unit."; + reference + "ITU-T G.984.2"; + } + identity aluGponPhysicalUni { + base iana-interface-type; + description + "GPON physical User to Network interface."; + reference + "ITU-T G.984.2"; + } + identity vmwareNicTeam { + base iana-interface-type; + description + "VMware NIC Team."; + } + identity docsOfdmDownstream { + base iana-interface-type; + description + "CATV Downstream OFDM interface."; + } + identity docsOfdmaUpstream { + base iana-interface-type; + description + "CATV Upstream OFDMA interface."; + } + identity gfast { + base iana-interface-type; + description + "G.fast port."; + reference + "ITU-T G.9701"; + } + identity sdci { + base iana-interface-type; + description + "SDCI (IO-Link)."; + reference + "IEC 61131-9 Edition 1.0 2013-09"; + } + identity xboxWireless { + base iana-interface-type; + description + "Xbox wireless."; + } + identity fastdsl { + base iana-interface-type; + description + "FastDSL."; + reference + "BBF TR-355"; + } + identity docsCableScte55d1FwdOob { + base iana-interface-type; + description + "Cable SCTE 55-1 OOB Forward Channel."; + } + identity docsCableScte55d1RetOob { + base iana-interface-type; + description + "Cable SCTE 55-1 OOB Return Channel."; + } + identity docsCableScte55d2DsOob { + base iana-interface-type; + description + "Cable SCTE 55-2 OOB Downstream Channel."; + } + identity docsCableScte55d2UsOob { + base iana-interface-type; + description + "Cable SCTE 55-2 OOB Upstream Channel."; + } + identity docsCableNdf { + base iana-interface-type; + description + "Cable Narrowband Digital Forward."; + } + identity docsCableNdr { + base iana-interface-type; + description + "Cable Narrowband Digital Return."; + } + identity ptm { + base iana-interface-type; + description + "Packet Transfer Mode."; + } +} diff --git a/src/confd/yang/ietf-datastores@2018-02-14.yang b/src/confd/yang/ietf-datastores@2018-02-14.yang new file mode 100644 index 00000000..9e875ab6 --- /dev/null +++ b/src/confd/yang/ietf-datastores@2018-02-14.yang @@ -0,0 +1,117 @@ +module ietf-datastores { + yang-version 1.1; + namespace "urn:ietf:params:xml:ns:yang:ietf-datastores"; + prefix ds; + + organization + "IETF Network Modeling (NETMOD) Working Group"; + + contact + "WG Web: + + WG List: + + Author: Martin Bjorklund + + + Author: Juergen Schoenwaelder + + + Author: Phil Shafer + + + Author: Kent Watsen + + + Author: Rob Wilton + "; + + description + "This YANG module defines a set of identities for identifying + datastores. + + Copyright (c) 2018 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject to + the license terms contained in, the Simplified BSD License set + forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (https://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC 8342 + (https://www.rfc-editor.org/info/rfc8342); see the RFC itself + for full legal notices."; + + revision 2018-02-14 { + description + "Initial revision."; + reference + "RFC 8342: Network Management Datastore Architecture (NMDA)"; + } + + /* + * Identities + */ + + identity datastore { + description + "Abstract base identity for datastore identities."; + } + + identity conventional { + base datastore; + description + "Abstract base identity for conventional configuration + datastores."; + } + + identity running { + base conventional; + description + "The running configuration datastore."; + } + + identity candidate { + base conventional; + description + "The candidate configuration datastore."; + } + + identity startup { + base conventional; + description + "The startup configuration datastore."; + } + + identity intended { + base conventional; + description + "The intended configuration datastore."; + } + + identity dynamic { + base datastore; + description + "Abstract base identity for dynamic configuration datastores."; + } + + identity operational { + base datastore; + description + "The operational state datastore."; + } + + /* + * Type definitions + */ + + typedef datastore-ref { + type identityref { + base datastore; + } + description + "A datastore identity reference."; + } +} diff --git a/src/confd/yang/ietf-inet-types@2013-07-15.yang b/src/confd/yang/ietf-inet-types@2013-07-15.yang new file mode 100644 index 00000000..eacefb63 --- /dev/null +++ b/src/confd/yang/ietf-inet-types@2013-07-15.yang @@ -0,0 +1,458 @@ +module ietf-inet-types { + + namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types"; + prefix "inet"; + + organization + "IETF NETMOD (NETCONF Data Modeling Language) Working Group"; + + contact + "WG Web: + WG List: + + WG Chair: David Kessens + + + WG Chair: Juergen Schoenwaelder + + + Editor: Juergen Schoenwaelder + "; + + description + "This module contains a collection of generally useful derived + YANG data types for Internet addresses and related things. + + Copyright (c) 2013 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (http://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC 6991; see + the RFC itself for full legal notices."; + + revision 2013-07-15 { + description + "This revision adds the following new data types: + - ip-address-no-zone + - ipv4-address-no-zone + - ipv6-address-no-zone"; + reference + "RFC 6991: Common YANG Data Types"; + } + + revision 2010-09-24 { + description + "Initial revision."; + reference + "RFC 6021: Common YANG Data Types"; + } + + /*** collection of types related to protocol fields ***/ + + typedef ip-version { + type enumeration { + enum unknown { + value "0"; + description + "An unknown or unspecified version of the Internet + protocol."; + } + enum ipv4 { + value "1"; + description + "The IPv4 protocol as defined in RFC 791."; + } + enum ipv6 { + value "2"; + description + "The IPv6 protocol as defined in RFC 2460."; + } + } + description + "This value represents the version of the IP protocol. + + In the value set and its semantics, this type is equivalent + to the InetVersion textual convention of the SMIv2."; + reference + "RFC 791: Internet Protocol + RFC 2460: Internet Protocol, Version 6 (IPv6) Specification + RFC 4001: Textual Conventions for Internet Network Addresses"; + } + + typedef dscp { + type uint8 { + range "0..63"; + } + description + "The dscp type represents a Differentiated Services Code Point + that may be used for marking packets in a traffic stream. + In the value set and its semantics, this type is equivalent + to the Dscp textual convention of the SMIv2."; + reference + "RFC 3289: Management Information Base for the Differentiated + Services Architecture + RFC 2474: Definition of the Differentiated Services Field + (DS Field) in the IPv4 and IPv6 Headers + RFC 2780: IANA Allocation Guidelines For Values In + the Internet Protocol and Related Headers"; + } + + typedef ipv6-flow-label { + type uint32 { + range "0..1048575"; + } + description + "The ipv6-flow-label type represents the flow identifier or Flow + Label in an IPv6 packet header that may be used to + discriminate traffic flows. + + In the value set and its semantics, this type is equivalent + to the IPv6FlowLabel textual convention of the SMIv2."; + reference + "RFC 3595: Textual Conventions for IPv6 Flow Label + RFC 2460: Internet Protocol, Version 6 (IPv6) Specification"; + } + + typedef port-number { + type uint16 { + range "0..65535"; + } + description + "The port-number type represents a 16-bit port number of an + Internet transport-layer protocol such as UDP, TCP, DCCP, or + SCTP. Port numbers are assigned by IANA. A current list of + all assignments is available from . + + Note that the port number value zero is reserved by IANA. In + situations where the value zero does not make sense, it can + be excluded by subtyping the port-number type. + In the value set and its semantics, this type is equivalent + to the InetPortNumber textual convention of the SMIv2."; + reference + "RFC 768: User Datagram Protocol + RFC 793: Transmission Control Protocol + RFC 4960: Stream Control Transmission Protocol + RFC 4340: Datagram Congestion Control Protocol (DCCP) + RFC 4001: Textual Conventions for Internet Network Addresses"; + } + + /*** collection of types related to autonomous systems ***/ + + typedef as-number { + type uint32; + description + "The as-number type represents autonomous system numbers + which identify an Autonomous System (AS). An AS is a set + of routers under a single technical administration, using + an interior gateway protocol and common metrics to route + packets within the AS, and using an exterior gateway + protocol to route packets to other ASes. IANA maintains + the AS number space and has delegated large parts to the + regional registries. + + Autonomous system numbers were originally limited to 16 + bits. BGP extensions have enlarged the autonomous system + number space to 32 bits. This type therefore uses an uint32 + base type without a range restriction in order to support + a larger autonomous system number space. + + In the value set and its semantics, this type is equivalent + to the InetAutonomousSystemNumber textual convention of + the SMIv2."; + reference + "RFC 1930: Guidelines for creation, selection, and registration + of an Autonomous System (AS) + RFC 4271: A Border Gateway Protocol 4 (BGP-4) + RFC 4001: Textual Conventions for Internet Network Addresses + RFC 6793: BGP Support for Four-Octet Autonomous System (AS) + Number Space"; + } + + /*** collection of types related to IP addresses and hostnames ***/ + + typedef ip-address { + type union { + type inet:ipv4-address; + type inet:ipv6-address; + } + description + "The ip-address type represents an IP address and is IP + version neutral. The format of the textual representation + implies the IP version. This type supports scoped addresses + by allowing zone identifiers in the address format."; + reference + "RFC 4007: IPv6 Scoped Address Architecture"; + } + + typedef ipv4-address { + type string { + pattern + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}' + + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])' + + '(%[\p{N}\p{L}]+)?'; + } + description + "The ipv4-address type represents an IPv4 address in + dotted-quad notation. The IPv4 address may include a zone + index, separated by a % sign. + + The zone index is used to disambiguate identical address + values. For link-local addresses, the zone index will + typically be the interface index number or the name of an + interface. If the zone index is not present, the default + zone of the device will be used. + + The canonical format for the zone index is the numerical + format"; + } + + typedef ipv6-address { + type string { + pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}' + + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|' + + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}' + + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))' + + '(%[\p{N}\p{L}]+)?'; + pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|' + + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)' + + '(%.+)?'; + } + description + "The ipv6-address type represents an IPv6 address in full, + mixed, shortened, and shortened-mixed notation. The IPv6 + address may include a zone index, separated by a % sign. + + The zone index is used to disambiguate identical address + values. For link-local addresses, the zone index will + typically be the interface index number or the name of an + interface. If the zone index is not present, the default + zone of the device will be used. + + The canonical format of IPv6 addresses uses the textual + representation defined in Section 4 of RFC 5952. The + canonical format for the zone index is the numerical + format as described in Section 11.2 of RFC 4007."; + reference + "RFC 4291: IP Version 6 Addressing Architecture + RFC 4007: IPv6 Scoped Address Architecture + RFC 5952: A Recommendation for IPv6 Address Text + Representation"; + } + + typedef ip-address-no-zone { + type union { + type inet:ipv4-address-no-zone; + type inet:ipv6-address-no-zone; + } + description + "The ip-address-no-zone type represents an IP address and is + IP version neutral. The format of the textual representation + implies the IP version. This type does not support scoped + addresses since it does not allow zone identifiers in the + address format."; + reference + "RFC 4007: IPv6 Scoped Address Architecture"; + } + + typedef ipv4-address-no-zone { + type inet:ipv4-address { + pattern '[0-9\.]*'; + } + description + "An IPv4 address without a zone index. This type, derived from + ipv4-address, may be used in situations where the zone is + known from the context and hence no zone index is needed."; + } + + typedef ipv6-address-no-zone { + type inet:ipv6-address { + pattern '[0-9a-fA-F:\.]*'; + } + description + "An IPv6 address without a zone index. This type, derived from + ipv6-address, may be used in situations where the zone is + known from the context and hence no zone index is needed."; + reference + "RFC 4291: IP Version 6 Addressing Architecture + RFC 4007: IPv6 Scoped Address Architecture + RFC 5952: A Recommendation for IPv6 Address Text + Representation"; + } + + typedef ip-prefix { + type union { + type inet:ipv4-prefix; + type inet:ipv6-prefix; + } + description + "The ip-prefix type represents an IP prefix and is IP + version neutral. The format of the textual representations + implies the IP version."; + } + + typedef ipv4-prefix { + type string { + pattern + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}' + + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])' + + '/(([0-9])|([1-2][0-9])|(3[0-2]))'; + } + description + "The ipv4-prefix type represents an IPv4 address prefix. + The prefix length is given by the number following the + slash character and must be less than or equal to 32. + + A prefix length value of n corresponds to an IP address + mask that has n contiguous 1-bits from the most + significant bit (MSB) and all other bits set to 0. + + The canonical format of an IPv4 prefix has all bits of + the IPv4 address set to zero that are not part of the + IPv4 prefix."; + } + + typedef ipv6-prefix { + type string { + pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}' + + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|' + + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}' + + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))' + + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'; + pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|' + + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)' + + '(/.+)'; + } + + description + "The ipv6-prefix type represents an IPv6 address prefix. + The prefix length is given by the number following the + slash character and must be less than or equal to 128. + + A prefix length value of n corresponds to an IP address + mask that has n contiguous 1-bits from the most + significant bit (MSB) and all other bits set to 0. + + The IPv6 address should have all bits that do not belong + to the prefix set to zero. + + The canonical format of an IPv6 prefix has all bits of + the IPv6 address set to zero that are not part of the + IPv6 prefix. Furthermore, the IPv6 address is represented + as defined in Section 4 of RFC 5952."; + reference + "RFC 5952: A Recommendation for IPv6 Address Text + Representation"; + } + + /*** collection of domain name and URI types ***/ + + typedef domain-name { + type string { + pattern + '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*' + + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)' + + '|\.'; + length "1..253"; + } + description + "The domain-name type represents a DNS domain name. The + name SHOULD be fully qualified whenever possible. + + Internet domain names are only loosely specified. Section + 3.5 of RFC 1034 recommends a syntax (modified in Section + 2.1 of RFC 1123). The pattern above is intended to allow + for current practice in domain name use, and some possible + future expansion. It is designed to hold various types of + domain names, including names used for A or AAAA records + (host names) and other records, such as SRV records. Note + that Internet host names have a stricter syntax (described + in RFC 952) than the DNS recommendations in RFCs 1034 and + 1123, and that systems that want to store host names in + schema nodes using the domain-name type are recommended to + adhere to this stricter standard to ensure interoperability. + + The encoding of DNS names in the DNS protocol is limited + to 255 characters. Since the encoding consists of labels + prefixed by a length bytes and there is a trailing NULL + byte, only 253 characters can appear in the textual dotted + notation. + + The description clause of schema nodes using the domain-name + type MUST describe when and how these names are resolved to + IP addresses. Note that the resolution of a domain-name value + may require to query multiple DNS records (e.g., A for IPv4 + and AAAA for IPv6). The order of the resolution process and + which DNS record takes precedence can either be defined + explicitly or may depend on the configuration of the + resolver. + + Domain-name values use the US-ASCII encoding. Their canonical + format uses lowercase US-ASCII characters. Internationalized + domain names MUST be A-labels as per RFC 5890."; + reference + "RFC 952: DoD Internet Host Table Specification + RFC 1034: Domain Names - Concepts and Facilities + RFC 1123: Requirements for Internet Hosts -- Application + and Support + RFC 2782: A DNS RR for specifying the location of services + (DNS SRV) + RFC 5890: Internationalized Domain Names in Applications + (IDNA): Definitions and Document Framework"; + } + + typedef host { + type union { + type inet:ip-address; + type inet:domain-name; + } + description + "The host type represents either an IP address or a DNS + domain name."; + } + + typedef uri { + type string; + description + "The uri type represents a Uniform Resource Identifier + (URI) as defined by STD 66. + + Objects using the uri type MUST be in US-ASCII encoding, + and MUST be normalized as described by RFC 3986 Sections + 6.2.1, 6.2.2.1, and 6.2.2.2. All unnecessary + percent-encoding is removed, and all case-insensitive + characters are set to lowercase except for hexadecimal + digits, which are normalized to uppercase as described in + Section 6.2.2.1. + + The purpose of this normalization is to help provide + unique URIs. Note that this normalization is not + sufficient to provide uniqueness. Two URIs that are + textually distinct after this normalization may still be + equivalent. + + Objects using the uri type may restrict the schemes that + they permit. For example, 'data:' and 'urn:' schemes + might not be appropriate. + + A zero-length URI is not a valid URI. This can be used to + express 'URI absent' where required. + + In the value set and its semantics, this type is equivalent + to the Uri SMIv2 textual convention defined in RFC 5017."; + reference + "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax + RFC 3305: Report from the Joint W3C/IETF URI Planning Interest + Group: Uniform Resource Identifiers (URIs), URLs, + and Uniform Resource Names (URNs): Clarifications + and Recommendations + RFC 5017: MIB Textual Conventions for Uniform Resource + Identifiers (URIs)"; + } + +} diff --git a/src/confd/yang/ietf-interfaces@2018-02-20.yang b/src/confd/yang/ietf-interfaces@2018-02-20.yang new file mode 100644 index 00000000..f66c205c --- /dev/null +++ b/src/confd/yang/ietf-interfaces@2018-02-20.yang @@ -0,0 +1,1123 @@ +module ietf-interfaces { + yang-version 1.1; + namespace "urn:ietf:params:xml:ns:yang:ietf-interfaces"; + prefix if; + + import ietf-yang-types { + prefix yang; + } + + organization + "IETF NETMOD (Network Modeling) Working Group"; + + contact + "WG Web: + WG List: + + Editor: Martin Bjorklund + "; + + description + "This module contains a collection of YANG definitions for + managing network interfaces. + + Copyright (c) 2018 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (https://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC 8343; see + the RFC itself for full legal notices."; + + revision 2018-02-20 { + description + "Updated to support NMDA."; + reference + "RFC 8343: A YANG Data Model for Interface Management"; + } + + revision 2014-05-08 { + description + "Initial revision."; + reference + "RFC 7223: A YANG Data Model for Interface Management"; + } + + /* + * Typedefs + */ + + typedef interface-ref { + type leafref { + path "/if:interfaces/if:interface/if:name"; + } + description + "This type is used by data models that need to reference + interfaces."; + } + + /* + * Identities + */ + + identity interface-type { + description + "Base identity from which specific interface types are + derived."; + } + + /* + * Features + */ + + feature arbitrary-names { + description + "This feature indicates that the device allows user-controlled + interfaces to be named arbitrarily."; + } + feature pre-provisioning { + description + "This feature indicates that the device supports + pre-provisioning of interface configuration, i.e., it is + possible to configure an interface whose physical interface + hardware is not present on the device."; + } + feature if-mib { + description + "This feature indicates that the device implements + the IF-MIB."; + reference + "RFC 2863: The Interfaces Group MIB"; + } + + /* + * Data nodes + */ + + container interfaces { + description + "Interface parameters."; + + list interface { + key "name"; + + description + "The list of interfaces on the device. + + The status of an interface is available in this list in the + operational state. If the configuration of a + system-controlled interface cannot be used by the system + (e.g., the interface hardware present does not match the + interface type), then the configuration is not applied to + the system-controlled interface shown in the operational + state. If the configuration of a user-controlled interface + cannot be used by the system, the configured interface is + not instantiated in the operational state. + + System-controlled interfaces created by the system are + always present in this list in the operational state, + whether or not they are configured."; + + leaf name { + type string; + description + "The name of the interface. + + A device MAY restrict the allowed values for this leaf, + possibly depending on the type of the interface. + For system-controlled interfaces, this leaf is the + device-specific name of the interface. + + If a client tries to create configuration for a + system-controlled interface that is not present in the + operational state, the server MAY reject the request if + the implementation does not support pre-provisioning of + interfaces or if the name refers to an interface that can + never exist in the system. A Network Configuration + Protocol (NETCONF) server MUST reply with an rpc-error + with the error-tag 'invalid-value' in this case. + + If the device supports pre-provisioning of interface + configuration, the 'pre-provisioning' feature is + advertised. + + If the device allows arbitrarily named user-controlled + interfaces, the 'arbitrary-names' feature is advertised. + + When a configured user-controlled interface is created by + the system, it is instantiated with the same name in the + operational state. + + A server implementation MAY map this leaf to the ifName + MIB object. Such an implementation needs to use some + mechanism to handle the differences in size and characters + allowed between this leaf and ifName. The definition of + such a mechanism is outside the scope of this document."; + reference + "RFC 2863: The Interfaces Group MIB - ifName"; + } + + leaf description { + type string; + description + "A textual description of the interface. + + A server implementation MAY map this leaf to the ifAlias + MIB object. Such an implementation needs to use some + mechanism to handle the differences in size and characters + allowed between this leaf and ifAlias. The definition of + such a mechanism is outside the scope of this document. + + Since ifAlias is defined to be stored in non-volatile + storage, the MIB implementation MUST map ifAlias to the + value of 'description' in the persistently stored + configuration."; + reference + "RFC 2863: The Interfaces Group MIB - ifAlias"; + } + + leaf type { + type identityref { + base interface-type; + } + mandatory true; + description + "The type of the interface. + + When an interface entry is created, a server MAY + initialize the type leaf with a valid value, e.g., if it + is possible to derive the type from the name of the + interface. + + If a client tries to set the type of an interface to a + value that can never be used by the system, e.g., if the + type is not supported or if the type does not match the + name of the interface, the server MUST reject the request. + A NETCONF server MUST reply with an rpc-error with the + error-tag 'invalid-value' in this case."; + reference + "RFC 2863: The Interfaces Group MIB - ifType"; + } + + leaf enabled { + type boolean; + default "true"; + description + "This leaf contains the configured, desired state of the + interface. + + Systems that implement the IF-MIB use the value of this + leaf in the intended configuration to set + IF-MIB.ifAdminStatus to 'up' or 'down' after an ifEntry + has been initialized, as described in RFC 2863. + + Changes in this leaf in the intended configuration are + reflected in ifAdminStatus."; + reference + "RFC 2863: The Interfaces Group MIB - ifAdminStatus"; + } + + leaf link-up-down-trap-enable { + if-feature if-mib; + type enumeration { + enum enabled { + value 1; + description + "The device will generate linkUp/linkDown SNMP + notifications for this interface."; + } + enum disabled { + value 2; + description + "The device will not generate linkUp/linkDown SNMP + notifications for this interface."; + } + } + description + "Controls whether linkUp/linkDown SNMP notifications + should be generated for this interface. + + If this node is not configured, the value 'enabled' is + operationally used by the server for interfaces that do + not operate on top of any other interface (i.e., there are + no 'lower-layer-if' entries), and 'disabled' otherwise."; + reference + "RFC 2863: The Interfaces Group MIB - + ifLinkUpDownTrapEnable"; + } + + leaf admin-status { + if-feature if-mib; + type enumeration { + enum up { + value 1; + description + "Ready to pass packets."; + } + enum down { + value 2; + description + "Not ready to pass packets and not in some test mode."; + } + enum testing { + value 3; + description + "In some test mode."; + } + } + config false; + mandatory true; + description + "The desired state of the interface. + + This leaf has the same read semantics as ifAdminStatus."; + reference + "RFC 2863: The Interfaces Group MIB - ifAdminStatus"; + } + + leaf oper-status { + type enumeration { + enum up { + value 1; + description + "Ready to pass packets."; + } + enum down { + value 2; + + description + "The interface does not pass any packets."; + } + enum testing { + value 3; + description + "In some test mode. No operational packets can + be passed."; + } + enum unknown { + value 4; + description + "Status cannot be determined for some reason."; + } + enum dormant { + value 5; + description + "Waiting for some external event."; + } + enum not-present { + value 6; + description + "Some component (typically hardware) is missing."; + } + enum lower-layer-down { + value 7; + description + "Down due to state of lower-layer interface(s)."; + } + } + config false; + mandatory true; + description + "The current operational state of the interface. + + This leaf has the same semantics as ifOperStatus."; + reference + "RFC 2863: The Interfaces Group MIB - ifOperStatus"; + } + + leaf last-change { + type yang:date-and-time; + config false; + description + "The time the interface entered its current operational + state. If the current state was entered prior to the + last re-initialization of the local network management + subsystem, then this node is not present."; + reference + "RFC 2863: The Interfaces Group MIB - ifLastChange"; + } + + leaf if-index { + if-feature if-mib; + type int32 { + range "1..2147483647"; + } + config false; + mandatory true; + description + "The ifIndex value for the ifEntry represented by this + interface."; + reference + "RFC 2863: The Interfaces Group MIB - ifIndex"; + } + + leaf phys-address { + type yang:phys-address; + config false; + description + "The interface's address at its protocol sub-layer. For + example, for an 802.x interface, this object normally + contains a Media Access Control (MAC) address. The + interface's media-specific modules must define the bit + and byte ordering and the format of the value of this + object. For interfaces that do not have such an address + (e.g., a serial line), this node is not present."; + reference + "RFC 2863: The Interfaces Group MIB - ifPhysAddress"; + } + + leaf-list higher-layer-if { + type interface-ref; + config false; + description + "A list of references to interfaces layered on top of this + interface."; + reference + "RFC 2863: The Interfaces Group MIB - ifStackTable"; + } + + leaf-list lower-layer-if { + type interface-ref; + config false; + + description + "A list of references to interfaces layered underneath this + interface."; + reference + "RFC 2863: The Interfaces Group MIB - ifStackTable"; + } + + leaf speed { + type yang:gauge64; + units "bits/second"; + config false; + description + "An estimate of the interface's current bandwidth in bits + per second. For interfaces that do not vary in + bandwidth or for those where no accurate estimation can + be made, this node should contain the nominal bandwidth. + For interfaces that have no concept of bandwidth, this + node is not present."; + reference + "RFC 2863: The Interfaces Group MIB - + ifSpeed, ifHighSpeed"; + } + + container statistics { + config false; + description + "A collection of interface-related statistics objects."; + + leaf discontinuity-time { + type yang:date-and-time; + mandatory true; + description + "The time on the most recent occasion at which any one or + more of this interface's counters suffered a + discontinuity. If no such discontinuities have occurred + since the last re-initialization of the local management + subsystem, then this node contains the time the local + management subsystem re-initialized itself."; + } + + leaf in-octets { + type yang:counter64; + description + "The total number of octets received on the interface, + including framing characters. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCInOctets"; + } + + leaf in-unicast-pkts { + type yang:counter64; + description + "The number of packets, delivered by this sub-layer to a + higher (sub-)layer, that were not addressed to a + multicast or broadcast address at this sub-layer. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCInUcastPkts"; + } + + leaf in-broadcast-pkts { + type yang:counter64; + description + "The number of packets, delivered by this sub-layer to a + higher (sub-)layer, that were addressed to a broadcast + address at this sub-layer. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCInBroadcastPkts"; + } + + leaf in-multicast-pkts { + type yang:counter64; + description + "The number of packets, delivered by this sub-layer to a + higher (sub-)layer, that were addressed to a multicast + address at this sub-layer. For a MAC-layer protocol, + this includes both Group and Functional addresses. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCInMulticastPkts"; + } + + leaf in-discards { + type yang:counter32; + description + "The number of inbound packets that were chosen to be + discarded even though no errors had been detected to + prevent their being deliverable to a higher-layer + protocol. One possible reason for discarding such a + packet could be to free up buffer space. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifInDiscards"; + } + + leaf in-errors { + type yang:counter32; + description + "For packet-oriented interfaces, the number of inbound + packets that contained errors preventing them from being + deliverable to a higher-layer protocol. For character- + oriented or fixed-length interfaces, the number of + inbound transmission units that contained errors + preventing them from being deliverable to a higher-layer + protocol. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifInErrors"; + } + + leaf in-unknown-protos { + type yang:counter32; + + description + "For packet-oriented interfaces, the number of packets + received via the interface that were discarded because + of an unknown or unsupported protocol. For + character-oriented or fixed-length interfaces that + support protocol multiplexing, the number of + transmission units received via the interface that were + discarded because of an unknown or unsupported protocol. + For any interface that does not support protocol + multiplexing, this counter is not present. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifInUnknownProtos"; + } + + leaf out-octets { + type yang:counter64; + description + "The total number of octets transmitted out of the + interface, including framing characters. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCOutOctets"; + } + + leaf out-unicast-pkts { + type yang:counter64; + description + "The total number of packets that higher-level protocols + requested be transmitted and that were not addressed + to a multicast or broadcast address at this sub-layer, + including those that were discarded or not sent. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCOutUcastPkts"; + } + + leaf out-broadcast-pkts { + type yang:counter64; + description + "The total number of packets that higher-level protocols + requested be transmitted and that were addressed to a + broadcast address at this sub-layer, including those + that were discarded or not sent. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCOutBroadcastPkts"; + } + + leaf out-multicast-pkts { + type yang:counter64; + description + "The total number of packets that higher-level protocols + requested be transmitted and that were addressed to a + multicast address at this sub-layer, including those + that were discarded or not sent. For a MAC-layer + protocol, this includes both Group and Functional + addresses. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCOutMulticastPkts"; + } + + leaf out-discards { + type yang:counter32; + description + "The number of outbound packets that were chosen to be + discarded even though no errors had been detected to + prevent their being transmitted. One possible reason + for discarding such a packet could be to free up buffer + space. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifOutDiscards"; + } + + leaf out-errors { + type yang:counter32; + description + "For packet-oriented interfaces, the number of outbound + packets that could not be transmitted because of errors. + For character-oriented or fixed-length interfaces, the + number of outbound transmission units that could not be + transmitted because of errors. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifOutErrors"; + } + } + + } + } + + /* + * Legacy typedefs + */ + + typedef interface-state-ref { + type leafref { + path "/if:interfaces-state/if:interface/if:name"; + } + status deprecated; + description + "This type is used by data models that need to reference + the operationally present interfaces."; + } + + /* + * Legacy operational state data nodes + */ + + container interfaces-state { + config false; + status deprecated; + description + "Data nodes for the operational state of interfaces."; + + list interface { + key "name"; + status deprecated; + + description + "The list of interfaces on the device. + + System-controlled interfaces created by the system are + always present in this list, whether or not they are + configured."; + + leaf name { + type string; + status deprecated; + description + "The name of the interface. + + A server implementation MAY map this leaf to the ifName + MIB object. Such an implementation needs to use some + mechanism to handle the differences in size and characters + allowed between this leaf and ifName. The definition of + such a mechanism is outside the scope of this document."; + reference + "RFC 2863: The Interfaces Group MIB - ifName"; + } + + leaf type { + type identityref { + base interface-type; + } + mandatory true; + status deprecated; + description + "The type of the interface."; + reference + "RFC 2863: The Interfaces Group MIB - ifType"; + } + + leaf admin-status { + if-feature if-mib; + type enumeration { + enum up { + value 1; + description + "Ready to pass packets."; + } + enum down { + value 2; + description + "Not ready to pass packets and not in some test mode."; + } + enum testing { + value 3; + description + "In some test mode."; + } + } + mandatory true; + status deprecated; + description + "The desired state of the interface. + + This leaf has the same read semantics as ifAdminStatus."; + reference + "RFC 2863: The Interfaces Group MIB - ifAdminStatus"; + } + + leaf oper-status { + type enumeration { + enum up { + value 1; + description + "Ready to pass packets."; + } + enum down { + value 2; + description + "The interface does not pass any packets."; + } + enum testing { + value 3; + description + "In some test mode. No operational packets can + be passed."; + } + enum unknown { + value 4; + description + "Status cannot be determined for some reason."; + } + enum dormant { + value 5; + description + "Waiting for some external event."; + } + enum not-present { + value 6; + description + "Some component (typically hardware) is missing."; + } + enum lower-layer-down { + value 7; + description + "Down due to state of lower-layer interface(s)."; + } + } + mandatory true; + status deprecated; + description + "The current operational state of the interface. + + This leaf has the same semantics as ifOperStatus."; + reference + "RFC 2863: The Interfaces Group MIB - ifOperStatus"; + } + + leaf last-change { + type yang:date-and-time; + status deprecated; + description + "The time the interface entered its current operational + state. If the current state was entered prior to the + last re-initialization of the local network management + subsystem, then this node is not present."; + reference + "RFC 2863: The Interfaces Group MIB - ifLastChange"; + } + + leaf if-index { + if-feature if-mib; + type int32 { + range "1..2147483647"; + } + mandatory true; + status deprecated; + description + "The ifIndex value for the ifEntry represented by this + interface."; + + reference + "RFC 2863: The Interfaces Group MIB - ifIndex"; + } + + leaf phys-address { + type yang:phys-address; + status deprecated; + description + "The interface's address at its protocol sub-layer. For + example, for an 802.x interface, this object normally + contains a Media Access Control (MAC) address. The + interface's media-specific modules must define the bit + and byte ordering and the format of the value of this + object. For interfaces that do not have such an address + (e.g., a serial line), this node is not present."; + reference + "RFC 2863: The Interfaces Group MIB - ifPhysAddress"; + } + + leaf-list higher-layer-if { + type interface-state-ref; + status deprecated; + description + "A list of references to interfaces layered on top of this + interface."; + reference + "RFC 2863: The Interfaces Group MIB - ifStackTable"; + } + + leaf-list lower-layer-if { + type interface-state-ref; + status deprecated; + description + "A list of references to interfaces layered underneath this + interface."; + reference + "RFC 2863: The Interfaces Group MIB - ifStackTable"; + } + + leaf speed { + type yang:gauge64; + units "bits/second"; + status deprecated; + description + "An estimate of the interface's current bandwidth in bits + per second. For interfaces that do not vary in + bandwidth or for those where no accurate estimation can + + be made, this node should contain the nominal bandwidth. + For interfaces that have no concept of bandwidth, this + node is not present."; + reference + "RFC 2863: The Interfaces Group MIB - + ifSpeed, ifHighSpeed"; + } + + container statistics { + status deprecated; + description + "A collection of interface-related statistics objects."; + + leaf discontinuity-time { + type yang:date-and-time; + mandatory true; + status deprecated; + description + "The time on the most recent occasion at which any one or + more of this interface's counters suffered a + discontinuity. If no such discontinuities have occurred + since the last re-initialization of the local management + subsystem, then this node contains the time the local + management subsystem re-initialized itself."; + } + + leaf in-octets { + type yang:counter64; + status deprecated; + description + "The total number of octets received on the interface, + including framing characters. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCInOctets"; + } + + leaf in-unicast-pkts { + type yang:counter64; + status deprecated; + description + "The number of packets, delivered by this sub-layer to a + higher (sub-)layer, that were not addressed to a + multicast or broadcast address at this sub-layer. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCInUcastPkts"; + } + + leaf in-broadcast-pkts { + type yang:counter64; + status deprecated; + description + "The number of packets, delivered by this sub-layer to a + higher (sub-)layer, that were addressed to a broadcast + address at this sub-layer. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCInBroadcastPkts"; + } + + leaf in-multicast-pkts { + type yang:counter64; + status deprecated; + description + "The number of packets, delivered by this sub-layer to a + higher (sub-)layer, that were addressed to a multicast + address at this sub-layer. For a MAC-layer protocol, + this includes both Group and Functional addresses. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCInMulticastPkts"; + } + + leaf in-discards { + type yang:counter32; + status deprecated; + + description + "The number of inbound packets that were chosen to be + discarded even though no errors had been detected to + prevent their being deliverable to a higher-layer + protocol. One possible reason for discarding such a + packet could be to free up buffer space. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifInDiscards"; + } + + leaf in-errors { + type yang:counter32; + status deprecated; + description + "For packet-oriented interfaces, the number of inbound + packets that contained errors preventing them from being + deliverable to a higher-layer protocol. For character- + oriented or fixed-length interfaces, the number of + inbound transmission units that contained errors + preventing them from being deliverable to a higher-layer + protocol. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifInErrors"; + } + + leaf in-unknown-protos { + type yang:counter32; + status deprecated; + description + "For packet-oriented interfaces, the number of packets + received via the interface that were discarded because + of an unknown or unsupported protocol. For + character-oriented or fixed-length interfaces that + support protocol multiplexing, the number of + transmission units received via the interface that were + discarded because of an unknown or unsupported protocol. + For any interface that does not support protocol + multiplexing, this counter is not present. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifInUnknownProtos"; + } + + leaf out-octets { + type yang:counter64; + status deprecated; + description + "The total number of octets transmitted out of the + interface, including framing characters. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCOutOctets"; + } + + leaf out-unicast-pkts { + type yang:counter64; + status deprecated; + description + "The total number of packets that higher-level protocols + requested be transmitted and that were not addressed + to a multicast or broadcast address at this sub-layer, + including those that were discarded or not sent. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCOutUcastPkts"; + } + + leaf out-broadcast-pkts { + type yang:counter64; + status deprecated; + + description + "The total number of packets that higher-level protocols + requested be transmitted and that were addressed to a + broadcast address at this sub-layer, including those + that were discarded or not sent. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCOutBroadcastPkts"; + } + + leaf out-multicast-pkts { + type yang:counter64; + status deprecated; + description + "The total number of packets that higher-level protocols + requested be transmitted and that were addressed to a + multicast address at this sub-layer, including those + that were discarded or not sent. For a MAC-layer + protocol, this includes both Group and Functional + addresses. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCOutMulticastPkts"; + } + + leaf out-discards { + type yang:counter32; + status deprecated; + description + "The number of outbound packets that were chosen to be + discarded even though no errors had been detected to + prevent their being transmitted. One possible reason + for discarding such a packet could be to free up buffer + space. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifOutDiscards"; + } + + leaf out-errors { + type yang:counter32; + status deprecated; + description + "For packet-oriented interfaces, the number of outbound + packets that could not be transmitted because of errors. + For character-oriented or fixed-length interfaces, the + number of outbound transmission units that could not be + transmitted because of errors. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifOutErrors"; + } + } + } + } +} diff --git a/src/confd/yang/ietf-ip@2018-02-22.yang b/src/confd/yang/ietf-ip@2018-02-22.yang new file mode 100644 index 00000000..a270f67b --- /dev/null +++ b/src/confd/yang/ietf-ip@2018-02-22.yang @@ -0,0 +1,876 @@ +module ietf-ip { + yang-version 1.1; + namespace "urn:ietf:params:xml:ns:yang:ietf-ip"; + prefix ip; + + import ietf-interfaces { + prefix if; + } + import ietf-inet-types { + prefix inet; + } + import ietf-yang-types { + prefix yang; + } + + organization + "IETF NETMOD (Network Modeling) Working Group"; + + contact + "WG Web: + WG List: + + Editor: Martin Bjorklund + "; + description + "This module contains a collection of YANG definitions for + managing IP implementations. + + Copyright (c) 2018 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (https://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC 8344; see + the RFC itself for full legal notices."; + + revision 2018-02-22 { + description + "Updated to support NMDA."; + reference + "RFC 8344: A YANG Data Model for IP Management"; + } + + revision 2014-06-16 { + description + "Initial revision."; + reference + "RFC 7277: A YANG Data Model for IP Management"; + } + + /* + * Features + */ + + feature ipv4-non-contiguous-netmasks { + description + "Indicates support for configuring non-contiguous + subnet masks."; + } + + feature ipv6-privacy-autoconf { + description + "Indicates support for privacy extensions for stateless address + autoconfiguration in IPv6."; + reference + "RFC 4941: Privacy Extensions for Stateless Address + Autoconfiguration in IPv6"; + } + + /* + * Typedefs + */ + + typedef ip-address-origin { + type enumeration { + enum other { + description + "None of the following."; + } + + enum static { + description + "Indicates that the address has been statically + configured -- for example, using the Network Configuration + Protocol (NETCONF) or a command line interface."; + } + enum dhcp { + description + "Indicates an address that has been assigned to this + system by a DHCP server."; + } + enum link-layer { + description + "Indicates an address created by IPv6 stateless + autoconfiguration that embeds a link-layer address in its + interface identifier."; + } + enum random { + description + "Indicates an address chosen by the system at + random, e.g., an IPv4 address within 169.254/16, a + temporary address as described in RFC 4941, or a + semantically opaque address as described in RFC 7217."; + reference + "RFC 4941: Privacy Extensions for Stateless Address + Autoconfiguration in IPv6 + RFC 7217: A Method for Generating Semantically Opaque + Interface Identifiers with IPv6 Stateless + Address Autoconfiguration (SLAAC)"; + } + } + description + "The origin of an address."; + } + + typedef neighbor-origin { + type enumeration { + enum other { + description + "None of the following."; + } + enum static { + description + "Indicates that the mapping has been statically + configured -- for example, using NETCONF or a command line + interface."; + } + + enum dynamic { + description + "Indicates that the mapping has been dynamically resolved + using, for example, IPv4 ARP or the IPv6 Neighbor + Discovery protocol."; + } + } + description + "The origin of a neighbor entry."; + } + + /* + * Data nodes + */ + + augment "/if:interfaces/if:interface" { + description + "IP parameters on interfaces. + + If an interface is not capable of running IP, the server + must not allow the client to configure these parameters."; + + container ipv4 { + presence + "Enables IPv4 unless the 'enabled' leaf + (which defaults to 'true') is set to 'false'"; + description + "Parameters for the IPv4 address family."; + + leaf enabled { + type boolean; + default true; + description + "Controls whether IPv4 is enabled or disabled on this + interface. When IPv4 is enabled, this interface is + connected to an IPv4 stack, and the interface can send + and receive IPv4 packets."; + } + leaf forwarding { + type boolean; + default false; + description + "Controls IPv4 packet forwarding of datagrams received by, + but not addressed to, this interface. IPv4 routers + forward datagrams. IPv4 hosts do not (except those + source-routed via the host)."; + } + + leaf mtu { + type uint16 { + range "68..max"; + } + units "octets"; + description + "The size, in octets, of the largest IPv4 packet that the + interface will send and receive. + + The server may restrict the allowed values for this leaf, + depending on the interface's type. + + If this leaf is not configured, the operationally used MTU + depends on the interface's type."; + reference + "RFC 791: Internet Protocol"; + } + list address { + key "ip"; + description + "The list of IPv4 addresses on the interface."; + + leaf ip { + type inet:ipv4-address-no-zone; + description + "The IPv4 address on the interface."; + } + choice subnet { + mandatory true; + description + "The subnet can be specified as a prefix length or, + if the server supports non-contiguous netmasks, as + a netmask."; + leaf prefix-length { + type uint8 { + range "0..32"; + } + description + "The length of the subnet prefix."; + } + leaf netmask { + if-feature ipv4-non-contiguous-netmasks; + type yang:dotted-quad; + description + "The subnet specified as a netmask."; + } + } + + leaf origin { + type ip-address-origin; + config false; + description + "The origin of this address."; + } + } + list neighbor { + key "ip"; + description + "A list of mappings from IPv4 addresses to + link-layer addresses. + + Entries in this list in the intended configuration are + used as static entries in the ARP Cache. + + In the operational state, this list represents the ARP + Cache."; + reference + "RFC 826: An Ethernet Address Resolution Protocol"; + + leaf ip { + type inet:ipv4-address-no-zone; + description + "The IPv4 address of the neighbor node."; + } + leaf link-layer-address { + type yang:phys-address; + mandatory true; + description + "The link-layer address of the neighbor node."; + } + leaf origin { + type neighbor-origin; + config false; + description + "The origin of this neighbor entry."; + } + } + } + + container ipv6 { + presence + "Enables IPv6 unless the 'enabled' leaf + (which defaults to 'true') is set to 'false'"; + description + "Parameters for the IPv6 address family."; + + leaf enabled { + type boolean; + default true; + description + "Controls whether IPv6 is enabled or disabled on this + interface. When IPv6 is enabled, this interface is + connected to an IPv6 stack, and the interface can send + and receive IPv6 packets."; + } + leaf forwarding { + type boolean; + default false; + description + "Controls IPv6 packet forwarding of datagrams received by, + but not addressed to, this interface. IPv6 routers + forward datagrams. IPv6 hosts do not (except those + source-routed via the host)."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) + Section 6.2.1, IsRouter"; + } + leaf mtu { + type uint32 { + range "1280..max"; + } + units "octets"; + description + "The size, in octets, of the largest IPv6 packet that the + interface will send and receive. + + The server may restrict the allowed values for this leaf, + depending on the interface's type. + + If this leaf is not configured, the operationally used MTU + depends on the interface's type."; + reference + "RFC 8200: Internet Protocol, Version 6 (IPv6) + Specification + Section 5"; + } + + list address { + key "ip"; + description + "The list of IPv6 addresses on the interface."; + + leaf ip { + type inet:ipv6-address-no-zone; + description + "The IPv6 address on the interface."; + } + leaf prefix-length { + type uint8 { + range "0..128"; + } + mandatory true; + description + "The length of the subnet prefix."; + } + leaf origin { + type ip-address-origin; + config false; + description + "The origin of this address."; + } + leaf status { + type enumeration { + enum preferred { + description + "This is a valid address that can appear as the + destination or source address of a packet."; + } + enum deprecated { + description + "This is a valid but deprecated address that should + no longer be used as a source address in new + communications, but packets addressed to such an + address are processed as expected."; + } + enum invalid { + description + "This isn't a valid address, and it shouldn't appear + as the destination or source address of a packet."; + } + + enum inaccessible { + description + "The address is not accessible because the interface + to which this address is assigned is not + operational."; + } + enum unknown { + description + "The status cannot be determined for some reason."; + } + enum tentative { + description + "The uniqueness of the address on the link is being + verified. Addresses in this state should not be + used for general communication and should only be + used to determine the uniqueness of the address."; + } + enum duplicate { + description + "The address has been determined to be non-unique on + the link and so must not be used."; + } + enum optimistic { + description + "The address is available for use, subject to + restrictions, while its uniqueness on a link is + being verified."; + } + } + config false; + description + "The status of an address. Most of the states correspond + to states from the IPv6 Stateless Address + Autoconfiguration protocol."; + reference + "RFC 4293: Management Information Base for the + Internet Protocol (IP) + - IpAddressStatusTC + RFC 4862: IPv6 Stateless Address Autoconfiguration"; + } + } + + list neighbor { + key "ip"; + description + "A list of mappings from IPv6 addresses to + link-layer addresses. + + Entries in this list in the intended configuration are + used as static entries in the Neighbor Cache. + + In the operational state, this list represents the + Neighbor Cache."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 (IPv6)"; + + leaf ip { + type inet:ipv6-address-no-zone; + description + "The IPv6 address of the neighbor node."; + } + leaf link-layer-address { + type yang:phys-address; + mandatory true; + description + "The link-layer address of the neighbor node. + + In the operational state, if the neighbor's 'state' leaf + is 'incomplete', this leaf is not instantiated."; + } + leaf origin { + type neighbor-origin; + config false; + description + "The origin of this neighbor entry."; + } + leaf is-router { + type empty; + config false; + description + "Indicates that the neighbor node acts as a router."; + } + + leaf state { + type enumeration { + enum incomplete { + description + "Address resolution is in progress, and the + link-layer address of the neighbor has not yet been + determined."; + } + enum reachable { + description + "Roughly speaking, the neighbor is known to have been + reachable recently (within tens of seconds ago)."; + } + enum stale { + description + "The neighbor is no longer known to be reachable, but + until traffic is sent to the neighbor no attempt + should be made to verify its reachability."; + } + enum delay { + description + "The neighbor is no longer known to be reachable, and + traffic has recently been sent to the neighbor. + Rather than probe the neighbor immediately, however, + delay sending probes for a short while in order to + give upper-layer protocols a chance to provide + reachability confirmation."; + } + enum probe { + description + "The neighbor is no longer known to be reachable, and + unicast Neighbor Solicitation probes are being sent + to verify reachability."; + } + } + config false; + description + "The Neighbor Unreachability Detection state of this + entry."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) + Section 7.3.2"; + } + } + + leaf dup-addr-detect-transmits { + type uint32; + default 1; + description + "The number of consecutive Neighbor Solicitation messages + sent while performing Duplicate Address Detection on a + tentative address. A value of zero indicates that + Duplicate Address Detection is not performed on + tentative addresses. A value of one indicates a single + transmission with no follow-up retransmissions."; + reference + "RFC 4862: IPv6 Stateless Address Autoconfiguration"; + } + container autoconf { + description + "Parameters to control the autoconfiguration of IPv6 + addresses, as described in RFC 4862."; + reference + "RFC 4862: IPv6 Stateless Address Autoconfiguration"; + + leaf create-global-addresses { + type boolean; + default true; + description + "If enabled, the host creates global addresses as + described in RFC 4862."; + reference + "RFC 4862: IPv6 Stateless Address Autoconfiguration + Section 5.5"; + } + leaf create-temporary-addresses { + if-feature ipv6-privacy-autoconf; + type boolean; + default false; + description + "If enabled, the host creates temporary addresses as + described in RFC 4941."; + reference + "RFC 4941: Privacy Extensions for Stateless Address + Autoconfiguration in IPv6"; + } + + leaf temporary-valid-lifetime { + if-feature ipv6-privacy-autoconf; + type uint32; + units "seconds"; + default 604800; + description + "The time period during which the temporary address + is valid."; + reference + "RFC 4941: Privacy Extensions for Stateless Address + Autoconfiguration in IPv6 + - TEMP_VALID_LIFETIME"; + } + leaf temporary-preferred-lifetime { + if-feature ipv6-privacy-autoconf; + type uint32; + units "seconds"; + default 86400; + description + "The time period during which the temporary address is + preferred."; + reference + "RFC 4941: Privacy Extensions for Stateless Address + Autoconfiguration in IPv6 + - TEMP_PREFERRED_LIFETIME"; + } + } + } + } + + /* + * Legacy operational state data nodes + */ + + augment "/if:interfaces-state/if:interface" { + status deprecated; + description + "Data nodes for the operational state of IP on interfaces."; + + container ipv4 { + presence + "Present if IPv4 is enabled on this interface"; + config false; + status deprecated; + description + "Interface-specific parameters for the IPv4 address family."; + + leaf forwarding { + type boolean; + status deprecated; + description + "Indicates whether IPv4 packet forwarding is enabled or + disabled on this interface."; + } + leaf mtu { + type uint16 { + range "68..max"; + } + units "octets"; + status deprecated; + description + "The size, in octets, of the largest IPv4 packet that the + interface will send and receive."; + reference + "RFC 791: Internet Protocol"; + } + list address { + key "ip"; + status deprecated; + description + "The list of IPv4 addresses on the interface."; + + leaf ip { + type inet:ipv4-address-no-zone; + status deprecated; + description + "The IPv4 address on the interface."; + } + choice subnet { + status deprecated; + description + "The subnet can be specified as a prefix length or, + if the server supports non-contiguous netmasks, as + a netmask."; + leaf prefix-length { + type uint8 { + range "0..32"; + } + status deprecated; + description + "The length of the subnet prefix."; + } + leaf netmask { + if-feature ipv4-non-contiguous-netmasks; + type yang:dotted-quad; + status deprecated; + description + "The subnet specified as a netmask."; + } + } + leaf origin { + type ip-address-origin; + status deprecated; + description + "The origin of this address."; + } + } + list neighbor { + key "ip"; + status deprecated; + description + "A list of mappings from IPv4 addresses to + link-layer addresses. + + This list represents the ARP Cache."; + reference + "RFC 826: An Ethernet Address Resolution Protocol"; + + leaf ip { + type inet:ipv4-address-no-zone; + status deprecated; + description + "The IPv4 address of the neighbor node."; + } + + leaf link-layer-address { + type yang:phys-address; + status deprecated; + description + "The link-layer address of the neighbor node."; + } + leaf origin { + type neighbor-origin; + status deprecated; + description + "The origin of this neighbor entry."; + } + } + } + + container ipv6 { + presence + "Present if IPv6 is enabled on this interface"; + config false; + status deprecated; + description + "Parameters for the IPv6 address family."; + + leaf forwarding { + type boolean; + default false; + status deprecated; + description + "Indicates whether IPv6 packet forwarding is enabled or + disabled on this interface."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) + Section 6.2.1, IsRouter"; + } + leaf mtu { + type uint32 { + range "1280..max"; + } + units "octets"; + status deprecated; + description + "The size, in octets, of the largest IPv6 packet that the + interface will send and receive."; + reference + "RFC 8200: Internet Protocol, Version 6 (IPv6) + Specification + Section 5"; + } + list address { + key "ip"; + status deprecated; + description + "The list of IPv6 addresses on the interface."; + + leaf ip { + type inet:ipv6-address-no-zone; + status deprecated; + description + "The IPv6 address on the interface."; + } + leaf prefix-length { + type uint8 { + range "0..128"; + } + mandatory true; + status deprecated; + description + "The length of the subnet prefix."; + } + leaf origin { + type ip-address-origin; + status deprecated; + description + "The origin of this address."; + } + leaf status { + type enumeration { + enum preferred { + description + "This is a valid address that can appear as the + destination or source address of a packet."; + } + enum deprecated { + description + "This is a valid but deprecated address that should + no longer be used as a source address in new + communications, but packets addressed to such an + address are processed as expected."; + } + enum invalid { + description + "This isn't a valid address, and it shouldn't appear + as the destination or source address of a packet."; + } + + enum inaccessible { + description + "The address is not accessible because the interface + to which this address is assigned is not + operational."; + } + enum unknown { + description + "The status cannot be determined for some reason."; + } + enum tentative { + description + "The uniqueness of the address on the link is being + verified. Addresses in this state should not be + used for general communication and should only be + used to determine the uniqueness of the address."; + } + enum duplicate { + description + "The address has been determined to be non-unique on + the link and so must not be used."; + } + enum optimistic { + description + "The address is available for use, subject to + restrictions, while its uniqueness on a link is + being verified."; + } + } + status deprecated; + description + "The status of an address. Most of the states correspond + to states from the IPv6 Stateless Address + Autoconfiguration protocol."; + reference + "RFC 4293: Management Information Base for the + Internet Protocol (IP) + - IpAddressStatusTC + RFC 4862: IPv6 Stateless Address Autoconfiguration"; + } + } + + list neighbor { + key "ip"; + status deprecated; + description + "A list of mappings from IPv6 addresses to + link-layer addresses. + + This list represents the Neighbor Cache."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 (IPv6)"; + + leaf ip { + type inet:ipv6-address-no-zone; + status deprecated; + description + "The IPv6 address of the neighbor node."; + } + leaf link-layer-address { + type yang:phys-address; + status deprecated; + description + "The link-layer address of the neighbor node."; + } + leaf origin { + type neighbor-origin; + status deprecated; + description + "The origin of this neighbor entry."; + } + leaf is-router { + type empty; + status deprecated; + description + "Indicates that the neighbor node acts as a router."; + } + leaf state { + type enumeration { + enum incomplete { + description + "Address resolution is in progress, and the + link-layer address of the neighbor has not yet been + determined."; + } + enum reachable { + description + "Roughly speaking, the neighbor is known to have been + reachable recently (within tens of seconds ago)."; + } + enum stale { + description + "The neighbor is no longer known to be reachable, but + until traffic is sent to the neighbor no attempt + should be made to verify its reachability."; + } + enum delay { + description + "The neighbor is no longer known to be reachable, and + traffic has recently been sent to the neighbor. + Rather than probe the neighbor immediately, however, + delay sending probes for a short while in order to + give upper-layer protocols a chance to provide + reachability confirmation."; + } + enum probe { + description + "The neighbor is no longer known to be reachable, and + unicast Neighbor Solicitation probes are being sent + to verify reachability."; + } + } + status deprecated; + description + "The Neighbor Unreachability Detection state of this + entry."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) + Section 7.3.2"; + } + } + } + } +} diff --git a/src/confd/yang/ietf-netconf-acm@2018-02-14.yang b/src/confd/yang/ietf-netconf-acm@2018-02-14.yang new file mode 100644 index 00000000..bf4855fa --- /dev/null +++ b/src/confd/yang/ietf-netconf-acm@2018-02-14.yang @@ -0,0 +1,464 @@ +module ietf-netconf-acm { + + namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-acm"; + + prefix nacm; + + import ietf-yang-types { + prefix yang; + } + + organization + "IETF NETCONF (Network Configuration) Working Group"; + + contact + "WG Web: + WG List: + + Author: Andy Bierman + + + Author: Martin Bjorklund + "; + + description + "Network Configuration Access Control Model. + + Copyright (c) 2012 - 2018 IETF Trust and the persons + identified as authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD + License set forth in Section 4.c of the IETF Trust's + Legal Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC 8341; see + the RFC itself for full legal notices."; + + revision "2018-02-14" { + description + "Added support for YANG 1.1 actions and notifications tied to + data nodes. Clarified how NACM extensions can be used by + other data models."; + reference + "RFC 8341: Network Configuration Access Control Model"; + } + + revision "2012-02-22" { + description + "Initial version."; + reference + "RFC 6536: Network Configuration Protocol (NETCONF) + Access Control Model"; + } + + /* + * Extension statements + */ + + extension default-deny-write { + description + "Used to indicate that the data model node + represents a sensitive security system parameter. + + If present, the NETCONF server will only allow the designated + 'recovery session' to have write access to the node. An + explicit access control rule is required for all other users. + + If the NACM module is used, then it must be enabled (i.e., + /nacm/enable-nacm object equals 'true'), or this extension + is ignored. + + The 'default-deny-write' extension MAY appear within a data + definition statement. It is ignored otherwise."; + } + + extension default-deny-all { + description + "Used to indicate that the data model node + controls a very sensitive security system parameter. + + If present, the NETCONF server will only allow the designated + 'recovery session' to have read, write, or execute access to + the node. An explicit access control rule is required for all + other users. + + If the NACM module is used, then it must be enabled (i.e., + /nacm/enable-nacm object equals 'true'), or this extension + is ignored. + + The 'default-deny-all' extension MAY appear within a data + definition statement, 'rpc' statement, or 'notification' + statement. It is ignored otherwise."; + } + + /* + * Derived types + */ + + typedef user-name-type { + type string { + length "1..max"; + } + description + "General-purpose username string."; + } + + typedef matchall-string-type { + type string { + pattern '\*'; + } + description + "The string containing a single asterisk '*' is used + to conceptually represent all possible values + for the particular leaf using this data type."; + } + + typedef access-operations-type { + type bits { + bit create { + description + "Any protocol operation that creates a + new data node."; + } + bit read { + description + "Any protocol operation or notification that + returns the value of a data node."; + } + bit update { + description + "Any protocol operation that alters an existing + data node."; + } + bit delete { + description + "Any protocol operation that removes a data node."; + } + bit exec { + description + "Execution access to the specified protocol operation."; + } + } + description + "Access operation."; + } + + typedef group-name-type { + type string { + length "1..max"; + pattern '[^\*].*'; + } + description + "Name of administrative group to which + users can be assigned."; + } + + typedef action-type { + type enumeration { + enum permit { + description + "Requested action is permitted."; + } + enum deny { + description + "Requested action is denied."; + } + } + description + "Action taken by the server when a particular + rule matches."; + } + + typedef node-instance-identifier { + type yang:xpath1.0; + description + "Path expression used to represent a special + data node, action, or notification instance-identifier + string. + + A node-instance-identifier value is an + unrestricted YANG instance-identifier expression. + All the same rules as an instance-identifier apply, + except that predicates for keys are optional. If a key + predicate is missing, then the node-instance-identifier + represents all possible server instances for that key. + + This XML Path Language (XPath) expression is evaluated in the + following context: + + o The set of namespace declarations are those in scope on + the leaf element where this type is used. + + o The set of variable bindings contains one variable, + 'USER', which contains the name of the user of the + current session. + + o The function library is the core function library, but + note that due to the syntax restrictions of an + instance-identifier, no functions are allowed. + + o The context node is the root node in the data tree. + + The accessible tree includes actions and notifications tied + to data nodes."; + } + + /* + * Data definition statements + */ + + container nacm { + nacm:default-deny-all; + + description + "Parameters for NETCONF access control model."; + + leaf enable-nacm { + type boolean; + default "true"; + description + "Enables or disables all NETCONF access control + enforcement. If 'true', then enforcement + is enabled. If 'false', then enforcement + is disabled."; + } + + leaf read-default { + type action-type; + default "permit"; + description + "Controls whether read access is granted if + no appropriate rule is found for a + particular read request."; + } + + leaf write-default { + type action-type; + default "deny"; + description + "Controls whether create, update, or delete access + is granted if no appropriate rule is found for a + particular write request."; + } + + leaf exec-default { + type action-type; + default "permit"; + description + "Controls whether exec access is granted if no appropriate + rule is found for a particular protocol operation request."; + } + + leaf enable-external-groups { + type boolean; + default "true"; + description + "Controls whether the server uses the groups reported by the + NETCONF transport layer when it assigns the user to a set of + NACM groups. If this leaf has the value 'false', any group + names reported by the transport layer are ignored by the + server."; + } + + leaf denied-operations { + type yang:zero-based-counter32; + config false; + mandatory true; + description + "Number of times since the server last restarted that a + protocol operation request was denied."; + } + + leaf denied-data-writes { + type yang:zero-based-counter32; + config false; + mandatory true; + description + "Number of times since the server last restarted that a + protocol operation request to alter + a configuration datastore was denied."; + } + + leaf denied-notifications { + type yang:zero-based-counter32; + config false; + mandatory true; + description + "Number of times since the server last restarted that + a notification was dropped for a subscription because + access to the event type was denied."; + } + + container groups { + description + "NETCONF access control groups."; + + list group { + key name; + + description + "One NACM group entry. This list will only contain + configured entries, not any entries learned from + any transport protocols."; + + leaf name { + type group-name-type; + description + "Group name associated with this entry."; + } + + leaf-list user-name { + type user-name-type; + description + "Each entry identifies the username of + a member of the group associated with + this entry."; + } + } + } + + list rule-list { + key name; + ordered-by user; + description + "An ordered collection of access control rules."; + + leaf name { + type string { + length "1..max"; + } + description + "Arbitrary name assigned to the rule-list."; + } + leaf-list group { + type union { + type matchall-string-type; + type group-name-type; + } + description + "List of administrative groups that will be + assigned the associated access rights + defined by the 'rule' list. + + The string '*' indicates that all groups apply to the + entry."; + } + + list rule { + key name; + ordered-by user; + description + "One access control rule. + + Rules are processed in user-defined order until a match is + found. A rule matches if 'module-name', 'rule-type', and + 'access-operations' match the request. If a rule + matches, the 'action' leaf determines whether or not + access is granted."; + + leaf name { + type string { + length "1..max"; + } + description + "Arbitrary name assigned to the rule."; + } + + leaf module-name { + type union { + type matchall-string-type; + type string; + } + default "*"; + description + "Name of the module associated with this rule. + + This leaf matches if it has the value '*' or if the + object being accessed is defined in the module with the + specified module name."; + } + choice rule-type { + description + "This choice matches if all leafs present in the rule + match the request. If no leafs are present, the + choice matches all requests."; + case protocol-operation { + leaf rpc-name { + type union { + type matchall-string-type; + type string; + } + description + "This leaf matches if it has the value '*' or if + its value equals the requested protocol operation + name."; + } + } + case notification { + leaf notification-name { + type union { + type matchall-string-type; + type string; + } + description + "This leaf matches if it has the value '*' or if its + value equals the requested notification name."; + } + } + + case data-node { + leaf path { + type node-instance-identifier; + mandatory true; + description + "Data node instance-identifier associated with the + data node, action, or notification controlled by + this rule. + + Configuration data or state data + instance-identifiers start with a top-level + data node. A complete instance-identifier is + required for this type of path value. + + The special value '/' refers to all possible + datastore contents."; + } + } + } + + leaf access-operations { + type union { + type matchall-string-type; + type access-operations-type; + } + default "*"; + description + "Access operations associated with this rule. + + This leaf matches if it has the value '*' or if the + bit corresponding to the requested operation is set."; + } + + leaf action { + type action-type; + mandatory true; + description + "The access control action associated with the + rule. If a rule has been determined to match a + particular request, then this object is used + to determine whether to permit or deny the + request."; + } + + leaf comment { + type string; + description + "A textual description of the access rule."; + } + } + } + } +} diff --git a/src/confd/yang/ietf-system@2014-08-06.yang b/src/confd/yang/ietf-system@2014-08-06.yang new file mode 100644 index 00000000..1618242b --- /dev/null +++ b/src/confd/yang/ietf-system@2014-08-06.yang @@ -0,0 +1,800 @@ +module ietf-system { + namespace "urn:ietf:params:xml:ns:yang:ietf-system"; + prefix "sys"; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import ietf-netconf-acm { + prefix nacm; + } + + import iana-crypt-hash { + prefix ianach; + } + + organization + "IETF NETMOD (NETCONF Data Modeling Language) Working Group"; + + contact + "WG Web: + WG List: + + WG Chair: Thomas Nadeau + + + WG Chair: Juergen Schoenwaelder + + + Editor: Andy Bierman + + + Editor: Martin Bjorklund + "; + + description + "This module contains a collection of YANG definitions for the + configuration and identification of some common system + properties within a device containing a NETCONF server. This + includes data node definitions for system identification, + time-of-day management, user management, DNS resolver + configuration, and some protocol operations for system + management. + + Copyright (c) 2014 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (http://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC 7317; see + the RFC itself for full legal notices."; + + revision 2014-08-06 { + description + "Initial revision."; + reference + "RFC 7317: A YANG Data Model for System Management"; + } + + /* + * Typedefs + */ + + typedef timezone-name { + type string; + description + "A time zone name as used by the Time Zone Database, + sometimes referred to as the 'Olson Database'. + + The exact set of valid values is an implementation-specific + matter. Client discovery of the exact set of time zone names + for a particular server is out of scope."; + reference + "RFC 6557: Procedures for Maintaining the Time Zone Database"; + } + + /* + * Features + */ + + feature radius { + description + "Indicates that the device can be configured as a RADIUS + client."; + reference + "RFC 2865: Remote Authentication Dial In User Service (RADIUS)"; + } + + feature authentication { + description + "Indicates that the device supports configuration of + user authentication."; + } + + feature local-users { + if-feature authentication; + description + "Indicates that the device supports configuration of + local user authentication."; + } + + feature radius-authentication { + if-feature radius; + if-feature authentication; + description + "Indicates that the device supports configuration of user + authentication over RADIUS."; + reference + "RFC 2865: Remote Authentication Dial In User Service (RADIUS) + RFC 5607: Remote Authentication Dial-In User Service (RADIUS) + Authorization for Network Access Server (NAS) + Management"; + } + + feature ntp { + description + "Indicates that the device can be configured to use one or + more NTP servers to set the system date and time."; + } + + feature ntp-udp-port { + if-feature ntp; + description + "Indicates that the device supports the configuration of + the UDP port for NTP servers. + + This is a 'feature', since many implementations do not support + any port other than the default port."; + } + + feature timezone-name { + description + "Indicates that the local time zone on the device + can be configured to use the TZ database + to set the time zone and manage daylight saving time."; + reference + "RFC 6557: Procedures for Maintaining the Time Zone Database"; + } + + feature dns-udp-tcp-port { + description + "Indicates that the device supports the configuration of + the UDP and TCP port for DNS servers. + + This is a 'feature', since many implementations do not support + any port other than the default port."; + } + + /* + * Identities + */ + + identity authentication-method { + description + "Base identity for user authentication methods."; + } + + identity radius { + base authentication-method; + description + "Indicates user authentication using RADIUS."; + reference + "RFC 2865: Remote Authentication Dial In User Service (RADIUS) + RFC 5607: Remote Authentication Dial-In User Service (RADIUS) + Authorization for Network Access Server (NAS) + Management"; + } + + identity local-users { + base authentication-method; + description + "Indicates password-based authentication of locally + configured users."; + } + + identity radius-authentication-type { + description + "Base identity for RADIUS authentication types."; + } + + identity radius-pap { + base radius-authentication-type; + description + "The device requests Password Authentication Protocol (PAP) + authentication from the RADIUS server."; + reference + "RFC 2865: Remote Authentication Dial In User Service (RADIUS)"; + } + + identity radius-chap { + base radius-authentication-type; + description + "The device requests Challenge Handshake Authentication + Protocol (CHAP) authentication from the RADIUS server."; + reference + "RFC 2865: Remote Authentication Dial In User Service (RADIUS)"; + } + + /* + * Configuration data nodes + */ + + container system { + description + "System group configuration."; + + leaf contact { + type string; + description + "The administrator contact information for the system. + + A server implementation MAY map this leaf to the sysContact + MIB object. Such an implementation needs to use some + mechanism to handle the differences in size and characters + allowed between this leaf and sysContact. The definition of + such a mechanism is outside the scope of this document."; + reference + "RFC 3418: Management Information Base (MIB) for the + Simple Network Management Protocol (SNMP) + SNMPv2-MIB.sysContact"; + } + leaf hostname { + type inet:domain-name; + description + "The name of the host. This name can be a single domain + label or the fully qualified domain name of the host."; + } + leaf location { + type string; + description + "The system location. + + A server implementation MAY map this leaf to the sysLocation + MIB object. Such an implementation needs to use some + mechanism to handle the differences in size and characters + allowed between this leaf and sysLocation. The definition + of such a mechanism is outside the scope of this document."; + reference + "RFC 3418: Management Information Base (MIB) for the + Simple Network Management Protocol (SNMP) + SNMPv2-MIB.sysLocation"; + } + + container clock { + description + "Configuration of the system date and time properties."; + + choice timezone { + description + "The system time zone information."; + + case timezone-name { + if-feature timezone-name; + leaf timezone-name { + type timezone-name; + description + "The TZ database name to use for the system, such + as 'Europe/Stockholm'."; + } + } + case timezone-utc-offset { + leaf timezone-utc-offset { + type int16 { + range "-1500 .. 1500"; + } + units "minutes"; + description + "The number of minutes to add to UTC time to + identify the time zone for this system. For example, + 'UTC - 8:00 hours' would be represented as '-480'. + Note that automatic daylight saving time adjustment + is not provided if this object is used."; + } + } + } + } + + container ntp { + if-feature ntp; + presence + "Enables the NTP client unless the 'enabled' leaf + (which defaults to 'true') is set to 'false'"; + description + "Configuration of the NTP client."; + + leaf enabled { + type boolean; + default true; + description + "Indicates that the system should attempt to + synchronize the system clock with an NTP server + from the 'ntp/server' list."; + } + list server { + key name; + description + "List of NTP servers to use for system clock + synchronization. If '/system/ntp/enabled' + is 'true', then the system will attempt to + contact and utilize the specified NTP servers."; + + leaf name { + type string; + description + "An arbitrary name for the NTP server."; + } + choice transport { + mandatory true; + description + "The transport-protocol-specific parameters for this + server."; + + case udp { + container udp { + description + "Contains UDP-specific configuration parameters + for NTP."; + leaf address { + type inet:host; + mandatory true; + description + "The address of the NTP server."; + } + leaf port { + if-feature ntp-udp-port; + type inet:port-number; + default 123; + description + "The port number of the NTP server."; + } + } + } + } + leaf association-type { + type enumeration { + enum server { + description + "Use client association mode. This device + will not provide synchronization to the + configured NTP server."; + } + enum peer { + description + "Use symmetric active association mode. + This device may provide synchronization + to the configured NTP server."; + } + enum pool { + description + "Use client association mode with one or + more of the NTP servers found by DNS + resolution of the domain name given by + the 'address' leaf. This device will not + provide synchronization to the servers."; + } + } + default server; + description + "The desired association type for this NTP server."; + } + leaf iburst { + type boolean; + default false; + description + "Indicates whether this server should enable burst + synchronization or not."; + } + leaf prefer { + type boolean; + default false; + description + "Indicates whether this server should be preferred + or not."; + } + } + } + + container dns-resolver { + description + "Configuration of the DNS resolver."; + + leaf-list search { + type inet:domain-name; + ordered-by user; + description + "An ordered list of domains to search when resolving + a host name."; + } + list server { + key name; + ordered-by user; + description + "List of the DNS servers that the resolver should query. + + When the resolver is invoked by a calling application, it + sends the query to the first name server in this list. If + no response has been received within 'timeout' seconds, + the resolver continues with the next server in the list. + If no response is received from any server, the resolver + continues with the first server again. When the resolver + has traversed the list 'attempts' times without receiving + any response, it gives up and returns an error to the + calling application. + + Implementations MAY limit the number of entries in this + list."; + + leaf name { + type string; + description + "An arbitrary name for the DNS server."; + } + choice transport { + mandatory true; + description + "The transport-protocol-specific parameters for this + server."; + + case udp-and-tcp { + container udp-and-tcp { + description + "Contains UDP- and TCP-specific configuration + parameters for DNS."; + reference + "RFC 1035: Domain Names - Implementation and + Specification + RFC 5966: DNS Transport over TCP - Implementation + Requirements"; + + leaf address { + type inet:ip-address; + mandatory true; + description + "The address of the DNS server."; + } + leaf port { + if-feature dns-udp-tcp-port; + type inet:port-number; + default 53; + description + "The UDP and TCP port number of the DNS server."; + } + } + } + } + } + container options { + description + "Resolver options. The set of available options has been + limited to those that are generally available across + different resolver implementations and generally useful."; + leaf timeout { + type uint8 { + range "1..max"; + } + units "seconds"; + default "5"; + description + "The amount of time the resolver will wait for a + response from each remote name server before + retrying the query via a different name server."; + } + leaf attempts { + type uint8 { + range "1..max"; + } + default "2"; + description + "The number of times the resolver will send a query to + all of its name servers before giving up and returning + an error to the calling application."; + } + } + } + + container radius { + if-feature radius; + + description + "Configuration of the RADIUS client."; + + list server { + key name; + ordered-by user; + description + "List of RADIUS servers used by the device. + + When the RADIUS client is invoked by a calling + application, it sends the query to the first server in + this list. If no response has been received within + 'timeout' seconds, the client continues with the next + server in the list. If no response is received from any + server, the client continues with the first server again. + When the client has traversed the list 'attempts' times + without receiving any response, it gives up and returns an + error to the calling application."; + + leaf name { + type string; + description + "An arbitrary name for the RADIUS server."; + } + choice transport { + mandatory true; + description + "The transport-protocol-specific parameters for this + server."; + + case udp { + container udp { + description + "Contains UDP-specific configuration parameters + for RADIUS."; + leaf address { + type inet:host; + mandatory true; + description + "The address of the RADIUS server."; + } + + leaf authentication-port { + type inet:port-number; + default "1812"; + description + "The port number of the RADIUS server."; + } + leaf shared-secret { + type string; + mandatory true; + nacm:default-deny-all; + description + "The shared secret, which is known to both the + RADIUS client and server."; + reference + "RFC 2865: Remote Authentication Dial In User + Service (RADIUS)"; + } + } + } + } + leaf authentication-type { + type identityref { + base radius-authentication-type; + } + default radius-pap; + description + "The authentication type requested from the RADIUS + server."; + } + } + container options { + description + "RADIUS client options."; + + leaf timeout { + type uint8 { + range "1..max"; + } + units "seconds"; + default "5"; + description + "The number of seconds the device will wait for a + response from each RADIUS server before trying with a + different server."; + } + + leaf attempts { + type uint8 { + range "1..max"; + } + default "2"; + description + "The number of times the device will send a query to + all of its RADIUS servers before giving up."; + } + } + } + + container authentication { + nacm:default-deny-write; + if-feature authentication; + + description + "The authentication configuration subtree."; + + leaf-list user-authentication-order { + type identityref { + base authentication-method; + } + must '(. != "sys:radius" or ../../radius/server)' { + error-message + "When 'radius' is used, a RADIUS server" + + " must be configured."; + description + "When 'radius' is used as an authentication method, + a RADIUS server must be configured."; + } + ordered-by user; + + description + "When the device authenticates a user with a password, + it tries the authentication methods in this leaf-list in + order. If authentication with one method fails, the next + method is used. If no method succeeds, the user is + denied access. + + An empty user-authentication-order leaf-list still allows + authentication of users using mechanisms that do not + involve a password. + + If the 'radius-authentication' feature is advertised by + the NETCONF server, the 'radius' identity can be added to + this list. + + If the 'local-users' feature is advertised by the + NETCONF server, the 'local-users' identity can be + added to this list."; + } + + list user { + if-feature local-users; + key name; + description + "The list of local users configured on this device."; + + leaf name { + type string; + description + "The user name string identifying this entry."; + } + leaf password { + type ianach:crypt-hash; + description + "The password for this entry."; + } + list authorized-key { + key name; + description + "A list of public SSH keys for this user. These keys + are allowed for SSH authentication, as described in + RFC 4253."; + reference + "RFC 4253: The Secure Shell (SSH) Transport Layer + Protocol"; + + leaf name { + type string; + description + "An arbitrary name for the SSH key."; + } + + leaf algorithm { + type string; + mandatory true; + description + "The public key algorithm name for this SSH key. + + Valid values are the values in the IANA 'Secure Shell + (SSH) Protocol Parameters' registry, Public Key + Algorithm Names."; + reference + "IANA 'Secure Shell (SSH) Protocol Parameters' + registry, Public Key Algorithm Names"; + } + leaf key-data { + type binary; + mandatory true; + description + "The binary public key data for this SSH key, as + specified by RFC 4253, Section 6.6, i.e.: + + string certificate or public key format + identifier + byte[n] key/certificate data."; + reference + "RFC 4253: The Secure Shell (SSH) Transport Layer + Protocol"; + } + } + } + } + } + + /* + * Operational state data nodes + */ + + container system-state { + config false; + description + "System group operational state."; + + container platform { + description + "Contains vendor-specific information for + identifying the system platform and operating system."; + reference + "IEEE Std 1003.1-2008 - sys/utsname.h"; + + leaf os-name { + type string; + description + "The name of the operating system in use - + for example, 'Linux'."; + reference + "IEEE Std 1003.1-2008 - utsname.sysname"; + } + leaf os-release { + type string; + description + "The current release level of the operating + system in use. This string MAY indicate + the OS source code revision."; + reference + "IEEE Std 1003.1-2008 - utsname.release"; + } + leaf os-version { + type string; + description + "The current version level of the operating + system in use. This string MAY indicate + the specific OS build date and target variant + information."; + reference + "IEEE Std 1003.1-2008 - utsname.version"; + } + leaf machine { + type string; + description + "A vendor-specific identifier string representing + the hardware in use."; + reference + "IEEE Std 1003.1-2008 - utsname.machine"; + } + } + + container clock { + description + "Monitoring of the system date and time properties."; + + leaf current-datetime { + type yang:date-and-time; + description + "The current system date and time."; + } + + leaf boot-datetime { + type yang:date-and-time; + description + "The system date and time when the system last restarted."; + } + } + } + + rpc set-current-datetime { + nacm:default-deny-all; + description + "Set the /system-state/clock/current-datetime leaf + to the specified value. + + If the system is using NTP (i.e., /system/ntp/enabled + is set to 'true'), then this operation will fail with + error-tag 'operation-failed' and error-app-tag value of + 'ntp-active'."; + input { + leaf current-datetime { + type yang:date-and-time; + mandatory true; + description + "The current system date and time."; + } + } + } + + rpc system-restart { + nacm:default-deny-all; + description + "Request that the entire system be restarted immediately. + A server SHOULD send an rpc reply to the client before + restarting the system."; + } + + rpc system-shutdown { + nacm:default-deny-all; + description + "Request that the entire system be shut down immediately. + A server SHOULD send an rpc reply to the client before + shutting down the system."; + } + +} diff --git a/src/confd/yang/ietf-yang-types@2013-07-15.yang b/src/confd/yang/ietf-yang-types@2013-07-15.yang new file mode 100644 index 00000000..ee58fa3a --- /dev/null +++ b/src/confd/yang/ietf-yang-types@2013-07-15.yang @@ -0,0 +1,474 @@ +module ietf-yang-types { + + namespace "urn:ietf:params:xml:ns:yang:ietf-yang-types"; + prefix "yang"; + + organization + "IETF NETMOD (NETCONF Data Modeling Language) Working Group"; + + contact + "WG Web: + WG List: + + WG Chair: David Kessens + + + WG Chair: Juergen Schoenwaelder + + + Editor: Juergen Schoenwaelder + "; + + description + "This module contains a collection of generally useful derived + YANG data types. + + Copyright (c) 2013 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (http://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC 6991; see + the RFC itself for full legal notices."; + + revision 2013-07-15 { + description + "This revision adds the following new data types: + - yang-identifier + - hex-string + - uuid + - dotted-quad"; + reference + "RFC 6991: Common YANG Data Types"; + } + + revision 2010-09-24 { + description + "Initial revision."; + reference + "RFC 6021: Common YANG Data Types"; + } + + /*** collection of counter and gauge types ***/ + + typedef counter32 { + type uint32; + description + "The counter32 type represents a non-negative integer + that monotonically increases until it reaches a + maximum value of 2^32-1 (4294967295 decimal), when it + wraps around and starts increasing again from zero. + + Counters have no defined 'initial' value, and thus, a + single value of a counter has (in general) no information + content. Discontinuities in the monotonically increasing + value normally occur at re-initialization of the + management system, and at other times as specified in the + description of a schema node using this type. If such + other times can occur, for example, the creation of + a schema node of type counter32 at times other than + re-initialization, then a corresponding schema node + should be defined, with an appropriate type, to indicate + the last discontinuity. + + The counter32 type should not be used for configuration + schema nodes. A default statement SHOULD NOT be used in + combination with the type counter32. + + In the value set and its semantics, this type is equivalent + to the Counter32 type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 + (SMIv2)"; + } + + typedef zero-based-counter32 { + type yang:counter32; + default "0"; + description + "The zero-based-counter32 type represents a counter32 + that has the defined 'initial' value zero. + + A schema node of this type will be set to zero (0) on creation + and will thereafter increase monotonically until it reaches + a maximum value of 2^32-1 (4294967295 decimal), when it + wraps around and starts increasing again from zero. + + Provided that an application discovers a new schema node + of this type within the minimum time to wrap, it can use the + 'initial' value as a delta. It is important for a management + station to be aware of this minimum time and the actual time + between polls, and to discard data if the actual time is too + long or there is no defined minimum time. + + In the value set and its semantics, this type is equivalent + to the ZeroBasedCounter32 textual convention of the SMIv2."; + reference + "RFC 4502: Remote Network Monitoring Management Information + Base Version 2"; + } + + typedef counter64 { + type uint64; + description + "The counter64 type represents a non-negative integer + that monotonically increases until it reaches a + maximum value of 2^64-1 (18446744073709551615 decimal), + when it wraps around and starts increasing again from zero. + + Counters have no defined 'initial' value, and thus, a + single value of a counter has (in general) no information + content. Discontinuities in the monotonically increasing + value normally occur at re-initialization of the + management system, and at other times as specified in the + description of a schema node using this type. If such + other times can occur, for example, the creation of + a schema node of type counter64 at times other than + re-initialization, then a corresponding schema node + should be defined, with an appropriate type, to indicate + the last discontinuity. + + The counter64 type should not be used for configuration + schema nodes. A default statement SHOULD NOT be used in + combination with the type counter64. + + In the value set and its semantics, this type is equivalent + to the Counter64 type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 + (SMIv2)"; + } + + typedef zero-based-counter64 { + type yang:counter64; + default "0"; + description + "The zero-based-counter64 type represents a counter64 that + has the defined 'initial' value zero. + + A schema node of this type will be set to zero (0) on creation + and will thereafter increase monotonically until it reaches + a maximum value of 2^64-1 (18446744073709551615 decimal), + when it wraps around and starts increasing again from zero. + + Provided that an application discovers a new schema node + of this type within the minimum time to wrap, it can use the + 'initial' value as a delta. It is important for a management + station to be aware of this minimum time and the actual time + between polls, and to discard data if the actual time is too + long or there is no defined minimum time. + + In the value set and its semantics, this type is equivalent + to the ZeroBasedCounter64 textual convention of the SMIv2."; + reference + "RFC 2856: Textual Conventions for Additional High Capacity + Data Types"; + } + + typedef gauge32 { + type uint32; + description + "The gauge32 type represents a non-negative integer, which + may increase or decrease, but shall never exceed a maximum + value, nor fall below a minimum value. The maximum value + cannot be greater than 2^32-1 (4294967295 decimal), and + the minimum value cannot be smaller than 0. The value of + a gauge32 has its maximum value whenever the information + being modeled is greater than or equal to its maximum + value, and has its minimum value whenever the information + being modeled is smaller than or equal to its minimum value. + If the information being modeled subsequently decreases + below (increases above) the maximum (minimum) value, the + gauge32 also decreases (increases). + + In the value set and its semantics, this type is equivalent + to the Gauge32 type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 + (SMIv2)"; + } + + typedef gauge64 { + type uint64; + description + "The gauge64 type represents a non-negative integer, which + may increase or decrease, but shall never exceed a maximum + value, nor fall below a minimum value. The maximum value + cannot be greater than 2^64-1 (18446744073709551615), and + the minimum value cannot be smaller than 0. The value of + a gauge64 has its maximum value whenever the information + being modeled is greater than or equal to its maximum + value, and has its minimum value whenever the information + being modeled is smaller than or equal to its minimum value. + If the information being modeled subsequently decreases + below (increases above) the maximum (minimum) value, the + gauge64 also decreases (increases). + + In the value set and its semantics, this type is equivalent + to the CounterBasedGauge64 SMIv2 textual convention defined + in RFC 2856"; + reference + "RFC 2856: Textual Conventions for Additional High Capacity + Data Types"; + } + + /*** collection of identifier-related types ***/ + + typedef object-identifier { + type string { + pattern '(([0-1](\.[1-3]?[0-9]))|(2\.(0|([1-9]\d*))))' + + '(\.(0|([1-9]\d*)))*'; + } + description + "The object-identifier type represents administratively + assigned names in a registration-hierarchical-name tree. + + Values of this type are denoted as a sequence of numerical + non-negative sub-identifier values. Each sub-identifier + value MUST NOT exceed 2^32-1 (4294967295). Sub-identifiers + are separated by single dots and without any intermediate + whitespace. + + The ASN.1 standard restricts the value space of the first + sub-identifier to 0, 1, or 2. Furthermore, the value space + of the second sub-identifier is restricted to the range + 0 to 39 if the first sub-identifier is 0 or 1. Finally, + the ASN.1 standard requires that an object identifier + has always at least two sub-identifiers. The pattern + captures these restrictions. + + Although the number of sub-identifiers is not limited, + module designers should realize that there may be + implementations that stick with the SMIv2 limit of 128 + sub-identifiers. + + This type is a superset of the SMIv2 OBJECT IDENTIFIER type + since it is not restricted to 128 sub-identifiers. Hence, + this type SHOULD NOT be used to represent the SMIv2 OBJECT + IDENTIFIER type; the object-identifier-128 type SHOULD be + used instead."; + reference + "ISO9834-1: Information technology -- Open Systems + Interconnection -- Procedures for the operation of OSI + Registration Authorities: General procedures and top + arcs of the ASN.1 Object Identifier tree"; + } + + typedef object-identifier-128 { + type object-identifier { + pattern '\d*(\.\d*){1,127}'; + } + description + "This type represents object-identifiers restricted to 128 + sub-identifiers. + + In the value set and its semantics, this type is equivalent + to the OBJECT IDENTIFIER type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 + (SMIv2)"; + } + + typedef yang-identifier { + type string { + length "1..max"; + pattern '[a-zA-Z_][a-zA-Z0-9\-_.]*'; + pattern '.|..|[^xX].*|.[^mM].*|..[^lL].*'; + } + description + "A YANG identifier string as defined by the 'identifier' + rule in Section 12 of RFC 6020. An identifier must + start with an alphabetic character or an underscore + followed by an arbitrary sequence of alphabetic or + numeric characters, underscores, hyphens, or dots. + + A YANG identifier MUST NOT start with any possible + combination of the lowercase or uppercase character + sequence 'xml'."; + reference + "RFC 6020: YANG - A Data Modeling Language for the Network + Configuration Protocol (NETCONF)"; + } + + /*** collection of types related to date and time***/ + + typedef date-and-time { + type string { + pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?' + + '(Z|[\+\-]\d{2}:\d{2})'; + } + description + "The date-and-time type is a profile of the ISO 8601 + standard for representation of dates and times using the + Gregorian calendar. The profile is defined by the + date-time production in Section 5.6 of RFC 3339. + + The date-and-time type is compatible with the dateTime XML + schema type with the following notable exceptions: + + (a) The date-and-time type does not allow negative years. + + (b) The date-and-time time-offset -00:00 indicates an unknown + time zone (see RFC 3339) while -00:00 and +00:00 and Z + all represent the same time zone in dateTime. + + (c) The canonical format (see below) of data-and-time values + differs from the canonical format used by the dateTime XML + schema type, which requires all times to be in UTC using + the time-offset 'Z'. + + This type is not equivalent to the DateAndTime textual + convention of the SMIv2 since RFC 3339 uses a different + separator between full-date and full-time and provides + higher resolution of time-secfrac. + + The canonical format for date-and-time values with a known time + zone uses a numeric time zone offset that is calculated using + the device's configured known offset to UTC time. A change of + the device's offset to UTC time will cause date-and-time values + to change accordingly. Such changes might happen periodically + in case a server follows automatically daylight saving time + (DST) time zone offset changes. The canonical format for + date-and-time values with an unknown time zone (usually + referring to the notion of local time) uses the time-offset + -00:00."; + reference + "RFC 3339: Date and Time on the Internet: Timestamps + RFC 2579: Textual Conventions for SMIv2 + XSD-TYPES: XML Schema Part 2: Datatypes Second Edition"; + } + + typedef timeticks { + type uint32; + description + "The timeticks type represents a non-negative integer that + represents the time, modulo 2^32 (4294967296 decimal), in + hundredths of a second between two epochs. When a schema + node is defined that uses this type, the description of + the schema node identifies both of the reference epochs. + + In the value set and its semantics, this type is equivalent + to the TimeTicks type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 + (SMIv2)"; + } + + typedef timestamp { + type yang:timeticks; + description + "The timestamp type represents the value of an associated + timeticks schema node at which a specific occurrence + happened. The specific occurrence must be defined in the + description of any schema node defined using this type. When + the specific occurrence occurred prior to the last time the + associated timeticks attribute was zero, then the timestamp + value is zero. Note that this requires all timestamp values + to be reset to zero when the value of the associated timeticks + attribute reaches 497+ days and wraps around to zero. + + The associated timeticks schema node must be specified + in the description of any schema node using this type. + + In the value set and its semantics, this type is equivalent + to the TimeStamp textual convention of the SMIv2."; + reference + "RFC 2579: Textual Conventions for SMIv2"; + } + + /*** collection of generic address types ***/ + + typedef phys-address { + type string { + pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?'; + } + + description + "Represents media- or physical-level addresses represented + as a sequence octets, each octet represented by two hexadecimal + numbers. Octets are separated by colons. The canonical + representation uses lowercase characters. + + In the value set and its semantics, this type is equivalent + to the PhysAddress textual convention of the SMIv2."; + reference + "RFC 2579: Textual Conventions for SMIv2"; + } + + typedef mac-address { + type string { + pattern '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'; + } + description + "The mac-address type represents an IEEE 802 MAC address. + The canonical representation uses lowercase characters. + + In the value set and its semantics, this type is equivalent + to the MacAddress textual convention of the SMIv2."; + reference + "IEEE 802: IEEE Standard for Local and Metropolitan Area + Networks: Overview and Architecture + RFC 2579: Textual Conventions for SMIv2"; + } + + /*** collection of XML-specific types ***/ + + typedef xpath1.0 { + type string; + description + "This type represents an XPATH 1.0 expression. + + When a schema node is defined that uses this type, the + description of the schema node MUST specify the XPath + context in which the XPath expression is evaluated."; + reference + "XPATH: XML Path Language (XPath) Version 1.0"; + } + + /*** collection of string types ***/ + + typedef hex-string { + type string { + pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?'; + } + description + "A hexadecimal string with octets represented as hex digits + separated by colons. The canonical representation uses + lowercase characters."; + } + + typedef uuid { + type string { + pattern '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-' + + '[0-9a-fA-F]{4}-[0-9a-fA-F]{12}'; + } + description + "A Universally Unique IDentifier in the string representation + defined in RFC 4122. The canonical representation uses + lowercase characters. + + The following is an example of a UUID in string representation: + f81d4fae-7dec-11d0-a765-00a0c91e6bf6 + "; + reference + "RFC 4122: A Universally Unique IDentifier (UUID) URN + Namespace"; + } + + typedef dotted-quad { + type string { + pattern + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}' + + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'; + } + description + "An unsigned 32-bit number expressed in the dotted-quad + notation, i.e., four octets written as decimal numbers + and separated with the '.' (full stop) character."; + } +} diff --git a/src/confd/yang/infix-system@2014-08-06.yang b/src/confd/yang/infix-system@2014-08-06.yang new file mode 100644 index 00000000..3034613b --- /dev/null +++ b/src/confd/yang/infix-system@2014-08-06.yang @@ -0,0 +1,20 @@ +module infix-system { + prefix "infix-sys"; + yang-version 1.1; + namespace "urn:infix:params:xml:ns:yang:infix-system"; + + import ietf-system { + prefix "sys"; + } + + revision 2014-08-06 { + description "Initial revision."; + } + + augment "/sys:system" { + leaf motd { + type string; + description "Set the MotD (Message of the Day), which is shown after login"; + } + } +} diff --git a/src/confd/yang/kernelkit-infix-deviations.yang b/src/confd/yang/kernelkit-infix-deviations.yang new file mode 100644 index 00000000..0513d1d7 --- /dev/null +++ b/src/confd/yang/kernelkit-infix-deviations.yang @@ -0,0 +1,19 @@ +module kernelkit-infix-deviations { + yang-version 1.1; + namespace "urn:kernelkit:params:xml:ns:yang:infix"; + prefix "kkit"; + import ietf-system { + prefix sys; + } + organization "KernelKit"; + contact "kernelkit@googlegroups.com"; + description "Infix deviations in standard yang models."; + + revision "2023-04-03" { + description "Initial revision."; + } + + deviation /sys:system/sys:clock/sys:timezone/sys:timezone-utc-offset/sys:timezone-utc-offset { + deviate not-supported; + } +} diff --git a/src/klinfix/.gitignore b/src/klinfix/.gitignore new file mode 100644 index 00000000..e9e8e747 --- /dev/null +++ b/src/klinfix/.gitignore @@ -0,0 +1,33 @@ +*~ +*.o +*.la +*.lo +*.so +.deps +.libs + +/aclocal.m4 +/autom4te.cache/ +/aux +/clixon.xml +/compile +/config.h +/config.h.in +/config.guess +/config.log +/config.status +/config.sub +/configure +/depcomp +/install-sh +/libtool +/ltmain.sh +/m4 +/missing + +GPATH +GRTAGS +GTAGS +Makefile +Makefile.in + diff --git a/src/klinfix/Makefile.am b/src/klinfix/Makefile.am new file mode 100644 index 00000000..cb106dee --- /dev/null +++ b/src/klinfix/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = src xml +DISTCLEANFILES = *~ *.d +ACLOCAL_AMFLAGS = -I m4 diff --git a/src/klinfix/README.md b/src/klinfix/README.md new file mode 100644 index 00000000..7dfcc518 --- /dev/null +++ b/src/klinfix/README.md @@ -0,0 +1,74 @@ +Infix Extensions to klish-plugin-sysrepo +---------------------------------------- + +Tailor `klish` and `klish-plugin-sysrepo` to suit Infix. The resulting +CLI is, in many respects, still very similar to Juniper's JunOS, since +that is also the primary inspiration for klish, with some additions +and modifications. + +Broadly speaking, the CLI is split up in two major modes: + +- Admin/Exec: This is the default mode, where operational commands can + be issued. +- Configure: Where a new candidate configuration is prepared. + + +### Admin/Exec Mode + +The following table lists the available commands: + +| Command | Description | Hotkey | +|--------------------|---------------------------------------|--------| +| `configure` | Enter configuration mode | | +| `copy ` | Copy `` to `` | | +| `exit` | Exit | `C-d` | +| `logout` | Alias for `exit` | | +| `shell` | Start system shell | | +| `show ` | Show various configuration and status | | + +#### Copy Command + +`copy ` + +Where `` is one of: +- `factory-config` +- `startup-config` +- `running-config` + +And `` is one of: +- `startup-config` +- `running-config` + +#### Show Command + +`show ` + +The following table lists the available items: + +| Item | Description | +|------------------|--------------------------------------| +| `running-config` | Show the active system configuration | +| | | + + +### Configure + +The following table lists the available commands: + +| Command | Description | Hotkey | +|------------|--------------------------------------------------------------|--------| +| `abort` | Abandon candidate | `C-d` | +| `check` | Validate candidate | | +| `commit` | Commit current candidate to running-config | | +| `delete` | Delete configuration setting(s) | | +| `diff` | Summarize uncommitted changes | | +| `do` | Execute operational mode command | | +| `edit` | Descend to the specified configuration node | | +| `exit` | Ascend to the parent configuration node, or abort (from top) | | +| `leave` | Finalize candidate and apply to running-config | `C-z` | +| `no` | Alias for delete | | +| `rollback` | Restore candidate to running-config | | +| `set` | Set configuration setting | | +| `show` | Show configuration | | +| `top` | Ascend to the configuration root | | +| `up` | Ascend to the parent configuration node | `C-c` | diff --git a/src/klinfix/autogen.sh b/src/klinfix/autogen.sh new file mode 100755 index 00000000..69ad0e18 --- /dev/null +++ b/src/klinfix/autogen.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +autoreconf -W portability -vifm diff --git a/src/klinfix/configure.ac b/src/klinfix/configure.ac new file mode 100644 index 00000000..06f0af1d --- /dev/null +++ b/src/klinfix/configure.ac @@ -0,0 +1,33 @@ +AC_PREREQ(2.61) +AC_INIT([klinfix], [1.0.0], + [https://github.com/kernelkit/infix/issues]) +AM_INIT_AUTOMAKE(1.11 foreign subdir-objects) +AM_SILENT_RULES(yes) + +LT_INIT + +AC_CONFIG_FILES([ + Makefile + src/Makefile + xml/Makefile +]) + +AC_PROG_CC +AC_PROG_INSTALL + +# Check for pkg-config first, warn if it's not installed +PKG_PROG_PKG_CONFIG + +PKG_CHECK_MODULES([sysrepo], [sysrepo >= 2.2.60]) +AC_CHECK_LIB([klish], [kplugin_new],, AC_MSG_ERROR([Klish not found])) + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +KLISHLIBDIR=`eval echo $libdir/klish` +AC_SUBST(KLISHLIBDIR) + +KLISHCONFDIR=`eval echo $sysconfdir/klish` +AC_SUBST(KLISHCONFDIR) + +AC_OUTPUT diff --git a/src/klinfix/src/Makefile.am b/src/klinfix/src/Makefile.am new file mode 100644 index 00000000..5e236e85 --- /dev/null +++ b/src/klinfix/src/Makefile.am @@ -0,0 +1,9 @@ +CFLAGS = -Wall -Wextra -Werror -Wno-unused-parameter + +pluginsdir = $(KLISHLIBDIR)/plugins +plugins_LTLIBRARIES = kplugin-klinfix.la + +kplugin_klinfix_la_CFLAGS = $(sysrepo_CFLAGS) $(klish_CFLAGS) $(CFLAGS) +kplugin_klinfix_la_LIBADD = $(sysrepo_LIBS) $(klish_LIBS) +kplugin_klinfix_la_LDFLAGS = -module -avoid-version -shared +kplugin_klinfix_la_SOURCES = klinfix.c diff --git a/src/klinfix/src/klinfix.c b/src/klinfix/src/klinfix.c new file mode 100644 index 00000000..8abd910f --- /dev/null +++ b/src/klinfix/src/klinfix.c @@ -0,0 +1,155 @@ +#include +#include + +#include +#include + +#include +#include + +const uint8_t kplugin_klinfix_major = 1; +const uint8_t kplugin_klinfix_minor = 0; + +int klix_ds_from_str(const char *text, sr_datastore_t *ds) +{ + size_t len = strlen(text); + + if (!strncmp("startup-config", text, len)) + *ds = SR_DS_STARTUP; + else if (!strncmp("running-config", text, len)) + *ds = SR_DS_RUNNING; + else if (!strncmp("candidate-config", text, len)) + *ds = SR_DS_CANDIDATE; + else if (!strncmp("operational-config", text, len)) + *ds = SR_DS_OPERATIONAL; + else if (!strncmp("factory-config", text, len)) + *ds = SR_DS_FACTORY_DEFAULT; + else + return -1; + + return 0; +} + +int klix_copy(kcontext_t *ctx) +{ + kpargv_t *pargv = kcontext_pargv(ctx); + sr_datastore_t srcds, dstds; + kparg_t *srcarg, *dstarg; + sr_session_ctx_t *sess; + sr_conn_ctx_t *conn; + int err; + + srcarg = kpargv_find(pargv, "src"); + dstarg = kpargv_find(pargv, "dst"); + if (!srcarg || !dstarg) + goto err; + + if (klix_ds_from_str(kparg_value(srcarg), &srcds)) { + fprintf(stderr, + "Error: \"%s\" is not the name of any known datastore\n", + kparg_value(srcarg)); + goto err; + } + if (klix_ds_from_str(kparg_value(dstarg), &dstds)) { + fprintf(stderr, + "Error: \"%s\" is not the name of any known datastore\n", + kparg_value(dstarg)); + goto err; + } + + switch (srcds) { + case SR_DS_STARTUP: + case SR_DS_RUNNING: + case SR_DS_FACTORY_DEFAULT: + break; + default: + fprintf(stderr, + "Error: \"%s\" is not a valid source datastore\n", + kparg_value(srcarg)); + goto err; + } + + switch (dstds) { + case SR_DS_STARTUP: + case SR_DS_RUNNING: + break; + default: + fprintf(stderr, + "Error: \"%s\" is not a valid destination datastore\n", + kparg_value(dstarg)); + goto err; + } + + if (sr_connect(SR_CONN_DEFAULT, &conn)) { + fprintf(stderr, "Error: Connection to datastore failed\n"); + goto err; + } + if (sr_session_start(conn, dstds, &sess)) { + fprintf(stderr, "Error: Unable to open transaction to %s\n", + kparg_value(dstarg)); + goto err_disconnect; + } + + err = sr_copy_config(sess, NULL, srcds, 0); + if (err) { + fprintf(stderr, "Error: Unable to copy configuration (%d)\n", + err); + goto err_disconnect; + } + + sr_disconnect(conn); + return 0; + +err_disconnect: + sr_disconnect(conn); +err: + return -1; +} + +int klix_commit(kcontext_t *ctx) +{ + sr_session_ctx_t *sess; + sr_conn_ctx_t *conn; + int err; + + if (sr_connect(SR_CONN_DEFAULT, &conn)) { + fprintf(stderr, "Error: Connection to datastore failed\n"); + goto err; + } + + if (sr_session_start(conn, SR_DS_RUNNING, &sess)) { + fprintf(stderr, + "Error: Unable to open transaction to running-config\n"); + goto err_disconnect; + } + + err = sr_copy_config(sess, NULL, SR_DS_CANDIDATE, 0); + if (err) { + fprintf(stderr, + "Error: Unable to commit candidate to running (%d)\n", + err); + goto err; + } + + sr_disconnect(conn); + return 0; + +err_disconnect: + sr_disconnect(conn); +err: + return -1; +} + +int kplugin_klinfix_fini(kcontext_t *ctx) +{ + return 0; +} + +int kplugin_klinfix_init(kcontext_t *ctx) +{ + kplugin_t *plugin = kcontext_plugin(ctx); + + kplugin_add_syms(plugin, ksym_new("klix_copy", klix_copy)); + kplugin_add_syms(plugin, ksym_new("klix_commit", klix_commit)); + return 0; +} diff --git a/src/klinfix/xml/Makefile.am b/src/klinfix/xml/Makefile.am new file mode 100644 index 00000000..1bd6bfa9 --- /dev/null +++ b/src/klinfix/xml/Makefile.am @@ -0,0 +1,2 @@ +klishconfdir = $(KLISHCONFDIR) +klishconf_DATA = $(wildcard *.xml) diff --git a/src/klinfix/xml/infix.xml b/src/klinfix/xml/infix.xml new file mode 100644 index 00000000..927ff1dc --- /dev/null +++ b/src/klinfix/xml/infix.xml @@ -0,0 +1,215 @@ + + + + + + + + + ShowBrackets = y + ShowSemicolons = y + FirstKeyWithStatement = n + MultiKeysWithStatement = y + Colorize = y + Indent = 2 + + + + + factory-config + startup-config + running-config + + + + + + + startup-config + running-config + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %u@%h:exec> + + + + /bin/sh -l + + + + pop + + + pop + + + + replace configure + + + + + + + + + + + + + + + + + + + + + %u@%h:configure> + + + + + + + + + + + replace main + + + + + replace main + + + + + + replace main + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/net/.gitignore b/src/net/.gitignore new file mode 100644 index 00000000..5166df2d --- /dev/null +++ b/src/net/.gitignore @@ -0,0 +1,2 @@ +*.o +net diff --git a/src/net/Makefile b/src/net/Makefile new file mode 100644 index 00000000..5c14a66e --- /dev/null +++ b/src/net/Makefile @@ -0,0 +1,14 @@ +LDLIBS = -lite +EXEC = net + +net: main.o + $(CC) -o $@ $^ $(LDLIBS) + +check: $(EXEC) + ./test.sh + +clean: + $(RM) net + +distclean: clean + $(RM) *.o *~ diff --git a/src/net/README.md b/src/net/README.md new file mode 100644 index 00000000..55625148 --- /dev/null +++ b/src/net/README.md @@ -0,0 +1,158 @@ +net - an iproute2 wrapper +========================= + +The net tool is a wrapper around the iproute2 and ethtool programs to +set up networking on a Linux system. It also handles transitions from +a previously configured state to the next while attempting to keep the +amount of changes needed to a minimum. + + +Concept Overview +---------------- + +net applies a configuration from `/run/net/next`, where `next` is a file +that holds the number of the current generation. It is up to the user, +i.e., sysrepo, to create the below tree structure with commands to run. + +The setup we start with and later move `eth4` from `lag0` to `br0`. + + vlan1 + ______/____ + [____br0____] + / / \ \ + eth1 eth2 eth3 lag0 + / \ + eth4 eth5 + +Consider the case when `next` contains `0`, net reads all interfaces, in +dependency order, from `/run/net/0/` running all `ip-link` and `ip-addr` +commands. When done, it writes `0` to the file `/run/net/gen` and then +removes the `next` file to confirm the generation has been activated. + +**Note:** it is currently up to the user to remove any old generation. + + /run/net/0/ + |-- lo/ + | |-- deps/ + | |-- ip-link.up + | `-- ip-addr.up + |-- br0/ + | |-- deps/ + | | |-- eth1 -> ../../eth1 + | | |-- eth2 -> ../../eth2 + | | |-- eth3 -> ../../eth3 + | | `-- lag0 -> ../../lag0 + | |-- ip-link.up + | `-- ip-addr.up + |-- eth0/ + | |-- deps/ + | |-- ip-link.up + | `-- ip-addr.up + |-- ethX/ + | |-- ... + : : + |-- lag0/ + | |-- deps/ + | | |-- eth4 -> ../../eth4 + | | `-- eth5 -> ../../eth5 + | |-- ip-link.up + | `-- ip-addr.up + `-- vlan1/ + |-- deps/ + | `-- br0 -> ../../br0 + |-- ip-link.up + `-- ip-addr.up + +The `deps/` sub-directory for each of the interfaces contains symlinks +to any interfaces this interface may depend on. I.e., those interfaces +are evaluated first. + +Essentially, all leaves must be set up before their parents. Moving a +leaf from one parent to another, e.g., from lag0 to br0, is tricky, it +involves traversing the previous dependency order when removing leaves, +and traversing the next dependency order when addning, see next section +for an example. + + +Example +------- + +net is built to complement sysrepo. The idea is to listen to any added, +deleted, modified states in sysrepo changes to a candidate configuration +and generate the `next` generation. However, as mentioned previously, +when moving leaves between parents we must do so in the dependency order +of the current generation. + +So, the user (sysrepo) needs to add `.dn` scripts in the current tree, +and `.up` scripts in the next. + +In our example, interface `eth4` is moved from `lag0` to `br0`, so we +need to run `eth4/ip-link.dn` in the current generation first to remove +`eth4` from `lag0` before its `ip-link.up` script in the next generation +sets `eth4` as a bridge member instead. + +We traverse the current generation and execute all `.dn` scripts: + + /run/net// + |-- lo/ + | `-- deps/ + |-- br0/ + | |-- deps/ + | | |-- eth1 -> ../../eth1 + | | |-- eth2 -> ../../eth2 + | | |-- eth3 -> ../../eth3 + | | `-- lag0 -> ../../lag0 + | `-- ip-link.up + |-- eth0/ + | |-- deps/ + | |-- ip-link.up + | `-- ip-addr.up + |-- eth4/ + | |-- deps/ + | |-- ip-link.dn + | `-- ip-link.up + |-- lag0/ + | |-- deps/ + | | |-- eth4 -> ../../eth4 + | | `-- eth5 -> ../../eth5 + | `-- ip-link.up + `-- vlan1/ + |-- deps/ + | `-- br0 -> ../../br0 + |-- ip-link.up + `-- ip-addr.up + +Now we can run all the `.up` scripts in the next generation: + + /run/net// + |-- lo/ + | |-- deps/ + | |-- ip-link.up + | `-- ip-addr.up + |-- br0/ + | |-- deps/ + | | |-- eth1 -> ../../eth1 + | | |-- eth2 -> ../../eth2 + | | |-- eth3 -> ../../eth3 + | | |-- eth4 -> ../../eth4 + | | `-- lag0 -> ../../lag0 + | `-- ip-link.up + |-- eth0/ + | |-- deps/ + | |-- ip-link.up + | `-- ip-addr.up + |-- eth4/ + | |-- deps/ + | |-- ip-link.dn + | `-- ip-link.up + |-- lag0/ + | |-- deps/ + | | `-- eth5 -> ../../eth5 + | `-- ip-link.up + `-- vlan1/ + |-- deps/ + | `-- br0 -> ../../br0 + |-- ip-link.up + `-- ip-addr.up + + diff --git a/src/net/main.c b/src/net/main.c new file mode 100644 index 00000000..8b0943c8 --- /dev/null +++ b/src/net/main.c @@ -0,0 +1,222 @@ +#include +#include +#include +#include +#include +#include + +#define _PATH_NET "/run/net" +#define DEBUG 0 +#define dbg(fmt, args...) if (DEBUG) warnx(fmt, ##args) + +static char **handled; +static int if_num; + + +static void if_alloc(int num) +{ + handled = calloc(num, sizeof(char *)); + if (!handled) + err(1, "calloc"); + if_num = num; +} + +static void if_free() +{ + for (int i = 0; i < if_num; i++) { + if (handled[i]) + free(handled[i]); + } + free(handled); +} + +static void if_done(char *ifname) +{ + for (int i = 0; i < if_num; i++) { + if (handled[i]) { + if (strcmp(handled[i], ifname)) + continue; + return; + } + handled[i] = strdup(ifname); + break; + } +} + +static int if_find(char *ifname) +{ + for (int i = 0; i < if_num; i++) { + if (handled[i] && !strcmp(handled[i], ifname)) + return 1; + } + return 0; +} + +static int deps(char *ipath, char *ifname, const char *action) +{ + char path[strlen(ipath) + 42]; + int num, rc = -1; + char **files; + char *cmd; + + snprintf(path, sizeof(path), "%s/deps", ipath); + num = dir(path, NULL, NULL, &files, 0); + for (int i = 0; i < num; i++) { + char dpath[sizeof(path) + strlen(files[i])]; + char *ifnm = files[i]; + char *rp; + + snprintf(dpath, sizeof(dpath), "%s/%s", path, ifnm); + rp = realpath(dpath, NULL); + if (!rp) + continue; + + deps(rp, ifnm, action); + free(ifnm); + free(rp); + } + + if (if_find(ifname)) + return 0; + + snprintf(path, sizeof(path), "%s/%s", ipath, action); + cmd = realpath(path, NULL); + if (!cmd || access(cmd, X_OK)) { + if (errno == ENOENT) + rc = 0; /* no action for this interface */ + goto done; + } + + rc = systemf("%s", cmd); +done: + free(cmd); + if_done(ifname); + + return rc; +} + +static int iter(char *path, size_t len, const char *action) +{ + char **files; + int rc = 0; + int num; + + num = dir(path, NULL, NULL, &files, 0); + if_alloc(num); + + for (int j = 0; j < num; j++) { + char *ifname = files[j]; + char ipath[len]; + + snprintf(ipath, sizeof(ipath), "%s/%s", path, ifname); + dbg("Calling deps(%s, %s, %s)", ipath, ifname, action); + rc += deps(ipath, ifname, action); + free(ifname); + } + + if_free(); + + return rc; +} + +static int deactivate(const char *net, char *gen) +{ + char path[strlen(net) + strlen(gen) + 5 + IFNAMSIZ]; + char *action[] = { + "ip-addr.dn", + "ip-link.dn", + }; + int rc = 0; + + snprintf(path, sizeof(path), "%s/%s", net, gen); + for (size_t i = 0; i < NELEMS(action); i++) + rc += iter(path, sizeof(path), action[i]); + + return rc; +} + +static int activate(const char *net, char *gen) +{ + char path[strlen(net) + strlen(gen) + 5 + IFNAMSIZ]; + char *action[] = { + "ip-link.up", + "ip-addr.up", + }; + int rc = 0; + + snprintf(path, sizeof(path), "%s/%s", net, gen); + for (size_t i = 0; i < NELEMS(action); i++) + rc += iter(path, sizeof(path), action[i]); + + return rc; +} + +static int load_gen(const char *net, char *gen, char *buf, size_t len) +{ + FILE *fp; + + fp = fopenf("r", "%s/%s", net, gen); + if (!fp) + return EX_OSFILE; + if (!fgets(buf, len, fp)) + return EX_IOERR; + fclose(fp); + chomp(buf); + + return 0; +} + +static int save_gen(const char *net, char *gen, char *buf) +{ + FILE *fp; + + fp = fopenf("w", "%s/%s", net, gen); + if (!fp) + return -1; + fprintf(fp, "%s\n", buf); + fclose(fp); + + return 0; +} + +int main(void) +{ + const char *net = _PATH_NET; + char curr[512], next[512]; + int rc; + + if (getenv("NET_DIR")) + net = getenv("NET_DIR"); + if (access(net, X_OK)) { + if (makedir(net, 0755)) + err(1, "makedir"); + } + + if ((rc = load_gen(net, "next", next, sizeof(next)))) { + if (rc == EX_IOERR) + warnx("missing next generation"); + exit(0); /* nothing to do */ + } + + if ((rc = load_gen(net, "gen", curr, sizeof(curr)))) { + if (rc == EX_IOERR) + errx(rc, "missing current generation"); + /* no current generation */ + } else { + rc = deactivate(net, curr); + if (rc) + err(1, "failed deactivating current generation"); + } + + rc = activate(net, next); + if (rc) + err(1, "failed activating next generation"); + + if (save_gen(net, "gen", next)) + err(1, "next generation applied, failed current"); + + if (fremove("%s/next", net)) + err(1, "failed removing %s/next", net); + + return 0; +} diff --git a/src/net/test.sh b/src/net/test.sh new file mode 100755 index 00000000..c008f527 --- /dev/null +++ b/src/net/test.sh @@ -0,0 +1,101 @@ +#!/bin/sh +# Generate test directory structure for verifying the net tool +set -e + +NET_DIR=/tmp/net +export NET_DIR + +gensh() +{ + cat <<-EOF >"$1" + #!/bin/sh + echo "Running \$0 ..." + EOF + chmod +x "$1" +} + +check() +{ + if ./net; then + printf "\n[\033[1;32m OK \033[0m] Checking %s\n" "$1" + return 0 + fi + + printf "\n[\033[1;31FAIL\033[0m] Checking %s\n" "$1" + return 1 +} + +echo "Verify that all leaves and dependencies are" +echo "evaluated first:" +echo " vlan1" +echo " ______/____" +echo " [____br0____]" +echo " / / \\ \\" +echo "lo eth0 eth1 eth2 eth3 lag0" +echo " / \\" +echo " eth4 eth5" +printf "_______________________________________________\n\n" + +mkdir -p $NET_DIR/0 +echo 0 > $NET_DIR/next + +mkdir -p $NET_DIR/0/lo/deps +gensh $NET_DIR/0/lo/ip-link.up + +mkdir -p $NET_DIR/0/eth0/deps +mkdir -p $NET_DIR/0/eth1/deps +mkdir -p $NET_DIR/0/eth2/deps +mkdir -p $NET_DIR/0/eth3/deps +mkdir -p $NET_DIR/0/eth4/deps + +gensh $NET_DIR/0/eth0/ip-link.up +gensh $NET_DIR/0/eth1/ip-link.up +gensh $NET_DIR/0/eth2/ip-link.up +gensh $NET_DIR/0/eth3/ip-link.up +gensh $NET_DIR/0/eth4/ip-link.up + +mkdir -p $NET_DIR/0/lag0/deps +ln -sf ../../eth3 $NET_DIR/0/lag0/deps/ +ln -sf ../../eth4 $NET_DIR/0/lag0/deps/ +gensh $NET_DIR/0/lag0/ip-link.up + +mkdir -p $NET_DIR/0/br0/deps +ln -sf ../../eth1 $NET_DIR/0/br0/deps/ +ln -sf ../../eth2 $NET_DIR/0/br0/deps/ +ln -sf ../../lag0 $NET_DIR/0/br0/deps/ +gensh $NET_DIR/0/br0/ip-link.up + +mkdir -p $NET_DIR/0/vlan1/deps +ln -sf ../../br0 $NET_DIR/0/vlan1/deps/ +gensh $NET_DIR/0/vlan1/ip-link.up + +check "initial startup, gen 0" + +printf "_______________________________________________\n\n" +mkdir -p $NET_DIR/1 + +mkdir -p $NET_DIR/1/lo/deps +mkdir -p $NET_DIR/1/eth0/deps +mkdir -p $NET_DIR/1/eth1/deps +mkdir -p $NET_DIR/1/eth2/deps +mkdir -p $NET_DIR/1/eth3/deps +mkdir -p $NET_DIR/1/eth4/deps + +mkdir -p $NET_DIR/1/lag0/deps +ln -sf ../../eth4 $NET_DIR/1/lag0/deps/ + +mkdir -p $NET_DIR/1/br0/deps +ln -sf ../../eth1 $NET_DIR/1/br0/deps/ +ln -sf ../../eth2 $NET_DIR/1/br0/deps/ +ln -sf ../../eth3 $NET_DIR/1/br0/deps/ + +mkdir -p $NET_DIR/1/vlan1/deps +ln -sf ../../br0 $NET_DIR/1/vlan1/deps/ + +gensh $NET_DIR/0/eth3/ip-link.dn +gensh $NET_DIR/1/eth3/ip-link.up +echo 1 > $NET_DIR/next + +check "move eth3 from lag0 to br0" + +exit 0