├── test ├── bin │ ├── dhcpcd-mock │ ├── nsupdate-mock │ ├── radvd-trigger │ ├── rdisc6-mock │ ├── systemctl-mock │ ├── resolvconf-mock │ ├── resolvectl-mock │ ├── systemd-run-mock │ ├── dhclient-mock │ ├── dummy-mock │ └── dig-mock ├── conf │ ├── ipv6-prefix-wan1.conf │ ├── ipv6-prefix-eth3-from-wan0.conf │ ├── ipv6-prefix-wan2.conf │ ├── ddns-br1-from-wan1.conf │ ├── ddns-eth0.conf │ ├── ddns-br1-from-wan0.conf │ ├── ddns-eth0-from-eth0.conf │ ├── ipv6-prefix-br0-from-wan0.conf │ ├── nm-ddns-br1-from-xxx.conf │ ├── test-ddns.conf │ ├── ipv6-prefix-br1-from-wan0.conf │ ├── ddns-eth1.conf │ ├── nm-ddns-eth0.conf │ ├── testweb-ddns.conf │ ├── ip-mock-monitor │ ├── 4-ip-mock-addrs │ ├── 3-radvd.conf.templ │ ├── 2-ip-mock-addrs │ ├── 1-ip-mock-addrs │ ├── 3-ip-mock-addrs │ ├── 2-radvd.conf.templ │ ├── 1-radvd.conf.templ │ ├── 4-radvd.conf.templ │ ├── 4-radvd.conf │ ├── radvd-gen.conf │ ├── dig-mock-names │ ├── common.conf │ ├── ip-mock-routes │ ├── ip-mock-addrs │ ├── general.conf │ ├── nmg_xtest │ └── xtest_setup ├── expected │ ├── 1-radvd.conf │ ├── 4-radvd.conf │ ├── 3-radvd.conf │ └── 2-radvd.conf ├── radvd-test ├── Makefile ├── nm-ddns-test ├── ipv6-prefix-addr-test └── ddns-test ├── etc ├── NetworkManager │ └── dispatcher.d │ │ ├── pre-down.d │ │ ├── 08-ipv6-prefix │ │ └── 96-interface-action │ │ ├── 96-interface-action │ │ ├── 90-transmission │ │ └── 09-ddns ├── systemd │ └── system │ │ ├── ddns-onboot@.timer │ │ └── ddns-onboot@.service └── nmutils │ ├── dispatcher_action │ ├── ipv6_utils.sh │ └── ddns-functions ├── .gitignore ├── examples ├── simple │ ├── radvd.conf.templ │ ├── ifa99-rsyslog-eth0.conf │ └── ipv6-prefix-eth0.conf └── complex │ ├── general.conf │ ├── radvd-gen.conf │ ├── ipv6-prefix-eth1-from-eth0.conf │ ├── ipv6-prefix-eth2-from-eth0.conf │ ├── ddns-eth1-from-eth0.conf │ ├── ddns-eth1.conf │ ├── ddns-eth0-from-eth0.conf │ ├── radvd.conf.templ │ ├── ifa50-mylogger-eth1.conf │ ├── ddns-eth0.conf │ └── ipv6-prefix-eth0.conf ├── meson_options.txt ├── selinux ├── GNUmakefile ├── nmutils.te └── nmutils.fc ├── NEWS.md ├── GNUmakefile ├── nmutils.spec ├── meson.build ├── LICENSE.LGPLv3 └── README.md /test/bin/dhcpcd-mock: -------------------------------------------------------------------------------- 1 | dummy-mock -------------------------------------------------------------------------------- /test/bin/nsupdate-mock: -------------------------------------------------------------------------------- 1 | dummy-mock -------------------------------------------------------------------------------- /test/bin/radvd-trigger: -------------------------------------------------------------------------------- 1 | dummy-mock -------------------------------------------------------------------------------- /test/bin/rdisc6-mock: -------------------------------------------------------------------------------- 1 | dummy-mock -------------------------------------------------------------------------------- /test/bin/systemctl-mock: -------------------------------------------------------------------------------- 1 | dummy-mock -------------------------------------------------------------------------------- /test/bin/resolvconf-mock: -------------------------------------------------------------------------------- 1 | dummy-mock -------------------------------------------------------------------------------- /test/bin/resolvectl-mock: -------------------------------------------------------------------------------- 1 | dummy-mock -------------------------------------------------------------------------------- /test/bin/systemd-run-mock: -------------------------------------------------------------------------------- 1 | dummy-mock -------------------------------------------------------------------------------- /etc/NetworkManager/dispatcher.d/pre-down.d/08-ipv6-prefix: -------------------------------------------------------------------------------- 1 | ../08-ipv6-prefix -------------------------------------------------------------------------------- /etc/NetworkManager/dispatcher.d/pre-down.d/96-interface-action: -------------------------------------------------------------------------------- 1 | ../96-interface-action -------------------------------------------------------------------------------- /test/conf/ipv6-prefix-wan1.conf: -------------------------------------------------------------------------------- 1 | # for ipv6-prefix-nm-test 2 | # shellcheck shell=bash disable=SC2034 3 | WAN_LAN_INTFS="br1" 4 | -------------------------------------------------------------------------------- /test/conf/ipv6-prefix-eth3-from-wan0.conf: -------------------------------------------------------------------------------- 1 | # used by ipv6-prefix-dhclient-test 2 | # shellcheck shell=bash disable=SC2034 3 | LAN_NODE=1 -------------------------------------------------------------------------------- /test/conf/ipv6-prefix-wan2.conf: -------------------------------------------------------------------------------- 1 | # for ipv6-prefix-nm-test 2 | # shellcheck shell=bash disable=SC2034 3 | WAN_LAN_INTFS="br1" 4 | WAN_DHCPCD_ARGS=(-E -d) 5 | -------------------------------------------------------------------------------- /test/conf/ddns-br1-from-wan1.conf: -------------------------------------------------------------------------------- 1 | # for ipv6-prefix-nm-test 2 | # shellcheck shell=bash disable=SC2034 3 | DDNS_ZONE=example.test 4 | DDNS_RREC_AAAA_NAME=br1-w1.example.test 5 | -------------------------------------------------------------------------------- /test/conf/ddns-eth0.conf: -------------------------------------------------------------------------------- 1 | # test config for ddns-test helper 2 | # shellcheck shell=bash disable=SC2034 3 | DDNS_ZONE=example.test 4 | DDNS_RREC_AAAA_NAME=www.example.test 5 | -------------------------------------------------------------------------------- /test/conf/ddns-br1-from-wan0.conf: -------------------------------------------------------------------------------- 1 | # for ipv6-prefix-dhclient-test 2 | # shellcheck shell=bash disable=SC2034 3 | DDNS_ZONE=example.test 4 | DDNS_RREC_AAAA_NAME=home.example.test 5 | -------------------------------------------------------------------------------- /test/conf/ddns-eth0-from-eth0.conf: -------------------------------------------------------------------------------- 1 | # for ipv6-prefix-dhclient-test 2 | # shellcheck shell=bash disable=SC2034 3 | DDNS_ZONE=example.test 4 | DDNS_RREC_AAAA_NAME=eth0.example.test 5 | -------------------------------------------------------------------------------- /test/conf/ipv6-prefix-br0-from-wan0.conf: -------------------------------------------------------------------------------- 1 | # for ipv6-prefix-dhclient-test 2 | # shellcheck shell=bash disable=SC2034 3 | # pspace=56, site=0 4 | LAN_SITE=ab80 5 | LAN_PREFIX_LEN=63 6 | -------------------------------------------------------------------------------- /test/conf/nm-ddns-br1-from-xxx.conf: -------------------------------------------------------------------------------- 1 | # test config for nm-ddns-test 2 | # shellcheck shell=bash disable=SC2034 3 | DDNS_ZONE=example.test 4 | DDNS_RREC_AAAA_NAME=dns2.example.test 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .*.sw? 3 | *.bak 4 | *.tgz 5 | *.tar.gz 6 | *.rpm 7 | /test/run/ 8 | /test/results/ 9 | /selinux/nmutils.if 10 | /selinux/nmutils.pp* 11 | /selinux/tmp/ 12 | /build/ 13 | -------------------------------------------------------------------------------- /test/conf/test-ddns.conf: -------------------------------------------------------------------------------- 1 | # test config for ddns-test ddns 2 | # shellcheck shell=bash disable=SC2034 3 | DDNS_ZONE=example.test 4 | DDNS_RREC_A_PRIVATE=1 5 | DDNS_RREC_A_NAME=www.example.test 6 | -------------------------------------------------------------------------------- /test/conf/ipv6-prefix-br1-from-wan0.conf: -------------------------------------------------------------------------------- 1 | # for ipv6-prefix-dhclient-test 2 | # pspace=64, site=2 - addrs in ip-mock for ddns 3 | # shellcheck shell=bash disable=SC2034 4 | LAN_SITE=2 5 | LAN_PREFIX_LEN=64 6 | -------------------------------------------------------------------------------- /etc/systemd/system/ddns-onboot@.timer: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Activate DDNS after boot 3 | 4 | [Timer] 5 | OnActiveSec=45 6 | RemainAfterElapse=no 7 | 8 | [Install] 9 | WantedBy=named.service 10 | 11 | -------------------------------------------------------------------------------- /test/conf/ddns-eth1.conf: -------------------------------------------------------------------------------- 1 | # test config for ddns-test helper 2 | # shellcheck shell=bash disable=SC2034 3 | DDNS_SERVER=home.test 4 | DDNS_ZONE=home.test 5 | DDNS_RREC_A_NAME=gateway.home.test 6 | DDNS_RREC_A_PRIVATE=1 -------------------------------------------------------------------------------- /test/conf/nm-ddns-eth0.conf: -------------------------------------------------------------------------------- 1 | # test config for nm-ddns-test 2 | # shellcheck shell=bash disable=SC2034 3 | DDNS_ZONE=example.test 4 | DDNS_RREC_A_NAME=dns.example.test 5 | DDNS_RREC_A_PRIVATE=1 6 | DDNS_RREC_AAAA_NAME=dns.example.test 7 | -------------------------------------------------------------------------------- /test/conf/testweb-ddns.conf: -------------------------------------------------------------------------------- 1 | # test config for ddns-test helper 2 | # shellcheck shell=bash disable=SC2034 3 | DDNS_ZONE=example.test 4 | DDNS_RREC_A_NAME=web.example.test 5 | DDNS_RREC_AAAA_NAME=web.example.test 6 | DDNS_RREC_TXT_NAME=web.example.test 7 | DDNS_RREC_TXT_VALUE="replacement txt" 8 | 9 | -------------------------------------------------------------------------------- /test/conf/ip-mock-monitor: -------------------------------------------------------------------------------- 1 | ADDR6: 13: eth1 2001:db8:a0b:12f0::1/64 scope global tentative 2 | ADDR6: valid_lft forever preferred_lft forever 3 | ROUTE6: local 2001:db8:a0b:12f0::1 dev eth1 table local proto kernel metric 0 pref medium 4 | ROUTE6: fd66:7777:7777::1 dev eth1 proto kernel metric 256 pref medium 5 | SLEEP: 5 6 | -------------------------------------------------------------------------------- /etc/systemd/system/ddns-onboot@.service: -------------------------------------------------------------------------------- 1 | # 2 | # ddns-onboot.service 3 | # 4 | # systemd service to trigger ddns-onboot 5 | # 6 | [Unit] 7 | Description=Set addresses in Bind from interface %I 8 | After=nss-lookup.target 9 | 10 | [Service] 11 | Type=oneshot 12 | ExecStart=/etc/NetworkManager/dispatcher.d/09-ddns direct %I 13 | 14 | [Install] 15 | WantedBy=multi-user.target 16 | -------------------------------------------------------------------------------- /test/conf/4-ip-mock-addrs: -------------------------------------------------------------------------------- 1 | dev eth0 9000 2 | addr 192.168.10.4/24 8600sec 2400sec 3 | addr6 fda5:3d6f:2bc7:203d:1c52:4ac2:27ff:fe1b/64 3600sec 1800sec global noprefixroute 4 | addr6 fe80::a00:27ff:fe1b:ff9a/64 forever forever link 5 | dev eth1 6 | addr 10.0.10.12/24 forever forever 7 | addr6 fdac:3741:50f8:f623::1/48 86400sec 14400sec global 8 | addr6 fe80::31fd:68fd:ed8b:4d77/64 forever forever link 9 | -------------------------------------------------------------------------------- /test/conf/3-radvd.conf.templ: -------------------------------------------------------------------------------- 1 | interface eth0 2 | { 3 | AdvDefaultLifetime @ROUTER_LIFETIME@; 4 | AdvSendAdvert on; 5 | MinRtrAdvInterval 30; 6 | # should match 2 additional 7 | @PREFIX@ 8 | }; 9 | interface eth1 10 | { 11 | AdvSendAdvert on; 12 | MinRtrAdvInterval 30; 13 | # prefix wired, no options 14 | prefix fdac:3741:50f8::/48; 15 | # should match 1 additional 16 | @PREFIX@; 17 | }; 18 | -------------------------------------------------------------------------------- /examples/simple/radvd.conf.templ: -------------------------------------------------------------------------------- 1 | # 2 | # radvd template used by 95-radvd-gen 3 | # 4 | # See /etc/NetworkManager/dispatcher.d/95-radvd-gen for docs 5 | # 6 | # Unlike other configurations in this directory, place this file in 7 | # /etc/NetworkManager 8 | # 9 | # @PREFIX@ will be replaced with any ipv6 prefixes on interface eth1 10 | # 11 | interface eth1 12 | { 13 | @PREFIX@ { 14 | DecrementLifetimes on; 15 | }; 16 | }; 17 | -------------------------------------------------------------------------------- /test/conf/2-ip-mock-addrs: -------------------------------------------------------------------------------- 1 | dev eth0 2 | addr 192.168.10.4/24 8600sec 2400sec 3 | addr6 2001:0db8:871a:00c1::1/64 86400sec 14400sec 4 | addr6 fda5:3d6f:1000:203d::fe1b/64 3600sec 1800sec global noprefixroute 5 | addr6 fe80::a00:27ff:fe1b:ff9a/64 forever forever link 6 | dev eth1 7 | addr 10.0.10.12/24 forever forever 8 | addr6 2001:db8:a0b:12f0::1/64 86400sec 14400sec 9 | addr6 fdac:3741:50f8:f623::1/64 86400sec 14400sec global 10 | addr6 fe80::31fd:68fd:ed8b:4d77/64 forever forever link 11 | -------------------------------------------------------------------------------- /test/conf/1-ip-mock-addrs: -------------------------------------------------------------------------------- 1 | dev eth0 9000 2 | addr 192.168.66.4/24 8600sec 2400sec 3 | addr6 2001:db8:871a:28c1::1/64 86400sec 14400sec 4 | addr6 fda5:3d6f:2bc7:203d:1c52:4ac2:27ff:fe1b/64 3600sec 1800sec global noprefixroute 5 | addr6 fe80::a00:27ff:fe1b:ff9a/64 forever forever link 6 | dev eth1 7 | addr 10.0.10.12/24 forever forever 8 | addr6 2001:db8:a0b:12f0::1/64 86400sec 14400sec 9 | addr6 fdac:3741:50f8:f623::1/48 86400sec 14400sec global 10 | addr6 fe80::31fd:68fd:ed8b:4d77/64 forever forever link 11 | -------------------------------------------------------------------------------- /test/conf/3-ip-mock-addrs: -------------------------------------------------------------------------------- 1 | dev eth0 9000 2 | addr 192.168.66.4/24 8600sec 2400sec 3 | addr6 2001:db8:871a:28c1::1/64 86400sec 14400sec 4 | addr6 fda5:3d6f:2bc7:203d:1c52:4ac2:27ff:fe1b/64 3600sec 1800sec global noprefixroute 5 | addr6 fe80::a00:27ff:fe1b:ff9a/64 forever forever link 6 | dev eth1 7 | addr 10.0.10.12/24 forever forever 8 | addr6 2001:db8:a0b:12f0::1/64 86400sec 14400sec 9 | addr6 fdac:3741:50f8:f623::1/48 86400sec 14400sec global 10 | addr6 fe80::31fd:68fd:ed8b:4d77/64 forever forever link 11 | -------------------------------------------------------------------------------- /examples/simple/ifa99-rsyslog-eth0.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Configuration for 96-interface-action 3 | # 4 | # Named: ifa99-rsyslog-eth0.conf 5 | # 6 | # Pattern: ifa##--.conf 7 | # 8 | # See /etc/NetworkManager/dispatcher.d/96-interface-action for docs 9 | # 10 | 11 | # Config with restart `rsyslog` whenever the `eth0` interface is brought up, 12 | # ordered 99 (after other 96-interface-action configs) 13 | # 14 | # Useful when a UDP listener doesn't have netlink support 15 | # 16 | CMD_UP=on 17 | -------------------------------------------------------------------------------- /test/conf/2-radvd.conf.templ: -------------------------------------------------------------------------------- 1 | interface eth0 2 | { 3 | AdvSendAdvert on; 4 | MinRtrAdvInterval 30; 5 | # address not wired 6 | prefix fda5:0000:2bc7:203d::/64 { 7 | AdvAutonomous off; 8 | }; 9 | # should match multiple prefixes 10 | @PREFIX@ { 11 | AdvAutonomous on; 12 | # Comment in dynamic 13 | AdvPreferredLifetime 300; 14 | AdvValidLifetime 100; 15 | }; 16 | }; 17 | interface eth1 18 | { 19 | AdvSendAdvert on; 20 | # empty saved, should match 2 21 | @PREFIX@ { 22 | }; 23 | }; 24 | -------------------------------------------------------------------------------- /examples/simple/ipv6-prefix-eth0.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Configuration for 08-ipv6-prefix 3 | # 4 | # Named: ipv6-prefix-eth0.conf 5 | # 6 | # Pattern: ipv6-prefix-.conf 7 | # 8 | # Simplest setup to assign an ipv6 sub-prefix (/64 by default) to a LAN 9 | # interface (`eth1` below) from the prefix delegated to WAN 10 | # (`eth0` in the file name) 11 | # 12 | # See /etc/NetworkManager/dispatcher.d/08-ipv6-prefix for docs 13 | # 14 | 15 | # WAN_LAN_INTFS contains a space-separated list of LAN interfaces 16 | # to receive sub-prefixes 17 | WAN_LAN_INTFS="eth1" 18 | -------------------------------------------------------------------------------- /test/conf/1-radvd.conf.templ: -------------------------------------------------------------------------------- 1 | interface eth0 2 | { 3 | AdvSendAdvert on; 4 | MinRtrAdvInterval 30; 5 | # prefix not wired 6 | prefix fda5:0000:2bc7:203d::/64; 7 | # prefix match wired 8 | prefix fda5:3d6f:2bc7:203d::/64 { 9 | route fddd:1000:0:1234/64 { 10 | RemoveRoute on; 11 | }; 12 | AdvAutonomous off; 13 | AdvPreferredLifetime 600; 14 | }; 15 | # should match 1 additional 16 | @PREFIX@ { 17 | DNSSL example.test { 18 | AdvDNSSLLifetime 60; 19 | }; 20 | AdvPreferredLifetime 300; 21 | AdvValidLifetime 100; 22 | }; 23 | }; 24 | # end? -------------------------------------------------------------------------------- /test/conf/4-radvd.conf.templ: -------------------------------------------------------------------------------- 1 | interface eth0 2 | { 3 | AdvDefaultLifetime @ROUTER_LIFETIME@; 4 | AdvSendAdvert on; 5 | MinRtrAdvInterval 30; 6 | # should match 1 additional (and remove 1 from source conf) 7 | @PREFIX@ { 8 | AdvAutonomous on; 9 | DecrementLifetimes on; 10 | }; 11 | }; 12 | interface eth1 13 | { 14 | AdvSendAdvert on; 15 | MinRtrAdvInterval 30; 16 | # prefix wired, no options 17 | prefix fdac:3741:50f8::/48; 18 | # should remove existing source prefix as not wired 19 | @PREFIX@ { 20 | AdvValidLifetime 14400; 21 | AdvPreferredLifetime 86400; 22 | }; 23 | }; 24 | -------------------------------------------------------------------------------- /test/expected/1-radvd.conf: -------------------------------------------------------------------------------- 1 | interface eth0 2 | { 3 | AdvSendAdvert on; 4 | MinRtrAdvInterval 30; 5 | # prefix not wired 6 | prefix fda5:0000:2bc7:203d::/64; 7 | # prefix match wired 8 | prefix fda5:3d6f:2bc7:203d::/64 { 9 | route fddd:1000:0:1234/64 { 10 | RemoveRoute on; 11 | }; 12 | AdvAutonomous off; 13 | AdvPreferredLifetime 600; 14 | AdvValidLifetime 3600; 15 | }; 16 | # should match 1 additional 17 | prefix 2001:db8:871a:28c1::/64 { 18 | DNSSL example.test { 19 | AdvDNSSLLifetime 60; 20 | }; 21 | AdvPreferredLifetime 300; 22 | AdvValidLifetime 100; 23 | }; 24 | }; 25 | # end? 26 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | option('unitdir', type: 'string', value: 'auto', 2 | description: 'Directory for systemd service files, or "" to disable') 3 | option('runstatedir', type: 'string', value: '/run', 4 | description: 'Directory for transient runtime state') 5 | option('selinuxtype', type: 'string', value: 'auto', 6 | description: 'SELinux policy type (eg. targeted,mls...), or "" to disable') 7 | option('nmlibdir', type: 'string', value: '/usr/lib', 8 | description: 'NetworkManager system libdir') 9 | option('pkg', type: 'boolean', value: false, 10 | description: 'Patch paths for packaged install') 11 | -------------------------------------------------------------------------------- /selinux/GNUmakefile: -------------------------------------------------------------------------------- 1 | 2 | .SUFFIXES: 3 | .SUFFIXES: .pp .bz2 4 | 5 | V := 0 6 | VB_0 := @ 7 | VB := $(VB_$(V)) 8 | SELINUX_MAKE := /usr/share/selinux/devel/Makefile 9 | 10 | all: nmutils.pp.bz2 11 | 12 | nmutils.pp.bz2: selinux-devel nmutils.pp 13 | $(VB)rm -f "$@" 14 | bzip2 -k -9 nmutils.pp 15 | 16 | .PHONY: selinux-devel 17 | selinux-devel: 18 | $(VB)[ -f "$(SELINUX_MAKE)" ] || { \ 19 | echo "Install selinux-policy-devel before compiling policy"; \ 20 | false; } 21 | 22 | local_clean: 23 | $(VB)rm -f nmutils.pp.bz2 nmutils.if 24 | 25 | # clean defined in include, add dep 26 | clean: local_clean 27 | 28 | -include $(SELINUX_MAKE) 29 | -------------------------------------------------------------------------------- /test/expected/4-radvd.conf: -------------------------------------------------------------------------------- 1 | interface eth0 2 | { 3 | AdvDefaultLifetime 1800; 4 | AdvSendAdvert on; 5 | MinRtrAdvInterval 30; 6 | # should match 1 additional (and remove 1 from source conf) 7 | prefix fda5:3d6f:2bc7:203d::/64 { 8 | AdvValidLifetime 3600; 9 | AdvPreferredLifetime 1800; 10 | AdvAutonomous on; 11 | DecrementLifetimes on; 12 | }; 13 | }; 14 | interface eth1 15 | { 16 | AdvSendAdvert on; 17 | MinRtrAdvInterval 30; 18 | # prefix wired, no options 19 | prefix fdac:3741:50f8::/48 { 20 | AdvValidLifetime 86400; 21 | AdvPreferredLifetime 14400; 22 | }; 23 | # should remove existing source prefix as not wired 24 | }; 25 | -------------------------------------------------------------------------------- /examples/complex/general.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Optional overrides of global values 3 | # 4 | # See /etc/nmutils/general-functions for docs 5 | # 6 | 7 | # uncomment for command line debugging 8 | nmg_log_stderr=1 9 | nmg_show_debug=1 10 | 11 | # uncomment to disable commands that change things 12 | #nmg_dryrun=0 13 | 14 | # for systems without /run 15 | RUNDIR="/tmp/nmutils" 16 | 17 | # use single lockfile for everything... (default is ddns-*.conf file) 18 | DDNS_GLOBAL_LOCKFILE="/etc/named.conf" 19 | 20 | # longer timeouts for slow name servers 21 | DDNS_GLOBAL_DIG_TIMEOUT=15 22 | DDNS_GLOBAL_NSUPDATE_TIMEOUT=15 23 | DDNS_GLOBAL_NSUPDATE_OPTIONS="-v -k /etc/Kexample.net.+157+43833.private" 24 | -------------------------------------------------------------------------------- /examples/complex/radvd-gen.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Configuration for 95-radvd-gen 3 | # 4 | # See /etc/NetworkManager/dispatcher.d/95-radvd-gen for docs 5 | # 6 | # Unlike other configurations in this directory, place this file in 7 | # /etc/NetworkManager 8 | # 9 | 10 | # only regen radvd.conf from template if differences are 20% (default 10%) 11 | PERDIFF=20 12 | 13 | # override conf group 14 | RADVD_GROUP=wheel 15 | 16 | # set SELinux context 17 | RESTORECON_EXE="/usr/sbin/restorecon" 18 | 19 | # default for @ROUTER_LIFETIME@ if no dynamic prefixes 20 | ROUTER_DEFAULT_LIFETIME=900 21 | # override min/max defaults for @ROUTER_LIFETIME@ 22 | ROUTER_MIN_LIFETIME=900 23 | ROUTER_MAX_LIFETIME=3600 24 | 25 | # disable router test (always succeed) 26 | DEFROUTE_TEST= 27 | -------------------------------------------------------------------------------- /test/expected/3-radvd.conf: -------------------------------------------------------------------------------- 1 | interface eth0 2 | { 3 | AdvDefaultLifetime 9000; 4 | AdvSendAdvert on; 5 | MinRtrAdvInterval 30; 6 | # should match 2 additional 7 | prefix 2001:db8:871a:28c1::/64 { 8 | AdvValidLifetime 86400; 9 | AdvPreferredLifetime 14400; 10 | }; 11 | prefix fda5:3d6f:2bc7:203d::/64 { 12 | AdvValidLifetime 3600; 13 | AdvPreferredLifetime 1800; 14 | }; 15 | }; 16 | interface eth1 17 | { 18 | AdvSendAdvert on; 19 | MinRtrAdvInterval 30; 20 | # prefix wired, no options 21 | prefix fdac:3741:50f8::/48 { 22 | AdvValidLifetime 86400; 23 | AdvPreferredLifetime 14400; 24 | }; 25 | # should match 1 additional 26 | prefix 2001:db8:a0b:12f0::/64 { 27 | AdvValidLifetime 86400; 28 | AdvPreferredLifetime 14400; 29 | }; 30 | }; 31 | -------------------------------------------------------------------------------- /examples/complex/ipv6-prefix-eth1-from-eth0.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Optional LAN configuration for 08-ipv6-prefix 3 | # 4 | # See /etc/NetworkManager/dispatcher.d/08-ipv6-prefix for docs 5 | # 6 | # FILENAME: ipv6-prefix-eth1-from-eth0.conf 7 | # PATTERN: ipv6-prefix--from-.conf 8 | # 9 | # So below will affect eth1 (LAN) sub-prefix allocated from delegation 10 | # given to eth0 (WAN) 11 | # 12 | # eg: with 2001:db8:3311:aa00::/56 delegation on eth0, config would assign 13 | # 2001:db8:3311:aa00::4000/62 14 | # made from 15 | # 2001:db8:3311:aa - 56-bit delegation from DHCP 16 | LAN_PREFIX_LEN=62 17 | # LAN_PREFIX_LEN /62 18 | # LAN_SITE=auto 00:: - 6-bit (LAN_PREFIX_LEN - 56) auto-allocated site 19 | LAN_NODE=4000 20 | # LAN_NODE ::4000 21 | -------------------------------------------------------------------------------- /test/conf/4-radvd.conf: -------------------------------------------------------------------------------- 1 | interface eth0 2 | { 3 | AdvSendAdvert on; 4 | MinRtrAdvInterval 30; 5 | # should match 1 additional (and remove 1 from source conf) 6 | prefix 2001:db8:871a:28c1::/64 { 7 | AdvValidLifetime 86400; 8 | AdvPreferredLifetime 14400; 9 | }; 10 | prefix fda5:3d6f:2bc7:203d::/64 { 11 | AdvValidLifetime 86400; 12 | AdvPreferredLifetime 14400; 13 | }; 14 | }; 15 | interface eth1 16 | { 17 | AdvSendAdvert on; 18 | MinRtrAdvInterval 30; 19 | # prefix wired, no options 20 | prefix fdac:3741:50f8::/48 { 21 | AdvValidLifetime 86400; 22 | AdvPreferredLifetime 14400; 23 | }; 24 | # should remove existing source prefix as not wired 25 | prefix 2001:db8:a0b:12f0::/64 { 26 | AdvValidLifetime 14400; 27 | AdvPreferredLifetime 86400; 28 | }; 29 | }; 30 | -------------------------------------------------------------------------------- /examples/complex/ipv6-prefix-eth2-from-eth0.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Optional LAN configuration for 08-ipv6-prefix 3 | # 4 | # See /etc/NetworkManager/dispatcher.d/08-ipv6-prefix for docs 5 | # 6 | # FILENAME: ipv6-prefix-eth2-from-eth0.conf 7 | # PATTERN: ipv6-prefix--from-.conf 8 | # 9 | # So below will affect eth2 (LAN) sub-prefix allocated from delegation 10 | # given to eth0 (WAN) 11 | # 12 | # eg: with 2001:db8:3311:aa00::/56 delegation on eth0, config would assign 13 | # 2001:db8:3311:aad0::1/60 14 | # made from 15 | # 2001:db8:3311:aa - 56-bit delegation from DHCP 16 | LAN_PREFIX_LEN=60 17 | # LAN_PREFIX_LEN /60 18 | LAN_SITE=cd 19 | # LAN_SITE d0:: - lowest 4-bits (LAN_PREFIX_LEN - 56) of "cd" 20 | LAN_NODE=1 21 | # LAN_NODE ::1 22 | -------------------------------------------------------------------------------- /test/conf/radvd-gen.conf: -------------------------------------------------------------------------------- 1 | # -*- mode: sh; sh-basic-offset: 2; indent-tabs-mode: nil; -*- 2 | # vim:set ft=sh et sw=2 ts=2: 3 | # shellcheck shell=bash disable=SC2034 4 | 5 | # test # is required 6 | TEST_NUM=${TEST_NUM:-1} 7 | 8 | SRC_ROOT=${SRC_ROOT-..} 9 | TEST_BIN=${TEST_BIN-bin} 10 | 11 | IPV6_UTILS="$SRC_ROOT/etc/nmutils/ipv6_utils.sh" 12 | IP_EXE=${TEST_IP-$TEST_BIN/ip-mock} 13 | SC_EXE=${TEST_SYSTEMCTL-$TEST_BIN/systemctl-mock} 14 | KILL_EXE='' 15 | RESTORECON_EXE='' 16 | 17 | # radvd specific overrides 18 | RADVD_GROUP= 19 | 20 | SRC="$TEST_CONF/${TEST_NUM}-radvd.conf.templ" 21 | # shellcheck disable=SC2153 22 | DST="$TEST_OUT/${TEST_NUM}-radvd.conf" 23 | 24 | # override if it exists 25 | [[ -r $TEST_CONF/${TEST_NUM}-ip-mock-addrs ]] && 26 | export IP_MOCK_ADDRS="$TEST_CONF/${TEST_NUM}-ip-mock-addrs" 27 | -------------------------------------------------------------------------------- /examples/complex/ddns-eth1-from-eth0.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Dynamic DNS configuration for 08-ipv6-prefix 3 | # 4 | # See /etc/NetworkManager/dispatcher.d/08-ipv6-prefix and 5 | # /etc/nmutils/ddns-functions for docs 6 | # 7 | # FILENAME: ddns-eth1-from-eth0.conf 8 | # PATTERN: ddns--from-.conf 9 | # 10 | # So below will affect addresses assigned by the DHCP client running 11 | # on eth0 (WAN) to eth1 (INTF) via sub-prefix assignment 12 | # 13 | 14 | # zone to update (required) 15 | DDNS_ZONE=example.net. 16 | 17 | # resources 18 | DDNS_RREC_AAAA_NAME=int.example.net. 19 | 20 | DDNS_RREC_CNAME_NAME=ldap.example.net. 21 | DDNS_RREC_CNAME_VALUE=int.example.net. 22 | 23 | # change default nsupdate options 24 | DDNS_NSUPDATE_OPTIONS="-v -k /etc/Kinternal.example.net.+157+{random}.private" 25 | DDNS_SERVER=192.168.1.1 26 | DDNS_TTL=1200 27 | 28 | -------------------------------------------------------------------------------- /test/radvd-test: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # -*- mode: sh; sh-basic-offset: 2; indent-tabs-mode: nil; -*- 3 | # vim:set ft=sh et sw=2 ts=2: 4 | # SPDX-License-Identifier: GPL-3.0-or-later 5 | # 6 | # Fake radvd to test scripts 7 | # 8 | # Set the following in your radvd-gen.conf file to test: 9 | # 10 | # shellcheck disable=SC1090 11 | 12 | [ "$1" = "-h" ] && { 13 | echo "Usage: ${0##*/} [ ]" 14 | exit 1 15 | } 16 | 17 | fail() { 18 | echo >&2 "$*" 19 | exit 1 20 | } 21 | 22 | # load common.conf 23 | TEST_COMMON=${TEST_COMMON:-conf/common.conf} 24 | { [[ -r ${TEST_COMMON} ]] && . "${TEST_COMMON}"; } || 25 | fail "Unable to load ${TEST_COMMON}" 26 | 27 | # radvd-gen.conf loads general.conf for program overrides 28 | export RADVDGEN_CONF=${RADVDGEN_CONF-$TEST_CONF/radvd-gen.conf} 29 | 30 | "${BASH}" "${TEST_NMDIR}/95-radvd-gen" "$@" eth0 up 31 | -------------------------------------------------------------------------------- /test/expected/2-radvd.conf: -------------------------------------------------------------------------------- 1 | interface eth0 2 | { 3 | AdvSendAdvert on; 4 | MinRtrAdvInterval 30; 5 | # address not wired 6 | prefix fda5:0000:2bc7:203d::/64 { 7 | AdvAutonomous off; 8 | }; 9 | # should match multiple prefixes 10 | prefix 2001:db8:871a:c1::/64 { 11 | AdvAutonomous on; 12 | # Comment in dynamic 13 | AdvPreferredLifetime 300; 14 | AdvValidLifetime 100; 15 | }; 16 | prefix fda5:3d6f:1000:203d::/64 { 17 | AdvAutonomous on; 18 | # Comment in dynamic 19 | AdvPreferredLifetime 300; 20 | AdvValidLifetime 100; 21 | }; 22 | }; 23 | interface eth1 24 | { 25 | AdvSendAdvert on; 26 | # empty saved, should match 2 27 | prefix 2001:db8:a0b:12f0::/64 { 28 | AdvValidLifetime 86400; 29 | AdvPreferredLifetime 14400; 30 | }; 31 | prefix fdac:3741:50f8:f623::/64 { 32 | AdvValidLifetime 86400; 33 | AdvPreferredLifetime 14400; 34 | }; 35 | }; 36 | -------------------------------------------------------------------------------- /test/conf/dig-mock-names: -------------------------------------------------------------------------------- 1 | # dns names for dig-mock 2 | # format: 3 | # $ORIGIN 4 | # $TTL 5 | # [ ] 6 | $TTL 12894 7 | . NS a.root-servers.test. 8 | $SERVER 127.0.0.1 9 | $ORIGIN example.test. 10 | $TTL 1800 11 | www A 192.0.2.8 12 | A 203.0.113.4 13 | AAAA 2001:DB8:4860:4860::8888 14 | ipv6 AAAA 2001:DB8:4860:4860::8844 15 | mail TXT "v=spf1 mx ~all" 16 | TXT "some value" 17 | home AAAA 2001:db8:100:2:32fb:93c5:555:1 18 | dns A 198.51.100.2 19 | AAAA 2001:db8:871a:28c1::1 20 | dns2 AAAA 2001:db8:100:2:32fb:93c5:555:1 21 | AAAA 2001:db8:200:2:32fb:93c5:555:1 22 | web A 198.51.100.2 23 | AAAA 2001:db8:871a:28c1::1 24 | TXT "v=spf1 mx ~all" 25 | $ORIGIN . 26 | example.test MX 10 mail.example.test. 27 | 28 | $SERVER home.test 29 | $ORIGIN home.test. 30 | $TTL 120 31 | gateway AAAA fda5:3d6f:2bc7:203d:1c52:4ac2:27ff:fe1b 32 | A 10.0.10.12 33 | desktop A 198.168.66.24 34 | -------------------------------------------------------------------------------- /examples/complex/ddns-eth1.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Configuration for 09-ddns 3 | # 4 | # See /etc/NetworkManager/dispatcher.d/09-ddns and /etc/nmutils/ddns-functions 5 | # for docs 6 | # 7 | # FILENAME: ddns-eth1.conf 8 | # PATTERN: ddns-.conf 9 | # 10 | # So below will affect addresses assigned to eth1 (INTF) 11 | # 12 | 13 | # zone to update (required) 14 | DDNS_ZONE=example.net. 15 | 16 | # resources 17 | DDNS_RREC_A_NAME=router.example.net. 18 | DDNS_RREC_A_FALLBACK=192.168.1.1 19 | DDNS_RREC_A_PRIVATE=1 20 | 21 | DDNS_RREC_AAAA_NAME=router.example.net. 22 | DDNS_RREC_AAAA_PRIVATE=1 23 | 24 | DDNS_RREC_CNAME_NAME=mail.example.net. 25 | DDNS_RREC_CNAME_VALUE=router.example.net. 26 | DDNS_RREC_CNAME_FALLBACK=internal.example.net. 27 | 28 | DDNS_RREC_TXT_NAME=router.example.net. 29 | DDNS_RREC_TXT_VALUE="The router is up" 30 | 31 | # change default nsupdate options 32 | DDNS_NSUPDATE_OPTIONS="-v -k /etc/Kinternal.example.net.+157+{random}.private" 33 | DDNS_SERVER=192.168.1.1 34 | DDNS_TTL=1200 35 | -------------------------------------------------------------------------------- /selinux/nmutils.te: -------------------------------------------------------------------------------- 1 | policy_module(nmutils, 0.2.0) 2 | 3 | # 4 | # Policy labels nmutils files in dispatcher.d as nmutils_exec_t (see .fc file) 5 | # and then defines domain transition so scripts are run in the initrc_t domain 6 | # 7 | require { 8 | type dhcpc_t; 9 | type NetworkManager_etc_t; 10 | type NetworkManager_initrc_exec_t; 11 | } 12 | 13 | # define entry point, useable by NetworkManager and init scripts 14 | type nmutils_exec_t; 15 | init_script_file(nmutils_exec_t) 16 | 17 | # Required for dhclient to execute 08-ipv6-prefix 18 | search_dirs_pattern(dhcpc_t, NetworkManager_etc_t, NetworkManager_initrc_exec_t); 19 | domtrans_pattern(dhcpc_t, nmutils_exec_t, initrc_t) 20 | 21 | # required for newer NetworkManager 22 | optional { 23 | require { 24 | type NetworkManager_dispatcher_t; 25 | type NetworkManager_dispatcher_script_t; 26 | } 27 | domtrans_pattern(NetworkManager_dispatcher_t, nmutils_exec_t, initrc_t) 28 | search_dirs_pattern(dhcpc_t, NetworkManager_etc_t, NetworkManager_dispatcher_script_t); 29 | } 30 | -------------------------------------------------------------------------------- /examples/complex/ddns-eth0-from-eth0.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Dynamic DNS configuration for 08-ipv6-prefix 3 | # 4 | # See /etc/NetworkManager/dispatcher.d/08-ipv6-prefix and 5 | # /etc/nmutils/ddns-functions for docs 6 | # 7 | # FILENAME: ddns-eth0-from-eth0.conf 8 | # PATTERN: ddns--from-.conf 9 | # 10 | # So below will affect addresses assigned by the DHCP client running 11 | # on eth0 (WAN) to eth0 (INTF) 12 | # 13 | 14 | # zone to update (required) 15 | DDNS_ZONE=example.net. 16 | 17 | # resources 18 | # for prefix, only AAAA will be assigned 19 | DDNS_RREC_AAAA_NAME=www.example.net. 20 | 21 | # A values can be set when prefix assigned by using DDNS_RREC_A_VALUE 22 | DDNS_RREC_A_NAME=www.example.net. 23 | DDNS_RREC_A_VALUE=4.3.2.1 24 | 25 | DDNS_RREC_CNAME_NAME=mail.example.net. 26 | DDNS_RREC_CNAME_VALUE=www.example.net. 27 | DDNS_RREC_CNAME_FALLBACK=alt.example.net. 28 | 29 | # change default nsupdate options 30 | DDNS_NSUPDATE_OPTIONS="-v -k /etc/Kpublic.example.net.+157+{random}.private" 31 | DDNS_SERVER=2.3.4.5 32 | DDNS_TTL=300 33 | 34 | -------------------------------------------------------------------------------- /examples/complex/radvd.conf.templ: -------------------------------------------------------------------------------- 1 | # 2 | # radvd template used by 95-radvd-gen 3 | # 4 | # See /etc/NetworkManager/dispatcher.d/95-radvd-gen for docs 5 | # 6 | # Unlike other configurations in this directory, place this file in 7 | # /etc/NetworkManager 8 | # 9 | # @PREFIX@ will be replaced with any ipv6 prefixes on interface eth1 10 | # 11 | interface eth0 12 | { 13 | AdvSendAdvert on; 14 | MinRtrAdvInterval 30; 15 | # static prefix 16 | prefix fda5:0000:2bc7:203d::/64 { 17 | # no addr-gen for this prefix 18 | AdvAutonomous off; 19 | }; 20 | # delegated prefixes with fixed lifetimes 21 | @PREFIX@ { 22 | AdvAutonomous on; 23 | DecrementLifetimes on; 24 | }; 25 | # @ROUTER_LIFETIME@ replaced with from max preferred life of 26 | # any addresses found for @PREFIX@ above 27 | AdvDefaultLifetime @ROUTER_LIFETIME@; 28 | }; 29 | interface eth1 30 | { 31 | AdvSendAdvert on; 32 | MinRtrAdvInterval 30; 33 | # prefix, no options 34 | prefix fdac:3741:50f8::/48; 35 | # override lifetimes 36 | @PREFIX@ { 37 | AdvValidLifetime 14400; 38 | AdvPreferredLifetime 86400; 39 | }; 40 | }; 41 | -------------------------------------------------------------------------------- /examples/complex/ifa50-mylogger-eth1.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Config for 96-interface-action 3 | # 4 | # See /etc/NetworkManager/dispatcher.d/96-interface-action for docs 5 | # 6 | # FILENAME: ifa50-mylogger-eth1.conf 7 | # PATTERN: ifa##--.conf 8 | # 9 | # So config below affects the `mylogger` service based on on `eth1` interface 10 | # changes, ordered at "50" vs other interface-action configs 11 | # (ie. after ifa{49-}-xxx, before ifa{51+}-xxx) 12 | # 13 | # ignore service is-enabled flag - eg. service may be disabled at boot, 14 | # but started when interface is up 15 | IGNORE_ENABLED=1 16 | # service is started/restarted on interface up 17 | CMD_UP=restart 18 | # service is reloaded on dhcp4-change 19 | CMD_CHANGE=reload 20 | # ... also on dhcp6-change 21 | CMD_CHANGE6=reload 22 | # service is stopped on interface before interface is brought down 23 | CMD_PRE_DOWN=stop 24 | 25 | # name of state file (may be used in combination with other flags 26 | # in service conditions) 27 | STATE_FILE=/run/mylogger-flag-eth1 28 | # contents on $RESTART_UP written to $STATE_FILE on interface up 29 | RESTART_UP="eth1 up at $(date)" 30 | # $STATE_FILE removed on interface down 31 | STOP_DOWN=1 32 | 33 | -------------------------------------------------------------------------------- /test/conf/common.conf: -------------------------------------------------------------------------------- 1 | # -*- mode: sh; sh-basic-offset: 2; indent-tabs-mode: nil; -*- 2 | # vim:set ft=sh et sw=2 ts=2: 3 | # common.conf - sourced before any tests start 4 | # 5 | # shellcheck shell=bash disable=SC2034 6 | 7 | # don't use syslog 8 | export nmg_log_stderr=1 9 | # never use default logger 10 | export NMG_LOGGER=echo 11 | 12 | export SRC_ROOT=${SRC_ROOT:-..} 13 | export TEST_ROOT=${TEST_ROOT:-.} 14 | export TEST_CONF=${TEST_CONF:-${TEST_ROOT}/conf} 15 | export TEST_BIN=${TEST_BIN:-${TEST_ROOT}/bin} 16 | export TEST_NMUTILS=${TEST_NMUTILS:-${SRC_ROOT}/etc/nmutils} 17 | export TEST_NMDIR=${TEST_NMDIR:-${SRC_ROOT}/etc/NetworkManager/dispatcher.d} 18 | export TEST_RUNDIR=${TEST_RUNDIR:-${TEST_ROOT}/run/nmutils} 19 | 20 | # used for file outputs 21 | export TEST_OUT=${TEST_OUT:-${TEST_ROOT}/results} 22 | [ -d "${TEST_OUT}" ] || command -p mkdir -p "${TEST_OUT}" 23 | 24 | # check if xtest_common available 25 | XTEST_SETUP=${XTEST_SETUP:-${TEST_CONF}/xtest_setup} 26 | [[ -r ${XTEST_SETUP} ]] || XTEST_SETUP='' 27 | 28 | export NMUTILS="${TEST_NMUTILS}" 29 | export NMCONF="${TEST_CONF}" 30 | 31 | # for state/pids 32 | export RUNDIR="${TEST_RUNDIR}" 33 | [ -d "${RUNDIR}" ] || command -p mkdir -p "${RUNDIR}" 34 | -------------------------------------------------------------------------------- /examples/complex/ddns-eth0.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Configuration for 09-ddns 3 | # 4 | # See /etc/NetworkManager/dispatcher.d/09-ddns and /etc/nmutils/ddns-functions 5 | # for docs 6 | # 7 | # FILENAME: ddns-eth0.conf 8 | # PATTERN: ddns-.conf 9 | # 10 | # So below will affect addresses assigned to eth0 (INTF) 11 | # 12 | 13 | # zone to update (required) 14 | DDNS_ZONE=example.net. 15 | 16 | # resources 17 | DDNS_RREC_A_NAME=www.example.net. 18 | # if DDNS_RREC_A_VALUE (or AAAA) set, it's value is used instead 19 | # of address on interface 20 | #DDNS_RREC_A_VALUE=10.10.10.10 21 | # if DDNS_RREC__FALLBACK empty (default) removed when down 22 | #DDNS_RREC_A_FALLBACK= 23 | 24 | DDNS_RREC_AAAA_NAME=www.example.net. 25 | 26 | DDNS_RREC_CNAME_NAME=mail.example.net. 27 | DDNS_RREC_CNAME_VALUE=www.example.net. 28 | DDNS_RREC_CNAME_FALLBACK=alt.example.net. 29 | 30 | # change default nsupdate options 31 | DDNS_NSUPDATE_OPTIONS="-v -k /etc/Kpublic.example.net.+157+{random}.private" 32 | DDNS_SERVER=2.3.4.5 33 | DDNS_TTL=300 34 | 35 | # DDNS server is slow 36 | DDNS_DIG_TIMEOUT=15 37 | DDNS_NSUPDATE_TIMEOUT=15 38 | DDNS_FLOCK_TIMEOUT=30 39 | # use our own lockfile 40 | DDNS_LOCKFILE="/etc/nmutils/conf/ddns-eth0.conf" -------------------------------------------------------------------------------- /selinux/nmutils.fc: -------------------------------------------------------------------------------- 1 | /run/nmutils/dhclient.* -- gen_context(system_u:object_r:dhcpc_var_run_t,s0) 2 | /run/nmutils/.* -- gen_context(system_u:object_r:initrc_var_run_t,s0) 3 | /etc/NetworkManager/dispatcher\.d/[0-9][0-9]-ifd-.* -- gen_context(system_u:object_r:nmutils_exec_t,s0) 4 | /etc/NetworkManager/dispatcher\.d/08-ipv6-prefix -- gen_context(system_u:object_r:nmutils_exec_t,s0) 5 | /etc/NetworkManager/dispatcher\.d/09-ddns -- gen_context(system_u:object_r:nmutils_exec_t,s0) 6 | /etc/NetworkManager/dispatcher\.d/90-transmission -- gen_context(system_u:object_r:nmutils_exec_t,s0) 7 | /etc/NetworkManager/dispatcher\.d/95-radvd-gen -- gen_context(system_u:object_r:nmutils_exec_t,s0) 8 | /etc/NetworkManager/dispatcher\.d/96-interfac(e)-action -- gen_context(system_u:object_r:nmutils_exec_t,s0) 9 | /usr/lib/NetworkManager/dispatcher\.d/08-ipv6-prefix -- gen_context(system_u:object_r:nmutils_exec_t,s0) 10 | /usr/lib/NetworkManager/dispatcher\.d/09-ddns -- gen_context(system_u:object_r:nmutils_exec_t,s0) 11 | /usr/lib/NetworkManager/dispatcher\.d/90-transmission -- gen_context(system_u:object_r:nmutils_exec_t,s0) 12 | /usr/lib/NetworkManager/dispatcher\.d/95-radvd-gen -- gen_context(system_u:object_r:nmutils_exec_t,s0) 13 | /usr/lib/NetworkManager/dispatcher\.d/96-interfac(e)-action -- gen_context(system_u:object_r:nmutils_exec_t,s0) 14 | -------------------------------------------------------------------------------- /test/conf/ip-mock-routes: -------------------------------------------------------------------------------- 1 | route default via 192.168.66.254 dev eth0 proto static src 192.168.66.4 metric 400 2 | route6 default via fe80::fcac:2fff:fe4f:a805 dev eth0 proto ra metric 405 3 | route 192.168.66.0/24 dev eth0 proto kernel src 192.168.66.4 metric 400 4 | route6 2001:db8:871a:28c1::/64 dev eth0 proto kernel 5 | route6 2001:db8:4860:4860::/64 dev eth0 proto kernel 6 | route6 fda5:3d6f:2bc7:203d::/64 dev eth0 proto kernel 7 | route6 fe80::/64 dev eth0 proto kernel 8 | route default via 10.0.10.1 dev eth1 proto static src 10.0.10.12 metric 400 9 | route6 default via fe80::59b1:2362:2abc:512f dev eth1 proto ra metric 406 10 | route6 default from 2001:db8:871a:28c1::/64 via fe80::59b1:2362:2abc:512f dev eth1 proto static 11 | route 10.0.10.0/24 dev eth1 proto kernel scope link src 10.0.10.12 metric 400 12 | route6 2001:db8:a0b:12f0::/64 dev eth1 proto kernel 13 | route6 fdac:3741:50f8:f623::/64 dev eth1 proto kernel 14 | route6 fe80::/64 dev eth1 proto kernel 15 | route6 default via fe80::faaa:dead:beef:8000 dev wan0 proto ra metric 405 16 | route6 default from 2001:db8:100::/56 via fe80::faaa:dead:beef:8000 dev wan0 proto static 17 | route6 default from 2001:db8:200::/56 via fe80::faaa:dead:beef:8000 dev wan0 proto static 18 | route6 2001:db8:100::/56 type unreachable dev lo metric 2147483647 19 | route6 2001:db8:200::/56 type unreachable dev lo metric 2147483647 20 | # 21 | # ip route get entries (totally separate for now) 22 | # 23 | groute6 2001:db8:aaa::100 from :: dev wan0 proto ra src 2001:db8:aaa::1 24 | groute6 2001:db8:aaa::200 from :: dev wan0 proto ra src 2001:db8:aaa::1 25 | groute6 default from :: via fe80::faaa:dead:beef:8000 dev wan0 proto ra src 2001:db8:aaa::1 26 | -------------------------------------------------------------------------------- /examples/complex/ipv6-prefix-eth0.conf: -------------------------------------------------------------------------------- 1 | # 2 | # WAN configuration for 08-ipv6-prefix 3 | # 4 | # See /etc/NetworkManager/dispatcher.d/08-ipv6-prefix for docs 5 | # 6 | # FILENAME: ipv6-prefix-eth0.conf 7 | # PATTERN: ipv6-prefix-.conf 8 | # 9 | # So below will affect configuration for eth0 (WAN) 10 | # 11 | # Add space-separated list of LAN interfaces to assign prefixes to them 12 | WAN_LAN_INTFS="eth1 eth2" 13 | 14 | # prefix-len (works on dhclient and dhcpcd) 15 | WAN_PREFIXLEN_HINT=60 16 | 17 | # uncomment to force use of dhclient 18 | #DHCPCD='' 19 | WAN_DHCLIENT_ARGS=(-H router.example.net) 20 | 21 | # debug for dhcpcd 22 | WAN_DHCPCD_ARGS=(-d) 23 | # add global config for dhcpcd 24 | #WAN_DHCPCD_PRECONFIG=/etc/nmutils/conf/dhcpcd-pre-eth0.conf 25 | # add vlan1 interface config for dhcpcd 26 | #WAN_DHCPCD_POSTCONFIG=/etc/nmutils/conf/dhcpcd-post-eth0.conf 27 | 28 | # override 2m timeout to restart dhcp client 29 | DHCP_REBIND_TIMEOUT=30 30 | 31 | # set WAN_REQUIRE_IP4=any if even a private address is enough to trigger 32 | # prefix delegation (unset means no ipv4 address is needed to start dhclient) 33 | WAN_REQUIRE_IP4=1 34 | 35 | # Static ips added when interface up 36 | WAN_STATIC_IP6="2001:db8:55::1/64, 2001:db8:100::1/64" 37 | # Static DNS entries for interface (can't be assigned in NM until 38 | # interface has an address) 39 | WAN_STATIC_DNS6="2001:db8:aaaa::1, 2001:db8:bbbb::1" 40 | # Static DNS search list 41 | WAN_STATIC_DNS6_SEARCH='home.lan, office.lan' 42 | 43 | # config for source-based default routes 44 | WAN_SADR_METRIC=100 45 | #WAN_SADR_DISABLE=1 46 | 47 | # use the 95-radvd-gen to update radvd.conf when LAN delegations change 48 | NMG_RADVD_TRIGGER="/etc/NetworkManager/dispatcher.d/95-radvd-gen" 49 | -------------------------------------------------------------------------------- /test/conf/ip-mock-addrs: -------------------------------------------------------------------------------- 1 | dev eth0 9000 2 | addr 192.168.66.4/24 8600sec 2400sec 3 | addr6 2001:db8:871a:28c1::1/128 86400sec 14400sec 4 | addr6 2001:db8:4860:4860::8888/128 86400sec 14400sec 5 | addr6 fda5:3d6f:2bc7:203d:1c52:4ac2:27ff:fe1b/64 3600sec 1800sec global noprefixroute 6 | addr6 fe80::a00:27ff:fe1b:ff9a/64 forever forever link 7 | dev eth1 8 | addr 10.0.10.12/24 forever forever global noprefixroute 9 | addr6 2001:db8:a0b:12f0::1/64 86400sec 14400sec 10 | addr6 fdac:3741:50f8:f623::1/48 86400sec 14400sec global 11 | addr6 fe80::31fd:68fd:ed8b:4d77/64 forever forever link 12 | dev eth2 13 | addr 10.1.10.12/24 forever forever global noprefixroute 14 | addr 10.2.10.12/24 forever forever global noprefixroute 15 | addr6 2001:db8:1::1/64 14400sec 86400sec global tentative 16 | addr6 fe80::50fa:5fff:ec9b:5d92/64 forever forever link noprefixroute 17 | dev eth3 18 | addr6 2001:db8:5::1/64 14400sec 86400sec global tentative dadfailed 19 | addr6 fe80::1e5a:81fe:ed8a:21a4/64 forever forever link noprefixroute 20 | dev wan0 21 | addr6 2001:db8:800::2/128 forever forever global 22 | addr6 2001:db8:aaa::1/128 forever forever global 23 | addr6 2001:db8:aaa::2/128 forever forever global tentative dadfailed 24 | addr6 2001:db8:ffee::1/64 forever forever global 25 | addr6 fe80::0a44:e1f0:d471:03b5/64 forever forever link noprefixroute 26 | dev br0 27 | addr 192.168.88.1/24 forever forever global noprefixroute 28 | addr6 fdc0:4455:b240::1/64 forever forever global noprefixroute 29 | addr6 2001:db8:100:0:32fb:93c5:6555:845a/63 240 120 global 30 | addr6 2001:db8:200:0:32fb:93c5:6555:845a/63 forever forever global 31 | addr6 2001:db8:200:4:32fb:93c5:6555:845a/63 7200 3600 global 32 | addr6 fe80::32fb:93c5:6555:845a/64 forever forever link noprefixroute 33 | dev br1 34 | addr 192.168.99.1/24 forever forever global noprefixroute 35 | addr6 2001:db8:100:2:32fb:93c5:555:1/64 forever forever global noprefixroute 36 | addr6 2001:db8:200:2:32fb:93c5:555:1/64 forever forever global noprefixroute 37 | addr6 fe80::32fb:93c5:555:1/64 forever forever link noprefixroute 38 | -------------------------------------------------------------------------------- /test/conf/general.conf: -------------------------------------------------------------------------------- 1 | # general.conf included by most scripts 2 | 3 | # shellcheck shell=bash disable=SC2034 4 | 5 | # in case test driver didn't load common.sh (assume pwd of test directory) 6 | SRC_ROOT=${SRC_ROOT-..} 7 | TEST_BIN=${TEST_BIN-bin} 8 | 9 | # no syslog, output to stderr (stdout may be used for returning values) 10 | nmg_log_stderr=${nmg_log_stderr:-1} 11 | # can be used to identify test 12 | NMG_TAG='' 13 | 14 | # locate programs 15 | NMDDNS_DHELPER=${TEST_DDNS_HELPER-$SRC_ROOT/etc/NetworkManager/dispatcher.d/09-ddns} 16 | 17 | # test programs 18 | NMG_IP=${TEST_IP-$TEST_BIN/ip-mock} 19 | # useful for debug 20 | #NMDDNS_GLOBAL_DIG_OPTIONS="-d" 21 | NMDDNS_DIG=${TEST_DIG-$TEST_BIN/dig-mock} 22 | 23 | NMDDNS_NSUPDATE=${TEST_NSUPDATE-$TEST_BIN/nsupdate-mock} 24 | 25 | # pgrep/date not used in tests 26 | NMG_PGREP=${TEST_PGREP-$(PATH=/usr/bin:/bin command -v false)} 27 | EPOCHREALTIME=1.000000 28 | NMG_DATE=${TEST_DATE:-$(PATH=/usr/bin:/bin command -v false)} 29 | # handle empty PATH bug in bash3 30 | NMG_RM=${TEST_RM:-$(PATH=/usr/bin:/bin command -v rm)} 31 | NMDDNS_FLOCK=${TEST_FLOCK:-$(PATH=/usr/local/bin:/usr/bin:/bin command -v flock)} 32 | [[ $NMDDNS_FLOCK ]] || DDNS_GLOBAL_LOCKFILE='' 33 | 34 | # just bogus so ignored 35 | NMG_RADVD="radvd-missing" 36 | 37 | DDNS_GLOBAL_DIG_OPTIONS="+time=1 +retry=2" 38 | 39 | # used in 08-ipv6-prefix 40 | NMCLI=${TEST_NMCLI-$TEST_BIN/nmcli-mock} 41 | DHCLIENT=${TEST_DHCLIENT-$TEST_BIN/dhclient-mock} 42 | SYSTEMCTL=${TEST_SYSTEMCTL-$TEST_BIN/systemctl-mock} 43 | SYSTEMD_RUN=${TEST_SYSTEMD_RUN-$TEST_BIN/systemd-run-mock} 44 | DHCPCD=${TEST_DHCPCD-$TEST_BIN/dhcpcd-mock} 45 | RDISC6=${TEST_RDISC6-$TEST_BIN/rdisc6-mock} 46 | RESOLVECTL=${TEST_RESOLVECTL-$TEST_BIN/resolvectl-mock} 47 | RESOLVCONF=${TEST_RESOLVCONF-$TEST_BIN/resolvconf-mock} 48 | 49 | # all tests check command args 50 | export MOCK_ECHO=1 51 | # nsupdate, resolvconf send commands to stdin 52 | export MOCK_ECHO_STDIN_nsupdate_mock=1 53 | export MOCK_ECHO_STDIN_resolvconf_mock=1 54 | export MOCK_ECHO_STDIN_ARGS_resolvconf_mock="-a" 55 | -------------------------------------------------------------------------------- /etc/nmutils/dispatcher_action: -------------------------------------------------------------------------------- 1 | # -*- mode: sh; sh-basic-offset: 2; indent-tabs-mode: nil; -*- 2 | # vim:set ft=sh et sw=2 ts=2: 3 | # SPDX-License-Identifier: GPL-3.0-or-later 4 | # 5 | # Copyright (C) 2015-2024 Scott Shambarger 6 | # 7 | # dispatcher_action v1.4.0 - service restart on interface change 8 | # Author: Scott Shambarger 9 | # 10 | # This file supports the same functions as 96-interface-action, but allows 11 | # re-ordering the action relative to other dispatchers. However, it requires 12 | # an extra config step. 13 | # 14 | # The extra step is creating a file named 15 | # 16 | # /etc/NetworkManager/dispatcher.d/##-ifd- 17 | # 18 | # (or wherever your distro has these files) where <##> is a 2-digit 19 | # number, and is a systemd service name. The file should be 20 | # executable and contain the following: 21 | # 22 | # --- start 23 | # #!/bin/bash 24 | # . /etc/nmutils/dispatcher_action 25 | # --- end 26 | # 27 | # The configuration settings are documented in 96-interface-action, but 28 | # those settings are should instead be placed in: 29 | # 30 | # /etc/nmutils/conf/ifd--.conf 31 | # 32 | # NOTE: If any PRE_DOWN actions are used, the ##-ifd- script 33 | # should be symlinked to the pre-down.d directory. 34 | # 35 | # shellcheck shell=bash disable=SC1090 36 | interface=${1-} 37 | action=${2-} 38 | 39 | ########## SCRIPT START 40 | 41 | # anything for us to do? 42 | [[ ${interface} && ${action} ]] || exit 0 43 | 44 | # check dispatcher name format for ##-ifd-service 45 | base_name=${0##*/} 46 | [[ ${base_name} =~ ^[0-9][0-9]-ifd-([^/]+)$ ]] || { 47 | echo >&2 "Invalid command name: ${base_name}" && exit 3 48 | } 49 | IFD_UNIT=${BASH_REMATCH[1]} 50 | 51 | # shellcheck disable=SC2034 52 | IFD_CONFIG="ifd-${IFD_UNIT}-${interface}.conf" 53 | 54 | NMG_TAG=${NMG_TAG-nm-ifd} 55 | IFA_FILE="/etc/NetworkManager/dispatcher.d/96-interface-action" 56 | { [[ -r "${IFA_FILE}" ]] && . "${IFA_FILE}"; } || { 57 | echo >&2 "Unable to load ${IFA_FILE}" && exit 2 58 | } 59 | 60 | exit 0 61 | -------------------------------------------------------------------------------- /test/bin/dhclient-mock: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # -*- mode: sh; sh-basic-offset: 2; indent-tabs-mode: nil; -*- 3 | # vim:set ft=sh et sw=2 ts=2: 4 | # SPDX-License-Identifier: GPL-3.0-or-later 5 | # 6 | # dhclient-mock for test scripts 7 | # 8 | # Set the following in your ipv6-prefix-wan-${interface}.conf file to test: 9 | # 10 | #if [ "$reason" = "BOUND6" ]; then 11 | # old_ip6_prefix= 12 | # new_ip6_prefix= 13 | # new_max_life=100 14 | #elif [ "$reason" = "STOP6" ]; then 15 | # old_ip6_prefix= 16 | #fi 17 | 18 | unset IFS 19 | 20 | err() { 21 | printf >&2 "%s\n" "$*" 22 | } 23 | 24 | fail() { 25 | local -i rc=0 26 | [[ $1 != 0 ]] && { printf 2>/dev/null -v rc "%d" "$1" || rc=1; } 27 | shift 28 | [[ $1 ]] && { if [[ $rc == 0 ]]; then echo "$@"; else err "$@"; fi; } 29 | exit "$rc" 30 | } 31 | 32 | [[ ${DHCLIENT_MOCK_FAIL-} || ${DHCLIENT_MOCK_OUTPUT-} ]] && { 33 | args='' arg=''; for arg in "$@"; do args+="${args:+ }'${arg}'"; done 34 | fail "${DHCLIENT_MOCK_FAIL:-0}" \ 35 | "${DHCLIENT_MOCK_OUTPUT+${DHCLIENT_MOCK_OUTPUT/@ARGS@/${args}}}" 36 | } 37 | 38 | SCRIPT='' PID='' CMD='' 39 | 40 | parse_args() { 41 | local arg nextarg='' 42 | 43 | for arg in "$@"; do 44 | 45 | [[ ${nextarg} ]] && { 46 | case ${nextarg} in 47 | script) SCRIPT=${arg} ;; 48 | pid) PID=${arg} ;; 49 | esac 50 | nextarg='' 51 | continue 52 | } 53 | 54 | case ${arg} in 55 | -sf) nextarg=script ;; 56 | -pf) nextarg=pid ;; 57 | *) CMD=${arg}; break ;; 58 | esac 59 | done 60 | return 0 61 | } 62 | 63 | usage() { 64 | err "Usage: ${0##*/} [ -sf