summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/pull-request-management.yml25
-rw-r--r--Makefile34
-rw-r--r--data/configd-include.json19
-rw-r--r--data/templates/accel-ppp/chap-secrets.config_dict.j2 (renamed from data/templates/accel-ppp/chap-secrets.config_dict.tmpl)14
-rw-r--r--data/templates/accel-ppp/chap-secrets.ipoe.j2 (renamed from data/templates/accel-ppp/chap-secrets.ipoe.tmpl)22
-rw-r--r--data/templates/accel-ppp/chap-secrets.j2 (renamed from data/templates/accel-ppp/chap-secrets.tmpl)10
-rw-r--r--data/templates/accel-ppp/config_chap_secrets_radius.j230
-rw-r--r--data/templates/accel-ppp/config_ip_pool.j218
-rw-r--r--data/templates/accel-ppp/config_ipv6_pool.j220
-rw-r--r--data/templates/accel-ppp/config_modules_auth_mode.j24
-rw-r--r--data/templates/accel-ppp/config_modules_auth_protocols.j28
-rw-r--r--data/templates/accel-ppp/config_modules_ipv6.j22
-rw-r--r--data/templates/accel-ppp/config_name_server.j212
-rw-r--r--data/templates/accel-ppp/config_shaper_radius.j211
-rw-r--r--data/templates/accel-ppp/ipoe.config.j2142
-rw-r--r--data/templates/accel-ppp/ipoe.config.tmpl116
-rw-r--r--data/templates/accel-ppp/l2tp.config.j2 (renamed from data/templates/accel-ppp/l2tp.config.tmpl)69
-rw-r--r--data/templates/accel-ppp/pppoe.config.j2172
-rw-r--r--data/templates/accel-ppp/pppoe.config.tmpl174
-rw-r--r--data/templates/accel-ppp/pptp.config.j2 (renamed from data/templates/accel-ppp/pptp.config.tmpl)32
-rw-r--r--data/templates/accel-ppp/sstp.config.j2 (renamed from data/templates/accel-ppp/sstp.config.tmpl)2
-rw-r--r--data/templates/bcast-relay/udp-broadcast-relay.j25
-rw-r--r--data/templates/bcast-relay/udp-broadcast-relay.tmpl7
-rw-r--r--data/templates/conntrack/nftables-ct.j248
-rw-r--r--data/templates/conntrack/sysctl.conf.j2 (renamed from data/templates/conntrack/sysctl.conf.tmpl)2
-rw-r--r--data/templates/conntrack/vyos_nf_conntrack.conf.j2 (renamed from data/templates/conntrack/vyos_nf_conntrack.conf.tmpl)0
-rw-r--r--data/templates/conntrackd/conntrackd.conf.j2 (renamed from data/templates/conntrackd/conntrackd.conf.tmpl)58
-rw-r--r--data/templates/conntrackd/conntrackd.op-mode.j213
-rw-r--r--data/templates/conntrackd/conntrackd.op-mode.tmpl13
-rw-r--r--data/templates/conserver/conserver.conf.j2 (renamed from data/templates/conserver/conserver.conf.tmpl)2
-rw-r--r--data/templates/conserver/dropbear@.service.j2 (renamed from data/templates/conserver/dropbear@.service.tmpl)0
-rw-r--r--data/templates/container/registries.conf.j227
-rw-r--r--data/templates/container/storage.conf.j24
-rw-r--r--data/templates/containers/registry.tmpl5
-rw-r--r--data/templates/containers/storage.tmpl5
-rw-r--r--data/templates/dhcp-client/daemon-options.j24
-rw-r--r--data/templates/dhcp-client/daemon-options.tmpl4
-rw-r--r--data/templates/dhcp-client/ipv4.j2 (renamed from data/templates/dhcp-client/ipv4.tmpl)18
-rw-r--r--data/templates/dhcp-client/ipv6.j260
-rw-r--r--data/templates/dhcp-client/ipv6.tmpl60
-rw-r--r--data/templates/dhcp-relay/dhcrelay.conf.j2 (renamed from data/templates/dhcp-relay/dhcrelay.conf.tmpl)2
-rw-r--r--data/templates/dhcp-relay/dhcrelay6.conf.j221
-rw-r--r--data/templates/dhcp-relay/dhcrelay6.conf.tmpl21
-rw-r--r--data/templates/dhcp-server/dhcpd.conf.j2246
-rw-r--r--data/templates/dhcp-server/dhcpd.conf.tmpl231
-rw-r--r--data/templates/dhcp-server/dhcpdv6.conf.j2132
-rw-r--r--data/templates/dhcp-server/dhcpdv6.conf.tmpl124
-rw-r--r--data/templates/dns-forwarding/recursor.conf.j2 (renamed from data/templates/dns-forwarding/recursor.conf.tmpl)11
-rw-r--r--data/templates/dns-forwarding/recursor.conf.lua.j2 (renamed from data/templates/dns-forwarding/recursor.conf.lua.tmpl)0
-rw-r--r--data/templates/dns-forwarding/recursor.forward-zones.conf.j2 (renamed from data/templates/dns-forwarding/recursor.forward-zones.conf.tmpl)19
-rw-r--r--data/templates/dns-forwarding/recursor.vyos-hostsd.conf.lua.j230
-rw-r--r--data/templates/dns-forwarding/recursor.vyos-hostsd.conf.lua.tmpl24
-rw-r--r--data/templates/dns-forwarding/recursor.zone.conf.j26
-rw-r--r--data/templates/dynamic-dns/ddclient.conf.j251
-rw-r--r--data/templates/dynamic-dns/ddclient.conf.tmpl49
-rw-r--r--data/templates/ethernet/wpa_supplicant.conf.j2 (renamed from data/templates/ethernet/wpa_supplicant.conf.tmpl)10
-rw-r--r--data/templates/firewall/nftables-defines.j232
-rw-r--r--data/templates/firewall/nftables-nat.j2182
-rw-r--r--data/templates/firewall/nftables-nat.tmpl181
-rw-r--r--data/templates/firewall/nftables-nat66.j2102
-rw-r--r--data/templates/firewall/nftables-nat66.tmpl102
-rw-r--r--data/templates/firewall/nftables-policy.j255
-rw-r--r--data/templates/firewall/nftables-vrf-zones.j2 (renamed from data/templates/firewall/nftables-vrf-zones.tmpl)0
-rw-r--r--data/templates/firewall/nftables.j2274
-rw-r--r--data/templates/firewall/upnpd.conf.j2172
-rw-r--r--data/templates/frr/bfdd.frr.j258
-rw-r--r--data/templates/frr/bfdd.frr.tmpl44
-rw-r--r--data/templates/frr/bgpd.frr.j2533
-rw-r--r--data/templates/frr/bgpd.frr.tmpl528
-rw-r--r--data/templates/frr/igmp.frr.j241
-rw-r--r--data/templates/frr/igmp.frr.tmpl41
-rw-r--r--data/templates/frr/isisd.frr.j2197
-rw-r--r--data/templates/frr/isisd.frr.tmpl198
-rw-r--r--data/templates/frr/ldpd.frr.j2149
-rw-r--r--data/templates/frr/ldpd.frr.tmpl187
-rw-r--r--data/templates/frr/ospf6d.frr.j295
-rw-r--r--data/templates/frr/ospf6d.frr.tmpl92
-rw-r--r--data/templates/frr/ospfd.frr.j2189
-rw-r--r--data/templates/frr/ospfd.frr.tmpl192
-rw-r--r--data/templates/frr/pimd.frr.j2 (renamed from data/templates/frr/pimd.frr.tmpl)16
-rw-r--r--data/templates/frr/policy.frr.j2331
-rw-r--r--data/templates/frr/policy.frr.tmpl322
-rw-r--r--data/templates/frr/rip_ripng.frr.j242
-rw-r--r--data/templates/frr/ripd.frr.j292
-rw-r--r--data/templates/frr/ripd.frr.tmpl96
-rw-r--r--data/templates/frr/ripngd.frr.j257
-rw-r--r--data/templates/frr/ripngd.frr.tmpl60
-rw-r--r--data/templates/frr/rpki.frr.j2 (renamed from data/templates/frr/rpki.frr.tmpl)17
-rw-r--r--data/templates/frr/static_mcast.frr.j2 (renamed from data/templates/frr/static_mcast.frr.tmpl)20
-rw-r--r--data/templates/frr/static_routes_macro.j229
-rw-r--r--data/templates/frr/staticd.frr.j264
-rw-r--r--data/templates/frr/staticd.frr.tmpl58
-rw-r--r--data/templates/frr/vrf-vni.frr.j29
-rw-r--r--data/templates/frr/vrf-vni.frr.tmpl9
-rw-r--r--data/templates/frr/vrf.route-map.frr.j210
-rw-r--r--data/templates/frr/vrf.route-map.frr.tmpl10
-rw-r--r--data/templates/getty/serial-getty.service.j2 (renamed from data/templates/getty/serial-getty.service.tmpl)0
-rw-r--r--data/templates/high-availability/keepalived.conf.j2169
-rw-r--r--data/templates/https/nginx.default.j2 (renamed from data/templates/https/nginx.default.tmpl)50
-rw-r--r--data/templates/https/override.conf.j215
-rw-r--r--data/templates/https/vyos-http-api.service.j222
-rw-r--r--data/templates/ids/fastnetmon.j2 (renamed from data/templates/ids/fastnetmon.tmpl)38
-rw-r--r--data/templates/ids/fastnetmon_networks_list.j27
-rw-r--r--data/templates/ids/fastnetmon_networks_list.tmpl7
-rw-r--r--data/templates/igmp-proxy/igmpproxy.conf.j2 (renamed from data/templates/igmp-proxy/igmpproxy.conf.tmpl)30
-rw-r--r--data/templates/ipsec/charon.j2 (renamed from data/templates/ipsec/charon.tmpl)12
-rw-r--r--data/templates/ipsec/charon/dhcp.conf.j2 (renamed from data/templates/ipsec/charon/dhcp.conf.tmpl)8
-rw-r--r--data/templates/ipsec/charon/eap-radius.conf.j2 (renamed from data/templates/ipsec/charon/eap-radius.conf.tmpl)16
-rw-r--r--data/templates/ipsec/interfaces_use.conf.j2 (renamed from data/templates/ipsec/interfaces_use.conf.tmpl)4
-rw-r--r--data/templates/ipsec/ios_profile.j2 (renamed from data/templates/ipsec/ios_profile.tmpl)2
-rw-r--r--data/templates/ipsec/ipsec.conf.j219
-rw-r--r--data/templates/ipsec/ipsec.conf.tmpl18
-rw-r--r--data/templates/ipsec/ipsec.secrets.j2 (renamed from data/templates/ipsec/ipsec.secrets.tmpl)4
-rw-r--r--data/templates/ipsec/swanctl.conf.j2131
-rw-r--r--data/templates/ipsec/swanctl.conf.tmpl131
-rw-r--r--data/templates/ipsec/swanctl/l2tp.j2 (renamed from data/templates/ipsec/swanctl/l2tp.tmpl)8
-rw-r--r--data/templates/ipsec/swanctl/peer.j2166
-rw-r--r--data/templates/ipsec/swanctl/peer.tmpl142
-rw-r--r--data/templates/ipsec/swanctl/profile.j2 (renamed from data/templates/ipsec/swanctl/profile.tmpl)26
-rw-r--r--data/templates/ipsec/swanctl/remote_access.j2 (renamed from data/templates/ipsec/swanctl/remote_access.tmpl)39
-rw-r--r--data/templates/ipsec/windows_profile.j2 (renamed from data/templates/ipsec/windows_profile.tmpl)0
-rw-r--r--data/templates/lcd/LCDd.conf.j2 (renamed from data/templates/lcd/LCDd.conf.tmpl)20
-rw-r--r--data/templates/lcd/lcdproc.conf.j2 (renamed from data/templates/lcd/lcdproc.conf.tmpl)0
-rw-r--r--data/templates/lldp/lldpd.j22
-rw-r--r--data/templates/lldp/lldpd.tmpl3
-rw-r--r--data/templates/lldp/vyos.conf.j225
-rw-r--r--data/templates/lldp/vyos.conf.tmpl20
-rw-r--r--data/templates/login/authorized_keys.j29
-rw-r--r--data/templates/login/authorized_keys.tmpl9
-rw-r--r--data/templates/login/pam_radius_auth.conf.j236
-rw-r--r--data/templates/login/pam_radius_auth.conf.tmpl36
-rw-r--r--data/templates/logs/logrotate/vyos-atop.j220
-rw-r--r--data/templates/logs/logrotate/vyos-rsyslog.j213
-rw-r--r--data/templates/macsec/wpa_supplicant.conf.j2 (renamed from data/templates/macsec/wpa_supplicant.conf.tmpl)10
-rw-r--r--data/templates/mdns-repeater/avahi-daemon.j2 (renamed from data/templates/mdns-repeater/avahi-daemon.tmpl)0
-rw-r--r--data/templates/monitoring/override.conf.j27
-rw-r--r--data/templates/monitoring/syslog_telegraf.j25
-rw-r--r--data/templates/monitoring/systemd_vyos_telegraf_service.j216
-rw-r--r--data/templates/monitoring/telegraf.j2122
-rw-r--r--data/templates/ndppd/ndppd.conf.j244
-rw-r--r--data/templates/ndppd/ndppd.conf.tmpl44
-rw-r--r--data/templates/netflow/uacctd.conf.tmpl72
-rw-r--r--data/templates/nhrp/opennhrp.conf.j242
-rw-r--r--data/templates/nhrp/opennhrp.conf.tmpl41
-rw-r--r--data/templates/ntp/ntpd.conf.j2 (renamed from data/templates/ntp/ntpd.conf.tmpl)29
-rw-r--r--data/templates/ntp/override.conf.j214
-rw-r--r--data/templates/ntp/override.conf.tmpl14
-rw-r--r--data/templates/ocserv/ocserv_config.j2 (renamed from data/templates/ocserv/ocserv_config.tmpl)45
-rw-r--r--data/templates/ocserv/ocserv_otp_usr.j28
-rw-r--r--data/templates/ocserv/ocserv_passwd.j28
-rw-r--r--data/templates/ocserv/ocserv_passwd.tmpl6
-rw-r--r--data/templates/ocserv/radius_conf.j2 (renamed from data/templates/ocserv/radius_conf.tmpl)12
-rw-r--r--data/templates/ocserv/radius_servers.j27
-rw-r--r--data/templates/ocserv/radius_servers.tmpl7
-rw-r--r--data/templates/openvpn/auth.pw.j2 (renamed from data/templates/openvpn/auth.pw.tmpl)2
-rw-r--r--data/templates/openvpn/client.conf.j2 (renamed from data/templates/openvpn/client.conf.tmpl)30
-rw-r--r--data/templates/openvpn/server.conf.j2224
-rw-r--r--data/templates/openvpn/server.conf.tmpl226
-rw-r--r--data/templates/openvpn/service-override.conf.j221
-rw-r--r--data/templates/openvpn/service-override.conf.tmpl20
-rw-r--r--data/templates/pmacct/override.conf.j217
-rw-r--r--data/templates/pmacct/uacctd.conf.j280
-rw-r--r--data/templates/pppoe/ip-down.script.tmpl38
-rw-r--r--data/templates/pppoe/ip-pre-up.script.tmpl18
-rw-r--r--data/templates/pppoe/ip-up.script.tmpl49
-rw-r--r--data/templates/pppoe/ipv6-up.script.tmpl46
-rw-r--r--data/templates/pppoe/peer.j2 (renamed from data/templates/pppoe/peer.tmpl)32
-rw-r--r--data/templates/router-advert/radvd.conf.j266
-rw-r--r--data/templates/router-advert/radvd.conf.tmpl66
-rw-r--r--data/templates/salt-minion/minion.j2 (renamed from data/templates/salt-minion/minion.tmpl)18
-rw-r--r--data/templates/snmp/etc.snmp.conf.j2 (renamed from data/templates/snmp/etc.snmp.conf.tmpl)2
-rw-r--r--data/templates/snmp/etc.snmpd.conf.j2182
-rw-r--r--data/templates/snmp/etc.snmpd.conf.tmpl119
-rw-r--r--data/templates/snmp/override.conf.j214
-rw-r--r--data/templates/snmp/override.conf.tmpl14
-rw-r--r--data/templates/snmp/usr.snmpd.conf.j28
-rw-r--r--data/templates/snmp/usr.snmpd.conf.tmpl6
-rw-r--r--data/templates/snmp/var.snmpd.conf.j216
-rw-r--r--data/templates/snmp/var.snmpd.conf.tmpl14
-rw-r--r--data/templates/squid/sg_acl.conf.j2 (renamed from data/templates/squid/sg_acl.conf.tmpl)0
-rw-r--r--data/templates/squid/squid.conf.j2111
-rw-r--r--data/templates/squid/squid.conf.tmpl113
-rw-r--r--data/templates/squid/squidGuard.conf.j2124
-rw-r--r--data/templates/squid/squidGuard.conf.tmpl124
-rw-r--r--data/templates/ssh/override.conf.j213
-rw-r--r--data/templates/ssh/override.conf.tmpl13
-rw-r--r--data/templates/ssh/sshd_config.j2 (renamed from data/templates/ssh/sshd_config.tmpl)54
-rw-r--r--data/templates/ssh/sshguard_config.j227
-rw-r--r--data/templates/ssh/sshguard_whitelist.j27
-rw-r--r--data/templates/syslog/logrotate.j211
-rw-r--r--data/templates/syslog/logrotate.tmpl12
-rw-r--r--data/templates/syslog/rsyslog.conf.j254
-rw-r--r--data/templates/syslog/rsyslog.conf.tmpl48
-rw-r--r--data/templates/system/curlrc.j26
-rw-r--r--data/templates/system/curlrc.tmpl8
-rw-r--r--data/templates/system/proxy.j27
-rw-r--r--data/templates/system/ssh_config.j23
-rw-r--r--data/templates/system/ssh_config.tmpl3
-rw-r--r--data/templates/system/sysctl.conf.j27
-rw-r--r--data/templates/system/sysctl.conf.tmpl7
-rw-r--r--data/templates/tftp-server/default.j28
-rw-r--r--data/templates/tftp-server/default.tmpl2
-rw-r--r--data/templates/vrf/vrf.conf.j29
-rw-r--r--data/templates/vrf/vrf.conf.tmpl9
-rw-r--r--data/templates/vrrp/keepalived.conf.tmpl106
-rw-r--r--data/templates/vyos-hostsd/hosts.j2 (renamed from data/templates/vyos-hostsd/hosts.tmpl)15
-rw-r--r--data/templates/vyos-hostsd/resolv.conf.j2 (renamed from data/templates/vyos-hostsd/resolv.conf.tmpl)14
-rw-r--r--data/templates/wifi/cfg80211.conf.tmpl1
-rw-r--r--data/templates/wifi/crda.tmpl1
-rw-r--r--data/templates/wifi/hostapd.conf.j2 (renamed from data/templates/wifi/hostapd.conf.tmpl)342
-rw-r--r--data/templates/wifi/wpa_supplicant.conf.j2 (renamed from data/templates/wifi/wpa_supplicant.conf.tmpl)8
-rw-r--r--data/templates/zone_policy/nftables.j2113
-rw-r--r--debian/control8
-rw-r--r--debian/vyos-1x.install2
-rw-r--r--debian/vyos-1x.postinst14
-rw-r--r--debian/vyos-1x.preinst2
-rw-r--r--interface-definitions/container.xml.in (renamed from interface-definitions/containers.xml.in)45
-rw-r--r--interface-definitions/dhcp-relay.xml.in9
-rw-r--r--interface-definitions/dhcp-server.xml.in51
-rw-r--r--interface-definitions/dhcpv6-relay.xml.in2
-rw-r--r--interface-definitions/dhcpv6-server.xml.in27
-rw-r--r--interface-definitions/dns-domain-name.xml.in7
-rw-r--r--interface-definitions/dns-dynamic.xml.in4
-rw-r--r--interface-definitions/dns-forwarding.xml.in473
-rw-r--r--interface-definitions/firewall.xml.in341
-rw-r--r--interface-definitions/flow-accounting-conf.xml.in116
-rw-r--r--interface-definitions/high-availability.xml.in (renamed from interface-definitions/vrrp.xml.in)191
-rw-r--r--interface-definitions/https.xml.in22
-rw-r--r--interface-definitions/igmp-proxy.xml.in10
-rw-r--r--interface-definitions/include/accel-ppp/auth-mode.xml.i2
-rw-r--r--interface-definitions/include/accel-ppp/auth-protocols.xml.i2
-rw-r--r--interface-definitions/include/accel-ppp/client-ip-pool-subnet-single.xml.i15
-rw-r--r--interface-definitions/include/accel-ppp/client-ipv6-pool.xml.i2
-rw-r--r--interface-definitions/include/accel-ppp/ppp-mppe.xml.i2
-rw-r--r--interface-definitions/include/accel-ppp/ppp-options-ipv4.xml.i2
-rw-r--r--interface-definitions/include/accel-ppp/ppp-options-ipv6.xml.i2
-rw-r--r--interface-definitions/include/accel-ppp/radius-additions-rate-limit.xml.i14
-rw-r--r--interface-definitions/include/accel-ppp/radius-additions.xml.i6
-rw-r--r--interface-definitions/include/arp-ndp-table-size.xml.i14
-rw-r--r--interface-definitions/include/auth-local-users.xml.i4
-rw-r--r--interface-definitions/include/bfd.xml.i8
-rw-r--r--interface-definitions/include/bfd/bfd.xml.i10
-rw-r--r--interface-definitions/include/bfd/common.xml.i (renamed from interface-definitions/include/bfd-common.xml.i)8
-rw-r--r--interface-definitions/include/bfd/profile.xml.i14
-rw-r--r--interface-definitions/include/bgp/afi-ipv4-prefix-list.xml.i4
-rw-r--r--interface-definitions/include/bgp/afi-ipv6-prefix-list.xml.i4
-rw-r--r--interface-definitions/include/bgp/afi-l2vpn-common.xml.i6
-rw-r--r--interface-definitions/include/bgp/afi-label.xml.i2
-rw-r--r--interface-definitions/include/bgp/afi-rd.xml.i2
-rw-r--r--interface-definitions/include/bgp/afi-route-map-export-import.xml.i4
-rw-r--r--interface-definitions/include/bgp/afi-route-target-vpn.xml.i6
-rw-r--r--interface-definitions/include/bgp/neighbor-afi-ipv4-ipv6-common.xml.i (renamed from interface-definitions/include/bgp/afi-common.xml.i)61
-rw-r--r--interface-definitions/include/bgp/neighbor-afi-ipv4-labeled-unicast.xml.i2
-rw-r--r--interface-definitions/include/bgp/neighbor-afi-ipv4-multicast.xml.i2
-rw-r--r--interface-definitions/include/bgp/neighbor-afi-ipv4-unicast.xml.i2
-rw-r--r--interface-definitions/include/bgp/neighbor-afi-ipv4-vpn.xml.i2
-rw-r--r--interface-definitions/include/bgp/neighbor-afi-ipv6-labeled-unicast.xml.i2
-rw-r--r--interface-definitions/include/bgp/neighbor-afi-ipv6-multicast.xml.i2
-rw-r--r--interface-definitions/include/bgp/neighbor-afi-ipv6-unicast.xml.i2
-rw-r--r--interface-definitions/include/bgp/neighbor-afi-ipv6-vpn.xml.i2
-rw-r--r--interface-definitions/include/bgp/neighbor-bfd.xml.i1
-rw-r--r--interface-definitions/include/bgp/neighbor-graceful-restart.xml.i2
-rw-r--r--interface-definitions/include/bgp/neighbor-shutdown.xml.i2
-rw-r--r--interface-definitions/include/bgp/protocol-common-config.xml.i68
-rw-r--r--interface-definitions/include/bgp/remote-as.xml.i2
-rw-r--r--interface-definitions/include/bgp/route-distinguisher.xml.i2
-rw-r--r--interface-definitions/include/bgp/timers-keepalive.xml.i2
-rw-r--r--interface-definitions/include/conntrack/log-common.xml.i20
-rw-r--r--interface-definitions/include/conntrack/timeout-common-protocols.xml.i172
-rw-r--r--interface-definitions/include/dhcp/ntp-server.xml.i26
-rw-r--r--interface-definitions/include/dns/time-to-live.xml.i15
-rw-r--r--interface-definitions/include/firewall/action-accept-drop-reject.xml.i2
-rw-r--r--interface-definitions/include/firewall/action.xml.i16
-rw-r--r--interface-definitions/include/firewall/common-rule.xml.i146
-rw-r--r--interface-definitions/include/firewall/icmp-type-name.xml.i142
-rw-r--r--interface-definitions/include/firewall/icmpv6-type-name.xml.i73
-rw-r--r--interface-definitions/include/firewall/mac-group.xml.i10
-rw-r--r--interface-definitions/include/firewall/name-default-action.xml.i4
-rw-r--r--interface-definitions/include/firewall/port.xml.i5
-rw-r--r--interface-definitions/include/firewall/source-destination-group-ipv6.xml.i34
-rw-r--r--interface-definitions/include/firewall/source-destination-group.xml.i10
-rw-r--r--interface-definitions/include/firewall/tcp-flags.xml.i119
-rw-r--r--interface-definitions/include/generic-disable-node.xml.i2
-rw-r--r--interface-definitions/include/interface/address-ipv4-ipv6-dhcp.xml.i2
-rw-r--r--interface-definitions/include/interface/adjust-mss.xml.i2
-rw-r--r--interface-definitions/include/interface/arp-cache-timeout.xml.i2
-rw-r--r--interface-definitions/include/interface/default-route-distance.xml.i15
-rw-r--r--interface-definitions/include/interface/description.xml.i2
-rw-r--r--interface-definitions/include/interface/dhcp-options.xml.i20
-rw-r--r--interface-definitions/include/interface/dhcpv6-options.xml.i4
-rw-r--r--interface-definitions/include/interface/inbound-interface.xml.i10
-rw-r--r--interface-definitions/include/interface/interface-firewall-vif-c.xml.i79
-rw-r--r--interface-definitions/include/interface/interface-firewall-vif.xml.i79
-rw-r--r--interface-definitions/include/interface/interface-firewall.xml.i79
-rw-r--r--interface-definitions/include/interface/interface-policy-vif-c.xml.i26
-rw-r--r--interface-definitions/include/interface/interface-policy-vif.xml.i26
-rw-r--r--interface-definitions/include/interface/interface-policy.xml.i26
-rw-r--r--interface-definitions/include/interface/netns.xml.i14
-rw-r--r--interface-definitions/include/interface/no-default-route.xml.i8
-rw-r--r--interface-definitions/include/interface/parameters-df.xml.i26
-rw-r--r--interface-definitions/include/interface/parameters-dont-fragment.xml.i8
-rw-r--r--interface-definitions/include/interface/parameters-flowlabel.xml.i2
-rw-r--r--interface-definitions/include/interface/redirect.xml.i17
-rw-r--r--interface-definitions/include/interface/source-validation.xml.i2
-rw-r--r--interface-definitions/include/interface/tunnel-remote-multi.xml.i19
-rw-r--r--interface-definitions/include/interface/tunnel-remote.xml.i2
-rw-r--r--interface-definitions/include/interface/vif-s.xml.i10
-rw-r--r--interface-definitions/include/interface/vif.xml.i10
-rw-r--r--interface-definitions/include/interface/vrf.xml.i2
-rw-r--r--interface-definitions/include/ipsec/local-address.xml.i3
-rw-r--r--interface-definitions/include/ipsec/local-traffic-selector.xml.i4
-rw-r--r--interface-definitions/include/isis/high-low-label-value.xml.i26
-rw-r--r--interface-definitions/include/isis/password.xml.i20
-rw-r--r--interface-definitions/include/isis/protocol-common-config.xml.i112
-rw-r--r--interface-definitions/include/listen-address-ipv4.xml.i4
-rw-r--r--interface-definitions/include/listen-address-vrf.xml.i25
-rw-r--r--interface-definitions/include/listen-address.xml.i5
-rw-r--r--interface-definitions/include/monitoring/url.xml.i15
-rw-r--r--interface-definitions/include/nat-port.xml.i9
-rw-r--r--interface-definitions/include/nat-rule.xml.i8
-rw-r--r--interface-definitions/include/nat-translation-options.xml.i14
-rw-r--r--interface-definitions/include/nat-translation-port.xml.i3
-rw-r--r--interface-definitions/include/ospf/authentication.xml.i4
-rw-r--r--interface-definitions/include/ospf/auto-cost.xml.i22
-rw-r--r--interface-definitions/include/ospf/default-information.xml.i25
-rw-r--r--interface-definitions/include/ospf/interface-common.xml.i4
-rw-r--r--interface-definitions/include/ospf/intervals.xml.i8
-rw-r--r--interface-definitions/include/ospf/metric-type.xml.i2
-rw-r--r--interface-definitions/include/ospf/protocol-common-config.xml.i144
-rw-r--r--interface-definitions/include/ospfv3/no-summary.xml.i8
-rw-r--r--interface-definitions/include/ospfv3/protocol-common-config.xml.i252
-rw-r--r--interface-definitions/include/policy/action.xml.i2
-rw-r--r--interface-definitions/include/policy/route-common-rule-ipv6.xml.i553
-rw-r--r--interface-definitions/include/policy/route-common-rule.xml.i402
-rw-r--r--interface-definitions/include/policy/route-rule-action.xml.i17
-rw-r--r--interface-definitions/include/qos/bandwidth.xml.i15
-rw-r--r--interface-definitions/include/qos/burst.xml.i16
-rw-r--r--interface-definitions/include/qos/codel-quantum.xml.i16
-rw-r--r--interface-definitions/include/qos/dscp.xml.i143
-rw-r--r--interface-definitions/include/qos/flows.xml.i16
-rw-r--r--interface-definitions/include/qos/hfsc-d.xml.i15
-rw-r--r--interface-definitions/include/qos/hfsc-m1.xml.i32
-rw-r--r--interface-definitions/include/qos/hfsc-m2.xml.i32
-rw-r--r--interface-definitions/include/qos/interval.xml.i16
-rw-r--r--interface-definitions/include/qos/match.xml.i221
-rw-r--r--interface-definitions/include/qos/max-length.xml.i15
-rw-r--r--interface-definitions/include/qos/queue-limit-1-4294967295.xml.i15
-rw-r--r--interface-definitions/include/qos/queue-limit-2-10999.xml.i16
-rw-r--r--interface-definitions/include/qos/queue-type.xml.i30
-rw-r--r--interface-definitions/include/qos/set-dscp.xml.i63
-rw-r--r--interface-definitions/include/qos/target.xml.i16
-rw-r--r--interface-definitions/include/qos/tcp-flags.xml.i21
-rw-r--r--interface-definitions/include/radius-server-port.xml.i2
-rw-r--r--interface-definitions/include/rip/rip-timers.xml.i6
-rw-r--r--interface-definitions/include/route-map.xml.i2
-rw-r--r--interface-definitions/include/routing-passive-interface.xml.i2
-rw-r--r--interface-definitions/include/snmp/access-mode.xml.i23
-rw-r--r--interface-definitions/include/snmp/authentication-type.xml.i22
-rw-r--r--interface-definitions/include/snmp/privacy-type.xml.i22
-rw-r--r--interface-definitions/include/snmp/protocol.xml.i22
-rw-r--r--interface-definitions/include/ssh-user.xml.i4
-rw-r--r--interface-definitions/include/static/static-route-blackhole.xml.i3
-rw-r--r--interface-definitions/include/static/static-route-reject.xml.i12
-rw-r--r--interface-definitions/include/static/static-route-tag.xml.i14
-rw-r--r--interface-definitions/include/static/static-route-vrf.xml.i2
-rw-r--r--interface-definitions/include/static/static-route.xml.i24
-rw-r--r--interface-definitions/include/static/static-route6.xml.i24
-rw-r--r--interface-definitions/include/version/bgp-version.xml.i3
-rw-r--r--interface-definitions/include/version/broadcast-relay-version.xml.i3
-rw-r--r--interface-definitions/include/version/cluster-version.xml.i3
-rw-r--r--interface-definitions/include/version/config-management-version.xml.i3
-rw-r--r--interface-definitions/include/version/conntrack-sync-version.xml.i3
-rw-r--r--interface-definitions/include/version/conntrack-version.xml.i3
-rw-r--r--interface-definitions/include/version/dhcp-relay-version.xml.i3
-rw-r--r--interface-definitions/include/version/dhcp-server-version.xml.i3
-rw-r--r--interface-definitions/include/version/dhcpv6-server-version.xml.i3
-rw-r--r--interface-definitions/include/version/dns-forwarding-version.xml.i3
-rw-r--r--interface-definitions/include/version/firewall-version.xml.i3
-rw-r--r--interface-definitions/include/version/flow-accounting-version.xml.i3
-rw-r--r--interface-definitions/include/version/https-version.xml.i3
-rw-r--r--interface-definitions/include/version/interfaces-version.xml.i3
-rw-r--r--interface-definitions/include/version/ipoe-server-version.xml.i3
-rw-r--r--interface-definitions/include/version/ipsec-version.xml.i3
-rw-r--r--interface-definitions/include/version/isis-version.xml.i3
-rw-r--r--interface-definitions/include/version/l2tp-version.xml.i3
-rw-r--r--interface-definitions/include/version/lldp-version.xml.i3
-rw-r--r--interface-definitions/include/version/mdns-version.xml.i3
-rw-r--r--interface-definitions/include/version/nat-version.xml.i3
-rw-r--r--interface-definitions/include/version/nat66-version.xml.i3
-rw-r--r--interface-definitions/include/version/ntp-version.xml.i3
-rw-r--r--interface-definitions/include/version/openconnect-version.xml.i3
-rw-r--r--interface-definitions/include/version/ospf-version.xml.i3
-rw-r--r--interface-definitions/include/version/policy-version.xml.i3
-rw-r--r--interface-definitions/include/version/pppoe-server-version.xml.i3
-rw-r--r--interface-definitions/include/version/pptp-version.xml.i3
-rw-r--r--interface-definitions/include/version/qos-version.xml.i3
-rw-r--r--interface-definitions/include/version/quagga-version.xml.i3
-rw-r--r--interface-definitions/include/version/rpki-version.xml.i3
-rw-r--r--interface-definitions/include/version/salt-version.xml.i3
-rw-r--r--interface-definitions/include/version/snmp-version.xml.i3
-rw-r--r--interface-definitions/include/version/ssh-version.xml.i3
-rw-r--r--interface-definitions/include/version/sstp-version.xml.i3
-rw-r--r--interface-definitions/include/version/system-version.xml.i3
-rw-r--r--interface-definitions/include/version/vrf-version.xml.i3
-rw-r--r--interface-definitions/include/version/vrrp-version.xml.i3
-rw-r--r--interface-definitions/include/version/vyos-accel-ppp-version.xml.i3
-rw-r--r--interface-definitions/include/version/wanloadbalance-version.xml.i3
-rw-r--r--interface-definitions/include/version/webproxy-version.xml.i3
-rw-r--r--interface-definitions/include/vpn-ipsec-encryption.xml.i5
-rw-r--r--interface-definitions/include/vpn-ipsec-hash.xml.i5
-rw-r--r--interface-definitions/include/webproxy-url-filtering.xml.i2
-rw-r--r--interface-definitions/interfaces-bonding.xml.in17
-rw-r--r--interface-definitions/interfaces-bridge.xml.in17
-rw-r--r--interface-definitions/interfaces-dummy.xml.in7
-rw-r--r--interface-definitions/interfaces-ethernet.xml.in13
-rw-r--r--interface-definitions/interfaces-geneve.xml.in8
-rw-r--r--interface-definitions/interfaces-input.xml.in29
-rw-r--r--interface-definitions/interfaces-l2tpv3.xml.in14
-rw-r--r--interface-definitions/interfaces-loopback.xml.in4
-rw-r--r--interface-definitions/interfaces-macsec.xml.in20
-rw-r--r--interface-definitions/interfaces-openvpn.xml.in48
-rw-r--r--interface-definitions/interfaces-pppoe.xml.in37
-rw-r--r--interface-definitions/interfaces-pseudo-ethernet.xml.in8
-rw-r--r--interface-definitions/interfaces-tunnel.xml.in68
-rw-r--r--interface-definitions/interfaces-vti.xml.in6
-rw-r--r--interface-definitions/interfaces-vxlan.xml.in22
-rw-r--r--interface-definitions/interfaces-wireguard.xml.in17
-rw-r--r--interface-definitions/interfaces-wireless.xml.in58
-rw-r--r--interface-definitions/interfaces-wwan.xml.in10
-rw-r--r--interface-definitions/lldp.xml.in22
-rw-r--r--interface-definitions/nat.xml.in3
-rw-r--r--interface-definitions/nat66.xml.in2
-rw-r--r--interface-definitions/netns.xml.in23
-rw-r--r--interface-definitions/policy-local-route.xml.in111
-rw-r--r--interface-definitions/policy-route.xml.in105
-rw-r--r--interface-definitions/policy.xml.in151
-rw-r--r--interface-definitions/protocols-bfd.xml.in20
-rw-r--r--interface-definitions/protocols-nhrp.xml.in6
-rw-r--r--interface-definitions/protocols-ospfv3.xml.in221
-rw-r--r--interface-definitions/protocols-rip.xml.in4
-rw-r--r--interface-definitions/protocols-rpki.xml.in2
-rw-r--r--interface-definitions/protocols-static-arp.xml.in44
-rw-r--r--interface-definitions/qos.xml.in789
-rw-r--r--interface-definitions/salt-minion.xml.in15
-rw-r--r--interface-definitions/service-ids-ddos-protection.xml.in2
-rw-r--r--interface-definitions/service_conntrack-sync.xml.in7
-rw-r--r--interface-definitions/service_console-server.xml.in12
-rw-r--r--interface-definitions/service_ipoe-server.xml.in22
-rw-r--r--interface-definitions/service_monitoring_telegraf.xml.in308
-rw-r--r--interface-definitions/service_pppoe-server.xml.in26
-rw-r--r--interface-definitions/service_router-advert.xml.in24
-rw-r--r--interface-definitions/service_upnp.xml.in224
-rw-r--r--interface-definitions/service_webproxy.xml.in41
-rw-r--r--interface-definitions/snmp.xml.in276
-rw-r--r--interface-definitions/ssh.xml.in82
-rw-r--r--interface-definitions/system-conntrack.xml.in332
-rw-r--r--interface-definitions/system-console.xml.in4
-rw-r--r--interface-definitions/system-ip.xml.in16
-rw-r--r--interface-definitions/system-ipv6.xml.in21
-rw-r--r--interface-definitions/system-lcd.xml.in4
-rw-r--r--interface-definitions/system-login-banner.xml.in4
-rw-r--r--interface-definitions/system-login.xml.in12
-rw-r--r--interface-definitions/system-logs.xml.in92
-rw-r--r--interface-definitions/system-option.xml.in4
-rw-r--r--interface-definitions/system-proxy.xml.in4
-rw-r--r--interface-definitions/system-syslog.xml.in22
-rw-r--r--interface-definitions/tftp-server.xml.in2
-rw-r--r--interface-definitions/vpn_ipsec.xml.in249
-rw-r--r--interface-definitions/vpn_l2tp.xml.in14
-rw-r--r--interface-definitions/vpn_openconnect.xml.in142
-rw-r--r--interface-definitions/vpn_pptp.xml.in2
-rw-r--r--interface-definitions/vrf.xml.in25
-rw-r--r--interface-definitions/xml-component-version.xml.in44
-rw-r--r--interface-definitions/zone-policy.xml.in147
-rw-r--r--op-mode-definitions/conntrack-sync.xml.in12
-rw-r--r--op-mode-definitions/container.xml.in (renamed from op-mode-definitions/containers.xml.in)60
-rw-r--r--op-mode-definitions/disks.xml.in2
-rw-r--r--op-mode-definitions/firewall.xml.in191
-rw-r--r--op-mode-definitions/generate-openconnect-user-key.xml.in67
-rw-r--r--op-mode-definitions/generate-openvpn-config-client.xml.in58
-rw-r--r--op-mode-definitions/include/bgp/afi-common.xml.i1
-rw-r--r--op-mode-definitions/include/bgp/afi-ipv4-ipv6-common.xml.i1
-rw-r--r--op-mode-definitions/include/bgp/afi-ipv4-ipv6-flowspec.xml.i25
-rw-r--r--op-mode-definitions/include/bgp/show-bgp-common.xml.i1
-rw-r--r--op-mode-definitions/include/ospf-common.xml.i9
-rw-r--r--op-mode-definitions/include/ospfv3/border-routers.xml.i20
-rw-r--r--op-mode-definitions/include/ospfv3/database.xml.i238
-rw-r--r--op-mode-definitions/include/ospfv3/interface.xml.i75
-rw-r--r--op-mode-definitions/include/ospfv3/linkstate.xml.i38
-rw-r--r--op-mode-definitions/include/ospfv3/neighbor.xml.i17
-rw-r--r--op-mode-definitions/include/ospfv3/redistribute.xml.i8
-rw-r--r--op-mode-definitions/include/ospfv3/route.xml.i79
-rw-r--r--op-mode-definitions/include/show-route-bgp.xml.i8
-rw-r--r--op-mode-definitions/include/show-route-connected.xml.i8
-rw-r--r--op-mode-definitions/include/show-route-isis.xml.i8
-rw-r--r--op-mode-definitions/include/show-route-kernel.xml.i8
-rw-r--r--op-mode-definitions/include/show-route-ospf.xml.i8
-rw-r--r--op-mode-definitions/include/show-route-ospfv3.xml.i8
-rw-r--r--op-mode-definitions/include/show-route-rip.xml.i8
-rw-r--r--op-mode-definitions/include/show-route-ripng.xml.i8
-rw-r--r--op-mode-definitions/include/show-route-static.xml.i8
-rw-r--r--op-mode-definitions/include/show-route-summary.xml.i8
-rw-r--r--op-mode-definitions/include/show-route-supernets-only.xml.i8
-rw-r--r--op-mode-definitions/include/show-route-table.xml.i17
-rw-r--r--op-mode-definitions/include/show-route-tag.xml.i16
-rw-r--r--op-mode-definitions/monitor-log.xml.in172
-rw-r--r--op-mode-definitions/policy-route.xml.in143
-rw-r--r--op-mode-definitions/reboot.xml.in4
-rw-r--r--op-mode-definitions/restart-frr.xml.in6
-rw-r--r--op-mode-definitions/show-bfd.xml.in56
-rw-r--r--op-mode-definitions/show-configuration.xml.in15
-rw-r--r--op-mode-definitions/show-interfaces-geneve.xml.in42
-rw-r--r--op-mode-definitions/show-ip-route.xml.in109
-rw-r--r--op-mode-definitions/show-ipv6-ospfv3.xml.in469
-rw-r--r--op-mode-definitions/show-ipv6-route.xml.in97
-rw-r--r--op-mode-definitions/show-log.xml.in106
-rw-r--r--op-mode-definitions/show-netns.xml.in13
-rw-r--r--op-mode-definitions/show-protocols.xml.in44
-rw-r--r--op-mode-definitions/show-system.xml.in4
-rw-r--r--op-mode-definitions/show-virtual-server.xml.in13
-rw-r--r--op-mode-definitions/traceroute.xml.in220
-rw-r--r--op-mode-definitions/zone-policy.xml.in24
-rw-r--r--python/vyos/base.py21
-rw-r--r--python/vyos/config.py57
-rw-r--r--python/vyos/configdict.py210
-rw-r--r--python/vyos/configdiff.py114
-rw-r--r--python/vyos/configquery.py46
-rw-r--r--python/vyos/configsource.py5
-rw-r--r--python/vyos/configtree.py96
-rw-r--r--python/vyos/configverify.py58
-rw-r--r--python/vyos/cpu.py102
-rw-r--r--python/vyos/defaults.py8
-rw-r--r--python/vyos/ethtool.py13
-rw-r--r--python/vyos/firewall.py259
-rw-r--r--python/vyos/frr.py66
-rw-r--r--python/vyos/hostsd_client.py12
-rw-r--r--python/vyos/ifconfig/__init__.py1
-rw-r--r--python/vyos/ifconfig/bridge.py12
-rw-r--r--python/vyos/ifconfig/ethernet.py17
-rw-r--r--python/vyos/ifconfig/geneve.py2
-rwxr-xr-xpython/vyos/ifconfig/interface.py252
-rw-r--r--python/vyos/ifconfig/loopback.py12
-rw-r--r--python/vyos/ifconfig/pppoe.py80
-rw-r--r--python/vyos/ifconfig/section.py10
-rw-r--r--python/vyos/ifconfig/vxlan.py32
-rw-r--r--python/vyos/ifconfig/wireless.py6
-rw-r--r--python/vyos/migrator.py2
-rw-r--r--python/vyos/pki.py26
-rw-r--r--python/vyos/range_regex.py142
-rw-r--r--python/vyos/remote.py39
-rw-r--r--python/vyos/systemversions.py7
-rw-r--r--python/vyos/template.py164
-rw-r--r--python/vyos/util.py67
-rw-r--r--python/vyos/validate.py32
-rw-r--r--python/vyos/xml/__init__.py4
-rw-r--r--python/vyos/xml/definition.py9
-rwxr-xr-xscripts/build-command-templates17
-rw-r--r--smoketest/configs.no-load/firewall-big43440
-rw-r--r--smoketest/configs/basic-vyos140
-rw-r--r--smoketest/configs/bgp-big-as-cloud10
-rw-r--r--smoketest/configs/dialup-router-complex19
-rw-r--r--smoketest/configs/dialup-router-medium-vpn33
-rw-r--r--smoketest/configs/ipv6-disable83
-rw-r--r--smoketest/configs/qos-basic205
-rw-r--r--smoketest/scripts/cli/base_interfaces_test.py103
-rw-r--r--smoketest/scripts/cli/base_vyostest_shim.py17
-rwxr-xr-xsmoketest/scripts/cli/test_component_version.py36
-rwxr-xr-xsmoketest/scripts/cli/test_configd_init.py38
-rwxr-xr-xsmoketest/scripts/cli/test_firewall.py233
-rwxr-xr-xsmoketest/scripts/cli/test_ha_virtual_server.py146
-rwxr-xr-xsmoketest/scripts/cli/test_ha_vrrp.py46
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_bonding.py43
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_bridge.py5
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_dummy.py2
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_ethernet.py152
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_geneve.py6
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_l2tpv3.py2
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_loopback.py2
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_macsec.py5
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_netns.py83
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_openvpn.py114
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_pppoe.py14
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_pseudo_ethernet.py5
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_tunnel.py108
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_vxlan.py75
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_wireguard.py9
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_wireless.py2
-rwxr-xr-xsmoketest/scripts/cli/test_nat.py119
-rwxr-xr-xsmoketest/scripts/cli/test_nat66.py4
-rwxr-xr-xsmoketest/scripts/cli/test_pki.py9
-rwxr-xr-xsmoketest/scripts/cli/test_policy.py433
-rwxr-xr-xsmoketest/scripts/cli/test_policy_route.py145
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_bfd.py85
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_bgp.py335
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_isis.py51
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_mpls.py116
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_nhrp.py9
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_ospf.py171
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_ospfv3.py135
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_ripng.py22
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_rpki.py2
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_static.py57
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_static_arp.py88
-rwxr-xr-xsmoketest/scripts/cli/test_service_dhcp-server.py9
-rwxr-xr-xsmoketest/scripts/cli/test_service_dhcpv6-server.py20
-rwxr-xr-xsmoketest/scripts/cli/test_service_https.py78
-rwxr-xr-xsmoketest/scripts/cli/test_service_ids.py94
-rwxr-xr-xsmoketest/scripts/cli/test_service_lldp.py127
-rwxr-xr-xsmoketest/scripts/cli/test_service_monitoring_telegraf.py65
-rwxr-xr-xsmoketest/scripts/cli/test_service_salt.py105
-rwxr-xr-xsmoketest/scripts/cli/test_service_snmp.py104
-rwxr-xr-xsmoketest/scripts/cli/test_service_ssh.py123
-rwxr-xr-xsmoketest/scripts/cli/test_service_tftp-server.py39
-rwxr-xr-xsmoketest/scripts/cli/test_service_upnp.py105
-rwxr-xr-xsmoketest/scripts/cli/test_service_webproxy.py16
-rwxr-xr-xsmoketest/scripts/cli/test_system_conntrack.py24
-rwxr-xr-xsmoketest/scripts/cli/test_system_flow-accounting.py230
-rwxr-xr-xsmoketest/scripts/cli/test_system_ipv6.py17
-rwxr-xr-xsmoketest/scripts/cli/test_system_login.py10
-rwxr-xr-xsmoketest/scripts/cli/test_system_logs.py117
-rwxr-xr-xsmoketest/scripts/cli/test_system_ntp.py60
-rwxr-xr-xsmoketest/scripts/cli/test_vpn_ipsec.py111
-rwxr-xr-xsmoketest/scripts/cli/test_vpn_openconnect.py42
-rwxr-xr-xsmoketest/scripts/cli/test_vrf.py93
-rwxr-xr-xsmoketest/scripts/cli/test_zone_policy.py69
-rwxr-xr-xsrc/conf_mode/arp.py114
-rwxr-xr-xsrc/conf_mode/bcast_relay.py4
-rwxr-xr-xsrc/conf_mode/conntrack.py66
-rwxr-xr-xsrc/conf_mode/conntrack_sync.py15
-rwxr-xr-xsrc/conf_mode/container.py (renamed from src/conf_mode/containers.py)102
-rwxr-xr-xsrc/conf_mode/dhcp_relay.py7
-rwxr-xr-xsrc/conf_mode/dhcp_server.py8
-rwxr-xr-xsrc/conf_mode/dhcpv6_relay.py7
-rwxr-xr-xsrc/conf_mode/dhcpv6_server.py37
-rwxr-xr-xsrc/conf_mode/dns_forwarding.py234
-rwxr-xr-xsrc/conf_mode/dynamic_dns.py2
-rwxr-xr-xsrc/conf_mode/firewall-interface.py175
-rwxr-xr-xsrc/conf_mode/firewall.py388
-rwxr-xr-xsrc/conf_mode/flow_accounting_conf.py454
-rwxr-xr-xsrc/conf_mode/high-availability.py (renamed from src/conf_mode/vrrp.py)71
-rwxr-xr-xsrc/conf_mode/host_name.py5
-rwxr-xr-xsrc/conf_mode/http-api.py63
-rwxr-xr-xsrc/conf_mode/https.py18
-rwxr-xr-xsrc/conf_mode/igmp_proxy.py5
-rwxr-xr-xsrc/conf_mode/interfaces-bonding.py16
-rwxr-xr-xsrc/conf_mode/interfaces-bridge.py11
-rwxr-xr-xsrc/conf_mode/interfaces-dummy.py4
-rwxr-xr-xsrc/conf_mode/interfaces-ethernet.py33
-rwxr-xr-xsrc/conf_mode/interfaces-geneve.py30
-rwxr-xr-xsrc/conf_mode/interfaces-l2tpv3.py8
-rwxr-xr-xsrc/conf_mode/interfaces-loopback.py4
-rwxr-xr-xsrc/conf_mode/interfaces-macsec.py6
-rwxr-xr-xsrc/conf_mode/interfaces-openvpn.py45
-rwxr-xr-xsrc/conf_mode/interfaces-pppoe.py41
-rwxr-xr-xsrc/conf_mode/interfaces-pseudo-ethernet.py14
-rwxr-xr-xsrc/conf_mode/interfaces-tunnel.py95
-rwxr-xr-xsrc/conf_mode/interfaces-vti.py4
-rwxr-xr-xsrc/conf_mode/interfaces-vxlan.py94
-rwxr-xr-xsrc/conf_mode/interfaces-wireguard.py12
-rwxr-xr-xsrc/conf_mode/interfaces-wireless.py14
-rwxr-xr-xsrc/conf_mode/interfaces-wwan.py132
-rwxr-xr-xsrc/conf_mode/lldp.py240
-rwxr-xr-xsrc/conf_mode/nat.py42
-rwxr-xr-xsrc/conf_mode/nat66.py31
-rwxr-xr-xsrc/conf_mode/netns.py118
-rwxr-xr-xsrc/conf_mode/ntp.py4
-rwxr-xr-xsrc/conf_mode/policy-local-route.py205
-rwxr-xr-xsrc/conf_mode/policy-route-interface.py120
-rwxr-xr-xsrc/conf_mode/policy-route.py262
-rwxr-xr-xsrc/conf_mode/policy.py30
-rwxr-xr-xsrc/conf_mode/protocols_bfd.py35
-rwxr-xr-xsrc/conf_mode/protocols_bgp.py97
-rwxr-xr-xsrc/conf_mode/protocols_igmp.py2
-rwxr-xr-xsrc/conf_mode/protocols_isis.py76
-rwxr-xr-xsrc/conf_mode/protocols_mpls.py59
-rwxr-xr-xsrc/conf_mode/protocols_nhrp.py38
-rwxr-xr-xsrc/conf_mode/protocols_ospf.py44
-rwxr-xr-xsrc/conf_mode/protocols_ospfv3.py118
-rwxr-xr-xsrc/conf_mode/protocols_pim.py2
-rwxr-xr-xsrc/conf_mode/protocols_rip.py35
-rwxr-xr-xsrc/conf_mode/protocols_ripng.py29
-rwxr-xr-xsrc/conf_mode/protocols_rpki.py19
-rwxr-xr-xsrc/conf_mode/protocols_static.py28
-rwxr-xr-xsrc/conf_mode/protocols_static_multicast.py2
-rwxr-xr-xsrc/conf_mode/qos.py87
-rwxr-xr-xsrc/conf_mode/salt-minion.py75
-rwxr-xr-xsrc/conf_mode/service_console-server.py4
-rwxr-xr-xsrc/conf_mode/service_ids_fastnetmon.py4
-rwxr-xr-xsrc/conf_mode/service_ipoe-server.py27
-rwxr-xr-xsrc/conf_mode/service_mdns-repeater.py4
-rwxr-xr-xsrc/conf_mode/service_monitoring_telegraf.py229
-rwxr-xr-xsrc/conf_mode/service_pppoe-server.py19
-rwxr-xr-xsrc/conf_mode/service_router-advert.py2
-rwxr-xr-xsrc/conf_mode/service_upnp.py157
-rwxr-xr-xsrc/conf_mode/service_webproxy.py6
-rwxr-xr-xsrc/conf_mode/snmp.py642
-rwxr-xr-xsrc/conf_mode/ssh.py23
-rwxr-xr-xsrc/conf_mode/system-ip.py43
-rwxr-xr-xsrc/conf_mode/system-ipv6.py99
-rwxr-xr-xsrc/conf_mode/system-login-banner.py35
-rwxr-xr-xsrc/conf_mode/system-login.py25
-rwxr-xr-xsrc/conf_mode/system-logs.py83
-rwxr-xr-xsrc/conf_mode/system-option.py4
-rwxr-xr-xsrc/conf_mode/system-proxy.py90
-rwxr-xr-xsrc/conf_mode/system-syslog.py16
-rwxr-xr-xsrc/conf_mode/system_console.py2
-rwxr-xr-xsrc/conf_mode/system_lcd.py6
-rwxr-xr-xsrc/conf_mode/system_sysctl.py2
-rwxr-xr-xsrc/conf_mode/tftp_server.py16
-rwxr-xr-xsrc/conf_mode/vpn_ipsec.py20
-rwxr-xr-xsrc/conf_mode/vpn_l2tp.py4
-rwxr-xr-xsrc/conf_mode/vpn_openconnect.py100
-rwxr-xr-xsrc/conf_mode/vpn_pptp.py4
-rwxr-xr-xsrc/conf_mode/vpn_sstp.py4
-rwxr-xr-xsrc/conf_mode/vrf.py126
-rwxr-xr-xsrc/conf_mode/vrf_vni.py10
-rwxr-xr-xsrc/conf_mode/zone_policy.py213
-rw-r--r--src/etc/cron.d/check-wwan1
-rw-r--r--src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper2
-rw-r--r--src/etc/dhcp/dhclient-enter-hooks.d/04-vyos-resolvconf82
-rw-r--r--src/etc/dhcp/dhclient-exit-hooks.d/01-vyos-cleanup31
-rw-r--r--src/etc/logrotate.d/conntrackd9
-rw-r--r--src/etc/logrotate.d/vyos-rsyslog12
-rwxr-xr-xsrc/etc/ppp/ip-up.d/99-vyos-pppoe-callback20
-rw-r--r--src/etc/systemd/system/keepalived.service.d/override.conf13
-rwxr-xr-xsrc/etc/telegraf/custom_scripts/show_firewall_input_filter.py73
-rwxr-xr-xsrc/etc/telegraf/custom_scripts/show_interfaces_input_filter.py88
-rwxr-xr-xsrc/etc/telegraf/custom_scripts/vyos_services_input_filter.py61
-rwxr-xr-xsrc/helpers/strip-private.py10
-rwxr-xr-xsrc/helpers/system-versions-foot.py2
-rwxr-xr-xsrc/helpers/vyos-boot-config-loader.py4
-rwxr-xr-xsrc/helpers/vyos-check-wwan.py6
-rwxr-xr-xsrc/helpers/vyos-vrrp-conntracksync.sh8
-rwxr-xr-xsrc/helpers/vyos_net_name31
-rwxr-xr-xsrc/migration-scripts/bgp/0-to-12
-rwxr-xr-xsrc/migration-scripts/bgp/1-to-233
-rwxr-xr-xsrc/migration-scripts/dns-forwarding/1-to-283
-rwxr-xr-xsrc/migration-scripts/firewall/6-to-7226
-rwxr-xr-xsrc/migration-scripts/flow-accounting/0-to-169
-rwxr-xr-xsrc/migration-scripts/interfaces/25-to-2654
-rwxr-xr-xsrc/migration-scripts/ipsec/8-to-948
-rwxr-xr-xsrc/migration-scripts/openconnect/1-to-254
-rwxr-xr-xsrc/migration-scripts/ospf/0-to-181
-rwxr-xr-xsrc/migration-scripts/policy/1-to-286
-rwxr-xr-xsrc/migration-scripts/quagga/9-to-1062
-rwxr-xr-xsrc/migration-scripts/ssh/1-to-250
-rwxr-xr-xsrc/migration-scripts/system/22-to-2350
-rwxr-xr-xsrc/migration-scripts/system/23-to-2485
-rwxr-xr-xsrc/op_mode/conntrack_sync.py47
-rwxr-xr-xsrc/op_mode/containers_op.py78
-rwxr-xr-xsrc/op_mode/cpu_summary.py36
-rwxr-xr-xsrc/op_mode/firewall.py361
-rwxr-xr-xsrc/op_mode/format_disk.py76
-rwxr-xr-xsrc/op_mode/generate_openconnect_otp_key.py65
-rwxr-xr-xsrc/op_mode/generate_ovpn_client_file.py149
-rwxr-xr-xsrc/op_mode/generate_public_key_command.py11
-rwxr-xr-xsrc/op_mode/ikev2_profile_generator.py4
-rwxr-xr-xsrc/op_mode/lldp_op.py5
-rwxr-xr-xsrc/op_mode/monitor_bandwidth_test.sh3
-rwxr-xr-xsrc/op_mode/policy_route.py189
-rwxr-xr-xsrc/op_mode/powerctrl.py25
-rwxr-xr-xsrc/op_mode/ppp-server-ctrl.py2
-rwxr-xr-xsrc/op_mode/restart_frr.py5
-rwxr-xr-xsrc/op_mode/show_configuration_json.py36
-rwxr-xr-xsrc/op_mode/show_cpu.py63
-rwxr-xr-xsrc/op_mode/show_dhcp.py3
-rwxr-xr-xsrc/op_mode/show_dhcpv6.py3
-rwxr-xr-xsrc/op_mode/show_ipsec_sa.py186
-rwxr-xr-xsrc/op_mode/show_nat_rules.py22
-rwxr-xr-xsrc/op_mode/show_openvpn.py23
-rwxr-xr-xsrc/op_mode/show_ram.py19
-rwxr-xr-xsrc/op_mode/show_uptime.py38
-rwxr-xr-xsrc/op_mode/show_version.py22
-rwxr-xr-xsrc/op_mode/show_virtual_server.py33
-rwxr-xr-xsrc/op_mode/traceroute.py207
-rwxr-xr-xsrc/op_mode/vpn_ipsec.py17
-rwxr-xr-xsrc/op_mode/vrrp.py13
-rwxr-xr-xsrc/op_mode/zone_policy.py81
-rw-r--r--src/services/api/graphql/README.graphql84
-rw-r--r--src/services/api/graphql/bindings.py18
-rw-r--r--src/services/api/graphql/graphql/directives.py50
-rw-r--r--src/services/api/graphql/graphql/mutations.py41
-rw-r--r--src/services/api/graphql/graphql/queries.py89
-rw-r--r--src/services/api/graphql/graphql/schema/firewall_group.graphql48
-rw-r--r--src/services/api/graphql/graphql/schema/image.graphql29
-rw-r--r--src/services/api/graphql/graphql/schema/schema.graphql17
-rw-r--r--src/services/api/graphql/graphql/schema/show.graphql14
-rw-r--r--src/services/api/graphql/graphql/schema/show_config.graphql21
-rw-r--r--src/services/api/graphql/recipes/remove_firewall_address_group_members.py14
-rw-r--r--src/services/api/graphql/recipes/session.py75
-rw-r--r--src/services/api/graphql/recipes/templates/create_firewall_address_ipv_6_group.tmpl4
-rw-r--r--src/services/api/graphql/recipes/templates/remove_firewall_address_ipv_6_group_members.tmpl3
-rw-r--r--src/services/api/graphql/recipes/templates/update_firewall_address_ipv_6_group_members.tmpl3
-rwxr-xr-xsrc/services/vyos-configd3
-rwxr-xr-xsrc/services/vyos-hostsd44
-rwxr-xr-xsrc/services/vyos-http-api-server36
-rwxr-xr-xsrc/system/keepalived-fifo.py39
-rw-r--r--src/systemd/keepalived.service13
-rw-r--r--src/systemd/miniupnpd.service13
-rw-r--r--src/systemd/tftpd@.service2
-rw-r--r--src/systemd/vyos-hostsd.service2
-rw-r--r--src/systemd/vyos-http-api.service23
-rw-r--r--src/tests/test_util.py5
-rw-r--r--src/tests/test_validate.py4
-rwxr-xr-xsrc/utils/vyos-hostsd-client3
-rwxr-xr-xsrc/validators/as-number-list29
-rwxr-xr-xsrc/validators/bgp-rd-rt (renamed from src/validators/bgp-route-target)30
-rwxr-xr-xsrc/validators/ip-address7
-rwxr-xr-xsrc/validators/ip-cidr7
-rwxr-xr-xsrc/validators/ip-host7
-rwxr-xr-xsrc/validators/ip-prefix7
-rwxr-xr-xsrc/validators/ip-protocol3
-rwxr-xr-xsrc/validators/ipv47
-rwxr-xr-xsrc/validators/ipv4-address7
-rwxr-xr-xsrc/validators/ipv4-host7
-rwxr-xr-xsrc/validators/ipv4-multicast9
-rwxr-xr-xsrc/validators/ipv4-prefix7
-rwxr-xr-xsrc/validators/ipv4-range13
-rwxr-xr-xsrc/validators/ipv67
-rwxr-xr-xsrc/validators/ipv6-address7
-rwxr-xr-xsrc/validators/ipv6-host7
-rwxr-xr-xsrc/validators/ipv6-link-local12
-rwxr-xr-xsrc/validators/ipv6-multicast9
-rwxr-xr-xsrc/validators/ipv6-prefix7
-rwxr-xr-xsrc/validators/ipv6-range30
-rwxr-xr-xsrc/validators/mac-address-firewall27
-rwxr-xr-xsrc/validators/port-multi52
-rwxr-xr-xsrc/validators/port-range35
-rwxr-xr-xsrc/validators/range56
-rwxr-xr-xsrc/validators/script4
-rwxr-xr-xsrc/validators/tcp-flag17
-rw-r--r--test-requirements.txt1
832 files changed, 73336 insertions, 11706 deletions
diff --git a/.github/workflows/pull-request-management.yml b/.github/workflows/pull-request-management.yml
new file mode 100644
index 000000000..3a855c107
--- /dev/null
+++ b/.github/workflows/pull-request-management.yml
@@ -0,0 +1,25 @@
+---
+name: Build Pull Request Package
+
+on:
+ pull_request:
+ branches:
+ - current
+ - crux
+ - equuleus
+
+jobs:
+ j2lint:
+ name: Validate j2 files
+ runs-on: ubuntu-20.04
+ steps:
+ - uses: actions/checkout@v2
+ timeout-minutes: 2
+ - name: Setup J2Lint
+ timeout-minutes: 2
+ run: |
+ sudo pip install git+https://github.com/aristanetworks/j2lint.git@341b5d5db86e095b622f09770cb6367a1583620e
+ - name: Run J2lint
+ timeout-minutes: 2
+ run: |
+ j2lint $GITHUB_WORKSPACE/data
diff --git a/Makefile b/Makefile
index b582ef84c..2333eebed 100644
--- a/Makefile
+++ b/Makefile
@@ -7,6 +7,8 @@ XDP_DIR := src/xdp
LIBS := -lzmq
CFLAGS :=
+J2LINT := $(shell command -v j2lint 2> /dev/null)
+
config_xml_src = $(wildcard interface-definitions/*.xml.in)
config_xml_obj = $(config_xml_src:.xml.in=.xml)
op_xml_src = $(wildcard op-mode-definitions/*.xml.in)
@@ -29,9 +31,12 @@ interface_definitions: $(config_xml_obj)
# XXX: delete top level node.def's that now live in other packages
# IPSec VPN EAP-RADIUS does not support source-address
rm -rf $(TMPL_DIR)/vpn/ipsec/remote-access/radius/source-address
- # T3568: firewall is yet not migrated to XML and Python - this is only a dummy
- rm -rf $(TMPL_DIR)/firewall/node.def
- rm -rf $(TMPL_DIR)/nfirewall
+
+ # T4284 neq QoS implementation is not yet live
+ find $(TMPL_DIR)/interfaces -name redirect -type d -exec rm -rf {} \;
+ rm -rf $(TMPL_DIR)/qos
+ rm -rf $(TMPL_DIR)/interfaces/input
+
# XXX: test if there are empty node.def files - this is not allowed as these
# could mask help strings or mandatory priority statements
find $(TMPL_DIR) -name node.def -type f -empty -exec false {} + || sh -c 'echo "There are empty node.def files! Check your interface definitions." && exit 1'
@@ -55,9 +60,10 @@ op_mode_definitions: $(op_xml_obj)
rm -f $(OP_TMPL_DIR)/show/node.def
rm -f $(OP_TMPL_DIR)/show/system/node.def
- # XXX: ping must be able to recursivly call itself as the
+ # XXX: ping and traceroute must be able to recursivly call itself as the
# options are provided from the script itself
ln -s ../node.tag $(OP_TMPL_DIR)/ping/node.tag/node.tag/
+ ln -s ../node.tag $(OP_TMPL_DIR)/traceroute/node.tag/node.tag/
# XXX: test if there are empty node.def files - this is not allowed as these
# could mask help strings or mandatory priority statements
@@ -72,7 +78,18 @@ vyxdp:
$(MAKE) -C $(XDP_DIR)
.PHONY: all
-all: clean interface_definitions op_mode_definitions vyshim
+all: clean interface_definitions op_mode_definitions check test j2lint vyshim
+
+.PHONY: check
+.ONESHELL:
+check:
+ @echo "Checking which CLI scripts are not enabled to work with vyos-configd..."
+ @for file in `ls src/conf_mode -I__pycache__`
+ do
+ if ! grep -q $$file data/configd-include.json; then
+ echo "* $$file"
+ fi
+ done
.PHONY: clean
clean:
@@ -87,6 +104,13 @@ test:
set -e; python3 -m compileall -q -x '/vmware-tools/scripts/, /ppp/' .
PYTHONPATH=python/ python3 -m "nose" --with-xunit src --with-coverage --cover-erase --cover-xml --cover-package src/conf_mode,src/op_mode,src/completion,src/helpers,src/validators,src/tests --verbose
+.PHONY: j2lint
+j2lint:
+ifndef J2LINT
+ $(error "j2lint binary not found, consider installing: pip install git+https://github.com/aristanetworks/j2lint.git@341b5d5db86")
+endif
+ $(J2LINT) data/
+
.PHONY: sonar
sonar:
sonar-scanner -X -Dsonar.login=${SONAR_TOKEN}
diff --git a/data/configd-include.json b/data/configd-include.json
index 6893aaa86..5a4912e30 100644
--- a/data/configd-include.json
+++ b/data/configd-include.json
@@ -1,11 +1,18 @@
[
+"arp.py",
"bcast_relay.py",
+"container.py",
"conntrack.py",
"conntrack_sync.py",
"dhcp_relay.py",
+"dhcp_server.py",
"dhcpv6_relay.py",
+"dhcpv6_server.py",
"dns_forwarding.py",
"dynamic_dns.py",
+"firewall.py",
+"flow_accounting_conf.py",
+"high-availability.py",
"host_name.py",
"https.py",
"igmp_proxy.py",
@@ -22,6 +29,7 @@
"interfaces-pppoe.py",
"interfaces-pseudo-ethernet.py",
"interfaces-tunnel.py",
+"interfaces-vti.py",
"interfaces-vxlan.py",
"interfaces-wireguard.py",
"interfaces-wireless.py",
@@ -29,6 +37,7 @@
"lldp.py",
"nat.py",
"nat66.py",
+"netns.py",
"ntp.py",
"pki.py",
"policy.py",
@@ -44,20 +53,27 @@
"protocols_pim.py",
"protocols_rip.py",
"protocols_ripng.py",
+"protocols_rpki.py",
"protocols_static.py",
"protocols_static_multicast.py",
+"qos.py",
"salt-minion.py",
"service_console-server.py",
"service_ids_fastnetmon.py",
"service_ipoe-server.py",
"service_mdns-repeater.py",
+"service_monitoring_telegraf.py",
"service_pppoe-server.py",
"service_router-advert.py",
+"service_upnp.py",
"ssh.py",
"system-ip.py",
"system-ipv6.py",
"system-login-banner.py",
+"system-logs.py",
"system-option.py",
+"system-proxy.py",
+"system_sysctl.py",
"system-syslog.py",
"system-timezone.py",
"system_console.py",
@@ -68,6 +84,5 @@
"vpn_pptp.py",
"vpn_sstp.py",
"vrf.py",
-"vrf_vni.py",
-"vrrp.py"
+"vrf_vni.py"
]
diff --git a/data/templates/accel-ppp/chap-secrets.config_dict.tmpl b/data/templates/accel-ppp/chap-secrets.config_dict.j2
index da64b64d5..51e66d57c 100644
--- a/data/templates/accel-ppp/chap-secrets.config_dict.tmpl
+++ b/data/templates/accel-ppp/chap-secrets.config_dict.j2
@@ -1,12 +1,10 @@
# username server password acceptable local IP addresses shaper
-{% if authentication is defined and authentication.local_users is defined and authentication.local_users.username is defined %}
-{% for user, user_config in authentication.local_users.username.items() %}
-{% if user_config.disabled is not defined %}
-{% if user_config.rate_limit is defined %}
+{% if authentication.local_users.username is vyos_defined %}
+{% for user, user_config in authentication.local_users.username.items() if user_config.disabled is not vyos_defined %}
+{% if user_config.rate_limit is vyos_defined %}
{{ "%-12s" | format(user) }} * {{ "%-16s" | format(user_config.password) }} {{ "%-16s" | format(user_config.static_ip) }} {{ user_config.rate_limit.download }}/{{ user_config.rate_limit.upload }}
-{% else %}
+{% else %}
{{ "%-12s" | format(user) }} * {{ "%-16s" | format(user_config.password) }} {{ "%-16s" | format(user_config.static_ip) }}
-{% endif %}
-{% endif %}
-{% endfor %}
+{% endif %}
+{% endfor %}
{% endif %}
diff --git a/data/templates/accel-ppp/chap-secrets.ipoe.tmpl b/data/templates/accel-ppp/chap-secrets.ipoe.j2
index 1df878fcf..a1430ec22 100644
--- a/data/templates/accel-ppp/chap-secrets.ipoe.tmpl
+++ b/data/templates/accel-ppp/chap-secrets.ipoe.j2
@@ -1,18 +1,18 @@
# username server password acceptable local IP addresses shaper
{% for interface in auth_interfaces %}
-{% for mac in interface.mac %}
-{% if mac.rate_upload and mac.rate_download %}
-{% if mac.vlan_id %}
+{% for mac in interface.mac %}
+{% if mac.rate_upload and mac.rate_download %}
+{% if mac.vlan_id %}
{{ interface.name }}.{{ mac.vlan_id }} * {{ mac.address | lower }} * {{ mac.rate_download }}/{{ mac.rate_upload }}
-{% else %}
+{% else %}
{{ interface.name }} * {{ mac.address | lower }} * {{ mac.rate_download }}/{{ mac.rate_upload }}
-{% endif %}
-{% else %}
-{% if mac.vlan_id %}
+{% endif %}
+{% else %}
+{% if mac.vlan_id %}
{{ interface.name }}.{{ mac.vlan_id }} * {{ mac.address | lower }} *
-{% else %}
+{% else %}
{{ interface.name }} * {{ mac.address | lower }} *
-{% endif %}
-{% endif %}
-{% endfor %}
+{% endif %}
+{% endif %}
+{% endfor %}
{% endfor %}
diff --git a/data/templates/accel-ppp/chap-secrets.tmpl b/data/templates/accel-ppp/chap-secrets.j2
index 6cace5401..cc3ddc28f 100644
--- a/data/templates/accel-ppp/chap-secrets.tmpl
+++ b/data/templates/accel-ppp/chap-secrets.j2
@@ -1,10 +1,10 @@
# username server password acceptable local IP addresses shaper
{% for user in local_users %}
-{% if user.state == 'enabled' %}
-{% if user.upload and user.download %}
+{% if user.state == 'enabled' %}
+{% if user.upload and user.download %}
{{ "%-12s" | format(user.name) }} * {{ "%-16s" | format(user.password) }} {{ "%-16s" | format(user.ip) }} {{ user.download }}/{{ user.upload }}
-{% else %}
+{% else %}
{{ "%-12s" | format(user.name) }} * {{ "%-16s" | format(user.password) }} {{ "%-16s" | format(user.ip) }}
-{% endif %}
-{% endif %}
+{% endif %}
+{% endif %}
{% endfor %}
diff --git a/data/templates/accel-ppp/config_chap_secrets_radius.j2 b/data/templates/accel-ppp/config_chap_secrets_radius.j2
index 49af3a228..bb820497b 100644
--- a/data/templates/accel-ppp/config_chap_secrets_radius.j2
+++ b/data/templates/accel-ppp/config_chap_secrets_radius.j2
@@ -1,33 +1,33 @@
-{% if authentication.mode is defined and authentication.mode == 'local' %}
+{% if authentication.mode is vyos_defined('local') %}
[chap-secrets]
chap-secrets={{ chap_secrets_file }}
-{% elif authentication.mode is defined and authentication.mode == 'radius' %}
+{% elif authentication.mode is vyos_defined('radius') %}
[radius]
verbose=1
-{% for server, options in authentication.radius.server.items() if not options.disable is defined %}
+{% for server, options in authentication.radius.server.items() if not options.disable is vyos_defined %}
server={{ server }},{{ options.key }},auth-port={{ options.port }},acct-port={{ options.acct_port }},req-limit=0,fail-time={{ options.fail_time }}
-{% endfor %}
-{% if authentication.radius.acct_interim_jitter is defined and authentication.radius.acct_interim_jitter is not none %}
+{% endfor %}
+{% if authentication.radius.acct_interim_jitter is vyos_defined %}
acct-interim-jitter={{ authentication.radius.acct_interim_jitter }}
-{% endif %}
+{% endif %}
acct-timeout={{ authentication.radius.acct_timeout }}
timeout={{ authentication.radius.timeout }}
max-try={{ authentication.radius.max_try }}
-{% if authentication.radius.nas_identifier is defined and authentication.radius.nas_identifier is not none %}
+{% if authentication.radius.nas_identifier is vyos_defined %}
nas-identifier={{ authentication.radius.nas_identifier }}
-{% endif %}
-{% if authentication.radius.nas_ip_address is defined and authentication.radius.nas_ip_address is not none %}
+{% endif %}
+{% if authentication.radius.nas_ip_address is vyos_defined %}
nas-ip-address={{ authentication.radius.nas_ip_address }}
-{% endif %}
-{% if authentication.radius.source_address is defined and authentication.radius.source_address is not none %}
+{% endif %}
+{% if authentication.radius.source_address is vyos_defined %}
bind={{ authentication.radius.source_address }}
-{% endif %}
-{% if authentication.radius.dynamic_author.server is defined and authentication.radius.dynamic_author.server is not none %}
+{% endif %}
+{% if authentication.radius.dynamic_author.server is vyos_defined %}
dae-server={{ authentication.radius.dynamic_author.server }}:{{ authentication.radius.dynamic_author.port }},{{ authentication.radius.dynamic_author.key }}
-{% endif %}
+{% endif %}
{% endif %}
{# Both chap-secrets and radius block required the gw-ip-address #}
-{% if gateway_address is defined and gateway_address is not none %}
+{% if gateway_address is vyos_defined %}
gw-ip-address={{ gateway_address }}
{% endif %}
diff --git a/data/templates/accel-ppp/config_ip_pool.j2 b/data/templates/accel-ppp/config_ip_pool.j2
index 3b0f68084..0bef4ad69 100644
--- a/data/templates/accel-ppp/config_ip_pool.j2
+++ b/data/templates/accel-ppp/config_ip_pool.j2
@@ -1,14 +1,14 @@
-{% if client_ip_pool is defined and client_ip_pool is not none %}
+{% if client_ip_pool is vyos_defined %}
[ip-pool]
-{% if gateway_address is defined and gateway_address is not none %}
+{% if gateway_address is vyos_defined %}
gw-ip-address={{ gateway_address }}
-{% endif %}
-{% if client_ip_pool.start is defined and client_ip_pool.stop is defined and client_ip_pool.start is not none and client_ip_pool.stop is not none %}
+{% endif %}
+{% if client_ip_pool.start is vyos_defined and client_ip_pool.stop is vyos_defined %}
{{ client_ip_pool.start }}-{{ client_ip_pool.stop.split('.')[3] }}
-{% endif %}
-{% if client_ip_pool.subnet is defined and client_ip_pool.subnet is not none %}
-{% for subnet in client_ip_pool.subnet %}
+{% endif %}
+{% if client_ip_pool.subnet is vyos_defined %}
+{% for subnet in client_ip_pool.subnet %}
{{ subnet }}
-{% endfor %}
-{% endif %}
+{% endfor %}
+{% endif %}
{% endif %}
diff --git a/data/templates/accel-ppp/config_ipv6_pool.j2 b/data/templates/accel-ppp/config_ipv6_pool.j2
index f45bf9442..953469577 100644
--- a/data/templates/accel-ppp/config_ipv6_pool.j2
+++ b/data/templates/accel-ppp/config_ipv6_pool.j2
@@ -1,20 +1,20 @@
-{% if client_ipv6_pool is defined and client_ipv6_pool is not none %}
+{% if client_ipv6_pool is vyos_defined %}
[ipv6-nd]
AdvAutonomousFlag=1
-{% if client_ipv6_pool.prefix is defined and client_ipv6_pool.prefix is not none %}
+{% if client_ipv6_pool.prefix is vyos_defined %}
[ipv6-pool]
-{% for prefix, options in client_ipv6_pool.prefix.items() %}
+{% for prefix, options in client_ipv6_pool.prefix.items() %}
{{ prefix }},{{ options.mask }}
-{% endfor %}
-{% if client_ipv6_pool.delegate is defined and client_ipv6_pool.delegate is not none %}
-{% for prefix, options in client_ipv6_pool.delegate.items() %}
+{% endfor %}
+{% if client_ipv6_pool.delegate is vyos_defined %}
+{% for prefix, options in client_ipv6_pool.delegate.items() %}
delegate={{ prefix }},{{ options.delegation_prefix }}
-{% endfor %}
+{% endfor %}
+{% endif %}
{% endif %}
-{% endif %}
-{% if client_ipv6_pool.delegate is defined and client_ipv6_pool.delegate is not none %}
+{% if client_ipv6_pool.delegate is vyos_defined %}
[ipv6-dhcp]
verbose=1
-{% endif %}
+{% endif %}
{% endif %}
diff --git a/data/templates/accel-ppp/config_modules_auth_mode.j2 b/data/templates/accel-ppp/config_modules_auth_mode.j2
index e3d578b38..3fb8a011f 100644
--- a/data/templates/accel-ppp/config_modules_auth_mode.j2
+++ b/data/templates/accel-ppp/config_modules_auth_mode.j2
@@ -1,5 +1,5 @@
-{% if authentication is defined and authentication.mode is defined and authentication.mode == 'local' %}
+{% if authentication.mode is vyos_defined('local') %}
chap-secrets
-{% elif authentication is defined and authentication.mode is defined and authentication.mode == 'radius' %}
+{% elif authentication.mode is vyos_defined('radius') %}
radius
{% endif %}
diff --git a/data/templates/accel-ppp/config_modules_auth_protocols.j2 b/data/templates/accel-ppp/config_modules_auth_protocols.j2
index 454d37792..285468406 100644
--- a/data/templates/accel-ppp/config_modules_auth_protocols.j2
+++ b/data/templates/accel-ppp/config_modules_auth_protocols.j2
@@ -1,10 +1,10 @@
{% for protocol in authentication.protocols %}
{# this should be fixed in the CLI by a migrator #}
-{% if protocol == 'chap' %}
+{% if protocol == 'chap' %}
auth_chap_md5
-{% elif protocol == 'mschap' %}
+{% elif protocol == 'mschap' %}
auth_mschap_v1
-{% else %}
+{% else %}
auth_{{ protocol.replace('-', '_') }}
-{% endif %}
+{% endif %}
{% endfor %}
diff --git a/data/templates/accel-ppp/config_modules_ipv6.j2 b/data/templates/accel-ppp/config_modules_ipv6.j2
index 02740ce7c..6174779a5 100644
--- a/data/templates/accel-ppp/config_modules_ipv6.j2
+++ b/data/templates/accel-ppp/config_modules_ipv6.j2
@@ -1,4 +1,4 @@
-{% if ppp_options.ipv6 is defined and ppp_options.ipv6 != 'deny' %}
+{% if ppp_options.ipv6 is vyos_defined and ppp_options.ipv6 is not vyos_defined('deny') %}
ipv6pool
ipv6_nd
ipv6_dhcp
diff --git a/data/templates/accel-ppp/config_name_server.j2 b/data/templates/accel-ppp/config_name_server.j2
index 2bf064f92..9c745fe62 100644
--- a/data/templates/accel-ppp/config_name_server.j2
+++ b/data/templates/accel-ppp/config_name_server.j2
@@ -1,13 +1,13 @@
-{% if name_server_ipv4 is defined and name_server_ipv4 is not none %}
+{% if name_server_ipv4 is vyos_defined %}
[dns]
-{% for ns in name_server_ipv4 %}
+{% for ns in name_server_ipv4 %}
dns{{ loop.index }}={{ ns }}
-{% endfor %}
+{% endfor %}
{% endif %}
-{% if name_server_ipv6 is defined and name_server_ipv6 is not none %}
+{% if name_server_ipv6 is vyos_defined %}
[ipv6-dns]
-{% for ns in name_server_ipv6 %}
+{% for ns in name_server_ipv6 %}
{{ ns }}
-{% endfor %}
+{% endfor %}
{% endif %}
diff --git a/data/templates/accel-ppp/config_shaper_radius.j2 b/data/templates/accel-ppp/config_shaper_radius.j2
index 8de5f5df3..942cdf132 100644
--- a/data/templates/accel-ppp/config_shaper_radius.j2
+++ b/data/templates/accel-ppp/config_shaper_radius.j2
@@ -1,10 +1,13 @@
-{% if authentication is defined and authentication.mode is defined and authentication.mode == 'radius' %}
-{% if authentication is defined and authentication.radius is defined and authentication.radius.rate_limit is defined and authentication.radius.rate_limit.enable is defined %}
+{% if authentication.mode is vyos_defined('radius') %}
+{% if authentication.radius.rate_limit.enable is vyos_defined %}
[shaper]
verbose=1
attr={{ authentication.radius.rate_limit.attribute }}
-{% if authentication.radius.rate_limit.vendor is defined and authentication.radius.rate_limit.vendor is not none %}
+{% if authentication.radius.rate_limit.vendor is vyos_defined %}
vendor={{ authentication.radius.rate_limit.vendor }}
+{% endif %}
+{% if authentication.radius.rate_limit.multiplier is vyos_defined %}
+rate-multiplier={{ authentication.radius.rate_limit.multiplier }}
+{% endif %}
{% endif %}
-{% endif %}
{% endif %}
diff --git a/data/templates/accel-ppp/ipoe.config.j2 b/data/templates/accel-ppp/ipoe.config.j2
new file mode 100644
index 000000000..3c0d47b27
--- /dev/null
+++ b/data/templates/accel-ppp/ipoe.config.j2
@@ -0,0 +1,142 @@
+{# j2lint: disable=operator-enclosed-by-spaces #}
+### generated by ipoe.py ###
+[modules]
+log_syslog
+ipoe
+shaper
+ipv6pool
+ipv6_nd
+ipv6_dhcp
+ippool
+{% if auth_mode == 'radius' %}
+radius
+{% elif auth_mode == 'local' %}
+chap-secrets
+{% endif %}
+
+[core]
+thread-count={{ thread_cnt }}
+
+[log]
+syslog=accel-ipoe,daemon
+copy=1
+level=5
+
+[ipoe]
+verbose=1
+{% for interface in interfaces %}
+{% set tmp = 'interface=' %}
+{% if interface.vlan_mon %}
+{% set tmp = tmp ~ 're:' ~ interface.name ~ '\.\d+' %}
+{% else %}
+{% set tmp = tmp ~ interface.name %}
+{% endif %}
+{{ tmp }},shared={{ interface.shared }},mode={{ interface.mode }},ifcfg={{ interface.ifcfg }}{{ ',range=' ~ interface.range if interface.range is defined and interface.range is not none }},start={{ interface.sess_start }},ipv6=1
+{% endfor %}
+{% if auth_mode == 'noauth' %}
+noauth=1
+{% if client_named_ip_pool %}
+{% for pool in client_named_ip_pool %}
+{% if pool.subnet is defined %}
+ip-pool={{ pool.name }}
+{% endif %}
+{% if pool.gateway_address is defined %}
+gw-ip-address={{ pool.gateway_address }}/{{ pool.subnet.split('/')[1] }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% elif auth_mode == 'local' %}
+username=ifname
+password=csid
+{% endif %}
+proxy-arp=1
+
+{% for interface in interfaces %}
+{% if (interface.shared == '0') and (interface.vlan_mon) %}
+vlan-mon={{ interface.name }},{{ interface.vlan_mon | join(',') }}
+{% endif %}
+{% endfor %}
+
+{% if dnsv4 %}
+[dns]
+{% for dns in dnsv4 %}
+dns{{ loop.index }}={{ dns }}
+{% endfor %}
+{% endif %}
+
+{% if dnsv6 %}
+[ipv6-dns]
+{% for dns in dnsv6 %}
+{{ dns }}
+{% endfor %}
+{% endif %}
+
+[ipv6-nd]
+verbose=1
+
+[ipv6-dhcp]
+verbose=1
+
+{% if client_named_ip_pool %}
+[ip-pool]
+{% for pool in client_named_ip_pool %}
+{% if pool.subnet is defined %}
+{{ pool.subnet }},name={{ pool.name }}
+{% endif %}
+{% if pool.gateway_address is defined %}
+gw-ip-address={{ pool.gateway_address }}/{{ pool.subnet.split('/')[1] }}
+{% endif %}
+{% endfor %}
+{% endif %}
+
+{% if client_ipv6_pool %}
+[ipv6-pool]
+{% for p in client_ipv6_pool %}
+{{ p.prefix }},{{ p.mask }}
+{% endfor %}
+{% for p in client_ipv6_delegate_prefix %}
+delegate={{ p.prefix }},{{ p.mask }}
+{% endfor %}
+{% endif %}
+
+{% if auth_mode == 'local' %}
+[chap-secrets]
+chap-secrets={{ chap_secrets_file }}
+{% elif auth_mode == 'radius' %}
+[radius]
+verbose=1
+{% for r in radius_server %}
+server={{ r.server }},{{ r.key }},auth-port={{ r.port }},acct-port={{ r.acct_port }},req-limit=0,fail-time={{ r.fail_time }}
+{% endfor %}
+
+{% if radius_acct_inter_jitter %}
+acct-interim-jitter={{ radius_acct_inter_jitter }}
+{% endif %}
+
+acct-timeout={{ radius_acct_tmo }}
+timeout={{ radius_timeout }}
+max-try={{ radius_max_try }}
+{% if radius_nas_id %}
+nas-identifier={{ radius_nas_id }}
+{% endif %}
+{% if radius_nas_ip %}
+nas-ip-address={{ radius_nas_ip }}
+{% endif %}
+{% if radius_source_address %}
+bind={{ radius_source_address }}
+{% endif %}
+{% if radius_dynamic_author %}
+dae-server={{ radius_dynamic_author.server }}:{{ radius_dynamic_author.port }},{{ radius_dynamic_author.key }}
+{% endif %}
+{% if radius_shaper_attr %}
+[shaper]
+verbose=1
+attr={{ radius_shaper_attr }}
+{% if radius_shaper_vendor %}
+vendor={{ radius_shaper_vendor }}
+{% endif %}
+{% endif %}
+{% endif %}
+
+[cli]
+tcp=127.0.0.1:2002
diff --git a/data/templates/accel-ppp/ipoe.config.tmpl b/data/templates/accel-ppp/ipoe.config.tmpl
deleted file mode 100644
index 1cf2ab0be..000000000
--- a/data/templates/accel-ppp/ipoe.config.tmpl
+++ /dev/null
@@ -1,116 +0,0 @@
-### generated by ipoe.py ###
-[modules]
-log_syslog
-ipoe
-shaper
-ipv6pool
-ipv6_nd
-ipv6_dhcp
-ippool
-{% if auth_mode == 'radius' %}
-radius
-{% elif auth_mode == 'local' %}
-chap-secrets
-{% endif %}
-
-[core]
-thread-count={{ thread_cnt }}
-
-[log]
-syslog=accel-ipoe,daemon
-copy=1
-level=5
-
-[ipoe]
-verbose=1
-{% for interface in interfaces %}
-{% if interface.vlan_mon %}
-interface=re:{{ interface.name }}\.\d+,{% else %}interface={{ interface.name }},{% endif %}shared={{ interface.shared }},mode={{ interface.mode }},ifcfg={{ interface.ifcfg }},range={{ interface.range }},start={{ interface.sess_start }},ipv6=1
-{% endfor %}
-{% if auth_mode == 'noauth' %}
-noauth=1
-{% elif auth_mode == 'local' %}
-username=ifname
-password=csid
-{% endif %}
-proxy-arp=1
-
-{% for interface in interfaces %}
-{% if (interface.shared == '0') and (interface.vlan_mon) %}
-vlan-mon={{ interface.name }},{{ interface.vlan_mon | join(',') }}
-{% endif %}
-{% endfor %}
-
-{% if dnsv4 %}
-[dns]
-{% for dns in dnsv4 %}
-dns{{ loop.index }}={{ dns }}
-{% endfor %}
-{% endif %}
-
-{% if dnsv6 %}
-[ipv6-dns]
-{% for dns in dnsv6 %}
-{{ dns }}
-{% endfor %}
-{% endif %}
-
-[ipv6-nd]
-verbose=1
-
-[ipv6-dhcp]
-verbose=1
-
-{% if client_ipv6_pool %}
-[ipv6-pool]
-{% for p in client_ipv6_pool %}
-{{ p.prefix }},{{ p.mask }}
-{% endfor %}
-{% for p in client_ipv6_delegate_prefix %}
-delegate={{ p.prefix }},{{ p.mask }}
-{% endfor %}
-{% endif %}
-
-{% if auth_mode == 'local' %}
-[chap-secrets]
-chap-secrets={{ chap_secrets_file }}
-{% elif auth_mode == 'radius' %}
-[radius]
-verbose=1
-{% for r in radius_server %}
-server={{ r.server }},{{ r.key }},auth-port={{ r.port }},acct-port={{ r.acct_port }},req-limit=0,fail-time={{ r.fail_time }}
-{% endfor %}
-
-{% if radius_acct_inter_jitter %}
-acct-interim-jitter={{ radius_acct_inter_jitter }}
-{% endif %}
-
-acct-timeout={{ radius_acct_tmo }}
-timeout={{ radius_timeout }}
-max-try={{ radius_max_try }}
-{% if radius_nas_id %}
-nas-identifier={{ radius_nas_id }}
-{% endif %}
-{% if radius_nas_ip %}
-nas-ip-address={{ radius_nas_ip }}
-{% endif %}
-{% if radius_source_address %}
-bind={{ radius_source_address }}
-{% endif %}
-
-{% if radius_dynamic_author %}
-dae-server={{ radius_dynamic_author.server }}:{{ radius_dynamic_author.port }},{{ radius_dynamic_author.key }}
-{% endif %}
-
-{% if radius_shaper_attr %}
-[shaper]
-verbose=1
-attr={{ radius_shaper_attr }}
-{% if radius_shaper_vendor %}
-vendor={{ radius_shaper_vendor }}
-{% endif %}
-{% endif %}
-{% endif %}
-
-[cli]
-tcp=127.0.0.1:2002
diff --git a/data/templates/accel-ppp/l2tp.config.tmpl b/data/templates/accel-ppp/l2tp.config.j2
index 9fcda76d4..9eeaf7622 100644
--- a/data/templates/accel-ppp/l2tp.config.tmpl
+++ b/data/templates/accel-ppp/l2tp.config.j2
@@ -3,9 +3,9 @@
log_syslog
l2tp
chap-secrets
-{% for proto in auth_proto: %}
-{{proto}}
-{% endfor%}
+{% for proto in auth_proto %}
+{{ proto }}
+{% endfor %}
{% if auth_mode == 'radius' %}
radius
@@ -18,7 +18,7 @@ ipv6_nd
ipv6_dhcp
[core]
-thread-count={{thread_cnt}}
+thread-count={{ thread_cnt }}
[log]
syslog=accel-l2tp,daemon
@@ -27,23 +27,23 @@ level=5
{% if dnsv4 %}
[dns]
-{% for dns in dnsv4 %}
+{% for dns in dnsv4 %}
dns{{ loop.index }}={{ dns }}
-{% endfor %}
+{% endfor %}
{% endif %}
{% if dnsv6 %}
[ipv6-dns]
-{% for dns in dnsv6 %}
+{% for dns in dnsv6 %}
{{ dns }}
-{% endfor %}
+{% endfor %}
{% endif %}
{% if wins %}
[wins]
-{% for server in wins %}
+{% for server in wins %}
wins{{ loop.index }}={{ server }}
-{% endfor %}
+{% endfor %}
{% endif %}
[l2tp]
@@ -66,14 +66,14 @@ host-name={{ lns_host_name }}
{% if client_ip_pool or client_ip_subnets %}
[ip-pool]
-{% if client_ip_pool %}
+{% if client_ip_pool %}
{{ client_ip_pool }}
-{% endif %}
-{% if client_ip_subnets %}
-{% for sn in client_ip_subnets %}
-{{sn}}
-{% endfor %}
-{% endif %}
+{% endif %}
+{% if client_ip_subnets %}
+{% for sn in client_ip_subnets %}
+{{ sn }}
+{% endfor %}
+{% endif %}
{% endif %}
{% if gateway_address %}
gw-ip-address={{ gateway_address }}
@@ -85,27 +85,24 @@ chap-secrets={{ chap_secrets_file }}
{% elif auth_mode == 'radius' %}
[radius]
verbose=1
-{% for r in radius_server %}
+{% for r in radius_server %}
server={{ r.server }},{{ r.key }},auth-port={{ r.port }},acct-port={{ r.acct_port }},req-limit=0,fail-time={{ r.fail_time }}
-{% endfor %}
-
-{% if radius_acct_inter_jitter %}
+{% endfor %}
+{% if radius_acct_inter_jitter %}
acct-interim-jitter={{ radius_acct_inter_jitter }}
-{% endif %}
-
+{% endif %}
acct-timeout={{ radius_acct_tmo }}
timeout={{ radius_timeout }}
max-try={{ radius_max_try }}
-
-{% if radius_nas_id %}
+{% if radius_nas_id %}
nas-identifier={{ radius_nas_id }}
-{% endif %}
-{% if radius_nas_ip %}
+{% endif %}
+{% if radius_nas_ip %}
nas-ip-address={{ radius_nas_ip }}
-{% endif %}
-{% if radius_source_address %}
+{% endif %}
+{% if radius_source_address %}
bind={{ radius_source_address }}
-{% endif %}
+{% endif %}
{% endif %}
{% if gateway_address %}
gw-ip-address={{ gateway_address }}
@@ -128,12 +125,12 @@ ipv6=allow
{% if client_ipv6_pool %}
[ipv6-pool]
-{% for p in client_ipv6_pool %}
+{% for p in client_ipv6_pool %}
{{ p.prefix }},{{ p.mask }}
-{% endfor %}
-{% for p in client_ipv6_delegate_prefix %}
+{% endfor %}
+{% for p in client_ipv6_delegate_prefix %}
delegate={{ p.prefix }},{{ p.mask }}
-{% endfor %}
+{% endfor %}
{% endif %}
{% if client_ipv6_delegate_prefix %}
@@ -145,9 +142,9 @@ verbose=1
[shaper]
verbose=1
attr={{ radius_shaper_attr }}
-{% if radius_shaper_vendor %}
+{% if radius_shaper_vendor %}
vendor={{ radius_shaper_vendor }}
-{% endif %}
+{% endif %}
{% endif %}
[cli]
diff --git a/data/templates/accel-ppp/pppoe.config.j2 b/data/templates/accel-ppp/pppoe.config.j2
new file mode 100644
index 000000000..0a92e2d54
--- /dev/null
+++ b/data/templates/accel-ppp/pppoe.config.j2
@@ -0,0 +1,172 @@
+### generated by accel_pppoe.py ###
+[modules]
+log_syslog
+pppoe
+shaper
+{# Common authentication backend definitions #}
+{% include 'accel-ppp/config_modules_auth_mode.j2' %}
+ippool
+{# Common IPv6 definitions #}
+{% include 'accel-ppp/config_modules_ipv6.j2' %}
+{# Common authentication protocols (pap, chap ...) #}
+{% include 'accel-ppp/config_modules_auth_protocols.j2' %}
+
+{% if snmp is vyos_defined %}
+net-snmp
+{% endif %}
+{% if limits is vyos_defined %}
+connlimit
+{% endif %}
+{% if extended_scripts is vyos_defined %}
+sigchld
+pppd_compat
+{% endif %}
+
+[core]
+thread-count={{ thread_count }}
+
+[log]
+syslog=accel-pppoe,daemon
+copy=1
+level=5
+
+{% if snmp.master_agent is vyos_defined %}
+[snmp]
+master=1
+{% endif %}
+
+[client-ip-range]
+disable
+
+{# Common IP pool definitions #}
+{% include 'accel-ppp/config_ip_pool.j2' %}
+
+{# Common IPv6 pool definitions #}
+{% include 'accel-ppp/config_ipv6_pool.j2' %}
+
+{# Common DNS name-server definition #}
+{% include 'accel-ppp/config_name_server.j2' %}
+
+{% if wins_server is vyos_defined %}
+[wins]
+{% for server in wins_server %}
+wins{{ loop.index }}={{ server }}
+{% endfor %}
+{% endif %}
+
+{# Common chap-secrets and RADIUS server/option definitions #}
+{% include 'accel-ppp/config_chap_secrets_radius.j2' %}
+
+{% if session_control is vyos_defined and session_control is not vyos_defined('disable') %}
+[common]
+single-session={{ session_control }}
+{% endif %}
+
+[ppp]
+verbose=1
+check-ip=1
+ccp={{ "1" if ppp_options.ccp is vyos_defined else "0" }}
+unit-preallocate={{ "1" if authentication.radius.preallocate_vif is vyos_defined else "0" }}
+{% if ppp_options.min_mtu is vyos_defined %}
+min-mtu={{ ppp_options.min_mtu }}
+{% else %}
+min-mtu={{ mtu }}
+{% endif %}
+{% if ppp_options.mru is vyos_defined %}
+mru={{ ppp_options.mru }}
+{% endif %}
+mppe={{ ppp_options.mppe }}
+lcp-echo-interval={{ ppp_options.lcp_echo_interval }}
+lcp-echo-timeout={{ ppp_options.lcp_echo_timeout }}
+lcp-echo-failure={{ ppp_options.lcp_echo_failure }}
+{% if ppp_options.ipv4 is vyos_defined %}
+ipv4={{ ppp_options.ipv4 }}
+{% endif %}
+{# IPv6 #}
+{% if ppp_options.ipv6 is vyos_defined %}
+ipv6={{ ppp_options.ipv6 }}
+{% if ppp_options.ipv6_intf_id is vyos_defined %}
+ipv6-intf-id={{ ppp_options.ipv6_intf_id }}
+{% endif %}
+{% if ppp_options.ipv6_peer_intf_id is vyos_defined %}
+ipv6-peer-intf-id={{ ppp_options.ipv6_peer_intf_id }}
+{% endif %}
+ipv6-accept-peer-intf-id={{ "1" if ppp_options.ipv6_accept_peer_intf_id is vyos_defined else "0" }}
+{% endif %}
+{# MTU #}
+mtu={{ mtu }}
+{% if ppp_options.interface_cache is vyos_defined %}
+unit-cache={{ ppp_options.interface_cache }}
+{% endif %}
+
+[pppoe]
+verbose=1
+ac-name={{ access_concentrator }}
+
+{% if interface is vyos_defined %}
+{% for iface, iface_config in interface.items() %}
+{% if iface_config.vlan_id is not vyos_defined and iface_config.vlan_range is not vyos_defined %}
+interface={{ iface }}
+{% endif %}
+{% if iface_config.vlan_range is vyos_defined %}
+{% for regex in iface_config.regex %}
+interface=re:^{{ iface | replace('.', '\\.') }}\.({{ regex }})$
+{% endfor %}
+vlan-mon={{ iface }},{{ iface_config.vlan_range | join(',') }}
+{% endif %}
+{% if iface_config.vlan_id is vyos_defined %}
+{% for vlan in iface_config.vlan_id %}
+vlan-mon={{ iface }},{{ vlan }}
+interface=re:^{{ iface | replace('.', '\\.') }}\.{{ vlan }}$
+{% endfor %}
+{% endif %}
+{% endfor %}
+{% endif %}
+
+{% if service_name %}
+service-name={{ service_name | join(',') }}
+{% endif %}
+
+{% if pado_delay %}
+{% set pado_delay_param = namespace(value='0') %}
+{% for delay in pado_delay | sort(attribute='0') %}
+{% if not loop.last %}
+{% set pado_delay_param.value = pado_delay_param.value + ',' + delay + ':' + pado_delay[delay].sessions %}
+{% else %}
+{% set pado_delay_param.value = pado_delay_param.value + ',-1:' + pado_delay[delay].sessions %}
+{% endif %}
+{% endfor %}
+pado-delay={{ pado_delay_param.value }}
+{% endif %}
+{% if authentication.radius.called_sid_format is vyos_defined %}
+called-sid={{ authentication.radius.called_sid_format }}
+{% endif %}
+
+{% if limits is vyos_defined %}
+[connlimit]
+{% if limits.connection_limit is vyos_defined %}
+limit={{ limits.connection_limit }}
+{% endif %}
+{% if limits.burst is vyos_defined %}
+burst={{ limits.burst }}
+{% endif %}
+{% if limits.timeout is vyos_defined %}
+timeout={{ limits.timeout }}
+{% endif %}
+{% endif %}
+
+{# Common RADIUS shaper configuration #}
+{% include 'accel-ppp/config_shaper_radius.j2' %}
+
+{% if extended_scripts is vyos_defined %}
+[pppd-compat]
+verbose=1
+radattr-prefix=/run/accel-pppd/radattr
+{% set script_name = {'on_up': 'ip-up', 'on_down': 'ip-down', 'on_change':'ip-change', 'on_pre_up':'ip-pre-up'} %}
+{% for script in extended_scripts %}
+{{ script_name[script] }}={{ extended_scripts[script] }}
+{% endfor %}
+{% endif %}
+
+[cli]
+tcp=127.0.0.1:2001
diff --git a/data/templates/accel-ppp/pppoe.config.tmpl b/data/templates/accel-ppp/pppoe.config.tmpl
deleted file mode 100644
index 238e7ee15..000000000
--- a/data/templates/accel-ppp/pppoe.config.tmpl
+++ /dev/null
@@ -1,174 +0,0 @@
-### generated by accel_pppoe.py ###
-[modules]
-log_syslog
-pppoe
-shaper
-{# Common authentication backend definitions #}
-{% include 'accel-ppp/config_modules_auth_mode.j2' %}
-ippool
-{# Common IPv6 definitions #}
-{% include 'accel-ppp/config_modules_ipv6.j2' %}
-{# Common authentication protocols (pap, chap ...) #}
-{% include 'accel-ppp/config_modules_auth_protocols.j2' %}
-
-{% if snmp is defined %}
-net-snmp
-{% endif %}
-{% if limits is defined %}
-connlimit
-{% endif %}
-{% if extended_scripts is defined %}
-sigchld
-pppd_compat
-{% endif %}
-
-[core]
-thread-count={{ thread_count }}
-
-[log]
-syslog=accel-pppoe,daemon
-copy=1
-level=5
-
-{% if snmp is defined and snmp.master_agent is defined %}
-[snmp]
-master=1
-{% endif %}
-
-[client-ip-range]
-disable
-
-{# Common IP pool definitions #}
-{% include 'accel-ppp/config_ip_pool.j2' %}
-
-{# Common IPv6 pool definitions #}
-{% include 'accel-ppp/config_ipv6_pool.j2' %}
-
-{# Common DNS name-server definition #}
-{% include 'accel-ppp/config_name_server.j2' %}
-
-{% if wins_server is defined and wins_server is not none %}
-[wins]
-{% for server in wins_server %}
-wins{{ loop.index }}={{ server }}
-{% endfor %}
-{% endif %}
-
-{# Common chap-secrets and RADIUS server/option definitions #}
-{% include 'accel-ppp/config_chap_secrets_radius.j2' %}
-
-{% if session_control is defined and session_control != 'disable' %}
-[common]
-single-session={{ session_control }}
-{% endif %}
-
-[ppp]
-verbose=1
-check-ip=1
-ccp={{ "1" if ppp_options.ccp is defined else "0" }}
-unit-preallocate={{ "1" if authentication.radius.preallocate_vif is defined else "0" }}
-{% if ppp_options.min_mtu is defined and ppp_options.min_mtu is not none %}
-min-mtu={{ ppp_options.min_mtu }}
-{% else %}
-min-mtu={{ mtu }}
-{% endif %}
-{% if ppp_options.mru is defined and ppp_options.mru is not none %}
-mru={{ ppp_options.mru }}
-{% endif %}
-mppe={{ ppp_options.mppe }}
-lcp-echo-interval={{ ppp_options.lcp_echo_interval }}
-lcp-echo-timeout={{ ppp_options.lcp_echo_timeout }}
-lcp-echo-failure={{ ppp_options.lcp_echo_failure }}
-{% if ppp_options.ipv4 is defined and ppp_options.ipv4 is not none %}
-ipv4={{ ppp_options.ipv4 }}
-{% endif %}
-{# IPv6 #}
-{% if ppp_options.ipv6 is defined and ppp_options.ipv6 is not none %}
-ipv6={{ ppp_options.ipv6 }}
-{% if ppp_options.ipv6_intf_id is defined and ppp_options.ipv6_intf_id is not none %}
-ipv6-intf-id={{ ppp_options.ipv6_intf_id }}
-{% endif %}
-{% if ppp_options.ipv6_peer_intf_id is defined and ppp_options.ipv6_peer_intf_id is not none %}
-ipv6-peer-intf-id={{ ppp_options.ipv6_peer_intf_id }}
-{% endif %}
-ipv6-accept-peer-intf-id={{ "1" if ppp_options.ipv6_accept_peer_intf_id is defined else "0" }}
-{% endif %}
-{# MTU #}
-mtu={{ mtu }}
-{% if ppp_options.interface_cache is defined and ppp_options.interface_cache is not none %}
-unit-cache={{ ppp_options.interface_cache }}
-{% endif %}
-
-[pppoe]
-verbose=1
-ac-name={{ access_concentrator }}
-
-{% if interface is defined and interface is not none %}
-{% for iface, iface_config in interface.items() %}
-{% if iface_config.vlan_id is not defined and iface_config.vlan_range is not defined %}
-interface={{ iface }}
-{% endif %}
-{% if iface_config.vlan_id is defined and iface_config.vlan_range is not defined %}
-{% for vlan in iface_config.vlan_id %}
-interface={{ iface }}.{{ vlan }}
-vlan-mon={{ iface }},{{ vlan }}
-{% endfor %}
-{% endif %}
-{% if iface_config.vlan_range is defined and iface_config.vlan_id is not defined %}
-vlan-mon={{ iface }},{{ iface_config.vlan_range | join(',') }}
-interface=re:{{ iface | replace('.', '\\.') }}\.\d+
-{% endif %}
-{% if iface_config.vlan_id is defined and iface_config.vlan_range is defined %}
-vlan-mon={{ iface }},{{ iface_config.vlan_id | join(',') }},{{ iface_config.vlan_range | join(',') }}
-interface=re:{{ iface | replace('.', '\\.') }}\.\d+
-{% endif %}
-{% endfor %}
-{% endif %}
-
-{% if service_name %}
-service-name={{ service_name | join(',') }}
-{% endif %}
-
-{% if pado_delay %}
-{% set pado_delay_param = namespace(value='0') %}
-{% for delay in pado_delay|sort(attribute='0') %}
-{% if not loop.last %}
-{% set pado_delay_param.value = pado_delay_param.value + ',' + delay + ':' + pado_delay[delay].sessions %}
-{% else %}
-{% set pado_delay_param.value = pado_delay_param.value + ',-1:' + pado_delay[delay].sessions %}
-{% endif %}
-{% endfor %}
-pado-delay={{ pado_delay_param.value }}
-{% endif %}
-{% if authentication.radius.called_sid_format is defined and authentication.radius.called_sid_format is not none %}
-called-sid={{ authentication.radius.called_sid_format }}
-{% endif %}
-
-{% if limits is defined %}
-[connlimit]
-{% if limits.connection_limit is defined and limits.connection_limit is not none %}
-limit={{ limits.connection_limit }}
-{% endif %}
-{% if limits.burst is defined and limits.burst %}
-burst={{ limits.burst }}
-{% endif %}
-{% if limits.timeout is defined and limits.timeout is not none %}
-timeout={{ limits.timeout }}
-{% endif %}
-{% endif %}
-
-{# Common RADIUS shaper configuration #}
-{% include 'accel-ppp/config_shaper_radius.j2' %}
-
-{% if extended_scripts is defined %}
-[pppd-compat]
-verbose=1
-radattr-prefix=/run/accel-pppd/radattr
-{% set script_name = {'on_up': 'ip-up', 'on_down': 'ip-down', 'on_change':'ip-change', 'on_pre_up':'ip-pre-up'} %}
-{% for script in extended_scripts %}
-{{ script_name[script] }}={{ extended_scripts[script] }}
-{% endfor %}
-{% endif %}
-
-[cli]
-tcp=127.0.0.1:2001
diff --git a/data/templates/accel-ppp/pptp.config.tmpl b/data/templates/accel-ppp/pptp.config.j2
index 3cfc4a906..cc1a45d6b 100644
--- a/data/templates/accel-ppp/pptp.config.tmpl
+++ b/data/templates/accel-ppp/pptp.config.j2
@@ -10,7 +10,7 @@ radius
{% endif %}
ippool
{% for proto in auth_proto %}
-{{proto}}
+{{ proto }}
{% endfor %}
[core]
@@ -23,16 +23,16 @@ level=5
{% if dnsv4 %}
[dns]
-{% for dns in dnsv4 %}
+{% for dns in dnsv4 %}
dns{{ loop.index }}={{ dns }}
-{% endfor %}
+{% endfor %}
{% endif %}
{% if wins %}
[wins]
-{% for server in wins %}
+{% for server in wins %}
wins{{ loop.index }}={{ server }}
-{% endfor %}
+{% endfor %}
{% endif %}
@@ -42,7 +42,7 @@ ifname=pptp%d
bind={{ outside_addr }}
{% endif %}
verbose=1
-ppp-max-mtu={{mtu}}
+ppp-max-mtu={{ mtu }}
mppe={{ ppp_mppe }}
echo-interval=10
echo-failure=3
@@ -66,27 +66,27 @@ chap-secrets={{ chap_secrets_file }}
{% elif auth_mode == 'radius' %}
[radius]
verbose=1
-{% for r in radius_server %}
+{% for r in radius_server %}
server={{ r.server }},{{ r.key }},auth-port={{ r.port }},acct-port={{ r.acct_port }},req-limit=0,fail-time={{ r.fail_time }}
-{% endfor %}
+{% endfor %}
-{% if radius_acct_inter_jitter %}
+{% if radius_acct_inter_jitter %}
acct-interim-jitter={{ radius_acct_inter_jitter }}
-{% endif %}
+{% endif %}
acct-timeout={{ radius_acct_tmo }}
timeout={{ radius_timeout }}
max-try={{ radius_max_try }}
-{% if radius_nas_id %}
+{% if radius_nas_id %}
nas-identifier={{ radius_nas_id }}
-{% endif %}
-{% if radius_nas_ip %}
+{% endif %}
+{% if radius_nas_ip %}
nas-ip-address={{ radius_nas_ip }}
-{% endif %}
-{% if radius_source_address %}
+{% endif %}
+{% if radius_source_address %}
bind={{ radius_source_address }}
-{% endif %}
+{% endif %}
{% endif %}
{# Both chap-secrets and radius block required the gw-ip-address #}
{% if gw_ip is defined and gw_ip is not none %}
diff --git a/data/templates/accel-ppp/sstp.config.tmpl b/data/templates/accel-ppp/sstp.config.j2
index 8fd7d230d..5c6f19306 100644
--- a/data/templates/accel-ppp/sstp.config.tmpl
+++ b/data/templates/accel-ppp/sstp.config.j2
@@ -50,7 +50,7 @@ verbose=1
check-ip=1
{# MTU #}
mtu={{ mtu }}
-ipv6={{ 'allow' if ppp_options.ipv6 == "deny" and client_ipv6_pool is defined else ppp_options.ipv6 }}
+ipv6={{ 'allow' if ppp_options.ipv6 is vyos_defined("deny") and client_ipv6_pool is vyos_defined else ppp_options.ipv6 }}
ipv4={{ ppp_options.ipv4 }}
mppe={{ ppp_options.mppe }}
diff --git a/data/templates/bcast-relay/udp-broadcast-relay.j2 b/data/templates/bcast-relay/udp-broadcast-relay.j2
new file mode 100644
index 000000000..75740e04c
--- /dev/null
+++ b/data/templates/bcast-relay/udp-broadcast-relay.j2
@@ -0,0 +1,5 @@
+### Autogenerated by bcast_relay.py ###
+
+# UDP broadcast relay configuration for instance {{ id }}
+{{ '# ' ~ description if description is vyos_defined }}
+DAEMON_ARGS="{{ '-s ' ~ address if address is vyos_defined }} {{ instance }} {{ port }} {{ interface | join(' ') }}"
diff --git a/data/templates/bcast-relay/udp-broadcast-relay.tmpl b/data/templates/bcast-relay/udp-broadcast-relay.tmpl
deleted file mode 100644
index 73e9acad4..000000000
--- a/data/templates/bcast-relay/udp-broadcast-relay.tmpl
+++ /dev/null
@@ -1,7 +0,0 @@
-### Autogenerated by bcast_relay.py ###
-
-# UDP broadcast relay configuration for instance {{ id }}
-{% if description %}
-# Comment: {{ description }}
-{% endif %}
-DAEMON_ARGS="{{ '-s ' + address if address is defined }} {{ instance }} {{ port }} {{ interface | join(' ') }}"
diff --git a/data/templates/conntrack/nftables-ct.j2 b/data/templates/conntrack/nftables-ct.j2
new file mode 100644
index 000000000..16a03fc6e
--- /dev/null
+++ b/data/templates/conntrack/nftables-ct.j2
@@ -0,0 +1,48 @@
+#!/usr/sbin/nft -f
+
+{% set nft_ct_ignore_name = 'VYOS_CT_IGNORE' %}
+{% set nft_ct_timeout_name = 'VYOS_CT_TIMEOUT' %}
+
+# we first flush all chains and render the content from scratch - this makes
+# any delta check obsolete
+flush chain raw {{ nft_ct_ignore_name }}
+flush chain raw {{ nft_ct_timeout_name }}
+
+table raw {
+ chain {{ nft_ct_ignore_name }} {
+{% if ignore.rule is vyos_defined %}
+{% for rule, rule_config in ignore.rule.items() %}
+ # rule-{{ rule }} {{ '- ' ~ rule_config.description if rule_config.description is vyos_defined }}
+{% set nft_command = '' %}
+{% if rule_config.inbound_interface is vyos_defined %}
+{% set nft_command = nft_command ~ ' iifname ' ~ rule_config.inbound_interface %}
+{% endif %}
+{% if rule_config.protocol is vyos_defined %}
+{% set nft_command = nft_command ~ ' ip protocol ' ~ rule_config.protocol %}
+{% endif %}
+{% if rule_config.destination.address is vyos_defined %}
+{% set nft_command = nft_command ~ ' ip daddr ' ~ rule_config.destination.address %}
+{% endif %}
+{% if rule_config.destination.port is vyos_defined %}
+{% set nft_command = nft_command ~ ' ' ~ rule_config.protocol ~ ' dport { ' ~ rule_config.destination.port ~ ' }' %}
+{% endif %}
+{% if rule_config.source.address is vyos_defined %}
+{% set nft_command = nft_command ~ ' ip saddr ' ~ rule_config.source.address %}
+{% endif %}
+{% if rule_config.source.port is vyos_defined %}
+{% set nft_command = nft_command ~ ' ' ~ rule_config.protocol ~ ' sport { ' ~ rule_config.source.port ~ ' }' %}
+{% endif %}
+ {{ nft_command }} counter notrack comment ignore-{{ rule }}
+{% endfor %}
+{% endif %}
+ return
+ }
+ chain {{ nft_ct_timeout_name }} {
+{% if timeout.custom.rule is vyos_defined %}
+{% for rule, rule_config in timeout.custom.rule.items() %}
+ # rule-{{ rule }} {{ '- ' ~ rule_config.description if rule_config.description is vyos_defined }}
+{% endfor %}
+{% endif %}
+ return
+ }
+}
diff --git a/data/templates/conntrack/sysctl.conf.tmpl b/data/templates/conntrack/sysctl.conf.j2
index 9e97c3286..075402c04 100644
--- a/data/templates/conntrack/sysctl.conf.tmpl
+++ b/data/templates/conntrack/sysctl.conf.j2
@@ -6,7 +6,7 @@ net.netfilter.nf_conntrack_max = {{ table_size }}
net.ipv4.tcp_max_syn_backlog = {{ tcp.half_open_connections }}
-net.netfilter.nf_conntrack_tcp_loose = {{ '1' if tcp.loose == 'enable' else '0' }}
+net.netfilter.nf_conntrack_tcp_loose = {{ '1' if tcp.loose is vyos_defined('enable') else '0' }}
net.netfilter.nf_conntrack_tcp_max_retrans = {{ tcp.max_retrans }}
net.netfilter.nf_conntrack_icmp_timeout = {{ timeout.icmp }}
diff --git a/data/templates/conntrack/vyos_nf_conntrack.conf.tmpl b/data/templates/conntrack/vyos_nf_conntrack.conf.j2
index 111459485..111459485 100644
--- a/data/templates/conntrack/vyos_nf_conntrack.conf.tmpl
+++ b/data/templates/conntrack/vyos_nf_conntrack.conf.j2
diff --git a/data/templates/conntrackd/conntrackd.conf.tmpl b/data/templates/conntrackd/conntrackd.conf.j2
index 45b7bff09..66024869d 100644
--- a/data/templates/conntrackd/conntrackd.conf.tmpl
+++ b/data/templates/conntrackd/conntrackd.conf.j2
@@ -3,45 +3,45 @@
# Synchronizer settings
Sync {
Mode FTFW {
- DisableExternalCache {{ 'on' if disable_external_cache is defined else 'off' }}
+ DisableExternalCache {{ 'on' if disable_external_cache is vyos_defined else 'off' }}
}
{% for iface, iface_config in interface.items() %}
-{% if iface_config.peer is defined and iface_config.peer is not none %}
+{% if iface_config.peer is vyos_defined %}
UDP {
-{% if listen_address is defined and listen_address is not none %}
+{% if listen_address is vyos_defined %}
IPv4_address {{ listen_address }}
-{% endif %}
+{% endif %}
IPv4_Destination_Address {{ iface_config.peer }}
- Port {{ iface_config.port if iface_config.port is defined else '3780' }}
+ Port {{ iface_config.port if iface_config.port is vyos_defined else '3780' }}
Interface {{ iface }}
SndSocketBuffer {{ sync_queue_size | int *1024 *1024 }}
RcvSocketBuffer {{ sync_queue_size | int *1024 *1024 }}
Checksum on
}
-{% else %}
+{% else %}
Multicast {
-{% set ip_address = iface | get_ipv4 %}
+{% set ip_address = iface | get_ipv4 %}
IPv4_address {{ mcast_group }}
- Group {{ iface_config.port if iface_config.port is defined else '3780' }}
+ Group {{ iface_config.port if iface_config.port is vyos_defined else '3780' }}
IPv4_interface {{ ip_address[0] | ip_from_cidr }}
Interface {{ iface }}
SndSocketBuffer {{ sync_queue_size | int *1024 *1024 }}
RcvSocketBuffer {{ sync_queue_size | int *1024 *1024 }}
Checksum on
}
-{% endif %}
+{% endif %}
{% endfor %}
-{% if expect_sync is defined and expect_sync is not none %}
+{% if expect_sync is vyos_defined %}
Options {
-{% if 'all' in expect_sync %}
+{% if 'all' in expect_sync %}
ExpectationSync on
-{% else %}
+{% else %}
ExpectationSync {
-{% for protocol in expect_sync %}
+{% for protocol in expect_sync %}
{{ protocol }}
-{% endfor %}
+{% endfor %}
}
-{% endif %}
+{% endif %}
}
{% endif %}
}
@@ -83,29 +83,29 @@ General {
NetlinkBufferSizeMaxGrowth {{ event_listen_queue_size | int *1024 *1024 }}
NetlinkOverrunResync off
NetlinkEventsReliable on
-{% if ignore_address is defined or accept_protocol is defined %}
+{% if ignore_address is vyos_defined or accept_protocol is vyos_defined %}
Filter From Userspace {
-{% if ignore_address is defined and ignore_address is not none %}
+{% if ignore_address is vyos_defined %}
Address Ignore {
-{% for address in ignore_address if address | is_ipv4 %}
+{% for address in ignore_address if address | is_ipv4 %}
IPv4_address {{ address }}
-{% endfor %}
-{% for address in ignore_address if address | is_ipv6 %}
+{% endfor %}
+{% for address in ignore_address if address | is_ipv6 %}
IPv6_address {{ address }}
-{% endfor %}
+{% endfor %}
}
-{% endif %}
-{% if accept_protocol is defined and accept_protocol is not none %}
+{% endif %}
+{% if accept_protocol is vyos_defined %}
Protocol Accept {
-{% for protocol in accept_protocol %}
-{% if protocol == 'icmp6' %}
+{% for protocol in accept_protocol %}
+{% if protocol == 'icmp6' %}
IPv6-ICMP
-{% else %}
+{% else %}
{{ protocol | upper }}
-{% endif %}
-{% endfor %}
+{% endif %}
+{% endfor %}
}
-{% endif %}
+{% endif %}
}
{% endif %}
}
diff --git a/data/templates/conntrackd/conntrackd.op-mode.j2 b/data/templates/conntrackd/conntrackd.op-mode.j2
new file mode 100644
index 000000000..82f7e2859
--- /dev/null
+++ b/data/templates/conntrackd/conntrackd.op-mode.j2
@@ -0,0 +1,13 @@
+Source Destination Protocol
+{% for parsed in data if parsed.flow.meta is vyos_defined %}
+{% for key in parsed.flow.meta %}
+{% if key['@direction'] == 'original' %}
+{% set saddr = key.layer3.src | bracketize_ipv6 %}
+{% set sport = key.layer4.sport %}
+{% set daddr = key.layer3.dst | bracketize_ipv6 %}
+{% set dport = key.layer4.dport %}
+{% set protocol = key.layer4['@protoname'] %}
+{{ "%-48s" | format(saddr ~ ':' ~ sport) }} {{ "%-48s" | format(daddr ~ ':' ~ dport) }} {{ protocol }}
+{% endif %}
+{% endfor %}
+{% endfor %}
diff --git a/data/templates/conntrackd/conntrackd.op-mode.tmpl b/data/templates/conntrackd/conntrackd.op-mode.tmpl
deleted file mode 100644
index 82a4b09ad..000000000
--- a/data/templates/conntrackd/conntrackd.op-mode.tmpl
+++ /dev/null
@@ -1,13 +0,0 @@
-Source Destination Protocol
-{% for parsed in data if parsed.flow is defined and parsed.flow.meta is defined %}
-{% for key in parsed.flow.meta %}
-{% if key['@direction'] == 'original' %}
-{% set saddr = key.layer3.src | bracketize_ipv6 %}
-{% set sport = key.layer4.sport %}
-{% set daddr = key.layer3.dst | bracketize_ipv6 %}
-{% set dport = key.layer4.dport %}
-{% set protocol = key.layer4['@protoname'] %}
-{{ "%-48s" | format(saddr ~ ':' ~ sport) }} {{ "%-48s" | format(daddr ~ ':' ~ dport) }} {{ protocol }}
-{% endif %}
-{% endfor %}
-{% endfor %}
diff --git a/data/templates/conserver/conserver.conf.tmpl b/data/templates/conserver/conserver.conf.j2
index 4e7b5d8d7..1823657d7 100644
--- a/data/templates/conserver/conserver.conf.tmpl
+++ b/data/templates/conserver/conserver.conf.j2
@@ -17,7 +17,7 @@ default * {
##
{% for key, value in device.items() %}
{# Depending on our USB serial console we could require a path adjustment #}
-{% set path = '/dev' if key.startswith('ttyS') else '/dev/serial/by-bus' %}
+{% set path = '/dev' if key.startswith('ttyS') else '/dev/serial/by-bus' %}
console {{ key }} {
master localhost;
type device;
diff --git a/data/templates/conserver/dropbear@.service.tmpl b/data/templates/conserver/dropbear@.service.j2
index e355dab43..e355dab43 100644
--- a/data/templates/conserver/dropbear@.service.tmpl
+++ b/data/templates/conserver/dropbear@.service.j2
diff --git a/data/templates/container/registries.conf.j2 b/data/templates/container/registries.conf.j2
new file mode 100644
index 000000000..2e86466a1
--- /dev/null
+++ b/data/templates/container/registries.conf.j2
@@ -0,0 +1,27 @@
+### Autogenerated by container.py ###
+
+# For more information on this configuration file, see containers-registries.conf(5).
+#
+# NOTE: RISK OF USING UNQUALIFIED IMAGE NAMES
+# We recommend always using fully qualified image names including the registry
+# server (full dns name), namespace, image name, and tag
+# (e.g., registry.redhat.io/ubi8/ubi:latest). Pulling by digest (i.e.,
+# quay.io/repository/name@digest) further eliminates the ambiguity of tags.
+# When using short names, there is always an inherent risk that the image being
+# pulled could be spoofed. For example, a user wants to pull an image named
+# `foobar` from a registry and expects it to come from myregistry.com. If
+# myregistry.com is not first in the search list, an attacker could place a
+# different `foobar` image at a registry earlier in the search list. The user
+# would accidentally pull and run the attacker's image and code rather than the
+# intended content. We recommend only adding registries which are completely
+# trusted (i.e., registries which don't allow unknown or anonymous users to
+# create accounts with arbitrary names). This will prevent an image from being
+# spoofed, squatted or otherwise made insecure. If it is necessary to use one
+# of these registries, it should be added at the end of the list.
+#
+# An array of host[:port] registries to try when pulling an unqualified image, in order.
+# unqualified-search-registries = ["example.com"]
+
+{% if registry is vyos_defined %}
+unqualified-search-registries = {{ registry }}
+{% endif %}
diff --git a/data/templates/container/storage.conf.j2 b/data/templates/container/storage.conf.j2
new file mode 100644
index 000000000..665f9bf95
--- /dev/null
+++ b/data/templates/container/storage.conf.j2
@@ -0,0 +1,4 @@
+### Autogenerated by container.py ###
+[storage]
+ driver = "vfs"
+ graphroot = "/usr/lib/live/mount/persistence/container/storage"
diff --git a/data/templates/containers/registry.tmpl b/data/templates/containers/registry.tmpl
deleted file mode 100644
index 0347de673..000000000
--- a/data/templates/containers/registry.tmpl
+++ /dev/null
@@ -1,5 +0,0 @@
-### Autogenerated by /usr/libexec/vyos/conf_mode/containers.py ###
-
-{% if registry is defined and registry is not none %}
-unqualified-search-registries = {{ registry }}
-{% endif %}
diff --git a/data/templates/containers/storage.tmpl b/data/templates/containers/storage.tmpl
deleted file mode 100644
index 3a69b7252..000000000
--- a/data/templates/containers/storage.tmpl
+++ /dev/null
@@ -1,5 +0,0 @@
-### Autogenerated by /usr/libexec/vyos/conf_mode/containers.py ###
-
-[storage]
- driver = "vfs"
- graphroot = "/config/containers/storage"
diff --git a/data/templates/dhcp-client/daemon-options.j2 b/data/templates/dhcp-client/daemon-options.j2
new file mode 100644
index 000000000..b21ad08ab
--- /dev/null
+++ b/data/templates/dhcp-client/daemon-options.j2
@@ -0,0 +1,4 @@
+### Autogenerated by interface.py ###
+{% set if_metric = '-e IF_METRIC=' ~ dhcp_options.default_route_distance if dhcp_options.default_route_distance is vyos_defined else '' %}
+DHCLIENT_OPTS="-nw -cf /var/lib/dhcp/dhclient_{{ ifname }}.conf -pf /var/lib/dhcp/dhclient_{{ ifname }}.pid -lf /var/lib/dhcp/dhclient_{{ ifname }}.leases {{ if_metric }} {{ ifname }}"
+
diff --git a/data/templates/dhcp-client/daemon-options.tmpl b/data/templates/dhcp-client/daemon-options.tmpl
deleted file mode 100644
index 40629dca1..000000000
--- a/data/templates/dhcp-client/daemon-options.tmpl
+++ /dev/null
@@ -1,4 +0,0 @@
-### Autogenerated by interface.py ###
-
-DHCLIENT_OPTS="-nw -cf /var/lib/dhcp/dhclient_{{ifname}}.conf -pf /var/lib/dhcp/dhclient_{{ifname}}.pid -lf /var/lib/dhcp/dhclient_{{ifname}}.leases{{" -e IF_METRIC=" ~ dhcp_options.default_route_distance if dhcp_options.default_route_distance is defined and dhcp_options.default_route_distance is not none}} {{ifname}}"
-
diff --git a/data/templates/dhcp-client/ipv4.tmpl b/data/templates/dhcp-client/ipv4.j2
index b3e74c22b..cc5ddf09c 100644
--- a/data/templates/dhcp-client/ipv4.tmpl
+++ b/data/templates/dhcp-client/ipv4.j2
@@ -7,26 +7,26 @@ initial-interval 2;
interface "{{ ifname }}" {
send host-name "{{ dhcp_options.host_name }}";
-{% if dhcp_options.client_id is defined and dhcp_options.client_id is not none %}
-{% set client_id = dhcp_options.client_id %}
+{% if dhcp_options.client_id is vyos_defined %}
+{% set client_id = dhcp_options.client_id %}
{# Use HEX representation of client-id as it is send in MAC-address style using hex characters. If not HEX, use double quotes ASCII format #}
-{% if not dhcp_options.client_id.split(':') | length >= 5 %}
-{% set client_id = '"' + dhcp_options.client_id + '"' %}
-{% endif %}
- send dhcp-client-identifier {{ client_id }};
+{% if not dhcp_options.client_id.split(':') | length >= 5 %}
+{% set client_id = '"' + dhcp_options.client_id + '"' %}
+{% endif %}
+ send dhcp-client-identifier {{ client_id }};
{% endif %}
-{% if dhcp_options.vendor_class_id is defined and dhcp_options.vendor_class_id is not none %}
+{% if dhcp_options.vendor_class_id is vyos_defined %}
send vendor-class-identifier "{{ dhcp_options.vendor_class_id }}";
{% endif %}
# The request statement causes the client to request that any server responding to the
# client send the client its values for the specified options.
- request subnet-mask, broadcast-address,{{ " routers," if dhcp_options.no_default_route is not defined }} domain-name-servers,
+ request subnet-mask, broadcast-address,{{ " routers," if dhcp_options.no_default_route is not vyos_defined }} domain-name-servers,
rfc3442-classless-static-routes, domain-name, interface-mtu;
# The require statement lists options that must be sent in order for an offer to be
# accepted. Offers that do not contain all the listed options will be ignored!
require subnet-mask;
-{% if dhcp_options.reject is defined and dhcp_options.reject is not none %}
+{% if dhcp_options.reject is vyos_defined %}
# Block addresses coming from theses dhcp servers if configured.
reject {{ dhcp_options.reject | join(', ') }};
{% endif %}
diff --git a/data/templates/dhcp-client/ipv6.j2 b/data/templates/dhcp-client/ipv6.j2
new file mode 100644
index 000000000..e136b1789
--- /dev/null
+++ b/data/templates/dhcp-client/ipv6.j2
@@ -0,0 +1,60 @@
+### Autogenerated by interface.py ###
+
+# man https://www.unix.com/man-page/debian/5/dhcp6c.conf/
+interface {{ ifname }} {
+{% if dhcpv6_options.duid is vyos_defined %}
+ send client-id {{ dhcpv6_options.duid }};
+{% endif %}
+{% if address is vyos_defined and 'dhcpv6' in address %}
+ request domain-name-servers;
+ request domain-name;
+{% if dhcpv6_options.parameters_only is vyos_defined %}
+ information-only;
+{% endif %}
+{% if dhcpv6_options.temporary is not vyos_defined %}
+ send ia-na 0; # non-temporary address
+{% endif %}
+{% if dhcpv6_options.rapid_commit is vyos_defined %}
+ send rapid-commit; # wait for immediate reply instead of advertisements
+{% endif %}
+{% endif %}
+{% if dhcpv6_options.pd is vyos_defined %}
+{% for pd in dhcpv6_options.pd %}
+ send ia-pd {{ pd }}; # prefix delegation #{{ pd }}
+{% endfor %}
+{% endif %}
+};
+
+{% if address is vyos_defined and 'dhcpv6' in address %}
+{% if dhcpv6_options.temporary is not vyos_defined %}
+id-assoc na 0 {
+ # Identity association for non temporary address
+};
+{% endif %}
+{% endif %}
+
+{% if dhcpv6_options.pd is vyos_defined %}
+{% for pd, pd_config in dhcpv6_options.pd.items() %}
+id-assoc pd {{ pd }} {
+{# length got a default value #}
+ prefix ::/{{ pd_config.length }} infinity;
+{% set sla_len = 64 - pd_config.length | int %}
+{% set count = namespace(value=0) %}
+{% for interface, interface_config in pd_config.interface.items() if pd_config.interface is vyos_defined %}
+ prefix-interface {{ interface }} {
+ sla-len {{ sla_len }};
+{% if interface_config.sla_id is vyos_defined %}
+ sla-id {{ interface_config.sla_id }};
+{% else %}
+ sla-id {{ count.value }};
+{% endif %}
+{% if interface_config.address is vyos_defined %}
+ ifid {{ interface_config.address }};
+{% endif %}
+ };
+{% set count.value = count.value + 1 %}
+{% endfor %}
+};
+{% endfor %}
+{% endif %}
+
diff --git a/data/templates/dhcp-client/ipv6.tmpl b/data/templates/dhcp-client/ipv6.tmpl
deleted file mode 100644
index c292664e9..000000000
--- a/data/templates/dhcp-client/ipv6.tmpl
+++ /dev/null
@@ -1,60 +0,0 @@
-### Autogenerated by interface.py ###
-
-# man https://www.unix.com/man-page/debian/5/dhcp6c.conf/
-interface {{ ifname }} {
-{% if dhcpv6_options is defined and dhcpv6_options.duid is defined and dhcpv6_options.duid is not none %}
- send client-id {{ dhcpv6_options.duid }};
-{% endif %}
-{% if address is defined and 'dhcpv6' in address %}
- request domain-name-servers;
- request domain-name;
-{% if dhcpv6_options is defined and dhcpv6_options.parameters_only is defined %}
- information-only;
-{% endif %}
-{% if dhcpv6_options is not defined or dhcpv6_options.temporary is not defined %}
- send ia-na 0; # non-temporary address
-{% endif %}
-{% if dhcpv6_options is defined and dhcpv6_options.rapid_commit is defined %}
- send rapid-commit; # wait for immediate reply instead of advertisements
-{% endif %}
-{% endif %}
-{% if dhcpv6_options is defined and dhcpv6_options.pd is defined %}
-{% for pd in dhcpv6_options.pd %}
- send ia-pd {{ pd }}; # prefix delegation #{{ pd }}
-{% endfor %}
-{% endif %}
-};
-
-{% if address is defined and 'dhcpv6' in address %}
-{% if dhcpv6_options is not defined or dhcpv6_options.temporary is not defined %}
-id-assoc na 0 {
- # Identity association for non temporary address
-};
-{% endif %}
-{% endif %}
-
-{% if dhcpv6_options is defined and dhcpv6_options.pd is defined %}
-{% for pd in dhcpv6_options.pd %}
-id-assoc pd {{ pd }} {
-{# length got a default value #}
- prefix ::/{{ dhcpv6_options.pd[pd].length }} infinity;
-{% set sla_len = 64 - dhcpv6_options.pd[pd].length|int %}
-{% set count = namespace(value=0) %}
-{% for interface in dhcpv6_options.pd[pd].interface if dhcpv6_options.pd[pd].interface is defined %}
- prefix-interface {{ interface }} {
- sla-len {{ sla_len }};
-{% if dhcpv6_options.pd[pd].interface[interface].sla_id is defined and dhcpv6_options.pd[pd].interface[interface].sla_id is not none %}
- sla-id {{ dhcpv6_options.pd[pd].interface[interface].sla_id }};
-{% else %}
- sla-id {{ count.value }};
-{% endif %}
-{% if dhcpv6_options.pd[pd].interface[interface].address is defined and dhcpv6_options.pd[pd].interface[interface].address is not none %}
- ifid {{ dhcpv6_options.pd[pd].interface[interface].address }};
-{% endif %}
- };
-{% set count.value = count.value + 1 %}
-{% endfor %}
-};
-{% endfor %}
-{% endif %}
-
diff --git a/data/templates/dhcp-relay/dhcrelay.conf.tmpl b/data/templates/dhcp-relay/dhcrelay.conf.j2
index a9d17ed9a..11710bd8e 100644
--- a/data/templates/dhcp-relay/dhcrelay.conf.tmpl
+++ b/data/templates/dhcp-relay/dhcrelay.conf.j2
@@ -1,6 +1,6 @@
### Autogenerated by dhcp_relay.py ###
-{% set max_size = '-A ' + relay_options.max_size if relay_options.max_size is defined and relay_options.max_size is not none %}
+{% set max_size = '-A ' ~ relay_options.max_size if relay_options.max_size is vyos_defined %}
{# hop_count and relay_agents_packets is a default option, thus it is always present #}
OPTIONS="-c {{ relay_options.hop_count }} -a -m {{ relay_options.relay_agents_packets }} {{ max_size }} -i {{ interface | join(' -i ') }} {{ server | join(' ') }}"
diff --git a/data/templates/dhcp-relay/dhcrelay6.conf.j2 b/data/templates/dhcp-relay/dhcrelay6.conf.j2
new file mode 100644
index 000000000..6365346b4
--- /dev/null
+++ b/data/templates/dhcp-relay/dhcrelay6.conf.j2
@@ -0,0 +1,21 @@
+### Autogenerated by dhcpv6_relay.py ###
+
+{# upstream_interface is mandatory so it's always present #}
+{% set upstream = namespace(value='') %}
+{% for interface, config in upstream_interface.items() %}
+{% for address in config.address %}
+{% set upstream.value = upstream.value ~ '-u ' ~ address ~ '%' ~ interface ~ ' ' %}
+{% endfor %}
+{% endfor %}
+{# listen_interface is mandatory so it's always present #}
+{% set listen = namespace(value='') %}
+{% for interface, config in listen_interface.items() %}
+{% if config.address is vyos_defined %}
+{% set listen.value = listen.value ~ '-l ' ~ config.address ~ '%' ~ interface ~ ' ' %}
+{% else %}
+{% set listen.value = listen.value ~ '-l ' ~ interface ~ ' ' %}
+{% endif %}
+{% endfor %}
+
+OPTIONS="{{ listen.value }} {{ upstream.value }} -c {{ max_hop_count }} {{ '-I' if use_interface_id_option is vyos_defined }}"
+
diff --git a/data/templates/dhcp-relay/dhcrelay6.conf.tmpl b/data/templates/dhcp-relay/dhcrelay6.conf.tmpl
deleted file mode 100644
index 58c216b7c..000000000
--- a/data/templates/dhcp-relay/dhcrelay6.conf.tmpl
+++ /dev/null
@@ -1,21 +0,0 @@
-### Autogenerated by dhcpv6_relay.py ###
-
-{# upstream_interface is mandatory so it's always present #}
-{% set upstream = namespace(value='') %}
-{% for interface, config in upstream_interface.items() %}
-{% for address in config.address %}
-{% set upstream.value = upstream.value + '-u ' + address + '%' + interface + ' ' %}
-{% endfor %}
-{% endfor %}
-{# listen_interface is mandatory so it's always present #}
-{% set listen = namespace(value='') %}
-{% for interface, config in listen_interface.items() %}
-{% if config.address is defined and config.address is not none %}
-{% set listen.value = listen.value + '-l ' + config.address + '%' + interface + ' ' %}
-{% else %}
-{% set listen.value = listen.value + '-l ' + interface + ' ' %}
-{% endif %}
-{% endfor %}
-
-OPTIONS="{{ listen.value }} {{ upstream.value }} -c {{ max_hop_count }} {{ '-I' if use_interface_id_option is defined }}"
-
diff --git a/data/templates/dhcp-server/dhcpd.conf.j2 b/data/templates/dhcp-server/dhcpd.conf.j2
new file mode 100644
index 000000000..4c2da0aa5
--- /dev/null
+++ b/data/templates/dhcp-server/dhcpd.conf.j2
@@ -0,0 +1,246 @@
+### Autogenerated by dhcp_server.py ###
+
+# For options please consult the following website:
+# https://www.isc.org/wp-content/uploads/2017/08/dhcp43options.html
+#
+# log-facility local7;
+{% if hostfile_update is vyos_defined %}
+on release {
+ set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name);
+ set ClientIp = binary-to-ascii(10, 8, ".",leased-address);
+ execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "release", "", ClientIp, "", "");
+}
+on expiry {
+ set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name);
+ set ClientIp = binary-to-ascii(10, 8, ".",leased-address);
+ execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "release", "", ClientIp, "", "");
+}
+{% endif %}
+
+{{ 'use-host-decl-names on;' if host_decl_name is vyos_defined }}
+ddns-update-style {{ 'interim' if dynamic_dns_update is vyos_defined else 'none' }};
+option rfc3442-static-route code 121 = array of integer 8;
+option windows-static-route code 249 = array of integer 8;
+option wpad-url code 252 = text;
+
+# Vendor specific options - Ubiquiti Networks
+option space ubnt;
+option ubnt.unifi-controller code 1 = ip-address;
+class "ubnt" {
+ match if substring (option vendor-class-identifier , 0, 4) = "ubnt";
+ option vendor-class-identifier "ubnt";
+ vendor-option-space ubnt;
+}
+
+{% if global_parameters is vyos_defined %}
+# The following {{ global_parameters | length }} line(s) have been added as
+# global-parameters in the CLI and have not been validated !!!
+{% for parameter in global_parameters %}
+{{ parameter }}
+{% endfor %}
+
+{% endif %}
+{% if failover is vyos_defined %}
+# DHCP failover configuration
+failover peer "{{ failover.name }}" {
+{% if failover.status == 'primary' %}
+ primary;
+ mclt 1800;
+ split 128;
+{% elif failover.status == 'secondary' %}
+ secondary;
+{% endif %}
+ address {{ failover.source_address }};
+ port 647;
+ peer address {{ failover.remote }};
+ peer port 647;
+ max-response-delay 30;
+ max-unacked-updates 10;
+ load balance max seconds 3;
+}
+{% endif %}
+{% if listen_address is vyos_defined %}
+
+# DHCP server serving relay subnet, we need a connector to the real world
+{% for address in listen_address %}
+# Connected subnet statement for listen-address {{ address }}
+subnet {{ address | network_from_ipv4 }} netmask {{ address | netmask_from_ipv4 }} { }
+{% endfor %}
+{% endif %}
+
+# Shared network configration(s)
+{% if shared_network_name is vyos_defined %}
+{% for network, network_config in shared_network_name.items() if network_config.disable is not vyos_defined %}
+shared-network {{ network }} {
+{% if network_config.authoritative is vyos_defined %}
+ authoritative;
+{% endif %}
+{% if network_config.name_server is vyos_defined %}
+ option domain-name-servers {{ network_config.name_server | join(', ') }};
+{% endif %}
+{% if network_config.domain_name is vyos_defined %}
+ option domain-name "{{ network_config.domain_name }}";
+{% endif %}
+{% if network_config.domain_search is vyos_defined %}
+ option domain-search "{{ network_config.domain_search | join('", "') }}";
+{% endif %}
+{% if network_config.ntp_server is vyos_defined %}
+ option ntp-servers {{ network_config.ntp_server | join(', ') }};
+{% endif %}
+{% if network_config.ping_check is vyos_defined %}
+ ping-check true;
+{% endif %}
+{% if network_config.shared_network_parameters is vyos_defined %}
+ # The following {{ network_config.shared_network_parameters | length }} line(s)
+ # were added as shared-network-parameters in the CLI and have not been validated
+{% for parameter in network_config.shared_network_parameters %}
+ {{ parameter }}
+{% endfor %}
+{% endif %}
+{% if network_config.subnet is vyos_defined %}
+{% for subnet, subnet_config in network_config.subnet.items() %}
+{% if subnet_config.description is vyos_defined %}
+ # {{ subnet_config.description }}
+{% endif %}
+ subnet {{ subnet | address_from_cidr }} netmask {{ subnet | netmask_from_cidr }} {
+{% if subnet_config.name_server is vyos_defined %}
+ option domain-name-servers {{ subnet_config.name_server | join(', ') }};
+{% endif %}
+{% if subnet_config.domain_name is vyos_defined %}
+ option domain-name "{{ subnet_config.domain_name }}";
+{% endif %}
+{% if subnet_config.domain_search is vyos_defined %}
+ option domain-search "{{ subnet_config.domain_search | join('", "') }}";
+{% endif %}
+{% if subnet_config.ntp_server is vyos_defined %}
+ option ntp-servers {{ subnet_config.ntp_server | join(', ') }};
+{% endif %}
+{% if subnet_config.pop_server is vyos_defined %}
+ option pop-server {{ subnet_config.pop_server | join(', ') }};
+{% endif %}
+{% if subnet_config.smtp_server is vyos_defined %}
+ option smtp-server {{ subnet_config.smtp_server | join(', ') }};
+{% endif %}
+{% if subnet_config.time_server is vyos_defined %}
+ option time-servers {{ subnet_config.time_server | join(', ') }};
+{% endif %}
+{% if subnet_config.wins_server is vyos_defined %}
+ option netbios-name-servers {{ subnet_config.wins_server | join(', ') }};
+{% endif %}
+{% if subnet_config.static_route is vyos_defined %}
+{% set static_default_route = '' %}
+{% if subnet_config.default_router is vyos_defined %}
+{% set static_default_route = ', ' ~ '0.0.0.0/0' | isc_static_route(subnet_config.default_router) %}
+{% endif %}
+{% if subnet_config.static_route is vyos_defined %}
+{% set rfc3442_routes = [] %}
+{% for route, route_options in subnet_config.static_route.items() %}
+{% set rfc3442_routes = rfc3442_routes.append(route | isc_static_route(route_options.next_hop)) %}
+{% endfor %}
+ option rfc3442-static-route {{ rfc3442_routes | join(', ') }}{{ static_default_route }};
+ option windows-static-route {{ rfc3442_routes | join(', ') }};
+{% endif %}
+{% endif %}
+{% if subnet_config.ip_forwarding is vyos_defined %}
+ option ip-forwarding true;
+{% endif %}
+{% if subnet_config.default_router is vyos_defined %}
+ option routers {{ subnet_config.default_router }};
+{% endif %}
+{% if subnet_config.server_identifier is vyos_defined %}
+ option dhcp-server-identifier {{ subnet_config.server_identifier }};
+{% endif %}
+{% if subnet_config.subnet_parameters is vyos_defined %}
+ # The following {{ subnet_config.subnet_parameters | length }} line(s) were added as
+ # subnet-parameters in the CLI and have not been validated!!!
+{% for parameter in subnet_config.subnet_parameters %}
+ {{ parameter }}
+{% endfor %}
+{% endif %}
+{% if subnet_config.tftp_server_name is vyos_defined %}
+ option tftp-server-name "{{ subnet_config.tftp_server_name }}";
+{% endif %}
+{% if subnet_config.bootfile_name is vyos_defined %}
+ option bootfile-name "{{ subnet_config.bootfile_name }}";
+ filename "{{ subnet_config.bootfile_name }}";
+{% endif %}
+{% if subnet_config.bootfile_server is vyos_defined %}
+ next-server {{ subnet_config.bootfile_server }};
+{% endif %}
+{% if subnet_config.bootfile_size is vyos_defined %}
+ option boot-size {{ subnet_config.bootfile_size }};
+{% endif %}
+{% if subnet_config.time_offset is vyos_defined %}
+ option time-offset {{ subnet_config.time_offset }};
+{% endif %}
+{% if subnet_config.wpad_url is vyos_defined %}
+ option wpad-url "{{ subnet_config.wpad_url }}";
+{% endif %}
+{% if subnet_config.client_prefix_length is vyos_defined %}
+ option subnet-mask {{ ('0.0.0.0/' ~ subnet_config.client_prefix_length) | netmask_from_cidr }};
+{% endif %}
+{% if subnet_config.lease is vyos_defined %}
+ default-lease-time {{ subnet_config.lease }};
+ max-lease-time {{ subnet_config.lease }};
+{% endif %}
+{% if network_config.ping_check is not vyos_defined and subnet_config.ping_check is vyos_defined %}
+ ping-check true;
+{% endif %}
+{% if subnet_config.static_mapping is vyos_defined %}
+{% for host, host_config in subnet_config.static_mapping.items() if host_config.disable is not vyos_defined %}
+ host {{ host | replace('_','-') if host_decl_name is vyos_defined else network | replace('_','-') ~ '_' ~ host | replace('_','-') }} {
+{% if host_config.ip_address is vyos_defined %}
+ fixed-address {{ host_config.ip_address }};
+{% endif %}
+ hardware ethernet {{ host_config.mac_address }};
+{% if host_config.static_mapping_parameters is vyos_defined %}
+ # The following {{ host_config.static_mapping_parameters | length }} line(s) were added
+ # as static-mapping-parameters in the CLI and have not been validated
+{% for parameter in host_config.static_mapping_parameters %}
+ {{ parameter }}
+{% endfor %}
+{% endif %}
+ }
+{% endfor %}
+{% endif %}
+{% if subnet_config.vendor_option.ubiquiti.unifi_controller is vyos_defined %}
+ option ubnt.unifi-controller {{ subnet_config.vendor_option.ubiquiti.unifi_controller }};
+{% endif %}
+{% if subnet_config.range is vyos_defined %}
+{# pool configuration can only be used if there follows a range option #}
+ pool {
+{% endif %}
+{% if subnet_config.enable_failover is vyos_defined %}
+ failover peer "{{ failover.name }}";
+ deny dynamic bootp clients;
+{% endif %}
+{% if subnet_config.range is vyos_defined %}
+{% for range, range_options in subnet_config.range.items() %}
+ range {{ range_options.start }} {{ range_options.stop }};
+{% endfor %}
+{% endif %}
+{% if subnet_config.range is vyos_defined %}
+{# pool configuration can only be used if there follows a range option #}
+ }
+{% endif %}
+ }
+{% endfor %}
+{% endif %}
+ on commit {
+ set shared-networkname = "{{ network }}";
+{% if hostfile_update is vyos_defined %}
+ set ClientIp = binary-to-ascii(10, 8, ".", leased-address);
+ set ClientMac = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6));
+ set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name, "empty_hostname");
+ if not (ClientName = "empty_hostname") {
+ set ClientDomain = pick-first-value(config-option domain-name, "..YYZ!");
+ execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "commit", ClientName, ClientIp, ClientMac, ClientDomain);
+ } else {
+ log(concat("Hostname is not defined for client with IP: ", ClientIP, " MAC: ", ClientMac));
+ }
+{% endif %}
+ }
+}
+
+{% endfor %}
+{% endif %}
diff --git a/data/templates/dhcp-server/dhcpd.conf.tmpl b/data/templates/dhcp-server/dhcpd.conf.tmpl
deleted file mode 100644
index 233e2cc53..000000000
--- a/data/templates/dhcp-server/dhcpd.conf.tmpl
+++ /dev/null
@@ -1,231 +0,0 @@
-### Autogenerated by dhcp_server.py ###
-
-# For options please consult the following website:
-# https://www.isc.org/wp-content/uploads/2017/08/dhcp43options.html
-#
-# log-facility local7;
-{% if hostfile_update is defined %}
-on release {
- set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name);
- set ClientIp = binary-to-ascii(10, 8, ".",leased-address);
- execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "release", "", ClientIp, "", "");
-}
-on expiry {
- set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name);
- set ClientIp = binary-to-ascii(10, 8, ".",leased-address);
- execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "release", "", ClientIp, "", "");
-}
-{% endif %}
-
-{{ 'use-host-decl-names on;' if host_decl_name is defined }}
-ddns-update-style {{ 'interim' if dynamic_dns_update is defined else 'none' }};
-option rfc3442-static-route code 121 = array of integer 8;
-option windows-static-route code 249 = array of integer 8;
-option wpad-url code 252 = text;
-
-{% if global_parameters is defined and global_parameters is not none %}
-# The following {{ global_parameters | length }} line(s) have been added as
-# global-parameters in the CLI and have not been validated !!!
-{% for parameter in global_parameters %}
-{{ parameter }}
-{% endfor %}
-
-{% endif %}
-{% if failover is defined and failover is not none %}
-# DHCP failover configuration
-failover peer "{{ failover.name }}" {
-{% if failover.status == 'primary' %}
- primary;
- mclt 1800;
- split 128;
-{% elif failover.status == 'secondary' %}
- secondary;
-{% endif %}
- address {{ failover.source_address }};
- port 520;
- peer address {{ failover.remote }};
- peer port 520;
- max-response-delay 30;
- max-unacked-updates 10;
- load balance max seconds 3;
-}
-{% endif %}
-{% if listen_address is defined and listen_address is not none %}
-
-# DHCP server serving relay subnet, we need a connector to the real world
-{% for address in listen_address %}
-# Connected subnet statement for listen-address {{ address }}
-subnet {{ address | network_from_ipv4 }} netmask {{ address | netmask_from_ipv4 }} { }
-{% endfor %}
-{% endif %}
-
-# Shared network configration(s)
-{% if shared_network_name is defined and shared_network_name is not none %}
-{% for network, network_config in shared_network_name.items() if network_config.disable is not defined %}
-shared-network {{ network | replace('_','-') }} {
-{% if network_config.authoritative is defined %}
- authoritative;
-{% endif %}
-{% if network_config.name_server is defined and network_config.name_server is not none %}
- option domain-name-servers {{ network_config.name_server | join(', ') }};
-{% endif %}
-{% if network_config.domain_name is defined and network_config.domain_name is not none %}
- option domain-name "{{ network_config.domain_name }}";
-{% endif %}
-{% if network_config.domain_search is defined and network_config.domain_search is not none %}
- option domain-search "{{ network_config.domain_search | join('", "') }}";
-{% endif %}
-{% if network_config.ntp_server is defined and network_config.ntp_server is not none %}
- option ntp-servers {{ network_config.ntp_server | join(', ') }};
-{% endif %}
-{% if network_config.ping_check is defined %}
- ping-check true;
-{% endif %}
-{% if network_config.shared_network_parameters is defined and network_config.shared_network_parameters is not none %}
- # The following {{ network_config.shared_network_parameters | length }} line(s)
- # were added as shared-network-parameters in the CLI and have not been validated
-{% for parameter in network_config.shared_network_parameters %}
- {{ parameter }}
-{% endfor %}
-{% endif %}
-{% if network_config.subnet is defined and network_config.subnet is not none %}
-{% for subnet, subnet_config in network_config.subnet.items() %}
-{% if subnet_config.description is defined and subnet_config.description is not none %}
- # {{ subnet_config.description }}
-{% endif %}
- subnet {{ subnet | address_from_cidr }} netmask {{ subnet | netmask_from_cidr }} {
-{% if subnet_config.name_server is defined and subnet_config.name_server is not none %}
- option domain-name-servers {{ subnet_config.name_server | join(', ') }};
-{% endif %}
-{% if subnet_config.domain_name is defined and subnet_config.domain_name is not none %}
- option domain-name "{{ subnet_config.domain_name }}";
-{% endif %}
-{% if subnet_config.domain_search is defined and subnet_config.domain_search is not none %}
- option domain-search "{{ subnet_config.domain_search | join('", "') }}";
-{% endif %}
-{% if subnet_config.ntp_server is defined and subnet_config.ntp_server is not none %}
- option ntp-servers {{ subnet_config.ntp_server | join(', ') }};
-{% endif %}
-{% if subnet_config.pop_server is defined and subnet_config.pop_server is not none %}
- option pop-server {{ subnet_config.pop_server | join(', ') }};
-{% endif %}
-{% if subnet_config.smtp_server is defined and subnet_config.smtp_server is not none %}
- option smtp-server {{ subnet_config.smtp_server | join(', ') }};
-{% endif %}
-{% if subnet_config.time_server is defined and subnet_config.time_server is not none %}
- option time-servers {{ subnet_config.time_server | join(', ') }};
-{% endif %}
-{% if subnet_config.wins_server is defined and subnet_config.wins_server is not none %}
- option netbios-name-servers {{ subnet_config.wins_server | join(', ') }};
-{% endif %}
-{% if subnet_config.static_route is defined and subnet_config.static_route is not none %}
-{% set static_default_route = '' %}
-{% if subnet_config.default_router and subnet_config.default_router is not none %}
-{% set static_default_route = ', ' + '0.0.0.0/0' | isc_static_route(subnet_config.default_router) %}
-{% endif %}
-{% if subnet_config.static_route is defined and subnet_config.static_route is not none %}
-{% set rfc3442_routes = [] %}
-{% for route, route_options in subnet_config.static_route.items() %}
-{% set rfc3442_routes = rfc3442_routes.append(route | isc_static_route(route_options.next_hop)) %}
-{% endfor %}
- option rfc3442-static-route {{ rfc3442_routes | join(', ') }}{{ static_default_route }};
- option windows-static-route {{ rfc3442_routes | join(', ') }};
-{% endif %}
-{% endif %}
-{% if subnet_config.ip_forwarding is defined %}
- option ip-forwarding true;
-{% endif %}
-{% if subnet_config.default_router and subnet_config.default_router is not none %}
- option routers {{ subnet_config.default_router }};
-{% endif %}
-{% if subnet_config.server_identifier is defined and subnet_config.server_identifier is not none %}
- option dhcp-server-identifier {{ subnet_config.server_identifier }};
-{% endif %}
-{% if subnet_config.subnet_parameters is defined and subnet_config.subnet_parameters is not none %}
- # The following {{ subnet_config.subnet_parameters | length }} line(s) were added as
- # subnet-parameters in the CLI and have not been validated!!!
-{% for parameter in subnet_config.subnet_parameters %}
- {{ parameter }}
-{% endfor %}
-{% endif %}
-{% if subnet_config.tftp_server_name is defined and subnet_config.tftp_server_name is not none %}
- option tftp-server-name "{{ subnet_config.tftp_server_name }}";
-{% endif %}
-{% if subnet_config.bootfile_name is defined and subnet_config.bootfile_name is not none %}
- option bootfile-name "{{ subnet_config.bootfile_name }}";
- filename "{{ subnet_config.bootfile_name }}";
-{% endif %}
-{% if subnet_config.bootfile_server is defined and subnet_config.bootfile_server is not none %}
- next-server {{ subnet_config.bootfile_server }};
-{% endif %}
-{% if subnet_config.time_offset is defined and subnet_config.time_offset is not none %}
- option time-offset {{ subnet_config.time_offset }};
-{% endif %}
-{% if subnet_config.wpad_url is defined and subnet_config.wpad_url is not none %}
- option wpad-url "{{ subnet_config.wpad_url }}";
-{% endif %}
-{% if subnet_config.client_prefix_length is defined and subnet_config.client_prefix_length is not none %}
- option subnet-mask {{ subnet_config.client_prefix_length }};
-{% endif %}
-{% if subnet_config.lease is defined and subnet_config.lease is not none %}
- default-lease-time {{ subnet_config.lease }};
- max-lease-time {{ subnet_config.lease }};
-{% endif %}
-{% if network_config.ping_check is not defined and subnet_config.ping_check is defined %}
- ping-check true;
-{% endif %}
-{% if subnet_config.static_mapping is defined and subnet_config.static_mapping is not none %}
-{% for host, host_config in subnet_config.static_mapping.items() if host_config.disable is not defined %}
- host {{ host | replace('_','-') if host_decl_name is defined else network | replace('_','-') + '_' + host | replace('_','-') }} {
-{% if host_config.ip_address is defined and host_config.ip_address is not none %}
- fixed-address {{ host_config.ip_address }};
-{% endif %}
- hardware ethernet {{ host_config.mac_address }};
-{% if host_config.static_mapping_parameters is defined and host_config.static_mapping_parameters is not none %}
- # The following {{ host_config.static_mapping_parameters | length }} line(s) were added
- # as static-mapping-parameters in the CLI and have not been validated
-{% for parameter in host_config.static_mapping_parameters %}
- {{ parameter }}
-{% endfor %}
-{% endif %}
- }
-{% endfor %}
-{% endif %}
-{% if subnet_config.range is defined and subnet_config.range is not none %}
-{# pool configuration can only be used if there follows a range option #}
- pool {
-{% endif %}
-{% if subnet_config.enable_failover is defined %}
- failover peer "{{ failover.name }}";
- deny dynamic bootp clients;
-{% endif %}
-{% if subnet_config.range is defined and subnet_config.range is not none %}
-{% for range, range_options in subnet_config.range.items() %}
- range {{ range_options.start }} {{ range_options.stop }};
-{% endfor %}
-{% endif %}
-{% if subnet_config.range is defined and subnet_config.range is not none %}
-{# pool configuration can only be used if there follows a range option #}
- }
-{% endif %}
- }
-{% endfor %}
-{% endif %}
- on commit {
- set shared-networkname = "{{ network | replace('_','-') }}";
-{% if hostfile_update is defined %}
- set ClientIp = binary-to-ascii(10, 8, ".", leased-address);
- set ClientMac = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6));
- set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name, "empty_hostname");
- if not (ClientName = "empty_hostname") {
- set ClientDomain = pick-first-value(config-option domain-name, "..YYZ!");
- execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "commit", ClientName, ClientIp, ClientMac, ClientDomain);
- } else {
- log(concat("Hostname is not defined for client with IP: ", ClientIP, " MAC: ", ClientMac));
- }
-{% endif %}
- }
-}
-
-{% endfor %}
-{% endif %}
diff --git a/data/templates/dhcp-server/dhcpdv6.conf.j2 b/data/templates/dhcp-server/dhcpdv6.conf.j2
new file mode 100644
index 000000000..5c3471316
--- /dev/null
+++ b/data/templates/dhcp-server/dhcpdv6.conf.j2
@@ -0,0 +1,132 @@
+### Autogenerated by dhcpv6_server.py ###
+
+# For options please consult the following website:
+# https://www.isc.org/wp-content/uploads/2017/08/dhcp43options.html
+
+log-facility local7;
+{% if preference is vyos_defined %}
+option dhcp6.preference {{ preference }};
+{% endif %}
+
+{% if global_parameters.name_server is vyos_defined %}
+option dhcp6.name-servers {{ global_parameters.name_server | join(', ') }};
+{% endif %}
+
+# Vendor specific options - Cisco
+option space cisco code width 2 length width 2;
+option cisco.tftp-servers code 1 = array of ip6-address;
+option vsio.cisco code 9 = encapsulate cisco;
+
+# Shared network configration(s)
+{% if shared_network_name is vyos_defined %}
+{% for network, network_config in shared_network_name.items() if network_config.disable is not vyos_defined %}
+shared-network {{ network }} {
+{% if network_config.common_options is vyos_defined %}
+{% if network_config.common_options.info_refresh_time is vyos_defined %}
+ option dhcp6.info-refresh-time {{ network_config.common_options.info_refresh_time }};
+{% endif %}
+{% if network_config.common_options.domain_search is vyos_defined %}
+ option dhcp6.domain-search "{{ network_config.common_options.domain_search | join('", "') }}";
+{% endif %}
+{% if network_config.common_options.name_server is vyos_defined %}
+ option dhcp6.name-servers {{ network_config.common_options.name_server | join(', ') }};
+{% endif %}
+{% endif %}
+{% if network_config.subnet is vyos_defined %}
+{% for subnet, subnet_config in network_config.subnet.items() %}
+ subnet6 {{ subnet }} {
+{% if subnet_config.address_range is vyos_defined %}
+{% if subnet_config.address_range.prefix is vyos_defined %}
+{% for prefix, prefix_config in subnet_config.address_range.prefix.items() %}
+ range6 {{ prefix }} {{ "temporary" if prefix_config.temporary is vyos_defined }};
+{% endfor %}
+{% endif %}
+{% if subnet_config.address_range.start is vyos_defined %}
+{% for address, address_config in subnet_config.address_range.start.items() %}
+ range6 {{ address }} {{ address_config.stop }};
+{% endfor %}
+{% endif %}
+{% endif %}
+{% if subnet_config.domain_search is vyos_defined %}
+ option dhcp6.domain-search "{{ subnet_config.domain_search | join('", "') }}";
+{% endif %}
+{% if subnet_config.lease_time is vyos_defined %}
+{% if subnet_config.lease_time.default is vyos_defined %}
+ default-lease-time {{ subnet_config.lease_time.default }};
+{% endif %}
+{% if subnet_config.lease_time.maximum is vyos_defined %}
+ max-lease-time {{ subnet_config.lease_time.maximum }};
+{% endif %}
+{% if subnet_config.lease_time.minimum is vyos_defined %}
+ min-lease-time {{ subnet_config.lease_time.minimum }};
+{% endif %}
+{% endif %}
+{% if subnet_config.name_server is vyos_defined %}
+ option dhcp6.name-servers {{ subnet_config.name_server | join(', ') }};
+{% endif %}
+{% if subnet_config.nis_domain is vyos_defined %}
+ option dhcp6.nis-domain-name "{{ subnet_config.nis_domain }}";
+{% endif %}
+{% if subnet_config.nis_server is vyos_defined %}
+ option dhcp6.nis-servers {{ subnet_config.nis_server | join(', ') }};
+{% endif %}
+{% if subnet_config.nisplus_domain is vyos_defined %}
+ option dhcp6.nisp-domain-name "{{ subnet_config.nisplus_domain }}";
+{% endif %}
+{% if subnet_config.nisplus_server is vyos_defined %}
+ option dhcp6.nisp-servers {{ subnet_config.nisplus_server | join(', ') }};
+{% endif %}
+{% if subnet_config.sip_server is vyos_defined %}
+{% set server_ip = [] %}
+{% set server_fqdn = [] %}
+{% for address in subnet_config.sip_server %}
+{% if address | is_ipv6 %}
+{% set server_ip = server_ip.append(address) %}
+{% else %}
+{% set server_fqdn = server_fqdn.append(address) %}
+{% endif %}
+{% endfor %}
+{% if server_ip is vyos_defined and server_ip | length > 0 %}
+ option dhcp6.sip-servers-addresses {{ server_ip | join(', ') }};
+{% endif %}
+{% if server_fqdn is vyos_defined and server_fqdn | length > 0 %}
+ option dhcp6.sip-servers-names "{{ server_fqdn | join('", "') }}";
+{% endif %}
+{% endif %}
+{% if subnet_config.sntp_server is vyos_defined %}
+ option dhcp6.sntp-servers {{ subnet_config.sntp_server | join(', ') }};
+{% endif %}
+{% if subnet_config.prefix_delegation.start is vyos_defined %}
+{% for prefix, prefix_config in subnet_config.prefix_delegation.start.items() %}
+ prefix6 {{ prefix }} {{ prefix_config.stop }} /{{ prefix_config.prefix_length }};
+{% endfor %}
+{% endif %}
+{% if subnet_config.static_mapping is vyos_defined %}
+
+ # begin configuration of static client mappings
+{% for host, host_config in subnet_config.static_mapping.items() if host_config.disable is not vyos_defined %}
+ host {{ network | replace('_','-') }}_{{ host | replace('_','-') }} {
+{% if host_config.identifier is vyos_defined %}
+ host-identifier option dhcp6.client-id {{ host_config.identifier }};
+{% endif %}
+{% if host_config.ipv6_address is vyos_defined %}
+ fixed-address6 {{ host_config.ipv6_address }};
+{% endif %}
+{% if host_config.ipv6_prefix is vyos_defined %}
+ fixed-prefix6 {{ host_config.ipv6_prefix }};
+{% endif %}
+ }
+{% endfor %}
+{% endif %}
+{% if subnet_config.vendor_option.cisco.tftp_server is vyos_defined %}
+ option cisco.tftp-servers {{ subnet_config.vendor_option.cisco.tftp_server | join(', ') }};
+{% endif %}
+ }
+{% endfor %}
+{% endif %}
+ on commit {
+ set shared-networkname = "{{ network }}";
+ }
+}
+{% endfor %}
+{% endif %}
diff --git a/data/templates/dhcp-server/dhcpdv6.conf.tmpl b/data/templates/dhcp-server/dhcpdv6.conf.tmpl
deleted file mode 100644
index 45d629928..000000000
--- a/data/templates/dhcp-server/dhcpdv6.conf.tmpl
+++ /dev/null
@@ -1,124 +0,0 @@
-### Autogenerated by dhcpv6_server.py ###
-
-# For options please consult the following website:
-# https://www.isc.org/wp-content/uploads/2017/08/dhcp43options.html
-
-log-facility local7;
-{% if preference is defined and preference is not none %}
-option dhcp6.preference {{ preference }};
-{% endif %}
-
-{% if global_parameters is defined and global_parameters.name_server is defined and global_parameters.name_server is not none %}
-option dhcp6.name-servers {{ global_parameters.name_server | join(', ') }};
-{% endif %}
-
-# Shared network configration(s)
-{% if shared_network_name is defined and shared_network_name is not none %}
-{% for network, network_config in shared_network_name.items() if network_config.disable is not defined %}
-shared-network {{ network | replace('_','-') }} {
-{% if network_config.common_options is defined and network_config.common_options is not none %}
-{% if network_config.common_options.info_refresh_time is defined and network_config.common_options.info_refresh_time is not none %}
- option dhcp6.info-refresh-time {{ network_config.common_options.info_refresh_time }};
-{% endif %}
-{% if network_config.common_options.domain_search is defined and network_config.common_options.domain_search is not none %}
- option dhcp6.domain-search "{{ network_config.common_options.domain_search | join('", "') }}";
-{% endif %}
-{% if network_config.common_options.name_server is defined and network_config.common_options.name_server is not none %}
- option dhcp6.name-servers {{ network_config.common_options.name_server | join(', ') }};
-{% endif %}
-{% endif %}
-{% if network_config.subnet is defined and network_config.subnet is not none %}
-{% for subnet, subnet_config in network_config.subnet.items() %}
- subnet6 {{ subnet }} {
-{% if subnet_config.address_range is defined and subnet_config.address_range is not none %}
-{% if subnet_config.address_range.prefix is defined and subnet_config.address_range.prefix is not none %}
-{% for prefix, prefix_config in subnet_config.address_range.prefix.items() %}
- range6 {{ prefix }} {{ "temporary" if prefix_config.temporary is defined }};
-{% endfor %}
-{% endif %}
-{% if subnet_config.address_range.start is defined and subnet_config.address_range.start is not none %}
-{% for address, address_config in subnet_config.address_range.start.items() %}
- range6 {{ address }} {{ address_config.stop }};
-{% endfor %}
-{% endif %}
-{% endif %}
-{% if subnet_config.domain_search is defined and subnet_config.domain_search is not none %}
- option dhcp6.domain-search "{{ subnet_config.domain_search | join('", "') }}";
-{% endif %}
-{% if subnet_config.lease_time is defined and subnet_config.lease_time is not none %}
-{% if subnet_config.lease_time.default is defined and subnet_config.lease_time.default is not none %}
- default-lease-time {{ subnet_config.lease_time.default }};
-{% endif %}
-{% if subnet_config.lease_time.maximum is defined and subnet_config.lease_time.maximum is not none %}
- max-lease-time {{ subnet_config.lease_time.maximum }};
-{% endif %}
-{% if subnet_config.lease_time.minimum is defined and subnet_config.lease_time.minimum is not none %}
- min-lease-time {{ subnet_config.lease_time.minimum }};
-{% endif %}
-{% endif %}
-{% if subnet_config.name_server is defined and subnet_config.name_server is not none %}
- option dhcp6.name-servers {{ subnet_config.name_server | join(', ') }};
-{% endif %}
-{% if subnet_config.nis_domain is defined and subnet_config.nis_domain is not none %}
- option dhcp6.nis-domain-name "{{ subnet_config.nis_domain }}";
-{% endif %}
-{% if subnet_config.nis_server is defined and subnet_config.nis_server is not none %}
- option dhcp6.nis-servers {{ subnet_config.nis_server | join(', ') }};
-{% endif %}
-{% if subnet_config.nisplus_domain is defined and subnet_config.nisplus_domain is not none %}
- option dhcp6.nisp-domain-name "{{ subnet_config.nisplus_domain }}";
-{% endif %}
-{% if subnet_config.nisplus_server is defined and subnet_config.nisplus_server is not none %}
- option dhcp6.nisp-servers {{ subnet_config.nisplus_server | join(', ') }};
-{% endif %}
-{% if subnet_config.sip_server is defined and subnet_config.sip_server is not none %}
-{% set server_ip = [] %}
-{% set server_fqdn = [] %}
-{% for address in subnet_config.sip_server %}
-{% if address | is_ipv6 %}
-{% set server_ip = server_ip.append(address) %}
-{% else %}
-{% set server_fqdn = server_fqdn.append(address) %}
-{% endif %}
-{% endfor %}
-{% if server_ip is defined and server_ip | length > 0 %}
- option dhcp6.sip-servers-addresses {{ server_ip | join(', ') }};
-{% endif %}
-{% if server_fqdn is defined and server_fqdn | length > 0 %}
- option dhcp6.sip-servers-names "{{ server_fqdn | join('", "') }}";
-{% endif %}
-{% endif %}
-{% if subnet_config.sntp_server is defined and subnet_config.sntp_server is not none %}
- option dhcp6.sntp-servers {{ subnet_config.sntp_server | join(', ') }};
-{% endif %}
-{% if subnet_config.prefix_delegation is defined and subnet_config.prefix_delegation.start is defined and subnet_config.prefix_delegation.start is not none %}
-{% for prefix, prefix_config in subnet_config.prefix_delegation.start.items() %}
- prefix6 {{ prefix }} {{ prefix_config.stop }} /{{ prefix_config.prefix_length }};
-{% endfor %}
-{% endif %}
-{% if subnet_config.static_mapping is defined and subnet_config.static_mapping is not none %}
-
- # begin configuration of static client mappings
-{% for host, host_config in subnet_config.static_mapping.items() if host_config.disable is not defined %}
- host {{ network | replace('_','-') }}_{{ host | replace('_','-') }} {
-{% if host_config.identifier is defined and host_config.identifier is not none %}
- host-identifier option dhcp6.client-id {{ host_config.identifier }};
-{% endif %}
-{% if host_config.ipv6_address is defined and host_config.ipv6_address is not none %}
- fixed-address6 {{ host_config.ipv6_address }};
-{% endif %}
-{% if host_config.ipv6_prefix is defined and host_config.ipv6_prefix is not none %}
- fixed-prefix6 {{ host_config.ipv6_prefix }};
-{% endif %}
- }
-{% endfor %}
-{% endif %}
- }
-{% endfor %}
-{% endif %}
- on commit {
- set shared-networkname = "{{ network | replace('_','-') }}";
- }
-}
-{% endfor %}
-{% endif %}
diff --git a/data/templates/dns-forwarding/recursor.conf.tmpl b/data/templates/dns-forwarding/recursor.conf.j2
index d44f756e8..c1950e1bc 100644
--- a/data/templates/dns-forwarding/recursor.conf.tmpl
+++ b/data/templates/dns-forwarding/recursor.conf.j2
@@ -1,3 +1,4 @@
+{# j2lint: disable=single-statement-per-line #}
### Autogenerated by dns_forwarding.py ###
# XXX: pdns recursor doesn't like whitespace near entry separators,
@@ -19,8 +20,11 @@ max-cache-entries={{ cache_size }}
# negative TTL for NXDOMAIN
max-negative-ttl={{ negative_ttl }}
+# timeout
+network-timeout={{ timeout }}
+
# ignore-hosts-file
-export-etc-hosts={{ 'no' if ignore_hosts_file is defined else 'yes' }}
+export-etc-hosts={{ 'no' if ignore_hosts_file is vyos_defined else 'yes' }}
# listen-address
local-address={{ listen_address | join(',') }}
@@ -29,7 +33,10 @@ local-address={{ listen_address | join(',') }}
dnssec={{ dnssec }}
# serve rfc1918 records
-serve-rfc1918={{ 'no' if no_serve_rfc1918 is defined else 'yes' }}
+serve-rfc1918={{ 'no' if no_serve_rfc1918 is vyos_defined else 'yes' }}
+
+# zones
+auth-zones={% for z in authoritative_zones %}{{ z.name }}={{ z.file }}{{- "," if not loop.last -}}{% endfor %}
forward-zones-file=recursor.forward-zones.conf
diff --git a/data/templates/dns-forwarding/recursor.conf.lua.tmpl b/data/templates/dns-forwarding/recursor.conf.lua.j2
index e2506238d..e2506238d 100644
--- a/data/templates/dns-forwarding/recursor.conf.lua.tmpl
+++ b/data/templates/dns-forwarding/recursor.conf.lua.j2
diff --git a/data/templates/dns-forwarding/recursor.forward-zones.conf.tmpl b/data/templates/dns-forwarding/recursor.forward-zones.conf.j2
index 3ab0c804d..de3269e47 100644
--- a/data/templates/dns-forwarding/recursor.forward-zones.conf.tmpl
+++ b/data/templates/dns-forwarding/recursor.forward-zones.conf.j2
@@ -1,3 +1,4 @@
+{# j2lint: disable=operator-enclosed-by-spaces #}
# Autogenerated by VyOS (vyos-hostsd)
# Do not edit, your changes will get overwritten
@@ -7,11 +8,11 @@
{# the order of tags, then by the order of nameservers within that tag #}
{% set n = namespace(dot_zone_ns='') %}
{% for tag in name_server_tags_recursor %}
-{% set ns = '' %}
-{% if tag in name_servers %}
-{% set ns = ns + name_servers[tag]|join(', ') %}
-{% set n.dot_zone_ns = (n.dot_zone_ns, ns)|join(', ') if n.dot_zone_ns != '' else ns %}
-{% endif %}
+{% set ns = '' %}
+{% if tag in name_servers %}
+{% set ns = ns + name_servers[tag] | join(', ') %}
+{% set n.dot_zone_ns = (n.dot_zone_ns, ns) | join(', ') if n.dot_zone_ns != '' else ns %}
+{% endif %}
# {{ tag }}: {{ ns }}
{% endfor %}
@@ -19,10 +20,10 @@
+.={{ n.dot_zone_ns }}
{% endif %}
-{% if forward_zones is defined %}
+{% if forward_zones is vyos_defined %}
# zones added via 'service dns forwarding domain'
-{% for zone, zonedata in forward_zones.items() %}
-{{ "+" if zonedata['recursion_desired'] is defined }}{{ zone | replace('_', '-') }}={{ zonedata['server']|join(', ') }}
-{% endfor %}
+{% for zone, zonedata in forward_zones.items() %}
+{{ "+" if zonedata.recursion_desired is vyos_defined }}{{ zone | replace('_', '-') }}={{ zonedata.server | join(', ') }}
+{% endfor %}
{% endif %}
diff --git a/data/templates/dns-forwarding/recursor.vyos-hostsd.conf.lua.j2 b/data/templates/dns-forwarding/recursor.vyos-hostsd.conf.lua.j2
new file mode 100644
index 000000000..987c7de1f
--- /dev/null
+++ b/data/templates/dns-forwarding/recursor.vyos-hostsd.conf.lua.j2
@@ -0,0 +1,30 @@
+-- Autogenerated by VyOS (vyos-hostsd) --
+-- Do not edit, your changes will get overwritten --
+
+{% if hosts %}
+-- from 'system static-host-mapping' and DHCP server
+{% for tag, taghosts in hosts.items() %}
+{% for host, hostprops in taghosts.items() %}
+addNTA("{{ host }}.", "{{ tag }}")
+{% for a in hostprops['aliases'] %}
+addNTA("{{ a }}.", "{{ tag }} alias")
+{% endfor %}
+{% endfor %}
+{% endfor %}
+{% endif %}
+
+{% if forward_zones is vyos_defined %}
+-- from 'service dns forwarding domain'
+{% for zone, zonedata in forward_zones.items() %}
+{% if zonedata.addnta is vyos_defined %}
+addNTA("{{ zone }}", "static")
+{% endif %}
+{% endfor %}
+{% endif %}
+
+{% if authoritative_zones is vyos_defined %}
+-- from 'service dns forwarding authoritative-domain'
+{% for zone in authoritative_zones %}
+addNTA("{{ zone }}", "static")
+{% endfor %}
+{% endif %}
diff --git a/data/templates/dns-forwarding/recursor.vyos-hostsd.conf.lua.tmpl b/data/templates/dns-forwarding/recursor.vyos-hostsd.conf.lua.tmpl
deleted file mode 100644
index 784d5c360..000000000
--- a/data/templates/dns-forwarding/recursor.vyos-hostsd.conf.lua.tmpl
+++ /dev/null
@@ -1,24 +0,0 @@
--- Autogenerated by VyOS (vyos-hostsd) --
--- Do not edit, your changes will get overwritten --
-
-{% if hosts %}
--- from 'system static-host-mapping' and DHCP server
-{% for tag, taghosts in hosts.items() %}
-{% for host, hostprops in taghosts.items() %}
-addNTA("{{ host }}.", "{{ tag }}")
-{% for a in hostprops['aliases'] %}
-addNTA("{{ a }}.", "{{ tag }} alias")
-{% endfor %}
-{% endfor %}
-{% endfor %}
-{% endif %}
-
-{% if forward_zones is defined %}
--- from 'service dns forwarding domain'
-{% for zone, zonedata in forward_zones.items() %}
-{% if zonedata['addnta'] is defined %}
-addNTA("{{ zone }}", "static")
-{% endif %}
-{% endfor %}
-{% endif %}
-
diff --git a/data/templates/dns-forwarding/recursor.zone.conf.j2 b/data/templates/dns-forwarding/recursor.zone.conf.j2
new file mode 100644
index 000000000..25193c2ec
--- /dev/null
+++ b/data/templates/dns-forwarding/recursor.zone.conf.j2
@@ -0,0 +1,6 @@
+;
+; Autogenerated by dns_forwarding.py
+;
+{% for r in records %}
+{{ r.name }} {{ r.ttl }} {{ r.type }} {{ r.value }}
+{% endfor %}
diff --git a/data/templates/dynamic-dns/ddclient.conf.j2 b/data/templates/dynamic-dns/ddclient.conf.j2
new file mode 100644
index 000000000..3c2d17cbb
--- /dev/null
+++ b/data/templates/dynamic-dns/ddclient.conf.j2
@@ -0,0 +1,51 @@
+### Autogenerated by dynamic_dns.py ###
+daemon=1m
+syslog=yes
+ssl=yes
+
+{% if interface is vyos_defined %}
+{% for iface, iface_config in interface.items() %}
+# ddclient configuration for interface "{{ iface }}"
+{% if iface_config.use_web is vyos_defined %}
+{% set web_skip = ", web-skip='" ~ iface_config.use_web.skip ~ "'" if iface_config.use_web.skip is vyos_defined else '' %}
+use=web, web='{{ iface_config.use_web.url }}'{{ web_skip }}
+{% else %}
+{{ 'usev6=if' if iface_config.ipv6_enable is vyos_defined else 'use=if' }}, if={{ iface }}
+{% endif %}
+
+{% if iface_config.rfc2136 is vyos_defined %}
+{% for rfc2136, config in iface_config.rfc2136.items() %}
+{% for dns_record in config.record if config.record is vyos_defined %}
+# RFC2136 dynamic DNS configuration for {{ rfc2136 }}, {{ config.zone }}, {{ dns_record }}
+server={{ config.server }}
+protocol=nsupdate
+password={{ config.key }}
+ttl={{ config.ttl }}
+zone={{ config.zone }}
+{{ dns_record }}
+
+{% endfor %}
+{% endfor %}
+{% endif %}
+
+{% if iface_config.service is vyos_defined %}
+{% for service, config in iface_config.service.items() %}
+{% for dns_record in config.host_name %}
+# DynDNS provider configuration for {{ service }}, {{ dns_record }}
+protocol={{ config.protocol }},
+max-interval=28d,
+login={{ config.login }},
+password='{{ config.password }}',
+{% if config.server is vyos_defined %}
+server={{ config.server }},
+{% endif %}
+{% if config.zone is vyos_defined %}
+zone={{ config.zone }},
+{% endif %}
+{{ dns_record }}
+
+{% endfor %}
+{% endfor %}
+{% endif %}
+{% endfor %}
+{% endif %}
diff --git a/data/templates/dynamic-dns/ddclient.conf.tmpl b/data/templates/dynamic-dns/ddclient.conf.tmpl
deleted file mode 100644
index 517e4bad4..000000000
--- a/data/templates/dynamic-dns/ddclient.conf.tmpl
+++ /dev/null
@@ -1,49 +0,0 @@
-### Autogenerated by dynamic_dns.py ###
-daemon=1m
-syslog=yes
-ssl=yes
-
-{% for iface in interface %}
-# ddclient configuration for interface "{{ iface }}"
-{% if interface[iface].use_web is defined and interface[iface].use_web is not none %}
-{% set web_skip = ", web-skip='" + interface[iface].use_web.skip + "'" if interface[iface].use_web.skip is defined else '' %}
-use=web, web='{{ interface[iface].use_web.url }}'{{ web_skip }}
-{% else %}
-{{ 'usev6=if' if interface[iface].ipv6_enable is defined else 'use=if' }}, if={{ iface }}
-{% endif %}
-
-{% if interface[iface].rfc2136 is defined and interface[iface].rfc2136 is not none %}
-{% for rfc2136, config in interface[iface].rfc2136.items() %}
-{% for dns_record in config.record if config.record is defined %}
-# RFC2136 dynamic DNS configuration for {{ rfc2136 }}, {{ config.zone }}, {{ dns_record }}
-server={{ config.server }}
-protocol=nsupdate
-password={{ config.key }}
-ttl={{ config.ttl }}
-zone={{ config.zone }}
-{{ dns_record }}
-
-{% endfor %}
-{% endfor %}
-{% endif %}
-
-{% if interface[iface].service is defined and interface[iface].service is not none %}
-{% for service, config in interface[iface].service.items() %}
-{% for dns_record in config.host_name %}
-# DynDNS provider configuration for {{ service }}, {{ dns_record }}
-protocol={{ config.protocol }},
-max-interval=28d,
-login={{ config.login }},
-password='{{ config.password }}',
-{% if config.server %}
-server={{ config.server }},
-{% endif %}
-{% if config.zone %}
-zone={{ config.zone }},
-{% endif %}
-{{ dns_record }}
-
-{% endfor %}
-{% endfor %}
-{% endif %}
-{% endfor %}
diff --git a/data/templates/ethernet/wpa_supplicant.conf.tmpl b/data/templates/ethernet/wpa_supplicant.conf.j2
index 308d777f1..8f140f6cb 100644
--- a/data/templates/ethernet/wpa_supplicant.conf.tmpl
+++ b/data/templates/ethernet/wpa_supplicant.conf.j2
@@ -31,19 +31,19 @@ ap_scan=0
fast_reauth=1
network={
-{% if eapol is defined and eapol is not none %}
-{% if eapol.ca_certificate is defined and eapol.ca_certificate is not none %}
+{% if eapol is vyos_defined %}
+{% if eapol.ca_certificate is vyos_defined %}
ca_cert="/run/wpa_supplicant/{{ ifname }}_ca.pem"
-{% endif %}
+{% endif %}
client_cert="/run/wpa_supplicant/{{ ifname }}_cert.pem"
private_key="/run/wpa_supplicant/{{ ifname }}_cert.key"
-{% endif %}
+{% endif %}
# list of accepted authenticated key management protocols
key_mgmt=IEEE8021X
eap=TLS
-{% if mac is defined and mac is not none %}
+{% if mac is vyos_defined %}
identity="{{ mac }}"
{% else %}
identity="{{ hw_id }}"
diff --git a/data/templates/firewall/nftables-defines.j2 b/data/templates/firewall/nftables-defines.j2
new file mode 100644
index 000000000..4fa92f2e3
--- /dev/null
+++ b/data/templates/firewall/nftables-defines.j2
@@ -0,0 +1,32 @@
+{% if group is vyos_defined %}
+{% if group.address_group is vyos_defined %}
+{% for group_name, group_conf in group.address_group.items() %}
+define A_{{ group_name }} = { {{ group_conf.address | join(",") }} }
+{% endfor %}
+{% endif %}
+{% if group.ipv6_address_group is vyos_defined %}
+{% for group_name, group_conf in group.ipv6_address_group.items() %}
+define A6_{{ group_name }} = { {{ group_conf.address | join(",") }} }
+{% endfor %}
+{% endif %}
+{% if group.mac_group is vyos_defined %}
+{% for group_name, group_conf in group.mac_group.items() %}
+define M_{{ group_name }} = { {{ group_conf.mac_address | join(",") }} }
+{% endfor %}
+{% endif %}
+{% if group.network_group is vyos_defined %}
+{% for group_name, group_conf in group.network_group.items() %}
+define N_{{ group_name }} = { {{ group_conf.network | join(",") }} }
+{% endfor %}
+{% endif %}
+{% if group.ipv6_network_group is vyos_defined %}
+{% for group_name, group_conf in group.ipv6_network_group.items() %}
+define N6_{{ group_name }} = { {{ group_conf.network | join(",") }} }
+{% endfor %}
+{% endif %}
+{% if group.port_group is vyos_defined %}
+{% for group_name, group_conf in group.port_group.items() %}
+define P_{{ group_name }} = { {{ group_conf.port | join(",") }} }
+{% endfor %}
+{% endif %}
+{% endif %} \ No newline at end of file
diff --git a/data/templates/firewall/nftables-nat.j2 b/data/templates/firewall/nftables-nat.j2
new file mode 100644
index 000000000..1481e9104
--- /dev/null
+++ b/data/templates/firewall/nftables-nat.j2
@@ -0,0 +1,182 @@
+#!/usr/sbin/nft -f
+
+{% macro nat_rule(rule, config, chain) %}
+{% set comment = '' %}
+{% set base_log = '' %}
+{% set src_addr = 'ip saddr ' ~ config.source.address.replace('!','!= ') if config.source.address is vyos_defined %}
+{% set dst_addr = 'ip daddr ' ~ config.destination.address.replace('!','!= ') if config.destination.address is vyos_defined %}
+{# negated port groups need special treatment, move != in front of { } group #}
+{% if config.source.port is vyos_defined and config.source.port.startswith('!') %}
+{% set src_port = 'sport != { ' ~ config.source.port.replace('!','') ~ ' }' %}
+{% else %}
+{% set src_port = 'sport { ' ~ config.source.port ~ ' }' if config.source.port is vyos_defined %}
+{% endif %}
+{# negated port groups need special treatment, move != in front of { } group #}
+{% if config.destination.port is vyos_defined and config.destination.port.startswith('!') %}
+{% set dst_port = 'dport != { ' ~ config.destination.port.replace('!','') ~ ' }' %}
+{% else %}
+{% set dst_port = 'dport { ' ~ config.destination.port ~ ' }' if config.destination.port is vyos_defined %}
+{% endif %}
+{% if chain is vyos_defined('PREROUTING') %}
+{% set comment = 'DST-NAT-' ~ rule %}
+{% set base_log = '[NAT-DST-' ~ rule %}
+{% set interface = ' iifname "' ~ config.inbound_interface ~ '"' if config.inbound_interface is vyos_defined and config.inbound_interface is not vyos_defined('any') else '' %}
+{% if config.translation.address is vyos_defined %}
+{# support 1:1 network translation #}
+{% if config.translation.address | is_ip_network %}
+{% set trns_addr = 'dnat ip prefix to ip daddr map { ' ~ config.destination.address ~ ' : ' ~ config.translation.address ~ ' }' %}
+{# we can now clear out the dst_addr part as it's already covered in aboves map #}
+{% set dst_addr = '' %}
+{% else %}
+{% set trns_addr = 'dnat to ' ~ config.translation.address %}
+{% endif %}
+{% endif %}
+{% elif chain is vyos_defined('POSTROUTING') %}
+{% set comment = 'SRC-NAT-' ~ rule %}
+{% set base_log = '[NAT-SRC-' ~ rule %}
+{% set interface = ' oifname "' ~ config.outbound_interface ~ '"' if config.outbound_interface is vyos_defined and config.outbound_interface is not vyos_defined('any') else '' %}
+{% if config.translation.address is vyos_defined %}
+{% if config.translation.address is vyos_defined('masquerade') %}
+{% set trns_addr = config.translation.address %}
+{% if config.translation.port is vyos_defined %}
+{% set trns_addr = trns_addr ~ ' to ' %}
+{% endif %}
+{# support 1:1 network translation #}
+{% elif config.translation.address | is_ip_network %}
+{% set trns_addr = 'snat ip prefix to ip saddr map { ' ~ config.source.address ~ ' : ' ~ config.translation.address ~ ' }' %}
+{# we can now clear out the src_addr part as it's already covered in aboves map #}
+{% set src_addr = '' %}
+{% else %}
+{% set trns_addr = 'snat to ' ~ config.translation.address %}
+{% endif %}
+{% endif %}
+{% endif %}
+{% set trns_port = ':' ~ config.translation.port if config.translation.port is vyos_defined %}
+{# protocol has a default value thus it is always present #}
+{% if config.protocol is vyos_defined('tcp_udp') %}
+{% set protocol = 'tcp' %}
+{% set comment = comment ~ ' tcp_udp' %}
+{% else %}
+{% set protocol = config.protocol %}
+{% endif %}
+{% if config.log is vyos_defined %}
+{% if config.exclude is vyos_defined %}
+{% set log = base_log ~ '-EXCL]' %}
+{% elif config.translation.address is vyos_defined('masquerade') %}
+{% set log = base_log ~ '-MASQ]' %}
+{% else %}
+{% set log = base_log ~ ']' %}
+{% endif %}
+{% endif %}
+{% if config.exclude is vyos_defined %}
+{# rule has been marked as 'exclude' thus we simply return here #}
+{% set trns_addr = 'return' %}
+{% set trns_port = '' %}
+{% endif %}
+{# T1083: NAT address and port translation options #}
+{% if config.translation.options is vyos_defined %}
+{% if config.translation.options.address_mapping is vyos_defined('persistent') %}
+{% set trns_opts_addr = 'persistent' %}
+{% endif %}
+{% if config.translation.options.port_mapping is vyos_defined('random') %}
+{% set trns_opts_port = 'random' %}
+{% elif config.translation.options.port_mapping is vyos_defined('fully-random') %}
+{% set trns_opts_port = 'fully-random' %}
+{% endif %}
+{% endif %}
+{% if trns_opts_addr is vyos_defined and trns_opts_port is vyos_defined %}
+{% set trns_opts = trns_opts_addr ~ ',' ~ trns_opts_port %}
+{% elif trns_opts_addr is vyos_defined %}
+{% set trns_opts = trns_opts_addr %}
+{% elif trns_opts_port is vyos_defined %}
+{% set trns_opts = trns_opts_port %}
+{% endif %}
+{% set output = 'add rule ip nat ' ~ chain ~ interface %}
+{% if protocol is not vyos_defined('all') %}
+{% set output = output ~ ' ip protocol ' ~ protocol %}
+{% endif %}
+{% if src_addr is vyos_defined %}
+{% set output = output ~ ' ' ~ src_addr %}
+{% endif %}
+{% if src_port is vyos_defined %}
+{% set output = output ~ ' ' ~ protocol ~ ' ' ~ src_port %}
+{% endif %}
+{% if dst_addr is vyos_defined %}
+{% set output = output ~ ' ' ~ dst_addr %}
+{% endif %}
+{% if dst_port is vyos_defined %}
+{% set output = output ~ ' ' ~ protocol ~ ' ' ~ dst_port %}
+{% endif %}
+{# Count packets #}
+{% set output = output ~ ' counter' %}
+{# Special handling of log option, we must repeat the entire rule before the #}
+{# NAT translation options are added, this is essential #}
+{% if log is vyos_defined %}
+{% set log_output = output ~ ' log prefix "' ~ log ~ '" comment "' ~ comment ~ '"' %}
+{% endif %}
+{% if trns_addr is vyos_defined %}
+{% set output = output ~ ' ' ~ trns_addr %}
+{% endif %}
+{% if trns_port is vyos_defined %}
+{# Do not add a whitespace here, translation port must be directly added after IP address #}
+{# e.g. 192.0.2.10:3389 #}
+{% set output = output ~ trns_port %}
+{% endif %}
+{% if trns_opts is vyos_defined %}
+{% set output = output ~ ' ' ~ trns_opts %}
+{% endif %}
+{% if comment is vyos_defined %}
+{% set output = output ~ ' comment "' ~ comment ~ '"' %}
+{% endif %}
+{{ log_output if log_output is vyos_defined }}
+{{ output }}
+{# Special handling if protocol is tcp_udp, we must repeat the entire rule with udp as protocol #}
+{% if config.protocol is vyos_defined('tcp_udp') %}
+{# Beware of trailing whitespace, without it the comment tcp_udp will be changed to udp_udp #}
+{{ log_output | replace('tcp ', 'udp ') if log_output is vyos_defined }}
+{{ output | replace('tcp ', 'udp ') }}
+{% endif %}
+{% endmacro %}
+
+# Start with clean SNAT and DNAT chains
+flush chain ip nat PREROUTING
+flush chain ip nat POSTROUTING
+{% if helper_functions is vyos_defined('remove') %}
+{# NAT if going to be disabled - remove rules and targets from nftables #}
+{% set base_command = 'delete rule ip raw' %}
+{{ base_command }} PREROUTING handle {{ pre_ct_ignore }}
+{{ base_command }} OUTPUT handle {{ out_ct_ignore }}
+{{ base_command }} PREROUTING handle {{ pre_ct_conntrack }}
+{{ base_command }} OUTPUT handle {{ out_ct_conntrack }}
+
+delete chain ip raw NAT_CONNTRACK
+
+{% elif helper_functions is vyos_defined('add') %}
+{# NAT if enabled - add targets to nftables #}
+add chain ip raw NAT_CONNTRACK
+add rule ip raw NAT_CONNTRACK counter accept
+{% set base_command = 'add rule ip raw' %}
+{{ base_command }} PREROUTING position {{ pre_ct_ignore }} counter jump VYOS_CT_HELPER
+{{ base_command }} OUTPUT position {{ out_ct_ignore }} counter jump VYOS_CT_HELPER
+{{ base_command }} PREROUTING position {{ pre_ct_conntrack }} counter jump NAT_CONNTRACK
+{{ base_command }} OUTPUT position {{ out_ct_conntrack }} counter jump NAT_CONNTRACK
+{% endif %}
+
+#
+# Destination NAT rules build up here
+#
+add rule ip nat PREROUTING counter jump VYOS_PRE_DNAT_HOOK
+{% if destination.rule is vyos_defined %}
+{% for rule, config in destination.rule.items() if config.disable is not vyos_defined %}
+{{ nat_rule(rule, config, 'PREROUTING') }}
+{% endfor %}
+{% endif %}
+#
+# Source NAT rules build up here
+#
+add rule ip nat POSTROUTING counter jump VYOS_PRE_SNAT_HOOK
+{% if source.rule is vyos_defined %}
+{% for rule, config in source.rule.items() if config.disable is not vyos_defined %}
+{{ nat_rule(rule, config, 'POSTROUTING') }}
+{% endfor %}
+{% endif %}
diff --git a/data/templates/firewall/nftables-nat.tmpl b/data/templates/firewall/nftables-nat.tmpl
deleted file mode 100644
index 40ed1b916..000000000
--- a/data/templates/firewall/nftables-nat.tmpl
+++ /dev/null
@@ -1,181 +0,0 @@
-#!/usr/sbin/nft -f
-
-{% macro nat_rule(rule, config, chain) %}
-{% set comment = '' %}
-{% set base_log = '' %}
-{% set src_addr = 'ip saddr ' + config.source.address.replace('!','!= ') if config.source is defined and config.source.address is defined and config.source.address is not none %}
-{% set dst_addr = 'ip daddr ' + config.destination.address.replace('!','!= ') if config.destination is defined and config.destination.address is defined and config.destination.address is not none %}
-{# negated port groups need special treatment, move != in front of { } group #}
-{% if config.source is defined and config.source.port is defined and config.source.port is not none and config.source.port.startswith('!=') %}
-{% set src_port = 'sport != { ' + config.source.port.replace('!=','') + ' }' %}
-{% else %}
-{% set src_port = 'sport { ' + config.source.port + ' }' if config.source is defined and config.source.port is defined and config.source.port is not none %}
-{% endif %}
-{# negated port groups need special treatment, move != in front of { } group #}
-{% if config.destination is defined and config.destination.port is defined and config.destination.port is not none and config.destination.port.startswith('!=') %}
-{% set dst_port = 'dport != { ' + config.destination.port.replace('!=','') + ' }' %}
-{% else %}
-{% set dst_port = 'dport { ' + config.destination.port + ' }' if config.destination is defined and config.destination.port is defined and config.destination.port is not none %}
-{% endif %}
-{% if chain == 'PREROUTING' %}
-{% set comment = 'DST-NAT-' + rule %}
-{% set base_log = '[NAT-DST-' + rule %}
-{% set interface = ' iifname "' + config.inbound_interface + '"' if config.inbound_interface is defined and config.inbound_interface != 'any' else '' %}
-{% if config.translation is defined and config.translation.address is defined and config.translation.address is not none %}
-{# support 1:1 network translation #}
-{% if config.translation.address | is_ip_network %}
-{% set trns_addr = 'dnat ip prefix to ip daddr map { ' + config.destination.address + ' : ' + config.translation.address + ' }' %}
-{# we can now clear out the dst_addr part as it's already covered in aboves map #}
-{% set dst_addr = '' %}
-{% else %}
-{% set trns_addr = 'dnat to ' + config.translation.address %}
-{% endif %}
-{% endif %}
-{% elif chain == 'POSTROUTING' %}
-{% set comment = 'SRC-NAT-' + rule %}
-{% set base_log = '[NAT-SRC-' + rule %}
-{% set interface = ' oifname "' + config.outbound_interface + '"' if config.outbound_interface is defined and config.outbound_interface != 'any' else '' %}
-{% if config.translation is defined and config.translation.address is defined and config.translation.address is not none %}
-{% if config.translation.address == 'masquerade' %}
-{% set trns_addr = config.translation.address %}
-{% if config.translation.port is defined and config.translation.port is not none %}
-{% set trns_addr = trns_addr + ' to ' %}
-{% endif %}
-{# support 1:1 network translation #}
-{% elif config.translation.address | is_ip_network %}
-{% set trns_addr = 'snat ip prefix to ip saddr map { ' + config.source.address + ' : ' + config.translation.address + ' }' %}
-{# we can now clear out the src_addr part as it's already covered in aboves map #}
-{% set src_addr = '' %}
-{% else %}
-{% set trns_addr = 'snat to ' + config.translation.address %}
-{% endif %}
-{% endif %}
-{% endif %}
-{% set trns_port = ':' + config.translation.port if config.translation is defined and config.translation.port is defined and config.translation.port is not none %}
-{# protocol has a default value thus it is always present #}
-{% if config.protocol == 'tcp_udp' %}
-{% set protocol = 'tcp' %}
-{% set comment = comment + ' tcp_udp' %}
-{% else %}
-{% set protocol = config.protocol %}
-{% endif %}
-{% if config.log is defined %}
-{% if config.exclude is defined %}
-{% set log = base_log + '-EXCL]' %}
-{% elif config.translation is defined and config.translation.address is defined and config.translation.address == 'masquerade' %}
-{% set log = base_log +'-MASQ]' %}
-{% else %}
-{% set log = base_log + ']' %}
-{% endif %}
-{% endif %}
-{% if config.exclude is defined %}
-{# rule has been marked as 'exclude' thus we simply return here #}
-{% set trns_addr = 'return' %}
-{% set trns_port = '' %}
-{% endif %}
-{# T1083: NAT address and port translation options #}
-{% if config.translation is defined and config.translation.options is defined and config.translation.options is not none %}
-{% if config.translation.options.address_mapping is defined and config.translation.options.address_mapping == "persistent" %}
-{% set trns_opts_addr = 'persistent' %}
-{% endif %}
-{% if config.translation.options.port_mapping is defined %}
-{% if config.translation.options.port_mapping == "random" %}
-{% set trns_opts_port = 'random' %}
-{% elif config.translation.options.port_mapping == "fully-random" %}
-{% set trns_opts_port = 'fully-random' %}
-{% endif %}
-{% endif %}
-{% endif %}
-{% if trns_opts_addr and trns_opts_port %}
-{% set trns_opts = trns_opts_addr + ',' + trns_opts_port %}
-{% elif trns_opts_addr %}
-{% set trns_opts = trns_opts_addr %}
-{% elif trns_opts_port %}
-{% set trns_opts = trns_opts_port %}
-{% endif %}
-{% set output = 'add rule ip nat ' + chain + interface %}
-{% if protocol != 'all' %}
-{% set output = output + ' ip protocol ' + protocol %}
-{% endif %}
-{% if src_addr %}
-{% set output = output + ' ' + src_addr %}
-{% endif %}
-{% if src_port %}
-{% set output = output + ' ' + protocol + ' ' + src_port %}
-{% endif %}
-{% if dst_addr %}
-{% set output = output + ' ' + dst_addr %}
-{% endif %}
-{% if dst_port %}
-{% set output = output + ' ' + protocol + ' ' + dst_port %}
-{% endif %}
-{# Count packets #}
-{% set output = output + ' counter' %}
-{# Special handling of log option, we must repeat the entire rule before the #}
-{# NAT translation options are added, this is essential #}
-{% if log %}
-{% set log_output = output + ' log prefix "' + log + '" comment "' + comment + '"' %}
-{% endif %}
-{% if trns_addr %}
-{% set output = output + ' ' + trns_addr %}
-{% endif %}
-{% if trns_port %}
-{# Do not add a whitespace here, translation port must be directly added after IP address #}
-{# e.g. 192.0.2.10:3389 #}
-{% set output = output + trns_port %}
-{% endif %}
-{% if trns_opts %}
-{% set output = output + ' ' + trns_opts %}
-{% endif %}
-{% if comment %}
-{% set output = output + ' comment "' + comment + '"' %}
-{% endif %}
-{{ log_output if log_output }}
-{{ output }}
-{# Special handling if protocol is tcp_udp, we must repeat the entire rule with udp as protocol #}
-{% if config.protocol == 'tcp_udp' %}
-{# Beware of trailing whitespace, without it the comment tcp_udp will be changed to udp_udp #}
-{{ log_output | replace('tcp ', 'udp ') if log_output }}
-{{ output | replace('tcp ', 'udp ') }}
-{% endif %}
-{% endmacro %}
-
-# Start with clean NAT table
-flush table ip nat
-{% if helper_functions == 'remove' %}
-{# NAT if going to be disabled - remove rules and targets from nftables #}
-{% set base_command = 'delete rule ip raw' %}
-{{ base_command }} PREROUTING handle {{ pre_ct_ignore }}
-{{ base_command }} OUTPUT handle {{ out_ct_ignore }}
-{{ base_command }} PREROUTING handle {{ pre_ct_conntrack }}
-{{ base_command }} OUTPUT handle {{ out_ct_conntrack }}
-
-delete chain ip raw NAT_CONNTRACK
-
-{% elif helper_functions == 'add' %}
-{# NAT if enabled - add targets to nftables #}
-add chain ip raw NAT_CONNTRACK
-add rule ip raw NAT_CONNTRACK counter accept
-{% set base_command = 'add rule ip raw' %}
-{{ base_command }} PREROUTING position {{ pre_ct_ignore }} counter jump VYATTA_CT_HELPER
-{{ base_command }} OUTPUT position {{ out_ct_ignore }} counter jump VYATTA_CT_HELPER
-{{ base_command }} PREROUTING position {{ pre_ct_conntrack }} counter jump NAT_CONNTRACK
-{{ base_command }} OUTPUT position {{ out_ct_conntrack }} counter jump NAT_CONNTRACK
-{% endif %}
-
-#
-# Destination NAT rules build up here
-#
-{% if destination is defined and destination.rule is defined and destination.rule is not none %}
-{% for rule, config in destination.rule.items() if config.disable is not defined %}
-{{ nat_rule(rule, config, 'PREROUTING') }}
-{% endfor %}
-{% endif %}
-#
-# Source NAT rules build up here
-#
-{% if source is defined and source.rule is defined and source.rule is not none %}
-{% for rule, config in source.rule.items() if config.disable is not defined %}
-{{ nat_rule(rule, config, 'POSTROUTING') }}
-{% endfor %}
-{% endif %}
diff --git a/data/templates/firewall/nftables-nat66.j2 b/data/templates/firewall/nftables-nat66.j2
new file mode 100644
index 000000000..003b138b2
--- /dev/null
+++ b/data/templates/firewall/nftables-nat66.j2
@@ -0,0 +1,102 @@
+#!/usr/sbin/nft -f
+
+{% macro nptv6_rule(rule,config, chain) %}
+{% set comment = '' %}
+{% set base_log = '' %}
+{% set src_prefix = 'ip6 saddr ' ~ config.source.prefix if config.source.prefix is vyos_defined %}
+{% set dest_address = 'ip6 daddr ' ~ config.destination.address if config.destination.address is vyos_defined %}
+{% if chain is vyos_defined('PREROUTING') %}
+{% set comment = 'DST-NAT66-' ~ rule %}
+{% set base_log = '[NAT66-DST-' ~ rule %}
+{% set interface = ' iifname "' ~ config.inbound_interface ~ '"' if config.inbound_interface is vyos_defined and config.inbound_interface is not vyos_defined('any') else '' %}
+{% if config.translation.address | is_ip_network %}
+{# support 1:1 network translation #}
+{% set dnat_type = 'dnat prefix to ' %}
+{% else %}
+{% set dnat_type = 'dnat to ' %}
+{% endif %}
+{% set trns_address = dnat_type ~ config.translation.address if config.translation.address is vyos_defined %}
+{% elif chain is vyos_defined('POSTROUTING') %}
+{% set comment = 'SRC-NAT66-' ~ rule %}
+{% set base_log = '[NAT66-SRC-' ~ rule %}
+{% if config.translation.address is vyos_defined %}
+{% if config.translation.address is vyos_defined('masquerade') %}
+{% set trns_address = config.translation.address %}
+{% else %}
+{% if config.translation.address | is_ip_network %}
+{# support 1:1 network translation #}
+{% set snat_type = 'snat prefix to ' %}
+{% else %}
+{% set snat_type = 'snat to ' %}
+{% endif %}
+{% set trns_address = snat_type ~ config.translation.address %}
+{% endif %}
+{% endif %}
+{% set interface = ' oifname "' ~ config.outbound_interface ~ '"' if config.outbound_interface is vyos_defined else '' %}
+{% endif %}
+{% if config.log is vyos_defined %}
+{% if config.translation.address is vyos_defined('masquerade') %}
+{% set log = base_log ~ '-MASQ]' %}
+{% else %}
+{% set log = base_log ~ ']' %}
+{% endif %}
+{% endif %}
+{% set output = 'add rule ip6 nat ' ~ chain ~ interface %}
+{# Count packets #}
+{% set output = output ~ ' counter' %}
+{# Special handling of log option, we must repeat the entire rule before the #}
+{# NAT translation options are added, this is essential #}
+{% if log is vyos_defined %}
+{% set log_output = output ~ ' log prefix "' ~ log ~ '" comment "' ~ comment ~ '"' %}
+{% endif %}
+{% if src_prefix is vyos_defined %}
+{% set output = output ~ ' ' ~ src_prefix %}
+{% endif %}
+{% if dest_address is vyos_defined %}
+{% set output = output ~ ' ' ~ dest_address %}
+{% endif %}
+{% if trns_address is vyos_defined %}
+{% set output = output ~ ' ' ~ trns_address %}
+{% endif %}
+{% if comment is vyos_defined %}
+{% set output = output ~ ' comment "' ~ comment ~ '"' %}
+{% endif %}
+{{ log_output if log_output is vyos_defined }}
+{{ output }}
+{% endmacro %}
+
+# Start with clean NAT table
+flush table ip6 nat
+{% if helper_functions is vyos_defined('remove') %}
+{# NAT if going to be disabled - remove rules and targets from nftables #}
+{% set base_command = 'delete rule ip6 raw' %}
+{{ base_command }} PREROUTING handle {{ pre_ct_conntrack }}
+{{ base_command }} OUTPUT handle {{ out_ct_conntrack }}
+
+delete chain ip6 raw NAT_CONNTRACK
+
+{% elif helper_functions is vyos_defined('add') %}
+{# NAT if enabled - add targets to nftables #}
+add chain ip6 raw NAT_CONNTRACK
+add rule ip6 raw NAT_CONNTRACK counter accept
+{% set base_command = 'add rule ip6 raw' %}
+{{ base_command }} PREROUTING position {{ pre_ct_conntrack }} counter jump NAT_CONNTRACK
+{{ base_command }} OUTPUT position {{ out_ct_conntrack }} counter jump NAT_CONNTRACK
+{% endif %}
+
+#
+# Destination NAT66 rules build up here
+#
+{% if destination.rule is vyos_defined %}
+{% for rule, config in destination.rule.items() if config.disable is not vyos_defined %}
+{{ nptv6_rule(rule, config, 'PREROUTING') }}
+{% endfor %}
+{% endif %}
+#
+# Source NAT66 rules build up here
+#
+{% if source.rule is vyos_defined %}
+{% for rule, config in source.rule.items() if config.disable is not vyos_defined %}
+{{ nptv6_rule(rule, config, 'POSTROUTING') }}
+{% endfor %}
+{% endif %}
diff --git a/data/templates/firewall/nftables-nat66.tmpl b/data/templates/firewall/nftables-nat66.tmpl
deleted file mode 100644
index e5c1b1b8d..000000000
--- a/data/templates/firewall/nftables-nat66.tmpl
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/usr/sbin/nft -f
-
-{% macro nptv6_rule(rule,config, chain) %}
-{% set comment = '' %}
-{% set base_log = '' %}
-{% set src_prefix = "ip6 saddr " + config.source.prefix if config.source is defined and config.source.prefix is defined and config.source.prefix is not none %}
-{% set dest_address = "ip6 daddr " + config.destination.address if config.destination is defined and config.destination.address is defined and config.destination.address is not none %}
-{% if chain == "PREROUTING" %}
-{% set comment = "DST-NAT66-" + rule %}
-{% set base_log = '[NAT66-DST-' + rule %}
-{% set interface = " iifname \"" + config.inbound_interface + "\"" if config.inbound_interface is defined and config.inbound_interface != 'any' else '' %}
-{% if config.translation.address | is_ip_network %}
-{# support 1:1 network translation #}
-{% set dnat_type = "dnat prefix to " %}
-{% else %}
-{% set dnat_type = "dnat to " %}
-{% endif %}
-{% set trns_address = dnat_type + config.translation.address if config.translation is defined and config.translation.address is defined and config.translation.address is not none %}
-{% elif chain == "POSTROUTING" %}
-{% set comment = 'SRC-NAT66-' + rule %}
-{% set base_log = '[NAT66-SRC-' + rule %}
-{% if config.translation is defined and config.translation.address is defined and config.translation.address is not none %}
-{% if config.translation.address == 'masquerade' %}
-{% set trns_address = config.translation.address %}
-{% else %}
-{% if config.translation.address | is_ip_network %}
-{# support 1:1 network translation #}
-{% set snat_type = "snat prefix to " %}
-{% else %}
-{% set snat_type = "snat to " %}
-{% endif %}
-{% set trns_address = snat_type + config.translation.address %}
-{% endif %}
-{% endif %}
-{% set interface = " oifname \"" + config.outbound_interface + "\"" if config.outbound_interface is defined else '' %}
-{% endif %}
-{% if config.log is defined %}
-{% if config.translation is defined and config.translation.address is defined and config.translation.address == 'masquerade' %}
-{% set log = base_log +'-MASQ]' %}
-{% else %}
-{% set log = base_log + "]" %}
-{% endif %}
-{% endif %}
-{% set output = "add rule ip6 nat " + chain + interface %}
-{# Count packets #}
-{% set output = output + " counter" %}
-{# Special handling of log option, we must repeat the entire rule before the #}
-{# NAT translation options are added, this is essential #}
-{% if log %}
-{% set log_output = output + " log prefix \"" + log + "\" comment \"" + comment + "\"" %}
-{% endif %}
-{% if src_prefix %}
-{% set output = output + " " + src_prefix %}
-{% endif %}
-{% if dest_address %}
-{% set output = output + " " + dest_address %}
-{% endif %}
-{% if trns_address %}
-{% set output = output + " " + trns_address %}
-{% endif %}
-{% if comment %}
-{% set output = output + " comment \"" + comment + "\"" %}
-{% endif %}
-{{ log_output if log_output }}
-{{ output }}
-{% endmacro %}
-
-# Start with clean NAT table
-flush table ip6 nat
-{% if helper_functions == 'remove' %}
-{# NAT if going to be disabled - remove rules and targets from nftables #}
-{% set base_command = "delete rule ip6 raw" %}
-{{base_command}} PREROUTING handle {{ pre_ct_conntrack }}
-{{base_command}} OUTPUT handle {{ out_ct_conntrack }}
-
-delete chain ip6 raw NAT_CONNTRACK
-
-{% elif helper_functions == 'add' %}
-{# NAT if enabled - add targets to nftables #}
-add chain ip6 raw NAT_CONNTRACK
-add rule ip6 raw NAT_CONNTRACK counter accept
-{% set base_command = "add rule ip6 raw" %}
-{{ base_command }} PREROUTING position {{ pre_ct_conntrack }} counter jump NAT_CONNTRACK
-{{ base_command }} OUTPUT position {{ out_ct_conntrack }} counter jump NAT_CONNTRACK
-{% endif %}
-
-#
-# Destination NAT66 rules build up here
-#
-{% if destination is defined and destination.rule is defined and destination.rule is not none %}
-{% for rule, config in destination.rule.items() if config.disable is not defined %}
-{{ nptv6_rule(rule, config, 'PREROUTING') }}
-{% endfor %}
-{% endif %}
-#
-# Source NAT66 rules build up here
-#
-{% if source is defined and source.rule is defined and source.rule is not none %}
-{% for rule, config in source.rule.items() if config.disable is not defined %}
-{{ nptv6_rule(rule, config, 'POSTROUTING') }}
-{% endfor %}
-{% endif %}
diff --git a/data/templates/firewall/nftables-policy.j2 b/data/templates/firewall/nftables-policy.j2
new file mode 100644
index 000000000..0154c9f7e
--- /dev/null
+++ b/data/templates/firewall/nftables-policy.j2
@@ -0,0 +1,55 @@
+#!/usr/sbin/nft -f
+
+{% if cleanup_commands is vyos_defined %}
+{% for command in cleanup_commands %}
+{{ command }}
+{% endfor %}
+{% endif %}
+
+include "/run/nftables_defines.conf"
+
+table ip mangle {
+{% if first_install is vyos_defined %}
+ chain VYOS_PBR_PREROUTING {
+ type filter hook prerouting priority -150; policy accept;
+ }
+ chain VYOS_PBR_POSTROUTING {
+ type filter hook postrouting priority -150; policy accept;
+ }
+{% endif %}
+{% if route is vyos_defined %}
+{% for route_text, conf in route.items() %}
+ chain VYOS_PBR_{{ route_text }} {
+{% if conf.rule is vyos_defined %}
+{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %}
+ {{ rule_conf | nft_rule(route_text, rule_id, 'ip') }}
+{% endfor %}
+{% endif %}
+ {{ conf | nft_default_rule(route_text) }}
+ }
+{% endfor %}
+{% endif %}
+}
+
+table ip6 mangle {
+{% if first_install is vyos_defined %}
+ chain VYOS_PBR6_PREROUTING {
+ type filter hook prerouting priority -150; policy accept;
+ }
+ chain VYOS_PBR6_POSTROUTING {
+ type filter hook postrouting priority -150; policy accept;
+ }
+{% endif %}
+{% if route6 is vyos_defined %}
+{% for route_text, conf in route6.items() %}
+ chain VYOS_PBR6_{{ route_text }} {
+{% if conf.rule is vyos_defined %}
+{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %}
+ {{ rule_conf | nft_rule(route_text, rule_id, 'ip6') }}
+{% endfor %}
+{% endif %}
+ {{ conf | nft_default_rule(route_text) }}
+ }
+{% endfor %}
+{% endif %}
+}
diff --git a/data/templates/firewall/nftables-vrf-zones.tmpl b/data/templates/firewall/nftables-vrf-zones.j2
index eecf47b78..eecf47b78 100644
--- a/data/templates/firewall/nftables-vrf-zones.tmpl
+++ b/data/templates/firewall/nftables-vrf-zones.j2
diff --git a/data/templates/firewall/nftables.j2 b/data/templates/firewall/nftables.j2
new file mode 100644
index 000000000..fac3fad03
--- /dev/null
+++ b/data/templates/firewall/nftables.j2
@@ -0,0 +1,274 @@
+#!/usr/sbin/nft -f
+
+{% if cleanup_commands is vyos_defined %}
+{% for command in cleanup_commands %}
+{{ command }}
+{% endfor %}
+{% endif %}
+
+include "/run/nftables_defines.conf"
+
+table ip filter {
+{% if first_install is vyos_defined %}
+ chain VYOS_FW_FORWARD {
+ type filter hook forward priority 0; policy accept;
+ jump VYOS_POST_FW
+ }
+ chain VYOS_FW_LOCAL {
+ type filter hook input priority 0; policy accept;
+ jump VYOS_POST_FW
+ }
+ chain VYOS_FW_OUTPUT {
+ type filter hook output priority 0; policy accept;
+ jump VYOS_POST_FW
+ }
+ chain VYOS_POST_FW {
+ return
+ }
+ chain VYOS_FRAG_MARK {
+ type filter hook prerouting priority -450; policy accept;
+ ip frag-off & 0x3fff != 0 meta mark set 0xffff1 return
+ }
+{% endif %}
+{% if name is vyos_defined %}
+{% set ns = namespace(sets=[]) %}
+{% for name_text, conf in name.items() %}
+ chain NAME_{{ name_text }} {
+{% if conf.rule is vyos_defined %}
+{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %}
+ {{ rule_conf | nft_rule(name_text, rule_id) }}
+{% if rule_conf.recent is vyos_defined %}
+{% set ns.sets = ns.sets + [name_text + '_' + rule_id] %}
+{% endif %}
+{% endfor %}
+{% endif %}
+ {{ conf | nft_default_rule(name_text) }}
+ }
+{% endfor %}
+{% for set_name in ns.sets %}
+ set RECENT_{{ set_name }} {
+ type ipv4_addr
+ size 65535
+ flags dynamic
+ }
+{% endfor %}
+{% endif %}
+{% if state_policy is vyos_defined %}
+ chain VYOS_STATE_POLICY {
+{% if state_policy.established is vyos_defined %}
+ {{ state_policy.established | nft_state_policy('established') }}
+{% endif %}
+{% if state_policy.invalid is vyos_defined %}
+ {{ state_policy.invalid | nft_state_policy('invalid') }}
+{% endif %}
+{% if state_policy.related is vyos_defined %}
+ {{ state_policy.related | nft_state_policy('related') }}
+{% endif %}
+ return
+ }
+{% endif %}
+}
+
+table ip6 filter {
+{% if first_install is vyos_defined %}
+ chain VYOS_FW6_FORWARD {
+ type filter hook forward priority 0; policy accept;
+ jump VYOS_POST_FW6
+ }
+ chain VYOS_FW6_LOCAL {
+ type filter hook input priority 0; policy accept;
+ jump VYOS_POST_FW6
+ }
+ chain VYOS_FW6_OUTPUT {
+ type filter hook output priority 0; policy accept;
+ jump VYOS_POST_FW6
+ }
+ chain VYOS_POST_FW6 {
+ return
+ }
+ chain VYOS_FRAG6_MARK {
+ type filter hook prerouting priority -450; policy accept;
+ exthdr frag exists meta mark set 0xffff1 return
+ }
+{% endif %}
+{% if ipv6_name is vyos_defined %}
+{% set ns = namespace(sets=[]) %}
+{% for name_text, conf in ipv6_name.items() %}
+ chain NAME6_{{ name_text }} {
+{% if conf.rule is vyos_defined %}
+{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %}
+ {{ rule_conf | nft_rule(name_text, rule_id, 'ip6') }}
+{% if rule_conf.recent is vyos_defined %}
+{% set ns.sets = ns.sets + [name_text + '_' + rule_id] %}
+{% endif %}
+{% endfor %}
+{% endif %}
+ {{ conf | nft_default_rule(name_text) }}
+ }
+{% endfor %}
+{% for set_name in ns.sets %}
+ set RECENT6_{{ set_name }} {
+ type ipv6_addr
+ size 65535
+ flags dynamic
+ }
+{% endfor %}
+{% endif %}
+{% if state_policy is vyos_defined %}
+ chain VYOS_STATE_POLICY6 {
+{% if state_policy.established is vyos_defined %}
+ {{ state_policy.established | nft_state_policy('established', ipv6=True) }}
+{% endif %}
+{% if state_policy.invalid is vyos_defined %}
+ {{ state_policy.invalid | nft_state_policy('invalid', ipv6=True) }}
+{% endif %}
+{% if state_policy.related is vyos_defined %}
+ {{ state_policy.related | nft_state_policy('related', ipv6=True) }}
+{% endif %}
+ return
+ }
+{% endif %}
+}
+
+{% if first_install is vyos_defined %}
+table ip nat {
+ chain PREROUTING {
+ type nat hook prerouting priority -100; policy accept;
+ counter jump VYOS_PRE_DNAT_HOOK
+ }
+
+ chain POSTROUTING {
+ type nat hook postrouting priority 100; policy accept;
+ counter jump VYOS_PRE_SNAT_HOOK
+ }
+
+ chain VYOS_PRE_DNAT_HOOK {
+ return
+ }
+
+ chain VYOS_PRE_SNAT_HOOK {
+ return
+ }
+}
+
+table ip6 nat {
+ chain PREROUTING {
+ type nat hook prerouting priority -100; policy accept;
+ counter jump VYOS_DNPT_HOOK
+ }
+
+ chain POSTROUTING {
+ type nat hook postrouting priority 100; policy accept;
+ counter jump VYOS_SNPT_HOOK
+ }
+
+ chain VYOS_DNPT_HOOK {
+ return
+ }
+
+ chain VYOS_SNPT_HOOK {
+ return
+ }
+}
+
+table inet mangle {
+ chain FORWARD {
+ type filter hook forward priority -150; policy accept;
+ }
+}
+
+table raw {
+ chain VYOS_TCP_MSS {
+ type filter hook forward priority -300; policy accept;
+ }
+
+ chain PREROUTING {
+ type filter hook prerouting priority -200; policy accept;
+ counter jump VYOS_CT_IGNORE
+ counter jump VYOS_CT_TIMEOUT
+ counter jump VYOS_CT_PREROUTING_HOOK
+ counter jump FW_CONNTRACK
+ notrack
+ }
+
+ chain OUTPUT {
+ type filter hook output priority -200; policy accept;
+ counter jump VYOS_CT_IGNORE
+ counter jump VYOS_CT_TIMEOUT
+ counter jump VYOS_CT_OUTPUT_HOOK
+ counter jump FW_CONNTRACK
+ notrack
+ }
+
+ ct helper rpc_tcp {
+ type "rpc" protocol tcp;
+ }
+
+ ct helper rpc_udp {
+ type "rpc" protocol udp;
+ }
+
+ ct helper tns_tcp {
+ type "tns" protocol tcp;
+ }
+
+ chain VYOS_CT_HELPER {
+ ct helper set "rpc_tcp" tcp dport {111} return
+ ct helper set "rpc_udp" udp dport {111} return
+ ct helper set "tns_tcp" tcp dport {1521,1525,1536} return
+ return
+ }
+
+ chain VYOS_CT_IGNORE {
+ return
+ }
+
+ chain VYOS_CT_TIMEOUT {
+ return
+ }
+
+ chain VYOS_CT_PREROUTING_HOOK {
+ return
+ }
+
+ chain VYOS_CT_OUTPUT_HOOK {
+ return
+ }
+
+ chain FW_CONNTRACK {
+ accept
+ }
+}
+
+table ip6 raw {
+ chain VYOS_TCP_MSS {
+ type filter hook forward priority -300; policy accept;
+ }
+
+ chain PREROUTING {
+ type filter hook prerouting priority -300; policy accept;
+ counter jump VYOS_CT_PREROUTING_HOOK
+ counter jump FW_CONNTRACK
+ notrack
+ }
+
+ chain OUTPUT {
+ type filter hook output priority -300; policy accept;
+ counter jump VYOS_CT_OUTPUT_HOOK
+ counter jump FW_CONNTRACK
+ notrack
+ }
+
+ chain VYOS_CT_PREROUTING_HOOK {
+ return
+ }
+
+ chain VYOS_CT_OUTPUT_HOOK {
+ return
+ }
+
+ chain FW_CONNTRACK {
+ accept
+ }
+}
+{% endif %}
diff --git a/data/templates/firewall/upnpd.conf.j2 b/data/templates/firewall/upnpd.conf.j2
new file mode 100644
index 000000000..27573cbf9
--- /dev/null
+++ b/data/templates/firewall/upnpd.conf.j2
@@ -0,0 +1,172 @@
+# This is the UPNP configuration file
+
+# WAN network interface
+ext_ifname={{ wan_interface }}
+{% if wan_ip is vyos_defined %}
+# If the WAN interface has several IP addresses, you
+# can specify the one to use below
+{% for addr in wan_ip %}
+ext_ip={{ addr }}
+{% endfor %}
+{% endif %}
+
+# LAN network interfaces IPs / networks
+{% if listen is vyos_defined %}
+# There can be multiple listening IPs for SSDP traffic, in that case
+# use multiple 'listening_ip=...' lines, one for each network interface.
+# It can be IP address or network interface name (ie. "eth0")
+# It is mandatory to use the network interface name in order to enable IPv6
+# HTTP is available on all interfaces.
+# When MULTIPLE_EXTERNAL_IP is enabled, the external IP
+# address associated with the subnet follows. For example:
+# listening_ip=192.168.0.1/24 88.22.44.13
+{% for addr in listen %}
+{% if addr | is_ipv4 %}
+listening_ip={{ addr }}
+{% elif addr | is_ipv6 %}
+ipv6_listening_ip={{ addr }}
+{% else %}
+listening_ip={{ addr }}
+{% endif %}
+{% endfor %}
+{% endif %}
+
+# CAUTION: mixing up WAN and LAN interfaces may introduce security risks!
+# Be sure to assign the correct interfaces to LAN and WAN and consider
+# implementing UPnP permission rules at the bottom of this configuration file
+
+# Port for HTTP (descriptions and SOAP) traffic. Set to 0 for autoselect.
+#http_port=0
+# Port for HTTPS. Set to 0 for autoselect (default)
+#https_port=0
+
+# Path to the UNIX socket used to communicate with MiniSSDPd
+# If running, MiniSSDPd will manage M-SEARCH answering.
+# default is /var/run/minissdpd.sock
+#minissdpdsocket=/var/run/minissdpd.sock
+
+{% if nat_pmp is vyos_defined %}
+# Enable NAT-PMP support (default is no)
+enable_natpmp=yes
+{% endif %}
+
+# Enable UPNP support (default is yes)
+enable_upnp=yes
+
+{% if pcp_lifetime is vyos_defined %}
+# PCP
+# Configure the minimum and maximum lifetime of a port mapping in seconds
+# 120s and 86400s (24h) are suggested values from PCP-base
+{% if pcp_lifetime.max is vyos_defined %}
+max_lifetime={{ pcp_lifetime.max }}
+{% endif %}
+{% if pcp_lifetime.min is vyos_defined %}
+min_lifetime={{ pcp_lifetime.min }}
+{% endif %}
+{% endif %}
+
+
+# To enable the next few runtime options, see compile time
+# ENABLE_MANUFACTURER_INFO_CONFIGURATION (config.h)
+
+{% if friendly_name is vyos_defined %}
+# Name of this service, default is "`uname -s` router"
+friendly_name= {{ friendly_name }}
+{% endif %}
+
+# Manufacturer name, default is "`uname -s`"
+manufacturer_name=VyOS
+
+# Manufacturer URL, default is URL of OS vendor
+manufacturer_url=https://vyos.io/
+
+# Model name, default is "`uname -s` router"
+model_name=VyOS Router Model
+
+# Model description, default is "`uname -s` router"
+model_description=Vyos open source enterprise router/firewall operating system
+
+# Model URL, default is URL of OS vendor
+model_url=https://vyos.io/
+
+{% if secure_mode is vyos_defined %}
+# Secure Mode, UPnP clients can only add mappings to their own IP
+secure_mode=yes
+{% else %}
+# Secure Mode, UPnP clients can only add mappings to their own IP
+secure_mode=no
+{% endif %}
+
+{% if presentation_url is vyos_defined %}
+# Default presentation URL is HTTP address on port 80
+# If set to an empty string, no presentationURL element will appear
+# in the XML description of the device, which prevents MS Windows
+# from displaying an icon in the "Network Connections" panel.
+#presentation_url= {{ presentation_url }}
+{% endif %}
+
+# Report system uptime instead of daemon uptime
+system_uptime=yes
+
+# Unused rules cleaning.
+# never remove any rule before this threshold for the number
+# of redirections is exceeded. default to 20
+clean_ruleset_threshold=10
+# Clean process work interval in seconds. default to 0 (disabled).
+# a 600 seconds (10 minutes) interval makes sense
+clean_ruleset_interval=600
+
+# Anchor name in pf (default is miniupnpd)
+anchor=VyOS
+
+uuid={{ uuid }}
+
+# Lease file location
+lease_file=/config/upnp.leases
+
+# Daemon's serial and model number when reporting to clients
+# (in XML description)
+#serial=12345678
+#model_number=1
+
+{% if rules is vyos_defined %}
+# UPnP permission rules
+# (allow|deny) (external port range) IP/mask (internal port range)
+# A port range is <min port>-<max port> or <port> if there is only
+# one port in the range.
+# IP/mask format must be nnn.nnn.nnn.nnn/nn
+# It is advised to only allow redirection of port >= 1024
+# and end the rule set with "deny 0-65535 0.0.0.0/0 0-65535"
+# The following default ruleset allows specific LAN side IP addresses
+# to request only ephemeral ports. It is recommended that users
+# modify the IP ranges to match their own internal networks, and
+# also consider implementing network-specific restrictions
+# CAUTION: failure to enforce any rules may permit insecure requests to be made!
+{% for rule, config in rules.items() %}
+{% if config.disable is vyos_defined %}
+{{ config.action }} {{ config.external_port_range }} {{ config.ip }} {{ config.internal_port_range }}
+{% endif %}
+{% endfor %}
+{% endif %}
+
+{% if stun is vyos_defined %}
+# WAN interface must have public IP address. Otherwise it is behind NAT
+# and port forwarding is impossible. In some cases WAN interface can be
+# behind unrestricted NAT 1:1 when all incoming traffic is NAT-ed and
+# routed to WAN interfaces without any filtering. In this cases miniupnpd
+# needs to know public IP address and it can be learnt by asking external
+# server via STUN protocol. Following option enable retrieving external
+# public IP address from STUN server and detection of NAT type. You need
+# to specify also external STUN server in stun_host option below.
+# This option is disabled by default.
+ext_perform_stun=yes
+# Specify STUN server, either hostname or IP address
+# Some public STUN servers:
+# stun.stunprotocol.org
+# stun.sipgate.net
+# stun.xten.com
+# stun.l.google.com (on non standard port 19302)
+ext_stun_host={{ stun.host }}
+# Specify STUN UDP port, by default it is standard port 3478.
+ext_stun_port={{ stun.port }}
+{% endif %}
diff --git a/data/templates/frr/bfdd.frr.j2 b/data/templates/frr/bfdd.frr.j2
new file mode 100644
index 000000000..c4adeb402
--- /dev/null
+++ b/data/templates/frr/bfdd.frr.j2
@@ -0,0 +1,58 @@
+{% if profile is vyos_defined or peer is vyos_defined %}
+bfd
+{% if profile is vyos_defined %}
+{% for profile_name, profile_config in profile.items() %}
+ profile {{ profile_name }}
+ detect-multiplier {{ profile_config.interval.multiplier }}
+ receive-interval {{ profile_config.interval.receive }}
+ transmit-interval {{ profile_config.interval.transmit }}
+{% if profile_config.interval.echo_interval is vyos_defined %}
+ echo transmit-interval {{ profile_config.interval.echo_interval }}
+ echo receive-interval {{ profile_config.interval.echo_interval }}
+{% endif %}
+{% if profile_config.echo_mode is vyos_defined %}
+ echo-mode
+{% endif %}
+{% if profile_config.passive is vyos_defined %}
+ passive-mode
+{% endif %}
+{% if profile_config.shutdown is vyos_defined %}
+ shutdown
+{% else %}
+ no shutdown
+{% endif %}
+ exit
+ !
+{% endfor %}
+{% endif %}
+{% if peer is vyos_defined %}
+{% for peer_name, peer_config in peer.items() %}
+ peer {{ peer_name }} {{ 'multihop' if peer_config.multihop is vyos_defined }} {{ 'local-address ' ~ peer_config.source.address if peer_config.source.address is vyos_defined }} {{ 'interface ' ~ peer_config.source.interface if peer_config.source.interface is vyos_defined }} {{ 'vrf ' ~ peer_config.vrf if peer_config.vrf is vyos_defined }}
+ detect-multiplier {{ peer_config.interval.multiplier }}
+ receive-interval {{ peer_config.interval.receive }}
+ transmit-interval {{ peer_config.interval.transmit }}
+{% if peer_config.interval.echo_interval is vyos_defined %}
+ echo transmit-interval {{ peer_config.interval.echo_interval }}
+ echo receive-interval {{ peer_config.interval.echo_interval }}
+{% endif %}
+{% if peer_config.echo_mode is vyos_defined %}
+ echo-mode
+{% endif %}
+{% if peer_config.passive is vyos_defined %}
+ passive-mode
+{% endif %}
+{% if peer_config.profile is vyos_defined %}
+ profile {{ peer_config.profile }}
+{% endif %}
+{% if peer_config.shutdown is vyos_defined %}
+ shutdown
+{% else %}
+ no shutdown
+{% endif %}
+ exit
+ !
+{% endfor %}
+{% endif %}
+exit
+!
+{% endif %}
diff --git a/data/templates/frr/bfdd.frr.tmpl b/data/templates/frr/bfdd.frr.tmpl
deleted file mode 100644
index 16f8be92c..000000000
--- a/data/templates/frr/bfdd.frr.tmpl
+++ /dev/null
@@ -1,44 +0,0 @@
-!
-bfd
-{% if profile is defined and profile is not none %}
-{% for profile_name, profile_config in profile.items() %}
- profile {{ profile_name }}
- detect-multiplier {{ profile_config.interval.multiplier }}
- receive-interval {{ profile_config.interval.receive }}
- transmit-interval {{ profile_config.interval.transmit }}
-{% if profile_config.interval['echo-interval'] is defined and profile_config.interval['echo-interval'] is not none %}
- echo-interval {{ profile_config.interval['echo-interval'] }}
-{% endif %}
-{% if profile_config['echo-mode'] is defined %}
- echo-mode
-{% endif %}
-{% if profile_config.shutdown is defined %}
- shutdown
-{% else %}
- no shutdown
-{% endif %}
- exit
-{% endfor %}
-{% endif %}
-{% if peer is defined and peer is not none %}
-{% for peer_name, peer_config in peer.items() %}
- peer {{ peer_name }}{{ ' multihop' if peer_config.multihop is defined }}{{ ' local-address ' + peer_config.source.address if peer_config.source is defined and peer_config.source.address is defined }}{{ ' interface ' + peer_config.source.interface if peer_config.source is defined and peer_config.source.interface is defined }}
- detect-multiplier {{ peer_config.interval.multiplier }}
- receive-interval {{ peer_config.interval.receive }}
- transmit-interval {{ peer_config.interval.transmit }}
-{% if peer_config.interval['echo-interval'] is defined and peer_config.interval['echo-interval'] is not none %}
- echo-interval {{ peer_config.interval['echo-interval'] }}
-{% endif %}
-{% if peer_config['echo-mode'] is defined %}
- echo-mode
-{% endif %}
-{% if peer_config.shutdown is defined %}
- shutdown
-{% else %}
- no shutdown
-{% endif %}
- exit
-{% endfor %}
-{% endif %}
- end
-!
diff --git a/data/templates/frr/bgpd.frr.j2 b/data/templates/frr/bgpd.frr.j2
new file mode 100644
index 000000000..7029f39af
--- /dev/null
+++ b/data/templates/frr/bgpd.frr.j2
@@ -0,0 +1,533 @@
+{### MACRO definition for recurring peer patter, this can be either fed by a ###}
+{### peer-group or an individual BGP neighbor ###}
+{% macro bgp_neighbor(neighbor, config, peer_group=false) %}
+{% if peer_group == true %}
+ neighbor {{ neighbor }} peer-group
+{% elif config.peer_group is vyos_defined %}
+ neighbor {{ neighbor }} peer-group {{ config.peer_group }}
+{% endif %}
+{% if config.remote_as is vyos_defined %}
+ neighbor {{ neighbor }} remote-as {{ config.remote_as }}
+{% endif %}
+{% if config.interface.remote_as is vyos_defined %}
+ neighbor {{ neighbor }} interface remote-as {{ config.interface.remote_as }}
+{% endif %}
+{% if config.advertisement_interval is vyos_defined %}
+ neighbor {{ neighbor }} advertisement-interval {{ config.advertisement_interval }}
+{% endif %}
+{% if config.bfd is vyos_defined %}
+ neighbor {{ neighbor }} bfd
+{% if config.bfd.check_control_plane_failure is vyos_defined %}
+ neighbor {{ neighbor }} bfd check-control-plane-failure
+{% endif %}
+{% if config.bfd.profile is vyos_defined %}
+ neighbor {{ neighbor }} bfd profile {{ config.bfd.profile }}
+{% endif %}
+{% endif %}
+{% if config.capability is vyos_defined %}
+{% if config.capability.dynamic is vyos_defined %}
+ neighbor {{ neighbor }} capability dynamic
+{% endif %}
+{% if config.capability.extended_nexthop is vyos_defined %}
+ neighbor {{ neighbor }} capability extended-nexthop
+{% endif %}
+{% endif %}
+{% if config.description is vyos_defined %}
+ neighbor {{ neighbor }} description {{ config.description }}
+{% endif %}
+{% if config.disable_capability_negotiation is vyos_defined %}
+ neighbor {{ neighbor }} dont-capability-negotiate
+{% endif %}
+{% if config.ebgp_multihop is vyos_defined %}
+ neighbor {{ neighbor }} ebgp-multihop {{ config.ebgp_multihop }}
+{% endif %}
+{% if config.graceful_restart is vyos_defined %}
+{% if config.graceful_restart is vyos_defined('enable') %}
+{% set graceful_restart = 'graceful-restart' %}
+{% elif config.graceful_restart is vyos_defined('disable') %}
+{% set graceful_restart = 'graceful-restart-disable' %}
+{% elif config.graceful_restart is vyos_defined('restart-helper') %}
+{% set graceful_restart = 'graceful-restart-helper' %}
+{% endif %}
+ neighbor {{ neighbor }} {{ graceful_restart }}
+{% endif %}
+{% if config.local_as is vyos_defined %}
+{% for local_as, local_as_config in config.local_as.items() %}
+{# There can be only one local-as value, this is checked in the Python code #}
+ neighbor {{ neighbor }} local-as {{ local_as }} {{ 'no-prepend' if local_as_config.no_prepend is vyos_defined }} {{ 'replace-as' if local_as_config.no_prepend is vyos_defined and local_as_config.no_prepend.replace_as is vyos_defined }}
+{% endfor %}
+{% endif %}
+{% if config.override_capability is vyos_defined %}
+ neighbor {{ neighbor }} override-capability
+{% endif %}
+{% if config.passive is vyos_defined %}
+ neighbor {{ neighbor }} passive
+{% endif %}
+{% if config.password is vyos_defined %}
+ neighbor {{ neighbor }} password {{ config.password }}
+{% endif %}
+{% if config.port is vyos_defined %}
+ neighbor {{ neighbor }} port {{ config.port }}
+{% endif %}
+{% if config.shutdown is vyos_defined %}
+ neighbor {{ neighbor }} shutdown
+{% endif %}
+{% if config.solo is vyos_defined %}
+ neighbor {{ neighbor }} solo
+{% endif %}
+{% if config.strict_capability_match is vyos_defined %}
+ neighbor {{ neighbor }} strict-capability-match
+{% endif %}
+{% if config.ttl_security.hops is vyos_defined %}
+ neighbor {{ neighbor }} ttl-security hops {{ config.ttl_security.hops }}
+{% endif %}
+{% if config.timers.connect is vyos_defined %}
+ neighbor {{ neighbor }} timers connect {{ config.timers.connect }}
+{% endif %}
+{% if config.timers.keepalive is vyos_defined and config.timers.holdtime is vyos_defined %}
+ neighbor {{ neighbor }} timers {{ config.timers.keepalive }} {{ config.timers.holdtime }}
+{% endif %}
+{% if config.update_source is vyos_defined %}
+ neighbor {{ neighbor }} update-source {{ config.update_source }}
+{% endif %}
+{% if config.interface is vyos_defined %}
+{% if config.interface.peer_group is vyos_defined %}
+ neighbor {{ neighbor }} interface peer-group {{ config.interface.peer_group }}
+{% endif %}
+{% if config.interface.source_interface is vyos_defined %}
+ neighbor {{ neighbor }} interface {{ config.interface.source_interface }}
+{% endif %}
+{% if config.interface.v6only is vyos_defined %}
+{% if config.interface.v6only.peer_group is vyos_defined %}
+ neighbor {{ neighbor }} interface v6only peer-group {{ config.interface.v6only.peer_group }}
+{% endif %}
+{% if config.interface.v6only.remote_as is vyos_defined %}
+ neighbor {{ neighbor }} interface v6only remote-as {{ config.interface.v6only.remote_as }}
+{% endif %}
+{% endif %}
+{% endif %}
+ !
+{% if config.address_family is vyos_defined %}
+{% for afi, afi_config in config.address_family.items() %}
+{% if afi == 'ipv4_unicast' %}
+ address-family ipv4 unicast
+{% elif afi == 'ipv4_multicast' %}
+ address-family ipv4 multicast
+{% elif afi == 'ipv4_labeled_unicast' %}
+ address-family ipv4 labeled-unicast
+{% elif afi == 'ipv4_vpn' %}
+ address-family ipv4 vpn
+{% elif afi == 'ipv4_flowspec' %}
+ address-family ipv4 flowspec
+{% elif afi == 'ipv6_unicast' %}
+ address-family ipv6 unicast
+{% elif afi == 'ipv6_multicast' %}
+ address-family ipv6 multicast
+{% elif afi == 'ipv6_labeled_unicast' %}
+ address-family ipv6 labeled-unicast
+{% elif afi == 'ipv6_vpn' %}
+ address-family ipv6 vpn
+{% elif afi == 'ipv6_flowspec' %}
+ address-family ipv6 flowspec
+{% elif afi == 'l2vpn_evpn' %}
+ address-family l2vpn evpn
+{% endif %}
+{% if afi_config.addpath_tx_all is vyos_defined %}
+ neighbor {{ neighbor }} addpath-tx-all-paths
+{% endif %}
+{% if afi_config.addpath_tx_per_as is vyos_defined %}
+ neighbor {{ neighbor }} addpath-tx-bestpath-per-AS
+{% endif %}
+{% if afi_config.allowas_in is vyos_defined %}
+ neighbor {{ neighbor }} allowas-in {{ afi_config.allowas_in.number if afi_config.allowas_in.number is vyos_defined }}
+{% endif %}
+{% if afi_config.as_override is vyos_defined %}
+ neighbor {{ neighbor }} as-override
+{% endif %}
+{% if afi_config.conditionally_advertise is vyos_defined %}
+{% if afi_config.conditionally_advertise.advertise_map is vyos_defined %}
+{% set exist_non_exist_map = 'exist-map' %}
+{% if afi_config.conditionally_advertise.exist_map is vyos_defined %}
+{% set exist_non_exist_map = 'exist-map ' ~ afi_config.conditionally_advertise.exist_map %}
+{% elif afi_config.conditionally_advertise.non_exist_map is vyos_defined %}
+{% set exist_non_exist_map = 'non-exist-map ' ~ afi_config.conditionally_advertise.non_exist_map %}
+{% endif %}
+ neighbor {{ neighbor }} advertise-map {{ afi_config.conditionally_advertise.advertise_map }} {{ exist_non_exist_map }}
+{% endif %}
+{% endif %}
+{% if afi_config.remove_private_as is vyos_defined %}
+ neighbor {{ neighbor }} remove-private-AS
+{% endif %}
+{% if afi_config.route_reflector_client is vyos_defined %}
+ neighbor {{ neighbor }} route-reflector-client
+{% endif %}
+{% if afi_config.weight is vyos_defined %}
+ neighbor {{ neighbor }} weight {{ afi_config.weight }}
+{% endif %}
+{% if afi_config.attribute_unchanged is vyos_defined %}
+ neighbor {{ neighbor }} attribute-unchanged {{ 'as-path ' if afi_config.attribute_unchanged.as_path is vyos_defined }}{{ 'med ' if afi_config.attribute_unchanged.med is vyos_defined }}{{ 'next-hop ' if afi_config.attribute_unchanged.next_hop is vyos_defined }}
+{% endif %}
+{% if afi_config.capability.orf.prefix_list.send is vyos_defined %}
+ neighbor {{ neighbor }} capability orf prefix-list send
+{% endif %}
+{% if afi_config.capability.orf.prefix_list.receive is vyos_defined %}
+ neighbor {{ neighbor }} capability orf prefix-list receive
+{% endif %}
+{% if afi_config.default_originate is vyos_defined %}
+ neighbor {{ neighbor }} default-originate {{ 'route-map ' ~ afi_config.default_originate.route_map if afi_config.default_originate.route_map is vyos_defined }}
+{% endif %}
+{% if afi_config.distribute_list.export is vyos_defined %}
+ neighbor {{ neighbor }} distribute-list {{ afi_config.distribute_list.export }} out
+{% endif %}
+{% if afi_config.distribute_list.import is vyos_defined %}
+ neighbor {{ neighbor }} distribute-list {{ afi_config.distribute_list.import }} in
+{% endif %}
+{% if afi_config.filter_list.export is vyos_defined %}
+ neighbor {{ neighbor }} filter-list {{ afi_config.filter_list.export }} out
+{% endif %}
+{% if afi_config.filter_list.import is vyos_defined %}
+ neighbor {{ neighbor }} filter-list {{ afi_config.filter_list.import }} in
+{% endif %}
+{% if afi_config.maximum_prefix is vyos_defined %}
+ neighbor {{ neighbor }} maximum-prefix {{ afi_config.maximum_prefix }}
+{% endif %}
+{% if afi_config.maximum_prefix_out is vyos_defined %}
+ neighbor {{ neighbor }} maximum-prefix-out {{ afi_config.maximum_prefix_out }}
+{% endif %}
+{% if afi_config.nexthop_self is vyos_defined %}
+ neighbor {{ neighbor }} next-hop-self {{ 'force' if afi_config.nexthop_self.force is vyos_defined }}
+{% endif %}
+{% if afi_config.route_server_client is vyos_defined %}
+ neighbor {{ neighbor }} route-server-client
+{% endif %}
+{% if afi_config.route_map.export is vyos_defined %}
+ neighbor {{ neighbor }} route-map {{ afi_config.route_map.export }} out
+{% endif %}
+{% if afi_config.route_map.import is vyos_defined %}
+ neighbor {{ neighbor }} route-map {{ afi_config.route_map.import }} in
+{% endif %}
+{% if afi_config.prefix_list.export is vyos_defined %}
+ neighbor {{ neighbor }} prefix-list {{ afi_config.prefix_list.export }} out
+{% endif %}
+{% if afi_config.prefix_list.import is vyos_defined %}
+ neighbor {{ neighbor }} prefix-list {{ afi_config.prefix_list.import }} in
+{% endif %}
+{% if afi_config.soft_reconfiguration.inbound is vyos_defined %}
+ neighbor {{ neighbor }} soft-reconfiguration inbound
+{% endif %}
+{% if afi_config.unsuppress_map is vyos_defined %}
+ neighbor {{ neighbor }} unsuppress-map {{ afi_config.unsuppress_map }}
+{% endif %}
+{% if afi_config.disable_send_community.extended is vyos_defined %}
+ no neighbor {{ neighbor }} send-community extended
+{% endif %}
+{% if afi_config.disable_send_community.standard is vyos_defined %}
+ no neighbor {{ neighbor }} send-community standard
+{% endif %}
+ neighbor {{ neighbor }} activate
+ exit-address-family
+ !
+{% endfor %}
+{% endif %}
+{% endmacro %}
+!
+router bgp {{ local_as }} {{ 'vrf ' ~ vrf if vrf is vyos_defined }}
+{% if parameters.ebgp_requires_policy is vyos_defined %}
+ bgp ebgp-requires-policy
+{% else %}
+ no bgp ebgp-requires-policy
+{% endif %}
+{# Option must be set before any neighbor - see https://phabricator.vyos.net/T3463 #}
+ no bgp default ipv4-unicast
+{# Workaround for T2100 until we have decided about a migration script #}
+ no bgp network import-check
+{% if address_family is vyos_defined %}
+{% for afi, afi_config in address_family.items() %}
+ !
+{% if afi == 'ipv4_unicast' %}
+ address-family ipv4 unicast
+{% elif afi == 'ipv4_multicast' %}
+ address-family ipv4 multicast
+{% elif afi == 'ipv4_labeled_unicast' %}
+ address-family ipv4 labeled-unicast
+{% elif afi == 'ipv4_vpn' %}
+ address-family ipv4 vpn
+{% elif afi == 'ipv4_flowspec' %}
+ address-family ipv4 flowspec
+{% elif afi == 'ipv6_unicast' %}
+ address-family ipv6 unicast
+{% elif afi == 'ipv6_multicast' %}
+ address-family ipv6 multicast
+{% elif afi == 'ipv6_labeled_unicast' %}
+ address-family ipv6 labeled-unicast
+{% elif afi == 'ipv6_vpn' %}
+ address-family ipv6 vpn
+{% elif afi == 'ipv6_flowspec' %}
+ address-family ipv6 flowspec
+{% elif afi == 'l2vpn_evpn' %}
+ address-family l2vpn evpn
+{% if afi_config.rd is vyos_defined %}
+ rd {{ afi_config.rd }}
+{% endif %}
+{% endif %}
+{% if afi_config.aggregate_address is vyos_defined %}
+{% for aggregate, aggregate_config in afi_config.aggregate_address.items() %}
+ aggregate-address {{ aggregate }}{{ ' as-set' if aggregate_config.as_set is vyos_defined }}{{ ' summary-only' if aggregate_config.summary_only is vyos_defined }}
+{% if aggregate_config.route_map is vyos_defined %}
+ aggregate-address {{ aggregate }} route-map {{ aggregate_config.route_map }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if afi_config.maximum_paths.ebgp is vyos_defined %}
+ maximum-paths {{ afi_config.maximum_paths.ebgp }}
+{% endif %}
+{% if afi_config.maximum_paths.ibgp is vyos_defined %}
+ maximum-paths ibgp {{ afi_config.maximum_paths.ibgp }}
+{% endif %}
+{% if afi_config.redistribute is vyos_defined %}
+{% for protocol, protocol_config in afi_config.redistribute.items() %}
+{% if protocol == 'table' %}
+ redistribute table {{ protocol_config.table }}
+{% else %}
+{% set redistribution_protocol = protocol %}
+{% if protocol == 'ospfv3' %}
+{% set redistribution_protocol = 'ospf6' %}
+{% endif %}
+ redistribute {{ redistribution_protocol }} {{ 'metric ' ~ protocol_config.metric if protocol_config.metric is vyos_defined }} {{ 'route-map ' ~ protocol_config.route_map if protocol_config.route_map is vyos_defined }}
+ {####### we need this blank line!! #######}
+
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if afi_config.network is vyos_defined %}
+{% for network, network_config in afi_config.network.items() %}
+ network {{ network }} {{ 'route-map ' ~ network_config.route_map if network_config.route_map is vyos_defined }} {{ 'backdoor' if network_config.backdoor is vyos_defined }} {{ 'rd ' ~ network_config.rd if network_config.rd is vyos_defined }} {{ 'label ' ~ network_config.label if network_config.label is vyos_defined }}
+{####### we need this blank line!! #######}
+
+{% endfor %}
+{% endif %}
+{% if afi_config.advertise is vyos_defined %}
+{% for adv_afi, adv_afi_config in afi_config.advertise.items() %}
+{% if adv_afi_config.unicast is vyos_defined %}
+ advertise {{ adv_afi }} unicast {{ 'route-map ' ~ adv_afi_config.unicast.route_map if adv_afi_config.unicast.route_map is vyos_defined }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if afi_config.distance.external is vyos_defined and afi_config.distance.internal is vyos_defined and afi_config.distance.local is vyos_defined %}
+ distance bgp {{ afi_config.distance.external }} {{ afi_config.distance.internal }} {{ afi_config.distance.local }}
+{% endif %}
+{% if afi_config.distance.prefix is vyos_defined %}
+{% for prefix in afi_config.distance.prefix %}
+ distance {{ afi_config.distance.prefix[prefix].distance }} {{ prefix }}
+{% endfor %}
+{% endif %}
+{% if afi_config.export.vpn is vyos_defined %}
+ export vpn
+{% endif %}
+{% if afi_config.import.vpn is vyos_defined %}
+ import vpn
+{% endif %}
+{% if afi_config.import.vrf is vyos_defined %}
+{% for vrf in afi_config.import.vrf %}
+ import vrf {{ vrf }}
+{% endfor %}
+{% endif %}
+{% if afi_config.label.vpn.export is vyos_defined %}
+ label vpn export {{ afi_config.label.vpn.export }}
+{% endif %}
+{% if afi_config.local_install is vyos_defined %}
+{% for interface in afi_config.local_install.interface %}
+ local-install {{ interface }}
+{% endfor %}
+{% endif %}
+{% if afi_config.advertise_all_vni is vyos_defined %}
+ advertise-all-vni
+{% endif %}
+{% if afi_config.advertise_default_gw is vyos_defined %}
+ advertise-default-gw
+{% endif %}
+{% if afi_config.advertise_pip is vyos_defined %}
+ advertise-pip ip {{ afi_config.advertise_pip }}
+{% endif %}
+{% if afi_config.advertise_svi_ip is vyos_defined %}
+ advertise-svi-ip
+{% endif %}
+{% if afi_config.rt_auto_derive is vyos_defined %}
+ autort rfc8365-compatible
+{% endif %}
+{% if afi_config.flooding.disable is vyos_defined %}
+ flooding disable
+{% endif %}
+{% if afi_config.flooding.head_end_replication is vyos_defined %}
+ flooding head-end-replication
+{% endif %}
+{% if afi_config.rd.vpn.export is vyos_defined %}
+ rd vpn export {{ afi_config.rd.vpn.export }}
+{% endif %}
+{% if afi_config.route_target.vpn.both is vyos_defined %}
+ route-target vpn both {{ afi_config.route_target.vpn.both }}
+{% else %}
+{% if afi_config.route_target.vpn.export is vyos_defined %}
+ route-target vpn export {{ afi_config.route_target.vpn.export }}
+{% endif %}
+{% if afi_config.route_target.vpn.import is vyos_defined %}
+ route-target vpn import {{ afi_config.route_target.vpn.import }}
+{% endif %}
+{% endif %}
+{% if afi_config.route_target.both is vyos_defined %}
+ route-target both {{ afi_config.route_target.both }}
+{% else %}
+{% if afi_config.route_target.export is vyos_defined %}
+ route-target export {{ afi_config.route_target.export }}
+{% endif %}
+{% if afi_config.route_target.import is vyos_defined %}
+ route-target import {{ afi_config.route_target.import }}
+{% endif %}
+{% endif %}
+{% if afi_config.route_map.vpn.export is vyos_defined %}
+ route-map vpn export {{ afi_config.route_map.vpn.export }}
+{% endif %}
+{% if afi_config.route_map.vpn.import is vyos_defined %}
+ route-map vpn import {{ afi_config.route_map.vpn.import }}
+{% endif %}
+{% if afi_config.vni is vyos_defined %}
+{% for vni, vni_config in afi_config.vni.items() %}
+ vni {{ vni }}
+{% if vni_config.advertise_default_gw is vyos_defined %}
+ advertise-default-gw
+{% endif %}
+{% if vni_config.advertise_svi_ip is vyos_defined %}
+ advertise-svi-ip
+{% endif %}
+{% if vni_config.rd is vyos_defined %}
+ rd {{ vni_config.rd }}
+{% endif %}
+{% if vni_config.route_target.both is vyos_defined %}
+ route-target both {{ vni_config.route_target.both }}
+{% endif %}
+{% if vni_config.route_target.export is vyos_defined %}
+ route-target export {{ vni_config.route_target.export }}
+{% endif %}
+{% if vni_config.route_target.import is vyos_defined %}
+ route-target import {{ vni_config.route_target.import }}
+{% endif %}
+ exit-vni
+{% endfor %}
+{% endif %}
+ exit-address-family
+{% endfor %}
+{% endif %}
+ !
+{% if peer_group is vyos_defined %}
+{% for peer, config in peer_group.items() %}
+{{ bgp_neighbor(peer, config, true) }}
+{% endfor %}
+{% endif %}
+ !
+{% if neighbor is vyos_defined %}
+{% for peer, config in neighbor.items() %}
+{{ bgp_neighbor(peer, config) }}
+{% endfor %}
+{% endif %}
+ !
+{% if listen.limit is vyos_defined %}
+ bgp listen limit {{ listen.limit }}
+{% endif %}
+{% if listen.range is vyos_defined %}
+{% for prefix, options in listen.range.items() %}
+{% if options.peer_group is vyos_defined %}
+ bgp listen range {{ prefix }} peer-group {{ options.peer_group }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if parameters.always_compare_med is vyos_defined %}
+ bgp always-compare-med
+{% endif %}
+{% if parameters.bestpath.as_path is vyos_defined %}
+{% for option in parameters.bestpath.as_path %}
+{# replace is required for multipath-relax option #}
+ bgp bestpath as-path {{ option | replace('_', '-') }}
+{% endfor %}
+{% endif %}
+{% if parameters.bestpath.bandwidth is vyos_defined %}
+ bgp bestpath bandwidth {{ parameters.bestpath.bandwidth }}
+{% endif %}
+{% if parameters.bestpath.compare_routerid is vyos_defined %}
+ bgp bestpath compare-routerid
+{% endif %}
+{% if parameters.bestpath.med is vyos_defined %}
+ bgp bestpath med {{ 'confed' if parameters.bestpath.med.confed is vyos_defined }} {{ 'missing-as-worst' if parameters.bestpath.med.missing_as_worst is vyos_defined }}
+{% endif %}
+{% if parameters.cluster_id is vyos_defined %}
+ bgp cluster-id {{ parameters.cluster_id }}
+{% endif %}
+{% if parameters.conditional_advertisement.timer is vyos_defined %}
+ bgp conditional-advertisement timer {{ parameters.conditional_advertisement.timer }}
+{% endif %}
+{% if parameters.confederation.identifier is vyos_defined %}
+ bgp confederation identifier {{ parameters.confederation.identifier }}
+{% endif %}
+{% if parameters.confederation.peers is vyos_defined %}
+ bgp confederation peers {{ parameters.confederation.peers | join(' ') }}
+{% endif %}
+{% if parameters.dampening.half_life is vyos_defined %}
+{# Doesn't work in current FRR configuration; vtysh (bgp dampening 16 751 2001 61) #}
+ bgp dampening {{ parameters.dampening.half_life }} {{ parameters.dampening.re_use if parameters.dampening.re_use is vyos_defined }} {{ parameters.dampening.start_suppress_time if parameters.dampening.start_suppress_time is vyos_defined }} {{ parameters.dampening.max_suppress_time if parameters.dampening.max_suppress_time is vyos_defined }}
+{% endif %}
+{% if parameters.default.local_pref is vyos_defined %}
+ bgp default local-preference {{ parameters.default.local_pref }}
+{% endif %}
+{% if parameters.deterministic_med is vyos_defined %}
+ bgp deterministic-med
+{% endif %}
+{% if parameters.distance.global.external is vyos_defined and parameters.distance.global.internal is vyos_defined and parameters.distance.global.local is vyos_defined %}
+ distance bgp {{ parameters.distance.global.external }} {{ parameters.distance.global.internal }} {{ parameters.distance.global.local }}
+{% endif %}
+{% if parameters.distance.prefix is vyos_defined %}
+{% for prefix in parameters.distance.prefix %}
+ distance {{ parameters.distance.prefix[prefix].distance }} {{ prefix }}
+{% endfor %}
+{% endif %}
+{% if parameters.fast_convergence is vyos_defined %}
+ bgp fast-convergence
+{% endif %}
+{% if parameters.graceful_restart is vyos_defined %}
+ bgp graceful-restart {{ 'stalepath-time ' ~ parameters.graceful_restart.stalepath_time if parameters.graceful_restart.stalepath_time is vyos_defined }}
+{% endif %}
+{% if parameters.graceful_shutdown is vyos_defined %}
+ bgp graceful-shutdown
+{% endif %}
+{% if parameters.log_neighbor_changes is vyos_defined %}
+ bgp log-neighbor-changes
+{% endif %}
+{% if parameters.minimum_holdtime is vyos_defined %}
+ bgp minimum-holdtime {{ parameters.minimum_holdtime }}
+{% endif %}
+{% if parameters.network_import_check is vyos_defined %}
+ bgp network import-check
+{% endif %}
+{% if parameters.no_client_to_client_reflection is vyos_defined %}
+ no bgp client-to-client reflection
+{% endif %}
+{% if parameters.no_fast_external_failover is vyos_defined %}
+ no bgp fast-external-failover
+{% endif %}
+{% if parameters.no_suppress_duplicates is vyos_defined %}
+ no bgp suppress-duplicates
+{% endif %}
+{% if parameters.reject_as_sets is vyos_defined %}
+ bgp reject-as-sets
+{% endif %}
+{% if parameters.router_id is vyos_defined and parameters.router_id is not none %}
+ bgp router-id {{ parameters.router_id }}
+{% endif %}
+{% if parameters.shutdown is vyos_defined %}
+ bgp shutdown
+{% endif %}
+{% if parameters.suppress_fib_pending is vyos_defined %}
+ bgp suppress-fib-pending
+{% endif %}
+{% if timers.keepalive is vyos_defined and timers.holdtime is vyos_defined %}
+ timers bgp {{ timers.keepalive }} {{ timers.holdtime }}
+{% endif %}
+exit
diff --git a/data/templates/frr/bgpd.frr.tmpl b/data/templates/frr/bgpd.frr.tmpl
deleted file mode 100644
index 61936bb56..000000000
--- a/data/templates/frr/bgpd.frr.tmpl
+++ /dev/null
@@ -1,528 +0,0 @@
-{### MACRO definition for recurring peer patter, this can be either fed by a ###}
-{### peer-group or an individual BGP neighbor ###}
-{% macro bgp_neighbor(neighbor, config, peer_group=false) %}
-{% if peer_group == true %}
- neighbor {{ neighbor }} peer-group
-{% elif config.peer_group is defined and config.peer_group is not none %}
- neighbor {{ neighbor }} peer-group {{ config.peer_group }}
-{% endif %}
-{% if config.remote_as is defined and config.remote_as is not none %}
- neighbor {{ neighbor }} remote-as {{ config.remote_as }}
-{% endif %}
-{% if config.interface is defined and config.interface.remote_as is defined and config.interface.remote_as is not none %}
- neighbor {{ neighbor }} interface remote-as {{ config.interface.remote_as }}
-{% endif %}
-{% if config.advertisement_interval is defined and config.advertisement_interval is not none %}
- neighbor {{ neighbor }} advertisement-interval {{ config.advertisement_interval }}
-{% endif %}
-{% if config.bfd is defined %}
- neighbor {{ neighbor }} bfd
-{% endif %}
-{% if config.capability is defined and config.capability is not none %}
-{% if config.capability.dynamic is defined %}
- neighbor {{ neighbor }} capability dynamic
-{% endif %}
-{% if config.capability.extended_nexthop is defined %}
- neighbor {{ neighbor }} capability extended-nexthop
-{% endif %}
-{% endif %}
-{% if config.description is defined and config.description is not none %}
- neighbor {{ neighbor }} description {{ config.description }}
-{% endif %}
-{% if config.disable_capability_negotiation is defined %}
- neighbor {{ neighbor }} dont-capability-negotiate
-{% endif %}
-{% if config.ebgp_multihop is defined and config.ebgp_multihop is not none %}
- neighbor {{ neighbor }} ebgp-multihop {{ config.ebgp_multihop }}
-{% endif %}
-{% if config.graceful_restart is defined and config.graceful_restart is not none %}
-{% if config.graceful_restart == 'enable' %}
-{% set graceful_restart = 'graceful-restart' %}
-{% elif config.graceful_restart == 'disable' %}
-{% set graceful_restart = 'graceful-restart-disable' %}
-{% elif config.graceful_restart == 'restart-helper' %}
-{% set graceful_restart = 'graceful-restart-helper' %}
-{% endif %}
- neighbor {{ neighbor }} {{ graceful_restart }}
-{% endif %}
-{% if config.local_as is defined and config.local_as is not none %}
-{% for local_as, local_as_config in config.local_as.items() %}
-{# There can be only one local-as value, this is checked in the Python code #}
- neighbor {{ neighbor }} local-as {{ local_as }} {{ 'no-prepend' if local_as_config.no_prepend is defined }} {{ 'replace-as' if local_as_config.no_prepend is defined and local_as_config.no_prepend.replace_as is defined }}
-{% endfor %}
-{% endif %}
-{% if config.override_capability is defined %}
- neighbor {{ neighbor }} override-capability
-{% endif %}
-{% if config.passive is defined %}
- neighbor {{ neighbor }} passive
-{% endif %}
-{% if config.password is defined and config.password is not none %}
- neighbor {{ neighbor }} password {{ config.password }}
-{% endif %}
-{% if config.port is defined and config.port is not none %}
- neighbor {{ neighbor }} port {{ config.port }}
-{% endif %}
-{% if config.shutdown is defined %}
- neighbor {{ neighbor }} shutdown
-{% endif %}
-{% if config.solo is defined %}
- neighbor {{ neighbor }} solo
-{% endif %}
-{% if config.strict_capability_match is defined %}
- neighbor {{ neighbor }} strict-capability-match
-{% endif %}
-{% if config.ttl_security is defined and config.ttl_security.hops is defined and config.ttl_security.hops is not none %}
- neighbor {{ neighbor }} ttl-security hops {{ config.ttl_security.hops }}
-{% endif %}
-{% if config.timers is defined %}
-{% if config.timers.connect is defined and config.timers.connect is not none %}
- neighbor {{ neighbor }} timers connect {{ config.timers.connect }}
-{% endif %}
-{% if config.timers.holdtime is defined and config.timers.keepalive is defined and config.timers.holdtime is not none and config.timers.keepalive is not none %}
- neighbor {{ neighbor }} timers {{ config.timers.keepalive }} {{ config.timers.holdtime }}
-{% endif %}
-{% endif %}
-{% if config.update_source is defined and config.update_source is not none %}
- neighbor {{ neighbor }} update-source {{ config.update_source }}
-{% endif %}
-{% if config.interface is defined and config.interface is not none %}
-{% if config.interface.peer_group is defined and config.interface.peer_group is not none %}
- neighbor {{ neighbor }} interface peer-group {{ config.interface.peer_group }}
-{% endif %}
-{% if config.interface.source_interface is defined and config.interface.source_interface is not none %}
- neighbor {{ neighbor }} interface {{ config.interface.source_interface }}
-{% endif %}
-{% if config.interface.v6only is defined and config.interface.v6only is not none %}
-{% if config.interface.v6only.peer_group is defined and config.interface.v6only.peer_group is not none %}
- neighbor {{ neighbor }} interface v6only peer-group {{ config.interface.v6only.peer_group }}
-{% endif %}
-{% if config.interface.v6only.remote_as is defined and config.interface.v6only.remote_as is not none %}
- neighbor {{ neighbor }} interface v6only remote-as {{ config.interface.v6only.remote_as }}
-{% endif %}
-{% endif %}
-{% endif %}
- !
-{% if config.address_family is defined and config.address_family is not none %}
-{% for afi, afi_config in config.address_family.items() %}
-{% if afi == 'ipv4_unicast' %}
- address-family ipv4 unicast
-{% elif afi == 'ipv4_multicast' %}
- address-family ipv4 multicast
-{% elif afi == 'ipv4_labeled_unicast' %}
- address-family ipv4 labeled-unicast
-{% elif afi == 'ipv4_vpn' %}
- address-family ipv4 vpn
-{% elif afi == 'ipv4_flowspec' %}
- address-family ipv4 flowspec
-{% elif afi == 'ipv6_unicast' %}
- address-family ipv6 unicast
-{% elif afi == 'ipv6_multicast' %}
- address-family ipv6 multicast
-{% elif afi == 'ipv6_labeled_unicast' %}
- address-family ipv6 labeled-unicast
-{% elif afi == 'ipv6_vpn' %}
- address-family ipv6 vpn
-{% elif afi == 'ipv6_flowspec' %}
- address-family ipv6 flowspec
-{% elif afi == 'l2vpn_evpn' %}
- address-family l2vpn evpn
-{% endif %}
-{% if afi_config.addpath_tx_all is defined %}
- neighbor {{ neighbor }} addpath-tx-all-paths
-{% endif %}
-{% if afi_config.addpath_tx_per_as is defined %}
- neighbor {{ neighbor }} addpath-tx-bestpath-per-AS
-{% endif %}
-{% if afi_config.allowas_in is defined and afi_config.allowas_in is not none %}
- neighbor {{ neighbor }} allowas-in {{ afi_config.allowas_in.number if afi_config.allowas_in.number is defined }}
-{% endif %}
-{% if afi_config.as_override is defined %}
- neighbor {{ neighbor }} as-override
-{% endif %}
-{% if afi_config.remove_private_as is defined %}
- neighbor {{ neighbor }} remove-private-AS
-{% endif %}
-{% if afi_config.route_reflector_client is defined %}
- neighbor {{ neighbor }} route-reflector-client
-{% endif %}
-{% if afi_config.weight is defined and afi_config.weight is not none %}
- neighbor {{ neighbor }} weight {{ afi_config.weight }}
-{% endif %}
-{% if afi_config.attribute_unchanged is defined and afi_config.attribute_unchanged is not none %}
- neighbor {{ neighbor }} attribute-unchanged {{ 'as-path ' if afi_config.attribute_unchanged.as_path is defined }}{{ 'med ' if afi_config.attribute_unchanged.med is defined }}{{ 'next-hop ' if afi_config.attribute_unchanged.next_hop is defined }}
-{% endif %}
-{% if afi_config.capability is defined and afi_config.capability.orf is defined and afi_config.capability.orf.prefix_list is defined and afi_config.capability.orf.prefix_list.send is defined %}
- neighbor {{ neighbor }} capability orf prefix-list send
-{% endif %}
-{% if afi_config.capability is defined and afi_config.capability.orf is defined and afi_config.capability.orf.prefix_list is defined and afi_config.capability.orf.prefix_list.receive is defined %}
- neighbor {{ neighbor }} capability orf prefix-list receive
-{% endif %}
-{% if afi_config.default_originate is defined %}
- neighbor {{ neighbor }} default-originate {{ 'route-map ' ~ afi_config.default_originate.route_map if afi_config.default_originate.route_map is defined }}
-{% endif %}
-{% if afi_config.distribute_list is defined and afi_config.distribute_list is not none %}
-{% if afi_config.distribute_list.export is defined and afi_config.distribute_list.export is not none %}
- neighbor {{ neighbor }} distribute-list {{ afi_config.distribute_list.export }} out
-{% endif %}
-{% if afi_config.distribute_list.import is defined and afi_config.distribute_list.import is not none %}
- neighbor {{ neighbor }} distribute-list {{ afi_config.distribute_list.import }} in
-{% endif %}
-{% endif %}
-{% if afi_config.filter_list is defined and afi_config.filter_list is not none %}
-{% if afi_config.filter_list.export is defined and afi_config.filter_list.export is not none %}
- neighbor {{ neighbor }} filter-list {{ afi_config.filter_list.export }} out
-{% endif %}
-{% if afi_config.filter_list.import is defined and afi_config.filter_list.import is not none %}
- neighbor {{ neighbor }} filter-list {{ afi_config.filter_list.import }} in
-{% endif %}
-{% endif %}
-{% if afi_config.maximum_prefix is defined and afi_config.maximum_prefix is not none %}
- neighbor {{ neighbor }} maximum-prefix {{ afi_config.maximum_prefix }}
-{% endif %}
-{% if afi_config.maximum_prefix_out is defined and afi_config.maximum_prefix_out is not none %}
- neighbor {{ neighbor }} maximum-prefix-out {{ afi_config.maximum_prefix_out }}
-{% endif %}
-{% if afi_config.nexthop_self is defined %}
- neighbor {{ neighbor }} next-hop-self {{ 'force' if afi_config.nexthop_self.force is defined }}
-{% endif %}
-{% if afi_config.route_server_client is defined %}
- neighbor {{ neighbor }} route-server-client
-{% endif %}
-{% if afi_config.route_map is defined and afi_config.route_map is not none %}
-{% if afi_config.route_map.export is defined and afi_config.route_map.export is not none %}
- neighbor {{ neighbor }} route-map {{ afi_config.route_map.export }} out
-{% endif %}
-{% if afi_config.route_map.import is defined and afi_config.route_map.import is not none %}
- neighbor {{ neighbor }} route-map {{ afi_config.route_map.import }} in
-{% endif %}
-{% endif %}
-{% if afi_config.prefix_list is defined and afi_config.prefix_list is not none %}
-{% if afi_config.prefix_list.export is defined and afi_config.prefix_list.export is not none %}
- neighbor {{ neighbor }} prefix-list {{ afi_config.prefix_list.export }} out
-{% endif %}
-{% if afi_config.prefix_list.import is defined and afi_config.prefix_list.import is not none %}
- neighbor {{ neighbor }} prefix-list {{ afi_config.prefix_list.import }} in
-{% endif %}
-{% endif %}
-{% if afi_config.soft_reconfiguration is defined and afi_config.soft_reconfiguration.inbound is defined %}
- neighbor {{ neighbor }} soft-reconfiguration inbound
-{% endif %}
-{% if afi_config.unsuppress_map is defined and afi_config.unsuppress_map is not none %}
- neighbor {{ neighbor }} unsuppress-map {{ afi_config.unsuppress_map }}
-{% endif %}
-{% if afi_config.disable_send_community is defined and afi_config.disable_send_community.extended is defined %}
- no neighbor {{ neighbor }} send-community extended
-{% endif %}
-{% if afi_config.disable_send_community is defined and afi_config.disable_send_community.standard is defined %}
- no neighbor {{ neighbor }} send-community standard
-{% endif %}
- neighbor {{ neighbor }} activate
- exit-address-family
- !
-{% endfor %}
-{% endif %}
-{% endmacro %}
-!
-router bgp {{ local_as }} {{ 'vrf ' ~ vrf if vrf is defined and vrf is not none }}
-{% if parameters is defined and parameters.ebgp_requires_policy is defined %}
- bgp ebgp-requires-policy
-{% else %}
- no bgp ebgp-requires-policy
-{% endif %}
-{# Option must be set before any neighbor - see https://phabricator.vyos.net/T3463 #}
- no bgp default ipv4-unicast
-{# Workaround for T2100 until we have decided about a migration script #}
- no bgp network import-check
-{% if address_family is defined and address_family is not none %}
-{% for afi, afi_config in address_family.items() %}
- !
-{% if afi == 'ipv4_unicast' %}
- address-family ipv4 unicast
-{% elif afi == 'ipv4_multicast' %}
- address-family ipv4 multicast
-{% elif afi == 'ipv4_labeled_unicast' %}
- address-family ipv4 labeled-unicast
-{% elif afi == 'ipv4_vpn' %}
- address-family ipv4 vpn
-{% elif afi == 'ipv4_flowspec' %}
- address-family ipv4 flowspec
-{% elif afi == 'ipv6_unicast' %}
- address-family ipv6 unicast
-{% elif afi == 'ipv6_multicast' %}
- address-family ipv6 multicast
-{% elif afi == 'ipv6_labeled_unicast' %}
- address-family ipv6 labeled-unicast
-{% elif afi == 'ipv6_vpn' %}
- address-family ipv6 vpn
-{% elif afi == 'ipv6_flowspec' %}
- address-family ipv6 flowspec
-{% elif afi == 'l2vpn_evpn' %}
- address-family l2vpn evpn
-{% if afi_config.rd is defined and afi_config.rd is not none %}
- rd {{ afi_config.rd }}
-{% endif %}
-{% endif %}
-{% if afi_config.aggregate_address is defined and afi_config.aggregate_address is not none %}
-{% for aggregate, aggregate_config in afi_config.aggregate_address.items() %}
- aggregate-address {{ aggregate }}{{ ' as-set' if aggregate_config.as_set is defined }}{{ ' summary-only' if aggregate_config.summary_only is defined }}
-{% if aggregate_config.route_map is defined and aggregate_config.route_map is not none %}
- aggregate-address {{ aggregate }} route-map {{ aggregate_config.route_map }}
-{% endif %}
-{% endfor %}
-{% endif %}
-{% if afi_config.maximum_paths is defined and afi_config.maximum_paths.ebgp is defined and afi_config.maximum_paths.ebgp is not none %}
- maximum-paths {{ afi_config.maximum_paths.ebgp }}
-{% endif %}
-{% if afi_config.maximum_paths is defined and afi_config.maximum_paths.ibgp is defined and afi_config.maximum_paths.ibgp is not none %}
- maximum-paths ibgp {{ afi_config.maximum_paths.ibgp }}
-{% endif %}
-{% if afi_config.redistribute is defined and afi_config.redistribute is not none %}
-{% for protocol in afi_config.redistribute %}
-{% if protocol == 'table' %}
- redistribute table {{ afi_config.redistribute[protocol].table }}
-{% else %}
-{% set redistribution_protocol = protocol %}
-{% if protocol == 'ospfv3' %}
-{% set redistribution_protocol = 'ospf6' %}
-{% endif %}
- redistribute {{ redistribution_protocol }}{% if afi_config.redistribute[protocol].metric is defined %} metric {{ afi_config.redistribute[protocol].metric }}{% endif %}{% if afi_config.redistribute[protocol].route_map is defined %} route-map {{ afi_config.redistribute[protocol].route_map }}{% endif %}
-{####### we need this blank line!! #######}
-
-{% endif %}
-{% endfor %}
-{% endif %}
-{% if afi_config.network is defined and afi_config.network is not none %}
-{% for network in afi_config.network %}
- network {{ network }}{% if afi_config.network[network].route_map is defined %} route-map {{ afi_config.network[network].route_map }}{% endif %}{% if afi_config.network[network].backdoor is defined %} backdoor{% endif %}{% if afi_config.network[network].rd is defined and afi_config.network[network].label is defined%} rd {{ afi_config.network[network].rd }} label {{ afi_config.network[network].label }}{% endif %}
-{####### we need this blank line!! #######}
-
-{% endfor %}
-{% endif %}
-{% if afi_config.advertise is defined and afi_config.advertise is not none %}
-{% for adv_afi, adv_afi_config in afi_config.advertise.items() %}
-{% if adv_afi_config.unicast is defined and adv_afi_config.unicast is not none %}
- advertise {{ adv_afi }} unicast {{ 'route-map ' ~ adv_afi_config.unicast.route_map if adv_afi_config.unicast.route_map is defined }}
-{% endif %}
-{% endfor %}
-{% endif %}
-{% if afi_config.distance is defined and afi_config.distance is not none %}
-{% if afi_config.distance is defined and afi_config.distance.external is defined and afi_config.distance.internal is defined and afi_config.distance.local is defined %}
- distance bgp {{ afi_config.distance.external }} {{ afi_config.distance.internal }} {{ afi_config.distance.local }}
-{% endif %}
-{% if afi_config.distance.prefix is defined and afi_config.distance.prefix is not none %}
-{% for prefix in afi_config.distance.prefix %}
- distance {{ afi_config.distance.prefix[prefix].distance }} {{ prefix }}
-{% endfor %}
-{% endif %}
-{% endif %}
-{% if afi_config.export is defined and afi_config.export.vpn is defined %}
- export vpn
-{% endif %}
-{% if afi_config.import is defined and afi_config.import is not none %}
-{% if afi_config.import.vpn is defined %}
- import vpn
-{% endif %}
-{% if afi_config.import.vrf is defined and afi_config.import.vrf is not none %}
-{% for vrf in afi_config.import.vrf %}
- import vrf {{ vrf }}
-{% endfor %}
-{% endif %}
-{% endif %}
-{% if afi_config.label is defined and afi_config.label.vpn is defined and afi_config.label.vpn.export is defined and afi_config.label.vpn.export is not none %}
- label vpn export {{ afi_config.label.vpn.export }}
-{% endif %}
-{% if afi_config.local_install is defined and afi_config.local_install is not none %}
-{% for interface in afi_config.local_install.interface %}
- local-install {{ interface }}
-{% endfor %}
-{% endif %}
-{% if afi_config.advertise_all_vni is defined %}
- advertise-all-vni
-{% endif %}
-{% if afi_config.advertise_default_gw is defined %}
- advertise-default-gw
-{% endif %}
-{% if afi_config.advertise_pip is defined and afi_config.advertise_pip is not none %}
- advertise-pip ip {{ afi_config.advertise_pip }}
-{% endif %}
-{% if afi_config.advertise_svi_ip is defined %}
- advertise-svi-ip
-{% endif %}
-{% if afi_config.rt_auto_derive is defined %}
- autort rfc8365-compatible
-{% endif %}
-{% if afi_config.flooding is defined and afi_config.flooding.disable is defined %}
- flooding disable
-{% endif %}
-{% if afi_config.flooding is defined and afi_config.flooding.head_end_replication is defined %}
- flooding head-end-replication
-{% endif %}
-{% if afi_config.rd is defined and afi_config.rd.vpn is defined and afi_config.rd.vpn.export is defined %}
- rd vpn export {{ afi_config.rd.vpn.export }}
-{% endif %}
-{% if afi_config.route_target is defined and afi_config.route_target is not none %}
-{% if afi_config.route_target.vpn is defined and afi_config.route_target.vpn is not none %}
-{% if afi_config.route_target.vpn.both is defined and afi_config.route_target.vpn.both is not none %}
- route-target vpn both {{ afi_config.route_target.vpn.both }}
-{% else %}
-{% if afi_config.route_target.vpn.export is defined and afi_config.route_target.vpn.export is not none %}
- route-target vpn export {{ afi_config.route_target.vpn.export }}
-{% endif %}
-{% if afi_config.route_target.vpn.import is defined and afi_config.route_target.vpn.import is not none %}
- route-target vpn import {{ afi_config.route_target.vpn.import }}
-{% endif %}
-{% endif %}
-{% endif %}
-{% if afi_config.route_target.both is defined and afi_config.route_target.both is not none %}
- route-target both {{ afi_config.route_target.both }}
-{% else %}
-{% if afi_config.route_target.export is defined and afi_config.route_target.export is not none %}
- route-target export {{ afi_config.route_target.export }}
-{% endif %}
-{% if afi_config.route_target.import is defined and afi_config.route_target.import is not none %}
- route-target import {{ afi_config.route_target.import }}
-{% endif %}
-{% endif %}
-{% endif %}
-{% if afi_config.route_map is defined and afi_config.route_map.vpn is defined and afi_config.route_map.vpn is not none %}
-{% if afi_config.route_map.vpn.export is defined and afi_config.route_map.vpn.export is not none %}
- route-map vpn export {{ afi_config.route_map.vpn.export }}
-{% endif %}
-{% if afi_config.route_map.vpn.import is defined and afi_config.route_map.vpn.import is not none %}
- route-map vpn import {{ afi_config.route_map.vpn.import }}
-{% endif %}
-{% endif %}
-{% if afi_config.vni is defined and afi_config.vni is not none %}
-{% for vni, vni_config in afi_config.vni.items() %}
- vni {{ vni }}
-{% if vni_config.advertise_default_gw is defined %}
- advertise-default-gw
-{% endif %}
-{% if vni_config.advertise_svi_ip is defined %}
- advertise-svi-ip
-{% endif %}
-{% if vni_config.rd is defined and vni_config.rd is not none %}
- rd {{ vni_config.rd }}
-{% endif %}
-{% if vni_config.route_target is defined and vni_config.route_target is not none %}
-{% if vni_config.route_target.both is defined and vni_config.route_target.both is not none %}
- route-target both {{ vni_config.route_target.both }}
-{% endif %}
-{% if vni_config.route_target.export is defined and vni_config.route_target.export is not none %}
- route-target export {{ vni_config.route_target.export }}
-{% endif %}
-{% if vni_config.route_target.import is defined and vni_config.route_target.import is not none %}
- route-target import {{ vni_config.route_target.import }}
-{% endif %}
-{% endif %}
- exit-vni
-{% endfor %}
-{% endif %}
- exit-address-family
-{% endfor %}
-{% endif %}
- !
-{% if peer_group is defined and peer_group is not none %}
-{% for peer, config in peer_group.items() %}
-{{ bgp_neighbor(peer, config, true) }}
-{% endfor %}
-{% endif %}
- !
-{% if neighbor is defined and neighbor is not none %}
-{% for peer, config in neighbor.items() %}
-{{ bgp_neighbor(peer, config) }}
-{% endfor %}
-{% endif %}
- !
-{% if listen is defined %}
-{% if listen.limit is defined and listen.limit is not none %}
- bgp listen limit {{ listen.limit }}
-{% endif %}
-{% for prefix, options in listen.range.items() %}
-{% if options.peer_group is defined and options.peer_group is not none %}
- bgp listen range {{ prefix }} peer-group {{ options.peer_group }}
-{% endif %}
-{% endfor %}
-{% endif %}
-{% if parameters is defined %}
-{% if parameters.always_compare_med is defined %}
- bgp always-compare-med
-{% endif %}
-{% if parameters.bestpath is defined and parameters.bestpath is not none %}
-{% if parameters.bestpath.as_path is defined and parameters.bestpath.as_path is not none %}
-{% for option in parameters.bestpath.as_path %}
-{# replace is required for multipath-relax option #}
- bgp bestpath as-path {{ option|replace('_', '-') }}
-{% endfor %}
-{% endif %}
-{% if parameters.bestpath.bandwidth is defined and parameters.bestpath.bandwidth is not none %}
- bgp bestpath bandwidth {{ parameters.bestpath.bandwidth }}
-{% endif %}
-{% if parameters.bestpath.compare_routerid is defined %}
- bgp bestpath compare-routerid
-{% endif %}
-{% if parameters.bestpath.med is defined and parameters.bestpath.med is not none %}
- bgp bestpath med {{ 'confed' if parameters.bestpath.med.confed is defined }} {{ 'missing-as-worst' if parameters.bestpath.med.missing_as_worst is defined }}
-{% endif %}
-{% endif %}
-{% if parameters.cluster_id is defined and parameters.cluster_id is not none %}
- bgp cluster-id {{ parameters.cluster_id }}
-{% endif %}
-{% if parameters.confederation is defined and parameters.confederation is not none %}
-{% if parameters.confederation.identifier is defined and parameters.confederation.identifier is not none %}
- bgp confederation identifier {{ parameters.confederation.identifier }}
-{% endif %}
-{% if parameters.confederation.peers is defined and parameters.confederation.peers is not none %}
- bgp confederation peers {{ parameters.confederation.peers | join(' ') }}
-{% endif %}
-{% endif %}
-{% if parameters.dampening is defined and parameters.dampening is defined and parameters.dampening.half_life is defined and parameters.dampening.half_life is not none %}
-{# Doesn't work in current FRR configuration; vtysh (bgp dampening 16 751 2001 61) #}
- bgp dampening {{ parameters.dampening.half_life }} {{ parameters.dampening.re_use if parameters.dampening.re_use is defined }} {{ parameters.dampening.start_suppress_time if parameters.dampening.start_suppress_time is defined }} {{ parameters.dampening.max_suppress_time if parameters.dampening.max_suppress_time is defined }}
-{% endif %}
-{% if parameters.default is defined and parameters.default is not none %}
-{% if parameters.default.local_pref is defined and parameters.default.local_pref is not none %}
- bgp default local-preference {{ parameters.default.local_pref }}
-{% endif %}
-{% endif %}
-{% if parameters.deterministic_med is defined %}
- bgp deterministic-med
-{% endif %}
-{% if parameters.distance is defined and parameters.distance is not none %}
-{% if parameters.distance.global is defined and parameters.distance.global.external is defined and parameters.distance.global.internal is defined and parameters.distance.global.local is defined %}
- distance bgp {{ parameters.distance.global.external }} {{ parameters.distance.global.internal }} {{ parameters.distance.global.local }}
-{% endif %}
-{% if parameters.distance.prefix is defined and parameters.distance.prefix is not none %}
-{% for prefix in parameters.distance.prefix %}
- distance {{ parameters.distance.prefix[prefix].distance }} {{ prefix }}
-{% endfor %}
-{% endif %}
-{% endif %}
-{% if parameters.graceful_restart is defined %}
- bgp graceful-restart {{ 'stalepath-time ' ~ parameters.graceful_restart.stalepath_time if parameters.graceful_restart.stalepath_time is defined }}
-{% endif %}
-{% if parameters.graceful_shutdown is defined %}
- bgp graceful-shutdown
-{% endif %}
-{% if parameters.log_neighbor_changes is defined %}
- bgp log-neighbor-changes
-{% endif %}
-{% if parameters.network_import_check is defined %}
- bgp network import-check
-{% endif %}
-{% if parameters.no_client_to_client_reflection is defined %}
- no bgp client-to-client reflection
-{% endif %}
-{% if parameters.no_fast_external_failover is defined %}
- no bgp fast-external-failover
-{% endif %}
-{% if parameters.router_id is defined and parameters.router_id is not none %}
- bgp router-id {{ parameters.router_id }}
-{% endif %}
-{% endif %}
-{% if timers is defined and timers.keepalive is defined and timers.holdtime is defined %}
- timers bgp {{ timers.keepalive }} {{ timers.holdtime }}
-{% endif %}
- end
-! \ No newline at end of file
diff --git a/data/templates/frr/igmp.frr.j2 b/data/templates/frr/igmp.frr.j2
new file mode 100644
index 000000000..ce1f8fdda
--- /dev/null
+++ b/data/templates/frr/igmp.frr.j2
@@ -0,0 +1,41 @@
+!
+{% for iface in old_ifaces %}
+interface {{ iface }}
+{% for group in old_ifaces[iface].gr_join %}
+{% if old_ifaces[iface].gr_join[group] %}
+{% for source in old_ifaces[iface].gr_join[group] %}
+ no ip igmp join {{ group }} {{ source }}
+{% endfor %}
+{% else %}
+ no ip igmp join {{ group }}
+{% endif %}
+{% endfor %}
+ no ip igmp
+!
+{% endfor %}
+{% for interface, interface_config in ifaces.items() %}
+interface {{ interface }}
+{% if interface_config.version %}
+ ip igmp version {{ interface_config.version }}
+{% else %}
+{# IGMP default version 3 #}
+ ip igmp
+{% endif %}
+{% if interface_config.query_interval %}
+ ip igmp query-interval {{ interface_config.query_interval }}
+{% endif %}
+{% if interface_config.query_max_resp_time %}
+ ip igmp query-max-response-time {{ interface_config.query_max_resp_time }}
+{% endif %}
+{% for group in interface_config.gr_join %}
+{% if ifaces[iface].gr_join[group] %}
+{% for source in ifaces[iface].gr_join[group] %}
+ ip igmp join {{ group }} {{ source }}
+{% endfor %}
+{% else %}
+ ip igmp join {{ group }}
+{% endif %}
+{% endfor %}
+!
+{% endfor %}
+!
diff --git a/data/templates/frr/igmp.frr.tmpl b/data/templates/frr/igmp.frr.tmpl
deleted file mode 100644
index 49b5aeaa5..000000000
--- a/data/templates/frr/igmp.frr.tmpl
+++ /dev/null
@@ -1,41 +0,0 @@
-!
-{% for iface in old_ifaces %}
-interface {{ iface }}
-{% for group in old_ifaces[iface].gr_join %}
-{% if old_ifaces[iface].gr_join[group] %}
-{% for source in old_ifaces[iface].gr_join[group] %}
- no ip igmp join {{ group }} {{ source }}
-{% endfor %}
-{% else %}
- no ip igmp join {{ group }}
-{% endif %}
-{% endfor %}
- no ip igmp
-!
-{% endfor %}
-{% for iface in ifaces %}
-interface {{ iface }}
-{% if ifaces[iface].version %}
- ip igmp version {{ ifaces[iface].version }}
-{% else %}
-{# IGMP default version 3 #}
- ip igmp
-{% endif %}
-{% if ifaces[iface].query_interval %}
- ip igmp query-interval {{ ifaces[iface].query_interval }}
-{% endif %}
-{% if ifaces[iface].query_max_resp_time %}
- ip igmp query-max-response-time {{ ifaces[iface].query_max_resp_time }}
-{% endif %}
-{% for group in ifaces[iface].gr_join %}
-{% if ifaces[iface].gr_join[group] %}
-{% for source in ifaces[iface].gr_join[group] %}
- ip igmp join {{ group }} {{ source }}
-{% endfor %}
-{% else %}
- ip igmp join {{ group }}
-{% endif %}
-{% endfor %}
-!
-{% endfor %}
-!
diff --git a/data/templates/frr/isisd.frr.j2 b/data/templates/frr/isisd.frr.j2
new file mode 100644
index 000000000..8e95348bc
--- /dev/null
+++ b/data/templates/frr/isisd.frr.j2
@@ -0,0 +1,197 @@
+!
+{% if interface is vyos_defined %}
+{% for iface, iface_config in interface.items() %}
+interface {{ iface }}
+ ip router isis VyOS
+ ipv6 router isis VyOS
+{% if iface_config.bfd is vyos_defined %}
+ isis bfd
+{% if iface_config.bfd.profile is vyos_defined %}
+ isis bfd profile {{ iface_config.bfd.profile }}
+{% endif %}
+{% endif %}
+{% if iface_config.network.point_to_point is vyos_defined %}
+ isis network point-to-point
+{% endif %}
+{% if iface_config.circuit_type is vyos_defined %}
+ isis circuit-type {{ iface_config.circuit_type }}
+{% endif %}
+{% if iface_config.hello_interval is vyos_defined %}
+ isis hello-interval {{ iface_config.hello_interval }}
+{% endif %}
+{% if iface_config.hello_multiplier is vyos_defined %}
+ isis hello-multiplier {{ iface_config.hello_multiplier }}
+{% endif %}
+{% if iface_config.hello_padding is vyos_defined %}
+ isis hello padding
+{% endif %}
+{% if iface_config.metric is vyos_defined %}
+ isis metric {{ iface_config.metric }}
+{% endif %}
+{% if iface_config.passive is vyos_defined %}
+ isis passive
+{% endif %}
+{% if iface_config.password.md5 is vyos_defined %}
+ isis password md5 {{ iface_config.password.md5 }}
+{% elif iface_config.password.plaintext_password is vyos_defined %}
+ isis password clear {{ iface_config.password.plaintext_password }}
+{% endif %}
+{% if iface_config.priority is vyos_defined %}
+ isis priority {{ iface_config.priority }}
+{% endif %}
+{% if iface_config.psnp_interval is vyos_defined %}
+ isis psnp-interval {{ iface_config.psnp_interval }}
+{% endif %}
+{% if iface_config.no_three_way_handshake is vyos_defined %}
+ no isis three-way-handshake
+{% endif %}
+exit
+!
+{% endfor %}
+{% endif %}
+!
+router isis VyOS {{ 'vrf ' + vrf if vrf is vyos_defined }}
+ net {{ net }}
+{% if dynamic_hostname is vyos_defined %}
+ hostname dynamic
+{% endif %}
+{% if purge_originator is vyos_defined %}
+ purge-originator
+{% endif %}
+{% if set_attached_bit is vyos_defined %}
+ set-attached-bit
+{% endif %}
+{% if set_overload_bit is vyos_defined %}
+ set-overload-bit
+{% endif %}
+{% if domain_password.md5 is vyos_defined %}
+ domain-password md5 {{ domain_password.plaintext_password }}
+{% elif domain_password.plaintext_password is vyos_defined %}
+ domain-password clear {{ domain_password.plaintext_password }}
+{% endif %}
+{% if log_adjacency_changes is vyos_defined %}
+ log-adjacency-changes
+{% endif %}
+{% if lsp_gen_interval is vyos_defined %}
+ lsp-gen-interval {{ lsp_gen_interval }}
+{% endif %}
+{% if lsp_mtu is vyos_defined %}
+ lsp-mtu {{ lsp_mtu }}
+{% endif %}
+{% if lsp_refresh_interval is vyos_defined %}
+ lsp-refresh-interval {{ lsp_refresh_interval }}
+{% endif %}
+{% if max_lsp_lifetime is vyos_defined %}
+ max-lsp-lifetime {{ max_lsp_lifetime }}
+{% endif %}
+{% if spf_interval is vyos_defined %}
+ spf-interval {{ spf_interval }}
+{% endif %}
+{% if traffic_engineering.enable is vyos_defined %}
+ mpls-te on
+{% endif %}
+{% if traffic_engineering.address is vyos_defined %}
+ mpls-te router-address {{ traffic_engineering.address }}
+{% endif %}
+{% if traffic_engineering.inter_as is vyos_defined %}
+{% set level = '' %}
+{% if traffic_engineering.inter_as.level_1 is vyos_defined %}
+{% set level = ' level-1' %}
+{% endif %}
+{% if traffic_engineering.inter_as.level_1_2 is vyos_defined %}
+{% set level = ' level-1-2' %}
+{% endif %}
+{% if traffic_engineering.inter_as.level_2 is vyos_defined %}
+{% set level = ' level-2-only' %}
+{% endif %}
+ mpls-te inter-as{{ level }}
+{% endif %}
+{% if segment_routing is vyos_defined %}
+{% if segment_routing.enable is vyos_defined %}
+ segment-routing on
+{% endif %}
+{% if segment_routing.maximum_label_depth is vyos_defined %}
+ segment-routing node-msd {{ segment_routing.maximum_label_depth }}
+{% endif %}
+{% if segment_routing.global_block is vyos_defined %}
+{% if segment_routing.local_block is vyos_defined %}
+ segment-routing global-block {{ segment_routing.global_block.low_label_value }} {{ segment_routing.global_block.high_label_value }} local-block {{ segment_routing.local_block.low_label_value }} {{ segment_routing.local_block.high_label_value }}
+{% else %}
+ segment-routing global-block {{ segment_routing.global_block.low_label_value }} {{ segment_routing.global_block.high_label_value }}
+{% endif %}
+{% endif %}
+{% if segment_routing.prefix is vyos_defined %}
+{% for prefix, prefix_config in segment_routing.prefix.items() %}
+{% if prefix_config.absolute is vyos_defined %}
+{% if prefix_config.absolute.value is vyos_defined %}
+ segment-routing prefix {{ prefixes }} absolute {{ prefix_config.absolute.value }}
+{% if prefix_config.absolute.explicit_null is vyos_defined %}
+ segment-routing prefix {{ prefixes }} absolute {{ prefix_config.absolute.value }} explicit-null
+{% endif %}
+{% if prefix_config.absolute.no_php_flag is vyos_defined %}
+ segment-routing prefix {{ prefixes }} absolute {{ prefix_config.absolute.value }} no-php-flag
+{% endif %}
+{% endif %}
+{% if prefix_config.index is vyos_defined %}
+{% if prefix_config.index.value is vyos_defined %}
+ segment-routing prefix {{ prefixes }} index {{ prefix_config.index.value }}
+{% if prefix_config.index.explicit_null is vyos_defined %}
+ segment-routing prefix {{ prefixes }} index {{ prefix_config.index.value }} explicit-null
+{% endif %}
+{% if prefix_config.index.no_php_flag is vyos_defined %}
+ segment-routing prefix {{ prefixes }} index {{ prefix_config.index.value }} no-php-flag
+{% endif %}
+{% endif %}
+{% endif %}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% endif %}
+{% if spf_delay_ietf.init_delay is vyos_defined %}
+ spf-delay-ietf init-delay {{ spf_delay_ietf.init_delay }} short-delay {{ spf_delay_ietf.short_delay }} long-delay {{ spf_delay_ietf.long_delay }} holddown {{ spf_delay_ietf.holddown }} time-to-learn {{ spf_delay_ietf.time_to_learn }}
+{% endif %}
+{% if area_password.md5 is vyos_defined %}
+ area-password md5 {{ area_password.md5 }}
+{% elif area_password.plaintext_password is vyos_defined %}
+ area-password clear {{ area_password.plaintext_password }}
+{% endif %}
+{% if default_information.originate is vyos_defined %}
+{% for afi, afi_config in default_information.originate.items() %}
+{% for level, level_config in afi_config.items() %}
+ default-information originate {{ afi }} {{ level | replace('_', '-') }} {{ 'always' if level_config.always is vyos_defined }} {{ 'route-map ' ~ level_config.route_map if level_config.route_map is vyos_defined }} {{ 'metric ' ~ level_config.metric if level_config.metric is vyos_defined }}
+{% endfor %}
+{% endfor %}
+{% endif %}
+{% if redistribute.ipv4 is vyos_defined %}
+{% for protocol, protocol_options in redistribute.ipv4.items() %}
+{% for level, level_config in protocol_options.items() %}
+{% if level_config.metric is vyos_defined %}
+ redistribute ipv4 {{ protocol }} {{ level | replace('_', '-') }} metric {{ level_config.metric }}
+{% elif level_config.route_map is vyos_defined %}
+ redistribute ipv4 {{ protocol }} {{ level | replace('_', '-') }} route-map {{ level_config.route_map }}
+{% else %}
+ redistribute ipv4 {{ protocol }} {{ level | replace('_', '-') }}
+{% endif %}
+{% endfor %}
+{% endfor %}
+{% endif %}
+{% if redistribute.ipv6 is vyos_defined %}
+{% for protocol, protocol_options in redistribute.ipv6.items() %}
+{% for level, level_config in protocol_options.items() %}
+{% if level_config.metric is vyos_defined %}
+ redistribute ipv6 {{ protocol }} {{ level | replace('_', '-') }} metric {{ level_config.metric }}
+{% elif level_config.route_map is vyos_defined %}
+ redistribute ipv6 {{ protocol }} {{ level | replace('_', '-') }} route-map {{ level_config.route_map }}
+{% else %}
+ redistribute ipv6 {{ protocol }} {{ level | replace('_', '-') }}
+{% endif %}
+{% endfor %}
+{% endfor %}
+{% endif %}
+{% if level is vyos_defined('level-2') %}
+ is-type level-2-only
+{% elif level is vyos_defined %}
+ is-type {{ level }}
+{% endif %}
+exit
+! \ No newline at end of file
diff --git a/data/templates/frr/isisd.frr.tmpl b/data/templates/frr/isisd.frr.tmpl
deleted file mode 100644
index 51ac40060..000000000
--- a/data/templates/frr/isisd.frr.tmpl
+++ /dev/null
@@ -1,198 +0,0 @@
-!
-router isis VyOS {{ 'vrf ' + vrf if vrf is defined and vrf is not none }}
- net {{ net }}
-{% if dynamic_hostname is defined %}
- hostname dynamic
-{% endif %}
-{% if purge_originator is defined %}
- purge-originator
-{% endif %}
-{% if set_attached_bit is defined %}
- set-attached-bit
-{% endif %}
-{% if set_overload_bit is defined %}
- set-overload-bit
-{% endif %}
-{% if domain_password is defined and domain_password is not none %}
-{% if domain_password.md5 is defined and domain_password.md5 is not none %}
- domain-password md5 {{ domain_password.plaintext_password }}
-{% elif domain_password.plaintext_password is defined and domain_password.plaintext_password is not none %}
- domain-password clear {{ domain_password.plaintext_password }}
-{% endif %}
-{% endif %}
-{% if log_adjacency_changes is defined %}
- log-adjacency-changes
-{% endif %}
-{% if lsp_gen_interval is defined and lsp_gen_interval is not none %}
- lsp-gen-interval {{ lsp_gen_interval }}
-{% endif %}
-{% if lsp_mtu is defined and lsp_mtu is not none %}
- lsp-mtu {{ lsp_mtu }}
-{% endif %}
-{% if lsp_refresh_interval is defined and lsp_refresh_interval is not none %}
- lsp-refresh-interval {{ lsp_refresh_interval }}
-{% endif %}
-{% if max_lsp_lifetime is defined and max_lsp_lifetime is not none %}
- max-lsp-lifetime {{ max_lsp_lifetime }}
-{% endif %}
-{% if spf_interval is defined and spf_interval is not none %}
- spf-interval {{ spf_interval }}
-{% endif %}
-{% if traffic_engineering is defined and traffic_engineering is not none %}
-{% if traffic_engineering.enable is defined %}
- mpls-te on
-{% endif %}
-{% if traffic_engineering.address is defined %}
- mpls-te router-address {{ traffic_engineering.address }}
-{% endif %}
-{% if traffic_engineering.inter_as is defined %}
-{% if traffic_engineering.inter_as.level_1 is defined %}
- mpls-te inter-as level-1
-{% endif %}
-{% if traffic_engineering.inter_as.level_1_2 is defined %}
- mpls-te inter-as level-1-2
-{% endif %}
-{% if traffic_engineering.inter_as.level_2 is defined %}
- mpls-te inter-as level-2-only
-{% endif %}
-{% else %}
- mpls-te inter-as
-{% endif %}
-{% endif %}
-{% if segment_routing is defined %}
-{% if segment_routing.enable is defined %}
- segment-routing on
-{% endif %}
-{% if segment_routing.maximum_label_depth is defined %}
- segment-routing node-msd {{ segment_routing.maximum_label_depth }}
-{% endif %}
-{% if segment_routing.global_block is defined %}
- segment-routing global-block {{ segment_routing.global_block.low_label_value }} {{ segment_routing.global_block.high_label_value }}
-{% endif %}
-{% if segment_routing.local_block is defined %}
- segment-routing local-block {{ segment_routing.global_block.low_label_value }} {{ segment_routing.local_block.high_label_value }}
-{% endif %}
-{% if segment_routing.prefix is defined %}
-{% for prefixes in segment_routing.prefix %}
-{% if segment_routing.prefix[prefixes].absolute is defined %}
-{% if segment_routing.prefix[prefixes].absolute.value is defined %}
- segment-routing prefix {{ prefixes }} absolute {{ segment_routing.prefix[prefixes].absolute.value }}
-{% if segment_routing.prefix[prefixes].absolute.explicit_null is defined %}
- segment-routing prefix {{ prefixes }} absolute {{ segment_routing.prefix[prefixes].absolute.value }} explicit-null
-{% endif %}
-{% if segment_routing.prefix[prefixes].absolute.no_php_flag is defined %}
- segment-routing prefix {{ prefixes }} absolute {{ segment_routing.prefix[prefixes].absolute.value }} no-php-flag
-{% endif %}
-{% endif %}
-{% if segment_routing.prefix[prefixes].index is defined %}
-{% if segment_routing.prefix[prefixes].index.value is defined %}
- segment-routing prefix {{ prefixes }} index {{ segment_routing.prefix[prefixes].index.value }}
-{% if segment_routing.prefix[prefixes].index.explicit_null is defined %}
- segment-routing prefix {{ prefixes }} index {{ segment_routing.prefix[prefixes].index.value }} explicit-null
-{% endif %}
-{% if segment_routing.prefix[prefixes].index.no_php_flag is defined %}
- segment-routing prefix {{ prefixes }} index {{ segment_routing.prefix[prefixes].index.value }} no-php-flag
-{% endif %}
-{% endif %}
-{% endif %}
-{% endif %}
-{% endfor %}
-{% endif %}
-{% endif %}
-{% if spf_delay_ietf is defined and spf_delay_ietf.init_delay is defined and spf_delay_ietf.init_delay is not none %}
- spf-delay-ietf init-delay {{ spf_delay_ietf.init_delay }} short-delay {{ spf_delay_ietf.short_delay }} long-delay {{ spf_delay_ietf.long_delay }} holddown {{ spf_delay_ietf.holddown }} time-to-learn {{ spf_delay_ietf.time_to_learn }}
-{% endif %}
-{% if area_password is defined and area_password is not none %}
-{% if area_password.md5 is defined and area_password.md5 is not none %}
- area-password md5 {{ area_password.md5 }}
-{% elif area_password.plaintext_password is defined and area_password.plaintext_password is not none %}
- area-password clear {{ area_password.plaintext_password }}
-{% endif %}
-{% endif %}
-{% if default_information is defined and default_information.originate is defined and default_information.originate is not none %}
-{% for afi, afi_config in default_information.originate.items() %}
-{% for level, level_config in afi_config.items() %}
- default-information originate {{ afi }} {{ level | replace('_', '-') }} {{ 'always' if level_config.always is defined }} {{ 'route-map ' ~ level_config.route_map if level_config.route_map is defined }} {{ 'metric ' ~ level_config.metric if level_config.metric is defined }}
-{% endfor %}
-{% endfor %}
-{% endif %}
-{% if redistribute is defined %}
-{% if redistribute.ipv4 is defined and redistribute.ipv4 is not none %}
-{% for protocol, protocol_options in redistribute.ipv4.items() %}
-{% for level, level_config in protocol_options.items() %}
-{% if level_config.metric is defined and level_config.metric is not none %}
- redistribute ipv4 {{ protocol }} {{ level | replace('_', '-') }} metric {{ level_config.metric }}
-{% elif level_config.route_map is defined and level_config.route_map is not none %}
- redistribute ipv4 {{ protocol }} {{ level | replace('_', '-') }} route-map {{ level_config.route_map }}
-{% else %}
- redistribute ipv4 {{ protocol }} {{ level | replace('_', '-') }}
-{% endif %}
-{% endfor %}
-{% endfor %}
-{% endif %}
-{% if redistribute.ipv6 is defined and redistribute.ipv6 is not none %}
-{% for protocol, protocol_options in redistribute.ipv6.items() %}
-{% for level, level_config in protocol_options.items() %}
-{% if level_config.metric is defined and level_config.metric is not none %}
- redistribute ipv6 {{ protocol }} {{ level | replace('_', '-') }} metric {{ level_config.metric }}
-{% elif level_config.route_map is defined and level_config.route_map is not none %}
- redistribute ipv6 {{ protocol }} {{ level | replace('_', '-') }} route-map {{ level_config.route_map }}
-{% else %}
- redistribute ipv6 {{ protocol }} {{ level | replace('_', '-') }}
-{% endif %}
-{% endfor %}
-{% endfor %}
-{% endif %}
-{% endif %}
-{% if level is defined and level is not none %}
-{% if level == 'level-2' %}
- is-type level-2-only
-{% else %}
- is-type {{ level }}
-{% endif %}
-{% endif %}
-!
-{% if interface is defined and interface is not none %}
-{% for iface, iface_config in interface.items() %}
-interface {{ iface }} {{ 'vrf ' + vrf if vrf is defined and vrf is not none }}
- ip router isis VyOS
- ipv6 router isis VyOS
-{% if iface_config.bfd is defined %}
- isis bfd
-{% endif %}
-{% if iface_config.network is defined and iface_config.network.point_to_point is defined %}
- isis network point-to-point
-{% endif %}
-{% if iface_config.circuit_type is defined %}
- isis circuit-type {{ iface_config.circuit_type }}
-{% endif %}
-{% if iface_config.hello_interval is defined and iface_config.hello_interval is not none %}
- isis hello-interval {{ iface_config.hello_interval }}
-{% endif %}
-{% if iface_config.hello_multiplier is defined and iface_config.hello_multiplier is not none %}
- isis hello-multiplier {{ iface_config.hello_multiplier }}
-{% endif %}
-{% if iface_config.hello_padding is defined %}
- isis hello padding
-{% endif %}
-{% if iface_config.metric is defined and iface_config.metric is not none %}
- isis metric {{ iface_config.metric }}
-{% endif %}
-{% if iface_config.passive is defined %}
- isis passive
-{% endif %}
-{% if iface_config.password is defined and iface_config.password.plaintext_password is defined and iface_config.password.plaintext_password is not none %}
- isis password clear {{ iface_config.password.plaintext_password }}
-{% endif %}
-{% if iface_config.priority is defined and iface_config.priority is not none %}
- isis priority {{ iface_config.priority }}
-{% endif %}
-{% if iface_config.psnp_interval is defined and iface_config.psnp_interval is not none %}
- isis psnp-interval {{ iface_config.psnp_interval }}
-{% endif %}
-{% if iface_config.no_three_way_handshake is defined %}
- no isis three-way-handshake
-{% endif %}
-{% endfor %}
-{% endif %}
-! \ No newline at end of file
diff --git a/data/templates/frr/ldpd.frr.j2 b/data/templates/frr/ldpd.frr.j2
new file mode 100644
index 000000000..11aff331a
--- /dev/null
+++ b/data/templates/frr/ldpd.frr.j2
@@ -0,0 +1,149 @@
+!
+{% if ldp is vyos_defined %}
+mpls ldp
+{% if ldp.router_id is vyos_defined %}
+ router-id {{ ldp.router_id }}
+{% endif %}
+{% if ldp.parameters.cisco_interop_tlv is vyos_defined %}
+ dual-stack cisco-interop
+{% endif %}
+{% if ldp.parameters.transport_prefer_ipv4 is vyos_defined %}
+ dual-stack transport-connection prefer ipv4
+{% endif %}
+{% if ldp.parameters.ordered_control is vyos_defined %}
+ ordered-control
+{% endif %}
+{% if ldp.neighbor is vyos_defined %}
+{% for neighbor, neighbor_config in ldp.neighbor %}
+{% if neighbor_config.password is vyos_defined %}
+ neighbor {{ neighbors }} password {{ neighbor_config.password }}
+{% endif %}
+{% if neighbor_config.ttl_security is vyos_defined %}
+{% if neighbor_config.ttl_security.disable is vyos_defined %}
+ neighbor {{ neighbors }} ttl-security disable
+{% else %}
+ neighbor {{ neighbors }} ttl-security hops {{ neighbor_config.ttl_security }}
+{% endif %}
+{% endif %}
+{% if neighbor_config.session_holdtime is vyos_defined %}
+ neighbor {{ neighbors }} session holdtime {{ neighbor_config.session_holdtime }}
+{% endif %}
+{% endfor %}
+{% endif %}
+ !
+{% if ldp.discovery.transport_ipv4_address is vyos_defined %}
+ address-family ipv4
+{% if ldp.allocation.ipv4.access_list is vyos_defined %}
+ label local allocate for {{ ldp.allocation.ipv4.access_list }}
+{% else %}
+ label local allocate host-routes
+{% endif %}
+{% if ldp.discovery.transport_ipv4_address is vyos_defined %}
+ discovery transport-address {{ ldp.discovery.transport_ipv4_address }}
+{% endif %}
+{% if ldp.discovery.hello_ipv4_holdtime is vyos_defined %}
+ discovery hello holdtime {{ ldp.discovery.hello_ipv4_holdtime }}
+{% endif %}
+{% if ldp.discovery.hello_ipv4_interval is vyos_defined %}
+ discovery hello interval {{ ldp.discovery.hello_ipv4_interval }}
+{% endif %}
+{% if ldp.discovery.session_ipv4_holdtime is vyos_defined %}
+ session holdtime {{ ldp.discovery.session_ipv4_holdtime }}
+{% endif %}
+{% if ldp.import.ipv4.import_filter.filter_access_list is vyos_defined %}
+{% if ldp.import.ipv4.import_filter.neighbor_access_list is vyos_defined %}
+ label remote accept for {{ ldp.import.ipv4.import_filter.filter_access_list }} from {{ ldp.import.ipv4.import_filter.neighbor_access_list }}
+{% else %}
+ label remote accept for {{ ldp.import.ipv4.import_filter.filter_access_list }}
+{% endif %}
+{% endif %}
+{% if ldp.export.ipv4.explicit_null is vyos_defined %}
+ label local advertise explicit-null
+{% endif %}
+{% if ldp.export.ipv4.export_filter.filter_access_list is vyos_defined %}
+{% if ldp.export.ipv4.export_filter.neighbor_access_list is vyos_defined %}
+ label local advertise for {{ ldp.export.ipv4.export_filter.filter_access_list }} to {{ ldp.export.ipv4.export_filter.neighbor_access_list }}
+{% else %}
+ label local advertise for {{ ldp.export.ipv4.export_filter.filter_access_list }}
+{% endif %}
+{% endif %}
+{% if ldp.targeted_neighbor is vyos_defined %}
+{% if ldp.targeted_neighbor.ipv4.enable is vyos_defined %}
+ discovery targeted-hello accept
+{% endif %}
+{% if ldp.targeted_neighbor.ipv4.hello_holdtime is vyos_defined %}
+ discovery targeted-hello holdtime {{ ldp.targeted_neighbor.ipv4.hello_holdtime }}
+{% endif %}
+{% if ldp.targeted_neighbor.ipv4.hello_interval is vyos_defined %}
+ discovery targeted-hello interval {{ ldp.targeted_neighbor.ipv4.hello_interval }}
+{% endif %}
+{% for addresses in ldp.targeted_neighbor.ipv4.address %}
+ neighbor {{ addresses }} targeted
+{% endfor %}
+{% endif %}
+{% if ldp.interface is vyos_defined %}
+{% for interface in ldp.interface %}
+ interface {{ interface }}
+ exit
+{% endfor %}
+{% endif %}
+ exit-address-family
+{% else %}
+ no address-family ipv4
+{% endif %}
+ !
+{% if ldp.discovery.transport_ipv6_address is vyos_defined %}
+ address-family ipv6
+{% if ldp.allocation.ipv6.access_list6 is vyos_defined %}
+ label local allocate for {{ ldp.allocation.ipv6.access_list6 }}
+{% else %}
+ label local allocate host-routes
+{% endif %}
+{% if ldp.discovery.transport_ipv6_address is vyos_defined %}
+ discovery transport-address {{ ldp.discovery.transport_ipv6_address }}
+{% endif %}
+{% if ldp.discovery.hello_ipv6_holdtime is vyos_defined %}
+ discovery hello holdtime {{ ldp.discovery.hello_ipv6_holdtime }}
+{% endif %}
+{% if ldp.discovery.hello_ipv6_interval is vyos_defined %}
+ discovery hello interval {{ ldp.discovery.hello_ipv6_interval }}
+{% endif %}
+{% if ldp.discovery.session_ipv6_holdtime is vyos_defined %}
+ session holdtime {{ ldp.discovery.session_ipv6_holdtime }}
+{% endif %}
+{% if ldp.import.ipv6.import_filter.filter_access_list6 is vyos_defined %}
+ label remote accept for {{ ldp.import.ipv6.import_filter.filter_access_list6 }} {{ 'from ' ~ ldp.import.ipv6.import_filter.neighbor_access_list6 if ldp.import.ipv6.import_filter.neighbor_access_list6 is vyos_defined }}
+{% endif %}
+{% if ldp.export.ipv6.explicit_null is vyos_defined %}
+ label local advertise explicit-null
+{% endif %}
+{% if ldp.export.ipv6.export_filter.filter_access_list6 is vyos_defined %}
+ label local advertise for {{ ldp.export.ipv6.export_filter.filter_access_list6 }} {{ 'to ' ~ ldp.export.ipv6.export_filter.neighbor_access_list6 if ldp.export.ipv6.export_filter.neighbor_access_list6 is vyos_defined }}
+{% endif %}
+{% if ldp.targeted_neighbor is vyos_defined %}
+{% if ldp.targeted_neighbor.ipv6.enable is vyos_defined %}
+ discovery targeted-hello accept
+{% endif %}
+{% if ldp.targeted_neighbor.ipv6.hello_holdtime is vyos_defined %}
+ discovery targeted-hello holdtime {{ ldp.targeted_neighbor.ipv6.hello_holdtime }}
+{% endif %}
+{% if ldp.targeted_neighbor.ipv6.hello_interval is vyos_defined %}
+ discovery targeted-hello interval {{ ldp.targeted_neighbor.ipv6.hello_interval }}
+{% endif %}
+{% for addresses in ldp.targeted_neighbor.ipv6.address %}
+ neighbor {{ addresses }} targeted
+{% endfor %}
+{% endif %}
+{% if ldp.interface is vyos_defined %}
+{% for interface in ldp.interface %}
+ interface {{ interface }}
+{% endfor %}
+{% endif %}
+ exit-address-family
+{% else %}
+ no address-family ipv6
+{% endif %}
+ !
+exit
+{% endif %}
+!
diff --git a/data/templates/frr/ldpd.frr.tmpl b/data/templates/frr/ldpd.frr.tmpl
deleted file mode 100644
index 0a5411552..000000000
--- a/data/templates/frr/ldpd.frr.tmpl
+++ /dev/null
@@ -1,187 +0,0 @@
-!
-{% if ldp is defined %}
-mpls ldp
-{% if ldp.router_id is defined %}
-router-id {{ ldp.router_id }}
-{% endif %}
-{% if ldp.parameters is defined %}
-{% if ldp.parameters.cisco_interop_tlv is defined %}
-dual-stack cisco-interop
-{% endif %}
-{% if ldp.parameters.transport_prefer_ipv4 is defined%}
-dual-stack transport-connection prefer ipv4
-{% endif %}
-{% if ldp.parameters.ordered_control is defined%}
-ordered-control
-{% endif %}
-{% endif %}
-{% if ldp.neighbor is defined %}
-{% for neighbors in ldp.neighbor %}
-{% if ldp.neighbor[neighbors].password is defined %}
-neighbor {{neighbors}} password {{ldp.neighbor[neighbors].password}}
-{% endif %}
-{% if ldp.neighbor[neighbors].ttl_security is defined %}
-{% if 'disable' in ldp.neighbor[neighbors].ttl_security %}
-neighbor {{neighbors}} ttl-security disable
-{% else %}
-neighbor {{neighbors}} ttl-security hops {{ldp.neighbor[neighbors].ttl_security}}
-{% endif %}
-{% endif %}
-{% if ldp.neighbor[neighbors].session_holdtime is defined %}
-neighbor {{neighbors}} session holdtime {{ldp.neighbor[neighbors].session_holdtime}}
-{% endif %}
-{% endfor %}
-{% endif %}
-!
-{% if ldp.discovery is defined %}
-{% if ldp.discovery.transport_ipv4_address is defined %}
-address-family ipv4
-{% if ldp.allocation is defined %}
-{% if ldp.allocation.ipv4 is defined %}
-{% if ldp.allocation.ipv4.access_list is defined %}
-label local allocate for {{ ldp.allocation.ipv4.access_list }}
-{% endif %}
-{% endif %}
-{% else %}
-label local allocate host-routes
-{% endif %}
-{% if ldp.discovery.transport_ipv4_address is defined %}
-discovery transport-address {{ ldp.discovery.transport_ipv4_address }}
-{% endif %}
-{% if ldp.discovery.hello_ipv4_holdtime is defined %}
-discovery hello holdtime {{ ldp.discovery.hello_ipv4_holdtime }}
-{% endif %}
-{% if ldp.discovery.hello_ipv4_interval is defined %}
-discovery hello interval {{ ldp.discovery.hello_ipv4_interval }}
-{% endif %}
-{% if ldp.discovery.session_ipv4_holdtime is defined %}
-session holdtime {{ ldp.discovery.session_ipv4_holdtime }}
-{% endif %}
-{% if ldp.import is defined %}
-{% if ldp.import.ipv4 is defined %}
-{% if ldp.import.ipv4.import_filter is defined %}
-{% if ldp.import.ipv4.import_filter.filter_access_list is defined %}
-{% if ldp.import.ipv4.import_filter.neighbor_access_list is defined %}
-label remote accept for {{ ldp.import.ipv4.import_filter.filter_access_list }} from {{ ldp.import.ipv4.import_filter.neighbor_access_list }}
-{% else %}
-label remote accept for {{ ldp.import.ipv4.import_filter.filter_access_list }}
-{% endif %}
-{% endif %}
-{% endif %}
-{% endif %}
-{% endif %}
-{% if ldp.export is defined %}
-{% if ldp.export.ipv4 is defined %}
-{% if ldp.export.ipv4.explicit_null is defined %}
-label local advertise explicit-null
-{% endif %}
-{% if ldp.export.ipv4.export_filter is defined %}
-{% if ldp.export.ipv4.export_filter.filter_access_list is defined %}
-{% if ldp.export.ipv4.export_filter.neighbor_access_list is defined %}
-label local advertise for {{ ldp.export.ipv4.export_filter.filter_access_list }} to {{ ldp.export.ipv4.export_filter.neighbor_access_list }}
-{% else %}
-label local advertise for {{ ldp.export.ipv4.export_filter.filter_access_list }}
-{% endif %}
-{% endif %}
-{% endif %}
-{% endif %}
-{% endif %}
-{% if ldp.targeted_neighbor is defined %}
-{% if ldp.targeted_neighbor.ipv4.enable is defined %}
-discovery targeted-hello accept
-{% endif %}
-{% if ldp.targeted_neighbor.ipv4.hello_holdtime is defined %}
-discovery targeted-hello holdtime {{ ldp.targeted_neighbor.ipv4.hello_holdtime }}
-{% endif %}
-{% if ldp.targeted_neighbor.ipv4.hello_interval is defined %}
-discovery targeted-hello interval {{ ldp.targeted_neighbor.ipv4.hello_interval }}
-{% endif %}
-{% for addresses in ldp.targeted_neighbor.ipv4.address %}
-neighbor {{addresses}} targeted
-{% endfor %}
-{% endif %}
-{% for interfaces in ldp.interface %}
-interface {{interfaces}}
-{% endfor %}
-exit-address-family
-{% else %}
-no address-family ipv4
-{% endif %}
-{% endif %}
-!
-{% if ldp.discovery is defined %}
-{% if ldp.discovery.transport_ipv6_address is defined %}
-address-family ipv6
-{% if ldp.allocation is defined %}
-{% if ldp.allocation.ipv6 is defined %}
-{% if ldp.allocation.ipv6.access_list6 is defined %}
-label local allocate for {{ ldp.allocation.ipv6.access_list6 }}
-{% endif %}
-{% endif %}
-{% else %}
-label local allocate host-routes
-{% endif %}
-{% if ldp.discovery.transport_ipv6_address is defined %}
-discovery transport-address {{ ldp.discovery.transport_ipv6_address }}
-{% endif %}
-{% if ldp.discovery.hello_ipv6_holdtime is defined %}
-discovery hello holdtime {{ ldp.discovery.hello_ipv6_holdtime }}
-{% endif %}
-{% if ldp.discovery.hello_ipv6_interval is defined %}
-discovery hello interval {{ ldp.discovery.hello_ipv6_interval }}
-{% endif %}
-{% if ldp.discovery.session_ipv6_holdtime is defined %}
-session holdtime {{ ldp.discovery.session_ipv6_holdtime }}
-{% endif %}
-{% if ldp.import is defined %}
-{% if ldp.import.ipv6 is defined %}
-{% if ldp.import.ipv6.import_filter is defined %}
-{% if ldp.import.ipv6.import_filter.filter_access_list6 is defined %}
-{% if ldp.import.ipv6.import_filter.neighbor_access_list6 is defined %}
-label remote accept for {{ ldp.import.ipv6.import_filter.filter_access_list6 }} from {{ ldp.import.ipv6.import_filter.neighbor_access_list6 }}
-{% else %}
-label remote accept for {{ ldp.import.ipv6.import_filter.filter_access_list6 }}
-{% endif %}
-{% endif %}
-{% endif %}
-{% endif %}
-{% endif %}
-{% if ldp.export is defined %}
-{% if ldp.export.ipv6 is defined %}
-{% if ldp.export.ipv6.explicit_null is defined %}
-label local advertise explicit-null
-{% endif %}
-{% if ldp.export.ipv6.export_filter is defined %}
-{% if ldp.export.ipv6.export_filter.filter_access_list6 is defined %}
-{% if ldp.export.ipv6.export_filter.neighbor_access_list6 is defined %}
-label local advertise for {{ ldp.export.ipv6.export_filter.filter_access_list6 }} to {{ ldp.export.ipv6.export_filter.neighbor_access_list6 }}
-{% else %}
-label local advertise for {{ ldp.export.ipv6.export_filter.filter_access_list6 }}
-{% endif %}
-{% endif %}
-{% endif %}
-{% endif %}
-{% endif %}
-{% if ldp.targeted_neighbor is defined %}
-{% if ldp.targeted_neighbor.ipv6.enable is defined %}
-discovery targeted-hello accept
-{% endif %}
-{% if ldp.targeted_neighbor.ipv6.hello_holdtime is defined %}
-discovery targeted-hello holdtime {{ ldp.targeted_neighbor.ipv6.hello_holdtime }}
-{% endif %}
-{% if ldp.targeted_neighbor.ipv6.hello_interval is defined %}
-discovery targeted-hello interval {{ ldp.targeted_neighbor.ipv6.hello_interval }}
-{% endif %}
-{% for addresses in ldp.targeted_neighbor.ipv6.address %}
-neighbor {{addresses}} targeted
-{% endfor %}
-{% endif %}
-{% for interfaces in ldp.interface %}
-interface {{interfaces}}
-{% endfor %}
-exit-address-family
-{% else %}
-no address-family ipv6
-{% endif %}
-{% endif %}
-{% endif %}
diff --git a/data/templates/frr/ospf6d.frr.j2 b/data/templates/frr/ospf6d.frr.j2
new file mode 100644
index 000000000..84394ed1a
--- /dev/null
+++ b/data/templates/frr/ospf6d.frr.j2
@@ -0,0 +1,95 @@
+!
+{% if interface is vyos_defined %}
+{% for iface, iface_config in interface.items() %}
+interface {{ iface }}
+{% if iface_config.area is vyos_defined %}
+ ipv6 ospf6 area {{ iface_config.area }}
+{% endif %}
+{% if iface_config.cost is vyos_defined %}
+ ipv6 ospf6 cost {{ iface_config.cost }}
+{% endif %}
+{% if iface_config.priority is vyos_defined %}
+ ipv6 ospf6 priority {{ iface_config.priority }}
+{% endif %}
+{% if iface_config.hello_interval is vyos_defined %}
+ ipv6 ospf6 hello-interval {{ iface_config.hello_interval }}
+{% endif %}
+{% if iface_config.retransmit_interval is vyos_defined %}
+ ipv6 ospf6 retransmit-interval {{ iface_config.retransmit_interval }}
+{% endif %}
+{% if iface_config.transmit_delay is vyos_defined %}
+ ipv6 ospf6 transmit-delay {{ iface_config.transmit_delay }}
+{% endif %}
+{% if iface_config.dead_interval is vyos_defined %}
+ ipv6 ospf6 dead-interval {{ iface_config.dead_interval }}
+{% endif %}
+{% if iface_config.bfd is vyos_defined %}
+ ipv6 ospf6 bfd
+{% endif %}
+{% if iface_config.bfd.profile is vyos_defined %}
+ ipv6 ospf6 bfd profile {{ iface_config.bfd.profile }}
+{% endif %}
+{% if iface_config.mtu_ignore is vyos_defined %}
+ ipv6 ospf6 mtu-ignore
+{% endif %}
+{% if iface_config.ifmtu is vyos_defined %}
+ ipv6 ospf6 ifmtu {{ iface_config.ifmtu }}
+{% endif %}
+{% if iface_config.network is vyos_defined %}
+ ipv6 ospf6 network {{ iface_config.network }}
+{% endif %}
+{% if iface_config.instance_id is vyos_defined %}
+ ipv6 ospf6 instance-id {{ iface_config.instance_id }}
+{% endif %}
+{% if iface_config.passive is vyos_defined %}
+ ipv6 ospf6 passive
+{% endif %}
+exit
+!
+{% endfor %}
+{% endif %}
+!
+router ospf6 {{ 'vrf ' ~ vrf if vrf is vyos_defined }}
+{% if area is vyos_defined %}
+{% for area_id, area_config in area.items() %}
+{% if area_config.area_type is vyos_defined %}
+{% for type, type_config in area_config.area_type.items() %}
+ area {{ area_id }} {{ type }} {{ 'default-information-originate' if type_config.default_information_originate is vyos_defined }} {{ 'no-summary' if type_config.no_summary is vyos_defined }}
+{% endfor %}
+{% endif %}
+{% if area_config.range is vyos_defined %}
+{% for prefix, prefix_config in area_config.range.items() %}
+ area {{ area_id }} range {{ prefix }} {{ 'advertise' if prefix_config.advertise is vyos_defined }} {{ 'not-advertise' if prefix_config.not_advertise is vyos_defined }}
+{% endfor %}
+{% endif %}
+{% if area_config.export_list is vyos_defined %}
+ area {{ area_id }} export-list {{ area_config.export_list }}
+{% endif %}
+{% if area_config.import_list is vyos_defined %}
+ area {{ area_id }} import-list {{ area_config.import_list }}
+{% endif %}
+{% endfor %}
+{% endif %}
+ auto-cost reference-bandwidth {{ auto_cost.reference_bandwidth }}
+{% if default_information.originate is vyos_defined %}
+ default-information originate {{ 'always' if default_information.originate.always is vyos_defined }} {{ 'metric ' ~ default_information.originate.metric if default_information.originate.metric is vyos_defined }} {{ 'metric-type ' ~ default_information.originate.metric_type if default_information.originate.metric_type is vyos_defined }} {{ 'route-map ' ~ default_information.originate.route_map if default_information.originate.route_map is vyos_defined }}
+{% endif %}
+{% if distance.global is vyos_defined %}
+ distance {{ distance.global }}
+{% endif %}
+{% if distance.ospfv3 is vyos_defined %}
+ distance ospf6 {{ 'intra-area ' ~ distance.ospfv3.intra_area if distance.ospfv3.intra_area is vyos_defined }} {{ 'inter-area ' ~ distance.ospfv3.inter_area if distance.ospfv3.inter_area is vyos_defined }} {{ 'external ' ~ distance.ospfv3.external if distance.ospfv3.external is vyos_defined }}
+{% endif %}
+{% if log_adjacency_changes is vyos_defined %}
+ log-adjacency-changes {{ "detail" if log_adjacency_changes.detail is vyos_defined }}
+{% endif %}
+{% if parameters.router_id is vyos_defined %}
+ ospf6 router-id {{ parameters.router_id }}
+{% endif %}
+{% if redistribute is vyos_defined %}
+{% for protocol, options in redistribute.items() %}
+ redistribute {{ protocol }} {{ 'route-map ' ~ options.route_map if options.route_map is vyos_defined }}
+{% endfor %}
+{% endif %}
+exit
+!
diff --git a/data/templates/frr/ospf6d.frr.tmpl b/data/templates/frr/ospf6d.frr.tmpl
deleted file mode 100644
index a8c53738f..000000000
--- a/data/templates/frr/ospf6d.frr.tmpl
+++ /dev/null
@@ -1,92 +0,0 @@
-!
-{% if interface is defined and interface is not none %}
-{% for iface, iface_config in interface.items() %}
-interface {{ iface }}
-{% if iface_config.cost is defined and iface_config.cost is not none %}
- ipv6 ospf6 cost {{ iface_config.cost }}
-{% endif %}
-{% if iface_config.priority is defined and iface_config.priority is not none %}
- ipv6 ospf6 priority {{ iface_config.priority }}
-{% endif %}
-{% if iface_config.hello_interval is defined and iface_config.hello_interval is not none %}
- ipv6 ospf6 hello-interval {{ iface_config.hello_interval }}
-{% endif %}
-{% if iface_config.retransmit_interval is defined and iface_config.retransmit_interval is not none %}
- ipv6 ospf6 retransmit-interval {{ iface_config.retransmit_interval }}
-{% endif %}
-{% if iface_config.transmit_delay is defined and iface_config.transmit_delay is not none %}
- ipv6 ospf6 transmit-delay {{ iface_config.transmit_delay }}
-{% endif %}
-{% if iface_config.dead_interval is defined and iface_config.dead_interval is not none %}
- ipv6 ospf6 dead-interval {{ iface_config.dead_interval }}
-{% endif %}
-{% if iface_config.bfd is defined %}
- ipv6 ospf6 bfd
-{% endif %}
-{% if iface_config.mtu_ignore is defined %}
- ipv6 ospf6 mtu-ignore
-{% endif %}
-{% if iface_config.ifmtu is defined and iface_config.ifmtu is not none %}
- ipv6 ospf6 ifmtu {{ iface_config.ifmtu }}
-{% endif %}
-{% if iface_config.network is defined and iface_config.network is not none %}
- ipv6 ospf6 network {{ iface_config.network }}
-{% endif %}
-{% if iface_config.instance_id is defined and iface_config.instance_id is not none %}
- ipv6 ospf6 instance-id {{ iface_config.instance_id }}
-{% endif %}
-{% if iface_config.passive is defined %}
- ipv6 ospf6 passive
-{% endif %}
-!
-{% endfor %}
-{% endif %}
-!
-router ospf6
-{% if area is defined and area is not none %}
-{% for area_id, area_config in area.items() %}
-{% if area_config.interface is defined and area_config.interface is not none %}
-{% for interface in area_config.interface %}
- interface {{ interface }} area {{ area_id }}
-{% endfor %}
-{% endif %}
-{% if area_config.area_type is defined and area_config.area_type is not none %}
-{% for type, type_config in area_config.area_type.items() %}
- area {{ area_id }} {{ type }} {{ 'no-summary' if type_config.no_summary is defined }}
-{% endfor %}
-{% endif %}
-{% if area_config.range is defined and area_config.range is not none %}
-{% for prefix, prefix_config in area_config.range.items() %}
- area {{ area_id }} range {{ prefix }} {{ 'advertise' if prefix_config.advertise is defined }} {{ 'not-advertise' if prefix_config.not_advertise is defined }}
-{% endfor %}
-{% endif %}
-{% if area_config.export_list is defined and area_config.export_list is not none %}
- area {{ area_id }} export-list {{ area_config.export_list }}
-{% endif %}
-{% if area_config.import_list is defined and area_config.import_list is not none %}
- area {{ area_id }} import-list {{ area_config.import_list }}
-{% endif %}
-{% endfor %}
-{% endif %}
-{% if distance is defined and distance is not none %}
-{% if distance.global is defined and distance.global is not none %}
- distance {{ distance.global }}
-{% endif %}
-{% if distance.ospfv3 is defined and distance.ospfv3 is not none %}
- distance ospf6 {{ 'intra-area ' + distance.ospfv3.intra_area if distance.ospfv3.intra_area is defined }} {{ 'inter-area ' + distance.ospfv3.inter_area if distance.ospfv3.inter_area is defined }} {{ 'external ' + distance.ospfv3.external if distance.ospfv3.external is defined }}
-{% endif %}
-{% endif %}
-{% if log_adjacency_changes is defined %}
- log-adjacency-changes {{ "detail" if log_adjacency_changes.detail is defined }}
-{% endif %}
-{% if parameters is defined and parameters is not none %}
-{% if parameters.router_id is defined and parameters.router_id is not none %}
- ospf6 router-id {{ parameters.router_id }}
-{% endif %}
-{% endif %}
-{% if redistribute is defined and redistribute is not none %}
-{% for protocol, options in redistribute.items() %}
- redistribute {{ protocol }} {{ 'route-map ' + options.route_map if options.route_map is defined }}
-{% endfor %}
-{% endif %}
-!
diff --git a/data/templates/frr/ospfd.frr.j2 b/data/templates/frr/ospfd.frr.j2
new file mode 100644
index 000000000..427fc8be7
--- /dev/null
+++ b/data/templates/frr/ospfd.frr.j2
@@ -0,0 +1,189 @@
+!
+{% if interface is vyos_defined %}
+{% for iface, iface_config in interface.items() %}
+interface {{ iface }}
+{% if iface_config.authentication.plaintext_password is vyos_defined %}
+ ip ospf authentication-key {{ iface_config.authentication.plaintext_password }}
+{% elif iface_config.authentication.md5 is vyos_defined %}
+ ip ospf authentication message-digest
+{% if iface_config.authentication.md5.key_id is vyos_defined %}
+{% for key, key_config in iface_config.authentication.md5.key_id.items() %}
+ ip ospf message-digest-key {{ key }} md5 {{ key_config.md5_key }}
+{% endfor %}
+{% endif %}
+{% endif %}
+{% if iface_config.area is vyos_defined %}
+ ip ospf area {{ iface_config.area }}
+{% endif %}
+{% if iface_config.bandwidth is vyos_defined %}
+ bandwidth {{ iface_config.bandwidth }}
+{% endif %}
+{% if iface_config.cost is vyos_defined %}
+ ip ospf cost {{ iface_config.cost }}
+{% endif %}
+{% if iface_config.priority is vyos_defined %}
+ ip ospf priority {{ iface_config.priority }}
+{% endif %}
+{% if iface_config.hello_interval is vyos_defined %}
+ ip ospf hello-interval {{ iface_config.hello_interval }}
+{% endif %}
+{% if iface_config.retransmit_interval is vyos_defined %}
+ ip ospf retransmit-interval {{ iface_config.retransmit_interval }}
+{% endif %}
+{% if iface_config.transmit_delay is vyos_defined %}
+ ip ospf transmit-delay {{ iface_config.transmit_delay }}
+{% endif %}
+{% if iface_config.dead_interval is vyos_defined %}
+ ip ospf dead-interval {{ iface_config.dead_interval }}
+{% elif iface_config.hello_multiplier is vyos_defined %}
+ ip ospf dead-interval minimal hello-multiplier {{ iface_config.hello_multiplier }}
+{% endif %}
+{% if iface_config.bfd is vyos_defined %}
+ ip ospf bfd
+{% endif %}
+{% if iface_config.bfd.profile is vyos_defined %}
+ ip ospf bfd profile {{ iface_config.bfd.profile }}
+{% endif %}
+{% if iface_config.mtu_ignore is vyos_defined %}
+ ip ospf mtu-ignore
+{% endif %}
+{% if iface_config.network is vyos_defined %}
+ ip ospf network {{ iface_config.network }}
+{% endif %}
+{% if iface_config.passive is vyos_defined %}
+ {{ 'no ' if iface_config.passive.disable is vyos_defined }}ip ospf passive
+{% endif %}
+exit
+!
+{% endfor %}
+{% endif %}
+!
+router ospf {{ 'vrf ' ~ vrf if vrf is vyos_defined }}
+{% if access_list is vyos_defined %}
+{% for acl, acl_config in access_list.items() %}
+{% for protocol in acl_config.export if acl_config.export is vyos_defined %}
+ distribute-list {{ acl }} out {{ protocol }}
+{% endfor %}
+{% endfor %}
+{% endif %}
+{% if area is vyos_defined %}
+{% for area_id, area_config in area.items() %}
+{% if area_config.area_type is vyos_defined %}
+{% for type, type_config in area_config.area_type.items() if type != 'normal' %}
+ area {{ area_id }} {{ type }} {{ 'no-summary' if type_config.no_summary is vyos_defined }}
+{% if type_config.default_cost is vyos_defined %}
+ area {{ area_id }} default-cost {{ type_config.default_cost }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if area_config.authentication is vyos_defined %}
+ area {{ area_id }} authentication {{ 'message-digest' if area_config.authentication is vyos_defined('md5') }}
+{% endif %}
+{% for network in area_config.network if area_config.network is vyos_defined %}
+ network {{ network }} area {{ area_id }}
+{% endfor %}
+{% if area_config.range is vyos_defined %}
+{% for range, range_config in area_config.range.items() %}
+{% if range_config.cost is vyos_defined %}
+ area {{ area_id }} range {{ range }} cost {{ range_config.cost }}
+{% endif %}
+{% if range_config.not_advertise is vyos_defined %}
+ area {{ area_id }} range {{ range }} not-advertise
+{% endif %}
+{% if range_config.substitute is vyos_defined %}
+ area {{ area_id }} range {{ range }} substitute {{ range_config.substitute }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if area_config.export_list is vyos_defined %}
+ area {{ area_id }} export-list {{ area_config.export_list }}
+{% endif %}
+{% if area_config.import_list is vyos_defined %}
+ area {{ area_id }} import-list {{ area_config.import_list }}
+{% endif %}
+{% if area_config.shortcut is vyos_defined %}
+ area {{ area_id }} shortcut {{ area_config.shortcut }}
+{% endif %}
+{% if area_config.virtual_link is vyos_defined %}
+{% for link, link_config in area_config.virtual_link.items() %}
+{% if link_config.authentication.plaintext_password is vyos_defined %}
+ area {{ area_id }} virtual-link {{ link }} authentication-key {{ link_config.authentication.plaintext_password }}
+{% elif link_config.authentication.md5.key_id is vyos_defined %}
+{% for key, key_config in link_config.authentication.md5.key_id.items() %}
+ area {{ area_id }} virtual-link {{ link }} message-digest-key {{ key }} md5 {{ key_config.md5_key }}
+{% endfor %}
+{% endif %}
+{# The following values are default values #}
+ area {{ area_id }} virtual-link {{ link }} hello-interval {{ link_config.hello_interval }} retransmit-interval {{ link_config.retransmit_interval }} transmit-delay {{ link_config.transmit_delay }} dead-interval {{ link_config.dead_interval }}
+{% endfor %}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if auto_cost.reference_bandwidth is vyos_defined %}
+ auto-cost reference-bandwidth {{ auto_cost.reference_bandwidth }}
+{% endif %}
+{% if default_information.originate is vyos_defined %}
+ default-information originate {{ 'always' if default_information.originate.always is vyos_defined }} {{ 'metric ' + default_information.originate.metric if default_information.originate.metric is vyos_defined }} {{ 'metric-type ' + default_information.originate.metric_type if default_information.originate.metric_type is vyos_defined }} {{ 'route-map ' + default_information.originate.route_map if default_information.originate.route_map is vyos_defined }}
+{% endif %}
+{% if default_metric is vyos_defined %}
+ default-metric {{ default_metric }}
+{% endif %}
+{% if maximum_paths is vyos_defined %}
+ maximum-paths {{ maximum_paths }}
+{% endif %}
+{% if distance.global is vyos_defined %}
+ distance {{ distance.global }}
+{% endif %}
+{% if distance.ospf is vyos_defined %}
+ distance ospf {{ 'intra-area ' + distance.ospf.intra_area if distance.ospf.intra_area is vyos_defined }} {{ 'inter-area ' + distance.ospf.inter_area if distance.ospf.inter_area is vyos_defined }} {{ 'external ' + distance.ospf.external if distance.ospf.external is vyos_defined }}
+{% endif %}
+{% if log_adjacency_changes is vyos_defined %}
+ log-adjacency-changes {{ "detail" if log_adjacency_changes.detail is vyos_defined }}
+{% endif %}
+{% if max_metric.router_lsa.administrative is vyos_defined %}
+ max-metric router-lsa administrative
+{% endif %}
+{% if max_metric.router_lsa.on_shutdown is vyos_defined %}
+ max-metric router-lsa on-shutdown {{ max_metric.router_lsa.on_shutdown }}
+{% endif %}
+{% if max_metric.router_lsa.on_startup is vyos_defined %}
+ max-metric router-lsa on-startup {{ max_metric.router_lsa.on_startup }}
+{% endif %}
+{% if mpls_te.enable is vyos_defined %}
+ mpls-te on
+ mpls-te router-address {{ mpls_te.router_address }}
+{% endif %}
+{% if neighbor is vyos_defined %}
+{% for address, address_config in neighbor.items() %}
+ neighbor {{ address }} {{ 'priority ' + address_config.priority if address_config.priority is vyos_defined }} {{ 'poll-interval ' + address_config.poll_interval if address_config.poll_interval is vyos_defined }}
+{% endfor %}
+{% endif %}
+{% if parameters.abr_type is vyos_defined %}
+ ospf abr-type {{ parameters.abr_type }}
+{% endif %}
+{% if parameters.router_id is vyos_defined %}
+ ospf router-id {{ parameters.router_id }}
+{% endif %}
+{% if passive_interface.default is vyos_defined %}
+ passive-interface default
+{% endif %}
+{% if redistribute is vyos_defined %}
+{% for protocol, protocols_options in redistribute.items() %}
+{% if protocol == 'table' %}
+{% for table, table_options in protocols_options.items() %}
+ redistribute {{ protocol }} {{ table }} {{ 'metric ' + table_options.metric if table_options.metric is vyos_defined }} {{ 'metric-type ' + table_options.metric_type if table_options.metric_type is vyos_defined }} {{ 'route-map ' + table_options.route_map if table_options.route_map is vyos_defined }}
+{% endfor %}
+{% else %}
+ redistribute {{ protocol }} {{ 'metric ' + protocols_options.metric if protocols_options.metric is vyos_defined }} {{ 'metric-type ' + protocols_options.metric_type if protocols_options.metric_type is vyos_defined }} {{ 'route-map ' + protocols_options.route_map if protocols_options.route_map is vyos_defined }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if refresh.timers is vyos_defined %}
+ refresh timer {{ refresh.timers }}
+{% endif %}
+{% if timers.throttle.spf.delay is vyos_defined and timers.throttle.spf.initial_holdtime is vyos_defined and timers.throttle.spf.max_holdtime is vyos_defined %}
+{# Timer values have default values #}
+ timers throttle spf {{ timers.throttle.spf.delay }} {{ timers.throttle.spf.initial_holdtime }} {{ timers.throttle.spf.max_holdtime }}
+{% endif %}
+exit
+!
diff --git a/data/templates/frr/ospfd.frr.tmpl b/data/templates/frr/ospfd.frr.tmpl
deleted file mode 100644
index 90a6bbd56..000000000
--- a/data/templates/frr/ospfd.frr.tmpl
+++ /dev/null
@@ -1,192 +0,0 @@
-!
-{% if interface is defined and interface is not none %}
-{% for iface, iface_config in interface.items() %}
-interface {{ iface }} {{ 'vrf ' + vrf if vrf is defined and vrf is not none }}
-{% if iface_config.authentication is defined and iface_config.authentication is not none %}
-{% if iface_config.authentication.plaintext_password is defined and iface_config.authentication.plaintext_password is not none %}
- ip ospf authentication-key {{ iface_config.authentication.plaintext_password }}
-{% elif iface_config.authentication.md5 is defined %}
- ip ospf authentication message-digest
-{% if iface_config.authentication.md5.key_id is defined and iface_config.authentication.md5.key_id is not none %}
-{% for key, key_config in iface_config.authentication.md5.key_id.items() %}
- ip ospf message-digest-key {{ key }} md5 {{ key_config.md5_key }}
-{% endfor %}
-{% endif %}
-{% endif %}
-{% endif %}
-{% if iface_config.area is defined and iface_config.area is not none %}
- ip ospf area {{ iface_config.area }}
-{% endif %}
-{% if iface_config.bandwidth is defined and iface_config.bandwidth is not none %}
- bandwidth {{ iface_config.bandwidth }}
-{% endif %}
-{% if iface_config.cost is defined and iface_config.cost is not none %}
- ip ospf cost {{ iface_config.cost }}
-{% endif %}
-{% if iface_config.priority is defined and iface_config.priority is not none %}
- ip ospf priority {{ iface_config.priority }}
-{% endif %}
-{% if iface_config.hello_interval is defined and iface_config.hello_interval is not none %}
- ip ospf hello-interval {{ iface_config.hello_interval }}
-{% endif %}
-{% if iface_config.retransmit_interval is defined and iface_config.retransmit_interval is not none %}
- ip ospf retransmit-interval {{ iface_config.retransmit_interval }}
-{% endif %}
-{% if iface_config.transmit_delay is defined and iface_config.transmit_delay is not none %}
- ip ospf transmit-delay {{ iface_config.transmit_delay }}
-{% endif %}
-{% if iface_config.dead_interval is defined and iface_config.dead_interval is not none %}
- ip ospf dead-interval {{ iface_config.dead_interval }}
-{% elif iface_config.hello_multiplier is defined and iface_config.hello_multiplier is not none %}
- ip ospf dead-interval minimal hello-multiplier {{ iface_config.hello_multiplier }}
-{% endif %}
-{% if iface_config.bfd is defined %}
- ip ospf bfd
-{% endif %}
-{% if iface_config.mtu_ignore is defined %}
- ip ospf mtu-ignore
-{% endif %}
-{% if iface_config.network is defined and iface_config.network is not none %}
- ip ospf network {{ iface_config.network }}
-{% endif %}
-!
-{% endfor %}
-{% endif %}
-!
-router ospf {{ 'vrf ' + vrf if vrf is defined and vrf is not none }}
-{% if access_list is defined and access_list is not none %}
-{% for acl, acl_config in access_list.items() %}
-{% for protocol in acl_config.export if acl_config.export is defined %}
- distribute-list {{ acl }} out {{ protocol }}
-{% endfor %}
-{% endfor %}
-{% endif %}
-{% if area is defined and area is not none %}
-{% for area_id, area_config in area.items() %}
-{% if area_config.area_type is defined and area_config.area_type is not none %}
-{% for type, type_config in area_config.area_type.items() if type != 'normal' %}
- area {{ area_id }} {{ type }} {{ 'no-summary' if type_config.no_summary is defined }}
-{% if type_config.default_cost is defined and type_config.default_cost is not none %}
- area {{ area_id }} default-cost {{ type_config.default_cost }}
-{% endif %}
-{% endfor %}
-{% endif %}
-{% if area_config.authentication is defined and area_config.authentication is not none %}
- area {{ area_id }} authentication {{ 'message-digest' if area_config.authentication == 'md5' }}
-{% endif %}
-{% for network in area_config.network if area_config.network is defined %}
- network {{ network }} area {{ area_id }}
-{% endfor %}
-{% if area_config.range is defined and area_config.range is not none %}
-{% for range, range_config in area_config.range.items() %}
-{% if range_config.cost is defined and range_config.cost is not none %}
- area {{ area_id }} range {{ range }} cost {{ range_config.cost }}
-{% endif %}
-{% if range_config.not_advertise is defined %}
- area {{ area_id }} range {{ range }} not-advertise
-{% endif %}
-{% if range_config.substitute is defined and range_config.substitute is not none %}
- area {{ area_id }} range {{ range }} substitute {{ range_config.substitute }}
-{% endif %}
-{% endfor %}
-{% endif %}
-{% if area_config.shortcut is defined and area_config.shortcut is not none %}
- area {{ area_id }} shortcut {{ area_config.shortcut }}
-{% endif %}
-{% if area_config.virtual_link is defined and area_config.virtual_link is not none %}
-{% for link, link_config in area_config.virtual_link.items() %}
-{% if link_config.authentication is defined and link_config.authentication is not none %}
-{% if link_config.authentication.plaintext_password is defined and link_config.authentication.plaintext_password is not none %}
- area {{ area_id }} virtual-link {{ link }} authentication-key {{ link_config.authentication.plaintext_password }}
-{% elif link_config.authentication.md5 is defined and link_config.authentication.md5.key_id is defined and link_config.authentication.md5.key_id is not none %}
-{% for key, key_config in link_config.authentication.md5.key_id.items() %}
- area {{ area_id }} virtual-link {{ link }} message-digest-key {{ key }} md5 {{ key_config.md5_key }}
-{% endfor %}
-{% endif %}
-{% endif %}
-{# The following values are default values #}
- area {{ area_id }} virtual-link {{ link }} hello-interval {{ link_config.hello_interval }} retransmit-interval {{ link_config.retransmit_interval }} transmit-delay {{ link_config.transmit_delay }} dead-interval {{ link_config.dead_interval }}
-{% endfor %}
-{% endif %}
-{% endfor %}
-{% endif %}
-{% if auto_cost is defined and auto_cost.reference_bandwidth is defined and auto_cost.reference_bandwidth is not none %}
- auto-cost reference-bandwidth {{ auto_cost.reference_bandwidth }}
-{% endif %}
-{% if default_information is defined and default_information.originate is defined and default_information.originate is not none %}
- default-information originate {{ 'always' if default_information.originate.always is defined }} {{ 'metric ' + default_information.originate.metric if default_information.originate.metric is defined }} {{ 'metric-type ' + default_information.originate.metric_type if default_information.originate.metric_type is defined }} {{ 'route-map ' + default_information.originate.route_map if default_information.originate.route_map is defined }}
-{% endif %}
-{% if default_metric is defined and default_metric is not none %}
- default-metric {{ default_metric }}
-{% endif %}
-{% if distance is defined and distance is not none %}
-{% if distance.global is defined and distance.global is not none %}
- distance {{ distance.global }}
-{% endif %}
-{% if distance.ospf is defined and distance.ospf is not none %}
- distance ospf {{ 'intra-area ' + distance.ospf.intra_area if distance.ospf.intra_area is defined }} {{ 'inter-area ' + distance.ospf.inter_area if distance.ospf.inter_area is defined }} {{ 'external ' + distance.ospf.external if distance.ospf.external is defined }}
-{% endif %}
-{% endif %}
-{% if log_adjacency_changes is defined %}
- log-adjacency-changes {{ "detail" if log_adjacency_changes.detail is defined }}
-{% endif %}
-{% if max_metric is defined and max_metric.router_lsa is defined and max_metric.router_lsa is not none %}
-{% if max_metric.router_lsa.administrative is defined %}
- max-metric router-lsa administrative
-{% endif %}
-{% if max_metric.router_lsa.on_shutdown is defined and max_metric.router_lsa.on_shutdown is not none %}
- max-metric router-lsa on-shutdown {{ max_metric.router_lsa.on_shutdown }}
-{% endif %}
-{% if max_metric.router_lsa.on_startup is defined and max_metric.router_lsa.on_startup is not none %}
- max-metric router-lsa on-startup {{ max_metric.router_lsa.on_startup }}
-{% endif %}
-{% endif %}
-{% if mpls_te is defined and mpls_te.enable is defined %}
- mpls-te on
- mpls-te router-address {{ mpls_te.router_address }}
-{% endif %}
-{% if neighbor is defined and neighbor is not none%}
-{% for address, address_config in neighbor.items() %}
- neighbor {{ address }} {{ 'priority ' + address_config.priority if address_config.priority is defined }} {{ 'poll-interval ' + address_config.poll_interval if address_config.poll_interval is defined }}
-{% endfor %}
-{% endif %}
-{% if parameters is defined and parameters is not none %}
-{% if parameters.abr_type is defined and parameters.abr_type is not none %}
- ospf abr-type {{ parameters.abr_type }}
-{% endif %}
-{% if parameters.router_id is defined and parameters.router_id is not none %}
- ospf router-id {{ parameters.router_id }}
-{% endif %}
-{% endif %}
-{% if passive_interface is defined and passive_interface is not none %}
-{% for interface in passive_interface %}
- passive-interface {{ interface }}
-{% endfor %}
-{% endif %}
-{% if passive_interface_exclude is defined and passive_interface_exclude is not none %}
-{% for interface in passive_interface_exclude if passive_interface_exclude is defined %}
-{% if interface.startswith('vlink') %}
-{% set interface = interface.upper() %}
-{% endif %}
- no passive-interface {{ interface }}
-{% endfor %}
-{% endif %}
-{% if redistribute is defined and redistribute is not none %}
-{% for protocol, protocols_options in redistribute.items() %}
-{% if protocol == 'table' %}
-{% for table, table_options in protocols_options.items() %}
- redistribute {{ protocol }} {{ table }} {{ 'metric ' + table_options.metric if table_options.metric is defined }} {{ 'metric-type ' + table_options.metric_type if table_options.metric_type is defined }} {{ 'route-map ' + table_options.route_map if table_options.route_map is defined }}
-{% endfor %}
-{% else %}
- redistribute {{ protocol }} {{ 'metric ' + protocols_options.metric if protocols_options.metric is defined }} {{ 'metric-type ' + protocols_options.metric_type if protocols_options.metric_type is defined }} {{ 'route-map ' + protocols_options.route_map if protocols_options.route_map is defined }}
-{% endif %}
-{% endfor %}
-{% endif %}
-{% if refresh is defined and refresh.timers is defined and refresh.timers is not none %}
- refresh timer {{ refresh.timers }}
-{% endif %}
-{% if timers is defined and timers.throttle is defined and timers.throttle.spf is defined and timers.throttle.spf is not none %}
-{# Timer values have default values #}
- timers throttle spf {{ timers.throttle.spf.delay }} {{ timers.throttle.spf.initial_holdtime }} {{ timers.throttle.spf.max_holdtime }}
-{% endif %}
-!
diff --git a/data/templates/frr/pimd.frr.tmpl b/data/templates/frr/pimd.frr.j2
index a5b56223a..cb2f2aa98 100644
--- a/data/templates/frr/pimd.frr.tmpl
+++ b/data/templates/frr/pimd.frr.j2
@@ -1,8 +1,8 @@
!
{% for rp_addr in old_pim.rp %}
-{% for group in old_pim.rp[rp_addr] %}
+{% for group in old_pim.rp[rp_addr] %}
no ip pim rp {{ rp_addr }} {{ group }}
-{% endfor %}
+{% endfor %}
{% endfor %}
{% if old_pim.rp_keep_alive %}
no ip pim rp keep-alive-timer {{ old_pim.rp_keep_alive }}
@@ -15,18 +15,18 @@ no ip pim
{% for iface in pim.ifaces %}
interface {{ iface }}
ip pim
-{% if pim.ifaces[iface].dr_prio %}
+{% if pim.ifaces[iface].dr_prio %}
ip pim drpriority {{ pim.ifaces[iface].dr_prio }}
-{% endif %}
-{% if pim.ifaces[iface].hello %}
+{% endif %}
+{% if pim.ifaces[iface].hello %}
ip pim hello {{ pim.ifaces[iface].hello }}
-{% endif %}
+{% endif %}
!
{% endfor %}
{% for rp_addr in pim.rp %}
-{% for group in pim.rp[rp_addr] %}
+{% for group in pim.rp[rp_addr] %}
ip pim rp {{ rp_addr }} {{ group }}
-{% endfor %}
+{% endfor %}
{% endfor %}
{% if pim.rp_keep_alive %}
ip pim rp keep-alive-timer {{ pim.rp_keep_alive }}
diff --git a/data/templates/frr/policy.frr.j2 b/data/templates/frr/policy.frr.j2
new file mode 100644
index 000000000..a42b73e98
--- /dev/null
+++ b/data/templates/frr/policy.frr.j2
@@ -0,0 +1,331 @@
+{% if access_list is vyos_defined %}
+{% for acl, acl_config in access_list.items() | natural_sort %}
+{% if acl_config.description is vyos_defined %}
+access-list {{ acl }} remark {{ acl_config.description }}
+{% endif %}
+{% if acl_config.rule is vyos_defined %}
+{% for rule, rule_config in acl_config.rule.items() | natural_sort %}
+{% set ip = '' %}
+{% set src = '' %}
+{% set src_mask = '' %}
+{% if rule_config.source.any is vyos_defined %}
+{% set src = 'any' %}
+{% elif rule_config.source.host is vyos_defined %}
+{% set src = 'host ' ~ rule_config.source.host %}
+{% elif rule_config.source.network is vyos_defined %}
+{% set src = rule_config.source.network %}
+{% set src_mask = rule_config.source.inverse_mask %}
+{% endif %}
+{% set dst = '' %}
+{% set dst_mask = '' %}
+{% if (acl | int >= 100 and acl | int <= 199) or (acl | int >= 2000 and acl | int <= 2699) %}
+{% set ip = 'ip' %}
+{% set dst = 'any' %}
+{% if rule_config.destination.any is vyos_defined %}
+{% set dst = 'any' %}
+{% elif rule_config.destination.host is vyos_defined %}
+{% set dst = 'host ' ~ rule_config.destination.host %}
+{% elif rule_config.destination.network is vyos_defined %}
+{% set dst = rule_config.destination.network %}
+{% set dst_mask = rule_config.destination.inverse_mask %}
+{% endif %}
+{% endif %}
+access-list {{ acl }} seq {{ rule }} {{ rule_config.action }} {{ ip }} {{ src }} {{ src_mask }} {{ dst }} {{ dst_mask }}
+{% endfor %}
+{% endif %}
+{% endfor %}
+{% endif %}
+!
+{% if access_list6 is vyos_defined %}
+{% for acl, acl_config in access_list6.items() | natural_sort %}
+{% if acl_config.description is vyos_defined %}
+ipv6 access-list {{ acl }} remark {{ acl_config.description }}
+{% endif %}
+{% if acl_config.rule is vyos_defined %}
+{% for rule, rule_config in acl_config.rule.items() | natural_sort %}
+{% set src = '' %}
+{% if rule_config.source.any is vyos_defined %}
+{% set src = 'any' %}
+{% elif rule_config.source.network is vyos_defined %}
+{% set src = rule_config.source.network %}
+{% endif %}
+ipv6 access-list {{ acl }} seq {{ rule }} {{ rule_config.action }} {{ src }} {{ 'exact-match' if rule_config.source.exact_match is vyos_defined }}
+{% endfor %}
+{% endif %}
+{% endfor %}
+{% endif %}
+!
+{% if as_path_list is vyos_defined %}
+{% for acl, acl_config in as_path_list.items() | natural_sort %}
+{% if acl_config.rule is vyos_defined %}
+{% for rule, rule_config in acl_config.rule.items() | natural_sort %}
+bgp as-path access-list {{ acl }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }}
+{% endfor %}
+{% endif %}
+{% endfor %}
+{% endif %}
+!
+{% if community_list is vyos_defined %}
+{% for list, list_config in community_list.items() | natural_sort %}
+{% if list_config.rule is vyos_defined %}
+{% for rule, rule_config in list_config.rule.items() | natural_sort %}
+{# by default, if casting to int fails it returns 0 #}
+{% if list | int != 0 %}
+bgp community-list {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }}
+{% else %}
+bgp community-list expanded {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% endfor %}
+{% endif %}
+!
+{% if extcommunity_list is vyos_defined %}
+{% for list, list_config in extcommunity_list.items() | natural_sort %}
+{% if list_config.rule is vyos_defined %}
+{% for rule, rule_config in list_config.rule.items() | natural_sort %}
+{# by default, if casting to int fails it returns 0 #}
+{% if list | int != 0 %}
+bgp extcommunity-list {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }}
+{% else %}
+bgp extcommunity-list expanded {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% endfor %}
+{% endif %}
+!
+{% if large_community_list is vyos_defined %}
+{% for list, list_config in large_community_list.items() | natural_sort %}
+{% if list_config.rule is vyos_defined %}
+{% for rule, rule_config in list_config.rule.items() | natural_sort %}
+{# by default, if casting to int fails it returns 0 #}
+{% if list | int != 0 %}
+bgp large-community-list {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }}
+{% else %}
+bgp large-community-list expanded {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% endfor %}
+{% endif %}
+!
+{% if prefix_list is vyos_defined %}
+{% for prefix_list, prefix_list_config in prefix_list.items() | natural_sort %}
+{% if prefix_list_config.description is vyos_defined %}
+ip prefix-list {{ prefix_list }} description {{ prefix_list_config.description }}
+{% endif %}
+{% if prefix_list_config.rule is vyos_defined %}
+{% for rule, rule_config in prefix_list_config.rule.items() | natural_sort %}
+{% if rule_config.prefix is vyos_defined %}
+ip prefix-list {{ prefix_list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.prefix }} {{ 'ge ' ~ rule_config.ge if rule_config.ge is vyos_defined }} {{ 'le ' ~ rule_config.le if rule_config.le is vyos_defined }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% endfor %}
+{% endif %}
+!
+{% if prefix_list6 is vyos_defined %}
+{% for prefix_list, prefix_list_config in prefix_list6.items() | natural_sort %}
+{% if prefix_list_config.description is vyos_defined %}
+ipv6 prefix-list {{ prefix_list }} description {{ prefix_list_config.description }}
+{% endif %}
+{% if prefix_list_config.rule is vyos_defined %}
+{% for rule, rule_config in prefix_list_config.rule.items() | natural_sort %}
+{% if rule_config.prefix is vyos_defined %}
+ipv6 prefix-list {{ prefix_list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.prefix }} {{ 'ge ' ~ rule_config.ge if rule_config.ge is vyos_defined }} {{ 'le ' ~ rule_config.le if rule_config.le is vyos_defined }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% endfor %}
+{% endif %}
+!
+{% if route_map is vyos_defined %}
+{% for route_map, route_map_config in route_map.items() | natural_sort %}
+{% if route_map_config.rule is vyos_defined %}
+{% for rule, rule_config in route_map_config.rule.items() | natural_sort %}
+route-map {{ route_map }} {{ rule_config.action }} {{ rule }}
+{% if rule_config.call is vyos_defined %}
+ call {{ rule_config.call }}
+{% endif %}
+{% if rule_config.continue is vyos_defined %}
+ on-match goto {{ rule_config.continue }}
+{% endif %}
+{% if rule_config.description is vyos_defined %}
+ description {{ rule_config.description }}
+{% endif %}
+{% if rule_config.match is vyos_defined %}
+{% if rule_config.match.as_path is vyos_defined %}
+ match as-path {{ rule_config.match.as_path }}
+{% endif %}
+{% if rule_config.match.community.community_list is vyos_defined %}
+ match community {{ rule_config.match.community.community_list }} {{ 'exact-match' if rule_config.match.community.exact_match is vyos_defined }}
+{% endif %}
+{% if rule_config.match.extcommunity is vyos_defined %}
+ match extcommunity {{ rule_config.match.extcommunity }}
+{% endif %}
+{% if rule_config.match.evpn.default_route is vyos_defined %}
+ match evpn default-route
+{% endif %}
+{% if rule_config.match.evpn.rd is vyos_defined %}
+ match evpn rd {{ rule_config.match.evpn.rd }}
+{% endif %}
+{% if rule_config.match.evpn.route_type is vyos_defined %}
+ match evpn route-type {{ rule_config.match.evpn.route_type }}
+{% endif %}
+{% if rule_config.match.evpn.vni is vyos_defined %}
+ match evpn vni {{ rule_config.match.evpn.vni }}
+{% endif %}
+{% if rule_config.match.interface is vyos_defined %}
+ match interface {{ rule_config.match.interface }}
+{% endif %}
+{% if rule_config.match.ip.address.access_list is vyos_defined %}
+ match ip address {{ rule_config.match.ip.address.access_list }}
+{% endif %}
+{% if rule_config.match.ip.address.prefix_list is vyos_defined %}
+ match ip address prefix-list {{ rule_config.match.ip.address.prefix_list }}
+{% endif %}
+{% if rule_config.match.ip.nexthop.access_list is vyos_defined %}
+ match ip next-hop {{ rule_config.match.ip.nexthop.access_list }}
+{% endif %}
+{% if rule_config.match.ip.nexthop.prefix_list is vyos_defined %}
+ match ip next-hop prefix-list {{ rule_config.match.ip.nexthop.prefix_list }}
+{% endif %}
+{% if rule_config.match.ip.route_source.access_list is vyos_defined %}
+ match ip route-source {{ rule_config.match.ip.route_source.access_list }}
+{% endif %}
+{% if rule_config.match.ip.route_source.prefix_list is vyos_defined %}
+ match ip route-source prefix-list {{ rule_config.match.ip.route_source.prefix_list }}
+{% endif %}
+{% if rule_config.match.ipv6.address.access_list is vyos_defined %}
+ match ipv6 address {{ rule_config.match.ipv6.address.access_list }}
+{% endif %}
+{% if rule_config.match.ipv6.address.prefix_list is vyos_defined %}
+ match ipv6 address prefix-list {{ rule_config.match.ipv6.address.prefix_list }}
+{% endif %}
+{% if rule_config.match.ipv6.nexthop is vyos_defined %}
+ match ipv6 next-hop address {{ rule_config.match.ipv6.nexthop }}
+{% endif %}
+{% if rule_config.match.large_community.large_community_list is vyos_defined %}
+ match large-community {{ rule_config.match.large_community.large_community_list }}
+{% endif %}
+{% if rule_config.match.local_preference is vyos_defined %}
+ match local-preference {{ rule_config.match.local_preference }}
+{% endif %}
+{% if rule_config.match.metric is vyos_defined %}
+ match metric {{ rule_config.match.metric }}
+{% endif %}
+{% if rule_config.match.origin is vyos_defined %}
+ match origin {{ rule_config.match.origin }}
+{% endif %}
+{% if rule_config.match.peer is vyos_defined %}
+ match peer {{ rule_config.match.peer }}
+{% endif %}
+{% if rule_config.match.rpki is vyos_defined %}
+ match rpki {{ rule_config.match.rpki }}
+{% endif %}
+{% if rule_config.match.tag is vyos_defined %}
+ match tag {{ rule_config.match.tag }}
+{% endif %}
+{% endif %}
+{% if rule_config.on_match.next is vyos_defined %}
+ on-match next
+{% endif %}
+{% if rule_config.on_match.goto is vyos_defined %}
+ on-match goto {{ rule_config.on_match.goto }}
+{% endif %}
+{% if rule_config.set is vyos_defined %}
+{% if rule_config.set.aggregator.as is vyos_defined and rule_config.set.aggregator.ip is vyos_defined %}
+ set aggregator as {{ rule_config.set.aggregator.as }} {{ rule_config.set.aggregator.ip }}
+{% endif %}
+{% if rule_config.set.as_path.exclude is vyos_defined %}
+ set as-path exclude {{ rule_config.set.as_path.exclude }}
+{% endif %}
+{% if rule_config.set.as_path.prepend is vyos_defined %}
+ set as-path prepend {{ rule_config.set.as_path.prepend }}
+{% endif %}
+{% if rule_config.set.as_path.prepend_last_as is vyos_defined %}
+ set as-path prepend last-as {{ rule_config.set.as_path.prepend_last_as }}
+{% endif %}
+{% if rule_config.set.atomic_aggregate is vyos_defined %}
+ set atomic-aggregate
+{% endif %}
+{% if rule_config.set.comm_list.comm_list is vyos_defined %}
+ set comm-list {{ rule_config.set.comm_list.comm_list }} {{ 'delete' if rule_config.set.comm_list.delete is vyos_defined }}
+{% endif %}
+{% if rule_config.set.community is vyos_defined %}
+ set community {{ rule_config.set.community }}
+{% endif %}
+{% if rule_config.set.distance is vyos_defined %}
+ set distance {{ rule_config.set.distance }}
+{% endif %}
+{% if rule_config.set.evpn.gateway.ipv4 is vyos_defined %}
+ set evpn gateway-ip ipv4 {{ rule_config.set.evpn.gateway.ipv4 }}
+{% endif %}
+{% if rule_config.set.evpn.gateway.ipv6 is vyos_defined %}
+ set evpn gateway-ip ipv6 {{ rule_config.set.evpn.gateway.ipv6 }}
+{% endif %}
+{% if rule_config.set.extcommunity.bandwidth is vyos_defined %}
+ set extcommunity bandwidth {{ rule_config.set.extcommunity.bandwidth }}
+{% endif %}
+{% if rule_config.set.extcommunity.rt is vyos_defined %}
+ set extcommunity rt {{ rule_config.set.extcommunity.rt }}
+{% endif %}
+{% if rule_config.set.extcommunity.soo is vyos_defined %}
+ set extcommunity soo {{ rule_config.set.extcommunity.soo }}
+{% endif %}
+{% if rule_config.set.ip_next_hop is vyos_defined %}
+ set ip next-hop {{ rule_config.set.ip_next_hop }}
+{% endif %}
+{% if rule_config.set.ipv6_next_hop.global is vyos_defined %}
+ set ipv6 next-hop global {{ rule_config.set.ipv6_next_hop.global }}
+{% endif %}
+{% if rule_config.set.ipv6_next_hop.local is vyos_defined %}
+ set ipv6 next-hop local {{ rule_config.set.ipv6_next_hop.local }}
+{% endif %}
+{% if rule_config.set.ipv6_next_hop.peer_address is vyos_defined %}
+ set ipv6 next-hop peer-address
+{% endif %}
+{% if rule_config.set.ipv6_next_hop.prefer_global is vyos_defined %}
+ set ipv6 next-hop prefer-global
+{% endif %}
+{% if rule_config.set.large_community is vyos_defined %}
+ set large-community {{ rule_config.set.large_community }}
+{% endif %}
+{% if rule_config.set.large_comm_list_delete is vyos_defined %}
+ set large-comm-list {{ rule_config.set.large_comm_list_delete }} delete
+{% endif %}
+{% if rule_config.set.local_preference is vyos_defined %}
+ set local-preference {{ rule_config.set.local_preference }}
+{% endif %}
+{% if rule_config.set.metric is vyos_defined %}
+ set metric {{ rule_config.set.metric }}
+{% endif %}
+{% if rule_config.set.metric_type is vyos_defined %}
+ set metric-type {{ rule_config.set.metric_type }}
+{% endif %}
+{% if rule_config.set.origin is vyos_defined %}
+ set origin {{ rule_config.set.origin }}
+{% endif %}
+{% if rule_config.set.originator_id is vyos_defined %}
+ set originator-id {{ rule_config.set.originator_id }}
+{% endif %}
+{% if rule_config.set.src is vyos_defined %}
+ set src {{ rule_config.set.src }}
+{% endif %}
+{% if rule_config.set.table is vyos_defined %}
+ set table {{ rule_config.set.table }}
+{% endif %}
+{% if rule_config.set.tag is vyos_defined %}
+ set tag {{ rule_config.set.tag }}
+{% endif %}
+{% if rule_config.set.weight is vyos_defined %}
+ set weight {{ rule_config.set.weight }}
+{% endif %}
+{% endif %}
+exit
+!
+{% endfor %}
+{% endif %}
+{% endfor %}
+{% endif %}
diff --git a/data/templates/frr/policy.frr.tmpl b/data/templates/frr/policy.frr.tmpl
deleted file mode 100644
index 51adc1902..000000000
--- a/data/templates/frr/policy.frr.tmpl
+++ /dev/null
@@ -1,322 +0,0 @@
-!
-{% if access_list is defined and access_list is not none %}
-{% for acl, acl_config in access_list.items() | natural_sort %}
-{% if acl_config.description is defined and acl_config.description is not none %}
-access-list {{ acl }} remark {{ acl_config.description }}
-{% endif %}
-{% if acl_config.rule is defined and acl_config.rule is not none %}
-{% for rule, rule_config in acl_config.rule.items() | natural_sort %}
-{% set ip = '' %}
-{% set src = '' %}
-{% set src_mask = '' %}
-{% if rule_config.source is defined and rule_config.source.any is defined %}
-{% set src = 'any' %}
-{% elif rule_config.source is defined and rule_config.source.host is defined and rule_config.source.host is not none %}
-{% set src = 'host ' + rule_config.source.host %}
-{% elif rule_config.source is defined and rule_config.source.network is defined and rule_config.source.network is not none %}
-{% set src = rule_config.source.network %}
-{% set src_mask = rule_config.source.inverse_mask %}
-{% endif %}
-{% set dst = '' %}
-{% set dst_mask = '' %}
-{% if (acl|int >= 100 and acl|int <= 199) or (acl|int >= 2000 and acl|int <= 2699) %}
-{% set ip = 'ip' %}
-{% set dst = 'any' %}
-{% if rule_config.destination is defined and rule_config.destination.any is defined %}
-{% set dst = 'any' %}
-{% elif rule_config.destination is defined and rule_config.destination.host is defined and rule_config.destination.host is not none %}
-{% set dst = 'host ' + rule_config.destination.host %}
-{% elif rule_config.destination is defined and rule_config.destination.network is defined and rule_config.destination.network is not none %}
-{% set dst = rule_config.destination.network %}
-{% set dst_mask = rule_config.destination.inverse_mask %}
-{% endif %}
-{% endif %}
-access-list {{ acl }} seq {{ rule }} {{ rule_config.action }} {{ ip }} {{ src }} {{ src_mask }} {{ dst }} {{ dst_mask }}
-{% endfor %}
-{% endif %}
-{% endfor %}
-{% endif %}
-!
-{% if access_list6 is defined and access_list6 is not none %}
-{% for acl, acl_config in access_list6.items() | natural_sort %}
-{% if acl_config.description is defined and acl_config.description is not none %}
-ipv6 access-list {{ acl }} remark {{ acl_config.description }}
-{% endif %}
-{% if acl_config.rule is defined and acl_config.rule is not none %}
-{% for rule, rule_config in acl_config.rule.items() | natural_sort %}
-{% set src = '' %}
-{% if rule_config.source is defined and rule_config.source.any is defined %}
-{% set src = 'any' %}
-{% elif rule_config.source is defined and rule_config.source.network is defined and rule_config.source.network is not none %}
-{% set src = rule_config.source.network %}
-{% endif %}
-ipv6 access-list {{ acl }} seq {{ rule }} {{ rule_config.action }} {{ src }} {{ 'exact-match' if rule_config.source.exact_match is defined }}
-{% endfor %}
-{% endif %}
-{% endfor %}
-{% endif %}
-!
-{% if as_path_list is defined and as_path_list is not none %}
-{% for acl, acl_config in as_path_list.items() | natural_sort %}
-{% if acl_config.rule is defined and acl_config.rule is not none %}
-{% for rule, rule_config in acl_config.rule.items() | natural_sort %}
-bgp as-path access-list {{ acl }} {{ rule_config.action }} {{ rule_config.regex }}
-{% endfor %}
-{% endif %}
-{% endfor %}
-{% endif %}
-!
-{% if community_list is defined and community_list is not none %}
-{% for list, list_config in community_list.items() | natural_sort %}
-{% if list_config.rule is defined and list_config.rule is not none %}
-{% for rule, rule_config in list_config.rule.items() | natural_sort %}
-{# by default, if casting to int fails it returns 0 #}
-{% if list|int != 0 %}
-bgp community-list {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }}
-{% else %}
-bgp community-list expanded {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }}
-{% endif %}
-{% endfor %}
-{% endif %}
-{% endfor %}
-{% endif %}
-!
-{% if extcommunity_list is defined and extcommunity_list is not none %}
-{% for list, list_config in extcommunity_list.items() | natural_sort %}
-{% if list_config.rule is defined and list_config.rule is not none %}
-{% for rule, rule_config in list_config.rule.items() | natural_sort %}
-{# by default, if casting to int fails it returns 0 #}
-{% if list|int != 0 %}
-bgp extcommunity-list {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }}
-{% else %}
-bgp extcommunity-list expanded {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }}
-{% endif %}
-{% endfor %}
-{% endif %}
-{% endfor %}
-{% endif %}
-!
-{% if large_community_list is defined and large_community_list is not none %}
-{% for list, list_config in large_community_list.items() | natural_sort %}
-{% if list_config.rule is defined and list_config.rule is not none %}
-{% for rule, rule_config in list_config.rule.items() | natural_sort %}
-{# by default, if casting to int fails it returns 0 #}
-{% if list|int != 0 %}
-bgp large-community-list {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }}
-{% else %}
-bgp large-community-list expanded {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }}
-{% endif %}
-{% endfor %}
-{% endif %}
-{% endfor %}
-{% endif %}
-!
-{% if prefix_list is defined and prefix_list is not none %}
-{% for prefix_list, prefix_list_config in prefix_list.items() | natural_sort %}
-{% if prefix_list_config.description is defined and prefix_list_config.description is not none %}
-ip prefix-list {{ prefix_list }} description {{ prefix_list_config.description }}
-{% endif %}
-{% if prefix_list_config.rule is defined and prefix_list_config.rule is not none %}
-{% for rule, rule_config in prefix_list_config.rule.items() | natural_sort %}
-{% if rule_config.prefix is defined and rule_config.prefix is not none %}
-ip prefix-list {{ prefix_list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.prefix }} {{ 'ge ' + rule_config.ge if rule_config.ge is defined }} {{ 'le ' + rule_config.le if rule_config.le is defined }}
-{% endif %}
-{% endfor %}
-{% endif %}
-{% endfor %}
-{% endif %}
-!
-{% if prefix_list6 is defined and prefix_list6 is not none %}
-{% for prefix_list, prefix_list_config in prefix_list6.items() | natural_sort %}
-{% if prefix_list_config.description is defined and prefix_list_config.description is not none %}
-ipv6 prefix-list {{ prefix_list }} description {{ prefix_list_config.description }}
-{% endif %}
-{% if prefix_list_config.rule is defined and prefix_list_config.rule is not none %}
-{% for rule, rule_config in prefix_list_config.rule.items() | natural_sort %}
-{% if rule_config.prefix is defined and rule_config.prefix is not none %}
-ipv6 prefix-list {{ prefix_list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.prefix }} {{ 'ge ' + rule_config.ge if rule_config.ge is defined }} {{ 'le ' + rule_config.le if rule_config.le is defined }}
-{% endif %}
-{% endfor %}
-{% endif %}
-{% endfor %}
-{% endif %}
-!
-{% if route_map is defined and route_map is not none %}
-{% for route_map, route_map_config in route_map.items() | natural_sort %}
-{% if route_map_config.rule is defined and route_map_config.rule is not none %}
-{% for rule, rule_config in route_map_config.rule.items() | natural_sort %}
-route-map {{ route_map }} {{ rule_config.action }} {{ rule }}
-{% if rule_config.call is defined and rule_config.call is not none %}
- call {{ rule_config.call }}
-{% endif %}
-{% if rule_config.continue is defined and rule_config.continue is not none %}
- on-match goto {{ rule_config.continue }}
-{% endif %}
-{% if rule_config.description is defined and rule_config.description is not none %}
- description {{ rule_config.description }}
-{% endif %}
-{% if rule_config.match is defined and rule_config.match is not none %}
-{% if rule_config.match.as_path is defined and rule_config.match.as_path is not none %}
- match as-path {{ rule_config.match.as_path }}
-{% endif %}
-{% if rule_config.match.community is defined and rule_config.match.community.community_list is defined and rule_config.match.community.community_list is not none %}
- match community {{ rule_config.match.community.community_list }} {{ 'exact-match' if rule_config.match.community.exact_match is defined }}
-{% endif %}
-{% if rule_config.match.extcommunity is defined and rule_config.match.extcommunity is not none %}
- match extcommunity {{ rule_config.match.extcommunity }}
-{% endif %}
-{% if rule_config.match.evpn is defined and rule_config.match.evpn.default_route is defined %}
- match evpn default-route
-{% endif %}
-{% if rule_config.match.evpn is defined and rule_config.match.evpn.rd is defined and rule_config.match.evpn.rd is not none %}
- match evpn rd {{ rule_config.match.evpn.rd }}
-{% endif %}
-{% if rule_config.match.evpn is defined and rule_config.match.evpn.route_type is defined and rule_config.match.evpn.route_type is not none %}
- match evpn route-type {{ rule_config.match.evpn.route_type }}
-{% endif %}
-{% if rule_config.match.evpn is defined and rule_config.match.evpn.vni is defined and rule_config.match.evpn.vni is not none %}
- match evpn vni {{ rule_config.match.evpn.vni }}
-{% endif %}
-{% if rule_config.match.interface is defined and rule_config.match.interface is not none %}
- match interface {{ rule_config.match.interface }}
-{% endif %}
-{% if rule_config.match.ip is defined and rule_config.match.ip.address is defined and rule_config.match.ip.address.access_list is defined and rule_config.match.ip.address.access_list is not none %}
- match ip address {{ rule_config.match.ip.address.access_list }}
-{% endif %}
-{% if rule_config.match.ip is defined and rule_config.match.ip.address is defined and rule_config.match.ip.address.prefix_list is defined and rule_config.match.ip.address.prefix_list is not none %}
- match ip address prefix-list {{ rule_config.match.ip.address.prefix_list }}
-{% endif %}
-{% if rule_config.match.ip is defined and rule_config.match.ip.nexthop is defined and rule_config.match.ip.nexthop.access_list is defined and rule_config.match.ip.nexthop.access_list is not none %}
- match ip next-hop {{ rule_config.match.ip.nexthop.access_list }}
-{% endif %}
-{% if rule_config.match.ip is defined and rule_config.match.ip.nexthop is defined and rule_config.match.ip.nexthop.prefix_list is defined and rule_config.match.ip.nexthop.prefix_list is not none %}
- match ip next-hop prefix-list {{ rule_config.match.ip.nexthop.prefix_list }}
-{% endif %}
-{% if rule_config.match.ip is defined and rule_config.match.ip.route_source is defined and rule_config.match.ip.route_source.access_list is defined and rule_config.match.ip.route_source.access_list is not none %}
- match ip route-source {{ rule_config.match.ip.route_source.access_list }}
-{% endif %}
-{% if rule_config.match.ip is defined and rule_config.match.ip.route_source is defined and rule_config.match.ip.route_source.prefix_list is defined and rule_config.match.ip.route_source.prefix_list is not none %}
- match ip route-source prefix-list {{ rule_config.match.ip.route_source.prefix_list }}
-{% endif %}
-{% if rule_config.match.ipv6 is defined and rule_config.match.ipv6.address is defined and rule_config.match.ipv6.address.access_list is defined and rule_config.match.ipv6.address.access_list is not none %}
- match ipv6 address {{ rule_config.match.ipv6.address.access_list }}
-{% endif %}
-{% if rule_config.match.ipv6 is defined and rule_config.match.ipv6.address is defined and rule_config.match.ipv6.address.prefix_list is defined and rule_config.match.ipv6.address.prefix_list is not none %}
- match ipv6 address prefix-list {{ rule_config.match.ipv6.address.prefix_list }}
-{% endif %}
-{% if rule_config.match.ipv6 is defined and rule_config.match.ipv6.nexthop is defined and rule_config.match.ipv6.nexthop is not none %}
- match ipv6 next-hop {{ rule_config.match.ipv6.nexthop }}
-{% endif %}
-{% if rule_config.match.large_community is defined and rule_config.match.large_community.large_community_list is defined and rule_config.match.large_community.large_community_list is not none %}
- match large-community {{ rule_config.match.large_community.large_community_list }}
-{% endif %}
-{% if rule_config.match.local_preference is defined and rule_config.match.local_preference is not none %}
- match local-preference {{ rule_config.match.local_preference }}
-{% endif %}
-{% if rule_config.match.metric is defined and rule_config.match.metric is not none %}
- match metric {{ rule_config.match.metric }}
-{% endif %}
-{% if rule_config.match.origin is defined and rule_config.match.origin is not none %}
- match origin {{ rule_config.match.origin }}
-{% endif %}
-{% if rule_config.match.peer is defined and rule_config.match.peer is not none %}
- match peer {{ rule_config.match.peer }}
-{% endif %}
-{% if rule_config.match.rpki is defined and rule_config.match.rpki is not none %}
- match rpki {{ rule_config.match.rpki }}
-{% endif %}
-{% if rule_config.match.tag is defined and rule_config.match.tag is not none %}
- match tag {{ rule_config.match.tag }}
-{% endif %}
-{% endif %}
-{% if rule_config.on_match is defined and rule_config.on_match is not none %}
-{% if rule_config.on_match.next is defined %}
- on-match next
-{% endif %}
-{% if rule_config.on_match.goto is defined and rule_config.on_match.goto is not none %}
- on-match goto {{ rule_config.on_match.goto }}
-{% endif %}
-{% endif %}
-{% if rule_config.set is defined and rule_config.set is not none %}
-{% if rule_config.set.aggregator is defined and rule_config.set.aggregator.as is defined and rule_config.set.aggregator.ip is defined %}
- set aggregator as {{ rule_config.set.aggregator.as }} {{ rule_config.set.aggregator.ip }}
-{% endif %}
-{% if rule_config.set.as_path_exclude is defined and rule_config.set.as_path_exclude is not none %}
- set as-path exclude {{ rule_config.set.as_path_exclude }}
-{% endif %}
-{% if rule_config.set.as_path_prepend is defined and rule_config.set.as_path_prepend is not none %}
- set as-path prepend {{ rule_config.set.as_path_prepend }}
-{% endif %}
-{% if rule_config.set.atomic_aggregate is defined %}
- set atomic-aggregate
-{% endif %}
-{% if rule_config.set.comm_list is defined and rule_config.set.comm_list.comm_list is defined and rule_config.set.comm_list.comm_list is not none %}
- set comm-list {{ rule_config.set.comm_list.comm_list }} {{ 'delete' if rule_config.set.comm_list.delete is defined }}
-{% endif %}
-{% if rule_config.set.community is defined and rule_config.set.community is not none %}
- set community {{ rule_config.set.community }}
-{% endif %}
-{% if rule_config.set.distance is defined and rule_config.set.distance is not none %}
- set distance {{ rule_config.set.distance }}
-{% endif %}
-{% if rule_config.set.extcommunity is defined and rule_config.set.extcommunity.bandwidth is defined and rule_config.set.extcommunity.bandwidth is not none %}
- set extcommunity bandwidth {{ rule_config.set.extcommunity.bandwidth }}
-{% endif %}
-{% if rule_config.set.extcommunity is defined and rule_config.set.extcommunity.rt is defined and rule_config.set.extcommunity.rt is not none %}
- set extcommunity rt {{ rule_config.set.extcommunity.rt }}
-{% endif %}
-{% if rule_config.set.extcommunity is defined and rule_config.set.extcommunity.soo is defined and rule_config.set.extcommunity.soo is not none %}
- set extcommunity soo {{ rule_config.set.extcommunity.soo }}
-{% endif %}
-{% if rule_config.set.ip_next_hop is defined and rule_config.set.ip_next_hop is not none %}
- set ip next-hop {{ rule_config.set.ip_next_hop }}
-{% endif %}
-{% if rule_config.set.ipv6_next_hop is defined and rule_config.set.ipv6_next_hop.global is defined and rule_config.set.ipv6_next_hop.global is not none %}
- set ipv6 next-hop global {{ rule_config.set.ipv6_next_hop.global }}
-{% endif %}
-{% if rule_config.set.ipv6_next_hop is defined and rule_config.set.ipv6_next_hop.local is defined and rule_config.set.ipv6_next_hop.local is not none %}
- set ipv6 next-hop local {{ rule_config.set.ipv6_next_hop.local }}
-{% endif %}
-{% if rule_config.set.ipv6_next_hop is defined and rule_config.set.ipv6_next_hop.prefer_global is defined %}
- set ipv6 next-hop prefer-global
-{% endif %}
-{% if rule_config.set.large_community is defined and rule_config.set.large_community is not none %}
- set large-community {{ rule_config.set.large_community }}
-{% endif %}
-{% if rule_config.set.large_comm_list_delete is defined and rule_config.set.large_comm_list_delete is not none %}
- set large-comm-list {{ rule_config.set.large_comm_list_delete }} delete
-{% endif %}
-{% if rule_config.set.local_preference is defined and rule_config.set.local_preference is not none %}
- set local-preference {{ rule_config.set.local_preference }}
-{% endif %}
-{% if rule_config.set.metric is defined and rule_config.set.metric is not none %}
- set metric {{ rule_config.set.metric }}
-{% endif %}
-{% if rule_config.set.metric_type is defined and rule_config.set.metric_type is not none %}
- set metric-type {{ rule_config.set.metric_type }}
-{% endif %}
-{% if rule_config.set.origin is defined and rule_config.set.origin is not none %}
- set origin {{ rule_config.set.origin }}
-{% endif %}
-{% if rule_config.set.originator_id is defined and rule_config.set.originator_id is not none %}
- set originator-id {{ rule_config.set.originator_id }}
-{% endif %}
-{% if rule_config.set.src is defined and rule_config.set.src is not none %}
- set src {{ rule_config.set.src }}
-{% endif %}
-{% if rule_config.set.table is defined and rule_config.set.table is not none %}
- set table {{ rule_config.set.table }}
-{% endif %}
-{% if rule_config.set.tag is defined and rule_config.set.tag is not none %}
- set tag {{ rule_config.set.tag }}
-{% endif %}
-{% if rule_config.set.weight is defined and rule_config.set.weight is not none %}
- set weight {{ rule_config.set.weight }}
-{% endif %}
-{% endif %}
-{% endfor %}
-!
-{% endif %}
-{% endfor %}
-{% endif %}
-!
diff --git a/data/templates/frr/rip_ripng.frr.j2 b/data/templates/frr/rip_ripng.frr.j2
index de180ee6b..dd547bb3e 100644
--- a/data/templates/frr/rip_ripng.frr.j2
+++ b/data/templates/frr/rip_ripng.frr.j2
@@ -1,36 +1,36 @@
-{% if default_information is defined and default_information.originate is defined %}
+{% if default_information is vyos_defined %}
default-information originate
{% endif %}
-{% if default_metric is defined and default_metric is not none %}
+{% if default_metric is vyos_defined %}
default-metric {{ default_metric }}
{% endif %}
-{% if passive_interface is defined and passive_interface is not none %}
-{% for interface in passive_interface %}
+{% if passive_interface is vyos_defined %}
+{% for interface in passive_interface %}
passive-interface {{ interface }}
-{% endfor %}
+{% endfor %}
{% endif %}
-{% if network is defined and network is not none %}
-{% for prefix in network %}
+{% if network is vyos_defined %}
+{% for prefix in network %}
network {{ prefix }}
-{% endfor %}
+{% endfor %}
{% endif %}
-{% if interface is defined and interface is not none %}
-{% for ifname in interface %}
+{% if interface is vyos_defined %}
+{% for ifname in interface %}
network {{ ifname }}
-{% endfor %}
+{% endfor %}
{% endif %}
-{% if route is defined and route is not none %}
-{% for prefix in route %}
+{% if route is vyos_defined %}
+{% for prefix in route %}
route {{ prefix }}
-{% endfor %}
+{% endfor %}
{% endif %}
{# timers have default values #}
timers basic {{ timers['update'] }} {{ timers.timeout }} {{ timers.garbage_collection }}
-{% if redistribute is defined and redistribute is not none %}
-{% for protocol, protocol_config in redistribute.items() %}
-{% if protocol == 'ospfv3' %}
-{% set protocol = 'ospf6' %}
-{% endif %}
- redistribute {{ protocol }} {{ 'metric ' + protocol_config.metric if protocol_config.metric is defined }} {{ 'route-map ' + protocol_config.route_map if protocol_config.route_map is defined }}
-{% endfor %}
+{% if redistribute is vyos_defined %}
+{% for protocol, protocol_config in redistribute.items() %}
+{% if protocol is vyos_defined('ospfv3') %}
+{% set protocol = 'ospf6' %}
+{% endif %}
+ redistribute {{ protocol }} {{ 'metric ' ~ protocol_config.metric if protocol_config.metric is vyos_defined }} {{ 'route-map ' ~ protocol_config.route_map if protocol_config.route_map is vyos_defined }}
+{% endfor %}
{% endif %}
diff --git a/data/templates/frr/ripd.frr.j2 b/data/templates/frr/ripd.frr.j2
new file mode 100644
index 000000000..df35150ca
--- /dev/null
+++ b/data/templates/frr/ripd.frr.j2
@@ -0,0 +1,92 @@
+{# RIP key-chain definition #}
+{% if interface is vyos_defined %}
+{% for iface, iface_config in interface.items() %}
+{% if iface_config.authentication.md5 is vyos_defined %}
+key chain {{ iface }}-rip
+{% for key_id, key_options in iface_config.authentication.md5.items() %}
+ key {{ key_id }}
+{% if key_options.password is vyos_defined %}
+ key-string {{ key_options.password }}
+{% endif %}
+ exit
+{% endfor %}
+exit
+{% endif %}
+{% endfor %}
+{% endif %}
+!
+{# Interface specific configuration #}
+{% if interface is vyos_defined %}
+{% for iface, iface_config in interface.items() %}
+interface {{ iface }}
+{% if iface_config.authentication.plaintext_password is vyos_defined %}
+ ip rip authentication mode text
+ ip rip authentication string {{ iface_config.authentication.plaintext_password }}
+{% elif iface_config.authentication.md5 is vyos_defined %}
+ ip rip authentication key-chain {{ iface }}-rip
+ ip rip authentication mode md5
+{% endif %}
+{% if iface_config.split_horizon.disable is vyos_defined %}
+ no ip rip split-horizon
+{% endif %}
+{% if iface_config.split_horizon.poison_reverse is vyos_defined %}
+ ip rip split-horizon poisoned-reverse
+{% endif %}
+exit
+!
+{% endfor %}
+{% endif %}
+!
+router rip
+{% if default_distance is vyos_defined %}
+ distance {{ default_distance }}
+{% endif %}
+{% if network_distance is vyos_defined %}
+{% for network, network_config in network_distance.items() %}
+{% if network_config.distance is vyos_defined %}
+ distance {{ network_config.distance }} {{ network }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if neighbor is vyos_defined %}
+{% for address in neighbor %}
+ neighbor {{ address }}
+{% endfor %}
+{% endif %}
+{% if distribute_list is vyos_defined %}
+{% if distribute_list.access_list.in is vyos_defined %}
+ distribute-list {{ distribute_list.access_list.in }} in
+{% endif %}
+{% if distribute_list.access_list.out is vyos_defined %}
+ distribute-list {{ distribute_list.access_list.out }} out
+{% endif %}
+{% if distribute_list.interface is vyos_defined %}
+{% for interface, interface_config in distribute_list.interface.items() %}
+{% if interface_config.access_list.in is vyos_defined %}
+ distribute-list {{ interface_config.access_list.in }} in {{ interface }}
+{% endif %}
+{% if interface_config.access_list.out is vyos_defined %}
+ distribute-list {{ interface_config.access_list.out }} out {{ interface }}
+{% endif %}
+{% if interface_config.prefix_list.in is vyos_defined %}
+ distribute-list prefix {{ interface_config.prefix_list.in }} in {{ interface }}
+{% endif %}
+{% if interface_config.prefix_list.out is vyos_defined %}
+ distribute-list prefix {{ interface_config.prefix_list.out }} out {{ interface }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if distribute_list.prefix_list.in is vyos_defined %}
+ distribute-list prefix {{ distribute_list.prefix_list.in }} in
+{% endif %}
+{% if distribute_list.prefix_list.out is vyos_defined %}
+ distribute-list prefix {{ distribute_list.prefix_list.out }} out
+{% endif %}
+{% endif %}
+{% include 'frr/rip_ripng.frr.j2' %}
+exit
+!
+{% if route_map is vyos_defined %}
+ip protocol rip route-map {{ route_map }}
+{% endif %}
+!
diff --git a/data/templates/frr/ripd.frr.tmpl b/data/templates/frr/ripd.frr.tmpl
deleted file mode 100644
index cabc236f0..000000000
--- a/data/templates/frr/ripd.frr.tmpl
+++ /dev/null
@@ -1,96 +0,0 @@
-!
-{# RIP key-chain definition #}
-{% if interface is defined and interface is not none %}
-{% for iface, iface_config in interface.items() %}
-{% if iface_config.authentication is defined and iface_config.authentication.md5 is defined and iface_config.authentication.md5 is not none %}
-key chain {{ iface }}-rip
-{% for key_id, key_options in iface_config.authentication.md5.items() %}
- key {{ key_id }}
-{% if key_options.password is defined and key_options.password is not none %}
- key-string {{ key_options.password }}
-{% endif %}
-{% endfor %}
-{% endif %}
-{% endfor %}
-{% endif %}
-!
-{# Interface specific configuration #}
-{% if interface is defined and interface is not none %}
-{% for iface, iface_config in interface.items() %}
-interface {{ iface }}
-{% if iface_config.authentication is defined and iface_config.authentication.plaintext_password is defined and iface_config.authentication.plaintext_password is not none %}
- ip rip authentication mode text
- ip rip authentication string {{ iface_config.authentication.plaintext_password }}
-{% elif iface_config.authentication is defined and iface_config.authentication.md5 is defined and iface_config.authentication.md5 is not none %}
- ip rip authentication key-chain {{ iface }}-rip
- ip rip authentication mode md5
-{% endif %}
-{% if iface_config.split_horizon is defined and iface_config.split_horizon.disable is defined %}
- no ip rip split-horizon
-{% endif %}
-{% if iface_config.split_horizon is defined and iface_config.split_horizon.poison_reverse is defined %}
- ip rip split-horizon poisoned-reverse
-{% endif %}
-{% endfor %}
-{% endif %}
-!
-router rip
-{% if default_distance is defined and default_distance is not none %}
- distance {{ default_distance }}
-{% endif %}
-{% if network_distance is defined and network_distance is not none %}
-{% for network, network_config in network_distance.items() %}
-{% if network_config.distance is defined and network_config.distance is not none %}
- distance {{ network_config.distance }} {{ network }}
-{% endif %}
-{% endfor %}
-{% endif %}
-{% if neighbor is defined and neighbor is not none %}
-{% for address in neighbor %}
- neighbor {{ address }}
-{% endfor %}
-{% endif %}
-{% if distribute_list is defined and distribute_list is not none %}
-{% if distribute_list.access_list is defined and distribute_list.access_list is not none %}
-{% if distribute_list.access_list.in is defined and distribute_list.access_list.in is not none %}
- distribute-list {{ distribute_list.access_list.in }} in
-{% endif %}
-{% if distribute_list.access_list.out is defined and distribute_list.access_list.out is not none %}
- distribute-list {{ distribute_list.access_list.out }} out
-{% endif %}
-{% endif %}
-{% if distribute_list.interface is defined and distribute_list.interface is not none %}
-{% for interface, interface_config in distribute_list.interface.items() %}
-{% if interface_config.access_list is defined and interface_config.access_list is not none %}
-{% if interface_config.access_list.in is defined and interface_config.access_list.in is not none %}
- distribute-list {{ interface_config.access_list.in }} in {{ interface }}
-{% endif %}
-{% if interface_config.access_list.out is defined and interface_config.access_list.out is not none %}
- distribute-list {{ interface_config.access_list.out }} out {{ interface }}
-{% endif %}
-{% endif %}
-{% if interface_config.prefix_list is defined and interface_config.prefix_list is not none %}
-{% if interface_config.prefix_list.in is defined and interface_config.prefix_list.in is not none %}
- distribute-list prefix {{ interface_config.prefix_list.in }} in {{ interface }}
-{% endif %}
-{% if interface_config.prefix_list.out is defined and interface_config.prefix_list.out is not none %}
- distribute-list prefix {{ interface_config.prefix_list.out }} out {{ interface }}
-{% endif %}
-{% endif %}
-{% endfor %}
-{% endif %}
-{% if distribute_list.prefix_list is defined and distribute_list.prefix_list is not none %}
-{% if distribute_list.prefix_list.in is defined and distribute_list.prefix_list.in is not none %}
- distribute-list prefix {{ distribute_list.prefix_list.in }} in
-{% endif %}
-{% if distribute_list.prefix_list.out is defined and distribute_list.prefix_list.out is not none %}
- distribute-list prefix {{ distribute_list.prefix_list.out }} out
-{% endif %}
-{% endif %}
-{% endif %}
-{% include 'frr/rip_ripng.frr.j2' %}
-!
-{% if route_map is defined and route_map is not none %}
-ip protocol rip route-map {{ route_map }}
-{% endif %}
-!
diff --git a/data/templates/frr/ripngd.frr.j2 b/data/templates/frr/ripngd.frr.j2
new file mode 100644
index 000000000..7919b1bad
--- /dev/null
+++ b/data/templates/frr/ripngd.frr.j2
@@ -0,0 +1,57 @@
+{# Interface specific configuration #}
+{% if interface is vyos_defined %}
+{% for iface, iface_config in interface.items() %}
+interface {{ iface }}
+{% if iface_config.split_horizon.disable is vyos_defined %}
+ no ipv6 rip split-horizon
+{% endif %}
+{% if iface_config.split_horizon.poison_reverse is vyos_defined %}
+ ipv6 rip split-horizon poisoned-reverse
+{% endif %}
+exit
+{% endfor %}
+{% endif %}
+!
+router ripng
+{% if aggregate_address is vyos_defined %}
+{% for prefix in aggregate_address %}
+ aggregate-address {{ prefix }}
+{% endfor %}
+{% endif %}
+{% if distribute_list is vyos_defined %}
+{% if distribute_list.access_list.in is vyos_defined %}
+ ipv6 distribute-list {{ distribute_list.access_list.in }} in
+{% endif %}
+{% if distribute_list.access_list.out is vyos_defined %}
+ ipv6 distribute-list {{ distribute_list.access_list.out }} out
+{% endif %}
+{% if distribute_list.interface is vyos_defined %}
+{% for interface, interface_config in distribute_list.interface.items() %}
+{% if interface_config.access_list.in is vyos_defined %}
+ ipv6 distribute-list {{ interface_config.access_list.in }} in {{ interface }}
+{% endif %}
+{% if interface_config.access_list.out is vyos_defined %}
+ ipv6 distribute-list {{ interface_config.access_list.out }} out {{ interface }}
+{% endif %}
+{% if interface_config.prefix_list.in is vyos_defined %}
+ ipv6 distribute-list prefix {{ interface_config.prefix_list.in }} in {{ interface }}
+{% endif %}
+{% if interface_config.prefix_list.out is vyos_defined %}
+ ipv6 distribute-list prefix {{ interface_config.prefix_list.out }} out {{ interface }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if distribute_list.prefix_list.in is vyos_defined %}
+ ipv6 distribute-list prefix {{ distribute_list.prefix_list.in }} in
+{% endif %}
+{% if distribute_list.prefix_list.out is vyos_defined %}
+ ipv6 distribute-list prefix {{ distribute_list.prefix_list.out }} out
+{% endif %}
+{% endif %}
+{% include 'frr/rip_ripng.frr.j2' %}
+exit
+!
+{% if route_map is vyos_defined %}
+ipv6 protocol ripng route-map {{ route_map }}
+{% endif %}
+!
diff --git a/data/templates/frr/ripngd.frr.tmpl b/data/templates/frr/ripngd.frr.tmpl
deleted file mode 100644
index 25df15121..000000000
--- a/data/templates/frr/ripngd.frr.tmpl
+++ /dev/null
@@ -1,60 +0,0 @@
-!
-{# Interface specific configuration #}
-{% if interface is defined and interface is not none %}
-{% for iface, iface_config in interface.items() %}
-interface {{ iface }}
-{% if iface_config.split_horizon is defined and iface_config.split_horizon.disable is defined %}
- no ipv6 rip split-horizon
-{% endif %}
-{% if iface_config.split_horizon is defined and iface_config.split_horizon.poison_reverse is defined %}
- ipv6 rip split-horizon poisoned-reverse
-{% endif %}
-{% endfor %}
-{% endif %}
-!
-router ripng
-{% if aggregate_address is defined and aggregate_address is not none %}
-{% for prefix in aggregate_address %}
- aggregate-address {{ prefix }}
-{% endfor %}
-{% endif %}
-{% if distribute_list is defined and distribute_list is not none %}
-{% if distribute_list.access_list is defined and distribute_list.access_list is not none %}
-{% if distribute_list.access_list.in is defined and distribute_list.access_list.in is not none %}
- ipv6 distribute-list {{ distribute_list.access_list.in }} in
-{% endif %}
-{% if distribute_list.access_list.out is defined and distribute_list.access_list.out is not none %}
- ipv6 distribute-list {{ distribute_list.access_list.out }} out
-{% endif %}
-{% endif %}
-{% if distribute_list.interface is defined and distribute_list.interface is not none %}
-{% for interface, interface_config in distribute_list.interface.items() %}
-{% if interface_config.access_list is defined and interface_config.access_list is not none %}
-{% if interface_config.access_list.in is defined and interface_config.access_list.in is not none %}
- ipv6 distribute-list {{ interface_config.access_list.in }} in {{ interface }}
-{% endif %}
-{% if interface_config.access_list.out is defined and interface_config.access_list.out is not none %}
- ipv6 distribute-list {{ interface_config.access_list.out }} out {{ interface }}
-{% endif %}
-{% endif %}
-{% if interface_config.prefix_list is defined and interface_config.prefix_list is not none %}
-{% if interface_config.prefix_list.in is defined and interface_config.prefix_list.in is not none %}
- ipv6 distribute-list prefix {{ interface_config.prefix_list.in }} in {{ interface }}
-{% endif %}
-{% if interface_config.prefix_list.out is defined and interface_config.prefix_list.out is not none %}
- ipv6 distribute-list prefix {{ interface_config.prefix_list.out }} out {{ interface }}
-{% endif %}
-{% endif %}
-{% endfor %}
-{% endif %}
-{% if distribute_list.prefix_list is defined and distribute_list.prefix_list is not none %}
-{% if distribute_list.prefix_list.in is defined and distribute_list.prefix_list.in is not none %}
- ipv6 distribute-list prefix {{ distribute_list.prefix_list.in }} in
-{% endif %}
-{% if distribute_list.prefix_list.out is defined and distribute_list.prefix_list.out is not none %}
- ipv6 distribute-list prefix {{ distribute_list.prefix_list.out }} out
-{% endif %}
-{% endif %}
-{% endif %}
-{% include 'frr/rip_ripng.frr.j2' %}
-!
diff --git a/data/templates/frr/rpki.frr.tmpl b/data/templates/frr/rpki.frr.j2
index fbdfa27c3..9a549d6de 100644
--- a/data/templates/frr/rpki.frr.tmpl
+++ b/data/templates/frr/rpki.frr.j2
@@ -1,17 +1,18 @@
!
{# as FRR does not support deleting the entire rpki section we leave it in place even when it's empty #}
rpki
-{% if cache is defined and cache is not none %}
-{% for peer, peer_config in cache.items() %}
-{# port is mandatory and preference uses a default value #}
-{% if peer_config.ssh is defined and peer_config.ssh.username is defined and peer_config.ssh.username is not none %}
+{% if cache is vyos_defined %}
+{% for peer, peer_config in cache.items() %}
+{# port is mandatory and preference uses a default value #}
+{% if peer_config.ssh.username is vyos_defined %}
rpki cache {{ peer | replace('_', '-') }} {{ peer_config.port }} {{ peer_config.ssh.username }} {{ peer_config.ssh.private_key_file }} {{ peer_config.ssh.public_key_file }} {{ peer_config.ssh.known_hosts_file }} preference {{ peer_config.preference }}
-{% else %}
+{% else %}
rpki cache {{ peer | replace('_', '-') }} {{ peer_config.port }} preference {{ peer_config.preference }}
-{% endif %}
-{% endfor %}
+{% endif %}
+{% endfor %}
{% endif %}
-{% if polling_period is defined and polling_period is not none %}
+{% if polling_period is vyos_defined %}
rpki polling_period {{ polling_period }}
{% endif %}
+exit
!
diff --git a/data/templates/frr/static_mcast.frr.tmpl b/data/templates/frr/static_mcast.frr.j2
index 4f114109a..491d4b54a 100644
--- a/data/templates/frr/static_mcast.frr.tmpl
+++ b/data/templates/frr/static_mcast.frr.j2
@@ -1,20 +1,20 @@
!
{% for route_gr in old_mroute %}
-{% for nh in old_mroute[route_gr] %}
-{% if old_mroute[route_gr][nh] %}
+{% for nh in old_mroute[route_gr] %}
+{% if old_mroute[route_gr][nh] %}
no ip mroute {{ route_gr }} {{ nh }} {{ old_mroute[route_gr][nh] }}
-{% else %}
+{% else %}
no ip mroute {{ route_gr }} {{ nh }}
-{% endif %}
-{% endfor %}
+{% endif %}
+{% endfor %}
{% endfor %}
{% for route_gr in mroute %}
-{% for nh in mroute[route_gr] %}
-{% if mroute[route_gr][nh] %}
+{% for nh in mroute[route_gr] %}
+{% if mroute[route_gr][nh] %}
ip mroute {{ route_gr }} {{ nh }} {{ mroute[route_gr][nh] }}
-{% else %}
+{% else %}
ip mroute {{ route_gr }} {{ nh }}
-{% endif %}
-{% endfor %}
+{% endif %}
+{% endfor %}
{% endfor %}
!
diff --git a/data/templates/frr/static_routes_macro.j2 b/data/templates/frr/static_routes_macro.j2
index 3b432b49b..1c64ac58b 100644
--- a/data/templates/frr/static_routes_macro.j2
+++ b/data/templates/frr/static_routes_macro.j2
@@ -1,21 +1,24 @@
{% macro static_routes(ip_ipv6, prefix, prefix_config, table=None) %}
-{% if prefix_config.blackhole is defined %}
-{{ ip_ipv6 }} route {{ prefix }} blackhole {{ prefix_config.blackhole.distance if prefix_config.blackhole.distance is defined }} {{ 'tag ' + prefix_config.blackhole.tag if prefix_config.blackhole.tag is defined }} {{ 'table ' + table if table is defined and table is not none }}
-{% endif %}
-{% if prefix_config.dhcp_interface is defined and prefix_config.dhcp_interface is not none %}
+{% if prefix_config.blackhole is vyos_defined %}
+{{ ip_ipv6 }} route {{ prefix }} blackhole {{ prefix_config.blackhole.distance if prefix_config.blackhole.distance is vyos_defined }} {{ 'tag ' ~ prefix_config.blackhole.tag if prefix_config.blackhole.tag is vyos_defined }} {{ 'table ' ~ table if table is vyos_defined and table is not none }}
+{% endif %}
+{% if prefix_config.reject is vyos_defined %}
+{{ ip_ipv6 }} route {{ prefix }} reject {{ prefix_config.reject.distance if prefix_config.reject.distance is vyos_defined }} {{ 'tag ' ~ prefix_config.reject.tag if prefix_config.reject.tag is vyos_defined }} {{ 'table ' ~ table if table is vyos_defined }}
+{% endif %}
+{% if prefix_config.dhcp_interface is vyos_defined %}
{% set next_hop = prefix_config.dhcp_interface | get_dhcp_router %}
-{% if next_hop is defined and next_hop is not none %}
-{{ ip_ipv6 }} route {{ prefix }} {{ next_hop }} {{ prefix_config.dhcp_interface }}
+{% if next_hop is vyos_defined %}
+{{ ip_ipv6 }} route {{ prefix }} {{ next_hop }} {{ prefix_config.dhcp_interface }} {{ 'table ' ~ table if table is vyos_defined }}
{% endif %}
-{% endif %}
-{% if prefix_config.interface is defined and prefix_config.interface is not none %}
+{% endif %}
+{% if prefix_config.interface is vyos_defined %}
{% for interface, interface_config in prefix_config.interface.items() if interface_config.disable is not defined %}
-{{ ip_ipv6 }} route {{ prefix }} {{ interface }} {{ interface_config.distance if interface_config.distance is defined }} {{ 'nexthop-vrf ' + interface_config.vrf if interface_config.vrf is defined }} {{ 'table ' + table if table is defined and table is not none }}
+{{ ip_ipv6 }} route {{ prefix }} {{ interface }} {{ interface_config.distance if interface_config.distance is vyos_defined }} {{ 'nexthop-vrf ' ~ interface_config.vrf if interface_config.vrf is vyos_defined }} {{ 'table ' ~ table if table is vyos_defined }}
{% endfor %}
-{% endif %}
-{% if prefix_config.next_hop is defined and prefix_config.next_hop is not none %}
+{% endif %}
+{% if prefix_config.next_hop is vyos_defined and prefix_config.next_hop is not none %}
{% for next_hop, next_hop_config in prefix_config.next_hop.items() if next_hop_config.disable is not defined %}
-{{ ip_ipv6 }} route {{ prefix }} {{ next_hop }} {{ next_hop_config.interface if next_hop_config.interface is defined }} {{ next_hop_config.distance if next_hop_config.distance is defined }} {{ 'nexthop-vrf ' + next_hop_config.vrf if next_hop_config.vrf is defined }} {{ 'table ' + table if table is defined and table is not none }}
+{{ ip_ipv6 }} route {{ prefix }} {{ next_hop }} {{ next_hop_config.interface if next_hop_config.interface is vyos_defined }} {{ next_hop_config.distance if next_hop_config.distance is vyos_defined }} {{ 'nexthop-vrf ' ~ next_hop_config.vrf if next_hop_config.vrf is vyos_defined }} {{ 'table ' ~ table if table is vyos_defined }}
{% endfor %}
-{% endif %}
+{% endif %}
{% endmacro %}
diff --git a/data/templates/frr/staticd.frr.j2 b/data/templates/frr/staticd.frr.j2
new file mode 100644
index 000000000..589f03c2c
--- /dev/null
+++ b/data/templates/frr/staticd.frr.j2
@@ -0,0 +1,64 @@
+{% from 'frr/static_routes_macro.j2' import static_routes %}
+!
+{% set ip_prefix = 'ip' %}
+{% set ipv6_prefix = 'ipv6' %}
+{% if vrf is vyos_defined %}
+{# We need to add an additional whitespace in front of the prefix #}
+{# when VRFs are in use, thus we use a variable for prefix handling #}
+{% set ip_prefix = ' ip' %}
+{% set ipv6_prefix = ' ipv6' %}
+vrf {{ vrf }}
+{% endif %}
+{# IPv4 routing #}
+{% if route is vyos_defined %}
+{% for prefix, prefix_config in route.items() %}
+{{ static_routes(ip_prefix, prefix, prefix_config) }}
+{% endfor %}
+{% endif %}
+{# IPv4 default routes from DHCP interfaces #}
+{% if dhcp is vyos_defined %}
+{% for interface, interface_config in dhcp.items() %}
+{% set next_hop = interface | get_dhcp_router %}
+{% if next_hop is vyos_defined %}
+{{ ip_prefix }} route 0.0.0.0/0 {{ next_hop }} {{ interface }} tag 210 {{ interface_config.dhcp_options.default_route_distance if interface_config.dhcp_options.default_route_distance is vyos_defined }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{# IPv4 default routes from PPPoE interfaces #}
+{% if pppoe is vyos_defined %}
+{% for interface, interface_config in pppoe.items() %}
+{{ ip_prefix }} route 0.0.0.0/0 {{ interface }} tag 210 {{ interface_config.default_route_distance if interface_config.default_route_distance is vyos_defined }}
+{% endfor %}
+{% endif %}
+{# IPv6 routing #}
+{% if route6 is vyos_defined %}
+{% for prefix, prefix_config in route6.items() %}
+{{ static_routes(ipv6_prefix, prefix, prefix_config) }}
+{% endfor %}
+{% endif %}
+{% if vrf is vyos_defined %}
+ exit-vrf
+{% endif %}
+!
+{# Policy route tables #}
+{% if table is vyos_defined %}
+{% for table_id, table_config in table.items() %}
+{% if table_config.route is vyos_defined %}
+{% for prefix, prefix_config in table_config.route.items() %}
+{{ static_routes('ip', prefix, prefix_config, table_id) }}
+{% endfor %}
+{% endif %}
+!
+{% if table_config.route6 is vyos_defined %}
+{% for prefix, prefix_config in table_config.route6.items() %}
+{{ static_routes('ipv6', prefix, prefix_config, table_id) }}
+{% endfor %}
+{% endif %}
+!
+{% endfor %}
+{% endif %}
+!
+{% if route_map is vyos_defined %}
+ip protocol static route-map {{ route_map }}
+!
+{% endif %}
diff --git a/data/templates/frr/staticd.frr.tmpl b/data/templates/frr/staticd.frr.tmpl
deleted file mode 100644
index bfe959c1d..000000000
--- a/data/templates/frr/staticd.frr.tmpl
+++ /dev/null
@@ -1,58 +0,0 @@
-{% from 'frr/static_routes_macro.j2' import static_routes %}
-!
-{% set ip_prefix = 'ip' %}
-{% set ipv6_prefix = 'ipv6' %}
-{% if vrf is defined and vrf is not none %}
-{# We need to add an additional whitespace in front of the prefix #}
-{# when VRFs are in use, thus we use a variable for prefix handling #}
-{% set ip_prefix = ' ip' %}
-{% set ipv6_prefix = ' ipv6' %}
-vrf {{ vrf }}
-{% endif %}
-{# IPv4 routing #}
-{% if route is defined and route is not none %}
-{% for prefix, prefix_config in route.items() %}
-{{ static_routes(ip_prefix, prefix, prefix_config) }}
-{%- endfor -%}
-{% endif %}
-{# IPv4 default routes from DHCP interfaces #}
-{% if dhcp is defined and dhcp is not none %}
-{% for interface in dhcp %}
-{% set next_hop = interface | get_dhcp_router %}
-{% if next_hop is defined and next_hop is not none %}
-{{ ip_prefix }} route 0.0.0.0/0 {{ next_hop }} {{ interface }} tag 210 210
-{% endif %}
-{% endfor %}
-{% endif %}
-{# IPv6 routing #}
-{% if route6 is defined and route6 is not none %}
-{% for prefix, prefix_config in route6.items() %}
-{{ static_routes(ipv6_prefix, prefix, prefix_config) }}
-{%- endfor -%}
-{% endif %}
-{% if vrf is defined and vrf is not none %}
- exit-vrf
-{% endif %}
-!
-{# Policy route tables #}
-{% if table is defined and table is not none %}
-{% for table_id, table_config in table.items() %}
-{% if table_config.route is defined and table_config.route is not none %}
-{% for prefix, prefix_config in table_config.route.items() %}
-{{ static_routes('ip', prefix, prefix_config, table_id) }}
-{%- endfor -%}
-{% endif %}
-!
-{% if table_config.route6 is defined and table_config.route6 is not none %}
-{% for prefix, prefix_config in table_config.route6.items() %}
-{{ static_routes('ipv6', prefix, prefix_config, table_id) }}
-{%- endfor -%}
-{% endif %}
-!
-{% endfor %}
-{% endif %}
-!
-{% if route_map is defined and route_map is not none %}
-ip protocol static route-map {{ route_map }}
-!
-{% endif %}
diff --git a/data/templates/frr/vrf-vni.frr.j2 b/data/templates/frr/vrf-vni.frr.j2
new file mode 100644
index 000000000..e5f4810a1
--- /dev/null
+++ b/data/templates/frr/vrf-vni.frr.j2
@@ -0,0 +1,9 @@
+{% if name is vyos_defined %}
+{% for vrf, vrf_config in name.items() %}
+vrf {{ vrf }}
+{% if vrf_config.vni is vyos_defined %}
+ vni {{ vrf_config.vni }}
+{% endif %}
+ exit-vrf
+{% endfor %}
+{% endif %}
diff --git a/data/templates/frr/vrf-vni.frr.tmpl b/data/templates/frr/vrf-vni.frr.tmpl
deleted file mode 100644
index 299c9719e..000000000
--- a/data/templates/frr/vrf-vni.frr.tmpl
+++ /dev/null
@@ -1,9 +0,0 @@
-{% if name is defined and name is not none %}
-{% for vrf, vrf_config in name.items() %}
-vrf {{ vrf }}
-{% if vrf_config.vni is defined and vrf_config.vni is not none %}
- vni {{ vrf_config.vni }}
-{% endif %}
- exit-vrf
-{% endfor %}
-{% endif %}
diff --git a/data/templates/frr/vrf.route-map.frr.j2 b/data/templates/frr/vrf.route-map.frr.j2
new file mode 100644
index 000000000..5e0c56a7b
--- /dev/null
+++ b/data/templates/frr/vrf.route-map.frr.j2
@@ -0,0 +1,10 @@
+!
+{% if vrf is vyos_defined and route_map is vyos_defined %}
+vrf {{ vrf }}
+ ip protocol {{ protocol }} route-map {{ route_map }}
+ exit-vrf
+!
+{% elif route_map is vyos_defined %}
+ip protocol {{ protocol }} route-map {{ route_map }}
+{% endif %}
+!
diff --git a/data/templates/frr/vrf.route-map.frr.tmpl b/data/templates/frr/vrf.route-map.frr.tmpl
deleted file mode 100644
index cb0e07616..000000000
--- a/data/templates/frr/vrf.route-map.frr.tmpl
+++ /dev/null
@@ -1,10 +0,0 @@
-!
-{% if vrf is defined and vrf is not none and route_map is defined and route_map is not none %}
-vrf {{ vrf }}
- ip protocol {{ protocol }} route-map {{ route_map }}
- exit-vrf
-!
-{% elif route_map is defined and route_map is not none %}
-ip protocol {{ protocol }} route-map {{ route_map }}
-{% endif %}
-!
diff --git a/data/templates/getty/serial-getty.service.tmpl b/data/templates/getty/serial-getty.service.j2
index 0183eae7d..0183eae7d 100644
--- a/data/templates/getty/serial-getty.service.tmpl
+++ b/data/templates/getty/serial-getty.service.j2
diff --git a/data/templates/high-availability/keepalived.conf.j2 b/data/templates/high-availability/keepalived.conf.j2
new file mode 100644
index 000000000..6684dbc2c
--- /dev/null
+++ b/data/templates/high-availability/keepalived.conf.j2
@@ -0,0 +1,169 @@
+# Autogenerated by VyOS
+# Do not edit this file, all your changes will be lost
+# on next commit or reboot
+
+global_defs {
+ dynamic_interfaces
+ script_user root
+ notify_fifo /run/keepalived/keepalived_notify_fifo
+ notify_fifo_script /usr/libexec/vyos/system/keepalived-fifo.py
+}
+
+{% if vrrp.group is vyos_defined %}
+{% for name, group_config in vrrp.group.items() if group_config.disable is not vyos_defined %}
+{% if group_config.health_check.script is vyos_defined %}
+vrrp_script healthcheck_{{ name }} {
+ script "{{ group_config.health_check.script }}"
+ interval {{ group_config.health_check.interval }}
+ fall {{ group_config.health_check.failure_count }}
+ rise 1
+}
+{% endif %}
+vrrp_instance {{ name }} {
+{% if group_config.description is vyos_defined %}
+ # {{ group_config.description }}
+{% endif %}
+ state BACKUP
+ interface {{ group_config.interface }}
+ virtual_router_id {{ group_config.vrid }}
+ priority {{ group_config.priority }}
+ advert_int {{ group_config.advertise_interval }}
+{% if group_config.track.exclude_vrrp_interface is vyos_defined %}
+ dont_track_primary
+{% endif %}
+{% if group_config.no_preempt is not vyos_defined and group_config.preempt_delay is vyos_defined %}
+ preempt_delay {{ group_config.preempt_delay }}
+{% elif group_config.no_preempt is vyos_defined %}
+ nopreempt
+{% endif %}
+{% if group_config.peer_address is vyos_defined %}
+ unicast_peer { {{ group_config.peer_address }} }
+{% endif %}
+{% if group_config.hello_source_address is vyos_defined %}
+{% if group_config.peer_address is vyos_defined %}
+ unicast_src_ip {{ group_config.hello_source_address }}
+{% else %}
+ mcast_src_ip {{ group_config.hello_source_address }}
+{% endif %}
+{% endif %}
+{% if group_config.rfc3768_compatibility is vyos_defined and group_config.peer_address is vyos_defined %}
+ use_vmac {{ group_config.interface }}v{{ group_config.vrid }}
+ vmac_xmit_base
+{% elif group_config.rfc3768_compatibility is vyos_defined %}
+ use_vmac {{ group_config.interface }}v{{ group_config.vrid }}
+{% endif %}
+{% if group_config.authentication is vyos_defined %}
+ authentication {
+ auth_pass "{{ group_config.authentication.password }}"
+{% if group_config.authentication.type is vyos_defined('plaintext-password') %}
+ auth_type PASS
+{% else %}
+ auth_type {{ group_config.authentication.type | upper }}
+{% endif %}
+ }
+{% endif %}
+{% if group_config.address is vyos_defined %}
+ virtual_ipaddress {
+{% for addr, addr_config in group_config.address.items() %}
+ {{ addr }}{{ ' dev ' + addr_config.interface if addr_config.interface is vyos_defined }}
+{% endfor %}
+ }
+{% endif %}
+{% if group_config.excluded_address is vyos_defined %}
+ virtual_ipaddress_excluded {
+{% for addr in group_config.excluded_address %}
+ {{ addr }}
+{% endfor %}
+ }
+{% endif %}
+{% if group_config.track.interface is vyos_defined %}
+ track_interface {
+{% for interface in group_config.track.interface %}
+ {{ interface }}
+{% endfor %}
+ }
+{% endif %}
+{% if group_config.health_check.script is vyos_defined %}
+ track_script {
+ healthcheck_{{ name }}
+ }
+{% endif %}
+}
+{% endfor %}
+{% endif %}
+
+{% if vrrp.sync_group is vyos_defined %}
+{% for name, sync_group_config in vrrp.sync_group.items() if sync_group_config.disable is not vyos_defined %}
+vrrp_sync_group {{ name }} {
+ group {
+{% if sync_group_config.member is vyos_defined %}
+{% for member in sync_group_config.member %}
+ {{ member }}
+{% endfor %}
+{% endif %}
+ }
+
+{# Health-check scripts should be in section sync-group if member is part of the sync-group T4081 #}
+{% if vrrp.group is vyos_defined %}
+{% for name, group_config in vrrp.group.items() if group_config.disable is not vyos_defined %}
+{% if group_config.health_check.script is vyos_defined and name in sync_group_config.member %}
+ track_script {
+ healthcheck_{{ name }}
+ }
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if conntrack_sync_group is vyos_defined(name) %}
+{% set vyos_helper = "/usr/libexec/vyos/vyos-vrrp-conntracksync.sh" %}
+ notify_master "{{ vyos_helper }} master {{ name }}"
+ notify_backup "{{ vyos_helper }} backup {{ name }}"
+ notify_fault "{{ vyos_helper }} fault {{ name }}"
+{% endif %}
+}
+{% endfor %}
+{% endif %}
+
+{% if virtual_server is vyos_defined %}
+# Virtual-server configuration
+{% for vserver, vserver_config in virtual_server.items() %}
+virtual_server {{ vserver }} {{ vserver_config.port }} {
+ delay_loop {{ vserver_config.delay_loop }}
+{% if vserver_config.algorithm is vyos_defined('round-robin') %}
+ lb_algo rr
+{% elif vserver_config.algorithm is vyos_defined('weighted-round-robin') %}
+ lb_algo wrr
+{% elif vserver_config.algorithm is vyos_defined('least-connection') %}
+ lb_algo lc
+{% elif vserver_config.algorithm is vyos_defined('weighted-least-connection') %}
+ lb_algo wlc
+{% elif vserver_config.algorithm is vyos_defined('source-hashing') %}
+ lb_algo sh
+{% elif vserver_config.algorithm is vyos_defined('destination-hashing') %}
+ lb_algo dh
+{% elif vserver_config.algorithm is vyos_defined('locality-based-least-connection') %}
+ lb_algo lblc
+{% endif %}
+{% if vserver_config.forward_method is vyos_defined('nat') %}
+ lb_kind NAT
+{% elif vserver_config.forward_method is vyos_defined('direct') %}
+ lb_kind DR
+{% elif vserver_config.forward_method is vyos_defined('tunnel') %}
+ lb_kind TUN
+{% endif %}
+ persistence_timeout {{ vserver_config.persistence_timeout }}
+ protocol {{ vserver_config.protocol | upper }}
+{% if vserver_config.real_server is vyos_defined %}
+{% for rserver, rserver_config in vserver_config.real_server.items() %}
+ real_server {{ rserver }} {{ rserver_config.port }} {
+ weight 1
+ {{ vserver_config.protocol | upper }}_CHECK {
+{% if rserver_config.connection_timeout is vyos_defined %}
+ connect_timeout {{ rserver_config.connection_timeout }}
+{% endif %}
+ }
+ }
+{% endfor %}
+{% endif %}
+}
+{% endfor %}
+{% endif %}
diff --git a/data/templates/https/nginx.default.tmpl b/data/templates/https/nginx.default.j2
index 9d73baeee..70e62ae7a 100644
--- a/data/templates/https/nginx.default.tmpl
+++ b/data/templates/https/nginx.default.j2
@@ -1,74 +1,56 @@
### Autogenerated by https.py ###
# Default server configuration
-#
-server {
- listen 80 default_server;
- listen [::]:80 default_server;
- server_name _;
- return 301 https://$host$request_uri;
-}
{% for server in server_block_list %}
server {
-
# SSL configuration
#
-{% if server.address == '*' %}
+{% if server.address == '*' %}
listen {{ server.port }} ssl;
listen [::]:{{ server.port }} ssl;
-{% else %}
+{% else %}
listen {{ server.address | bracketize_ipv6 }}:{{ server.port }} ssl;
-{% endif %}
+{% endif %}
-{% for name in server.name %}
+{% for name in server.name %}
server_name {{ name }};
-{% endfor %}
+{% endfor %}
-{% if server.certbot %}
+{% if server.certbot %}
ssl_certificate {{ server.certbot_dir }}/live/{{ server.certbot_domain_dir }}/fullchain.pem;
ssl_certificate_key {{ server.certbot_dir }}/live/{{ server.certbot_domain_dir }}/privkey.pem;
include {{ server.certbot_dir }}/options-ssl-nginx.conf;
ssl_dhparam {{ server.certbot_dir }}/ssl-dhparams.pem;
-{% elif server.vyos_cert %}
+{% elif server.vyos_cert %}
ssl_certificate {{ server.vyos_cert.crt }};
ssl_certificate_key {{ server.vyos_cert.key }};
-{% else %}
+{% else %}
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
include snippets/snakeoil.conf;
-{% endif %}
+{% endif %}
ssl_protocols TLSv1.2 TLSv1.3;
# proxy settings for HTTP API, if enabled; 503, if not
location ~ /(retrieve|configure|config-file|image|generate|show|docs|openapi.json|redoc|graphql) {
-{% if server.api %}
+{% if server.api %}
+{% if server.api.socket %}
+ proxy_pass http://unix:/run/api.sock;
+{% else %}
proxy_pass http://localhost:{{ server.api.port }};
+{% endif %}
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 600;
proxy_buffering off;
-{% else %}
+{% else %}
return 503;
-{% endif %}
+{% endif %}
}
error_page 497 =301 https://$host:{{ server.port }}$request_uri;
- error_page 501 502 503 =200 @50*_json;
-
-{% if api_set %}
- location @50*_json {
- default_type application/json;
- return 200 '{"error": "service https api unavailable at this proxy address: set service https api-restrict virtual-host"}';
- }
-{% else %}
- location @50*_json {
- default_type application/json;
- return 200 '{"error": "Start service in configuration mode: set service https api"}';
- }
-{% endif %}
-
}
{% endfor %}
diff --git a/data/templates/https/override.conf.j2 b/data/templates/https/override.conf.j2
new file mode 100644
index 000000000..c2c191b06
--- /dev/null
+++ b/data/templates/https/override.conf.j2
@@ -0,0 +1,15 @@
+{% set vrf_command = 'ip vrf exec ' ~ vrf ~ ' ' if vrf is vyos_defined else '' %}
+[Unit]
+StartLimitIntervalSec=0
+After=vyos-router.service
+
+[Service]
+ExecStartPre=
+ExecStartPre={{ vrf_command }}/usr/sbin/nginx -t -q -g 'daemon on; master_process on;'
+ExecStart=
+ExecStart={{ vrf_command }}/usr/sbin/nginx -g 'daemon on; master_process on;'
+ExecReload=
+ExecReload={{ vrf_command }}/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload
+Restart=always
+RestartPreventExitStatus=
+RestartSec=10
diff --git a/data/templates/https/vyos-http-api.service.j2 b/data/templates/https/vyos-http-api.service.j2
new file mode 100644
index 000000000..fb424e06c
--- /dev/null
+++ b/data/templates/https/vyos-http-api.service.j2
@@ -0,0 +1,22 @@
+{% set vrf_command = 'ip vrf exec ' ~ vrf ~ ' ' if vrf is vyos_defined else '' %}
+[Unit]
+Description=VyOS HTTP API service
+After=vyos-router.service
+Requires=vyos-router.service
+
+[Service]
+ExecStart={{ vrf_command }}/usr/libexec/vyos/services/vyos-http-api-server
+Type=idle
+
+SyslogIdentifier=vyos-http-api
+SyslogFacility=daemon
+
+Restart=on-failure
+
+# Does't work but leave it here
+User=root
+Group=vyattacfg
+
+[Install]
+WantedBy=vyos.target
+
diff --git a/data/templates/ids/fastnetmon.tmpl b/data/templates/ids/fastnetmon.j2
index 1f6a1c808..c482002fa 100644
--- a/data/templates/ids/fastnetmon.tmpl
+++ b/data/templates/ids/fastnetmon.j2
@@ -25,36 +25,32 @@ unban_only_if_attack_finished = on
# For each subnet, list track speed in bps and pps for both directions
enable_subnet_counters = off
-{% if "mirror" in mode %}
+{% if mode.mirror is vyos_defined %}
mirror_afpacket = on
{% endif %}
-{% if "in" in direction %}
-process_incoming_traffic = on
-{% endif %}
-{% if "out" in direction %}
-process_outgoing_traffic = on
-{% endif %}
-{% for th in threshold %}
-{% if th == "fps" %}
+process_incoming_traffic = {{ 'on' if direction is vyos_defined and 'in' in direction else 'off' }}
+process_outgoing_traffic = {{ 'on' if direction is vyos_defined and 'out' in direction else 'off' }}
+
+{% if threshold is vyos_defined %}
+{% for thr, thr_value in threshold.items() %}
+{% if thr is vyos_defined('fps') %}
ban_for_flows = on
-threshold_flows = {{ threshold[th] }}
-{% endif %}
-{% if th == "mbps" %}
+threshold_flows = {{ thr_value }}
+{% elif thr is vyos_defined('mbps') %}
ban_for_bandwidth = on
-threshold_mbps = {{ threshold[th] }}
-{% endif %}
-{% if th == "pps" %}
+threshold_mbps = {{ thr_value }}
+{% elif thr is vyos_defined('pps') %}
ban_for_pps = on
-threshold_pps = {{ threshold[th] }}
+threshold_pps = {{ thr_value }}
+{% endif %}
+{% endfor %}
{% endif %}
-{% endfor %}
-{% if listen_interface %}
-{% set value = listen_interface if listen_interface is string else listen_interface | join(',') %}
-interfaces = {{ value }}
+{% if listen_interface is vyos_defined %}
+interfaces = {{ listen_interface | join(',') }}
{% endif %}
-{% if alert_script %}
+{% if alert_script is vyos_defined %}
notify_script_path = {{ alert_script }}
{% endif %}
diff --git a/data/templates/ids/fastnetmon_networks_list.j2 b/data/templates/ids/fastnetmon_networks_list.j2
new file mode 100644
index 000000000..1c81180be
--- /dev/null
+++ b/data/templates/ids/fastnetmon_networks_list.j2
@@ -0,0 +1,7 @@
+{% if network is vyos_defined(var_type=str) %}
+{{ network }}
+{% else %}
+{% for net in network %}
+{{ net }}
+{% endfor %}
+{% endif %}
diff --git a/data/templates/ids/fastnetmon_networks_list.tmpl b/data/templates/ids/fastnetmon_networks_list.tmpl
deleted file mode 100644
index d58990053..000000000
--- a/data/templates/ids/fastnetmon_networks_list.tmpl
+++ /dev/null
@@ -1,7 +0,0 @@
-{% if network is string %}
-{{ network }}
-{% else %}
-{% for net in network %}
-{{ net }}
-{% endfor %}
-{% endif %}
diff --git a/data/templates/igmp-proxy/igmpproxy.conf.tmpl b/data/templates/igmp-proxy/igmpproxy.conf.j2
index e3966def3..ab3c9fd31 100644
--- a/data/templates/igmp-proxy/igmpproxy.conf.tmpl
+++ b/data/templates/igmp-proxy/igmpproxy.conf.j2
@@ -14,27 +14,27 @@
#
########################################################
-{% if disable_quickleave is not defined %}
+{% if disable_quickleave is not vyos_defined %}
quickleave
{% endif %}
-{% if interface is defined and interface is not none %}
-{% for iface, config in interface.items() %}
+{% if interface is vyos_defined %}
+{% for iface, config in interface.items() %}
# Configuration for {{ iface }} ({{ config.role }} interface)
-{% if config.role == 'disabled' %}
+{% if config.role is vyos_defined('disabled') %}
phyint {{ iface }} disabled
-{% else %}
+{% else %}
phyint {{ iface }} {{ config.role }} ratelimit 0 threshold {{ config.threshold }}
-{% endif %}
-{% if config.alt_subnet is defined and config.alt_subnet is not none %}
-{% for subnet in config.alt_subnet %}
+{% endif %}
+{% if config.alt_subnet is vyos_defined %}
+{% for subnet in config.alt_subnet %}
altnet {{ subnet }}
-{% endfor %}
-{% endif %}
-{% if config.whitelist is defined and config.whitelist is not none %}
-{% for subnet in config.whitelist %}
+{% endfor %}
+{% endif %}
+{% if config.whitelist is vyos_defined %}
+{% for subnet in config.whitelist %}
whitelist {{ subnet }}
-{% endfor %}
-{% endif %}
-{% endfor %}
+{% endfor %}
+{% endif %}
+{% endfor %}
{% endif %}
diff --git a/data/templates/ipsec/charon.tmpl b/data/templates/ipsec/charon.j2
index 4d710921e..388559af8 100644
--- a/data/templates/ipsec/charon.tmpl
+++ b/data/templates/ipsec/charon.j2
@@ -1,6 +1,5 @@
# Options for the charon IKE daemon.
charon {
-
# Accept unencrypted ID and HASH payloads in IKEv1 Main Mode.
# accept_unencrypted_mainmode_messages = no
@@ -20,6 +19,17 @@ charon {
# Send Cisco Unity vendor ID payload (IKEv1 only).
# cisco_unity = no
+ # Cisco FlexVPN
+{% if options is vyos_defined %}
+ cisco_flexvpn = {{ 'yes' if options.flexvpn is vyos_defined else 'no' }}
+{% if options.virtual_ip is vyos_defined %}
+ install_virtual_ip = yes
+{% endif %}
+{% if options.interface is vyos_defined %}
+ install_virtual_ip_on = {{ options.interface }}
+{% endif %}
+{% endif %}
+
# Close the IKE_SA if setup of the CHILD_SA along with IKE_AUTH failed.
# close_ike_on_child_failure = no
diff --git a/data/templates/ipsec/charon/dhcp.conf.tmpl b/data/templates/ipsec/charon/dhcp.conf.j2
index 92774b275..aaa5613fb 100644
--- a/data/templates/ipsec/charon/dhcp.conf.tmpl
+++ b/data/templates/ipsec/charon/dhcp.conf.j2
@@ -1,12 +1,10 @@
dhcp {
load = yes
-{% if remote_access is defined and remote_access.dhcp is defined %}
-{% if remote_access.dhcp.interface is defined %}
+{% if remote_access.dhcp.interface is vyos_defined %}
interface = {{ remote_access.dhcp.interface }}
-{% endif %}
-{% if remote_access.dhcp.server is defined %}
+{% endif %}
+{% if remote_access.dhcp.server is vyos_defined %}
server = {{ remote_access.dhcp.server }}
-{% endif %}
{% endif %}
# Always use the configured server address.
diff --git a/data/templates/ipsec/charon/eap-radius.conf.tmpl b/data/templates/ipsec/charon/eap-radius.conf.j2
index 5ec35c988..8495011fe 100644
--- a/data/templates/ipsec/charon/eap-radius.conf.tmpl
+++ b/data/templates/ipsec/charon/eap-radius.conf.j2
@@ -41,7 +41,7 @@ eap-radius {
load = yes
# NAS-Identifier to include in RADIUS messages.
- nas_identifier = {{ remote_access.radius.nas_identifier if remote_access is defined and remote_access.radius is defined and remote_access.radius.nas_identifier is defined else 'strongSwan' }}
+ nas_identifier = {{ remote_access.radius.nas_identifier if remote_access.radius.nas_identifier is vyos_defined else 'strongSwan' }}
# Port of RADIUS server (authentication).
# port = 1812
@@ -94,19 +94,19 @@ eap-radius {
# Section to specify multiple RADIUS servers.
servers {
-{% if remote_access is defined and remote_access.radius is defined and remote_access.radius.server is defined %}
-{% for server, server_options in remote_access.radius.server.items() if server_options.disable is not defined %}
+{% if remote_access.radius.server is vyos_defined %}
+{% for server, server_options in remote_access.radius.server.items() if server_options.disable is not vyos_defined %}
{{ server | replace('.', '-') }} {
address = {{ server }}
secret = {{ server_options.key }}
auth_port = {{ server_options.port }}
-{% if server_options.disable_accounting is not defined %}
- acct_port = {{ server_options.port | int +1 }}
-{% endif %}
+{% if server_options.disable_accounting is not vyos_defined %}
+ acct_port = {{ server_options.port | int + 1 }}
+{% endif %}
sockets = 20
}
-{% endfor %}
-{% endif %}
+{% endfor %}
+{% endif %}
}
# Section to configure multiple XAuth authentication rounds via RADIUS.
diff --git a/data/templates/ipsec/interfaces_use.conf.tmpl b/data/templates/ipsec/interfaces_use.conf.j2
index a77102396..c1bf8270d 100644
--- a/data/templates/ipsec/interfaces_use.conf.tmpl
+++ b/data/templates/ipsec/interfaces_use.conf.j2
@@ -1,5 +1,5 @@
-{% if interface is defined %}
+{% if interface is vyos_defined %}
charon {
interfaces_use = {{ ', '.join(interface) }}
}
-{% endif %} \ No newline at end of file
+{% endif %} \ No newline at end of file
diff --git a/data/templates/ipsec/ios_profile.tmpl b/data/templates/ipsec/ios_profile.j2
index af6c79d6e..c8e17729a 100644
--- a/data/templates/ipsec/ios_profile.tmpl
+++ b/data/templates/ipsec/ios_profile.j2
@@ -41,7 +41,7 @@
<!-- Remote identity, can be a FQDN, a userFQDN, an IP or (theoretically) a certificate's subject DN. Can't be empty.
IMPORTANT: DNs are currently not handled correctly, they are always sent as identities of type FQDN -->
<key>RemoteIdentifier</key>
- <string>{{ authentication.id if authentication.id is defined else 'fooo' }}</string>
+ <string>{{ authentication.id if authentication.id is vyos_defined else 'VyOS' }}</string>
<!-- Local IKE identity, same restrictions as above. If it is empty the client's IP address will be used -->
<key>LocalIdentifier</key>
<string></string>
diff --git a/data/templates/ipsec/ipsec.conf.j2 b/data/templates/ipsec/ipsec.conf.j2
new file mode 100644
index 000000000..f63995b38
--- /dev/null
+++ b/data/templates/ipsec/ipsec.conf.j2
@@ -0,0 +1,19 @@
+# Created by VyOS - manual changes will be overwritten
+
+config setup
+{% set charondebug = '' %}
+{% if log.subsystem is vyos_defined %}
+{% set subsystem = log.subsystem %}
+{% if 'any' in log.subsystem %}
+{% set subsystem = ['dmn', 'mgr', 'ike', 'chd','job', 'cfg', 'knl',
+ 'net', 'asn', 'enc', 'lib', 'esp', 'tls', 'tnc',
+ 'imc', 'imv', 'pts'] %}
+{% endif %}
+{% set charondebug = subsystem | join (' ' ~ log.level ~ ', ') ~ ' ' ~ log.level %}
+{% endif %}
+ charondebug = "{{ charondebug }}"
+ uniqueids = {{ "no" if disable_uniqreqids is vyos_defined else "yes" }}
+
+{% if include_ipsec_conf is vyos_defined %}
+include {{ include_ipsec_conf }}
+{% endif %}
diff --git a/data/templates/ipsec/ipsec.conf.tmpl b/data/templates/ipsec/ipsec.conf.tmpl
deleted file mode 100644
index 1cb531e76..000000000
--- a/data/templates/ipsec/ipsec.conf.tmpl
+++ /dev/null
@@ -1,18 +0,0 @@
-# Created by VyOS - manual changes will be overwritten
-
-config setup
-{% set charondebug = '' %}
-{% if log is defined and log.subsystem is defined and log.subsystem is not none %}
-{% set subsystem = log.subsystem %}
-{% if 'any' in log.subsystem %}
-{% set subsystem = ['dmn', 'mgr', 'ike', 'chd','job', 'cfg', 'knl', 'net', 'asn',
- 'enc', 'lib', 'esp', 'tls', 'tnc', 'imc', 'imv', 'pts'] %}
-{% endif %}
-{% set charondebug = subsystem | join (' ' ~ log.level ~ ', ') ~ ' ' ~ log.level %}
-{% endif %}
- charondebug = "{{ charondebug }}"
- uniqueids = {{ "no" if disable_uniqreqids is defined else "yes" }}
-
-{% if include_ipsec_conf is defined %}
-include {{ include_ipsec_conf }}
-{% endif %}
diff --git a/data/templates/ipsec/ipsec.secrets.tmpl b/data/templates/ipsec/ipsec.secrets.j2
index 057e291ed..a87ac9bc7 100644
--- a/data/templates/ipsec/ipsec.secrets.tmpl
+++ b/data/templates/ipsec/ipsec.secrets.j2
@@ -1,5 +1,5 @@
# Created by VyOS - manual changes will be overwritten
-{% if include_ipsec_secrets is defined %}
+{% if include_ipsec_secrets is vyos_defined %}
include {{ include_ipsec_secrets }}
-{% endif %}
+{% endif %}
diff --git a/data/templates/ipsec/swanctl.conf.j2 b/data/templates/ipsec/swanctl.conf.j2
new file mode 100644
index 000000000..bf6b8259c
--- /dev/null
+++ b/data/templates/ipsec/swanctl.conf.j2
@@ -0,0 +1,131 @@
+### Autogenerated by vpn_ipsec.py ###
+{% import 'ipsec/swanctl/l2tp.j2' as l2tp_tmpl %}
+{% import 'ipsec/swanctl/profile.j2' as profile_tmpl %}
+{% import 'ipsec/swanctl/peer.j2' as peer_tmpl %}
+{% import 'ipsec/swanctl/remote_access.j2' as remote_access_tmpl %}
+
+connections {
+{% if profile is vyos_defined %}
+{% for name, profile_conf in profile.items() if profile_conf.disable is not vyos_defined and profile_conf.bind.tunnel is vyos_defined %}
+{{ profile_tmpl.conn(name, profile_conf, ike_group, esp_group) }}
+{% endfor %}
+{% endif %}
+{% if site_to_site.peer is vyos_defined %}
+{% for peer, peer_conf in site_to_site.peer.items() if peer not in dhcp_no_address and peer_conf.disable is not vyos_defined %}
+{{ peer_tmpl.conn(peer, peer_conf, ike_group, esp_group) }}
+{% endfor %}
+{% endif %}
+{% if remote_access.connection is vyos_defined %}
+{% for rw, rw_conf in remote_access.connection.items() if rw_conf.disable is not vyos_defined %}
+{{ remote_access_tmpl.conn(rw, rw_conf, ike_group, esp_group) }}
+{% endfor %}
+{% endif %}
+{% if l2tp %}
+{{ l2tp_tmpl.conn(l2tp, l2tp_outside_address, l2tp_ike_default, l2tp_esp_default, ike_group, esp_group) }}
+{% endif %}
+}
+
+pools {
+{% if remote_access.pool is vyos_defined %}
+{% for pool, pool_config in remote_access.pool.items() %}
+ {{ pool }} {
+{% if pool_config.prefix is vyos_defined %}
+ addrs = {{ pool_config.prefix }}
+{% endif %}
+{% if pool_config.name_server is vyos_defined %}
+ dns = {{ pool_config.name_server | join(',') }}
+{% endif %}
+{% if pool_config.exclude is vyos_defined %}
+ split_exclude = {{ pool_config.exclude | join(',') }}
+{% endif %}
+ }
+{% endfor %}
+{% endif %}
+}
+
+secrets {
+{% if profile is vyos_defined %}
+{% for name, profile_conf in profile.items() if profile_conf.disable is not vyos_defined and profile_conf.bind.tunnel is vyos_defined %}
+{% if profile_conf.authentication.mode is vyos_defined('pre-shared-secret') %}
+{% for interface in profile_conf.bind.tunnel %}
+ ike-dmvpn-{{ interface }} {
+ secret = {{ profile_conf.authentication.pre_shared_secret }}
+ }
+{% endfor %}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if site_to_site.peer is vyos_defined %}
+{% for peer, peer_conf in site_to_site.peer.items() if peer not in dhcp_no_address and peer_conf.disable is not vyos_defined %}
+{% set peer_name = peer.replace("@", "") | dot_colon_to_dash %}
+{% if peer_conf.authentication.mode is vyos_defined('pre-shared-secret') %}
+ ike_{{ peer_name }} {
+{% if peer_conf.local_address is vyos_defined %}
+ id-local = {{ peer_conf.local_address }} # dhcp:{{ peer_conf.dhcp_interface if 'dhcp_interface' in peer_conf else 'no' }}
+{% endif %}
+ id-remote = {{ peer }}
+{% if peer_conf.authentication.id is vyos_defined %}
+ id-localid = {{ peer_conf.authentication.id }}
+{% endif %}
+{% if peer_conf.authentication.remote_id is vyos_defined %}
+ id-remoteid = {{ peer_conf.authentication.remote_id }}
+{% endif %}
+ secret = "{{ peer_conf.authentication.pre_shared_secret }}"
+ }
+{% elif peer_conf.authentication.mode is vyos_defined('x509') %}
+ private_{{ peer_name }} {
+ file = {{ peer_conf.authentication.x509.certificate }}.pem
+{% if peer_conf.authentication.x509.passphrase is vyos_defined %}
+ secret = "{{ peer_conf.authentication.x509.passphrase }}"
+{% endif %}
+ }
+{% elif peer_conf.authentication.mode is vyos_defined('rsa') %}
+ rsa_{{ peer_name }}_local {
+ file = {{ peer_conf.authentication.rsa.local_key }}.pem
+{% if peer_conf.authentication.rsa.passphrase is vyos_defined %}
+ secret = "{{ peer_conf.authentication.rsa.passphrase }}"
+{% endif %}
+ }
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if remote_access.connection is vyos_defined %}
+{% for ra, ra_conf in remote_access.connection.items() if ra_conf.disable is not vyos_defined %}
+{% if ra_conf.authentication.server_mode is vyos_defined('pre-shared-secret') %}
+ ike_{{ ra }} {
+{% if ra_conf.authentication.id is vyos_defined %}
+ id = "{{ ra_conf.authentication.id }}"
+{% elif ra_conf.local_address is vyos_defined %}
+ id = "{{ ra_conf.local_address }}"
+{% endif %}
+ secret = "{{ ra_conf.authentication.pre_shared_secret }}"
+ }
+{% endif %}
+{% if ra_conf.authentication.client_mode is vyos_defined('eap-mschapv2') and ra_conf.authentication.local_users.username is vyos_defined %}
+{% for user, user_conf in ra_conf.authentication.local_users.username.items() if user_conf.disable is not vyos_defined %}
+ eap-{{ ra }}-{{ user }} {
+ secret = "{{ user_conf.password }}"
+ id-{{ ra }}-{{ user }} = "{{ user }}"
+ }
+{% endfor %}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if l2tp %}
+{% if l2tp.authentication.mode is vyos_defined('pre-shared-secret') %}
+ ike_l2tp_remote_access {
+ id = "{{ l2tp_outside_address }}"
+ secret = "{{ l2tp.authentication.pre_shared_secret }}"
+ }
+{% elif l2tp.authentication.mode is vyos_defined('x509') %}
+ private_l2tp_remote_access {
+ id = "{{ l2tp_outside_address }}"
+ file = {{ l2tp.authentication.x509.certificate }}.pem
+{% if l2tp.authentication.x509.passphrase is vyos_defined %}
+ secret = "{{ l2tp.authentication.x509.passphrase }}"
+{% endif %}
+ }
+{% endif %}
+{% endif %}
+}
+
diff --git a/data/templates/ipsec/swanctl.conf.tmpl b/data/templates/ipsec/swanctl.conf.tmpl
deleted file mode 100644
index 161f19f95..000000000
--- a/data/templates/ipsec/swanctl.conf.tmpl
+++ /dev/null
@@ -1,131 +0,0 @@
-### Autogenerated by vpn_ipsec.py ###
-{% import 'ipsec/swanctl/l2tp.tmpl' as l2tp_tmpl %}
-{% import 'ipsec/swanctl/profile.tmpl' as profile_tmpl %}
-{% import 'ipsec/swanctl/peer.tmpl' as peer_tmpl %}
-{% import 'ipsec/swanctl/remote_access.tmpl' as remote_access_tmpl %}
-
-connections {
-{% if profile is defined %}
-{% for name, profile_conf in profile.items() if profile_conf.disable is not defined and profile_conf.bind is defined and profile_conf.bind.tunnel is defined %}
-{{ profile_tmpl.conn(name, profile_conf, ike_group, esp_group) }}
-{% endfor %}
-{% endif %}
-{% if site_to_site is defined and site_to_site.peer is defined %}
-{% for peer, peer_conf in site_to_site.peer.items() if peer not in dhcp_no_address and peer_conf.disable is not defined %}
-{{ peer_tmpl.conn(peer, peer_conf, ike_group, esp_group) }}
-{% endfor %}
-{% endif %}
-{% if remote_access is defined and remote_access.connection is defined and remote_access.connection is not none %}
-{% for rw, rw_conf in remote_access.connection.items() if rw_conf.disable is not defined %}
-{{ remote_access_tmpl.conn(rw, rw_conf, ike_group, esp_group) }}
-{% endfor %}
-{% endif %}
-{% if l2tp %}
-{{ l2tp_tmpl.conn(l2tp, l2tp_outside_address, l2tp_ike_default, l2tp_esp_default, ike_group, esp_group) }}
-{% endif %}
-}
-
-pools {
-{% if remote_access is defined and remote_access.pool is defined and remote_access.pool is not none %}
-{% for pool, pool_config in remote_access.pool.items() %}
- {{ pool }} {
-{% if pool_config.prefix is defined and pool_config.prefix is not none %}
- addrs = {{ pool_config.prefix }}
-{% endif %}
-{% if pool_config.name_server is defined and pool_config.name_server is not none %}
- dns = {{ pool_config.name_server | join(',') }}
-{% endif %}
-{% if pool_config.exclude is defined and pool_config.exclude is not none %}
- split_exclude = {{ pool_config.exclude | join(',') }}
-{% endif %}
- }
-{% endfor %}
-{% endif %}
-}
-
-secrets {
-{% if profile is defined %}
-{% for name, profile_conf in profile.items() if profile_conf.disable is not defined and profile_conf.bind is defined and profile_conf.bind.tunnel is defined %}
-{% if profile_conf.authentication.mode == 'pre-shared-secret' %}
-{% for interface in profile_conf.bind.tunnel %}
- ike-dmvpn-{{ interface }} {
- secret = {{ profile_conf.authentication.pre_shared_secret }}
- }
-{% endfor %}
-{% endif %}
-{% endfor %}
-{% endif %}
-{% if site_to_site is defined and site_to_site.peer is defined %}
-{% for peer, peer_conf in site_to_site.peer.items() if peer not in dhcp_no_address and peer_conf.disable is not defined %}
-{% set peer_name = peer.replace(".", "-").replace("@", "") %}
-{% if peer_conf.authentication.mode == 'pre-shared-secret' %}
- ike_{{ peer_name }} {
-{% if peer_conf.local_address is defined %}
- id-local = {{ peer_conf.local_address }} # dhcp:{{ peer_conf.dhcp_interface if 'dhcp_interface' in peer_conf else 'no' }}
-{% endif %}
- id-remote = {{ peer }}
-{% if peer_conf.authentication.id is defined %}
- id-localid = {{ peer_conf.authentication.id }}
-{% endif %}
-{% if peer_conf.authentication.remote_id is defined %}
- id-remoteid = {{ peer_conf.authentication.remote_id }}
-{% endif %}
- secret = "{{ peer_conf.authentication.pre_shared_secret }}"
- }
-{% elif peer_conf.authentication.mode == 'x509' %}
- private_{{ peer_name }} {
- file = {{ peer_conf.authentication.x509.certificate }}.pem
-{% if peer_conf.authentication.x509.passphrase is defined %}
- secret = "{{ peer_conf.authentication.x509.passphrase }}"
-{% endif %}
- }
-{% elif peer_conf.authentication.mode == 'rsa' %}
- rsa_{{ peer_name }}_local {
- file = {{ peer_conf.authentication.rsa.local_key }}.pem
-{% if peer_conf.authentication.rsa.passphrase is defined %}
- secret = "{{ peer_conf.authentication.rsa.passphrase }}"
-{% endif %}
- }
-{% endif %}
-{% endfor %}
-{% endif %}
-{% if remote_access is defined and remote_access.connection is defined and remote_access.connection is not none %}
-{% for ra, ra_conf in remote_access.connection.items() if ra_conf.disable is not defined %}
-{% if ra_conf.authentication.server_mode == 'pre-shared-secret' %}
- ike_{{ ra }} {
-{% if ra_conf.authentication.id is defined %}
- id = "{{ ra_conf.authentication.id }}"
-{% elif ra_conf.local_address is defined %}
- id = "{{ ra_conf.local_address }}"
-{% endif %}
- secret = "{{ ra_conf.authentication.pre_shared_secret }}"
- }
-{% endif %}
-{% if ra_conf.authentication.client_mode == 'eap-mschapv2' and ra_conf.authentication.local_users is defined and ra_conf.authentication.local_users.username is defined %}
-{% for user, user_conf in ra_conf.authentication.local_users.username.items() if user_conf.disable is not defined %}
- eap-{{ ra }}-{{ user }} {
- secret = "{{ user_conf.password }}"
- id-{{ ra }}-{{ user }} = "{{ user }}"
- }
-{% endfor %}
-{% endif %}
-{% endfor %}
-{% endif %}
-{% if l2tp %}
-{% if l2tp.authentication.mode == 'pre-shared-secret' %}
- ike_l2tp_remote_access {
- id = "{{ l2tp_outside_address }}"
- secret = "{{ l2tp.authentication.pre_shared_secret }}"
- }
-{% elif l2tp.authentication.mode == 'x509' %}
- private_l2tp_remote_access {
- id = "{{ l2tp_outside_address }}"
- file = {{ l2tp.authentication.x509.certificate }}.pem
-{% if l2tp.authentication.x509.passphrase is defined %}
- secret = "{{ l2tp.authentication.x509.passphrase }}"
-{% endif %}
- }
-{% endif %}
-{% endif %}
-}
-
diff --git a/data/templates/ipsec/swanctl/l2tp.tmpl b/data/templates/ipsec/swanctl/l2tp.j2
index 4cd1b4af3..7e63865cc 100644
--- a/data/templates/ipsec/swanctl/l2tp.tmpl
+++ b/data/templates/ipsec/swanctl/l2tp.j2
@@ -1,6 +1,6 @@
{% macro conn(l2tp, l2tp_outside_address, l2tp_ike_default, l2tp_esp_default, ike_group, esp_group) %}
-{% set l2tp_ike = ike_group[l2tp.ike_group] if l2tp.ike_group is defined else None %}
-{% set l2tp_esp = esp_group[l2tp.esp_group] if l2tp.esp_group is defined else None %}
+{% set l2tp_ike = ike_group[l2tp.ike_group] if l2tp.ike_group is vyos_defined else None %}
+{% set l2tp_esp = esp_group[l2tp.esp_group] if l2tp.esp_group is vyos_defined else None %}
l2tp_remote_access {
proposals = {{ l2tp_ike | get_esp_ike_cipher | join(',') if l2tp_ike else l2tp_ike_default }}
local_addrs = {{ l2tp_outside_address }}
@@ -10,9 +10,9 @@
reauth_time = 0
local {
auth = {{ 'psk' if l2tp.authentication.mode == 'pre-shared-secret' else 'pubkey' }}
-{% if l2tp.authentication.mode == 'x509' %}
+{% if l2tp.authentication.mode == 'x509' %}
certs = {{ l2tp.authentication.x509.certificate }}.pem
-{% endif %}
+{% endif %}
}
remote {
auth = {{ 'psk' if l2tp.authentication.mode == 'pre-shared-secret' else 'pubkey' }}
diff --git a/data/templates/ipsec/swanctl/peer.j2 b/data/templates/ipsec/swanctl/peer.j2
new file mode 100644
index 000000000..90d2c774f
--- /dev/null
+++ b/data/templates/ipsec/swanctl/peer.j2
@@ -0,0 +1,166 @@
+{% macro conn(peer, peer_conf, ike_group, esp_group) %}
+{% set name = peer.replace("@", "") | dot_colon_to_dash %}
+{# peer needs to reference the global IKE configuration for certain values #}
+{% set ike = ike_group[peer_conf.ike_group] %}
+ peer_{{ name }} {
+ proposals = {{ ike | get_esp_ike_cipher | join(',') }}
+ version = {{ ike.key_exchange[4:] if ike.key_exchange is vyos_defined else "0" }}
+{% if peer_conf.virtual_address is vyos_defined %}
+ vips = {{ peer_conf.virtual_address | join(', ') }}
+{% endif %}
+ local_addrs = {{ peer_conf.local_address if peer_conf.local_address != 'any' else '0.0.0.0/0' }} # dhcp:{{ peer_conf.dhcp_interface if 'dhcp_interface' in peer_conf else 'no' }}
+ remote_addrs = {{ peer if peer not in ['any', '0.0.0.0'] and peer[0:1] != '@' else '0.0.0.0/0' }}
+{% if peer_conf.authentication.mode is vyos_defined('x509') %}
+ send_cert = always
+{% endif %}
+{% if ike.dead_peer_detection is vyos_defined %}
+ dpd_timeout = {{ ike.dead_peer_detection.timeout }}
+ dpd_delay = {{ ike.dead_peer_detection.interval }}
+{% endif %}
+{% if ike.key_exchange is vyos_defined('ikev1') and ike.mode is vyos_defined('aggressive') %}
+ aggressive = yes
+{% endif %}
+ rekey_time = {{ ike.lifetime }}s
+ mobike = {{ "yes" if ike.mobike is not defined or ike.mobike == "enable" else "no" }}
+{% if peer[0:1] == '@' %}
+ keyingtries = 0
+ reauth_time = 0
+{% elif peer_conf.connection_type is not vyos_defined or peer_conf.connection_type is vyos_defined('initiate') %}
+ keyingtries = 0
+{% elif peer_conf.connection_type is vyos_defined('respond') %}
+ keyingtries = 1
+{% endif %}
+{% if peer_conf.force_encapsulation is vyos_defined('enable') %}
+ encap = yes
+{% endif %}
+ local {
+{% if peer_conf.authentication.id is vyos_defined %}
+ id = "{{ peer_conf.authentication.id }}"
+{% endif %}
+ auth = {{ 'psk' if peer_conf.authentication.mode == 'pre-shared-secret' else 'pubkey' }}
+{% if peer_conf.authentication.mode == 'x509' %}
+ certs = {{ peer_conf.authentication.x509.certificate }}.pem
+{% elif peer_conf.authentication.mode == 'rsa' %}
+ pubkeys = {{ peer_conf.authentication.rsa.local_key }}.pem
+{% endif %}
+ }
+ remote {
+{% if peer_conf.authentication.remote_id is vyos_defined %}
+ id = "{{ peer_conf.authentication.remote_id }}"
+{% else %}
+ id = "{{ peer }}"
+{% endif %}
+ auth = {{ 'psk' if peer_conf.authentication.mode == 'pre-shared-secret' else 'pubkey' }}
+{% if peer_conf.authentication.mode == 'rsa' %}
+ pubkeys = {{ peer_conf.authentication.rsa.remote_key }}.pem
+{% endif %}
+ }
+ children {
+{% if peer_conf.vti.bind is vyos_defined and peer_conf.tunnel is not vyos_defined %}
+{% set vti_esp = esp_group[ peer_conf.vti.esp_group ] if peer_conf.vti.esp_group is vyos_defined else esp_group[ peer_conf.default_esp_group ] %}
+ peer_{{ name }}_vti {
+ esp_proposals = {{ vti_esp | get_esp_ike_cipher(ike) | join(',') }}
+{% if vti_esp.life_bytes is vyos_defined %}
+ life_bytes = {{ vti_esp.life_bytes }}
+{% endif %}
+{% if vti_esp.life_packets is vyos_defined %}
+ life_packets = {{ vti_esp.life_packets }}
+{% endif %}
+ life_time = {{ vti_esp.lifetime }}s
+ local_ts = 0.0.0.0/0,::/0
+ remote_ts = 0.0.0.0/0,::/0
+ updown = "/etc/ipsec.d/vti-up-down {{ peer_conf.vti.bind }}"
+{# The key defaults to 0 and will match any policies which similarly do not have a lookup key configuration. #}
+{# Thus we simply shift the key by one to also support a vti0 interface #}
+{% set if_id = peer_conf.vti.bind | replace('vti', '') | int + 1 %}
+ if_id_in = {{ if_id }}
+ if_id_out = {{ if_id }}
+ ipcomp = {{ 'yes' if vti_esp.compression is vyos_defined('enable') else 'no' }}
+ mode = {{ vti_esp.mode }}
+{% if peer[0:1] == '@' %}
+ start_action = none
+{% elif peer_conf.connection_type is not vyos_defined or peer_conf.connection_type is vyos_defined('initiate') %}
+ start_action = start
+{% elif peer_conf.connection_type is vyos_defined('respond') %}
+ start_action = trap
+{% elif peer_conf.connection_type is vyos_defined('none') %}
+ start_action = none
+{% endif %}
+{% if ike.dead_peer_detection is vyos_defined %}
+{% set dpd_translate = {'clear': 'clear', 'hold': 'trap', 'restart': 'restart'} %}
+ dpd_action = {{ dpd_translate[ike.dead_peer_detection.action] }}
+{% endif %}
+ close_action = {{ {'none': 'none', 'hold': 'trap', 'restart': 'start'}[ike.close_action] }}
+ }
+{% elif peer_conf.tunnel is vyos_defined %}
+{% for tunnel_id, tunnel_conf in peer_conf.tunnel.items() if tunnel_conf.disable is not defined %}
+{% set tunnel_esp_name = tunnel_conf.esp_group if tunnel_conf.esp_group is vyos_defined else peer_conf.default_esp_group %}
+{% set tunnel_esp = esp_group[tunnel_esp_name] %}
+{% set proto = tunnel_conf.protocol if tunnel_conf.protocol is vyos_defined else '' %}
+{% set local_port = tunnel_conf.local.port if tunnel_conf.local.port is vyos_defined else '' %}
+{% set local_suffix = '[{0}/{1}]'.format(proto, local_port) if proto or local_port else '' %}
+{% set remote_port = tunnel_conf.remote.port if tunnel_conf.remote.port is vyos_defined else '' %}
+{% set remote_suffix = '[{0}/{1}]'.format(proto, remote_port) if proto or remote_port else '' %}
+ peer_{{ name }}_tunnel_{{ tunnel_id }} {
+ esp_proposals = {{ tunnel_esp | get_esp_ike_cipher(ike) | join(',') }}
+{% if tunnel_esp.life_bytes is vyos_defined %}
+ life_bytes = {{ tunnel_esp.life_bytes }}
+{% endif %}
+{% if tunnel_esp.life_packets is vyos_defined %}
+ life_packets = {{ tunnel_esp.life_packets }}
+{% endif %}
+ life_time = {{ tunnel_esp.lifetime }}s
+{% if tunnel_esp.mode is not defined or tunnel_esp.mode == 'tunnel' %}
+{% if tunnel_conf.local.prefix is vyos_defined %}
+{% set local_prefix = tunnel_conf.local.prefix if 'any' not in tunnel_conf.local.prefix else ['0.0.0.0/0', '::/0'] %}
+ local_ts = {{ local_prefix | join(local_suffix + ",") }}{{ local_suffix }}
+{% endif %}
+{% if tunnel_conf.remote.prefix is vyos_defined %}
+{% set remote_prefix = tunnel_conf.remote.prefix if 'any' not in tunnel_conf.remote.prefix else ['0.0.0.0/0', '::/0'] %}
+ remote_ts = {{ remote_prefix | join(remote_suffix + ",") }}{{ remote_suffix }}
+{% endif %}
+{% if tunnel_conf.priority is vyos_defined %}
+ priority = {{ tunnel_conf.priority }}
+{% endif %}
+{% elif tunnel_esp.mode == 'transport' %}
+ local_ts = {{ peer_conf.local_address }}{{ local_suffix }}
+ remote_ts = {{ peer }}{{ remote_suffix }}
+{% endif %}
+ ipcomp = {{ 'yes' if tunnel_esp.compression is vyos_defined('enable') else 'no' }}
+ mode = {{ tunnel_esp.mode }}
+{% if peer[0:1] == '@' %}
+ start_action = none
+{% elif peer_conf.connection_type is not vyos_defined or peer_conf.connection_type is vyos_defined('initiate') %}
+ start_action = start
+{% elif peer_conf.connection_type is vyos_defined('respond') %}
+ start_action = trap
+{% elif peer_conf.connection_type is vyos_defined('none') %}
+ start_action = none
+{% endif %}
+{% if ike.dead_peer_detection is vyos_defined %}
+{% set dpd_translate = {'clear': 'clear', 'hold': 'trap', 'restart': 'restart'} %}
+ dpd_action = {{ dpd_translate[ike.dead_peer_detection.action] }}
+{% endif %}
+ close_action = {{ {'none': 'none', 'hold': 'trap', 'restart': 'start'}[ike.close_action] }}
+{% if peer_conf.vti.bind is vyos_defined %}
+{# The key defaults to 0 and will match any policies which similarly do not have a lookup key configuration. #}
+{# Thus we simply shift the key by one to also support a vti0 interface #}
+{% set if_id = peer_conf.vti.bind | replace('vti', '') | int + 1 %}
+ updown = "/etc/ipsec.d/vti-up-down {{ peer_conf.vti.bind }}"
+ if_id_in = {{ if_id }}
+ if_id_out = {{ if_id }}
+{% endif %}
+ }
+{% if tunnel_conf.passthrough is vyos_defined %}
+ peer_{{ name }}_tunnel_{{ tunnel_id }}_passthrough {
+ local_ts = {{ tunnel_conf.passthrough | join(",") }}
+ remote_ts = {{ tunnel_conf.passthrough | join(",") }}
+ start_action = trap
+ mode = pass
+ }
+{% endif %}
+{% endfor %}
+{% endif %}
+ }
+ }
+{% endmacro %}
diff --git a/data/templates/ipsec/swanctl/peer.tmpl b/data/templates/ipsec/swanctl/peer.tmpl
deleted file mode 100644
index 8c3776bf1..000000000
--- a/data/templates/ipsec/swanctl/peer.tmpl
+++ /dev/null
@@ -1,142 +0,0 @@
-{% macro conn(peer, peer_conf, ike_group, esp_group) %}
-{% set name = peer.replace(".", "-").replace("@", "") %}
-{# peer needs to reference the global IKE configuration for certain values #}
-{% set ike = ike_group[peer_conf.ike_group] %}
- peer_{{ name }} {
- proposals = {{ ike | get_esp_ike_cipher | join(',') }}
- version = {{ ike.key_exchange[4:] if ike is defined and ike.key_exchange is defined else "0" }}
- local_addrs = {{ peer_conf.local_address if peer_conf.local_address != 'any' else '0.0.0.0/0' }} # dhcp:{{ peer_conf.dhcp_interface if 'dhcp_interface' in peer_conf else 'no' }}
- remote_addrs = {{ peer if peer not in ['any', '0.0.0.0'] and peer[0:1] != '@' else '0.0.0.0/0' }}
-{% if peer_conf.authentication is defined and peer_conf.authentication.mode is defined and peer_conf.authentication.mode == 'x509' %}
- send_cert = always
-{% endif %}
-{% if ike.dead_peer_detection is defined %}
- dpd_timeout = {{ ike.dead_peer_detection.timeout }}
- dpd_delay = {{ ike.dead_peer_detection.interval }}
-{% endif %}
-{% if ike.key_exchange is defined and ike.key_exchange == "ikev1" and ike.mode is defined and ike.mode == "aggressive" %}
- aggressive = yes
-{% endif %}
- rekey_time = {{ ike.lifetime }}s
- mobike = {{ "yes" if ike.mobike is not defined or ike.mobike == "enable" else "no" }}
-{% if peer[0:1] == '@' %}
- keyingtries = 0
- reauth_time = 0
-{% elif peer_conf.connection_type is not defined or peer_conf.connection_type == 'initiate' %}
- keyingtries = 0
-{% elif peer_conf.connection_type is defined and peer_conf.connection_type == 'respond' %}
- keyingtries = 1
-{% endif %}
-{% if peer_conf.force_encapsulation is defined and peer_conf.force_encapsulation == 'enable' %}
- encap = yes
-{% endif %}
- local {
-{% if peer_conf.authentication is defined and peer_conf.authentication.id is defined and peer_conf.authentication.id is not none %}
- id = "{{ peer_conf.authentication.id }}"
-{% endif %}
- auth = {{ 'psk' if peer_conf.authentication.mode == 'pre-shared-secret' else 'pubkey' }}
-{% if peer_conf.authentication.mode == 'x509' %}
- certs = {{ peer_conf.authentication.x509.certificate }}.pem
-{% elif peer_conf.authentication.mode == 'rsa' %}
- pubkeys = {{ peer_conf.authentication.rsa.local_key }}.pem
-{% endif %}
- }
- remote {
-{% if peer_conf.authentication is defined and peer_conf.authentication.remote_id is defined and peer_conf.authentication.remote_id is not none %}
- id = "{{ peer_conf.authentication.remote_id }}"
-{% else %}
- id = "{{ peer }}"
-{% endif %}
- auth = {{ 'psk' if peer_conf.authentication.mode == 'pre-shared-secret' else 'pubkey' }}
-{% if peer_conf.authentication.mode == 'rsa' %}
- pubkeys = {{ peer_conf.authentication.rsa.remote_key }}.pem
-{% endif %}
- }
- children {
-{% if peer_conf.vti is defined and peer_conf.vti.bind is defined and peer_conf.tunnel is not defined %}
-{% set vti_esp = esp_group[ peer_conf.vti.esp_group ] if peer_conf.vti.esp_group is defined else esp_group[ peer_conf.default_esp_group ] %}
- peer_{{ name }}_vti {
- esp_proposals = {{ vti_esp | get_esp_ike_cipher(ike) | join(',') }}
- life_time = {{ vti_esp.lifetime }}s
- local_ts = 0.0.0.0/0,::/0
- remote_ts = 0.0.0.0/0,::/0
- updown = "/etc/ipsec.d/vti-up-down {{ peer_conf.vti.bind }}"
- {# The key defaults to 0 and will match any policies which similarly do not have a lookup key configuration. #}
- {# Thus we simply shift the key by one to also support a vti0 interface #}
-{% set if_id = peer_conf.vti.bind | replace('vti', '') | int +1 %}
- if_id_in = {{ if_id }}
- if_id_out = {{ if_id }}
- ipcomp = {{ 'yes' if vti_esp.compression is defined and vti_esp.compression == 'enable' else 'no' }}
- mode = {{ vti_esp.mode }}
-{% if peer[0:1] == '@' %}
- start_action = none
-{% elif peer_conf.connection_type is not defined or peer_conf.connection_type == 'initiate' %}
- start_action = start
-{% elif peer_conf.connection_type == 'respond' %}
- start_action = trap
-{% endif %}
-{% if ike.dead_peer_detection is defined %}
-{% set dpd_translate = {'clear': 'clear', 'hold': 'trap', 'restart': 'start'} %}
- dpd_action = {{ dpd_translate[ike.dead_peer_detection.action] }}
-{% endif %}
- }
-{% elif peer_conf.tunnel is defined %}
-{% for tunnel_id, tunnel_conf in peer_conf.tunnel.items() if tunnel_conf.disable is not defined %}
-{% set tunnel_esp_name = tunnel_conf.esp_group if tunnel_conf.esp_group is defined else peer_conf.default_esp_group %}
-{% set tunnel_esp = esp_group[tunnel_esp_name] %}
-{% set proto = tunnel_conf.protocol if tunnel_conf.protocol is defined else '' %}
-{% set local_port = tunnel_conf.local.port if tunnel_conf.local is defined and tunnel_conf.local.port is defined else '' %}
-{% set local_suffix = '[{0}/{1}]'.format(proto, local_port) if proto or local_port else '' %}
-{% set remote_port = tunnel_conf.remote.port if tunnel_conf.remote is defined and tunnel_conf.remote.port is defined else '' %}
-{% set remote_suffix = '[{0}/{1}]'.format(proto, remote_port) if proto or remote_port else '' %}
- peer_{{ name }}_tunnel_{{ tunnel_id }} {
- esp_proposals = {{ tunnel_esp | get_esp_ike_cipher(ike) | join(',') }}
- life_time = {{ tunnel_esp.lifetime }}s
-{% if tunnel_esp.mode is not defined or tunnel_esp.mode == 'tunnel' %}
-{% if tunnel_conf.local is defined and tunnel_conf.local.prefix is defined %}
-{% set local_prefix = tunnel_conf.local.prefix if 'any' not in tunnel_conf.local.prefix else ['0.0.0.0/0', '::/0'] %}
- local_ts = {{ local_prefix | join(local_suffix + ",") }}{{ local_suffix }}
-{% endif %}
-{% if tunnel_conf.remote is defined and tunnel_conf.remote.prefix is defined %}
-{% set remote_prefix = tunnel_conf.remote.prefix if 'any' not in tunnel_conf.remote.prefix else ['0.0.0.0/0', '::/0'] %}
- remote_ts = {{ remote_prefix | join(remote_suffix + ",") }}{{ remote_suffix }}
-{% endif %}
-{% elif tunnel_esp.mode == 'transport' %}
- local_ts = {{ peer_conf.local_address }}{{ local_suffix }}
- remote_ts = {{ peer }}{{ remote_suffix }}
-{% endif %}
- ipcomp = {{ 'yes' if tunnel_esp.compression is defined and tunnel_esp.compression == 'enable' else 'no' }}
- mode = {{ tunnel_esp.mode }}
-{% if peer[0:1] == '@' %}
- start_action = none
-{% elif peer_conf.connection_type is not defined or peer_conf.connection_type == 'initiate' %}
- start_action = start
-{% elif peer_conf.connection_type == 'respond' %}
- start_action = trap
-{% endif %}
-{% if ike.dead_peer_detection is defined %}
-{% set dpd_translate = {'clear': 'clear', 'hold': 'trap', 'restart': 'start'} %}
- dpd_action = {{ dpd_translate[ike.dead_peer_detection.action] }}
-{% endif %}
-{% if peer_conf.vti is defined and peer_conf.vti.bind is defined %}
- updown = "/etc/ipsec.d/vti-up-down {{ peer_conf.vti.bind }}"
- {# The key defaults to 0 and will match any policies which similarly do not have a lookup key configuration. #}
- {# Thus we simply shift the key by one to also support a vti0 interface #}
-{% set if_id = peer_conf.vti.bind | replace('vti', '') | int +1 %}
- if_id_in = {{ if_id }}
- if_id_out = {{ if_id }}
-{% endif %}
- }
-{% if tunnel_conf.passthrough is defined and tunnel_conf.passthrough %}
- peer_{{ name }}_tunnel_{{ tunnel_id }}_passthough {
- local_ts = {{ tunnel_conf.passthrough | join(",") }}
- remote_ts = {{ tunnel_conf.passthrough | join(",") }}
- start_action = trap
- mode = pass
- }
-{% endif %}
-{% endfor %}
-{% endif %}
- }
- }
-{% endmacro %}
diff --git a/data/templates/ipsec/swanctl/profile.tmpl b/data/templates/ipsec/swanctl/profile.j2
index a5cae31c0..d4f417378 100644
--- a/data/templates/ipsec/swanctl/profile.tmpl
+++ b/data/templates/ipsec/swanctl/profile.j2
@@ -1,39 +1,39 @@
{% macro conn(name, profile_conf, ike_group, esp_group) %}
-{# peer needs to reference the global IKE configuration for certain values #}
-{% set ike = ike_group[profile_conf.ike_group] %}
-{% set esp = esp_group[profile_conf.esp_group] %}
-{% if profile_conf.bind is defined and profile_conf.bind.tunnel is defined %}
+{# peer needs to reference the global IKE configuration for certain values #}
+{% set ike = ike_group[profile_conf.ike_group] %}
+{% set esp = esp_group[profile_conf.esp_group] %}
+{% if profile_conf.bind.tunnel is vyos_defined %}
{% for interface in profile_conf.bind.tunnel %}
dmvpn-{{ name }}-{{ interface }} {
proposals = {{ ike_group[profile_conf.ike_group] | get_esp_ike_cipher | join(',') }}
- version = {{ ike.key_exchange[4:] if ike is defined and ike.key_exchange is defined else "0" }}
+ version = {{ ike.key_exchange[4:] if ike.key_exchange is vyos_defined else "0" }}
rekey_time = {{ ike.lifetime }}s
keyingtries = 0
-{% if profile_conf.authentication is defined and profile_conf.authentication.mode is defined and profile_conf.authentication.mode == 'pre-shared-secret' %}
+{% if profile_conf.authentication.mode is vyos_defined('pre-shared-secret') %}
local {
auth = psk
}
remote {
auth = psk
}
-{% endif %}
+{% endif %}
children {
dmvpn {
- esp_proposals = {{ esp | get_esp_ike_cipher(ike) | join(',') }}
+ esp_proposals = {{ esp | get_esp_ike_cipher(ike) | join(',') }}
rekey_time = {{ esp.lifetime }}s
rand_time = 540s
local_ts = dynamic[gre]
remote_ts = dynamic[gre]
mode = {{ esp.mode }}
-{% if ike.dead_peer_detection is defined and ike.dead_peer_detection.action is defined %}
+{% if ike.dead_peer_detection.action is vyos_defined %}
dpd_action = {{ ike.dead_peer_detection.action }}
-{% endif %}
-{% if esp.compression is defined and esp.compression == 'enable' %}
+{% endif %}
+{% if esp.compression is vyos_defined('enable') %}
ipcomp = yes
-{% endif %}
+{% endif %}
}
}
}
{% endfor %}
-{% endif %}
+{% endif %}
{% endmacro %}
diff --git a/data/templates/ipsec/swanctl/remote_access.tmpl b/data/templates/ipsec/swanctl/remote_access.j2
index 6354c60b1..d2760ec1f 100644
--- a/data/templates/ipsec/swanctl/remote_access.tmpl
+++ b/data/templates/ipsec/swanctl/remote_access.j2
@@ -1,37 +1,38 @@
{% macro conn(name, rw_conf, ike_group, esp_group) %}
-{# peer needs to reference the global IKE configuration for certain values #}
-{% set ike = ike_group[rw_conf.ike_group] %}
-{% set esp = esp_group[rw_conf.esp_group] %}
+{# peer needs to reference the global IKE configuration for certain values #}
+{% set ike = ike_group[rw_conf.ike_group] %}
+{% set esp = esp_group[rw_conf.esp_group] %}
ra-{{ name }} {
remote_addrs = %any
- local_addrs = {{ rw_conf.local_address if rw_conf.local_address is defined else '%any' }}
+ local_addrs = {{ rw_conf.local_address if rw_conf.local_address is vyos_defined else '%any' }}
proposals = {{ ike_group[rw_conf.ike_group] | get_esp_ike_cipher | join(',') }}
- version = {{ ike.key_exchange[4:] if ike is defined and ike.key_exchange is defined else "0" }}
+ version = {{ ike.key_exchange[4:] if ike.key_exchange is vyos_defined else "0" }}
send_certreq = no
rekey_time = {{ ike.lifetime }}s
keyingtries = 0
-{% if rw_conf.unique is defined and rw_conf.unique is not none %}
+{% if rw_conf.unique is vyos_defined %}
unique = {{ rw_conf.unique }}
-{% endif %}
-{% if rw_conf.pool is defined and rw_conf.pool is not none %}
+{% endif %}
+{% if rw_conf.pool is vyos_defined %}
pools = {{ rw_conf.pool | join(',') }}
-{% endif %}
+{% endif %}
local {
-{% if rw_conf.authentication.id is defined and rw_conf.authentication.use_x509_id is not defined %}
+{% if rw_conf.authentication.id is vyos_defined and rw_conf.authentication.use_x509_id is not vyos_defined %}
+{# please use " quotes - else Apple iOS goes crazy #}
id = "{{ rw_conf.authentication.id }}"
-{% endif %}
-{% if rw_conf.authentication.server_mode == 'x509' %}
+{% endif %}
+{% if rw_conf.authentication.server_mode == 'x509' %}
auth = pubkey
certs = {{ rw_conf.authentication.x509.certificate }}.pem
-{% elif rw_conf.authentication.server_mode == 'pre-shared-secret' %}
+{% elif rw_conf.authentication.server_mode == 'pre-shared-secret' %}
auth = psk
-{% endif %}
+{% endif %}
}
remote {
auth = {{ rw_conf.authentication.client_mode }}
-{% if rw_conf.authentication.client_mode.startswith("eap") %}
+{% if rw_conf.authentication.client_mode.startswith("eap") %}
eap_id = %any
-{% endif %}
+{% endif %}
}
children {
ikev2-vpn {
@@ -40,9 +41,9 @@
rand_time = 540s
dpd_action = clear
inactivity = {{ rw_conf.timeout }}
-{% set local_prefix = rw_conf.local.prefix if rw_conf.local is defined and rw_conf.local.prefix is defined else ['0.0.0.0/0', '::/0'] %}
-{% set local_port = rw_conf.local.port if rw_conf.local is defined and rw_conf.local.port is defined else '' %}
-{% set local_suffix = '[%any/{1}]'.format(local_port) if local_port else '' %}
+{% set local_prefix = rw_conf.local.prefix if rw_conf.local.prefix is vyos_defined else ['0.0.0.0/0', '::/0'] %}
+{% set local_port = rw_conf.local.port if rw_conf.local.port is vyos_defined else '' %}
+{% set local_suffix = '[%any/{1}]'.format(local_port) if local_port else '' %}
local_ts = {{ local_prefix | join(local_suffix + ",") }}{{ local_suffix }}
}
}
diff --git a/data/templates/ipsec/windows_profile.tmpl b/data/templates/ipsec/windows_profile.j2
index 8c26944be..8c26944be 100644
--- a/data/templates/ipsec/windows_profile.tmpl
+++ b/data/templates/ipsec/windows_profile.j2
diff --git a/data/templates/lcd/LCDd.conf.tmpl b/data/templates/lcd/LCDd.conf.j2
index 2c7ad920f..3631add1d 100644
--- a/data/templates/lcd/LCDd.conf.tmpl
+++ b/data/templates/lcd/LCDd.conf.j2
@@ -48,14 +48,14 @@ DriverPath=/usr/lib/x86_64-linux-gnu/lcdproc/
# sed1520, serialPOS, serialVFD, shuttleVFD, sli, stv5730, svga, t6963,
# text, tyan, ula200, vlsys_m428, xosd, yard2LCD
-{% if model is defined %}
-{% if model.startswith('cfa-') %}
+{% if model is vyos_defined %}
+{% if model.startswith('cfa-') %}
Driver=CFontzPacket
-{% elif model == 'sdec' %}
+{% elif model == 'sdec' %}
Driver=sdeclcd
-{% elif model == 'hd44780' %}
+{% elif model == 'hd44780' %}
Driver=hd44780
-{% endif %}
+{% endif %}
{% endif %}
# Tells the driver to bind to the given interface. [default: 127.0.0.1]
@@ -115,8 +115,8 @@ Heartbeat=off
# set title scrolling speed [default: 10; legal: 0-10]
TitleSpeed=10
-{% if model is defined and model is not none %}
-{% if model.startswith('cfa-') %}
+{% if model is vyos_defined %}
+{% if model.startswith('cfa-') %}
## CrystalFontz packet driver (for CFA533, CFA631, CFA633 & CFA635) ##
[CFontzPacket]
Model={{ model.split('-')[1] }}
@@ -126,14 +126,14 @@ Brightness=500
OffBrightness=50
Reboot=yes
USB=yes
-{% elif model == 'sdec' %}
+{% elif model == 'sdec' %}
## SDEC driver for Lanner, Watchguard, Sophos sppliances ##
[sdeclcd]
# No options
-{% elif model == 'hd44780' %}
+{% elif model == 'hd44780' %}
[hd44780]
ConnectionType=ezio
Device={{ device }}
Size=16x2
-{% endif %}
+{% endif %}
{% endif %}
diff --git a/data/templates/lcd/lcdproc.conf.tmpl b/data/templates/lcd/lcdproc.conf.j2
index c79f3cd0d..c79f3cd0d 100644
--- a/data/templates/lcd/lcdproc.conf.tmpl
+++ b/data/templates/lcd/lcdproc.conf.j2
diff --git a/data/templates/lldp/lldpd.j2 b/data/templates/lldp/lldpd.j2
new file mode 100644
index 000000000..3c499197d
--- /dev/null
+++ b/data/templates/lldp/lldpd.j2
@@ -0,0 +1,2 @@
+### Autogenerated by lldp.py ###
+DAEMON_ARGS="-M 4 {{ '-x' if snmp.enable is vyos_defined }} {{ '-c' if legacy_protocols.cdp is vyos_defined }} {{ '-e' if legacy_protocols.edp is vyos_defined }} {{ '-f' if legacy_protocols.fdp is vyos_defined }} {{ '-s' if legacy_protocols.sonmp is vyos_defined }}"
diff --git a/data/templates/lldp/lldpd.tmpl b/data/templates/lldp/lldpd.tmpl
deleted file mode 100644
index 3db955b48..000000000
--- a/data/templates/lldp/lldpd.tmpl
+++ /dev/null
@@ -1,3 +0,0 @@
-### Autogenerated by lldp.py ###
-DAEMON_ARGS="-M 4{% if options.snmp %} -x{% endif %}{% if options.cdp %} -c{% endif %}{% if options.edp %} -e{% endif %}{% if options.fdp %} -f{% endif %}{% if options.sonmp %} -s{% endif %}"
-
diff --git a/data/templates/lldp/vyos.conf.j2 b/data/templates/lldp/vyos.conf.j2
new file mode 100644
index 000000000..ec84231d8
--- /dev/null
+++ b/data/templates/lldp/vyos.conf.j2
@@ -0,0 +1,25 @@
+### Autogenerated by lldp.py ###
+
+configure system platform VyOS
+configure system description "VyOS {{ version }}"
+{% if interface is vyos_defined %}
+{% set tmp = [] %}
+{% for iface, iface_options in interface.items() if not iface_options.disable %}
+{% if iface == 'all' %}
+{% set iface = '*' %}
+{% endif %}
+{% set _ = tmp.append(iface) %}
+{% if iface_options.location is vyos_defined %}
+{% if iface_options.location.elin is vyos_defined %}
+configure ports {{ iface }} med location elin "{{ iface_options.location.elin }}"
+{% endif %}
+{% if iface_options.location.coordinate_based is vyos_defined %}
+configure ports {{ iface }} med location coordinate latitude "{{ iface_options.location.coordinate_based.latitude }}" longitude "{{ iface_options.location.coordinate_based.longitude }}" altitude "{{ iface_options.location.coordinate_based.altitude }}m" datum "{{ iface_options.location.coordinate_based.datum }}"
+{% endif %}
+{% endif %}
+{% endfor %}
+configure system interface pattern "{{ tmp | join(",") }}"
+{% endif %}
+{% if management_address is vyos_defined %}
+configure system ip management pattern {{ management_address | join(",") }}
+{% endif %}
diff --git a/data/templates/lldp/vyos.conf.tmpl b/data/templates/lldp/vyos.conf.tmpl
deleted file mode 100644
index 07bbaf604..000000000
--- a/data/templates/lldp/vyos.conf.tmpl
+++ /dev/null
@@ -1,20 +0,0 @@
-### Autogenerated by lldp.py ###
-
-configure system platform VyOS
-configure system description "VyOS {{ options.description }}"
-{% if options.listen_on %}
-configure system interface pattern "{{ ( options.listen_on | select('equalto','all') | map('replace','all','*') | list + options.listen_on | select('equalto','!all') | map('replace','!all','!*') | list + options.listen_on | reject('equalto','all') | reject('equalto','!all') | list ) | unique | join(",") }}"
-{% endif %}
-{% if options.mgmt_addr %}
-configure system ip management pattern {{ options.mgmt_addr | join(",") }}
-{% endif %}
-{% for loc in location %}
-{% if loc.elin %}
-configure ports {{ loc.name }} med location elin "{{ loc.elin }}"
-{% endif %}
-{% if loc.coordinate_based %}
-configure ports {{ loc.name }} med location coordinate {% if loc.coordinate_based.latitude %}latitude {{ loc.coordinate_based.latitude }}{% endif %} {% if loc.coordinate_based.longitude %}longitude {{ loc.coordinate_based.longitude }}{% endif %} {% if loc.coordinate_based.altitude %}altitude {{ loc.coordinate_based.altitude }} m{% endif %} {% if loc.coordinate_based.datum %}datum {{ loc.coordinate_based.datum }}{% endif %}
-{% endif %}
-
-
-{% endfor %}
diff --git a/data/templates/login/authorized_keys.j2 b/data/templates/login/authorized_keys.j2
new file mode 100644
index 000000000..aabca47cf
--- /dev/null
+++ b/data/templates/login/authorized_keys.j2
@@ -0,0 +1,9 @@
+### Automatically generated by system-login.py ###
+
+{% if authentication.public_keys is vyos_defined %}
+{% for key, key_options in authentication.public_keys.items() %}
+{# The whitespace after options is wisely chosen #}
+{{ key_options.options ~ ' ' if key_options.options is vyos_defined }}{{ key_options.type }} {{ key_options.key }} {{ key }}
+{% endfor %}
+{% endif %}
+
diff --git a/data/templates/login/authorized_keys.tmpl b/data/templates/login/authorized_keys.tmpl
deleted file mode 100644
index 639a80e1d..000000000
--- a/data/templates/login/authorized_keys.tmpl
+++ /dev/null
@@ -1,9 +0,0 @@
-### Automatically generated by system-login.py ###
-
-{% if authentication is defined and authentication.public_keys is defined and authentication.public_keys is not none %}
-{% for key, key_options in authentication.public_keys.items() %}
-{# The whitespace after options is wisely chosen #}
-{{ key_options.options + ' ' if key_options.options is defined }}{{ key_options.type }} {{ key_options.key }} {{ key }}
-{% endfor %}
-{% endif %}
-
diff --git a/data/templates/login/pam_radius_auth.conf.j2 b/data/templates/login/pam_radius_auth.conf.j2
new file mode 100644
index 000000000..1105b60e5
--- /dev/null
+++ b/data/templates/login/pam_radius_auth.conf.j2
@@ -0,0 +1,36 @@
+# Automatically generated by system-login.py
+# RADIUS configuration file
+
+{% if radius is vyos_defined %}
+{# RADIUS IPv6 source address must be specified in [] notation #}
+{% set source_address = namespace() %}
+{% if radius.source_address is vyos_defined %}
+{% for address in radius.source_address %}
+{% if address | is_ipv4 %}
+{% set source_address.ipv4 = address %}
+{% elif address | is_ipv6 %}
+{% set source_address.ipv6 = "[" + address + "]" %}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if radius.server is vyos_defined %}
+# server[:port] shared_secret timeout source_ip
+{# .items() returns a tuple of two elements: key and value. 1 relates to the 2nd element i.e. the value and .priority relates to the key from the internal dict #}
+{% for server, options in radius.server.items() | sort(attribute='1.priority') if not options.disabled %}
+{# RADIUS IPv6 servers must be specified in [] notation #}
+{% if server | is_ipv4 %}
+{{ server }}:{{ options.port }} {{ "%-25s" | format(options.key) }} {{ "%-10s" | format(options.timeout) }} {{ source_address.ipv4 if source_address.ipv4 is vyos_defined }}
+{% else %}
+[{{ server }}]:{{ options.port }} {{ "%-25s" | format(options.key) }} {{ "%-10s" | format(options.timeout) }} {{ source_address.ipv6 if source_address.ipv6 is vyos_defined }}
+{% endif %}
+{% endfor %}
+{% endif %}
+
+priv-lvl 15
+mapped_priv_user radius_priv_user
+
+{% if radius.vrf is vyos_defined %}
+vrf-name {{ radius.vrf }}
+{% endif %}
+{% endif %}
+
diff --git a/data/templates/login/pam_radius_auth.conf.tmpl b/data/templates/login/pam_radius_auth.conf.tmpl
deleted file mode 100644
index fad8e7dcb..000000000
--- a/data/templates/login/pam_radius_auth.conf.tmpl
+++ /dev/null
@@ -1,36 +0,0 @@
-# Automatically generated by system-login.py
-# RADIUS configuration file
-
-{% if radius is defined and radius is not none %}
-{# RADIUS IPv6 source address must be specified in [] notation #}
-{% set source_address = namespace() %}
-{% if radius.source_address is defined and radius.source_address is not none %}
-{% for address in radius.source_address %}
-{% if address | is_ipv4 %}
-{% set source_address.ipv4 = address %}
-{% elif address | is_ipv6 %}
-{% set source_address.ipv6 = "[" + address + "]" %}
-{% endif %}
-{% endfor %}
-{% endif %}
-{% if radius.server is defined and radius.server is not none %}
-# server[:port] shared_secret timeout source_ip
-{# .items() returns a tuple of two elements: key and value. 1 relates to the 2nd element i.e. the value and .priority relates to the key from the internal dict #}
-{% for server, options in radius.server.items() | sort(attribute='1.priority') if not options.disabled %}
-{# RADIUS IPv6 servers must be specified in [] notation #}
-{% if server | is_ipv4 %}
-{{ server }}:{{ options.port }} {{ "%-25s" | format(options.key) }} {{ "%-10s" | format(options.timeout) }} {{ source_address.ipv4 if source_address.ipv4 is defined }}
-{% else %}
-[{{ server }}]:{{ options.port }} {{ "%-25s" | format(options.key) }} {{ "%-10s" | format(options.timeout) }} {{ source_address.ipv6 if source_address.ipv6 is defined }}
-{% endif %}
-{% endfor %}
-{% endif %}
-
-priv-lvl 15
-mapped_priv_user radius_priv_user
-
-{% if radius.vrf is defined and radius.vrf is not none %}
-vrf-name {{ radius.vrf }}
-{% endif %}
-{% endif %}
-
diff --git a/data/templates/logs/logrotate/vyos-atop.j2 b/data/templates/logs/logrotate/vyos-atop.j2
new file mode 100644
index 000000000..2d078f379
--- /dev/null
+++ b/data/templates/logs/logrotate/vyos-atop.j2
@@ -0,0 +1,20 @@
+/var/log/atop/atop.log {
+ daily
+ dateext
+ dateformat _%Y-%m-%d_%H-%M-%S
+ maxsize {{ max_size }}M
+ missingok
+ nocompress
+ nocreate
+ nomail
+ rotate {{ rotate }}
+ prerotate
+ # stop the service
+ systemctl stop atop.service
+ endscript
+ postrotate
+ # start atop service again
+ systemctl start atop.service
+ endscript
+}
+
diff --git a/data/templates/logs/logrotate/vyos-rsyslog.j2 b/data/templates/logs/logrotate/vyos-rsyslog.j2
new file mode 100644
index 000000000..f2e4d2ab2
--- /dev/null
+++ b/data/templates/logs/logrotate/vyos-rsyslog.j2
@@ -0,0 +1,13 @@
+/var/log/messages {
+ create
+ missingok
+ nomail
+ notifempty
+ rotate {{ rotate }}
+ size {{ max_size }}M
+ postrotate
+ # inform rsyslog service about rotation
+ /usr/lib/rsyslog/rsyslog-rotate
+ endscript
+}
+
diff --git a/data/templates/macsec/wpa_supplicant.conf.tmpl b/data/templates/macsec/wpa_supplicant.conf.j2
index 5b353def8..0ac7cb860 100644
--- a/data/templates/macsec/wpa_supplicant.conf.tmpl
+++ b/data/templates/macsec/wpa_supplicant.conf.j2
@@ -45,10 +45,9 @@ network={
# - the key server has decided to enable MACsec
# 0: Encrypt traffic (default)
# 1: Integrity only
- macsec_integ_only={{ '0' if security is defined and security.encrypt is defined else '1' }}
+ macsec_integ_only={{ '0' if security.encrypt is vyos_defined else '1' }}
-{% if security is defined %}
-{% if security.encrypt is defined %}
+{% if security.encrypt is vyos_defined %}
# mka_cak, mka_ckn, and mka_priority: IEEE 802.1X/MACsec pre-shared key mode
# This allows to configure MACsec with a pre-shared key using a (CAK,CKN) pair.
# In this mode, instances of wpa_supplicant can act as MACsec peers. The peer
@@ -63,9 +62,9 @@ network={
# mka_priority (Priority of MKA Actor) is in 0..255 range with 255 being
# default priority
mka_priority={{ security.mka.priority }}
-{% endif %}
+{% endif %}
-{% if security.replay_window is defined %}
+{% if security.replay_window is vyos_defined %}
# macsec_replay_protect: IEEE 802.1X/MACsec replay protection
# This setting applies only when MACsec is in use, i.e.,
# - macsec_policy is enabled
@@ -83,7 +82,6 @@ network={
# 0: No replay window, strict check (default)
# 1..2^32-1: number of packets that could be misordered
macsec_replay_window={{ security.replay_window }}
-{% endif %}
{% endif %}
}
diff --git a/data/templates/mdns-repeater/avahi-daemon.tmpl b/data/templates/mdns-repeater/avahi-daemon.j2
index 65bb5a306..65bb5a306 100644
--- a/data/templates/mdns-repeater/avahi-daemon.tmpl
+++ b/data/templates/mdns-repeater/avahi-daemon.j2
diff --git a/data/templates/monitoring/override.conf.j2 b/data/templates/monitoring/override.conf.j2
new file mode 100644
index 000000000..f8f150791
--- /dev/null
+++ b/data/templates/monitoring/override.conf.j2
@@ -0,0 +1,7 @@
+[Unit]
+After=vyos-router.service
+ConditionPathExists=/run/telegraf/vyos-telegraf.conf
+[Service]
+Environment=INFLUX_TOKEN={{ authentication.token }}
+CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN CAP_SYS_ADMIN
+AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN
diff --git a/data/templates/monitoring/syslog_telegraf.j2 b/data/templates/monitoring/syslog_telegraf.j2
new file mode 100644
index 000000000..cdcbd92a4
--- /dev/null
+++ b/data/templates/monitoring/syslog_telegraf.j2
@@ -0,0 +1,5 @@
+# Generated by /usr/libexec/vyos/conf_mode/service_monitoring_telegraf.py
+
+$ModLoad omuxsock
+$OMUxSockSocket /run/telegraf/telegraf_syslog.sock
+*.notice :omuxsock:
diff --git a/data/templates/monitoring/systemd_vyos_telegraf_service.j2 b/data/templates/monitoring/systemd_vyos_telegraf_service.j2
new file mode 100644
index 000000000..234ef5586
--- /dev/null
+++ b/data/templates/monitoring/systemd_vyos_telegraf_service.j2
@@ -0,0 +1,16 @@
+[Unit]
+Description=The plugin-driven server agent for reporting metrics into InfluxDB
+Documentation=https://github.com/influxdata/telegraf
+After=network.target
+
+[Service]
+EnvironmentFile=-/etc/default/telegraf
+User=telegraf
+ExecStart=/usr/bin/telegraf -config /run/telegraf/vyos-telegraf.conf -config-directory /etc/telegraf/telegraf.d $TELEGRAF_OPTS
+ExecReload=/bin/kill -HUP $MAINPID
+Restart=on-failure
+RestartForceExitStatus=SIGPIPE
+KillMode=control-group
+
+[Install]
+WantedBy=multi-user.target
diff --git a/data/templates/monitoring/telegraf.j2 b/data/templates/monitoring/telegraf.j2
new file mode 100644
index 000000000..a732fb5de
--- /dev/null
+++ b/data/templates/monitoring/telegraf.j2
@@ -0,0 +1,122 @@
+# Generated by /usr/libexec/vyos/conf_mode/service_monitoring_telegraf.py
+
+[agent]
+ interval = "15s"
+ round_interval = true
+ metric_batch_size = 1000
+ metric_buffer_limit = 10000
+ collection_jitter = "5s"
+ flush_interval = "15s"
+ flush_jitter = "0s"
+ precision = ""
+ debug = false
+ quiet = false
+ logfile = ""
+ hostname = ""
+ omit_hostname = false
+{% if azure_data_explorer is vyos_defined %}
+### Azure Data Explorer ###
+[[outputs.azure_data_explorer]]
+ ## The URI property of the Azure Data Explorer resource on Azure
+ endpoint_url = "{{ azure_data_explorer.url }}"
+
+ ## The Azure Data Explorer database that the metrics will be ingested into.
+ ## The plugin will NOT generate this database automatically, it's expected that this database already exists before ingestion.
+ database = "{{ azure_data_explorer.database }}"
+ metrics_grouping_type = "{{ azure_data_explorer.group_metrics }}"
+
+ ## Name of the single table to store all the metrics (Only needed if metrics_grouping_type is "SingleTable").
+{% if azure_data_explorer.table is vyos_defined and azure_data_explorer.group_metrics == 'SingleTable' %}
+ table_name = "{{ azure_data_explorer.table }}"
+{% endif %}
+### End Azure Data Explorer ###
+{% endif %}
+{% if influxdb_configured is vyos_defined %}
+### InfluxDB2 ###
+[[outputs.influxdb_v2]]
+ urls = ["{{ url }}:{{ port }}"]
+ insecure_skip_verify = true
+ token = "$INFLUX_TOKEN"
+ organization = "{{ authentication.organization }}"
+ bucket = "{{ bucket }}"
+### End InfluxDB2 ###
+{% endif %}
+{% if prometheus_client is vyos_defined %}
+### Prometheus ###
+[[outputs.prometheus_client]]
+ ## Address to listen on
+ listen = "{{ prometheus_client.listen_address if prometheus_client.listen_address is vyos_defined else '' }}:{{ prometheus_client.port }}"
+ metric_version = {{ prometheus_client.metric_version }}
+{% if prometheus_client.authentication.username is vyos_defined and prometheus_client.authentication.password is vyos_defined %}
+ ## Use HTTP Basic Authentication
+ basic_username = "{{ prometheus_client.authentication.username }}"
+ basic_password = "{{ prometheus_client.authentication.password }}"
+{% endif %}
+{% if prometheus_client.allow_from is vyos_defined %}
+ ip_range = {{ prometheus_client.allow_from }}
+{% endif %}
+### End Prometheus ###
+{% endif %}
+{% if splunk is vyos_defined %}
+### Splunk ###
+[[outputs.http]]
+ ## URL is the address to send metrics to
+ url = "{{ splunk.url }}"
+ ## Timeout for HTTP message
+ # timeout = "5s"
+ ## Use TLS but skip chain & host verification
+{% if splunk.authentication.insecure is vyos_defined %}
+ insecure_skip_verify = true
+{% endif %}
+ ## Data format to output
+ data_format = "splunkmetric"
+ ## Provides time, index, source overrides for the HEC
+ splunkmetric_hec_routing = true
+ ## Additional HTTP headers
+ [outputs.http.headers]
+ # Should be set manually to "application/json" for json data_format
+ Content-Type = "application/json"
+ Authorization = "Splunk {{ splunk.authentication.token }}"
+ X-Splunk-Request-Channel = "{{ splunk.authentication.token }}"
+### End Splunk ###
+{% endif %}
+[[inputs.cpu]]
+ percpu = true
+ totalcpu = true
+ collect_cpu_time = false
+ report_active = false
+[[inputs.disk]]
+ ignore_fs = ["devtmpfs", "devfs"]
+[[inputs.diskio]]
+[[inputs.mem]]
+[[inputs.net]]
+[[inputs.system]]
+[[inputs.netstat]]
+[[inputs.processes]]
+[[inputs.kernel]]
+[[inputs.interrupts]]
+[[inputs.linux_sysctl_fs]]
+[[inputs.systemd_units]]
+[[inputs.conntrack]]
+ files = ["ip_conntrack_count","ip_conntrack_max","nf_conntrack_count","nf_conntrack_max"]
+ dirs = ["/proc/sys/net/ipv4/netfilter","/proc/sys/net/netfilter"]
+[[inputs.ethtool]]
+ interface_include = {{ interfaces_ethernet }}
+[[inputs.ntpq]]
+ dns_lookup = true
+[[inputs.internal]]
+[[inputs.nstat]]
+[[inputs.syslog]]
+ server = "unixgram:///run/telegraf/telegraf_syslog.sock"
+ best_effort = true
+ syslog_standard = "RFC3164"
+{% if influxdb_configured is vyos_defined %}
+[[inputs.exec]]
+ commands = [
+ "{{ custom_scripts_dir }}/show_firewall_input_filter.py",
+ "{{ custom_scripts_dir }}/show_interfaces_input_filter.py",
+ "{{ custom_scripts_dir }}/vyos_services_input_filter.py"
+ ]
+ timeout = "10s"
+ data_format = "influx"
+{% endif %}
diff --git a/data/templates/ndppd/ndppd.conf.j2 b/data/templates/ndppd/ndppd.conf.j2
new file mode 100644
index 000000000..120fa0a64
--- /dev/null
+++ b/data/templates/ndppd/ndppd.conf.j2
@@ -0,0 +1,44 @@
+########################################################
+#
+# autogenerated by nat66.py
+#
+# The configuration file must define one upstream
+# interface.
+#
+# For some services, such as nat66, because it runs
+# stateless, it needs to rely on NDP Proxy to respond
+# to NDP requests.
+#
+# When using nat66 source rules, NDP Proxy needs
+# to be enabled
+#
+########################################################
+
+{% set global = namespace(ndppd_interfaces = [],ndppd_prefixs = []) %}
+{% if source.rule is vyos_defined %}
+{% for rule, config in source.rule.items() if config.disable is not defined %}
+{% if config.outbound_interface is vyos_defined %}
+{% if config.outbound_interface not in global.ndppd_interfaces %}
+{% set global.ndppd_interfaces = global.ndppd_interfaces + [config.outbound_interface] %}
+{% endif %}
+{% if config.translation.address is vyos_defined and config.translation.address | is_ip_network %}
+{% set global.ndppd_prefixs = global.ndppd_prefixs + [{'interface':config.outbound_interface,'rule':config.translation.address}] %}
+{% endif %}
+{% endif %}
+{% endfor %}
+{% endif %}
+
+{% for interface in global.ndppd_interfaces %}
+proxy {{ interface }} {
+ router yes
+ timeout 500
+ ttl 30000
+{% for map in global.ndppd_prefixs %}
+{% if map.interface == interface %}
+ rule {{ map.rule }} {
+ static
+ }
+{% endif %}
+{% endfor %}
+}
+{% endfor %}
diff --git a/data/templates/ndppd/ndppd.conf.tmpl b/data/templates/ndppd/ndppd.conf.tmpl
deleted file mode 100644
index 502dab5b8..000000000
--- a/data/templates/ndppd/ndppd.conf.tmpl
+++ /dev/null
@@ -1,44 +0,0 @@
-########################################################
-#
-# autogenerated by nat66.py
-#
-# The configuration file must define one upstream
-# interface.
-#
-# For some services, such as nat66, because it runs
-# stateless, it needs to rely on NDP Proxy to respond
-# to NDP requests.
-#
-# When using nat66 source rules, NDP Proxy needs
-# to be enabled
-#
-########################################################
-
-{% set global = namespace(ndppd_interfaces = [],ndppd_prefixs = []) %}
-{% if source is defined and source.rule is defined and source.rule is not none %}
-{% for rule, config in source.rule.items() if config.disable is not defined %}
-{% if config.outbound_interface is defined %}
-{% if config.outbound_interface not in global.ndppd_interfaces %}
-{% set global.ndppd_interfaces = global.ndppd_interfaces + [config.outbound_interface] %}
-{% endif %}
-{% if config.translation is defined and config.translation.address is defined and config.translation.address | is_ip_network %}
-{% set global.ndppd_prefixs = global.ndppd_prefixs + [{'interface':config.outbound_interface,'rule':config.translation.address}] %}
-{% endif %}
-{% endif %}
-{% endfor %}
-{% endif %}
-
-{% for interface in global.ndppd_interfaces %}
-proxy {{ interface }} {
- router yes
- timeout 500
- ttl 30000
-{% for map in global.ndppd_prefixs %}
-{% if map.interface == interface %}
- rule {{ map.rule }} {
- static
- }
-{% endif %}
-{% endfor %}
-}
-{% endfor %}
diff --git a/data/templates/netflow/uacctd.conf.tmpl b/data/templates/netflow/uacctd.conf.tmpl
deleted file mode 100644
index 1c183bb20..000000000
--- a/data/templates/netflow/uacctd.conf.tmpl
+++ /dev/null
@@ -1,72 +0,0 @@
-# Genereated from VyOS configuration
-daemonize: true
-promisc: false
-pidfile: /var/run/uacctd.pid
-uacctd_group: 2
-uacctd_nl_size: 2097152
-snaplen: {{ snaplen }}
-{% if templatecfg['enable-egress'] != none %}
-aggregate: in_iface,out_iface,src_mac,dst_mac,vlan,src_host,dst_host,src_port,dst_port,proto,tos,flows
-{% else %}
-aggregate: in_iface,src_mac,dst_mac,vlan,src_host,dst_host,src_port,dst_port,proto,tos,flows
-{% endif %}
-plugin_pipe_size: {{ templatecfg['plugin_pipe_size'] }}
-plugin_buffer_size: {{ templatecfg['plugin_buffer_size'] }}
-{% if templatecfg['syslog-facility'] != none %}
-syslog: {{ templatecfg['syslog-facility'] }}
-{% endif %}
-{% if templatecfg['disable-imt'] == none %}
-imt_path: /tmp/uacctd.pipe
-imt_mem_pools_number: 169
-{% endif %}
-plugins: {% if templatecfg['netflow']['servers'] != none %}
-{% for server in templatecfg['netflow']['servers'] %}
-{% if loop.last %}nfprobe[nf_{{ server['address'] }}]{% else %}nfprobe[nf_{{ server['address'] }}],{% endif %}
-{% endfor %}
-{% set plugins_presented = true %}
-{% endif %}
-{% if templatecfg['sflow']['servers'] != none %}
-{% if plugins_presented %}
-{% for server in templatecfg['sflow']['servers'] %},sfprobe[sf_{{ server['address'] }}]{% endfor %}
-{% else %}
-{% for server in templatecfg['sflow']['servers'] %}
-{% if loop.last %}sfprobe[sf_{{ server['address'] }}]{% else %}sfprobe[sf_{{ server['address'] }}],{% endif %}
-{% endfor %}
-{% endif %}
-{% set plugins_presented = true %}
-{% endif %}
-{% if templatecfg['disable-imt'] == none %}
-{% if plugins_presented %},memory{% else %}memory{% endif %}
-{% endif %}
-
-{% if templatecfg['netflow']['servers'] != none %}
-{% for server in templatecfg['netflow']['servers'] %}
-nfprobe_receiver[nf_{{ server['address'] }}]: {{ server['address'] }}:{{ server['port'] }}
-nfprobe_version[nf_{{ server['address'] }}]: {{ templatecfg['netflow']['version'] }}
-{% if templatecfg['netflow']['engine-id'] != none %}
-nfprobe_engine[nf_{{ server['address'] }}]: {{ templatecfg['netflow']['engine-id'] }}
-{% endif %}
-{% if templatecfg['netflow']['max-flows'] != none %}
-nfprobe_maxflows[nf_{{ server['address'] }}]: {{ templatecfg['netflow']['max-flows'] }}
-{% endif %}
-{% if templatecfg['netflow']['sampling-rate'] != none %}
-sampling_rate[nf_{{ server['address'] }}]: {{ templatecfg['netflow']['sampling-rate'] }}
-{% endif %}
-{% if templatecfg['netflow']['source-ip'] != none %}
-nfprobe_source_ip[nf_{{ server['address'] }}]: {{ templatecfg['netflow']['source-ip'] }}
-{% endif %}
-{% if templatecfg['netflow']['timeout_string'] != '' %}
-nfprobe_timeouts[nf_{{ server['address'] }}]: {{ templatecfg['netflow']['timeout_string'] }}
-{% endif %}
-{% endfor %}
-{% endif %}
-
-{% if templatecfg['sflow']['servers'] != none %}
-{% for server in templatecfg['sflow']['servers'] %}
-sfprobe_receiver[sf_{{ server['address'] }}]: {{ server['address'] }}:{{ server['port'] }}
-sfprobe_agentip[sf_{{ server['address'] }}]: {{ templatecfg['sflow']['agent-address'] }}
-{% if templatecfg['sflow']['sampling-rate'] != none %}
-sampling_rate[sf_{{ server['address'] }}]: {{ templatecfg['sflow']['sampling-rate'] }}
-{% endif %}
-{% endfor %}
-{% endif %}
diff --git a/data/templates/nhrp/opennhrp.conf.j2 b/data/templates/nhrp/opennhrp.conf.j2
new file mode 100644
index 000000000..c040a8f14
--- /dev/null
+++ b/data/templates/nhrp/opennhrp.conf.j2
@@ -0,0 +1,42 @@
+{# j2lint: disable=jinja-variable-format #}
+# Created by VyOS - manual changes will be overwritten
+
+{% if tunnel is vyos_defined %}
+{% for name, tunnel_conf in tunnel.items() %}
+{% set type = 'spoke' if tunnel_conf.map is vyos_defined or tunnel_conf.dynamic_map is vyos_defined else 'hub' %}
+{% set profile_name = profile_map[name] if profile_map is vyos_defined and name in profile_map else '' %}
+interface {{ name }} #{{ type }} {{ profile_name }}
+{% if tunnel_conf.map is vyos_defined %}
+{% for map, map_conf in tunnel_conf.map.items() %}
+{% set cisco = ' cisco' if map_conf.cisco is vyos_defined else '' %}
+{% set register = ' register' if map_conf.register is vyos_defined else '' %}
+ map {{ map }} {{ map_conf.nbma_address }}{{ register }}{{ cisco }}
+{% endfor %}
+{% endif %}
+{% if tunnel_conf.dynamic_map is vyos_defined %}
+{% for map, map_conf in tunnel_conf.dynamic_map.items() %}
+ dynamic-map {{ map }} {{ map_conf.nbma_domain_name }}
+{% endfor %}
+{% endif %}
+{% if tunnel_conf.cisco_authentication is vyos_defined %}
+ cisco-authentication {{ tunnel_conf.cisco_authentication }}
+{% endif %}
+{% if tunnel_conf.holding_time is vyos_defined %}
+ holding-time {{ tunnel_conf.holding_time }}
+{% endif %}
+{% if tunnel_conf.multicast is vyos_defined %}
+ multicast {{ tunnel_conf.multicast }}
+{% endif %}
+{% for key in ['non_caching', 'redirect', 'shortcut', 'shortcut_destination'] %}
+{% if key in tunnel_conf %}
+ {{ key | replace("_", "-") }}
+{% endif %}
+{% endfor %}
+{% if tunnel_conf.shortcut_target is vyos_defined %}
+{% for target, shortcut_conf in tunnel_conf.shortcut_target.items() %}
+ shortcut-target {{ target }}{{ ' holding-time ' + shortcut_conf.holding_time if shortcut_conf.holding_time is vyos_defined }}
+{% endfor %}
+{% endif %}
+
+{% endfor %}
+{% endif %}
diff --git a/data/templates/nhrp/opennhrp.conf.tmpl b/data/templates/nhrp/opennhrp.conf.tmpl
deleted file mode 100644
index 948327198..000000000
--- a/data/templates/nhrp/opennhrp.conf.tmpl
+++ /dev/null
@@ -1,41 +0,0 @@
-# Created by VyOS - manual changes will be overwritten
-
-{% if tunnel is defined and tunnel is not none %}
-{% for name, tunnel_conf in tunnel.items() %}
-{% set type = 'spoke' if tunnel_conf.map is defined or tunnel_conf.dynamic_map is defined else 'hub' %}
-{% set profile_name = profile_map[name] if profile_map is defined and name in profile_map else '' %}
-interface {{ name }} #{{ type }} {{ profile_name }}
-{% if tunnel_conf.map is defined and tunnel_conf.map is not none %}
-{% for map, map_conf in tunnel_conf.map.items() %}
-{% set cisco = ' cisco' if map_conf.cisco is defined else '' %}
-{% set register = ' register' if map_conf.register is defined else '' %}
- map {{ map }} {{ map_conf.nbma_address }}{{ register }}{{ cisco }}
-{% endfor %}
-{% endif %}
-{% if tunnel_conf.dynamic_map is defined and tunnel_conf.dynamic_map is not none %}
-{% for map, map_conf in tunnel_conf.dynamic_map.items() %}
- dynamic-map {{ map }} {{ map_conf.nbma_domain_name }}
-{% endfor %}
-{% endif %}
-{% if tunnel_conf.cisco_authentication is defined and tunnel_conf.cisco_authentication is not none %}
- cisco-authentication {{ tunnel_conf.cisco_authentication }}
-{% endif %}
-{% if tunnel_conf.holding_time is defined and tunnel_conf.holding_time is not none %}
- holding-time {{ tunnel_conf.holding_time }}
-{% endif %}
-{% if tunnel_conf.multicast is defined and tunnel_conf.multicast is not none %}
- multicast {{ tunnel_conf.multicast }}
-{% endif %}
-{% for key in ['non_caching', 'redirect', 'shortcut', 'shortcut_destination'] %}
-{% if key in tunnel_conf %}
- {{ key | replace("_", "-") }}
-{% endif %}
-{% endfor %}
-{% if tunnel_conf.shortcut_target is defined and tunnel_conf.shortcut_target is not none %}
-{% for target, shortcut_conf in tunnel_conf.shortcut_target.items() %}
- shortcut-target {{ target }} {{ shortcut_conf.holding_time if shortcut_conf.holding_time is defined else '' }}
-{% endfor %}
-{% endif %}
-
-{% endfor %}
-{% endif %}
diff --git a/data/templates/ntp/ntpd.conf.tmpl b/data/templates/ntp/ntpd.conf.j2
index 38e68f24f..da610051e 100644
--- a/data/templates/ntp/ntpd.conf.tmpl
+++ b/data/templates/ntp/ntpd.conf.j2
@@ -15,27 +15,28 @@ restrict -6 ::1
#
# Configurable section
#
-{% if server is defined and server is not none %}
-{% for server, config in server.items() %}
-{% set association = 'server' %}
-{% if config.pool is defined %}
-{% set association = 'pool' %}
-{% endif %}
-{{ association }} {{ server | replace('_', '-') }} iburst {{ 'noselect' if config.noselect is defined }} {{ 'preempt' if config.preempt is defined }} {{ 'prefer' if config.prefer is defined }}
-{% endfor %}
+{% if server is vyos_defined %}
+{% for server, config in server.items() %}
+{% set association = 'server' %}
+{% if config.pool is vyos_defined %}
+{% set association = 'pool' %}
+{% endif %}
+{{ association }} {{ server | replace('_', '-') }} iburst {{ 'noselect' if config.noselect is vyos_defined }} {{ 'preempt' if config.preempt is vyos_defined }} {{ 'prefer' if config.prefer is vyos_defined }}
+{% endfor %}
{% endif %}
-{% if allow_clients is defined and allow_clients.address is defined %}
+{% if allow_clients.address is vyos_defined %}
# Allowed clients configuration
-{% for address in allow_clients.address %}
-restrict {{ address|address_from_cidr }} mask {{ address|netmask_from_cidr }} nomodify notrap nopeer
-{% endfor %}
+restrict default ignore
+{% for address in allow_clients.address %}
+restrict {{ address | address_from_cidr }} mask {{ address | netmask_from_cidr }} nomodify notrap nopeer
+{% endfor %}
{% endif %}
{% if listen_address %}
# NTP should listen on configured addresses only
interface ignore wildcard
-{% for address in listen_address %}
+{% for address in listen_address %}
interface listen {{ address }}
-{% endfor %}
+{% endfor %}
{% endif %}
diff --git a/data/templates/ntp/override.conf.j2 b/data/templates/ntp/override.conf.j2
new file mode 100644
index 000000000..6fed9d7d2
--- /dev/null
+++ b/data/templates/ntp/override.conf.j2
@@ -0,0 +1,14 @@
+{% set vrf_command = 'ip vrf exec ' ~ vrf ~ ' ' if vrf is vyos_defined else '' %}
+[Unit]
+StartLimitIntervalSec=0
+ConditionPathExists={{ config_file }}
+After=vyos-router.service
+
+[Service]
+ExecStart=
+ExecStart={{ vrf_command }}/usr/sbin/ntpd -g -p {{ config_file | replace('.conf', '.pid') }} -c {{ config_file }} -u ntp:ntp
+PIDFile=
+PIDFile={{ config_file | replace('.conf', '.pid') }}
+Restart=always
+RestartSec=10
+
diff --git a/data/templates/ntp/override.conf.tmpl b/data/templates/ntp/override.conf.tmpl
deleted file mode 100644
index 28eb61b21..000000000
--- a/data/templates/ntp/override.conf.tmpl
+++ /dev/null
@@ -1,14 +0,0 @@
-{% set vrf_command = 'ip vrf exec ' + vrf + ' ' if vrf is defined else '' %}
-[Unit]
-StartLimitIntervalSec=0
-ConditionPathExists={{config_file}}
-After=vyos-router.service
-
-[Service]
-ExecStart=
-ExecStart={{vrf_command}}/usr/sbin/ntpd -g -p {{config_file | replace('.conf', '.pid') }} -c {{config_file}} -u ntp:ntp
-PIDFile=
-PIDFile={{config_file | replace('.conf', '.pid') }}
-Restart=always
-RestartSec=10
-
diff --git a/data/templates/ocserv/ocserv_config.tmpl b/data/templates/ocserv/ocserv_config.j2
index 0be805235..8418a2185 100644
--- a/data/templates/ocserv/ocserv_config.tmpl
+++ b/data/templates/ocserv/ocserv_config.j2
@@ -8,19 +8,27 @@ run-as-group = daemon
{% if "radius" in authentication.mode %}
auth = "radius [config=/run/ocserv/radiusclient.conf]"
+{% elif "local" in authentication.mode %}
+{% if authentication.mode.local == "password-otp" %}
+auth = "plain[passwd=/run/ocserv/ocpasswd,otp=/run/ocserv/users.oath]"
+{% elif authentication.mode.local == "otp" %}
+auth = "plain[otp=/run/ocserv/users.oath]"
+{% else %}
+auth = "plain[/run/ocserv/ocpasswd]"
+{% endif %}
{% else %}
auth = "plain[/run/ocserv/ocpasswd]"
{% endif %}
-{% if ssl.certificate is defined %}
+{% if ssl.certificate is vyos_defined %}
server-cert = /run/ocserv/cert.pem
server-key = /run/ocserv/cert.key
-{% if ssl.passphrase is defined %}
+{% if ssl.passphrase is vyos_defined %}
key-pin = {{ ssl.passphrase }}
-{% endif %}
+{% endif %}
{% endif %}
-{% if ssl.ca_certificate is defined %}
+{% if ssl.ca_certificate is vyos_defined %}
ca-cert = /run/ocserv/ca.pem
{% endif %}
@@ -42,7 +50,8 @@ rekey-method = ssl
try-mtu-discovery = true
cisco-client-compat = true
dtls-legacy = true
-
+max-ban-score = 80
+ban-reset-time = 300
# The name to use for the tun device
device = sslvpn
@@ -50,33 +59,33 @@ device = sslvpn
# An alternative way of specifying the network:
{% if network_settings %}
# DNS settings
-{% if network_settings.name_server is string %}
+{% if network_settings.name_server is string %}
dns = {{ network_settings.name_server }}
-{% else %}
-{% for dns in network_settings.name_server %}
+{% else %}
+{% for dns in network_settings.name_server %}
dns = {{ dns }}
-{% endfor %}
-{% endif %}
+{% endfor %}
+{% endif %}
# IPv4 network pool
-{% if network_settings.client_ip_settings %}
-{% if network_settings.client_ip_settings.subnet %}
+{% if network_settings.client_ip_settings %}
+{% if network_settings.client_ip_settings.subnet %}
ipv4-network = {{ network_settings.client_ip_settings.subnet }}
+{% endif %}
{% endif %}
-{% endif %}
# IPv6 network pool
-{% if network_settings.client_ipv6_pool %}
-{% if network_settings.client_ipv6_pool.prefix %}
+{% if network_settings.client_ipv6_pool %}
+{% if network_settings.client_ipv6_pool.prefix %}
ipv6-network = {{ network_settings.client_ipv6_pool.prefix }}
ipv6-subnet-prefix = {{ network_settings.client_ipv6_pool.mask }}
+{% endif %}
{% endif %}
-{% endif %}
{% endif %}
{% if network_settings.push_route is string %}
route = {{ network_settings.push_route }}
{% else %}
-{% for route in network_settings.push_route %}
+{% for route in network_settings.push_route %}
route = {{ route }}
-{% endfor %}
+{% endfor %}
{% endif %}
diff --git a/data/templates/ocserv/ocserv_otp_usr.j2 b/data/templates/ocserv/ocserv_otp_usr.j2
new file mode 100644
index 000000000..b2511ed94
--- /dev/null
+++ b/data/templates/ocserv/ocserv_otp_usr.j2
@@ -0,0 +1,8 @@
+#<token_type> <username> <pin> <secret_hex_key> <counter> <lastpass> <time>
+{% if username is vyos_defined %}
+{% for user, user_config in username.items() %}
+{% if user_config.disable is not vyos_defined and user_config.otp is vyos_defined %}
+{{ user_config.otp.token_tmpl }} {{ user }} {{ user_config.otp.pin | default("-", true) }} {{ user_config.otp.key }}
+{% endif %}
+{% endfor %}
+{% endif %}
diff --git a/data/templates/ocserv/ocserv_passwd.j2 b/data/templates/ocserv/ocserv_passwd.j2
new file mode 100644
index 000000000..30c79d66a
--- /dev/null
+++ b/data/templates/ocserv/ocserv_passwd.j2
@@ -0,0 +1,8 @@
+#<username>:<group>:<hash>
+{% if username is vyos_defined %}
+{% for user, user_config in username.items() %}
+{% if user_config.disable is not vyos_defined %}
+{{ user }}:*:{{ user_config.hash }}
+{% endif %}
+{% endfor %}
+{% endif %} \ No newline at end of file
diff --git a/data/templates/ocserv/ocserv_passwd.tmpl b/data/templates/ocserv/ocserv_passwd.tmpl
deleted file mode 100644
index ffadb4860..000000000
--- a/data/templates/ocserv/ocserv_passwd.tmpl
+++ /dev/null
@@ -1,6 +0,0 @@
-#<username>:<group>:<hash>
-{% for user in username if username is defined %}
-{% if not "disable" in username[user] %}
-{{ user }}:*:{{ username[user].hash }}
-{% endif %}
-{% endfor %} \ No newline at end of file
diff --git a/data/templates/ocserv/radius_conf.tmpl b/data/templates/ocserv/radius_conf.j2
index 1712d83ef..b6612fee5 100644
--- a/data/templates/ocserv/radius_conf.tmpl
+++ b/data/templates/ocserv/radius_conf.j2
@@ -1,13 +1,13 @@
### generated by vpn_openconnect.py ###
nas-identifier VyOS
{% for srv in server %}
-{% if not "disable" in server[srv] %}
-{% if "port" in server[srv] %}
-authserver {{ srv }}:{{server[srv]["port"]}}
-{% else %}
+{% if not "disable" in server[srv] %}
+{% if "port" in server[srv] %}
+authserver {{ srv }}:{{ server[srv]["port"] }}
+{% else %}
authserver {{ srv }}
+{% endif %}
{% endif %}
-{% endif %}
{% endfor %}
radius_timeout {{ timeout }}
{% if source_address %}
@@ -15,7 +15,7 @@ bindaddr {{ source_address }}
{% else %}
bindaddr *
{% endif %}
-servers /run/ocserv/radius_servers
+servers /run/ocserv/radius_servers
dictionary /etc/radcli/dictionary
default_realm
radius_retries 3
diff --git a/data/templates/ocserv/radius_servers.j2 b/data/templates/ocserv/radius_servers.j2
new file mode 100644
index 000000000..302e91600
--- /dev/null
+++ b/data/templates/ocserv/radius_servers.j2
@@ -0,0 +1,7 @@
+### generated by vpn_openconnect.py ###
+# server key
+{% for srv in server %}
+{% if not "disable" in server[srv] %}
+{{ srv }} {{ server[srv].key }}
+{% endif %}
+{% endfor %}
diff --git a/data/templates/ocserv/radius_servers.tmpl b/data/templates/ocserv/radius_servers.tmpl
deleted file mode 100644
index 7bacac992..000000000
--- a/data/templates/ocserv/radius_servers.tmpl
+++ /dev/null
@@ -1,7 +0,0 @@
-### generated by vpn_openconnect.py ###
-# server key
-{% for srv in server %}
-{% if not "disable" in server[srv] %}
-{{ srv }} {{ server[srv].key }}
-{% endif %}
-{% endfor %}
diff --git a/data/templates/openvpn/auth.pw.tmpl b/data/templates/openvpn/auth.pw.j2
index 9b20c9742..218121062 100644
--- a/data/templates/openvpn/auth.pw.tmpl
+++ b/data/templates/openvpn/auth.pw.j2
@@ -1,5 +1,5 @@
{# Autogenerated by interfaces-openvpn.py #}
-{% if authentication is defined and authentication is not none %}
+{% if authentication is vyos_defined %}
{{ authentication.username }}
{{ authentication.password }}
{% endif %}
diff --git a/data/templates/openvpn/client.conf.tmpl b/data/templates/openvpn/client.conf.j2
index e6e15b6ad..2e327e4d3 100644
--- a/data/templates/openvpn/client.conf.tmpl
+++ b/data/templates/openvpn/client.conf.j2
@@ -1,31 +1,31 @@
### Autogenerated by interfaces-openvpn.py ###
-{% if ip %}
+{% if ip is vyos_defined %}
ifconfig-push {{ ip[0] }} {{ server_subnet[0] | netmask_from_cidr }}
{% endif %}
-{% if push_route is defined and push_route is not none %}
-{% for route in push_route %}
+{% if push_route is vyos_defined %}
+{% for route in push_route %}
push "route {{ route | address_from_cidr }} {{ route | netmask_from_cidr }}"
-{% endfor %}
+{% endfor %}
{% endif %}
-{% if subnet is defined and subnet is not none %}
-{% for network in subnet %}
+{% if subnet is vyos_defined %}
+{% for network in subnet %}
iroute {{ network | address_from_cidr }} {{ network | netmask_from_cidr }}
-{% endfor %}
+{% endfor %}
{% endif %}
{# ipv6_remote is only set when IPv6 server is enabled #}
-{% if ipv6_remote %}
+{% if ipv6_remote is vyos_defined %}
# IPv6
-{% if ipv6_ip %}
+{% if ipv6_ip is vyos_defined %}
ifconfig-ipv6-push {{ ipv6_ip[0] }} {{ ipv6_remote }}
-{% endif %}
-{% for route6 in ipv6_push_route %}
+{% endif %}
+{% for route6 in ipv6_push_route %}
push "route-ipv6 {{ route6 }}"
-{% endfor %}
-{% for net6 in ipv6_subnet %}
+{% endfor %}
+{% for net6 in ipv6_subnet %}
iroute-ipv6 {{ net6 }}
-{% endfor %}
+{% endfor %}
{% endif %}
-{% if disable is defined %}
+{% if disable is vyos_defined %}
disable
{% endif %}
diff --git a/data/templates/openvpn/server.conf.j2 b/data/templates/openvpn/server.conf.j2
new file mode 100644
index 000000000..6dd4ef88d
--- /dev/null
+++ b/data/templates/openvpn/server.conf.j2
@@ -0,0 +1,224 @@
+### Autogenerated by interfaces-openvpn.py ###
+#
+# See https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage
+# for individual keyword definition
+#
+# {{ description if description is vyos_defined }}
+#
+
+verb 3
+dev-type {{ device_type }}
+dev {{ ifname }}
+persist-key
+{% if protocol is vyos_defined('tcp-active') %}
+proto tcp-client
+{% elif protocol is vyos_defined('tcp-passive') %}
+proto tcp-server
+{% else %}
+proto udp
+{% endif %}
+{% if local_host is vyos_defined %}
+local {{ local_host }}
+{% endif %}
+{% if mode is vyos_defined('server') and protocol is vyos_defined('udp') and local_host is not vyos_defined %}
+multihome
+{% endif %}
+{% if local_port is vyos_defined %}
+lport {{ local_port }}
+{% endif %}
+{% if remote_port is vyos_defined %}
+rport {{ remote_port }}
+{% endif %}
+{% if remote_host is vyos_defined %}
+{% for remote in remote_host %}
+remote {{ remote }}
+{% endfor %}
+{% endif %}
+{% if shared_secret_key is vyos_defined %}
+secret /run/openvpn/{{ ifname }}_shared.key
+{% endif %}
+{% if persistent_tunnel is vyos_defined %}
+persist-tun
+{% endif %}
+{% if replace_default_route.local is vyos_defined %}
+push "redirect-gateway local def1"
+{% elif replace_default_route is vyos_defined %}
+push "redirect-gateway def1"
+{% endif %}
+{% if use_lzo_compression is vyos_defined %}
+compress lzo
+{% endif %}
+
+{% if mode is vyos_defined('client') %}
+#
+# OpenVPN Client mode
+#
+client
+nobind
+
+{% elif mode is vyos_defined('server') %}
+#
+# OpenVPN Server mode
+#
+mode server
+tls-server
+{% if server is vyos_defined %}
+{% if server.subnet is vyos_defined %}
+{% if server.topology is vyos_defined('point-to-point') %}
+topology p2p
+{% elif server.topology is vyos_defined %}
+topology {{ server.topology }}
+{% endif %}
+{% for subnet in server.subnet %}
+{% if subnet | is_ipv4 %}
+server {{ subnet | address_from_cidr }} {{ subnet | netmask_from_cidr }} nopool
+{# First ip address is used as gateway. It's allows to use metrics #}
+{% if server.push_route is vyos_defined %}
+{% for route, route_config in server.push_route.items() %}
+{% if route | is_ipv4 %}
+push "route {{ route | address_from_cidr }} {{ route | netmask_from_cidr }} {{ subnet | first_host_address ~ ' ' ~ route_config.metric if route_config.metric is vyos_defined }}"
+{% elif route | is_ipv6 %}
+push "route-ipv6 {{ route }}"
+{% endif %}
+{% endfor %}
+{% endif %}
+{# OpenVPN assigns the first IP address to its local interface so the pool used #}
+{# in net30 topology - where each client receives a /30 must start from the second subnet #}
+{% if server.topology is vyos_defined('net30') %}
+ifconfig-pool {{ subnet | inc_ip('4') }} {{ subnet | last_host_address | dec_ip('1') }} {{ subnet | netmask_from_cidr if device_type == 'tap' else '' }}
+{% else %}
+{# OpenVPN assigns the first IP address to its local interface so the pool must #}
+{# start from the second address and end on the last address #}
+ifconfig-pool {{ subnet | first_host_address | inc_ip('1') }} {{ subnet | last_host_address | dec_ip('1') }} {{ subnet | netmask_from_cidr if device_type == 'tun' else '' }}
+{% endif %}
+{% elif subnet | is_ipv6 %}
+server-ipv6 {{ subnet }}
+{% endif %}
+{% endfor %}
+{% endif %}
+
+{% if server.client_ip_pool is vyos_defined and server.client_ip_pool.disable is not vyos_defined %}
+ifconfig-pool {{ server.client_ip_pool.start }} {{ server.client_ip_pool.stop }}{{ server.client_ip_pool.subnet_mask if server.client_ip_pool.subnet_mask is vyos_defined }}
+{% endif %}
+{% if server.max_connections is vyos_defined %}
+max-clients {{ server.max_connections }}
+{% endif %}
+{% if server.client is vyos_defined %}
+client-config-dir /run/openvpn/ccd/{{ ifname }}
+{% endif %}
+{% endif %}
+keepalive {{ keep_alive.interval }} {{ keep_alive.interval | int * keep_alive.failure_count | int }}
+management /run/openvpn/openvpn-mgmt-intf unix
+{% if server is vyos_defined %}
+{% if server.reject_unconfigured_clients is vyos_defined %}
+ccd-exclusive
+{% endif %}
+
+{% if server.name_server is vyos_defined %}
+{% for nameserver in server.name_server %}
+{% if nameserver | is_ipv4 %}
+push "dhcp-option DNS {{ nameserver }}"
+{% elif nameserver | is_ipv6 %}
+push "dhcp-option DNS6 {{ nameserver }}"
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if server.domain_name is vyos_defined %}
+push "dhcp-option DOMAIN {{ server.domain_name }}"
+{% endif %}
+{% if server.mfa.totp is vyos_defined %}
+{% set totp_config = server.mfa.totp %}
+plugin "{{ plugin_dir }}/openvpn-otp.so" "otp_secrets=/config/auth/openvpn/{{ ifname }}-otp-secrets otp_slop={{ totp_config.slop }} totp_t0={{ totp_config.drift }} totp_step={{ totp_config.step }} totp_digits={{ totp_config.digits }} password_is_cr={{ '1' if totp_config.challenge == 'enable' else '0' }}"
+{% endif %}
+{% endif %}
+{% else %}
+#
+# OpenVPN site-2-site mode
+#
+ping {{ keep_alive.interval }}
+ping-restart {{ keep_alive.failure_count }}
+
+{% if device_type == 'tap' %}
+{% if local_address is vyos_defined %}
+{% for laddr, laddr_conf in local_address.items() if laddr | is_ipv4 %}
+{% if laddr_conf.subnet_mask is vyos_defined %}
+ifconfig {{ laddr }} {{ laddr_conf.subnet_mask }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% else %}
+{% for laddr in local_address if laddr | is_ipv4 %}
+{% for raddr in remote_address if raddr | is_ipv4 %}
+ifconfig {{ laddr }} {{ raddr }}
+{% endfor %}
+{% endfor %}
+{% for laddr in local_address if laddr | is_ipv6 %}
+{% for raddr in remote_address if raddr | is_ipv6 %}
+ifconfig-ipv6 {{ laddr }} {{ raddr }}
+{% endfor %}
+{% endfor %}
+{% endif %}
+{% endif %}
+
+{% if tls is vyos_defined %}
+# TLS options
+{% if tls.ca_certificate is vyos_defined %}
+ca /run/openvpn/{{ ifname }}_ca.pem
+{% endif %}
+{% if tls.certificate is vyos_defined %}
+cert /run/openvpn/{{ ifname }}_cert.pem
+{% endif %}
+{% if tls.private_key is vyos_defined %}
+key /run/openvpn/{{ ifname }}_cert.key
+{% endif %}
+{% if tls.crypt_key is vyos_defined %}
+tls-crypt /run/openvpn/{{ ifname }}_crypt.key
+{% endif %}
+{% if tls.crl is vyos_defined %}
+crl-verify /run/openvpn/{{ ifname }}_crl.pem
+{% endif %}
+{% if tls.tls_version_min is vyos_defined %}
+tls-version-min {{ tls.tls_version_min }}
+{% endif %}
+{% if tls.dh_params is vyos_defined %}
+dh /run/openvpn/{{ ifname }}_dh.pem
+{% elif mode is vyos_defined('server') and tls.private_key is vyos_defined %}
+dh none
+{% endif %}
+{% if tls.auth_key is vyos_defined %}
+{% if mode == 'client' %}
+tls-auth /run/openvpn/{{ ifname }}_auth.key 1
+{% elif mode == 'server' %}
+tls-auth /run/openvpn/{{ ifname }}_auth.key 0
+{% endif %}
+{% endif %}
+{% if tls.role is vyos_defined('active') %}
+tls-client
+{% elif tls.role is vyos_defined('passive') %}
+tls-server
+{% endif %}
+{% endif %}
+
+# Encryption options
+{% if encryption is vyos_defined %}
+{% if encryption.cipher is vyos_defined %}
+cipher {{ encryption.cipher | openvpn_cipher }}
+{% if encryption.cipher is vyos_defined('bf128') %}
+keysize 128
+{% elif encryption.cipher is vyos_defined('bf256') %}
+keysize 256
+{% endif %}
+{% endif %}
+{% if encryption.ncp_ciphers is vyos_defined %}
+data-ciphers {{ encryption.ncp_ciphers | openvpn_ncp_ciphers }}
+{% endif %}
+{% endif %}
+
+{% if hash is vyos_defined %}
+auth {{ hash }}
+{% endif %}
+
+{% if authentication is vyos_defined %}
+auth-user-pass {{ auth_user_pass_file }}
+auth-retry nointeract
+{% endif %}
diff --git a/data/templates/openvpn/server.conf.tmpl b/data/templates/openvpn/server.conf.tmpl
deleted file mode 100644
index 7a0470d0e..000000000
--- a/data/templates/openvpn/server.conf.tmpl
+++ /dev/null
@@ -1,226 +0,0 @@
-### Autogenerated by interfaces-openvpn.py ###
-#
-# See https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage
-# for individual keyword definition
-#
-# {{ description if description is defined and description is not none }}
-#
-
-verb 3
-dev-type {{ device_type }}
-dev {{ ifname }}
-persist-key
-{% if protocol == 'tcp-active' %}
-proto tcp-client
-{% elif protocol == 'tcp-passive' %}
-proto tcp-server
-{% else %}
-proto udp
-{% endif %}
-{% if local_host is defined and local_host is not none %}
-local {{ local_host }}
-{% endif %}
-{% if mode is defined and mode == 'server' and protocol == 'udp' and local_host is not defined %}
-multihome
-{% endif %}
-{% if local_port is defined and local_port is not none %}
-lport {{ local_port }}
-{% endif %}
-{% if remote_port is defined and remote_port is not none %}
-rport {{ remote_port }}
-{% endif %}
-{% if remote_host is defined and remote_host is not none %}
-{% for remote in remote_host %}
-remote {{ remote }}
-{% endfor %}
-{% endif %}
-{% if shared_secret_key is defined and shared_secret_key is not none %}
-secret /run/openvpn/{{ ifname }}_shared.key
-{% endif %}
-{% if persistent_tunnel is defined %}
-persist-tun
-{% endif %}
-{% if replace_default_route is defined and replace_default_route.local is defined %}
-push "redirect-gateway local def1"
-{% elif replace_default_route is defined %}
-push "redirect-gateway def1"
-{% endif %}
-{% if use_lzo_compression is defined %}
-compress lzo
-{% endif %}
-
-{% if mode == 'client' %}
-#
-# OpenVPN Client mode
-#
-client
-nobind
-
-{% elif mode == 'server' %}
-#
-# OpenVPN Server mode
-#
-mode server
-tls-server
-{% if server is defined and server is not none %}
-{% if server.subnet is defined and server.subnet is not none %}
-{% if server.topology is defined and server.topology == 'point-to-point' %}
-topology p2p
-{% elif server.topology is defined and server.topology is not none %}
-topology {{ server.topology }}
-{% endif %}
-{% for subnet in server.subnet %}
-{% if subnet | is_ipv4 %}
-server {{ subnet | address_from_cidr }} {{ subnet | netmask_from_cidr }} nopool
-{# First ip address is used as gateway. It's allows to use metrics #}
-{% if server.push_route is defined and server.push_route is not none %}
-{% for route, route_config in server.push_route.items() %}
-{% if route | is_ipv4 %}
-push "route {{ route | address_from_cidr }} {{ route | netmask_from_cidr }}{% if route_config.metric is defined %} {{ subnet | first_host_address }} {{ route_config.metric }}{% endif %}"
-{% elif route | is_ipv6 %}
-push "route-ipv6 {{ route }}"
-{% endif %}
-{% endfor %}
-{% endif %}
-{# OpenVPN assigns the first IP address to its local interface so the pool used #}
-{# in net30 topology - where each client receives a /30 must start from the second subnet #}
-{% if server.topology is defined and server.topology == 'net30' %}
-ifconfig-pool {{ subnet | inc_ip('4') }} {{ subnet | last_host_address | dec_ip('1') }} {{ subnet | netmask_from_cidr if device_type == 'tap' else '' }}
-{% else %}
-{# OpenVPN assigns the first IP address to its local interface so the pool must #}
-{# start from the second address and end on the last address #}
-ifconfig-pool {{ subnet | first_host_address | inc_ip('1') }} {{ subnet | last_host_address | dec_ip('1') }} {{ subnet | netmask_from_cidr if device_type == 'tun' else '' }}
-{% endif %}
-{% elif subnet | is_ipv6 %}
-server-ipv6 {{ subnet }}
-{% endif %}
-{% endfor %}
-{% endif %}
-
-{% if server.client_ip_pool is defined and server.client_ip_pool is not none and server.client_ip_pool.disable is not defined %}
-ifconfig-pool {{ server.client_ip_pool.start }} {{ server.client_ip_pool.stop }}{{ server.client_ip_pool.subnet_mask if server.client_ip_pool.subnet_mask is defined and server.client_ip_pool.subnet_mask is not none }}
-{% endif %}
-{% if server.max_connections is defined and server.max_connections is not none %}
-max-clients {{ server.max_connections }}
-{% endif %}
-{% if server.client is defined and server.client is not none %}
-client-config-dir /run/openvpn/ccd/{{ ifname }}
-{% endif %}
-{% endif %}
-keepalive {{ keep_alive.interval }} {{ keep_alive.interval|int * keep_alive.failure_count|int }}
-management /run/openvpn/openvpn-mgmt-intf unix
-{% if server is defined and server is not none %}
-{% if server.reject_unconfigured_clients is defined %}
-ccd-exclusive
-{% endif %}
-
-{% if server.name_server is defined and server.name_server is not none %}
-{% for nameserver in server.name_server %}
-{% if nameserver | is_ipv4 %}
-push "dhcp-option DNS {{ nameserver }}"
-{% elif nameserver | is_ipv6 %}
-push "dhcp-option DNS6 {{ nameserver }}"
-{% endif %}
-{% endfor %}
-{% endif %}
-{% if server.domain_name is defined and server.domain_name is not none %}
-push "dhcp-option DOMAIN {{ server.domain_name }}"
-{% endif %}
-{% if server.mfa is defined and server.mfa is not none %}
-{% if server.mfa.totp is defined and server.mfa.totp is not none %}
-{% set totp_config = server.mfa.totp %}
-plugin "{{ plugin_dir}}/openvpn-otp.so" "otp_secrets=/config/auth/openvpn/{{ ifname }}-otp-secrets {{ 'otp_slop=' ~ totp_config.slop }} {{ 'totp_t0=' ~ totp_config.drift }} {{ 'totp_step=' ~ totp_config.step }} {{ 'totp_digits=' ~ totp_config.digits }} password_is_cr={{ '1' if totp_config.challenge == 'enable' else '0' }}"
-{% endif %}
-{% endif %}
-{% endif %}
-{% else %}
-#
-# OpenVPN site-2-site mode
-#
-ping {{ keep_alive.interval }}
-ping-restart {{ keep_alive.failure_count }}
-
-{% if device_type == 'tap' %}
-{% for laddr, laddr_conf in local_address.items() if laddr | is_ipv4 %}
-{% if laddr_conf is defined and laddr_conf.subnet_mask is defined and laddr_conf.subnet_mask is not none %}
-ifconfig {{ laddr }} {{ laddr_conf.subnet_mask }}
-{% endif %}
-{% endfor %}
-{% else %}
-{% for laddr in local_address if laddr | is_ipv4 %}
-{% for raddr in remote_address if raddr | is_ipv4 %}
-ifconfig {{ laddr }} {{ raddr }}
-{% endfor %}
-{% endfor %}
-{% for laddr in local_address if laddr | is_ipv6 %}
-{% for raddr in remote_address if raddr | is_ipv6 %}
-ifconfig-ipv6 {{ laddr }} {{ raddr }}
-{% endfor %}
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if tls is defined and tls is not none %}
-# TLS options
-{% if tls.ca_certificate is defined and tls.ca_certificate is not none %}
-ca /run/openvpn/{{ ifname }}_ca.pem
-{% endif %}
-{% if tls.certificate is defined and tls.certificate is not none %}
-cert /run/openvpn/{{ ifname }}_cert.pem
-{% endif %}
-{% if tls.private_key is defined %}
-key /run/openvpn/{{ ifname }}_cert.key
-{% endif %}
-{% if tls.crypt_key is defined and tls.crypt_key is not none %}
-tls-crypt /run/openvpn/{{ ifname }}_crypt.key
-{% endif %}
-{% if tls.crl is defined %}
-crl-verify /run/openvpn/{{ ifname }}_crl.pem
-{% endif %}
-{% if tls.tls_version_min is defined and tls.tls_version_min is not none %}
-tls-version-min {{ tls.tls_version_min }}
-{% endif %}
-{% if tls.dh_params is defined and tls.dh_params is not none %}
-dh /run/openvpn/{{ ifname }}_dh.pem
-{% elif mode == 'server' and tls.private_key is defined %}
-dh none
-{% endif %}
-{% if tls.auth_key is defined and tls.auth_key is not none %}
-{% if mode == 'client' %}
-tls-auth /run/openvpn/{{ ifname }}_auth.key 1
-{% elif mode == 'server' %}
-tls-auth /run/openvpn/{{ ifname }}_auth.key 0
-{% endif %}
-{% endif %}
-{% if tls.role is defined and tls.role is not none %}
-{% if tls.role == 'active' %}
-tls-client
-{% elif tls.role == 'passive' %}
-tls-server
-{% endif %}
-{% endif %}
-{% endif %}
-
-# Encryption options
-{% if encryption is defined and encryption is not none %}
-{% if encryption.cipher is defined and encryption.cipher is not none %}
-cipher {{ encryption.cipher | openvpn_cipher }}
-{% if encryption.cipher == 'bf128' %}
-keysize 128
-{% elif encryption.cipher == 'bf256' %}
-keysize 256
-{% endif %}
-{% endif %}
-{% if encryption.ncp_ciphers is defined and encryption.ncp_ciphers is not none %}
-data-ciphers {{ encryption.ncp_ciphers | openvpn_ncp_ciphers }}
-{% endif %}
-{% endif %}
-
-{% if hash is defined and hash is not none %}
-auth {{ hash }}
-{% endif %}
-
-{% if authentication is defined and authentication is not none %}
-auth-user-pass {{ auth_user_pass_file }}
-auth-retry nointeract
-{% endif %}
diff --git a/data/templates/openvpn/service-override.conf.j2 b/data/templates/openvpn/service-override.conf.j2
new file mode 100644
index 000000000..616ba3bfc
--- /dev/null
+++ b/data/templates/openvpn/service-override.conf.j2
@@ -0,0 +1,21 @@
+{% set options = namespace(value='') %}
+{% if openvpn_option is vyos_defined %}
+{% for option in openvpn_option %}
+{# Remove the '--' prefix from variable if it is presented #}
+{% if option.startswith('--') %}
+{% set option = option.split('--', maxsplit=1)[1] %}
+{% endif %}
+{# Workaround to pass '--push' options properly. Previously openvpn accepted this option without values in double-quotes #}
+{# But now it stopped doing this, so we need to add them for compatibility #}
+{# HOWEVER! This is a raw option and we do not promise that this or any other trick will work for all the cases. #}
+{# Using 'openvpn-option' you take all responsibility for compatibility for yourself. #}
+{% if option.startswith('push') and not (option.startswith('push "') and option.endswith('"')) %}
+{% set option = 'push \"%s\"' | format(option.split('push ', maxsplit=1)[1]) %}
+{% endif %}
+{% set options.value = options.value ~ ' --' ~ option %}
+{% endfor %}
+{% endif %}
+[Service]
+ExecStart=
+ExecStart=/usr/sbin/openvpn --daemon openvpn-%i --config %i.conf --status %i.status 30 --writepid %i.pid {{ options.value }}
+
diff --git a/data/templates/openvpn/service-override.conf.tmpl b/data/templates/openvpn/service-override.conf.tmpl
deleted file mode 100644
index 069bdbd08..000000000
--- a/data/templates/openvpn/service-override.conf.tmpl
+++ /dev/null
@@ -1,20 +0,0 @@
-[Service]
-ExecStart=
-ExecStart=/usr/sbin/openvpn --daemon openvpn-%i --config %i.conf --status %i.status 30 --writepid %i.pid
-{%- if openvpn_option is defined and openvpn_option is not none %}
-{% for option in openvpn_option %}
-{# Remove the '--' prefix from variable if it is presented #}
-{% if option.startswith('--') %}
-{% set option = option.split('--', maxsplit=1)[1] %}
-{% endif %}
-{# Workaround to pass '--push' options properly. Previously openvpn accepted this option without values in double-quotes #}
-{# But now it stopped doing this, so we need to add them for compatibility #}
-{# HOWEVER! This is a raw option and we do not promise that this or any other trick will work for all the cases. #}
-{# Using 'openvpn-option' you take all responsibility for compatibility for yourself. #}
-{% if option.startswith('push') and not (option.startswith('push "') and option.endswith('"')) %}
-{% set option = 'push \"%s\"'|format(option.split('push ', maxsplit=1)[1]) %}
-{% endif %}
- --{{ option }}
-{%- endfor %}
-{% endif %}
-
diff --git a/data/templates/pmacct/override.conf.j2 b/data/templates/pmacct/override.conf.j2
new file mode 100644
index 000000000..213569ddc
--- /dev/null
+++ b/data/templates/pmacct/override.conf.j2
@@ -0,0 +1,17 @@
+{% set vrf_command = 'ip vrf exec ' ~ vrf ~ ' ' if vrf is vyos_defined else '' %}
+[Unit]
+After=
+After=vyos-router.service
+ConditionPathExists=
+ConditionPathExists=/run/pmacct/uacctd.conf
+
+[Service]
+EnvironmentFile=
+ExecStart=
+ExecStart={{ vrf_command }}/usr/sbin/uacctd -f /run/pmacct/uacctd.conf
+WorkingDirectory=
+WorkingDirectory=/run/pmacct
+PIDFile=
+PIDFile=/run/pmacct/uacctd.pid
+Restart=always
+RestartSec=10
diff --git a/data/templates/pmacct/uacctd.conf.j2 b/data/templates/pmacct/uacctd.conf.j2
new file mode 100644
index 000000000..a5016691f
--- /dev/null
+++ b/data/templates/pmacct/uacctd.conf.j2
@@ -0,0 +1,80 @@
+# Genereated from VyOS configuration
+daemonize: true
+promisc: false
+pidfile: /run/pmacct/uacctd.pid
+uacctd_group: 2
+uacctd_nl_size: 2097152
+snaplen: {{ packet_length }}
+aggregate: in_iface{{ ',out_iface' if enable_egress is vyos_defined }},src_mac,dst_mac,vlan,src_host,dst_host,src_port,dst_port,proto,tos,flows
+{% set pipe_size = buffer_size | int *1024 *1024 %}
+plugin_pipe_size: {{ pipe_size }}
+{# We need an integer division (//) without any remainder or fraction #}
+plugin_buffer_size: {{ pipe_size // 1000 }}
+{% if syslog_facility is vyos_defined %}
+syslog: {{ syslog_facility }}
+{% endif %}
+{% if disable_imt is not defined %}
+imt_path: /tmp/uacctd.pipe
+imt_mem_pools_number: 169
+{% endif %}
+
+{% set plugin = [] %}
+{% if netflow.server is vyos_defined %}
+{% for server in netflow.server %}
+{% set nf_server_key = 'nf_' ~ server | replace(':', '.') %}
+{% set _ = plugin.append('nfprobe['~ nf_server_key ~ ']') %}
+{% endfor %}
+{% endif %}
+{% if sflow.server is vyos_defined %}
+{% for server in sflow.server %}
+{% set sf_server_key = 'sf_' ~ server | replace(':', '.') %}
+{% set _ = plugin.append('sfprobe[' ~ sf_server_key ~ ']') %}
+{% endfor %}
+{% endif %}
+{% if disable_imt is not defined %}
+{% set _ = plugin.append('memory') %}
+{% endif %}
+plugins: {{ plugin | join(',') }}
+
+{% if netflow.server is vyos_defined %}
+# NetFlow servers
+{% for server, server_config in netflow.server.items() %}
+{# # prevent pmacct syntax error when using IPv6 flow collectors #}
+{% set nf_server_key = 'nf_' ~ server | replace(':', '.') %}
+nfprobe_receiver[{{ nf_server_key }}]: {{ server | bracketize_ipv6 }}:{{ server_config.port }}
+nfprobe_version[{{ nf_server_key }}]: {{ netflow.version }}
+{% if netflow.engine_id is vyos_defined %}
+nfprobe_engine[{{ nf_server_key }}]: {{ netflow.engine_id }}
+{% endif %}
+{% if netflow.max_flows is vyos_defined %}
+nfprobe_maxflows[{{ nf_server_key }}]: {{ netflow.max_flows }}
+{% endif %}
+{% if netflow.sampling_rate is vyos_defined %}
+sampling_rate[{{ nf_server_key }}]: {{ netflow.sampling_rate }}
+{% endif %}
+{% if netflow.source_address is vyos_defined %}
+nfprobe_source_ip[{{ nf_server_key }}]: {{ netflow.source_address }}
+{% endif %}
+{% if netflow.timeout is vyos_defined %}
+nfprobe_timeouts[{{ nf_server_key }}]: expint={{ netflow.timeout.expiry_interval }}:general={{ netflow.timeout.flow_generic }}:icmp={{ netflow.timeout.icmp }}:maxlife={{ netflow.timeout.max_active_life }}:tcp.fin={{ netflow.timeout.tcp_fin }}:tcp={{ netflow.timeout.tcp_generic }}:tcp.rst={{ netflow.timeout.tcp_rst }}:udp={{ netflow.timeout.udp }}
+{% endif %}
+
+{% endfor %}
+{% endif %}
+
+{% if sflow.server is vyos_defined %}
+# sFlow servers
+{% for server, server_config in sflow.server.items() %}
+{# # prevent pmacct syntax error when using IPv6 flow collectors #}
+{% set sf_server_key = 'sf_' ~ server | replace(':', '.') %}
+sfprobe_receiver[{{ sf_server_key }}]: {{ server | bracketize_ipv6 }}:{{ server_config.port }}
+sfprobe_agentip[{{ sf_server_key }}]: {{ sflow.agent_address }}
+{% if sflow.sampling_rate is vyos_defined %}
+sampling_rate[{{ sf_server_key }}]: {{ sflow.sampling_rate }}
+{% endif %}
+{% if sflow.source_address is vyos_defined %}
+sfprobe_source_ip[{{ sf_server_key }}]: {{ sflow.source_address }}
+{% endif %}
+
+{% endfor %}
+{% endif %}
diff --git a/data/templates/pppoe/ip-down.script.tmpl b/data/templates/pppoe/ip-down.script.tmpl
deleted file mode 100644
index bac4155d6..000000000
--- a/data/templates/pppoe/ip-down.script.tmpl
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/sh
-
-# As PPPoE is an "on demand" interface we need to re-configure it when it
-# becomes up
-if [ "$6" != "{{ ifname }}" ]; then
- exit
-fi
-
-# add some info to syslog
-DIALER_PID=$(cat /var/run/{{ ifname }}.pid)
-logger -t pppd[$DIALER_PID] "executing $0"
-
-{% if connect_on_demand is not defined %}
-# See https://phabricator.vyos.net/T2248. Determine if we are enslaved to a
-# VRF, this is needed to properly insert the default route.
-VRF_NAME=""
-if [ -d /sys/class/net/{{ ifname }}/upper_* ]; then
- # Determine upper (VRF) interface
- VRF=$(basename $(ls -d /sys/class/net/{{ ifname }}/upper_*))
- # Remove upper_ prefix from result string
- VRF=${VRF#"upper_"}
- # Populate variable to run in VR context
- VRF_NAME="vrf ${VRF_NAME}"
-fi
-
-{% if default_route != 'none' %}
-# Always delete default route when interface goes down if we installed it
-vtysh -c "conf t" ${VRF_NAME} -c "no ip route 0.0.0.0/0 {{ ifname }} ${VRF_NAME}"
-{% if ipv6 is defined and ipv6.address is defined and ipv6.address.autoconf is defined %}
-vtysh -c "conf t" ${VRF_NAME} -c "no ipv6 route ::/0 {{ ifname }} ${VRF_NAME}"
-{% endif %}
-{% endif %}
-{% endif %}
-
-{% if dhcpv6_options is defined and dhcpv6_options.pd is defined %}
-# Stop wide dhcpv6 client
-systemctl stop dhcp6c@{{ ifname }}.service
-{% endif %}
diff --git a/data/templates/pppoe/ip-pre-up.script.tmpl b/data/templates/pppoe/ip-pre-up.script.tmpl
deleted file mode 100644
index a54e4e9bd..000000000
--- a/data/templates/pppoe/ip-pre-up.script.tmpl
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/sh
-
-# As PPPoE is an "on demand" interface we need to re-configure it when it
-# becomes up
-if [ "$6" != "{{ ifname }}" ]; then
- exit
-fi
-
-# add some info to syslog
-DIALER_PID=$(cat /var/run/{{ ifname }}.pid)
-logger -t pppd[$DIALER_PID] "executing $0"
-
-echo "{{ description }}" > /sys/class/net/{{ ifname }}/ifalias
-
-{% if vrf %}
-logger -t pppd[$DIALER_PID] "configuring dialer interface $6 for VRF {{ vrf }}"
-ip link set dev {{ ifname }} master {{ vrf }}
-{% endif %}
diff --git a/data/templates/pppoe/ip-up.script.tmpl b/data/templates/pppoe/ip-up.script.tmpl
deleted file mode 100644
index 302756960..000000000
--- a/data/templates/pppoe/ip-up.script.tmpl
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/bin/sh
-
-# As PPPoE is an "on demand" interface we need to re-configure it when it
-# becomes up
-if [ "$6" != "{{ ifname }}" ]; then
- exit
-fi
-
-{% if connect_on_demand is not defined %}
-# add some info to syslog
-DIALER_PID=$(cat /var/run/{{ ifname }}.pid)
-logger -t pppd[$DIALER_PID] "executing $0"
-
-{% if default_route != 'none' %}
-# See https://phabricator.vyos.net/T2248 & T2220. Determine if we are enslaved
-# to a VRF, this is needed to properly insert the default route.
-
-SED_OPT="^ip route"
-VRF_NAME=""
-if [ -d /sys/class/net/{{ ifname }}/upper_* ]; then
- # Determine upper (VRF) interface
- VRF=$(basename $(ls -d /sys/class/net/{{ ifname }}/upper_*))
- # Remove upper_ prefix from result string
- VRF=${VRF#"upper_"}
- # generate new SED command
- SED_OPT="vrf ${VRF}"
- # generate vtysh option
- VRF_NAME="vrf ${VRF}"
-fi
-
-{% if default_route == 'auto' %}
-# Only insert a new default route if there is no default route configured
-routes=$(vtysh -c "show running-config" | sed -n "/${SED_OPT}/,/!/p" | grep 0.0.0.0/0 | wc -l)
-if [ "$routes" -ne 0 ]; then
- exit 1
-fi
-
-{% elif default_route == 'force' %}
-# Retrieve current static default routes and remove it from the routing table
-vtysh -c "show running-config" | sed -n "/${SED_OPT}/,/!/p" | grep 0.0.0.0/0 | while read route ; do
- vtysh -c "conf t" ${VTY_OPT} -c "no ${route} ${VRF_NAME}"
-done
-{% endif %}
-
-# Add default route to default or VRF routing table
-vtysh -c "conf t" ${VTY_OPT} -c "ip route 0.0.0.0/0 {{ ifname }} ${VRF_NAME}"
-logger -t pppd[$DIALER_PID] "added default route via {{ ifname }} ${VRF_NAME}"
-{% endif %}
-{% endif %}
diff --git a/data/templates/pppoe/ipv6-up.script.tmpl b/data/templates/pppoe/ipv6-up.script.tmpl
deleted file mode 100644
index da73cb4d5..000000000
--- a/data/templates/pppoe/ipv6-up.script.tmpl
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/sh
-
-# As PPPoE is an "on demand" interface we need to re-configure it when it
-# becomes up
-
-if [ "$6" != "{{ ifname }}" ]; then
- exit
-fi
-
-
-{% if default_route != 'none' %}
-# See https://phabricator.vyos.net/T2248 & T2220. Determine if we are enslaved
-# to a VRF, this is needed to properly insert the default route.
-
-SED_OPT="^ipv6 route"
-VRF_NAME=""
-if [ -d /sys/class/net/{{ ifname }}/upper_* ]; then
- # Determine upper (VRF) interface
- VRF=$(basename $(ls -d /sys/class/net/{{ ifname }}/upper_*))
- # Remove upper_ prefix from result string
- VRF=${VRF#"upper_"}
- # generate new SED command
- SED_OPT="vrf ${VRF}"
- # generate vtysh option
- VRF_NAME="vrf ${VRF}"
-fi
-
-{% if default_route == 'auto' %}
-# Only insert a new default route if there is no default route configured
-routes=$(vtysh -c "show running-config" | sed -n "/${SED_OPT}/,/!/p" | grep ::/0 | wc -l)
-if [ "$routes" -ne 0 ]; then
- exit 1
-fi
-
-{% elif default_route == 'force' %}
-# Retrieve current static default routes and remove it from the routing table
-vtysh -c "show running-config" | sed -n "/${SED_OPT}/,/!/p" | grep ::/0 | while read route ; do
- vtysh -c "conf t" ${VTY_OPT} -c "no ${route} ${VRF_NAME}"
-done
-{% endif %}
-
-# Add default route to default or VRF routing table
-vtysh -c "conf t" ${VTY_OPT} -c "ipv6 route ::/0 {{ ifname }} ${VRF_NAME}"
-logger -t pppd[$DIALER_PID] "added default route via {{ ifname }} ${VRF_NAME}"
-{% endif %}
-
diff --git a/data/templates/pppoe/peer.tmpl b/data/templates/pppoe/peer.j2
index 928ed1238..6221abb9b 100644
--- a/data/templates/pppoe/peer.tmpl
+++ b/data/templates/pppoe/peer.j2
@@ -1,5 +1,5 @@
### Autogenerated by interfaces-pppoe.py ###
-{{ '# ' ~ description if description is defined else '' }}
+{{ '# ' ~ description if description is vyos_defined else '' }}
# Require peer to provide the local IP address if it is not
# specified explicitly in the config file.
@@ -35,10 +35,10 @@ noproxyarp
maxfail 0
plugin rp-pppoe.so {{ source_interface }}
-{% if access_concentrator is defined and access_concentrator is not none %}
+{% if access_concentrator is vyos_defined %}
rp_pppoe_ac '{{ access_concentrator }}'
{% endif %}
-{% if service_name is defined and service_name is not none %}
+{% if service_name is vyos_defined %}
rp_pppoe_service '{{ service_name }}'
{% endif %}
@@ -49,34 +49,34 @@ debug
mtu {{ mtu }}
mru {{ mtu }}
-{% if authentication is defined %}
-{{ 'user "' + authentication.user + '"' if authentication.user is defined }}
-{{ 'password "' + authentication.password + '"' if authentication.password is defined }}
+{% if authentication is vyos_defined %}
+{{ 'user "' + authentication.user + '"' if authentication.user is vyos_defined }}
+{{ 'password "' + authentication.password + '"' if authentication.password is vyos_defined }}
{% endif %}
-{{ "usepeerdns" if no_peer_dns is not defined }}
+{{ "usepeerdns" if no_peer_dns is not vyos_defined }}
-{% if ipv6 is defined %}
-+ipv6 {{ 'ipv6cp-use-ipaddr' if ipv6.address is defined and ipv6.address.autoconf is defined }}
+{% if ipv6 is vyos_defined %}
++ipv6 {{ 'ipv6cp-use-ipaddr' if ipv6.address.autoconf is vyos_defined }}
{% else %}
noipv6
{% endif %}
-{% if connect_on_demand is defined %}
+{% if connect_on_demand is vyos_defined %}
demand
# See T2249. PPP default route options should only be set when in on-demand
# mode. As soon as we are not in on-demand mode the default-route handling is
# passed to the ip-up.d/ip-down.s scripts which is required for VRF support.
-{% if 'auto' in default_route %}
+{% if 'auto' in default_route %}
defaultroute
-{{ 'defaultroute6' if ipv6 is defined }}
-{% elif 'force' in default_route %}
+{{ 'defaultroute6' if ipv6 is vyos_defined }}
+{% elif 'force' in default_route %}
defaultroute
replacedefaultroute
-{{ 'defaultroute6' if ipv6 is defined }}
-{% endif %}
+{{ 'defaultroute6' if ipv6 is vyos_defined }}
+{% endif %}
{% else %}
nodefaultroute
noreplacedefaultroute
-{{ 'nodefaultroute6' if ipv6 is defined }}
+{{ 'nodefaultroute6' if ipv6 is vyos_defined }}
{% endif %}
diff --git a/data/templates/router-advert/radvd.conf.j2 b/data/templates/router-advert/radvd.conf.j2
new file mode 100644
index 000000000..6902dc05a
--- /dev/null
+++ b/data/templates/router-advert/radvd.conf.j2
@@ -0,0 +1,66 @@
+### Autogenerated by service_router-advert.py ###
+
+{% if interface is vyos_defined %}
+{% for iface, iface_config in interface.items() %}
+interface {{ iface }} {
+ IgnoreIfMissing on;
+{% if iface_config.default_preference is vyos_defined %}
+ AdvDefaultPreference {{ iface_config.default_preference }};
+{% endif %}
+{% if iface_config.managed_flag is vyos_defined %}
+ AdvManagedFlag {{ 'on' if iface_config.managed_flag is vyos_defined else 'off' }};
+{% endif %}
+{% if iface_config.interval.max is vyos_defined %}
+ MaxRtrAdvInterval {{ iface_config.interval.max }};
+{% endif %}
+{% if iface_config.interval.min is vyos_defined %}
+ MinRtrAdvInterval {{ iface_config.interval.min }};
+{% endif %}
+{% if iface_config.reachable_time is vyos_defined %}
+ AdvReachableTime {{ iface_config.reachable_time }};
+{% endif %}
+ AdvIntervalOpt {{ 'off' if iface_config.no_send_advert is vyos_defined else 'on' }};
+ AdvSendAdvert {{ 'off' if iface_config.no_send_advert is vyos_defined else 'on' }};
+{% if iface_config.default_lifetime is vyos_defined %}
+ AdvDefaultLifetime {{ iface_config.default_lifetime }};
+{% endif %}
+{% if iface_config.link_mtu is vyos_defined %}
+ AdvLinkMTU {{ iface_config.link_mtu }};
+{% endif %}
+ AdvOtherConfigFlag {{ 'on' if iface_config.other_config_flag is vyos_defined else 'off' }};
+ AdvRetransTimer {{ iface_config.retrans_timer }};
+ AdvCurHopLimit {{ iface_config.hop_limit }};
+{% if iface_config.route is vyos_defined %}
+{% for route, route_options in iface_config.route.items() %}
+ route {{ route }} {
+{% if route_options.valid_lifetime is vyos_defined %}
+ AdvRouteLifetime {{ route_options.valid_lifetime }};
+{% endif %}
+{% if route_options.route_preference is vyos_defined %}
+ AdvRoutePreference {{ route_options.route_preference }};
+{% endif %}
+ RemoveRoute {{ 'off' if route_options.no_remove_route is vyos_defined else 'on' }};
+ };
+{% endfor %}
+{% endif %}
+{% if iface_config.prefix is vyos_defined %}
+{% for prefix, prefix_options in iface_config.prefix.items() %}
+ prefix {{ prefix }} {
+ AdvAutonomous {{ 'off' if prefix_options.no_autonomous_flag is vyos_defined else 'on' }};
+ AdvValidLifetime {{ prefix_options.valid_lifetime }};
+ AdvOnLink {{ 'off' if prefix_options.no_on_link_flag is vyos_defined else 'on' }};
+ AdvPreferredLifetime {{ prefix_options.preferred_lifetime }};
+ };
+{% endfor %}
+{% endif %}
+{% if iface_config.name_server is vyos_defined %}
+ RDNSS {{ iface_config.name_server | join(" ") }} {
+ };
+{% endif %}
+{% if iface_config.dnssl is vyos_defined %}
+ DNSSL {{ iface_config.dnssl | join(" ") }} {
+ };
+{% endif %}
+};
+{% endfor %}
+{% endif %}
diff --git a/data/templates/router-advert/radvd.conf.tmpl b/data/templates/router-advert/radvd.conf.tmpl
deleted file mode 100644
index 88d066491..000000000
--- a/data/templates/router-advert/radvd.conf.tmpl
+++ /dev/null
@@ -1,66 +0,0 @@
-### Autogenerated by service_router-advert.py ###
-
-{% if interface is defined and interface is not none %}
-{% for iface, iface_config in interface.items() %}
-interface {{ iface }} {
- IgnoreIfMissing on;
-{% if iface_config.default_preference is defined and iface_config.default_preference is not none %}
- AdvDefaultPreference {{ iface_config.default_preference }};
-{% endif %}
-{% if iface_config.managed_flag is defined and iface_config.managed_flag is not none %}
- AdvManagedFlag {{ 'on' if iface_config.managed_flag is defined else 'off' }};
-{% endif %}
-{% if iface_config.interval.max is defined and iface_config.interval.max is not none %}
- MaxRtrAdvInterval {{ iface_config.interval.max }};
-{% endif %}
-{% if iface_config.interval.min is defined and iface_config.interval.min is not none %}
- MinRtrAdvInterval {{ iface_config.interval.min }};
-{% endif %}
-{% if iface_config.reachable_time is defined and iface_config.reachable_time is not none %}
- AdvReachableTime {{ iface_config.reachable_time }};
-{% endif %}
- AdvIntervalOpt {{ 'off' if iface_config.no_send_advert is defined else 'on' }};
- AdvSendAdvert {{ 'off' if iface_config.no_send_advert is defined else 'on' }};
-{% if iface_config.default_lifetime is defined %}
- AdvDefaultLifetime {{ iface_config.default_lifetime }};
-{% endif %}
-{% if iface_config.link_mtu is defined %}
- AdvLinkMTU {{ iface_config.link_mtu }};
-{% endif %}
- AdvOtherConfigFlag {{ 'on' if iface_config.other_config_flag is defined else 'off' }};
- AdvRetransTimer {{ iface_config.retrans_timer }};
- AdvCurHopLimit {{ iface_config.hop_limit }};
-{% if iface_config.route is defined %}
-{% for route, route_options in iface_config.route.items() %}
- route {{ route }} {
-{% if route_options.valid_lifetime is defined %}
- AdvRouteLifetime {{ route_options.valid_lifetime }};
-{% endif %}
-{% if route_options.route_preference is defined %}
- AdvRoutePreference {{ route_options.route_preference }};
-{% endif %}
- RemoveRoute {{ 'off' if route_options.no_remove_route is defined else 'on' }};
- };
-{% endfor %}
-{% endif %}
-{% if iface_config.prefix is defined and iface_config.prefix is not none %}
-{% for prefix, prefix_options in iface_config.prefix.items() %}
- prefix {{ prefix }} {
- AdvAutonomous {{ 'off' if prefix_options.no_autonomous_flag is defined else 'on' }};
- AdvValidLifetime {{ prefix_options.valid_lifetime }};
- AdvOnLink {{ 'off' if prefix_options.no_on_link_flag is defined else 'on' }};
- AdvPreferredLifetime {{ prefix_options.preferred_lifetime }};
- };
-{% endfor %}
-{% endif %}
-{% if iface_config.name_server is defined %}
- RDNSS {{ iface_config.name_server | join(" ") }} {
- };
-{% endif %}
-{% if iface_config.dnssl is defined %}
- DNSSL {{ iface_config.dnssl | join(" ") }} {
- };
-{% endif %}
-};
-{% endfor %}
-{% endif %}
diff --git a/data/templates/salt-minion/minion.tmpl b/data/templates/salt-minion/minion.j2
index 99749b57a..f4001db64 100644
--- a/data/templates/salt-minion/minion.tmpl
+++ b/data/templates/salt-minion/minion.j2
@@ -32,17 +32,17 @@ log_file: /var/log/salt/minion
# ['garbage', 'trace', 'debug']
#
# Default: 'warning'
-log_level: {{ log_level }}
+log_level: warning
# Set the location of the salt master server, if the master server cannot be
# resolved, then the minion will fail to start.
master:
{% for host in master %}
-- {{ host }}
+ - {{ host | bracketize_ipv6 }}
{% endfor %}
# The user to run salt
-user: {{ user }}
+user: minion
# The directory to store the pki information in
pki_dir: /config/salt/pki/minion
@@ -52,10 +52,16 @@ pki_dir: /config/salt/pki/minion
# Since salt uses detached ids it is possible to run multiple minions on the
# same machine but with different ids, this can be useful for salt compute
# clusters.
-id: {{ salt_id }}
-
+id: {{ id }}
# The number of minutes between mine updates.
mine_interval: {{ interval }}
-verify_master_pubkey_sign: {{ verify_master_pubkey_sign }}
+{% if source_interface is vyos_defined %}
+# The name of the interface to use when establishing the connection to the Master.
+source_interface_name: {{ source_interface }}
+{% endif %}
+
+# Enables verification of the master-public-signature returned by the master
+# in auth-replies.
+verify_master_pubkey_sign: {{ 'True' if master_key is vyos_defined else 'False' }}
diff --git a/data/templates/snmp/etc.snmp.conf.tmpl b/data/templates/snmp/etc.snmp.conf.j2
index 6e4c6f063..8012cf6bb 100644
--- a/data/templates/snmp/etc.snmp.conf.tmpl
+++ b/data/templates/snmp/etc.snmp.conf.j2
@@ -1,4 +1,4 @@
### Autogenerated by snmp.py ###
-{% if trap_source %}
+{% if trap_source is vyos_defined %}
clientaddr {{ trap_source }}
{% endif %}
diff --git a/data/templates/snmp/etc.snmpd.conf.j2 b/data/templates/snmp/etc.snmpd.conf.j2
new file mode 100644
index 000000000..d7dc0ba5d
--- /dev/null
+++ b/data/templates/snmp/etc.snmpd.conf.j2
@@ -0,0 +1,182 @@
+### Autogenerated by snmp.py ###
+
+# non configurable defaults
+sysObjectID 1.3.6.1.4.1.44641
+sysServices 14
+master agentx
+agentXPerms 0777 0777
+pass .1.3.6.1.2.1.31.1.1.1.18 /opt/vyatta/sbin/if-mib-alias
+smuxpeer .1.3.6.1.2.1.83
+smuxpeer .1.3.6.1.2.1.157
+smuxsocket localhost
+
+# linkUp/Down configure the Event MIB tables to monitor
+# the ifTable for network interfaces being taken up or down
+# for making internal queries to retrieve any necessary information
+iquerySecName {{ vyos_user }}
+
+# Modified from the default linkUpDownNotification
+# to include more OIDs and poll more frequently
+notificationEvent linkUpTrap linkUp ifIndex ifDescr ifType ifAdminStatus ifOperStatus
+notificationEvent linkDownTrap linkDown ifIndex ifDescr ifType ifAdminStatus ifOperStatus
+monitor -r 10 -e linkUpTrap "Generate linkUp" ifOperStatus != 2
+monitor -r 10 -e linkDownTrap "Generate linkDown" ifOperStatus == 2
+
+# Remove all old ifTable entries with the same ifName as newly appeared
+# interface (with different ifIndex) - this is the case on e.g. ppp interfaces
+interface_replace_old yes
+
+########################
+# configurable section #
+########################
+
+# Default system description is VyOS version
+sysDescr VyOS {{ version }}
+
+{% if description is vyos_defined %}
+# Description
+SysDescr {{ description }}
+{% endif %}
+
+# Listen
+{% set options = [] %}
+{% if listen_address is vyos_defined %}
+{% for address, address_options in listen_address.items() %}
+{% if address | is_ipv6 %}
+{% set protocol = protocol ~ '6' %}
+{% endif %}
+{% set _ = options.append(protocol ~ ':' ~ address | bracketize_ipv6 ~ ':' ~ address_options.port) %}
+{% endfor %}
+{% else %}
+{% set _ = options.append(protocol ~ ':161') %}
+{% set _ = options.append(protocol ~ '6:161') %}
+{% endif %}
+agentaddress unix:/run/snmpd.socket{{ ',' ~ options | join(',') if options is vyos_defined }}
+
+# SNMP communities
+{% if community is vyos_defined %}
+{% for comm, comm_config in community.items() %}
+{% if comm_config.client is vyos_defined %}
+{% for client in comm_config.client %}
+{% if client | is_ipv4 %}
+{{ comm_config.authorization }}community {{ comm }} {{ client }}
+{% elif client | is_ipv6 %}
+{{ comm_config.authorization }}community6 {{ comm }} {{ client }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if comm_config.network is vyos_defined %}
+{% for network in comm_config.network %}
+{% if network | is_ipv4 %}
+{{ comm_config.authorization }}community {{ comm }} {{ network }}
+{% elif client | is_ipv6 %}
+{{ comm_config.authorization }}community6 {{ comm }} {{ network }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if comm_config.client is not vyos_defined and comm_config.network is not vyos_defined %}
+{{ comm_config.authorization }}community {{ comm }}
+{% endif %}
+{% endfor %}
+{% endif %}
+
+{% if contact is vyos_defined %}
+# system contact information
+SysContact {{ contact }}
+{% endif %}
+
+{% if location is vyos_defined %}
+# system location information
+SysLocation {{ location }}
+{% endif %}
+
+{% if smux_peer is vyos_defined %}
+# additional smux peers
+{% for peer in smux_peer %}
+smuxpeer {{ peer }}
+{% endfor %}
+{% endif %}
+
+{% if trap_target is vyos_defined %}
+# if there is a problem - tell someone!
+{% for trap, trap_config in trap_target.items() %}
+trap2sink {{ trap }}:{{ trap_config.port }} {{ trap_config.community }}
+{% endfor %}
+{% endif %}
+
+{% if v3 is vyos_defined %}
+#
+# SNMPv3 stuff goes here
+#
+{% if v3.view is vyos_defined %}
+# views
+{% for view, view_config in v3.view.items() %}
+{% if view_config.oid is vyos_defined %}
+{% for oid in view_config.oid %}
+view {{ view }} included .{{ oid }}
+{% endfor %}
+{% endif %}
+{% endfor %}
+{% endif %}
+
+# access
+{% if v3.group is vyos_defined %}
+# context sec.model sec.level match read write notif
+{% for group, group_config in v3.group.items() %}
+access {{ group }} "" usm {{ group_config.seclevel }} exact {{ group_config.view }} {{ 'none' if group_config.mode == 'ro' else group_config.view }} none
+{% endfor %}
+{% endif %}
+
+# trap-target
+{% if v3.trap_target is vyos_defined %}
+{% for trap, trap_config in v3.trap_target.items() %}
+{% set options = '' %}
+{% if trap_config.type == 'inform' %}
+{% set options = options ~ ' -Ci' %}
+{% endif %}
+{% if v3.engineid is vyos_defined %}
+{% set options = options ~ ' -e "' ~ v3.engineid ~ '"' %}
+{% endif %}
+{% if trap_config.user is vyos_defined %}
+{% set options = options ~ ' -u ' ~ trap_config.user %}
+{% endif %}
+{% if trap_config.auth.plaintext_password is vyos_defined or trap_config.auth.encrypted_password is vyos_defined %}
+{% set options = options ~ ' -a ' ~ trap_config.auth.type %}
+{% if trap_config.auth.plaintext_password is vyos_defined %}
+{% set options = options ~ ' -A ' ~ trap_config.auth.plaintext_password %}
+{% elif trap_config.auth.encrypted_password is vyos_defined %}
+{% set options = options ~ ' -3m ' ~ trap_config.auth.encrypted_password %}
+{% endif %}
+{% if trap_config.privacy.plaintext_password is vyos_defined or trap_config.privacy.encrypted_password is vyos_defined %}
+{% set options = options ~ ' -x ' ~ trap_config.privacy.type %}
+{% if trap_config.privacy.plaintext_password is vyos_defined %}
+{% set options = options ~ ' -X ' ~ trap_config.privacy.plaintext_password %}
+{% elif trap_config.privacy.encrypted_password is vyos_defined %}
+{% set options = options ~ ' -3M ' ~ trap_config.privacy.encrypted_password %}
+{% endif %}
+{% set options = options ~ ' -l authPriv' %}
+{% else %}
+{% set options = options ~ ' -l authNoPriv' %}
+{% endif %}
+{% else %}
+{% set options = options ~ ' -l noAuthNoPriv' %}
+{% endif %}
+trapsess -v 3 {{ options }} {{ trap }}:{{ trap_config.protocol }}:{{ trap_config.port }}
+{% endfor %}
+{% endif %}
+
+# group
+{% if v3.user is vyos_defined %}
+{% for user, user_config in v3.user.items() %}
+group {{ user_config.group }} usm {{ user }}
+{% endfor %}
+{% endif %}
+{# SNMPv3 end #}
+{% endif %}
+
+{% if script_extensions.extension_name is vyos_defined %}
+# extension scripts
+{% for script, script_config in script_extensions.extension_name.items() | sort(attribute=script) %}
+extend {{ script }} {{ script_config.script }}
+{% endfor %}
+{% endif %}
diff --git a/data/templates/snmp/etc.snmpd.conf.tmpl b/data/templates/snmp/etc.snmpd.conf.tmpl
deleted file mode 100644
index 30806ce8a..000000000
--- a/data/templates/snmp/etc.snmpd.conf.tmpl
+++ /dev/null
@@ -1,119 +0,0 @@
-### Autogenerated by snmp.py ###
-
-# non configurable defaults
-sysObjectID 1.3.6.1.4.1.44641
-sysServices 14
-master agentx
-agentXPerms 0777 0777
-pass .1.3.6.1.2.1.31.1.1.1.18 /opt/vyatta/sbin/if-mib-alias
-smuxpeer .1.3.6.1.2.1.83
-smuxpeer .1.3.6.1.2.1.157
-smuxsocket localhost
-
-# linkUp/Down configure the Event MIB tables to monitor
-# the ifTable for network interfaces being taken up or down
-# for making internal queries to retrieve any necessary information
-iquerySecName {{ vyos_user }}
-
-# Modified from the default linkUpDownNotification
-# to include more OIDs and poll more frequently
-notificationEvent linkUpTrap linkUp ifIndex ifDescr ifType ifAdminStatus ifOperStatus
-notificationEvent linkDownTrap linkDown ifIndex ifDescr ifType ifAdminStatus ifOperStatus
-monitor -r 10 -e linkUpTrap "Generate linkUp" ifOperStatus != 2
-monitor -r 10 -e linkDownTrap "Generate linkDown" ifOperStatus == 2
-
-# Remove all old ifTable entries with the same ifName as newly appeared
-# interface (with different ifIndex) - this is the case on e.g. ppp interfaces
-interface_replace_old yes
-
-########################
-# configurable section #
-########################
-
-# Default system description is VyOS version
-sysDescr VyOS {{ version }}
-
-{% if description %}
-# Description
-SysDescr {{ description }}
-{% endif %}
-
-# Listen
-agentaddress unix:/run/snmpd.socket{% if listen_on %}{% for li in listen_on %},{{ li }}{% endfor %}{% else %},{{protocol}}:161{% if ipv6_enabled %},{{protocol}}6:161{% endif %}{% endif %}
-
-# SNMP communities
-{% for c in communities %}
-{% if c.network_v4 %}
-{% for network in c.network_v4 %}
-{{ c.authorization }}community {{ c.name }} {{ network }}
-{% endfor %}
-{% elif not c.has_source %}
-{{ c.authorization }}community {{ c.name }}
-{% endif %}
-{% if c.network_v6 %}
-{% for network in c.network_v6 %}
-{{ c.authorization }}community6 {{ c.name }} {{ network }}
-{% endfor %}
-{% elif not c.has_source %}
-{{ c.authorization }}community6 {{ c.name }}
-{% endif %}
-{% endfor %}
-
-{% if contact %}
-# system contact information
-SysContact {{ contact }}
-{% endif %}
-
-{% if location %}
-# system location information
-SysLocation {{ location }}
-{% endif %}
-
-{% if smux_peers %}
-# additional smux peers
-{% for sp in smux_peers %}
-smuxpeer {{ sp }}
-{% endfor %}
-{% endif %}
-
-{% if trap_targets %}
-# if there is a problem - tell someone!
-{% for trap in trap_targets %}
-trap2sink {{ trap.target }}{{ ":" + trap.port if trap.port is defined }} {{ trap.community }}
-{% endfor %}
-{% endif %}
-
-{% if v3_enabled %}
-#
-# SNMPv3 stuff goes here
-#
-# views
-{% for view in v3_views %}
-{% for oid in view.oids %}
-view {{ view.name }} included .{{ oid.oid }}
-{% endfor %}
-{% endfor %}
-
-# access
-# context sec.model sec.level match read write notif
-{% for group in v3_groups %}
-access {{ group.name }} "" usm {{ group.seclevel }} exact {{ group.view }} {% if group.mode == 'ro' %}none{% else %}{{ group.view }}{% endif %} none
-{% endfor %}
-
-# trap-target
-{% for t in v3_traps %}
-trapsess -v 3 {{ '-Ci' if t.type == 'inform' }} -e {{ v3_engineid }} -u {{ t.secName }} -l {{ t.secLevel }} -a {{ t.authProtocol }} {% if t.authPassword %}-A {{ t.authPassword }}{% elif t.authMasterKey %}-3m {{ t.authMasterKey }}{% endif %} -x {{ t.privProtocol }} {% if t.privPassword %}-X {{ t.privPassword }}{% elif t.privMasterKey %}-3M {{ t.privMasterKey }}{% endif %} {{ t.ipProto }}:{{ t.ipAddr }}:{{ t.ipPort }}
-{% endfor %}
-
-# group
-{% for u in v3_users %}
-group {{ u.group }} usm {{ u.name }}
-{% endfor %}
-{% endif %}
-
-{% if script_ext %}
-# extension scripts
-{% for ext in script_ext|sort(attribute='name') %}
-extend {{ ext.name }} {{ ext.script }}
-{% endfor %}
-{% endif %}
diff --git a/data/templates/snmp/override.conf.j2 b/data/templates/snmp/override.conf.j2
new file mode 100644
index 000000000..5d787de86
--- /dev/null
+++ b/data/templates/snmp/override.conf.j2
@@ -0,0 +1,14 @@
+{% set vrf_command = 'ip vrf exec ' ~ vrf ~ ' ' if vrf is vyos_defined else '' %}
+{% set oid_route_table = ' ' if oid_enable is vyos_defined('route-table') else '-I -ipCidrRouteTable,inetCidrRouteTable' %}
+[Unit]
+StartLimitIntervalSec=0
+After=vyos-router.service
+
+[Service]
+Environment=
+Environment="MIBDIRS=/usr/share/snmp/mibs:/usr/share/snmp/mibs/iana:/usr/share/snmp/mibs/ietf:/usr/share/vyos/mibs"
+ExecStart=
+ExecStart={{ vrf_command }}/usr/sbin/snmpd -LS0-5d -Lf /dev/null -u Debian-snmp -g Debian-snmp {{ oid_route_table }} -f -p /run/snmpd.pid
+Restart=always
+RestartSec=10
+
diff --git a/data/templates/snmp/override.conf.tmpl b/data/templates/snmp/override.conf.tmpl
deleted file mode 100644
index 2ac45a89f..000000000
--- a/data/templates/snmp/override.conf.tmpl
+++ /dev/null
@@ -1,14 +0,0 @@
-{% set vrf_command = 'ip vrf exec ' + vrf + ' ' if vrf is defined else '' %}
-{% set oid_route_table = ' ' if route_table is sameas true else '-I -ipCidrRouteTable,inetCidrRouteTable' %}
-[Unit]
-StartLimitIntervalSec=0
-After=vyos-router.service
-
-[Service]
-Environment=
-Environment="MIBDIRS=/usr/share/snmp/mibs:/usr/share/snmp/mibs/iana:/usr/share/snmp/mibs/ietf:/usr/share/vyos/mibs"
-ExecStart=
-ExecStart={{vrf_command}}/usr/sbin/snmpd -LS0-5d -Lf /dev/null -u Debian-snmp -g Debian-snmp {{oid_route_table}} -f -p /run/snmpd.pid
-Restart=always
-RestartSec=10
-
diff --git a/data/templates/snmp/usr.snmpd.conf.j2 b/data/templates/snmp/usr.snmpd.conf.j2
new file mode 100644
index 000000000..a713c1cec
--- /dev/null
+++ b/data/templates/snmp/usr.snmpd.conf.j2
@@ -0,0 +1,8 @@
+### Autogenerated by snmp.py ###
+{% if v3.user is vyos_defined %}
+{% for user, user_config in v3.user.items() %}
+{{ user_config.mode }}user {{ user }}
+{% endfor %}
+{% endif %}
+
+rwuser {{ vyos_user }}
diff --git a/data/templates/snmp/usr.snmpd.conf.tmpl b/data/templates/snmp/usr.snmpd.conf.tmpl
deleted file mode 100644
index e2c5ec102..000000000
--- a/data/templates/snmp/usr.snmpd.conf.tmpl
+++ /dev/null
@@ -1,6 +0,0 @@
-### Autogenerated by snmp.py ###
-{% for u in v3_users %}
-{{ u.mode }}user {{ u.name }}
-{% endfor %}
-
-rwuser {{ vyos_user }}
diff --git a/data/templates/snmp/var.snmpd.conf.j2 b/data/templates/snmp/var.snmpd.conf.j2
new file mode 100644
index 000000000..012f33aeb
--- /dev/null
+++ b/data/templates/snmp/var.snmpd.conf.j2
@@ -0,0 +1,16 @@
+### Autogenerated by snmp.py ###
+# user
+{% if v3 is vyos_defined %}
+{% if v3.user is vyos_defined %}
+{% for user, user_config in v3.user.items() %}
+usmUser 1 3 0x{{ v3.engineid }} "{{ user }}" "{{ user }}" NULL {{ user_config.auth.type | snmp_auth_oid }} 0x{{ user_config.auth.encrypted_password }} {{ user_config.privacy.type | snmp_auth_oid }} 0x{{ user_config.privacy.encrypted_password }} 0x
+{% endfor %}
+{% endif %}
+
+# VyOS default user
+createUser {{ vyos_user }} MD5 "{{ vyos_user_pass }}" DES
+
+{% if v3.engineid is vyos_defined %}
+oldEngineID 0x{{ v3.engineid }}
+{% endif %}
+{% endif %}
diff --git a/data/templates/snmp/var.snmpd.conf.tmpl b/data/templates/snmp/var.snmpd.conf.tmpl
deleted file mode 100644
index c779587df..000000000
--- a/data/templates/snmp/var.snmpd.conf.tmpl
+++ /dev/null
@@ -1,14 +0,0 @@
-### Autogenerated by snmp.py ###
-# user
-{% for u in v3_users %}
-{% if u.authOID == 'none' %}
-createUser {{ u.name }}
-{% else %}
-usmUser 1 3 0x{{ v3_engineid }} "{{ u.name }}" "{{ u.name }}" NULL {{ u.authOID }} 0x{{ u.authMasterKey }} {{ u.privOID }} 0x{{ u.privMasterKey }} 0x
-{% endif %}
-{% endfor %}
-
-createUser {{ vyos_user }} MD5 "{{ vyos_user_pass }}" DES
-{% if v3_engineid %}
-oldEngineID 0x{{ v3_engineid }}
-{% endif %}
diff --git a/data/templates/squid/sg_acl.conf.tmpl b/data/templates/squid/sg_acl.conf.j2
index ce72b173a..ce72b173a 100644
--- a/data/templates/squid/sg_acl.conf.tmpl
+++ b/data/templates/squid/sg_acl.conf.j2
diff --git a/data/templates/squid/squid.conf.j2 b/data/templates/squid/squid.conf.j2
new file mode 100644
index 000000000..a0fdeb20e
--- /dev/null
+++ b/data/templates/squid/squid.conf.j2
@@ -0,0 +1,111 @@
+### generated by service_webproxy.py ###
+
+acl net src all
+acl SSL_ports port 443
+acl Safe_ports port 80 # http
+acl Safe_ports port 21 # ftp
+acl Safe_ports port 443 # https
+acl Safe_ports port 873 # rsync
+acl Safe_ports port 70 # gopher
+acl Safe_ports port 210 # wais
+acl Safe_ports port 1025-65535 # unregistered ports
+acl Safe_ports port 280 # http-mgmt
+acl Safe_ports port 488 # gss-http
+acl Safe_ports port 591 # filemaker
+acl Safe_ports port 777 # multiling http
+acl CONNECT method CONNECT
+
+{% if authentication is vyos_defined %}
+{% if authentication.children is vyos_defined %}
+auth_param basic children {{ authentication.children }}
+{% endif %}
+{% if authentication.credentials_ttl is vyos_defined %}
+auth_param basic credentialsttl {{ authentication.credentials_ttl }} minute
+{% endif %}
+{% if authentication.realm is vyos_defined %}
+auth_param basic realm "{{ authentication.realm }}"
+{% endif %}
+{# LDAP based Authentication #}
+{% if authentication.method is vyos_defined %}
+{% if authentication.ldap is vyos_defined and authentication.method is vyos_defined('ldap') %}
+auth_param basic program /usr/lib/squid/basic_ldap_auth -v {{ authentication.ldap.version }} -b "{{ authentication.ldap.base_dn }}" {{ '-D "' ~ authentication.ldap.bind_dn ~ '"' if authentication.ldap.bind_dn is vyos_defined }} {{ '-w "' ~ authentication.ldap.password ~ '"' if authentication.ldap.password is vyos_defined }} {{ '-f "' ~ authentication.ldap.filter_expression ~ '"' if authentication.ldap.filter_expression is vyos_defined }} {{ '-u "' ~ authentication.ldap.username_attribute ~ '"' if authentication.ldap.username_attribute is vyos_defined }} -p {{ authentication.ldap.port }} {{ '-ZZ' if authentication.ldap.use_ssl is vyos_defined }} -R -h "{{ authentication.ldap.server }}"
+{% endif %}
+acl auth proxy_auth REQUIRED
+http_access allow auth
+{% endif %}
+{% endif %}
+
+http_access allow manager localhost
+http_access deny manager
+http_access deny !Safe_ports
+http_access deny CONNECT !SSL_ports
+http_access allow localhost
+http_access allow net
+http_access deny all
+
+{% if reply_block_mime is vyos_defined %}
+{% for mime_type in reply_block_mime %}
+acl BLOCK_MIME rep_mime_type {{ mime_type }}
+{% endfor %}
+http_reply_access deny BLOCK_MIME
+{% endif %}
+
+{% if cache_size is vyos_defined %}
+{% if cache_size | int > 0 %}
+cache_dir ufs /var/spool/squid {{ cache_size }} 16 256
+{% else %}
+# disabling disk cache
+{% endif %}
+{% endif %}
+{% if mem_cache_size is vyos_defined %}
+cache_mem {{ mem_cache_size }} MB
+{% endif %}
+{% if disable_access_log is vyos_defined %}
+access_log none
+{% else %}
+access_log /var/log/squid/access.log squid
+{% endif %}
+
+{# by default we'll disable the store log #}
+cache_store_log none
+
+{% if append_domain is vyos_defined %}
+append_domain {{ append_domain }}
+{% endif %}
+{% if maximum_object_size is vyos_defined %}
+maximum_object_size {{ maximum_object_size }} KB
+{% endif %}
+{% if minimum_object_size is vyos_defined %}
+minimum_object_size {{ minimum_object_size }} KB
+{% endif %}
+{% if reply_body_max_size is vyos_defined %}
+reply_body_max_size {{ reply_body_max_size }} KB
+{% endif %}
+{% if outgoing_address is vyos_defined %}
+tcp_outgoing_address {{ outgoing_address }}
+{% endif %}
+
+
+{% if listen_address is vyos_defined %}
+{% for address, config in listen_address.items() %}
+http_port {{ address | bracketize_ipv6 }}:{{ config.port if config.port is vyos_defined else default_port }} {{ 'intercept' if config.disable_transparent is not vyos_defined }}
+{% endfor %}
+{% endif %}
+http_port 127.0.0.1:{{ default_port }}
+
+{# NOT insert the client address in X-Forwarded-For header #}
+forwarded_for off
+
+{# SquidGuard #}
+{% if url_filtering.disable is not vyos_defined and url_filtering.squidguard is vyos_defined %}
+url_rewrite_program /usr/bin/squidGuard -c {{ squidguard_conf }}
+url_rewrite_children 8
+url_rewrite_bypass on
+{% endif %}
+
+{% if cache_peer is vyos_defined %}
+{% for peer, config in cache_peer.items() %}
+cache_peer {{ config.address }} {{ config.type }} {{ config.http_port }} {{ config.icp_port }} {{ config.options }}
+{% endfor %}
+never_direct allow all
+{% endif %}
diff --git a/data/templates/squid/squid.conf.tmpl b/data/templates/squid/squid.conf.tmpl
deleted file mode 100644
index 80826fc75..000000000
--- a/data/templates/squid/squid.conf.tmpl
+++ /dev/null
@@ -1,113 +0,0 @@
-### generated by service_webproxy.py ###
-
-acl net src all
-acl SSL_ports port 443
-acl Safe_ports port 80 # http
-acl Safe_ports port 21 # ftp
-acl Safe_ports port 443 # https
-acl Safe_ports port 873 # rsync
-acl Safe_ports port 70 # gopher
-acl Safe_ports port 210 # wais
-acl Safe_ports port 1025-65535 # unregistered ports
-acl Safe_ports port 280 # http-mgmt
-acl Safe_ports port 488 # gss-http
-acl Safe_ports port 591 # filemaker
-acl Safe_ports port 777 # multiling http
-acl CONNECT method CONNECT
-
-{% if authentication is defined and authentication is not none %}
-{% if authentication.children is defined and authentication.children is not none %}
-auth_param basic children {{ authentication.children }}
-{% endif %}
-{% if authentication.credentials_ttl is defined and authentication.credentials_ttl is not none %}
-auth_param basic credentialsttl {{ authentication.credentials_ttl }} minute
-{% endif %}
-{% if authentication.realm is defined and authentication.realm is not none %}
-auth_param basic realm "{{ authentication.realm }}"
-{% endif %}
-{# LDAP based Authentication #}
-{% if authentication.method is defined and authentication.method is not none %}
-{% if authentication.ldap is defined and authentication.ldap is not none and authentication.method == 'ldap' %}
-auth_param basic program /usr/lib/squid/basic_ldap_auth -v {{ authentication.ldap.version }} -b "{{ authentication.ldap.base_dn }}" {{ '-D "' + authentication.ldap.bind_dn + '"' if authentication.ldap.bind_dn is defined }} {{ '-w "' + authentication.ldap.password + '"' if authentication.ldap.password is defined }} {{ '-f "' + authentication.ldap.filter_expression + '"' if authentication.ldap.filter_expression is defined }} {{ '-u "' + authentication.ldap.username_attribute + '"' if authentication.ldap.username_attribute is defined }} -p {{ authentication.ldap.port }} {{ '-ZZ' if authentication.ldap.use_ssl is defined }} -R -h "{{ authentication.ldap.server }}"
-{% endif %}
-acl auth proxy_auth REQUIRED
-http_access allow auth
-{% endif %}
-{% endif %}
-
-http_access allow manager localhost
-http_access deny manager
-http_access deny !Safe_ports
-http_access deny CONNECT !SSL_ports
-http_access allow localhost
-http_access allow net
-http_access deny all
-
-{% if reply_block_mime is defined and reply_block_mime is not none %}
-{% for mime_type in reply_block_mime %}
-acl BLOCK_MIME rep_mime_type {{ mime_type }}
-{% endfor %}
-http_reply_access deny BLOCK_MIME
-{% endif %}
-
-{% if cache_size is defined and cache_size is not none %}
-{% if cache_size | int > 0 %}
-cache_dir ufs /var/spool/squid {{ cache_size }} 16 256
-{% else %}
-# disabling disk cache
-{% endif %}
-{% endif %}
-{% if mem_cache_size is defined and mem_cache_size is not none %}
-cache_mem {{ mem_cache_size }} MB
-{% endif %}
-{% if disable_access_log is defined %}
-access_log none
-{% else %}
-access_log /var/log/squid/access.log squid
-{% endif %}
-
-{# by default we'll disable the store log #}
-cache_store_log none
-
-{% if append_domain is defined and append_domain is not none %}
-append_domain {{ append_domain }}
-{% endif %}
-{% if maximum_object_size is defined and maximum_object_size is not none %}
-maximum_object_size {{ maximum_object_size }} KB
-{% endif %}
-{% if minimum_object_size is defined and minimum_object_size is not none %}
-minimum_object_size {{ minimum_object_size }} KB
-{% endif %}
-{% if reply_body_max_size is defined and reply_body_max_size is not none %}
-reply_body_max_size {{ reply_body_max_size }} KB
-{% endif %}
-{% if outgoing_address is defined and outgoing_address is not none %}
-tcp_outgoing_address {{ outgoing_address }}
-{% endif %}
-
-
-{% if listen_address is defined and listen_address is not none %}
-{% for address, config in listen_address.items() %}
-http_port {{ address }}:{{ config.port if config.port is defined else default_port }} {{ 'intercept' if config.disable_transparent is not defined }}
-{% endfor %}
-{% endif %}
-http_port 127.0.0.1:{{ default_port }}
-
-{# NOT insert the client address in X-Forwarded-For header #}
-forwarded_for off
-
-{# SquidGuard #}
-{% if url_filtering is defined and url_filtering.disable is not defined %}
-{% if url_filtering.squidguard is defined and url_filtering.squidguard is not none %}
-url_rewrite_program /usr/bin/squidGuard -c {{ squidguard_conf }}
-url_rewrite_children 8
-url_rewrite_bypass on
-{% endif %}
-{% endif %}
-
-{% if cache_peer is defined and cache_peer is not none %}
-{% for peer, config in cache_peer.items() %}
-cache_peer {{ config.address }} {{ config.type }} {{ config.http_port }} {{ config.icp_port }} {{ config.options }}
-{% endfor %}
-never_direct allow all
-{% endif %}
diff --git a/data/templates/squid/squidGuard.conf.j2 b/data/templates/squid/squidGuard.conf.j2
new file mode 100644
index 000000000..1bc4c984f
--- /dev/null
+++ b/data/templates/squid/squidGuard.conf.j2
@@ -0,0 +1,124 @@
+### generated by service_webproxy.py ###
+
+{% macro sg_rule(category, log, db_dir) %}
+{% set expressions = db_dir + '/' + category + '/expressions' %}
+dest {{ category }}-default {
+ domainlist {{ category }}/domains
+ urllist {{ category }}/urls
+{% if expressions | is_file %}
+ expressionlist {{ category }}/expressions
+{% endif %}
+{% if log is vyos_defined %}
+ log blacklist.log
+{% endif %}
+}
+{% endmacro %}
+
+{% if url_filtering is vyos_defined and url_filtering.disable is not vyos_defined %}
+{% if url_filtering.squidguard is vyos_defined %}
+{% set sg_config = url_filtering.squidguard %}
+{% set acl = namespace(value='local-ok-default') %}
+{% set acl.value = acl.value + ' !in-addr' if sg_config.allow_ipaddr_url is not defined else acl.value %}
+dbhome {{ squidguard_db_dir }}
+logdir /var/log/squid
+
+rewrite safesearch {
+ s@(.*\.google\..*/(custom|search|images|groups|news)?.*q=.*)@\1\&safe=active@i
+ s@(.*\..*/yandsearch?.*text=.*)@\1\&fyandex=1@i
+ s@(.*\.yahoo\..*/search.*p=.*)@\1\&vm=r@i
+ s@(.*\.live\..*/.*q=.*)@\1\&adlt=strict@i
+ s@(.*\.msn\..*/.*q=.*)@\1\&adlt=strict@i
+ s@(.*\.bing\..*/search.*q=.*)@\1\&adlt=strict@i
+ log rewrite.log
+}
+
+{% if sg_config.local_ok is vyos_defined %}
+{% set acl.value = acl.value + ' local-ok-default' %}
+dest local-ok-default {
+ domainlist local-ok-default/domains
+}
+{% endif %}
+{% if sg_config.local_ok_url is vyos_defined %}
+{% set acl.value = acl.value + ' local-ok-url-default' %}
+dest local-ok-url-default {
+ urllist local-ok-url-default/urls
+}
+{% endif %}
+{% if sg_config.local_block is vyos_defined %}
+{% set acl.value = acl.value + ' !local-block-default' %}
+dest local-block-default {
+ domainlist local-block-default/domains
+}
+{% endif %}
+{% if sg_config.local_block_url is vyos_defined %}
+{% set acl.value = acl.value + ' !local-block-url-default' %}
+dest local-block-url-default {
+ urllist local-block-url-default/urls
+}
+{% endif %}
+{% if sg_config.local_block_keyword is vyos_defined %}
+{% set acl.value = acl.value + ' !local-block-keyword-default' %}
+dest local-block-keyword-default {
+ expressionlist local-block-keyword-default/expressions
+}
+{% endif %}
+
+{% if sg_config.block_category is vyos_defined %}
+{% for category in sg_config.block_category %}
+{{ sg_rule(category, sg_config.log, squidguard_db_dir) }}
+{% set acl.value = acl.value + ' !' + category + '-default' %}
+{% endfor %}
+{% endif %}
+{% if sg_config.allow_category is vyos_defined %}
+{% for category in sg_config.allow_category %}
+{{ sg_rule(category, False, squidguard_db_dir) }}
+{% set acl.value = acl.value + ' ' + category + '-default' %}
+{% endfor %}
+{% endif %}
+{% if sg_config.source_group is vyos_defined %}
+{% for sgroup, sg_config in sg_config.source_group.items() %}
+{% if sg_config.address is vyos_defined %}
+src {{ sgroup }} {
+{% for address in sg_config.address %}
+ ip {{ address }}
+{% endfor %}
+}
+
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if sg_config.rule is vyos_defined %}
+{% for rule, rule_config in sg_config.rule.items() %}
+{% for b_category in rule_config.block_category %}
+dest {{ b_category }} {
+ domainlist {{ b_category }}/domains
+ urllist {{ b_category }}/urls
+}
+{% endfor %}
+
+{% endfor %}
+{% endif %}
+acl {
+{% if sg_config.rule is vyos_defined %}
+{% for rule, rule_config in sg_config.rule.items() %}
+ {{ rule_config.source_group }} {
+{% for b_category in rule_config.block_category %}
+ pass local-ok-1 !in-addr !{{ b_category }} all
+{% endfor %}
+ }
+{% endfor %}
+{% endif %}
+
+ default {
+{% if sg_config.enable_safe_search is vyos_defined %}
+ rewrite safesearch
+{% endif %}
+ pass {{ acl.value }} {{ 'none' if sg_config.default_action is vyos_defined('block') else 'allow' }}
+ redirect 302:http://{{ sg_config.redirect_url }}
+{% if sg_config.log is vyos_defined %}
+ log blacklist.log
+{% endif %}
+ }
+}
+{% endif %}
+{% endif %}
diff --git a/data/templates/squid/squidGuard.conf.tmpl b/data/templates/squid/squidGuard.conf.tmpl
deleted file mode 100644
index c59dc901e..000000000
--- a/data/templates/squid/squidGuard.conf.tmpl
+++ /dev/null
@@ -1,124 +0,0 @@
-### generated by service_webproxy.py ###
-
-{% macro sg_rule(category, log, db_dir) %}
-{% set expressions = db_dir + '/' + category + '/expressions' %}
-dest {{ category }}-default {
- domainlist {{ category }}/domains
- urllist {{ category }}/urls
-{% if expressions | is_file %}
- expressionlist {{ category }}/expressions
-{% endif %}
-{% if log is defined %}
- log blacklist.log
-{% endif %}
-}
-{% endmacro %}
-
-{% if url_filtering is defined and url_filtering.disable is not defined %}
-{% if url_filtering.squidguard is defined and url_filtering.squidguard is not none %}
-{% set sg_config = url_filtering.squidguard %}
-{% set acl = namespace(value='local-ok-default') %}
-{% set acl.value = acl.value + ' !in-addr' if sg_config.allow_ipaddr_url is not defined else acl.value %}
-dbhome {{ squidguard_db_dir }}
-logdir /var/log/squid
-
-rewrite safesearch {
- s@(.*\.google\..*/(custom|search|images|groups|news)?.*q=.*)@\1\&safe=active@i
- s@(.*\..*/yandsearch?.*text=.*)@\1\&fyandex=1@i
- s@(.*\.yahoo\..*/search.*p=.*)@\1\&vm=r@i
- s@(.*\.live\..*/.*q=.*)@\1\&adlt=strict@i
- s@(.*\.msn\..*/.*q=.*)@\1\&adlt=strict@i
- s@(.*\.bing\..*/search.*q=.*)@\1\&adlt=strict@i
- log rewrite.log
-}
-
-{% if sg_config.local_ok is defined and sg_config.local_ok is not none %}
-{% set acl.value = acl.value + ' local-ok-default' %}
-dest local-ok-default {
- domainlist local-ok-default/domains
-}
-{% endif %}
-{% if sg_config.local_ok_url is defined and sg_config.local_ok_url is not none %}
-{% set acl.value = acl.value + ' local-ok-url-default' %}
-dest local-ok-url-default {
- urllist local-ok-url-default/urls
-}
-{% endif %}
-{% if sg_config.local_block is defined and sg_config.local_block is not none %}
-{% set acl.value = acl.value + ' !local-block-default' %}
-dest local-block-default {
- domainlist local-block-default/domains
-}
-{% endif %}
-{% if sg_config.local_block_url is defined and sg_config.local_block_url is not none %}
-{% set acl.value = acl.value + ' !local-block-url-default' %}
-dest local-block-url-default {
- urllist local-block-url-default/urls
-}
-{% endif %}
-{% if sg_config.local_block_keyword is defined and sg_config.local_block_keyword is not none %}
-{% set acl.value = acl.value + ' !local-block-keyword-default' %}
-dest local-block-keyword-default {
- expressionlist local-block-keyword-default/expressions
-}
-{% endif %}
-
-{% if sg_config.block_category is defined and sg_config.block_category is not none %}
-{% for category in sg_config.block_category %}
-{{ sg_rule(category, sg_config.log, squidguard_db_dir) }}
-{% set acl.value = acl.value + ' !' + category + '-default' %}
-{% endfor %}
-{% endif %}
-{% if sg_config.allow_category is defined and sg_config.allow_category is not none %}
-{% for category in sg_config.allow_category %}
-{{ sg_rule(category, False, squidguard_db_dir) }}
-{% set acl.value = acl.value + ' ' + category + '-default' %}
-{% endfor %}
-{% endif %}
-{% if sg_config.source_group is defined and sg_config.source_group is not none %}
-{% for sgroup, sg_config in sg_config.source_group.items() %}
-{% if sg_config.address is defined and sg_config.address is not none %}
-src {{ sgroup }} {
-{% for address in sg_config.address %}
- ip {{ address }}
-{% endfor %}
-}
-
-{% endif %}
-{% endfor %}
-{% endif %}
-{% if sg_config.rule is defined and sg_config.rule is not none %}
-{% for rule, rule_config in sg_config.rule.items() %}
-{% for b_category in rule_config.block_category%}
-dest {{ b_category }} {
- domainlist {{ b_category }}/domains
- urllist {{ b_category }}/urls
-}
-{% endfor %}
-
-{% endfor %}
-{% endif %}
-acl {
-{% if sg_config.rule is defined and sg_config.rule is not none %}
-{% for rule, rule_config in sg_config.rule.items() %}
- {{ rule_config.source_group }} {
-{% for b_category in rule_config.block_category%}
- pass local-ok-1 !in-addr !{{ b_category }} all
-{% endfor %}
- }
-{% endfor %}
-{% endif %}
-
- default {
-{% if sg_config.enable_safe_search is defined %}
- rewrite safesearch
-{% endif %}
- pass {{ acl.value }} {{ 'none' if sg_config.default_action is defined and sg_config.default_action == 'block' else 'allow' }}
- redirect 302:http://{{ sg_config.redirect_url }}
-{% if sg_config.log is defined and sg_config.log is not none %}
- log blacklist.log
-{% endif %}
- }
-}
-{% endif %}
-{% endif %}
diff --git a/data/templates/ssh/override.conf.j2 b/data/templates/ssh/override.conf.j2
new file mode 100644
index 000000000..e4d6f51cb
--- /dev/null
+++ b/data/templates/ssh/override.conf.j2
@@ -0,0 +1,13 @@
+{% set vrf_command = 'ip vrf exec ' ~ vrf ~ ' ' if vrf is vyos_defined else '' %}
+[Unit]
+StartLimitIntervalSec=0
+After=vyos-router.service
+ConditionPathExists={{ config_file }}
+
+[Service]
+ExecStart=
+ExecStart={{ vrf_command }}/usr/sbin/sshd -f {{ config_file }} -D $SSHD_OPTS
+Restart=always
+RestartPreventExitStatus=
+RestartSec=10
+RuntimeDirectoryPreserve=yes
diff --git a/data/templates/ssh/override.conf.tmpl b/data/templates/ssh/override.conf.tmpl
deleted file mode 100644
index 5f8f35e89..000000000
--- a/data/templates/ssh/override.conf.tmpl
+++ /dev/null
@@ -1,13 +0,0 @@
-{% set vrf_command = 'ip vrf exec ' + vrf + ' ' if vrf is defined else '' %}
-[Unit]
-StartLimitIntervalSec=0
-After=vyos-router.service
-ConditionPathExists={{config_file}}
-
-[Service]
-ExecStart=
-ExecStart={{vrf_command}}/usr/sbin/sshd -f {{config_file}} -D $SSHD_OPTS
-Restart=always
-RestartPreventExitStatus=
-RestartSec=10
-RuntimeDirectoryPreserve=yes
diff --git a/data/templates/ssh/sshd_config.tmpl b/data/templates/ssh/sshd_config.j2
index 2f2b78a66..e7dbca581 100644
--- a/data/templates/ssh/sshd_config.tmpl
+++ b/data/templates/ssh/sshd_config.j2
@@ -29,6 +29,7 @@ UsePAM yes
PermitRootLogin no
PidFile /run/sshd/sshd.pid
AddressFamily any
+DebianBanner no
#
# User configurable section
@@ -36,7 +37,7 @@ AddressFamily any
# Look up remote host name and check that the resolved host name for the remote IP
# address maps back to the very same IP address.
-UseDNS {{ "no" if disable_host_validation is defined else "yes" }}
+UseDNS {{ "no" if disable_host_validation is vyos_defined else "yes" }}
# Specifies the port number that sshd(8) listens on
{% for value in port %}
@@ -47,61 +48,50 @@ Port {{ value }}
LogLevel {{ loglevel | upper }}
# Specifies whether password authentication is allowed
-PasswordAuthentication {{ "no" if disable_password_authentication is defined else "yes" }}
+PasswordAuthentication {{ "no" if disable_password_authentication is vyos_defined else "yes" }}
-{% if listen_address is defined and listen_address is not none %}
+{% if listen_address is vyos_defined %}
# Specifies the local addresses sshd should listen on
-{% for address in listen_address %}
+{% for address in listen_address %}
ListenAddress {{ address }}
-{% endfor %}
+{% endfor %}
{% endif %}
-{% if ciphers is defined and ciphers is not none %}
+{% if ciphers is vyos_defined %}
# Specifies the ciphers allowed for protocol version 2
-{% set value = ciphers if ciphers is string else ciphers | join(',') %}
-Ciphers {{ value }}
+Ciphers {{ ciphers | join(',') }}
{% endif %}
-{% if mac is defined and mac is not none %}
+{% if mac is vyos_defined %}
# Specifies the available MAC (message authentication code) algorithms
-{% set value = mac if mac is string else mac | join(',') %}
-MACs {{ value }}
+MACs {{ mac | join(',') }}
{% endif %}
-{% if key_exchange is defined and key_exchange is not none %}
+{% if key_exchange is vyos_defined %}
# Specifies the available Key Exchange algorithms
-{% set value = key_exchange if key_exchange is string else key_exchange | join(',') %}
-KexAlgorithms {{ value }}
+KexAlgorithms {{ key_exchange | join(',') }}
{% endif %}
-{% if access_control is defined and access_control is not none %}
-{% if access_control.allow is defined and access_control.allow is not none %}
-{% if access_control.allow.user is defined %}
+{% if access_control is vyos_defined %}
+{% if access_control.allow.user is vyos_defined %}
# If specified, login is allowed only for user names that match
-{% set value = access_control.allow.user if access_control.allow.user is string else access_control.allow.user | join(' ') %}
-AllowUsers {{ value }}
+AllowUsers {{ access_control.allow.user | join(' ') }}
{% endif %}
-{% if access_control.allow.group is defined %}
+{% if access_control.allow.group is vyos_defined %}
# If specified, login is allowed only for users whose primary group or supplementary group list matches
-{% set value = access_control.allow.group if access_control.allow.group is string else access_control.allow.group | join(' ') %}
-AllowGroups {{ value }}
+AllowGroups {{ access_control.allow.group | join(' ') }}
{% endif %}
-{% endif %}
-{% if access_control.deny is defined and access_control.deny is not none %}
-{% if access_control.deny.user is defined %}
+{% if access_control.deny.user is vyos_defined %}
# Login is disallowed for user names that match
-{% set value = access_control.deny.user if access_control.deny.user is string else access_control.deny.user | join(' ') %}
-DenyUsers {{ value }}
+DenyUsers {{ access_control.deny.user | join(' ') }}
{% endif %}
-{% if access_control.deny.group is defined %}
+{% if access_control.deny.group is vyos_defined %}
# Login is disallowed for users whose primary group or supplementary group list matches
-{% set value = access_control.deny.group if access_control.deny.group is string else access_control.deny.group | join(' ') %}
-DenyGroups {{ value }}
+DenyGroups {{ access_control.deny.group | join(' ') }}
{% endif %}
-{% endif %}
{% endif %}
-{% if client_keepalive_interval is defined and client_keepalive_interval is not none %}
+{% if client_keepalive_interval is vyos_defined %}
# Sets a timeout interval in seconds after which if no data has been received from the client,
# sshd(8) will send a message through the encrypted channel to request a response from the client
ClientAliveInterval {{ client_keepalive_interval }}
diff --git a/data/templates/ssh/sshguard_config.j2 b/data/templates/ssh/sshguard_config.j2
new file mode 100644
index 000000000..58c6ad48d
--- /dev/null
+++ b/data/templates/ssh/sshguard_config.j2
@@ -0,0 +1,27 @@
+### Autogenerated by ssh.py ###
+
+{% if dynamic_protection is vyos_defined %}
+# Full path to backend executable (required, no default)
+BACKEND="/usr/libexec/sshguard/sshg-fw-nft-sets"
+
+# Shell command that provides logs on standard output. (optional, no default)
+# Example 1: ssh and sendmail from systemd journal:
+LOGREADER="LANG=C journalctl -afb -p info -n1 -t sshd -o cat"
+
+#### OPTIONS ####
+# Block attackers when their cumulative attack score exceeds THRESHOLD.
+# Most attacks have a score of 10. (optional, default 30)
+THRESHOLD={{ dynamic_protection.threshold }}
+
+# Block attackers for initially BLOCK_TIME seconds after exceeding THRESHOLD.
+# Subsequent blocks increase by a factor of 1.5. (optional, default 120)
+BLOCK_TIME={{ dynamic_protection.block_time }}
+
+# Remember potential attackers for up to DETECTION_TIME seconds before
+# resetting their score. (optional, default 1800)
+DETECTION_TIME={{ dynamic_protection.detect_time }}
+
+# IP addresses listed in the WHITELIST_FILE are considered to be
+# friendlies and will never be blocked.
+WHITELIST_FILE=/etc/sshguard/whitelist
+{% endif %}
diff --git a/data/templates/ssh/sshguard_whitelist.j2 b/data/templates/ssh/sshguard_whitelist.j2
new file mode 100644
index 000000000..47a950a2b
--- /dev/null
+++ b/data/templates/ssh/sshguard_whitelist.j2
@@ -0,0 +1,7 @@
+### Autogenerated by ssh.py ###
+
+{% if dynamic_protection.allow_from is vyos_defined %}
+{% for address in dynamic_protection.allow_from %}
+{{ address }}
+{% endfor %}
+{% endif %}
diff --git a/data/templates/syslog/logrotate.j2 b/data/templates/syslog/logrotate.j2
new file mode 100644
index 000000000..c1b951e8b
--- /dev/null
+++ b/data/templates/syslog/logrotate.j2
@@ -0,0 +1,11 @@
+{{ config_render['log-file'] }} {
+ missingok
+ notifempty
+ create
+ rotate {{ config_render['max-files'] }}
+ size={{ config_render['max-size'] // 1024 }}k
+ postrotate
+ invoke-rc.d rsyslog rotate > /dev/null
+ endscript
+}
+
diff --git a/data/templates/syslog/logrotate.tmpl b/data/templates/syslog/logrotate.tmpl
deleted file mode 100644
index f758265e4..000000000
--- a/data/templates/syslog/logrotate.tmpl
+++ /dev/null
@@ -1,12 +0,0 @@
-{% for file in files %}
-{{files[file]['log-file']}} {
- missingok
- notifempty
- create
- rotate {{files[file]['max-files']}}
- size={{files[file]['max-size']//1024}}k
- postrotate
- invoke-rc.d rsyslog rotate > /dev/null
- endscript
-}
-{% endfor %}
diff --git a/data/templates/syslog/rsyslog.conf.j2 b/data/templates/syslog/rsyslog.conf.j2
new file mode 100644
index 000000000..4445d568b
--- /dev/null
+++ b/data/templates/syslog/rsyslog.conf.j2
@@ -0,0 +1,54 @@
+## generated by syslog.py ##
+## file based logging
+{% if files['global']['marker'] %}
+$ModLoad immark
+{% if files['global']['marker-interval'] %}
+$MarkMessagePeriod {{ files['global']['marker-interval'] }}
+{% endif %}
+{% endif %}
+{% if files['global']['preserver_fqdn'] %}
+$PreserveFQDN on
+{% endif %}
+{% for file, file_options in files.items() %}
+$outchannel {{ file }},{{ file_options['log-file'] }},{{ file_options['max-size'] }},{{ file_options['action-on-max-size'] }}
+{{ file_options['selectors'] }} :omfile:${{ file }}
+{% endfor %}
+{% if console is defined and console is not none %}
+## console logging
+{% for con, con_options in console.items() %}
+{{ con_options['selectors'] }} /dev/console
+{% endfor %}
+{% endif %}
+{% if hosts is defined and hosts is not none %}
+## remote logging
+{% for host, host_options in hosts.items() %}
+{% if host_options.proto == 'tcp' %}
+{% if host_options.port is defined %}
+{% if host_options.oct_count is defined %}
+{{ host_options.selectors }} @@(o){{ host | bracketize_ipv6 }}:{{ host_options.port }};RSYSLOG_SyslogProtocol23Format
+{% else %}
+{{ host_options.selectors }} @@{{ host | bracketize_ipv6 }}:{{ host_options.port }}
+{% endif %}
+{% else %}
+{{ host_options.selectors }} @@{{ host | bracketize_ipv6 }}
+{% endif %}
+{% elif host_options.proto == 'udp' %}
+{% if host_options.port is defined %}
+{{ host_options.selectors }} @{{ host | bracketize_ipv6 }}:{{ host_options.port }}{{ ';RSYSLOG_SyslogProtocol23Format' if host_options.oct_count is sameas true }}
+{% else %}
+{{ host_options.selectors }} @{{ host | bracketize_ipv6 }}
+{% endif %}
+{% else %}
+{% if host_options['port'] %}
+{{ host_options.selectors }} @{{ host | bracketize_ipv6 }}:{{ host_options.port }}
+{% else %}
+{{ host_options.selectors }} @{{ host | bracketize_ipv6 }}
+{% endif %}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if user is defined and user is not none %}
+{% for username, user_options in user.items() %}
+{{ user_options.selectors }} :omusrmsg:{{ username }}
+{% endfor %}
+{% endif %}
diff --git a/data/templates/syslog/rsyslog.conf.tmpl b/data/templates/syslog/rsyslog.conf.tmpl
deleted file mode 100644
index e25ef48d4..000000000
--- a/data/templates/syslog/rsyslog.conf.tmpl
+++ /dev/null
@@ -1,48 +0,0 @@
-## generated by syslog.py ##
-## file based logging
-{% if files['global']['marker'] %}
-$ModLoad immark
-{% if files['global']['marker-interval'] %}
-$MarkMessagePeriod {{files['global']['marker-interval']}}
-{% endif %}
-{% endif %}
-{% if files['global']['preserver_fqdn'] %}
-$PreserveFQDN on
-{% endif %}
-{% for file, file_options in files.items() %}
-$outchannel {{ file }},{{ file_options['log-file'] }},{{ file_options['max-size'] }},{{ file_options['action-on-max-size'] }}
-{{ file_options['selectors'] }} :omfile:${{ file }}
-{% endfor %}
-{% if console is defined and console is not none %}
-## console logging
-{% for con, con_options in console.items() %}
-{{ con_options['selectors'] }} /dev/console
-{% endfor %}
-{% endif %}
-{% if hosts is defined and hosts is not none %}
-## remote logging
-{% for host, host_options in hosts.items() %}
-{% if host_options.proto == 'tcp' %}
-{% if host_options.port is defined %}
-{% if host_options.oct_count is defined %}
-{{ host_options.selectors }} @@(o){{ host }}:{{ host_options.port }};RSYSLOG_SyslogProtocol23Format
-{% else %}
-{{ host_options.selectors }} @@{{ host }}:{{ host_options.port }}
-{% endif %}
-{% else %}
-{{ host_options.selectors }} @@{{ host }}
-{% endif %}
-{% else %}
-{% if host_options['port'] %}
-{{ host_options.selectors }} @{{ host | bracketize_ipv6 }}:{{ host_options.port }}
-{% else %}
-{{ host_options.selectors }} @{{ host | bracketize_ipv6 }}
-{% endif %}
-{% endif %}
-{% endfor %}
-{% endif %}
-{% if user is defined and user is not none %}
-{% for username, user_options in user.items() %}
-{{ user_options.selectors }} :omusrmsg:{{ username }}
-{% endfor %}
-{% endif %}
diff --git a/data/templates/system/curlrc.j2 b/data/templates/system/curlrc.j2
new file mode 100644
index 000000000..be4efe8ba
--- /dev/null
+++ b/data/templates/system/curlrc.j2
@@ -0,0 +1,6 @@
+{% if http_client.source_interface is vyos_defined %}
+--interface "{{ http_client.source_interface }}"
+{% endif %}
+{% if http_client.source_address is vyos_defined %}
+--interface "{{ http_client.source_address }}"
+{% endif %}
diff --git a/data/templates/system/curlrc.tmpl b/data/templates/system/curlrc.tmpl
deleted file mode 100644
index 3e5ce801c..000000000
--- a/data/templates/system/curlrc.tmpl
+++ /dev/null
@@ -1,8 +0,0 @@
-{% if http_client is defined %}
-{% if http_client.source_interface is defined %}
---interface "{{ http_client.source_interface }}"
-{% endif %}
-{% if http_client.source_address is defined %}
---interface "{{ http_client.source_address }}"
-{% endif %}
-{% endif %}
diff --git a/data/templates/system/proxy.j2 b/data/templates/system/proxy.j2
new file mode 100644
index 000000000..215c4c5c2
--- /dev/null
+++ b/data/templates/system/proxy.j2
@@ -0,0 +1,7 @@
+# generated by system-proxy.py
+{% if url is vyos_defined and port is vyos_defined %}
+{# remove http:// prefix so we can inject a username/password if present #}
+export http_proxy=http://{{ username ~ ':' ~ password ~ '@' if username is vyos_defined and password is vyos_defined }}{{ url | replace('http://', '') }}:{{ port }}
+export https_proxy=$http_proxy
+export ftp_proxy=$http_proxy
+{% endif %}
diff --git a/data/templates/system/ssh_config.j2 b/data/templates/system/ssh_config.j2
new file mode 100644
index 000000000..1449f95b1
--- /dev/null
+++ b/data/templates/system/ssh_config.j2
@@ -0,0 +1,3 @@
+{% if ssh_client.source_address is vyos_defined %}
+BindAddress {{ ssh_client.source_address }}
+{% endif %}
diff --git a/data/templates/system/ssh_config.tmpl b/data/templates/system/ssh_config.tmpl
deleted file mode 100644
index abc03f069..000000000
--- a/data/templates/system/ssh_config.tmpl
+++ /dev/null
@@ -1,3 +0,0 @@
-{% if ssh_client is defined and ssh_client.source_address is defined and ssh_client.source_address is not none %}
-BindAddress {{ ssh_client.source_address }}
-{% endif %}
diff --git a/data/templates/system/sysctl.conf.j2 b/data/templates/system/sysctl.conf.j2
new file mode 100644
index 000000000..59a19e157
--- /dev/null
+++ b/data/templates/system/sysctl.conf.j2
@@ -0,0 +1,7 @@
+# autogenerated by system_sysctl.py
+
+{% if parameter is vyos_defined %}
+{% for k, v in parameter.items() %}
+{{ k }} = {{ v.value }}
+{% endfor %}
+{% endif %}
diff --git a/data/templates/system/sysctl.conf.tmpl b/data/templates/system/sysctl.conf.tmpl
deleted file mode 100644
index 72af82ee5..000000000
--- a/data/templates/system/sysctl.conf.tmpl
+++ /dev/null
@@ -1,7 +0,0 @@
-# autogenerated by system_sysctl.py
-
-{% if parameter is defined and parameter is not none %}
-{% for k, v in parameter.items() %}
-{{ k }} = {{ v.value }}
-{% endfor %}
-{% endif %}
diff --git a/data/templates/tftp-server/default.j2 b/data/templates/tftp-server/default.j2
new file mode 100644
index 000000000..b2676e0aa
--- /dev/null
+++ b/data/templates/tftp-server/default.j2
@@ -0,0 +1,8 @@
+{# j2lint: disable=jinja-variable-format #}
+### Autogenerated by tftp_server.py ###
+DAEMON_ARGS="--listen --user tftp --address {{ listen_address }} {{ "--create --umask 000" if allow_upload is vyos_defined }} --secure {{ directory }}"
+{% if vrf is vyos_defined %}
+VRF_ARGS="ip vrf exec {{ vrf }}"
+{% else %}
+VRF_ARGS=""
+{% endif %}
diff --git a/data/templates/tftp-server/default.tmpl b/data/templates/tftp-server/default.tmpl
deleted file mode 100644
index 6b2d6a903..000000000
--- a/data/templates/tftp-server/default.tmpl
+++ /dev/null
@@ -1,2 +0,0 @@
-### Autogenerated by tftp_server.py ###
-DAEMON_ARGS="--listen --user tftp --address {{ listen_address }} {{ "--create --umask 000" if allow_upload is defined }} --secure {{ directory }}"
diff --git a/data/templates/vrf/vrf.conf.j2 b/data/templates/vrf/vrf.conf.j2
new file mode 100644
index 000000000..d31d23574
--- /dev/null
+++ b/data/templates/vrf/vrf.conf.j2
@@ -0,0 +1,9 @@
+### Autogenerated by vrf.py ###
+#
+# Routing table ID to name mapping reference
+# id vrf name comment
+{% if name is vyos_defined %}
+{% for vrf, vrf_config in name.items() %}
+{{ "%-10s" | format(vrf_config.table) }} {{ "%-16s" | format(vrf) }} {{ '# ' ~ vrf_config.description if vrf_config.description is vyos_defined }}
+{% endfor %}
+{% endif %}
diff --git a/data/templates/vrf/vrf.conf.tmpl b/data/templates/vrf/vrf.conf.tmpl
deleted file mode 100644
index 29c0ba08d..000000000
--- a/data/templates/vrf/vrf.conf.tmpl
+++ /dev/null
@@ -1,9 +0,0 @@
-### Autogenerated by vrf.py ###
-#
-# Routing table ID to name mapping reference
-# id vrf name comment
-{% if name is defined and name is not none %}
-{% for vrf, vrf_config in name.items() %}
-{{ "%-10s" | format(vrf_config.table) }} {{ "%-16s" | format(vrf) }} {{ '# ' + vrf_config.description if vrf_config.description is defined and vrf_config.description is not none }}
-{% endfor %}
-{% endif %}
diff --git a/data/templates/vrrp/keepalived.conf.tmpl b/data/templates/vrrp/keepalived.conf.tmpl
deleted file mode 100644
index b4824a994..000000000
--- a/data/templates/vrrp/keepalived.conf.tmpl
+++ /dev/null
@@ -1,106 +0,0 @@
-# Autogenerated by VyOS
-# Do not edit this file, all your changes will be lost
-# on next commit or reboot
-
-global_defs {
- dynamic_interfaces
- script_user root
- # Don't run scripts configured to be run as root if any part of the path
- # is writable by a non-root user.
- enable_script_security
- notify_fifo /run/keepalived/keepalived_notify_fifo
- notify_fifo_script /usr/libexec/vyos/system/keepalived-fifo.py
-}
-
-{% if group is defined and group is not none %}
-{% for name, group_config in group.items() if group_config.disable is not defined %}
-{% if group_config.health_check is defined and group_config.health_check.script is defined and group_config.health_check.script is not none %}
-vrrp_script healthcheck_{{ name }} {
- script "{{ group_config.health_check.script }}"
- interval {{ group_config.health_check.interval }}
- fall {{ group_config.health_check.failure_count }}
- rise 1
-}
-{% endif %}
-vrrp_instance {{ name }} {
-{% if group_config.description is defined and group_config.description is not none %}
- # {{ group_config.description }}
-{% endif %}
- state BACKUP
- interface {{ group_config.interface }}
- virtual_router_id {{ group_config.vrid }}
- priority {{ group_config.priority }}
- advert_int {{ group_config.advertise_interval }}
-{% if group_config.no_preempt is not defined and group_config.preempt_delay is defined and group_config.preempt_delay is not none %}
- preempt_delay {{ group_config.preempt_delay }}
-{% elif group_config.no_preempt is defined %}
- nopreempt
-{% endif %}
-{% if group_config.peer_address is defined and group_config.peer_address is not none %}
- unicast_peer { {{ group_config.peer_address }} }
-{% endif %}
-{% if group_config.hello_source_address is defined and group_config.hello_source_address is not none %}
-{% if group_config.peer_address is defined and group_config.peer_address is not none %}
- unicast_src_ip {{ group_config.hello_source_address }}
-{% else %}
- mcast_src_ip {{ group_config.hello_source_address }}
-{% endif %}
-{% endif %}
-{% if group_config.rfc3768_compatibility is defined and group_config.peer_address is defined %}
- use_vmac {{ group_config.interface }}v{{ group_config.vrid }}
- vmac_xmit_base
-{% elif group_config.rfc3768_compatibility is defined %}
- use_vmac {{ group_config.interface }}v{{ group_config.vrid }}
-{% endif %}
-{% if group_config.authentication is defined and group_config.authentication is not none %}
- authentication {
- auth_pass "{{ group_config.authentication.password }}"
-{% if group_config.authentication.type == 'plaintext-password' %}
- auth_type PASS
-{% else %}
- auth_type {{ group_config.authentication.type | upper }}
-{% endif %}
- }
-{% endif %}
-{% if group_config.address is defined and group_config.address is not none %}
- virtual_ipaddress {
-{% for addr in group_config.address %}
- {{ addr }}
-{% endfor %}
- }
-{% endif %}
-{% if group_config.excluded_address is defined and group_config.excluded_address is not none %}
- virtual_ipaddress_excluded {
-{% for addr in group_config.excluded_address %}
- {{ addr }}
-{% endfor %}
- }
-{% endif %}
-{% if group_config.health_check is defined and group_config.health_check.script is defined and group_config.health_check.script is not none %}
- track_script {
- healthcheck_{{ name }}
- }
-{% endif %}
-}
-{% endfor %}
-{% endif %}
-
-{% if sync_group is defined and sync_group is not none %}
-{% for name, group_config in sync_group.items() if group_config.disable is not defined %}
-vrrp_sync_group {{ name }} {
- group {
-{% if group_config.member is defined and group_config.member is not none %}
-{% for member in group_config.member %}
- {{ member }}
-{% endfor %}
-{% endif %}
- }
-{% if conntrack_sync_group is defined and conntrack_sync_group == name %}
-{% set vyos_helper = "/usr/libexec/vyos/vyos-vrrp-conntracksync.sh" %}
- notify_master "{{ vyos_helper }} master {{ name }}"
- notify_backup "{{ vyos_helper }} backup {{ name }}"
- notify_fault "{{ vyos_helper }} fault {{ name }}"
-{% endif %}
-}
-{% endfor %}
-{% endif %}
diff --git a/data/templates/vyos-hostsd/hosts.tmpl b/data/templates/vyos-hostsd/hosts.j2
index 03662d562..5cad983b4 100644
--- a/data/templates/vyos-hostsd/hosts.tmpl
+++ b/data/templates/vyos-hostsd/hosts.j2
@@ -1,3 +1,4 @@
+{# j2lint: disable=single-statement-per-line #}
### Autogenerated by VyOS ###
### Do not edit, your changes will get overwritten ###
@@ -12,14 +13,14 @@ ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
-{% if hosts is defined and hosts is not none %}
+{% if hosts is vyos_defined %}
# From 'system static-host-mapping' and DHCP server
-{% for tag, taghosts in hosts.items() %}
+{% for tag, taghosts in hosts.items() %}
# {{ tag }}
-{% for host, hostprops in taghosts.items() if hostprops.address is defined %}
-{% for addr in hostprops.address %}
-{{ "%-15s" | format(addr) }} {{ host }} {{ hostprops.aliases|join(' ') if hostprops.aliases is defined }}
-{% endfor %}
+{% for host, hostprops in taghosts.items() if hostprops.address is vyos_defined %}
+{% for addr in hostprops.address %}
+{{ "%-15s" | format(addr) }} {{ host }} {{ hostprops.aliases | join(' ') if hostprops.aliases is vyos_defined }}
+{% endfor %}
+{% endfor %}
{% endfor %}
-{% endfor %}
{% endif %}
diff --git a/data/templates/vyos-hostsd/resolv.conf.tmpl b/data/templates/vyos-hostsd/resolv.conf.j2
index 58a5f9312..5f651f1a1 100644
--- a/data/templates/vyos-hostsd/resolv.conf.tmpl
+++ b/data/templates/vyos-hostsd/resolv.conf.j2
@@ -5,12 +5,12 @@
{# the order of tags, then by the order of nameservers within that tag #}
{% for tag in name_server_tags_system %}
-{% if tag in name_servers %}
+{% if tag in name_servers %}
# {{ tag }}
-{% for ns in name_servers[tag] %}
+{% for ns in name_servers[tag] %}
nameserver {{ ns }}
-{% endfor %}
-{% endif %}
+{% endfor %}
+{% endif %}
{% endfor %}
{% if domain_name %}
@@ -18,8 +18,8 @@ domain {{ domain_name }}
{% endif %}
{% for tag in name_server_tags_system %}
-{% if tag in search_domains %}
+{% if tag in search_domains %}
# {{ tag }}
-search {{ search_domains[tag]|join(' ') }}
-{% endif %}
+search {{ search_domains[tag] | join(' ') }}
+{% endif %}
{% endfor %}
diff --git a/data/templates/wifi/cfg80211.conf.tmpl b/data/templates/wifi/cfg80211.conf.tmpl
deleted file mode 100644
index 91df57aab..000000000
--- a/data/templates/wifi/cfg80211.conf.tmpl
+++ /dev/null
@@ -1 +0,0 @@
-{{ 'options cfg80211 ieee80211_regdom=' + regdom if regdom is defined }}
diff --git a/data/templates/wifi/crda.tmpl b/data/templates/wifi/crda.tmpl
deleted file mode 100644
index 6cd125e37..000000000
--- a/data/templates/wifi/crda.tmpl
+++ /dev/null
@@ -1 +0,0 @@
-{{ 'REGDOMAIN=' + regdom if regdom is defined }}
diff --git a/data/templates/wifi/hostapd.conf.tmpl b/data/templates/wifi/hostapd.conf.j2
index 433e1d36f..f2312d2d4 100644
--- a/data/templates/wifi/hostapd.conf.tmpl
+++ b/data/templates/wifi/hostapd.conf.j2
@@ -1,5 +1,6 @@
+{# j2lint: disable=operator-enclosed-by-spaces #}
### Autogenerated by interfaces-wireless.py ###
-{% if description %}
+{% if description is vyos_defined %}
# Description: {{ description }}
# User-friendly description of device; up to 32 octets encoded in UTF-8
device_name={{ description | truncate(32, True) }}
@@ -11,7 +12,7 @@ device_name={{ description | truncate(32, True) }}
# command line parameter.
interface={{ ifname }}
-{% if is_bridge_member is defined %}
+{% if is_bridge_member is vyos_defined %}
# In case of atheros and nl80211 driver interfaces, an additional
# configuration parameter, bridge, may be used to notify hostapd if the
# interface is included in a bridge. This parameter is not used with Host AP
@@ -24,9 +25,9 @@ interface={{ ifname }}
# has been started to change the interface mode). If needed, the bridge
# interface is also created.
{# as there can only be one bridge interface it is save to loop #}
-{% for bridge in is_bridge_member %}
+{% for bridge in is_bridge_member %}
bridge={{ bridge }}
-{% endfor %}
+{% endfor %}
{% endif %}
# Driver interface type (hostap/wired/none/nl80211/bsd);
@@ -72,7 +73,7 @@ ssid={{ ssid }}
channel={{ channel }}
{% endif %}
-{% if mode is defined and mode is not none %}
+{% if mode is vyos_defined %}
# Operation mode (a = IEEE 802.11a (5 GHz), b = IEEE 802.11b (2.4 GHz),
# g = IEEE 802.11g (2.4 GHz), ad = IEEE 802.11ad (60 GHz); a/g options are used
# with IEEE 802.11n (HT), too, to specify band). For IEEE 802.11ac (VHT), this
@@ -81,15 +82,15 @@ channel={{ channel }}
# special value "any" can be used to indicate that any support band can be used.
# This special case is currently supported only with drivers with which
# offloaded ACS is used.
-{% if mode == 'n' %}
+{% if mode is vyos_defined('n') %}
hw_mode=g
-{% elif mode == 'ac' %}
+{% elif mode is vyos_defined('ac') %}
hw_mode=a
ieee80211h=1
ieee80211ac=1
-{% else %}
+{% else %}
hw_mode={{ mode }}
-{% endif %}
+{% endif %}
{% endif %}
# ieee80211w: Whether management frame protection (MFP) is enabled
@@ -104,7 +105,7 @@ ieee80211w=1
ieee80211w=2
{% endif %}
-{% if capabilities is defined and capabilities.ht is defined %}
+{% if capabilities is vyos_defined %}
# ht_capab: HT capabilities (list of flags)
# LDPC coding capability: [LDPC] = supported
# Supported channel width set: [HT40-] = both 20 MHz and 40 MHz with secondary
@@ -138,70 +139,70 @@ ieee80211w=2
# DSSS/CCK Mode in 40 MHz: [DSSS_CCK-40] = allowed (not allowed if not set)
# 40 MHz intolerant [40-INTOLERANT] (not advertised if not set)
# L-SIG TXOP protection support: [LSIG-TXOP-PROT] (disabled if not set)
-{% set output = namespace(value='') %}
-
-{% if capabilities.ht.fourtymhz_incapable is defined %}
-{% set output.value = output.value + '[40-INTOLERANT]' %}
-{% endif %}
-{% if capabilities.ht.delayed_block_ack is defined %}
-{% set output.value = output.value + '[DELAYED-BA]' %}
-{% endif %}
-{% if capabilities.ht.dsss_cck_40 is defined %}
-{% set output.value = output.value + '[DSSS_CCK-40]' %}
-{% endif %}
-{% if capabilities.ht.greenfield is defined %}
-{% set output.value = output.value + '[GF]' %}
-{% endif %}
-{% if capabilities.ht.ldpc is defined %}
-{% set output.value = output.value + '[LDPC]' %}
-{% endif %}
-{% if capabilities.ht.lsig_protection is defined %}
-{% set output.value = output.value + '[LSIG-TXOP-PROT]' %}
-{% endif %}
-{% if capabilities.ht.stbc is defined and capabilities.ht.stbc.tx is defined %}
-{% set output.value = output.value + '[TX-STBC]' %}
-{% endif %}
-{% if capabilities.ht.stbc is defined and capabilities.ht.stbc.rx is defined %}
-{% set output.value = output.value + '[RX-STBC-' + capabilities.ht.stbc.rx | upper + ']' %}
-{% endif %}
-{% if capabilities.ht.max_amsdu is defined %}
-{% set output.value = output.value + '[MAX-AMSDU-' + capabilities.ht.max_amsdu + ']' %}
-{% endif %}
-{% if capabilities.ht.smps is defined %}
-{% set output.value = output.value + '[SMPS-' + capabilities.ht.smps | upper + ']' %}
-{% endif %}
-
-{% if capabilities.ht.channel_set_width is defined %}
-{% for csw in capabilities.ht.channel_set_width %}
-{% set output.value = output.value + '[' + csw | upper + ']' %}
-{% endfor %}
-{% endif %}
+{% set output = namespace(value='') %}
-{% if capabilities.ht.short_gi is defined %}
-{% for short_gi in capabilities.ht.short_gi %}
-{% set output.value = output.value + '[SHORT-GI-' + short_gi | upper + ']' %}
-{% endfor %}
-{% endif %}
+{% if capabilities.ht.fourtymhz_incapable is vyos_defined %}
+{% set output.value = output.value ~ '[40-INTOLERANT]' %}
+{% endif %}
+{% if capabilities.ht.delayed_block_ack is vyos_defined %}
+{% set output.value = output.value ~ '[DELAYED-BA]' %}
+{% endif %}
+{% if capabilities.ht.dsss_cck_40 is vyos_defined %}
+{% set output.value = output.value ~ '[DSSS_CCK-40]' %}
+{% endif %}
+{% if capabilities.ht.greenfield is vyos_defined %}
+{% set output.value = output.value ~ '[GF]' %}
+{% endif %}
+{% if capabilities.ht.ldpc is vyos_defined %}
+{% set output.value = output.value ~ '[LDPC]' %}
+{% endif %}
+{% if capabilities.ht.lsig_protection is vyos_defined %}
+{% set output.value = output.value ~ '[LSIG-TXOP-PROT]' %}
+{% endif %}
+{% if capabilities.ht.stbc.tx is vyos_defined %}
+{% set output.value = output.value ~ '[TX-STBC]' %}
+{% endif %}
+{% if capabilities.ht.stbc.rx is vyos_defined %}
+{% set output.value = output.value ~ '[RX-STBC-' ~ capabilities.ht.stbc.rx | upper ~ ']' %}
+{% endif %}
+{% if capabilities.ht.max_amsdu is vyos_defined %}
+{% set output.value = output.value ~ '[MAX-AMSDU-' ~ capabilities.ht.max_amsdu ~ ']' %}
+{% endif %}
+{% if capabilities.ht.smps is vyos_defined %}
+{% set output.value = output.value ~ '[SMPS-' ~ capabilities.ht.smps | upper ~ ']' %}
+{% endif %}
+
+{% if capabilities.ht.channel_set_width is vyos_defined %}
+{% for csw in capabilities.ht.channel_set_width %}
+{% set output.value = output.value ~ '[' ~ csw | upper ~ ']' %}
+{% endfor %}
+{% endif %}
+
+{% if capabilities.ht.short_gi is vyos_defined %}
+{% for short_gi in capabilities.ht.short_gi %}
+{% set output.value = output.value ~ '[SHORT-GI-' ~ short_gi | upper ~ ']' %}
+{% endfor %}
+{% endif %}
ht_capab={{ output.value }}
-{% if capabilities.ht.auto_powersave is defined %}
+{% if capabilities.ht.auto_powersave is vyos_defined %}
# WMM-PS Unscheduled Automatic Power Save Delivery [U-APSD]
# Enable this flag if U-APSD supported outside hostapd (eg., Firmware/driver)
uapsd_advertisement_enabled=1
-{% endif %}
+{% endif %}
{% endif %}
# Required for full HT and VHT functionality
wme_enabled=1
-{% if capabilities is defined and capabilities.require_ht is defined %}
+{% if capabilities.require_ht is vyos_defined %}
# Require stations to support HT PHY (reject association if they do not)
require_ht=1
{% endif %}
-{% if capabilities is defined and capabilities.vht is defined %}
+{% if capabilities.vht is vyos_defined %}
# vht_capab: VHT capabilities (list of flags)
#
# vht_max_mpdu_len: [MAX-MPDU-7991] [MAX-MPDU-11454]
@@ -297,7 +298,7 @@ require_ht=1
# Indicates the maximum length of A-MPDU pre-EOF padding that the STA can recv
# This field is an integer in the range of 0 to 7.
# The length defined by this field is equal to
-# 2 pow(13 + Maximum A-MPDU Length Exponent) -1 octets
+# 2 pow(13 ~ Maximum A-MPDU Length Exponent) -1 octets
#
# VHT Link Adaptation Capable: [VHT-LINK-ADAPT2] [VHT-LINK-ADAPT3]
# Indicates whether or not the STA supports link adaptation using VHT variant
@@ -320,87 +321,86 @@ require_ht=1
# 0 = Tx antenna pattern might change during the lifetime of an association
# 1 = Tx antenna pattern does not change during the lifetime of an
-{% if capabilities.vht.center_channel_freq is defined and capabilities.vht.center_channel_freq.freq_1 is defined %}
-# center freq = 5 GHz + (5 * index)
+{% if capabilities.vht.center_channel_freq.freq_1 is vyos_defined %}
+# center freq = 5 GHz ~ (5 * index)
# So index 42 gives center freq 5.210 GHz
# which is channel 42 in 5G band
vht_oper_centr_freq_seg0_idx={{ capabilities.vht.center_channel_freq.freq_1 }}
-{% endif %}
+{% endif %}
-{% if capabilities.vht.center_channel_freq is defined and capabilities.vht.center_channel_freq.freq_2 is defined %}
-# center freq = 5 GHz + (5 * index)
+{% if capabilities.vht.center_channel_freq.freq_2 is vyos_defined %}
+# center freq = 5 GHz ~ (5 * index)
# So index 159 gives center freq 5.795 GHz
# which is channel 159 in 5G band
vht_oper_centr_freq_seg1_idx={{ capabilities.vht.center_channel_freq.freq_2 }}
-{% endif %}
+{% endif %}
-{% if capabilities.vht.channel_set_width is defined %}
+{% if capabilities.vht.channel_set_width is vyos_defined %}
vht_oper_chwidth={{ capabilities.vht.channel_set_width }}
-{% endif %}
-
-{% set output = namespace(value='') %}
-{% if capabilities.vht.stbc is defined and capabilities.vht.stbc.tx is defined %}
-{% set output.value = output.value + '[TX-STBC-2BY1]' %}
-{% endif %}
-{% if capabilities.vht.stbc is defined and capabilities.vht.stbc.rx is defined %}
-{% set output.value = output.value + '[RX-STBC-' + capabilities.vht.stbc.rx + ']' %}
-{% endif %}
-{% if capabilities.vht.ldpc is defined %}
-{% set output.value = output.value + '[RXLDPC]' %}
-{% endif %}
-{% if capabilities.vht.tx_powersave is defined %}
-{% set output.value = output.value + '[VHT-TXOP-PS]' %}
-{% endif %}
-{% if capabilities.vht.vht_cf is defined %}
-{% set output.value = output.value + '[HTC-VHT]' %}
-{% endif %}
-{% if capabilities.vht.antenna_pattern_fixed is defined %}
-{% set output.value = output.value + '[RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]' %}
-{% endif %}
-{% if capabilities.vht.max_mpdu is defined %}
-{% set output.value = output.value + '[MAX-MPDU-' + capabilities.vht.max_mpdu + ']' %}
-{% endif %}
-{% if capabilities.vht.max_mpdu_exp is defined %}
-{% set output.value = output.value + '[MAX-A-MPDU-LEN-EXP-' + capabilities.vht.max_mpdu_exp + ']' %}
-{% endif %}
-{% if capabilities.vht.max_mpdu_exp is defined and capabilities.vht.max_mpdu_exp == '2' %}
-{% set output.value = output.value + '[VHT160]' %}
-{% endif %}
-{% if capabilities.vht.max_mpdu_exp is defined and capabilities.vht.max_mpdu_exp == '3' %}
-{% set output.value = output.value + '[VHT160-80PLUS80]' %}
-{% endif %}
-{% if capabilities.vht.link_adaptation is defined and capabilities.vht.link_adaptation == 'unsolicited' %}
-{% set output.value = output.value + '[VHT-LINK-ADAPT2]' %}
-{% endif %}
-{% if capabilities.vht.link_adaptation is defined and capabilities.vht.link_adaptation == 'both' %}
-{% set output.value = output.value + '[VHT-LINK-ADAPT3]' %}
-{% endif %}
-
-{% for short_gi in capabilities.vht.short_gi if capabilities.vht.short_gi is defined %}
-{% set output.value = output.value + '[SHORT-GI-' + short_gi | upper + ']' %}
-{% endfor %}
-
-{% for beamform in capabilities.vht.beamform if capabilities.vht.beamform is defined %}
-{% set output.value = output.value + '[SU-BEAMFORMER]' if beamform == 'single-user-beamformer' else '' %}
-{% set output.value = output.value + '[SU-BEAMFORMEE]' if beamform == 'single-user-beamformee' else '' %}
-{% set output.value = output.value + '[MU-BEAMFORMER]' if beamform == 'multi-user-beamformer' else '' %}
-{% set output.value = output.value + '[MU-BEAMFORMEE]' if beamform == 'multi-user-beamformee' else '' %}
-{% endfor %}
-
-{% if capabilities.vht.antenna_count is defined and capabilities.vht.antenna_count|int > 1 %}
-{% if capabilities.vht.beamform %}
-{% if beamform == 'single-user-beamformer' %}
-{% if capabilities.vht.antenna_count is defined and capabilities.vht.antenna_count|int > 1 and capabilities.vht.antenna_count|int < 6 %}
-{% set output.value = output.value + '[BF-ANTENNA-' + capabilities.vht.antenna_count|int -1 + ']' %}
-{% set output.value = output.value + '[SOUNDING-DIMENSION-' + capabilities.vht.antenna_count|int -1 + ']' %}
+{% endif %}
+
+{% set output = namespace(value='') %}
+{% if capabilities.vht.stbc.tx is vyos_defined %}
+{% set output.value = output.value ~ '[TX-STBC-2BY1]' %}
+{% endif %}
+{% if capabilities.vht.stbc.rx is vyos_defined %}
+{% set output.value = output.value ~ '[RX-STBC-' ~ capabilities.vht.stbc.rx ~ ']' %}
+{% endif %}
+{% if capabilities.vht.ldpc is vyos_defined %}
+{% set output.value = output.value ~ '[RXLDPC]' %}
+{% endif %}
+{% if capabilities.vht.tx_powersave is vyos_defined %}
+{% set output.value = output.value ~ '[VHT-TXOP-PS]' %}
+{% endif %}
+{% if capabilities.vht.vht_cf is vyos_defined %}
+{% set output.value = output.value ~ '[HTC-VHT]' %}
+{% endif %}
+{% if capabilities.vht.antenna_pattern_fixed is vyos_defined %}
+{% set output.value = output.value ~ '[RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]' %}
+{% endif %}
+{% if capabilities.vht.max_mpdu is vyos_defined %}
+{% set output.value = output.value ~ '[MAX-MPDU-' ~ capabilities.vht.max_mpdu ~ ']' %}
+{% endif %}
+{% if capabilities.vht.max_mpdu_exp is vyos_defined %}
+{% set output.value = output.value ~ '[MAX-A-MPDU-LEN-EXP-' ~ capabilities.vht.max_mpdu_exp ~ ']' %}
+{% if capabilities.vht.max_mpdu_exp is vyos_defined('2') %}
+{% set output.value = output.value ~ '[VHT160]' %}
+{% endif %}
+{% if capabilities.vht.max_mpdu_exp is vyos_defined('3') %}
+{% set output.value = output.value ~ '[VHT160-80PLUS80]' %}
+{% endif %}
+{% endif %}
+{% if capabilities.vht.link_adaptation is vyos_defined('unsolicited') %}
+{% set output.value = output.value ~ '[VHT-LINK-ADAPT2]' %}
+{% elif capabilities.vht.link_adaptation is vyos_defined('both') %}
+{% set output.value = output.value ~ '[VHT-LINK-ADAPT3]' %}
+{% endif %}
+
+{% for short_gi in capabilities.vht.short_gi if capabilities.vht.short_gi is vyos_defined %}
+{% set output.value = output.value ~ '[SHORT-GI-' ~ short_gi | upper ~ ']' %}
+{% endfor %}
+
+{% for beamform in capabilities.vht.beamform if capabilities.vht.beamform is vyos_defined %}
+{% set output.value = output.value ~ '[SU-BEAMFORMER]' if beamform is vyos_defined('single-user-beamformer') else '' %}
+{% set output.value = output.value ~ '[SU-BEAMFORMEE]' if beamform is vyos_defined('single-user-beamformee') else '' %}
+{% set output.value = output.value ~ '[MU-BEAMFORMER]' if beamform is vyos_defined('multi-user-beamformer') else '' %}
+{% set output.value = output.value ~ '[MU-BEAMFORMEE]' if beamform is vyos_defined('multi-user-beamformee') else '' %}
+{% endfor %}
+
+{% if capabilities.vht.antenna_count is vyos_defined and capabilities.vht.antenna_count | int > 1 %}
+{% if capabilities.vht.beamform is vyos_defined %}
+{% if capabilities.vht.beamform == 'single-user-beamformer' %}
+{% if capabilities.vht.antenna_count is vyos_defined and capabilities.vht.antenna_count | int > 1 and capabilities.vht.antenna_count | int < 6 %}
+{% set output.value = output.value ~ '[BF-ANTENNA-' ~ capabilities.vht.antenna_count | int -1 ~ ']' %}
+{% set output.value = output.value ~ '[SOUNDING-DIMENSION-' ~ capabilities.vht.antenna_count | int -1 ~ ']' %}
+{% endif %}
+{% endif %}
+{% if capabilities.vht.antenna_count is vyos_defined and capabilities.vht.antenna_count | int > 1 and capabilities.vht.antenna_count | int < 5 %}
+{% set output.value = output.value ~ '[BF-ANTENNA-' ~ capabilities.vht.antenna_count ~ ']' %}
+{% set output.value = output.value ~ '[SOUNDING-DIMENSION-' ~ capabilities.vht.antenna_count ~ ']' %}
+{% endif %}
{% endif %}
-{% endif %}
-{% if capabilities.vht.antenna_count is defined and capabilities.vht.antenna_count|int > 1 and capabilities.vht.antenna_count|int < 5 %}
-{% set output.value = output.value + '[BF-ANTENNA-' + capabilities.vht.antenna_count + ']' %}
-{% set output.value = output.value + '[SOUNDING-DIMENSION-' + capabilities.vht.antenna_count+ ']' %}
-{% endif %}
{% endif %}
-{% endif %}
vht_capab={{ output.value }}
{% endif %}
@@ -410,19 +410,15 @@ vht_capab={{ output.value }}
# 1 = enabled
# Note: You will also need to enable WMM for full HT functionality.
# Note: hw_mode=g (2.4 GHz) and hw_mode=a (5 GHz) is used to specify the band.
-{% if capabilities is defined and capabilities.require_vht is defined %}
+{% if capabilities.require_vht is vyos_defined %}
ieee80211n=0
# Require stations to support VHT PHY (reject association if they do not)
require_vht=1
{% else %}
-{% if 'n' in mode or 'ac' in mode %}
-ieee80211n=1
-{% else %}
-ieee80211n=0
-{% endif %}
+ieee80211n={{ '1' if 'n' in mode or 'ac' in mode else '0' }}
{% endif %}
-{% if disable_broadcast_ssid is defined %}
+{% if disable_broadcast_ssid is vyos_defined %}
# Send empty SSID in beacons and ignore probe request frames that do not
# specify full SSID, i.e., require stations to know SSID.
# default: disabled (0)
@@ -443,7 +439,7 @@ ignore_broadcast_ssid=1
# 2 = use external RADIUS server (accept/deny lists are searched first)
macaddr_acl=0
-{% if max_stations is defined %}
+{% if max_stations is vyos_defined %}
# Maximum number of stations allowed in station table. New stations will be
# rejected after the station table is full. IEEE 802.11 has a limit of 2007
# different association IDs, so this number should not be larger than that.
@@ -451,13 +447,13 @@ macaddr_acl=0
max_num_sta={{ max_stations }}
{% endif %}
-{% if isolate_stations is defined %}
+{% if isolate_stations is vyos_defined %}
# Client isolation can be used to prevent low-level bridging of frames between
# associated stations in the BSS. By default, this bridging is allowed.
ap_isolate=1
{% endif %}
-{% if reduce_transmit_power is defined %}
+{% if reduce_transmit_power is vyos_defined %}
# Add Power Constraint element to Beacon and Probe Response frames
# This config option adds Power Constraint element when applicable and Country
# element is added. Power Constraint element is required by Transmit Power
@@ -466,7 +462,7 @@ ap_isolate=1
local_pwr_constraint={{ reduce_transmit_power }}
{% endif %}
-{% if expunge_failing_stations is defined %}
+{% if expunge_failing_stations is vyos_defined %}
# Disassociate stations based on excessive transmission failures or other
# indications of connection loss. This depends on the driver capabilities and
# may not be available with all drivers.
@@ -474,7 +470,7 @@ disassoc_low_ack=1
{% endif %}
-{% if security is defined and security.wep is defined %}
+{% if security.wep is vyos_defined %}
# IEEE 802.11 specifies two authentication algorithms. hostapd can be
# configured to allow both of these or only one. Open system authentication
# should be used with IEEE 802.1X.
@@ -503,14 +499,14 @@ wep_default_key=0
# digits, depending on whether 40-bit (64-bit), 104-bit (128-bit), or
# 128-bit (152-bit) WEP is used.
# Only the default key must be supplied; the others are optional.
-{% if security.wep.key is defined %}
-{% for key in sec_wep_key %}
+{% if security.wep.key is vyos_defined %}
+{% for key in sec_wep_key %}
wep_key{{ loop.index -1 }}={{ security.wep.key }}
-{% endfor %}
-{% endif %}
+{% endfor %}
+{% endif %}
-{% elif security is defined and security.wpa is defined %}
+{% elif security.wpa is vyos_defined %}
##### WPA/IEEE 802.11i configuration ##########################################
# Enable WPA. Setting this variable configures the AP to require WPA (either
@@ -527,17 +523,15 @@ wep_key{{ loop.index -1 }}={{ security.wep.key }}
# Note that WPA3 is also configured with bit1 since it uses RSN just like WPA2.
# In other words, for WPA3, wpa 2 is used the configuration (and
# wpa_key_mgmt=SAE for WPA3-Personal instead of wpa_key_mgmt=WPA-PSK).
-{% if security.wpa.mode is defined %}
-{% if security.wpa.mode == 'wpa+wpa2' %}
+{% if security.wpa.mode is vyos_defined('wpa+wpa2') %}
wpa=3
-{% elif security.wpa.mode == 'wpa2' or security.wpa.mode == 'wpa3' %}
+{% elif security.wpa.mode is vyos_defined('wpa2') or security.wpa.mode is vyos_defined('wpa3') %}
wpa=2
-{% elif security.wpa.mode == 'wpa' %}
+{% elif security.wpa.mode is vyos_defined('wpa') %}
wpa=1
{% endif %}
-{% endif %}
-{% if security.wpa.cipher is defined %}
+{% if security.wpa.cipher is vyos_defined %}
# Set of accepted cipher suites (encryption algorithms) for pairwise keys
# (unicast packets). This is a space separated list of algorithms:
# CCMP = AES in Counter mode with CBC-MAC (CCMP-128)
@@ -551,16 +545,16 @@ wpa=1
# TKIP will be used as the group cipher. The optional group_cipher parameter can
# be used to override this automatic selection.
-{% if security.wpa.mode is defined and security.wpa.mode == 'wpa2' %}
+{% if security.wpa.mode is vyos_defined('wpa2') %}
# Pairwise cipher for RSN/WPA2 (default: use wpa_pairwise value)
rsn_pairwise={{ security.wpa.cipher | join(" ") }}
-{% else %}
+{% else %}
# Pairwise cipher for WPA (v1) (default: TKIP)
wpa_pairwise={{ security.wpa.cipher | join(" ") }}
+{% endif %}
{% endif %}
-{% endif %}
-{% if security.wpa.group_cipher is defined %}
+{% if security.wpa.group_cipher is vyos_defined %}
# Optional override for automatic group cipher selection
# This can be used to select a specific group cipher regardless of which
# pairwise ciphers were enabled for WPA and RSN. It should be noted that
@@ -568,9 +562,9 @@ wpa_pairwise={{ security.wpa.cipher | join(" ") }}
# interoperability issues and in general, this parameter is mainly used for
# testing purposes.
group_cipher={{ security.wpa.group_cipher | join(" ") }}
-{% endif %}
+{% endif %}
-{% if security.wpa.passphrase is defined %}
+{% if security.wpa.passphrase is vyos_defined %}
# IEEE 802.11 specifies two authentication algorithms. hostapd can be
# configured to allow both of these or only one. Open system authentication
# should be used with IEEE 802.1X.
@@ -594,13 +588,13 @@ wpa_passphrase={{ security.wpa.passphrase }}
# WPA-EAP-SHA256 = WPA2-Enterprise using SHA256
# SAE = SAE (WPA3-Personal)
# WPA-EAP-SUITE-B-192 = WPA3-Enterprise with 192-bit security/CNSA suite
-{% if security.wpa.mode is defined and security.wpa.mode == 'wpa3' %}
+{% if security.wpa.mode is vyos_defined('wpa3') %}
wpa_key_mgmt=SAE
-{% else %}
+{% else %}
wpa_key_mgmt=WPA-PSK WPA-PSK-SHA256
-{% endif %}
+{% endif %}
-{% elif security.wpa.radius is defined %}
+{% elif security.wpa.radius is vyos_defined %}
##### IEEE 802.1X-2004 related configuration ##################################
# Require IEEE 802.1X authorization
ieee8021x=1
@@ -614,43 +608,43 @@ ieee8021x=1
# WPA-EAP-SHA256 = WPA2-Enterprise using SHA256
# SAE = SAE (WPA3-Personal)
# WPA-EAP-SUITE-B-192 = WPA3-Enterprise with 192-bit security/CNSA suite
-{% if security.wpa.mode is defined and security.wpa.mode == 'wpa3' %}
+{% if security.wpa.mode is vyos_defined('wpa3') %}
wpa_key_mgmt=WPA-EAP-SUITE-B-192
-{% else %}
+{% else %}
wpa_key_mgmt=WPA-EAP WPA-EAP-SHA256
-{% endif %}
+{% endif %}
-{% if security.wpa.radius.server is defined %}
+{% if security.wpa.radius.server is vyos_defined %}
# RADIUS client forced local IP address for the access point
# Normally the local IP address is determined automatically based on configured
# IP addresses, but this field can be used to force a specific address to be
# used, e.g., when the device has multiple IP addresses.
# The own IP address of the access point (used as NAS-IP-Address)
-{% if security.wpa.radius.source_address is defined %}
+{% if security.wpa.radius.source_address is vyos_defined %}
radius_client_addr={{ security.wpa.radius.source_address }}
own_ip_addr={{ security.wpa.radius.source_address }}
-{% else %}
+{% else %}
own_ip_addr=127.0.0.1
-{% endif %}
+{% endif %}
-{% for radius in security.wpa.radius.server if not radius.disabled %}
+{% for radius in security.wpa.radius.server if not radius.disabled %}
# RADIUS authentication server
auth_server_addr={{ radius.server }}
auth_server_port={{ radius.port }}
auth_server_shared_secret={{ radius.key }}
-{% if radius.acc_port %}
+{% if radius.acc_port %}
# RADIUS accounting server
acct_server_addr={{ radius.server }}
acct_server_port={{ radius.acc_port }}
acct_server_shared_secret={{ radius.key }}
-{% endif %}
-{% endfor %}
-{% else %}
+{% endif %}
+{% endfor %}
+{% else %}
# Open system
auth_algs=1
+{% endif %}
{% endif %}
-{% endif %}
{% endif %}
# TX queue parameters (EDCF / bursting)
diff --git a/data/templates/wifi/wpa_supplicant.conf.tmpl b/data/templates/wifi/wpa_supplicant.conf.j2
index 20b4f7976..01e0d632f 100644
--- a/data/templates/wifi/wpa_supplicant.conf.tmpl
+++ b/data/templates/wifi/wpa_supplicant.conf.j2
@@ -18,7 +18,7 @@ network={
# this will add latency to scanning, so enable this only when needed)
scan_ssid=1
-{% if security is defined and security.wpa is defined and security.wpa.passphrase is defined %}
+{% if security.wpa.passphrase is vyos_defined %}
# ieee80211w: whether management frame protection is enabled
# 0 = disabled (default unless changed with the global pmf parameter)
# 1 = optional
@@ -59,11 +59,11 @@ network={
# OWE = Opportunistic Wireless Encryption (a.k.a. Enhanced Open)
# DPP = Device Provisioning Protocol
# If not set, this defaults to: WPA-PSK WPA-EAP
-{% if security.wpa.mode is defined and security.wpa.mode == 'wpa3' %}
+{% if security.wpa.mode is vyos_defined('wpa3') %}
key_mgmt=SAE
-{% else %}
+{% else %}
key_mgmt=WPA-PSK WPA-PSK-SHA256
-{% endif %}
+{% endif %}
# psk: WPA preshared key; 256-bit pre-shared key
# The key used in WPA-PSK mode can be entered either as 64 hex-digits, i.e.,
diff --git a/data/templates/zone_policy/nftables.j2 b/data/templates/zone_policy/nftables.j2
new file mode 100644
index 000000000..e4c4dd7da
--- /dev/null
+++ b/data/templates/zone_policy/nftables.j2
@@ -0,0 +1,113 @@
+#!/usr/sbin/nft -f
+
+{% if cleanup_commands is vyos_defined %}
+{% for command in cleanup_commands %}
+{{ command }}
+{% endfor %}
+{% endif %}
+
+{% if zone is vyos_defined %}
+table ip filter {
+{% for zone_name, zone_conf in zone.items() if zone_conf.ipv4 %}
+{% if zone_conf.local_zone is vyos_defined %}
+ chain VZONE_{{ zone_name }}_IN {
+ iifname lo counter return
+{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall.name is vyos_defined %}
+ iifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME_{{ from_conf.firewall.name }}
+ iifname { {{ zone[from_zone].interface | join(",") }} } counter return
+{% endfor %}
+ counter {{ zone_conf.default_action }}
+ }
+ chain VZONE_{{ zone_name }}_OUT {
+ oifname lo counter return
+{% for from_zone, from_conf in zone_conf.from_local.items() if from_conf.firewall.name is vyos_defined %}
+ oifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME_{{ from_conf.firewall.name }}
+ oifname { {{ zone[from_zone].interface | join(",") }} } counter return
+{% endfor %}
+ counter {{ zone_conf.default_action }}
+ }
+{% else %}
+ chain VZONE_{{ zone_name }} {
+ iifname { {{ zone_conf.interface | join(",") }} } counter {{ zone_conf | nft_intra_zone_action(ipv6=False) }}
+{% if zone_conf.intra_zone_filtering is vyos_defined %}
+ iifname { {{ zone_conf.interface | join(",") }} } counter return
+{% endif %}
+{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall.name is vyos_defined %}
+{% if zone[from_zone].local_zone is not defined %}
+ iifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME_{{ from_conf.firewall.name }}
+ iifname { {{ zone[from_zone].interface | join(",") }} } counter return
+{% endif %}
+{% endfor %}
+ counter {{ zone_conf.default_action }}
+ }
+{% endif %}
+{% endfor %}
+}
+
+table ip6 filter {
+{% for zone_name, zone_conf in zone.items() if zone_conf.ipv6 %}
+{% if zone_conf.local_zone is vyos_defined %}
+ chain VZONE6_{{ zone_name }}_IN {
+ iifname lo counter return
+{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall.ipv6_name is vyos_defined %}
+ iifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME6_{{ from_conf.firewall.ipv6_name }}
+ iifname { {{ zone[from_zone].interface | join(",") }} } counter return
+{% endfor %}
+ counter {{ zone_conf.default_action }}
+ }
+ chain VZONE6_{{ zone_name }}_OUT {
+ oifname lo counter return
+{% for from_zone, from_conf in zone_conf.from_local.items() if from_conf.firewall.ipv6_name is vyos_defined %}
+ oifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME6_{{ from_conf.firewall.ipv6_name }}
+ oifname { {{ zone[from_zone].interface | join(",") }} } counter return
+{% endfor %}
+ counter {{ zone_conf.default_action }}
+ }
+{% else %}
+ chain VZONE6_{{ zone_name }} {
+ iifname { {{ zone_conf.interface | join(",") }} } counter {{ zone_conf | nft_intra_zone_action(ipv6=True) }}
+{% if zone_conf.intra_zone_filtering is vyos_defined %}
+ iifname { {{ zone_conf.interface | join(",") }} } counter return
+{% endif %}
+{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall.ipv6_name is vyos_defined %}
+{% if zone[from_zone].local_zone is not defined %}
+ iifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME6_{{ from_conf.firewall.ipv6_name }}
+ iifname { {{ zone[from_zone].interface | join(",") }} } counter return
+{% endif %}
+{% endfor %}
+ counter {{ zone_conf.default_action }}
+ }
+{% endif %}
+{% endfor %}
+}
+
+{% for zone_name, zone_conf in zone.items() %}
+{% if zone_conf.ipv4 %}
+{% if 'local_zone' in zone_conf %}
+insert rule ip filter VYOS_FW_LOCAL counter jump VZONE_{{ zone_name }}_IN
+insert rule ip filter VYOS_FW_OUTPUT counter jump VZONE_{{ zone_name }}_OUT
+{% else %}
+insert rule ip filter VYOS_FW_FORWARD oifname { {{ zone_conf.interface | join(',') }} } counter jump VZONE_{{ zone_name }}
+{% endif %}
+{% endif %}
+{% if zone_conf.ipv6 %}
+{% if 'local_zone' in zone_conf %}
+insert rule ip6 filter VYOS_FW6_LOCAL counter jump VZONE6_{{ zone_name }}_IN
+insert rule ip6 filter VYOS_FW6_OUTPUT counter jump VZONE6_{{ zone_name }}_OUT
+{% else %}
+insert rule ip6 filter VYOS_FW6_FORWARD oifname { {{ zone_conf.interface | join(',') }} } counter jump VZONE6_{{ zone_name }}
+{% endif %}
+{% endif %}
+{% endfor %}
+
+{# Ensure that state-policy rule is first in the chain #}
+{% if firewall.state_policy is vyos_defined %}
+{% for chain in ['VYOS_FW_FORWARD', 'VYOS_FW_OUTPUT', 'VYOS_FW_LOCAL'] %}
+insert rule ip filter {{ chain }} jump VYOS_STATE_POLICY
+{% endfor %}
+{% for chain in ['VYOS_FW6_FORWARD', 'VYOS_FW6_OUTPUT', 'VYOS_FW6_LOCAL'] %}
+insert rule ip6 filter {{ chain }} jump VYOS_STATE_POLICY6
+{% endfor %}
+{% endif %}
+
+{% endif %}
diff --git a/debian/control b/debian/control
index 08c04b439..bcd5acfdd 100644
--- a/debian/control
+++ b/debian/control
@@ -94,6 +94,7 @@ Depends:
ndisc6,
ndppd,
netplug,
+ nfct,
nftables (>= 0.9.3),
nginx-light,
ntp,
@@ -146,11 +147,13 @@ Depends:
squid,
squidclient,
squidguard,
+ sshguard,
ssl-cert,
strongswan (>= 5.9),
strongswan-swanctl (>= 5.9),
sudo,
systemd,
+ telegraf (>= 1.20),
tcpdump,
tcptraceroute,
telnet,
@@ -168,7 +171,9 @@ Depends:
wide-dhcpv6-client,
wireguard-tools,
wireless-regdb,
- wpasupplicant (>= 0.6.7)
+ wpasupplicant (>= 0.6.7),
+ ndppd,
+ miniupnpd-nftables
Description: VyOS configuration scripts and data
VyOS configuration scripts, interface definitions, and everything
@@ -183,5 +188,6 @@ Description: VyOS configuration scripts and data for VMware
Package: vyos-1x-smoketest
Architecture: all
Depends:
+ snmp,
vyos-1x
Description: VyOS build sanity checking toolkit
diff --git a/debian/vyos-1x.install b/debian/vyos-1x.install
index 29d74390f..493c896eb 100644
--- a/debian/vyos-1x.install
+++ b/debian/vyos-1x.install
@@ -1,4 +1,3 @@
-etc/cron.d
etc/cron.hourly
etc/dhcp
etc/ipsec.d
@@ -12,6 +11,7 @@ etc/security
etc/sudoers.d
etc/systemd
etc/sysctl.d
+etc/telegraf
etc/udev
etc/update-motd.d
etc/vyos
diff --git a/debian/vyos-1x.postinst b/debian/vyos-1x.postinst
index 4b4c4c13e..1ca6687a3 100644
--- a/debian/vyos-1x.postinst
+++ b/debian/vyos-1x.postinst
@@ -83,3 +83,17 @@ fi
if [ -L /etc/init.d/README ]; then
rm -f /etc/init.d/README
fi
+
+# Remove unwanted daemon files from /etc
+# conntackd
+DELETE="/etc/logrotate.d/conntrackd.distrib /etc/init.d/conntrackd /etc/default/conntrackd
+ /etc/default/pmacctd /etc/pmacct"
+for file in $DELETE; do
+ if [ -f ${file} ]; then
+ rm -f ${file}
+ fi
+done
+
+# Remove logrotate items controlled via CLI and VyOS defaults
+sed -i '/^\/var\/log\/messages$/d' /etc/logrotate.d/rsyslog
+sed -i '/^\/var\/log\/auth.log$/d' /etc/logrotate.d/rsyslog
diff --git a/debian/vyos-1x.preinst b/debian/vyos-1x.preinst
index 45440bf64..71750b3a1 100644
--- a/debian/vyos-1x.preinst
+++ b/debian/vyos-1x.preinst
@@ -1,4 +1,4 @@
dpkg-divert --package vyos-1x --add --rename /etc/securetty
dpkg-divert --package vyos-1x --add --rename /etc/security/capability.conf
dpkg-divert --package vyos-1x --add --rename /lib/systemd/system/lcdproc.service
-
+dpkg-divert --package vyos-1x --add --rename /etc/logrotate.d/conntrackd
diff --git a/interface-definitions/containers.xml.in b/interface-definitions/container.xml.in
index 30c7110b8..51171d881 100644
--- a/interface-definitions/containers.xml.in
+++ b/interface-definitions/container.xml.in
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<interfaceDefinition>
- <node name="container" owner="${vyos_conf_scripts_dir}/containers.py">
+ <node name="container" owner="${vyos_conf_scripts_dir}/container.py">
<properties>
<help>Container applications</help>
<priority>1280</priority>
@@ -10,7 +10,7 @@
<properties>
<help>Container name</help>
<constraint>
- <regex>^[-a-zA-Z0-9]+$</regex>
+ <regex>[-a-zA-Z0-9]+</regex>
</constraint>
<constraintErrorMessage>Container name must be alphanumeric and can contain hyphens</constraintErrorMessage>
</properties>
@@ -52,18 +52,43 @@
<description>Permission to set system clock</description>
</valueHelp>
<constraint>
- <regex>^(net-admin|net-bind-service|net-raw|setpcap|sys-admin|sys-time)$</regex>
+ <regex>(net-admin|net-bind-service|net-raw|setpcap|sys-admin|sys-time)</regex>
</constraint>
<multi/>
</properties>
</leafNode>
#include <include/generic-description.xml.i>
+ <tagNode name="device">
+ <properties>
+ <help>Add a host device to the container</help>
+ </properties>
+ <children>
+ <leafNode name="source">
+ <properties>
+ <help>Source device (Example: "/dev/x")</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Source device</description>
+ </valueHelp>
+ </properties>
+ </leafNode>
+ <leafNode name="destination">
+ <properties>
+ <help>Destination container device (Example: "/dev/x")</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Destination container device</description>
+ </valueHelp>
+ </properties>
+ </leafNode>
+ </children>
+ </tagNode>
#include <include/generic-disable-node.xml.i>
<tagNode name="environment">
<properties>
<help>Add custom environment variables</help>
<constraint>
- <regex>^[-_a-zA-Z0-9]+$</regex>
+ <regex>[-_a-zA-Z0-9]+</regex>
</constraint>
<constraintErrorMessage>Environment variable name must be alphanumeric and can contain hyphen and underscores</constraintErrorMessage>
</properties>
@@ -86,7 +111,7 @@
</leafNode>
<leafNode name="memory">
<properties>
- <help>Constrain the memory available to a container (default: 512MB)</help>
+ <help>Constrain the memory available to a container</help>
<valueHelp>
<format>u32:0</format>
<description>Unlimited</description>
@@ -169,7 +194,7 @@
<list>tcp udp</list>
</completionHelp>
<constraint>
- <regex>^(tcp|udp)$</regex>
+ <regex>(tcp|udp)</regex>
</constraint>
</properties>
</leafNode>
@@ -187,14 +212,14 @@
</valueHelp>
<valueHelp>
<format>on-failure</format>
- <description>Restart containers when they exit with a non-zero exit code, retrying indefinitely (default)</description>
+ <description>Restart containers when they exit with a non-zero exit code, retrying indefinitely</description>
</valueHelp>
<valueHelp>
<format>always</format>
<description>Restart containers when they exit, regardless of status, retrying indefinitely</description>
</valueHelp>
<constraint>
- <regex>^(no|on-failure|always)$</regex>
+ <regex>(no|on-failure|always)</regex>
</constraint>
</properties>
<defaultValue>on-failure</defaultValue>
@@ -258,10 +283,10 @@
</tagNode>
<leafNode name="registry">
<properties>
- <help>Add registry (default docker.io)</help>
+ <help>Registry Name</help>
<multi/>
</properties>
- <defaultValue>docker.io</defaultValue>
+ <defaultValue>docker.io quay.io</defaultValue>
</leafNode>
</children>
</node>
diff --git a/interface-definitions/dhcp-relay.xml.in b/interface-definitions/dhcp-relay.xml.in
index 483e776a7..27d0a3e6c 100644
--- a/interface-definitions/dhcp-relay.xml.in
+++ b/interface-definitions/dhcp-relay.xml.in
@@ -20,7 +20,7 @@
<help>Policy to discard packets that have reached specified hop-count</help>
<valueHelp>
<format>u32:1-255</format>
- <description>Hop count (default: 10)</description>
+ <description>Hop count</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-255"/>
@@ -34,17 +34,18 @@
<help>Maximum packet size to send to a DHCPv4/BOOTP server</help>
<valueHelp>
<format>u32:64-1400</format>
- <description>Maximum packet size (default: 576)</description>
+ <description>Maximum packet size</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 64-1400"/>
</constraint>
<constraintErrorMessage>max-size must be a value between 64 and 1400</constraintErrorMessage>
</properties>
+ <defaultValue>576</defaultValue>
</leafNode>
<leafNode name="relay-agents-packets">
<properties>
- <help>Policy to handle incoming DHCPv4 packets which already contain relay agent options (default: forward)</help>
+ <help>Policy to handle incoming DHCPv4 packets which already contain relay agent options</help>
<completionHelp>
<list>append replace forward discard</list>
</completionHelp>
@@ -65,7 +66,7 @@
<description>discard packet (default action if giaddr not set in packet)</description>
</valueHelp>
<constraint>
- <regex>^(append|replace|forward|discard)$</regex>
+ <regex>(append|replace|forward|discard)</regex>
</constraint>
</properties>
<defaultValue>forward</defaultValue>
diff --git a/interface-definitions/dhcp-server.xml.in b/interface-definitions/dhcp-server.xml.in
index d1ed579e9..60e738e01 100644
--- a/interface-definitions/dhcp-server.xml.in
+++ b/interface-definitions/dhcp-server.xml.in
@@ -58,7 +58,7 @@
<description>Configure this server to be the secondary node</description>
</valueHelp>
<constraint>
- <regex>^(primary|secondary)$</regex>
+ <regex>(primary|secondary)</regex>
</constraint>
<constraintErrorMessage>Invalid DHCP failover peer status</constraintErrorMessage>
</properties>
@@ -142,6 +142,11 @@
boot file is to be loaded</help>
</properties>
</leafNode>
+ <leafNode name="bootfile-size">
+ <properties>
+ <help>Bootstrap file size in 512 byte blocks</help>
+ </properties>
+ </leafNode>
<leafNode name="client-prefix-length">
<properties>
<help>Specifies the clients subnet mask as per RFC 950. If unset, subnet declaration is used.</help>
@@ -198,7 +203,7 @@
</leafNode>
<leafNode name="lease">
<properties>
- <help>Lease timeout in seconds (default: 86400)</help>
+ <help>Lease timeout in seconds</help>
<valueHelp>
<format>u32</format>
<description>DHCP lease time in seconds</description>
@@ -254,7 +259,7 @@
<properties>
<help>DHCP lease range</help>
<constraint>
- <regex>^[-_a-zA-Z0-9.]+$</regex>
+ <regex>[-_a-zA-Z0-9.]+</regex>
</constraint>
<constraintErrorMessage>Invalid range name, may only be alphanumeric, dot and hyphen</constraintErrorMessage>
</properties>
@@ -289,7 +294,7 @@
<properties>
<help>Name of static mapping</help>
<constraint>
- <regex>^[-_a-zA-Z0-9.]+$</regex>
+ <regex>[-_a-zA-Z0-9.]+</regex>
</constraint>
<constraintErrorMessage>Invalid static mapping name, may only be alphanumeric, dot and hyphen</constraintErrorMessage>
</properties>
@@ -369,6 +374,18 @@
<leafNode name="tftp-server-name">
<properties>
<help>TFTP server name</help>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>TFTP server IPv4 address</description>
+ </valueHelp>
+ <valueHelp>
+ <format>hostname</format>
+ <description>TFTP server FQDN</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv4-address"/>
+ <validator name="fqdn"/>
+ </constraint>
</properties>
</leafNode>
<leafNode name="time-offset">
@@ -397,6 +414,32 @@
<multi/>
</properties>
</leafNode>
+ <node name="vendor-option">
+ <properties>
+ <help>Vendor Specific Options</help>
+ </properties>
+ <children>
+ <node name="ubiquiti">
+ <properties>
+ <help>Ubiquiti specific parameters</help>
+ </properties>
+ <children>
+ <leafNode name="unifi-controller">
+ <properties>
+ <help>Address of UniFi controller</help>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>IP address of UniFi controller</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv4-address"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+ </node>
<leafNode name="wins-server">
<properties>
<help>IP address for Windows Internet Name Service (WINS) server</help>
diff --git a/interface-definitions/dhcpv6-relay.xml.in b/interface-definitions/dhcpv6-relay.xml.in
index 7162cf353..5abcbe804 100644
--- a/interface-definitions/dhcpv6-relay.xml.in
+++ b/interface-definitions/dhcpv6-relay.xml.in
@@ -36,7 +36,7 @@
<help>Maximum hop count for which requests will be processed</help>
<valueHelp>
<format>u32:1-255</format>
- <description>Hop count (default: 10)</description>
+ <description>Hop count</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-255"/>
diff --git a/interface-definitions/dhcpv6-server.xml.in b/interface-definitions/dhcpv6-server.xml.in
index fb96571f5..10335b07e 100644
--- a/interface-definitions/dhcpv6-server.xml.in
+++ b/interface-definitions/dhcpv6-server.xml.in
@@ -338,6 +338,33 @@
</leafNode>
</children>
</tagNode>
+ <node name="vendor-option">
+ <properties>
+ <help>Vendor Specific Options</help>
+ </properties>
+ <children>
+ <node name="cisco">
+ <properties>
+ <help>Cisco specific parameters</help>
+ </properties>
+ <children>
+ <leafNode name="tftp-server">
+ <properties>
+ <help>TFTP server name</help>
+ <valueHelp>
+ <format>ipv6</format>
+ <description>TFTP server IPv6 address</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv6-address"/>
+ </constraint>
+ <multi/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+ </node>
</children>
</tagNode>
</children>
diff --git a/interface-definitions/dns-domain-name.xml.in b/interface-definitions/dns-domain-name.xml.in
index 005a55ab3..0d6418272 100644
--- a/interface-definitions/dns-domain-name.xml.in
+++ b/interface-definitions/dns-domain-name.xml.in
@@ -29,6 +29,7 @@
</constraint>
</properties>
</leafNode>
+ <!-- script does not use XML defaults so far -->
<leafNode name="host-name" owner="${vyos_conf_scripts_dir}/host_name.py">
<properties>
<help>System host name (default: vyos)</help>
@@ -55,7 +56,7 @@
<properties>
<help>DNS domain completion order</help>
<constraint>
- <regex>[-a-zA-Z0-9.]+$</regex>
+ <regex>[-a-zA-Z0-9.]+</regex>
</constraint>
<constraintErrorMessage>Invalid domain name</constraintErrorMessage>
<multi/>
@@ -73,7 +74,7 @@
<properties>
<help>Host name for static address mapping</help>
<constraint>
- <regex>[A-Za-z0-9][-.A-Za-z0-9]*[A-Za-z0-9]$</regex>
+ <regex>[A-Za-z0-9][-.A-Za-z0-9]*[A-Za-z0-9]</regex>
</constraint>
<constraintErrorMessage>invalid hostname</constraintErrorMessage>
</properties>
@@ -82,7 +83,7 @@
<properties>
<help>Alias for this address</help>
<constraint>
- <regex>.{1,63}$</regex>
+ <regex>.{1,63}</regex>
</constraint>
<constraintErrorMessage>invalid alias hostname, needs to be between 1 and 63 charactes</constraintErrorMessage>
<multi />
diff --git a/interface-definitions/dns-dynamic.xml.in b/interface-definitions/dns-dynamic.xml.in
index 64826516e..6bc467b76 100644
--- a/interface-definitions/dns-dynamic.xml.in
+++ b/interface-definitions/dns-dynamic.xml.in
@@ -120,7 +120,7 @@
<description>zoneedit.com Services</description>
</valueHelp>
<constraint>
- <regex>^(custom|afraid|changeip|cloudflare|dnspark|dslreports|dyndns|easydns|namecheap|noip|sitelutions|zoneedit|\w+)$</regex>
+ <regex>(custom|afraid|changeip|cloudflare|dnspark|dslreports|dyndns|easydns|namecheap|noip|sitelutions|zoneedit|\w+)</regex>
</constraint>
<constraintErrorMessage>You can use only predefined list of services or word characters (_, a-z, A-Z, 0-9) as service name</constraintErrorMessage>
</properties>
@@ -232,7 +232,7 @@
<description>Zoneedit protocol</description>
</valueHelp>
<constraint>
- <regex>^(changeip|cloudflare|dnsmadeeasy|dnspark|dondominio|dslreports1|dtdns|duckdns|dyndns2|easydns|freedns|freemyip|googledomains|hammernode1|namecheap|nfsn|noip|sitelutions|woima|yandex|zoneedit1)$</regex>
+ <regex>(changeip|cloudflare|dnsmadeeasy|dnspark|dondominio|dslreports1|dtdns|duckdns|dyndns2|easydns|freedns|freemyip|googledomains|hammernode1|namecheap|nfsn|noip|sitelutions|woima|yandex|zoneedit1)</regex>
</constraint>
<constraintErrorMessage>Please choose from the list of allowed protocols</constraintErrorMessage>
</properties>
diff --git a/interface-definitions/dns-forwarding.xml.in b/interface-definitions/dns-forwarding.xml.in
index 5b0c87597..6ead3e199 100644
--- a/interface-definitions/dns-forwarding.xml.in
+++ b/interface-definitions/dns-forwarding.xml.in
@@ -16,7 +16,7 @@
<children>
<leafNode name="cache-size">
<properties>
- <help>DNS forwarding cache size (default: 10000)</help>
+ <help>DNS forwarding cache size</help>
<valueHelp>
<format>u32:0-2147483647</format>
<description>DNS forwarding cache size</description>
@@ -38,7 +38,7 @@
</leafNode>
<leafNode name="dnssec">
<properties>
- <help>DNSSEC mode (default: process-no-validate)</help>
+ <help>DNSSEC mode</help>
<completionHelp>
<list>off process-no-validate process log-fail validate</list>
</completionHelp>
@@ -63,7 +63,7 @@
<description>Full blown DNSSEC validation. Send SERVFAIL to clients on bogus responses.</description>
</valueHelp>
<constraint>
- <regex>^(off|process-no-validate|process|log-fail|validate)$</regex>
+ <regex>(off|process-no-validate|process|log-fail|validate)</regex>
</constraint>
</properties>
<defaultValue>process-no-validate</defaultValue>
@@ -105,6 +105,456 @@
</leafNode>
</children>
</tagNode>
+ <tagNode name="authoritative-domain">
+ <properties>
+ <help>Domain to host authoritative records for</help>
+ <valueHelp>
+ <format>text</format>
+ <description>An absolute DNS name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[-_a-zA-Z0-9.]{1,63}</regex>
+ </constraint>
+ </properties>
+ <children>
+ <node name="records">
+ <properties>
+ <help>DNS zone records</help>
+ </properties>
+ <children>
+ <tagNode name="a">
+ <properties>
+ <help>"A" record</help>
+ <valueHelp>
+ <format>text</format>
+ <description>A DNS name relative to the root record</description>
+ </valueHelp>
+ <valueHelp>
+ <format>@</format>
+ <description>Root record</description>
+ </valueHelp>
+ <constraint>
+ <regex>([-_a-zA-Z0-9.]{1,63}|@)(?&lt;!\.)</regex>
+ </constraint>
+ </properties>
+ <children>
+ <leafNode name="address">
+ <properties>
+ <help>IPv4 address [REQUIRED]</help>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>IPv4 address</description>
+ </valueHelp>
+ <multi/>
+ <constraint>
+ <validator name="ipv4-address"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ #include <include/dns/time-to-live.xml.i>
+ #include <include/generic-disable-node.xml.i>
+ </children>
+ </tagNode>
+ <tagNode name="aaaa">
+ <properties>
+ <help>"AAAA" record</help>
+ <valueHelp>
+ <format>text</format>
+ <description>A DNS name relative to the root record</description>
+ </valueHelp>
+ <valueHelp>
+ <format>@</format>
+ <description>Root record</description>
+ </valueHelp>
+ <constraint>
+ <regex>([-_a-zA-Z0-9.]{1,63}|@)(?&lt;!\.)</regex>
+ </constraint>
+ </properties>
+ <children>
+ <leafNode name="address">
+ <properties>
+ <help>IPv6 address [REQUIRED]</help>
+ <valueHelp>
+ <format>ipv6</format>
+ <description>IPv6 address</description>
+ </valueHelp>
+ <multi/>
+ <constraint>
+ <validator name="ipv6-address"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ #include <include/dns/time-to-live.xml.i>
+ #include <include/generic-disable-node.xml.i>
+ </children>
+ </tagNode>
+ <tagNode name="cname">
+ <properties>
+ <help>"CNAME" record</help>
+ <valueHelp>
+ <format>text</format>
+ <description>A DNS name relative to the root record</description>
+ </valueHelp>
+ <valueHelp>
+ <format>@</format>
+ <description>Root record</description>
+ </valueHelp>
+ <constraint>
+ <regex>([-_a-zA-Z0-9.]{1,63}|@)(?&lt;!\.)</regex>
+ </constraint>
+ </properties>
+ <children>
+ <leafNode name="target">
+ <properties>
+ <help>Target DNS name [REQUIRED]</help>
+ <valueHelp>
+ <format>name.example.com</format>
+ <description>An absolute DNS name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[-_a-zA-Z0-9.]{1,63}(?&lt;!\.)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ #include <include/dns/time-to-live.xml.i>
+ #include <include/generic-disable-node.xml.i>
+ </children>
+ </tagNode>
+ <tagNode name="mx">
+ <properties>
+ <help>"MX" record</help>
+ <valueHelp>
+ <format>text</format>
+ <description>A DNS name relative to the root record</description>
+ </valueHelp>
+ <valueHelp>
+ <format>@</format>
+ <description>Root record</description>
+ </valueHelp>
+ <constraint>
+ <regex>([-_a-zA-Z0-9.]{1,63}|@)(?&lt;!\.)</regex>
+ </constraint>
+ </properties>
+ <children>
+ <tagNode name="server">
+ <properties>
+ <help>Mail server [REQUIRED]</help>
+ <valueHelp>
+ <format>name.example.com</format>
+ <description>An absolute DNS name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[-_a-zA-Z0-9.]{1,63}(?&lt;!\.)</regex>
+ </constraint>
+ </properties>
+ <children>
+ <leafNode name="priority">
+ <properties>
+ <help>Server priority</help>
+ <valueHelp>
+ <format>u32:1-999</format>
+ <description>Server priority (lower numbers are higher priority)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-999"/>
+ </constraint>
+ </properties>
+ <defaultValue>10</defaultValue>
+ </leafNode>
+ </children>
+ </tagNode>
+ #include <include/dns/time-to-live.xml.i>
+ #include <include/generic-disable-node.xml.i>
+ </children>
+ </tagNode>
+ <tagNode name="ptr">
+ <properties>
+ <help>"PTR" record</help>
+ <valueHelp>
+ <format>text</format>
+ <description>A DNS name relative to the root record</description>
+ </valueHelp>
+ <valueHelp>
+ <format>@</format>
+ <description>Root record</description>
+ </valueHelp>
+ <constraint>
+ <regex>([-_a-zA-Z0-9.]{1,63}|@)(?&lt;!\.)</regex>
+ </constraint>
+ </properties>
+ <children>
+ <leafNode name="target">
+ <properties>
+ <help>Target DNS name [REQUIRED]</help>
+ <valueHelp>
+ <format>name.example.com</format>
+ <description>An absolute DNS name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[-_a-zA-Z0-9.]{1,63}(?&lt;!\.)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ #include <include/dns/time-to-live.xml.i>
+ #include <include/generic-disable-node.xml.i>
+ </children>
+ </tagNode>
+ <tagNode name="txt">
+ <properties>
+ <help>"TXT" record</help>
+ <valueHelp>
+ <format>text</format>
+ <description>A DNS name relative to the root record</description>
+ </valueHelp>
+ <valueHelp>
+ <format>@</format>
+ <description>Root record</description>
+ </valueHelp>
+ <constraint>
+ <regex>([-_a-zA-Z0-9.]{1,63}|@)(?&lt;!\.)</regex>
+ </constraint>
+ </properties>
+ <children>
+ <leafNode name="value">
+ <properties>
+ <help>Record contents [REQUIRED]</help>
+ <valueHelp>
+ <format>text</format>
+ <description>Record contents</description>
+ </valueHelp>
+ <multi/>
+ </properties>
+ </leafNode>
+ #include <include/dns/time-to-live.xml.i>
+ #include <include/generic-disable-node.xml.i>
+ </children>
+ </tagNode>
+ <tagNode name="spf">
+ <properties>
+ <help>"SPF" record (type=SPF)</help>
+ <valueHelp>
+ <format>text</format>
+ <description>A DNS name relative to the root record</description>
+ </valueHelp>
+ <valueHelp>
+ <format>@</format>
+ <description>Root record</description>
+ </valueHelp>
+ <constraint>
+ <regex>([-_a-zA-Z0-9.]{1,63}|@)(?&lt;!\.)</regex>
+ </constraint>
+ </properties>
+ <children>
+ <leafNode name="value">
+ <properties>
+ <help>Record contents [REQUIRED]</help>
+ <valueHelp>
+ <format>text</format>
+ <description>Record contents</description>
+ </valueHelp>
+ </properties>
+ </leafNode>
+ #include <include/dns/time-to-live.xml.i>
+ #include <include/generic-disable-node.xml.i>
+ </children>
+ </tagNode>
+ <tagNode name="srv">
+ <properties>
+ <help>"SRV" record</help>
+ <valueHelp>
+ <format>text</format>
+ <description>A DNS name relative to the root record</description>
+ </valueHelp>
+ <valueHelp>
+ <format>@</format>
+ <description>Root record</description>
+ </valueHelp>
+ <constraint>
+ <regex>([-_a-zA-Z0-9.]{1,63}|@)(?&lt;!\.)</regex>
+ </constraint>
+ </properties>
+ <children>
+ <tagNode name="entry">
+ <properties>
+ <help>Service entry [REQUIRED]</help>
+ <valueHelp>
+ <format>u32:0-65535</format>
+ <description>Entry number</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-65535"/>
+ </constraint>
+ </properties>
+ <children>
+ <leafNode name="hostname">
+ <properties>
+ <help>Server hostname [REQUIRED]</help>
+ <valueHelp>
+ <format>name.example.com</format>
+ <description>An absolute DNS name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[-_a-zA-Z0-9.]{1,63}(?&lt;!\.)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="port">
+ <properties>
+ <help>Port number [REQUIRED]</help>
+ <valueHelp>
+ <format>u32:0-65535</format>
+ <description>TCP/UDP port number</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-65536"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="priority">
+ <properties>
+ <help>Entry priority</help>
+ <valueHelp>
+ <format>u32:0-65535</format>
+ <description>Entry priority (lower numbers are higher priority)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-65535"/>
+ </constraint>
+ </properties>
+ <defaultValue>10</defaultValue>
+ </leafNode>
+ <leafNode name="weight">
+ <properties>
+ <help>Entry weight</help>
+ <valueHelp>
+ <format>u32:0-65535</format>
+ <description>Entry weight</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-65535"/>
+ </constraint>
+ </properties>
+ <defaultValue>0</defaultValue>
+ </leafNode>
+ </children>
+ </tagNode>
+ #include <include/dns/time-to-live.xml.i>
+ #include <include/generic-disable-node.xml.i>
+ </children>
+ </tagNode>
+ <tagNode name="naptr">
+ <properties>
+ <help>"NAPTR" record</help>
+ <valueHelp>
+ <format>text</format>
+ <description>A DNS name relative to the root record</description>
+ </valueHelp>
+ <valueHelp>
+ <format>@</format>
+ <description>Root record</description>
+ </valueHelp>
+ <constraint>
+ <regex>([-_a-zA-Z0-9.]{1,63}|@)(?&lt;!\.)</regex>
+ </constraint>
+ </properties>
+ <children>
+ <tagNode name="rule">
+ <properties>
+ <help>NAPTR rule [REQUIRED]</help>
+ <valueHelp>
+ <format>u32:0-65535</format>
+ <description>Rule number</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-65535"/>
+ </constraint>
+ </properties>
+ <children>
+ <leafNode name="order">
+ <properties>
+ <help>Rule order</help>
+ <valueHelp>
+ <format>u32:0-65535</format>
+ <description>Rule order (lower order is evaluated first)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-65535"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="preference">
+ <properties>
+ <help>Rule preference</help>
+ <valueHelp>
+ <format>u32:0-65535</format>
+ <description>Rule preference</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-65535"/>
+ </constraint>
+ </properties>
+ <defaultValue>0</defaultValue>
+ </leafNode>
+ <leafNode name="lookup-srv">
+ <properties>
+ <help>"S" flag</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="lookup-a">
+ <properties>
+ <help>"A" flag</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="resolve-uri">
+ <properties>
+ <help>"U" flag</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="protocol-specific">
+ <properties>
+ <help>"P" flag</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="service">
+ <properties>
+ <help>Service type</help>
+ <constraint>
+ <regex>[a-zA-Z][a-zA-Z0-9]{0,31}(\+[a-zA-Z][a-zA-Z0-9]{0,31})?</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="regexp">
+ <properties>
+ <help>Regular expression</help>
+ </properties>
+ </leafNode>
+ <leafNode name="replacement">
+ <properties>
+ <help>Replacement DNS name</help>
+ <valueHelp>
+ <format>name.example.com</format>
+ <description>An absolute DNS name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[-_a-zA-Z0-9.]{1,63}(?&lt;!\.)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+ </tagNode>
+ #include <include/dns/time-to-live.xml.i>
+ #include <include/generic-disable-node.xml.i>
+ </children>
+ </tagNode>
+ </children>
+ </node>
+ #include <include/generic-disable-node.xml.i>
+ </children>
+ </tagNode>
<leafNode name="ignore-hosts-file">
<properties>
<help>Do not use local /etc/hosts file in name resolution</help>
@@ -114,7 +564,7 @@
<leafNode name="no-serve-rfc1918">
<properties>
<help>Makes the server authoritatively not aware of RFC1918 addresses</help>
- <valueless/>
+ <valueless/>
</properties>
</leafNode>
<leafNode name="allow-from">
@@ -137,7 +587,7 @@
#include <include/listen-address.xml.i>
<leafNode name="negative-ttl">
<properties>
- <help>Maximum amount of time negative entries are cached (default: 3600)</help>
+ <help>Maximum amount of time negative entries are cached</help>
<valueHelp>
<format>u32:0-7200</format>
<description>Seconds to cache NXDOMAIN entries</description>
@@ -148,6 +598,19 @@
</properties>
<defaultValue>3600</defaultValue>
</leafNode>
+ <leafNode name="timeout">
+ <properties>
+ <help>Number of milliseconds to wait for a remote authoritative server to respond</help>
+ <valueHelp>
+ <format>u32:10-60000</format>
+ <description>Network timeout in milliseconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 10-60000"/>
+ </constraint>
+ </properties>
+ <defaultValue>1500</defaultValue>
+ </leafNode>
#include <include/name-server-ipv4-ipv6.xml.i>
<leafNode name="source-address">
<properties>
diff --git a/interface-definitions/firewall.xml.in b/interface-definitions/firewall.xml.in
index f07c619a8..ff8d92a24 100644
--- a/interface-definitions/firewall.xml.in
+++ b/interface-definitions/firewall.xml.in
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<interfaceDefinition>
- <node name="nfirewall" owner="${vyos_conf_scripts_dir}/firewall.py">
+ <node name="firewall" owner="${vyos_conf_scripts_dir}/firewall.py">
<properties>
<priority>199</priority>
<help>Firewall</help>
@@ -21,9 +21,10 @@
<description>Disable processing of all IPv4 ICMP echo requests</description>
</valueHelp>
<constraint>
- <regex>^(enable|disable)$</regex>
+ <regex>(enable|disable)</regex>
</constraint>
</properties>
+ <defaultValue>enable</defaultValue>
</leafNode>
<leafNode name="broadcast-ping">
<properties>
@@ -40,9 +41,10 @@
<description>Disable processing of broadcast IPv4 ICMP echo/timestamp requests</description>
</valueHelp>
<constraint>
- <regex>^(enable|disable)$</regex>
+ <regex>(enable|disable)</regex>
</constraint>
</properties>
+ <defaultValue>disable</defaultValue>
</leafNode>
<leafNode name="config-trap">
<properties>
@@ -59,9 +61,10 @@
<description>Disable sending SNMP trap on firewall configuration change</description>
</valueHelp>
<constraint>
- <regex>^(enable|disable)$</regex>
+ <regex>(enable|disable)</regex>
</constraint>
</properties>
+ <defaultValue>disable</defaultValue>
</leafNode>
<node name="group">
<properties>
@@ -71,6 +74,9 @@
<tagNode name="address-group">
<properties>
<help>Firewall address-group</help>
+ <constraint>
+ <regex>[a-zA-Z0-9][\w\-\.]*</regex>
+ </constraint>
</properties>
<children>
<leafNode name="address">
@@ -97,6 +103,9 @@
<tagNode name="ipv6-address-group">
<properties>
<help>Firewall ipv6-address-group</help>
+ <constraint>
+ <regex>[a-zA-Z0-9][\w\-\.]*</regex>
+ </constraint>
</properties>
<children>
<leafNode name="address">
@@ -106,8 +115,13 @@
<format>ipv6</format>
<description>IPv6 address to match</description>
</valueHelp>
+ <valueHelp>
+ <format>ipv6range</format>
+ <description>IPv6 range to match (e.g. 2002::1-2002::ff)</description>
+ </valueHelp>
<constraint>
<validator name="ipv6-address"/>
+ <validator name="ipv6-range"/>
</constraint>
<multi/>
</properties>
@@ -117,7 +131,10 @@
</tagNode>
<tagNode name="ipv6-network-group">
<properties>
- <help>Network-group member</help>
+ <help>Firewall ipv6-network-group</help>
+ <constraint>
+ <regex>[a-zA-Z0-9][\w\-\.]*</regex>
+ </constraint>
</properties>
<children>
#include <include/generic-description.xml.i>
@@ -136,9 +153,36 @@
</leafNode>
</children>
</tagNode>
+ <tagNode name="mac-group">
+ <properties>
+ <help>Firewall mac-group</help>
+ <constraint>
+ <regex>[a-zA-Z0-9][\w\-\.]*</regex>
+ </constraint>
+ </properties>
+ <children>
+ #include <include/generic-description.xml.i>
+ <leafNode name="mac-address">
+ <properties>
+ <help>Mac-group member</help>
+ <valueHelp>
+ <format>&lt;MAC address&gt;</format>
+ <description>MAC address to match</description>
+ </valueHelp>
+ <constraint>
+ <validator name="mac-address"/>
+ </constraint>
+ <multi/>
+ </properties>
+ </leafNode>
+ </children>
+ </tagNode>
<tagNode name="network-group">
<properties>
<help>Firewall network-group</help>
+ <constraint>
+ <regex>[a-zA-Z0-9][\w\-\.]*</regex>
+ </constraint>
</properties>
<children>
#include <include/generic-description.xml.i>
@@ -160,6 +204,9 @@
<tagNode name="port-group">
<properties>
<help>Firewall port-group</help>
+ <constraint>
+ <regex>[a-zA-Z0-9][\w\-\.]*</regex>
+ </constraint>
</properties>
<children>
#include <include/generic-description.xml.i>
@@ -179,6 +226,9 @@
<description>Numbered port range (e.g. 1001-1050)</description>
</valueHelp>
<multi/>
+ <constraint>
+ <validator name="port-range"/>
+ </constraint>
</properties>
</leafNode>
</children>
@@ -200,13 +250,17 @@
<description>Disable processing of IPv4 packets with source route option</description>
</valueHelp>
<constraint>
- <regex>^(enable|disable)$</regex>
+ <regex>(enable|disable)</regex>
</constraint>
</properties>
+ <defaultValue>disable</defaultValue>
</leafNode>
<tagNode name="ipv6-name">
<properties>
<help>IPv6 firewall rule-set name</help>
+ <constraint>
+ <regex>[a-zA-Z0-9][\w\-\.]*</regex>
+ </constraint>
</properties>
<children>
#include <include/firewall/name-default-action.xml.i>
@@ -214,7 +268,15 @@
#include <include/generic-description.xml.i>
<tagNode name="rule">
<properties>
- <help>Rule number (1-9999)</help>
+ <help>Firewall rule number (IPv6)</help>
+ <valueHelp>
+ <format>u32:1-999999</format>
+ <description>Number for this Firewall rule</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-999999"/>
+ </constraint>
+ <constraintErrorMessage>Firewall rule number must be between 1 and 999999</constraintErrorMessage>
</properties>
<children>
#include <include/firewall/action.xml.i>
@@ -225,7 +287,7 @@
</properties>
<children>
#include <include/firewall/address-ipv6.xml.i>
- #include <include/firewall/source-destination-group.xml.i>
+ #include <include/firewall/source-destination-group-ipv6.xml.i>
#include <include/firewall/port.xml.i>
</children>
</node>
@@ -235,7 +297,7 @@
</properties>
<children>
#include <include/firewall/address-ipv6.xml.i>
- #include <include/firewall/source-destination-group.xml.i>
+ #include <include/firewall/source-destination-group-ipv6.xml.i>
#include <include/firewall/port.xml.i>
</children>
</node>
@@ -288,227 +350,31 @@
<help>ICMPv6 type and code information</help>
</properties>
<children>
- <leafNode name="type">
+ <leafNode name="code">
<properties>
- <help>ICMP type-name</help>
- <completionHelp>
- <list>any echo-reply pong destination-unreachable network-unreachable host-unreachable protocol-unreachable port-unreachable fragmentation-needed source-route-failed network-unknown host-unknown network-prohibited host-prohibited TOS-network-unreachable TOS-host-unreachable communication-prohibited host-precedence-violation precedence-cutoff source-quench redirect network-redirect host-redirect TOS-network-redirect TOS host-redirect echo-request ping router-advertisement router-solicitation time-exceeded ttl-exceeded ttl-zero-during-transit ttl-zero-during-reassembly parameter-problem ip-header-bad required-option-missing timestamp-request timestamp-reply address-mask-request address-mask-reply</list>
- </completionHelp>
- <valueHelp>
- <format>any</format>
- <description>Any ICMP type/code</description>
- </valueHelp>
- <valueHelp>
- <format>echo-reply</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>pong</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>destination-unreachable</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>network-unreachable</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>host-unreachable</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>protocol-unreachable</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>port-unreachable</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>fragmentation-needed</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>source-route-failed</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>network-unknown</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>host-unknown</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>network-prohibited</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>host-prohibited</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>TOS-network-unreachable</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>TOS-host-unreachable</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>communication-prohibited</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>host-precedence-violation</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>precedence-cutoff</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>source-quench</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>redirect</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>network-redirect</format>
- <description>ICMP type/code name</description>
- </valueHelp>
+ <help>ICMPv6 code (0-255)</help>
<valueHelp>
- <format>host-redirect</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>TOS-network-redirect</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>TOS host-redirect</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>echo-request</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>ping</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>router-advertisement</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>router-solicitation</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>time-exceeded</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>ttl-exceeded</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>ttl-zero-during-transit</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>ttl-zero-during-reassembly</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>parameter-problem</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>ip-header-bad</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>required-option-missing</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>timestamp-request</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>timestamp-reply</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>address-mask-request</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>address-mask-reply</format>
- <description>ICMP type/code name</description>
+ <format>u32:0-255</format>
+ <description>ICMPv6 code (0-255)</description>
</valueHelp>
<constraint>
- <regex>^(any|echo-reply|pong|destination-unreachable|network-unreachable|host-unreachable|protocol-unreachable|port-unreachable|fragmentation-needed|source-route-failed|network-unknown|host-unknown|network-prohibited|host-prohibited|TOS-network-unreachable|TOS-host-unreachable|communication-prohibited|host-precedence-violation|precedence-cutoff|source-quench|redirect|network-redirect|host-redirect|TOS-network-redirect|TOS host-redirect|echo-request|ping|router-advertisement|router-solicitation|time-exceeded|ttl-exceeded|ttl-zero-during-transit|ttl-zero-during-reassembly|parameter-problem|ip-header-bad|required-option-missing|timestamp-request|timestamp-reply|address-mask-request|address-mask-reply)$</regex>
<validator name="numeric" argument="--range 0-255"/>
</constraint>
</properties>
</leafNode>
- </children>
- </node>
- <node name="p2p">
- <properties>
- <help>P2P application packets</help>
- </properties>
- <children>
- <leafNode name="all">
- <properties>
- <help>AppleJuice/BitTorrent/Direct Connect/eDonkey/eMule/Gnutella/KaZaA application packets</help>
- <valueless/>
- </properties>
- </leafNode>
- <leafNode name="applejuice">
- <properties>
- <help>AppleJuice application packets</help>
- <valueless/>
- </properties>
- </leafNode>
- <leafNode name="bittorrent">
- <properties>
- <help>BitTorrent application packets</help>
- <valueless/>
- </properties>
- </leafNode>
- <leafNode name="directconnect">
- <properties>
- <help>Direct Connect application packets</help>
- <valueless/>
- </properties>
- </leafNode>
- <leafNode name="edonkey">
- <properties>
- <help>eDonkey/eMule application packets</help>
- <valueless/>
- </properties>
- </leafNode>
- <leafNode name="gnutella">
- <properties>
- <help>Gnutella application packets</help>
- <valueless/>
- </properties>
- </leafNode>
- <leafNode name="kazaa">
+ <leafNode name="type">
<properties>
- <help>KaZaA application packets</help>
- <valueless/>
+ <help>ICMPv6 type (0-255)</help>
+ <valueHelp>
+ <format>u32:0-255</format>
+ <description>ICMPv6 type (0-255)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-255"/>
+ </constraint>
</properties>
</leafNode>
+ #include <include/firewall/icmpv6-type-name.xml.i>
</children>
</node>
</children>
@@ -530,9 +396,10 @@
<description>Disable processing of received ICMPv6 redirect messages</description>
</valueHelp>
<constraint>
- <regex>^(enable|disable)$</regex>
+ <regex>(enable|disable)</regex>
</constraint>
</properties>
+ <defaultValue>disable</defaultValue>
</leafNode>
<leafNode name="ipv6-src-route">
<properties>
@@ -549,9 +416,10 @@
<description>Disable processing of IPv6 packets with routing header</description>
</valueHelp>
<constraint>
- <regex>^(enable|disable)$</regex>
+ <regex>(enable|disable)</regex>
</constraint>
</properties>
+ <defaultValue>disable</defaultValue>
</leafNode>
<leafNode name="log-martians">
<properties>
@@ -568,13 +436,17 @@
<description>Disable logging of Ipv4 packets with invalid addresses</description>
</valueHelp>
<constraint>
- <regex>^(enable|disable)$</regex>
+ <regex>(enable|disable)</regex>
</constraint>
</properties>
+ <defaultValue>enable</defaultValue>
</leafNode>
<tagNode name="name">
<properties>
<help>IPv4 firewall rule-set name</help>
+ <constraint>
+ <regex>[a-zA-Z0-9][\w\-\.]*</regex>
+ </constraint>
</properties>
<children>
#include <include/firewall/name-default-action.xml.i>
@@ -582,7 +454,15 @@
#include <include/generic-description.xml.i>
<tagNode name="rule">
<properties>
- <help>Rule number (1-9999)</help>
+ <help>Firewall rule number (IPv4)</help>
+ <valueHelp>
+ <format>u32:1-999999</format>
+ <description>Number for this Firewall rule</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-999999"/>
+ </constraint>
+ <constraintErrorMessage>Firewall rule number must be between 1 and 999999</constraintErrorMessage>
</properties>
<children>
#include <include/firewall/action.xml.i>
@@ -659,9 +539,10 @@
<description>Disable processing of received IPv4 ICMP redirect messages</description>
</valueHelp>
<constraint>
- <regex>^(enable|disable)$</regex>
+ <regex>(enable|disable)</regex>
</constraint>
</properties>
+ <defaultValue>disable</defaultValue>
</leafNode>
<leafNode name="send-redirects">
<properties>
@@ -678,9 +559,10 @@
<description>Disable sending IPv4 ICMP redirect messages</description>
</valueHelp>
<constraint>
- <regex>^(enable|disable)$</regex>
+ <regex>(enable|disable)</regex>
</constraint>
</properties>
+ <defaultValue>enable</defaultValue>
</leafNode>
<leafNode name="source-validation">
<properties>
@@ -701,9 +583,10 @@
<description>No source validation</description>
</valueHelp>
<constraint>
- <regex>^(strict|loose|disable)$</regex>
+ <regex>(strict|loose|disable)</regex>
</constraint>
</properties>
+ <defaultValue>disable</defaultValue>
</leafNode>
<node name="state-policy">
<properties>
@@ -754,9 +637,10 @@
<description>Disable use of TCP SYN cookies with IPv4</description>
</valueHelp>
<constraint>
- <regex>^(enable|disable)$</regex>
+ <regex>(enable|disable)</regex>
</constraint>
</properties>
+ <defaultValue>enable</defaultValue>
</leafNode>
<leafNode name="twa-hazards-protection">
<properties>
@@ -773,9 +657,10 @@
<description>Disable RFC1337 TIME-WAIT hazards protection</description>
</valueHelp>
<constraint>
- <regex>^(enable|disable)$</regex>
+ <regex>(enable|disable)</regex>
</constraint>
</properties>
+ <defaultValue>disable</defaultValue>
</leafNode>
</children>
</node>
diff --git a/interface-definitions/flow-accounting-conf.xml.in b/interface-definitions/flow-accounting-conf.xml.in
index 113c1d849..878566b3f 100644
--- a/interface-definitions/flow-accounting-conf.xml.in
+++ b/interface-definitions/flow-accounting-conf.xml.in
@@ -17,20 +17,34 @@
<description>Buffer size in MiB</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-4294967295" />
+ <validator name="numeric" argument="--range 0-4294967295"/>
</constraint>
</properties>
+ <defaultValue>10</defaultValue>
+ </leafNode>
+ <leafNode name="packet-length">
+ <properties>
+ <help>Specifies the maximum number of bytes to capture for each packet</help>
+ <valueHelp>
+ <format>u32:128-750</format>
+ <description>Packet length in bytes</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 128-750"/>
+ </constraint>
+ </properties>
+ <defaultValue>128</defaultValue>
</leafNode>
<leafNode name="enable-egress">
<properties>
<help>Enable egress flow accounting</help>
- <valueless />
+ <valueless/>
</properties>
</leafNode>
<leafNode name="disable-imt">
<properties>
<help>Disable in memory table plugin</help>
- <valueless />
+ <valueless/>
</properties>
</leafNode>
<leafNode name="syslog-facility">
@@ -132,7 +146,7 @@
<description>Authentication and authorization</description>
</valueHelp>
<constraint>
- <regex>^(auth|authpriv|cron|daemon|kern|lpr|mail|mark|news|protocols|security|syslog|user|uucp|local0|local1|local2|local3|local4|local5|local6|local7|all)$</regex>
+ <regex>(auth|authpriv|cron|daemon|kern|lpr|mail|mark|news|protocols|security|syslog|user|uucp|local0|local1|local2|local3|local4|local5|local6|local7|all)</regex>
</constraint>
</properties>
</leafNode>
@@ -154,7 +168,7 @@
<description>NetFlow engine-id for v9 / IPFIX</description>
</valueHelp>
<constraint>
- <regex>(\d|[1-9]\d{1,8}|[1-3]\d{9}|4[01]\d{8}|42[0-8]\d{7}|429[0-3]\d{6}|4294[0-8]\d{5}|42949[0-5]\d{4}|429496[0-6]\d{3}|4294967[01]\d{2}|42949672[0-8]\d|429496729[0-5])$|^(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]):(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$</regex>
+ <regex>(\d|[1-9]\d{1,8}|[1-3]\d{9}|4[01]\d{8}|42[0-8]\d{7}|429[0-3]\d{6}|4294[0-8]\d{5}|42949[0-5]\d{4}|429496[0-6]\d{3}|4294967[01]\d{2}|42949672[0-8]\d|429496729[0-5])$|^(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]):(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])</regex>
</constraint>
</properties>
</leafNode>
@@ -166,7 +180,7 @@
<description>NetFlow maximum flows</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-4294967295" />
+ <validator name="numeric" argument="--range 0-4294967295"/>
</constraint>
</properties>
</leafNode>
@@ -178,27 +192,11 @@
<description>Sampling rate (1 in N packets)</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-4294967295" />
- </constraint>
- </properties>
- </leafNode>
- <leafNode name="source-ip">
- <properties>
- <help>IPv4 or IPv6 source address of NetFlow packets</help>
- <valueHelp>
- <format>ipv4</format>
- <description>IPv4 source address of NetFlow packets</description>
- </valueHelp>
- <valueHelp>
- <format>ipv6</format>
- <description>IPv6 source address of NetFlow packets</description>
- </valueHelp>
- <constraint>
- <validator name="ipv4-address"/>
- <validator name="ipv6-address"/>
+ <validator name="numeric" argument="--range 0-4294967295"/>
</constraint>
</properties>
</leafNode>
+ #include <include/source-address-ipv4-ipv6.xml.i>
<leafNode name="version">
<properties>
<help>NetFlow version to export</help>
@@ -211,17 +209,18 @@
</valueHelp>
<valueHelp>
<format>9</format>
- <description>NetFlow version 9 (default)</description>
+ <description>NetFlow version 9</description>
</valueHelp>
<valueHelp>
<format>10</format>
<description>Internet Protocol Flow Information Export (IPFIX)</description>
</valueHelp>
</properties>
+ <defaultValue>9</defaultValue>
</leafNode>
<tagNode name="server">
<properties>
- <help>Server to export NetFlow [REQUIRED]</help>
+ <help>NetFlow destination server</help>
<valueHelp>
<format>ipv4</format>
<description>IPv4 server to export NetFlow</description>
@@ -241,12 +240,13 @@
<help>NetFlow port number</help>
<valueHelp>
<format>u32:1025-65535</format>
- <description>NetFlow port number (default 2055)</description>
+ <description>NetFlow port number</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 1025-65535" />
+ <validator name="numeric" argument="--range 1025-65535"/>
</constraint>
</properties>
+ <defaultValue>2055</defaultValue>
</leafNode>
</children>
</tagNode>
@@ -260,96 +260,104 @@
<help>Expiry scan interval</help>
<valueHelp>
<format>u32:0-2147483647</format>
- <description>Expiry scan interval (default 60)</description>
+ <description>Expiry scan interval</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-2147483647" />
+ <validator name="numeric" argument="--range 0-2147483647"/>
</constraint>
</properties>
+ <defaultValue>60</defaultValue>
</leafNode>
<leafNode name="flow-generic">
<properties>
<help>Generic flow timeout value</help>
<valueHelp>
<format>u32:0-2147483647</format>
- <description>Generic flow timeout in seconds (default 3600)</description>
+ <description>Generic flow timeout in seconds</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-2147483647" />
+ <validator name="numeric" argument="--range 0-2147483647"/>
</constraint>
</properties>
+ <defaultValue>3600</defaultValue>
</leafNode>
<leafNode name="icmp">
<properties>
<help>ICMP timeout value</help>
<valueHelp>
<format>u32:0-2147483647</format>
- <description>ICMP timeout in seconds (default 300)</description>
+ <description>ICMP timeout in seconds</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-2147483647" />
+ <validator name="numeric" argument="--range 0-2147483647"/>
</constraint>
</properties>
+ <defaultValue>300</defaultValue>
</leafNode>
<leafNode name="max-active-life">
<properties>
<help>Max active timeout value</help>
<valueHelp>
<format>u32:0-2147483647</format>
- <description>Max active timeout in seconds (default 604800)</description>
+ <description>Max active timeout in seconds</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-2147483647" />
+ <validator name="numeric" argument="--range 0-2147483647"/>
</constraint>
</properties>
+ <defaultValue>604800</defaultValue>
</leafNode>
<leafNode name="tcp-fin">
<properties>
<help>TCP finish timeout value</help>
<valueHelp>
<format>u32:0-2147483647</format>
- <description>TCP FIN timeout in seconds (default 300)</description>
+ <description>TCP FIN timeout in seconds</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-2147483647" />
+ <validator name="numeric" argument="--range 0-2147483647"/>
</constraint>
</properties>
+ <defaultValue>300</defaultValue>
</leafNode>
<leafNode name="tcp-generic">
<properties>
<help>TCP generic timeout value</help>
<valueHelp>
<format>u32:0-2147483647</format>
- <description>TCP generic timeout in seconds (default 3600)</description>
+ <description>TCP generic timeout in seconds</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-2147483647" />
+ <validator name="numeric" argument="--range 0-2147483647"/>
</constraint>
</properties>
+ <defaultValue>3600</defaultValue>
</leafNode>
<leafNode name="tcp-rst">
<properties>
<help>TCP reset timeout value</help>
<valueHelp>
<format>u32:0-2147483647</format>
- <description>TCP RST timeout in seconds (default 120)</description>
+ <description>TCP RST timeout in seconds</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-2147483647" />
+ <validator name="numeric" argument="--range 0-2147483647"/>
</constraint>
</properties>
+ <defaultValue>120</defaultValue>
</leafNode>
<leafNode name="udp">
<properties>
<help>UDP timeout value</help>
<valueHelp>
<format>u32:0-2147483647</format>
- <description>UDP timeout in seconds (default 300)</description>
+ <description>UDP timeout in seconds</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-2147483647" />
+ <validator name="numeric" argument="--range 0-2147483647"/>
</constraint>
</properties>
+ <defaultValue>300</defaultValue>
</leafNode>
</children>
</node>
@@ -363,17 +371,16 @@
<leafNode name="agent-address">
<properties>
<help>sFlow agent IPv4 address</help>
- <valueHelp>
- <format>auto</format>
- <description>auto select sFlow agent-address (default)</description>
- </valueHelp>
+ <completionHelp>
+ <list>auto</list>
+ <script>${vyos_completion_dir}/list_local_ips.sh --ipv4</script>
+ </completionHelp>
<valueHelp>
<format>ipv4</format>
<description>sFlow IPv4 agent address</description>
</valueHelp>
<constraint>
<validator name="ipv4-address"/>
- <regex>^auto$</regex>
</constraint>
</properties>
</leafNode>
@@ -385,13 +392,13 @@
<description>Sampling rate (1 in N packets)</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-4294967295" />
+ <validator name="numeric" argument="--range 0-4294967295"/>
</constraint>
</properties>
</leafNode>
<tagNode name="server">
<properties>
- <help>Server to export sFlow [REQUIRED]</help>
+ <help>sFlow destination server</help>
<valueHelp>
<format>ipv4</format>
<description>IPv4 server to export sFlow</description>
@@ -411,17 +418,20 @@
<help>sFlow port number</help>
<valueHelp>
<format>u32:1025-65535</format>
- <description>sFlow port number (default 6343)</description>
+ <description>sFlow port number</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 1025-65535" />
+ <validator name="numeric" argument="--range 1025-65535"/>
</constraint>
</properties>
+ <defaultValue>6343</defaultValue>
</leafNode>
</children>
</tagNode>
+ #include <include/source-address-ipv4-ipv6.xml.i>
</children>
</node>
+ #include <include/interface/vrf.xml.i>
</children>
</node>
</children>
diff --git a/interface-definitions/vrrp.xml.in b/interface-definitions/high-availability.xml.in
index 53d79caac..0631acdda 100644
--- a/interface-definitions/vrrp.xml.in
+++ b/interface-definitions/high-availability.xml.in
@@ -1,13 +1,13 @@
<?xml version="1.0"?>
<interfaceDefinition>
- <node name="high-availability">
+ <node name="high-availability" owner="${vyos_conf_scripts_dir}/high-availability.py">
<properties>
+ <priority>800</priority> <!-- after all interfaces and conntrack-sync -->
<help>High availability settings</help>
</properties>
<children>
- <node name="vrrp" owner="${vyos_conf_scripts_dir}/vrrp.py">
+ <node name="vrrp">
<properties>
- <priority>800</priority> <!-- after all interfaces and conntrack-sync -->
<help>Virtual Router Redundancy Protocol settings</help>
</properties>
<children>
@@ -22,7 +22,7 @@
<help>Advertise interval</help>
<valueHelp>
<format>u32:1-255</format>
- <description>Advertise interval in seconds (default: 1)</description>
+ <description>Advertise interval in seconds</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-255"/>
@@ -63,7 +63,7 @@
<description>AH - IPSEC (not recommended)</description>
</valueHelp>
<constraint>
- <regex>^(plaintext-password|ah)$</regex>
+ <regex>(plaintext-password|ah)</regex>
</constraint>
<constraintErrorMessage>Authentication type must be plaintext-password or ah</constraintErrorMessage>
</properties>
@@ -79,7 +79,7 @@
<children>
<leafNode name="failure-count">
<properties>
- <help>Health check failure count required for transition to fault (default: 3)</help>
+ <help>Health check failure count required for transition to fault</help>
<constraint>
<validator name="numeric" argument="--positive" />
</constraint>
@@ -88,7 +88,7 @@
</leafNode>
<leafNode name="interval">
<properties>
- <help>Health check execution interval in seconds (default: 60)</help>
+ <help>Health check execution interval in seconds</help>
<constraint>
<validator name="numeric" argument="--positive"/>
</constraint>
@@ -160,7 +160,7 @@
</leafNode>
<leafNode name="priority">
<properties>
- <help>Router priority (default: 100)</help>
+ <help>Router priority</help>
<valueHelp>
<format>u32:1-255</format>
<description>Router priority</description>
@@ -177,8 +177,37 @@
<valueless/>
</properties>
</leafNode>
+ <node name="track">
+ <properties>
+ <help>Track settings</help>
+ </properties>
+ <children>
+ <leafNode name="exclude-vrrp-interface">
+ <properties>
+ <valueless/>
+ <help>Disable track state of main interface</help>
+ </properties>
+ </leafNode>
+ <leafNode name="interface">
+ <properties>
+ <help>Interface name state check</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces.py --broadcast</script>
+ </completionHelp>
+ <valueHelp>
+ <format>txt</format>
+ <description>Interface name</description>
+ </valueHelp>
+ <constraint>
+ <validator name="interface-name"/>
+ </constraint>
+ <multi/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
#include <include/vrrp-transition-script.xml.i>
- <leafNode name="address">
+ <tagNode name="address">
<properties>
<help>Virtual IP address</help>
<valueHelp>
@@ -193,9 +222,11 @@
<validator name="ipv4-host"/>
<validator name="ipv6-host"/>
</constraint>
- <multi/>
</properties>
- </leafNode>
+ <children>
+ #include <include/generic-interface-broadcast.xml.i>
+ </children>
+ </tagNode>
<leafNode name="excluded-address">
<properties>
<help>Virtual address (If you need additional IPv4 and IPv6 in same group)</help>
@@ -252,6 +283,144 @@
</tagNode>
</children>
</node>
+ <tagNode name="virtual-server">
+ <properties>
+ <help>Load-balancing virtual server address</help>
+ </properties>
+ <children>
+ <leafNode name="algorithm">
+ <properties>
+ <help>Schedule algorithm (default - least-connection)</help>
+ <completionHelp>
+ <list>round-robin weighted-round-robin least-connection weighted-least-connection source-hashing destination-hashing locality-based-least-connection</list>
+ </completionHelp>
+ <valueHelp>
+ <format>round-robin</format>
+ <description>Round robin</description>
+ </valueHelp>
+ <valueHelp>
+ <format>weighted-round-robin</format>
+ <description>Weighted round robin</description>
+ </valueHelp>
+ <valueHelp>
+ <format>least-connection</format>
+ <description>Least connection</description>
+ </valueHelp>
+ <valueHelp>
+ <format>weighted-least-connection</format>
+ <description>Weighted least connection</description>
+ </valueHelp>
+ <valueHelp>
+ <format>source-hashing</format>
+ <description>Source hashing</description>
+ </valueHelp>
+ <valueHelp>
+ <format>destination-hashing</format>
+ <description>Destination hashing</description>
+ </valueHelp>
+ <valueHelp>
+ <format>locality-based-least-connection</format>
+ <description>Locality-Based least connection</description>
+ </valueHelp>
+ <constraint>
+ <regex>(round-robin|weighted-round-robin|least-connection|weighted-least-connection|source-hashing|destination-hashing|locality-based-least-connection)</regex>
+ </constraint>
+ </properties>
+ <defaultValue>least-connection</defaultValue>
+ </leafNode>
+ <leafNode name="delay-loop">
+ <properties>
+ <help>Interval between health-checks (in seconds)</help>
+ <valueHelp>
+ <format>u32:1-600</format>
+ <description>Interval in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-3600"/>
+ </constraint>
+ </properties>
+ <defaultValue>10</defaultValue>
+ </leafNode>
+ <leafNode name="forward-method">
+ <properties>
+ <help>Forwarding method</help>
+ <completionHelp>
+ <list>direct nat tunnel</list>
+ </completionHelp>
+ <valueHelp>
+ <format>direct</format>
+ <description>Direct routing</description>
+ </valueHelp>
+ <valueHelp>
+ <format>nat</format>
+ <description>NAT</description>
+ </valueHelp>
+ <valueHelp>
+ <format>tunnel</format>
+ <description>Tunneling</description>
+ </valueHelp>
+ <constraint>
+ <regex>(direct|nat|tunnel)</regex>
+ </constraint>
+ </properties>
+ <defaultValue>nat</defaultValue>
+ </leafNode>
+ #include <include/port-number.xml.i>
+ <leafNode name="persistence-timeout">
+ <properties>
+ <help>Timeout for persistent connections</help>
+ <valueHelp>
+ <format>u32:1-86400</format>
+ <description>Timeout for persistent connections</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-86400"/>
+ </constraint>
+ </properties>
+ <defaultValue>300</defaultValue>
+ </leafNode>
+ <leafNode name="protocol">
+ <properties>
+ <help>Protocol for port checks</help>
+ <completionHelp>
+ <list>tcp udp</list>
+ </completionHelp>
+ <valueHelp>
+ <format>tcp</format>
+ <description>TCP</description>
+ </valueHelp>
+ <valueHelp>
+ <format>udp</format>
+ <description>UDP</description>
+ </valueHelp>
+ <constraint>
+ <regex>(tcp|udp)</regex>
+ </constraint>
+ </properties>
+ <defaultValue>tcp</defaultValue>
+ </leafNode>
+ <tagNode name="real-server">
+ <properties>
+ <help>Real server address</help>
+ </properties>
+ <children>
+ #include <include/port-number.xml.i>
+ <leafNode name="connection-timeout">
+ <properties>
+ <help>Server connection timeout</help>
+ <valueHelp>
+ <format>u32:1-86400</format>
+ <description>Connection timeout to remote server</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-86400"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+ </tagNode>
+ </children>
+ </tagNode>
</children>
</node>
</interfaceDefinition>
diff --git a/interface-definitions/https.xml.in b/interface-definitions/https.xml.in
index f60df7c34..d2c393036 100644
--- a/interface-definitions/https.xml.in
+++ b/interface-definitions/https.xml.in
@@ -38,7 +38,7 @@
<constraint>
<validator name="ipv4-address"/>
<validator name="ipv6-address"/>
- <regex>\*$</regex>
+ <regex>\*</regex>
</constraint>
</properties>
</leafNode>
@@ -101,6 +101,25 @@
<hidden/>
</properties>
</leafNode>
+ <leafNode name="socket">
+ <properties>
+ <help>Run server on Unix domain socket</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <node name="cors">
+ <properties>
+ <help>Set CORS options</help>
+ </properties>
+ <children>
+ <leafNode name="allow-origin">
+ <properties>
+ <help>Allow resource request from origin</help>
+ <multi/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
</children>
</node>
<node name="api-restrict">
@@ -143,6 +162,7 @@
</node>
</children>
</node>
+ #include <include/interface/vrf.xml.i>
</children>
</node>
</children>
diff --git a/interface-definitions/igmp-proxy.xml.in b/interface-definitions/igmp-proxy.xml.in
index 91c912d8b..8e738fa7f 100644
--- a/interface-definitions/igmp-proxy.xml.in
+++ b/interface-definitions/igmp-proxy.xml.in
@@ -39,7 +39,7 @@
</leafNode>
<leafNode name="role">
<properties>
- <help>IGMP interface role (default: downstream)</help>
+ <help>IGMP interface role</help>
<completionHelp>
<list>upstream downstream disabled</list>
</completionHelp>
@@ -49,24 +49,24 @@
</valueHelp>
<valueHelp>
<format>downstream</format>
- <description>Downstream interface(s) (default)</description>
+ <description>Downstream interface(s)</description>
</valueHelp>
<valueHelp>
<format>disabled</format>
<description>Disabled interface</description>
</valueHelp>
<constraint>
- <regex>^(upstream|downstream|disabled)$</regex>
+ <regex>(upstream|downstream|disabled)</regex>
</constraint>
</properties>
<defaultValue>downstream</defaultValue>
</leafNode>
<leafNode name="threshold">
<properties>
- <help>TTL threshold (default: 1)</help>
+ <help>TTL threshold</help>
<valueHelp>
<format>u32:1-255</format>
- <description>TTL threshold for the interfaces (default: 1)</description>
+ <description>TTL threshold for the interfaces</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-255"/>
diff --git a/interface-definitions/include/accel-ppp/auth-mode.xml.i b/interface-definitions/include/accel-ppp/auth-mode.xml.i
index a7711b675..c1a87cfe3 100644
--- a/interface-definitions/include/accel-ppp/auth-mode.xml.i
+++ b/interface-definitions/include/accel-ppp/auth-mode.xml.i
@@ -11,7 +11,7 @@
<description>Use RADIUS server for user autentication</description>
</valueHelp>
<constraint>
- <regex>^(local|radius)$</regex>
+ <regex>(local|radius)</regex>
</constraint>
<completionHelp>
<list>local radius</list>
diff --git a/interface-definitions/include/accel-ppp/auth-protocols.xml.i b/interface-definitions/include/accel-ppp/auth-protocols.xml.i
index 480747f53..d43266152 100644
--- a/interface-definitions/include/accel-ppp/auth-protocols.xml.i
+++ b/interface-definitions/include/accel-ppp/auth-protocols.xml.i
@@ -22,7 +22,7 @@
<description>Authentication via MS-CHAPv2 (Microsoft Challenge Handshake Authentication Protocol, version 2)</description>
</valueHelp>
<constraint>
- <regex>^(pap|chap|mschap|mschap-v2)$</regex>
+ <regex>(pap|chap|mschap|mschap-v2)</regex>
</constraint>
<multi/>
</properties>
diff --git a/interface-definitions/include/accel-ppp/client-ip-pool-subnet-single.xml.i b/interface-definitions/include/accel-ppp/client-ip-pool-subnet-single.xml.i
new file mode 100644
index 000000000..e5918b765
--- /dev/null
+++ b/interface-definitions/include/accel-ppp/client-ip-pool-subnet-single.xml.i
@@ -0,0 +1,15 @@
+<!-- include start from accel-ppp/client-ip-pool-subnet-single.xml.i -->
+<leafNode name="subnet">
+ <properties>
+ <help>Client IP subnet (CIDR notation)</help>
+ <valueHelp>
+ <format>ipv4net</format>
+ <description>IPv4 address and prefix length</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv4-prefix"/>
+ </constraint>
+ <constraintErrorMessage>Not a valid CIDR formatted prefix</constraintErrorMessage>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/accel-ppp/client-ipv6-pool.xml.i b/interface-definitions/include/accel-ppp/client-ipv6-pool.xml.i
index a692f2335..01cf0e040 100644
--- a/interface-definitions/include/accel-ppp/client-ipv6-pool.xml.i
+++ b/interface-definitions/include/accel-ppp/client-ipv6-pool.xml.i
@@ -21,7 +21,7 @@
<help>Prefix length used for individual client</help>
<valueHelp>
<format>u32:48-128</format>
- <description>Client prefix length (default: 64)</description>
+ <description>Client prefix length</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 48-128"/>
diff --git a/interface-definitions/include/accel-ppp/ppp-mppe.xml.i b/interface-definitions/include/accel-ppp/ppp-mppe.xml.i
index e8370180b..4c2e84c25 100644
--- a/interface-definitions/include/accel-ppp/ppp-mppe.xml.i
+++ b/interface-definitions/include/accel-ppp/ppp-mppe.xml.i
@@ -18,7 +18,7 @@
<description>drop all mppe</description>
</valueHelp>
<constraint>
- <regex>^(require|prefer|deny)$</regex>
+ <regex>(require|prefer|deny)</regex>
</constraint>
</properties>
<defaultValue>prefer</defaultValue>
diff --git a/interface-definitions/include/accel-ppp/ppp-options-ipv4.xml.i b/interface-definitions/include/accel-ppp/ppp-options-ipv4.xml.i
index 3e065329d..a45390f43 100644
--- a/interface-definitions/include/accel-ppp/ppp-options-ipv4.xml.i
+++ b/interface-definitions/include/accel-ppp/ppp-options-ipv4.xml.i
@@ -3,7 +3,7 @@
<properties>
<help>IPv4 negotiation algorithm</help>
<constraint>
- <regex>^(deny|allow)$</regex>
+ <regex>(deny|allow)</regex>
</constraint>
<constraintErrorMessage>invalid value</constraintErrorMessage>
<valueHelp>
diff --git a/interface-definitions/include/accel-ppp/ppp-options-ipv6.xml.i b/interface-definitions/include/accel-ppp/ppp-options-ipv6.xml.i
index b9fbac5c6..98abc1111 100644
--- a/interface-definitions/include/accel-ppp/ppp-options-ipv6.xml.i
+++ b/interface-definitions/include/accel-ppp/ppp-options-ipv6.xml.i
@@ -3,7 +3,7 @@
<properties>
<help>IPv6 (IPCP6) negotiation algorithm</help>
<constraint>
- <regex>^(deny|allow|prefer|require)$</regex>
+ <regex>(deny|allow|prefer|require)</regex>
</constraint>
<constraintErrorMessage>invalid value</constraintErrorMessage>
<valueHelp>
diff --git a/interface-definitions/include/accel-ppp/radius-additions-rate-limit.xml.i b/interface-definitions/include/accel-ppp/radius-additions-rate-limit.xml.i
index be49fce5a..f44920c3f 100644
--- a/interface-definitions/include/accel-ppp/radius-additions-rate-limit.xml.i
+++ b/interface-definitions/include/accel-ppp/radius-additions-rate-limit.xml.i
@@ -21,6 +21,20 @@
<valueless />
</properties>
</leafNode>
+ <leafNode name="multiplier">
+ <properties>
+ <help>Shaper multiplier</help>
+ <valueHelp>
+ <format>&lt;0.001-1000&gt;</format>
+ <description>Shaper multiplier</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0.001-1000 --float"/>
+ </constraint>
+ <constraintErrorMessage>Multiplier needs to be between 0.001 and 1000</constraintErrorMessage>
+ </properties>
+ <defaultValue>1</defaultValue>
+ </leafNode>
</children>
</node>
<!-- include end -->
diff --git a/interface-definitions/include/accel-ppp/radius-additions.xml.i b/interface-definitions/include/accel-ppp/radius-additions.xml.i
index 258ece2b5..441c9dda5 100644
--- a/interface-definitions/include/accel-ppp/radius-additions.xml.i
+++ b/interface-definitions/include/accel-ppp/radius-additions.xml.i
@@ -21,7 +21,7 @@
<help>Accounting port</help>
<valueHelp>
<format>u32:1-65535</format>
- <description>Numeric IP port (default: 1813)</description>
+ <description>Numeric IP port</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-65535"/>
@@ -62,7 +62,7 @@
</leafNode>
<leafNode name="acct-timeout">
<properties>
- <help>Timeout for Interim-Update packets, terminate session afterwards (default 3 seconds)</help>
+ <help>Timeout for Interim-Update packets, terminate session afterwards</help>
<valueHelp>
<format>u32:0-60</format>
<description>Timeout in seconds, 0 to keep active</description>
@@ -126,7 +126,7 @@
</leafNode>
<leafNode name="port">
<properties>
- <help>Port for Dynamic Authorization Extension server (DM/CoA) (default: 1700)</help>
+ <help>Port for Dynamic Authorization Extension server (DM/CoA)</help>
<valueHelp>
<format>u32:1-65535</format>
<description>TCP port</description>
diff --git a/interface-definitions/include/arp-ndp-table-size.xml.i b/interface-definitions/include/arp-ndp-table-size.xml.i
new file mode 100644
index 000000000..dec86e91a
--- /dev/null
+++ b/interface-definitions/include/arp-ndp-table-size.xml.i
@@ -0,0 +1,14 @@
+<!-- include start from arp-ndp-table-size.xml.i -->
+<leafNode name="table-size">
+ <properties>
+ <help>Maximum number of entries to keep in the cache</help>
+ <completionHelp>
+ <list>1024 2048 4096 8192 16384 32768</list>
+ </completionHelp>
+ <constraint>
+ <regex>(1024|2048|4096|8192|16384|32768)</regex>
+ </constraint>
+ </properties>
+ <defaultValue>8192</defaultValue>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/auth-local-users.xml.i b/interface-definitions/include/auth-local-users.xml.i
index 8ef09554e..9fb507474 100644
--- a/interface-definitions/include/auth-local-users.xml.i
+++ b/interface-definitions/include/auth-local-users.xml.i
@@ -7,6 +7,10 @@
<tagNode name="username">
<properties>
<help>Username used for authentication</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Username used for authentication</description>
+ </valueHelp>
</properties>
<children>
#include <include/generic-disable-node.xml.i>
diff --git a/interface-definitions/include/bfd.xml.i b/interface-definitions/include/bfd.xml.i
deleted file mode 100644
index 2bc3664e1..000000000
--- a/interface-definitions/include/bfd.xml.i
+++ /dev/null
@@ -1,8 +0,0 @@
-<!-- include start from bfd.xml.i -->
-<leafNode name="bfd">
- <properties>
- <help>Enable Bidirectional Forwarding Detection (BFD)</help>
- <valueless/>
- </properties>
-</leafNode>
-<!-- include end -->
diff --git a/interface-definitions/include/bfd/bfd.xml.i b/interface-definitions/include/bfd/bfd.xml.i
new file mode 100644
index 000000000..022956d98
--- /dev/null
+++ b/interface-definitions/include/bfd/bfd.xml.i
@@ -0,0 +1,10 @@
+<!-- include start from bfd/bfd.xml.i -->
+<node name="bfd">
+ <properties>
+ <help>Enable Bidirectional Forwarding Detection (BFD)</help>
+ </properties>
+ <children>
+ #include <include/bfd/profile.xml.i>
+ </children>
+</node>
+<!-- include end -->
diff --git a/interface-definitions/include/bfd-common.xml.i b/interface-definitions/include/bfd/common.xml.i
index 1d6ab5d55..126ab9b9a 100644
--- a/interface-definitions/include/bfd-common.xml.i
+++ b/interface-definitions/include/bfd/common.xml.i
@@ -1,4 +1,4 @@
-<!-- include start from bfd-common.xml.i -->
+<!-- include start from bfd/common.xml.i -->
<leafNode name="echo-mode">
<properties>
<help>Enables the echo transmission mode</help>
@@ -63,6 +63,12 @@
</leafNode>
</children>
</node>
+<leafNode name="passive">
+ <properties>
+ <help>Do not attempt to start sessions</help>
+ <valueless/>
+ </properties>
+</leafNode>
<leafNode name="shutdown">
<properties>
<help>Disable this peer</help>
diff --git a/interface-definitions/include/bfd/profile.xml.i b/interface-definitions/include/bfd/profile.xml.i
new file mode 100644
index 000000000..5ff057286
--- /dev/null
+++ b/interface-definitions/include/bfd/profile.xml.i
@@ -0,0 +1,14 @@
+<!-- include start from bfd/profile.xml.i -->
+<leafNode name="profile">
+ <properties>
+ <help>Use settings from BFD profile</help>
+ <completionHelp>
+ <path>protocols bfd profile</path>
+ </completionHelp>
+ <valueHelp>
+ <format>txt</format>
+ <description>BFD profile name</description>
+ </valueHelp>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/bgp/afi-ipv4-prefix-list.xml.i b/interface-definitions/include/bgp/afi-ipv4-prefix-list.xml.i
index de42eeac9..34b5ec7d7 100644
--- a/interface-definitions/include/bgp/afi-ipv4-prefix-list.xml.i
+++ b/interface-definitions/include/bgp/afi-ipv4-prefix-list.xml.i
@@ -15,7 +15,7 @@
<description>Name of IPv4 prefix-list</description>
</valueHelp>
<constraint>
- <regex>^[-_a-zA-Z0-9]+$</regex>
+ <regex>[-_a-zA-Z0-9]+</regex>
</constraint>
<constraintErrorMessage>Name of prefix-list can only contain alpha-numeric letters, hyphen and underscores</constraintErrorMessage>
</properties>
@@ -31,7 +31,7 @@
<description>Name of IPv4 prefix-list</description>
</valueHelp>
<constraint>
- <regex>^[-_a-zA-Z0-9]+$</regex>
+ <regex>[-_a-zA-Z0-9]+</regex>
</constraint>
<constraintErrorMessage>Name of prefix-list can only contain alpha-numeric letters, hyphen and underscores</constraintErrorMessage>
</properties>
diff --git a/interface-definitions/include/bgp/afi-ipv6-prefix-list.xml.i b/interface-definitions/include/bgp/afi-ipv6-prefix-list.xml.i
index 2bf4753be..06c661a90 100644
--- a/interface-definitions/include/bgp/afi-ipv6-prefix-list.xml.i
+++ b/interface-definitions/include/bgp/afi-ipv6-prefix-list.xml.i
@@ -15,7 +15,7 @@
<description>Name of IPv6 prefix-list</description>
</valueHelp>
<constraint>
- <regex>^[-_a-zA-Z0-9]+$</regex>
+ <regex>[-_a-zA-Z0-9]+</regex>
</constraint>
<constraintErrorMessage>Name of prefix-list6 can only contain alpha-numeric letters, hyphen and underscores</constraintErrorMessage>
</properties>
@@ -31,7 +31,7 @@
<description>Name of IPv6 prefix-list</description>
</valueHelp>
<constraint>
- <regex>^[-_a-zA-Z0-9]+$</regex>
+ <regex>[-_a-zA-Z0-9]+</regex>
</constraint>
<constraintErrorMessage>Name of prefix-list6 can only contain alpha-numeric letters, hyphen and underscores</constraintErrorMessage>
</properties>
diff --git a/interface-definitions/include/bgp/afi-l2vpn-common.xml.i b/interface-definitions/include/bgp/afi-l2vpn-common.xml.i
index 8deb189ab..d586635c8 100644
--- a/interface-definitions/include/bgp/afi-l2vpn-common.xml.i
+++ b/interface-definitions/include/bgp/afi-l2vpn-common.xml.i
@@ -25,7 +25,7 @@
<description>Route target (A.B.C.D:MN|EF:OPQR|GHJK:MN)</description>
</valueHelp>
<constraint>
- <validator name="bgp-route-target" argument="--single"/>
+ <validator name="bgp-rd-rt" argument="--route-target"/>
</constraint>
</properties>
</leafNode>
@@ -37,7 +37,7 @@
<description>Route target (A.B.C.D:MN|EF:OPQR|GHJK:MN)</description>
</valueHelp>
<constraint>
- <validator name="bgp-route-target" argument="--single"/>
+ <validator name="bgp-rd-rt" argument="--route-target"/>
</constraint>
</properties>
</leafNode>
@@ -49,7 +49,7 @@
<description>Route target (A.B.C.D:MN|EF:OPQR|GHJK:MN)</description>
</valueHelp>
<constraint>
- <validator name="bgp-route-target" argument="--single"/>
+ <validator name="bgp-rd-rt" argument="--route-target"/>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/include/bgp/afi-label.xml.i b/interface-definitions/include/bgp/afi-label.xml.i
index f7a1f609f..9535d19e8 100644
--- a/interface-definitions/include/bgp/afi-label.xml.i
+++ b/interface-definitions/include/bgp/afi-label.xml.i
@@ -25,7 +25,7 @@
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-1048575"/>
- <regex>^(auto)$</regex>
+ <regex>(auto)</regex>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/include/bgp/afi-rd.xml.i b/interface-definitions/include/bgp/afi-rd.xml.i
index c4d29268c..767502094 100644
--- a/interface-definitions/include/bgp/afi-rd.xml.i
+++ b/interface-definitions/include/bgp/afi-rd.xml.i
@@ -17,7 +17,7 @@
<description>Route Distinguisher, (x.x.x.x:yyy|xxxx:yyyy)</description>
</valueHelp>
<constraint>
- <regex>^((25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9][0-9]|[0-9]?)(\.(25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9][0-9]|[0-9]?)){3}|[0-9]{1,10}):[0-9]{1,5}$</regex>
+ <regex>((25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9][0-9]|[0-9]?)(\.(25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9][0-9]|[0-9]?)){3}|[0-9]{1,10}):[0-9]{1,5}</regex>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/include/bgp/afi-route-map-export-import.xml.i b/interface-definitions/include/bgp/afi-route-map-export-import.xml.i
index eae10d312..c218937c8 100644
--- a/interface-definitions/include/bgp/afi-route-map-export-import.xml.i
+++ b/interface-definitions/include/bgp/afi-route-map-export-import.xml.i
@@ -10,7 +10,7 @@
<description>Route map name</description>
</valueHelp>
<constraint>
- <regex>^[-_a-zA-Z0-9.]+$</regex>
+ <regex>[-_a-zA-Z0-9.]+</regex>
</constraint>
<constraintErrorMessage>Name of route-map can only contain alpha-numeric letters, hyphen and underscores</constraintErrorMessage>
</properties>
@@ -26,7 +26,7 @@
<description>Route map name</description>
</valueHelp>
<constraint>
- <regex>^[-_a-zA-Z0-9.]+$</regex>
+ <regex>[-_a-zA-Z0-9.]+</regex>
</constraint>
<constraintErrorMessage>Name of route-map can only contain alpha-numeric letters, hyphen and underscores</constraintErrorMessage>
</properties>
diff --git a/interface-definitions/include/bgp/afi-route-target-vpn.xml.i b/interface-definitions/include/bgp/afi-route-target-vpn.xml.i
index 0cd0fdd76..5784f9eac 100644
--- a/interface-definitions/include/bgp/afi-route-target-vpn.xml.i
+++ b/interface-definitions/include/bgp/afi-route-target-vpn.xml.i
@@ -17,7 +17,7 @@
<description>Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)</description>
</valueHelp>
<constraint>
- <validator name="bgp-route-target" argument="--multi"/>
+ <validator name="bgp-rd-rt" argument="--route-target-multi"/>
</constraint>
</properties>
</leafNode>
@@ -29,7 +29,7 @@
<description>Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)</description>
</valueHelp>
<constraint>
- <validator name="bgp-route-target" argument="--multi"/>
+ <validator name="bgp-rd-rt" argument="--route-target-multi"/>
</constraint>
</properties>
</leafNode>
@@ -41,7 +41,7 @@
<description>Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)</description>
</valueHelp>
<constraint>
- <validator name="bgp-route-target" argument="--multi"/>
+ <validator name="bgp-rd-rt" argument="--route-target-multi"/>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/include/bgp/afi-common.xml.i b/interface-definitions/include/bgp/neighbor-afi-ipv4-ipv6-common.xml.i
index 62beff40c..75221a348 100644
--- a/interface-definitions/include/bgp/afi-common.xml.i
+++ b/interface-definitions/include/bgp/neighbor-afi-ipv4-ipv6-common.xml.i
@@ -1,4 +1,4 @@
-<!-- include start from bgp/afi-common.xml.i -->
+<!-- include start from bgp/neighbor-afi-ipv4-ipv6-common.xml.i -->
<leafNode name="addpath-tx-all">
<properties>
<help>Use addpath to advertise all paths to a neighbor</help>
@@ -11,10 +11,65 @@
<valueless/>
</properties>
</leafNode>
+<node name="conditionally-advertise">
+ <properties>
+ <help>Use route-map to conditionally advertise routes</help>
+ </properties>
+ <children>
+ <leafNode name="advertise-map">
+ <properties>
+ <help>Route-map to conditionally advertise routes</help>
+ <completionHelp>
+ <path>policy route-map</path>
+ </completionHelp>
+ <valueHelp>
+ <format>txt</format>
+ <description>Route map name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[-_a-zA-Z0-9.]+</regex>
+ </constraint>
+ <constraintErrorMessage>Name of route-map can only contain alpha-numeric letters, hyphen and underscores</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ <leafNode name="exist-map">
+ <properties>
+ <help>Advertise routes only if prefixes in exist-map are installed in BGP table</help>
+ <completionHelp>
+ <path>policy route-map</path>
+ </completionHelp>
+ <valueHelp>
+ <format>txt</format>
+ <description>Route map name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[-_a-zA-Z0-9.]+</regex>
+ </constraint>
+ <constraintErrorMessage>Name of route-map can only contain alpha-numeric letters, hyphen and underscores</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ <leafNode name="non-exist-map">
+ <properties>
+ <help>Advertise routes only if prefixes in non-exist-map are not installed in BGP table</help>
+ <completionHelp>
+ <path>policy route-map</path>
+ </completionHelp>
+ <valueHelp>
+ <format>txt</format>
+ <description>Route map name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[-_a-zA-Z0-9.]+</regex>
+ </constraint>
+ <constraintErrorMessage>Name of route-map can only contain alpha-numeric letters, hyphen and underscores</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ </children>
+</node>
#include <include/bgp/afi-allowas-in.xml.i>
<leafNode name="as-override">
<properties>
- <help>AS for routes sent to this peer to be the local AS</help>
+ <help>Override ASN in outbound updates to configured neighbor local-as</help>
<valueless/>
</properties>
</leafNode>
@@ -122,7 +177,7 @@
<description>Route map name</description>
</valueHelp>
<constraint>
- <regex>^[-_a-zA-Z0-9.]+$</regex>
+ <regex>[-_a-zA-Z0-9.]+</regex>
</constraint>
<constraintErrorMessage>Name of route-map can only contain alpha-numeric letters, hyphen and underscores</constraintErrorMessage>
</properties>
diff --git a/interface-definitions/include/bgp/neighbor-afi-ipv4-labeled-unicast.xml.i b/interface-definitions/include/bgp/neighbor-afi-ipv4-labeled-unicast.xml.i
index 45a440fd8..0eae29f5e 100644
--- a/interface-definitions/include/bgp/neighbor-afi-ipv4-labeled-unicast.xml.i
+++ b/interface-definitions/include/bgp/neighbor-afi-ipv4-labeled-unicast.xml.i
@@ -13,7 +13,7 @@
</children>
</node>
#include <include/bgp/afi-ipv4-prefix-list.xml.i>
- #include <include/bgp/afi-common.xml.i>
+ #include <include/bgp/neighbor-afi-ipv4-ipv6-common.xml.i>
#include <include/bgp/afi-default-originate.xml.i>
</children>
</node>
diff --git a/interface-definitions/include/bgp/neighbor-afi-ipv4-multicast.xml.i b/interface-definitions/include/bgp/neighbor-afi-ipv4-multicast.xml.i
index 6526169ca..4bb6df7c3 100644
--- a/interface-definitions/include/bgp/neighbor-afi-ipv4-multicast.xml.i
+++ b/interface-definitions/include/bgp/neighbor-afi-ipv4-multicast.xml.i
@@ -13,7 +13,7 @@
</children>
</node>
#include <include/bgp/afi-ipv4-prefix-list.xml.i>
- #include <include/bgp/afi-common.xml.i>
+ #include <include/bgp/neighbor-afi-ipv4-ipv6-common.xml.i>
#include <include/bgp/afi-default-originate.xml.i>
</children>
</node>
diff --git a/interface-definitions/include/bgp/neighbor-afi-ipv4-unicast.xml.i b/interface-definitions/include/bgp/neighbor-afi-ipv4-unicast.xml.i
index b7b7ca5b5..0094ce874 100644
--- a/interface-definitions/include/bgp/neighbor-afi-ipv4-unicast.xml.i
+++ b/interface-definitions/include/bgp/neighbor-afi-ipv4-unicast.xml.i
@@ -13,7 +13,7 @@
</children>
</node>
#include <include/bgp/afi-ipv4-prefix-list.xml.i>
- #include <include/bgp/afi-common.xml.i>
+ #include <include/bgp/neighbor-afi-ipv4-ipv6-common.xml.i>
#include <include/bgp/afi-default-originate.xml.i>
</children>
</node>
diff --git a/interface-definitions/include/bgp/neighbor-afi-ipv4-vpn.xml.i b/interface-definitions/include/bgp/neighbor-afi-ipv4-vpn.xml.i
index 838327bc9..220f22fe3 100644
--- a/interface-definitions/include/bgp/neighbor-afi-ipv4-vpn.xml.i
+++ b/interface-definitions/include/bgp/neighbor-afi-ipv4-vpn.xml.i
@@ -5,7 +5,7 @@
</properties>
<children>
#include <include/bgp/afi-ipv4-prefix-list.xml.i>
- #include <include/bgp/afi-common.xml.i>
+ #include <include/bgp/neighbor-afi-ipv4-ipv6-common.xml.i>
</children>
</node>
<!-- include end -->
diff --git a/interface-definitions/include/bgp/neighbor-afi-ipv6-labeled-unicast.xml.i b/interface-definitions/include/bgp/neighbor-afi-ipv6-labeled-unicast.xml.i
index f680b7357..995183571 100644
--- a/interface-definitions/include/bgp/neighbor-afi-ipv6-labeled-unicast.xml.i
+++ b/interface-definitions/include/bgp/neighbor-afi-ipv6-labeled-unicast.xml.i
@@ -14,7 +14,7 @@
</node>
#include <include/bgp/afi-ipv6-nexthop-local.xml.i>
#include <include/bgp/afi-ipv6-prefix-list.xml.i>
- #include <include/bgp/afi-common.xml.i>
+ #include <include/bgp/neighbor-afi-ipv4-ipv6-common.xml.i>
#include <include/bgp/afi-default-originate.xml.i>
</children>
</node>
diff --git a/interface-definitions/include/bgp/neighbor-afi-ipv6-multicast.xml.i b/interface-definitions/include/bgp/neighbor-afi-ipv6-multicast.xml.i
index 1f8db8361..bb713c313 100644
--- a/interface-definitions/include/bgp/neighbor-afi-ipv6-multicast.xml.i
+++ b/interface-definitions/include/bgp/neighbor-afi-ipv6-multicast.xml.i
@@ -6,7 +6,7 @@
<children>
#include <include/bgp/afi-ipv6-nexthop-local.xml.i>
#include <include/bgp/afi-ipv6-prefix-list.xml.i>
- #include <include/bgp/afi-common.xml.i>
+ #include <include/bgp/neighbor-afi-ipv4-ipv6-common.xml.i>
#include <include/bgp/afi-default-originate.xml.i>
</children>
</node>
diff --git a/interface-definitions/include/bgp/neighbor-afi-ipv6-unicast.xml.i b/interface-definitions/include/bgp/neighbor-afi-ipv6-unicast.xml.i
index f6b812c28..26a5e7090 100644
--- a/interface-definitions/include/bgp/neighbor-afi-ipv6-unicast.xml.i
+++ b/interface-definitions/include/bgp/neighbor-afi-ipv6-unicast.xml.i
@@ -14,7 +14,7 @@
</node>
#include <include/bgp/afi-ipv6-nexthop-local.xml.i>
#include <include/bgp/afi-ipv6-prefix-list.xml.i>
- #include <include/bgp/afi-common.xml.i>
+ #include <include/bgp/neighbor-afi-ipv4-ipv6-common.xml.i>
#include <include/bgp/afi-default-originate.xml.i>
</children>
</node>
diff --git a/interface-definitions/include/bgp/neighbor-afi-ipv6-vpn.xml.i b/interface-definitions/include/bgp/neighbor-afi-ipv6-vpn.xml.i
index c0df71cf3..5c6811986 100644
--- a/interface-definitions/include/bgp/neighbor-afi-ipv6-vpn.xml.i
+++ b/interface-definitions/include/bgp/neighbor-afi-ipv6-vpn.xml.i
@@ -6,7 +6,7 @@
<children>
#include <include/bgp/afi-ipv6-nexthop-local.xml.i>
#include <include/bgp/afi-ipv6-prefix-list.xml.i>
- #include <include/bgp/afi-common.xml.i>
+ #include <include/bgp/neighbor-afi-ipv4-ipv6-common.xml.i>
</children>
</node>
<!-- include end -->
diff --git a/interface-definitions/include/bgp/neighbor-bfd.xml.i b/interface-definitions/include/bgp/neighbor-bfd.xml.i
index d486bdd8a..fac2a1166 100644
--- a/interface-definitions/include/bgp/neighbor-bfd.xml.i
+++ b/interface-definitions/include/bgp/neighbor-bfd.xml.i
@@ -4,6 +4,7 @@
<help>Enable Bidirectional Forwarding Detection (BFD) support</help>
</properties>
<children>
+ #include <include/bfd/profile.xml.i>
<leafNode name="check-control-plane-failure">
<properties>
<help>Allow to write CBIT independence in BFD outgoing packets and read both C-BIT value of BFD and lookup BGP peer status</help>
diff --git a/interface-definitions/include/bgp/neighbor-graceful-restart.xml.i b/interface-definitions/include/bgp/neighbor-graceful-restart.xml.i
index 25558cd5c..4399d7988 100644
--- a/interface-definitions/include/bgp/neighbor-graceful-restart.xml.i
+++ b/interface-definitions/include/bgp/neighbor-graceful-restart.xml.i
@@ -18,7 +18,7 @@
<description>Enable BGP graceful restart helper only functionality</description>
</valueHelp>
<constraint>
- <regex>^(enable|disable|restart-helper)$</regex>
+ <regex>(enable|disable|restart-helper)</regex>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/include/bgp/neighbor-shutdown.xml.i b/interface-definitions/include/bgp/neighbor-shutdown.xml.i
index 6d15899a6..acc7bc5a9 100644
--- a/interface-definitions/include/bgp/neighbor-shutdown.xml.i
+++ b/interface-definitions/include/bgp/neighbor-shutdown.xml.i
@@ -1,7 +1,7 @@
<!-- include start from bgp/neighbor-shutdown.xml.i -->
<leafNode name="shutdown">
<properties>
- <help>Administratively shut down this neighbor</help>
+ <help>Administratively shutdown this neighbor</help>
<valueless/>
</properties>
</leafNode>
diff --git a/interface-definitions/include/bgp/protocol-common-config.xml.i b/interface-definitions/include/bgp/protocol-common-config.xml.i
index 2dfae517e..abaff5232 100644
--- a/interface-definitions/include/bgp/protocol-common-config.xml.i
+++ b/interface-definitions/include/bgp/protocol-common-config.xml.i
@@ -1106,7 +1106,7 @@
<description>Ignore paths without link bandwidth for ECMP (if other paths have it)</description>
</valueHelp>
<constraint>
- <regex>^(default-weight-for-missing|ignore|skip-missing)$</regex>
+ <regex>(default-weight-for-missing|ignore|skip-missing)</regex>
</constraint>
</properties>
</leafNode>
@@ -1181,6 +1181,26 @@
</leafNode>
</children>
</node>
+ <node name="conditional-advertisement">
+ <properties>
+ <help>Conditional advertisement settings</help>
+ </properties>
+ <children>
+ <leafNode name="timer">
+ <properties>
+ <help>Set period to rescan BGP table to check if condition is met</help>
+ <valueHelp>
+ <format>u32:5-240</format>
+ <description>Period to rerun the conditional advertisement scanner process</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 5-240"/>
+ </constraint>
+ </properties>
+ <defaultValue>60</defaultValue>
+ </leafNode>
+ </children>
+ </node>
<node name="dampening">
<properties>
<help>Enable route-flap dampening</help>
@@ -1343,6 +1363,12 @@
<valueless/>
</properties>
</leafNode>
+ <leafNode name="fast-convergence">
+ <properties>
+ <help>Teardown sessions immediately whenever peer becomes unreachable</help>
+ <valueless/>
+ </properties>
+ </leafNode>
<node name="graceful-restart">
<properties>
<help>Graceful restart capability parameters</help>
@@ -1374,6 +1400,18 @@
<valueless/>
</properties>
</leafNode>
+ <leafNode name="minimum-holdtime">
+ <properties>
+ <help>BGP minimum holdtime</help>
+ <valueHelp>
+ <format>u32:1-65535</format>
+ <description>Minimum holdtime in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-65535"/>
+ </constraint>
+ </properties>
+ </leafNode>
<leafNode name="network-import-check">
<properties>
<help>Enable IGP route check for network statements</help>
@@ -1392,6 +1430,30 @@
<valueless/>
</properties>
</leafNode>
+ <leafNode name="no-suppress-duplicates">
+ <properties>
+ <help>Disable suppress duplicate updates if the route actually not changed</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="reject-as-sets">
+ <properties>
+ <help>Reject routes with AS_SET or AS_CONFED_SET flag</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="shutdown">
+ <properties>
+ <help>Administrative shutdown of the BGP instance</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="suppress-fib-pending">
+ <properties>
+ <help>Advertise only routes that are programmed in kernel to peers</help>
+ <valueless/>
+ </properties>
+ </leafNode>
#include <include/router-id.xml.i>
</children>
</node>
@@ -1399,7 +1461,7 @@
<properties>
<help>Name of peer-group</help>
<constraint>
- <regex>^[-_a-zA-Z0-9]+$</regex>
+ <regex>[-_a-zA-Z0-9]+</regex>
</constraint>
</properties>
<children>
@@ -1441,4 +1503,4 @@
#include <include/bgp/timers-keepalive.xml.i>
</children>
</node>
-<!-- include end --> \ No newline at end of file
+<!-- include end -->
diff --git a/interface-definitions/include/bgp/remote-as.xml.i b/interface-definitions/include/bgp/remote-as.xml.i
index 11eb7c256..58595b3b9 100644
--- a/interface-definitions/include/bgp/remote-as.xml.i
+++ b/interface-definitions/include/bgp/remote-as.xml.i
@@ -19,7 +19,7 @@
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-4294967294"/>
- <regex>^(external|internal)$</regex>
+ <regex>(external|internal)</regex>
</constraint>
<constraintErrorMessage>Invalid AS number</constraintErrorMessage>
</properties>
diff --git a/interface-definitions/include/bgp/route-distinguisher.xml.i b/interface-definitions/include/bgp/route-distinguisher.xml.i
index 6d0aa3ef1..8bc5b452e 100644
--- a/interface-definitions/include/bgp/route-distinguisher.xml.i
+++ b/interface-definitions/include/bgp/route-distinguisher.xml.i
@@ -7,7 +7,7 @@
<description>Route Distinguisher, (x.x.x.x:yyy|xxxx:yyyy)</description>
</valueHelp>
<constraint>
- <regex>^((25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9][0-9]|[0-9]?)(\.(25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9][0-9]|[0-9]?)){3}|[0-9]{1,10}):[0-9]{1,5}$</regex>
+ <validator name="bgp-rd-rt" argument="--route-distinguisher"/>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/include/bgp/timers-keepalive.xml.i b/interface-definitions/include/bgp/timers-keepalive.xml.i
index b2771e326..b23f96ec8 100644
--- a/interface-definitions/include/bgp/timers-keepalive.xml.i
+++ b/interface-definitions/include/bgp/timers-keepalive.xml.i
@@ -4,7 +4,7 @@
<help>BGP keepalive interval for this neighbor</help>
<valueHelp>
<format>u32:1-65535</format>
- <description>Keepalive interval in seconds (default 60)</description>
+ <description>Keepalive interval in seconds</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-65535"/>
diff --git a/interface-definitions/include/conntrack/log-common.xml.i b/interface-definitions/include/conntrack/log-common.xml.i
new file mode 100644
index 000000000..38799f8f4
--- /dev/null
+++ b/interface-definitions/include/conntrack/log-common.xml.i
@@ -0,0 +1,20 @@
+<!-- include start from conntrack/log-common.xml.i -->
+<leafNode name="destroy">
+ <properties>
+ <help>Log connection deletion</help>
+ <valueless/>
+ </properties>
+</leafNode>
+<leafNode name="new">
+ <properties>
+ <help>Log connection creation</help>
+ <valueless/>
+ </properties>
+</leafNode>
+<leafNode name="update">
+ <properties>
+ <help>Log connection updates</help>
+ <valueless/>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/conntrack/timeout-common-protocols.xml.i b/interface-definitions/include/conntrack/timeout-common-protocols.xml.i
new file mode 100644
index 000000000..2676d846e
--- /dev/null
+++ b/interface-definitions/include/conntrack/timeout-common-protocols.xml.i
@@ -0,0 +1,172 @@
+<!-- include start from conntrack/timeout-common-protocols.xml.i -->
+<leafNode name="icmp">
+ <properties>
+ <help>ICMP timeout in seconds</help>
+ <valueHelp>
+ <format>u32:1-21474836</format>
+ <description>ICMP timeout in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-21474836"/>
+ </constraint>
+ </properties>
+ <defaultValue>30</defaultValue>
+</leafNode>
+<leafNode name="other">
+ <properties>
+ <help>Generic connection timeout in seconds</help>
+ <valueHelp>
+ <format>u32:1-21474836</format>
+ <description>Generic connection timeout in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-21474836"/>
+ </constraint>
+ </properties>
+ <defaultValue>600</defaultValue>
+</leafNode>
+<node name="tcp">
+ <properties>
+ <help>TCP connection timeout options</help>
+ </properties>
+ <children>
+ <leafNode name="close-wait">
+ <properties>
+ <help>TCP CLOSE-WAIT timeout in seconds</help>
+ <valueHelp>
+ <format>u32:1-21474836</format>
+ <description>TCP CLOSE-WAIT timeout in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-21474836"/>
+ </constraint>
+ </properties>
+ <defaultValue>60</defaultValue>
+ </leafNode>
+ <leafNode name="close">
+ <properties>
+ <help>TCP CLOSE timeout in seconds</help>
+ <valueHelp>
+ <format>u32:1-21474836</format>
+ <description>TCP CLOSE timeout in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-21474836"/>
+ </constraint>
+ </properties>
+ <defaultValue>10</defaultValue>
+ </leafNode>
+ <leafNode name="established">
+ <properties>
+ <help>TCP ESTABLISHED timeout in seconds</help>
+ <valueHelp>
+ <format>u32:1-21474836</format>
+ <description>TCP ESTABLISHED timeout in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-21474836"/>
+ </constraint>
+ </properties>
+ <defaultValue>432000</defaultValue>
+ </leafNode>
+ <leafNode name="fin-wait">
+ <properties>
+ <help>TCP FIN-WAIT timeout in seconds</help>
+ <valueHelp>
+ <format>u32:1-21474836</format>
+ <description>TCP FIN-WAIT timeout in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-21474836"/>
+ </constraint>
+ </properties>
+ <defaultValue>120</defaultValue>
+ </leafNode>
+ <leafNode name="last-ack">
+ <properties>
+ <help>TCP LAST-ACK timeout in seconds</help>
+ <valueHelp>
+ <format>u32:1-21474836</format>
+ <description>TCP LAST-ACK timeout in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-21474836"/>
+ </constraint>
+ </properties>
+ <defaultValue>30</defaultValue>
+ </leafNode>
+ <leafNode name="syn-recv">
+ <properties>
+ <help>TCP SYN-RECEIVED timeout in seconds</help>
+ <valueHelp>
+ <format>u32:1-21474836</format>
+ <description>TCP SYN-RECEIVED timeout in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-21474836"/>
+ </constraint>
+ </properties>
+ <defaultValue>60</defaultValue>
+ </leafNode>
+ <leafNode name="syn-sent">
+ <properties>
+ <help>TCP SYN-SENT timeout in seconds</help>
+ <valueHelp>
+ <format>u32:1-21474836</format>
+ <description>TCP SYN-SENT timeout in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-21474836"/>
+ </constraint>
+ </properties>
+ <defaultValue>120</defaultValue>
+ </leafNode>
+ <leafNode name="time-wait">
+ <properties>
+ <help>TCP TIME-WAIT timeout in seconds</help>
+ <valueHelp>
+ <format>u32:1-21474836</format>
+ <description>TCP TIME-WAIT timeout in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-21474836"/>
+ </constraint>
+ </properties>
+ <defaultValue>120</defaultValue>
+ </leafNode>
+ </children>
+</node>
+<node name="udp">
+ <properties>
+ <help>UDP timeout options</help>
+ </properties>
+ <children>
+ <leafNode name="other">
+ <properties>
+ <help>UDP generic timeout in seconds</help>
+ <valueHelp>
+ <format>u32:1-21474836</format>
+ <description>UDP generic timeout in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-21474836"/>
+ </constraint>
+ </properties>
+ <defaultValue>30</defaultValue>
+ </leafNode>
+ <leafNode name="stream">
+ <properties>
+ <help>UDP stream timeout in seconds</help>
+ <valueHelp>
+ <format>u32:1-21474836</format>
+ <description>UDP stream timeout in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-21474836"/>
+ </constraint>
+ </properties>
+ <defaultValue>180</defaultValue>
+ </leafNode>
+ </children>
+</node>
+<!-- include end -->
diff --git a/interface-definitions/include/dhcp/ntp-server.xml.i b/interface-definitions/include/dhcp/ntp-server.xml.i
index 32d8207e5..4d7235aa1 100644
--- a/interface-definitions/include/dhcp/ntp-server.xml.i
+++ b/interface-definitions/include/dhcp/ntp-server.xml.i
@@ -1,15 +1,15 @@
<!-- include start from dhcp/ntp-server.xml.i -->
- <leafNode name="ntp-server">
- <properties>
- <help>IP address of NTP server</help>
- <valueHelp>
- <format>ipv4</format>
- <description>NTP server IPv4 address</description>
- </valueHelp>
- <constraint>
- <validator name="ipv4-address"/>
- </constraint>
- <multi/>
- </properties>
- </leafNode>
+<leafNode name="ntp-server">
+ <properties>
+ <help>IP address of NTP server</help>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>NTP server IPv4 address</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv4-address"/>
+ </constraint>
+ <multi/>
+ </properties>
+</leafNode>
<!-- include end -->
diff --git a/interface-definitions/include/dns/time-to-live.xml.i b/interface-definitions/include/dns/time-to-live.xml.i
new file mode 100644
index 000000000..5c1a1472d
--- /dev/null
+++ b/interface-definitions/include/dns/time-to-live.xml.i
@@ -0,0 +1,15 @@
+<!-- include start from dns/time-to-live.xml.i -->
+<leafNode name="ttl">
+ <properties>
+ <help>Time-to-live (TTL)</help>
+ <valueHelp>
+ <format>u32:0-2147483647</format>
+ <description>TTL in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-2147483647"/>
+ </constraint>
+ </properties>
+ <defaultValue>300</defaultValue>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/firewall/action-accept-drop-reject.xml.i b/interface-definitions/include/firewall/action-accept-drop-reject.xml.i
index 9f8baa884..7fd52319a 100644
--- a/interface-definitions/include/firewall/action-accept-drop-reject.xml.i
+++ b/interface-definitions/include/firewall/action-accept-drop-reject.xml.i
@@ -18,7 +18,7 @@
<description>Action to reject</description>
</valueHelp>
<constraint>
- <regex>^(accept|drop|reject)$</regex>
+ <regex>(accept|drop|reject)</regex>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/include/firewall/action.xml.i b/interface-definitions/include/firewall/action.xml.i
index 230f590cb..0f60e3c38 100644
--- a/interface-definitions/include/firewall/action.xml.i
+++ b/interface-definitions/include/firewall/action.xml.i
@@ -3,18 +3,22 @@
<properties>
<help>Rule action [REQUIRED]</help>
<completionHelp>
- <list>permit deny</list>
+ <list>accept reject drop</list>
</completionHelp>
<valueHelp>
- <format>permit</format>
- <description>Permit matching entries</description>
+ <format>accept</format>
+ <description>Accept matching entries</description>
</valueHelp>
<valueHelp>
- <format>deny</format>
- <description>Deny matching entries</description>
+ <format>reject</format>
+ <description>Reject matching entries</description>
+ </valueHelp>
+ <valueHelp>
+ <format>drop</format>
+ <description>Drop matching entries</description>
</valueHelp>
<constraint>
- <regex>^(permit|deny)$</regex>
+ <regex>(accept|reject|drop)</regex>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/include/firewall/common-rule.xml.i b/interface-definitions/include/firewall/common-rule.xml.i
index a59c0b390..2a5137dbf 100644
--- a/interface-definitions/include/firewall/common-rule.xml.i
+++ b/interface-definitions/include/firewall/common-rule.xml.i
@@ -55,7 +55,7 @@
<help>Maximum number of packets to allow in excess of rate</help>
<valueHelp>
<format>u32:0-4294967295</format>
- <description>burst__change_me</description>
+ <description>Maximum number of packets to allow in excess of rate</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-4294967295"/>
@@ -66,11 +66,11 @@
<properties>
<help>Maximum average matching rate</help>
<valueHelp>
- <format>u32:0-4294967295</format>
- <description>rate__change_me</description>
+ <format>txt</format>
+ <description>integer/unit (Example: 5/minute)</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-4294967295"/>
+ <regex>\d+/(second|minute|hour|day)</regex>
</constraint>
</properties>
</leafNode>
@@ -91,15 +91,42 @@
<description>Disable log</description>
</valueHelp>
<constraint>
- <regex>^(enable|disable)$</regex>
+ <regex>(enable|disable)</regex>
</constraint>
</properties>
</leafNode>
+<node name="connection-status">
+ <properties>
+ <help>Connection status</help>
+ </properties>
+ <children>
+ <leafNode name="nat">
+ <properties>
+ <help>NAT connection status</help>
+ <completionHelp>
+ <list>destination source</list>
+ </completionHelp>
+ <valueHelp>
+ <format>destination</format>
+ <description>Match connections that are subject to destination NAT</description>
+ </valueHelp>
+ <valueHelp>
+ <format>source</format>
+ <description>Match connections that are subject to source NAT</description>
+ </valueHelp>
+ <constraint>
+ <regex>^(destination|source)$</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+</node>
<leafNode name="protocol">
<properties>
<help>Protocol to match (protocol name, number, or "all")</help>
<completionHelp>
- <script>cat /etc/protocols | sed -e '/^#.*/d' | awk '{ print $1 }'</script>
+ <script>${vyos_completion_dir}/list_protocols.sh</script>
+ <list>all tcp_udp</list>
</completionHelp>
<valueHelp>
<format>all</format>
@@ -114,14 +141,17 @@
<description>IP protocol number</description>
</valueHelp>
<valueHelp>
+ <format>&lt;protocol&gt;</format>
+ <description>IP protocol name</description>
+ </valueHelp>
+ <valueHelp>
<format>!&lt;protocol&gt;</format>
- <description>IP protocol number</description>
+ <description>IP protocol name</description>
</valueHelp>
<constraint>
<validator name="ip-protocol"/>
</constraint>
</properties>
- <defaultValue>all</defaultValue>
</leafNode>
<node name="recent">
<properties>
@@ -142,13 +172,24 @@
</leafNode>
<leafNode name="time">
<properties>
- <help>Source addresses seen in the last N seconds</help>
+ <help>Source addresses seen in the last second/minute/hour</help>
+ <completionHelp>
+ <list>second minute hour</list>
+ </completionHelp>
<valueHelp>
- <format>u32:0-4294967295</format>
- <description>Source addresses seen in the last N seconds</description>
+ <format>second</format>
+ <description>Source addresses seen COUNT times in the last second</description>
+ </valueHelp>
+ <valueHelp>
+ <format>minute</format>
+ <description>Source addresses seen COUNT times in the last minute</description>
+ </valueHelp>
+ <valueHelp>
+ <format>hour</format>
+ <description>Source addresses seen COUNT times in the last hour</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-4294967295"/>
+ <regex>(second|minute|hour)</regex>
</constraint>
</properties>
</leafNode>
@@ -172,6 +213,9 @@
<format>!&lt;MAC address&gt;</format>
<description>Match everything except the specified MAC address</description>
</valueHelp>
+ <constraint>
+ <validator name="mac-address-firewall"/>
+ </constraint>
</properties>
</leafNode>
#include <include/firewall/port.xml.i>
@@ -197,7 +241,7 @@
<description>Disable</description>
</valueHelp>
<constraint>
- <regex>^(enable|disable)$</regex>
+ <regex>(enable|disable)</regex>
</constraint>
</properties>
</leafNode>
@@ -216,7 +260,7 @@
<description>Disable</description>
</valueHelp>
<constraint>
- <regex>^(enable|disable)$</regex>
+ <regex>(enable|disable)</regex>
</constraint>
</properties>
</leafNode>
@@ -235,7 +279,7 @@
<description>Disable</description>
</valueHelp>
<constraint>
- <regex>^(enable|disable)$</regex>
+ <regex>(enable|disable)</regex>
</constraint>
</properties>
</leafNode>
@@ -254,71 +298,77 @@
<description>Disable</description>
</valueHelp>
<constraint>
- <regex>^(enable|disable)$</regex>
+ <regex>(enable|disable)</regex>
</constraint>
</properties>
</leafNode>
</children>
</node>
-<node name="tcp">
- <properties>
- <help>TCP flags to match</help>
- </properties>
- <children>
- <leafNode name="flags">
- <properties>
- <help>TCP flags to match</help>
- <valueHelp>
- <format>txt</format>
- <description>TCP flags to match</description>
- </valueHelp>
- <valueHelp>
- <format> </format>
- <description>\n\n Allowed values for TCP flags : SYN ACK FIN RST URG PSH ALL\n When specifying more than one flag, flags should be comma-separated.\n For example : value of 'SYN,!ACK,!FIN,!RST' will only match packets with\n the SYN flag set, and the ACK, FIN and RST flags unset</description>
- </valueHelp>
- </properties>
- </leafNode>
- </children>
-</node>
+#include <include/firewall/tcp-flags.xml.i>
<node name="time">
<properties>
<help>Time to match rule</help>
</properties>
<children>
- <leafNode name="monthdays">
- <properties>
- <help>Monthdays to match rule on</help>
- </properties>
- </leafNode>
<leafNode name="startdate">
<properties>
<help>Date to start matching rule</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Enter date using following notation - YYYY-MM-DD</description>
+ </valueHelp>
+ <constraint>
+ <regex>(\d{4}\-\d{2}\-\d{2})</regex>
+ </constraint>
</properties>
</leafNode>
<leafNode name="starttime">
<properties>
<help>Time of day to start matching rule</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Enter time using using 24 hour notation - hh:mm:ss</description>
+ </valueHelp>
+ <constraint>
+ <regex>([0-2][0-9](\:[0-5][0-9]){1,2})</regex>
+ </constraint>
</properties>
</leafNode>
<leafNode name="stopdate">
<properties>
<help>Date to stop matching rule</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Enter date using following notation - YYYY-MM-DD</description>
+ </valueHelp>
+ <constraint>
+ <regex>(\d{4}\-\d{2}\-\d{2})</regex>
+ </constraint>
</properties>
</leafNode>
<leafNode name="stoptime">
<properties>
<help>Time of day to stop matching rule</help>
- </properties>
- </leafNode>
- <leafNode name="utc">
- <properties>
- <help>Interpret times for startdate, stopdate, starttime and stoptime to be UTC</help>
- <valueless/>
+ <valueHelp>
+ <format>txt</format>
+ <description>Enter time using using 24 hour notation - hh:mm:ss</description>
+ </valueHelp>
+ <constraint>
+ <regex>([0-2][0-9](\:[0-5][0-9]){1,2})</regex>
+ </constraint>
</properties>
</leafNode>
<leafNode name="weekdays">
<properties>
- <help>Weekdays to match rule on</help>
+ <help>Comma separated weekdays to match rule on</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Name of day (Monday, Tuesday, Wednesday, Thursdays, Friday, Saturday, Sunday)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>u32:0-6</format>
+ <description>Day number (0 = Sunday ... 6 = Saturday)</description>
+ </valueHelp>
</properties>
</leafNode>
</children>
diff --git a/interface-definitions/include/firewall/icmp-type-name.xml.i b/interface-definitions/include/firewall/icmp-type-name.xml.i
index b45fb619b..d4197cf82 100644
--- a/interface-definitions/include/firewall/icmp-type-name.xml.i
+++ b/interface-definitions/include/firewall/icmp-type-name.xml.i
@@ -3,170 +3,70 @@
<properties>
<help>ICMP type-name</help>
<completionHelp>
- <list>any echo-reply pong destination-unreachable network-unreachable host-unreachable protocol-unreachable port-unreachable fragmentation-needed source-route-failed network-unknown host-unknown network-prohibited host-prohibited TOS-network-unreachable TOS-host-unreachable communication-prohibited host-precedence-violation precedence-cutoff source-quench redirect network-redirect host-redirect TOS-network-redirect TOS host-redirect echo-request ping router-advertisement router-solicitation time-exceeded ttl-exceeded ttl-zero-during-transit ttl-zero-during-reassembly parameter-problem ip-header-bad required-option-missing timestamp-request timestamp-reply address-mask-request address-mask-reply</list>
+ <list>echo-reply destination-unreachable source-quench redirect echo-request router-advertisement router-solicitation time-exceeded parameter-problem timestamp-request timestamp-reply info-request info-reply address-mask-request address-mask-reply</list>
</completionHelp>
<valueHelp>
- <format>any</format>
- <description>Any ICMP type/code</description>
- </valueHelp>
- <valueHelp>
<format>echo-reply</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>pong</format>
- <description>ICMP type/code name</description>
+ <description>ICMP type 0: echo-reply</description>
</valueHelp>
<valueHelp>
<format>destination-unreachable</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>network-unreachable</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>host-unreachable</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>protocol-unreachable</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>port-unreachable</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>fragmentation-needed</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>source-route-failed</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>network-unknown</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>host-unknown</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>network-prohibited</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>host-prohibited</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>TOS-network-unreachable</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>TOS-host-unreachable</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>communication-prohibited</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>host-precedence-violation</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>precedence-cutoff</format>
- <description>ICMP type/code name</description>
+ <description>ICMP type 3: destination-unreachable</description>
</valueHelp>
<valueHelp>
<format>source-quench</format>
- <description>ICMP type/code name</description>
+ <description>ICMP type 4: source-quench</description>
</valueHelp>
<valueHelp>
<format>redirect</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>network-redirect</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>host-redirect</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>TOS-network-redirect</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>TOS host-redirect</format>
- <description>ICMP type/code name</description>
+ <description>ICMP type 5: redirect</description>
</valueHelp>
<valueHelp>
<format>echo-request</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>ping</format>
- <description>ICMP type/code name</description>
+ <description>ICMP type 8: echo-request</description>
</valueHelp>
<valueHelp>
<format>router-advertisement</format>
- <description>ICMP type/code name</description>
+ <description>ICMP type 9: router-advertisement</description>
</valueHelp>
<valueHelp>
<format>router-solicitation</format>
- <description>ICMP type/code name</description>
+ <description>ICMP type 10: router-solicitation</description>
</valueHelp>
<valueHelp>
<format>time-exceeded</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>ttl-exceeded</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>ttl-zero-during-transit</format>
- <description>ICMP type/code name</description>
- </valueHelp>
- <valueHelp>
- <format>ttl-zero-during-reassembly</format>
- <description>ICMP type/code name</description>
+ <description>ICMP type 11: time-exceeded</description>
</valueHelp>
<valueHelp>
<format>parameter-problem</format>
- <description>ICMP type/code name</description>
+ <description>ICMP type 12: parameter-problem</description>
</valueHelp>
<valueHelp>
- <format>ip-header-bad</format>
- <description>ICMP type/code name</description>
+ <format>timestamp-request</format>
+ <description>ICMP type 13: timestamp-request</description>
</valueHelp>
<valueHelp>
- <format>required-option-missing</format>
- <description>ICMP type/code name</description>
+ <format>timestamp-reply</format>
+ <description>ICMP type 14: timestamp-reply</description>
</valueHelp>
<valueHelp>
- <format>timestamp-request</format>
- <description>ICMP type/code name</description>
+ <format>info-request</format>
+ <description>ICMP type 15: info-request</description>
</valueHelp>
<valueHelp>
- <format>timestamp-reply</format>
- <description>ICMP type/code name</description>
+ <format>info-reply</format>
+ <description>ICMP type 16: info-reply</description>
</valueHelp>
<valueHelp>
<format>address-mask-request</format>
- <description>ICMP type/code name</description>
+ <description>ICMP type 17: address-mask-request</description>
</valueHelp>
<valueHelp>
<format>address-mask-reply</format>
- <description>ICMP type/code name</description>
+ <description>ICMP type 18: address-mask-reply</description>
</valueHelp>
<constraint>
- <regex>^(any|echo-reply|pong|destination-unreachable|network-unreachable|host-unreachable|protocol-unreachable|port-unreachable|fragmentation-needed|source-route-failed|network-unknown|host-unknown|network-prohibited|host-prohibited|TOS-network-unreachable|TOS-host-unreachable|communication-prohibited|host-precedence-violation|precedence-cutoff|source-quench|redirect|network-redirect|host-redirect|TOS-network-redirect|TOS host-redirect|echo-request|ping|router-advertisement|router-solicitation|time-exceeded|ttl-exceeded|ttl-zero-during-transit|ttl-zero-during-reassembly|parameter-problem|ip-header-bad|required-option-missing|timestamp-request|timestamp-reply|address-mask-request|address-mask-reply)$</regex>
+ <regex>(echo-reply|destination-unreachable|source-quench|redirect|echo-request|router-advertisement|router-solicitation|time-exceeded|parameter-problem|timestamp-request|timestamp-reply|info-request|info-reply|address-mask-request|address-mask-reply)</regex>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/include/firewall/icmpv6-type-name.xml.i b/interface-definitions/include/firewall/icmpv6-type-name.xml.i
new file mode 100644
index 000000000..a2e68abfb
--- /dev/null
+++ b/interface-definitions/include/firewall/icmpv6-type-name.xml.i
@@ -0,0 +1,73 @@
+<!-- include start from firewall/icmpv6-type-name.xml.i -->
+<leafNode name="type-name">
+ <properties>
+ <help>ICMPv6 type-name</help>
+ <completionHelp>
+ <list>destination-unreachable packet-too-big time-exceeded echo-request echo-reply mld-listener-query mld-listener-report mld-listener-reduction nd-router-solicit nd-router-advert nd-neighbor-solicit nd-neighbor-advert nd-redirect parameter-problem router-renumbering</list>
+ </completionHelp>
+ <valueHelp>
+ <format>destination-unreachable</format>
+ <description>ICMPv6 type 1: destination-unreachable</description>
+ </valueHelp>
+ <valueHelp>
+ <format>packet-too-big</format>
+ <description>ICMPv6 type 2: packet-too-big</description>
+ </valueHelp>
+ <valueHelp>
+ <format>time-exceeded</format>
+ <description>ICMPv6 type 3: time-exceeded</description>
+ </valueHelp>
+ <valueHelp>
+ <format>echo-request</format>
+ <description>ICMPv6 type 128: echo-request</description>
+ </valueHelp>
+ <valueHelp>
+ <format>echo-reply</format>
+ <description>ICMPv6 type 129: echo-reply</description>
+ </valueHelp>
+ <valueHelp>
+ <format>mld-listener-query</format>
+ <description>ICMPv6 type 130: mld-listener-query</description>
+ </valueHelp>
+ <valueHelp>
+ <format>mld-listener-report</format>
+ <description>ICMPv6 type 131: mld-listener-report</description>
+ </valueHelp>
+ <valueHelp>
+ <format>mld-listener-reduction</format>
+ <description>ICMPv6 type 132: mld-listener-reduction</description>
+ </valueHelp>
+ <valueHelp>
+ <format>nd-router-solicit</format>
+ <description>ICMPv6 type 133: nd-router-solicit</description>
+ </valueHelp>
+ <valueHelp>
+ <format>nd-router-advert</format>
+ <description>ICMPv6 type 134: nd-router-advert</description>
+ </valueHelp>
+ <valueHelp>
+ <format>nd-neighbor-solicit</format>
+ <description>ICMPv6 type 135: nd-neighbor-solicit</description>
+ </valueHelp>
+ <valueHelp>
+ <format>nd-neighbor-advert</format>
+ <description>ICMPv6 type 136: nd-neighbor-advert</description>
+ </valueHelp>
+ <valueHelp>
+ <format>nd-redirect</format>
+ <description>ICMPv6 type 137: nd-redirect</description>
+ </valueHelp>
+ <valueHelp>
+ <format>parameter-problem</format>
+ <description>ICMPv6 type 4: parameter-problem</description>
+ </valueHelp>
+ <valueHelp>
+ <format>router-renumbering</format>
+ <description>ICMPv6 type 138: router-renumbering</description>
+ </valueHelp>
+ <constraint>
+ <regex>(destination-unreachable|packet-too-big|time-exceeded|echo-request|echo-reply|mld-listener-query|mld-listener-report|mld-listener-reduction|nd-router-solicit|nd-router-advert|nd-neighbor-solicit|nd-neighbor-advert|nd-redirect|parameter-problem|router-renumbering)</regex>
+ </constraint>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/firewall/mac-group.xml.i b/interface-definitions/include/firewall/mac-group.xml.i
new file mode 100644
index 000000000..dbce3fc88
--- /dev/null
+++ b/interface-definitions/include/firewall/mac-group.xml.i
@@ -0,0 +1,10 @@
+<!-- include start from firewall/mac-group.xml.i -->
+<leafNode name="mac-group">
+ <properties>
+ <help>Group of MAC addresses</help>
+ <completionHelp>
+ <path>firewall group mac-group</path>
+ </completionHelp>
+ </properties>
+</leafNode>
+<!-- include start from firewall/mac-group.xml.i --> \ No newline at end of file
diff --git a/interface-definitions/include/firewall/name-default-action.xml.i b/interface-definitions/include/firewall/name-default-action.xml.i
index 1b61b076f..512b0296f 100644
--- a/interface-definitions/include/firewall/name-default-action.xml.i
+++ b/interface-definitions/include/firewall/name-default-action.xml.i
@@ -7,7 +7,7 @@
</completionHelp>
<valueHelp>
<format>drop</format>
- <description>Drop if no prior rules are hit (default)</description>
+ <description>Drop if no prior rules are hit</description>
</valueHelp>
<valueHelp>
<format>reject</format>
@@ -18,7 +18,7 @@
<description>Accept if no prior rules are hit</description>
</valueHelp>
<constraint>
- <regex>^(drop|reject|accept)$</regex>
+ <regex>(drop|reject|accept)</regex>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/include/firewall/port.xml.i b/interface-definitions/include/firewall/port.xml.i
index 59d92978b..3bacafff8 100644
--- a/interface-definitions/include/firewall/port.xml.i
+++ b/interface-definitions/include/firewall/port.xml.i
@@ -16,8 +16,11 @@
</valueHelp>
<valueHelp>
<format> </format>
- <description>\n\n Multiple destination ports can be specified as a comma-separated list.\n The whole list can also be negated using '!'.\n For example: '!22,telnet,http,123,1001-1005'</description>
+ <description>\n\n Multiple destination ports can be specified as a comma-separated list.\n For example: 'telnet,http,123,1001-1005'</description>
</valueHelp>
+ <constraint>
+ <validator name="port-multi"/>
+ </constraint>
</properties>
</leafNode>
<!-- include end -->
diff --git a/interface-definitions/include/firewall/source-destination-group-ipv6.xml.i b/interface-definitions/include/firewall/source-destination-group-ipv6.xml.i
new file mode 100644
index 000000000..c2cc7edb3
--- /dev/null
+++ b/interface-definitions/include/firewall/source-destination-group-ipv6.xml.i
@@ -0,0 +1,34 @@
+<!-- include start from firewall/source-destination-group-ipv6.xml.i -->
+<node name="group">
+ <properties>
+ <help>Group</help>
+ </properties>
+ <children>
+ <leafNode name="address-group">
+ <properties>
+ <help>Group of addresses</help>
+ <completionHelp>
+ <path>firewall group ipv6-address-group</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ #include <include/firewall/mac-group.xml.i>
+ <leafNode name="network-group">
+ <properties>
+ <help>Group of networks</help>
+ <completionHelp>
+ <path>firewall group ipv6-network-group</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ <leafNode name="port-group">
+ <properties>
+ <help>Group of ports</help>
+ <completionHelp>
+ <path>firewall group port-group</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<!-- include end -->
diff --git a/interface-definitions/include/firewall/source-destination-group.xml.i b/interface-definitions/include/firewall/source-destination-group.xml.i
index 30226b0d8..ab11e89e9 100644
--- a/interface-definitions/include/firewall/source-destination-group.xml.i
+++ b/interface-definitions/include/firewall/source-destination-group.xml.i
@@ -7,16 +7,26 @@
<leafNode name="address-group">
<properties>
<help>Group of addresses</help>
+ <completionHelp>
+ <path>firewall group address-group</path>
+ </completionHelp>
</properties>
</leafNode>
+ #include <include/firewall/mac-group.xml.i>
<leafNode name="network-group">
<properties>
<help>Group of networks</help>
+ <completionHelp>
+ <path>firewall group network-group</path>
+ </completionHelp>
</properties>
</leafNode>
<leafNode name="port-group">
<properties>
<help>Group of ports</help>
+ <completionHelp>
+ <path>firewall group port-group</path>
+ </completionHelp>
</properties>
</leafNode>
</children>
diff --git a/interface-definitions/include/firewall/tcp-flags.xml.i b/interface-definitions/include/firewall/tcp-flags.xml.i
new file mode 100644
index 000000000..b99896687
--- /dev/null
+++ b/interface-definitions/include/firewall/tcp-flags.xml.i
@@ -0,0 +1,119 @@
+<!-- include start from firewall/tcp-flags.xml.i -->
+<node name="tcp">
+ <properties>
+ <help>TCP flags to match</help>
+ </properties>
+ <children>
+ <node name="flags">
+ <properties>
+ <help>TCP flags to match</help>
+ </properties>
+ <children>
+ <leafNode name="syn">
+ <properties>
+ <help>Synchronise flag</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="ack">
+ <properties>
+ <help>Acknowledge flag</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="fin">
+ <properties>
+ <help>Finish flag</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="rst">
+ <properties>
+ <help>Reset flag</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="urg">
+ <properties>
+ <help>Urgent flag</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="psh">
+ <properties>
+ <help>Push flag</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="ecn">
+ <properties>
+ <help>Explicit Congestion Notification flag</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="cwr">
+ <properties>
+ <help>Congestion Window Reduced flag</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <node name="not">
+ <properties>
+ <help>Match flags not set</help>
+ </properties>
+ <children>
+ <leafNode name="syn">
+ <properties>
+ <help>Synchronise flag</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="ack">
+ <properties>
+ <help>Acknowledge flag</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="fin">
+ <properties>
+ <help>Finish flag</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="rst">
+ <properties>
+ <help>Reset flag</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="urg">
+ <properties>
+ <help>Urgent flag</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="psh">
+ <properties>
+ <help>Push flag</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="ecn">
+ <properties>
+ <help>Explicit Congestion Notification flag</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="cwr">
+ <properties>
+ <help>Congestion Window Reduced flag</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+ </node>
+ </children>
+</node>
+<!-- include end -->
diff --git a/interface-definitions/include/generic-disable-node.xml.i b/interface-definitions/include/generic-disable-node.xml.i
index bb4fa5c4b..97a328ecc 100644
--- a/interface-definitions/include/generic-disable-node.xml.i
+++ b/interface-definitions/include/generic-disable-node.xml.i
@@ -1,7 +1,7 @@
<!-- include start from generic-disable-node.xml.i -->
<leafNode name="disable">
<properties>
- <help>Temporary disable</help>
+ <help>Disable instance</help>
<valueless/>
</properties>
</leafNode>
diff --git a/interface-definitions/include/interface/address-ipv4-ipv6-dhcp.xml.i b/interface-definitions/include/interface/address-ipv4-ipv6-dhcp.xml.i
index 123590c08..b9dd59bea 100644
--- a/interface-definitions/include/interface/address-ipv4-ipv6-dhcp.xml.i
+++ b/interface-definitions/include/interface/address-ipv4-ipv6-dhcp.xml.i
@@ -23,7 +23,7 @@
</valueHelp>
<constraint>
<validator name="ip-host"/>
- <regex>^(dhcp|dhcpv6)$</regex>
+ <regex>(dhcp|dhcpv6)</regex>
</constraint>
<multi/>
</properties>
diff --git a/interface-definitions/include/interface/adjust-mss.xml.i b/interface-definitions/include/interface/adjust-mss.xml.i
index 57019f02c..41140ffe1 100644
--- a/interface-definitions/include/interface/adjust-mss.xml.i
+++ b/interface-definitions/include/interface/adjust-mss.xml.i
@@ -16,7 +16,7 @@
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 500-65535"/>
- <regex>^(clamp-mss-to-pmtu)$</regex>
+ <regex>(clamp-mss-to-pmtu)</regex>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/include/interface/arp-cache-timeout.xml.i b/interface-definitions/include/interface/arp-cache-timeout.xml.i
index cb01d0525..06d7ffe96 100644
--- a/interface-definitions/include/interface/arp-cache-timeout.xml.i
+++ b/interface-definitions/include/interface/arp-cache-timeout.xml.i
@@ -4,7 +4,7 @@
<help>ARP cache entry timeout in seconds</help>
<valueHelp>
<format>u32:1-86400</format>
- <description>ARP cache entry timout in seconds (default 30)</description>
+ <description>ARP cache entry timout in seconds</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-86400"/>
diff --git a/interface-definitions/include/interface/default-route-distance.xml.i b/interface-definitions/include/interface/default-route-distance.xml.i
new file mode 100644
index 000000000..6eda52c91
--- /dev/null
+++ b/interface-definitions/include/interface/default-route-distance.xml.i
@@ -0,0 +1,15 @@
+<!-- include start from interface/default-route-distance.xml.i -->
+<leafNode name="default-route-distance">
+ <properties>
+ <help>Distance for installed default route</help>
+ <valueHelp>
+ <format>u32:1-255</format>
+ <description>Distance for the default route from DHCP server</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-255"/>
+ </constraint>
+ </properties>
+ <defaultValue>210</defaultValue>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/interface/description.xml.i b/interface-definitions/include/interface/description.xml.i
index 8579cf7d1..de01d22ca 100644
--- a/interface-definitions/include/interface/description.xml.i
+++ b/interface-definitions/include/interface/description.xml.i
@@ -3,7 +3,7 @@
<properties>
<help>Interface specific description</help>
<constraint>
- <regex>.{1,256}$</regex>
+ <regex>.{1,256}</regex>
</constraint>
<constraintErrorMessage>Description too long (limit 256 characters)</constraintErrorMessage>
</properties>
diff --git a/interface-definitions/include/interface/dhcp-options.xml.i b/interface-definitions/include/interface/dhcp-options.xml.i
index b65b0802a..914b60503 100644
--- a/interface-definitions/include/interface/dhcp-options.xml.i
+++ b/interface-definitions/include/interface/dhcp-options.xml.i
@@ -19,24 +19,8 @@
<help>Identify the vendor client type to the DHCP server</help>
</properties>
</leafNode>
- <leafNode name="no-default-route">
- <properties>
- <help>Do not request routers from DHCP server</help>
- <valueless/>
- </properties>
- </leafNode>
- <leafNode name="default-route-distance">
- <properties>
- <help>Distance for the default route from DHCP server</help>
- <valueHelp>
- <format>u32:1-255</format>
- <description>Distance for the default route from DHCP server (default 210)</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-255"/>
- </constraint>
- </properties>
- </leafNode>
+ #include <include/interface/no-default-route.xml.i>
+ #include <include/interface/default-route-distance.xml.i>
<leafNode name="reject">
<properties>
<help>IP addresses or subnets from which to reject DHCP leases</help>
diff --git a/interface-definitions/include/interface/dhcpv6-options.xml.i b/interface-definitions/include/interface/dhcpv6-options.xml.i
index d1abf4a90..08e4f5e0a 100644
--- a/interface-definitions/include/interface/dhcpv6-options.xml.i
+++ b/interface-definitions/include/interface/dhcpv6-options.xml.i
@@ -57,10 +57,10 @@
<children>
<leafNode name="address">
<properties>
- <help>Local interface address assigned to interface</help>
+ <help>Local interface address assigned to interface (default: EUI-64)</help>
<valueHelp>
<format>&gt;0</format>
- <description>Used to form IPv6 interface address (default: EUI-64)</description>
+ <description>Used to form IPv6 interface address</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--non-negative"/>
diff --git a/interface-definitions/include/interface/inbound-interface.xml.i b/interface-definitions/include/interface/inbound-interface.xml.i
new file mode 100644
index 000000000..5a8d47280
--- /dev/null
+++ b/interface-definitions/include/interface/inbound-interface.xml.i
@@ -0,0 +1,10 @@
+<!-- include start from interface/inbound-interface.xml.i -->
+<leafNode name="inbound-interface">
+ <properties>
+ <help>Inbound Interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces.py</script>
+ </completionHelp>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/interface/interface-firewall-vif-c.xml.i b/interface-definitions/include/interface/interface-firewall-vif-c.xml.i
new file mode 100644
index 000000000..1bc235fcb
--- /dev/null
+++ b/interface-definitions/include/interface/interface-firewall-vif-c.xml.i
@@ -0,0 +1,79 @@
+<!-- include start from interface/interface-firewall-vif-c.xml.i -->
+<node name="firewall" owner="${vyos_conf_scripts_dir}/firewall-interface.py $VAR(../../../@).$VAR(../../@).$VAR(../@)">
+ <properties>
+ <priority>615</priority>
+ <help>Firewall options</help>
+ </properties>
+ <children>
+ <node name="in">
+ <properties>
+ <help>forwarded packets on inbound interface</help>
+ </properties>
+ <children>
+ <leafNode name="name">
+ <properties>
+ <help>Inbound IPv4 firewall ruleset name for interface</help>
+ <completionHelp>
+ <path>firewall name</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ <leafNode name="ipv6-name">
+ <properties>
+ <help>Inbound IPv6 firewall ruleset name for interface</help>
+ <completionHelp>
+ <path>firewall ipv6-name</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ <node name="out">
+ <properties>
+ <help>forwarded packets on outbound interface</help>
+ </properties>
+ <children>
+ <leafNode name="name">
+ <properties>
+ <help>Outbound IPv4 firewall ruleset name for interface</help>
+ <completionHelp>
+ <path>firewall name</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ <leafNode name="ipv6-name">
+ <properties>
+ <help>Outbound IPv6 firewall ruleset name for interface</help>
+ <completionHelp>
+ <path>firewall ipv6-name</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ <node name="local">
+ <properties>
+ <help>packets destined for this router</help>
+ </properties>
+ <children>
+ <leafNode name="name">
+ <properties>
+ <help>Local IPv4 firewall ruleset name for interface</help>
+ <completionHelp>
+ <path>firewall name</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ <leafNode name="ipv6-name">
+ <properties>
+ <help>Local IPv6 firewall ruleset name for interface</help>
+ <completionHelp>
+ <path>firewall ipv6-name</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+</node>
+<!-- include end -->
diff --git a/interface-definitions/include/interface/interface-firewall-vif.xml.i b/interface-definitions/include/interface/interface-firewall-vif.xml.i
new file mode 100644
index 000000000..a37ac5c4a
--- /dev/null
+++ b/interface-definitions/include/interface/interface-firewall-vif.xml.i
@@ -0,0 +1,79 @@
+<!-- include start from interface/interface-firewall-vif.xml.i -->
+<node name="firewall" owner="${vyos_conf_scripts_dir}/firewall-interface.py $VAR(../../@).$VAR(../@)">
+ <properties>
+ <priority>615</priority>
+ <help>Firewall options</help>
+ </properties>
+ <children>
+ <node name="in">
+ <properties>
+ <help>forwarded packets on inbound interface</help>
+ </properties>
+ <children>
+ <leafNode name="name">
+ <properties>
+ <help>Inbound IPv4 firewall ruleset name for interface</help>
+ <completionHelp>
+ <path>firewall name</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ <leafNode name="ipv6-name">
+ <properties>
+ <help>Inbound IPv6 firewall ruleset name for interface</help>
+ <completionHelp>
+ <path>firewall ipv6-name</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ <node name="out">
+ <properties>
+ <help>forwarded packets on outbound interface</help>
+ </properties>
+ <children>
+ <leafNode name="name">
+ <properties>
+ <help>Outbound IPv4 firewall ruleset name for interface</help>
+ <completionHelp>
+ <path>firewall name</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ <leafNode name="ipv6-name">
+ <properties>
+ <help>Outbound IPv6 firewall ruleset name for interface</help>
+ <completionHelp>
+ <path>firewall ipv6-name</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ <node name="local">
+ <properties>
+ <help>packets destined for this router</help>
+ </properties>
+ <children>
+ <leafNode name="name">
+ <properties>
+ <help>Local IPv4 firewall ruleset name for interface</help>
+ <completionHelp>
+ <path>firewall name</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ <leafNode name="ipv6-name">
+ <properties>
+ <help>Local IPv6 firewall ruleset name for interface</help>
+ <completionHelp>
+ <path>firewall ipv6-name</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+</node>
+<!-- include end -->
diff --git a/interface-definitions/include/interface/interface-firewall.xml.i b/interface-definitions/include/interface/interface-firewall.xml.i
new file mode 100644
index 000000000..b3f20c3bf
--- /dev/null
+++ b/interface-definitions/include/interface/interface-firewall.xml.i
@@ -0,0 +1,79 @@
+<!-- include start from interface/interface-firewall.xml.i -->
+<node name="firewall" owner="${vyos_conf_scripts_dir}/firewall-interface.py $VAR(../@)">
+ <properties>
+ <priority>615</priority>
+ <help>Firewall options</help>
+ </properties>
+ <children>
+ <node name="in">
+ <properties>
+ <help>forwarded packets on inbound interface</help>
+ </properties>
+ <children>
+ <leafNode name="name">
+ <properties>
+ <help>Inbound IPv4 firewall ruleset name for interface</help>
+ <completionHelp>
+ <path>firewall name</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ <leafNode name="ipv6-name">
+ <properties>
+ <help>Inbound IPv6 firewall ruleset name for interface</help>
+ <completionHelp>
+ <path>firewall ipv6-name</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ <node name="out">
+ <properties>
+ <help>forwarded packets on outbound interface</help>
+ </properties>
+ <children>
+ <leafNode name="name">
+ <properties>
+ <help>Outbound IPv4 firewall ruleset name for interface</help>
+ <completionHelp>
+ <path>firewall name</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ <leafNode name="ipv6-name">
+ <properties>
+ <help>Outbound IPv6 firewall ruleset name for interface</help>
+ <completionHelp>
+ <path>firewall ipv6-name</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ <node name="local">
+ <properties>
+ <help>packets destined for this router</help>
+ </properties>
+ <children>
+ <leafNode name="name">
+ <properties>
+ <help>Local IPv4 firewall ruleset name for interface</help>
+ <completionHelp>
+ <path>firewall name</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ <leafNode name="ipv6-name">
+ <properties>
+ <help>Local IPv6 firewall ruleset name for interface</help>
+ <completionHelp>
+ <path>firewall ipv6-name</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+</node>
+<!-- include end -->
diff --git a/interface-definitions/include/interface/interface-policy-vif-c.xml.i b/interface-definitions/include/interface/interface-policy-vif-c.xml.i
new file mode 100644
index 000000000..866fcd5c0
--- /dev/null
+++ b/interface-definitions/include/interface/interface-policy-vif-c.xml.i
@@ -0,0 +1,26 @@
+<!-- include start from interface/interface-policy-vif-c.xml.i -->
+<node name="policy" owner="${vyos_conf_scripts_dir}/policy-route-interface.py $VAR(../../../@).$VAR(../../@).$VAR(../@)">
+ <properties>
+ <priority>620</priority>
+ <help>Policy route options</help>
+ </properties>
+ <children>
+ <leafNode name="route">
+ <properties>
+ <help>IPv4 policy route ruleset for interface</help>
+ <completionHelp>
+ <path>policy route</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ <leafNode name="route6">
+ <properties>
+ <help>IPv6 policy route ruleset for interface</help>
+ <completionHelp>
+ <path>policy route6</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<!-- include end -->
diff --git a/interface-definitions/include/interface/interface-policy-vif.xml.i b/interface-definitions/include/interface/interface-policy-vif.xml.i
new file mode 100644
index 000000000..83510fe59
--- /dev/null
+++ b/interface-definitions/include/interface/interface-policy-vif.xml.i
@@ -0,0 +1,26 @@
+<!-- include start from interface/interface-policy-vif.xml.i -->
+<node name="policy" owner="${vyos_conf_scripts_dir}/policy-route-interface.py $VAR(../../@).$VAR(../@)">
+ <properties>
+ <priority>620</priority>
+ <help>Policy route options</help>
+ </properties>
+ <children>
+ <leafNode name="route">
+ <properties>
+ <help>IPv4 policy route ruleset for interface</help>
+ <completionHelp>
+ <path>policy route</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ <leafNode name="route6">
+ <properties>
+ <help>IPv6 policy route ruleset for interface</help>
+ <completionHelp>
+ <path>policy route6</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<!-- include end -->
diff --git a/interface-definitions/include/interface/interface-policy.xml.i b/interface-definitions/include/interface/interface-policy.xml.i
new file mode 100644
index 000000000..42a8fd009
--- /dev/null
+++ b/interface-definitions/include/interface/interface-policy.xml.i
@@ -0,0 +1,26 @@
+<!-- include start from interface/interface-policy.xml.i -->
+<node name="policy" owner="${vyos_conf_scripts_dir}/policy-route-interface.py $VAR(../@)">
+ <properties>
+ <priority>620</priority>
+ <help>Policy route options</help>
+ </properties>
+ <children>
+ <leafNode name="route">
+ <properties>
+ <help>IPv4 policy route ruleset for interface</help>
+ <completionHelp>
+ <path>policy route</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ <leafNode name="route6">
+ <properties>
+ <help>IPv6 policy route ruleset for interface</help>
+ <completionHelp>
+ <path>policy route6</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<!-- include end -->
diff --git a/interface-definitions/include/interface/netns.xml.i b/interface-definitions/include/interface/netns.xml.i
new file mode 100644
index 000000000..39f9118fa
--- /dev/null
+++ b/interface-definitions/include/interface/netns.xml.i
@@ -0,0 +1,14 @@
+<!-- include start from interface/netns.xml.i -->
+<leafNode name="netns">
+ <properties>
+ <help>Network namespace name</help>
+ <valueHelp>
+ <format>text</format>
+ <description>Network namespace name</description>
+ </valueHelp>
+ <completionHelp>
+ <path>netns name</path>
+ </completionHelp>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/interface/no-default-route.xml.i b/interface-definitions/include/interface/no-default-route.xml.i
new file mode 100644
index 000000000..307fcff1e
--- /dev/null
+++ b/interface-definitions/include/interface/no-default-route.xml.i
@@ -0,0 +1,8 @@
+<!-- include start from interface/dhcp-options.xml.i -->
+<leafNode name="no-default-route">
+ <properties>
+ <help>Do not install default route to system</help>
+ <valueless/>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/interface/parameters-df.xml.i b/interface-definitions/include/interface/parameters-df.xml.i
new file mode 100644
index 000000000..82436b5e4
--- /dev/null
+++ b/interface-definitions/include/interface/parameters-df.xml.i
@@ -0,0 +1,26 @@
+<!-- include start from interface/parameters-df.xml.i -->
+<leafNode name="df">
+ <properties>
+ <help>Usage of the DF (don't Fragment) bit in outgoing packets</help>
+ <completionHelp>
+ <list>set unset inherit</list>
+ </completionHelp>
+ <valueHelp>
+ <format>set</format>
+ <description>Always set DF (don't fragment) bit</description>
+ </valueHelp>
+ <valueHelp>
+ <format>unset</format>
+ <description>Always unset DF (don't fragment) bit</description>
+ </valueHelp>
+ <valueHelp>
+ <format>inherit</format>
+ <description>Copy from the original IP header</description>
+ </valueHelp>
+ <constraint>
+ <regex>(set|unset|inherit)</regex>
+ </constraint>
+ </properties>
+ <defaultValue>unset</defaultValue>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/interface/parameters-dont-fragment.xml.i b/interface-definitions/include/interface/parameters-dont-fragment.xml.i
deleted file mode 100644
index d34f0a97b..000000000
--- a/interface-definitions/include/interface/parameters-dont-fragment.xml.i
+++ /dev/null
@@ -1,8 +0,0 @@
-<!-- include start from interface/parameters-df.xml.i -->
-<leafNode name="dont-fragment">
- <properties>
- <help>Specifies the usage of the dont fragment (DF) bit</help>
- <valueless/>
- </properties>
-</leafNode>
-<!-- include end -->
diff --git a/interface-definitions/include/interface/parameters-flowlabel.xml.i b/interface-definitions/include/interface/parameters-flowlabel.xml.i
index bd0d1e070..b2e88215b 100644
--- a/interface-definitions/include/interface/parameters-flowlabel.xml.i
+++ b/interface-definitions/include/interface/parameters-flowlabel.xml.i
@@ -14,7 +14,7 @@
<description>Tunnel key, or hex value</description>
</valueHelp>
<constraint>
- <regex>^((0x){0,1}(0?[0-9A-Fa-f]{1,5})|inherit)$</regex>
+ <regex>((0x){0,1}(0?[0-9A-Fa-f]{1,5})|inherit)</regex>
</constraint>
<constraintErrorMessage>Must be 'inherit' or a number</constraintErrorMessage>
</properties>
diff --git a/interface-definitions/include/interface/redirect.xml.i b/interface-definitions/include/interface/redirect.xml.i
new file mode 100644
index 000000000..3be9ee16b
--- /dev/null
+++ b/interface-definitions/include/interface/redirect.xml.i
@@ -0,0 +1,17 @@
+<!-- include start from interface/redirect.xml.i -->
+<leafNode name="redirect">
+ <properties>
+ <help>Incoming packet redirection destination</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces.py</script>
+ </completionHelp>
+ <valueHelp>
+ <format>txt</format>
+ <description>Interface name</description>
+ </valueHelp>
+ <constraint>
+ <validator name="interface-name"/>
+ </constraint>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/interface/source-validation.xml.i b/interface-definitions/include/interface/source-validation.xml.i
index f38065f4d..fc9a7d376 100644
--- a/interface-definitions/include/interface/source-validation.xml.i
+++ b/interface-definitions/include/interface/source-validation.xml.i
@@ -18,7 +18,7 @@
<description>No source validation</description>
</valueHelp>
<constraint>
- <regex>^(strict|loose|disable)$</regex>
+ <regex>(strict|loose|disable)</regex>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/include/interface/tunnel-remote-multi.xml.i b/interface-definitions/include/interface/tunnel-remote-multi.xml.i
new file mode 100644
index 000000000..f672087a4
--- /dev/null
+++ b/interface-definitions/include/interface/tunnel-remote-multi.xml.i
@@ -0,0 +1,19 @@
+<!-- include start from interface/tunnel-remote-multi.xml.i -->
+<leafNode name="remote">
+ <properties>
+ <help>Tunnel remote address</help>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>Tunnel remote IPv4 address</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv6</format>
+ <description>Tunnel remote IPv6 address</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ip-address"/>
+ </constraint>
+ <multi/>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/interface/tunnel-remote.xml.i b/interface-definitions/include/interface/tunnel-remote.xml.i
index 1ba9b0382..2a8891b85 100644
--- a/interface-definitions/include/interface/tunnel-remote.xml.i
+++ b/interface-definitions/include/interface/tunnel-remote.xml.i
@@ -1,4 +1,4 @@
-<!-- include start from rip/tunnel-remote.xml.i -->
+<!-- include start from interface/tunnel-remote.xml.i -->
<leafNode name="remote">
<properties>
<help>Tunnel remote address</help>
diff --git a/interface-definitions/include/interface/vif-s.xml.i b/interface-definitions/include/interface/vif-s.xml.i
index e7ba6d193..c1af9f9e3 100644
--- a/interface-definitions/include/interface/vif-s.xml.i
+++ b/interface-definitions/include/interface/vif-s.xml.i
@@ -18,6 +18,8 @@
#include <include/interface/dhcpv6-options.xml.i>
#include <include/interface/disable-link-detect.xml.i>
#include <include/interface/disable.xml.i>
+ #include <include/interface/interface-firewall-vif.xml.i>
+ #include <include/interface/interface-policy-vif.xml.i>
<leafNode name="protocol">
<properties>
<help>Protocol used for service VLAN (default: 802.1ad)</help>
@@ -33,7 +35,7 @@
<description>VLAN-tagged frame (IEEE 802.1q), ethertype 0x8100</description>
</valueHelp>
<constraint>
- <regex>^(802.1q|802.1ad)$</regex>
+ <regex>(802.1q|802.1ad)</regex>
</constraint>
<constraintErrorMessage>Ethertype must be 802.1ad or 802.1q</constraintErrorMessage>
</properties>
@@ -42,6 +44,7 @@
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
#include <include/interface/mac.xml.i>
+ #include <include/interface/mirror.xml.i>
#include <include/interface/mtu-68-16000.xml.i>
<tagNode name="vif-c">
<properties>
@@ -61,10 +64,15 @@
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
#include <include/interface/mac.xml.i>
+ #include <include/interface/mirror.xml.i>
#include <include/interface/mtu-68-16000.xml.i>
+ #include <include/interface/redirect.xml.i>
#include <include/interface/vrf.xml.i>
+ #include <include/interface/interface-firewall-vif-c.xml.i>
+ #include <include/interface/interface-policy-vif-c.xml.i>
</children>
</tagNode>
+ #include <include/interface/redirect.xml.i>
#include <include/interface/vrf.xml.i>
</children>
</tagNode>
diff --git a/interface-definitions/include/interface/vif.xml.i b/interface-definitions/include/interface/vif.xml.i
index 5644c554f..57ef8d64c 100644
--- a/interface-definitions/include/interface/vif.xml.i
+++ b/interface-definitions/include/interface/vif.xml.i
@@ -18,7 +18,8 @@
#include <include/interface/dhcpv6-options.xml.i>
#include <include/interface/disable-link-detect.xml.i>
#include <include/interface/disable.xml.i>
- #include <include/interface/vrf.xml.i>
+ #include <include/interface/interface-firewall-vif.xml.i>
+ #include <include/interface/interface-policy-vif.xml.i>
<leafNode name="egress-qos">
<properties>
<help>VLAN egress QoS</help>
@@ -27,7 +28,7 @@
<description>Format for qos mapping, e.g.: '0:1 1:6 7:6'</description>
</valueHelp>
<constraint>
- <regex>[:0-7 ]+$</regex>
+ <regex>[:0-7 ]+</regex>
</constraint>
<constraintErrorMessage>QoS mapping should be in the format of '0:7 2:3' with numbers 0-9</constraintErrorMessage>
</properties>
@@ -40,7 +41,7 @@
<description>Format for qos mapping, e.g.: '0:1 1:6 7:6'</description>
</valueHelp>
<constraint>
- <regex>[:0-7 ]+$</regex>
+ <regex>[:0-7 ]+</regex>
</constraint>
<constraintErrorMessage>QoS mapping should be in the format of '0:7 2:3' with numbers 0-9</constraintErrorMessage>
</properties>
@@ -48,7 +49,10 @@
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
#include <include/interface/mac.xml.i>
+ #include <include/interface/mirror.xml.i>
#include <include/interface/mtu-68-16000.xml.i>
+ #include <include/interface/redirect.xml.i>
+ #include <include/interface/vrf.xml.i>
</children>
</tagNode>
<!-- include end -->
diff --git a/interface-definitions/include/interface/vrf.xml.i b/interface-definitions/include/interface/vrf.xml.i
index 5ad978a27..8605f56e8 100644
--- a/interface-definitions/include/interface/vrf.xml.i
+++ b/interface-definitions/include/interface/vrf.xml.i
@@ -3,7 +3,7 @@
<properties>
<help>VRF instance name</help>
<valueHelp>
- <format>text</format>
+ <format>txt</format>
<description>VRF instance name</description>
</valueHelp>
<completionHelp>
diff --git a/interface-definitions/include/ipsec/local-address.xml.i b/interface-definitions/include/ipsec/local-address.xml.i
index 2de6ecb1f..9d267f3f7 100644
--- a/interface-definitions/include/ipsec/local-address.xml.i
+++ b/interface-definitions/include/ipsec/local-address.xml.i
@@ -4,6 +4,7 @@
<help>IPv4 or IPv6 address of a local interface to use for VPN</help>
<completionHelp>
<list>any</list>
+ <script>${vyos_completion_dir}/list_local_ips.sh --both</script>
</completionHelp>
<valueHelp>
<format>ipv4</format>
@@ -20,7 +21,7 @@
<constraint>
<validator name="ipv4-address"/>
<validator name="ipv6-address"/>
- <regex>^(any)$</regex>
+ <regex>(any)</regex>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/include/ipsec/local-traffic-selector.xml.i b/interface-definitions/include/ipsec/local-traffic-selector.xml.i
index d30a6d11a..9ae67f583 100644
--- a/interface-definitions/include/ipsec/local-traffic-selector.xml.i
+++ b/interface-definitions/include/ipsec/local-traffic-selector.xml.i
@@ -9,11 +9,11 @@
<properties>
<help>Local IPv4 or IPv6 prefix</help>
<valueHelp>
- <format>ipv4</format>
+ <format>ipv4net</format>
<description>Local IPv4 prefix</description>
</valueHelp>
<valueHelp>
- <format>ipv6</format>
+ <format>ipv6net</format>
<description>Local IPv6 prefix</description>
</valueHelp>
<constraint>
diff --git a/interface-definitions/include/isis/high-low-label-value.xml.i b/interface-definitions/include/isis/high-low-label-value.xml.i
new file mode 100644
index 000000000..adc28417d
--- /dev/null
+++ b/interface-definitions/include/isis/high-low-label-value.xml.i
@@ -0,0 +1,26 @@
+<!-- include start from isis/high-low-label-value.xml.i -->
+<leafNode name="low-label-value">
+ <properties>
+ <help>MPLS label lower bound</help>
+ <valueHelp>
+ <format>u32:16-1048575</format>
+ <description>Label value</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 16-1048575"/>
+ </constraint>
+ </properties>
+</leafNode>
+<leafNode name="high-label-value">
+ <properties>
+ <help>MPLS label upper bound</help>
+ <valueHelp>
+ <format>u32:16-1048575</format>
+ <description>Label value</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 16-1048575"/>
+ </constraint>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/isis/password.xml.i b/interface-definitions/include/isis/password.xml.i
new file mode 100644
index 000000000..27c3b0fa0
--- /dev/null
+++ b/interface-definitions/include/isis/password.xml.i
@@ -0,0 +1,20 @@
+<!-- include start from isis/password.xml.i -->
+<leafNode name="plaintext-password">
+ <properties>
+ <help>Plain-text authentication type</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Circuit password</description>
+ </valueHelp>
+ </properties>
+</leafNode>
+<leafNode name="md5">
+ <properties>
+ <help>MD5 authentication type</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Level-wide password</description>
+ </valueHelp>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/isis/protocol-common-config.xml.i b/interface-definitions/include/isis/protocol-common-config.xml.i
index 84e2f7bb2..75a0355d4 100644
--- a/interface-definitions/include/isis/protocol-common-config.xml.i
+++ b/interface-definitions/include/isis/protocol-common-config.xml.i
@@ -4,24 +4,7 @@
<help>Configure the authentication password for an area</help>
</properties>
<children>
- <leafNode name="plaintext-password">
- <properties>
- <help>Plain-text authentication type</help>
- <valueHelp>
- <format>txt</format>
- <description>Level-wide password</description>
- </valueHelp>
- </properties>
- </leafNode>
- <leafNode name="md5">
- <properties>
- <help>MD5 authentication type</help>
- <valueHelp>
- <format>txt</format>
- <description>Level-wide password</description>
- </valueHelp>
- </properties>
- </leafNode>
+ #include <include/isis/password.xml.i>
</children>
</node>
<node name="default-information">
@@ -59,24 +42,7 @@
<help>Set the authentication password for a routing domain</help>
</properties>
<children>
- <leafNode name="plaintext-password">
- <properties>
- <help>Plain-text authentication type</help>
- <valueHelp>
- <format>txt</format>
- <description>Level-wide password</description>
- </valueHelp>
- </properties>
- </leafNode>
- <leafNode name="md5">
- <properties>
- <help>MD5 authentication type</help>
- <valueHelp>
- <format>txt</format>
- <description>Level-wide password</description>
- </valueHelp>
- </properties>
- </leafNode>
+ #include <include/isis/password.xml.i>
</children>
</node>
<leafNode name="dynamic-hostname">
@@ -104,7 +70,7 @@
<description>Act as an area router</description>
</valueHelp>
<constraint>
- <regex>^(level-1|level-1-2|level-2)$</regex>
+ <regex>(level-1|level-1-2|level-2)</regex>
</constraint>
</properties>
</leafNode>
@@ -182,7 +148,7 @@
<description>Use new style of TLVs to carry wider metric</description>
</valueHelp>
<constraint>
- <regex>^(narrow|transition|wide)$</regex>
+ <regex>(narrow|transition|wide)</regex>
</constraint>
</properties>
</leafNode>
@@ -275,68 +241,20 @@
</leafNode>
<node name="global-block">
<properties>
- <help>Global block label range</help>
+ <help>Segment Routing Global Block label range</help>
</properties>
<children>
- <leafNode name="low-label-value">
- <properties>
- <help>The lower bound of the global block</help>
- <valueHelp>
- <format>u32:16-1048575</format>
- <description>MPLS label value</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 16-1048575"/>
- </constraint>
- </properties>
- </leafNode>
- <leafNode name="high-label-value">
- <properties>
- <help>The upper bound of the global block</help>
- <valueHelp>
- <format>u32:16-1048575</format>
- <description>MPLS label value</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 16-1048575"/>
- </constraint>
- </properties>
- </leafNode>
+ #include <include/isis/high-low-label-value.xml.i>
</children>
</node>
-<!--
<node name="local-block">
<properties>
- <help>Local Block label range</help>
+ <help>Segment Routing Local Block label range</help>
</properties>
<children>
- <leafNode name="low-label-value">
- <properties>
- <help>The lower bound of the local block</help>
- <valueHelp>
- <format>u32:16-1048575</format>
- <description>MPLS label value</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument=" range 16-1048575"/>
- </constraint>
- </properties>
- </leafNode>
- <leafNode name="high-label-value">
- <properties>
- <help>The upper bound of the local block</help>
- <valueHelp>
- <format>u32:16-1048575</format>
- <description>MPLS label value</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument=" range 16-1048575"/>
- </constraint>
- </properties>
- </leafNode>
+ #include <include/isis/high-low-label-value.xml.i>
</children>
</node>
--->
<leafNode name="maximum-label-depth">
<properties>
<help>Maximum MPLS labels allowed for this router</help>
@@ -648,7 +566,7 @@
</completionHelp>
</properties>
<children>
- #include <include/bfd.xml.i>
+ #include <include/bfd/bfd.xml.i>
<leafNode name="circuit-type">
<properties>
<help>Configure circuit type for interface</help>
@@ -668,7 +586,7 @@
<description>Level-2 only adjacencies are formed</description>
</valueHelp>
<constraint>
- <regex>^(level-1|level-1-2|level-2-only)$</regex>
+ <regex>(level-1|level-1-2|level-2-only)</regex>
</constraint>
</properties>
</leafNode>
@@ -722,15 +640,7 @@
<help>Configure the authentication password for a circuit</help>
</properties>
<children>
- <leafNode name="plaintext-password">
- <properties>
- <help>Plain-text authentication type</help>
- <valueHelp>
- <format>txt</format>
- <description>Circuit password</description>
- </valueHelp>
- </properties>
- </leafNode>
+ #include <include/isis/password.xml.i>
</children>
</node>
<leafNode name="priority">
diff --git a/interface-definitions/include/listen-address-ipv4.xml.i b/interface-definitions/include/listen-address-ipv4.xml.i
index ee52cebe8..9cca297a0 100644
--- a/interface-definitions/include/listen-address-ipv4.xml.i
+++ b/interface-definitions/include/listen-address-ipv4.xml.i
@@ -1,13 +1,13 @@
<!-- include start from listen-address-ipv4.xml.i -->
<leafNode name="listen-address">
<properties>
- <help>Local IPv4 addresses for service to listen on</help>
+ <help>Local IPv4 addresses to listen on</help>
<completionHelp>
<script>${vyos_completion_dir}/list_local_ips.sh --ipv4</script>
</completionHelp>
<valueHelp>
<format>ipv4</format>
- <description>IP address to listen for incoming connections</description>
+ <description>IPv4 address to listen for incoming connections</description>
</valueHelp>
<multi/>
<constraint>
diff --git a/interface-definitions/include/listen-address-vrf.xml.i b/interface-definitions/include/listen-address-vrf.xml.i
new file mode 100644
index 000000000..8c2bdce70
--- /dev/null
+++ b/interface-definitions/include/listen-address-vrf.xml.i
@@ -0,0 +1,25 @@
+<!-- include start from listen-address-vrf.xml.i -->
+<tagNode name="listen-address">
+ <properties>
+ <help>Local IP addresses to listen on</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_local_ips.sh --both</script>
+ </completionHelp>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>IPv4 address to listen for incoming connections</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv6</format>
+ <description>IPv6 address to listen for incoming connections</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv4-address"/>
+ <validator name="ipv6-address"/>
+ </constraint>
+ </properties>
+ <children>
+ #include <include/interface/vrf.xml.i>
+ </children>
+</tagNode>
+<!-- include end -->
diff --git a/interface-definitions/include/listen-address.xml.i b/interface-definitions/include/listen-address.xml.i
index 9b86851c7..48003dbf2 100644
--- a/interface-definitions/include/listen-address.xml.i
+++ b/interface-definitions/include/listen-address.xml.i
@@ -1,13 +1,13 @@
<!-- include start from listen-address.xml.i -->
<leafNode name="listen-address">
<properties>
- <help>Local IP addresses for service to listen on</help>
+ <help>Local IP addresses to listen on</help>
<completionHelp>
<script>${vyos_completion_dir}/list_local_ips.sh --both</script>
</completionHelp>
<valueHelp>
<format>ipv4</format>
- <description>IP address to listen for incoming connections</description>
+ <description>IPv4 address to listen for incoming connections</description>
</valueHelp>
<valueHelp>
<format>ipv6</format>
@@ -17,6 +17,7 @@
<constraint>
<validator name="ipv4-address"/>
<validator name="ipv6-address"/>
+ <validator name="ipv6-link-local"/>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/include/monitoring/url.xml.i b/interface-definitions/include/monitoring/url.xml.i
new file mode 100644
index 000000000..32c81122d
--- /dev/null
+++ b/interface-definitions/include/monitoring/url.xml.i
@@ -0,0 +1,15 @@
+<!-- include start from monitoring/url.xml.i -->
+<leafNode name="url">
+ <properties>
+ <help>Remote URL [REQUIRED]</help>
+ <valueHelp>
+ <format>url</format>
+ <description>Remote URL</description>
+ </valueHelp>
+ <constraint>
+ <regex>(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}?(\/.*)?</regex>
+ </constraint>
+ <constraintErrorMessage>Incorrect URL format</constraintErrorMessage>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/nat-port.xml.i b/interface-definitions/include/nat-port.xml.i
index ebba43712..5f762cfb3 100644
--- a/interface-definitions/include/nat-port.xml.i
+++ b/interface-definitions/include/nat-port.xml.i
@@ -3,6 +3,10 @@
<properties>
<help>Port number</help>
<valueHelp>
+ <format>txt</format>
+ <description>Named port (any name in /etc/services, e.g., http)</description>
+ </valueHelp>
+ <valueHelp>
<format>u32:1-65535</format>
<description>Numeric IP port</description>
</valueHelp>
@@ -11,9 +15,12 @@
<description>Numbered port range (e.g. 1001-1005)</description>
</valueHelp>
<valueHelp>
- <format> </format>
+ <format/>
<description>\n\nMultiple destination ports can be specified as a comma-separated list.\nThe whole list can also be negated using '!'.\nFor example: '!22,telnet,http,123,1001-1005'</description>
</valueHelp>
+ <constraint>
+ <validator name="port-multi"/>
+ </constraint>
</properties>
</leafNode>
<!-- include end -->
diff --git a/interface-definitions/include/nat-rule.xml.i b/interface-definitions/include/nat-rule.xml.i
index 084f1f722..bdb86ed9b 100644
--- a/interface-definitions/include/nat-rule.xml.i
+++ b/interface-definitions/include/nat-rule.xml.i
@@ -4,7 +4,7 @@
<help>Rule number for NAT</help>
<valueHelp>
<format>u32:1-999999</format>
- <description>Number for this NAT rule</description>
+ <description>Number of NAT rule</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-999999"/>
@@ -12,11 +12,7 @@
<constraintErrorMessage>NAT rule number must be between 1 and 999999</constraintErrorMessage>
</properties>
<children>
- <leafNode name="description">
- <properties>
- <help>Rule description</help>
- </properties>
- </leafNode>
+ #include <include/generic-description.xml.i>
<node name="destination">
<properties>
<help>NAT destination parameters</help>
diff --git a/interface-definitions/include/nat-translation-options.xml.i b/interface-definitions/include/nat-translation-options.xml.i
index df2f76397..6b95de045 100644
--- a/interface-definitions/include/nat-translation-options.xml.i
+++ b/interface-definitions/include/nat-translation-options.xml.i
@@ -16,13 +16,14 @@
</valueHelp>
<valueHelp>
<format>random</format>
- <description>Random source or destination address allocation for each connection (default)</description>
+ <description>Random source or destination address allocation for each connection</description>
</valueHelp>
<constraint>
- <regex>^(persistent|random)$</regex>
+ <regex>(persistent|random)</regex>
</constraint>
</properties>
- </leafNode>
+ <defaultValue>random</defaultValue>
+ </leafNode>
<leafNode name="port-mapping">
<properties>
<help>Port mapping options</help>
@@ -39,13 +40,14 @@
</valueHelp>
<valueHelp>
<format>none</format>
- <description>Do not apply port randomization (default)</description>
+ <description>Do not apply port randomization</description>
</valueHelp>
<constraint>
- <regex>^(random|fully-random|none)$</regex>
+ <regex>(random|fully-random|none)</regex>
</constraint>
</properties>
- </leafNode>
+ <defaultValue>none</defaultValue>
+ </leafNode>
</children>
</node>
<!-- include end -->
diff --git a/interface-definitions/include/nat-translation-port.xml.i b/interface-definitions/include/nat-translation-port.xml.i
index 6e507353c..6f17df3d9 100644
--- a/interface-definitions/include/nat-translation-port.xml.i
+++ b/interface-definitions/include/nat-translation-port.xml.i
@@ -10,6 +10,9 @@
<format>range</format>
<description>Numbered port range (e.g., 1001-1005)</description>
</valueHelp>
+ <constraint>
+ <validator name="port-range"/>
+ </constraint>
</properties>
</leafNode>
<!-- include end -->
diff --git a/interface-definitions/include/ospf/authentication.xml.i b/interface-definitions/include/ospf/authentication.xml.i
index 1e6050b97..8e8cad067 100644
--- a/interface-definitions/include/ospf/authentication.xml.i
+++ b/interface-definitions/include/ospf/authentication.xml.i
@@ -29,7 +29,7 @@
<description>MD5 Key (16 characters or less)</description>
</valueHelp>
<constraint>
- <regex>^[^[:space:]]{1,16}$</regex>
+ <regex>[^[:space:]]{1,16}</regex>
</constraint>
<constraintErrorMessage>Password must be 16 characters or less</constraintErrorMessage>
</properties>
@@ -46,7 +46,7 @@
<description>Plain text password (8 characters or less)</description>
</valueHelp>
<constraint>
- <regex>^[^[:space:]]{1,8}$</regex>
+ <regex>[^[:space:]]{1,8}</regex>
</constraint>
<constraintErrorMessage>Password must be 8 characters or less</constraintErrorMessage>
</properties>
diff --git a/interface-definitions/include/ospf/auto-cost.xml.i b/interface-definitions/include/ospf/auto-cost.xml.i
new file mode 100644
index 000000000..da6483a00
--- /dev/null
+++ b/interface-definitions/include/ospf/auto-cost.xml.i
@@ -0,0 +1,22 @@
+<!-- include start from ospf/auto-cost.xml.i -->
+<node name="auto-cost">
+ <properties>
+ <help>Calculate interface cost according to bandwidth</help>
+ </properties>
+ <children>
+ <leafNode name="reference-bandwidth">
+ <properties>
+ <help>Reference bandwidth method to assign cost</help>
+ <valueHelp>
+ <format>u32:1-4294967</format>
+ <description>Reference bandwidth cost in Mbits/sec</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-4294967"/>
+ </constraint>
+ </properties>
+ <defaultValue>100</defaultValue>
+ </leafNode>
+ </children>
+</node>
+<!-- include end -->
diff --git a/interface-definitions/include/ospf/default-information.xml.i b/interface-definitions/include/ospf/default-information.xml.i
new file mode 100644
index 000000000..50cda54a4
--- /dev/null
+++ b/interface-definitions/include/ospf/default-information.xml.i
@@ -0,0 +1,25 @@
+<!-- include start from ospf/intervals.xml.i -->
+<node name="default-information">
+ <properties>
+ <help>Default route advertisment settings</help>
+ </properties>
+ <children>
+ <node name="originate">
+ <properties>
+ <help>Distribute a default route</help>
+ </properties>
+ <children>
+ <leafNode name="always">
+ <properties>
+ <help>Always advertise a default route</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ #include <include/ospf/metric.xml.i>
+ #include <include/ospf/metric-type.xml.i>
+ #include <include/route-map.xml.i>
+ </children>
+ </node>
+ </children>
+</node>
+<!-- include end -->
diff --git a/interface-definitions/include/ospf/interface-common.xml.i b/interface-definitions/include/ospf/interface-common.xml.i
index 4b0aef380..9c8b94f0b 100644
--- a/interface-definitions/include/ospf/interface-common.xml.i
+++ b/interface-definitions/include/ospf/interface-common.xml.i
@@ -1,5 +1,5 @@
<!-- include start from ospf/interface-common.xml.i -->
-#include <include/bfd.xml.i>
+#include <include/bfd/bfd.xml.i>
<leafNode name="cost">
<properties>
<help>Interface cost</help>
@@ -20,7 +20,7 @@
</leafNode>
<leafNode name="priority">
<properties>
- <help>Router priority (default: 1)</help>
+ <help>Router priority</help>
<valueHelp>
<format>u32:0-255</format>
<description>OSPF router priority cost</description>
diff --git a/interface-definitions/include/ospf/intervals.xml.i b/interface-definitions/include/ospf/intervals.xml.i
index fad1a6305..9f6e5df69 100644
--- a/interface-definitions/include/ospf/intervals.xml.i
+++ b/interface-definitions/include/ospf/intervals.xml.i
@@ -1,7 +1,7 @@
<!-- include start from ospf/intervals.xml.i -->
<leafNode name="dead-interval">
<properties>
- <help>Interval after which a neighbor is declared dead (default: 40)</help>
+ <help>Interval after which a neighbor is declared dead</help>
<valueHelp>
<format>u32:1-65535</format>
<description>Neighbor dead interval (seconds)</description>
@@ -14,7 +14,7 @@
</leafNode>
<leafNode name="hello-interval">
<properties>
- <help>Interval between hello packets (default: 10)</help>
+ <help>Interval between hello packets</help>
<valueHelp>
<format>u32:1-65535</format>
<description>Hello interval (seconds)</description>
@@ -27,7 +27,7 @@
</leafNode>
<leafNode name="retransmit-interval">
<properties>
- <help>Interval between retransmitting lost link state advertisements (default: 5)</help>
+ <help>Interval between retransmitting lost link state advertisements</help>
<valueHelp>
<format>u32:1-65535</format>
<description>Retransmit interval (seconds)</description>
@@ -40,7 +40,7 @@
</leafNode>
<leafNode name="transmit-delay">
<properties>
- <help>Link state transmit delay (default: 1)</help>
+ <help>Link state transmit delay</help>
<valueHelp>
<format>u32:1-65535</format>
<description>Link state transmit delay (seconds)</description>
diff --git a/interface-definitions/include/ospf/metric-type.xml.i b/interface-definitions/include/ospf/metric-type.xml.i
index ef9fd8ac0..de55c7645 100644
--- a/interface-definitions/include/ospf/metric-type.xml.i
+++ b/interface-definitions/include/ospf/metric-type.xml.i
@@ -1,7 +1,7 @@
<!-- include start from ospf/metric-type.xml.i -->
<leafNode name="metric-type">
<properties>
- <help>OSPF metric type for default routes (default: 2)</help>
+ <help>OSPF metric type for default routes</help>
<valueHelp>
<format>u32:1-2</format>
<description>Set OSPF External Type 1/2 metrics</description>
diff --git a/interface-definitions/include/ospf/protocol-common-config.xml.i b/interface-definitions/include/ospf/protocol-common-config.xml.i
index 982e519a9..c156d5b1c 100644
--- a/interface-definitions/include/ospf/protocol-common-config.xml.i
+++ b/interface-definitions/include/ospf/protocol-common-config.xml.i
@@ -45,7 +45,7 @@
<description>Filter static routes</description>
</valueHelp>
<constraint>
- <regex>^(bgp|connected|isis|kernel|rip|static)$</regex>
+ <regex>(bgp|connected|isis|kernel|rip|static)</regex>
</constraint>
<constraintErrorMessage>Must be bgp, connected, kernel, rip, or static</constraintErrorMessage>
<multi/>
@@ -106,7 +106,7 @@
</leafNode>
<leafNode name="translate">
<properties>
- <help>Configure NSSA-ABR (default: candidate)</help>
+ <help>Configure NSSA-ABR</help>
<completionHelp>
<list>always candidate never</list>
</completionHelp>
@@ -116,14 +116,14 @@
</valueHelp>
<valueHelp>
<format>candidate</format>
- <description>Translate for election (default)</description>
+ <description>Translate for election</description>
</valueHelp>
<valueHelp>
<format>never</format>
<description>Never translate LSA types</description>
</valueHelp>
<constraint>
- <regex>^(always|candidate|never)$</regex>
+ <regex>(always|candidate|never)</regex>
</constraint>
</properties>
<defaultValue>candidate</defaultValue>
@@ -172,7 +172,7 @@
<description>Use MD5 authentication</description>
</valueHelp>
<constraint>
- <regex>^(plaintext-password|md5)$</regex>
+ <regex>(plaintext-password|md5)</regex>
</constraint>
</properties>
</leafNode>
@@ -252,72 +252,61 @@
<description>Enable shortcutting mode</description>
</valueHelp>
<constraint>
- <regex>^(default|disable|enable)$</regex>
+ <regex>(default|disable|enable)</regex>
</constraint>
</properties>
</leafNode>
- <tagNode name="virtual-link">
+ <leafNode name="export-list">
<properties>
- <help>Virtual link</help>
+ <help>Set the filter for networks announced to other areas</help>
+ <completionHelp>
+ <path>policy access-list</path>
+ </completionHelp>
<valueHelp>
- <format>ipv4</format>
- <description>OSPF area in dotted decimal notation</description>
+ <format>u32</format>
+ <description>Access-list number</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-4294967295"/>
- <validator name="ip-address"/>
</constraint>
</properties>
- <children>
- #include <include/ospf/authentication.xml.i>
- #include <include/ospf/intervals.xml.i>
- </children>
- </tagNode>
- </children>
-</tagNode>
-<node name="auto-cost">
- <properties>
- <help>Calculate OSPF interface cost according to bandwidth (default: 100)</help>
- </properties>
- <children>
- <leafNode name="reference-bandwidth">
+ </leafNode>
+ <leafNode name="import-list">
<properties>
- <help>Reference bandwidth method to assign OSPF cost</help>
+ <help>Set the filter for networks from other areas announced</help>
+ <completionHelp>
+ <path>policy access-list</path>
+ </completionHelp>
<valueHelp>
- <format>u32:1-4294967</format>
- <description>Reference bandwidth cost in Mbits/sec</description>
+ <format>u32</format>
+ <description>Access-list number</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 1-4294967"/>
+ <validator name="numeric" argument="--range 0-4294967295"/>
</constraint>
</properties>
- <defaultValue>100</defaultValue>
</leafNode>
- </children>
-</node>
-<node name="default-information">
- <properties>
- <help>Default route advertisment settings</help>
- </properties>
- <children>
- <node name="originate">
+ <tagNode name="virtual-link">
<properties>
- <help>Distribute a default route</help>
+ <help>Virtual link</help>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>OSPF area in dotted decimal notation</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-4294967295"/>
+ <validator name="ip-address"/>
+ </constraint>
</properties>
<children>
- <leafNode name="always">
- <properties>
- <help>Always advertise a default route</help>
- <valueless/>
- </properties>
- </leafNode>
- #include <include/ospf/metric.xml.i>
- #include <include/ospf/metric-type.xml.i>
- #include <include/route-map.xml.i>
+ #include <include/ospf/authentication.xml.i>
+ #include <include/ospf/intervals.xml.i>
</children>
- </node>
+ </tagNode>
</children>
-</node>
+</tagNode>
+#include <include/ospf/auto-cost.xml.i>
+#include <include/ospf/default-information.xml.i>
<leafNode name="default-metric">
<properties>
<help>Metric of redistributed routes</help>
@@ -330,6 +319,18 @@
</constraint>
</properties>
</leafNode>
+<leafNode name="maximum-paths">
+ <properties>
+ <help>Maximum multiple paths (ECMP)</help>
+ <valueHelp>
+ <format>u32:1-64</format>
+ <description>Maximum multiple paths (ECMP)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-64"/>
+ </constraint>
+ </properties>
+</leafNode>
<node name="distance">
<properties>
<help>Administrative distance</help>
@@ -431,11 +432,19 @@
<description>Point-to-point network type</description>
</valueHelp>
<constraint>
- <regex>^(broadcast|non-broadcast|point-to-multipoint|point-to-point)$</regex>
+ <regex>(broadcast|non-broadcast|point-to-multipoint|point-to-point)</regex>
</constraint>
<constraintErrorMessage>Must be broadcast, non-broadcast, point-to-multipoint or point-to-point</constraintErrorMessage>
</properties>
</leafNode>
+ <node name="passive">
+ <properties>
+ <help>Suppress routing updates on an interface</help>
+ </properties>
+ <children>
+ #include <include/generic-disable-node.xml.i>
+ </children>
+ </node>
</children>
</tagNode>
#include <include/ospf/log-adjacency-changes.xml.i>
@@ -523,7 +532,7 @@
<children>
<leafNode name="poll-interval">
<properties>
- <help>Dead neighbor polling interval (default: 60)</help>
+ <help>Dead neighbor polling interval</help>
<valueHelp>
<format>u32:1-65535</format>
<description>Seconds between dead neighbor polling interval</description>
@@ -536,7 +545,7 @@
</leafNode>
<leafNode name="priority">
<properties>
- <help>Neighbor priority in seconds (default: 0)</help>
+ <help>Neighbor priority in seconds</help>
<valueHelp>
<format>u32:0-255</format>
<description>Neighbor priority</description>
@@ -556,13 +565,13 @@
<children>
<leafNode name="abr-type">
<properties>
- <help>OSPF ABR type (default: cisco)</help>
+ <help>OSPF ABR type</help>
<completionHelp>
<list>cisco ibm shortcut standard</list>
</completionHelp>
<valueHelp>
<format>cisco</format>
- <description>Cisco ABR type (default)</description>
+ <description>Cisco ABR type</description>
</valueHelp>
<valueHelp>
<format>ibm</format>
@@ -577,7 +586,7 @@
<description>Standard ABR type</description>
</valueHelp>
<constraint>
- <regex>^(cisco|ibm|shortcut|standard)$</regex>
+ <regex>(cisco|ibm|shortcut|standard)</regex>
</constraint>
</properties>
<defaultValue>cisco</defaultValue>
@@ -597,26 +606,19 @@
#include <include/router-id.xml.i>
</children>
</node>
-#include <include/routing-passive-interface.xml.i>
-<leafNode name="passive-interface-exclude">
+<leafNode name="passive-interface">
<properties>
- <help>Interface to exclude when using 'passive-interface default'</help>
+ <help>Suppress routing updates on an interface</help>
<completionHelp>
- <script>${vyos_completion_dir}/list_interfaces.py</script>
+ <list>default</list>
</completionHelp>
<valueHelp>
- <format>txt</format>
- <description>Interface to exclude when suppressing routing updates</description>
- </valueHelp>
- <valueHelp>
- <format>vlinkN</format>
- <description>Virtual-link interface to exclude when suppressing routing updates</description>
+ <format>default</format>
+ <description>Default to suppress routing updates on all interfaces</description>
</valueHelp>
<constraint>
- <validator name="interface-name"/>
- <regex>^(vlink[0-9]+)$</regex>
+ <regex>(default)</regex>
</constraint>
- <multi/>
</properties>
</leafNode>
<node name="redistribute">
@@ -740,7 +742,7 @@
<children>
<leafNode name="delay">
<properties>
- <help>Delay from the first change received to SPF calculation (default: 200)</help>
+ <help>Delay from the first change received to SPF calculation</help>
<valueHelp>
<format>u32:0-600000</format>
<description>Delay in milliseconds</description>
@@ -753,7 +755,7 @@
</leafNode>
<leafNode name="initial-holdtime">
<properties>
- <help>Initial hold time between consecutive SPF calculations (default: 1000)</help>
+ <help>Initial hold time between consecutive SPF calculations</help>
<valueHelp>
<format>u32:0-600000</format>
<description>Initial hold time in milliseconds</description>
@@ -766,7 +768,7 @@
</leafNode>
<leafNode name="max-holdtime">
<properties>
- <help>Maximum hold time (default: 10000)</help>
+ <help>Maximum hold time</help>
<valueHelp>
<format>u32:0-600000</format>
<description>Max hold time in milliseconds</description>
diff --git a/interface-definitions/include/ospfv3/no-summary.xml.i b/interface-definitions/include/ospfv3/no-summary.xml.i
new file mode 100644
index 000000000..a6afda3e0
--- /dev/null
+++ b/interface-definitions/include/ospfv3/no-summary.xml.i
@@ -0,0 +1,8 @@
+<!-- include start from ospfv3/no-summary.xml.i -->
+<leafNode name="no-summary">
+ <properties>
+ <help>Do not inject inter-area routes into the stub</help>
+ <valueless/>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/ospfv3/protocol-common-config.xml.i b/interface-definitions/include/ospfv3/protocol-common-config.xml.i
new file mode 100644
index 000000000..630534eea
--- /dev/null
+++ b/interface-definitions/include/ospfv3/protocol-common-config.xml.i
@@ -0,0 +1,252 @@
+<!-- include start from ospfv3/protocol-common-config.xml.i -->
+<tagNode name="area">
+ <properties>
+ <help>OSPFv3 Area</help>
+ <valueHelp>
+ <format>u32</format>
+ <description>Area ID as a decimal value</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>Area ID in IP address forma</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-4294967295"/>
+ <validator name="ip-address"/>
+ </constraint>
+ </properties>
+ <children>
+ <node name="area-type">
+ <properties>
+ <help>OSPFv3 Area type</help>
+ </properties>
+ <children>
+ <node name="nssa">
+ <properties>
+ <help>NSSA OSPFv3 area</help>
+ </properties>
+ <children>
+ <leafNode name="default-information-originate">
+ <properties>
+ <help>Originate Type 7 default into NSSA area</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ #include <include/ospfv3/no-summary.xml.i>
+ </children>
+ </node>
+ <node name="stub">
+ <properties>
+ <help>Stub OSPFv3 area</help>
+ </properties>
+ <children>
+ #include <include/ospfv3/no-summary.xml.i>
+ </children>
+ </node>
+ </children>
+ </node>
+ <leafNode name="export-list">
+ <properties>
+ <help>Name of export-list</help>
+ <completionHelp>
+ <path>policy access-list6</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ <leafNode name="import-list">
+ <properties>
+ <help>Name of import-list</help>
+ <completionHelp>
+ <path>policy access-list6</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ <tagNode name="range">
+ <properties>
+ <help>Specify IPv6 prefix (border routers only)</help>
+ <valueHelp>
+ <format>ipv6net</format>
+ <description>Specify IPv6 prefix (border routers only)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv6-prefix"/>
+ </constraint>
+ </properties>
+ <children>
+ <leafNode name="advertise">
+ <properties>
+ <help>Advertise this range</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="not-advertise">
+ <properties>
+ <help>Do not advertise this range</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ </children>
+ </tagNode>
+ </children>
+</tagNode>
+#include <include/ospf/auto-cost.xml.i>
+#include <include/ospf/default-information.xml.i>
+<node name="distance">
+ <properties>
+ <help>Administrative distance</help>
+ </properties>
+ <children>
+ #include <include/ospf/distance-global.xml.i>
+ <node name="ospfv3">
+ <properties>
+ <help>OSPFv3 administrative distance</help>
+ </properties>
+ <children>
+ #include <include/ospf/distance-per-protocol.xml.i>
+ </children>
+ </node>
+ </children>
+</node>
+<tagNode name="interface">
+ <properties>
+ <help>Enable routing on an IPv6 interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces.py</script>
+ </completionHelp>
+ <valueHelp>
+ <format>txt</format>
+ <description>Interface used for routing information exchange</description>
+ </valueHelp>
+ <constraint>
+ <validator name="interface-name"/>
+ </constraint>
+ </properties>
+ <children>
+ <leafNode name="area">
+ <properties>
+ <help>Enable OSPF on this interface</help>
+ <completionHelp>
+ <path>protocols ospfv3 area</path>
+ </completionHelp>
+ <valueHelp>
+ <format>u32</format>
+ <description>OSPF area ID as decimal notation</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>OSPF area ID in IP address notation</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-4294967295"/>
+ <validator name="ip-address"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ #include <include/ospf/intervals.xml.i>
+ #include <include/ospf/interface-common.xml.i>
+ <leafNode name="ifmtu">
+ <properties>
+ <help>Interface MTU</help>
+ <valueHelp>
+ <format>u32:1-65535</format>
+ <description>Interface MTU</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-65535"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="instance-id">
+ <properties>
+ <help>Instance ID</help>
+ <valueHelp>
+ <format>u32:0-255</format>
+ <description>Instance Id</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-255"/>
+ </constraint>
+ </properties>
+ <defaultValue>0</defaultValue>
+ </leafNode>
+ <leafNode name="network">
+ <properties>
+ <help>Network type</help>
+ <completionHelp>
+ <list>broadcast point-to-point</list>
+ </completionHelp>
+ <valueHelp>
+ <format>broadcast</format>
+ <description>Broadcast network type</description>
+ </valueHelp>
+ <valueHelp>
+ <format>point-to-point</format>
+ <description>Point-to-point network type</description>
+ </valueHelp>
+ <constraint>
+ <regex>(broadcast|point-to-point)</regex>
+ </constraint>
+ <constraintErrorMessage>Must be broadcast or point-to-point</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ #include <include/isis/passive.xml.i>
+ </children>
+</tagNode>
+#include <include/ospf/log-adjacency-changes.xml.i>
+<node name="parameters">
+ <properties>
+ <help>OSPFv3 specific parameters</help>
+ </properties>
+ <children>
+ #include <include/router-id.xml.i>
+ </children>
+</node>
+<node name="redistribute">
+ <properties>
+ <help>Redistribute information from another routing protocol</help>
+ </properties>
+ <children>
+ <node name="bgp">
+ <properties>
+ <help>Redistribute BGP routes</help>
+ </properties>
+ <children>
+ #include <include/route-map.xml.i>
+ </children>
+ </node>
+ <node name="connected">
+ <properties>
+ <help>Redistribute connected routes</help>
+ </properties>
+ <children>
+ #include <include/route-map.xml.i>
+ </children>
+ </node>
+ <node name="kernel">
+ <properties>
+ <help>Redistribute kernel routes</help>
+ </properties>
+ <children>
+ #include <include/route-map.xml.i>
+ </children>
+ </node>
+ <node name="ripng">
+ <properties>
+ <help>Redistribute RIPNG routes</help>
+ </properties>
+ <children>
+ #include <include/route-map.xml.i>
+ </children>
+ </node>
+ <node name="static">
+ <properties>
+ <help>Redistribute static routes</help>
+ </properties>
+ <children>
+ #include <include/route-map.xml.i>
+ </children>
+ </node>
+ </children>
+</node>
+#include <include/route-map.xml.i>
+<!-- include end -->
diff --git a/interface-definitions/include/policy/action.xml.i b/interface-definitions/include/policy/action.xml.i
index 3b9b458d4..0a3dc158a 100644
--- a/interface-definitions/include/policy/action.xml.i
+++ b/interface-definitions/include/policy/action.xml.i
@@ -14,7 +14,7 @@
<description>Deny matching entries</description>
</valueHelp>
<constraint>
- <regex>^(permit|deny)$</regex>
+ <regex>(permit|deny)</regex>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/include/policy/route-common-rule-ipv6.xml.i b/interface-definitions/include/policy/route-common-rule-ipv6.xml.i
new file mode 100644
index 000000000..cfeba1a6c
--- /dev/null
+++ b/interface-definitions/include/policy/route-common-rule-ipv6.xml.i
@@ -0,0 +1,553 @@
+<!-- include start from policy/route-common-rule.xml.i -->
+#include <include/policy/route-rule-action.xml.i>
+#include <include/generic-description.xml.i>
+<leafNode name="disable">
+ <properties>
+ <help>Option to disable firewall rule</help>
+ <valueless/>
+ </properties>
+</leafNode>
+<node name="fragment">
+ <properties>
+ <help>IP fragment match</help>
+ </properties>
+ <children>
+ <leafNode name="match-frag">
+ <properties>
+ <help>Second and further fragments of fragmented packets</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="match-non-frag">
+ <properties>
+ <help>Head fragments or unfragmented packets</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<node name="ipsec">
+ <properties>
+ <help>Inbound IPsec packets</help>
+ </properties>
+ <children>
+ <leafNode name="match-ipsec">
+ <properties>
+ <help>Inbound IPsec packets</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="match-none">
+ <properties>
+ <help>Inbound non-IPsec packets</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<node name="limit">
+ <properties>
+ <help>Rate limit using a token bucket filter</help>
+ </properties>
+ <children>
+ <leafNode name="burst">
+ <properties>
+ <help>Maximum number of packets to allow in excess of rate</help>
+ <valueHelp>
+ <format>u32:0-4294967295</format>
+ <description>Maximum number of packets to allow in excess of rate</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-4294967295"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="rate">
+ <properties>
+ <help>Maximum average matching rate</help>
+ <valueHelp>
+ <format>u32:0-4294967295</format>
+ <description>Maximum average matching rate</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-4294967295"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<leafNode name="log">
+ <properties>
+ <help>Option to log packets matching rule</help>
+ <completionHelp>
+ <list>enable disable</list>
+ </completionHelp>
+ <valueHelp>
+ <format>enable</format>
+ <description>Enable log</description>
+ </valueHelp>
+ <valueHelp>
+ <format>disable</format>
+ <description>Disable log</description>
+ </valueHelp>
+ <constraint>
+ <regex>(enable|disable)</regex>
+ </constraint>
+ </properties>
+</leafNode>
+<leafNode name="protocol">
+ <properties>
+ <help>Protocol to match (protocol name, number, or "all")</help>
+ <completionHelp>
+ <script>cat /etc/protocols | sed -e '/^#.*/d' | awk '{ print $1 }'</script>
+ </completionHelp>
+ <valueHelp>
+ <format>all</format>
+ <description>All IP protocols</description>
+ </valueHelp>
+ <valueHelp>
+ <format>tcp_udp</format>
+ <description>Both TCP and UDP</description>
+ </valueHelp>
+ <valueHelp>
+ <format>0-255</format>
+ <description>IP protocol number</description>
+ </valueHelp>
+ <valueHelp>
+ <format>!&lt;protocol&gt;</format>
+ <description>IP protocol number</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ip-protocol"/>
+ </constraint>
+ </properties>
+ <defaultValue>all</defaultValue>
+</leafNode>
+<node name="recent">
+ <properties>
+ <help>Parameters for matching recently seen sources</help>
+ </properties>
+ <children>
+ <leafNode name="count">
+ <properties>
+ <help>Source addresses seen more than N times</help>
+ <valueHelp>
+ <format>u32:1-255</format>
+ <description>Source addresses seen more than N times</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-255"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="time">
+ <properties>
+ <help>Source addresses seen in the last N seconds</help>
+ <valueHelp>
+ <format>u32:0-4294967295</format>
+ <description>Source addresses seen in the last N seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-4294967295"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<node name="set">
+ <properties>
+ <help>Packet modifications</help>
+ </properties>
+ <children>
+ <leafNode name="dscp">
+ <properties>
+ <help>Packet Differentiated Services Codepoint (DSCP)</help>
+ <valueHelp>
+ <format>u32:0-63</format>
+ <description>DSCP number</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-63"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="mark">
+ <properties>
+ <help>Packet marking</help>
+ <valueHelp>
+ <format>u32:1-2147483647</format>
+ <description>Packet marking</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-2147483647"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="table">
+ <properties>
+ <help>Routing table to forward packet with</help>
+ <valueHelp>
+ <format>u32:1-200</format>
+ <description>Table number</description>
+ </valueHelp>
+ <valueHelp>
+ <format>main</format>
+ <description>Main table</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-200"/>
+ <regex>(main)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="tcp-mss">
+ <properties>
+ <help>TCP Maximum Segment Size</help>
+ <valueHelp>
+ <format>u32:500-1460</format>
+ <description>Explicitly set TCP MSS value</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 500-1460"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<node name="source">
+ <properties>
+ <help>Source parameters</help>
+ </properties>
+ <children>
+ #include <include/firewall/address-ipv6.xml.i>
+ #include <include/firewall/source-destination-group.xml.i>
+ <leafNode name="mac-address">
+ <properties>
+ <help>Source MAC address</help>
+ <valueHelp>
+ <format>&lt;MAC address&gt;</format>
+ <description>MAC address to match</description>
+ </valueHelp>
+ <valueHelp>
+ <format>!&lt;MAC address&gt;</format>
+ <description>Match everything except the specified MAC address</description>
+ </valueHelp>
+ <constraint>
+ <validator name="mac-address-firewall"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ #include <include/firewall/port.xml.i>
+ </children>
+</node>
+<node name="state">
+ <properties>
+ <help>Session state</help>
+ </properties>
+ <children>
+ <leafNode name="established">
+ <properties>
+ <help>Established state</help>
+ <completionHelp>
+ <list>enable disable</list>
+ </completionHelp>
+ <valueHelp>
+ <format>enable</format>
+ <description>Enable</description>
+ </valueHelp>
+ <valueHelp>
+ <format>disable</format>
+ <description>Disable</description>
+ </valueHelp>
+ <constraint>
+ <regex>(enable|disable)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="invalid">
+ <properties>
+ <help>Invalid state</help>
+ <completionHelp>
+ <list>enable disable</list>
+ </completionHelp>
+ <valueHelp>
+ <format>enable</format>
+ <description>Enable</description>
+ </valueHelp>
+ <valueHelp>
+ <format>disable</format>
+ <description>Disable</description>
+ </valueHelp>
+ <constraint>
+ <regex>(enable|disable)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="new">
+ <properties>
+ <help>New state</help>
+ <completionHelp>
+ <list>enable disable</list>
+ </completionHelp>
+ <valueHelp>
+ <format>enable</format>
+ <description>Enable</description>
+ </valueHelp>
+ <valueHelp>
+ <format>disable</format>
+ <description>Disable</description>
+ </valueHelp>
+ <constraint>
+ <regex>(enable|disable)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="related">
+ <properties>
+ <help>Related state</help>
+ <completionHelp>
+ <list>enable disable</list>
+ </completionHelp>
+ <valueHelp>
+ <format>enable</format>
+ <description>Enable</description>
+ </valueHelp>
+ <valueHelp>
+ <format>disable</format>
+ <description>Disable</description>
+ </valueHelp>
+ <constraint>
+ <regex>(enable|disable)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+#include <include/firewall/tcp-flags.xml.i>
+<node name="time">
+ <properties>
+ <help>Time to match rule</help>
+ </properties>
+ <children>
+ <leafNode name="monthdays">
+ <properties>
+ <help>Monthdays to match rule on</help>
+ </properties>
+ </leafNode>
+ <leafNode name="startdate">
+ <properties>
+ <help>Date to start matching rule</help>
+ </properties>
+ </leafNode>
+ <leafNode name="starttime">
+ <properties>
+ <help>Time of day to start matching rule</help>
+ </properties>
+ </leafNode>
+ <leafNode name="stopdate">
+ <properties>
+ <help>Date to stop matching rule</help>
+ </properties>
+ </leafNode>
+ <leafNode name="stoptime">
+ <properties>
+ <help>Time of day to stop matching rule</help>
+ </properties>
+ </leafNode>
+ <leafNode name="utc">
+ <properties>
+ <help>Interpret times for startdate, stopdate, starttime and stoptime to be UTC</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="weekdays">
+ <properties>
+ <help>Weekdays to match rule on</help>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<node name="icmpv6">
+ <properties>
+ <help>ICMPv6 type and code information</help>
+ </properties>
+ <children>
+ <leafNode name="type">
+ <properties>
+ <help>ICMP type-name</help>
+ <completionHelp>
+ <list>any echo-reply pong destination-unreachable network-unreachable host-unreachable protocol-unreachable port-unreachable fragmentation-needed source-route-failed network-unknown host-unknown network-prohibited host-prohibited TOS-network-unreachable TOS-host-unreachable communication-prohibited host-precedence-violation precedence-cutoff source-quench redirect network-redirect host-redirect TOS-network-redirect TOS host-redirect echo-request ping router-advertisement router-solicitation time-exceeded ttl-exceeded ttl-zero-during-transit ttl-zero-during-reassembly parameter-problem ip-header-bad required-option-missing timestamp-request timestamp-reply address-mask-request address-mask-reply packet-too-big</list>
+ </completionHelp>
+ <valueHelp>
+ <format>any</format>
+ <description>Any ICMP type/code</description>
+ </valueHelp>
+ <valueHelp>
+ <format>echo-reply</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>pong</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>destination-unreachable</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>network-unreachable</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>host-unreachable</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>protocol-unreachable</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>port-unreachable</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>fragmentation-needed</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>source-route-failed</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>network-unknown</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>host-unknown</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>network-prohibited</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>host-prohibited</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>TOS-network-unreachable</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>TOS-host-unreachable</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>communication-prohibited</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>host-precedence-violation</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>precedence-cutoff</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>source-quench</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>redirect</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>network-redirect</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>host-redirect</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>TOS-network-redirect</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>TOS host-redirect</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>echo-request</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ping</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>router-advertisement</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>router-solicitation</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>time-exceeded</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ttl-exceeded</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ttl-zero-during-transit</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ttl-zero-during-reassembly</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>parameter-problem</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ip-header-bad</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>required-option-missing</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>timestamp-request</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>timestamp-reply</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>address-mask-request</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>address-mask-reply</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>packet-too-big</format>
+ <description>ICMP type/code name</description>
+ </valueHelp>
+ <constraint>
+ <regex>(any|echo-reply|pong|destination-unreachable|network-unreachable|host-unreachable|protocol-unreachable|port-unreachable|fragmentation-needed|source-route-failed|network-unknown|host-unknown|network-prohibited|host-prohibited|TOS-network-unreachable|TOS-host-unreachable|communication-prohibited|host-precedence-violation|precedence-cutoff|source-quench|redirect|network-redirect|host-redirect|TOS-network-redirect|TOS host-redirect|echo-request|ping|router-advertisement|router-solicitation|time-exceeded|ttl-exceeded|ttl-zero-during-transit|ttl-zero-during-reassembly|parameter-problem|ip-header-bad|required-option-missing|timestamp-request|timestamp-reply|address-mask-request|address-mask-reply|packet-too-big)</regex>
+ <validator name="numeric" argument="--range 0-255"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<!-- include end -->
diff --git a/interface-definitions/include/policy/route-common-rule.xml.i b/interface-definitions/include/policy/route-common-rule.xml.i
new file mode 100644
index 000000000..5a17dbc95
--- /dev/null
+++ b/interface-definitions/include/policy/route-common-rule.xml.i
@@ -0,0 +1,402 @@
+<!-- include start from policy/route-common-rule.xml.i -->
+#include <include/policy/route-rule-action.xml.i>
+#include <include/generic-description.xml.i>
+<leafNode name="disable">
+ <properties>
+ <help>Option to disable firewall rule</help>
+ <valueless/>
+ </properties>
+</leafNode>
+<node name="fragment">
+ <properties>
+ <help>IP fragment match</help>
+ </properties>
+ <children>
+ <leafNode name="match-frag">
+ <properties>
+ <help>Second and further fragments of fragmented packets</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="match-non-frag">
+ <properties>
+ <help>Head fragments or unfragmented packets</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<node name="ipsec">
+ <properties>
+ <help>Inbound IPsec packets</help>
+ </properties>
+ <children>
+ <leafNode name="match-ipsec">
+ <properties>
+ <help>Inbound IPsec packets</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="match-none">
+ <properties>
+ <help>Inbound non-IPsec packets</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<node name="limit">
+ <properties>
+ <help>Rate limit using a token bucket filter</help>
+ </properties>
+ <children>
+ <leafNode name="burst">
+ <properties>
+ <help>Maximum number of packets to allow in excess of rate</help>
+ <valueHelp>
+ <format>u32:0-4294967295</format>
+ <description>Maximum number of packets to allow in excess of rate</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-4294967295"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="rate">
+ <properties>
+ <help>Maximum average matching rate</help>
+ <valueHelp>
+ <format>u32:0-4294967295</format>
+ <description>Maximum average matching rate</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-4294967295"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<leafNode name="log">
+ <properties>
+ <help>Option to log packets matching rule</help>
+ <completionHelp>
+ <list>enable disable</list>
+ </completionHelp>
+ <valueHelp>
+ <format>enable</format>
+ <description>Enable log</description>
+ </valueHelp>
+ <valueHelp>
+ <format>disable</format>
+ <description>Disable log</description>
+ </valueHelp>
+ <constraint>
+ <regex>(enable|disable)</regex>
+ </constraint>
+ </properties>
+</leafNode>
+<leafNode name="protocol">
+ <properties>
+ <help>Protocol to match (protocol name, number, or "all")</help>
+ <completionHelp>
+ <script>cat /etc/protocols | sed -e '/^#.*/d' | awk '{ print $1 }'</script>
+ </completionHelp>
+ <valueHelp>
+ <format>all</format>
+ <description>All IP protocols</description>
+ </valueHelp>
+ <valueHelp>
+ <format>tcp_udp</format>
+ <description>Both TCP and UDP</description>
+ </valueHelp>
+ <valueHelp>
+ <format>0-255</format>
+ <description>IP protocol number</description>
+ </valueHelp>
+ <valueHelp>
+ <format>!&lt;protocol&gt;</format>
+ <description>IP protocol number</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ip-protocol"/>
+ </constraint>
+ </properties>
+ <defaultValue>all</defaultValue>
+</leafNode>
+<node name="recent">
+ <properties>
+ <help>Parameters for matching recently seen sources</help>
+ </properties>
+ <children>
+ <leafNode name="count">
+ <properties>
+ <help>Source addresses seen more than N times</help>
+ <valueHelp>
+ <format>u32:1-255</format>
+ <description>Source addresses seen more than N times</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-255"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="time">
+ <properties>
+ <help>Source addresses seen in the last N seconds</help>
+ <valueHelp>
+ <format>u32:0-4294967295</format>
+ <description>Source addresses seen in the last N seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-4294967295"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<node name="set">
+ <properties>
+ <help>Packet modifications</help>
+ </properties>
+ <children>
+ <leafNode name="dscp">
+ <properties>
+ <help>Packet Differentiated Services Codepoint (DSCP)</help>
+ <valueHelp>
+ <format>u32:0-63</format>
+ <description>DSCP number</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-63"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="mark">
+ <properties>
+ <help>Packet marking</help>
+ <valueHelp>
+ <format>u32:1-2147483647</format>
+ <description>Packet marking</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-2147483647"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="table">
+ <properties>
+ <help>Routing table to forward packet with</help>
+ <valueHelp>
+ <format>u32:1-200</format>
+ <description>Table number</description>
+ </valueHelp>
+ <valueHelp>
+ <format>main</format>
+ <description>Main table</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-200"/>
+ <regex>(main)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="tcp-mss">
+ <properties>
+ <help>TCP Maximum Segment Size</help>
+ <valueHelp>
+ <format>u32:500-1460</format>
+ <description>Explicitly set TCP MSS value</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 500-1460"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<node name="source">
+ <properties>
+ <help>Source parameters</help>
+ </properties>
+ <children>
+ #include <include/firewall/address.xml.i>
+ #include <include/firewall/source-destination-group.xml.i>
+ <leafNode name="mac-address">
+ <properties>
+ <help>Source MAC address</help>
+ <valueHelp>
+ <format>&lt;MAC address&gt;</format>
+ <description>MAC address to match</description>
+ </valueHelp>
+ <valueHelp>
+ <format>!&lt;MAC address&gt;</format>
+ <description>Match everything except the specified MAC address</description>
+ </valueHelp>
+ <constraint>
+ <validator name="mac-address-firewall"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ #include <include/firewall/port.xml.i>
+ </children>
+</node>
+<node name="state">
+ <properties>
+ <help>Session state</help>
+ </properties>
+ <children>
+ <leafNode name="established">
+ <properties>
+ <help>Established state</help>
+ <completionHelp>
+ <list>enable disable</list>
+ </completionHelp>
+ <valueHelp>
+ <format>enable</format>
+ <description>Enable</description>
+ </valueHelp>
+ <valueHelp>
+ <format>disable</format>
+ <description>Disable</description>
+ </valueHelp>
+ <constraint>
+ <regex>(enable|disable)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="invalid">
+ <properties>
+ <help>Invalid state</help>
+ <completionHelp>
+ <list>enable disable</list>
+ </completionHelp>
+ <valueHelp>
+ <format>enable</format>
+ <description>Enable</description>
+ </valueHelp>
+ <valueHelp>
+ <format>disable</format>
+ <description>Disable</description>
+ </valueHelp>
+ <constraint>
+ <regex>(enable|disable)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="new">
+ <properties>
+ <help>New state</help>
+ <completionHelp>
+ <list>enable disable</list>
+ </completionHelp>
+ <valueHelp>
+ <format>enable</format>
+ <description>Enable</description>
+ </valueHelp>
+ <valueHelp>
+ <format>disable</format>
+ <description>Disable</description>
+ </valueHelp>
+ <constraint>
+ <regex>(enable|disable)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="related">
+ <properties>
+ <help>Related state</help>
+ <completionHelp>
+ <list>enable disable</list>
+ </completionHelp>
+ <valueHelp>
+ <format>enable</format>
+ <description>Enable</description>
+ </valueHelp>
+ <valueHelp>
+ <format>disable</format>
+ <description>Disable</description>
+ </valueHelp>
+ <constraint>
+ <regex>(enable|disable)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+#include <include/firewall/tcp-flags.xml.i>
+<node name="time">
+ <properties>
+ <help>Time to match rule</help>
+ </properties>
+ <children>
+ <leafNode name="monthdays">
+ <properties>
+ <help>Monthdays to match rule on</help>
+ </properties>
+ </leafNode>
+ <leafNode name="startdate">
+ <properties>
+ <help>Date to start matching rule</help>
+ </properties>
+ </leafNode>
+ <leafNode name="starttime">
+ <properties>
+ <help>Time of day to start matching rule</help>
+ </properties>
+ </leafNode>
+ <leafNode name="stopdate">
+ <properties>
+ <help>Date to stop matching rule</help>
+ </properties>
+ </leafNode>
+ <leafNode name="stoptime">
+ <properties>
+ <help>Time of day to stop matching rule</help>
+ </properties>
+ </leafNode>
+ <leafNode name="utc">
+ <properties>
+ <help>Interpret times for startdate, stopdate, starttime and stoptime to be UTC</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="weekdays">
+ <properties>
+ <help>Weekdays to match rule on</help>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<node name="icmp">
+ <properties>
+ <help>ICMP type and code information</help>
+ </properties>
+ <children>
+ <leafNode name="code">
+ <properties>
+ <help>ICMP code (0-255)</help>
+ <valueHelp>
+ <format>u32:0-255</format>
+ <description>ICMP code (0-255)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-255"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="type">
+ <properties>
+ <help>ICMP type (0-255)</help>
+ <valueHelp>
+ <format>u32:0-255</format>
+ <description>ICMP type (0-255)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-255"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ #include <include/firewall/icmp-type-name.xml.i>
+ </children>
+</node>
+<!-- include end -->
diff --git a/interface-definitions/include/policy/route-rule-action.xml.i b/interface-definitions/include/policy/route-rule-action.xml.i
new file mode 100644
index 000000000..1217055f2
--- /dev/null
+++ b/interface-definitions/include/policy/route-rule-action.xml.i
@@ -0,0 +1,17 @@
+<!-- include start from policy/route-rule-action.xml.i -->
+<leafNode name="action">
+ <properties>
+ <help>Rule action [REQUIRED]</help>
+ <completionHelp>
+ <list>drop</list>
+ </completionHelp>
+ <valueHelp>
+ <format>drop</format>
+ <description>Drop matching entries</description>
+ </valueHelp>
+ <constraint>
+ <regex>(drop)</regex>
+ </constraint>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/qos/bandwidth.xml.i b/interface-definitions/include/qos/bandwidth.xml.i
new file mode 100644
index 000000000..82af22f42
--- /dev/null
+++ b/interface-definitions/include/qos/bandwidth.xml.i
@@ -0,0 +1,15 @@
+<!-- include start from qos/bandwidth.xml.i -->
+<leafNode name="bandwidth">
+ <properties>
+ <help>Traffic-limit used for this class</help>
+ <valueHelp>
+ <format>&lt;number&gt;</format>
+ <description>Rate in kbit (kilobit per second)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;&lt;suffix&gt;</format>
+ <description>Rate with scaling suffix (mbit, mbps, ...)</description>
+ </valueHelp>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/qos/burst.xml.i b/interface-definitions/include/qos/burst.xml.i
new file mode 100644
index 000000000..761618027
--- /dev/null
+++ b/interface-definitions/include/qos/burst.xml.i
@@ -0,0 +1,16 @@
+<!-- include start from qos/burst.xml.i -->
+<leafNode name="burst">
+ <properties>
+ <help>Burst size for this class</help>
+ <valueHelp>
+ <format>&lt;number&gt;</format>
+ <description>Bytes</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;&lt;suffix&gt;</format>
+ <description>Bytes with scaling suffix (kb, mb, gb)</description>
+ </valueHelp>
+ </properties>
+ <defaultValue>15k</defaultValue>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/qos/codel-quantum.xml.i b/interface-definitions/include/qos/codel-quantum.xml.i
new file mode 100644
index 000000000..bc24630b6
--- /dev/null
+++ b/interface-definitions/include/qos/codel-quantum.xml.i
@@ -0,0 +1,16 @@
+<!-- include start from qos/codel-quantum.xml.i -->
+<leafNode name="codel-quantum">
+ <properties>
+ <help>Deficit in the fair queuing algorithm</help>
+ <valueHelp>
+ <format>u32:0-1048576</format>
+ <description>Number of bytes used as 'deficit'</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-1048576"/>
+ </constraint>
+ <constraintErrorMessage>Interval must be in range 0 to 1048576</constraintErrorMessage>
+ </properties>
+ <defaultValue>1514</defaultValue>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/qos/dscp.xml.i b/interface-definitions/include/qos/dscp.xml.i
new file mode 100644
index 000000000..bb90850ac
--- /dev/null
+++ b/interface-definitions/include/qos/dscp.xml.i
@@ -0,0 +1,143 @@
+<!-- include start from qos/dscp.xml.i -->
+<leafNode name="dscp">
+ <properties>
+ <help>Match on Differentiated Services Codepoint (DSCP)</help>
+ <completionHelp>
+ <list>default reliability throughput lowdelay priority immediate flash flash-override critical internet network AF11 AF12 AF13 AF21 AF22 AF23 AF31 AF32 AF33 AF41 AF42 AF43 CS1 CS2 CS3 CS4 CS5 CS6 CS7 EF</list>
+ </completionHelp>
+ <valueHelp>
+ <format>u32:0-63</format>
+ <description>Differentiated Services Codepoint (DSCP) value </description>
+ </valueHelp>
+ <valueHelp>
+ <format>default</format>
+ <description>match DSCP (000000)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>reliability</format>
+ <description>match DSCP (000001)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>throughput</format>
+ <description>match DSCP (000010)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>lowdelay</format>
+ <description>match DSCP (000100)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>priority</format>
+ <description>match DSCP (001000)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>immediate</format>
+ <description>match DSCP (010000)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>flash</format>
+ <description>match DSCP (011000)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>flash-override</format>
+ <description>match DSCP (100000)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>critical</format>
+ <description>match DSCP (101000)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>internet</format>
+ <description>match DSCP (110000)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>network</format>
+ <description>match DSCP (111000)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>AF11</format>
+ <description>High-throughput data</description>
+ </valueHelp>
+ <valueHelp>
+ <format>AF12</format>
+ <description>High-throughput data</description>
+ </valueHelp>
+ <valueHelp>
+ <format>AF13</format>
+ <description>High-throughput data</description>
+ </valueHelp>
+ <valueHelp>
+ <format>AF21</format>
+ <description>Low-latency data</description>
+ </valueHelp>
+ <valueHelp>
+ <format>AF22</format>
+ <description>Low-latency data</description>
+ </valueHelp>
+ <valueHelp>
+ <format>AF23</format>
+ <description>Low-latency data</description>
+ </valueHelp>
+ <valueHelp>
+ <format>AF31</format>
+ <description>Multimedia streaming</description>
+ </valueHelp>
+ <valueHelp>
+ <format>AF32</format>
+ <description>Multimedia streaming</description>
+ </valueHelp>
+ <valueHelp>
+ <format>AF33</format>
+ <description>Multimedia streaming</description>
+ </valueHelp>
+ <valueHelp>
+ <format>AF41</format>
+ <description>Multimedia conferencing</description>
+ </valueHelp>
+ <valueHelp>
+ <format>AF42</format>
+ <description>Multimedia conferencing</description>
+ </valueHelp>
+ <valueHelp>
+ <format>AF43</format>
+ <description>Multimedia conferencing</description>
+ </valueHelp>
+ <valueHelp>
+ <format>CS1</format>
+ <description>Low-priority data</description>
+ </valueHelp>
+ <valueHelp>
+ <format>CS2</format>
+ <description>OAM</description>
+ </valueHelp>
+ <valueHelp>
+ <format>CS3</format>
+ <description>Broadcast video</description>
+ </valueHelp>
+ <valueHelp>
+ <format>CS4</format>
+ <description>Real-time interactive</description>
+ </valueHelp>
+ <valueHelp>
+ <format>CS5</format>
+ <description>Signaling</description>
+ </valueHelp>
+ <valueHelp>
+ <format>CS6</format>
+ <description>Network control</description>
+ </valueHelp>
+ <valueHelp>
+ <format>CS7</format>
+ <description></description>
+ </valueHelp>
+ <valueHelp>
+ <format>EF</format>
+ <description>Expedited Forwarding</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-63"/>
+ <regex>(default|reliability|throughput|lowdelay|priority|immediate|flash|flash-override|critical|internet|network|AF11|AF12|AF13|AF21|AF22|AF23|AF31|AF32|AF33|AF41|AF42|AF43|CS1|CS2|CS3|CS4|CS5|CS6|CS7|EF)</regex>
+ </constraint>
+ <constraintErrorMessage>Priority must be between 0 and 63</constraintErrorMessage>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/qos/flows.xml.i b/interface-definitions/include/qos/flows.xml.i
new file mode 100644
index 000000000..a7d7c6422
--- /dev/null
+++ b/interface-definitions/include/qos/flows.xml.i
@@ -0,0 +1,16 @@
+<!-- include start from qos/flows.xml.i -->
+<leafNode name="flows">
+ <properties>
+ <help>Number of flows into which the incoming packets are classified</help>
+ <valueHelp>
+ <format>u32:1-65536</format>
+ <description>Number of flows</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-65536"/>
+ </constraint>
+ <constraintErrorMessage>Interval must be in range 1 to 65536</constraintErrorMessage>
+ </properties>
+ <defaultValue>1024</defaultValue>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/qos/hfsc-d.xml.i b/interface-definitions/include/qos/hfsc-d.xml.i
new file mode 100644
index 000000000..2a513509c
--- /dev/null
+++ b/interface-definitions/include/qos/hfsc-d.xml.i
@@ -0,0 +1,15 @@
+<!-- include start from qos/hfsc-d.xml.i -->
+<leafNode name="d">
+ <properties>
+ <help>Service curve delay</help>
+ <valueHelp>
+ <format>&lt;number&gt;</format>
+ <description>Time in milliseconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-65535"/>
+ </constraint>
+ <constraintErrorMessage>Priority must be between 0 and 65535</constraintErrorMessage>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/qos/hfsc-m1.xml.i b/interface-definitions/include/qos/hfsc-m1.xml.i
new file mode 100644
index 000000000..749d01f57
--- /dev/null
+++ b/interface-definitions/include/qos/hfsc-m1.xml.i
@@ -0,0 +1,32 @@
+<!-- include start from qos/hfsc-m1.xml.i -->
+<leafNode name="m1">
+ <properties>
+ <help>Linkshare m1 parameter for class traffic</help>
+ <valueHelp>
+ <format>&lt;number&gt;</format>
+ <description>Rate in kbit (kilobit per second)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;%%</format>
+ <description>Percentage of overall rate</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;bit</format>
+ <description>bit(1), kbit(10^3), mbit(10^6), gbit, tbit</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;ibit</format>
+ <description>kibit(1024), mibit(1024^2), gibit(1024^3), tbit(1024^4)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;ibps</format>
+ <description>kibps(1024*8), mibps(1024^2*8), gibps, tibps - Byte/sec</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;bps</format>
+ <description>bps(8),kbps(8*10^3),mbps(8*10^6), gbps, tbps - Byte/sec</description>
+ </valueHelp>
+ </properties>
+ <defaultValue>100%</defaultValue>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/qos/hfsc-m2.xml.i b/interface-definitions/include/qos/hfsc-m2.xml.i
new file mode 100644
index 000000000..24e8f5d63
--- /dev/null
+++ b/interface-definitions/include/qos/hfsc-m2.xml.i
@@ -0,0 +1,32 @@
+<!-- include start from qos/hfsc-m2.xml.i -->
+<leafNode name="m2">
+ <properties>
+ <help>Linkshare m2 parameter for class traffic</help>
+ <valueHelp>
+ <format>&lt;number&gt;</format>
+ <description>Rate in kbit (kilobit per second)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;%%</format>
+ <description>Percentage of overall rate</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;bit</format>
+ <description>bit(1), kbit(10^3), mbit(10^6), gbit, tbit</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;ibit</format>
+ <description>kibit(1024), mibit(1024^2), gibit(1024^3), tbit(1024^4)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;ibps</format>
+ <description>kibps(1024*8), mibps(1024^2*8), gibps, tibps - Byte/sec</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;bps</format>
+ <description>bps(8),kbps(8*10^3),mbps(8*10^6), gbps, tbps - Byte/sec</description>
+ </valueHelp>
+ </properties>
+ <defaultValue>100%</defaultValue>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/qos/interval.xml.i b/interface-definitions/include/qos/interval.xml.i
new file mode 100644
index 000000000..41896ac9c
--- /dev/null
+++ b/interface-definitions/include/qos/interval.xml.i
@@ -0,0 +1,16 @@
+<!-- include start from qos/interval.xml.i -->
+<leafNode name="interval">
+ <properties>
+ <help>Interval used to measure the delay</help>
+ <valueHelp>
+ <format>u32</format>
+ <description>Interval in milliseconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-4294967295"/>
+ </constraint>
+ <constraintErrorMessage>Interval must be in range 0 to 4294967295</constraintErrorMessage>
+ </properties>
+ <defaultValue>100</defaultValue>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/qos/match.xml.i b/interface-definitions/include/qos/match.xml.i
new file mode 100644
index 000000000..7d89e4460
--- /dev/null
+++ b/interface-definitions/include/qos/match.xml.i
@@ -0,0 +1,221 @@
+<!-- include start from qos/match.xml.i -->
+<tagNode name="match">
+ <properties>
+ <help>Class matching rule name</help>
+ <constraint>
+ <regex>[^-].*</regex>
+ </constraint>
+ <constraintErrorMessage>Match queue name cannot start with hyphen (-)</constraintErrorMessage>
+ </properties>
+ <children>
+ #include <include/generic-description.xml.i>
+ <node name="ether">
+ <properties>
+ <help>Ethernet header match</help>
+ </properties>
+ <children>
+ <leafNode name="destination">
+ <properties>
+ <help>Ethernet destination address for this match</help>
+ <valueHelp>
+ <format>macaddr</format>
+ <description>MAC address to match</description>
+ </valueHelp>
+ <constraint>
+ <validator name="mac-address"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="protocol">
+ <properties>
+ <help>Ethernet protocol for this match</help>
+ <!-- this refers to /etc/protocols -->
+ <completionHelp>
+ <list>all 802.1Q 802_2 802_3 aarp aoe arp atalk dec ip ipv6 ipx lat localtalk rarp snap x25</list>
+ </completionHelp>
+ <valueHelp>
+ <format>u32:0-65535</format>
+ <description>Ethernet protocol number</description>
+ </valueHelp>
+ <valueHelp>
+ <format>txt</format>
+ <description>Ethernet protocol name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>all</format>
+ <description>Any protocol</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ip</format>
+ <description>Internet IP (IPv4)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv6</format>
+ <description>Internet IP (IPv6)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>arp</format>
+ <description>Address Resolution Protocol</description>
+ </valueHelp>
+ <valueHelp>
+ <format>atalk</format>
+ <description>Appletalk</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipx</format>
+ <description>Novell Internet Packet Exchange</description>
+ </valueHelp>
+ <valueHelp>
+ <format>802.1Q</format>
+ <description>802.1Q VLAN tag</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ip-protocol"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="source">
+ <properties>
+ <help>Ethernet source address for this match</help>
+ <valueHelp>
+ <format>macaddr</format>
+ <description>MAC address to match</description>
+ </valueHelp>
+ <constraint>
+ <validator name="mac-address"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ #include <include/generic-interface.xml.i>
+ <node name="ip">
+ <properties>
+ <help>Match IP protocol header</help>
+ </properties>
+ <children>
+ <node name="destination">
+ <properties>
+ <help>Match on destination port or address</help>
+ </properties>
+ <children>
+ <leafNode name="address">
+ <properties>
+ <help>IPv4 destination address for this match</help>
+ <valueHelp>
+ <format>ipv4net</format>
+ <description>IPv4 address and prefix length</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv4"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ #include <include/port-number.xml.i>
+ </children>
+ </node>
+ #include <include/qos/dscp.xml.i>
+ #include <include/qos/max-length.xml.i>
+ #include <include/ip-protocol.xml.i>
+ <node name="source">
+ <properties>
+ <help>Match on source port or address</help>
+ </properties>
+ <children>
+ <leafNode name="address">
+ <properties>
+ <help>IPv4 source address for this match</help>
+ <valueHelp>
+ <format>ipv4net</format>
+ <description>IPv4 address and prefix length</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv4"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ #include <include/port-number.xml.i>
+ </children>
+ </node>
+ #include <include/qos/tcp-flags.xml.i>
+ </children>
+ </node>
+ <node name="ipv6">
+ <properties>
+ <help>Match IPv6 protocol header</help>
+ </properties>
+ <children>
+ <node name="destination">
+ <properties>
+ <help>Match on destination port or address</help>
+ </properties>
+ <children>
+ <leafNode name="address">
+ <properties>
+ <help>IPv6 destination address for this match</help>
+ <valueHelp>
+ <format>ipv6net</format>
+ <description>IPv6 address and prefix length</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv6"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ #include <include/port-number.xml.i>
+ </children>
+ </node>
+ #include <include/qos/dscp.xml.i>
+ #include <include/qos/max-length.xml.i>
+ #include <include/ip-protocol.xml.i>
+ <node name="source">
+ <properties>
+ <help>Match on source port or address</help>
+ </properties>
+ <children>
+ <leafNode name="address">
+ <properties>
+ <help>IPv6 source address for this match</help>
+ <valueHelp>
+ <format>ipv6net</format>
+ <description>IPv6 address and prefix length</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv6"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ #include <include/port-number.xml.i>
+ </children>
+ </node>
+ #include <include/qos/tcp-flags.xml.i>
+ </children>
+ </node>
+ <leafNode name="mark">
+ <properties>
+ <help>Match on mark applied by firewall</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>FW mark to match</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0x0-0xffff"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="vif">
+ <properties>
+ <help>Virtual Local Area Network (VLAN) ID for this match</help>
+ <valueHelp>
+ <format>u32:0-4095</format>
+ <description>Virtual Local Area Network (VLAN) tag </description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-4095"/>
+ </constraint>
+ <constraintErrorMessage>VLAN ID must be between 0 and 4095</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ </children>
+</tagNode>
+<!-- include end -->
diff --git a/interface-definitions/include/qos/max-length.xml.i b/interface-definitions/include/qos/max-length.xml.i
new file mode 100644
index 000000000..4cc20f8c4
--- /dev/null
+++ b/interface-definitions/include/qos/max-length.xml.i
@@ -0,0 +1,15 @@
+<!-- include start from qos/max-length.xml.i -->
+<leafNode name="max-length">
+ <properties>
+ <help>Maximum packet length (ipv4)</help>
+ <valueHelp>
+ <format>u32:0-65535</format>
+ <description>Maximum packet/payload length</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-65535"/>
+ </constraint>
+ <constraintErrorMessage>Maximum IPv4 total packet length is 65535</constraintErrorMessage>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/qos/queue-limit-1-4294967295.xml.i b/interface-definitions/include/qos/queue-limit-1-4294967295.xml.i
new file mode 100644
index 000000000..2f2d44631
--- /dev/null
+++ b/interface-definitions/include/qos/queue-limit-1-4294967295.xml.i
@@ -0,0 +1,15 @@
+<!-- include start from qos/queue-limit-1-4294967295.xml.i -->
+<leafNode name="queue-limit">
+ <properties>
+ <help>Maximum queue size</help>
+ <valueHelp>
+ <format>u32:1-4294967295</format>
+ <description>Queue size in packets</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-4294967295"/>
+ </constraint>
+ <constraintErrorMessage>Queue limit must be greater than zero</constraintErrorMessage>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/qos/queue-limit-2-10999.xml.i b/interface-definitions/include/qos/queue-limit-2-10999.xml.i
new file mode 100644
index 000000000..7a9c8266b
--- /dev/null
+++ b/interface-definitions/include/qos/queue-limit-2-10999.xml.i
@@ -0,0 +1,16 @@
+<!-- include start from qos/queue-limit.xml.i -->
+<leafNode name="queue-limit">
+ <properties>
+ <help>Upper limit of the queue</help>
+ <valueHelp>
+ <format>u32:2-10999</format>
+ <description>Queue size in packets</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 2-10999"/>
+ </constraint>
+ <constraintErrorMessage>Queue limit must greater than 1 and less than 11000</constraintErrorMessage>
+ </properties>
+ <defaultValue>10240</defaultValue>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/qos/queue-type.xml.i b/interface-definitions/include/qos/queue-type.xml.i
new file mode 100644
index 000000000..634f61024
--- /dev/null
+++ b/interface-definitions/include/qos/queue-type.xml.i
@@ -0,0 +1,30 @@
+<!-- include start from qos/queue-type.xml.i -->
+<leafNode name="queue-type">
+ <properties>
+ <help>Queue type for default traffic</help>
+ <completionHelp>
+ <list>fq-codel fair-queue drop-tail random-detect</list>
+ </completionHelp>
+ <valueHelp>
+ <format>fq-codel</format>
+ <description>Fair Queue Codel</description>
+ </valueHelp>
+ <valueHelp>
+ <format>fair-queue</format>
+ <description>Stochastic Fair Queue (SFQ)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>drop-tail</format>
+ <description>First-In-First-Out (FIFO)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>random-detect</format>
+ <description>Random Early Detection (RED)</description>
+ </valueHelp>
+ <constraint>
+ <regex>(fq-codel|fair-queue|drop-tail|random-detect)</regex>
+ </constraint>
+ </properties>
+ <defaultValue>drop-tail</defaultValue>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/qos/set-dscp.xml.i b/interface-definitions/include/qos/set-dscp.xml.i
new file mode 100644
index 000000000..55c0ea44d
--- /dev/null
+++ b/interface-definitions/include/qos/set-dscp.xml.i
@@ -0,0 +1,63 @@
+<!-- include start from qos/set-dscp.xml.i -->
+<leafNode name="set-dscp">
+ <properties>
+ <help>Change the Differentiated Services (DiffServ) field in the IP header</help>
+ <completionHelp>
+ <list>default reliability throughput lowdelay priority immediate flash flash-override critical internet network</list>
+ </completionHelp>
+ <valueHelp>
+ <format>u32:0-63</format>
+ <description>Priority order for bandwidth pool</description>
+ </valueHelp>
+ <valueHelp>
+ <format>default</format>
+ <description>match DSCP (000000)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>reliability</format>
+ <description>match DSCP (000001)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>throughput</format>
+ <description>match DSCP (000010)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>lowdelay</format>
+ <description>match DSCP (000100)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>priority</format>
+ <description>match DSCP (001000)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>immediate</format>
+ <description>match DSCP (010000)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>flash</format>
+ <description>match DSCP (011000)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>flash-override</format>
+ <description>match DSCP (100000)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>critical</format>
+ <description>match DSCP (101000)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>internet</format>
+ <description>match DSCP (110000)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>network</format>
+ <description>match DSCP (111000)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-63"/>
+ <regex>(default|reliability|throughput|lowdelay|priority|immediate|flash|flash-override|critical|internet|network)</regex>
+ </constraint>
+ <constraintErrorMessage>Priority must be between 0 and 63</constraintErrorMessage>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/qos/target.xml.i b/interface-definitions/include/qos/target.xml.i
new file mode 100644
index 000000000..bf6342ac9
--- /dev/null
+++ b/interface-definitions/include/qos/target.xml.i
@@ -0,0 +1,16 @@
+<!-- include start from qos/target.xml.i -->
+<leafNode name="target">
+ <properties>
+ <help>Acceptable minimum standing/persistent queue delay</help>
+ <valueHelp>
+ <format>u32</format>
+ <description>Queue delay in milliseconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-4294967295"/>
+ </constraint>
+ <constraintErrorMessage>Delay must be in range 0 to 4294967295</constraintErrorMessage>
+ </properties>
+ <defaultValue>5</defaultValue>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/qos/tcp-flags.xml.i b/interface-definitions/include/qos/tcp-flags.xml.i
new file mode 100644
index 000000000..81d70d1f3
--- /dev/null
+++ b/interface-definitions/include/qos/tcp-flags.xml.i
@@ -0,0 +1,21 @@
+<!-- include start from qos/tcp-flags.xml.i -->
+<node name="tcp">
+ <properties>
+ <help>TCP Flags matching</help>
+ </properties>
+ <children>
+ <leafNode name="ack">
+ <properties>
+ <help>Match TCP ACK</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="syn">
+ <properties>
+ <help>Match TCP SYN</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<!-- include end -->
diff --git a/interface-definitions/include/radius-server-port.xml.i b/interface-definitions/include/radius-server-port.xml.i
index 4e5d906bc..c6b691a0f 100644
--- a/interface-definitions/include/radius-server-port.xml.i
+++ b/interface-definitions/include/radius-server-port.xml.i
@@ -4,7 +4,7 @@
<help>Authentication port</help>
<valueHelp>
<format>u32:1-65535</format>
- <description>Numeric IP port (default: 1812)</description>
+ <description>Numeric IP port</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-65535"/>
diff --git a/interface-definitions/include/rip/rip-timers.xml.i b/interface-definitions/include/rip/rip-timers.xml.i
index 3aaaf8e65..129d9ed23 100644
--- a/interface-definitions/include/rip/rip-timers.xml.i
+++ b/interface-definitions/include/rip/rip-timers.xml.i
@@ -9,7 +9,7 @@
<help>Garbage collection timer</help>
<valueHelp>
<format>u32:5-2147483647</format>
- <description>Garbage colletion time (default 120)</description>
+ <description>Garbage colletion time</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 5-2147483647"/>
@@ -22,7 +22,7 @@
<help>Routing information timeout timer</help>
<valueHelp>
<format>u32:5-2147483647</format>
- <description>Routing information timeout timer (default 180)</description>
+ <description>Routing information timeout timer</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 5-2147483647"/>
@@ -35,7 +35,7 @@
<help>Routing table update timer</help>
<valueHelp>
<format>u32:5-2147483647</format>
- <description>Routing table update timer in seconds (default 30)</description>
+ <description>Routing table update timer in seconds</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 5-2147483647"/>
diff --git a/interface-definitions/include/route-map.xml.i b/interface-definitions/include/route-map.xml.i
index 88092b7d4..019868373 100644
--- a/interface-definitions/include/route-map.xml.i
+++ b/interface-definitions/include/route-map.xml.i
@@ -10,7 +10,7 @@
<description>Route map name</description>
</valueHelp>
<constraint>
- <regex>^[-_a-zA-Z0-9.]+$</regex>
+ <regex>[-_a-zA-Z0-9.]+</regex>
</constraint>
<constraintErrorMessage>Name of route-map can only contain alpha-numeric letters, hyphen and underscores</constraintErrorMessage>
</properties>
diff --git a/interface-definitions/include/routing-passive-interface.xml.i b/interface-definitions/include/routing-passive-interface.xml.i
index 43dfb5e44..095b683de 100644
--- a/interface-definitions/include/routing-passive-interface.xml.i
+++ b/interface-definitions/include/routing-passive-interface.xml.i
@@ -15,7 +15,7 @@
<description>Default to suppress routing updates on all interfaces</description>
</valueHelp>
<constraint>
- <regex>^(default)$</regex>
+ <regex>(default)</regex>
<validator name="interface-name"/>
</constraint>
<multi/>
diff --git a/interface-definitions/include/snmp/access-mode.xml.i b/interface-definitions/include/snmp/access-mode.xml.i
new file mode 100644
index 000000000..7469805ac
--- /dev/null
+++ b/interface-definitions/include/snmp/access-mode.xml.i
@@ -0,0 +1,23 @@
+<!-- include start from snmp/access-mode.xml.i -->
+<leafNode name="mode">
+ <properties>
+ <help>Define access permission</help>
+ <completionHelp>
+ <list>ro rw</list>
+ </completionHelp>
+ <valueHelp>
+ <format>ro</format>
+ <description>Read-Only</description>
+ </valueHelp>
+ <valueHelp>
+ <format>rw</format>
+ <description>read write</description>
+ </valueHelp>
+ <constraint>
+ <regex>(ro|rw)</regex>
+ </constraint>
+ <constraintErrorMessage>Authorization type must be either 'rw' or 'ro'</constraintErrorMessage>
+ </properties>
+ <defaultValue>ro</defaultValue>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/snmp/authentication-type.xml.i b/interface-definitions/include/snmp/authentication-type.xml.i
new file mode 100644
index 000000000..047d8cff4
--- /dev/null
+++ b/interface-definitions/include/snmp/authentication-type.xml.i
@@ -0,0 +1,22 @@
+<!-- include start from snmp/authentication-type.xml.i -->
+<leafNode name="type">
+ <properties>
+ <help>Define used protocol</help>
+ <completionHelp>
+ <list>md5 sha</list>
+ </completionHelp>
+ <valueHelp>
+ <format>md5</format>
+ <description>Message Digest 5</description>
+ </valueHelp>
+ <valueHelp>
+ <format>sha</format>
+ <description>Secure Hash Algorithm</description>
+ </valueHelp>
+ <constraint>
+ <regex>(md5|sha)</regex>
+ </constraint>
+ </properties>
+ <defaultValue>md5</defaultValue>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/snmp/privacy-type.xml.i b/interface-definitions/include/snmp/privacy-type.xml.i
new file mode 100644
index 000000000..d5fd1e811
--- /dev/null
+++ b/interface-definitions/include/snmp/privacy-type.xml.i
@@ -0,0 +1,22 @@
+<!-- include start from snmp/privacy-type.xml.i -->
+<leafNode name="type">
+ <properties>
+ <help>Defines the protocol for privacy</help>
+ <completionHelp>
+ <list>des aes</list>
+ </completionHelp>
+ <valueHelp>
+ <format>des</format>
+ <description>Data Encryption Standard</description>
+ </valueHelp>
+ <valueHelp>
+ <format>aes</format>
+ <description>Advanced Encryption Standard</description>
+ </valueHelp>
+ <constraint>
+ <regex>(des|aes)</regex>
+ </constraint>
+ </properties>
+ <defaultValue>des</defaultValue>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/snmp/protocol.xml.i b/interface-definitions/include/snmp/protocol.xml.i
new file mode 100644
index 000000000..d7e6752ad
--- /dev/null
+++ b/interface-definitions/include/snmp/protocol.xml.i
@@ -0,0 +1,22 @@
+<!-- include start from snmp/protocol.xml.i -->
+<leafNode name="protocol">
+ <properties>
+ <help>Protocol to be used (TCP/UDP)</help>
+ <completionHelp>
+ <list>udp tcp</list>
+ </completionHelp>
+ <valueHelp>
+ <format>udp</format>
+ <description>Listen protocol UDP</description>
+ </valueHelp>
+ <valueHelp>
+ <format>tcp</format>
+ <description>Listen protocol TCP</description>
+ </valueHelp>
+ <constraint>
+ <regex>(udp|tcp)</regex>
+ </constraint>
+ </properties>
+ <defaultValue>udp</defaultValue>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/ssh-user.xml.i b/interface-definitions/include/ssh-user.xml.i
index 677602dd8..6ac1f35bc 100644
--- a/interface-definitions/include/ssh-user.xml.i
+++ b/interface-definitions/include/ssh-user.xml.i
@@ -3,9 +3,9 @@
<properties>
<help>Allow specific users to login</help>
<constraint>
- <regex>[a-z_][a-z0-9_-]{1,31}[$]?</regex>
+ <regex>[-_a-zA-Z0-9.]{1,100}</regex>
</constraint>
- <constraintErrorMessage>illegal characters or more than 32 characters</constraintErrorMessage>
+ <constraintErrorMessage>Illegal characters or more than 100 characters</constraintErrorMessage>
<multi/>
</properties>
</leafNode>
diff --git a/interface-definitions/include/static/static-route-blackhole.xml.i b/interface-definitions/include/static/static-route-blackhole.xml.i
index f2ad23e69..487f775f5 100644
--- a/interface-definitions/include/static/static-route-blackhole.xml.i
+++ b/interface-definitions/include/static/static-route-blackhole.xml.i
@@ -1,10 +1,11 @@
<!-- include start from static/static-route-blackhole.xml.i -->
<node name="blackhole">
<properties>
- <help>Silently discard packets when matched</help>
+ <help>Silently discard pkts when matched</help>
</properties>
<children>
#include <include/static/static-route-distance.xml.i>
+ #include <include/static/static-route-tag.xml.i>
</children>
</node>
<!-- include end -->
diff --git a/interface-definitions/include/static/static-route-reject.xml.i b/interface-definitions/include/static/static-route-reject.xml.i
new file mode 100644
index 000000000..81d4f9afd
--- /dev/null
+++ b/interface-definitions/include/static/static-route-reject.xml.i
@@ -0,0 +1,12 @@
+<!-- include start from static/static-route-blackhole.xml.i -->
+<node name="reject">
+ <properties>
+ <help>Emit an ICMP unreachable when matched</help>
+ </properties>
+ <children>
+ #include <include/static/static-route-distance.xml.i>
+ #include <include/static/static-route-tag.xml.i>
+ </children>
+</node>
+<!-- include end -->
+
diff --git a/interface-definitions/include/static/static-route-tag.xml.i b/interface-definitions/include/static/static-route-tag.xml.i
new file mode 100644
index 000000000..24bfa732e
--- /dev/null
+++ b/interface-definitions/include/static/static-route-tag.xml.i
@@ -0,0 +1,14 @@
+<!-- include start from static/static-route-tag.xml.i -->
+<leafNode name="tag">
+ <properties>
+ <help>Tag value for this route</help>
+ <valueHelp>
+ <format>u32:1-4294967295</format>
+ <description>Tag value for this route</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-4294967295"/>
+ </constraint>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/static/static-route-vrf.xml.i b/interface-definitions/include/static/static-route-vrf.xml.i
index 69aba253c..e1968f04a 100644
--- a/interface-definitions/include/static/static-route-vrf.xml.i
+++ b/interface-definitions/include/static/static-route-vrf.xml.i
@@ -11,7 +11,7 @@
<description>Name of VRF to leak to</description>
</valueHelp>
<constraint>
- <regex>^(default)$</regex>
+ <regex>(default)</regex>
<validator name="vrf-name"/>
</constraint>
</properties>
diff --git a/interface-definitions/include/static/static-route.xml.i b/interface-definitions/include/static/static-route.xml.i
index 21babc015..2de5dc58f 100644
--- a/interface-definitions/include/static/static-route.xml.i
+++ b/interface-definitions/include/static/static-route.xml.i
@@ -1,7 +1,7 @@
<!-- include start from static/static-route.xml.i -->
<tagNode name="route">
<properties>
- <help>VRF static IPv4 route</help>
+ <help>Static IPv4 route</help>
<valueHelp>
<format>ipv4net</format>
<description>IPv4 static route</description>
@@ -11,26 +11,8 @@
</constraint>
</properties>
<children>
- <node name="blackhole">
- <properties>
- <help>Silently discard pkts when matched</help>
- </properties>
- <children>
- #include <include/static/static-route-distance.xml.i>
- <leafNode name="tag">
- <properties>
- <help>Tag value for this route</help>
- <valueHelp>
- <format>u32:1-4294967295</format>
- <description>Tag value for this route</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-4294967295"/>
- </constraint>
- </properties>
- </leafNode>
- </children>
- </node>
+ #include <include/static/static-route-blackhole.xml.i>
+ #include <include/static/static-route-reject.xml.i>
#include <include/dhcp-interface.xml.i>
<tagNode name="interface">
<properties>
diff --git a/interface-definitions/include/static/static-route6.xml.i b/interface-definitions/include/static/static-route6.xml.i
index 0ea995588..35feef41c 100644
--- a/interface-definitions/include/static/static-route6.xml.i
+++ b/interface-definitions/include/static/static-route6.xml.i
@@ -1,7 +1,7 @@
<!-- include start from static/static-route6.xml.i -->
<tagNode name="route6">
<properties>
- <help>VRF static IPv6 route</help>
+ <help>Static IPv6 route</help>
<valueHelp>
<format>ipv6net</format>
<description>IPv6 static route</description>
@@ -11,26 +11,8 @@
</constraint>
</properties>
<children>
- <node name="blackhole">
- <properties>
- <help>Silently discard pkts when matched</help>
- </properties>
- <children>
- #include <include/static/static-route-distance.xml.i>
- <leafNode name="tag">
- <properties>
- <help>Tag value for this route</help>
- <valueHelp>
- <format>u32:1-4294967295</format>
- <description>Tag value for this route</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-4294967295"/>
- </constraint>
- </properties>
- </leafNode>
- </children>
- </node>
+ #include <include/static/static-route-blackhole.xml.i>
+ #include <include/static/static-route-reject.xml.i>
<tagNode name="interface">
<properties>
<help>IPv6 gateway interface name</help>
diff --git a/interface-definitions/include/version/bgp-version.xml.i b/interface-definitions/include/version/bgp-version.xml.i
new file mode 100644
index 000000000..15bc5abd4
--- /dev/null
+++ b/interface-definitions/include/version/bgp-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/bgp-version.xml.i -->
+<syntaxVersion component='bgp' version='2'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/broadcast-relay-version.xml.i b/interface-definitions/include/version/broadcast-relay-version.xml.i
new file mode 100644
index 000000000..98481f446
--- /dev/null
+++ b/interface-definitions/include/version/broadcast-relay-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/broadcast-relay-version.xml.i -->
+<syntaxVersion component='broadcast-relay' version='1'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/cluster-version.xml.i b/interface-definitions/include/version/cluster-version.xml.i
new file mode 100644
index 000000000..621996df4
--- /dev/null
+++ b/interface-definitions/include/version/cluster-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/cluster-version.xml.i -->
+<syntaxVersion component='cluster' version='1'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/config-management-version.xml.i b/interface-definitions/include/version/config-management-version.xml.i
new file mode 100644
index 000000000..695ba09ab
--- /dev/null
+++ b/interface-definitions/include/version/config-management-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/config-management-version.xml.i -->
+<syntaxVersion component='config-management' version='1'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/conntrack-sync-version.xml.i b/interface-definitions/include/version/conntrack-sync-version.xml.i
new file mode 100644
index 000000000..f040c29f6
--- /dev/null
+++ b/interface-definitions/include/version/conntrack-sync-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/conntrack-sync-version.xml.i -->
+<syntaxVersion component='conntrack-sync' version='2'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/conntrack-version.xml.i b/interface-definitions/include/version/conntrack-version.xml.i
new file mode 100644
index 000000000..696f76362
--- /dev/null
+++ b/interface-definitions/include/version/conntrack-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/conntrack-version.xml.i -->
+<syntaxVersion component='conntrack' version='3'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/dhcp-relay-version.xml.i b/interface-definitions/include/version/dhcp-relay-version.xml.i
new file mode 100644
index 000000000..75f5d5486
--- /dev/null
+++ b/interface-definitions/include/version/dhcp-relay-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/dhcp-relay-version.xml.i -->
+<syntaxVersion component='dhcp-relay' version='2'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/dhcp-server-version.xml.i b/interface-definitions/include/version/dhcp-server-version.xml.i
new file mode 100644
index 000000000..330cb7d1b
--- /dev/null
+++ b/interface-definitions/include/version/dhcp-server-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/dhcp-server-version.xml.i -->
+<syntaxVersion component='dhcp-server' version='6'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/dhcpv6-server-version.xml.i b/interface-definitions/include/version/dhcpv6-server-version.xml.i
new file mode 100644
index 000000000..4b2cf40aa
--- /dev/null
+++ b/interface-definitions/include/version/dhcpv6-server-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/dhcpv6-server-version.xml.i -->
+<syntaxVersion component='dhcpv6-server' version='1'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/dns-forwarding-version.xml.i b/interface-definitions/include/version/dns-forwarding-version.xml.i
new file mode 100644
index 000000000..fe817940a
--- /dev/null
+++ b/interface-definitions/include/version/dns-forwarding-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/dns-forwarding-version.xml.i -->
+<syntaxVersion component='dns-forwarding' version='3'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/firewall-version.xml.i b/interface-definitions/include/version/firewall-version.xml.i
new file mode 100644
index 000000000..059a89f24
--- /dev/null
+++ b/interface-definitions/include/version/firewall-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/firewall-version.xml.i -->
+<syntaxVersion component='firewall' version='7'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/flow-accounting-version.xml.i b/interface-definitions/include/version/flow-accounting-version.xml.i
new file mode 100644
index 000000000..5b01fe4b5
--- /dev/null
+++ b/interface-definitions/include/version/flow-accounting-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/flow-accounting-version.xml.i -->
+<syntaxVersion component='flow-accounting' version='1'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/https-version.xml.i b/interface-definitions/include/version/https-version.xml.i
new file mode 100644
index 000000000..586083649
--- /dev/null
+++ b/interface-definitions/include/version/https-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/https-version.xml.i -->
+<syntaxVersion component='https' version='3'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/interfaces-version.xml.i b/interface-definitions/include/version/interfaces-version.xml.i
new file mode 100644
index 000000000..0a209bc3a
--- /dev/null
+++ b/interface-definitions/include/version/interfaces-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/interfaces-version.xml.i -->
+<syntaxVersion component='interfaces' version='26'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/ipoe-server-version.xml.i b/interface-definitions/include/version/ipoe-server-version.xml.i
new file mode 100644
index 000000000..00d2544e6
--- /dev/null
+++ b/interface-definitions/include/version/ipoe-server-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/ipoe-server-version.xml.i -->
+<syntaxVersion component='ipoe-server' version='1'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/ipsec-version.xml.i b/interface-definitions/include/version/ipsec-version.xml.i
new file mode 100644
index 000000000..59295cc91
--- /dev/null
+++ b/interface-definitions/include/version/ipsec-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/ipsec-version.xml.i -->
+<syntaxVersion component='ipsec' version='9'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/isis-version.xml.i b/interface-definitions/include/version/isis-version.xml.i
new file mode 100644
index 000000000..4a8fef39c
--- /dev/null
+++ b/interface-definitions/include/version/isis-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/isis-version.xml.i -->
+<syntaxVersion component='isis' version='1'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/l2tp-version.xml.i b/interface-definitions/include/version/l2tp-version.xml.i
new file mode 100644
index 000000000..86114d676
--- /dev/null
+++ b/interface-definitions/include/version/l2tp-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/l2tp-version.xml.i -->
+<syntaxVersion component='l2tp' version='4'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/lldp-version.xml.i b/interface-definitions/include/version/lldp-version.xml.i
new file mode 100644
index 000000000..0deb73279
--- /dev/null
+++ b/interface-definitions/include/version/lldp-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/lldp-version.xml.i -->
+<syntaxVersion component='lldp' version='1'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/mdns-version.xml.i b/interface-definitions/include/version/mdns-version.xml.i
new file mode 100644
index 000000000..b200a68b4
--- /dev/null
+++ b/interface-definitions/include/version/mdns-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/mdns-version.xml.i -->
+<syntaxVersion component='mdns' version='1'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/nat-version.xml.i b/interface-definitions/include/version/nat-version.xml.i
new file mode 100644
index 000000000..027216a07
--- /dev/null
+++ b/interface-definitions/include/version/nat-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/nat-version.xml.i -->
+<syntaxVersion component='nat' version='5'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/nat66-version.xml.i b/interface-definitions/include/version/nat66-version.xml.i
new file mode 100644
index 000000000..7b7123dcc
--- /dev/null
+++ b/interface-definitions/include/version/nat66-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/nat66-version.xml.i -->
+<syntaxVersion component='nat66' version='1'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/ntp-version.xml.i b/interface-definitions/include/version/ntp-version.xml.i
new file mode 100644
index 000000000..cc4ff9a1c
--- /dev/null
+++ b/interface-definitions/include/version/ntp-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/ntp-version.xml.i -->
+<syntaxVersion component='ntp' version='1'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/openconnect-version.xml.i b/interface-definitions/include/version/openconnect-version.xml.i
new file mode 100644
index 000000000..654806278
--- /dev/null
+++ b/interface-definitions/include/version/openconnect-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/openconnect-version.xml.i -->
+<syntaxVersion component='openconnect' version='2'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/ospf-version.xml.i b/interface-definitions/include/version/ospf-version.xml.i
new file mode 100644
index 000000000..755965daa
--- /dev/null
+++ b/interface-definitions/include/version/ospf-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/ospf-version.xml.i -->
+<syntaxVersion component='ospf' version='1'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/policy-version.xml.i b/interface-definitions/include/version/policy-version.xml.i
new file mode 100644
index 000000000..6d0c80518
--- /dev/null
+++ b/interface-definitions/include/version/policy-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/policy-version.xml.i -->
+<syntaxVersion component='policy' version='2'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/pppoe-server-version.xml.i b/interface-definitions/include/version/pppoe-server-version.xml.i
new file mode 100644
index 000000000..ec81487f8
--- /dev/null
+++ b/interface-definitions/include/version/pppoe-server-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/pppoe-server-version.xml.i -->
+<syntaxVersion component='pppoe-server' version='5'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/pptp-version.xml.i b/interface-definitions/include/version/pptp-version.xml.i
new file mode 100644
index 000000000..0296c44e9
--- /dev/null
+++ b/interface-definitions/include/version/pptp-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/pptp-version.xml.i -->
+<syntaxVersion component='pptp' version='2'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/qos-version.xml.i b/interface-definitions/include/version/qos-version.xml.i
new file mode 100644
index 000000000..e4d139349
--- /dev/null
+++ b/interface-definitions/include/version/qos-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/qos-version.xml.i -->
+<syntaxVersion component='qos' version='1'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/quagga-version.xml.i b/interface-definitions/include/version/quagga-version.xml.i
new file mode 100644
index 000000000..f9944acce
--- /dev/null
+++ b/interface-definitions/include/version/quagga-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/quagga-version.xml.i -->
+<syntaxVersion component='quagga' version='10'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/rpki-version.xml.i b/interface-definitions/include/version/rpki-version.xml.i
new file mode 100644
index 000000000..2fff259a8
--- /dev/null
+++ b/interface-definitions/include/version/rpki-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/rpki-version.xml.i -->
+<syntaxVersion component='rpki' version='1'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/salt-version.xml.i b/interface-definitions/include/version/salt-version.xml.i
new file mode 100644
index 000000000..fe4684050
--- /dev/null
+++ b/interface-definitions/include/version/salt-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/salt-version.xml.i -->
+<syntaxVersion component='salt' version='1'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/snmp-version.xml.i b/interface-definitions/include/version/snmp-version.xml.i
new file mode 100644
index 000000000..0416288f0
--- /dev/null
+++ b/interface-definitions/include/version/snmp-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/snmp-version.xml.i -->
+<syntaxVersion component='snmp' version='2'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/ssh-version.xml.i b/interface-definitions/include/version/ssh-version.xml.i
new file mode 100644
index 000000000..0f25caf98
--- /dev/null
+++ b/interface-definitions/include/version/ssh-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/ssh-version.xml.i -->
+<syntaxVersion component='ssh' version='2'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/sstp-version.xml.i b/interface-definitions/include/version/sstp-version.xml.i
new file mode 100644
index 000000000..79b43a3e7
--- /dev/null
+++ b/interface-definitions/include/version/sstp-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/sstp-version.xml.i -->
+<syntaxVersion component='sstp' version='4'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/system-version.xml.i b/interface-definitions/include/version/system-version.xml.i
new file mode 100644
index 000000000..3cf92001c
--- /dev/null
+++ b/interface-definitions/include/version/system-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/system-version.xml.i -->
+<syntaxVersion component='system' version='24'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/vrf-version.xml.i b/interface-definitions/include/version/vrf-version.xml.i
new file mode 100644
index 000000000..9d7ff35fe
--- /dev/null
+++ b/interface-definitions/include/version/vrf-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/vrf-version.xml.i -->
+<syntaxVersion component='vrf' version='3'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/vrrp-version.xml.i b/interface-definitions/include/version/vrrp-version.xml.i
new file mode 100644
index 000000000..626dd6cbc
--- /dev/null
+++ b/interface-definitions/include/version/vrrp-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/vrrp-version.xml.i -->
+<syntaxVersion component='vrrp' version='3'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/vyos-accel-ppp-version.xml.i b/interface-definitions/include/version/vyos-accel-ppp-version.xml.i
new file mode 100644
index 000000000..e5a4e1613
--- /dev/null
+++ b/interface-definitions/include/version/vyos-accel-ppp-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/vyos-accel-ppp-version.xml.i -->
+<syntaxVersion component='vyos-accel-ppp' version='2'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/wanloadbalance-version.xml.i b/interface-definitions/include/version/wanloadbalance-version.xml.i
new file mode 100644
index 000000000..59f8729cc
--- /dev/null
+++ b/interface-definitions/include/version/wanloadbalance-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/wanloadbalance-version.xml.i -->
+<syntaxVersion component='wanloadbalance' version='3'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/version/webproxy-version.xml.i b/interface-definitions/include/version/webproxy-version.xml.i
new file mode 100644
index 000000000..42dbf3f8b
--- /dev/null
+++ b/interface-definitions/include/version/webproxy-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/webproxy-version.xml.i -->
+<syntaxVersion component='webproxy' version='2'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/include/vpn-ipsec-encryption.xml.i b/interface-definitions/include/vpn-ipsec-encryption.xml.i
index 9ef2f7c90..629e6a0b9 100644
--- a/interface-definitions/include/vpn-ipsec-encryption.xml.i
+++ b/interface-definitions/include/vpn-ipsec-encryption.xml.i
@@ -11,7 +11,7 @@
</valueHelp>
<valueHelp>
<format>aes128</format>
- <description>128 bit AES-CBC (default)</description>
+ <description>128 bit AES-CBC</description>
</valueHelp>
<valueHelp>
<format>aes192</format>
@@ -226,8 +226,9 @@
<description>256 bit ChaCha20/Poly1305 with 128 bit ICV</description>
</valueHelp>
<constraint>
- <regex>^(null|aes128|aes192|aes256|aes128ctr|aes192ctr|aes256ctr|aes128ccm64|aes192ccm64|aes256ccm64|aes128ccm96|aes192ccm96|aes256ccm96|aes128ccm128|aes192ccm128|aes256ccm128|aes128gcm64|aes192gcm64|aes256gcm64|aes128gcm96|aes192gcm96|aes256gcm96|aes128gcm128|aes192gcm128|aes256gcm128|aes128gmac|aes192gmac|aes256gmac|3des|blowfish128|blowfish192|blowfish256|camellia128|camellia192|camellia256|camellia128ctr|camellia192ctr|camellia256ctr|camellia128ccm64|camellia192ccm64|camellia256ccm64|camellia128ccm96|camellia192ccm96|camellia256ccm96|camellia128ccm128|camellia192ccm128|camellia256ccm128|serpent128|serpent192|serpent256|twofish128|twofish192|twofish256|cast128|chacha20poly1305)$</regex>
+ <regex>(null|aes128|aes192|aes256|aes128ctr|aes192ctr|aes256ctr|aes128ccm64|aes192ccm64|aes256ccm64|aes128ccm96|aes192ccm96|aes256ccm96|aes128ccm128|aes192ccm128|aes256ccm128|aes128gcm64|aes192gcm64|aes256gcm64|aes128gcm96|aes192gcm96|aes256gcm96|aes128gcm128|aes192gcm128|aes256gcm128|aes128gmac|aes192gmac|aes256gmac|3des|blowfish128|blowfish192|blowfish256|camellia128|camellia192|camellia256|camellia128ctr|camellia192ctr|camellia256ctr|camellia128ccm64|camellia192ccm64|camellia256ccm64|camellia128ccm96|camellia192ccm96|camellia256ccm96|camellia128ccm128|camellia192ccm128|camellia256ccm128|serpent128|serpent192|serpent256|twofish128|twofish192|twofish256|cast128|chacha20poly1305)</regex>
</constraint>
</properties>
+ <defaultValue>aes128</defaultValue>
</leafNode>
<!-- include end -->
diff --git a/interface-definitions/include/vpn-ipsec-hash.xml.i b/interface-definitions/include/vpn-ipsec-hash.xml.i
index 5a06b290e..73d19c24b 100644
--- a/interface-definitions/include/vpn-ipsec-hash.xml.i
+++ b/interface-definitions/include/vpn-ipsec-hash.xml.i
@@ -15,7 +15,7 @@
</valueHelp>
<valueHelp>
<format>sha1</format>
- <description>SHA1 HMAC (default)</description>
+ <description>SHA1 HMAC</description>
</valueHelp>
<valueHelp>
<format>sha1_160</format>
@@ -58,8 +58,9 @@
<description>256-bit AES-GMAC</description>
</valueHelp>
<constraint>
- <regex>^(md5|md5_128|sha1|sha1_160|sha256|sha256_96|sha384|sha512|aesxcbc|aescmac|aes128gmac|aes192gmac|aes256gmac)$</regex>
+ <regex>(md5|md5_128|sha1|sha1_160|sha256|sha256_96|sha384|sha512|aesxcbc|aescmac|aes128gmac|aes192gmac|aes256gmac)</regex>
</constraint>
</properties>
+ <defaultValue>sha1</defaultValue>
</leafNode>
<!-- include end -->
diff --git a/interface-definitions/include/webproxy-url-filtering.xml.i b/interface-definitions/include/webproxy-url-filtering.xml.i
index 265bbff94..7763cb393 100644
--- a/interface-definitions/include/webproxy-url-filtering.xml.i
+++ b/interface-definitions/include/webproxy-url-filtering.xml.i
@@ -38,7 +38,7 @@
<description>Default filter action is block</description>
</valueHelp>
<constraint>
- <regex>^(allow|block)$</regex>
+ <regex>(allow|block)</regex>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/interfaces-bonding.xml.in b/interface-definitions/interfaces-bonding.xml.in
index 17879cf1e..96dede723 100644
--- a/interface-definitions/interfaces-bonding.xml.in
+++ b/interface-definitions/interfaces-bonding.xml.in
@@ -7,7 +7,7 @@
<help>Bonding Interface/Link Aggregation</help>
<priority>320</priority>
<constraint>
- <regex>^bond[0-9]+$</regex>
+ <regex>bond[0-9]+</regex>
</constraint>
<constraintErrorMessage>Bonding interface must be named bondN</constraintErrorMessage>
<valueHelp>
@@ -56,6 +56,8 @@
#include <include/interface/disable.xml.i>
#include <include/interface/vrf.xml.i>
#include <include/interface/mirror.xml.i>
+ #include <include/interface/interface-firewall.xml.i>
+ #include <include/interface/interface-policy.xml.i>
<leafNode name="hash-policy">
<properties>
<help>Bonding transmit hash policy</help>
@@ -64,7 +66,7 @@
</completionHelp>
<valueHelp>
<format>layer2</format>
- <description>use MAC addresses to generate the hash (802.3ad, default)</description>
+ <description>use MAC addresses to generate the hash</description>
</valueHelp>
<valueHelp>
<format>layer2+3</format>
@@ -83,7 +85,7 @@
<description>combine encapsulated IP address and port to make hash</description>
</valueHelp>
<constraint>
- <regex>^(layer2\+3|layer3\+4|layer2|encap2\+3|encap3\+4)$</regex>
+ <regex>(layer2\+3|layer3\+4|layer2|encap2\+3|encap3\+4)</regex>
</constraint>
<constraintErrorMessage>hash-policy must be layer2 layer2+3 layer3+4 encap2+3 or encap3+4</constraintErrorMessage>
</properties>
@@ -113,14 +115,14 @@
</completionHelp>
<valueHelp>
<format>slow</format>
- <description>Request partner to transmit LACPDUs every 30 seconds (default)</description>
+ <description>Request partner to transmit LACPDUs every 30 seconds</description>
</valueHelp>
<valueHelp>
<format>fast</format>
<description>Request partner to transmit LACPDUs every 1 second</description>
</valueHelp>
<constraint>
- <regex>^(slow|fast)$</regex>
+ <regex>(slow|fast)</regex>
</constraint>
</properties>
<defaultValue>slow</defaultValue>
@@ -133,7 +135,7 @@
</completionHelp>
<valueHelp>
<format>802.3ad</format>
- <description>IEEE 802.3ad Dynamic link aggregation (Default)</description>
+ <description>IEEE 802.3ad Dynamic link aggregation</description>
</valueHelp>
<valueHelp>
<format>active-backup</format>
@@ -160,7 +162,7 @@
<description>Distribute based on MAC address</description>
</valueHelp>
<constraint>
- <regex>^(802.3ad|active-backup|broadcast|round-robin|transmit-load-balance|adaptive-load-balance|xor-hash)$</regex>
+ <regex>(802.3ad|active-backup|broadcast|round-robin|transmit-load-balance|adaptive-load-balance|xor-hash)</regex>
</constraint>
<constraintErrorMessage>mode must be 802.3ad, active-backup, broadcast, round-robin, transmit-load-balance, adaptive-load-balance, or xor</constraintErrorMessage>
</properties>
@@ -205,6 +207,7 @@
</constraint>
</properties>
</leafNode>
+ #include <include/interface/redirect.xml.i>
#include <include/interface/vif-s.xml.i>
#include <include/interface/vif.xml.i>
#include <include/interface/xdp.xml.i>
diff --git a/interface-definitions/interfaces-bridge.xml.in b/interface-definitions/interfaces-bridge.xml.in
index 144f43f32..60edf3ce2 100644
--- a/interface-definitions/interfaces-bridge.xml.in
+++ b/interface-definitions/interfaces-bridge.xml.in
@@ -7,7 +7,7 @@
<help>Bridge Interface</help>
<priority>310</priority>
<constraint>
- <regex>^br[0-9]+$</regex>
+ <regex>br[0-9]+</regex>
</constraint>
<constraintErrorMessage>Bridge interface must be named brN</constraintErrorMessage>
<valueHelp>
@@ -26,7 +26,7 @@
</valueHelp>
<valueHelp>
<format>u32:10-1000000</format>
- <description>MAC address aging time in seconds (default: 300)</description>
+ <description>MAC address aging time in seconds</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-0 --range 10-1000000"/>
@@ -41,12 +41,14 @@
#include <include/interface/disable.xml.i>
#include <include/interface/vrf.xml.i>
#include <include/interface/mtu-68-16000.xml.i>
+ #include <include/interface/interface-firewall.xml.i>
+ #include <include/interface/interface-policy.xml.i>
<leafNode name="forwarding-delay">
<properties>
<help>Forwarding delay</help>
<valueHelp>
<format>u32:0-200</format>
- <description>Spanning Tree Protocol forwarding delay in seconds (default 15)</description>
+ <description>Spanning Tree Protocol forwarding delay in seconds</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-200"/>
@@ -57,10 +59,10 @@
</leafNode>
<leafNode name="hello-time">
<properties>
- <help>Hello packet advertisment interval</help>
+ <help>Hello packet advertisement interval</help>
<valueHelp>
<format>u32:1-10</format>
- <description>Spanning Tree Protocol hello advertisement interval in seconds (default 2)</description>
+ <description>Spanning Tree Protocol hello advertisement interval in seconds</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-10"/>
@@ -97,7 +99,7 @@
<help>Interval at which neighbor bridges are removed</help>
<valueHelp>
<format>u32:1-40</format>
- <description>Bridge maximum aging time in seconds (default 20)</description>
+ <description>Bridge maximum aging time in seconds</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-40"/>
@@ -193,7 +195,7 @@
<help>Priority for this bridge</help>
<valueHelp>
<format>u32:0-65535</format>
- <description>Bridge priority (default 32768)</description>
+ <description>Bridge priority</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-65535"/>
@@ -208,6 +210,7 @@
<valueless/>
</properties>
</leafNode>
+ #include <include/interface/redirect.xml.i>
#include <include/interface/vif.xml.i>
</children>
</tagNode>
diff --git a/interface-definitions/interfaces-dummy.xml.in b/interface-definitions/interfaces-dummy.xml.in
index 2bc88c1a7..01438de31 100644
--- a/interface-definitions/interfaces-dummy.xml.in
+++ b/interface-definitions/interfaces-dummy.xml.in
@@ -7,7 +7,7 @@
<help>Dummy Interface</help>
<priority>300</priority>
<constraint>
- <regex>^dum[0-9]+$</regex>
+ <regex>dum[0-9]+</regex>
</constraint>
<constraintErrorMessage>Dummy interface must be named dumN</constraintErrorMessage>
<valueHelp>
@@ -19,6 +19,8 @@
#include <include/interface/address-ipv4-ipv6.xml.i>
#include <include/interface/description.xml.i>
#include <include/interface/disable.xml.i>
+ #include <include/interface/interface-firewall.xml.i>
+ #include <include/interface/interface-policy.xml.i>
<node name="ip">
<properties>
<help>IPv4 routing parameters</help>
@@ -27,6 +29,9 @@
#include <include/interface/source-validation.xml.i>
</children>
</node>
+ #include <include/interface/mirror.xml.i>
+ #include <include/interface/netns.xml.i>
+ #include <include/interface/redirect.xml.i>
#include <include/interface/vrf.xml.i>
</children>
</tagNode>
diff --git a/interface-definitions/interfaces-ethernet.xml.in b/interface-definitions/interfaces-ethernet.xml.in
index ceeda12a0..c821f04b2 100644
--- a/interface-definitions/interfaces-ethernet.xml.in
+++ b/interface-definitions/interfaces-ethernet.xml.in
@@ -14,7 +14,7 @@
<description>Ethernet interface name</description>
</valueHelp>
<constraint>
- <regex>^((eth|lan)[0-9]+|(eno|ens|enp|enx).+)$</regex>
+ <regex>((eth|lan)[0-9]+|(eno|ens|enp|enx).+)</regex>
</constraint>
<constraintErrorMessage>Invalid Ethernet interface name</constraintErrorMessage>
</properties>
@@ -31,6 +31,8 @@
</leafNode>
#include <include/interface/disable-link-detect.xml.i>
#include <include/interface/disable.xml.i>
+ #include <include/interface/interface-firewall.xml.i>
+ #include <include/interface/interface-policy.xml.i>
<leafNode name="duplex">
<properties>
<help>Duplex mode</help>
@@ -39,7 +41,7 @@
</completionHelp>
<valueHelp>
<format>auto</format>
- <description>Auto negotiation (default)</description>
+ <description>Auto negotiation</description>
</valueHelp>
<valueHelp>
<format>half</format>
@@ -50,7 +52,7 @@
<description>Full duplex</description>
</valueHelp>
<constraint>
- <regex>^(auto|half|full)$</regex>
+ <regex>(auto|half|full)</regex>
</constraint>
<constraintErrorMessage>duplex must be auto, half or full</constraintErrorMessage>
</properties>
@@ -108,7 +110,7 @@
</node>
<leafNode name="speed">
<properties>
- <help>Link speed (default: auto)</help>
+ <help>Link speed</help>
<completionHelp>
<list>auto 10 100 1000 2500 5000 10000 25000 40000 50000 100000</list>
</completionHelp>
@@ -157,7 +159,7 @@
<description>100 Gbit/sec</description>
</valueHelp>
<constraint>
- <regex>^(auto|10|100|1000|2500|5000|10000|25000|40000|50000|100000)$</regex>
+ <regex>(auto|10|100|1000|2500|5000|10000|25000|40000|50000|100000)</regex>
</constraint>
<constraintErrorMessage>Speed must be auto, 10, 100, 1000, 2500, 5000, 10000, 25000, 40000, 50000 or 100000</constraintErrorMessage>
</properties>
@@ -194,6 +196,7 @@
</leafNode>
</children>
</node>
+ #include <include/interface/redirect.xml.i>
#include <include/interface/vif-s.xml.i>
#include <include/interface/vif.xml.i>
#include <include/interface/vrf.xml.i>
diff --git a/interface-definitions/interfaces-geneve.xml.in b/interface-definitions/interfaces-geneve.xml.in
index 2ca7dd9f6..6e8a8fee2 100644
--- a/interface-definitions/interfaces-geneve.xml.in
+++ b/interface-definitions/interfaces-geneve.xml.in
@@ -7,7 +7,7 @@
<help>Generic Network Virtualization Encapsulation (GENEVE) Interface</help>
<priority>460</priority>
<constraint>
- <regex>^gnv[0-9]+$</regex>
+ <regex>gnv[0-9]+</regex>
</constraint>
<constraintErrorMessage>GENEVE interface must be named gnvN</constraintErrorMessage>
<valueHelp>
@@ -23,6 +23,8 @@
#include <include/interface/ipv6-options.xml.i>
#include <include/interface/mac.xml.i>
#include <include/interface/mtu-1450-16000.xml.i>
+ #include <include/interface/interface-firewall.xml.i>
+ #include <include/interface/interface-policy.xml.i>
<node name="parameters">
<properties>
<help>GENEVE tunnel parameters</help>
@@ -33,7 +35,7 @@
<help>IPv4 specific tunnel parameters</help>
</properties>
<children>
- #include <include/interface/parameters-dont-fragment.xml.i>
+ #include <include/interface/parameters-df.xml.i>
#include <include/interface/parameters-tos.xml.i>
#include <include/interface/parameters-ttl.xml.i>
</children>
@@ -48,6 +50,8 @@
</node>
</children>
</node>
+ #include <include/interface/mirror.xml.i>
+ #include <include/interface/redirect.xml.i>
#include <include/interface/tunnel-remote.xml.i>
#include <include/vni.xml.i>
</children>
diff --git a/interface-definitions/interfaces-input.xml.in b/interface-definitions/interfaces-input.xml.in
new file mode 100644
index 000000000..2164bfa4e
--- /dev/null
+++ b/interface-definitions/interfaces-input.xml.in
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="interfaces">
+ <children>
+ <tagNode name="input" owner="${vyos_conf_scripts_dir}/interfaces-input.py">
+ <properties>
+ <help>Input Functional Block (IFB) interface name</help>
+ <!-- before real devices that redirect -->
+ <priority>310</priority>
+ <constraint>
+ <regex>ifb[0-9]+</regex>
+ </constraint>
+ <constraintErrorMessage>Input interface must be named ifbN</constraintErrorMessage>
+ <valueHelp>
+ <format>ifbN</format>
+ <description>Input interface name</description>
+ </valueHelp>
+ </properties>
+ <children>
+ #include <include/interface/description.xml.i>
+ #include <include/interface/disable.xml.i>
+ #include <include/interface/interface-firewall.xml.i>
+ #include <include/interface/interface-policy.xml.i>
+ #include <include/interface/redirect.xml.i>
+ </children>
+ </tagNode>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/interface-definitions/interfaces-l2tpv3.xml.in b/interface-definitions/interfaces-l2tpv3.xml.in
index 9364c85cd..6a85064cd 100644
--- a/interface-definitions/interfaces-l2tpv3.xml.in
+++ b/interface-definitions/interfaces-l2tpv3.xml.in
@@ -7,7 +7,7 @@
<help>Layer 2 Tunnel Protocol Version 3 (L2TPv3) Interface</help>
<priority>485</priority>
<constraint>
- <regex>^l2tpeth[0-9]+$</regex>
+ <regex>l2tpeth[0-9]+</regex>
</constraint>
<constraintErrorMessage>L2TPv3 interface must be named l2tpethN</constraintErrorMessage>
<valueHelp>
@@ -20,7 +20,7 @@
#include <include/interface/description.xml.i>
<leafNode name="destination-port">
<properties>
- <help>UDP destination port for L2TPv3 tunnel (default: 5000)</help>
+ <help>UDP destination port for L2TPv3 tunnel</help>
<valueHelp>
<format>u32:1-65535</format>
<description>Numeric IP port</description>
@@ -32,9 +32,11 @@
<defaultValue>5000</defaultValue>
</leafNode>
#include <include/interface/disable.xml.i>
+ #include <include/interface/interface-firewall.xml.i>
+ #include <include/interface/interface-policy.xml.i>
<leafNode name="encapsulation">
<properties>
- <help>Encapsulation type (default: UDP)</help>
+ <help>Encapsulation type</help>
<completionHelp>
<list>udp ip</list>
</completionHelp>
@@ -47,7 +49,7 @@
<description>IP encapsulation</description>
</valueHelp>
<constraint>
- <regex>^(udp|ip)$</regex>
+ <regex>(udp|ip)</regex>
</constraint>
<constraintErrorMessage>Encapsulation must be UDP or IP</constraintErrorMessage>
</properties>
@@ -56,6 +58,7 @@
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
#include <include/source-address-ipv4-ipv6.xml.i>
+ #include <include/interface/mirror.xml.i>
#include <include/interface/mtu-68-16000.xml.i>
<leafNode name="mtu">
<defaultValue>1488</defaultValue>
@@ -84,7 +87,6 @@
</constraint>
</properties>
</leafNode>
- #include <include/interface/mtu-68-16000.xml.i>
#include <include/interface/tunnel-remote.xml.i>
<leafNode name="session-id">
<properties>
@@ -100,7 +102,7 @@
</leafNode>
<leafNode name="source-port">
<properties>
- <help>UDP source port for L2TPv3 tunnel (default: 5000)</help>
+ <help>UDP source port for L2TPv3 tunnel</help>
<valueHelp>
<format>u32:1-65535</format>
<description>Numeric IP port</description>
diff --git a/interface-definitions/interfaces-loopback.xml.in b/interface-definitions/interfaces-loopback.xml.in
index 7be15ab89..7f59db543 100644
--- a/interface-definitions/interfaces-loopback.xml.in
+++ b/interface-definitions/interfaces-loopback.xml.in
@@ -7,7 +7,7 @@
<help>Loopback Interface</help>
<priority>300</priority>
<constraint>
- <regex>^lo$</regex>
+ <regex>lo</regex>
</constraint>
<constraintErrorMessage>Loopback interface must be named lo</constraintErrorMessage>
<valueHelp>
@@ -26,6 +26,8 @@
#include <include/interface/source-validation.xml.i>
</children>
</node>
+ #include <include/interface/mirror.xml.i>
+ #include <include/interface/redirect.xml.i>
</children>
</tagNode>
</children>
diff --git a/interface-definitions/interfaces-macsec.xml.in b/interface-definitions/interfaces-macsec.xml.in
index 4a566ef8b..dbb989588 100644
--- a/interface-definitions/interfaces-macsec.xml.in
+++ b/interface-definitions/interfaces-macsec.xml.in
@@ -7,7 +7,7 @@
<help>MACsec Interface (802.1ae)</help>
<priority>461</priority>
<constraint>
- <regex>^macsec[0-9]+$</regex>
+ <regex>macsec[0-9]+</regex>
</constraint>
<constraintErrorMessage>MACsec interface must be named macsecN</constraintErrorMessage>
<valueHelp>
@@ -16,9 +16,14 @@
</valueHelp>
</properties>
<children>
- #include <include/interface/address-ipv4-ipv6.xml.i>
+ #include <include/interface/address-ipv4-ipv6-dhcp.xml.i>
+ #include <include/interface/dhcp-options.xml.i>
+ #include <include/interface/dhcpv6-options.xml.i>
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
+ #include <include/interface/interface-firewall.xml.i>
+ #include <include/interface/interface-policy.xml.i>
+ #include <include/interface/mirror.xml.i>
<node name="security">
<properties>
<help>Security/Encryption Settings</help>
@@ -32,14 +37,14 @@
</completionHelp>
<valueHelp>
<format>gcm-aes-128</format>
- <description>Galois/Counter Mode of AES cipher with 128-bit key (default)</description>
+ <description>Galois/Counter Mode of AES cipher with 128-bit key</description>
</valueHelp>
<valueHelp>
<format>gcm-aes-256</format>
<description>Galois/Counter Mode of AES cipher with 256-bit key</description>
</valueHelp>
<constraint>
- <regex>^(gcm-aes-128|gcm-aes-256)$</regex>
+ <regex>(gcm-aes-128|gcm-aes-256)</regex>
</constraint>
</properties>
</leafNode>
@@ -62,7 +67,7 @@
<description>16-byte (128-bit) hex-string (32 hex-digits)</description>
</valueHelp>
<constraint>
- <regex>^[A-Fa-f0-9]{32}$</regex>
+ <regex>[A-Fa-f0-9]{32}</regex>
</constraint>
</properties>
</leafNode>
@@ -74,13 +79,13 @@
<description>32-byte (256-bit) hex-string (64 hex-digits)</description>
</valueHelp>
<constraint>
- <regex>^[A-Fa-f0-9]{64}$</regex>
+ <regex>[A-Fa-f0-9]{64}</regex>
</constraint>
</properties>
</leafNode>
<leafNode name="priority">
<properties>
- <help>Priority of MACsec Key Agreement protocol (MKA) actor (default: 255)</help>
+ <help>Priority of MACsec Key Agreement protocol (MKA) actor</help>
<valueHelp>
<format>u32:0-255</format>
<description>MACsec Key Agreement protocol (MKA) priority</description>
@@ -118,6 +123,7 @@
<defaultValue>1460</defaultValue>
</leafNode>
#include <include/source-interface-ethernet.xml.i>
+ #include <include/interface/redirect.xml.i>
#include <include/interface/vrf.xml.i>
</children>
</tagNode>
diff --git a/interface-definitions/interfaces-openvpn.xml.in b/interface-definitions/interfaces-openvpn.xml.in
index 6b4440688..edcf7b37f 100644
--- a/interface-definitions/interfaces-openvpn.xml.in
+++ b/interface-definitions/interfaces-openvpn.xml.in
@@ -7,7 +7,7 @@
<help>OpenVPN Tunnel Interface</help>
<priority>460</priority>
<constraint>
- <regex>^vtun[0-9]+$</regex>
+ <regex>vtun[0-9]+</regex>
</constraint>
<constraintErrorMessage>OpenVPN tunnel interface must be named vtunN</constraintErrorMessage>
<valueHelp>
@@ -34,9 +34,11 @@
</children>
</node>
#include <include/interface/description.xml.i>
+ #include <include/interface/interface-firewall.xml.i>
+ #include <include/interface/interface-policy.xml.i>
<leafNode name="device-type">
<properties>
- <help>OpenVPN interface device-type (default: tun)</help>
+ <help>OpenVPN interface device-type</help>
<completionHelp>
<list>tun tap</list>
</completionHelp>
@@ -49,7 +51,7 @@
<description>TAP device, required for OSI layer 2</description>
</valueHelp>
<constraint>
- <regex>^(tun|tap)$</regex>
+ <regex>(tun|tap)</regex>
</constraint>
</properties>
<defaultValue>tun</defaultValue>
@@ -111,7 +113,7 @@
<description>AES algorithm with 256-bit key GCM</description>
</valueHelp>
<constraint>
- <regex>^(none|des|3des|bf128|bf256|aes128|aes128gcm|aes192|aes192gcm|aes256|aes256gcm)$</regex>
+ <regex>(none|des|3des|bf128|bf256|aes128|aes128gcm|aes192|aes192gcm|aes256|aes256gcm)</regex>
</constraint>
</properties>
</leafNode>
@@ -158,7 +160,7 @@
<description>AES algorithm with 256-bit key GCM</description>
</valueHelp>
<constraint>
- <regex>^(none|des|3des|aes128|aes128gcm|aes192|aes192gcm|aes256|aes256gcm)$</regex>
+ <regex>(none|des|3des|aes128|aes128gcm|aes192|aes192gcm|aes256|aes256gcm)</regex>
</constraint>
<multi/>
</properties>
@@ -166,6 +168,7 @@
</children>
</node>
#include <include/interface/ipv6-options.xml.i>
+ #include <include/interface/mirror.xml.i>
<leafNode name="hash">
<properties>
<help>Hashing Algorithm</help>
@@ -193,7 +196,7 @@
<description>SHA-512 algorithm</description>
</valueHelp>
<constraint>
- <regex>^(md5|sha1|sha256|sha384|sha512)$</regex>
+ <regex>(md5|sha1|sha256|sha384|sha512)</regex>
</constraint>
</properties>
</leafNode>
@@ -204,7 +207,7 @@
<children>
<leafNode name="failure-count">
<properties>
- <help>Maximum number of keepalive packet failures (default: 60)</help>
+ <help>Maximum number of keepalive packet failures</help>
<valueHelp>
<format>u32:0-1000</format>
<description>Maximum number of keepalive packet failures</description>
@@ -217,7 +220,7 @@
</leafNode>
<leafNode name="interval">
<properties>
- <help>Keepalive packet interval in seconds (default: 10)</help>
+ <help>Keepalive packet interval in seconds</help>
<valueHelp>
<format>u32:0-600</format>
<description>Keepalive packet interval (seconds)</description>
@@ -295,7 +298,7 @@
<description>Server in client-server mode</description>
</valueHelp>
<constraint>
- <regex>^(site-to-site|client|server)$</regex>
+ <regex>(site-to-site|client|server)</regex>
</constraint>
</properties>
</leafNode>
@@ -333,7 +336,7 @@
<description>TCP and initiates connections actively</description>
</valueHelp>
<constraint>
- <regex>^(udp|tcp-passive|tcp-active)$</regex>
+ <regex>(udp|tcp-passive|tcp-active)</regex>
</constraint>
</properties>
<defaultValue>udp</defaultValue>
@@ -611,13 +614,13 @@
</leafNode>
<leafNode name="topology">
<properties>
- <help>Topology for clients (default: net30)</help>
+ <help>Topology for clients</help>
<completionHelp>
<list>net30 point-to-point subnet</list>
</completionHelp>
<valueHelp>
<format>net30</format>
- <description>net30 topology (default)</description>
+ <description>net30 topology</description>
</valueHelp>
<valueHelp>
<format>point-to-point</format>
@@ -628,7 +631,7 @@
<description>Subnet topology</description>
</valueHelp>
<constraint>
- <regex>^(subnet|point-to-point|net30)$</regex>
+ <regex>(subnet|point-to-point|net30)</regex>
</constraint>
</properties>
<defaultValue>net30</defaultValue>
@@ -645,7 +648,7 @@
<children>
<leafNode name="slop">
<properties>
- <help>Maximum allowed clock slop in seconds (default: 180)</help>
+ <help>Maximum allowed clock slop in seconds</help>
<valueHelp>
<format>1-65535</format>
<description>Seconds</description>
@@ -658,7 +661,7 @@
</leafNode>
<leafNode name="drift">
<properties>
- <help>Time drift in seconds (default: 0)</help>
+ <help>Time drift in seconds</help>
<valueHelp>
<format>1-65535</format>
<description>Seconds</description>
@@ -671,7 +674,7 @@
</leafNode>
<leafNode name="step">
<properties>
- <help>Step value for totp in seconds (default: 30)</help>
+ <help>Step value for totp in seconds</help>
<valueHelp>
<format>1-65535</format>
<description>Seconds</description>
@@ -684,7 +687,7 @@
</leafNode>
<leafNode name="digits">
<properties>
- <help>Number of digits to use for totp hash (default: 6)</help>
+ <help>Number of digits to use for totp hash</help>
<valueHelp>
<format>1-65535</format>
<description>Seconds</description>
@@ -697,7 +700,7 @@
</leafNode>
<leafNode name="challenge">
<properties>
- <help>Expect password as result of a challenge response protocol (default: enabled)</help>
+ <help>Expect password as result of a challenge response protocol</help>
<completionHelp>
<list>disable enable</list>
</completionHelp>
@@ -707,10 +710,10 @@
</valueHelp>
<valueHelp>
<format>enable</format>
- <description>Enable chalenge-response (default)</description>
+ <description>Enable chalenge-response</description>
</valueHelp>
<constraint>
- <regex>^(disable|enable)$</regex>
+ <regex>(disable|enable)</regex>
</constraint>
</properties>
<defaultValue>enable</defaultValue>
@@ -783,7 +786,7 @@
<description>TLS v1.3</description>
</valueHelp>
<constraint>
- <regex>^(1.0|1.1|1.2|1.3)$</regex>
+ <regex>(1.0|1.1|1.2|1.3)</regex>
</constraint>
</properties>
</leafNode>
@@ -802,7 +805,7 @@
<description>Wait for incoming TLS connection</description>
</valueHelp>
<constraint>
- <regex>^(active|passive)$</regex>
+ <regex>(active|passive)</regex>
</constraint>
</properties>
</leafNode>
@@ -814,6 +817,7 @@
<valueless/>
</properties>
</leafNode>
+ #include <include/interface/redirect.xml.i>
#include <include/interface/vrf.xml.i>
</children>
</tagNode>
diff --git a/interface-definitions/interfaces-pppoe.xml.in b/interface-definitions/interfaces-pppoe.xml.in
index 57bb01258..664914baa 100644
--- a/interface-definitions/interfaces-pppoe.xml.in
+++ b/interface-definitions/interfaces-pppoe.xml.in
@@ -7,7 +7,7 @@
<help>Point-to-Point Protocol over Ethernet (PPPoE)</help>
<priority>322</priority>
<constraint>
- <regex>^pppoe[0-9]+$</regex>
+ <regex>pppoe[0-9]+</regex>
</constraint>
<constraintErrorMessage>PPPoE interface must be named pppoeN</constraintErrorMessage>
<valueHelp>
@@ -19,35 +19,13 @@
#include <include/pppoe-access-concentrator.xml.i>
#include <include/interface/authentication.xml.i>
#include <include/interface/dial-on-demand.xml.i>
- <leafNode name="default-route">
- <properties>
- <help>Default route insertion behaviour (default: auto)</help>
- <completionHelp>
- <list>auto none force</list>
- </completionHelp>
- <constraint>
- <regex>^(auto|none|force)$</regex>
- </constraint>
- <constraintErrorMessage>PPPoE default-route option must be 'auto', 'none', or 'force'</constraintErrorMessage>
- <valueHelp>
- <format>auto</format>
- <description>Automatically install a default route</description>
- </valueHelp>
- <valueHelp>
- <format>none</format>
- <description>Do not install a default route</description>
- </valueHelp>
- <valueHelp>
- <format>force</format>
- <description>Replace existing default route</description>
- </valueHelp>
- </properties>
- <defaultValue>auto</defaultValue>
- </leafNode>
+ #include <include/interface/interface-firewall.xml.i>
+ #include <include/interface/interface-policy.xml.i>
+ #include <include/interface/no-default-route.xml.i>
+ #include <include/interface/default-route-distance.xml.i>
#include <include/interface/dhcpv6-options.xml.i>
#include <include/interface/description.xml.i>
#include <include/interface/disable.xml.i>
- #include <include/interface/vrf.xml.i>
<leafNode name="idle-timeout">
<properties>
<help>Delay before disconnecting idle session (in seconds)</help>
@@ -101,6 +79,7 @@
</constraint>
</properties>
</leafNode>
+ #include <include/interface/mirror.xml.i>
#include <include/interface/mtu-68-1500.xml.i>
<leafNode name="mtu">
<defaultValue>1492</defaultValue>
@@ -127,11 +106,13 @@
<properties>
<help>Service name, only connect to access concentrators advertising this</help>
<constraint>
- <regex>[a-zA-Z0-9]+$</regex>
+ <regex>[a-zA-Z0-9]+</regex>
</constraint>
<constraintErrorMessage>Service name must be alphanumeric only</constraintErrorMessage>
</properties>
</leafNode>
+ #include <include/interface/redirect.xml.i>
+ #include <include/interface/vrf.xml.i>
</children>
</tagNode>
</children>
diff --git a/interface-definitions/interfaces-pseudo-ethernet.xml.in b/interface-definitions/interfaces-pseudo-ethernet.xml.in
index 366892032..6b62f4c61 100644
--- a/interface-definitions/interfaces-pseudo-ethernet.xml.in
+++ b/interface-definitions/interfaces-pseudo-ethernet.xml.in
@@ -7,7 +7,7 @@
<help>Pseudo Ethernet</help>
<priority>321</priority>
<constraint>
- <regex>^peth[0-9]+$</regex>
+ <regex>peth[0-9]+</regex>
</constraint>
<constraintErrorMessage>Pseudo Ethernet interface must be named pethN</constraintErrorMessage>
<valueHelp>
@@ -27,6 +27,9 @@
#include <include/interface/ipv6-options.xml.i>
#include <include/source-interface-ethernet.xml.i>
#include <include/interface/mac.xml.i>
+ #include <include/interface/mirror.xml.i>
+ #include <include/interface/interface-firewall.xml.i>
+ #include <include/interface/interface-policy.xml.i>
<leafNode name="mode">
<properties>
<help>Receive mode (default: private)</help>
@@ -50,13 +53,14 @@
<description>Promicious mode passthrough of underlying device</description>
</valueHelp>
<constraint>
- <regex>^(private|vepa|bridge|passthru)$</regex>
+ <regex>(private|vepa|bridge|passthru)</regex>
</constraint>
<constraintErrorMessage>mode must be private, vepa, bridge or passthru</constraintErrorMessage>
</properties>
<defaultValue>private</defaultValue>
</leafNode>
#include <include/interface/mtu-68-16000.xml.i>
+ #include <include/interface/redirect.xml.i>
#include <include/interface/vif-s.xml.i>
#include <include/interface/vif.xml.i>
</children>
diff --git a/interface-definitions/interfaces-tunnel.xml.in b/interface-definitions/interfaces-tunnel.xml.in
index cca732f82..98ff878ba 100644
--- a/interface-definitions/interfaces-tunnel.xml.in
+++ b/interface-definitions/interfaces-tunnel.xml.in
@@ -7,7 +7,7 @@
<help>Tunnel interface</help>
<priority>380</priority>
<constraint>
- <regex>^tun[0-9]+$</regex>
+ <regex>tun[0-9]+</regex>
</constraint>
<constraintErrorMessage>tunnel interface must be named tunN</constraintErrorMessage>
<valueHelp>
@@ -20,7 +20,6 @@
#include <include/interface/address-ipv4-ipv6.xml.i>
#include <include/interface/disable.xml.i>
#include <include/interface/disable-link-detect.xml.i>
- #include <include/interface/vrf.xml.i>
#include <include/interface/mtu-64-8024.xml.i>
<leafNode name="mtu">
<defaultValue>1476</defaultValue>
@@ -30,6 +29,8 @@
#include <include/source-address-ipv4-ipv6.xml.i>
#include <include/interface/tunnel-remote.xml.i>
#include <include/source-interface.xml.i>
+ #include <include/interface/interface-firewall.xml.i>
+ #include <include/interface/interface-policy.xml.i>
<leafNode name="6rd-prefix">
<properties>
<help>6rd network prefix</help>
@@ -66,46 +67,47 @@
</valueHelp>
<valueHelp>
<format>gre</format>
- <description>Generic Routing Encapsulation</description>
+ <description>Generic Routing Encapsulation (network layer)</description>
</valueHelp>
<valueHelp>
<format>gretap</format>
- <description>Generic Routing Encapsulation (virtual L2 tunnel)</description>
+ <description>Generic Routing Encapsulation (datalink layer)</description>
</valueHelp>
<valueHelp>
<format>ip6erspan</format>
- <description>Encapsulated Remote Switched Port Analyzer over IPv6 network</description>
+ <description>Encapsulated Remote Switched Port Analyzer over IPv6</description>
</valueHelp>
<valueHelp>
<format>ip6gre</format>
- <description>GRE over IPv6 network</description>
+ <description>GRE over IPv6 (network layer)</description>
</valueHelp>
<valueHelp>
<format>ip6gretap</format>
- <description>Generic Routing Encapsulation over IPv6 (virtual L2 tunnel)</description>
+ <description>GRE over IPv6 (datalink layer)</description>
</valueHelp>
<valueHelp>
<format>ip6ip6</format>
- <description>IP6 in IP6 encapsulation</description>
+ <description>IPv6 in IPv6 encapsulation</description>
</valueHelp>
<valueHelp>
<format>ipip</format>
- <description>IP in IP encapsulation</description>
+ <description>IPv4 in IPv4 encapsulation</description>
</valueHelp>
<valueHelp>
<format>ipip6</format>
- <description>IP in IP6 encapsulation</description>
+ <description>IPv4 in IP6 encapsulation</description>
</valueHelp>
<valueHelp>
<format>sit</format>
- <description>Simple Internet Transition encapsulation</description>
+ <description>Simple Internet Transition (IPv6 in IPv4)</description>
</valueHelp>
<constraint>
- <regex>^(erspan|gre|gretap|ip6erspan|ip6gre|ip6gretap|ip6ip6|ipip|ipip6|sit)$</regex>
+ <regex>(erspan|gre|gretap|ip6erspan|ip6gre|ip6gretap|ip6ip6|ipip|ipip6|sit)</regex>
</constraint>
<constraintErrorMessage>Invalid encapsulation, must be one of: erspan, gre, gretap, ip6erspan, ip6gre, ip6gretap, ipip, sit, ipip6 or ip6ip6</constraintErrorMessage>
</properties>
</leafNode>
+ #include <include/interface/mirror.xml.i>
<leafNode name="multicast">
<properties>
<help>Multicast operation over tunnel</help>
@@ -114,14 +116,14 @@
</completionHelp>
<valueHelp>
<format>enable</format>
- <description>Enable Multicast</description>
+ <description>Enable multicast</description>
</valueHelp>
<valueHelp>
<format>disable</format>
- <description>Disable Multicast (default)</description>
+ <description>Disable multicast (default)</description>
</valueHelp>
<constraint>
- <regex>^(enable|disable)$</regex>
+ <regex>(enable|disable)</regex>
</constraint>
<constraintErrorMessage>Must be 'disable' or 'enable'</constraintErrorMessage>
</properties>
@@ -133,34 +135,34 @@
<children>
<node name="erspan">
<properties>
- <help>ERSPAN Tunnel parameters</help>
+ <help>ERSPAN tunnel parameters</help>
</properties>
<children>
<leafNode name="direction">
<properties>
- <help>Specifies mirrored traffic direction</help>
+ <help>Mirrored traffic direction</help>
<completionHelp>
<list>ingress egress</list>
</completionHelp>
<valueHelp>
<format>ingress</format>
- <description>Mirror ingress direction</description>
+ <description>Mirror ingress traffic</description>
</valueHelp>
<valueHelp>
<format>egress</format>
- <description>Mirror egress direction</description>
+ <description>Mirror egress traffic</description>
</valueHelp>
<constraint>
- <regex>^(ingress|egress)$</regex>
+ <regex>(ingress|egress)</regex>
</constraint>
</properties>
</leafNode>
<leafNode name="hw-id">
<properties>
- <help>Unique identifier of ERSPAN engine within a system</help>
+ <help>Unique identifier of an ERSPAN engine within a system</help>
<valueHelp>
<format>u32:0-1048575</format>
- <description>Unique identifier of ERSPAN engine</description>
+ <description>Unique identifier of an ERSPAN engine</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-1048575"/>
@@ -169,7 +171,7 @@
</leafNode>
<leafNode name="index">
<properties>
- <help>Specifify ERSPAN version 1 index field</help>
+ <help>ERSPAN version 1 index field</help>
<valueHelp>
<format>u32:0-63</format>
<description>Platform-depedent field for specifying port number and direction</description>
@@ -203,18 +205,18 @@
</node>
<node name="ip">
<properties>
- <help>IPv4 specific tunnel parameters</help>
+ <help>IPv4-specific tunnel parameters</help>
</properties>
<children>
<leafNode name="no-pmtu-discovery">
<properties>
- <help>Disable Path MTU Discovery on this tunnel</help>
+ <help>Disable path MTU discovery</help>
<valueless/>
</properties>
</leafNode>
<leafNode name="ignore-df">
<properties>
- <help>Enable IPv4 DF suppression on this tunnel</help>
+ <help>Ignore the DF (don't fragment) bit</help>
<valueless/>
</properties>
</leafNode>
@@ -228,7 +230,7 @@
</node>
<node name="ipv6">
<properties>
- <help>IPv6 specific tunnel parameters</help>
+ <help>IPv6-specific tunnel parameters</help>
</properties>
<children>
<leafNode name="encaplimit">
@@ -239,14 +241,14 @@
</completionHelp>
<valueHelp>
<format>u32:0-255</format>
- <description>Encaplimit (default: 4)</description>
+ <description>Encapsulation limit</description>
</valueHelp>
<valueHelp>
<format>none</format>
- <description>Encaplimit disabled</description>
+ <description>Disable encapsulation limit</description>
</valueHelp>
<constraint>
- <regex>^(none)$</regex>
+ <regex>(none)</regex>
<validator name="numeric" argument="--range 0-255"/>
</constraint>
<constraintErrorMessage>Tunnel encaplimit must be 0-255 or none</constraintErrorMessage>
@@ -259,12 +261,12 @@
<help>Hoplimit</help>
<valueHelp>
<format>u32:0-255</format>
- <description>Hoplimit (default 64)</description>
+ <description>Hop limit</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-255"/>
</constraint>
- <constraintErrorMessage>hoplimit must be between 0-255</constraintErrorMessage>
+ <constraintErrorMessage>hop limit must be between 0-255</constraintErrorMessage>
</properties>
<defaultValue>64</defaultValue>
</leafNode>
@@ -286,6 +288,8 @@
</node>
</children>
</node>
+ #include <include/interface/vrf.xml.i>
+ #include <include/interface/redirect.xml.i>
</children>
</tagNode>
</children>
diff --git a/interface-definitions/interfaces-vti.xml.in b/interface-definitions/interfaces-vti.xml.in
index b12434ae7..b471c3b92 100644
--- a/interface-definitions/interfaces-vti.xml.in
+++ b/interface-definitions/interfaces-vti.xml.in
@@ -7,7 +7,7 @@
<help>Virtual Tunnel interface</help>
<priority>381</priority>
<constraint>
- <regex>^vti[0-9]+$</regex>
+ <regex>vti[0-9]+</regex>
</constraint>
<constraintErrorMessage>VTI interface must be named vtiN</constraintErrorMessage>
<valueHelp>
@@ -34,7 +34,11 @@
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
#include <include/interface/mtu-68-16000.xml.i>
+ #include <include/interface/mirror.xml.i>
+ #include <include/interface/redirect.xml.i>
#include <include/interface/vrf.xml.i>
+ #include <include/interface/interface-firewall.xml.i>
+ #include <include/interface/interface-policy.xml.i>
</children>
</tagNode>
</children>
diff --git a/interface-definitions/interfaces-vxlan.xml.in b/interface-definitions/interfaces-vxlan.xml.in
index 0a8a88596..faa3dd5e0 100644
--- a/interface-definitions/interfaces-vxlan.xml.in
+++ b/interface-definitions/interfaces-vxlan.xml.in
@@ -7,7 +7,7 @@
<help>Virtual Extensible LAN (VXLAN) Interface</help>
<priority>460</priority>
<constraint>
- <regex>^vxlan[0-9]+$</regex>
+ <regex>vxlan[0-9]+</regex>
</constraint>
<constraintErrorMessage>VXLAN interface must be named vxlanN</constraintErrorMessage>
<valueHelp>
@@ -19,6 +19,18 @@
#include <include/interface/address-ipv4-ipv6.xml.i>
#include <include/interface/description.xml.i>
#include <include/interface/disable.xml.i>
+ <leafNode name="external">
+ <properties>
+ <help>Use external control plane</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="gpe">
+ <properties>
+ <help>Enable Generic Protocol extension (VXLAN-GPE)</help>
+ <valueless/>
+ </properties>
+ </leafNode>
<leafNode name="group">
<properties>
<help>Multicast group address for VXLAN interface</help>
@@ -41,6 +53,9 @@
#include <include/interface/ipv6-options.xml.i>
#include <include/interface/mac.xml.i>
#include <include/interface/mtu-1200-16000.xml.i>
+ #include <include/interface/mirror.xml.i>
+ #include <include/interface/interface-firewall.xml.i>
+ #include <include/interface/interface-policy.xml.i>
<leafNode name="mtu">
<defaultValue>1450</defaultValue>
</leafNode>
@@ -54,7 +69,7 @@
<help>IPv4 specific tunnel parameters</help>
</properties>
<children>
- #include <include/interface/parameters-dont-fragment.xml.i>
+ #include <include/interface/parameters-df.xml.i>
#include <include/interface/parameters-tos.xml.i>
#include <include/interface/parameters-ttl.xml.i>
<leafNode name="ttl">
@@ -84,7 +99,8 @@
</leafNode>
#include <include/source-address-ipv4-ipv6.xml.i>
#include <include/source-interface.xml.i>
- #include <include/interface/tunnel-remote.xml.i>
+ #include <include/interface/tunnel-remote-multi.xml.i>
+ #include <include/interface/redirect.xml.i>
#include <include/interface/vrf.xml.i>
#include <include/vni.xml.i>
</children>
diff --git a/interface-definitions/interfaces-wireguard.xml.in b/interface-definitions/interfaces-wireguard.xml.in
index 403282e5c..4a1b4ac68 100644
--- a/interface-definitions/interfaces-wireguard.xml.in
+++ b/interface-definitions/interfaces-wireguard.xml.in
@@ -7,7 +7,7 @@
<help>WireGuard Interface</help>
<priority>459</priority>
<constraint>
- <regex>^wg[0-9]+$</regex>
+ <regex>wg[0-9]+</regex>
</constraint>
<constraintErrorMessage>WireGuard interface must be named wgN</constraintErrorMessage>
<valueHelp>
@@ -19,9 +19,11 @@
#include <include/interface/address-ipv4-ipv6.xml.i>
#include <include/interface/description.xml.i>
#include <include/interface/disable.xml.i>
- #include <include/interface/vrf.xml.i>
#include <include/port-number.xml.i>
#include <include/interface/mtu-68-16000.xml.i>
+ #include <include/interface/interface-firewall.xml.i>
+ #include <include/interface/interface-policy.xml.i>
+ #include <include/interface/mirror.xml.i>
<leafNode name="mtu">
<defaultValue>1420</defaultValue>
</leafNode>
@@ -44,7 +46,7 @@
<properties>
<help>Base64 encoded private key</help>
<constraint>
- <regex>[0-9a-zA-Z\+/]{43}=$</regex>
+ <regex>[0-9a-zA-Z\+/]{43}=</regex>
</constraint>
<constraintErrorMessage>Key is not valid 44-character (32-bytes) base64</constraintErrorMessage>
</properties>
@@ -53,7 +55,7 @@
<properties>
<help>peer alias</help>
<constraint>
- <regex>[^ ]{1,100}$</regex>
+ <regex>[^ ]{1,100}</regex>
</constraint>
<constraintErrorMessage>peer alias too long (limit 100 characters)</constraintErrorMessage>
</properties>
@@ -63,7 +65,7 @@
<properties>
<help>base64 encoded public key</help>
<constraint>
- <regex>[0-9a-zA-Z\+/]{43}=$</regex>
+ <regex>[0-9a-zA-Z\+/]{43}=</regex>
</constraint>
<constraintErrorMessage>Key is not valid 44-character (32-bytes) base64</constraintErrorMessage>
</properties>
@@ -72,7 +74,7 @@
<properties>
<help>base64 encoded preshared key</help>
<constraint>
- <regex>[0-9a-zA-Z\+/]{43}=$</regex>
+ <regex>[0-9a-zA-Z\+/]{43}=</regex>
</constraint>
<constraintErrorMessage>Key is not valid 44-character (32-bytes) base64</constraintErrorMessage>
</properties>
@@ -99,6 +101,7 @@
</valueHelp>
<constraint>
<validator name="ip-address"/>
+ <validator name="ipv6-link-local"/>
</constraint>
</properties>
</leafNode>
@@ -117,6 +120,8 @@
</leafNode>
</children>
</tagNode>
+ #include <include/interface/redirect.xml.i>
+ #include <include/interface/vrf.xml.i>
</children>
</tagNode>
</children>
diff --git a/interface-definitions/interfaces-wireless.xml.in b/interface-definitions/interfaces-wireless.xml.in
index 048c7b475..eb6107303 100644
--- a/interface-definitions/interfaces-wireless.xml.in
+++ b/interface-definitions/interfaces-wireless.xml.in
@@ -6,8 +6,11 @@
<properties>
<help>Wireless (WiFi/WLAN) Network Interface</help>
<priority>318</priority>
+ <completionHelp>
+ <script>cd /sys/class/net; if compgen -G "wlan*" > /dev/null; then ls -d wlan*; fi</script>
+ </completionHelp>
<constraint>
- <regex>^wlan[0-9]+$</regex>
+ <regex>wlan[0-9]+</regex>
</constraint>
<constraintErrorMessage>Wireless interface must be named wlanN</constraintErrorMessage>
<valueHelp>
@@ -17,6 +20,8 @@
</properties>
<children>
#include <include/interface/address-ipv4-ipv6-dhcp.xml.i>
+ #include <include/interface/interface-firewall.xml.i>
+ #include <include/interface/interface-policy.xml.i>
<node name="capabilities">
<properties>
<help>HT and VHT capabilities for your card</help>
@@ -58,7 +63,7 @@
<description>Supported channel set width both 20 MHz and 40 MHz with secondary channel below primary channel</description>
</valueHelp>
<constraint>
- <regex>^(ht20|ht40\+|ht40-)$</regex>
+ <regex>(ht20|ht40\+|ht40-)</regex>
</constraint>
<multi/>
</properties>
@@ -108,7 +113,7 @@
<description>Set maximum A-MSDU length to 7935 octets</description>
</valueHelp>
<constraint>
- <regex>^(3839|7935)$</regex>
+ <regex>(3839|7935)</regex>
</constraint>
</properties>
</leafNode>
@@ -127,7 +132,7 @@
<description>Short GI for 40 MHz</description>
</valueHelp>
<constraint>
- <regex>^(20|40)$</regex>
+ <regex>(20|40)</regex>
</constraint>
<multi/>
</properties>
@@ -147,7 +152,7 @@
<description>DYNAMIC Spatial Multiplexing (SM) Power Save</description>
</valueHelp>
<constraint>
- <regex>^(static|dynamic)$</regex>
+ <regex>(static|dynamic)</regex>
</constraint>
</properties>
</leafNode>
@@ -164,7 +169,7 @@
<description>Number of spacial streams that can use RX STBC</description>
</valueHelp>
<constraint>
- <regex>^[1-3]+$</regex>
+ <regex>[1-3]+</regex>
</constraint>
<constraintErrorMessage>Invalid capability item</constraintErrorMessage>
</properties>
@@ -243,7 +248,7 @@
<description>Support for operation as multi user beamformee</description>
</valueHelp>
<constraint>
- <regex>^(single-user-beamformer|single-user-beamformee|multi-user-beamformer|multi-user-beamformee)$</regex>
+ <regex>(single-user-beamformer|single-user-beamformee|multi-user-beamformer|multi-user-beamformee)</regex>
</constraint>
<multi/>
</properties>
@@ -289,7 +294,7 @@
</completionHelp>
<valueHelp>
<format>0</format>
- <description>20 or 40 MHz channel width (default)</description>
+ <description>20 or 40 MHz channel width</description>
</valueHelp>
<valueHelp>
<format>1</format>
@@ -329,7 +334,7 @@
<description>Station can provide VHT MFB in response to VHT MRQ and unsolicited VHT MFB</description>
</valueHelp>
<constraint>
- <regex>^(unsolicited|both)$</regex>
+ <regex>(unsolicited|both)</regex>
</constraint>
<constraintErrorMessage>Invalid capability item</constraintErrorMessage>
</properties>
@@ -361,7 +366,7 @@
<description>ncrease Maximum MPDU length to 11454 octets</description>
</valueHelp>
<constraint>
- <regex>^(7991|11454)$</regex>
+ <regex>(7991|11454)</regex>
</constraint>
</properties>
</leafNode>
@@ -380,7 +385,7 @@
<description>Short GI for 160 MHz</description>
</valueHelp>
<constraint>
- <regex>^(80|160)$</regex>
+ <regex>(80|160)</regex>
</constraint>
<multi/>
</properties>
@@ -398,7 +403,7 @@
<description>Number of spacial streams that can use RX STBC</description>
</valueHelp>
<constraint>
- <regex>^[1-4]+$</regex>
+ <regex>[1-4]+</regex>
</constraint>
<constraintErrorMessage>Invalid capability item</constraintErrorMessage>
</properties>
@@ -429,7 +434,7 @@
</node>
<leafNode name="channel">
<properties>
- <help>Wireless radio channel (default: 0)</help>
+ <help>Wireless radio channel</help>
<valueHelp>
<format>0</format>
<description>Automatic Channel Selection (ACS)</description>
@@ -459,7 +464,7 @@
<description>ISO/IEC 3166-1 Country Code</description>
</valueHelp>
<constraint>
- <regex>^[a-z][a-z]$</regex>
+ <regex>[a-z][a-z]</regex>
</constraint>
<constraintErrorMessage>Invalid ISO/IEC 3166-1 Country Code</constraintErrorMessage>
</properties>
@@ -513,7 +518,7 @@
</completionHelp>
<valueHelp>
<format>disabled</format>
- <description>no MFP (hostapd default)</description>
+ <description>no MFP</description>
</valueHelp>
<valueHelp>
<format>optional</format>
@@ -524,9 +529,10 @@
<description>MFP enforced</description>
</valueHelp>
<constraint>
- <regex>^(disabled|optional|required)$</regex>
+ <regex>(disabled|optional|required)</regex>
</constraint>
</properties>
+ <defaultValue>disabled</defaultValue>
</leafNode>
<leafNode name="mode">
<properties>
@@ -544,7 +550,7 @@
</valueHelp>
<valueHelp>
<format>g</format>
- <description>802.11g - 54 Mbits/sec (default)</description>
+ <description>802.11g - 54 Mbits/sec</description>
</valueHelp>
<valueHelp>
<format>n</format>
@@ -555,14 +561,15 @@
<description>802.11ac - 1300 Mbits/sec</description>
</valueHelp>
<constraint>
- <regex>^(a|b|g|n|ac)$</regex>
+ <regex>(a|b|g|n|ac)</regex>
</constraint>
</properties>
<defaultValue>g</defaultValue>
</leafNode>
+ #include <include/interface/mirror.xml.i>
<leafNode name="physical-device">
<properties>
- <help>Wireless physical device (default: phy0)</help>
+ <help>Wireless physical device</help>
<completionHelp>
<script>${vyos_completion_dir}/list_wireless_phys.sh</script>
</completionHelp>
@@ -643,7 +650,7 @@
<description>Temporal Key Integrity Protocol [IEEE 802.11i/D7.0]</description>
</valueHelp>
<constraint>
- <regex>^(GCMP-256|GCMP|CCMP-256|CCMP|TKIP)$</regex>
+ <regex>(GCMP-256|GCMP|CCMP-256|CCMP|TKIP)</regex>
</constraint>
<constraintErrorMessage>Invalid cipher selection</constraintErrorMessage>
<multi/>
@@ -676,7 +683,7 @@
<description>Temporal Key Integrity Protocol [IEEE 802.11i/D7.0]</description>
</valueHelp>
<constraint>
- <regex>^(GCMP-256|GCMP|CCMP-256|CCMP|TKIP)$</regex>
+ <regex>(GCMP-256|GCMP|CCMP-256|CCMP|TKIP)</regex>
</constraint>
<constraintErrorMessage>Invalid group cipher selection</constraintErrorMessage>
<multi/>
@@ -701,7 +708,7 @@
<description>Allow both WPA and WPA2</description>
</valueHelp>
<constraint>
- <regex>^(wpa|wpa2|wpa\+wpa2|wpa3)$</regex>
+ <regex>(wpa|wpa2|wpa\+wpa2|wpa3)</regex>
</constraint>
<constraintErrorMessage>Unknown WPA mode</constraintErrorMessage>
</properties>
@@ -717,7 +724,7 @@
<description>Passphrase of at least 8 but not more than 63 printable characters</description>
</valueHelp>
<constraint>
- <regex>.{8,63}$</regex>
+ <regex>.{8,63}</regex>
</constraint>
<constraintErrorMessage>Invalid WPA pass phrase, must be 8 to 63 printable characters!</constraintErrorMessage>
</properties>
@@ -745,7 +752,7 @@
<properties>
<help>Wireless access-point service set identifier (SSID)</help>
<constraint>
- <regex>.{1,32}$</regex>
+ <regex>.{1,32}</regex>
</constraint>
<constraintErrorMessage>Invalid SSID</constraintErrorMessage>
</properties>
@@ -769,12 +776,13 @@
<description>Passively monitor all packets on the frequency/channel</description>
</valueHelp>
<constraint>
- <regex>^(access-point|station|monitor)$</regex>
+ <regex>(access-point|station|monitor)</regex>
</constraint>
<constraintErrorMessage>Type must be access-point, station or monitor</constraintErrorMessage>
</properties>
<defaultValue>monitor</defaultValue>
</leafNode>
+ #include <include/interface/redirect.xml.i>
#include <include/interface/vif.xml.i>
#include <include/interface/vif-s.xml.i>
</children>
diff --git a/interface-definitions/interfaces-wwan.xml.in b/interface-definitions/interfaces-wwan.xml.in
index 6b6fa1a66..3071e6091 100644
--- a/interface-definitions/interfaces-wwan.xml.in
+++ b/interface-definitions/interfaces-wwan.xml.in
@@ -7,10 +7,10 @@
<help>Wireless Modem (WWAN) Interface</help>
<priority>350</priority>
<completionHelp>
- <script>cd /sys/class/net; ls -d wwan*</script>
+ <script>cd /sys/class/net; if compgen -G "wwan*" > /dev/null; then ls -d wwan*; fi</script>
</completionHelp>
<constraint>
- <regex>^wwan[0-9]+$</regex>
+ <regex>wwan[0-9]+</regex>
</constraint>
<constraintErrorMessage>Wireless Modem interface must be named wwanN</constraintErrorMessage>
<valueHelp>
@@ -30,8 +30,8 @@
#include <include/interface/authentication.xml.i>
#include <include/interface/description.xml.i>
#include <include/interface/disable.xml.i>
- #include <include/interface/vrf.xml.i>
#include <include/interface/disable-link-detect.xml.i>
+ #include <include/interface/mirror.xml.i>
#include <include/interface/mtu-68-1500.xml.i>
<leafNode name="mtu">
<defaultValue>1430</defaultValue>
@@ -39,6 +39,10 @@
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
#include <include/interface/dial-on-demand.xml.i>
+ #include <include/interface/interface-firewall.xml.i>
+ #include <include/interface/interface-policy.xml.i>
+ #include <include/interface/redirect.xml.i>
+ #include <include/interface/vrf.xml.i>
</children>
</tagNode>
</children>
diff --git a/interface-definitions/lldp.xml.in b/interface-definitions/lldp.xml.in
index 32ef0ad14..b9ffe234c 100644
--- a/interface-definitions/lldp.xml.in
+++ b/interface-definitions/lldp.xml.in
@@ -28,7 +28,7 @@
#include <include/generic-disable-node.xml.i>
<node name="location">
<properties>
- <help>LLDP-MED location data [REQUIRED]</help>
+ <help>LLDP-MED location data</help>
</properties>
<children>
<node name="coordinate-based">
@@ -40,6 +40,10 @@
<properties>
<help>Altitude in meters</help>
<valueHelp>
+ <format>0</format>
+ <description>No altitude</description>
+ </valueHelp>
+ <valueHelp>
<format>[+-]&lt;meters&gt;</format>
<description>Altitude in meters</description>
</valueHelp>
@@ -48,13 +52,14 @@
<validator name="numeric"/>
</constraint>
</properties>
+ <defaultValue>0</defaultValue>
</leafNode>
<leafNode name="datum">
<properties>
<help>Coordinate datum type</help>
<valueHelp>
<format>WGS84</format>
- <description>WGS84 (default)</description>
+ <description>WGS84</description>
</valueHelp>
<valueHelp>
<format>NAD83</format>
@@ -69,33 +74,34 @@
</completionHelp>
<constraintErrorMessage>Datum should be WGS84, NAD83, or MLLW</constraintErrorMessage>
<constraint>
- <regex>^(WGS84|NAD83|MLLW)$</regex>
+ <regex>(WGS84|NAD83|MLLW)</regex>
</constraint>
</properties>
+ <defaultValue>WGS84</defaultValue>
</leafNode>
<leafNode name="latitude">
<properties>
- <help>Latitude [REQUIRED]</help>
+ <help>Latitude</help>
<valueHelp>
<format>&lt;latitude&gt;</format>
<description>Latitude (example "37.524449N")</description>
</valueHelp>
<constraintErrorMessage>Latitude should be a number followed by S or N</constraintErrorMessage>
<constraint>
- <regex>(\d+)(\.\d+)?[nNsS]$</regex>
+ <regex>(\d+)(\.\d+)?[nNsS]</regex>
</constraint>
</properties>
</leafNode>
<leafNode name="longitude">
<properties>
- <help>Longitude [REQUIRED]</help>
+ <help>Longitude</help>
<valueHelp>
<format>&lt;longitude&gt;</format>
<description>Longitude (example "122.267255W")</description>
</valueHelp>
<constraintErrorMessage>Longiture should be a number followed by E or W</constraintErrorMessage>
<constraint>
- <regex>(\d+)(\.\d+)?[eEwW]$</regex>
+ <regex>(\d+)(\.\d+)?[eEwW]</regex>
</constraint>
</properties>
</leafNode>
@@ -109,7 +115,7 @@
<description>Emergency Call Service ELIN number (between 10-25 numbers)</description>
</valueHelp>
<constraint>
- <regex>[0-9]{10,25}$</regex>
+ <regex>[0-9]{10,25}</regex>
</constraint>
<constraintErrorMessage>ELIN number must be between 10-25 numbers</constraintErrorMessage>
</properties>
diff --git a/interface-definitions/nat.xml.in b/interface-definitions/nat.xml.in
index 3cf3ba6aa..9295b631f 100644
--- a/interface-definitions/nat.xml.in
+++ b/interface-definitions/nat.xml.in
@@ -18,6 +18,7 @@
<properties>
<help>Inbound interface of NAT traffic</help>
<completionHelp>
+ <list>any</list>
<script>${vyos_completion_dir}/list_interfaces.py</script>
</completionHelp>
</properties>
@@ -97,7 +98,7 @@
<validator name="ipv4-prefix"/>
<validator name="ipv4-address"/>
<validator name="ipv4-range"/>
- <regex>^(masquerade)$</regex>
+ <regex>(masquerade)</regex>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/nat66.xml.in b/interface-definitions/nat66.xml.in
index 11d986c96..b47f653c6 100644
--- a/interface-definitions/nat66.xml.in
+++ b/interface-definitions/nat66.xml.in
@@ -94,7 +94,7 @@
<constraint>
<validator name="ipv6-address"/>
<validator name="ipv6-prefix"/>
- <regex>^(masquerade)$</regex>
+ <regex>(masquerade)</regex>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/netns.xml.in b/interface-definitions/netns.xml.in
new file mode 100644
index 000000000..088985cb6
--- /dev/null
+++ b/interface-definitions/netns.xml.in
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="netns" owner="${vyos_conf_scripts_dir}/netns.py">
+ <properties>
+ <help>Network namespace</help>
+ <priority>299</priority>
+ </properties>
+ <children>
+ <tagNode name="name">
+ <properties>
+ <help>Network namespace name</help>
+ <constraint>
+ <regex>[a-zA-Z0-9-_]{1,100}</regex>
+ </constraint>
+ <constraintErrorMessage>Netns name must be alphanumeric and can contain hyphens and underscores.</constraintErrorMessage>
+ </properties>
+ <children>
+ #include <include/interface/description.xml.i>
+ </children>
+ </tagNode>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/interface-definitions/policy-local-route.xml.in b/interface-definitions/policy-local-route.xml.in
index 86445b65d..d969613b1 100644
--- a/interface-definitions/policy-local-route.xml.in
+++ b/interface-definitions/policy-local-route.xml.in
@@ -14,7 +14,7 @@
<valueHelp>
<!-- table main with prio 32766 -->
<format>u32:1-32765</format>
- <description>Local-route rule number (1-219)</description>
+ <description>Local-route rule number (1-32765)</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-32765"/>
@@ -70,6 +70,115 @@
<multi/>
</properties>
</leafNode>
+ <leafNode name="destination">
+ <properties>
+ <help>Destination address or prefix</help>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>Address to match against</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv4net</format>
+ <description>Prefix to match against</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv4-address"/>
+ <validator name="ip-prefix"/>
+ </constraint>
+ <multi/>
+ </properties>
+ </leafNode>
+ #include <include/interface/inbound-interface.xml.i>
+ </children>
+ </tagNode>
+ </children>
+ </node>
+ <node name="local-route6" owner="${vyos_conf_scripts_dir}/policy-local-route.py">
+ <properties>
+ <help>IPv6 policy route of local traffic</help>
+ </properties>
+ <children>
+ <tagNode name="rule">
+ <properties>
+ <help>IPv6 policy local-route rule set number</help>
+ <valueHelp>
+ <!-- table main with prio 32766 -->
+ <format>u32:1-32765</format>
+ <description>Local-route rule number (1-32765)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-32765"/>
+ </constraint>
+ </properties>
+ <children>
+ <node name="set">
+ <properties>
+ <help>Packet modifications</help>
+ </properties>
+ <children>
+ <leafNode name="table">
+ <properties>
+ <help>Routing table to forward packet with</help>
+ <valueHelp>
+ <format>u32:1-200</format>
+ <description>Table number</description>
+ </valueHelp>
+ <completionHelp>
+ <list>main</list>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ <leafNode name="fwmark">
+ <properties>
+ <help>Match fwmark value</help>
+ <valueHelp>
+ <format>u32:1-2147483647</format>
+ <description>Address to match against</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-2147483647"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="source">
+ <properties>
+ <help>Source address or prefix</help>
+ <valueHelp>
+ <format>ipv6</format>
+ <description>Address to match against</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv6net</format>
+ <description>Prefix to match against</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv6-address"/>
+ <validator name="ipv6-prefix"/>
+ </constraint>
+ <multi/>
+ </properties>
+ </leafNode>
+ <leafNode name="destination">
+ <properties>
+ <help>Destination address or prefix</help>
+ <valueHelp>
+ <format>ipv6</format>
+ <description>Address to match against</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv6net</format>
+ <description>Prefix to match against</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv6-address"/>
+ <validator name="ipv6-prefix"/>
+ </constraint>
+ <multi/>
+ </properties>
+ </leafNode>
+ #include <include/interface/inbound-interface.xml.i>
</children>
</tagNode>
</children>
diff --git a/interface-definitions/policy-route.xml.in b/interface-definitions/policy-route.xml.in
new file mode 100644
index 000000000..a10c9b08f
--- /dev/null
+++ b/interface-definitions/policy-route.xml.in
@@ -0,0 +1,105 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="policy">
+ <children>
+ <tagNode name="route6" owner="${vyos_conf_scripts_dir}/policy-route.py">
+ <properties>
+ <help>Policy route rule set name for IPv6</help>
+ <constraint>
+ <regex>[a-zA-Z0-9][\w\-\.]*</regex>
+ </constraint>
+ <priority>201</priority>
+ </properties>
+ <children>
+ #include <include/generic-description.xml.i>
+ #include <include/firewall/name-default-log.xml.i>
+ <tagNode name="rule">
+ <properties>
+ <help>Policy rule number</help>
+ <valueHelp>
+ <format>u32:1-999999</format>
+ <description>Number of policy rule</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-999999"/>
+ </constraint>
+ <constraintErrorMessage>Policy rule number must be between 1 and 999999</constraintErrorMessage>
+ </properties>
+ <children>
+ <node name="destination">
+ <properties>
+ <help>Destination parameters</help>
+ </properties>
+ <children>
+ #include <include/firewall/address-ipv6.xml.i>
+ #include <include/firewall/source-destination-group-ipv6.xml.i>
+ #include <include/firewall/port.xml.i>
+ </children>
+ </node>
+ <node name="source">
+ <properties>
+ <help>Source parameters</help>
+ </properties>
+ <children>
+ #include <include/firewall/address-ipv6.xml.i>
+ #include <include/firewall/source-destination-group-ipv6.xml.i>
+ #include <include/firewall/port.xml.i>
+ </children>
+ </node>
+ #include <include/policy/route-common-rule-ipv6.xml.i>
+ </children>
+ </tagNode>
+ </children>
+ </tagNode>
+ <tagNode name="route" owner="${vyos_conf_scripts_dir}/policy-route.py">
+ <properties>
+ <help>Policy route rule set name for IPv4</help>
+ <constraint>
+ <regex>[a-zA-Z0-9][\w\-\.]*</regex>
+ </constraint>
+ <priority>201</priority>
+ </properties>
+ <children>
+ #include <include/generic-description.xml.i>
+ #include <include/firewall/name-default-log.xml.i>
+ <tagNode name="rule">
+ <properties>
+ <help>Policy rule number</help>
+ <valueHelp>
+ <format>u32:1-999999</format>
+ <description>Number of policy rule</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-999999"/>
+ </constraint>
+ <constraintErrorMessage>Policy rule number must be between 1 and 999999</constraintErrorMessage>
+ </properties>
+ <children>
+ <node name="destination">
+ <properties>
+ <help>Destination parameters</help>
+ </properties>
+ <children>
+ #include <include/firewall/address.xml.i>
+ #include <include/firewall/source-destination-group.xml.i>
+ #include <include/firewall/port.xml.i>
+ </children>
+ </node>
+ <node name="source">
+ <properties>
+ <help>Source parameters</help>
+ </properties>
+ <children>
+ #include <include/firewall/address.xml.i>
+ #include <include/firewall/source-destination-group.xml.i>
+ #include <include/firewall/port.xml.i>
+ </children>
+ </node>
+ #include <include/policy/route-common-rule.xml.i>
+ </children>
+ </tagNode>
+ </children>
+ </tagNode>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/interface-definitions/policy.xml.in b/interface-definitions/policy.xml.in
index 225f9a6f9..50b7cbc84 100644
--- a/interface-definitions/policy.xml.in
+++ b/interface-definitions/policy.xml.in
@@ -242,7 +242,7 @@
<description>BGP extended community-list name</description>
</valueHelp>
<constraint>
- <regex>^[-_a-zA-Z0-9]+$</regex>
+ <regex>[-_a-zA-Z0-9]+</regex>
</constraint>
<constraintErrorMessage>Should be an alphanumeric name</constraintErrorMessage>
</properties>
@@ -291,7 +291,7 @@
<description>BGP large-community-list name</description>
</valueHelp>
<constraint>
- <regex>^[-_a-zA-Z0-9]+$</regex>
+ <regex>[-_a-zA-Z0-9]+</regex>
</constraint>
<constraintErrorMessage>Should be an alphanumeric name</constraintErrorMessage>
</properties>
@@ -340,7 +340,7 @@
<description>Name of IPv4 prefix-list</description>
</valueHelp>
<constraint>
- <regex>^[-_a-zA-Z0-9]+$</regex>
+ <regex>[-_a-zA-Z0-9]+</regex>
</constraint>
<constraintErrorMessage>Name of prefix-list can only contain alpha-numeric letters, hyphen and underscores</constraintErrorMessage>
</properties>
@@ -408,7 +408,7 @@
<description>Name of IPv6 prefix-list</description>
</valueHelp>
<constraint>
- <regex>^[-_a-zA-Z0-9]+$</regex>
+ <regex>[-_a-zA-Z0-9]+</regex>
</constraint>
<constraintErrorMessage>Name of prefix-list6 can only contain alpha-numeric letters, hyphen and underscores</constraintErrorMessage>
</properties>
@@ -476,7 +476,7 @@
<description>Route map name</description>
</valueHelp>
<constraint>
- <regex>^[-_a-zA-Z0-9.]+$</regex>
+ <regex>[-_a-zA-Z0-9.]+</regex>
</constraint>
<constraintErrorMessage>Name of route-map can only contain alpha-numeric letters, hyphen and underscores</constraintErrorMessage>
</properties>
@@ -582,7 +582,7 @@
<description>Prefix route</description>
</valueHelp>
<constraint>
- <regex>^(macip|multicast|prefix)$</regex>
+ <regex>(macip|multicast|prefix)</regex>
</constraint>
</properties>
</leafNode>
@@ -793,7 +793,7 @@
</node>
<leafNode name="local-preference">
<properties>
- <help>local-preference_help</help>
+ <help>Local Preference</help>
<valueHelp>
<format>u32:0-4294967295</format>
<description>Local Preference</description>
@@ -834,7 +834,7 @@
<description>Incomplete origin</description>
</valueHelp>
<constraint>
- <regex>^(egp|igp|incomplete)$</regex>
+ <regex>(egp|igp|incomplete)</regex>
</constraint>
</properties>
</leafNode>
@@ -869,7 +869,7 @@
<description>Match valid entries</description>
</valueHelp>
<constraint>
- <regex>^(invalid|notfound|valid)$</regex>
+ <regex>(invalid|notfound|valid)</regex>
</constraint>
</properties>
</leafNode>
@@ -948,24 +948,49 @@
</leafNode>
</children>
</node>
- <leafNode name="as-path-exclude">
+ <node name="as-path">
<properties>
- <help>Remove ASN(s) from a Border Gateway Protocol (BGP) AS-path attribute</help>
- <valueHelp>
- <format>txt</format>
- <description>BGP AS path exclude string (ex: "456 64500 45001")</description>
- </valueHelp>
- </properties>
- </leafNode>
- <leafNode name="as-path-prepend">
- <properties>
- <help>Prepend string for a Border Gateway Protocol (BGP) AS-path attribute</help>
- <valueHelp>
- <format>txt</format>
- <description>BGP AS path prepend string (ex: "64501 64501")</description>
- </valueHelp>
+ <help>Transform BGP AS_PATH attribute</help>
</properties>
- </leafNode>
+ <children>
+ <leafNode name="exclude">
+ <properties>
+ <help>Remove/exclude from the as-path attribute</help>
+ <valueHelp>
+ <format>u32</format>
+ <description>AS number</description>
+ </valueHelp>
+ <constraint>
+ <validator name="as-number-list"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="prepend">
+ <properties>
+ <help>Prepend to the as-path</help>
+ <valueHelp>
+ <format>u32</format>
+ <description>AS number</description>
+ </valueHelp>
+ <constraint>
+ <validator name="as-number-list"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="prepend-last-as">
+ <properties>
+ <help>Use the last AS-number in the as-path</help>
+ <valueHelp>
+ <format>u32:1-10</format>
+ <description>Number of times to insert</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-10"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
<leafNode name="atomic-aggregate">
<properties>
<help>BGP atomic aggregate attribute</help>
@@ -1045,6 +1070,44 @@
</constraint>
</properties>
</leafNode>
+ <node name="evpn">
+ <properties>
+ <help>Ethernet Virtual Private Network</help>
+ </properties>
+ <children>
+ <node name="gateway">
+ <properties>
+ <help>Set gateway IP for prefix advertisement route</help>
+ </properties>
+ <children>
+ <leafNode name="ipv4">
+ <properties>
+ <help>Set gateway IPv4 address</help>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>Gateway IPv4 address</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv4-address"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="ipv6">
+ <properties>
+ <help>Set gateway IPv6 address</help>
+ <valueHelp>
+ <format>ipv6</format>
+ <description>Gateway IPv6 address</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv6-address"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+ </node>
<node name="extcommunity">
<properties>
<help>BGP extended community attribute</help>
@@ -1070,7 +1133,7 @@
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-25600"/>
- <regex>^(cumulative|num-multipaths)$</regex>
+ <regex>(cumulative|num-multipaths)</regex>
</constraint>
</properties>
</leafNode>
@@ -1086,7 +1149,7 @@
<description>Based on a router-id IP address</description>
</valueHelp>
<constraint>
- <regex>^((?:[0-9]{1,3}\.){3}[0-9]{1,3}|\d+):\d+$</regex>
+ <regex>(((\b(?:(?:2(?:[0-4][0-9]|5[0-5])|[0-1]?[0-9]?[0-9])\.){3}(?:(?:2([0-4][0-9]|5[0-5])|[0-1]?[0-9]?[0-9]))\b)|(\d+)):(\d+) ?)+</regex>
</constraint>
<constraintErrorMessage>Should be in form: ASN:NN or IPADDR:NN where ASN is autonomous system number</constraintErrorMessage>
</properties>
@@ -1103,7 +1166,7 @@
<description>Based on a router-id IP address</description>
</valueHelp>
<constraint>
- <regex>^((?:[0-9]{1,3}\.){3}[0-9]{1,3}|\d+):\d+$</regex>
+ <regex>((?:[0-9]{1,3}\.){3}[0-9]{1,3}|\d+):\d+</regex>
</constraint>
<constraintErrorMessage>Should be in form: ASN:NN or IPADDR:NN where ASN is autonomous system number</constraintErrorMessage>
</properties>
@@ -1113,12 +1176,25 @@
<leafNode name="ip-next-hop">
<properties>
<help>Nexthop IP address</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_local_ips.sh --ipv4</script>
+ <list>unchanged peer-address</list>
+ </completionHelp>
<valueHelp>
<format>ipv4</format>
<description>IP address</description>
</valueHelp>
+ <valueHelp>
+ <format>unchanged</format>
+ <description>Set the BGP nexthop address as unchanged</description>
+ </valueHelp>
+ <valueHelp>
+ <format>peer-address</format>
+ <description>Set the BGP nexthop address to the address of the peer</description>
+ </valueHelp>
<constraint>
<validator name="ipv4-address"/>
+ <regex>(unchanged|peer-address)</regex>
</constraint>
</properties>
</leafNode>
@@ -1130,6 +1206,9 @@
<leafNode name="global">
<properties>
<help>Nexthop IPv6 global address</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_local_ips.sh --ipv6</script>
+ </completionHelp>
<valueHelp>
<format>ipv6</format>
<description>IPv6 address and prefix length</description>
@@ -1142,6 +1221,9 @@
<leafNode name="local">
<properties>
<help>Nexthop IPv6 local address</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_local_ips.sh --ipv6</script>
+ </completionHelp>
<valueHelp>
<format>ipv6</format>
<description>IPv6 address and prefix length</description>
@@ -1151,6 +1233,12 @@
</constraint>
</properties>
</leafNode>
+ <leafNode name="peer-address">
+ <properties>
+ <help>Use peer address (for BGP only)</help>
+ <valueless/>
+ </properties>
+ </leafNode>
<leafNode name="prefer-global">
<properties>
<help>Prefer global address as the nexthop</help>
@@ -1226,7 +1314,7 @@
<description>OSPF external type 2 metric</description>
</valueHelp>
<constraint>
- <regex>^(type-1|type-2)$</regex>
+ <regex>(type-1|type-2)</regex>
</constraint>
</properties>
</leafNode>
@@ -1249,7 +1337,7 @@
<description>Incomplete origin</description>
</valueHelp>
<constraint>
- <regex>^(igp|egp|incomplete)$</regex>
+ <regex>(igp|egp|incomplete)</regex>
</constraint>
</properties>
</leafNode>
@@ -1268,6 +1356,9 @@
<leafNode name="src">
<properties>
<help>Source address for route</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_local_ips.sh --both</script>
+ </completionHelp>
<valueHelp>
<format>ipv4</format>
<description>IPv4 address</description>
diff --git a/interface-definitions/protocols-bfd.xml.in b/interface-definitions/protocols-bfd.xml.in
index 7b22b8125..edbac8d0e 100644
--- a/interface-definitions/protocols-bfd.xml.in
+++ b/interface-definitions/protocols-bfd.xml.in
@@ -26,18 +26,7 @@
</constraint>
</properties>
<children>
- <leafNode name="profile">
- <properties>
- <help>Use settings from BFD profile</help>
- <completionHelp>
- <path>protocols bfd profile</path>
- </completionHelp>
- <valueHelp>
- <format>txt</format>
- <description>BFD profile name</description>
- </valueHelp>
- </properties>
- </leafNode>
+ #include <include/bfd/profile.xml.i>
<node name="source">
<properties>
<help>Bind listener to specified interface/address, mandatory for IPv6</help>
@@ -66,13 +55,14 @@
</leafNode>
</children>
</node>
- #include <include/bfd-common.xml.i>
+ #include <include/bfd/common.xml.i>
<leafNode name="multihop">
<properties>
<help>Allow this BFD peer to not be directly connected</help>
<valueless/>
</properties>
</leafNode>
+ #include <include/interface/vrf.xml.i>
</children>
</tagNode>
<tagNode name="profile">
@@ -83,11 +73,11 @@
<description>Name of BFD profile</description>
</valueHelp>
<constraint>
- <regex>^[-_a-zA-Z0-9]{1,32}$</regex>
+ <regex>[-_a-zA-Z0-9]{1,32}</regex>
</constraint>
</properties>
<children>
- #include <include/bfd-common.xml.i>
+ #include <include/bfd/common.xml.i>
</children>
</tagNode>
</children>
diff --git a/interface-definitions/protocols-nhrp.xml.in b/interface-definitions/protocols-nhrp.xml.in
index 9dd9d3389..1e08c6873 100644
--- a/interface-definitions/protocols-nhrp.xml.in
+++ b/interface-definitions/protocols-nhrp.xml.in
@@ -4,7 +4,7 @@
<children>
<node name="nhrp" owner="${vyos_conf_scripts_dir}/protocols_nhrp.py">
<properties>
- <help>NHRP parameters</help>
+ <help>Next Hop Resolution Protocol (NHRP) parameters</help>
<priority>680</priority>
</properties>
<children>
@@ -12,7 +12,7 @@
<properties>
<help>Tunnel for NHRP [REQUIRED]</help>
<constraint>
- <regex>^tun[0-9]+$</regex>
+ <regex>tun[0-9]+</regex>
</constraint>
<valueHelp>
<format>tunN</format>
@@ -85,7 +85,7 @@
<list>dynamic nhs</list>
</completionHelp>
<constraint>
- <regex>^(dynamic|nhs)$</regex>
+ <regex>(dynamic|nhs)</regex>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/protocols-ospfv3.xml.in b/interface-definitions/protocols-ospfv3.xml.in
index fffeeb9a5..2b98ffa7b 100644
--- a/interface-definitions/protocols-ospfv3.xml.in
+++ b/interface-definitions/protocols-ospfv3.xml.in
@@ -8,226 +8,7 @@
<priority>620</priority>
</properties>
<children>
- <tagNode name="area">
- <properties>
- <help>OSPFv3 Area</help>
- <valueHelp>
- <format>u32</format>
- <description>Area ID as a decimal value</description>
- </valueHelp>
- <valueHelp>
- <format>ipv4</format>
- <description>Area ID in IP address forma</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-4294967295"/>
- <validator name="ip-address"/>
- </constraint>
- </properties>
- <children>
- <node name="area-type">
- <properties>
- <help>OSPFv3 Area type</help>
- </properties>
- <children>
- <node name="stub">
- <properties>
- <help>Stub OSPFv3 area</help>
- </properties>
- <children>
- <leafNode name="no-summary">
- <properties>
- <help>Do not inject inter-area routes into the stub</help>
- <valueless/>
- </properties>
- </leafNode>
- </children>
- </node>
- </children>
- </node>
- <leafNode name="export-list">
- <properties>
- <help>Name of export-list</help>
- <completionHelp>
- <path>policy access-list6</path>
- </completionHelp>
- </properties>
- </leafNode>
- <leafNode name="import-list">
- <properties>
- <help>Name of import-list</help>
- <completionHelp>
- <path>policy access-list6</path>
- </completionHelp>
- </properties>
- </leafNode>
- #include <include/generic-interface-multi.xml.i>
- <tagNode name="range">
- <properties>
- <help>Specify IPv6 prefix (border routers only)</help>
- <valueHelp>
- <format>ipv6net</format>
- <description>Specify IPv6 prefix (border routers only)</description>
- </valueHelp>
- <constraint>
- <validator name="ipv6-prefix"/>
- </constraint>
- </properties>
- <children>
- <leafNode name="advertise">
- <properties>
- <help>Advertise this range</help>
- <valueless/>
- </properties>
- </leafNode>
- <leafNode name="not-advertise">
- <properties>
- <help>Do not advertise this range</help>
- <valueless/>
- </properties>
- </leafNode>
- </children>
- </tagNode>
- </children>
- </tagNode>
- <node name="distance">
- <properties>
- <help>Administrative distance</help>
- </properties>
- <children>
- #include <include/ospf/distance-global.xml.i>
- <node name="ospfv3">
- <properties>
- <help>OSPFv3 administrative distance</help>
- </properties>
- <children>
- #include <include/ospf/distance-per-protocol.xml.i>
- </children>
- </node>
- </children>
- </node>
- <tagNode name="interface">
- <properties>
- <help>Enable routing on an IPv6 interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces.py</script>
- </completionHelp>
- <valueHelp>
- <format>txt</format>
- <description>Interface used for routing information exchange</description>
- </valueHelp>
- <constraint>
- <validator name="interface-name"/>
- </constraint>
- </properties>
- <children>
- #include <include/ospf/intervals.xml.i>
- #include <include/ospf/interface-common.xml.i>
- <leafNode name="ifmtu">
- <properties>
- <help>Interface MTU</help>
- <valueHelp>
- <format>u32:1-65535</format>
- <description>Interface MTU</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-65535"/>
- </constraint>
- </properties>
- </leafNode>
- <leafNode name="instance-id">
- <properties>
- <help>Instance Id (default: 0)</help>
- <valueHelp>
- <format>u32:0-255</format>
- <description>Instance Id</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-255"/>
- </constraint>
- </properties>
- <defaultValue>0</defaultValue>
- </leafNode>
- <leafNode name="network">
- <properties>
- <help>Network type</help>
- <completionHelp>
- <list>broadcast point-to-point</list>
- </completionHelp>
- <valueHelp>
- <format>broadcast</format>
- <description>Broadcast network type</description>
- </valueHelp>
- <valueHelp>
- <format>point-to-point</format>
- <description>Point-to-point network type</description>
- </valueHelp>
- <constraint>
- <regex>^(broadcast|point-to-point)$</regex>
- </constraint>
- <constraintErrorMessage>Must be broadcast or point-to-point</constraintErrorMessage>
- </properties>
- </leafNode>
- #include <include/isis/passive.xml.i>
- </children>
- </tagNode>
- #include <include/ospf/log-adjacency-changes.xml.i>
- <node name="parameters">
- <properties>
- <help>OSPFv3 specific parameters</help>
- </properties>
- <children>
- #include <include/router-id.xml.i>
- </children>
- </node>
- <node name="redistribute">
- <properties>
- <help>Redistribute information from another routing protocol</help>
- </properties>
- <children>
- <node name="bgp">
- <properties>
- <help>Redistribute BGP routes</help>
- </properties>
- <children>
- #include <include/route-map.xml.i>
- </children>
- </node>
- <node name="connected">
- <properties>
- <help>Redistribute connected routes</help>
- </properties>
- <children>
- #include <include/route-map.xml.i>
- </children>
- </node>
- <node name="kernel">
- <properties>
- <help>Redistribute kernel routes</help>
- </properties>
- <children>
- #include <include/route-map.xml.i>
- </children>
- </node>
- <node name="ripng">
- <properties>
- <help>Redistribute RIPNG routes</help>
- </properties>
- <children>
- #include <include/route-map.xml.i>
- </children>
- </node>
- <node name="static">
- <properties>
- <help>Redistribute static routes</help>
- </properties>
- <children>
- #include <include/route-map.xml.i>
- </children>
- </node>
- </children>
- </node>
- #include <include/route-map.xml.i>
+ #include <include/ospfv3/protocol-common-config.xml.i>
</children>
</node>
</children>
diff --git a/interface-definitions/protocols-rip.xml.in b/interface-definitions/protocols-rip.xml.in
index d3be4e1af..bbb88aef1 100644
--- a/interface-definitions/protocols-rip.xml.in
+++ b/interface-definitions/protocols-rip.xml.in
@@ -78,7 +78,7 @@
<description>MD5 Key (16 characters or less)</description>
</valueHelp>
<constraint>
- <regex>^[^[:space:]]{1,16}$</regex>
+ <regex>[^[:space:]]{1,16}</regex>
</constraint>
<constraintErrorMessage>Password must be 16 characters or less</constraintErrorMessage>
</properties>
@@ -93,7 +93,7 @@
<description>Plain text password (16 characters or less)</description>
</valueHelp>
<constraint>
- <regex>^[^[:space:]]{1,16}$</regex>
+ <regex>[^[:space:]]{1,16}</regex>
</constraint>
<constraintErrorMessage>Password must be 16 characters or less</constraintErrorMessage>
</properties>
diff --git a/interface-definitions/protocols-rpki.xml.in b/interface-definitions/protocols-rpki.xml.in
index a73d0aae4..68762ff9a 100644
--- a/interface-definitions/protocols-rpki.xml.in
+++ b/interface-definitions/protocols-rpki.xml.in
@@ -82,7 +82,7 @@
</tagNode>
<leafNode name="polling-period">
<properties>
- <help>RPKI cache polling period (default: 300)</help>
+ <help>RPKI cache polling period</help>
<valueHelp>
<format>u32:1-86400</format>
<description>Polling period in seconds</description>
diff --git a/interface-definitions/protocols-static-arp.xml.in b/interface-definitions/protocols-static-arp.xml.in
index e5e8a9ad9..8b1b3b5e1 100644
--- a/interface-definitions/protocols-static-arp.xml.in
+++ b/interface-definitions/protocols-static-arp.xml.in
@@ -4,32 +4,46 @@
<children>
<node name="static">
<children>
- <tagNode name="arp" owner="${vyos_conf_scripts_dir}/arp.py">
+ <node name="arp" owner="${vyos_conf_scripts_dir}/arp.py">
<properties>
<help>Static ARP translation</help>
- <valueHelp>
- <format>ipv4</format>
- <description>IPv4 destination address</description>
- </valueHelp>
- <constraint>
- <validator name="ipv4-address"/>
- </constraint>
</properties>
<children>
- <leafNode name="hwaddr">
+ <tagNode name="interface">
<properties>
- <help>Translation MAC address</help>
+ <help>Interface configuration</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces.py</script>
+ </completionHelp>
<valueHelp>
- <format>macaddr</format>
- <description>Hardware (MAC) address</description>
+ <format>txt</format>
+ <description>Interface name</description>
</valueHelp>
<constraint>
- <validator name="mac-address"/>
+ <validator name="interface-name"/>
</constraint>
</properties>
- </leafNode>
+ <children>
+ <tagNode name="address">
+ <properties>
+ <help>IP address for static ARP entry</help>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>IPv4 destination address</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv4-address"/>
+ </constraint>
+ </properties>
+ <children>
+ #include <include/generic-description.xml.i>
+ #include <include/interface/mac.xml.i>
+ </children>
+ </tagNode>
+ </children>
+ </tagNode>
</children>
- </tagNode>
+ </node>
</children>
</node>
</children>
diff --git a/interface-definitions/qos.xml.in b/interface-definitions/qos.xml.in
new file mode 100644
index 000000000..e8f575a1e
--- /dev/null
+++ b/interface-definitions/qos.xml.in
@@ -0,0 +1,789 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="qos" owner="${vyos_conf_scripts_dir}/qos.py">
+ <properties>
+ <help>Quality of Service (QoS)</help>
+ </properties>
+ <children>
+ <tagNode name="interface">
+ <properties>
+ <help>Interface to apply QoS policy</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces.py</script>
+ </completionHelp>
+ <valueHelp>
+ <format>txt</format>
+ <description>Interface name</description>
+ </valueHelp>
+ <constraint>
+ <validator name="interface-name"/>
+ </constraint>
+ </properties>
+ <children>
+ <leafNode name="ingress">
+ <properties>
+ <help>Interface ingress traffic policy</help>
+ <completionHelp>
+ <path>traffic-policy drop-tail</path>
+ <path>traffic-policy fair-queue</path>
+ <path>traffic-policy fq-codel</path>
+ <path>traffic-policy limiter</path>
+ <path>traffic-policy network-emulator</path>
+ <path>traffic-policy priority-queue</path>
+ <path>traffic-policy random-detect</path>
+ <path>traffic-policy rate-control</path>
+ <path>traffic-policy round-robin</path>
+ <path>traffic-policy shaper</path>
+ <path>traffic-policy shaper-hfsc</path>
+ </completionHelp>
+ <valueHelp>
+ <format>txt</format>
+ <description>QoS Policy name</description>
+ </valueHelp>
+ </properties>
+ </leafNode>
+ <leafNode name="egress">
+ <properties>
+ <help>Interface egress traffic policy</help>
+ <completionHelp>
+ <path>traffic-policy drop-tail</path>
+ <path>traffic-policy fair-queue</path>
+ <path>traffic-policy fq-codel</path>
+ <path>traffic-policy limiter</path>
+ <path>traffic-policy network-emulator</path>
+ <path>traffic-policy priority-queue</path>
+ <path>traffic-policy random-detect</path>
+ <path>traffic-policy rate-control</path>
+ <path>traffic-policy round-robin</path>
+ <path>traffic-policy shaper</path>
+ <path>traffic-policy shaper-hfsc</path>
+ </completionHelp>
+ <valueHelp>
+ <format>txt</format>
+ <description>QoS Policy name</description>
+ </valueHelp>
+ </properties>
+ </leafNode>
+ </children>
+ </tagNode>
+ <node name="policy" owner="${vyos_conf_scripts_dir}/qos.py">
+ <properties>
+ <help>Service Policy definitions</help>
+ <priority>900</priority>
+ </properties>
+ <children>
+ <tagNode name="drop-tail">
+ <properties>
+ <help>Packet limited First In, First Out queue</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Policy name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[[:alnum:]][-_[:alnum:]]*</regex>
+ </constraint>
+ <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
+ </properties>
+ <children>
+ #include <include/generic-description.xml.i>
+ #include <include/qos/queue-limit-1-4294967295.xml.i>
+ </children>
+ </tagNode>
+ <tagNode name="fair-queue">
+ <properties>
+ <help>Stochastic Fairness Queueing</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Policy name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[[:alnum:]][-_[:alnum:]]*</regex>
+ </constraint>
+ <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
+ </properties>
+ <children>
+ #include <include/generic-description.xml.i>
+ <leafNode name="hash-interval">
+ <properties>
+ <help>Interval in seconds for queue algorithm perturbation</help>
+ <valueHelp>
+ <format>u32:0</format>
+ <description>No perturbation</description>
+ </valueHelp>
+ <valueHelp>
+ <format>u32:1-127</format>
+ <description>Interval in seconds for queue algorithm perturbation (advised: 10)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-127"/>
+ </constraint>
+ <constraintErrorMessage>Interval must be in range 0 to 127</constraintErrorMessage>
+ </properties>
+ <defaultValue>0</defaultValue>
+ </leafNode>
+ <leafNode name="queue-limit">
+ <properties>
+ <help>Upper limit of the SFQ</help>
+ <valueHelp>
+ <format>u32:2-127</format>
+ <description>Queue size in packets</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 2-127"/>
+ </constraint>
+ <constraintErrorMessage>Queue limit must greater than 1 and less than 128</constraintErrorMessage>
+ </properties>
+ <defaultValue>127</defaultValue>
+ </leafNode>
+ </children>
+ </tagNode>
+ <tagNode name="fq-codel">
+ <properties>
+ <help>Fair Queuing Controlled Delay</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Policy name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[[:alnum:]][-_[:alnum:]]*</regex>
+ </constraint>
+ <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
+ </properties>
+ <children>
+ #include <include/generic-description.xml.i>
+ #include <include/qos/codel-quantum.xml.i>
+ #include <include/qos/flows.xml.i>
+ #include <include/qos/interval.xml.i>
+ #include <include/qos/queue-limit-2-10999.xml.i>
+ #include <include/qos/target.xml.i>
+ </children>
+ </tagNode>
+ <tagNode name="limiter">
+ <properties>
+ <help>Traffic input limiting policy</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Policy name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[[:alnum:]][-_[:alnum:]]*</regex>
+ </constraint>
+ <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
+ </properties>
+ <children>
+ <tagNode name="class">
+ <properties>
+ <help>Class ID</help>
+ <valueHelp>
+ <format>u32:1-4090</format>
+ <description>Class Identifier</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-4090"/>
+ </constraint>
+ <constraintErrorMessage>Class identifier must be between 1 and 4090</constraintErrorMessage>
+ </properties>
+ <children>
+ #include <include/qos/bandwidth.xml.i>
+ #include <include/qos/burst.xml.i>
+ #include <include/generic-description.xml.i>
+ #include <include/qos/match.xml.i>
+ <leafNode name="priority">
+ <properties>
+ <help>Priority for rule evaluation</help>
+ <valueHelp>
+ <format>u32:0-20</format>
+ <description>Priority for match rule evaluation</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-20"/>
+ </constraint>
+ <constraintErrorMessage>Priority must be between 0 and 20</constraintErrorMessage>
+ </properties>
+ <defaultValue>20</defaultValue>
+ </leafNode>
+ </children>
+ </tagNode>
+ <node name="default">
+ <properties>
+ <help>Default policy</help>
+ </properties>
+ <children>
+ #include <include/qos/bandwidth.xml.i>
+ #include <include/qos/burst.xml.i>
+ </children>
+ </node>
+ #include <include/generic-description.xml.i>
+ </children>
+ </tagNode>
+ <tagNode name="network-emulator">
+ <properties>
+ <help>Network emulator policy</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Policy name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[[:alnum:]][-_[:alnum:]]*</regex>
+ </constraint>
+ <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
+ </properties>
+ <children>
+ #include <include/qos/bandwidth.xml.i>
+ #include <include/qos/burst.xml.i>
+ #include <include/generic-description.xml.i>
+ <leafNode name="network-delay">
+ <properties>
+ <help>Adds delay to packets outgoing to chosen network interface</help>
+ <valueHelp>
+ <format>&lt;number&gt;</format>
+ <description>Time in milliseconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-65535"/>
+ </constraint>
+ <constraintErrorMessage>Priority must be between 0 and 65535</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ <leafNode name="packet-corruption">
+ <properties>
+ <help>Introducing error in a random position for chosen percent of packets</help>
+ <valueHelp>
+ <format>&lt;number&gt;</format>
+ <description>Percentage of packets affected</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-100"/>
+ </constraint>
+ <constraintErrorMessage>Priority must be between 0 and 100</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ <leafNode name="packet-loss">
+ <properties>
+ <help>Add independent loss probability to the packets outgoing to chosen network interface</help>
+ <valueHelp>
+ <format>&lt;number&gt;</format>
+ <description>Percentage of packets affected</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-100"/>
+ </constraint>
+ <constraintErrorMessage>Must be between 0 and 100</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ <leafNode name="packet-loss">
+ <properties>
+ <help>Add independent loss probability to the packets outgoing to chosen network interface</help>
+ <valueHelp>
+ <format>&lt;number&gt;</format>
+ <description>Percentage of packets affected</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-100"/>
+ </constraint>
+ <constraintErrorMessage>Must be between 0 and 100</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ <leafNode name="packet-loss">
+ <properties>
+ <help>Packet reordering percentage</help>
+ <valueHelp>
+ <format>&lt;number&gt;</format>
+ <description>Percentage of packets affected</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-100"/>
+ </constraint>
+ <constraintErrorMessage>Must be between 0 and 100</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ #include <include/qos/queue-limit-1-4294967295.xml.i>
+ </children>
+ </tagNode>
+ <tagNode name="priority-queue">
+ <properties>
+ <help>Priority queuing based policy</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Policy name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[[:alnum:]][-_[:alnum:]]*</regex>
+ </constraint>
+ <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
+ </properties>
+ <children>
+ <tagNode name="class">
+ <properties>
+ <help>Class Handle</help>
+ <valueHelp>
+ <format>u32:1-7</format>
+ <description>Priority</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-7"/>
+ </constraint>
+ <constraintErrorMessage>Class handle must be between 1 and 7</constraintErrorMessage>
+ </properties>
+ <children>
+ #include <include/generic-description.xml.i>
+ #include <include/qos/codel-quantum.xml.i>
+ #include <include/qos/flows.xml.i>
+ #include <include/qos/interval.xml.i>
+ #include <include/qos/match.xml.i>
+ #include <include/qos/queue-limit-2-10999.xml.i>
+ #include <include/qos/target.xml.i>
+ #include <include/qos/queue-type.xml.i>
+ </children>
+ </tagNode>
+ <node name="default">
+ <properties>
+ <help>Default policy</help>
+ </properties>
+ <children>
+ #include <include/generic-description.xml.i>
+ #include <include/qos/codel-quantum.xml.i>
+ #include <include/qos/flows.xml.i>
+ #include <include/qos/interval.xml.i>
+ #include <include/qos/queue-limit-2-10999.xml.i>
+ #include <include/qos/target.xml.i>
+ #include <include/qos/queue-type.xml.i>
+ </children>
+ </node>
+ #include <include/generic-description.xml.i>
+ </children>
+ </tagNode>
+ <tagNode name="random-detect">
+ <properties>
+ <help>Priority queuing based policy</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Policy name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[[:alnum:]][-_[:alnum:]]*</regex>
+ </constraint>
+ <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
+ </properties>
+ <children>
+ #include <include/qos/bandwidth.xml.i>
+ <leafNode name="bandwidth">
+ <defaultValue>auto</defaultValue>
+ </leafNode>
+ #include <include/generic-description.xml.i>
+ <tagNode name="precedence">
+ <properties>
+ <help>IP precedence</help>
+ <valueHelp>
+ <format>u32:0-7</format>
+ <description>IP precedence value</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-7"/>
+ </constraint>
+ <constraintErrorMessage>IP precedence value must be between 0 and 7</constraintErrorMessage>
+ </properties>
+ <children>
+ #include <include/qos/queue-limit-1-4294967295.xml.i>
+ <leafNode name="average-packet">
+ <properties>
+ <help>Average packet size (bytes)</help>
+ <valueHelp>
+ <format>u32:16-10240</format>
+ <description>Average packet size in bytes</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-100"/>
+ </constraint>
+ <constraintErrorMessage>Average packet size must be between 16 and 10240</constraintErrorMessage>
+ </properties>
+ <defaultValue>1024</defaultValue>
+ </leafNode>
+ <leafNode name="mark-probability">
+ <properties>
+ <help>Mark probability for this precedence</help>
+ <valueHelp>
+ <format>&lt;number&gt;</format>
+ <description>Numeric value (1/N)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--positive"/>
+ </constraint>
+ <constraintErrorMessage>Mark probability must be greater than 0</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ <leafNode name="maximum-threshold">
+ <properties>
+ <help>Maximum threshold for random detection</help>
+ <valueHelp>
+ <format>u32:0-4096</format>
+ <description>Maximum Threshold in packets</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-4096"/>
+ </constraint>
+ <constraintErrorMessage>Threshold must be between 0 and 4096</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ <leafNode name="minimum-threshold">
+ <properties>
+ <help>Minimum threshold for random detection</help>
+ <valueHelp>
+ <format>u32:0-4096</format>
+ <description>Maximum Threshold in packets</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-4096"/>
+ </constraint>
+ <constraintErrorMessage>Threshold must be between 0 and 4096</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ </children>
+ </tagNode>
+ </children>
+ </tagNode>
+ <tagNode name="rate-control">
+ <properties>
+ <help>Rate limiting policy (Token Bucket Filter)</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Policy name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[[:alnum:]][-_[:alnum:]]*</regex>
+ </constraint>
+ <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
+ </properties>
+ <children>
+ #include <include/qos/bandwidth.xml.i>
+ #include <include/generic-description.xml.i>
+ #include <include/qos/burst.xml.i>
+ <leafNode name="latency">
+ <properties>
+ <help>Maximum latency</help>
+ <valueHelp>
+ <format>&lt;number&gt;</format>
+ <description>Time in milliseconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-4096"/>
+ </constraint>
+ <constraintErrorMessage>Threshold must be between 0 and 4096</constraintErrorMessage>
+ </properties>
+ <defaultValue>50</defaultValue>
+ </leafNode>
+ </children>
+ </tagNode>
+ <tagNode name="round-robin">
+ <properties>
+ <help>Round-Robin based policy</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Policy name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[[:alnum:]][-_[:alnum:]]*</regex>
+ </constraint>
+ <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
+ </properties>
+ <children>
+ #include <include/generic-description.xml.i>
+ <tagNode name="class">
+ <properties>
+ <help>Class ID</help>
+ <valueHelp>
+ <format>u32:1-4095</format>
+ <description>Class Identifier</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-4095"/>
+ </constraint>
+ <constraintErrorMessage>Class identifier must be between 1 and 4095</constraintErrorMessage>
+ </properties>
+ <children>
+ #include <include/qos/codel-quantum.xml.i>
+ #include <include/generic-description.xml.i>
+ #include <include/qos/flows.xml.i>
+ #include <include/qos/interval.xml.i>
+ #include <include/qos/match.xml.i>
+ <leafNode name="quantum">
+ <properties>
+ <help>Packet scheduling quantum</help>
+ <valueHelp>
+ <format>u32:1-4294967295</format>
+ <description>Packet scheduling quantum (bytes)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-4294967295"/>
+ </constraint>
+ <constraintErrorMessage>Quantum must be in range 1 to 4294967295</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ #include <include/qos/queue-limit-1-4294967295.xml.i>
+ #include <include/qos/queue-type.xml.i>
+ #include <include/qos/target.xml.i>
+ </children>
+ </tagNode>
+ </children>
+ </tagNode>
+ <tagNode name="shaper-hfsc">
+ <properties>
+ <help>Hierarchical Fair Service Curve's policy</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Policy name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[[:alnum:]][-_[:alnum:]]*</regex>
+ </constraint>
+ <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
+ </properties>
+ <children>
+ #include <include/qos/bandwidth.xml.i>
+ <leafNode name="bandwidth">
+ <defaultValue>auto</defaultValue>
+ </leafNode>
+ #include <include/generic-description.xml.i>
+ <tagNode name="class">
+ <properties>
+ <help>Class ID</help>
+ <valueHelp>
+ <format>u32:1-4095</format>
+ <description>Class Identifier</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-4095"/>
+ </constraint>
+ <constraintErrorMessage>Class identifier must be between 1 and 4095</constraintErrorMessage>
+ </properties>
+ <children>
+ #include <include/generic-description.xml.i>
+ <node name="linkshare">
+ <properties>
+ <help>Linkshare class settings</help>
+ </properties>
+ <children>
+ #include <include/qos/hfsc-d.xml.i>
+ #include <include/qos/hfsc-m1.xml.i>
+ #include <include/qos/hfsc-m2.xml.i>
+ </children>
+ </node>
+ #include <include/qos/match.xml.i>
+ <node name="realtime">
+ <properties>
+ <help>Realtime class settings</help>
+ </properties>
+ <children>
+ #include <include/qos/hfsc-d.xml.i>
+ #include <include/qos/hfsc-m1.xml.i>
+ #include <include/qos/hfsc-m2.xml.i>
+ </children>
+ </node>
+ <node name="upperlimit">
+ <properties>
+ <help>Upperlimit class settings</help>
+ </properties>
+ <children>
+ #include <include/qos/hfsc-d.xml.i>
+ #include <include/qos/hfsc-m1.xml.i>
+ #include <include/qos/hfsc-m2.xml.i>
+ </children>
+ </node>
+ </children>
+ </tagNode>
+ <node name="default">
+ <properties>
+ <help>Default policy</help>
+ </properties>
+ <children>
+ <node name="linkshare">
+ <properties>
+ <help>Linkshare class settings</help>
+ </properties>
+ <children>
+ #include <include/qos/hfsc-d.xml.i>
+ #include <include/qos/hfsc-m1.xml.i>
+ #include <include/qos/hfsc-m2.xml.i>
+ </children>
+ </node>
+ <node name="realtime">
+ <properties>
+ <help>Realtime class settings</help>
+ </properties>
+ <children>
+ #include <include/qos/hfsc-d.xml.i>
+ #include <include/qos/hfsc-m1.xml.i>
+ #include <include/qos/hfsc-m2.xml.i>
+ </children>
+ </node>
+ <node name="upperlimit">
+ <properties>
+ <help>Upperlimit class settings</help>
+ </properties>
+ <children>
+ #include <include/qos/hfsc-d.xml.i>
+ #include <include/qos/hfsc-m1.xml.i>
+ #include <include/qos/hfsc-m2.xml.i>
+ </children>
+ </node>
+ </children>
+ </node>
+ </children>
+ </tagNode>
+ <tagNode name="shaper">
+ <properties>
+ <help>Traffic shaping based policy (Hierarchy Token Bucket)</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Policy name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[[:alnum:]][-_[:alnum:]]*</regex>
+ </constraint>
+ <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
+ </properties>
+ <children>
+ #include <include/qos/bandwidth.xml.i>
+ <leafNode name="bandwidth">
+ <defaultValue>auto</defaultValue>
+ </leafNode>
+ <tagNode name="class">
+ <properties>
+ <help>Class ID</help>
+ <valueHelp>
+ <format>u32:2-4095</format>
+ <description>Class Identifier</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 2-4095"/>
+ </constraint>
+ <constraintErrorMessage>Class identifier must be between 2 and 4095</constraintErrorMessage>
+ </properties>
+ <children>
+ #include <include/qos/bandwidth.xml.i>
+ <leafNode name="bandwidth">
+ <defaultValue>100%</defaultValue>
+ </leafNode>
+ #include <include/qos/burst.xml.i>
+ <leafNode name="ceiling">
+ <properties>
+ <help>Bandwidth limit for this class</help>
+ <valueHelp>
+ <format>&lt;number&gt;</format>
+ <description>Rate in kbit (kilobit per second)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;%%</format>
+ <description>Percentage of overall rate</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;bit</format>
+ <description>bit(1), kbit(10^3), mbit(10^6), gbit, tbit</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;ibit</format>
+ <description>kibit(1024), mibit(1024^2), gibit(1024^3), tbit(1024^4)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;ibps</format>
+ <description>kibps(1024*8), mibps(1024^2*8), gibps, tibps - Byte/sec</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;bps</format>
+ <description>bps(8),kbps(8*10^3),mbps(8*10^6), gbps, tbps - Byte/sec</description>
+ </valueHelp>
+ </properties>
+ </leafNode>
+ #include <include/qos/codel-quantum.xml.i>
+ #include <include/generic-description.xml.i>
+ #include <include/qos/flows.xml.i>
+ #include <include/qos/interval.xml.i>
+ #include <include/qos/match.xml.i>
+ <leafNode name="priority">
+ <properties>
+ <help>Priority for usage of excess bandwidth</help>
+ <valueHelp>
+ <format>u32:0-7</format>
+ <description>Priority order for bandwidth pool</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-7"/>
+ </constraint>
+ <constraintErrorMessage>Priority must be between 0 and 7</constraintErrorMessage>
+ </properties>
+ <defaultValue>20</defaultValue>
+ </leafNode>
+ #include <include/qos/queue-limit-1-4294967295.xml.i>
+ #include <include/qos/queue-type.xml.i>
+ #include <include/qos/set-dscp.xml.i>
+ #include <include/qos/target.xml.i>
+ </children>
+ </tagNode>
+ #include <include/generic-description.xml.i>
+ <node name="default">
+ <properties>
+ <help>Default policy</help>
+ </properties>
+ <children>
+ #include <include/qos/bandwidth.xml.i>
+ #include <include/qos/burst.xml.i>
+ <leafNode name="ceiling">
+ <properties>
+ <help>Bandwidth limit for this class</help>
+ <valueHelp>
+ <format>&lt;number&gt;</format>
+ <description>Rate in kbit (kilobit per second)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;%%</format>
+ <description>Percentage of overall rate</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;bit</format>
+ <description>bit(1), kbit(10^3), mbit(10^6), gbit, tbit</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;ibit</format>
+ <description>kibit(1024), mibit(1024^2), gibit(1024^3), tbit(1024^4)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;ibps</format>
+ <description>kibps(1024*8), mibps(1024^2*8), gibps, tibps - Byte/sec</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;bps</format>
+ <description>bps(8),kbps(8*10^3),mbps(8*10^6), gbps, tbps - Byte/sec</description>
+ </valueHelp>
+ </properties>
+ </leafNode>
+ #include <include/qos/codel-quantum.xml.i>
+ #include <include/generic-description.xml.i>
+ #include <include/qos/flows.xml.i>
+ #include <include/qos/interval.xml.i>
+ <leafNode name="priority">
+ <properties>
+ <help>Priority for usage of excess bandwidth</help>
+ <valueHelp>
+ <format>u32:0-7</format>
+ <description>Priority order for bandwidth pool</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-7"/>
+ </constraint>
+ <constraintErrorMessage>Priority must be between 0 and 7</constraintErrorMessage>
+ </properties>
+ <defaultValue>20</defaultValue>
+ </leafNode>
+ #include <include/qos/queue-limit-1-4294967295.xml.i>
+ #include <include/qos/queue-type.xml.i>
+ #include <include/qos/set-dscp.xml.i>
+ #include <include/qos/target.xml.i>
+ </children>
+ </node>
+ </children>
+ </tagNode>
+ </children>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/interface-definitions/salt-minion.xml.in b/interface-definitions/salt-minion.xml.in
index d3b022d12..c3219cff3 100644
--- a/interface-definitions/salt-minion.xml.in
+++ b/interface-definitions/salt-minion.xml.in
@@ -15,20 +15,25 @@
<list>md5 sha1 sha224 sha256 sha384 sha512</list>
</completionHelp>
<constraint>
- <regex>^(md5|sha1|sha224|sha256|sha384|sha512)$</regex>
+ <regex>(md5|sha1|sha224|sha256|sha384|sha512)</regex>
</constraint>
</properties>
+ <defaultValue>sha256</defaultValue>
</leafNode>
<leafNode name="master">
<properties>
- <help>The hostname or IP address of the master.</help>
+ <help>Hostname or IP address of the Salt master server</help>
<valueHelp>
<format>ipv4</format>
- <description>Remote syslog server IPv4 address</description>
+ <description>Salt server IPv4 address</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv6</format>
+ <description>Salt server IPv6 address</description>
</valueHelp>
<valueHelp>
<format>hostname</format>
- <description>Remote syslog server FQDN</description>
+ <description>Salt server FQDN address</description>
</valueHelp>
<constraint>
<validator name="ip-address"/>
@@ -54,12 +59,14 @@
<validator name="numeric" argument="--range 1-1440"/>
</constraint>
</properties>
+ <defaultValue>60</defaultValue>
</leafNode>
<leafNode name="master-key">
<properties>
<help>URL with signature of master for auth reply verification</help>
</properties>
</leafNode>
+ #include <include/source-interface.xml.i>
</children>
</node>
</children>
diff --git a/interface-definitions/service-ids-ddos-protection.xml.in b/interface-definitions/service-ids-ddos-protection.xml.in
index ff4c1c24e..5e65d3106 100644
--- a/interface-definitions/service-ids-ddos-protection.xml.in
+++ b/interface-definitions/service-ids-ddos-protection.xml.in
@@ -25,7 +25,7 @@
<list>in out</list>
</completionHelp>
<constraint>
- <regex>^(in|out)$</regex>
+ <regex>(in|out)</regex>
</constraint>
<multi/>
</properties>
diff --git a/interface-definitions/service_conntrack-sync.xml.in b/interface-definitions/service_conntrack-sync.xml.in
index 584f687c7..6fa6fc5f9 100644
--- a/interface-definitions/service_conntrack-sync.xml.in
+++ b/interface-definitions/service_conntrack-sync.xml.in
@@ -5,7 +5,8 @@
<node name="conntrack-sync" owner="${vyos_conf_scripts_dir}/conntrack_sync.py">
<properties>
<help>Connection tracking synchronization</help>
- <priority>995</priority>
+ <!-- before VRRP / HA -->
+ <priority>799</priority>
</properties>
<children>
<leafNode name="accept-protocol">
@@ -39,7 +40,7 @@
<description>Sync Datagram Congestion Control Protocol entries</description>
</valueHelp>
<constraint>
- <regex>^(tcp|udp|icmp|icmp6|sctp|dccp)$</regex>
+ <regex>(tcp|udp|icmp|icmp6|sctp|dccp)</regex>
</constraint>
<constraintErrorMessage>Allowed protocols: tcp udp icmp or sctp</constraintErrorMessage>
<multi/>
@@ -68,7 +69,7 @@
<list>all ftp sip h323 nfs sqlnet</list>
</completionHelp>
<constraint>
- <regex>^(all|ftp|sip|h323|nfs|sqlnet)$</regex>
+ <regex>(all|ftp|sip|h323|nfs|sqlnet)</regex>
</constraint>
<constraintErrorMessage>Invalid protocol</constraintErrorMessage>
<multi/>
diff --git a/interface-definitions/service_console-server.xml.in b/interface-definitions/service_console-server.xml.in
index 28aa7ea71..e9591ad87 100644
--- a/interface-definitions/service_console-server.xml.in
+++ b/interface-definitions/service_console-server.xml.in
@@ -23,7 +23,7 @@
<description>USB based serial interface</description>
</valueHelp>
<constraint>
- <regex>^(ttyS\d+|usb\d+b.*p.*)$</regex>
+ <regex>(ttyS\d+|usb\d+b.*p.*)</regex>
</constraint>
</properties>
<children>
@@ -35,13 +35,13 @@
<list>300 1200 2400 4800 9600 19200 38400 57600 115200</list>
</completionHelp>
<constraint>
- <regex>^(300|1200|2400|4800|9600|19200|38400|57600|115200)$</regex>
+ <regex>(300|1200|2400|4800|9600|19200|38400|57600|115200)</regex>
</constraint>
</properties>
</leafNode>
<leafNode name="data-bits">
<properties>
- <help>Serial port data bits (default: 8)</help>
+ <help>Serial port data bits</help>
<completionHelp>
<list>7 8</list>
</completionHelp>
@@ -53,7 +53,7 @@
</leafNode>
<leafNode name="stop-bits">
<properties>
- <help>Serial port stop bits (default: 1)</help>
+ <help>Serial port stop bits</help>
<completionHelp>
<list>1 2</list>
</completionHelp>
@@ -65,12 +65,12 @@
</leafNode>
<leafNode name="parity">
<properties>
- <help>Parity setting (default: none)</help>
+ <help>Parity setting</help>
<completionHelp>
<list>even odd none</list>
</completionHelp>
<constraint>
- <regex>^(even|odd|none)$</regex>
+ <regex>(even|odd|none)</regex>
</constraint>
</properties>
<defaultValue>none</defaultValue>
diff --git a/interface-definitions/service_ipoe-server.xml.in b/interface-definitions/service_ipoe-server.xml.in
index b19acab56..e222467b1 100644
--- a/interface-definitions/service_ipoe-server.xml.in
+++ b/interface-definitions/service_ipoe-server.xml.in
@@ -23,7 +23,7 @@
<list>L2 L3</list>
</completionHelp>
<constraint>
- <regex>^(L2|L3)$</regex>
+ <regex>(L2|L3)</regex>
</constraint>
<valueHelp>
<format>L2</format>
@@ -42,7 +42,7 @@
<list>shared vlan</list>
</completionHelp>
<constraint>
- <regex>^(shared|vlan)$</regex>
+ <regex>(shared|vlan)</regex>
</constraint>
<valueHelp>
<format>shared</format>
@@ -112,6 +112,22 @@
</children>
</tagNode>
#include <include/name-server-ipv4-ipv6.xml.i>
+ <node name="client-ip-pool">
+ <properties>
+ <help>Client IP pools and gateway setting</help>
+ </properties>
+ <children>
+ <tagNode name="name">
+ <properties>
+ <help>Pool name</help>
+ </properties>
+ <children>
+ #include <include/accel-ppp/gateway-address.xml.i>
+ #include <include/accel-ppp/client-ip-pool-subnet-single.xml.i>
+ </children>
+ </tagNode>
+ </children>
+ </node>
#include <include/accel-ppp/client-ipv6-pool.xml.i>
<node name="authentication">
<properties>
@@ -125,7 +141,7 @@
<list>local radius noauth</list>
</completionHelp>
<constraint>
- <regex>^(local|radius|noauth)$</regex>
+ <regex>(local|radius|noauth)</regex>
</constraint>
<valueHelp>
<format>local</format>
diff --git a/interface-definitions/service_monitoring_telegraf.xml.in b/interface-definitions/service_monitoring_telegraf.xml.in
new file mode 100644
index 000000000..bd528ea33
--- /dev/null
+++ b/interface-definitions/service_monitoring_telegraf.xml.in
@@ -0,0 +1,308 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="service">
+ <children>
+ <node name="monitoring">
+ <properties>
+ <help>Monitoring services</help>
+ <priority>1280</priority>
+ </properties>
+ <children>
+ <node name="telegraf" owner="${vyos_conf_scripts_dir}/service_monitoring_telegraf.py">
+ <properties>
+ <help>Telegraf monitoring</help>
+ </properties>
+ <children>
+ <node name="authentication">
+ <properties>
+ <help>Authentication parameters</help>
+ </properties>
+ <children>
+ <leafNode name="organization">
+ <properties>
+ <help>Authentication organization for InfluxDB v2 [REQUIRED]</help>
+ <constraint>
+ <regex>[a-zA-Z][1-9a-zA-Z@_\-.]{2,50}</regex>
+ </constraint>
+ <constraintErrorMessage>Organization name must be alphanumeric and can contain hyphens, underscores and at symbol.</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ <leafNode name="token">
+ <properties>
+ <help>Authentication token for InfluxDB v2 [REQUIRED]</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Authentication token</description>
+ </valueHelp>
+ <constraint>
+ <regex>[a-zA-Z0-9-_]{86}==</regex>
+ </constraint>
+ <constraintErrorMessage>Token must be 88 characters long and must contain only [a-zA-Z0-9-_] and '==' characters.</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ <node name="azure-data-explorer">
+ <properties>
+ <help>Output plugin Azure Data Explorer</help>
+ </properties>
+ <children>
+ <node name="authentication">
+ <properties>
+ <help>Authentication parameters</help>
+ </properties>
+ <children>
+ <leafNode name="client-id">
+ <properties>
+ <help>Application client id</help>
+ <constraint>
+ <regex>[-_a-zA-Z0-9]+</regex>
+ </constraint>
+ <constraintErrorMessage>Client-id is limited to alphanumerical characters and can contain hyphen and underscores</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ <leafNode name="client-secret">
+ <properties>
+ <help>Application client secret</help>
+ <constraint>
+ <regex>[-_a-zA-Z0-9]+</regex>
+ </constraint>
+ <constraintErrorMessage>Client-secret is limited to alphanumerical characters and can contain hyphen and underscores</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ <leafNode name="tenant-id">
+ <properties>
+ <help>Set tenant id</help>
+ <constraint>
+ <regex>[-_a-zA-Z0-9]+</regex>
+ </constraint>
+ <constraintErrorMessage>Tenant-id is limited to alphanumerical characters and can contain hyphen and underscores</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ <leafNode name="database">
+ <properties>
+ <help>Remote database name [REQUIRED]</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Remote database name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[-_a-zA-Z0-9]+</regex>
+ </constraint>
+ <constraintErrorMessage>Database is limited to alphanumerical characters and can contain hyphen and underscores</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ <leafNode name="group-metrics">
+ <properties>
+ <help>Type of metrics grouping when push to Azure Data Explorer</help>
+ <completionHelp>
+ <list>single-table table-per-metric</list>
+ </completionHelp>
+ <valueHelp>
+ <format>single-table</format>
+ <description>Metrics stores in one table</description>
+ </valueHelp>
+ <valueHelp>
+ <format>table-per-metric</format>
+ <description>One table per gorups of metric by the metric name</description>
+ </valueHelp>
+ <constraint>
+ <regex>(single-table|table-per-metric)</regex>
+ </constraint>
+ </properties>
+ <defaultValue>table-per-metric</defaultValue>
+ </leafNode>
+ <leafNode name="table">
+ <properties>
+ <help>Name of the single table [Only if set group-metrics single-table]</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Table name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[-_a-zA-Z0-9]+</regex>
+ </constraint>
+ <constraintErrorMessage>Table is limited to alphanumerical characters and can contain hyphen and underscores</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ #include <include/monitoring/url.xml.i>
+ </children>
+ </node>
+ <leafNode name="bucket">
+ <properties>
+ <help>Remote bucket</help>
+ </properties>
+ <defaultValue>main</defaultValue>
+ </leafNode>
+ <leafNode name="source">
+ <properties>
+ <help>Source parameters for monitoring</help>
+ <completionHelp>
+ <list>all hardware-utilization logs network system telegraf</list>
+ </completionHelp>
+ <valueHelp>
+ <format>all</format>
+ <description>All parameters</description>
+ </valueHelp>
+ <valueHelp>
+ <format>hardware-utilization</format>
+ <description>Hardware-utilization parameters (CPU, disk, memory)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>logs</format>
+ <description>Logs parameters</description>
+ </valueHelp>
+ <valueHelp>
+ <format>network</format>
+ <description>Network parameters (net, netstat, nftables)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>system</format>
+ <description>System parameters (system, processes, interrupts)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>telegraf</format>
+ <description>Telegraf internal statistics</description>
+ </valueHelp>
+ <constraint>
+ <regex>(all|hardware-utilization|logs|network|system|telegraf)</regex>
+ </constraint>
+ <multi/>
+ </properties>
+ <defaultValue>all</defaultValue>
+ </leafNode>
+ <node name="prometheus-client">
+ <properties>
+ <help>Output plugin Prometheus client</help>
+ </properties>
+ <children>
+ <node name="authentication">
+ <properties>
+ <help>HTTP basic authentication parameters</help>
+ </properties>
+ <children>
+ <leafNode name="username">
+ <properties>
+ <help>Authentication username</help>
+ </properties>
+ </leafNode>
+ <leafNode name="password">
+ <properties>
+ <help>Authentication password</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Authentication password</description>
+ </valueHelp>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ <leafNode name="allow-from">
+ <properties>
+ <help>Networks allowed to query this server</help>
+ <valueHelp>
+ <format>ipv4net</format>
+ <description>IP address and prefix length</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv6net</format>
+ <description>IPv6 address and prefix length</description>
+ </valueHelp>
+ <multi/>
+ <constraint>
+ <validator name="ip-prefix"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="listen-address">
+ <properties>
+ <help>Local IP addresses to listen on</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_local_ips.sh --both</script>
+ </completionHelp>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>IPv4 address to listen for incoming connections</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv6</format>
+ <description>IPv6 address to listen for incoming connections</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv4-address"/>
+ <validator name="ipv6-address"/>
+ <validator name="ipv6-link-local"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="metric-version">
+ <properties>
+ <help>Metric version control mapping from Telegraf to Prometheus format</help>
+ <valueHelp>
+ <format>u32:1-2</format>
+ <description>Metric version (default: 2)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-2"/>
+ </constraint>
+ </properties>
+ <defaultValue>2</defaultValue>
+ </leafNode>
+ #include <include/port-number.xml.i>
+ <leafNode name="port">
+ <defaultValue>9273</defaultValue>
+ </leafNode>
+ </children>
+ </node>
+ <node name="splunk">
+ <properties>
+ <help>Output plugin Splunk</help>
+ </properties>
+ <children>
+ <node name="authentication">
+ <properties>
+ <help>HTTP basic authentication parameters</help>
+ </properties>
+ <children>
+ <leafNode name="token">
+ <properties>
+ <help>Authorization token</help>
+ </properties>
+ </leafNode>
+ <leafNode name="insecure">
+ <properties>
+ <help>Use TLS but skip host validation</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ <leafNode name="url">
+ <properties>
+ <help>Remote URL [REQUIRED]</help>
+ <valueHelp>
+ <format>url</format>
+ <description>Remote URL to Splunk collector</description>
+ </valueHelp>
+ <constraint>
+ <regex>^(http(s?):\/\/.*):(\d*)\/?(.*)</regex>
+ </constraint>
+ <constraintErrorMessage>Incorrect URL format</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ #include <include/monitoring/url.xml.i>
+ #include <include/port-number.xml.i>
+ <leafNode name="port">
+ <defaultValue>8086</defaultValue>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/interface-definitions/service_pppoe-server.xml.in b/interface-definitions/service_pppoe-server.xml.in
index 188aed6c4..50f42849b 100644
--- a/interface-definitions/service_pppoe-server.xml.in
+++ b/interface-definitions/service_pppoe-server.xml.in
@@ -32,7 +32,7 @@
<list>ifname ifname:mac</list>
</completionHelp>
<constraint>
- <regex>^(ifname|ifname:mac)$</regex>
+ <regex>(ifname|ifname:mac)</regex>
</constraint>
<constraintErrorMessage>Invalid Called-Station-Id format</constraintErrorMessage>
<valueHelp>
@@ -70,19 +70,27 @@
<children>
<leafNode name="vlan-id">
<properties>
- <help>VLAN monitor for the automatic creation of vlans (user per vlan)</help>
+ <help>VLAN monitor for the automatic creation of single vlan</help>
+ <valueHelp>
+ <format>u32:1-4094</format>
+ <description>VLAN monitor for the automatic creation of single vlan</description>
+ </valueHelp>
<constraint>
- <validator name="numeric" argument="--range 1-4096"/>
+ <validator name="numeric" argument="--range 1-4094"/>
</constraint>
- <constraintErrorMessage>VLAN ID needs to be between 1 and 4096</constraintErrorMessage>
+ <constraintErrorMessage>VLAN ID needs to be between 1 and 4094</constraintErrorMessage>
<multi/>
</properties>
</leafNode>
<leafNode name="vlan-range">
<properties>
- <help>VLAN monitor for the automatic creation of vlans (user per vlan)</help>
+ <help>VLAN monitor for the automatic creation of vlans range</help>
+ <valueHelp>
+ <format>start-end</format>
+ <description>VLAN monitor range for the automatic creation of vlans (e.g. 1-4094)</description>
+ </valueHelp>
<constraint>
- <regex>(409[0-6]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{0,2})-(409[0-6]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{0,2})</regex>
+ <validator name="range" argument="--min=1 --max=4094"/>
</constraint>
<multi/>
</properties>
@@ -100,7 +108,7 @@
<properties>
<help>Acceptable rate of connections (e.g. 1/min, 60/sec)</help>
<constraint>
- <regex>[0-9]+\/(min|sec)$</regex>
+ <regex>[0-9]+\/(min|sec)</regex>
</constraint>
<constraintErrorMessage>illegal value</constraintErrorMessage>
</properties>
@@ -163,7 +171,7 @@
<properties>
<help>IPv4 (IPCP) negotiation algorithm</help>
<constraint>
- <regex>^(deny|allow|prefer|require)$</regex>
+ <regex>(deny|allow|prefer|require)</regex>
</constraint>
<constraintErrorMessage>invalid value</constraintErrorMessage>
<valueHelp>
@@ -268,7 +276,7 @@
<properties>
<help>control sessions count</help>
<constraint>
- <regex>^(deny|disable|replace)$</regex>
+ <regex>(deny|disable|replace)</regex>
</constraint>
<constraintErrorMessage>Invalid value</constraintErrorMessage>
<valueHelp>
diff --git a/interface-definitions/service_router-advert.xml.in b/interface-definitions/service_router-advert.xml.in
index 0f4009f5c..bb11e9cd0 100644
--- a/interface-definitions/service_router-advert.xml.in
+++ b/interface-definitions/service_router-advert.xml.in
@@ -18,7 +18,7 @@
<children>
<leafNode name="hop-limit">
<properties>
- <help>Set Hop Count field of the IP header for outgoing packets (default: 64)</help>
+ <help>Set Hop Count field of the IP header for outgoing packets</help>
<valueHelp>
<format>u32:0</format>
<description>Unspecified (by this router)</description>
@@ -63,14 +63,14 @@
</valueHelp>
<valueHelp>
<format>medium</format>
- <description>Default router has medium preference (default)</description>
+ <description>Default router has medium preference</description>
</valueHelp>
<valueHelp>
<format>high</format>
<description>Default router has high preference</description>
</valueHelp>
<constraint>
- <regex>^(low|medium|high)$</regex>
+ <regex>(low|medium|high)</regex>
</constraint>
<constraintErrorMessage>Default preference must be low, medium or high</constraintErrorMessage>
</properties>
@@ -108,7 +108,7 @@
<children>
<leafNode name="max">
<properties>
- <help>Maximum interval between unsolicited multicast RAs (default: 600)</help>
+ <help>Maximum interval between unsolicited multicast RAs</help>
<valueHelp>
<format>u32:4-1800</format>
<description>Maximum interval in seconds</description>
@@ -156,7 +156,7 @@
<children>
<leafNode name="valid-lifetime">
<properties>
- <help>Time in seconds that the route will remain valid (default: 1800 seconds)</help>
+ <help>Time in seconds that the route will remain valid</help>
<completionHelp>
<list>infinity</list>
</completionHelp>
@@ -170,7 +170,7 @@
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-4294967295"/>
- <regex>^(infinity)$</regex>
+ <regex>(infinity)</regex>
</constraint>
</properties>
<defaultValue>1800</defaultValue>
@@ -187,14 +187,14 @@
</valueHelp>
<valueHelp>
<format>medium</format>
- <description>Route has medium preference (default)</description>
+ <description>Route has medium preference</description>
</valueHelp>
<valueHelp>
<format>high</format>
<description>Route has high preference</description>
</valueHelp>
<constraint>
- <regex>^(low|medium|high)$</regex>
+ <regex>(low|medium|high)</regex>
</constraint>
<constraintErrorMessage>Route preference must be low, medium or high</constraintErrorMessage>
</properties>
@@ -234,7 +234,7 @@
</leafNode>
<leafNode name="preferred-lifetime">
<properties>
- <help>Time in seconds that the prefix will remain preferred (default 4 hours)</help>
+ <help>Time in seconds that the prefix will remain preferred</help>
<completionHelp>
<list>infinity</list>
</completionHelp>
@@ -248,14 +248,14 @@
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-4294967295"/>
- <regex>^(infinity)$</regex>
+ <regex>(infinity)</regex>
</constraint>
</properties>
<defaultValue>14400</defaultValue>
</leafNode>
<leafNode name="valid-lifetime">
<properties>
- <help>Time in seconds that the prefix will remain valid (default: 30 days)</help>
+ <help>Time in seconds that the prefix will remain valid</help>
<completionHelp>
<list>infinity</list>
</completionHelp>
@@ -269,7 +269,7 @@
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-4294967295"/>
- <regex>^(infinity)$</regex>
+ <regex>(infinity)</regex>
</constraint>
</properties>
<defaultValue>2592000</defaultValue>
diff --git a/interface-definitions/service_upnp.xml.in b/interface-definitions/service_upnp.xml.in
new file mode 100644
index 000000000..a129b7260
--- /dev/null
+++ b/interface-definitions/service_upnp.xml.in
@@ -0,0 +1,224 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="service">
+ <children>
+ <node name="upnp" owner="${vyos_conf_scripts_dir}/service_upnp.py">
+ <properties>
+ <help>Universal Plug and Play (UPnP) service</help>
+ <priority>900</priority>
+ </properties>
+ <children>
+ <leafNode name="friendly-name">
+ <properties>
+ <help>Name of this service</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Friendly name</description>
+ </valueHelp>
+ </properties>
+ </leafNode>
+ <leafNode name="wan-interface">
+ <properties>
+ <help>WAN network interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces.py</script>
+ </completionHelp>
+ <constraint>
+ <validator name="interface-name" />
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="wan-ip">
+ <properties>
+ <help>WAN network IP</help>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>IPv4 address</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv6</format>
+ <description>IPv6 address</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv4-address" />
+ <validator name="ipv6-address" />
+ </constraint>
+ <multi/>
+ </properties>
+ </leafNode>
+ <leafNode name="nat-pmp">
+ <properties>
+ <help>Enable NAT-PMP support</help>
+ <valueless />
+ </properties>
+ </leafNode>
+ <leafNode name="secure-mode">
+ <properties>
+ <help>Enable Secure Mode</help>
+ <valueless />
+ </properties>
+ </leafNode>
+ <leafNode name="presentation-url">
+ <properties>
+ <help>Presentation Url</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Presentation Url</description>
+ </valueHelp>
+ </properties>
+ </leafNode>
+ <node name="pcp-lifetime">
+ <properties>
+ <help>PCP-base lifetime Option</help>
+ </properties>
+ <children>
+ <leafNode name="max">
+ <properties>
+ <help>Max lifetime time</help>
+ <constraint>
+ <validator name="numeric" />
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="min">
+ <properties>
+ <help>Min lifetime time</help>
+ <constraint>
+ <validator name="numeric" />
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ <leafNode name="listen">
+ <properties>
+ <help>Local IP addresses for service to listen on</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_local_ips.sh --both</script>
+ <script>${vyos_completion_dir}/list_interfaces.py</script>
+ </completionHelp>
+ <valueHelp>
+ <format>&lt;interface&gt;</format>
+ <description>Monitor interface address</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>IP address to listen for incoming connections</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv4-prefix</format>
+ <description>IP prefix to listen for incoming connections</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv6</format>
+ <description>IP address to listen for incoming connections</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv6-prefix</format>
+ <description>IP prefix to listen for incoming connections</description>
+ </valueHelp>
+ <multi/>
+ <constraint>
+ <validator name="interface-name" />
+ <validator name="ipv4-address"/>
+ <validator name="ipv4-prefix"/>
+ <validator name="ipv6-address"/>
+ <validator name="ipv6-prefix"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <node name="stun">
+ <properties>
+ <help>Enable STUN probe support (can be used with NAT 1:1 support for WAN interfaces)</help>
+ </properties>
+ <children>
+ <leafNode name="host">
+ <properties>
+ <help>The STUN server address</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>The STUN server host address</description>
+ </valueHelp>
+ <constraint>
+ <validator name="fqdn"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ #include <include/port-number.xml.i>
+ </children>
+ </node>
+ <tagNode name="rule">
+ <properties>
+ <help>UPnP Rule</help>
+ <valueHelp>
+ <format>u32:0-65535</format>
+ <description>Rule number</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-65535"/>
+ </constraint>
+ </properties>
+ <children>
+ #include <include/generic-disable-node.xml.i>
+ <leafNode name="external-port-range">
+ <properties>
+ <help>Port range (REQUIRE)</help>
+ <valueHelp>
+ <format>&lt;port&gt;</format>
+ <description>single port</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;portN&gt;-&lt;portM&gt;</format>
+ <description>Port range (use '-' as delimiter)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="port-range"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="internal-port-range">
+ <properties>
+ <help>Port range (REQUIRE)</help>
+ <valueHelp>
+ <format>&lt;port&gt;</format>
+ <description>single port</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;portN&gt;-&lt;portM&gt;</format>
+ <description>Port range (use '-' as delimiter)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="port-range"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="ip">
+ <properties>
+ <help>The IP to which this rule applies (REQUIRE)</help>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>The IPv4 to which this rule applies</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv4-address" />
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="action">
+ <properties>
+ <help>Actions against the rule (REQUIRE)</help>
+ <completionHelp>
+ <list>allow deny</list>
+ </completionHelp>
+ <constraint>
+ <regex>(allow|deny)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+ </tagNode>
+ </children>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/interface-definitions/service_webproxy.xml.in b/interface-definitions/service_webproxy.xml.in
index d61a95690..9a75bc27d 100644
--- a/interface-definitions/service_webproxy.xml.in
+++ b/interface-definitions/service_webproxy.xml.in
@@ -16,7 +16,7 @@
<description>Domain to use for urls that do not contain a '.'</description>
</valueHelp>
<constraint>
- <regex>^[\.][a-z0-9-][$]?</regex>
+ <regex>[.][A-Za-z0-9][-.A-Za-z0-9]*</regex>
</constraint>
<constraintErrorMessage>Must start append-domain with a '.'</constraintErrorMessage>
</properties>
@@ -28,7 +28,7 @@
<children>
<leafNode name="children">
<properties>
- <help>Number of authentication helper processes (default: 5)</help>
+ <help>Number of authentication helper processes</help>
<valueHelp>
<format>n</format>
<description>Number of authentication helper processes</description>
@@ -41,7 +41,7 @@
</leafNode>
<leafNode name="credentials-ttl">
<properties>
- <help>Authenticated session time to live in minutes (default: 60)</help>
+ <help>Authenticated session time to live in minutes</help>
<valueHelp>
<format>n</format>
<description>Authenticated session timeout</description>
@@ -105,7 +105,7 @@
</leafNode>
<leafNode name="version">
<properties>
- <help>LDAP protocol version (default: 3)</help>
+ <help>LDAP protocol version</help>
<completionHelp>
<list>2 3</list>
</completionHelp>
@@ -136,7 +136,7 @@
<description>Lightweight Directory Access Protocol</description>
</valueHelp>
<constraint>
- <regex>^(ldap)$</regex>
+ <regex>(ldap)</regex>
</constraint>
<constraintErrorMessage>The only supported method currently is LDAP</constraintErrorMessage>
</properties>
@@ -177,7 +177,7 @@
</leafNode>
<leafNode name="http-port">
<properties>
- <help>Default Proxy Port (default: 3128)</help>
+ <help>Default Proxy Port</help>
<valueHelp>
<format>u32:1025-65535</format>
<description>Default port number</description>
@@ -190,7 +190,11 @@
</leafNode>
<leafNode name="icp-port">
<properties>
- <help>Cache peer ICP port (default: disabled)</help>
+ <help>Cache peer ICP port</help>
+ <valueHelp>
+ <format>u32:0</format>
+ <description>Cache peer disabled</description>
+ </valueHelp>
<valueHelp>
<format>u32:1-65535</format>
<description>Cache peer ICP port</description>
@@ -203,7 +207,7 @@
</leafNode>
<leafNode name="options">
<properties>
- <help>Cache peer options (default: "no-query default")</help>
+ <help>Cache peer options</help>
<valueHelp>
<format>txt</format>
<description>Cache peer options</description>
@@ -230,7 +234,7 @@
<description>Peer is a member of a multicast group</description>
</valueHelp>
<constraint>
- <regex>^(parent|sibling|multicast)$</regex>
+ <regex>(parent|sibling|multicast)</regex>
</constraint>
</properties>
<defaultValue>parent</defaultValue>
@@ -239,7 +243,7 @@
</tagNode>
<leafNode name="cache-size">
<properties>
- <help>Disk cache size in MB (default: 100)</help>
+ <help>Disk cache size in MB</help>
<valueHelp>
<format>u32</format>
<description>Disk cache size in MB</description>
@@ -253,7 +257,7 @@
</leafNode>
<leafNode name="default-port">
<properties>
- <help>Default Proxy Port (default: 3128)</help>
+ <help>Default Proxy Port</help>
<valueHelp>
<format>u32:1025-65535</format>
<description>Default port number</description>
@@ -296,7 +300,7 @@
<children>
<leafNode name="port">
<properties>
- <help>Default Proxy Port (default: 3128)</help>
+ <help>Default Proxy Port</help>
<valueHelp>
<format>u32:1025-65535</format>
<description>Default port number</description>
@@ -305,6 +309,7 @@
<validator name="numeric" argument="--range 1025-65535"/>
</constraint>
</properties>
+ <!-- no defaultValue specified as there is default-port -->
</leafNode>
<leafNode name="disable-transparent">
<properties>
@@ -363,7 +368,7 @@
<list>image/gif www/mime application/macbinary application/oda application/octet-stream application/pdf application/postscript application/postscript application/postscript text/rtf application/octet-stream application/octet-stream application/x-tar application/x-csh application/x-dvi application/x-hdf application/x-latex text/plain application/x-netcdf application/x-netcdf application/x-sh application/x-tcl application/x-tex application/x-texinfo application/x-texinfo application/x-troff application/x-troff application/x-troff application/x-troff-man application/x-troff-me application/x-troff-ms application/x-wais-source application/zip application/x-bcpio application/x-cpio application/x-gtar application/x-rpm application/x-shar application/x-sv4cpio application/x-sv4crc application/x-tar application/x-ustar audio/basic audio/basic audio/mpeg audio/mpeg audio/mpeg audio/x-aiff audio/x-aiff audio/x-aiff audio/x-wav image/bmp image/ief image/jpeg image/jpeg image/jpeg image/tiff image/tiff image/x-cmu-raster image/x-portable-anymap image/x-portable-bitmap image/x-portable-graymap image/x-portable-pixmap image/x-rgb image/x-xbitmap image/x-xpixmap image/x-xwindowdump text/html text/html text/css application/x-javascript text/plain text/plain text/plain text/plain text/plain text/plain text/plain text/plain text/plain text/richtext text/tab-separated-values text/x-setext video/mpeg video/mpeg video/mpeg video/quicktime video/quicktime video/x-msvideo video/x-sgi-movie application/mac-compactpro application/mac-binhex40 application/macwriteii application/msword application/msword application/vnd.ms-excel application/vnd.ms-powerpoint application/vnd.lotus-1-2-3 application/vnd.mif application/x-stuffit application/pict application/pict application/x-arj-compressed application/x-lha-compressed application/x-lha-compressed application/x-deflate text/plain application/octet-stream application/octet-stream image/png application/octet-stream application/x-xpinstall application/octet-stream text/plain application/x-director application/x-director application/x-director image/vnd.djvu image/vnd.djvu application/octet-stream application/octet-stream application/andrew-inset x-conference/x-cooltalk model/iges model/iges audio/midi audio/midi audio/midi model/mesh model/mesh video/vnd.mpegurl chemical/x-pdb application/x-chess-pgn audio/x-realaudio audio/x-pn-realaudio audio/x-pn-realaudio text/sgml text/sgml application/x-koan application/x-koan application/x-koan application/x-koan application/smil application/smil application/octet-stream application/x-futuresplash application/x-shockwave-flash application/x-cdlink model/vrml image/vnd.wap.wbmp application/vnd.wap.wbxml application/vnd.wap.wmlc application/vnd.wap.wmlscriptc application/vnd.wap.wmlscript application/xhtml application/xhtml text/xml text/xml chemical/x-xyz text/plain</list>
</completionHelp>
<constraint>
- <regex>^(image/gif|www/mime|application/macbinary|application/oda|application/octet-stream|application/pdf|application/postscript|application/postscript|application/postscript|text/rtf|application/octet-stream|application/octet-stream|application/x-tar|application/x-csh|application/x-dvi|application/x-hdf|application/x-latex|text/plain|application/x-netcdf|application/x-netcdf|application/x-sh|application/x-tcl|application/x-tex|application/x-texinfo|application/x-texinfo|application/x-troff|application/x-troff|application/x-troff|application/x-troff-man|application/x-troff-me|application/x-troff-ms|application/x-wais-source|application/zip|application/x-bcpio|application/x-cpio|application/x-gtar|application/x-rpm|application/x-shar|application/x-sv4cpio|application/x-sv4crc|application/x-tar|application/x-ustar|audio/basic|audio/basic|audio/mpeg|audio/mpeg|audio/mpeg|audio/x-aiff|audio/x-aiff|audio/x-aiff|audio/x-wav|image/bmp|image/ief|image/jpeg|image/jpeg|image/jpeg|image/tiff|image/tiff|image/x-cmu-raster|image/x-portable-anymap|image/x-portable-bitmap|image/x-portable-graymap|image/x-portable-pixmap|image/x-rgb|image/x-xbitmap|image/x-xpixmap|image/x-xwindowdump|text/html|text/html|text/css|application/x-javascript|text/plain|text/plain|text/plain|text/plain|text/plain|text/plain|text/plain|text/plain|text/plain|text/richtext|text/tab-separated-values|text/x-setext|video/mpeg|video/mpeg|video/mpeg|video/quicktime|video/quicktime|video/x-msvideo|video/x-sgi-movie|application/mac-compactpro|application/mac-binhex40|application/macwriteii|application/msword|application/msword|application/vnd.ms-excel|application/vnd.ms-powerpoint|application/vnd.lotus-1-2-3|application/vnd.mif|application/x-stuffit|application/pict|application/pict|application/x-arj-compressed|application/x-lha-compressed|application/x-lha-compressed|application/x-deflate|text/plain|application/octet-stream|application/octet-stream|image/png|application/octet-stream|application/x-xpinstall|application/octet-stream|text/plain|application/x-director|application/x-director|application/x-director|image/vnd.djvu|image/vnd.djvu|application/octet-stream|application/octet-stream|application/andrew-inset|x-conference/x-cooltalk|model/iges|model/iges|audio/midi|audio/midi|audio/midi|model/mesh|model/mesh|video/vnd.mpegurl|chemical/x-pdb|application/x-chess-pgn|audio/x-realaudio|audio/x-pn-realaudio|audio/x-pn-realaudio|text/sgml|text/sgml|application/x-koan|application/x-koan|application/x-koan|application/x-koan|application/smil|application/smil|application/octet-stream|application/x-futuresplash|application/x-shockwave-flash|application/x-cdlink|model/vrml|image/vnd.wap.wbmp|application/vnd.wap.wbxml|application/vnd.wap.wmlc|application/vnd.wap.wmlscriptc|application/vnd.wap.wmlscript|application/xhtml|application/xhtml|text/xml|text/xml|chemical/x-xyz|text/plain)$</regex>
+ <regex>(image/gif|www/mime|application/macbinary|application/oda|application/octet-stream|application/pdf|application/postscript|application/postscript|application/postscript|text/rtf|application/octet-stream|application/octet-stream|application/x-tar|application/x-csh|application/x-dvi|application/x-hdf|application/x-latex|text/plain|application/x-netcdf|application/x-netcdf|application/x-sh|application/x-tcl|application/x-tex|application/x-texinfo|application/x-texinfo|application/x-troff|application/x-troff|application/x-troff|application/x-troff-man|application/x-troff-me|application/x-troff-ms|application/x-wais-source|application/zip|application/x-bcpio|application/x-cpio|application/x-gtar|application/x-rpm|application/x-shar|application/x-sv4cpio|application/x-sv4crc|application/x-tar|application/x-ustar|audio/basic|audio/basic|audio/mpeg|audio/mpeg|audio/mpeg|audio/x-aiff|audio/x-aiff|audio/x-aiff|audio/x-wav|image/bmp|image/ief|image/jpeg|image/jpeg|image/jpeg|image/tiff|image/tiff|image/x-cmu-raster|image/x-portable-anymap|image/x-portable-bitmap|image/x-portable-graymap|image/x-portable-pixmap|image/x-rgb|image/x-xbitmap|image/x-xpixmap|image/x-xwindowdump|text/html|text/html|text/css|application/x-javascript|text/plain|text/plain|text/plain|text/plain|text/plain|text/plain|text/plain|text/plain|text/plain|text/richtext|text/tab-separated-values|text/x-setext|video/mpeg|video/mpeg|video/mpeg|video/quicktime|video/quicktime|video/x-msvideo|video/x-sgi-movie|application/mac-compactpro|application/mac-binhex40|application/macwriteii|application/msword|application/msword|application/vnd.ms-excel|application/vnd.ms-powerpoint|application/vnd.lotus-1-2-3|application/vnd.mif|application/x-stuffit|application/pict|application/pict|application/x-arj-compressed|application/x-lha-compressed|application/x-lha-compressed|application/x-deflate|text/plain|application/octet-stream|application/octet-stream|image/png|application/octet-stream|application/x-xpinstall|application/octet-stream|text/plain|application/x-director|application/x-director|application/x-director|image/vnd.djvu|image/vnd.djvu|application/octet-stream|application/octet-stream|application/andrew-inset|x-conference/x-cooltalk|model/iges|model/iges|audio/midi|audio/midi|audio/midi|model/mesh|model/mesh|video/vnd.mpegurl|chemical/x-pdb|application/x-chess-pgn|audio/x-realaudio|audio/x-pn-realaudio|audio/x-pn-realaudio|text/sgml|text/sgml|application/x-koan|application/x-koan|application/x-koan|application/x-koan|application/smil|application/smil|application/octet-stream|application/x-futuresplash|application/x-shockwave-flash|application/x-cdlink|model/vrml|image/vnd.wap.wbmp|application/vnd.wap.wbxml|application/vnd.wap.wmlc|application/vnd.wap.wmlscriptc|application/vnd.wap.wmlscript|application/xhtml|application/xhtml|text/xml|text/xml|chemical/x-xyz|text/plain)</regex>
</constraint>
<multi/>
</properties>
@@ -399,7 +404,7 @@
<children>
<leafNode name="update-hour">
<properties>
- <help>Hour of day for database update [REQUIRED]</help>
+ <help>Hour of day for database update</help>
<valueHelp>
<format>u32:0-23</format>
<description>Hour for database update</description>
@@ -414,7 +419,7 @@
</node>
<leafNode name="redirect-url">
<properties>
- <help>Redirect URL for filtered websites (default: block.vyos.net)</help>
+ <help>Redirect URL for filtered websites</help>
<valueHelp>
<format>url</format>
<description>URL for redirect</description>
@@ -479,7 +484,7 @@
<description>Name of source group</description>
</valueHelp>
<constraint>
- <regex>^[^0-9]</regex>
+ <regex>[^0-9]</regex>
</constraint>
<constraintErrorMessage>URL-filter source-group cannot start with a number!</constraintErrorMessage>
</properties>
@@ -593,7 +598,7 @@
<description>All days of the week</description>
</valueHelp>
<constraint>
- <regex>^(Sun|Mon|Tue|Wed|Thu|Fri|Sat|weekdays|weekend|all)$</regex>
+ <regex>(Sun|Mon|Tue|Wed|Thu|Fri|Sat|weekdays|weekend|all)</regex>
</constraint>
</properties>
<children>
@@ -606,7 +611,7 @@
</valueHelp>
<constraint>
<!-- time range example: 12:00-13:00 -->
- <regex>^(\d\d:\d\d)-(\d\d:\d\d)$</regex>
+ <regex>(\d\d:\d\d)-(\d\d:\d\d)</regex>
</constraint>
<constraintErrorMessage>Expected time format hh:mm - hh:mm in 24hr time</constraintErrorMessage>
</properties>
diff --git a/interface-definitions/snmp.xml.in b/interface-definitions/snmp.xml.in
index 949536fe7..b4f72589e 100644
--- a/interface-definitions/snmp.xml.in
+++ b/interface-definitions/snmp.xml.in
@@ -13,30 +13,31 @@
<properties>
<help>Community name</help>
<constraint>
- <regex>^[a-zA-Z0-9\-_]{1,100}$</regex>
+ <regex>[a-zA-Z0-9\-_]{1,100}</regex>
</constraint>
<constraintErrorMessage>Community string is limited to alphanumerical characters only with a total lenght of 100</constraintErrorMessage>
</properties>
<children>
<leafNode name="authorization">
<properties>
- <help>Authorization type (default: 'ro')</help>
+ <help>Authorization type</help>
<completionHelp>
<list>ro rw</list>
</completionHelp>
<valueHelp>
<format>ro</format>
- <description>read only</description>
+ <description>Read-Only</description>
</valueHelp>
<valueHelp>
<format>rw</format>
- <description>read write</description>
+ <description>Read-Write</description>
</valueHelp>
<constraint>
- <regex>^(ro|rw)$</regex>
+ <regex>(ro|rw)</regex>
</constraint>
<constraintErrorMessage>Authorization type must be either 'rw' or 'ro'</constraintErrorMessage>
</properties>
+ <defaultValue>ro</defaultValue>
</leafNode>
<leafNode name="client">
<properties>
@@ -71,7 +72,7 @@
<properties>
<help>Contact information</help>
<constraint>
- <regex>^.{1,255}$</regex>
+ <regex>.{1,255}</regex>
</constraint>
<constraintErrorMessage>Contact information is limited to 255 characters or less</constraintErrorMessage>
</properties>
@@ -80,7 +81,7 @@
<properties>
<help>Description information</help>
<constraint>
- <regex>^.{1,255}$</regex>
+ <regex>.{1,255}</regex>
</constraint>
<constraintErrorMessage>Description is limited to 255 characters or less</constraintErrorMessage>
</properties>
@@ -105,18 +106,9 @@
</constraint>
</properties>
<children>
+ #include <include/port-number.xml.i>
<leafNode name="port">
- <properties>
- <help>Port for SNMP service (default: '161')</help>
- <valueHelp>
- <format>u32:1-65535</format>
- <description>Numeric IP port</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-65535"/>
- </constraint>
- <constraintErrorMessage>Port number must be in range 1 to 65535</constraintErrorMessage>
- </properties>
+ <defaultValue>161</defaultValue>
</leafNode>
</children>
</tagNode>
@@ -124,57 +116,34 @@
<properties>
<help>Location information</help>
<constraint>
- <regex>^.{1,255}$</regex>
+ <regex>.{1,255}</regex>
</constraint>
<constraintErrorMessage>Location is limited to 255 characters or less</constraintErrorMessage>
</properties>
</leafNode>
<leafNode name="oid-enable">
<properties>
- <help>Enable specific oids</help>
- <valueHelp>
- <format>txt</format>
- <description>Enable specific oids</description>
- </valueHelp>
- <valueHelp>
- <format>route-table</format>
- <description>Enable route table oids (ipCidrRouteTable inetCidrRouteTable)</description>
- </valueHelp>
+ <help>Enable specific OIDs</help>
<completionHelp>
<list>route-table</list>
</completionHelp>
- <constraint>
- <regex>^(route-table)$</regex>
- </constraint>
- <constraintErrorMessage>Oid must be 'route-table'</constraintErrorMessage>
- </properties>
- </leafNode>
- <leafNode name="protocol">
- <properties>
- <help>Listen protocol for SNMP</help>
- <completionHelp>
- <list>udp tcp</list>
- </completionHelp>
<valueHelp>
- <format>udp</format>
- <description>Listen protocol UDP (default)</description>
- </valueHelp>
- <valueHelp>
- <format>tcp</format>
- <description>Listen protocol TCP</description>
+ <format>route-table</format>
+ <description>Enable routing table OIDs (ipCidrRouteTable inetCidrRouteTable)</description>
</valueHelp>
<constraint>
- <regex>^(udp|tcp)$</regex>
+ <regex>(route-table)</regex>
</constraint>
+ <constraintErrorMessage>OID must be 'route-table'</constraintErrorMessage>
</properties>
- <defaultValue>udp</defaultValue>
</leafNode>
+ #include <include/snmp/protocol.xml.i>
<leafNode name="smux-peer">
<properties>
<help>Register a subtree for SMUX-based processing</help>
<valueHelp>
- <format>oid</format>
- <description>Object Identifier</description>
+ <format>txt</format>
+ <description>SNMP Object Identifier</description>
</valueHelp>
<multi/>
</properties>
@@ -218,18 +187,9 @@
<help>Community used when sending trap information</help>
</properties>
</leafNode>
+ #include <include/port-number.xml.i>
<leafNode name="port">
- <properties>
- <help>Destination port used for trap notification</help>
- <valueHelp>
- <format>u32:1-65535</format>
- <description>Numeric IP port</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-65535"/>
- </constraint>
- <constraintErrorMessage>Port number must be in range 1 to 65535</constraintErrorMessage>
- </properties>
+ <defaultValue>162</defaultValue>
</leafNode>
</children>
</tagNode>
@@ -242,36 +202,18 @@
<properties>
<help>Specifies the EngineID that uniquely identify an agent (e.g. 000000000000000000000002)</help>
<constraint>
- <regex>^([0-9a-f][0-9a-f]){1,18}$</regex>
+ <regex>([0-9a-f][0-9a-f]){1,18}</regex>
</constraint>
<constraintErrorMessage>ID must contain an even number (from 2 to 36) of hex digits</constraintErrorMessage>
</properties>
+ <defaultValue></defaultValue>
</leafNode>
<tagNode name="group">
<properties>
<help>Specifies the group with name groupname</help>
</properties>
<children>
- <leafNode name="mode">
- <properties>
- <help>Define group access permission (default: 'ro')</help>
- <completionHelp>
- <list>ro rw</list>
- </completionHelp>
- <valueHelp>
- <format>ro</format>
- <description>read only</description>
- </valueHelp>
- <valueHelp>
- <format>rw</format>
- <description>read write</description>
- </valueHelp>
- <constraint>
- <regex>^(ro|rw)$</regex>
- </constraint>
- <constraintErrorMessage>Authorization type must be either 'rw' or 'ro'</constraintErrorMessage>
- </properties>
- </leafNode>
+ #include <include/snmp/access-mode.xml.i>
<leafNode name="seclevel">
<properties>
<help>Security levels</help>
@@ -291,9 +233,10 @@
<description>Messages are authenticated and encrypted (authPriv)</description>
</valueHelp>
<constraint>
- <regex>^(noauth|auth|priv)$</regex>
+ <regex>(noauth|auth|priv)</regex>
</constraint>
</properties>
+ <defaultValue>auth</defaultValue>
</leafNode>
<leafNode name="view">
<properties>
@@ -331,7 +274,7 @@
<properties>
<help>Defines the encrypted key for authentication</help>
<constraint>
- <regex>^[0-9a-f]*$</regex>
+ <regex>[0-9a-f]*</regex>
</constraint>
<constraintErrorMessage>Encrypted key must only contain hex digits</constraintErrorMessage>
</properties>
@@ -340,44 +283,17 @@
<properties>
<help>Defines the clear text key for authentication</help>
<constraint>
- <regex>^.{8,}$</regex>
+ <regex>.{8,}</regex>
</constraint>
<constraintErrorMessage>Key must contain 8 or more characters</constraintErrorMessage>
</properties>
</leafNode>
- <leafNode name="type">
- <properties>
- <help>Defines the protocol used for authentication (default: 'md5')</help>
- <completionHelp>
- <list>md5 sha</list>
- </completionHelp>
- <valueHelp>
- <format>md5</format>
- <description>Message Digest 5</description>
- </valueHelp>
- <valueHelp>
- <format>sha</format>
- <description>Secure Hash Algorithm</description>
- </valueHelp>
- <constraint>
- <regex>^(md5|sha)$</regex>
- </constraint>
- </properties>
- </leafNode>
+ #include <include/snmp/authentication-type.xml.i>
</children>
</node>
+ #include <include/port-number.xml.i>
<leafNode name="port">
- <properties>
- <help>Specifies TCP/UDP port of destination SNMP traps/informs (default: '162')</help>
- <valueHelp>
- <format>u32:1-65535</format>
- <description>Numeric IP port</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-65535"/>
- </constraint>
- <constraintErrorMessage>Port number must be in range 1 to 65535</constraintErrorMessage>
- </properties>
+ <defaultValue>162</defaultValue>
</leafNode>
<node name="privacy">
<properties>
@@ -388,7 +304,7 @@
<properties>
<help>Defines the encrypted key for privacy protocol</help>
<constraint>
- <regex>^[0-9a-f]*$</regex>
+ <regex>[0-9a-f]*</regex>
</constraint>
<constraintErrorMessage>Encrypted key must only contain hex digits</constraintErrorMessage>
</properties>
@@ -397,54 +313,18 @@
<properties>
<help>Defines the clear text key for privacy protocol</help>
<constraint>
- <regex>^.{8,}$</regex>
+ <regex>.{8,}</regex>
</constraint>
<constraintErrorMessage>Key must contain 8 or more characters</constraintErrorMessage>
</properties>
</leafNode>
- <leafNode name="type">
- <properties>
- <help>Defines the protocol for privacy (default: 'des')</help>
- <completionHelp>
- <list>des aes</list>
- </completionHelp>
- <valueHelp>
- <format>des</format>
- <description>Data Encryption Standard</description>
- </valueHelp>
- <valueHelp>
- <format>aes</format>
- <description>Advanced Encryption Standard</description>
- </valueHelp>
- <constraint>
- <regex>^(des|aes)$</regex>
- </constraint>
- </properties>
- </leafNode>
+ #include <include/snmp/privacy-type.xml.i>
</children>
</node>
- <leafNode name="protocol">
- <properties>
- <help>Defines protocol for notification between TCP and UDP</help>
- <completionHelp>
- <list>tcp udp</list>
- </completionHelp>
- <valueHelp>
- <format>tcp</format>
- <description>Use Transmission Control Protocol for notifications</description>
- </valueHelp>
- <valueHelp>
- <format>udp</format>
- <description>Use User Datagram Protocol for notifications</description>
- </valueHelp>
- <constraint>
- <regex>^(tcp|udp)$</regex>
- </constraint>
- </properties>
- </leafNode>
+ #include <include/snmp/protocol.xml.i>
<leafNode name="type">
<properties>
- <help>Specifies the type of notification between inform and trap (default: 'inform')</help>
+ <help>Specifies the type of notification between inform and trap</help>
<completionHelp>
<list>inform trap</list>
</completionHelp>
@@ -457,9 +337,10 @@
<description>Use TRAP</description>
</valueHelp>
<constraint>
- <regex>^(inform|trap)$</regex>
+ <regex>(inform|trap)</regex>
</constraint>
</properties>
+ <defaultValue>inform</defaultValue>
</leafNode>
<leafNode name="user">
<properties>
@@ -475,7 +356,7 @@
<properties>
<help>Specifies the user with name username</help>
<constraint>
- <regex>[^\(\)\|\-]+$</regex>
+ <regex>[^\(\)\|\-]+</regex>
</constraint>
<constraintErrorMessage>Illegal characters in name</constraintErrorMessage>
</properties>
@@ -489,7 +370,7 @@
<properties>
<help>Defines the encrypted key for authentication</help>
<constraint>
- <regex>^[0-9a-f]*$</regex>
+ <regex>[0-9a-f]*</regex>
</constraint>
<constraintErrorMessage>Encrypted key must only contain hex digits</constraintErrorMessage>
</properties>
@@ -498,30 +379,12 @@
<properties>
<help>Defines the clear text key for authentication</help>
<constraint>
- <regex>^.{8,}$</regex>
+ <regex>.{8,}</regex>
</constraint>
<constraintErrorMessage>Key must contain 8 or more characters</constraintErrorMessage>
</properties>
</leafNode>
- <leafNode name="type">
- <properties>
- <help>Defines the protocol used for authentication (default: 'md5')</help>
- <completionHelp>
- <list>md5 sha</list>
- </completionHelp>
- <valueHelp>
- <format>md5</format>
- <description>Message Digest 5</description>
- </valueHelp>
- <valueHelp>
- <format>sha</format>
- <description>Secure Hash Algorithm</description>
- </valueHelp>
- <constraint>
- <regex>^(md5|sha)$</regex>
- </constraint>
- </properties>
- </leafNode>
+ #include <include/snmp/authentication-type.xml.i>
</children>
</node>
<leafNode name="group">
@@ -532,26 +395,7 @@
</completionHelp>
</properties>
</leafNode>
- <leafNode name="mode">
- <properties>
- <help>Define users access permission (default: 'ro')</help>
- <completionHelp>
- <list>ro rw</list>
- </completionHelp>
- <valueHelp>
- <format>ro</format>
- <description>read only</description>
- </valueHelp>
- <valueHelp>
- <format>rw</format>
- <description>read write</description>
- </valueHelp>
- <constraint>
- <regex>^(ro|rw)$</regex>
- </constraint>
- <constraintErrorMessage>Authorization type must be either 'rw' or 'ro'</constraintErrorMessage>
- </properties>
- </leafNode>
+ #include <include/snmp/access-mode.xml.i>
<node name="privacy">
<properties>
<help>Defines the privacy</help>
@@ -561,7 +405,7 @@
<properties>
<help>Defines the encrypted key for privacy protocol</help>
<constraint>
- <regex>^[0-9a-f]*$</regex>
+ <regex>[0-9a-f]*</regex>
</constraint>
<constraintErrorMessage>Encrypted key must only contain hex digits</constraintErrorMessage>
</properties>
@@ -570,30 +414,12 @@
<properties>
<help>Defines the clear text key for privacy protocol</help>
<constraint>
- <regex>^.{8,}$</regex>
+ <regex>.{8,}</regex>
</constraint>
<constraintErrorMessage>Key must contain 8 or more characters</constraintErrorMessage>
</properties>
</leafNode>
- <leafNode name="type">
- <properties>
- <help>Defines the protocol for privacy (default: 'des')</help>
- <completionHelp>
- <list>des aes</list>
- </completionHelp>
- <valueHelp>
- <format>des</format>
- <description>Data Encryption Standard</description>
- </valueHelp>
- <valueHelp>
- <format>aes</format>
- <description>Advanced Encryption Standard</description>
- </valueHelp>
- <constraint>
- <regex>^(des|aes)$</regex>
- </constraint>
- </properties>
- </leafNode>
+ #include <include/snmp/privacy-type.xml.i>
</children>
</node>
</children>
@@ -602,7 +428,7 @@
<properties>
<help>Specifies the view with name viewname</help>
<constraint>
- <regex>[^\(\)\|\-]+$</regex>
+ <regex>[^\(\)\|\-]+</regex>
</constraint>
<constraintErrorMessage>Illegal characters in name</constraintErrorMessage>
</properties>
@@ -611,7 +437,7 @@
<properties>
<help>Specifies the oid</help>
<constraint>
- <regex>^[0-9]+(\.[0-9]+)*$</regex>
+ <regex>[0-9]+(\.[0-9]+)*</regex>
</constraint>
<constraintErrorMessage>OID must start from a number</constraintErrorMessage>
</properties>
@@ -625,7 +451,7 @@
<properties>
<help>Defines a bit-mask that is indicating which subidentifiers of the associated subtree OID should be regarded as significant</help>
<constraint>
- <regex>^[0-9a-f]{2}([\.:][0-9a-f]{2})*$</regex>
+ <regex>[0-9a-f]{2}([\.:][0-9a-f]{2})*</regex>
</constraint>
<constraintErrorMessage>MASK is a list of hex octets, separated by '.' or ':'</constraintErrorMessage>
</properties>
@@ -645,7 +471,7 @@
<properties>
<help>Extension name</help>
<constraint>
- <regex>^[a-z0-9\.\-\_]+</regex>
+ <regex>[a-z0-9\.\-\_]+</regex>
</constraint>
<constraintErrorMessage>Script extension contains invalid characters</constraintErrorMessage>
</properties>
@@ -657,7 +483,7 @@
<script>ls /config/user-data</script>
</completionHelp>
<constraint>
- <regex>^[a-z0-9\.\-\_\/]+</regex>
+ <regex>[a-z0-9\.\-\_\/]+</regex>
</constraint>
<constraintErrorMessage>Script extension contains invalid characters</constraintErrorMessage>
</properties>
diff --git a/interface-definitions/ssh.xml.in b/interface-definitions/ssh.xml.in
index e3b9d16e1..126183162 100644
--- a/interface-definitions/ssh.xml.in
+++ b/interface-definitions/ssh.xml.in
@@ -44,7 +44,7 @@
<list>3des-cbc aes128-cbc aes192-cbc aes256-cbc rijndael-cbc@lysator.liu.se aes128-ctr aes192-ctr aes256-ctr aes128-gcm@openssh.com aes256-gcm@openssh.com chacha20-poly1305@openssh.com</list>
</completionHelp>
<constraint>
- <regex>^(3des-cbc|aes128-cbc|aes192-cbc|aes256-cbc|rijndael-cbc@lysator.liu.se|aes128-ctr|aes192-ctr|aes256-ctr|aes128-gcm@openssh.com|aes256-gcm@openssh.com|chacha20-poly1305@openssh.com)$</regex>
+ <regex>(3des-cbc|aes128-cbc|aes192-cbc|aes256-cbc|rijndael-cbc@lysator.liu.se|aes128-ctr|aes192-ctr|aes256-ctr|aes128-gcm@openssh.com|aes256-gcm@openssh.com|chacha20-poly1305@openssh.com)</regex>
</constraint>
<multi/>
</properties>
@@ -61,6 +61,78 @@
<valueless/>
</properties>
</leafNode>
+ <node name="dynamic-protection">
+ <properties>
+ <help>Allow dynamic protection</help>
+ </properties>
+ <children>
+ <leafNode name="block-time">
+ <properties>
+ <help>Block source IP in seconds. Subsequent blocks increase by a factor of 1.5</help>
+ <valueHelp>
+ <format>u32:1-65535</format>
+ <description>Time interval in seconds for blocking</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-65535"/>
+ </constraint>
+ </properties>
+ <defaultValue>120</defaultValue>
+ </leafNode>
+ <leafNode name="detect-time">
+ <properties>
+ <help>Remember source IP in seconds before reset their score</help>
+ <valueHelp>
+ <format>u32:1-65535</format>
+ <description>Time interval in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-65535"/>
+ </constraint>
+ </properties>
+ <defaultValue>1800</defaultValue>
+ </leafNode>
+ <leafNode name="threshold">
+ <properties>
+ <help>Block source IP when their cumulative attack score exceeds threshold</help>
+ <valueHelp>
+ <format>u32:1-65535</format>
+ <description>Threshold score</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-65535"/>
+ </constraint>
+ </properties>
+ <defaultValue>30</defaultValue>
+ </leafNode>
+ <leafNode name="allow-from">
+ <properties>
+ <help>Always allow inbound connections from these systems</help>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>Address to match against</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv4net</format>
+ <description>IPv4 address and prefix length</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv6</format>
+ <description>IPv6 address to match against</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv6net</format>
+ <description>IPv6 address and prefix length</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ip-address"/>
+ <validator name="ip-prefix"/>
+ </constraint>
+ <multi/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
<leafNode name="key-exchange">
<properties>
<help>Allowed key exchange (KEX) algorithms</help>
@@ -70,7 +142,7 @@
</completionHelp>
<multi/>
<constraint>
- <regex>^(diffie-hellman-group1-sha1|diffie-hellman-group14-sha1|diffie-hellman-group14-sha256|diffie-hellman-group16-sha512|diffie-hellman-group18-sha512|diffie-hellman-group-exchange-sha1|diffie-hellman-group-exchange-sha256|ecdh-sha2-nistp256|ecdh-sha2-nistp384|ecdh-sha2-nistp521|curve25519-sha256|curve25519-sha256@libssh.org)$</regex>
+ <regex>(diffie-hellman-group1-sha1|diffie-hellman-group14-sha1|diffie-hellman-group14-sha256|diffie-hellman-group16-sha512|diffie-hellman-group18-sha512|diffie-hellman-group-exchange-sha1|diffie-hellman-group-exchange-sha256|ecdh-sha2-nistp256|ecdh-sha2-nistp384|ecdh-sha2-nistp521|curve25519-sha256|curve25519-sha256@libssh.org)</regex>
</constraint>
</properties>
</leafNode>
@@ -102,10 +174,10 @@
<description>enable logging of failed login attempts</description>
</valueHelp>
<constraint>
- <regex>^(quiet|fatal|error|info|verbose)$</regex>
+ <regex>(quiet|fatal|error|info|verbose)</regex>
</constraint>
</properties>
- <defaultValue>INFO</defaultValue>
+ <defaultValue>info</defaultValue>
</leafNode>
<leafNode name="mac">
<properties>
@@ -115,7 +187,7 @@
<list>hmac-sha1 hmac-sha1-96 hmac-sha2-256 hmac-sha2-512 hmac-md5 hmac-md5-96 umac-64@openssh.com umac-128@openssh.com hmac-sha1-etm@openssh.com hmac-sha1-96-etm@openssh.com hmac-sha2-256-etm@openssh.com hmac-sha2-512-etm@openssh.com hmac-md5-etm@openssh.com hmac-md5-96-etm@openssh.com umac-64-etm@openssh.com umac-128-etm@openssh.com</list>
</completionHelp>
<constraint>
- <regex>^(hmac-sha1|hmac-sha1-96|hmac-sha2-256|hmac-sha2-512|hmac-md5|hmac-md5-96|umac-64@openssh.com|umac-128@openssh.com|hmac-sha1-etm@openssh.com|hmac-sha1-96-etm@openssh.com|hmac-sha2-256-etm@openssh.com|hmac-sha2-512-etm@openssh.com|hmac-md5-etm@openssh.com|hmac-md5-96-etm@openssh.com|umac-64-etm@openssh.com|umac-128-etm@openssh.com)$</regex>
+ <regex>(hmac-sha1|hmac-sha1-96|hmac-sha2-256|hmac-sha2-512|hmac-md5|hmac-md5-96|umac-64@openssh.com|umac-128@openssh.com|hmac-sha1-etm@openssh.com|hmac-sha1-96-etm@openssh.com|hmac-sha2-256-etm@openssh.com|hmac-sha2-512-etm@openssh.com|hmac-md5-etm@openssh.com|hmac-md5-96-etm@openssh.com|umac-64-etm@openssh.com|umac-128-etm@openssh.com)</regex>
</constraint>
<multi/>
</properties>
diff --git a/interface-definitions/system-conntrack.xml.in b/interface-definitions/system-conntrack.xml.in
index daa4177c9..14f12b569 100644
--- a/interface-definitions/system-conntrack.xml.in
+++ b/interface-definitions/system-conntrack.xml.in
@@ -35,6 +35,128 @@
</properties>
<defaultValue>32768</defaultValue>
</leafNode>
+ <node name="ignore">
+ <properties>
+ <help>Customized rules to ignore selective connection tracking</help>
+ </properties>
+ <children>
+ <tagNode name="rule">
+ <properties>
+ <help>Rule number</help>
+ <valueHelp>
+ <format>u32:1-999999</format>
+ <description>Number of conntrack ignore rule</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-999999"/>
+ </constraint>
+ <constraintErrorMessage>Ignore rule number must be between 1 and 999999</constraintErrorMessage>
+ </properties>
+ <children>
+ #include <include/generic-description.xml.i>
+ <node name="destination">
+ <properties>
+ <help>Destination parameters</help>
+ </properties>
+ <children>
+ #include <include/nat-address.xml.i>
+ #include <include/nat-port.xml.i>
+ </children>
+ </node>
+ <leafNode name="inbound-interface">
+ <properties>
+ <help>Interface to ignore connections tracking on</help>
+ <completionHelp>
+ <list>any</list>
+ <script>${vyos_completion_dir}/list_interfaces.py</script>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ #include <include/ip-protocol.xml.i>
+ <leafNode name="protocol">
+ <properties>
+ <help>Protocol to match (protocol name, number, or "all")</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_protocols.sh</script>
+ <list>all tcp_udp</list>
+ </completionHelp>
+ <valueHelp>
+ <format>all</format>
+ <description>All IP protocols</description>
+ </valueHelp>
+ <valueHelp>
+ <format>tcp_udp</format>
+ <description>Both TCP and UDP</description>
+ </valueHelp>
+ <valueHelp>
+ <format>u32:0-255</format>
+ <description>IP protocol number</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;protocol&gt;</format>
+ <description>IP protocol name</description>
+ </valueHelp>
+ <valueHelp>
+ <format>!&lt;protocol&gt;</format>
+ <description>IP protocol name</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ip-protocol"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <node name="source">
+ <properties>
+ <help>Source parameters</help>
+ </properties>
+ <children>
+ #include <include/nat-address.xml.i>
+ #include <include/nat-port.xml.i>
+ </children>
+ </node>
+ </children>
+ </tagNode>
+ </children>
+ </node>
+ <node name="log">
+ <properties>
+ <help>Log connection tracking events per protocol</help>
+ </properties>
+ <children>
+ <node name="icmp">
+ <properties>
+ <help>Log connection tracking events for ICMP</help>
+ </properties>
+ <children>
+ #include <include/conntrack/log-common.xml.i>
+ </children>
+ </node>
+ <node name="other">
+ <properties>
+ <help>Log connection tracking events for all protocols other than TCP, UDP and ICMP</help>
+ </properties>
+ <children>
+ #include <include/conntrack/log-common.xml.i>
+ </children>
+ </node>
+ <node name="tcp">
+ <properties>
+ <help>Log connection tracking events for TCP</help>
+ </properties>
+ <children>
+ #include <include/conntrack/log-common.xml.i>
+ </children>
+ </node>
+ <node name="udp">
+ <properties>
+ <help>Log connection tracking events for UDP</help>
+ </properties>
+ <children>
+ #include <include/conntrack/log-common.xml.i>
+ </children>
+ </node>
+ </children>
+ </node>
<node name="modules">
<properties>
<help>Connection tracking modules</help>
@@ -130,7 +252,7 @@
<description>Do not allow tracking of previously established connections</description>
</valueHelp>
<constraint>
- <regex>^(enable|disable)$</regex>
+ <regex>(enable|disable)</regex>
</constraint>
</properties>
<defaultValue>enable</defaultValue>
@@ -155,176 +277,66 @@
<help>Connection timeout options</help>
</properties>
<children>
- <leafNode name="icmp">
- <properties>
- <help>ICMP timeout in seconds</help>
- <valueHelp>
- <format>u32:1-21474836</format>
- <description>ICMP timeout in seconds</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-21474836"/>
- </constraint>
- </properties>
- <defaultValue>30</defaultValue>
- </leafNode>
- <leafNode name="other">
- <properties>
- <help>Generic connection timeout in seconds</help>
- <valueHelp>
- <format>u32:1-21474836</format>
- <description>Generic connection timeout in seconds</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-21474836"/>
- </constraint>
- </properties>
- <defaultValue>600</defaultValue>
- </leafNode>
- <node name="tcp">
- <properties>
- <help>TCP connection timeout options</help>
- </properties>
- <children>
- <leafNode name="close-wait">
- <properties>
- <help>TCP CLOSE-WAIT timeout in seconds</help>
- <valueHelp>
- <format>u32:1-21474836</format>
- <description>TCP CLOSE-WAIT timeout in seconds</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-21474836"/>
- </constraint>
- </properties>
- <defaultValue>60</defaultValue>
- </leafNode>
- <leafNode name="close">
- <properties>
- <help>TCP CLOSE timeout in seconds</help>
- <valueHelp>
- <format>u32:1-21474836</format>
- <description>TCP CLOSE timeout in seconds</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-21474836"/>
- </constraint>
- </properties>
- <defaultValue>10</defaultValue>
- </leafNode>
- <leafNode name="established">
- <properties>
- <help>TCP ESTABLISHED timeout in seconds</help>
- <valueHelp>
- <format>u32:1-21474836</format>
- <description>TCP ESTABLISHED timeout in seconds</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-21474836"/>
- </constraint>
- </properties>
- <defaultValue>432000</defaultValue>
- </leafNode>
- <leafNode name="fin-wait">
- <properties>
- <help>TCP FIN-WAIT timeout in seconds</help>
- <valueHelp>
- <format>u32:1-21474836</format>
- <description>TCP FIN-WAIT timeout in seconds</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-21474836"/>
- </constraint>
- </properties>
- <defaultValue>120</defaultValue>
- </leafNode>
- <leafNode name="last-ack">
- <properties>
- <help>TCP LAST-ACK timeout in seconds</help>
- <valueHelp>
- <format>u32:1-21474836</format>
- <description>TCP LAST-ACK timeout in seconds</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-21474836"/>
- </constraint>
- </properties>
- <defaultValue>30</defaultValue>
- </leafNode>
- <leafNode name="syn-recv">
- <properties>
- <help>TCP SYN-RECEIVED timeout in seconds</help>
- <valueHelp>
- <format>u32:1-21474836</format>
- <description>TCP SYN-RECEIVED timeout in seconds</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-21474836"/>
- </constraint>
- </properties>
- <defaultValue>60</defaultValue>
- </leafNode>
- <leafNode name="syn-sent">
- <properties>
- <help>TCP SYN-SENT timeout in seconds</help>
- <valueHelp>
- <format>u32:1-21474836</format>
- <description>TCP SYN-SENT timeout in seconds</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-21474836"/>
- </constraint>
- </properties>
- <defaultValue>120</defaultValue>
- </leafNode>
- <leafNode name="time-wait">
- <properties>
- <help>TCP TIME-WAIT timeout in seconds</help>
- <valueHelp>
- <format>u32:1-21474836</format>
- <description>TCP TIME-WAIT timeout in seconds</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-21474836"/>
- </constraint>
- </properties>
- <defaultValue>120</defaultValue>
- </leafNode>
- </children>
- </node>
- <node name="udp">
+ <node name="custom">
<properties>
- <help>UDP timeout options</help>
+ <help>Define custom timeouts per connection</help>
</properties>
<children>
- <leafNode name="other">
+ <tagNode name="rule">
<properties>
- <help>UDP generic timeout in seconds</help>
+ <help>Rule number</help>
<valueHelp>
- <format>u32:1-21474836</format>
- <description>UDP generic timeout in seconds</description>
+ <format>u32:1-999999</format>
+ <description>Number of conntrack rule</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 1-21474836"/>
+ <validator name="numeric" argument="--range 1-999999"/>
</constraint>
+ <constraintErrorMessage>Ignore rule number must be between 1 and 999999</constraintErrorMessage>
</properties>
- <defaultValue>30</defaultValue>
- </leafNode>
- <leafNode name="stream">
- <properties>
- <help>UDP stream timeout in seconds</help>
- <valueHelp>
- <format>u32:1-21474836</format>
- <description>UDP stream timeout in seconds</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-21474836"/>
- </constraint>
- </properties>
- <defaultValue>180</defaultValue>
- </leafNode>
+ <children>
+ #include <include/generic-description.xml.i>
+ <node name="destination">
+ <properties>
+ <help>Destination parameters</help>
+ </properties>
+ <children>
+ #include <include/nat-address.xml.i>
+ #include <include/nat-port.xml.i>
+ </children>
+ </node>
+ <leafNode name="inbound-interface">
+ <properties>
+ <help>Interface to ignore connections tracking on</help>
+ <completionHelp>
+ <list>any</list>
+ <script>${vyos_completion_dir}/list_interfaces.py</script>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ #include <include/ip-protocol.xml.i>
+ <node name="protocol">
+ <properties>
+ <help>Customize protocol specific timers, one protocol configuration per rule</help>
+ </properties>
+ <children>
+ #include <include/conntrack/timeout-common-protocols.xml.i>
+ </children>
+ </node>
+ <node name="source">
+ <properties>
+ <help>Source parameters</help>
+ </properties>
+ <children>
+ #include <include/nat-address.xml.i>
+ #include <include/nat-port.xml.i>
+ </children>
+ </node>
+ </children>
+ </tagNode>
</children>
</node>
+ #include <include/conntrack/timeout-common-protocols.xml.i>
</children>
</node>
</children>
diff --git a/interface-definitions/system-console.xml.in b/interface-definitions/system-console.xml.in
index 2897e5e97..5acd3e90b 100644
--- a/interface-definitions/system-console.xml.in
+++ b/interface-definitions/system-console.xml.in
@@ -28,7 +28,7 @@
<description>Xen console</description>
</valueHelp>
<constraint>
- <regex>^(ttyS[0-9]+|hvc[0-9]+|usb[0-9]+b.*)$</regex>
+ <regex>(ttyS[0-9]+|hvc[0-9]+|usb[0-9]+b.*)</regex>
</constraint>
</properties>
<children>
@@ -71,7 +71,7 @@
<description>115200 bps</description>
</valueHelp>
<constraint>
- <regex>^(1200|2400|4800|9600|19200|38400|57600|115200)$</regex>
+ <regex>(1200|2400|4800|9600|19200|38400|57600|115200)</regex>
</constraint>
</properties>
<defaultValue>115200</defaultValue>
diff --git a/interface-definitions/system-ip.xml.in b/interface-definitions/system-ip.xml.in
index 86fbe5701..21d70694b 100644
--- a/interface-definitions/system-ip.xml.in
+++ b/interface-definitions/system-ip.xml.in
@@ -5,7 +5,8 @@
<node name="ip" owner="${vyos_conf_scripts_dir}/system-ip.py">
<properties>
<help>IPv4 Settings</help>
- <priority>400</priority>
+ <!-- must be before any interface, check /opt/vyatta/sbin/priority.pl -->
+ <priority>290</priority>
</properties>
<children>
<node name="arp">
@@ -13,18 +14,7 @@
<help>Parameters for ARP cache</help>
</properties>
<children>
- <leafNode name="table-size">
- <properties>
- <help>Maximum number of entries to keep in the ARP cache (default: 8192)</help>
- <completionHelp>
- <list>1024 2048 4096 8192 16384 32768</list>
- </completionHelp>
- <constraint>
- <regex>^(1024|2048|4096|8192|16384|32768)$</regex>
- </constraint>
- </properties>
- <defaultValue>8192</defaultValue>
- </leafNode>
+ #include <include/arp-ndp-table-size.xml.i>
</children>
</node>
<leafNode name="disable-forwarding">
diff --git a/interface-definitions/system-ipv6.xml.in b/interface-definitions/system-ipv6.xml.in
index 5ee7adf54..63260d00c 100644
--- a/interface-definitions/system-ipv6.xml.in
+++ b/interface-definitions/system-ipv6.xml.in
@@ -5,6 +5,7 @@
<node name="ipv6" owner="${vyos_conf_scripts_dir}/system-ipv6.py">
<properties>
<help>IPv6 Settings</help>
+ <!-- must be before any interface, check /opt/vyatta/sbin/priority.pl -->
<priority>290</priority>
</properties>
<children>
@@ -14,12 +15,6 @@
<valueless/>
</properties>
</leafNode>
- <leafNode name="disable">
- <properties>
- <help>Disable assignment of IPv6 addresses on all interfaces</help>
- <valueless/>
- </properties>
- </leafNode>
<node name="multipath">
<properties>
<help>IPv6 multipath settings</help>
@@ -35,20 +30,10 @@
</node>
<node name="neighbor">
<properties>
- <help>Parameters for Neighbor cache</help>
+ <help>Parameters for neighbor discovery cache</help>
</properties>
<children>
- <leafNode name="table-size">
- <properties>
- <help>Maximum number of entries to keep in the Neighbor cache</help>
- <completionHelp>
- <list>1024 2048 4096 8192 16384 32768</list>
- </completionHelp>
- <constraint>
- <regex>^(1024|2048|4096|8192|16384|32768)$</regex>
- </constraint>
- </properties>
- </leafNode>
+ #include <include/arp-ndp-table-size.xml.i>
</children>
</node>
<leafNode name="strict-dad">
diff --git a/interface-definitions/system-lcd.xml.in b/interface-definitions/system-lcd.xml.in
index 4c9d5c92e..9b1a15317 100644
--- a/interface-definitions/system-lcd.xml.in
+++ b/interface-definitions/system-lcd.xml.in
@@ -39,7 +39,7 @@
<description>Lanner, Watchguard, Nexcom NSA, Sophos UTM appliances</description>
</valueHelp>
<constraint>
- <regex>^(cfa-533|cfa-631|cfa-633|cfa-635|hd44780|sdec)$</regex>
+ <regex>(cfa-533|cfa-631|cfa-633|cfa-635|hd44780|sdec)</regex>
</constraint>
</properties>
</leafNode>
@@ -59,7 +59,7 @@
<description>TTY device name, USB based</description>
</valueHelp>
<constraint>
- <regex>^(ttyS[0-9]+|usb[0-9]+b.*)$</regex>
+ <regex>(ttyS[0-9]+|usb[0-9]+b.*)</regex>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/system-login-banner.xml.in b/interface-definitions/system-login-banner.xml.in
index c4bb14bd6..bdd0ad96a 100644
--- a/interface-definitions/system-login-banner.xml.in
+++ b/interface-definitions/system-login-banner.xml.in
@@ -15,12 +15,12 @@
<children>
<leafNode name="post-login">
<properties>
- <help>System loging banner post-login</help>
+ <help>A system banner after the user logs in </help>
</properties>
</leafNode>
<leafNode name="pre-login">
<properties>
- <help>System loging banner pre-login</help>
+ <help>A system banner before the user logs in</help>
</properties>
</leafNode>
</children>
diff --git a/interface-definitions/system-login.xml.in b/interface-definitions/system-login.xml.in
index 4bfe82268..24eeee355 100644
--- a/interface-definitions/system-login.xml.in
+++ b/interface-definitions/system-login.xml.in
@@ -12,7 +12,7 @@
<properties>
<help>Local user account information</help>
<constraint>
- <regex>^[-_a-zA-Z0-9.]{1,100}</regex>
+ <regex>[-_a-zA-Z0-9.]{1,100}</regex>
</constraint>
<constraintErrorMessage>Username contains illegal characters or\nexceeds 100 character limitation.</constraintErrorMessage>
</properties>
@@ -27,7 +27,7 @@
<help>Encrypted password</help>
<constraint>
<regex>(\*|\!)</regex>
- <regex>[a-zA-Z0-9\.\/]{13}$</regex>
+ <regex>[a-zA-Z0-9\.\/]{13}</regex>
<regex>\$1\$[a-zA-Z0-9\./]*\$[a-zA-Z0-9\./]{22}</regex>
<regex>\$5\$[a-zA-Z0-9\./]*\$[a-zA-Z0-9\./]{43}</regex>
<regex>\$6\$[a-zA-Z0-9\./]*\$[a-zA-Z0-9\./]{86}</regex>
@@ -90,7 +90,7 @@
<description/>
</valueHelp>
<constraint>
- <regex>^(ssh-dss|ssh-rsa|ecdsa-sha2-nistp256|ecdsa-sha2-nistp384|ecdsa-sha2-nistp521|ssh-ed25519)$</regex>
+ <regex>(ssh-dss|ssh-rsa|ecdsa-sha2-nistp256|ecdsa-sha2-nistp384|ecdsa-sha2-nistp521|ssh-ed25519)</regex>
</constraint>
</properties>
</leafNode>
@@ -102,7 +102,7 @@
<properties>
<help>Full name of the user (use quotes for names with spaces)</help>
<constraint>
- <regex>[^:]*$</regex>
+ <regex>[^:]*</regex>
</constraint>
<constraintErrorMessage>Cannot use ':' in full name</constraintErrorMessage>
</properties>
@@ -124,7 +124,7 @@
<help>Session timeout</help>
<valueHelp>
<format>u32:1-30</format>
- <description>Session timeout in seconds (default: 2)</description>
+ <description>Session timeout in seconds</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-30"/>
@@ -138,7 +138,7 @@
<help>Server priority</help>
<valueHelp>
<format>u32:1-255</format>
- <description>Server priority (default: 255)</description>
+ <description>Server priority</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-255"/>
diff --git a/interface-definitions/system-logs.xml.in b/interface-definitions/system-logs.xml.in
new file mode 100644
index 000000000..1caa7abb6
--- /dev/null
+++ b/interface-definitions/system-logs.xml.in
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interfaceDefinition>
+ <node name="system">
+ <children>
+ <node name="logs" owner="${vyos_conf_scripts_dir}/system-logs.py">
+ <properties>
+ <help>Logging options</help>
+ <priority>9999</priority>
+ </properties>
+ <children>
+ <node name="logrotate">
+ <properties>
+ <help>Logrotate options</help>
+ </properties>
+ <children>
+ <node name="atop">
+ <properties>
+ <help>Atop logs options (system resources usage)</help>
+ </properties>
+ <children>
+ <leafNode name="max-size">
+ <properties>
+ <help>Size of a single log file that triggers rotation</help>
+ <valueHelp>
+ <format>u32:1-1024</format>
+ <description>Size in MB</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-1024" />
+ </constraint>
+ <constraintErrorMessage>The size must be between 1 and 1024 MB</constraintErrorMessage>
+ </properties>
+ <defaultValue>10</defaultValue>
+ </leafNode>
+ <leafNode name="rotate">
+ <properties>
+ <help>Count of rotations before old logs will be deleted</help>
+ <valueHelp>
+ <format>u32:1-100</format>
+ <description>Rotations</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-100" />
+ </constraint>
+ <constraintErrorMessage>The count must be between 1 and 100</constraintErrorMessage>
+ </properties>
+ <defaultValue>10</defaultValue>
+ </leafNode>
+ </children>
+ </node>
+ <node name="messages">
+ <properties>
+ <help>The /var/log/messages file rotation</help>
+ </properties>
+ <children>
+ <leafNode name="max-size">
+ <properties>
+ <help>Size of a single log file that triggers rotation</help>
+ <valueHelp>
+ <format>u32:1-1024</format>
+ <description>Size in MB</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-1024" />
+ </constraint>
+ <constraintErrorMessage>The size must be between 1 and 1024 MB</constraintErrorMessage>
+ </properties>
+ <defaultValue>1</defaultValue>
+ </leafNode>
+ <leafNode name="rotate">
+ <properties>
+ <help>Count of rotations before old logs will be deleted</help>
+ <valueHelp>
+ <format>u32:1-100</format>
+ <description>Rotations</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-100" />
+ </constraint>
+ <constraintErrorMessage>The count must be between 1 and 100</constraintErrorMessage>
+ </properties>
+ <defaultValue>10</defaultValue>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+ </node>
+ </children>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/interface-definitions/system-option.xml.in b/interface-definitions/system-option.xml.in
index 75fa67271..8cd25799b 100644
--- a/interface-definitions/system-option.xml.in
+++ b/interface-definitions/system-option.xml.in
@@ -27,7 +27,7 @@
<description>Poweroff system</description>
</valueHelp>
<constraint>
- <regex>^(ignore|reboot|poweroff)$</regex>
+ <regex>(ignore|reboot|poweroff)</regex>
</constraint>
<constraintErrorMessage>Must be ignore, reboot, or poweroff</constraintErrorMessage>
</properties>
@@ -84,7 +84,7 @@
<description>Tune for low network latency</description>
</valueHelp>
<constraint>
- <regex>^(throughput|latency)$</regex>
+ <regex>(throughput|latency)</regex>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/system-proxy.xml.in b/interface-definitions/system-proxy.xml.in
index ade168522..1c06b347f 100644
--- a/interface-definitions/system-proxy.xml.in
+++ b/interface-definitions/system-proxy.xml.in
@@ -11,7 +11,7 @@
<properties>
<help>Proxy URL</help>
<constraint>
- <regex>http:\/\/[a-z0-9\.]+$</regex>
+ <regex>http:\/\/[a-z0-9\.]+</regex>
</constraint>
</properties>
</leafNode>
@@ -20,7 +20,7 @@
<properties>
<help>Proxy username</help>
<constraint>
- <regex>[a-z0-9-_\.]{1,100}$</regex>
+ <regex>[a-z0-9-_\.]{1,100}</regex>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/system-syslog.xml.in b/interface-definitions/system-syslog.xml.in
index 9280a43c8..480cb1ca6 100644
--- a/interface-definitions/system-syslog.xml.in
+++ b/interface-definitions/system-syslog.xml.in
@@ -28,7 +28,7 @@
<list>auth authpriv cron daemon kern lpr mail mark news protocols security syslog user uucp local0 local1 local2 local3 local4 local5 local6 local7 all</list>
</completionHelp>
<constraint>
- <regex>^(auth|authpriv|cron|daemon|kern|lpr|mail|mark|news|protocols|security|syslog|user|uucp|local0|local1|local2|local3|local4|local5|local6|local7|all)$</regex>
+ <regex>(auth|authpriv|cron|daemon|kern|lpr|mail|mark|news|protocols|security|syslog|user|uucp|local0|local1|local2|local3|local4|local5|local6|local7|all)</regex>
</constraint>
<constraintErrorMessage>Invalid facility type</constraintErrorMessage>
<valueHelp>
@@ -132,7 +132,7 @@
<list>emerg alert crit err warning notice info debug all</list>
</completionHelp>
<constraint>
- <regex>^(emerg|alert|crit|err|warning|notice|info|debug|all)$</regex>
+ <regex>(emerg|alert|crit|err|warning|notice|info|debug|all)</regex>
</constraint>
<constraintErrorMessage>Invalid loglevel</constraintErrorMessage>
<valueHelp>
@@ -203,7 +203,7 @@
<list>auth authpriv cron daemon kern lpr mail mark news protocols security syslog user uucp local0 local1 local2 local3 local4 local5 local6 local7 all</list>
</completionHelp>
<constraint>
- <regex>^(auth|authpriv|cron|daemon|kern|lpr|mail|mark|news|protocols|security|syslog|user|uucp|local0|local1|local2|local3|local4|local5|local6|local7|all)$</regex>
+ <regex>(auth|authpriv|cron|daemon|kern|lpr|mail|mark|news|protocols|security|syslog|user|uucp|local0|local1|local2|local3|local4|local5|local6|local7|all)</regex>
</constraint>
<constraintErrorMessage>Invalid facility type</constraintErrorMessage>
<valueHelp>
@@ -315,7 +315,7 @@
<list>udp tcp</list>
</completionHelp>
<constraint>
- <regex>^(udp|tcp)$</regex>
+ <regex>(udp|tcp)</regex>
</constraint>
<constraintErrorMessage>invalid protocol name</constraintErrorMessage>
</properties>
@@ -327,7 +327,7 @@
<list>emerg alert crit err warning notice info debug all</list>
</completionHelp>
<constraint>
- <regex>^(emerg|alert|crit|err|warning|notice|info|debug|all)$</regex>
+ <regex>(emerg|alert|crit|err|warning|notice|info|debug|all)</regex>
</constraint>
<constraintErrorMessage>Invalid loglevel</constraintErrorMessage>
<valueHelp>
@@ -422,7 +422,7 @@
<list>auth authpriv cron daemon kern lpr mail mark news protocols security syslog user uucp local0 local1 local2 local3 local4 local5 local6 local7 all</list>
</completionHelp>
<constraint>
- <regex>^(auth|authpriv|cron|daemon|kern|lpr|mail|mark|news|protocols|security|syslog|user|uucp|local0|local1|local2|local3|local4|local5|local6|local7|all)$</regex>
+ <regex>(auth|authpriv|cron|daemon|kern|lpr|mail|mark|news|protocols|security|syslog|user|uucp|local0|local1|local2|local3|local4|local5|local6|local7|all)</regex>
</constraint>
<constraintErrorMessage>Invalid facility type</constraintErrorMessage>
<valueHelp>
@@ -526,7 +526,7 @@
<list>emerg alert crit err warning notice info debug all</list>
</completionHelp>
<constraint>
- <regex>^(emerg|alert|crit|err|warning|notice|info|debug|all)$</regex>
+ <regex>(emerg|alert|crit|err|warning|notice|info|debug|all)</regex>
</constraint>
<constraintErrorMessage>Invalid loglevel</constraintErrorMessage>
<valueHelp>
@@ -633,7 +633,7 @@
<list>auth authpriv cron daemon kern lpr mail mark news protocols security syslog user uucp local0 local1 local2 local3 local4 local5 local6 local7 all</list>
</completionHelp>
<constraint>
- <regex>^(auth|authpriv|cron|daemon|kern|lpr|mail|mark|news|protocols|security|syslog|user|uucp|local0|local1|local2|local3|local4|local5|local6|local7|all)$</regex>
+ <regex>(auth|authpriv|cron|daemon|kern|lpr|mail|mark|news|protocols|security|syslog|user|uucp|local0|local1|local2|local3|local4|local5|local6|local7|all)</regex>
</constraint>
<constraintErrorMessage>Invalid facility type</constraintErrorMessage>
<valueHelp>
@@ -737,7 +737,7 @@
<list>emerg alert crit err warning notice info debug all</list>
</completionHelp>
<constraint>
- <regex>^(emerg|alert|crit|err|warning|notice|info|debug|all)$</regex>
+ <regex>(emerg|alert|crit|err|warning|notice|info|debug|all)</regex>
</constraint>
<constraintErrorMessage>Invalid loglevel</constraintErrorMessage>
<valueHelp>
@@ -794,7 +794,7 @@
<list>auth authpriv cron daemon kern lpr mail mark news protocols security syslog user uucp local0 local1 local2 local3 local4 local5 local6 local7 all</list>
</completionHelp>
<constraint>
- <regex>^(auth|authpriv|cron|daemon|kern|lpr|mail|mark|news|protocols|security|syslog|user|uucp|local0|local1|local2|local3|local4|local5|local6|local7|all)$</regex>
+ <regex>(auth|authpriv|cron|daemon|kern|lpr|mail|mark|news|protocols|security|syslog|user|uucp|local0|local1|local2|local3|local4|local5|local6|local7|all)</regex>
</constraint>
<constraintErrorMessage>Invalid facility type</constraintErrorMessage>
<valueHelp>
@@ -898,7 +898,7 @@
<list>emerg alert crit err warning notice info debug all</list>
</completionHelp>
<constraint>
- <regex>^(emerg|alert|crit|err|warning|notice|info|debug|all)$</regex>
+ <regex>(emerg|alert|crit|err|warning|notice|info|debug|all)</regex>
</constraint>
<constraintErrorMessage>Invalid loglevel</constraintErrorMessage>
<valueHelp>
diff --git a/interface-definitions/tftp-server.xml.in b/interface-definitions/tftp-server.xml.in
index 037c097ca..4963eab3c 100644
--- a/interface-definitions/tftp-server.xml.in
+++ b/interface-definitions/tftp-server.xml.in
@@ -24,7 +24,7 @@
<leafNode name="port">
<defaultValue>69</defaultValue>
</leafNode>
- #include <include/listen-address.xml.i>
+ #include <include/listen-address-vrf.xml.i>
</children>
</node>
</children>
diff --git a/interface-definitions/vpn_ipsec.xml.in b/interface-definitions/vpn_ipsec.xml.in
index e82249d44..555ba689f 100644
--- a/interface-definitions/vpn_ipsec.xml.in
+++ b/interface-definitions/vpn_ipsec.xml.in
@@ -13,13 +13,13 @@
<children>
<leafNode name="disable-uniqreqids">
<properties>
- <help>Option to disable requirement for unique IDs in the Security Database</help>
+ <help>Disable requirement for unique IDs in the Security Database</help>
<valueless/>
</properties>
</leafNode>
<tagNode name="esp-group">
<properties>
- <help>Name of Encapsulating Security Payload (ESP) group</help>
+ <help>Encapsulated Security Payload (ESP) group name</help>
</properties>
<children>
<leafNode name="compression">
@@ -30,14 +30,14 @@
</completionHelp>
<valueHelp>
<format>disable</format>
- <description>Disable ESP compression (default)</description>
+ <description>Disable ESP compression</description>
</valueHelp>
<valueHelp>
<format>enable</format>
<description>Enable ESP compression</description>
</valueHelp>
<constraint>
- <regex>^(disable|enable)$</regex>
+ <regex>(disable|enable)</regex>
</constraint>
</properties>
<defaultValue>disable</defaultValue>
@@ -47,7 +47,7 @@
<help>ESP lifetime</help>
<valueHelp>
<format>u32:30-86400</format>
- <description>ESP lifetime in seconds (default 3600)</description>
+ <description>ESP lifetime in seconds</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 30-86400"/>
@@ -55,6 +55,30 @@
</properties>
<defaultValue>3600</defaultValue>
</leafNode>
+ <leafNode name="life-bytes">
+ <properties>
+ <help>ESP life in bytes</help>
+ <valueHelp>
+ <format>u32:1024-26843545600000</format>
+ <description>ESP life in bytes</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1024-26843545600000"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="life-packets">
+ <properties>
+ <help>ESP life in packets</help>
+ <valueHelp>
+ <format>u32:1000-26843545600000</format>
+ <description>ESP life in packets</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1000-26843545600000"/>
+ </constraint>
+ </properties>
+ </leafNode>
<leafNode name="mode">
<properties>
<help>ESP mode</help>
@@ -63,14 +87,14 @@
</completionHelp>
<valueHelp>
<format>tunnel</format>
- <description>Tunnel mode (default)</description>
+ <description>Tunnel mode</description>
</valueHelp>
<valueHelp>
<format>transport</format>
<description>Transport mode</description>
</valueHelp>
<constraint>
- <regex>^(tunnel|transport)$</regex>
+ <regex>(tunnel|transport)</regex>
</constraint>
</properties>
<defaultValue>tunnel</defaultValue>
@@ -83,7 +107,7 @@
</completionHelp>
<valueHelp>
<format>enable</format>
- <description>Inherit Diffie-Hellman group from IKE group - default</description>
+ <description>Inherit Diffie-Hellman group from the IKE group</description>
</valueHelp>
<valueHelp>
<format>dh-group1</format>
@@ -178,17 +202,17 @@
<description>Disable PFS</description>
</valueHelp>
<constraint>
- <regex>^(enable|dh-group1|dh-group2|dh-group5|dh-group14|dh-group15|dh-group16|dh-group17|dh-group18|dh-group19|dh-group20|dh-group21|dh-group22|dh-group23|dh-group24|dh-group25|dh-group26|dh-group27|dh-group28|dh-group29|dh-group30|dh-group31|dh-group32|disable)$</regex>
+ <regex>(enable|dh-group1|dh-group2|dh-group5|dh-group14|dh-group15|dh-group16|dh-group17|dh-group18|dh-group19|dh-group20|dh-group21|dh-group22|dh-group23|dh-group24|dh-group25|dh-group26|dh-group27|dh-group28|dh-group29|dh-group30|dh-group31|dh-group32|disable)</regex>
</constraint>
</properties>
<defaultValue>enable</defaultValue>
</leafNode>
<tagNode name="proposal">
<properties>
- <help>ESP-group proposal [REQUIRED]</help>
+ <help>ESP group proposal [REQUIRED]</help>
<valueHelp>
<format>u32:1-65535</format>
- <description>ESP-group proposal number</description>
+ <description>ESP group proposal number</description>
</valueHelp>
</properties>
<children>
@@ -200,33 +224,29 @@
</tagNode>
<tagNode name="ike-group">
<properties>
- <help>Name of Internet Key Exchange (IKE) group</help>
+ <help>Internet Key Exchange (IKE) group name</help>
</properties>
<children>
<leafNode name="close-action">
<properties>
- <help>close-action_help</help>
+ <help>Action to take if a child SA is unexpectedly closed</help>
<completionHelp>
- <list>none hold clear restart</list>
+ <list>none hold restart</list>
</completionHelp>
<valueHelp>
<format>none</format>
- <description>Set action to none (default)</description>
+ <description>Do nothing</description>
</valueHelp>
<valueHelp>
<format>hold</format>
- <description>Set action to hold</description>
- </valueHelp>
- <valueHelp>
- <format>clear</format>
- <description>Set action to clear</description>
+ <description>Attempt to re-negotiate when matching traffic is seen</description>
</valueHelp>
<valueHelp>
<format>restart</format>
- <description>Set action to restart</description>
+ <description>Attempt to re-negotiate the connection immediately</description>
</valueHelp>
<constraint>
- <regex>^(none|hold|clear|restart)$</regex>
+ <regex>(none|hold|restart)</regex>
</constraint>
</properties>
</leafNode>
@@ -243,18 +263,18 @@
</completionHelp>
<valueHelp>
<format>hold</format>
- <description>Set action to hold (default)</description>
+ <description>Attempt to re-negotiate the connection when matching traffic is seen</description>
</valueHelp>
<valueHelp>
<format>clear</format>
- <description>Set action to clear</description>
+ <description>Remove the connection immediately</description>
</valueHelp>
<valueHelp>
<format>restart</format>
- <description>Set action to restart</description>
+ <description>Attempt to re-negotiate the connection immediately</description>
</valueHelp>
<constraint>
- <regex>^(hold|clear|restart)$</regex>
+ <regex>(hold|clear|restart)</regex>
</constraint>
</properties>
</leafNode>
@@ -263,30 +283,32 @@
<help>Keep-alive interval</help>
<valueHelp>
<format>u32:2-86400</format>
- <description>Keep-alive interval in seconds (default 30)</description>
+ <description>Keep-alive interval in seconds</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 2-86400"/>
</constraint>
</properties>
+ <defaultValue>30</defaultValue>
</leafNode>
<leafNode name="timeout">
<properties>
- <help>Dead-Peer-Detection keep-alive timeout (IKEv1 only)</help>
+ <help>Dead Peer Detection keep-alive timeout (IKEv1 only)</help>
<valueHelp>
<format>u32:2-86400</format>
- <description>Keep-alive timeout in seconds (default 120)</description>
+ <description>Keep-alive timeout in seconds</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 2-86400"/>
</constraint>
</properties>
+ <defaultValue>120</defaultValue>
</leafNode>
</children>
</node>
<leafNode name="ikev2-reauth">
<properties>
- <help>ikev2-reauth_help</help>
+ <help>Re-authentication of the remote peer during an IKE re-key - IKEv2 only</help>
<completionHelp>
<list>yes no</list>
</completionHelp>
@@ -296,29 +318,29 @@
</valueHelp>
<valueHelp>
<format>no</format>
- <description>Disable remote host re-authenticaton during an IKE rekey. (Default)</description>
+ <description>Disable remote host re-authenticaton during an IKE rekey</description>
</valueHelp>
<constraint>
- <regex>^(yes|no)$</regex>
+ <regex>(yes|no)</regex>
</constraint>
</properties>
</leafNode>
<leafNode name="key-exchange">
<properties>
- <help>Key Exchange Version</help>
+ <help>IKE version</help>
<completionHelp>
<list>ikev1 ikev2</list>
</completionHelp>
<valueHelp>
<format>ikev1</format>
- <description>Use IKEv1 for Key Exchange [DEFAULT]</description>
+ <description>Use IKEv1 for key exchange</description>
</valueHelp>
<valueHelp>
<format>ikev2</format>
- <description>Use IKEv2 for Key Exchange</description>
+ <description>Use IKEv2 for key exchange</description>
</valueHelp>
<constraint>
- <regex>^(ikev1|ikev2)$</regex>
+ <regex>(ikev1|ikev2)</regex>
</constraint>
</properties>
</leafNode>
@@ -327,7 +349,7 @@
<help>IKE lifetime</help>
<valueHelp>
<format>u32:30-86400</format>
- <description>IKE lifetime in seconds (default 28800)</description>
+ <description>IKE lifetime in seconds</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 30-86400"/>
@@ -337,48 +359,50 @@
</leafNode>
<leafNode name="mobike">
<properties>
- <help>Enable MOBIKE Support. MOBIKE is only available for IKEv2.</help>
+ <help>Enable MOBIKE Support (IKEv2 only)</help>
<completionHelp>
<list>enable disable</list>
</completionHelp>
<valueHelp>
<format>enable</format>
- <description>Enable MOBIKE (default for IKEv2)</description>
+ <description>Enable MOBIKE</description>
</valueHelp>
<valueHelp>
<format>disable</format>
<description>Disable MOBIKE</description>
</valueHelp>
<constraint>
- <regex>^(enable|disable)$</regex>
+ <regex>(enable|disable)</regex>
</constraint>
</properties>
+ <defaultValue>enable</defaultValue>
</leafNode>
<leafNode name="mode">
<properties>
- <help>IKEv1 Phase 1 Mode Selection</help>
+ <help>IKEv1 phase 1 mode selection</help>
<completionHelp>
<list>main aggressive</list>
</completionHelp>
<valueHelp>
<format>main</format>
- <description>Use Main mode for Key Exchanges in the IKEv1 Protocol (Recommended Default)</description>
+ <description>Use the main mode (recommended)</description>
</valueHelp>
<valueHelp>
<format>aggressive</format>
- <description>Use Aggressive mode for Key Exchanges in the IKEv1 protocol - We do not recommend users to use aggressive mode as it is much more insecure compared to Main mode.</description>
+ <description>Use the aggressive mode (insecure, not recommended)</description>
</valueHelp>
<constraint>
- <regex>^(main|aggressive)$</regex>
+ <regex>(main|aggressive)</regex>
</constraint>
</properties>
+ <defaultValue>main</defaultValue>
</leafNode>
<tagNode name="proposal">
<properties>
- <help>proposal_help</help>
+ <help>IKE proposal</help>
<valueHelp>
<format>u32:1-65535</format>
- <description>IKE-group proposal</description>
+ <description>IKE group proposal</description>
</valueHelp>
</properties>
<children>
@@ -477,7 +501,7 @@
<description>Diffie-Hellman group 32 (curve448)</description>
</valueHelp>
<constraint>
- <regex>^(1|2|5|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32)$</regex>
+ <regex>(1|2|5|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32)</regex>
</constraint>
</properties>
<defaultValue>2</defaultValue>
@@ -490,12 +514,12 @@
</tagNode>
<leafNode name="include-ipsec-conf">
<properties>
- <help>Sets to include an additional configuration directive file for strongSwan. Use an absolute path to specify the included file</help>
+ <help>Absolute path to specify a strongSwan config include file</help>
</properties>
</leafNode>
<leafNode name="include-ipsec-secrets">
<properties>
- <help>Sets to include an additional secrets file for strongSwan. Use an absolute path to specify the included file.</help>
+ <help>Absolute path to a strongSwan secrets include file</help>
</properties>
</leafNode>
#include <include/generic-interface-multi.xml.i>
@@ -506,10 +530,10 @@
<children>
<leafNode name="level">
<properties>
- <help>strongSwan Logger Level</help>
+ <help>strongSwan logging Level</help>
<valueHelp>
<format>0</format>
- <description>Very basic auditing logs e.g. SA up/SA down (default)</description>
+ <description>Very basic auditing logs e.g. SA up/SA down</description>
</valueHelp>
<valueHelp>
<format>1</format>
@@ -527,7 +551,7 @@
</leafNode>
<leafNode name="subsystem">
<properties>
- <help>Subsystem in the daemon the log comes from</help>
+ <help>Subsystem logging levels</help>
<completionHelp>
<list>dmn mgr ike chd job cfg knl net asn enc lib esp tls tnc imc imv pts any</list>
</completionHelp>
@@ -604,7 +628,7 @@
<description>Any subsystem</description>
</valueHelp>
<constraint>
- <regex>^(dmn|mgr|ike|chd|job|cfg|knl|net|asn|enc|lib|esp|tls|tnc|imc|imv|pts|any)$</regex>
+ <regex>(dmn|mgr|ike|chd|job|cfg|knl|net|asn|enc|lib|esp|tls|tnc|imc|imv|pts|any)</regex>
</constraint>
<multi/>
</properties>
@@ -622,11 +646,24 @@
<valueless/>
</properties>
</leafNode>
+ <leafNode name="flexvpn">
+ <properties>
+ <help>Allow FlexVPN vendor ID payload (IKEv2 only)</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ #include <include/generic-interface.xml.i>
+ <leafNode name="virtual-ip">
+ <properties>
+ <help>Allow install virtual-ip addresses</help>
+ <valueless/>
+ </properties>
+ </leafNode>
</children>
</node>
<tagNode name="profile">
<properties>
- <help>VPN IPSec Profile</help>
+ <help>VPN IPSec profile</help>
</properties>
<children>
#include <include/generic-disable-node.xml.i>
@@ -643,7 +680,7 @@
</completionHelp>
<valueHelp>
<format>pre-shared-secret</format>
- <description>Use pre shared secret key</description>
+ <description>Use a pre-shared secret key</description>
</valueHelp>
</properties>
</leafNode>
@@ -657,13 +694,13 @@
<children>
<leafNode name="tunnel">
<properties>
- <help>Tunnel interface associated with this configuration profile</help>
+ <help>Tunnel interface associated with this profile</help>
<completionHelp>
<path>interfaces tunnel</path>
</completionHelp>
<valueHelp>
<format>txt</format>
- <description>Associated interface to this configuration profile</description>
+ <description>Associated interface to this profile</description>
</valueHelp>
<multi/>
</properties>
@@ -699,18 +736,18 @@
</completionHelp>
<valueHelp>
<format>eap-tls</format>
- <description>Client uses EAP-TLS authentication</description>
+ <description>Use EAP-TLS authentication</description>
</valueHelp>
<valueHelp>
<format>eap-mschapv2</format>
- <description>Client uses EAP-MSCHAPv2 authentication</description>
+ <description>Use EAP-MSCHAPv2 authentication</description>
</valueHelp>
<valueHelp>
<format>eap-radius</format>
- <description>Client uses EAP-RADIUS authentication</description>
+ <description>Use EAP-RADIUS authentication</description>
</valueHelp>
<constraint>
- <regex>^(eap-tls|eap-mschapv2|eap-radius)$</regex>
+ <regex>(eap-tls|eap-mschapv2|eap-radius)</regex>
</constraint>
</properties>
<defaultValue>eap-mschapv2</defaultValue>
@@ -724,14 +761,14 @@
</completionHelp>
<valueHelp>
<format>pre-shared-secret</format>
- <description>Authentication pre-shared-secret</description>
+ <description>Use a pre-shared secret key</description>
</valueHelp>
<valueHelp>
<format>x509</format>
- <description>Authentication x509</description>
+ <description>Use x.509 certificate</description>
</valueHelp>
<constraint>
- <regex>^(pre-shared-secret|x509)$</regex>
+ <regex>(pre-shared-secret|x509)</regex>
</constraint>
</properties>
<defaultValue>x509</defaultValue>
@@ -754,7 +791,7 @@
</valueHelp>
<valueHelp>
<format>u32:1-86400</format>
- <description>Timeout in seconds (default 28800)</description>
+ <description>Timeout in seconds</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-86400"/>
@@ -764,14 +801,14 @@
</leafNode>
<leafNode name="pool">
<properties>
- <help>Pool name used for IP address assignments</help>
+ <help>IP address pool</help>
<completionHelp>
<path>vpn ipsec remote-access pool</path>
<list>dhcp radius</list>
</completionHelp>
<valueHelp>
<format>txt</format>
- <description>Name of predefined IP pool</description>
+ <description>Predefined IP pool name</description>
</valueHelp>
<valueHelp>
<format>dhcp</format>
@@ -786,24 +823,24 @@
</leafNode>
<leafNode name="unique">
<properties>
- <help>Connection uniqueness policy to enforce</help>
+ <help>Connection uniqueness enforcement policy</help>
<completionHelp>
<list>never keep replace</list>
</completionHelp>
<valueHelp>
<format>never</format>
- <description>Never enforce connection uniqueness policy</description>
+ <description>Never enforce connection uniqueness</description>
</valueHelp>
<valueHelp>
<format>keep</format>
- <description>Rejects new connection attempts if the same user already has an active connection</description>
+ <description>Reject new connection attempts if the same user already has an active connection</description>
</valueHelp>
<valueHelp>
<format>replace</format>
<description>Delete any existing connection if a new one for the same user gets established</description>
</valueHelp>
<constraint>
- <regex>^(never|keep|replace)$</regex>
+ <regex>(never|keep|replace)</regex>
</constraint>
</properties>
</leafNode>
@@ -811,7 +848,7 @@
</tagNode>
<node name="dhcp">
<properties>
- <help>DHCP pool options for remote-access</help>
+ <help>DHCP pool options for remote access</help>
</properties>
<children>
#include <include/generic-interface.xml.i>
@@ -831,18 +868,18 @@
</node>
<tagNode name="pool">
<properties>
- <help>IP address pool for remote-access users</help>
+ <help>IP address pool for remote access users</help>
</properties>
<children>
<leafNode name="exclude">
<properties>
<help>Local IPv4 or IPv6 pool prefix exclusions</help>
<valueHelp>
- <format>ipv4</format>
+ <format>ipv4net</format>
<description>Local IPv4 pool prefix exclusion</description>
</valueHelp>
<valueHelp>
- <format>ipv6</format>
+ <format>ipv6net</format>
<description>Local IPv6 pool prefix exclusion</description>
</valueHelp>
<constraint>
@@ -856,11 +893,11 @@
<properties>
<help>Local IPv4 or IPv6 pool prefix</help>
<valueHelp>
- <format>ipv4</format>
+ <format>ipv4net</format>
<description>Local IPv4 pool prefix</description>
</valueHelp>
<valueHelp>
- <format>ipv6</format>
+ <format>ipv6net</format>
<description>Local IPv6 pool prefix</description>
</valueHelp>
<constraint>
@@ -936,10 +973,10 @@
</valueHelp>
<valueHelp>
<format>x509</format>
- <description>Use X.509 certificate</description>
+ <description>Use x.509 certificate</description>
</valueHelp>
<constraint>
- <regex>^(pre-shared-secret|rsa|x509)$</regex>
+ <regex>(pre-shared-secret|rsa|x509)</regex>
</constraint>
</properties>
</leafNode>
@@ -965,7 +1002,7 @@
<properties>
<help>Connection type</help>
<completionHelp>
- <list>initiate respond</list>
+ <list>initiate respond none</list>
</completionHelp>
<valueHelp>
<format>initiate</format>
@@ -975,8 +1012,12 @@
<format>respond</format>
<description>Bring the connection up only if traffic is detected</description>
</valueHelp>
+ <valueHelp>
+ <format>none</format>
+ <description>Load the connection only</description>
+ </valueHelp>
<constraint>
- <regex>^(initiate|respond)$</regex>
+ <regex>(initiate|respond|none)</regex>
</constraint>
</properties>
</leafNode>
@@ -992,27 +1033,27 @@
#include <include/dhcp-interface.xml.i>
<leafNode name="force-encapsulation">
<properties>
- <help>Force UDP Encapsulation for ESP Payloads</help>
+ <help>Force UDP Encapsulation for ESP payloads</help>
<completionHelp>
<list>enable disable</list>
</completionHelp>
<valueHelp>
<format>enable</format>
- <description>This endpoint will force UDP encapsulation for this peer</description>
+ <description>Force UDP encapsulation</description>
</valueHelp>
<valueHelp>
<format>disable</format>
- <description>This endpoint will not force UDP encapsulation for this peer</description>
+ <description>Do not force UDP encapsulation</description>
</valueHelp>
<constraint>
- <regex>^(enable|disable)$</regex>
+ <regex>(enable|disable)</regex>
</constraint>
</properties>
</leafNode>
#include <include/ipsec/ike-group.xml.i>
<leafNode name="ikev2-reauth">
<properties>
- <help>Re-authentication of the remote peer during an IKE re-key. IKEv2 option only</help>
+ <help>Re-authentication of the remote peer during an IKE re-key (IKEv2 only)</help>
<completionHelp>
<list>yes no inherit</list>
</completionHelp>
@@ -1026,10 +1067,10 @@
</valueHelp>
<valueHelp>
<format>inherit</format>
- <description>Inherit the reauth configuration form your IKE-group (Default)</description>
+ <description>Inherit the reauth configuration form your IKE-group</description>
</valueHelp>
<constraint>
- <regex>^(yes|no|inherit)$</regex>
+ <regex>(yes|no|inherit)</regex>
</constraint>
</properties>
</leafNode>
@@ -1047,9 +1088,21 @@
#include <include/ipsec/esp-group.xml.i>
#include <include/ipsec/local-traffic-selector.xml.i>
#include <include/ip-protocol.xml.i>
+ <leafNode name="priority">
+ <properties>
+ <help>Priority for IPSec policy (lowest value more preferable)</help>
+ <valueHelp>
+ <format>u32:1-100</format>
+ <description>Priority for IPSec policy (lowest value more preferable)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-100"/>
+ </constraint>
+ </properties>
+ </leafNode>
<node name="remote">
<properties>
- <help>Remote parameters for interesting traffic</help>
+ <help>Match remote addresses</help>
</properties>
<children>
#include <include/port-number.xml.i>
@@ -1057,11 +1110,11 @@
<properties>
<help>Remote IPv4 or IPv6 prefix</help>
<valueHelp>
- <format>ipv4</format>
+ <format>ipv4net</format>
<description>Remote IPv4 prefix</description>
</valueHelp>
<valueHelp>
- <format>ipv6</format>
+ <format>ipv6net</format>
<description>Remote IPv6 prefix</description>
</valueHelp>
<constraint>
@@ -1075,6 +1128,20 @@
</node>
</children>
</tagNode>
+ <leafNode name="virtual-address">
+ <properties>
+ <help>Initiator request virtual-address from peer</help>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>Request IPv4 address from peer</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv6</format>
+ <description>Request IPv6 address from peer</description>
+ </valueHelp>
+ <multi/>
+ </properties>
+ </leafNode>
<node name="vti">
<properties>
<help>Virtual tunnel interface [REQUIRED]</help>
diff --git a/interface-definitions/vpn_l2tp.xml.in b/interface-definitions/vpn_l2tp.xml.in
index 6a88756a7..f734283e7 100644
--- a/interface-definitions/vpn_l2tp.xml.in
+++ b/interface-definitions/vpn_l2tp.xml.in
@@ -72,7 +72,7 @@
<description>Use X.509 certificate for IPsec authentication</description>
</valueHelp>
<constraint>
- <regex>^(pre-shared-secret|x509)$</regex>
+ <regex>(pre-shared-secret|x509)</regex>
</constraint>
<completionHelp>
<list>pre-shared-secret x509</list>
@@ -88,7 +88,7 @@
<help>IKE lifetime</help>
<valueHelp>
<format>u32:30-86400</format>
- <description>IKE lifetime in seconds (default 3600)</description>
+ <description>IKE lifetime in seconds</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 30-86400"/>
@@ -101,7 +101,7 @@
<help>ESP lifetime</help>
<valueHelp>
<format>u32:30-86400</format>
- <description>IKE lifetime in seconds (default 3600)</description>
+ <description>IKE lifetime in seconds</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 30-86400"/>
@@ -135,7 +135,7 @@
<help>PPP idle timeout</help>
<valueHelp>
<format>u32:30-86400</format>
- <description>PPP idle timeout in seconds (default 1800)</description>
+ <description>PPP idle timeout in seconds</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 30-86400"/>
@@ -167,7 +167,7 @@
<description>Require the peer to authenticate itself using MS-CHAPv2 [Microsoft Challenge Handshake Authentication Protocol, Version 2].</description>
</valueHelp>
<constraint>
- <regex>^(pap|chap|mschap|mschap-v2)$</regex>
+ <regex>(pap|chap|mschap|mschap-v2)</regex>
</constraint>
<completionHelp>
<list>pap chap mschap mschap-v2</list>
@@ -206,7 +206,7 @@
</leafNode>
<leafNode name="acct-timeout">
<properties>
- <help>Timeout to wait reply for Interim-Update packets. (default 3 seconds)</help>
+ <help>Timeout to wait reply for Interim-Update packets</help>
</properties>
</leafNode>
<leafNode name="max-try">
@@ -244,7 +244,7 @@
<children>
<leafNode name="attribute">
<properties>
- <help>Specifies which radius attribute contains rate information. (default is Filter-Id)</help>
+ <help>Specifies which radius attribute contains rate information</help>
</properties>
</leafNode>
<leafNode name="vendor">
diff --git a/interface-definitions/vpn_openconnect.xml.in b/interface-definitions/vpn_openconnect.xml.in
index 0db5e79d0..21b47125d 100644
--- a/interface-definitions/vpn_openconnect.xml.in
+++ b/interface-definitions/vpn_openconnect.xml.in
@@ -13,26 +13,120 @@
<help>Authentication for remote access SSL VPN Server</help>
</properties>
<children>
- <leafNode name="mode">
+ <node name="mode">
<properties>
<help>Authentication mode used by this server</help>
- <valueHelp>
- <format>local</format>
- <description>Use local username/password configuration</description>
- </valueHelp>
- <valueHelp>
- <format>radius</format>
- <description>Use RADIUS server for user autentication</description>
- </valueHelp>
- <constraint>
- <regex>^(local|radius)$</regex>
- </constraint>
- <completionHelp>
- <list>local radius</list>
- </completionHelp>
</properties>
- </leafNode>
+ <children>
+ <leafNode name="local">
+ <properties>
+ <help>Use local username/password configuration (OTP supported)</help>
+ <valueHelp>
+ <format>password</format>
+ <description>Password-only local authentication</description>
+ </valueHelp>
+ <valueHelp>
+ <format>otp</format>
+ <description>OTP-only local authentication</description>
+ </valueHelp>
+ <valueHelp>
+ <format>password-otp</format>
+ <description>Password (first) + OTP local authentication</description>
+ </valueHelp>
+ <constraint>
+ <regex>(password|otp|password-otp)</regex>
+ </constraint>
+ <constraintErrorMessage>Invalid authentication mode. Must be one of: password, otp or password-otp </constraintErrorMessage>
+ <completionHelp>
+ <list>otp password password-otp</list>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ <leafNode name="radius">
+ <properties>
+ <help>Use RADIUS server for user autentication</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
#include <include/auth-local-users.xml.i>
+ <node name="local-users">
+ <children>
+ <tagNode name="username">
+ <children>
+ <node name="otp">
+ <properties>
+ <help>2FA OTP authentication parameters</help>
+ </properties>
+ <children>
+ <leafNode name="key">
+ <properties>
+ <help>Token Key Secret key for the token algorithm (see RFC 4226)</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>OTP key in hex-encoded format</description>
+ </valueHelp>
+ <constraint>
+ <regex>[a-fA-F0-9]{20,10000}</regex>
+ </constraint>
+ <constraintErrorMessage>Key name must only include hex characters and be at least 20 characters long</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ <leafNode name="otp-length">
+ <properties>
+ <help>Number of digits in OTP code</help>
+ <valueHelp>
+ <format>u32:6-8</format>
+ <description>Number of digits in OTP code</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 6-8"/>
+ </constraint>
+ <constraintErrorMessage>Number of digits in OTP code must be between 6 and 8</constraintErrorMessage>
+ </properties>
+ <defaultValue>6</defaultValue>
+ </leafNode>
+ <leafNode name="interval">
+ <properties>
+ <help>Time tokens interval in seconds</help>
+ <valueHelp>
+ <format>u32:5-86400</format>
+ <description>Time tokens interval in seconds.</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 5-86400"/>
+ </constraint>
+ <constraintErrorMessage>Time token interval must be between 5 and 86400 seconds</constraintErrorMessage>
+ </properties>
+ <defaultValue>30</defaultValue>
+ </leafNode>
+ <leafNode name="token-type">
+ <properties>
+ <help>Token type</help>
+ <valueHelp>
+ <format>hotp-time</format>
+ <description>Time-based OTP algorithm</description>
+ </valueHelp>
+ <valueHelp>
+ <format>hotp-event</format>
+ <description>Event-based OTP algorithm</description>
+ </valueHelp>
+ <constraint>
+ <regex>(hotp-time|hotp-event)</regex>
+ </constraint>
+ <completionHelp>
+ <list>hotp-time hotp-event</list>
+ </completionHelp>
+ </properties>
+ <defaultValue>hotp-time</defaultValue>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+ </tagNode>
+ </children>
+ </node>
#include <include/radius-server-ipv4.xml.i>
<node name="radius">
<children>
@@ -40,13 +134,13 @@
<properties>
<help>Session timeout</help>
<valueHelp>
- <format>u32:1-30</format>
+ <format>u32:1-240</format>
<description>Session timeout in seconds (default: 2)</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 1-30"/>
+ <validator name="numeric" argument="--range 1-240"/>
</constraint>
- <constraintErrorMessage>Timeout must be between 1 and 30 seconds</constraintErrorMessage>
+ <constraintErrorMessage>Timeout must be between 1 and 240 seconds</constraintErrorMessage>
</properties>
<defaultValue>2</defaultValue>
</leafNode>
@@ -61,10 +155,10 @@
<children>
<leafNode name="tcp">
<properties>
- <help>tcp port number to accept connections (default: 443)</help>
+ <help>tcp port number to accept connections</help>
<valueHelp>
<format>u32:1-65535</format>
- <description>Numeric IP port (default: 443)</description>
+ <description>Numeric IP port</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-65535"/>
@@ -74,10 +168,10 @@
</leafNode>
<leafNode name="udp">
<properties>
- <help>udp port number to accept connections (default: 443)</help>
+ <help>udp port number to accept connections</help>
<valueHelp>
<format>u32:1-65535</format>
- <description>Numeric IP port (default: 443)</description>
+ <description>Numeric IP port</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-65535"/>
@@ -160,7 +254,7 @@
<help>Prefix length used for individual client</help>
<valueHelp>
<format>u32:48-128</format>
- <description>Client prefix length (default: 64)</description>
+ <description>Client prefix length</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 48-128"/>
diff --git a/interface-definitions/vpn_pptp.xml.in b/interface-definitions/vpn_pptp.xml.in
index 0d1690013..28a53acb9 100644
--- a/interface-definitions/vpn_pptp.xml.in
+++ b/interface-definitions/vpn_pptp.xml.in
@@ -75,7 +75,7 @@
<description>ask client for mppe, if it rejects drop connection</description>
</valueHelp>
<constraint>
- <regex>^(deny|prefer|require)$</regex>
+ <regex>(deny|prefer|require)</regex>
</constraint>
<completionHelp>
<list>deny prefer require</list>
diff --git a/interface-definitions/vrf.xml.in b/interface-definitions/vrf.xml.in
index d6a602f53..25a573887 100644
--- a/interface-definitions/vrf.xml.in
+++ b/interface-definitions/vrf.xml.in
@@ -28,6 +28,22 @@
<children>
#include <include/interface/description.xml.i>
#include <include/interface/disable.xml.i>
+ <node name="ip">
+ <properties>
+ <help>IPv4 routing parameters</help>
+ </properties>
+ <children>
+ #include <include/interface/disable-forwarding.xml.i>
+ </children>
+ </node>
+ <node name="ipv6">
+ <properties>
+ <help>IPv6 routing parameters</help>
+ </properties>
+ <children>
+ #include <include/interface/disable-forwarding.xml.i>
+ </children>
+ </node>
<node name="protocols">
<properties>
<help>Routing protocol parameters</help>
@@ -60,6 +76,15 @@
#include <include/ospf/protocol-common-config.xml.i>
</children>
</node>
+ <node name="ospfv3" owner="${vyos_conf_scripts_dir}/protocols_ospfv3.py $VAR(../../@)">
+ <properties>
+ <help>Open Shortest Path First (OSPF) for IPv6</help>
+ <priority>621</priority>
+ </properties>
+ <children>
+ #include <include/ospfv3/protocol-common-config.xml.i>
+ </children>
+ </node>
<node name="static" owner="${vyos_conf_scripts_dir}/protocols_static.py $VAR(../../@)">
<properties>
<help>Static route parameters</help>
diff --git a/interface-definitions/xml-component-version.xml.in b/interface-definitions/xml-component-version.xml.in
new file mode 100644
index 000000000..b7f063a6c
--- /dev/null
+++ b/interface-definitions/xml-component-version.xml.in
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ #include <include/version/bgp-version.xml.i>
+ #include <include/version/broadcast-relay-version.xml.i>
+ #include <include/version/cluster-version.xml.i>
+ #include <include/version/config-management-version.xml.i>
+ #include <include/version/conntrack-sync-version.xml.i>
+ #include <include/version/conntrack-version.xml.i>
+ #include <include/version/dhcp-relay-version.xml.i>
+ #include <include/version/dhcp-server-version.xml.i>
+ #include <include/version/dhcpv6-server-version.xml.i>
+ #include <include/version/dns-forwarding-version.xml.i>
+ #include <include/version/firewall-version.xml.i>
+ #include <include/version/flow-accounting-version.xml.i>
+ #include <include/version/https-version.xml.i>
+ #include <include/version/interfaces-version.xml.i>
+ #include <include/version/ipoe-server-version.xml.i>
+ #include <include/version/ipsec-version.xml.i>
+ #include <include/version/isis-version.xml.i>
+ #include <include/version/l2tp-version.xml.i>
+ #include <include/version/lldp-version.xml.i>
+ #include <include/version/mdns-version.xml.i>
+ #include <include/version/nat66-version.xml.i>
+ #include <include/version/nat-version.xml.i>
+ #include <include/version/ntp-version.xml.i>
+ #include <include/version/openconnect-version.xml.i>
+ #include <include/version/ospf-version.xml.i>
+ #include <include/version/policy-version.xml.i>
+ #include <include/version/pppoe-server-version.xml.i>
+ #include <include/version/pptp-version.xml.i>
+ #include <include/version/qos-version.xml.i>
+ #include <include/version/quagga-version.xml.i>
+ #include <include/version/rpki-version.xml.i>
+ #include <include/version/salt-version.xml.i>
+ #include <include/version/snmp-version.xml.i>
+ #include <include/version/ssh-version.xml.i>
+ #include <include/version/sstp-version.xml.i>
+ #include <include/version/system-version.xml.i>
+ #include <include/version/vrf-version.xml.i>
+ #include <include/version/vrrp-version.xml.i>
+ #include <include/version/vyos-accel-ppp-version.xml.i>
+ #include <include/version/wanloadbalance-version.xml.i>
+ #include <include/version/webproxy-version.xml.i>
+</interfaceDefinition>
diff --git a/interface-definitions/zone-policy.xml.in b/interface-definitions/zone-policy.xml.in
new file mode 100644
index 000000000..8af0dcfb6
--- /dev/null
+++ b/interface-definitions/zone-policy.xml.in
@@ -0,0 +1,147 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="zone-policy" owner="${vyos_conf_scripts_dir}/zone_policy.py">
+ <properties>
+ <help>Configure zone-policy</help>
+ <priority>250</priority>
+ </properties>
+ <children>
+ <tagNode name="zone">
+ <properties>
+ <help>Zone name</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Zone name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[a-zA-Z0-9][\w\-\.]*</regex>
+ </constraint>
+ </properties>
+ <children>
+ #include <include/generic-description.xml.i>
+ <leafNode name="default-action">
+ <properties>
+ <help>Default-action for traffic coming into this zone</help>
+ <completionHelp>
+ <list>drop reject</list>
+ </completionHelp>
+ <valueHelp>
+ <format>drop</format>
+ <description>Drop silently</description>
+ </valueHelp>
+ <valueHelp>
+ <format>reject</format>
+ <description>Drop and notify source</description>
+ </valueHelp>
+ <constraint>
+ <regex>(drop|reject)</regex>
+ </constraint>
+ </properties>
+ <defaultValue>drop</defaultValue>
+ </leafNode>
+ <tagNode name="from">
+ <properties>
+ <help>Zone from which to filter traffic</help>
+ <completionHelp>
+ <path>zone-policy zone</path>
+ </completionHelp>
+ </properties>
+ <children>
+ <node name="firewall">
+ <properties>
+ <help>Firewall options</help>
+ </properties>
+ <children>
+ <leafNode name="ipv6-name">
+ <properties>
+ <help>IPv6 firewall ruleset</help>
+ <completionHelp>
+ <path>firewall ipv6-name</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ <leafNode name="name">
+ <properties>
+ <help>IPv4 firewall ruleset</help>
+ <completionHelp>
+ <path>firewall name</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+ </tagNode>
+ <leafNode name="interface">
+ <properties>
+ <help>Interface associated with zone</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Interface associated with zone</description>
+ </valueHelp>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces.py</script>
+ </completionHelp>
+ <multi/>
+ </properties>
+ </leafNode>
+ <node name="intra-zone-filtering">
+ <properties>
+ <help>Intra-zone filtering</help>
+ </properties>
+ <children>
+ <leafNode name="action">
+ <properties>
+ <help>Action for intra-zone traffic</help>
+ <completionHelp>
+ <list>accept drop</list>
+ </completionHelp>
+ <valueHelp>
+ <format>accept</format>
+ <description>Accept traffic</description>
+ </valueHelp>
+ <valueHelp>
+ <format>drop</format>
+ <description>Drop silently</description>
+ </valueHelp>
+ <constraint>
+ <regex>(accept|drop)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ <node name="firewall">
+ <properties>
+ <help>Use the specified firewall chain</help>
+ </properties>
+ <children>
+ <leafNode name="ipv6-name">
+ <properties>
+ <help>IPv6 firewall ruleset</help>
+ <completionHelp>
+ <path>firewall ipv6-name</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ <leafNode name="name">
+ <properties>
+ <help>IPv4 firewall ruleset</help>
+ <completionHelp>
+ <path>firewall name</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+ </node>
+ <leafNode name="local-zone">
+ <properties>
+ <help>Zone to be local-zone</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ </children>
+ </tagNode>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/op-mode-definitions/conntrack-sync.xml.in b/op-mode-definitions/conntrack-sync.xml.in
index 41a71b04a..3e29ecd39 100644
--- a/op-mode-definitions/conntrack-sync.xml.in
+++ b/op-mode-definitions/conntrack-sync.xml.in
@@ -87,6 +87,18 @@
</node>
</children>
</node>
+ <leafNode name="statistics">
+ <properties>
+ <help>Show connection syncing statistics</help>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/conntrack_sync.py --show-statistics</command>
+ </leafNode>
+ <leafNode name="status">
+ <properties>
+ <help>Show conntrack-sync status</help>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/conntrack_sync.py --show-status</command>
+ </leafNode>
</children>
</node>
</children>
diff --git a/op-mode-definitions/containers.xml.in b/op-mode-definitions/container.xml.in
index b2b318786..fa66402dc 100644
--- a/op-mode-definitions/containers.xml.in
+++ b/op-mode-definitions/container.xml.in
@@ -11,7 +11,7 @@
<properties>
<help>Pull a new image for container</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/containers_op.py --pull "${4}"</command>
+ <command>sudo podman image pull "${4}"</command>
</tagNode>
</children>
</node>
@@ -44,7 +44,51 @@
<script>sudo podman image ls -q</script>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/containers_op.py --remove "${4}"</command>
+ <command>sudo podman image rm --force "${4}"</command>
+ </tagNode>
+ </children>
+ </node>
+ </children>
+ </node>
+ <node name="generate">
+ <children>
+ <node name="container">
+ <properties>
+ <help>Generate Container Image</help>
+ </properties>
+ <children>
+ <tagNode name="image">
+ <properties>
+ <help>Name of container image (tag)</help>
+ </properties>
+ <children>
+ <tagNode name="path">
+ <properties>
+ <help>Path to Dockerfile</help>
+ <completionHelp>
+ <list>&lt;filename&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>sudo podman build --layers --force-rm --tag "$4" $6</command>
+ </tagNode>
+ </children>
+ </tagNode>
+ </children>
+ </node>
+ </children>
+ </node>
+ <node name="monitor">
+ <children>
+ <node name="log">
+ <children>
+ <tagNode name="container">
+ <properties>
+ <help>Monitor last lines of container logs</help>
+ <completionHelp>
+ <path>container name</path>
+ </completionHelp>
+ </properties>
+ <command>sudo podman logs --follow --names "$4"</command>
</tagNode>
</children>
</node>
@@ -56,13 +100,13 @@
<properties>
<help>Show containers</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/containers_op.py --all</command>
+ <command>sudo podman ps --all</command>
<children>
<leafNode name="image">
<properties>
- <help>Delete container image</help>
+ <help>Show container image</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/containers_op.py --image</command>
+ <command>sudo podman image ls</command>
</leafNode>
<tagNode name="log">
<properties>
@@ -77,7 +121,7 @@
<properties>
<help>Show available container networks</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/containers_op.py --networks</command>
+ <command>sudo podman network ls</command>
</leafNode>
</children>
</node>
@@ -118,12 +162,12 @@
<children>
<tagNode name="image">
<properties>
- <help>Delete container image</help>
+ <help>Update container image</help>
<completionHelp>
<path>container name</path>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/containers_op.py --update "${4}"</command>
+ <command>if cli-shell-api existsActive container name "$4"; then sudo podman pull $(cli-shell-api returnActiveValue container name "$4" image); else echo "Container $4 does not exist"; fi</command>
</tagNode>
</children>
</node>
diff --git a/op-mode-definitions/disks.xml.in b/op-mode-definitions/disks.xml.in
index 2102a2e8e..117ac5065 100644
--- a/op-mode-definitions/disks.xml.in
+++ b/op-mode-definitions/disks.xml.in
@@ -20,7 +20,7 @@
<script>${vyos_completion_dir}/list_disks.py --exclude ${COMP_WORDS[2]}</script>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/format_disk.py --target $3 --proto $5</command>
+ <command>sudo ${vyos_op_scripts_dir}/format_disk.py --target $3 --proto $5</command>
</tagNode>
</children>
</tagNode>
diff --git a/op-mode-definitions/firewall.xml.in b/op-mode-definitions/firewall.xml.in
new file mode 100644
index 000000000..b5dee7c9e
--- /dev/null
+++ b/op-mode-definitions/firewall.xml.in
@@ -0,0 +1,191 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+<!--
+ <node name="clear">
+ <children>
+ <node name="firewall">
+ <properties>
+ <help>Clear firewall statistics</help>
+ </properties>
+ <children>
+ <tagNode name="ipv6-name">
+ <properties>
+ <help>Clear firewall statistics for chain</help>
+ <completionHelp>
+ <path>firewall ipv6-name</path>
+ </completionHelp>
+ </properties>
+ <children>
+ <leafNode name="counters">
+ <properties>
+ <help>Clear counters for specified chain</help>
+ </properties>
+ <command>echo "TODO"</command>
+ </leafNode>
+ <tagNode name="rule">
+ <properties>
+ <help>Clear firewall statistics for a rule</help>
+ <completionHelp>
+ <path>firewall ipv6-name ${COMP_WORDS[4]} rule</path>
+ </completionHelp>
+ </properties>
+ <children>
+ <leafNode name="counters">
+ <properties>
+ <help>Clear counters for specified rule</help>
+ </properties>
+ <command>echo "TODO"</command>
+ </leafNode>
+ </children>
+ </tagNode>
+ </children>
+ </tagNode>
+ <tagNode name="name">
+ <properties>
+ <help>Clear firewall statistics for chain</help>
+ <completionHelp>
+ <path>firewall name</path>
+ </completionHelp>
+ </properties>
+ <children>
+ <leafNode name="counters">
+ <properties>
+ <help>Clear counters for specified chain</help>
+ </properties>
+ <command>echo "TODO"</command>
+ </leafNode>
+ <tagNode name="rule">
+ <properties>
+ <help>Clear firewall statistics for a rule</help>
+ <completionHelp>
+ <path>firewall name ${COMP_WORDS[4]} rule</path>
+ </completionHelp>
+ </properties>
+ <children>
+ <leafNode name="counters">
+ <properties>
+ <help>Clear counters for specified rule</help>
+ </properties>
+ <command>echo "TODO"</command>
+ </leafNode>
+ </children>
+ </tagNode>
+ </children>
+ </tagNode>
+ </children>
+ </node>
+ </children>
+ </node>
+-->
+<!--
+ <node name="reset">
+ <children>
+ <node name="firewall">
+ <properties>
+ <help>Reset a firewall group</help>
+ </properties>
+ <children>
+ <tagNode name="address-group">
+ <properties>
+ <help>Reset a firewall address group</help>
+ </properties>
+ </tagNode>
+ <tagNode name="network-group">
+ <properties>
+ <help>Reset a firewall network group</help>
+ </properties>
+ </tagNode>
+ <tagNode name="port-group">
+ <properties>
+ <help>Reset a firewall port group</help>
+ </properties>
+ </tagNode>
+ </children>
+ </node>
+ </children>
+ </node>
+-->
+ <node name="show">
+ <children>
+ <node name="firewall">
+ <properties>
+ <help>Show firewall information</help>
+ </properties>
+ <children>
+ <tagNode name="group">
+ <properties>
+ <help>Show firewall group</help>
+ <completionHelp>
+ <path>firewall group address-group</path>
+ <path>firewall group network-group</path>
+ <path>firewall group port-group</path>
+ <path>firewall group ipv6-address-group</path>
+ <path>firewall group ipv6-network-group</path>
+ </completionHelp>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show_group --name $4</command>
+ </tagNode>
+ <leafNode name="group">
+ <properties>
+ <help>Show firewall group</help>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show_group</command>
+ </leafNode>
+ <tagNode name="ipv6-name">
+ <properties>
+ <help>Show IPv6 firewall chains</help>
+ <completionHelp>
+ <path>firewall ipv6-name</path>
+ </completionHelp>
+ </properties>
+ <children>
+ <tagNode name="rule">
+ <properties>
+ <help>Show summary of IPv6 firewall rules</help>
+ <completionHelp>
+ <path>firewall ipv6-name ${COMP_WORDS[6]} rule</path>
+ </completionHelp>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --name $4 --rule $6 --ipv6</command>
+ </tagNode>
+ </children>
+ <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --name $4 --ipv6</command>
+ </tagNode>
+ <tagNode name="name">
+ <properties>
+ <help>Show IPv4 firewall chains</help>
+ <completionHelp>
+ <path>firewall name</path>
+ </completionHelp>
+ </properties>
+ <children>
+ <tagNode name="rule">
+ <properties>
+ <help>Show summary of IPv4 firewall rules</help>
+ <completionHelp>
+ <path>firewall name ${COMP_WORDS[6]} rule</path>
+ </completionHelp>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --name $4 --rule $6</command>
+ </tagNode>
+ </children>
+ <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show --name $4</command>
+ </tagNode>
+ <leafNode name="statistics">
+ <properties>
+ <help>Show statistics of firewall application</help>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show_statistics</command>
+ </leafNode>
+ <leafNode name="summary">
+ <properties>
+ <help>Show summary of firewall application</help>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show_summary</command>
+ </leafNode>
+ </children>
+ <command>sudo ${vyos_op_scripts_dir}/firewall.py --action show_all</command>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/op-mode-definitions/generate-openconnect-user-key.xml.in b/op-mode-definitions/generate-openconnect-user-key.xml.in
new file mode 100644
index 000000000..80cdfb3d7
--- /dev/null
+++ b/op-mode-definitions/generate-openconnect-user-key.xml.in
@@ -0,0 +1,67 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="generate">
+ <children>
+ <node name="openconnect">
+ <properties>
+ <help>Generate OpenConnect client parameters</help>
+ </properties>
+ <children>
+ <tagNode name="username">
+ <properties>
+ <help>Username used for authentication</help>
+ <completionHelp>
+ <list>&lt;username&gt;</list>
+ </completionHelp>
+ </properties>
+ <children>
+ <node name="otp-key">
+ <properties>
+ <help>Generate OpenConnect OTP token</help>
+ </properties>
+ <children>
+ <node name="hotp-time">
+ <properties>
+ <help>HOTP time-based token</help>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/generate_openconnect_otp_key.py --username "$4" --interval 30 --digits 6</command>
+ <children>
+ <tagNode name="interval">
+ <properties>
+ <help>Duration of single time interval</help>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/generate_openconnect_otp_key.py --username "$4" --interval "$8" --digits 6</command>
+ <children>
+ <tagNode name="digits">
+ <properties>
+ <help>The number of digits in the one-time password</help>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/generate_openconnect_otp_key.py --username "$4" --interval "$8" --digits "${10}"</command>
+ </tagNode>
+ </children>
+ </tagNode>
+ <tagNode name="digits">
+ <properties>
+ <help>The number of digits in the one-time password</help>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/generate_openconnect_otp_key.py --username "$4" --interval 30 --digits "$8"</command>
+ <children>
+ <tagNode name="interval">
+ <properties>
+ <help>Duration of single time interval</help>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/generate_openconnect_otp_key.py --username "$4" --interval "${10}" --digits $8</command>
+ </tagNode>
+ </children>
+ </tagNode>
+ </children>
+ </node>
+ </children>
+ </node>
+ </children>
+ </tagNode>
+ </children>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/op-mode-definitions/generate-openvpn-config-client.xml.in b/op-mode-definitions/generate-openvpn-config-client.xml.in
new file mode 100644
index 000000000..4f9f31bfe
--- /dev/null
+++ b/op-mode-definitions/generate-openvpn-config-client.xml.in
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="generate">
+ <children>
+ <node name="openvpn">
+ <properties>
+ <help>Generate OpenVPN client configuration ovpn file</help>
+ </properties>
+ <children>
+ <node name="client-config">
+ <properties>
+ <help>Generate Client config</help>
+ </properties>
+ <children>
+ <tagNode name="interface">
+ <properties>
+ <help>Local interface used for connection</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces.py --type openvpn</script>
+ </completionHelp>
+ </properties>
+ <children>
+ <tagNode name="ca">
+ <properties>
+ <help>CA certificate</help>
+ <completionHelp>
+ <path>pki ca</path>
+ </completionHelp>
+ </properties>
+ <children>
+ <tagNode name="certificate">
+ <properties>
+ <help>Cerificate used by client</help>
+ <completionHelp>
+ <path>pki certificate</path>
+ </completionHelp>
+ </properties>
+ <children>
+ <tagNode name="key">
+ <properties>
+ <help>Certificate key used by client</help>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/generate_ovpn_client_file.py --interface "$5" --ca "$7" --cert "$9" --key "${11}"</command>
+ </tagNode>
+ </children>
+ <command>sudo ${vyos_op_scripts_dir}/generate_ovpn_client_file.py --interface "$5" --ca "$7" --cert "$9"</command>
+ </tagNode>
+ </children>
+ </tagNode>
+ </children>
+ </tagNode>
+ </children>
+ </node>
+ </children>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/op-mode-definitions/include/bgp/afi-common.xml.i b/op-mode-definitions/include/bgp/afi-common.xml.i
index 4d5f56656..acf20d950 100644
--- a/op-mode-definitions/include/bgp/afi-common.xml.i
+++ b/op-mode-definitions/include/bgp/afi-common.xml.i
@@ -61,5 +61,4 @@
</leafNode>
</children>
</node>
-#include <include/vtysh-generic-wide.xml.i>
<!-- included end -->
diff --git a/op-mode-definitions/include/bgp/afi-ipv4-ipv6-common.xml.i b/op-mode-definitions/include/bgp/afi-ipv4-ipv6-common.xml.i
index a51595b7f..084f5da83 100644
--- a/op-mode-definitions/include/bgp/afi-ipv4-ipv6-common.xml.i
+++ b/op-mode-definitions/include/bgp/afi-ipv4-ipv6-common.xml.i
@@ -230,4 +230,5 @@
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
</tagNode>
+#include <include/vtysh-generic-wide.xml.i>
<!-- included end -->
diff --git a/op-mode-definitions/include/bgp/afi-ipv4-ipv6-flowspec.xml.i b/op-mode-definitions/include/bgp/afi-ipv4-ipv6-flowspec.xml.i
new file mode 100644
index 000000000..34228fdd1
--- /dev/null
+++ b/op-mode-definitions/include/bgp/afi-ipv4-ipv6-flowspec.xml.i
@@ -0,0 +1,25 @@
+<!-- included start from bgp/afi-ipv4-ipv6-flowspec.xml.i -->
+<tagNode name="flowspec">
+ <properties>
+ <help>Network in the BGP routing table to display</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt; &lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
+ </completionHelp>
+ </properties>
+ <children>
+ #include <include/bgp/prefix-bestpath-multipath.xml.i>
+ </children>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</tagNode>
+<node name="flowspec">
+ <properties>
+ <help>Flowspec Address Family modifier</help>
+ </properties>
+ <children>
+ #include <include/bgp/afi-common.xml.i>
+ #include <include/bgp/afi-ipv4-ipv6-common.xml.i>
+ #include <include/vtysh-generic-detail.xml.i>
+ </children>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</node>
+<!-- included end -->
diff --git a/op-mode-definitions/include/bgp/show-bgp-common.xml.i b/op-mode-definitions/include/bgp/show-bgp-common.xml.i
index e81b26b3e..c9a112fca 100644
--- a/op-mode-definitions/include/bgp/show-bgp-common.xml.i
+++ b/op-mode-definitions/include/bgp/show-bgp-common.xml.i
@@ -20,6 +20,7 @@
<children>
#include <include/bgp/afi-common.xml.i>
#include <include/bgp/afi-ipv4-ipv6-common.xml.i>
+ #include <include/bgp/afi-ipv4-ipv6-flowspec.xml.i>
#include <include/bgp/afi-ipv4-ipv6-vpn.xml.i>
</children>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
diff --git a/op-mode-definitions/include/ospf-common.xml.i b/op-mode-definitions/include/ospf-common.xml.i
index 0edc3c37f..23769c8ba 100644
--- a/op-mode-definitions/include/ospf-common.xml.i
+++ b/op-mode-definitions/include/ospf-common.xml.i
@@ -523,15 +523,6 @@
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
- <tagNode name="address">
- <properties>
- <help>Show IPv4 OSPF neighbor information for specified IP address</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </tagNode>
<node name="detail">
<properties>
<help>Show detailed IPv4 OSPF neighbor information</help>
diff --git a/op-mode-definitions/include/ospfv3/border-routers.xml.i b/op-mode-definitions/include/ospfv3/border-routers.xml.i
new file mode 100644
index 000000000..b6fac6785
--- /dev/null
+++ b/op-mode-definitions/include/ospfv3/border-routers.xml.i
@@ -0,0 +1,20 @@
+<!-- included start from ospfv3/border-routers.xml.i -->
+<node name="border-routers">
+ <properties>
+ <help>Show OSPFv3 border-router (ABR and ASBR) information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/ospfv3/detail.xml.i>
+ </children>
+</node>
+<tagNode name="border-routers">
+ <properties>
+ <help>Border router ID</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</tagNode>
+<!-- included end -->
diff --git a/op-mode-definitions/include/ospfv3/database.xml.i b/op-mode-definitions/include/ospfv3/database.xml.i
new file mode 100644
index 000000000..e98f9e35b
--- /dev/null
+++ b/op-mode-definitions/include/ospfv3/database.xml.i
@@ -0,0 +1,238 @@
+<!-- included start from ospfv3/database.xml.i -->
+<node name="database">
+ <properties>
+ <help>Show OSPFv3 Link state database information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ <tagNode name="adv-router">
+ <properties>
+ <help>Search by Advertising Router ID</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt;</list>
+ </completionHelp>
+ </properties>
+ <children>
+ #include <include/ospfv3/linkstate-id.xml.i>
+ </children>
+ </tagNode>
+ <node name="any">
+ <properties>
+ <help>Search by Any Link state Type</help>
+ </properties>
+ <children>
+ <tagNode name="any">
+ <properties>
+ <help>Search by Link state ID</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt;</list>
+ </completionHelp>
+ </properties>
+ <children>
+ #include <include/ospfv3/detail.xml.i>
+ #include <include/ospfv3/dump.xml.i>
+ #include <include/ospfv3/internal.xml.i>
+ </children>
+ </tagNode>
+ </children>
+ </node>
+ <tagNode name="any">
+ <properties>
+ <help>Search by Link state ID</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>vtysh -c "show ipv6 ospf6 database * $6"</command>
+ <children>
+ #include <include/ospfv3/detail.xml.i>
+ #include <include/ospfv3/dump.xml.i>
+ #include <include/ospfv3/internal.xml.i>
+ #include <include/ospfv3/adv-router-id-node-tag.xml.i>
+ </children>
+ </tagNode>
+ <node name="as-external">
+ <properties>
+ <help>Show AS-External LSAs</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/ospfv3/adv-router.xml.i>
+ <tagNode name="any">
+ <properties>
+ <help>Search by Advertising Router ID</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>vtysh -c "show ipv6 ospf6 database as-external * $7"</command>
+ <children>
+ #include <include/ospfv3/detail.xml.i>
+ #include <include/ospfv3/dump.xml.i>
+ #include <include/ospfv3/internal.xml.i>
+ </children>
+ </tagNode>
+ #include <include/ospfv3/detail.xml.i>
+ #include <include/ospfv3/dump.xml.i>
+ #include <include/ospfv3/internal.xml.i>
+ #include <include/ospfv3/linkstate-id.xml.i>
+ #include <include/ospfv3/self-originated.xml.i>
+ </children>
+ </node>
+ <tagNode name="as-external">
+ <properties>
+ <help>Search by Advertising Router IDs</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt;</list>
+ </completionHelp>
+ </properties>
+ <children>
+ #include <include/ospfv3/detail.xml.i>
+ #include <include/ospfv3/dump.xml.i>
+ #include <include/ospfv3/internal.xml.i>
+ #include <include/ospfv3/self-originated.xml.i>
+ #include <include/ospfv3/adv-router-id-node-tag.xml.i>
+ </children>
+ </tagNode>
+ #include <include/ospfv3/detail.xml.i>
+ #include <include/ospfv3/internal.xml.i>
+ #include <include/ospfv3/linkstate-id.xml.i>
+ #include <include/ospfv3/self-originated.xml.i>
+ <node name="group-membership">
+ <properties>
+ <help>Show Group-Membership LSAs</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/ospfv3/adv-router.xml.i>
+ #include <include/ospfv3/detail.xml.i>
+ #include <include/ospfv3/dump.xml.i>
+ #include <include/ospfv3/internal.xml.i>
+ #include <include/ospfv3/linkstate-id.xml.i>
+ #include <include/ospfv3/linkstate-id-node-tag.xml.i>
+ #include <include/ospfv3/self-originated.xml.i>
+ </children>
+ </node>
+ <node name="inter-prefix">
+ <properties>
+ <help>Show Inter-Area-Prefix LSAs</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/ospfv3/adv-router.xml.i>
+ #include <include/ospfv3/detail.xml.i>
+ #include <include/ospfv3/dump.xml.i>
+ #include <include/ospfv3/internal.xml.i>
+ #include <include/ospfv3/linkstate-id.xml.i>
+ #include <include/ospfv3/linkstate-id-node-tag.xml.i>
+ #include <include/ospfv3/self-originated.xml.i>
+ </children>
+ </node>
+ <node name="inter-router">
+ <properties>
+ <help>Show Inter-Area-Router LSAs</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/ospfv3/adv-router.xml.i>
+ #include <include/ospfv3/detail.xml.i>
+ #include <include/ospfv3/dump.xml.i>
+ #include <include/ospfv3/internal.xml.i>
+ #include <include/ospfv3/linkstate-id.xml.i>
+ #include <include/ospfv3/linkstate-id-node-tag.xml.i>
+ #include <include/ospfv3/self-originated.xml.i>
+ </children>
+ </node>
+ <node name="intra-prefix">
+ <properties>
+ <help>Show Intra-Area-Prefix LSAs</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/ospfv3/adv-router.xml.i>
+ #include <include/ospfv3/detail.xml.i>
+ #include <include/ospfv3/dump.xml.i>
+ #include <include/ospfv3/internal.xml.i>
+ #include <include/ospfv3/linkstate-id.xml.i>
+ #include <include/ospfv3/linkstate-id-node-tag.xml.i>
+ #include <include/ospfv3/self-originated.xml.i>
+ </children>
+ </node>
+ <node name="link">
+ <properties>
+ <help>Show Link LSAs</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/ospfv3/adv-router.xml.i>
+ #include <include/ospfv3/detail.xml.i>
+ #include <include/ospfv3/dump.xml.i>
+ #include <include/ospfv3/internal.xml.i>
+ #include <include/ospfv3/linkstate-id.xml.i>
+ #include <include/ospfv3/linkstate-id-node-tag.xml.i>
+ #include <include/ospfv3/self-originated.xml.i>
+ </children>
+ </node>
+ <node name="network">
+ <properties>
+ <help>Show Network LSAs</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/ospfv3/adv-router.xml.i>
+ #include <include/ospfv3/detail.xml.i>
+ #include <include/ospfv3/dump.xml.i>
+ #include <include/ospfv3/internal.xml.i>
+ #include <include/ospfv3/linkstate-id.xml.i>
+ #include <include/ospfv3/linkstate-id-node-tag.xml.i>
+ #include <include/ospfv3/self-originated.xml.i>
+ </children>
+ </node>
+ <node name="node.tag">
+ <properties>
+ <help>Show LSAs</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/ospfv3/adv-router.xml.i>
+ #include <include/ospfv3/detail.xml.i>
+ #include <include/ospfv3/dump.xml.i>
+ #include <include/ospfv3/internal.xml.i>
+ #include <include/ospfv3/linkstate-id.xml.i>
+ #include <include/ospfv3/linkstate-id-node-tag.xml.i>
+ #include <include/ospfv3/self-originated.xml.i>
+ </children>
+ </node>
+ <node name="router">
+ <properties>
+ <help>Show router LSAs</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/ospfv3/adv-router.xml.i>
+ #include <include/ospfv3/detail.xml.i>
+ #include <include/ospfv3/dump.xml.i>
+ #include <include/ospfv3/internal.xml.i>
+ #include <include/ospfv3/linkstate-id.xml.i>
+ #include <include/ospfv3/linkstate-id-node-tag.xml.i>
+ #include <include/ospfv3/self-originated.xml.i>
+ </children>
+ </node>
+ <node name="type-7">
+ <properties>
+ <help>Show Type-7 LSAs</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/ospfv3/adv-router.xml.i>
+ #include <include/ospfv3/detail.xml.i>
+ #include <include/ospfv3/dump.xml.i>
+ #include <include/ospfv3/internal.xml.i>
+ #include <include/ospfv3/linkstate-id.xml.i>
+ #include <include/ospfv3/linkstate-id-node-tag.xml.i>
+ #include <include/ospfv3/self-originated.xml.i>
+ </children>
+ </node>
+ </children>
+</node>
+<!-- included end -->
diff --git a/op-mode-definitions/include/ospfv3/interface.xml.i b/op-mode-definitions/include/ospfv3/interface.xml.i
new file mode 100644
index 000000000..0fb66257d
--- /dev/null
+++ b/op-mode-definitions/include/ospfv3/interface.xml.i
@@ -0,0 +1,75 @@
+<!-- included start from ospfv3/interface.xml.i -->
+<node name="interface">
+ <properties>
+ <help>Show OSPFv3 interface information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ <node name="prefix">
+ <properties>
+ <help>Show connected prefixes to advertise</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/ospfv3/detail.xml.i>
+ </children>
+ </node>
+ <tagNode name="prefix">
+ <properties>
+ <help>Show interface prefix route specific information</help>
+ <completionHelp>
+ <list>&lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/ospfv3/detail.xml.i>
+ <node name="match">
+ <properties>
+ <help>Matched interface prefix information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </node>
+ </children>
+ </tagNode>
+ </children>
+</node>
+<tagNode name="interface">
+ <properties>
+ <help>Specific insterface to examine</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces.py</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ <node name="prefix">
+ <properties>
+ <help>Show connected prefixes to advertise</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/ospfv3/detail.xml.i>
+ </children>
+ </node>
+ <tagNode name="prefix">
+ <properties>
+ <help>Show interface prefix route specific information</help>
+ <completionHelp>
+ <list>&lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/ospfv3/detail.xml.i>
+ <node name="match">
+ <properties>
+ <help>Matched interface prefix information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </node>
+ </children>
+ </tagNode>
+ </children>
+</tagNode>
+<!-- included end -->
diff --git a/op-mode-definitions/include/ospfv3/linkstate.xml.i b/op-mode-definitions/include/ospfv3/linkstate.xml.i
new file mode 100644
index 000000000..78ef3efa1
--- /dev/null
+++ b/op-mode-definitions/include/ospfv3/linkstate.xml.i
@@ -0,0 +1,38 @@
+<!-- included start from ospfv3/linkstate.xml.i -->
+<node name="linkstate">
+ <properties>
+ <help>Show OSPFv3 linkstate routing information</help>
+ </properties>
+ <children>
+ #include <include/ospfv3/detail.xml.i>
+ <tagNode name="network">
+ <properties>
+ <help>Show linkstate Network information</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt;</list>
+ </completionHelp>
+ </properties>
+ <children>
+ <node name="node.tag">
+ <properties>
+ <help>Specify Link state ID as IPv4 address notation</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </node>
+ </children>
+ </tagNode>
+ <tagNode name="router">
+ <properties>
+ <help>Show linkstate Router information</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </tagNode>
+ </children>
+</node>
+<!-- included end -->
diff --git a/op-mode-definitions/include/ospfv3/neighbor.xml.i b/op-mode-definitions/include/ospfv3/neighbor.xml.i
new file mode 100644
index 000000000..37859f815
--- /dev/null
+++ b/op-mode-definitions/include/ospfv3/neighbor.xml.i
@@ -0,0 +1,17 @@
+<!-- included start from ospfv3/neighbor.xml.i -->
+<node name="neighbor">
+ <properties>
+ <help>Show OSPFv3 neighbor information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/ospfv3/detail.xml.i>
+ <node name="drchoice">
+ <properties>
+ <help>Show neighbor DR choice information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </node>
+ </children>
+</node>
+<!-- included end -->
diff --git a/op-mode-definitions/include/ospfv3/redistribute.xml.i b/op-mode-definitions/include/ospfv3/redistribute.xml.i
new file mode 100644
index 000000000..1c2d6494f
--- /dev/null
+++ b/op-mode-definitions/include/ospfv3/redistribute.xml.i
@@ -0,0 +1,8 @@
+<!-- included start from ospfv3/redistribute.xml.i -->
+<node name="redistribute">
+ <properties>
+ <help>Show OSPFv3 redistribute external information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</node>
+<!-- included end -->
diff --git a/op-mode-definitions/include/ospfv3/route.xml.i b/op-mode-definitions/include/ospfv3/route.xml.i
new file mode 100644
index 000000000..9271c9c3a
--- /dev/null
+++ b/op-mode-definitions/include/ospfv3/route.xml.i
@@ -0,0 +1,79 @@
+<!-- included start from ospfv3/route.xml.i -->
+<node name="route">
+ <properties>
+ <help>Show OSPFv3 routing table information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ <node name="external-1">
+ <properties>
+ <help>Show Type-1 External route information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/ospfv3/detail.xml.i>
+ </children>
+ </node>
+ <node name="external-2">
+ <properties>
+ <help>Show Type-2 External route information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/ospfv3/detail.xml.i>
+ </children>
+ </node>
+ <node name="inter-area">
+ <properties>
+ <help>Show Inter-Area route information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/ospfv3/detail.xml.i>
+ </children>
+ </node>
+ <node name="intra-area">
+ <properties>
+ <help>Show Intra-Area route information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/ospfv3/detail.xml.i>
+ </children>
+ </node>
+ #include <include/ospfv3/detail.xml.i>
+ <node name="summary">
+ <properties>
+ <help>Show route table summary</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </node>
+ </children>
+</node>
+<tagNode name="route">
+ <properties>
+ <help>Show specified route/prefix information</help>
+ <completionHelp>
+ <list>&lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ <node name="longer">
+ <properties>
+ <help>Show routes longer than specified prefix</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </node>
+ <node name="match">
+ <properties>
+ <help>Show routes matching specified prefix</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/ospfv3/detail.xml.i>
+ </children>
+ </node>
+ </children>
+</tagNode>
+<!-- included end -->
diff --git a/op-mode-definitions/include/show-route-bgp.xml.i b/op-mode-definitions/include/show-route-bgp.xml.i
new file mode 100644
index 000000000..5c26bf43f
--- /dev/null
+++ b/op-mode-definitions/include/show-route-bgp.xml.i
@@ -0,0 +1,8 @@
+<!-- included start from show-route-bgp.xml.i -->
+<leafNode name="bgp">
+ <properties>
+ <help>Border Gateway Protocol (BGP)</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</leafNode>
+<!-- included end -->
diff --git a/op-mode-definitions/include/show-route-connected.xml.i b/op-mode-definitions/include/show-route-connected.xml.i
new file mode 100644
index 000000000..37364de64
--- /dev/null
+++ b/op-mode-definitions/include/show-route-connected.xml.i
@@ -0,0 +1,8 @@
+<!-- included start from show-route-connected.xml.i -->
+<leafNode name="connected">
+ <properties>
+ <help>Connected routes (directly attached subnet or host)</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</leafNode>
+<!-- included end -->
diff --git a/op-mode-definitions/include/show-route-isis.xml.i b/op-mode-definitions/include/show-route-isis.xml.i
new file mode 100644
index 000000000..9ff2ccdc5
--- /dev/null
+++ b/op-mode-definitions/include/show-route-isis.xml.i
@@ -0,0 +1,8 @@
+<!-- included start from show-route-isis.xml.i -->
+<leafNode name="isis">
+ <properties>
+ <help>Intermediate System to Intermediate System (IS-IS)</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</leafNode>
+<!-- included end -->
diff --git a/op-mode-definitions/include/show-route-kernel.xml.i b/op-mode-definitions/include/show-route-kernel.xml.i
new file mode 100644
index 000000000..8c5ac414e
--- /dev/null
+++ b/op-mode-definitions/include/show-route-kernel.xml.i
@@ -0,0 +1,8 @@
+<!-- included start from show-route-kernel.xml.i -->
+<leafNode name="kernel">
+ <properties>
+ <help>Kernel routes (not installed via the zebra RIB)</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</leafNode>
+<!-- included end -->
diff --git a/op-mode-definitions/include/show-route-ospf.xml.i b/op-mode-definitions/include/show-route-ospf.xml.i
new file mode 100644
index 000000000..1122aaba5
--- /dev/null
+++ b/op-mode-definitions/include/show-route-ospf.xml.i
@@ -0,0 +1,8 @@
+<!-- included start from show-route-ospf.xml.i -->
+<leafNode name="ospf">
+ <properties>
+ <help>Open Shortest Path First (OSPFv2)</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</leafNode>
+<!-- included end -->
diff --git a/op-mode-definitions/include/show-route-ospfv3.xml.i b/op-mode-definitions/include/show-route-ospfv3.xml.i
new file mode 100644
index 000000000..c7a11b7ba
--- /dev/null
+++ b/op-mode-definitions/include/show-route-ospfv3.xml.i
@@ -0,0 +1,8 @@
+<!-- included start from show-route-ospfv3.xml.i -->
+<leafNode name="ospfv3">
+ <properties>
+ <help>Open Shortest Path First (IPv6) (OSPFv3)</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</leafNode>
+<!-- included end -->
diff --git a/op-mode-definitions/include/show-route-rip.xml.i b/op-mode-definitions/include/show-route-rip.xml.i
new file mode 100644
index 000000000..3c2fede28
--- /dev/null
+++ b/op-mode-definitions/include/show-route-rip.xml.i
@@ -0,0 +1,8 @@
+<!-- included start from show-route-rip.xml.i -->
+<leafNode name="rip">
+ <properties>
+ <help>Routing Information Protocol (RIP)</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</leafNode>
+<!-- included end -->
diff --git a/op-mode-definitions/include/show-route-ripng.xml.i b/op-mode-definitions/include/show-route-ripng.xml.i
new file mode 100644
index 000000000..6e59cb054
--- /dev/null
+++ b/op-mode-definitions/include/show-route-ripng.xml.i
@@ -0,0 +1,8 @@
+<!-- included start from show-route-ripng.xml.i -->
+<leafNode name="ripng">
+ <properties>
+ <help>Routing Information Protocol next-generation (IPv6) (RIPng)</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</leafNode>
+<!-- included end -->
diff --git a/op-mode-definitions/include/show-route-static.xml.i b/op-mode-definitions/include/show-route-static.xml.i
new file mode 100644
index 000000000..c2e396763
--- /dev/null
+++ b/op-mode-definitions/include/show-route-static.xml.i
@@ -0,0 +1,8 @@
+<!-- included start from show-route-static.xml.i -->
+<leafNode name="static">
+ <properties>
+ <help>Statically configured routes</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</leafNode>
+<!-- included end -->
diff --git a/op-mode-definitions/include/show-route-summary.xml.i b/op-mode-definitions/include/show-route-summary.xml.i
new file mode 100644
index 000000000..471124562
--- /dev/null
+++ b/op-mode-definitions/include/show-route-summary.xml.i
@@ -0,0 +1,8 @@
+<!-- included start from show-route-summary.xml.i -->
+<leafNode name="summary">
+ <properties>
+ <help>Summary of all routes</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</leafNode>
+<!-- included end -->
diff --git a/op-mode-definitions/include/show-route-supernets-only.xml.i b/op-mode-definitions/include/show-route-supernets-only.xml.i
new file mode 100644
index 000000000..4d1e7c51f
--- /dev/null
+++ b/op-mode-definitions/include/show-route-supernets-only.xml.i
@@ -0,0 +1,8 @@
+<!-- included start from show-route-supernets-only.xml.i -->
+<leafNode name="supernets-only">
+ <properties>
+ <help>Show supernet entries only</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</leafNode>
+<!-- included end -->
diff --git a/op-mode-definitions/include/show-route-table.xml.i b/op-mode-definitions/include/show-route-table.xml.i
new file mode 100644
index 000000000..c3cf82a86
--- /dev/null
+++ b/op-mode-definitions/include/show-route-table.xml.i
@@ -0,0 +1,17 @@
+<!-- included start from show-route-table.xml.i -->
+<node name="table">
+ <properties>
+ <help>Table to display</help>
+ </properties>
+</node>
+<tagNode name="table">
+ <properties>
+ <help>The table number to display</help>
+ <completionHelp>
+ <list>all</list>
+ <path>protocols static table</path>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</tagNode>
+<!-- included end -->
diff --git a/op-mode-definitions/include/show-route-tag.xml.i b/op-mode-definitions/include/show-route-tag.xml.i
new file mode 100644
index 000000000..8bfa0ae4e
--- /dev/null
+++ b/op-mode-definitions/include/show-route-tag.xml.i
@@ -0,0 +1,16 @@
+<!-- included start from show-route-tag.xml.i -->
+<node name="tag">
+ <properties>
+ <help>Show only routes with tag</help>
+ </properties>
+</node>
+<tagNode name="tag">
+ <properties>
+ <help>Tag value</help>
+ <completionHelp>
+ <list>&lt;1-4294967295&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</tagNode>
+<!-- included end -->
diff --git a/op-mode-definitions/monitor-log.xml.in b/op-mode-definitions/monitor-log.xml.in
index 352c84ff1..7ecce4f78 100644
--- a/op-mode-definitions/monitor-log.xml.in
+++ b/op-mode-definitions/monitor-log.xml.in
@@ -6,13 +6,181 @@
<properties>
<help>Monitor last lines of messages file</help>
</properties>
- <command>tail --follow=name /var/log/messages</command>
+ <command>journalctl --no-hostname --follow --boot</command>
<children>
<node name="colored">
<properties>
<help>Output log in a colored fashion</help>
</properties>
- <command>grc tail --follow=name /var/log/messages</command>
+ <command>grc journalctl --no-hostname --follow --boot</command>
+ </node>
+ <node name="dhcp">
+ <properties>
+ <help>Monitor last lines of Dynamic Host Control Protocol (DHCP)</help>
+ </properties>
+ <children>
+ <node name="server">
+ <properties>
+ <help>Monitor last lines of DHCP server</help>
+ </properties>
+ <command>journalctl --no-hostname --follow --boot --unit isc-dhcp-server.service</command>
+ </node>
+ <node name="client">
+ <properties>
+ <help>Monitor last lines of DHCP client</help>
+ </properties>
+ <command>journalctl --no-hostname --follow --boot --unit "dhclient@*.service"</command>
+ <children>
+ <tagNode name="interface">
+ <properties>
+ <help>Show DHCP client log on specific interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces.py --broadcast</script>
+ </completionHelp>
+ </properties>
+ <command>journalctl --no-hostname --follow --boot --unit "dhclient@$6.service"</command>
+ </tagNode>
+ </children>
+ </node>
+ </children>
+ </node>
+ <node name="dhcpv6">
+ <properties>
+ <help>Monitor last lines of Dynamic Host Control Protocol IPv6 (DHCPv6)</help>
+ </properties>
+ <children>
+ <node name="server">
+ <properties>
+ <help>Monitor last lines of DHCPv6 server</help>
+ </properties>
+ <command>journalctl --no-hostname --follow --boot --unit isc-dhcp-server6.service</command>
+ </node>
+ <node name="client">
+ <properties>
+ <help>Monitor last lines of DHCPv6 client</help>
+ </properties>
+ <command>journalctl --no-hostname --follow --boot --unit "dhcp6c@*.service"</command>
+ <children>
+ <tagNode name="interface">
+ <properties>
+ <help>Show DHCPv6 client log on specific interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces.py</script>
+ </completionHelp>
+ </properties>
+ <command>journalctl --no-hostname --follow --boot --unit "dhcp6c@$6.service"</command>
+ </tagNode>
+ </children>
+ </node>
+ </children>
+ </node>
+ <leafNode name="flow-accounting">
+ <properties>
+ <help>Monitor last lines of flow-accounting log</help>
+ </properties>
+ <command>journalctl --no-hostname --boot --follow --unit uacctd.service</command>
+ </leafNode>
+ <leafNode name="kernel">
+ <properties>
+ <help>Monitor last lines of Linux Kernel log</help>
+ </properties>
+ <command>journalctl --no-hostname --boot --follow --dmesg</command>
+ </leafNode>
+ <leafNode name="nhrp">
+ <properties>
+ <help>Monitor last lines of NHRP log</help>
+ </properties>
+ <command>journalctl --no-hostname --boot --unit opennhrp.service</command>
+ </leafNode>
+ <node name="pppoe">
+ <properties>
+ <help>Monitor last lines of PPPoE log</help>
+ </properties>
+ <command>journalctl --no-hostname --boot --follow --unit "ppp@pppoe*.service"</command>
+ <children>
+ <tagNode name="interface">
+ <properties>
+ <help>Monitor last lines of PPPoE log for specific interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces.py -t pppoe</script>
+ </completionHelp>
+ </properties>
+ <command>journalctl --no-hostname --boot --follow --unit "ppp@$6.service"</command>
+ </tagNode>
+ </children>
+ </node>
+ <node name="protocol">
+ <properties>
+ <help>Monitor log for Routing Protocols</help>
+ </properties>
+ <children>
+ <leafNode name="ospf">
+ <properties>
+ <help>Monitor log for OSPF</help>
+ </properties>
+ <command>journalctl --follow --no-hostname --boot /usr/lib/frr/ospfd</command>
+ </leafNode>
+ <leafNode name="ospfv3">
+ <properties>
+ <help>Monitor log for OSPF for IPv6</help>
+ </properties>
+ <command>journalctl --follow --no-hostname --boot /usr/lib/frr/ospf6d</command>
+ </leafNode>
+ <leafNode name="bgp">
+ <properties>
+ <help>Monitor log for BGP</help>
+ </properties>
+ <command>journalctl --follow --no-hostname --boot /usr/lib/frr/bgpd</command>
+ </leafNode>
+ <leafNode name="rip">
+ <properties>
+ <help>Monitor log for RIP</help>
+ </properties>
+ <command>journalctl --follow --no-hostname --boot /usr/lib/frr/ripd</command>
+ </leafNode>
+ <leafNode name="ripng">
+ <properties>
+ <help>Monitor log for RIPng</help>
+ </properties>
+ <command>journalctl --follow --no-hostname --boot /usr/lib/frr/ripngd</command>
+ </leafNode>
+ <leafNode name="static">
+ <properties>
+ <help>Monitor log for static route</help>
+ </properties>
+ <command>journalctl --follow --no-hostname --boot /usr/lib/frr/staticd</command>
+ </leafNode>
+ <leafNode name="multicast">
+ <properties>
+ <help>Monitor log for Multicast protocol</help>
+ </properties>
+ <command>journalctl --follow --no-hostname --boot /usr/lib/frr/pimd</command>
+ </leafNode>
+ <leafNode name="isis">
+ <properties>
+ <help>Monitor log for ISIS</help>
+ </properties>
+ <command>journalctl --follow --no-hostname --boot /usr/lib/frr/isisd</command>
+ </leafNode>
+ <leafNode name="nhrp">
+ <properties>
+ <help>Monitor log for NHRP</help>
+ </properties>
+ <command>journalctl --follow --no-hostname --boot /usr/lib/frr/nhrpd</command>
+ </leafNode>
+ <leafNode name="bfd">
+ <properties>
+ <help>Monitor log for BFD</help>
+ </properties>
+ <command>journalctl --follow --no-hostname --boot /usr/lib/frr/bfdd</command>
+ </leafNode>
+ <leafNode name="mpls">
+ <properties>
+ <help>Monitor log for MPLS</help>
+ </properties>
+ <command>journalctl --follow --no-hostname --boot /usr/lib/frr/ldpd</command>
+ </leafNode>
+ </children>
</node>
</children>
</node>
diff --git a/op-mode-definitions/policy-route.xml.in b/op-mode-definitions/policy-route.xml.in
new file mode 100644
index 000000000..bd4a61dc9
--- /dev/null
+++ b/op-mode-definitions/policy-route.xml.in
@@ -0,0 +1,143 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+<!--
+ <node name="clear">
+ <children>
+ <node name="policy">
+ <properties>
+ <help>Clear policy statistics</help>
+ </properties>
+ <children>
+ <tagNode name="ipv6-route">
+ <properties>
+ <help>Clear policy statistics for chain</help>
+ <completionHelp>
+ <path>policy ipv6-route</path>
+ </completionHelp>
+ </properties>
+ <children>
+ <leafNode name="counters">
+ <properties>
+ <help>Clear counters for specified chain</help>
+ </properties>
+ <command>echo "TODO"</command>
+ </leafNode>
+ <tagNode name="rule">
+ <properties>
+ <help>Clear policy statistics for a rule</help>
+ <completionHelp>
+ <path>policy ipv6-route ${COMP_WORDS[4]} rule</path>
+ </completionHelp>
+ </properties>
+ <children>
+ <leafNode name="counters">
+ <properties>
+ <help>Clear counters for specified rule</help>
+ </properties>
+ <command>echo "TODO"</command>
+ </leafNode>
+ </children>
+ </tagNode>
+ </children>
+ </tagNode>
+ <tagNode name="route">
+ <properties>
+ <help>Clear policy statistics for chain</help>
+ <completionHelp>
+ <path>policy route</path>
+ </completionHelp>
+ </properties>
+ <children>
+ <leafNode name="counters">
+ <properties>
+ <help>Clear counters for specified chain</help>
+ </properties>
+ <command>echo "TODO"</command>
+ </leafNode>
+ <tagNode name="rule">
+ <properties>
+ <help>Clear policy statistics for a rule</help>
+ <completionHelp>
+ <path>policy route ${COMP_WORDS[4]} rule</path>
+ </completionHelp>
+ </properties>
+ <children>
+ <leafNode name="counters">
+ <properties>
+ <help>Clear counters for specified rule</help>
+ </properties>
+ <command>echo "TODO"</command>
+ </leafNode>
+ </children>
+ </tagNode>
+ </children>
+ </tagNode>
+ </children>
+ </node>
+ </children>
+ </node>
+-->
+ <node name="show">
+ <children>
+ <node name="policy">
+ <properties>
+ <help>Show policy information</help>
+ </properties>
+ <children>
+ <node name="route6">
+ <properties>
+ <help>Show IPv6 policy chain</help>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/policy_route.py --action show_all --ipv6</command>
+ </node>
+ <tagNode name="route6">
+ <properties>
+ <help>Show IPv6 policy chains</help>
+ <completionHelp>
+ <path>policy route6</path>
+ </completionHelp>
+ </properties>
+ <children>
+ <tagNode name="rule">
+ <properties>
+ <help>Show summary of IPv6 policy rules</help>
+ <completionHelp>
+ <path>policy route6 ${COMP_WORDS[4]} rule</path>
+ </completionHelp>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/policy_route.py --action show --name $4 --rule $6 --ipv6</command>
+ </tagNode>
+ </children>
+ <command>sudo ${vyos_op_scripts_dir}/policy_route.py --action show --name $4 --ipv6</command>
+ </tagNode>
+ <node name="route">
+ <properties>
+ <help>Show IPv4 policy chain</help>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/policy_route.py --action show_all</command>
+ </node>
+ <tagNode name="route">
+ <properties>
+ <help>Show IPv4 policy chains</help>
+ <completionHelp>
+ <path>policy route</path>
+ </completionHelp>
+ </properties>
+ <children>
+ <tagNode name="rule">
+ <properties>
+ <help>Show summary of IPv4 policy rules</help>
+ <completionHelp>
+ <path>policy route ${COMP_WORDS[4]} rule</path>
+ </completionHelp>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/policy_route.py --action show --name $4 --rule $6</command>
+ </tagNode>
+ </children>
+ <command>sudo ${vyos_op_scripts_dir}/policy_route.py --action show --name $4</command>
+ </tagNode>
+ </children>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/op-mode-definitions/reboot.xml.in b/op-mode-definitions/reboot.xml.in
index 2c8daec5d..6414742d9 100644
--- a/op-mode-definitions/reboot.xml.in
+++ b/op-mode-definitions/reboot.xml.in
@@ -25,7 +25,7 @@
<list>&lt;Minutes&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --yes --reboot $3 $4</command>
+ <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --yes --reboot_in $3 $4</command>
</tagNode>
<tagNode name="at">
<properties>
@@ -40,7 +40,7 @@
<properties>
<help>Reboot at a specific date</help>
<completionHelp>
- <list>&lt;DDMMYYYY&gt; &lt;DD/MM/YYYY&gt; &lt;DD.MM.YYYY&gt; &lt;DD:MM:YYYY&gt;</list>
+ <list>&lt;DD/MM/YYYY&gt; &lt;DD.MM.YYYY&gt; &lt;DD:MM:YYYY&gt;</list>
</completionHelp>
</properties>
<command>sudo ${vyos_op_scripts_dir}/powerctrl.py --yes --reboot $3 $5</command>
diff --git a/op-mode-definitions/restart-frr.xml.in b/op-mode-definitions/restart-frr.xml.in
index 475bd1ee8..4e2be1bf2 100644
--- a/op-mode-definitions/restart-frr.xml.in
+++ b/op-mode-definitions/restart-frr.xml.in
@@ -26,6 +26,12 @@
</properties>
<command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon isisd</command>
</leafNode>
+ <leafNode name="ldp">
+ <properties>
+ <help>Restart the Label Distribution Protocol (LDP) daemon</help>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ldpd</command>
+ </leafNode>
<leafNode name="ospf">
<properties>
<help>Restart Open Shortest Path First (OSPF) routing daemon</help>
diff --git a/op-mode-definitions/show-bfd.xml.in b/op-mode-definitions/show-bfd.xml.in
new file mode 100644
index 000000000..39e42e6ec
--- /dev/null
+++ b/op-mode-definitions/show-bfd.xml.in
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="show">
+ <children>
+ <node name="bfd">
+ <properties>
+ <help>Show Bidirectional Forwarding Detection (BFD)</help>
+ </properties>
+ <children>
+ <node name="peer">
+ <properties>
+ <help>Show all Bidirectional Forwarding Detection (BFD) peer status</help>
+ </properties>
+ </node>
+ <tagNode name="peer">
+ <properties>
+ <help>Show Bidirectional Forwarding Detection (BFD) peer status</help>
+ <completionHelp>
+ <script>vtysh -c "show bfd peers" | awk '/[:blank:]*peer/ { printf "%s\n", $2 }'</script>
+ </completionHelp>
+ </properties>
+ <command>vtysh -c "show bfd peers" | sed -n "/peer $4 /,/^$/p"</command>
+ <children>
+ <leafNode name="counters">
+ <properties>
+ <help>Show Bidirectional Forwarding Detection (BFD) peer counters</help>
+ </properties>
+ <command>vtysh -c "show bfd peers counters" | sed -n "/peer $4 /,/^$/p"</command>
+ </leafNode>
+ </children>
+ </tagNode>
+ <node name="peers">
+ <properties>
+ <help>Show Bidirectional Forwarding Detection peers</help>
+ </properties>
+ <command>vtysh -c "show bfd peers"</command>
+ <children>
+ <leafNode name="counters">
+ <properties>
+ <help>Show Bidirectional Forwarding Detection (BFD) peer counters</help>
+ </properties>
+ <command>vtysh -c "show bfd peers counters"</command>
+ </leafNode>
+ <leafNode name="brief">
+ <properties>
+ <help>Show Bidirectional Forwarding Detection (BFD) peers brief</help>
+ </properties>
+ <command>vtysh -c "show bfd peers brief"</command>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/op-mode-definitions/show-configuration.xml.in b/op-mode-definitions/show-configuration.xml.in
index 318942ab0..5a2fdedfa 100644
--- a/op-mode-definitions/show-configuration.xml.in
+++ b/op-mode-definitions/show-configuration.xml.in
@@ -30,6 +30,21 @@
<!-- no admin check -->
<command>${vyos_op_scripts_dir}/show_configuration_files.sh</command>
</node>
+ <node name="json">
+ <properties>
+ <help>Show running configuration in JSON format</help>
+ </properties>
+ <!-- no admin check -->
+ <command>${vyos_op_scripts_dir}/show_configuration_json.py</command>
+ <children>
+ <node name="pretty">
+ <properties>
+ <help>Show running configuration in readable JSON format</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/show_configuration_json.py --pretty</command>
+ </node>
+ </children>
+ </node>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-interfaces-geneve.xml.in b/op-mode-definitions/show-interfaces-geneve.xml.in
new file mode 100644
index 000000000..a47933315
--- /dev/null
+++ b/op-mode-definitions/show-interfaces-geneve.xml.in
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="show">
+ <children>
+ <node name="interfaces">
+ <children>
+ <tagNode name="geneve">
+ <properties>
+ <help>Show specified GENEVE interface information</help>
+ <completionHelp>
+ <path>interfaces geneve</path>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4"</command>
+ <children>
+ <leafNode name="brief">
+ <properties>
+ <help>Show summary of the specified GENEVE interface information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4" --action=show-brief</command>
+ </leafNode>
+ </children>
+ </tagNode>
+ <node name="geneve">
+ <properties>
+ <help>Show GENEVE interface information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=geneve --action=show-brief</command>
+ <children>
+ <leafNode name="detail">
+ <properties>
+ <help>Show detailed GENEVE interface information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=geneve --action=show</command>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/op-mode-definitions/show-ip-route.xml.in b/op-mode-definitions/show-ip-route.xml.in
index fdbb6859d..1e906672d 100644
--- a/op-mode-definitions/show-ip-route.xml.in
+++ b/op-mode-definitions/show-ip-route.xml.in
@@ -13,12 +13,7 @@
</properties>
<command>vtysh -c "show ip route"</command>
<children>
- <leafNode name="bgp">
- <properties>
- <help>Show IP BGP routes</help>
- </properties>
- <command>vtysh -c "show ip route bgp"</command>
- </leafNode>
+ #include <include/show-route-bgp.xml.i>
<node name="cache">
<properties>
<help>Show kernel route cache</help>
@@ -34,12 +29,7 @@
</properties>
<command>ip -s route list cache $5</command>
</tagNode>
- <leafNode name="connected">
- <properties>
- <help>Show IP connected routes</help>
- </properties>
- <command>vtysh -c "show ip route connected"</command>
- </leafNode>
+ #include <include/show-route-connected.xml.i>
<node name="forward">
<properties>
<help>Show kernel route table</help>
@@ -55,76 +45,15 @@
</properties>
<command>ip -s route list $5</command>
</tagNode>
- <leafNode name="isis">
- <properties>
- <help>Show IP IS-IS routes</help>
- </properties>
- <command>vtysh -c "show ip route isis"</command>
- </leafNode>
- <leafNode name="kernel">
- <properties>
- <help>Show IP kernel routes</help>
- </properties>
- <command>vtysh -c "show ip route kernel"</command>
- </leafNode>
- <leafNode name="ospf">
- <properties>
- <help>Show IP OSPF routes</help>
- </properties>
- <command>vtysh -c "show ip route ospf"</command>
- </leafNode>
- <leafNode name="rip">
- <properties>
- <help>Show IP RIP routes</help>
- </properties>
- <command>vtysh -c "show ip route rip"</command>
- </leafNode>
- <leafNode name="static">
- <properties>
- <help>Show IP static routes</help>
- </properties>
- <command>vtysh -c "show ip route static"</command>
- </leafNode>
- <leafNode name="summary">
- <properties>
- <help>Show IP routes summary</help>
- </properties>
- <command>vtysh -c "show ip route summary"</command>
- </leafNode>
- <leafNode name="supernets-only">
- <properties>
- <help>Show IP supernet routes</help>
- </properties>
- <command>vtysh -c "show ip route supernets-only"</command>
- </leafNode>
- <node name="table">
- <properties>
- <help>Show IP routes in policy table</help>
- </properties>
- </node>
- <tagNode name="table">
- <properties>
- <help>Show IP routes in policy table</help>
- <completionHelp>
- <list>&lt;1-200&gt;</list>
- </completionHelp>
- </properties>
- <command>vtysh -c "show ip route table $5"</command>
- </tagNode>
- <node name="tag">
- <properties>
- <help>Show only routes with tag</help>
- </properties>
- </node>
- <tagNode name="tag">
- <properties>
- <help>Tag value</help>
- <completionHelp>
- <list>&lt;1-4294967295&gt;</list>
- </completionHelp>
- </properties>
- <command>vtysh -c "show ip route tag $5"</command>
- </tagNode>
+ #include <include/show-route-isis.xml.i>
+ #include <include/show-route-kernel.xml.i>
+ #include <include/show-route-ospf.xml.i>
+ #include <include/show-route-rip.xml.i>
+ #include <include/show-route-static.xml.i>
+ #include <include/show-route-summary.xml.i>
+ #include <include/show-route-supernets-only.xml.i>
+ #include <include/show-route-table.xml.i>
+ #include <include/show-route-tag.xml.i>
<tagNode name="vrf">
<properties>
<help>Show IP routes in VRF</help>
@@ -133,7 +62,19 @@
<path>vrf name</path>
</completionHelp>
</properties>
- <command>vtysh -c "show ip route vrf $5"</command>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/show-route-bgp.xml.i>
+ #include <include/show-route-connected.xml.i>
+ #include <include/show-route-isis.xml.i>
+ #include <include/show-route-kernel.xml.i>
+ #include <include/show-route-ospf.xml.i>
+ #include <include/show-route-rip.xml.i>
+ #include <include/show-route-static.xml.i>
+ #include <include/show-route-summary.xml.i>
+ #include <include/show-route-supernets-only.xml.i>
+ #include <include/show-route-tag.xml.i>
+ </children>
</tagNode>
</children>
</node>
@@ -144,7 +85,7 @@
<list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt;</list>
</completionHelp>
</properties>
- <command>vtysh -c "show ip route $4"</command>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
<leafNode name="longer-prefixes">
<properties>
diff --git a/op-mode-definitions/show-ipv6-ospfv3.xml.in b/op-mode-definitions/show-ipv6-ospfv3.xml.in
index e6c8a6700..a63465472 100644
--- a/op-mode-definitions/show-ipv6-ospfv3.xml.in
+++ b/op-mode-definitions/show-ipv6-ospfv3.xml.in
@@ -11,7 +11,7 @@
<properties>
<help>Show IPv6 Open Shortest Path First (OSPF)</help>
</properties>
- <command>vtysh -c "show ipv6 ospf6"</command>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
<node name="area">
<properties>
@@ -39,467 +39,74 @@
</tagNode>
</children>
</tagNode>
- <node name="border-routers">
+ #include <include/ospfv3/border-routers.xml.i>
+ #include <include/ospfv3/database.xml.i>
+ #include <include/ospfv3/interface.xml.i>
+ #include <include/ospfv3/linkstate.xml.i>
+ #include <include/ospfv3/neighbor.xml.i>
+ #include <include/ospfv3/redistribute.xml.i>
+ #include <include/ospfv3/route.xml.i>
+ <node name="vrf">
<properties>
- <help>Show OSPFv3 border-router (ABR and ASBR) information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/ospfv3/detail.xml.i>
- </children>
- </node>
- <tagNode name="border-routers">
- <properties>
- <help>Border router ID</help>
+ <help>Specify the VRF</help>
<completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
+ <list>all</list>
+ <path>vrf name</path>
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </tagNode>
- <node name="database">
- <properties>
- <help>Show OSPFv3 Link state database information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- <tagNode name="adv-router">
- <properties>
- <help>Search by Advertising Router ID</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
- </completionHelp>
- </properties>
- <children>
- #include <include/ospfv3/linkstate-id.xml.i>
- </children>
- </tagNode>
- <node name="any">
- <properties>
- <help>Search by Any Link state Type</help>
- </properties>
- <children>
- <tagNode name="any">
- <properties>
- <help>Search by Link state ID</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
- </completionHelp>
- </properties>
- <children>
- #include <include/ospfv3/detail.xml.i>
- #include <include/ospfv3/dump.xml.i>
- #include <include/ospfv3/internal.xml.i>
- </children>
- </tagNode>
- </children>
- </node>
- <tagNode name="any">
- <properties>
- <help>Search by Link state ID</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
- </completionHelp>
- </properties>
- <command>vtysh -c "show ipv6 ospf6 database * $6"</command>
- <children>
- #include <include/ospfv3/detail.xml.i>
- #include <include/ospfv3/dump.xml.i>
- #include <include/ospfv3/internal.xml.i>
- #include <include/ospfv3/adv-router-id-node-tag.xml.i>
- </children>
- </tagNode>
- <node name="as-external">
- <properties>
- <help>Show AS-External LSAs</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/ospfv3/adv-router.xml.i>
- <tagNode name="any">
- <properties>
- <help>Search by Advertising Router ID</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
- </completionHelp>
- </properties>
- <command>vtysh -c "show ipv6 ospf6 database as-external * $7"</command>
- <children>
- #include <include/ospfv3/detail.xml.i>
- #include <include/ospfv3/dump.xml.i>
- #include <include/ospfv3/internal.xml.i>
- </children>
- </tagNode>
- #include <include/ospfv3/detail.xml.i>
- #include <include/ospfv3/dump.xml.i>
- #include <include/ospfv3/internal.xml.i>
- #include <include/ospfv3/linkstate-id.xml.i>
- #include <include/ospfv3/self-originated.xml.i>
- </children>
- </node>
- <tagNode name="as-external">
- <properties>
- <help>Search by Advertising Router IDs</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
- </completionHelp>
- </properties>
- <children>
- #include <include/ospfv3/detail.xml.i>
- #include <include/ospfv3/dump.xml.i>
- #include <include/ospfv3/internal.xml.i>
- #include <include/ospfv3/self-originated.xml.i>
- #include <include/ospfv3/adv-router-id-node-tag.xml.i>
- </children>
- </tagNode>
- #include <include/ospfv3/detail.xml.i>
- #include <include/ospfv3/internal.xml.i>
- #include <include/ospfv3/linkstate-id.xml.i>
- #include <include/ospfv3/self-originated.xml.i>
- <node name="group-membership">
- <properties>
- <help>Show Group-Membership LSAs</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/ospfv3/adv-router.xml.i>
- #include <include/ospfv3/detail.xml.i>
- #include <include/ospfv3/dump.xml.i>
- #include <include/ospfv3/internal.xml.i>
- #include <include/ospfv3/linkstate-id.xml.i>
- #include <include/ospfv3/linkstate-id-node-tag.xml.i>
- #include <include/ospfv3/self-originated.xml.i>
- </children>
- </node>
- <node name="inter-prefix">
- <properties>
- <help>Show Inter-Area-Prefix LSAs</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/ospfv3/adv-router.xml.i>
- #include <include/ospfv3/detail.xml.i>
- #include <include/ospfv3/dump.xml.i>
- #include <include/ospfv3/internal.xml.i>
- #include <include/ospfv3/linkstate-id.xml.i>
- #include <include/ospfv3/linkstate-id-node-tag.xml.i>
- #include <include/ospfv3/self-originated.xml.i>
- </children>
- </node>
- <node name="inter-router">
- <properties>
- <help>Show Inter-Area-Router LSAs</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/ospfv3/adv-router.xml.i>
- #include <include/ospfv3/detail.xml.i>
- #include <include/ospfv3/dump.xml.i>
- #include <include/ospfv3/internal.xml.i>
- #include <include/ospfv3/linkstate-id.xml.i>
- #include <include/ospfv3/linkstate-id-node-tag.xml.i>
- #include <include/ospfv3/self-originated.xml.i>
- </children>
- </node>
- <node name="intra-prefix">
- <properties>
- <help>Show Intra-Area-Prefix LSAs</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/ospfv3/adv-router.xml.i>
- #include <include/ospfv3/detail.xml.i>
- #include <include/ospfv3/dump.xml.i>
- #include <include/ospfv3/internal.xml.i>
- #include <include/ospfv3/linkstate-id.xml.i>
- #include <include/ospfv3/linkstate-id-node-tag.xml.i>
- #include <include/ospfv3/self-originated.xml.i>
- </children>
- </node>
- <node name="link">
- <properties>
- <help>Show Link LSAs</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/ospfv3/adv-router.xml.i>
- #include <include/ospfv3/detail.xml.i>
- #include <include/ospfv3/dump.xml.i>
- #include <include/ospfv3/internal.xml.i>
- #include <include/ospfv3/linkstate-id.xml.i>
- #include <include/ospfv3/linkstate-id-node-tag.xml.i>
- #include <include/ospfv3/self-originated.xml.i>
- </children>
- </node>
- <node name="network">
- <properties>
- <help>Show Network LSAs</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/ospfv3/adv-router.xml.i>
- #include <include/ospfv3/detail.xml.i>
- #include <include/ospfv3/dump.xml.i>
- #include <include/ospfv3/internal.xml.i>
- #include <include/ospfv3/linkstate-id.xml.i>
- #include <include/ospfv3/linkstate-id-node-tag.xml.i>
- #include <include/ospfv3/self-originated.xml.i>
- </children>
- </node>
- <node name="node.tag">
- <properties>
- <help>Show LSAs</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/ospfv3/adv-router.xml.i>
- #include <include/ospfv3/detail.xml.i>
- #include <include/ospfv3/dump.xml.i>
- #include <include/ospfv3/internal.xml.i>
- #include <include/ospfv3/linkstate-id.xml.i>
- #include <include/ospfv3/linkstate-id-node-tag.xml.i>
- #include <include/ospfv3/self-originated.xml.i>
- </children>
- </node>
- <node name="router">
- <properties>
- <help>Show router LSAs</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/ospfv3/adv-router.xml.i>
- #include <include/ospfv3/detail.xml.i>
- #include <include/ospfv3/dump.xml.i>
- #include <include/ospfv3/internal.xml.i>
- #include <include/ospfv3/linkstate-id.xml.i>
- #include <include/ospfv3/linkstate-id-node-tag.xml.i>
- #include <include/ospfv3/self-originated.xml.i>
- </children>
- </node>
- <node name="type-7">
- <properties>
- <help>Show Type-7 LSAs</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/ospfv3/adv-router.xml.i>
- #include <include/ospfv3/detail.xml.i>
- #include <include/ospfv3/dump.xml.i>
- #include <include/ospfv3/internal.xml.i>
- #include <include/ospfv3/linkstate-id.xml.i>
- #include <include/ospfv3/linkstate-id-node-tag.xml.i>
- #include <include/ospfv3/self-originated.xml.i>
- </children>
- </node>
- </children>
</node>
- <node name="interface">
+ <tagNode name="vrf">
<properties>
- <help>Show OSPFv3 interface information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- <node name="prefix">
- <properties>
- <help>Show connected prefixes to advertise</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/ospfv3/detail.xml.i>
- </children>
- </node>
- <tagNode name="prefix">
- <properties>
- <help>Show interface prefix route specific information</help>
- <completionHelp>
- <list>&lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/ospfv3/detail.xml.i>
- <node name="match">
- <properties>
- <help>Matched interface prefix information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </node>
- </children>
- </tagNode>
- </children>
- </node>
- <tagNode name="interface">
- <properties>
- <help>Specific insterface to examine</help>
+ <help>VRF name</help>
<completionHelp>
- <script>${vyos_completion_dir}/list_interfaces.py</script>
+ <list>all</list>
+ <path>vrf name</path>
</completionHelp>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
- <node name="prefix">
+ <node name="area">
<properties>
- <help>Show connected prefixes to advertise</help>
+ <help>Show Shortest Path First tree information</help>
</properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/ospfv3/detail.xml.i>
- </children>
+ <command>vtysh -c "show ipv6 ospf6 vrf $5 spf tree"</command>
</node>
- <tagNode name="prefix">
+ <tagNode name="area">
<properties>
- <help>Show interface prefix route specific information</help>
+ <help>Area ID (as an IPv4 notation)</help>
<completionHelp>
- <list>&lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
+ <path>protocols ospfv3 area</path>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <command>vtysh -c "show ipv6 ospf6 vrf $5 area $7 spf tree"</command>
<children>
- #include <include/ospfv3/detail.xml.i>
- <node name="match">
+ <tagNode name="router">
<properties>
- <help>Matched interface prefix information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </node>
- </children>
- </tagNode>
- </children>
- </tagNode>
- <node name="linkstate">
- <properties>
- <help>Show OSPFv3 linkstate routing information</help>
- </properties>
- <children>
- #include <include/ospfv3/detail.xml.i>
- <tagNode name="network">
- <properties>
- <help>Show linkstate Network information</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
- </completionHelp>
- </properties>
- <children>
- <node name="node.tag">
- <properties>
- <help>Specify Link state ID as IPv4 address notation</help>
+ <help> Simulate view point (Router ID)</help>
<completionHelp>
<list>&lt;x.x.x.x&gt;</list>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </node>
+ <command>vtysh -c "show ipv6 ospf6 vrf $5 simulate spf-tree $9 $6 $7"</command>
+ </tagNode>
</children>
</tagNode>
- <tagNode name="router">
- <properties>
- <help>Show linkstate Router information</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </tagNode>
- </children>
- </node>
- <node name="neighbor">
- <properties>
- <help>Show OSPFv3 neighbor information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/ospfv3/detail.xml.i>
- <node name="drchoice">
- <properties>
- <help>Show neighbor DR choice information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </node>
+ #include <include/ospfv3/border-routers.xml.i>
+ #include <include/ospfv3/database.xml.i>
+ #include <include/ospfv3/interface.xml.i>
+ #include <include/ospfv3/linkstate.xml.i>
+ #include <include/ospfv3/neighbor.xml.i>
+ #include <include/ospfv3/redistribute.xml.i>
+ #include <include/ospfv3/route.xml.i>
</children>
- </node>
- <node name="redistribute">
- <properties>
- <help>Show OSPFv3 redistribute external information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </node>
- <node name="route">
- <properties>
- <help>Show OSPFv3 routing table information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- <node name="external-1">
- <properties>
- <help>Show Type-1 External route information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/ospfv3/detail.xml.i>
- </children>
- </node>
- <node name="external-2">
- <properties>
- <help>Show Type-2 External route information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/ospfv3/detail.xml.i>
- </children>
- </node>
- <node name="inter-area">
- <properties>
- <help>Show Inter-Area route information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/ospfv3/detail.xml.i>
- </children>
- </node>
- <node name="intra-area">
- <properties>
- <help>Show Intra-Area route information</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/ospfv3/detail.xml.i>
- </children>
- </node>
- #include <include/ospfv3/detail.xml.i>
- <node name="summary">
- <properties>
- <help>Show route table summary</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </node>
- </children>
- </node>
- <tagNode name="route">
+ </tagNode>
+ <leafNode name="vrfs">
<properties>
- <help>Show specified route/prefix information</help>
- <completionHelp>
- <list>&lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
- </completionHelp>
+ <help>Show OSPFv3 VRFs</help>
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- <node name="longer">
- <properties>
- <help>Show routes longer than specified prefix</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </node>
- <node name="match">
- <properties>
- <help>Show routes matching specified prefix</help>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- <children>
- #include <include/ospfv3/detail.xml.i>
- </children>
- </node>
- </children>
- </tagNode>
+ </leafNode>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-ipv6-route.xml.in b/op-mode-definitions/show-ipv6-route.xml.in
index 8624574ac..2c5024991 100644
--- a/op-mode-definitions/show-ipv6-route.xml.in
+++ b/op-mode-definitions/show-ipv6-route.xml.in
@@ -13,12 +13,7 @@
</properties>
<command>vtysh -c "show ipv6 route"</command>
<children>
- <node name="bgp">
- <properties>
- <help>Show IPv6 BGP routes</help>
- </properties>
- <command>vtysh -c "show ipv6 route bgp"</command>
- </node>
+ #include <include/show-route-bgp.xml.i>
<node name="cache">
<properties>
<help>Show kernel IPv6 route cache</help>
@@ -34,12 +29,7 @@
</properties>
<command>ip -s -f inet6 route list cache $5</command>
</tagNode>
- <node name="connected">
- <properties>
- <help>Show IPv6 connected routes</help>
- </properties>
- <command>vtysh -c "show ipv6 route connected"</command>
- </node>
+ #include <include/show-route-connected.xml.i>
<node name="forward">
<properties>
<help>Show kernel IPv6 route table</help>
@@ -55,71 +45,36 @@
</properties>
<command>ip -s -f inet6 route list $5</command>
</tagNode>
- <node name="isis">
- <properties>
- <help>Show IPv6 IS-IS routes</help>
- </properties>
- <command>vtysh -c "show ipv6 route isis"</command>
- </node>
- <node name="kernel">
- <properties>
- <help>Show IPv6 Kernel routes</help>
- </properties>
- <command>vtysh -c "show ipv6 route kernel"</command>
- </node>
- <node name="ospfv3">
- <properties>
- <help>Show IPv6 OSPF routes</help>
- </properties>
- <command>vtysh -c "show ipv6 route ospf6"</command>
- </node>
- <node name="ripng">
- <properties>
- <help>Show IPv6 RIPNG routes</help>
- </properties>
- <command>vtysh -c "show ipv6 route ripng"</command>
- </node>
- <node name="static">
- <properties>
- <help>Show IPv6 static routes</help>
- </properties>
- <command>vtysh -c "show ipv6 route static"</command>
- </node>
- <node name="summary">
- <properties>
- <help>Show IPv6 routes summary</help>
- </properties>
- <command>vtysh -c "show ipv6 route summary"</command>
- </node>
- <node name="table">
- <properties>
- <help>Show IPv6 routes in policy tables</help>
- </properties>
- <command>vtysh -c "show ipv6 route table all"</command>
- </node>
- <tagNode name="table">
- <properties>
- <help>Show IPv6 routes in specific policy table</help>
- <completionHelp>
- <path>protocols static table</path>
- </completionHelp>
- </properties>
- <command>vtysh -c "show ipv6 route table $5"</command>
- </tagNode>
- <node name="vrf">
- <properties>
- <help>Show IPv6 routes in VRFs</help>
- </properties>
- <command>vtysh -c "show ipv6 route vrf all"</command>
- </node>
+ #include <include/show-route-isis.xml.i>
+ #include <include/show-route-kernel.xml.i>
+ #include <include/show-route-ospfv3.xml.i>
+ #include <include/show-route-ripng.xml.i>
+ #include <include/show-route-static.xml.i>
+ #include <include/show-route-summary.xml.i>
+ #include <include/show-route-table.xml.i>
+ #include <include/show-route-tag.xml.i>
<tagNode name="vrf">
<properties>
- <help>Show IPv6 routes in specific VRF</help>
+ <help>Show IPv6 routes in VRF</help>
<completionHelp>
+ <list>all</list>
<path>vrf name</path>
</completionHelp>
</properties>
- <command>vtysh -c "show ipv6 route vrf $5"</command>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ #include <include/show-route-bgp.xml.i>
+ #include <include/show-route-connected.xml.i>
+ #include <include/show-route-isis.xml.i>
+ #include <include/show-route-kernel.xml.i>
+ #include <include/show-route-ospfv3.xml.i>
+ #include <include/show-route-ripng.xml.i>
+ #include <include/show-route-static.xml.i>
+ #include <include/show-route-summary.xml.i>
+ #include <include/show-route-supernets-only.xml.i>
+ #include <include/show-route-table.xml.i>
+ #include <include/show-route-tag.xml.i>
+ </children>
</tagNode>
</children>
</node>
diff --git a/op-mode-definitions/show-log.xml.in b/op-mode-definitions/show-log.xml.in
index 4c0a7913b..76879e5d6 100644
--- a/op-mode-definitions/show-log.xml.in
+++ b/op-mode-definitions/show-log.xml.in
@@ -139,6 +139,12 @@
</tagNode>
</children>
</node>
+ <leafNode name="flow-accounting">
+ <properties>
+ <help>Show log for flow-accounting</help>
+ </properties>
+ <command>journalctl --no-hostname --boot --unit uacctd.service</command>
+ </leafNode>
<leafNode name="https">
<properties>
<help>Show log for HTTPs</help>
@@ -179,9 +185,9 @@
</tagNode>
<leafNode name="kernel">
<properties>
- <help>Show messages in kernel ring buffer</help>
+ <help>Show log for Linux Kernel</help>
</properties>
- <command>sudo dmesg</command>
+ <command>journalctl --no-hostname --boot --dmesg</command>
</leafNode>
<leafNode name="lldp">
<properties>
@@ -195,6 +201,12 @@
</properties>
<command>egrep -i "kernel:.*\[NAT-[A-Z]{3,}-[0-9]+(-MASQ)?\]" $(find /var/log -maxdepth 1 -type f -name messages\* | sort -t. -k2nr)</command>
</leafNode>
+ <leafNode name="nhrp">
+ <properties>
+ <help>Show log for NHRP</help>
+ </properties>
+ <command>journalctl --no-hostname --boot --unit opennhrp.service</command>
+ </leafNode>
<node name="openvpn">
<properties>
<help>Show log for OpenVPN</help>
@@ -212,6 +224,96 @@
</tagNode>
</children>
</node>
+ <node name="pppoe">
+ <properties>
+ <help>Show log for PPPoE</help>
+ </properties>
+ <command>journalctl --no-hostname --boot --unit "ppp@pppoe*.service"</command>
+ <children>
+ <tagNode name="interface">
+ <properties>
+ <help>Show PPPoE log on specific interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces.py -t pppoe</script>
+ </completionHelp>
+ </properties>
+ <command>journalctl --no-hostname --boot --unit "ppp@$6.service"</command>
+ </tagNode>
+ </children>
+ </node>
+ <node name="protocol">
+ <properties>
+ <help>Show log for Routing Protocols</help>
+ </properties>
+ <children>
+ <leafNode name="ospf">
+ <properties>
+ <help>Show log for OSPF</help>
+ </properties>
+ <command>journalctl --boot /usr/lib/frr/ospfd</command>
+ </leafNode>
+ <leafNode name="ospfv3">
+ <properties>
+ <help>Show log for OSPF for IPv6</help>
+ </properties>
+ <command>journalctl --boot /usr/lib/frr/ospf6d</command>
+ </leafNode>
+ <leafNode name="bgp">
+ <properties>
+ <help>Show log for BGP</help>
+ </properties>
+ <command>journalctl --boot /usr/lib/frr/bgpd</command>
+ </leafNode>
+ <leafNode name="rip">
+ <properties>
+ <help>Show log for RIP</help>
+ </properties>
+ <command>journalctl --boot /usr/lib/frr/ripd</command>
+ </leafNode>
+ <leafNode name="ripng">
+ <properties>
+ <help>Show log for RIPng</help>
+ </properties>
+ <command>journalctl --boot /usr/lib/frr/ripngd</command>
+ </leafNode>
+ <leafNode name="static">
+ <properties>
+ <help>Show log for static route</help>
+ </properties>
+ <command>journalctl --boot /usr/lib/frr/staticd</command>
+ </leafNode>
+ <leafNode name="multicast">
+ <properties>
+ <help>Show log for Multicast protocol</help>
+ </properties>
+ <command>journalctl --boot /usr/lib/frr/pimd</command>
+ </leafNode>
+ <leafNode name="isis">
+ <properties>
+ <help>Show log for ISIS</help>
+ </properties>
+ <command>journalctl --boot /usr/lib/frr/isisd</command>
+ </leafNode>
+ <leafNode name="nhrp">
+ <properties>
+ <help>Show log for NHRP</help>
+ </properties>
+ <command>journalctl --boot /usr/lib/frr/nhrpd</command>
+ </leafNode>
+ <leafNode name="bfd">
+ <properties>
+ <help>Show log for BFD</help>
+ </properties>
+ <command>journalctl --boot /usr/lib/frr/bfdd</command>
+ </leafNode>
+ <leafNode name="mpls">
+ <properties>
+ <help>Show log for MPLS</help>
+ </properties>
+ <command>journalctl --boot /usr/lib/frr/ldpd</command>
+ </leafNode>
+ </children>
+ </node>
<leafNode name="snmp">
<properties>
<help>Show log for Simple Network Monitoring Protocol (SNMP)</help>
diff --git a/op-mode-definitions/show-netns.xml.in b/op-mode-definitions/show-netns.xml.in
new file mode 100644
index 000000000..8d5072d4e
--- /dev/null
+++ b/op-mode-definitions/show-netns.xml.in
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="show">
+ <children>
+ <node name="netns">
+ <properties>
+ <help>Show network namespace information</help>
+ </properties>
+ <command>ip netns ls</command>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/op-mode-definitions/show-protocols.xml.in b/op-mode-definitions/show-protocols.xml.in
index d595e2c3c..698001b76 100644
--- a/op-mode-definitions/show-protocols.xml.in
+++ b/op-mode-definitions/show-protocols.xml.in
@@ -7,50 +7,6 @@
<help>Show protocol specific information</help>
</properties>
<children>
- <node name="bfd">
- <properties>
- <help>Show Bidirectional Forwarding Detection (BFD)</help>
- </properties>
- <children>
- <node name="peer">
- <properties>
- <help>Show all Bidirectional Forwarding Detection (BFD) peer status</help>
- </properties>
- <command>vtysh -c "show bfd peers"</command>
- <children>
- <leafNode name="counters">
- <properties>
- <help>Show Bidirectional Forwarding Detection (BFD) peer counters</help>
- </properties>
- <command>vtysh -c "show bfd peers counters"</command>
- </leafNode>
- </children>
- </node>
- <tagNode name="peer">
- <properties>
- <help>Show Bidirectional Forwarding Detection (BFD) peer status</help>
- <completionHelp>
- <script>vtysh -c "show bfd peers" | awk '/[:blank:]*peer/ { printf "%s\n", $2 }'</script>
- </completionHelp>
- </properties>
- <command>vtysh -c "show bfd peers" | awk -v BFD_PEER=$5 'BEGIN { regex = sprintf("(peer %s.*)vrf", BFD_PEER) } { if (match($0, regex, bfd_peer_value)) peer=bfd_peer_value[1] } END { if (peer) system("vtysh -c \"show bfd " peer "\"") }'</command>
- <children>
- <leafNode name="counters">
- <properties>
- <help>Show Bidirectional Forwarding Detection (BFD) peer counters</help>
- </properties>
- <command>vtysh -c "show bfd peers" | awk -v BFD_PEER=$5 'BEGIN { regex = sprintf("(peer %s.*)vrf", BFD_PEER) } { if (match($0, regex, bfd_peer_value)) peer=bfd_peer_value[1] } END { if (peer) system("vtysh -c \"show bfd " peer " counters\"") }'</command>
- </leafNode>
- </children>
- </tagNode>
- <leafNode name="peers">
- <properties>
- <help>Show Bidirectional Forwarding Detection (BFD) peers brief</help>
- </properties>
- <command>vtysh -c "show bfd peers brief"</command>
- </leafNode>
- </children>
- </node>
<node name="static">
<properties>
<help>Show static protocol parameters</help>
diff --git a/op-mode-definitions/show-system.xml.in b/op-mode-definitions/show-system.xml.in
index 0f852164e..68b473bc1 100644
--- a/op-mode-definitions/show-system.xml.in
+++ b/op-mode-definitions/show-system.xml.in
@@ -166,9 +166,9 @@
</leafNode>
<leafNode name="uptime">
<properties>
- <help>Show how long the system has been up</help>
+ <help>Show system uptime and load averages</help>
</properties>
- <command>uptime</command>
+ <command>${vyos_op_scripts_dir}/show_uptime.py</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/show-virtual-server.xml.in b/op-mode-definitions/show-virtual-server.xml.in
new file mode 100644
index 000000000..5dbd3c759
--- /dev/null
+++ b/op-mode-definitions/show-virtual-server.xml.in
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interfaceDefinition>
+ <node name="show">
+ <children>
+ <node name="virtual-server">
+ <properties>
+ <help>Show virtual server information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/show_virtual_server.py</command>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/op-mode-definitions/traceroute.xml.in b/op-mode-definitions/traceroute.xml.in
index e3217235c..aba0f45e3 100644
--- a/op-mode-definitions/traceroute.xml.in
+++ b/op-mode-definitions/traceroute.xml.in
@@ -2,226 +2,22 @@
<interfaceDefinition>
<tagNode name="traceroute">
<properties>
- <help>Track network path to node</help>
- <completionHelp>
- <list>&lt;hostname&gt; &lt;x.x.x.x&gt; &lt;h:h:h:h:h:h:h:h&gt;</list>
- </completionHelp>
- </properties>
- <command>/usr/bin/traceroute "$2"</command>
- </tagNode>
- <node name="traceroute">
- <properties>
- <help>Track network path to node</help>
+ <help>Trace network path to node</help>
<completionHelp>
<list>&lt;hostname&gt; &lt;x.x.x.x&gt; &lt;h:h:h:h:h:h:h:h&gt;</list>
</completionHelp>
</properties>
+ <command>${vyos_op_scripts_dir}/traceroute.py ${@:2}</command>
<children>
- <tagNode name="ipv4">
+ <leafNode name="node.tag">
<properties>
- <help>Explicitly use IPv4 when tracing the path</help>
+ <help>Traceroute options</help>
<completionHelp>
- <list>&lt;hostname&gt; &lt;x.x.x.x&gt;</list>
+ <script>${vyos_op_scripts_dir}/traceroute.py --get-options "${COMP_WORDS[@]}"</script>
</completionHelp>
</properties>
- <command>/usr/bin/traceroute -4 "$3"</command>
- <children>
- <node name="tcp">
- <properties>
- <help>Route tracing and port detection using TCP</help>
- </properties>
- <command>sudo /usr/bin/tcptraceroute "$3" </command>
- <children>
- <tagNode name="port">
- <properties>
- <help>TCP port to connect to for path tracing</help>
- <completionHelp>
- <list>0-65535</list>
- </completionHelp>
- </properties>
- <command>sudo /usr/bin/tcptraceroute "$3" $6</command>
- </tagNode>
- </children>
- </node>
- </children>
- </tagNode>
- <tagNode name="ipv6">
- <properties>
- <help>Explicitly use IPv6 when tracing the path</help>
- <completionHelp>
- <list>&lt;hostname&gt; &lt;h:h:h:h:h:h:h:h&gt;</list>
- </completionHelp>
- </properties>
- <command>/usr/bin/traceroute -6 "$3"</command>
- <children>
- <node name="tcp">
- <properties>
- <help>Use TCP/IPv6 packets to perform a traceroute</help>
- </properties>
- <command>sudo /usr/bin/tcptraceroute6 "$3" </command>
- <children>
- <tagNode name="port">
- <properties>
- <help>TCP port to connect to for path tracing</help>
- <completionHelp>
- <list>0-65535</list>
- </completionHelp>
- </properties>
- <command>sudo /usr/bin/tcptraceroute6 "$3" $6</command>
- </tagNode>
- </children>
- </node>
- </children>
- </tagNode>
- <tagNode name="vrf">
- <properties>
- <help>Track network path to specified node via given VRF</help>
- <completionHelp>
- <path>vrf name</path>
- </completionHelp>
- </properties>
- <children>
- <!-- we need an empty tagNode to pass in a plain fqdn/ip address and
- let traceroute decide how to handle this parameter -->
- <tagNode name="">
- <properties>
- <help>Track network path to specified node via given VRF</help>
- <completionHelp>
- <list>&lt;hostname&gt; &lt;x.x.x.x&gt; &lt;h:h:h:h:h:h:h:h&gt;</list>
- </completionHelp>
- </properties>
- <command>sudo ip vrf exec "$3" /usr/bin/traceroute "$4"</command>
- </tagNode>
- <tagNode name="ipv4">
- <properties>
- <help>Explicitly use IPv4 when tracing the path via given VRF</help>
- <completionHelp>
- <list>&lt;hostname&gt; &lt;x.x.x.x&gt;</list>
- </completionHelp>
- </properties>
- <command>sudo ip vrf exec "$3" /usr/bin/traceroute -4 "$5"</command>
- <children>
- <node name="tcp">
- <properties>
- <help>Route tracing and port detection using TCP</help>
- </properties>
- <command>sudo ip vrf exec "$3" /usr/bin/tcptraceroute "$5" </command>
- <children>
- <tagNode name="port">
- <properties>
- <help>TCP port to connect to for path tracing</help>
- <completionHelp>
- <list>0-65535</list>
- </completionHelp>
- </properties>
- <command>sudo ip vrf exec "$3" /usr/bin/tcptraceroute "$5" $8</command>
- </tagNode>
- </children>
- </node>
- </children>
- </tagNode>
- <tagNode name="ipv6">
- <properties>
- <help>Explicitly use IPv6 when tracing the path via given VRF</help>
- <completionHelp>
- <list>&lt;hostname&gt; &lt;h:h:h:h:h:h:h:h&gt;</list>
- </completionHelp>
- </properties>
- <command>sudo ip vrf exec "$3" /usr/bin/traceroute -6 "$5"</command>
- <children>
- <node name="tcp">
- <properties>
- <help>Use TCP/IPv6 packets to perform a traceroute</help>
- </properties>
- <command>sudo ip vrf exec "$3" /usr/bin/tcptraceroute6 "$5" </command>
- <children>
- <tagNode name="port">
- <properties>
- <help>TCP port to connect to for path tracing</help>
- <completionHelp>
- <list>0-65535</list>
- </completionHelp>
- </properties>
- <command>sudo ip vrf exec "$3" /usr/bin/tcptraceroute6 "$5" $8</command>
- </tagNode>
- </children>
- </node>
- </children>
- </tagNode>
- </children>
- </tagNode>
- </children>
- </node>
- <node name="monitor">
- <children>
- <tagNode name="traceroute">
- <properties>
- <help>Monitor path to destination in realtime</help>
- <completionHelp>
- <list>&lt;hostname&gt; &lt;x.x.x.x&gt; &lt;h:h:h:h:h:h:h:h&gt;</list>
- </completionHelp>
- </properties>
- <command>/usr/bin/mtr "$3"</command>
- </tagNode>
- <node name="traceroute">
- <children>
- <tagNode name="ipv4">
- <properties>
- <help>IPv4 fully qualified domain name (FQDN)</help>
- <completionHelp>
- <list>&lt;fqdn&gt;</list>
- </completionHelp>
- </properties>
- <command>/usr/bin/mtr -4 "$4"</command>
- </tagNode>
- <tagNode name="ipv6">
- <properties>
- <help>IPv6 fully qualified domain name (FQDN)</help>
- <completionHelp>
- <list>&lt;fqdn&gt;</list>
- </completionHelp>
- </properties>
- <command>/usr/bin/mtr -6 "$4"</command>
- </tagNode>
- <tagNode name="vrf">
- <properties>
- <help>Monitor path to destination in realtime via given VRF</help>
- <completionHelp>
- <path>vrf name</path>
- </completionHelp>
- </properties>
- <children>
- <tagNode name="ipv4">
- <properties>
- <help>IPv4 fully qualified domain name (FQDN)</help>
- <completionHelp>
- <list>&lt;fqdn&gt;</list>
- </completionHelp>
- </properties>
- <command>sudo ip vrf exec "$4" /usr/bin/mtr -4 "$6"</command>
- </tagNode>
- <tagNode name="ipv6">
- <properties>
- <help>IPv6 fully qualified domain name (FQDN)</help>
- <completionHelp>
- <list>&lt;fqdn&gt;</list>
- </completionHelp>
- </properties>
- <command>sudo ip vrf exec "$4" /usr/bin/mtr -6 "$6"</command>
- </tagNode>
- <tagNode name="">
- <properties>
- <help>Track network path to specified node via given VRF</help>
- <completionHelp>
- <list>&lt;hostname&gt; &lt;x.x.x.x&gt; &lt;h:h:h:h:h:h:h:h&gt;</list>
- </completionHelp>
- </properties>
- <command>sudo ip vrf exec "$4" /usr/bin/mtr "$5"</command>
- </tagNode>
- </children>
- </tagNode>
- </children>
- </node>
+ <command>${vyos_op_scripts_dir}/traceroute.py ${@:2}</command>
+ </leafNode>
</children>
- </node>
+ </tagNode>
</interfaceDefinition>
diff --git a/op-mode-definitions/zone-policy.xml.in b/op-mode-definitions/zone-policy.xml.in
new file mode 100644
index 000000000..c4b02bcee
--- /dev/null
+++ b/op-mode-definitions/zone-policy.xml.in
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="show">
+ <children>
+ <node name="zone-policy">
+ <properties>
+ <help>Show zone policy information</help>
+ </properties>
+ <children>
+ <tagNode name="zone">
+ <properties>
+ <help>Show summary of zone policy for a specific zone</help>
+ <completionHelp>
+ <path>zone-policy zone</path>
+ </completionHelp>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/zone_policy.py --action show --name $4</command>
+ </tagNode>
+ </children>
+ <command>sudo ${vyos_op_scripts_dir}/zone_policy.py --action show</command>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/python/vyos/base.py b/python/vyos/base.py
index 4e23714e5..78067d5b2 100644
--- a/python/vyos/base.py
+++ b/python/vyos/base.py
@@ -1,4 +1,4 @@
-# Copyright 2018 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright 2018-2022 VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -13,6 +13,23 @@
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
+from textwrap import fill
+
+class Warning():
+ def __init__(self, message):
+ # Reformat the message and trim it to 72 characters in length
+ message = fill(message, width=72)
+ print(f'\nWARNING: {message}')
+
+class DeprecationWarning():
+ def __init__(self, message):
+ # Reformat the message and trim it to 72 characters in length
+ message = fill(message, width=72)
+ print(f'\nDEPRECATION WARNING: {message}\n')
class ConfigError(Exception):
- pass
+ def __init__(self, message):
+ # Reformat the message and trim it to 72 characters in length
+ message = fill(message, width=72)
+ # Call the base class constructor with the parameters it needs
+ super().__init__(message)
diff --git a/python/vyos/config.py b/python/vyos/config.py
index a5c1ad122..287fd2ed1 100644
--- a/python/vyos/config.py
+++ b/python/vyos/config.py
@@ -142,31 +142,41 @@ class Config(object):
def exists(self, path):
"""
- Checks if a node with given path exists in the running or proposed config
+ Checks if a node or value with given path exists in the proposed config.
+
+ Args:
+ path (str): Configuration tree path
Returns:
- True if node exists, False otherwise
+ True if node or value exists in the proposed config, False otherwise
Note:
- This function cannot be used outside a configuration sessions.
+ This function should not be used outside of configuration sessions.
In operational mode scripts, use ``exists_effective``.
"""
- if not self._session_config:
+ if self._session_config is None:
return False
+
+ # Assume the path is a node path first
if self._session_config.exists(self._make_path(path)):
return True
else:
+ # If that check fails, it may mean the path has a value at the end.
# libvyosconfig exists() works only for _nodes_, not _values_
- # libvyattacfg one also worked for values, so we emulate that case here
+ # libvyattacfg also worked for values, so we emulate that case here
if isinstance(path, str):
path = re.split(r'\s+', path)
path_without_value = path[:-1]
- path_str = " ".join(path_without_value)
try:
- value = self._session_config.return_value(self._make_path(path_str))
- return (value == path[-1])
+ # return_values() is safe to use with single-value nodes,
+ # it simply returns a single-item list in that case.
+ values = self._session_config.return_values(self._make_path(path_without_value))
+
+ # If we got this far, the node does exist and has values,
+ # so we need to check if it has the value in question among its values.
+ return (path[-1] in values)
except vyos.configtree.ConfigTreeError:
- # node doesn't exist at all
+ # Even the parent node doesn't exist at all
return False
def session_changed(self):
@@ -380,7 +390,7 @@ class Config(object):
def exists_effective(self, path):
"""
- Check if a node exists in the running (effective) config
+ Checks if a node or value exists in the running (effective) config.
Args:
path (str): Configuration tree path
@@ -392,10 +402,31 @@ class Config(object):
This function is safe to use in operational mode. In configuration mode,
it ignores uncommited changes.
"""
- if self._running_config:
- return(self._running_config.exists(self._make_path(path)))
+ if self._running_config is None:
+ return False
+
+ # Assume the path is a node path first
+ if self._running_config.exists(self._make_path(path)):
+ return True
+ else:
+ # If that check fails, it may mean the path has a value at the end.
+ # libvyosconfig exists() works only for _nodes_, not _values_
+ # libvyattacfg also worked for values, so we emulate that case here
+ if isinstance(path, str):
+ path = re.split(r'\s+', path)
+ path_without_value = path[:-1]
+ try:
+ # return_values() is safe to use with single-value nodes,
+ # it simply returns a single-item list in that case.
+ values = self._running_config.return_values(self._make_path(path_without_value))
+
+ # If we got this far, the node does exist and has values,
+ # so we need to check if it has the value in question among its values.
+ return (path[-1] in values)
+ except vyos.configtree.ConfigTreeError:
+ # Even the parent node doesn't exist at all
+ return False
- return False
def return_effective_value(self, path, default=None):
"""
diff --git a/python/vyos/configdict.py b/python/vyos/configdict.py
index 425a2e416..04ddc10e9 100644
--- a/python/vyos/configdict.py
+++ b/python/vyos/configdict.py
@@ -1,4 +1,4 @@
-# Copyright 2019 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright 2019-2022 VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -104,6 +104,11 @@ def list_diff(first, second):
second = set(second)
return [item for item in first if item not in second]
+def is_node_changed(conf, path):
+ from vyos.configdiff import get_config_diff
+ D = get_config_diff(conf, key_mangling=('-', '_'))
+ return D.is_node_changed(path)
+
def leaf_node_changed(conf, path):
"""
Check if a leaf node was altered. If it has been altered - values has been
@@ -114,9 +119,14 @@ def leaf_node_changed(conf, path):
"""
from vyos.configdiff import get_config_diff
D = get_config_diff(conf, key_mangling=('-', '_'))
- D.set_level(conf.get_level())
(new, old) = D.get_value_diff(path)
if new != old:
+ if isinstance(old, dict):
+ # valueLess nodes return {} if node is deleted
+ return True
+ if old is None and isinstance(new, dict):
+ # valueLess nodes return {} if node was added
+ return True
if old is None:
return []
if isinstance(old, str):
@@ -130,7 +140,7 @@ def leaf_node_changed(conf, path):
return None
-def node_changed(conf, path, key_mangling=None):
+def node_changed(conf, path, key_mangling=None, recursive=False):
"""
Check if a leaf node was altered. If it has been altered - values has been
changed, or it was added/removed, we will return the old value. If nothing
@@ -138,12 +148,11 @@ def node_changed(conf, path, key_mangling=None):
"""
from vyos.configdiff import get_config_diff, Diff
D = get_config_diff(conf, key_mangling)
- D.set_level(conf.get_level())
# get_child_nodes() will return dict_keys(), mangle this into a list with PEP448
- keys = D.get_child_nodes_diff(path, expand_nodes=Diff.DELETE)['delete'].keys()
+ keys = D.get_child_nodes_diff(path, expand_nodes=Diff.DELETE, recursive=recursive)['delete'].keys()
return list(keys)
-def get_removed_vlans(conf, dict):
+def get_removed_vlans(conf, path, dict):
"""
Common function to parse a dictionary retrieved via get_config_dict() and
determine any added/removed VLAN interfaces - be it 802.1q or Q-in-Q.
@@ -153,16 +162,17 @@ def get_removed_vlans(conf, dict):
# Check vif, vif-s/vif-c VLAN interfaces for removal
D = get_config_diff(conf, key_mangling=('-', '_'))
D.set_level(conf.get_level())
+
# get_child_nodes() will return dict_keys(), mangle this into a list with PEP448
- keys = D.get_child_nodes_diff(['vif'], expand_nodes=Diff.DELETE)['delete'].keys()
+ keys = D.get_child_nodes_diff(path + ['vif'], expand_nodes=Diff.DELETE)['delete'].keys()
if keys: dict['vif_remove'] = [*keys]
# get_child_nodes() will return dict_keys(), mangle this into a list with PEP448
- keys = D.get_child_nodes_diff(['vif-s'], expand_nodes=Diff.DELETE)['delete'].keys()
+ keys = D.get_child_nodes_diff(path + ['vif-s'], expand_nodes=Diff.DELETE)['delete'].keys()
if keys: dict['vif_s_remove'] = [*keys]
for vif in dict.get('vif_s', {}).keys():
- keys = D.get_child_nodes_diff(['vif-s', vif, 'vif-c'], expand_nodes=Diff.DELETE)['delete'].keys()
+ keys = D.get_child_nodes_diff(path + ['vif-s', vif, 'vif-c'], expand_nodes=Diff.DELETE)['delete'].keys()
if keys: dict['vif_s'][vif]['vif_c_remove'] = [*keys]
return dict
@@ -196,7 +206,7 @@ def is_member(conf, interface, intftype=None):
interface name -> Interface is a member of this interface
False -> interface type cannot have members
"""
- ret_val = None
+ ret_val = {}
intftypes = ['bonding', 'bridge']
if intftype not in intftypes + [None]:
@@ -206,20 +216,15 @@ def is_member(conf, interface, intftype=None):
intftype = intftypes if intftype == None else [intftype]
- # set config level to root
- old_level = conf.get_level()
- conf.set_level([])
-
for iftype in intftype:
base = ['interfaces', iftype]
for intf in conf.list_nodes(base):
member = base + [intf, 'member', 'interface', interface]
if conf.exists(member):
tmp = conf.get_config_dict(member, key_mangling=('-', '_'),
- get_first_key=True)
- ret_val = {intf : tmp}
+ get_first_key=True, no_tag_node_value_mangle=True)
+ ret_val.update({intf : tmp})
- old_level = conf.set_level(old_level)
return ret_val
def is_mirror_intf(conf, interface, direction=None):
@@ -241,8 +246,6 @@ def is_mirror_intf(conf, interface, direction=None):
direction = directions if direction == None else [direction]
ret_val = None
- old_level = conf.get_level()
- conf.set_level([])
base = ['interfaces']
for dir in direction:
@@ -256,7 +259,6 @@ def is_mirror_intf(conf, interface, direction=None):
get_first_key=True)
ret_val = {intf : tmp}
- old_level = conf.set_level(old_level)
return ret_val
def has_vlan_subinterface_configured(conf, intf):
@@ -270,15 +272,11 @@ def has_vlan_subinterface_configured(conf, intf):
from vyos.ifconfig import Section
ret = False
- old_level = conf.get_level()
- conf.set_level([])
-
intfpath = ['interfaces', Section.section(intf), intf]
if ( conf.exists(intfpath + ['vif']) or
conf.exists(intfpath + ['vif-s'])):
ret = True
- conf.set_level(old_level)
return ret
def is_source_interface(conf, interface, intftype=None):
@@ -300,11 +298,6 @@ def is_source_interface(conf, interface, intftype=None):
'have a source-interface')
intftype = intftypes if intftype == None else [intftype]
-
- # set config level to root
- old_level = conf.get_level()
- conf.set_level([])
-
for it in intftype:
base = ['interfaces', it]
for intf in conf.list_nodes(base):
@@ -313,43 +306,77 @@ def is_source_interface(conf, interface, intftype=None):
ret_val = intf
break
- old_level = conf.set_level(old_level)
return ret_val
def get_dhcp_interfaces(conf, vrf=None):
""" Common helper functions to retrieve all interfaces from current CLI
sessions that have DHCP configured. """
- dhcp_interfaces = []
+ dhcp_interfaces = {}
dict = conf.get_config_dict(['interfaces'], get_first_key=True)
if not dict:
return dhcp_interfaces
- def check_dhcp(config, ifname):
- out = []
+ def check_dhcp(config):
+ ifname = config['ifname']
+ tmp = {}
if 'address' in config and 'dhcp' in config['address']:
+ options = {}
+ if dict_search('dhcp_options.default_route_distance', config) != None:
+ options.update({'dhcp_options' : config['dhcp_options']})
if 'vrf' in config:
- if vrf is config['vrf']: out.append(ifname)
- else: out.append(ifname)
- return out
+ if vrf is config['vrf']: tmp.update({ifname : options})
+ else: tmp.update({ifname : options})
+
+ return tmp
for section, interface in dict.items():
- for ifname, ifconfig in interface.items():
- tmp = check_dhcp(ifconfig, ifname)
- dhcp_interfaces.extend(tmp)
+ for ifname in interface:
+ # always reset config level, as get_interface_dict() will alter it
+ conf.set_level([])
+ # we already have a dict representation of the config from get_config_dict(),
+ # but with the extended information from get_interface_dict() we also
+ # get the DHCP client default-route-distance default option if not specified.
+ _, ifconfig = get_interface_dict(conf, ['interfaces', section], ifname)
+
+ tmp = check_dhcp(ifconfig)
+ dhcp_interfaces.update(tmp)
# check per VLAN interfaces
for vif, vif_config in ifconfig.get('vif', {}).items():
- tmp = check_dhcp(vif_config, f'{ifname}.{vif}')
- dhcp_interfaces.extend(tmp)
+ tmp = check_dhcp(vif_config)
+ dhcp_interfaces.update(tmp)
# check QinQ VLAN interfaces
- for vif_s, vif_s_config in ifconfig.get('vif-s', {}).items():
- tmp = check_dhcp(vif_s_config, f'{ifname}.{vif_s}')
- dhcp_interfaces.extend(tmp)
- for vif_c, vif_c_config in vif_s_config.get('vif-c', {}).items():
- tmp = check_dhcp(vif_c_config, f'{ifname}.{vif_s}.{vif_c}')
- dhcp_interfaces.extend(tmp)
+ for vif_s, vif_s_config in ifconfig.get('vif_s', {}).items():
+ tmp = check_dhcp(vif_s_config)
+ dhcp_interfaces.update(tmp)
+ for vif_c, vif_c_config in vif_s_config.get('vif_c', {}).items():
+ tmp = check_dhcp(vif_c_config)
+ dhcp_interfaces.update(tmp)
return dhcp_interfaces
+def get_pppoe_interfaces(conf, vrf=None):
+ """ Common helper functions to retrieve all interfaces from current CLI
+ sessions that have DHCP configured. """
+ pppoe_interfaces = {}
+ for ifname in conf.list_nodes(['interfaces', 'pppoe']):
+ # always reset config level, as get_interface_dict() will alter it
+ conf.set_level([])
+ # we already have a dict representation of the config from get_config_dict(),
+ # but with the extended information from get_interface_dict() we also
+ # get the DHCP client default-route-distance default option if not specified.
+ ifconfig = get_interface_dict(conf, ['interfaces', 'pppoe'], ifname)
+
+ options = {}
+ if 'default_route_distance' in ifconfig:
+ options.update({'default_route_distance' : ifconfig['default_route_distance']})
+ if 'no_default_route' in ifconfig:
+ options.update({'no_default_route' : {}})
+ if 'vrf' in ifconfig:
+ if vrf is ifconfig['vrf']: pppoe_interfaces.update({ifname : options})
+ else: pppoe_interfaces.update({ifname : options})
+
+ return pppoe_interfaces
+
def get_interface_dict(config, base, ifname=''):
"""
Common utility function to retrieve and mangle the interfaces configuration
@@ -359,7 +386,6 @@ def get_interface_dict(config, base, ifname=''):
Return a dictionary with the necessary interface config keys.
"""
-
if not ifname:
from vyos import ConfigError
# determine tagNode instance
@@ -376,9 +402,8 @@ def get_interface_dict(config, base, ifname=''):
for vif in ['vif', 'vif_s']:
if vif in default_values: del default_values[vif]
- # setup config level which is extracted in get_removed_vlans()
- config.set_level(base + [ifname])
- dict = config.get_config_dict([], key_mangling=('-', '_'), get_first_key=True,
+ dict = config.get_config_dict(base + [ifname], key_mangling=('-', '_'),
+ get_first_key=True,
no_tag_node_value_mangle=True)
# Check if interface has been removed. We must use exists() as
@@ -386,8 +411,8 @@ def get_interface_dict(config, base, ifname=''):
# node like the following exists.
# +macsec macsec1 {
# +}
- if not config.exists([]):
- dict.update({'deleted' : ''})
+ if not config.exists(base + [ifname]):
+ dict.update({'deleted' : {}})
# Add interface instance name into dictionary
dict.update({'ifname': ifname})
@@ -405,10 +430,16 @@ def get_interface_dict(config, base, ifname=''):
if 'deleted' not in dict:
dict = dict_merge(default_values, dict)
+ # If interface does not request an IPv4 DHCP address there is no need
+ # to keep the dhcp-options key
+ if 'address' not in dict or 'dhcp' not in dict['address']:
+ if 'dhcp_options' in dict:
+ del dict['dhcp_options']
+
# XXX: T2665: blend in proper DHCPv6-PD default values
dict = T2665_set_dhcpv6pd_defaults(dict)
- address = leaf_node_changed(config, ['address'])
+ address = leaf_node_changed(config, base + [ifname, 'address'])
if address: dict.update({'address_old' : address})
# Check if we are a member of a bridge device
@@ -423,6 +454,10 @@ def get_interface_dict(config, base, ifname=''):
bond = is_member(config, ifname, 'bonding')
if bond: dict.update({'is_bond_member' : bond})
+ # Check if any DHCP options changed which require a client restat
+ dhcp = node_changed(config, ['dhcp-options'], recursive=True)
+ if dhcp: dict.update({'dhcp_options_changed' : ''})
+
# Some interfaces come with a source_interface which must also not be part
# of any other bond or bridge interface as it is exclusivly assigned as the
# Kernels "lower" interface to this new "virtual/upper" interface.
@@ -435,10 +470,10 @@ def get_interface_dict(config, base, ifname=''):
tmp = is_member(config, dict['source_interface'], 'bonding')
if tmp: dict.update({'source_interface_is_bond_member' : tmp})
- mac = leaf_node_changed(config, ['mac'])
+ mac = leaf_node_changed(config, base + [ifname, 'mac'])
if mac: dict.update({'mac_old' : mac})
- eui64 = leaf_node_changed(config, ['ipv6', 'address', 'eui64'])
+ eui64 = leaf_node_changed(config, base + [ifname, 'ipv6', 'address', 'eui64'])
if eui64:
tmp = dict_search('ipv6.address', dict)
if not tmp:
@@ -450,6 +485,9 @@ def get_interface_dict(config, base, ifname=''):
# identical for all types of VLAN interfaces as they all include the same
# XML definitions which hold the defaults.
for vif, vif_config in dict.get('vif', {}).items():
+ # Add subinterface name to dictionary
+ dict['vif'][vif].update({'ifname' : f'{ifname}.{vif}'})
+
default_vif_values = defaults(base + ['vif'])
# XXX: T2665: When there is no DHCPv6-PD configuration given, we can safely
# remove the default values from the dict.
@@ -459,15 +497,31 @@ def get_interface_dict(config, base, ifname=''):
# Only add defaults if interface is not about to be deleted - this is
# to keep a cleaner config dict.
if 'deleted' not in dict:
- dict['vif'][vif] = dict_merge(default_vif_values, vif_config)
+ address = leaf_node_changed(config, base + [ifname, 'vif', vif, 'address'])
+ if address: dict['vif'][vif].update({'address_old' : address})
+
+ dict['vif'][vif] = dict_merge(default_vif_values, dict['vif'][vif])
# XXX: T2665: blend in proper DHCPv6-PD default values
dict['vif'][vif] = T2665_set_dhcpv6pd_defaults(dict['vif'][vif])
+ # If interface does not request an IPv4 DHCP address there is no need
+ # to keep the dhcp-options key
+ if 'address' not in dict['vif'][vif] or 'dhcp' not in dict['vif'][vif]['address']:
+ if 'dhcp_options' in dict['vif'][vif]:
+ del dict['vif'][vif]['dhcp_options']
+
# Check if we are a member of a bridge device
bridge = is_member(config, f'{ifname}.{vif}', 'bridge')
if bridge: dict['vif'][vif].update({'is_bridge_member' : bridge})
+ # Check if any DHCP options changed which require a client restat
+ dhcp = node_changed(config, ['vif', vif, 'dhcp-options'], recursive=True)
+ if dhcp: dict['vif'][vif].update({'dhcp_options_changed' : ''})
+
for vif_s, vif_s_config in dict.get('vif_s', {}).items():
+ # Add subinterface name to dictionary
+ dict['vif_s'][vif_s].update({'ifname' : f'{ifname}.{vif_s}'})
+
default_vif_s_values = defaults(base + ['vif-s'])
# XXX: T2665: we only wan't the vif-s defaults - do not care about vif-c
if 'vif_c' in default_vif_s_values: del default_vif_s_values['vif_c']
@@ -480,15 +534,33 @@ def get_interface_dict(config, base, ifname=''):
# Only add defaults if interface is not about to be deleted - this is
# to keep a cleaner config dict.
if 'deleted' not in dict:
- dict['vif_s'][vif_s] = dict_merge(default_vif_s_values, vif_s_config)
+ address = leaf_node_changed(config, base + [ifname, 'vif-s', vif_s, 'address'])
+ if address: dict['vif_s'][vif_s].update({'address_old' : address})
+
+ dict['vif_s'][vif_s] = dict_merge(default_vif_s_values,
+ dict['vif_s'][vif_s])
# XXX: T2665: blend in proper DHCPv6-PD default values
dict['vif_s'][vif_s] = T2665_set_dhcpv6pd_defaults(dict['vif_s'][vif_s])
+ # If interface does not request an IPv4 DHCP address there is no need
+ # to keep the dhcp-options key
+ if 'address' not in dict['vif_s'][vif_s] or 'dhcp' not in \
+ dict['vif_s'][vif_s]['address']:
+ if 'dhcp_options' in dict['vif_s'][vif_s]:
+ del dict['vif_s'][vif_s]['dhcp_options']
+
# Check if we are a member of a bridge device
bridge = is_member(config, f'{ifname}.{vif_s}', 'bridge')
if bridge: dict['vif_s'][vif_s].update({'is_bridge_member' : bridge})
+ # Check if any DHCP options changed which require a client restat
+ dhcp = node_changed(config, ['vif-s', vif_s, 'dhcp-options'], recursive=True)
+ if dhcp: dict['vif_s'][vif_s].update({'dhcp_options_changed' : ''})
+
for vif_c, vif_c_config in vif_s_config.get('vif_c', {}).items():
+ # Add subinterface name to dictionary
+ dict['vif_s'][vif_s]['vif_c'][vif_c].update({'ifname' : f'{ifname}.{vif_s}.{vif_c}'})
+
default_vif_c_values = defaults(base + ['vif-s', 'vif-c'])
# XXX: T2665: When there is no DHCPv6-PD configuration given, we can safely
@@ -499,20 +571,35 @@ def get_interface_dict(config, base, ifname=''):
# Only add defaults if interface is not about to be deleted - this is
# to keep a cleaner config dict.
if 'deleted' not in dict:
+ address = leaf_node_changed(config, base + [ifname, 'vif-s', vif_s, 'vif-c', vif_c, 'address'])
+ if address: dict['vif_s'][vif_s]['vif_c'][vif_c].update(
+ {'address_old' : address})
+
dict['vif_s'][vif_s]['vif_c'][vif_c] = dict_merge(
- default_vif_c_values, vif_c_config)
+ default_vif_c_values, dict['vif_s'][vif_s]['vif_c'][vif_c])
# XXX: T2665: blend in proper DHCPv6-PD default values
dict['vif_s'][vif_s]['vif_c'][vif_c] = T2665_set_dhcpv6pd_defaults(
dict['vif_s'][vif_s]['vif_c'][vif_c])
+ # If interface does not request an IPv4 DHCP address there is no need
+ # to keep the dhcp-options key
+ if 'address' not in dict['vif_s'][vif_s]['vif_c'][vif_c] or 'dhcp' \
+ not in dict['vif_s'][vif_s]['vif_c'][vif_c]['address']:
+ if 'dhcp_options' in dict['vif_s'][vif_s]['vif_c'][vif_c]:
+ del dict['vif_s'][vif_s]['vif_c'][vif_c]['dhcp_options']
+
# Check if we are a member of a bridge device
bridge = is_member(config, f'{ifname}.{vif_s}.{vif_c}', 'bridge')
if bridge: dict['vif_s'][vif_s]['vif_c'][vif_c].update(
{'is_bridge_member' : bridge})
+ # Check if any DHCP options changed which require a client restat
+ dhcp = node_changed(config, ['vif-s', vif_s, 'vif-c', vif_c, 'dhcp-options'], recursive=True)
+ if dhcp: dict['vif_s'][vif_s]['vif_c'][vif_c].update({'dhcp_options_changed' : ''})
+
# Check vif, vif-s/vif-c VLAN interfaces for removal
- dict = get_removed_vlans(config, dict)
- return dict
+ dict = get_removed_vlans(config, base + [ifname], dict)
+ return ifname, dict
def get_vlan_ids(interface):
"""
@@ -534,7 +621,6 @@ def get_vlan_ids(interface):
return vlan_ids
-
def get_accel_dict(config, base, chap_secrets):
"""
Common utility function to retrieve and mangle the Accel-PPP configuration
diff --git a/python/vyos/configdiff.py b/python/vyos/configdiff.py
index 0e41fbe27..9185575df 100644
--- a/python/vyos/configdiff.py
+++ b/python/vyos/configdiff.py
@@ -16,8 +16,11 @@
from enum import IntFlag, auto
from vyos.config import Config
+from vyos.configtree import DiffTree
from vyos.configdict import dict_merge
+from vyos.configdict import list_diff
from vyos.util import get_sub_dict, mangle_dict_keys
+from vyos.util import dict_search_args
from vyos.xml import defaults
class ConfigDiffError(Exception):
@@ -36,6 +39,8 @@ class Diff(IntFlag):
ADD = auto()
STABLE = auto()
+ALL = Diff.MERGE | Diff.DELETE | Diff.ADD | Diff.STABLE
+
requires_effective = [enum_to_key(Diff.DELETE)]
target_defaults = [enum_to_key(Diff.MERGE)]
@@ -73,19 +78,24 @@ def get_config_diff(config, key_mangling=None):
isinstance(key_mangling[1], str)):
raise ValueError("key_mangling must be a tuple of two strings")
- return ConfigDiff(config, key_mangling)
+ diff_t = DiffTree(config._running_config, config._session_config)
+
+ return ConfigDiff(config, key_mangling, diff_tree=diff_t)
class ConfigDiff(object):
"""
The class of config changes as represented by comparison between the
session config dict and the effective config dict.
"""
- def __init__(self, config, key_mangling=None):
+ def __init__(self, config, key_mangling=None, diff_tree=None):
self._level = config.get_level()
self._session_config_dict = config.get_cached_root_dict(effective=False)
self._effective_config_dict = config.get_cached_root_dict(effective=True)
self._key_mangling = key_mangling
+ self._diff_tree = diff_tree
+ self._diff_dict = diff_tree.dict if diff_tree else {}
+
# mirrored from Config; allow path arguments relative to level
def _make_path(self, path):
if isinstance(path, str):
@@ -134,7 +144,45 @@ class ConfigDiff(object):
self._key_mangling[1])
return config_dict
- def get_child_nodes_diff(self, path=[], expand_nodes=Diff(0), no_defaults=False):
+ def is_node_changed(self, path=[]):
+ if self._diff_tree is None:
+ raise NotImplementedError("diff_tree class not available")
+
+ if (self._diff_tree.add.exists(self._make_path(path)) or
+ self._diff_tree.sub.exists(self._make_path(path))):
+ return True
+ return False
+
+ def get_child_nodes_diff_str(self, path=[]):
+ ret = {'add': {}, 'change': {}, 'delete': {}}
+
+ diff = self.get_child_nodes_diff(path,
+ expand_nodes=Diff.ADD | Diff.DELETE | Diff.MERGE | Diff.STABLE,
+ no_defaults=True)
+
+ def parse_dict(diff_dict, diff_type, prefix=[]):
+ for k, v in diff_dict.items():
+ if isinstance(v, dict):
+ parse_dict(v, diff_type, prefix + [k])
+ else:
+ path_str = ' '.join(prefix + [k])
+ if diff_type == 'add' or diff_type == 'delete':
+ if isinstance(v, list):
+ v = ', '.join(v)
+ ret[diff_type][path_str] = v
+ elif diff_type == 'merge':
+ old_value = dict_search_args(diff['stable'], *prefix, k)
+ if old_value and old_value != v:
+ ret['change'][path_str] = [old_value, v]
+
+ parse_dict(diff['merge'], 'merge')
+ parse_dict(diff['add'], 'add')
+ parse_dict(diff['delete'], 'delete')
+
+ return ret
+
+ def get_child_nodes_diff(self, path=[], expand_nodes=Diff(0), no_defaults=False,
+ recursive=False):
"""
Args:
path (str|list): config path
@@ -144,6 +192,8 @@ class ConfigDiff(object):
value
no_detaults=False: if expand_nodes & Diff.MERGE, do not merge default
values to ret['merge']
+ recursive: if true, use config_tree diff algorithm provided by
+ diff_tree class
Returns: dict of lists, representing differences between session
and effective config, under path
@@ -154,6 +204,34 @@ class ConfigDiff(object):
"""
session_dict = get_sub_dict(self._session_config_dict,
self._make_path(path), get_first_key=True)
+
+ if recursive:
+ if self._diff_tree is None:
+ raise NotImplementedError("diff_tree class not available")
+ else:
+ add = get_sub_dict(self._diff_tree.dict, ['add'], get_first_key=True)
+ sub = get_sub_dict(self._diff_tree.dict, ['sub'], get_first_key=True)
+ inter = get_sub_dict(self._diff_tree.dict, ['inter'], get_first_key=True)
+ ret = {}
+ ret[enum_to_key(Diff.MERGE)] = session_dict
+ ret[enum_to_key(Diff.DELETE)] = get_sub_dict(sub, self._make_path(path),
+ get_first_key=True)
+ ret[enum_to_key(Diff.ADD)] = get_sub_dict(add, self._make_path(path),
+ get_first_key=True)
+ ret[enum_to_key(Diff.STABLE)] = get_sub_dict(inter, self._make_path(path),
+ get_first_key=True)
+ for e in Diff:
+ k = enum_to_key(e)
+ if not (e & expand_nodes):
+ ret[k] = list(ret[k])
+ else:
+ if self._key_mangling:
+ ret[k] = self._mangle_dict_keys(ret[k])
+ if k in target_defaults and not no_defaults:
+ default_values = defaults(self._make_path(path))
+ ret[k] = dict_merge(default_values, ret[k])
+ return ret
+
effective_dict = get_sub_dict(self._effective_config_dict,
self._make_path(path), get_first_key=True)
@@ -179,7 +257,8 @@ class ConfigDiff(object):
return ret
- def get_node_diff(self, path=[], expand_nodes=Diff(0), no_defaults=False):
+ def get_node_diff(self, path=[], expand_nodes=Diff(0), no_defaults=False,
+ recursive=False):
"""
Args:
path (str|list): config path
@@ -189,6 +268,8 @@ class ConfigDiff(object):
value
no_detaults=False: if expand_nodes & Diff.MERGE, do not merge default
values to ret['merge']
+ recursive: if true, use config_tree diff algorithm provided by
+ diff_tree class
Returns: dict of lists, representing differences between session
and effective config, at path
@@ -198,6 +279,31 @@ class ConfigDiff(object):
dict['stable'] = config values in both session and effective
"""
session_dict = get_sub_dict(self._session_config_dict, self._make_path(path))
+
+ if recursive:
+ if self._diff_tree is None:
+ raise NotImplementedError("diff_tree class not available")
+ else:
+ add = get_sub_dict(self._diff_tree.dict, ['add'], get_first_key=True)
+ sub = get_sub_dict(self._diff_tree.dict, ['sub'], get_first_key=True)
+ inter = get_sub_dict(self._diff_tree.dict, ['inter'], get_first_key=True)
+ ret = {}
+ ret[enum_to_key(Diff.MERGE)] = session_dict
+ ret[enum_to_key(Diff.DELETE)] = get_sub_dict(sub, self._make_path(path))
+ ret[enum_to_key(Diff.ADD)] = get_sub_dict(add, self._make_path(path))
+ ret[enum_to_key(Diff.STABLE)] = get_sub_dict(inter, self._make_path(path))
+ for e in Diff:
+ k = enum_to_key(e)
+ if not (e & expand_nodes):
+ ret[k] = list(ret[k])
+ else:
+ if self._key_mangling:
+ ret[k] = self._mangle_dict_keys(ret[k])
+ if k in target_defaults and not no_defaults:
+ default_values = defaults(self._make_path(path))
+ ret[k] = dict_merge(default_values, ret[k])
+ return ret
+
effective_dict = get_sub_dict(self._effective_config_dict, self._make_path(path))
ret = _key_sets_from_dicts(session_dict, effective_dict)
diff --git a/python/vyos/configquery.py b/python/vyos/configquery.py
index 1cdcbcf39..5b097b312 100644
--- a/python/vyos/configquery.py
+++ b/python/vyos/configquery.py
@@ -18,16 +18,15 @@ A small library that allows querying existence or value(s) of config
settings from op mode, and execution of arbitrary op mode commands.
'''
-import re
-import json
-from copy import deepcopy
+import os
from subprocess import STDOUT
-import vyos.util
-import vyos.xml
+from vyos.util import popen, boot_configuration_complete
from vyos.config import Config
-from vyos.configtree import ConfigTree
-from vyos.configsource import ConfigSourceSession
+from vyos.configsource import ConfigSourceSession, ConfigSourceString
+from vyos.defaults import directories
+
+config_file = os.path.join(directories['config'], 'config.boot')
class ConfigQueryError(Exception):
pass
@@ -58,21 +57,21 @@ class CliShellApiConfigQuery(GenericConfigQuery):
def exists(self, path: list):
cmd = ' '.join(path)
- (_, err) = vyos.util.popen(f'cli-shell-api existsActive {cmd}')
+ (_, err) = popen(f'cli-shell-api existsActive {cmd}')
if err:
return False
return True
def value(self, path: list):
cmd = ' '.join(path)
- (out, err) = vyos.util.popen(f'cli-shell-api returnActiveValue {cmd}')
+ (out, err) = popen(f'cli-shell-api returnActiveValue {cmd}')
if err:
raise ConfigQueryError('No value for given path')
return out
def values(self, path: list):
cmd = ' '.join(path)
- (out, err) = vyos.util.popen(f'cli-shell-api returnActiveValues {cmd}')
+ (out, err) = popen(f'cli-shell-api returnActiveValues {cmd}')
if err:
raise ConfigQueryError('No values for given path')
return out
@@ -81,25 +80,36 @@ class ConfigTreeQuery(GenericConfigQuery):
def __init__(self):
super().__init__()
- config_source = ConfigSourceSession()
- self.configtree = Config(config_source=config_source)
+ if boot_configuration_complete():
+ config_source = ConfigSourceSession()
+ self.config = Config(config_source=config_source)
+ else:
+ try:
+ with open(config_file) as f:
+ config_string = f.read()
+ except OSError as err:
+ raise ConfigQueryError('No config file available') from err
+
+ config_source = ConfigSourceString(running_config_text=config_string,
+ session_config_text=config_string)
+ self.config = Config(config_source=config_source)
def exists(self, path: list):
- return self.configtree.exists(path)
+ return self.config.exists(path)
def value(self, path: list):
- return self.configtree.return_value(path)
+ return self.config.return_value(path)
def values(self, path: list):
- return self.configtree.return_values(path)
+ return self.config.return_values(path)
def list_nodes(self, path: list):
- return self.configtree.list_nodes(path)
+ return self.config.list_nodes(path)
def get_config_dict(self, path=[], effective=False, key_mangling=None,
get_first_key=False, no_multi_convert=False,
no_tag_node_value_mangle=False):
- return self.configtree.get_config_dict(path, effective=effective,
+ return self.config.get_config_dict(path, effective=effective,
key_mangling=key_mangling, get_first_key=get_first_key,
no_multi_convert=no_multi_convert,
no_tag_node_value_mangle=no_tag_node_value_mangle)
@@ -110,7 +120,7 @@ class VbashOpRun(GenericOpRun):
def run(self, path: list, **kwargs):
cmd = ' '.join(path)
- (out, err) = vyos.util.popen(f'. /opt/vyatta/share/vyatta-op/functions/interpreter/vyatta-op-run; _vyatta_op_run {cmd}', stderr=STDOUT, **kwargs)
+ (out, err) = popen(f'/opt/vyatta/bin/vyatta-op-cmd-wrapper {cmd}', stderr=STDOUT, **kwargs)
if err:
raise ConfigQueryError(out)
return out
diff --git a/python/vyos/configsource.py b/python/vyos/configsource.py
index b0981d25e..510b5b65a 100644
--- a/python/vyos/configsource.py
+++ b/python/vyos/configsource.py
@@ -19,6 +19,7 @@ import re
import subprocess
from vyos.configtree import ConfigTree
+from vyos.util import boot_configuration_complete
class VyOSError(Exception):
"""
@@ -117,7 +118,7 @@ class ConfigSourceSession(ConfigSource):
# Running config can be obtained either from op or conf mode, it always succeeds
# once the config system is initialized during boot;
# before initialization, set to empty string
- if os.path.isfile('/tmp/vyos-config-status'):
+ if boot_configuration_complete():
try:
running_config_text = self._run([self._cli_shell_api, '--show-active-only', '--show-show-defaults', '--show-ignore-edit', 'showConfig'])
except VyOSError:
@@ -161,7 +162,7 @@ class ConfigSourceSession(ConfigSource):
if p.returncode != 0:
raise VyOSError()
else:
- return out.decode('ascii', 'ignore')
+ return out.decode()
def set_level(self, path):
"""
diff --git a/python/vyos/configtree.py b/python/vyos/configtree.py
index d8ffaca99..e9cdb69e4 100644
--- a/python/vyos/configtree.py
+++ b/python/vyos/configtree.py
@@ -17,6 +17,7 @@ import json
from ctypes import cdll, c_char_p, c_void_p, c_int
+LIBPATH = '/usr/lib/libvyosconfig.so.0'
def escape_backslash(string: str) -> str:
"""Escape single backslashes in string that are not in escape sequence"""
@@ -42,7 +43,9 @@ class ConfigTreeError(Exception):
class ConfigTree(object):
- def __init__(self, config_string, libpath='/usr/lib/libvyosconfig.so.0'):
+ def __init__(self, config_string=None, address=None, libpath=LIBPATH):
+ if config_string is None and address is None:
+ raise TypeError("ConfigTree() requires one of 'config_string' or 'address'")
self.__config = None
self.__lib = cdll.LoadLibrary(libpath)
@@ -60,7 +63,7 @@ class ConfigTree(object):
self.__to_string.restype = c_char_p
self.__to_commands = self.__lib.to_commands
- self.__to_commands.argtypes = [c_void_p]
+ self.__to_commands.argtypes = [c_void_p, c_char_p]
self.__to_commands.restype = c_char_p
self.__to_json = self.__lib.to_json
@@ -123,18 +126,26 @@ class ConfigTree(object):
self.__set_tag.argtypes = [c_void_p, c_char_p]
self.__set_tag.restype = c_int
+ self.__get_subtree = self.__lib.get_subtree
+ self.__get_subtree.argtypes = [c_void_p, c_char_p]
+ self.__get_subtree.restype = c_void_p
+
self.__destroy = self.__lib.destroy
self.__destroy.argtypes = [c_void_p]
- config_section, version_section = extract_version(config_string)
- config_section = escape_backslash(config_section)
- config = self.__from_string(config_section.encode())
- if config is None:
- msg = self.__get_error().decode()
- raise ValueError("Failed to parse config: {0}".format(msg))
+ if address is None:
+ config_section, version_section = extract_version(config_string)
+ config_section = escape_backslash(config_section)
+ config = self.__from_string(config_section.encode())
+ if config is None:
+ msg = self.__get_error().decode()
+ raise ValueError("Failed to parse config: {0}".format(msg))
+ else:
+ self.__config = config
+ self.__version = version_section
else:
- self.__config = config
- self.__version = version_section
+ self.__config = address
+ self.__version = ''
def __del__(self):
if self.__config is not None:
@@ -143,13 +154,16 @@ class ConfigTree(object):
def __str__(self):
return self.to_string()
+ def _get_config(self):
+ return self.__config
+
def to_string(self):
config_string = self.__to_string(self.__config).decode()
config_string = "{0}\n{1}".format(config_string, self.__version)
return config_string
- def to_commands(self):
- return self.__to_commands(self.__config).decode()
+ def to_commands(self, op="set"):
+ return self.__to_commands(self.__config, op.encode()).decode()
def to_json(self):
return self.__to_json(self.__config).decode()
@@ -281,3 +295,61 @@ class ConfigTree(object):
else:
raise ConfigTreeError("Path [{}] doesn't exist".format(path_str))
+ def get_subtree(self, path, with_node=False):
+ check_path(path)
+ path_str = " ".join(map(str, path)).encode()
+
+ res = self.__get_subtree(self.__config, path_str, with_node)
+ subt = ConfigTree(address=res)
+ return subt
+
+class DiffTree:
+ def __init__(self, left, right, path=[], libpath=LIBPATH):
+ if left is None:
+ left = ConfigTree(config_string='\n')
+ if right is None:
+ right = ConfigTree(config_string='\n')
+ if not (isinstance(left, ConfigTree) and isinstance(right, ConfigTree)):
+ raise TypeError("Arguments must be instances of ConfigTree")
+ if path:
+ if not left.exists(path):
+ raise ConfigTreeError(f"Path {path} doesn't exist in lhs tree")
+ if not right.exists(path):
+ raise ConfigTreeError(f"Path {path} doesn't exist in rhs tree")
+
+ self.left = left
+ self.right = right
+
+ self.__lib = cdll.LoadLibrary(libpath)
+
+ self.__diff_tree = self.__lib.diff_tree
+ self.__diff_tree.argtypes = [c_char_p, c_void_p, c_void_p]
+ self.__diff_tree.restype = c_void_p
+
+ self.__trim_tree = self.__lib.trim_tree
+ self.__trim_tree.argtypes = [c_void_p, c_void_p]
+ self.__trim_tree.restype = c_void_p
+
+ check_path(path)
+ path_str = " ".join(map(str, path)).encode()
+
+ res = self.__diff_tree(path_str, left._get_config(), right._get_config())
+
+ # full diff config_tree and python dict representation
+ self.full = ConfigTree(address=res)
+ self.dict = json.loads(self.full.to_json())
+
+ # config_tree sub-trees
+ self.add = self.full.get_subtree(['add'])
+ self.sub = self.full.get_subtree(['sub'])
+ self.inter = self.full.get_subtree(['inter'])
+
+ # trim sub(-tract) tree to get delete tree for commands
+ ref = self.right.get_subtree(path, with_node=True) if path else self.right
+ res = self.__trim_tree(self.sub._get_config(), ref._get_config())
+ self.delete = ConfigTree(address=res)
+
+ def to_commands(self):
+ add = self.add.to_commands()
+ delete = self.delete.to_commands(op="delete")
+ return delete + "\n" + add
diff --git a/python/vyos/configverify.py b/python/vyos/configverify.py
index 365a28feb..438485d98 100644
--- a/python/vyos/configverify.py
+++ b/python/vyos/configverify.py
@@ -1,4 +1,4 @@
-# Copyright 2020-2021 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright 2020-2022 VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -173,24 +173,43 @@ def verify_eapol(config):
if ca_cert_name not in config['pki']['ca']:
raise ConfigError('Invalid CA certificate specified for EAPoL')
- ca_cert = config['pki']['ca'][cert_name]
+ ca_cert = config['pki']['ca'][ca_cert_name]
if 'certificate' not in ca_cert:
raise ConfigError('Invalid CA certificate specified for EAPoL')
-def verify_mirror(config):
+def verify_mirror_redirect(config):
"""
Common helper function used by interface implementations to perform
- recurring validation of mirror interface configuration.
+ recurring validation of mirror and redirect interface configuration via tc(8)
It makes no sense to mirror traffic back at yourself!
"""
+ import os
+ if {'mirror', 'redirect'} <= set(config):
+ raise ConfigError('Mirror and redirect can not be enabled at the same time!')
+
if 'mirror' in config:
for direction, mirror_interface in config['mirror'].items():
+ if not os.path.exists(f'/sys/class/net/{mirror_interface}'):
+ raise ConfigError(f'Requested mirror interface "{mirror_interface}" '\
+ 'does not exist!')
+
if mirror_interface == config['ifname']:
- raise ConfigError(f'Can not mirror "{direction}" traffic back ' \
+ raise ConfigError(f'Can not mirror "{direction}" traffic back '\
'the originating interface!')
+ if 'redirect' in config:
+ redirect_ifname = config['redirect']
+ if not os.path.exists(f'/sys/class/net/{redirect_ifname}'):
+ raise ConfigError(f'Requested redirect interface "{redirect_ifname}" '\
+ 'does not exist!')
+
+ if ('mirror' in config or 'redirect' in config) and dict_search('traffic_policy.in', config) is not None:
+ # XXX: support combination of limiting and redirect/mirror - this is an
+ # artificial limitation
+ raise ConfigError('Can not use ingress policy together with mirror or redirect!')
+
def verify_authentication(config):
"""
Common helper function used by interface implementations to perform
@@ -224,9 +243,10 @@ def verify_bridge_delete(config):
when interface also is part of a bridge.
"""
if 'is_bridge_member' in config:
- raise ConfigError(
- 'Interface "{ifname}" cannot be deleted as it is a '
- 'member of bridge "{is_bridge_member}"!'.format(**config))
+ interface = config['ifname']
+ for bridge in config['is_bridge_member']:
+ raise ConfigError(f'Interface "{interface}" cannot be deleted as it '
+ f'is a member of bridge "{bridge}"!')
def verify_interface_exists(ifname):
"""
@@ -308,27 +328,37 @@ def verify_vlan_config(config):
if duplicate:
raise ConfigError(f'Duplicate VLAN id "{duplicate[0]}" used for vif and vif-s interfaces!')
+ parent_ifname = config['ifname']
# 802.1q VLANs
- for vlan in config.get('vif', {}):
- vlan = config['vif'][vlan]
+ for vlan_id in config.get('vif', {}):
+ vlan = config['vif'][vlan_id]
+ vlan['ifname'] = f'{parent_ifname}.{vlan_id}'
+
verify_dhcpv6(vlan)
verify_address(vlan)
verify_vrf(vlan)
+ verify_mirror_redirect(vlan)
verify_mtu_parent(vlan, config)
# 802.1ad (Q-in-Q) VLANs
- for s_vlan in config.get('vif_s', {}):
- s_vlan = config['vif_s'][s_vlan]
+ for s_vlan_id in config.get('vif_s', {}):
+ s_vlan = config['vif_s'][s_vlan_id]
+ s_vlan['ifname'] = f'{parent_ifname}.{s_vlan_id}'
+
verify_dhcpv6(s_vlan)
verify_address(s_vlan)
verify_vrf(s_vlan)
+ verify_mirror_redirect(s_vlan)
verify_mtu_parent(s_vlan, config)
- for c_vlan in s_vlan.get('vif_c', {}):
- c_vlan = s_vlan['vif_c'][c_vlan]
+ for c_vlan_id in s_vlan.get('vif_c', {}):
+ c_vlan = s_vlan['vif_c'][c_vlan_id]
+ c_vlan['ifname'] = f'{parent_ifname}.{s_vlan_id}.{c_vlan_id}'
+
verify_dhcpv6(c_vlan)
verify_address(c_vlan)
verify_vrf(c_vlan)
+ verify_mirror_redirect(c_vlan)
verify_mtu_parent(c_vlan, config)
verify_mtu_parent(c_vlan, s_vlan)
diff --git a/python/vyos/cpu.py b/python/vyos/cpu.py
new file mode 100644
index 000000000..a0ef864be
--- /dev/null
+++ b/python/vyos/cpu.py
@@ -0,0 +1,102 @@
+#!/usr/bin/env python3
+# Copyright 2022 VyOS maintainers and contributors <maintainers@vyos.io>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library. If not, see <http://www.gnu.org/licenses/>.
+
+"""
+Retrieves (or at least attempts to retrieve) the total number of real CPU cores
+installed in a Linux system.
+
+The issue of core count is complicated by existence of SMT, e.g. Intel's Hyper Threading.
+GNU nproc returns the number of LOGICAL cores,
+which is 2x of the real cores if SMT is enabled.
+
+The idea is to find all physical CPUs and add up their core counts.
+It has special cases for x86_64 and MAY work correctly on other architectures,
+but nothing is certain.
+"""
+
+import re
+
+
+def _read_cpuinfo():
+ with open('/proc/cpuinfo', 'r') as f:
+ return f.readlines()
+
+def _split_line(l):
+ l = l.strip()
+ parts = re.split(r'\s*:\s*', l)
+ return (parts[0], ":".join(parts[1:]))
+
+def _find_cpus(cpuinfo_lines):
+ # Make a dict because it's more convenient to work with later,
+ # when we need to find physicall distinct CPUs there.
+ cpus = {}
+
+ cpu_number = 0
+
+ for l in cpuinfo_lines:
+ key, value = _split_line(l)
+ if key == 'processor':
+ cpu_number = value
+ cpus[cpu_number] = {}
+ else:
+ cpus[cpu_number][key] = value
+
+ return cpus
+
+def _find_physical_cpus():
+ cpus = _find_cpus(_read_cpuinfo())
+
+ phys_cpus = {}
+
+ for num in cpus:
+ if 'physical id' in cpus[num]:
+ # On at least some architectures, CPUs in different sockets
+ # have different 'physical id' field, e.g. on x86_64.
+ phys_id = cpus[num]['physical id']
+ if phys_id not in phys_cpus:
+ phys_cpus[phys_id] = cpus[num]
+ else:
+ # On other architectures, e.g. on ARM, there's no such field.
+ # We just assume they are different CPUs,
+ # whether single core ones or cores of physical CPUs.
+ phys_cpus[num] = cpu[num]
+
+ return phys_cpus
+
+def get_cpus():
+ """ Returns a list of /proc/cpuinfo entries that belong to different CPUs.
+ """
+ cpus_dict = _find_physical_cpus()
+ return list(cpus_dict.values())
+
+def get_core_count():
+ """ Returns the total number of physical CPU cores
+ (even if Hyper-Threading or another SMT is enabled and has inflated
+ the number of cores in /proc/cpuinfo)
+ """
+ physical_cpus = _find_physical_cpus()
+
+ core_count = 0
+
+ for num in physical_cpus:
+ # Some architectures, e.g. x86_64, include a field for core count.
+ # Since we found unique physical CPU entries, we can sum their core counts.
+ if 'cpu cores' in physical_cpus[num]:
+ core_count += int(physical_cpus[num]['cpu cores'])
+ else:
+ core_count += 1
+
+ return core_count
diff --git a/python/vyos/defaults.py b/python/vyos/defaults.py
index 00b14a985..fcb6a7fbc 100644
--- a/python/vyos/defaults.py
+++ b/python/vyos/defaults.py
@@ -29,6 +29,8 @@ directories = {
"vyos_udev_dir": "/run/udev/vyos"
}
+config_status = '/tmp/vyos-config-status'
+
cfg_group = 'vyattacfg'
cfg_vintage = 'vyos'
@@ -44,8 +46,10 @@ https_data = {
api_data = {
'listen_address' : '127.0.0.1',
'port' : '8080',
- 'strict' : 'false',
- 'debug' : 'false',
+ 'socket' : False,
+ 'strict' : False,
+ 'gql' : False,
+ 'debug' : False,
'api_keys' : [ {"id": "testapp", "key": "qwerty"} ]
}
diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py
index e45b0f041..2b6012a73 100644
--- a/python/vyos/ethtool.py
+++ b/python/vyos/ethtool.py
@@ -1,4 +1,4 @@
-# Copyright 2021 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright 2021-2022 VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -18,6 +18,11 @@ import re
from vyos.util import popen
+# These drivers do not support using ethtool to change the speed, duplex, or
+# flow control settings
+_drivers_without_speed_duplex_flow = ['vmxnet3', 'virtio_net', 'xen_netfront',
+ 'iavf', 'ice', 'i40e', 'hv_netvsc']
+
class Ethtool:
"""
Class is used to retrive and cache information about an ethernet adapter
@@ -41,7 +46,7 @@ class Ethtool:
# '100' : {'full': '', 'half': ''},
# '1000': {'full': ''}
# }
- _speed_duplex = { }
+ _speed_duplex = {'auto': {'auto': ''}}
_ring_buffers = { }
_ring_buffers_max = { }
_driver_name = None
@@ -188,7 +193,7 @@ class Ethtool:
if duplex not in ['auto', 'full', 'half']:
raise ValueError(f'Value "{duplex}" for duplex is invalid!')
- if self.get_driver_name() in ['vmxnet3', 'virtio_net', 'xen_netfront']:
+ if self.get_driver_name() in _drivers_without_speed_duplex_flow:
return False
if speed in self._speed_duplex:
@@ -198,7 +203,7 @@ class Ethtool:
def check_flow_control(self):
""" Check if the NIC supports flow-control """
- if self.get_driver_name() in ['vmxnet3', 'virtio_net', 'xen_netfront']:
+ if self.get_driver_name() in _drivers_without_speed_duplex_flow:
return False
return self._flow_control
diff --git a/python/vyos/firewall.py b/python/vyos/firewall.py
new file mode 100644
index 000000000..04fd44173
--- /dev/null
+++ b/python/vyos/firewall.py
@@ -0,0 +1,259 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import re
+
+from vyos.util import cmd
+from vyos.util import dict_search_args
+
+def find_nftables_rule(table, chain, rule_matches=[]):
+ # Find rule in table/chain that matches all criteria and return the handle
+ results = cmd(f'sudo nft -a list chain {table} {chain}').split("\n")
+ for line in results:
+ if all(rule_match in line for rule_match in rule_matches):
+ handle_search = re.search('handle (\d+)', line)
+ if handle_search:
+ return handle_search[1]
+ return None
+
+def remove_nftables_rule(table, chain, handle):
+ cmd(f'sudo nft delete rule {table} {chain} handle {handle}')
+
+# Functions below used by template generation
+
+def nft_action(vyos_action):
+ if vyos_action == 'accept':
+ return 'return'
+ return vyos_action
+
+def parse_rule(rule_conf, fw_name, rule_id, ip_name):
+ output = []
+ def_suffix = '6' if ip_name == 'ip6' else ''
+
+ if 'state' in rule_conf and rule_conf['state']:
+ states = ",".join([s for s, v in rule_conf['state'].items() if v == 'enable'])
+
+ if states:
+ output.append(f'ct state {{{states}}}')
+
+ if 'connection_status' in rule_conf and rule_conf['connection_status']:
+ status = rule_conf['connection_status']
+ if status['nat'] == 'destination':
+ nat_status = '{dnat}'
+ output.append(f'ct status {nat_status}')
+ if status['nat'] == 'source':
+ nat_status = '{snat}'
+ output.append(f'ct status {nat_status}')
+
+ if 'protocol' in rule_conf and rule_conf['protocol'] != 'all':
+ proto = rule_conf['protocol']
+ operator = ''
+ if proto[0] == '!':
+ operator = '!='
+ proto = proto[1:]
+ if proto == 'tcp_udp':
+ proto = '{tcp, udp}'
+ output.append(f'meta l4proto {operator} {proto}')
+
+ for side in ['destination', 'source']:
+ if side in rule_conf:
+ prefix = side[0]
+ side_conf = rule_conf[side]
+
+ if 'address' in side_conf:
+ suffix = side_conf['address']
+ if suffix[0] == '!':
+ suffix = f'!= {suffix[1:]}'
+ output.append(f'{ip_name} {prefix}addr {suffix}')
+
+ if 'mac_address' in side_conf:
+ suffix = side_conf["mac_address"]
+ if suffix[0] == '!':
+ suffix = f'!= {suffix[1:]}'
+ output.append(f'ether {prefix}addr {suffix}')
+
+ if 'port' in side_conf:
+ proto = rule_conf['protocol']
+ port = side_conf['port'].split(',')
+
+ ports = []
+ negated_ports = []
+
+ for p in port:
+ if p[0] == '!':
+ negated_ports.append(p[1:])
+ else:
+ ports.append(p)
+
+ if proto == 'tcp_udp':
+ proto = 'th'
+
+ if ports:
+ ports_str = ','.join(ports)
+ output.append(f'{proto} {prefix}port {{{ports_str}}}')
+
+ if negated_ports:
+ negated_ports_str = ','.join(negated_ports)
+ output.append(f'{proto} {prefix}port != {{{negated_ports_str}}}')
+
+ if 'group' in side_conf:
+ group = side_conf['group']
+ if 'address_group' in group:
+ group_name = group['address_group']
+ operator = ''
+ if group_name[0] == '!':
+ operator = '!='
+ group_name = group_name[1:]
+ output.append(f'{ip_name} {prefix}addr {operator} $A{def_suffix}_{group_name}')
+ elif 'network_group' in group:
+ group_name = group['network_group']
+ operator = ''
+ if group_name[0] == '!':
+ operator = '!='
+ group_name = group_name[1:]
+ output.append(f'{ip_name} {prefix}addr {operator} $N{def_suffix}_{group_name}')
+ if 'mac_group' in group:
+ group_name = group['mac_group']
+ operator = ''
+ if group_name[0] == '!':
+ operator = '!='
+ group_name = group_name[1:]
+ output.append(f'ether {prefix}addr {operator} $M_{group_name}')
+ if 'port_group' in group:
+ proto = rule_conf['protocol']
+ group_name = group['port_group']
+
+ if proto == 'tcp_udp':
+ proto = 'th'
+
+ operator = ''
+ if group_name[0] == '!':
+ operator = '!='
+ group_name = group_name[1:]
+
+ output.append(f'{proto} {prefix}port {operator} $P_{group_name}')
+
+ if 'log' in rule_conf and rule_conf['log'] == 'enable':
+ action = rule_conf['action'] if 'action' in rule_conf else 'accept'
+ output.append(f'log prefix "[{fw_name[:19]}-{rule_id}-{action[:1].upper()}] "')
+
+ if 'hop_limit' in rule_conf:
+ operators = {'eq': '==', 'gt': '>', 'lt': '<'}
+ for op, operator in operators.items():
+ if op in rule_conf['hop_limit']:
+ value = rule_conf['hop_limit'][op]
+ output.append(f'ip6 hoplimit {operator} {value}')
+
+ for icmp in ['icmp', 'icmpv6']:
+ if icmp in rule_conf:
+ if 'type_name' in rule_conf[icmp]:
+ output.append(icmp + ' type ' + rule_conf[icmp]['type_name'])
+ else:
+ if 'code' in rule_conf[icmp]:
+ output.append(icmp + ' code ' + rule_conf[icmp]['code'])
+ if 'type' in rule_conf[icmp]:
+ output.append(icmp + ' type ' + rule_conf[icmp]['type'])
+
+ if 'ipsec' in rule_conf:
+ if 'match_ipsec' in rule_conf['ipsec']:
+ output.append('meta ipsec == 1')
+ if 'match_non_ipsec' in rule_conf['ipsec']:
+ output.append('meta ipsec == 0')
+
+ if 'fragment' in rule_conf:
+ # Checking for fragmentation after priority -400 is not possible,
+ # so we use a priority -450 hook to set a mark
+ if 'match_frag' in rule_conf['fragment']:
+ output.append('meta mark 0xffff1')
+ if 'match_non_frag' in rule_conf['fragment']:
+ output.append('meta mark != 0xffff1')
+
+ if 'limit' in rule_conf:
+ if 'rate' in rule_conf['limit']:
+ output.append(f'limit rate {rule_conf["limit"]["rate"]}')
+ if 'burst' in rule_conf['limit']:
+ output.append(f'burst {rule_conf["limit"]["burst"]} packets')
+
+ if 'recent' in rule_conf:
+ count = rule_conf['recent']['count']
+ time = rule_conf['recent']['time']
+ output.append(f'add @RECENT{def_suffix}_{fw_name}_{rule_id} {{ {ip_name} saddr limit rate over {count}/{time} burst {count} packets }}')
+
+ if 'time' in rule_conf:
+ output.append(parse_time(rule_conf['time']))
+
+ tcp_flags = dict_search_args(rule_conf, 'tcp', 'flags')
+ if tcp_flags:
+ output.append(parse_tcp_flags(tcp_flags))
+
+ output.append('counter')
+
+ if 'set' in rule_conf:
+ output.append(parse_policy_set(rule_conf['set'], def_suffix))
+
+ if 'action' in rule_conf:
+ output.append(nft_action(rule_conf['action']))
+ else:
+ output.append('return')
+
+ output.append(f'comment "{fw_name}-{rule_id}"')
+ return " ".join(output)
+
+def parse_tcp_flags(flags):
+ include = [flag for flag in flags if flag != 'not']
+ exclude = list(flags['not']) if 'not' in flags else []
+ return f'tcp flags & ({"|".join(include + exclude)}) == {"|".join(include) if include else "0x0"}'
+
+def parse_time(time):
+ out = []
+ if 'startdate' in time:
+ start = time['startdate']
+ if 'T' not in start and 'starttime' in time:
+ start += f' {time["starttime"]}'
+ out.append(f'time >= "{start}"')
+ if 'starttime' in time and 'startdate' not in time:
+ out.append(f'hour >= "{time["starttime"]}"')
+ if 'stopdate' in time:
+ stop = time['stopdate']
+ if 'T' not in stop and 'stoptime' in time:
+ stop += f' {time["stoptime"]}'
+ out.append(f'time < "{stop}"')
+ if 'stoptime' in time and 'stopdate' not in time:
+ out.append(f'hour < "{time["stoptime"]}"')
+ if 'weekdays' in time:
+ days = time['weekdays'].split(",")
+ out_days = [f'"{day}"' for day in days if day[0] != '!']
+ out.append(f'day {{{",".join(out_days)}}}')
+ return " ".join(out)
+
+def parse_policy_set(set_conf, def_suffix):
+ out = []
+ if 'dscp' in set_conf:
+ dscp = set_conf['dscp']
+ out.append(f'ip{def_suffix} dscp set {dscp}')
+ if 'mark' in set_conf:
+ mark = set_conf['mark']
+ out.append(f'meta mark set {mark}')
+ if 'table' in set_conf:
+ table = set_conf['table']
+ if table == 'main':
+ table = '254'
+ mark = 0x7FFFFFFF - int(table)
+ out.append(f'meta mark set {mark}')
+ if 'tcp_mss' in set_conf:
+ mss = set_conf['tcp_mss']
+ out.append(f'tcp option maxseg size set {mss}')
+ return " ".join(out)
diff --git a/python/vyos/frr.py b/python/vyos/frr.py
index df6849472..cbba19ab7 100644
--- a/python/vyos/frr.py
+++ b/python/vyos/frr.py
@@ -73,23 +73,25 @@ from vyos.util import cmd
import logging
from logging.handlers import SysLogHandler
import os
+import sys
+
LOG = logging.getLogger(__name__)
+DEBUG = False
-DEBUG = os.path.exists('/tmp/vyos.frr.debug')
-if DEBUG:
- LOG.setLevel(logging.DEBUG)
- ch = SysLogHandler(address='/dev/log')
- ch2 = logging.StreamHandler()
- LOG.addHandler(ch)
- LOG.addHandler(ch2)
+ch = SysLogHandler(address='/dev/log')
+ch2 = logging.StreamHandler(stream=sys.stdout)
+LOG.addHandler(ch)
+LOG.addHandler(ch2)
_frr_daemons = ['zebra', 'bgpd', 'fabricd', 'isisd', 'ospf6d', 'ospfd', 'pbrd',
- 'pimd', 'ripd', 'ripngd', 'sharpd', 'staticd', 'vrrpd', 'ldpd']
+ 'pimd', 'ripd', 'ripngd', 'sharpd', 'staticd', 'vrrpd', 'ldpd',
+ 'bfdd']
path_vtysh = '/usr/bin/vtysh'
path_frr_reload = '/usr/lib/frr/frr-reload.py'
path_config = '/run/frr'
+default_add_before = r'(ip prefix-list .*|route-map .*|line vty|end)'
class FrrError(Exception):
pass
@@ -119,6 +121,12 @@ class ConfigSectionNotFound(FrrError):
"""
pass
+def init_debugging():
+ global DEBUG
+
+ DEBUG = os.path.exists('/tmp/vyos.frr.debug')
+ if DEBUG:
+ LOG.setLevel(logging.DEBUG)
def get_configuration(daemon=None, marked=False):
""" Get current running FRR configuration
@@ -214,13 +222,8 @@ def reload_configuration(config, daemon=None):
def save_configuration():
- """Save FRR configuration to /run/frr/config/frr.conf
- It save configuration on each commit. T3217
- """
-
- cmd(f'{path_vtysh} -n -w')
-
- return
+ """ T3217: Save FRR configuration to /run/frr/config/frr.conf """
+ return cmd(f'{path_vtysh} -n -w')
def execute(command):
@@ -427,6 +430,8 @@ class FRRConfig:
Using this overwrites the current loaded config objects and replaces the original loaded config
'''
+ init_debugging()
+
self.imported_config = get_configuration(daemon=daemon)
if daemon:
LOG.debug(f'load_configuration: Configuration loaded from FRR daemon {daemon}')
@@ -448,16 +453,37 @@ class FRRConfig:
mark_configuration('\n'.join(self.config))
def commit_configuration(self, daemon=None):
- '''Commit the current configuration to FRR
- daemon: str with name of the FRR daemon to commit to or
- None to use the consolidated config
+ '''
+ Commit the current configuration to FRR daemon: str with name of the
+ FRR daemon to commit to or None to use the consolidated config.
+
+ Configuration is automatically saved after apply
'''
LOG.debug('commit_configuration: Commiting configuration')
for i, e in enumerate(self.config):
LOG.debug(f'commit_configuration: new_config {i:3} {e}')
- reload_configuration('\n'.join(self.config), daemon=daemon)
- def modify_section(self, start_pattern, replacement=[], stop_pattern=r'\S+', remove_stop_mark=False, count=0):
+ # https://github.com/FRRouting/frr/issues/10132
+ # https://github.com/FRRouting/frr/issues/10133
+ count = 0
+ count_max = 5
+ while count < count_max:
+ count += 1
+ try:
+ reload_configuration('\n'.join(self.config), daemon=daemon)
+ break
+ except:
+ # we just need to re-try the commit of the configuration
+ # for the listed FRR issues above
+ pass
+ if count >= count_max:
+ raise ConfigurationNotValid(f'Config commit retry counter ({count_max}) exceeded')
+
+ # Save configuration to /run/frr/config/frr.conf
+ save_configuration()
+
+
+ def modify_section(self, start_pattern, replacement='!', stop_pattern=r'\S+', remove_stop_mark=False, count=0):
if isinstance(replacement, str):
replacement = replacement.split('\n')
elif not isinstance(replacement, list):
diff --git a/python/vyos/hostsd_client.py b/python/vyos/hostsd_client.py
index 303b6ea47..f31ef51cf 100644
--- a/python/vyos/hostsd_client.py
+++ b/python/vyos/hostsd_client.py
@@ -79,6 +79,18 @@ class Client(object):
msg = {'type': 'forward_zones', 'op': 'get'}
return self._communicate(msg)
+ def add_authoritative_zones(self, data):
+ msg = {'type': 'authoritative_zones', 'op': 'add', 'data': data}
+ self._communicate(msg)
+
+ def delete_authoritative_zones(self, data):
+ msg = {'type': 'authoritative_zones', 'op': 'delete', 'data': data}
+ self._communicate(msg)
+
+ def get_authoritative_zones(self):
+ msg = {'type': 'authoritative_zones', 'op': 'get'}
+ return self._communicate(msg)
+
def add_search_domains(self, data):
msg = {'type': 'search_domains', 'op': 'add', 'data': data}
self._communicate(msg)
diff --git a/python/vyos/ifconfig/__init__.py b/python/vyos/ifconfig/__init__.py
index 2d3e406ac..a37615c8f 100644
--- a/python/vyos/ifconfig/__init__.py
+++ b/python/vyos/ifconfig/__init__.py
@@ -26,6 +26,7 @@ from vyos.ifconfig.ethernet import EthernetIf
from vyos.ifconfig.geneve import GeneveIf
from vyos.ifconfig.loopback import LoopbackIf
from vyos.ifconfig.macvlan import MACVLANIf
+from vyos.ifconfig.input import InputIf
from vyos.ifconfig.vxlan import VXLANIf
from vyos.ifconfig.wireguard import WireGuardIf
from vyos.ifconfig.vtun import VTunIf
diff --git a/python/vyos/ifconfig/bridge.py b/python/vyos/ifconfig/bridge.py
index 27073b266..ffd9c590f 100644
--- a/python/vyos/ifconfig/bridge.py
+++ b/python/vyos/ifconfig/bridge.py
@@ -298,7 +298,6 @@ class BridgeIf(Interface):
tmp = dict_search('member.interface', config)
if tmp:
-
for interface, interface_config in tmp.items():
# if interface does yet not exist bail out early and
# add it later
@@ -316,10 +315,13 @@ class BridgeIf(Interface):
# enslave interface port to bridge
self.add_port(interface)
- # always set private-vlan/port isolation
- tmp = dict_search('isolated', interface_config)
- value = 'on' if (tmp != None) else 'off'
- lower.set_port_isolation(value)
+ if not interface.startswith('wlan'):
+ # always set private-vlan/port isolation - this can not be
+ # done when lower link is a wifi link, as it will trigger:
+ # RTNETLINK answers: Operation not supported
+ tmp = dict_search('isolated', interface_config)
+ value = 'on' if (tmp != None) else 'off'
+ lower.set_port_isolation(value)
# set bridge port path cost
if 'cost' in interface_config:
diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py
index 9d54dc78e..1280fc238 100644
--- a/python/vyos/ifconfig/ethernet.py
+++ b/python/vyos/ifconfig/ethernet.py
@@ -170,11 +170,18 @@ class EthernetIf(Interface):
return
cmd = f'ethtool --change {ifname}'
- if speed == 'auto' or duplex == 'auto':
- cmd += ' autoneg on'
- else:
- cmd += f' speed {speed} duplex {duplex} autoneg off'
- return self._cmd(cmd)
+ try:
+ if speed == 'auto' or duplex == 'auto':
+ cmd += ' autoneg on'
+ else:
+ cmd += f' speed {speed} duplex {duplex} autoneg off'
+ return self._cmd(cmd)
+ except PermissionError:
+ # Some NICs do not tell that they don't suppport settings speed/duplex,
+ # but they do not actually support it either.
+ # In that case it's probably better to ignore the error
+ # than end up with a broken config.
+ print('Warning: could not set speed/duplex settings: operation not permitted!')
def set_gro(self, state):
"""
diff --git a/python/vyos/ifconfig/geneve.py b/python/vyos/ifconfig/geneve.py
index 7cb3968df..276c34cd7 100644
--- a/python/vyos/ifconfig/geneve.py
+++ b/python/vyos/ifconfig/geneve.py
@@ -42,7 +42,7 @@ class GeneveIf(Interface):
# arguments used by iproute2. For more information please refer to:
# - https://man7.org/linux/man-pages/man8/ip-link.8.html
mapping = {
- 'parameters.ip.dont_fragment': 'df set',
+ 'parameters.ip.df' : 'df',
'parameters.ip.tos' : 'tos',
'parameters.ip.ttl' : 'ttl',
'parameters.ipv6.flowlabel' : 'flowlabel',
diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py
index 58d130ef6..22441d1d2 100755
--- a/python/vyos/ifconfig/interface.py
+++ b/python/vyos/ifconfig/interface.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2021 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright 2019-2022 VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -13,7 +13,6 @@
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
-from netifaces import interfaces
import os
import re
import json
@@ -37,6 +36,7 @@ from vyos.util import mac2eui64
from vyos.util import dict_search
from vyos.util import read_file
from vyos.util import get_interface_config
+from vyos.util import get_interface_namespace
from vyos.util import is_systemd_service_active
from vyos.template import is_ipv4
from vyos.template import is_ipv6
@@ -135,6 +135,9 @@ class Interface(Control):
'validate': assert_mtu,
'shellcmd': 'ip link set dev {ifname} mtu {value}',
},
+ 'netns': {
+ 'shellcmd': 'ip link set dev {ifname} netns {value}',
+ },
'vrf': {
'convert': lambda v: f'master {v}' if v else 'nomaster',
'shellcmd': 'ip link set dev {ifname} {value}',
@@ -512,6 +515,35 @@ class Interface(Control):
if prev_state == 'up':
self.set_admin_state('up')
+ def del_netns(self, netns):
+ """
+ Remove interface from given NETNS.
+ """
+
+ # If NETNS does not exist then there is nothing to delete
+ if not os.path.exists(f'/run/netns/{netns}'):
+ return None
+
+ # As a PoC we only allow 'dummy' interfaces
+ if 'dum' not in self.ifname:
+ return None
+
+ # Check if interface realy exists in namespace
+ if get_interface_namespace(self.ifname) != None:
+ self._cmd(f'ip netns exec {get_interface_namespace(self.ifname)} ip link del dev {self.ifname}')
+ return
+
+ def set_netns(self, netns):
+ """
+ Add interface from given NETNS.
+
+ Example:
+ >>> from vyos.ifconfig import Interface
+ >>> Interface('dum0').set_netns('foo')
+ """
+
+ self.set_interface('netns', netns)
+
def set_vrf(self, vrf):
"""
Add/Remove interface from given VRF instance.
@@ -544,6 +576,15 @@ class Interface(Control):
return None
return self.set_interface('arp_cache_tmo', tmo)
+ def _cleanup_mss_rules(self, table, ifname):
+ commands = []
+ results = self._cmd(f'nft -a list chain {table} VYOS_TCP_MSS').split("\n")
+ for line in results:
+ if f'oifname "{ifname}"' in line:
+ handle_search = re.search('handle (\d+)', line)
+ if handle_search:
+ self._cmd(f'nft delete rule {table} VYOS_TCP_MSS handle {handle_search[1]}')
+
def set_tcp_ipv4_mss(self, mss):
"""
Set IPv4 TCP MSS value advertised when TCP SYN packets leave this
@@ -555,22 +596,14 @@ class Interface(Control):
>>> from vyos.ifconfig import Interface
>>> Interface('eth0').set_tcp_ipv4_mss(1340)
"""
- iptables_bin = 'iptables'
- base_options = f'-A FORWARD -o {self.ifname} -p tcp -m tcp --tcp-flags SYN,RST SYN'
- out = self._cmd(f'{iptables_bin}-save -t mangle')
- for line in out.splitlines():
- if line.startswith(base_options):
- # remove OLD MSS mangling configuration
- line = line.replace('-A FORWARD', '-D FORWARD')
- self._cmd(f'{iptables_bin} -t mangle {line}')
-
- cmd_mss = f'{iptables_bin} -t mangle {base_options} --jump TCPMSS'
+ self._cleanup_mss_rules('raw', self.ifname)
+ nft_prefix = 'nft add rule raw VYOS_TCP_MSS'
+ base_cmd = f'oifname "{self.ifname}" tcp flags & (syn|rst) == syn'
if mss == 'clamp-mss-to-pmtu':
- self._cmd(f'{cmd_mss} --clamp-mss-to-pmtu')
+ self._cmd(f"{nft_prefix} '{base_cmd} tcp option maxseg size set rt mtu'")
elif int(mss) > 0:
- # probably add option to clamp only if bigger:
low_mss = str(int(mss) + 1)
- self._cmd(f'{cmd_mss} -m tcpmss --mss {low_mss}:65535 --set-mss {mss}')
+ self._cmd(f"{nft_prefix} '{base_cmd} tcp option maxseg size {low_mss}-65535 tcp option maxseg size set {mss}'")
def set_tcp_ipv6_mss(self, mss):
"""
@@ -583,22 +616,14 @@ class Interface(Control):
>>> from vyos.ifconfig import Interface
>>> Interface('eth0').set_tcp_mss(1320)
"""
- iptables_bin = 'ip6tables'
- base_options = f'-A FORWARD -o {self.ifname} -p tcp -m tcp --tcp-flags SYN,RST SYN'
- out = self._cmd(f'{iptables_bin}-save -t mangle')
- for line in out.splitlines():
- if line.startswith(base_options):
- # remove OLD MSS mangling configuration
- line = line.replace('-A FORWARD', '-D FORWARD')
- self._cmd(f'{iptables_bin} -t mangle {line}')
-
- cmd_mss = f'{iptables_bin} -t mangle {base_options} --jump TCPMSS'
+ self._cleanup_mss_rules('ip6 raw', self.ifname)
+ nft_prefix = 'nft add rule ip6 raw VYOS_TCP_MSS'
+ base_cmd = f'oifname "{self.ifname}" tcp flags & (syn|rst) == syn'
if mss == 'clamp-mss-to-pmtu':
- self._cmd(f'{cmd_mss} --clamp-mss-to-pmtu')
+ self._cmd(f"{nft_prefix} '{base_cmd} tcp option maxseg size set rt mtu'")
elif int(mss) > 0:
- # probably add option to clamp only if bigger:
low_mss = str(int(mss) + 1)
- self._cmd(f'{cmd_mss} -m tcpmss --mss {low_mss}:65535 --set-mss {mss}')
+ self._cmd(f"{nft_prefix} '{base_cmd} tcp option maxseg size {low_mss}-65535 tcp option maxseg size set {mss}'")
def set_arp_filter(self, arp_filter):
"""
@@ -711,8 +736,9 @@ class Interface(Control):
if all_rp_filter == 1: global_setting = 'strict'
elif all_rp_filter == 2: global_setting = 'loose'
- print(f'WARNING: Global source-validation is set to "{global_setting}\n"' \
- 'this overrides per interface setting!')
+ from vyos.base import Warning
+ Warning(f'Global source-validation is set to "{global_setting} '\
+ f'this overrides per interface setting!')
tmp = self.get_interface('rp_filter')
if int(tmp) == value:
@@ -1054,16 +1080,17 @@ class Interface(Control):
if addr in self._addr:
return False
- addr_is_v4 = is_ipv4(addr)
-
# add to interface
if addr == 'dhcp':
self.set_dhcp(True)
elif addr == 'dhcpv6':
self.set_dhcpv6(True)
elif not is_intf_addr_assigned(self.ifname, addr):
- self._cmd(f'ip addr add "{addr}" '
- f'{"brd + " if addr_is_v4 else ""}dev "{self.ifname}"')
+ tmp = f'ip addr add {addr} dev {self.ifname}'
+ # Add broadcast address for IPv4
+ if is_ipv4(addr): tmp += ' brd +'
+
+ self._cmd(tmp)
else:
return False
@@ -1202,12 +1229,11 @@ class Interface(Control):
options_file = f'{config_base}_{ifname}.options'
pid_file = f'{config_base}_{ifname}.pid'
lease_file = f'{config_base}_{ifname}.leases'
-
- # Stop client with old config files to get the right IF_METRIC.
systemd_service = f'dhclient@{ifname}.service'
- if is_systemd_service_active(systemd_service):
- self._cmd(f'systemctl stop {systemd_service}')
+ # 'up' check is mandatory b/c even if the interface is A/D, as soon as
+ # the DHCP client is started the interface will be placed in u/u state.
+ # This is not what we intended to do when disabling an interface.
if enable and 'disable' not in self._config:
if dict_search('dhcp_options.host_name', self._config) == None:
# read configured system hostname.
@@ -1218,16 +1244,19 @@ class Interface(Control):
tmp = {'dhcp_options' : { 'host_name' : hostname}}
self._config = dict_merge(tmp, self._config)
- render(options_file, 'dhcp-client/daemon-options.tmpl',
- self._config)
- render(config_file, 'dhcp-client/ipv4.tmpl',
- self._config)
+ render(options_file, 'dhcp-client/daemon-options.j2', self._config)
+ render(config_file, 'dhcp-client/ipv4.j2', self._config)
- # 'up' check is mandatory b/c even if the interface is A/D, as soon as
- # the DHCP client is started the interface will be placed in u/u state.
- # This is not what we intended to do when disabling an interface.
- return self._cmd(f'systemctl restart {systemd_service}')
+ # When the DHCP client is restarted a brief outage will occur, as
+ # the old lease is released a new one is acquired (T4203). We will
+ # only restart DHCP client if it's option changed, or if it's not
+ # running, but it should be running (e.g. on system startup)
+ if 'dhcp_options_changed' in self._config or not is_systemd_service_active(systemd_service):
+ return self._cmd(f'systemctl restart {systemd_service}')
+ return None
else:
+ if is_systemd_service_active(systemd_service):
+ self._cmd(f'systemctl stop {systemd_service}')
# cleanup old config files
for file in [config_file, options_file, pid_file, lease_file]:
if os.path.isfile(file):
@@ -1246,8 +1275,7 @@ class Interface(Control):
systemd_service = f'dhcp6c@{ifname}.service'
if enable and 'disable' not in self._config:
- render(config_file, 'dhcp-client/ipv6.tmpl',
- self._config)
+ render(config_file, 'dhcp-client/ipv6.j2', self._config)
# We must ignore any return codes. This is required to enable
# DHCPv6-PD for interfaces which are yet not up and running.
@@ -1258,48 +1286,57 @@ class Interface(Control):
if os.path.isfile(config_file):
os.remove(config_file)
- def set_mirror(self):
+ def set_mirror_redirect(self):
# Please refer to the document for details
# - https://man7.org/linux/man-pages/man8/tc.8.html
# - https://man7.org/linux/man-pages/man8/tc-mirred.8.html
# Depening if we are the source or the target interface of the port
# mirror we need to setup some variables.
source_if = self._config['ifname']
- config = self._config.get('mirror', None)
+ mirror_config = None
+ if 'mirror' in self._config:
+ mirror_config = self._config['mirror']
if 'is_mirror_intf' in self._config:
source_if = next(iter(self._config['is_mirror_intf']))
- config = self._config['is_mirror_intf'][source_if].get('mirror', None)
-
- # Check configuration stored by old perl code before delete T3782
- if not 'redirect' in self._config:
- # Please do not clear the 'set $? = 0 '. It's meant to force a return of 0
- # Remove existing mirroring rules
- delete_tc_cmd = f'tc qdisc del dev {source_if} handle ffff: ingress 2> /dev/null;'
- delete_tc_cmd += f'tc qdisc del dev {source_if} handle 1: root prio 2> /dev/null;'
- delete_tc_cmd += 'set $?=0'
- self._popen(delete_tc_cmd)
-
- # Bail out early if nothing needs to be configured
- if not config:
- return
-
- for direction, mirror_if in config.items():
- if mirror_if not in interfaces():
- continue
-
- if direction == 'ingress':
- handle = 'ffff: ingress'
- parent = 'ffff:'
- elif direction == 'egress':
- handle = '1: root prio'
- parent = '1:'
-
- # Mirror egress traffic
- mirror_cmd = f'tc qdisc add dev {source_if} handle {handle}; '
- # Export the mirrored traffic to the interface
- mirror_cmd += f'tc filter add dev {source_if} parent {parent} protocol all prio 10 u32 match u32 0 0 flowid 1:1 action mirred egress mirror dev {mirror_if}'
- self._popen(mirror_cmd)
+ mirror_config = self._config['is_mirror_intf'][source_if].get('mirror', None)
+
+ redirect_config = None
+
+ # clear existing ingess - ignore errors (e.g. "Error: Cannot find specified
+ # qdisc on specified device") - we simply cleanup all stuff here
+ self._popen(f'tc qdisc del dev {source_if} parent ffff: 2>/dev/null');
+ self._popen(f'tc qdisc del dev {source_if} parent 1: 2>/dev/null');
+
+ # Apply interface mirror policy
+ if mirror_config:
+ for direction, target_if in mirror_config.items():
+ if direction == 'ingress':
+ handle = 'ffff: ingress'
+ parent = 'ffff:'
+ elif direction == 'egress':
+ handle = '1: root prio'
+ parent = '1:'
+
+ # Mirror egress traffic
+ mirror_cmd = f'tc qdisc add dev {source_if} handle {handle}; '
+ # Export the mirrored traffic to the interface
+ mirror_cmd += f'tc filter add dev {source_if} parent {parent} protocol '\
+ f'all prio 10 u32 match u32 0 0 flowid 1:1 action mirred '\
+ f'egress mirror dev {target_if}'
+ _, err = self._popen(mirror_cmd)
+ if err: print('tc qdisc(filter for mirror port failed')
+
+ # Apply interface traffic redirection policy
+ elif 'redirect' in self._config:
+ _, err = self._popen(f'tc qdisc add dev {source_if} handle ffff: ingress')
+ if err: print(f'tc qdisc add for redirect failed!')
+
+ target_if = self._config['redirect']
+ _, err = self._popen(f'tc filter add dev {source_if} parent ffff: protocol '\
+ f'all prio 10 u32 match u32 0 0 flowid 1:1 action mirred '\
+ f'egress redirect dev {target_if}')
+ if err: print('tc filter add for redirect failed')
def set_xdp(self, state):
"""
@@ -1353,6 +1390,16 @@ class Interface(Control):
if mac:
self.set_mac(mac)
+ # If interface is connected to NETNS we don't have to check all other
+ # settings like MTU/IPv6/sysctl values, etc.
+ # Since the interface is pushed onto a separate logical stack
+ # Configure NETNS
+ if dict_search('netns', config) != None:
+ self.set_netns(config.get('netns', ''))
+ return
+ else:
+ self.del_netns(config.get('netns', ''))
+
# Update interface description
self.set_alias(config.get('description', ''))
@@ -1388,9 +1435,6 @@ class Interface(Control):
else:
self.del_addr(addr)
- for addr in new_addr:
- self.add_addr(addr)
-
# start DHCPv6 client when only PD was configured
if dhcpv6pd:
self.set_dhcpv6(True)
@@ -1405,16 +1449,15 @@ class Interface(Control):
# checked before
self.set_vrf(config.get('vrf', ''))
+ # Add this section after vrf T4331
+ for addr in new_addr:
+ self.add_addr(addr)
+
# Configure MSS value for IPv4 TCP connections
tmp = dict_search('ip.adjust_mss', config)
value = tmp if (tmp != None) else '0'
self.set_tcp_ipv4_mss(value)
- # Configure MSS value for IPv6 TCP connections
- tmp = dict_search('ipv6.adjust_mss', config)
- value = tmp if (tmp != None) else '0'
- self.set_tcp_ipv6_mss(value)
-
# Configure ARP cache timeout in milliseconds - has default value
tmp = dict_search('ip.arp_cache_timeout', config)
value = tmp if (tmp != None) else '30'
@@ -1460,6 +1503,18 @@ class Interface(Control):
value = tmp if (tmp != None) else '0'
self.set_ipv4_source_validation(value)
+ # MTU - Maximum Transfer Unit has a default value. It must ALWAYS be set
+ # before mangling any IPv6 option. If MTU is less then 1280 IPv6 will be
+ # automatically disabled by the kernel. Also MTU must be increased before
+ # configuring any IPv6 address on the interface.
+ if 'mtu' in config:
+ self.set_mtu(config.get('mtu'))
+
+ # Configure MSS value for IPv6 TCP connections
+ tmp = dict_search('ipv6.adjust_mss', config)
+ value = tmp if (tmp != None) else '0'
+ self.set_tcp_ipv6_mss(value)
+
# IPv6 forwarding
tmp = dict_search('ipv6.disable_forwarding', config)
value = '0' if (tmp != None) else '1'
@@ -1482,10 +1537,6 @@ class Interface(Control):
value = tmp if (tmp != None) else '1'
self.set_ipv6_dad_messages(value)
- # MTU - Maximum Transfer Unit
- if 'mtu' in config:
- self.set_mtu(config.get('mtu'))
-
# Delete old IPv6 EUI64 addresses before changing MAC
for addr in (dict_search('ipv6.address.eui64_old', config) or []):
self.del_ipv6_eui64_address(addr)
@@ -1510,8 +1561,8 @@ class Interface(Control):
# eXpress Data Path - highly experimental
self.set_xdp('xdp' in config)
- # configure port mirror
- self.set_mirror()
+ # configure interface mirror or redirection target
+ self.set_mirror_redirect()
# Enable/Disable of an interface must always be done at the end of the
# derived class to make use of the ref-counting set_admin_state()
@@ -1536,12 +1587,10 @@ class Interface(Control):
tmp['source_interface'] = ifname
tmp['vlan_id'] = vif_s_id
- vif_s_ifname = f'{ifname}.{vif_s_id}'
- vif_s_config['ifname'] = vif_s_ifname
-
# It is not possible to change the VLAN encapsulation protocol
# "on-the-fly". For this "quirk" we need to actively delete and
# re-create the VIF-S interface.
+ vif_s_ifname = f'{ifname}.{vif_s_id}'
if self.exists(vif_s_ifname):
cur_cfg = get_interface_config(vif_s_ifname)
protocol = dict_search('linkinfo.info_data.protocol', cur_cfg).lower()
@@ -1563,7 +1612,6 @@ class Interface(Control):
tmp['vlan_id'] = vif_c_id
vif_c_ifname = f'{vif_s_ifname}.{vif_c_id}'
- vif_c_config['ifname'] = vif_c_ifname
c_vlan = VLANIf(vif_c_ifname, **tmp)
c_vlan.update(vif_c_config)
@@ -1574,10 +1622,7 @@ class Interface(Control):
# create/update 802.1q VLAN interfaces
for vif_id, vif_config in config.get('vif', {}).items():
-
vif_ifname = f'{ifname}.{vif_id}'
- vif_config['ifname'] = vif_ifname
-
tmp = deepcopy(VLANIf.get_config())
tmp['source_interface'] = ifname
tmp['vlan_id'] = vif_id
@@ -1670,6 +1715,3 @@ class VLANIf(Interface):
return None
return super().set_admin_state(state)
-
- def set_mirror(self):
- return
diff --git a/python/vyos/ifconfig/loopback.py b/python/vyos/ifconfig/loopback.py
index 192c12f5c..b3babfadc 100644
--- a/python/vyos/ifconfig/loopback.py
+++ b/python/vyos/ifconfig/loopback.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2021 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright 2019-2022 VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -23,7 +23,6 @@ class LoopbackIf(Interface):
"""
_persistent_addresses = ['127.0.0.1/8', '::1/128']
iftype = 'loopback'
-
definition = {
**Interface.definition,
**{
@@ -32,6 +31,7 @@ class LoopbackIf(Interface):
'bridgeable': True,
}
}
+
def remove(self):
"""
Loopback interface can not be deleted from operating system. We can
@@ -57,12 +57,14 @@ class LoopbackIf(Interface):
interface setup code and provide a single point of entry when workin
on any interface. """
- addr = config.get('address', [])
+ address = config.get('address', [])
# We must ensure that the loopback addresses are never deleted from the system
- addr += self._persistent_addresses
+ for tmp in self._persistent_addresses:
+ if tmp not in address:
+ address.append(tmp)
# Update IP address entry in our dictionary
- config.update({'address' : addr})
+ config.update({'address' : address})
# call base class
super().update(config)
diff --git a/python/vyos/ifconfig/pppoe.py b/python/vyos/ifconfig/pppoe.py
index 1d13264bf..63ffc8069 100644
--- a/python/vyos/ifconfig/pppoe.py
+++ b/python/vyos/ifconfig/pppoe.py
@@ -27,12 +27,13 @@ class PPPoEIf(Interface):
},
}
- def _remove_routes(self, vrf=''):
+ def _remove_routes(self, vrf=None):
# Always delete default routes when interface is removed
+ vrf_cmd = ''
if vrf:
- vrf = f'-c "vrf {vrf}"'
- self._cmd(f'vtysh -c "conf t" {vrf} -c "no ip route 0.0.0.0/0 {self.ifname} tag 210"')
- self._cmd(f'vtysh -c "conf t" {vrf} -c "no ipv6 route ::/0 {self.ifname} tag 210"')
+ vrf_cmd = f'-c "vrf {vrf}"'
+ self._cmd(f'vtysh -c "conf t" {vrf_cmd} -c "no ip route 0.0.0.0/0 {self.ifname} tag 210"')
+ self._cmd(f'vtysh -c "conf t" {vrf_cmd} -c "no ipv6 route ::/0 {self.ifname} tag 210"')
def remove(self):
"""
@@ -44,11 +45,11 @@ class PPPoEIf(Interface):
>>> i = Interface('pppoe0')
>>> i.remove()
"""
-
+ vrf = None
tmp = get_interface_config(self.ifname)
- vrf = ''
if 'master' in tmp:
- self._remove_routes(tmp['master'])
+ vrf = tmp['master']
+ self._remove_routes(vrf)
# remove bond master which places members in disabled state
super().remove()
@@ -84,10 +85,12 @@ class PPPoEIf(Interface):
self._config = config
# remove old routes from an e.g. old VRF assignment
- vrf = ''
- if 'vrf_old' in config:
- vrf = config['vrf_old']
- self._remove_routes(vrf)
+ if 'shutdown_required':
+ vrf = None
+ tmp = get_interface_config(self.ifname)
+ if 'master' in tmp:
+ vrf = tmp['master']
+ self._remove_routes(vrf)
# DHCPv6 PD handling is a bit different on PPPoE interfaces, as we do
# not require an 'address dhcpv6' CLI option as with other interfaces
@@ -98,54 +101,15 @@ class PPPoEIf(Interface):
super().update(config)
- if 'default_route' not in config or config['default_route'] == 'none':
- return
-
- #
- # Set default routes pointing to pppoe interface
- #
- vrf = ''
- sed_opt = '^ip route'
-
- install_v4 = True
- install_v6 = True
-
# generate proper configuration string when VRFs are in use
+ vrf = ''
if 'vrf' in config:
tmp = config['vrf']
vrf = f'-c "vrf {tmp}"'
- sed_opt = f'vrf {tmp}'
-
- if config['default_route'] == 'auto':
- # only add route if there is no default route present
- tmp = self._cmd(f'vtysh -c "show running-config staticd no-header" | sed -n "/{sed_opt}/,/!/p"')
- for line in tmp.splitlines():
- line = line.lstrip()
- if line.startswith('ip route 0.0.0.0/0'):
- install_v4 = False
- continue
-
- if 'ipv6' in config and line.startswith('ipv6 route ::/0'):
- install_v6 = False
- continue
-
- elif config['default_route'] == 'force':
- # Force means that all static routes are replaced with the ones from this interface
- tmp = self._cmd(f'vtysh -c "show running-config staticd no-header" | sed -n "/{sed_opt}/,/!/p"')
- for line in tmp.splitlines():
- if self.ifname in line:
- # It makes no sense to remove a route with our interface and the later re-add it.
- # This will only make traffic disappear - which is a no-no!
- continue
-
- line = line.lstrip()
- if line.startswith('ip route 0.0.0.0/0'):
- self._cmd(f'vtysh -c "conf t" {vrf} -c "no {line}"')
-
- if 'ipv6' in config and line.startswith('ipv6 route ::/0'):
- self._cmd(f'vtysh -c "conf t" {vrf} -c "no {line}"')
-
- if install_v4:
- self._cmd(f'vtysh -c "conf t" {vrf} -c "ip route 0.0.0.0/0 {self.ifname} tag 210"')
- if install_v6 and 'ipv6' in config:
- self._cmd(f'vtysh -c "conf t" {vrf} -c "ipv6 route ::/0 {self.ifname} tag 210"')
+
+ if 'no_default_route' not in config:
+ # Set default route(s) pointing to PPPoE interface
+ distance = config['default_route_distance']
+ self._cmd(f'vtysh -c "conf t" {vrf} -c "ip route 0.0.0.0/0 {self.ifname} tag 210 {distance}"')
+ if 'ipv6' in config:
+ self._cmd(f'vtysh -c "conf t" {vrf} -c "ipv6 route ::/0 {self.ifname} tag 210 {distance}"')
diff --git a/python/vyos/ifconfig/section.py b/python/vyos/ifconfig/section.py
index 0e4447b9e..91f667b65 100644
--- a/python/vyos/ifconfig/section.py
+++ b/python/vyos/ifconfig/section.py
@@ -52,12 +52,12 @@ class Section:
name: name of the interface
vlan: if vlan is True, do not stop at the vlan number
"""
- name = name.rstrip('0123456789')
- name = name.rstrip('.')
- if vlan:
- name = name.rstrip('0123456789.')
if vrrp:
- name = name.rstrip('0123456789v')
+ name = re.sub(r'\d(\d|v|\.)*$', '', name)
+ elif vlan:
+ name = re.sub(r'\d(\d|\.)*$', '', name)
+ else:
+ name = re.sub(r'\d+$', '', name)
return name
@classmethod
diff --git a/python/vyos/ifconfig/vxlan.py b/python/vyos/ifconfig/vxlan.py
index d73fb47b8..5baff10a9 100644
--- a/python/vyos/ifconfig/vxlan.py
+++ b/python/vyos/ifconfig/vxlan.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2021 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright 2019-2022 VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -54,18 +54,31 @@ class VXLANIf(Interface):
# arguments used by iproute2. For more information please refer to:
# - https://man7.org/linux/man-pages/man8/ip-link.8.html
mapping = {
- 'source_address' : 'local',
- 'source_interface' : 'dev',
- 'remote' : 'remote',
'group' : 'group',
- 'parameters.ip.dont_fragment': 'df set',
+ 'external' : 'external',
+ 'gpe' : 'gpe',
+ 'parameters.ip.df' : 'df',
'parameters.ip.tos' : 'tos',
'parameters.ip.ttl' : 'ttl',
'parameters.ipv6.flowlabel' : 'flowlabel',
'parameters.nolearning' : 'nolearning',
+ 'remote' : 'remote',
+ 'source_address' : 'local',
+ 'source_interface' : 'dev',
+ 'vni' : 'id',
}
- cmd = 'ip link add {ifname} type {type} id {vni} dstport {port}'
+ # IPv6 flowlabels can only be used on IPv6 tunnels, thus we need to
+ # ensure that at least the first remote IP address is passed to the
+ # tunnel creation command. Subsequent tunnel remote addresses can later
+ # be added to the FDB
+ remote_list = None
+ if 'remote' in self.config:
+ # skip first element as this is already configured as remote
+ remote_list = self.config['remote'][1:]
+ self.config['remote'] = self.config['remote'][0]
+
+ cmd = 'ip link add {ifname} type {type} dstport {port}'
for vyos_key, iproute2_key in mapping.items():
# dict_search will return an empty dict "{}" for valueless nodes like
# "parameters.nolearning" - thus we need to test the nodes existence
@@ -79,3 +92,10 @@ class VXLANIf(Interface):
self._cmd(cmd.format(**self.config))
# interface is always A/D down. It needs to be enabled explicitly
self.set_admin_state('down')
+
+ # VXLAN tunnel is always recreated on any change - see interfaces-vxlan.py
+ if remote_list:
+ for remote in remote_list:
+ cmd = f'bridge fdb append to 00:00:00:00:00:00 dst {remote} ' \
+ 'port {port} dev {ifname}'
+ self._cmd(cmd.format(**self.config))
diff --git a/python/vyos/ifconfig/wireless.py b/python/vyos/ifconfig/wireless.py
index 748b6e02d..88eaa772b 100644
--- a/python/vyos/ifconfig/wireless.py
+++ b/python/vyos/ifconfig/wireless.py
@@ -49,10 +49,10 @@ class WiFiIf(Interface):
on any interface. """
# We can not call add_to_bridge() until wpa_supplicant is running, thus
- # we will remove the key from the config dict and react to this specal
- # case in thie derived class.
+ # we will remove the key from the config dict and react to this special
+ # case in this derived class.
# re-add ourselves to any bridge we might have fallen out of
- bridge_member = ''
+ bridge_member = None
if 'is_bridge_member' in config:
bridge_member = config['is_bridge_member']
del config['is_bridge_member']
diff --git a/python/vyos/migrator.py b/python/vyos/migrator.py
index 4574bb6d1..a2e0daabd 100644
--- a/python/vyos/migrator.py
+++ b/python/vyos/migrator.py
@@ -195,7 +195,7 @@ class Migrator(object):
# This will force calling all migration scripts:
cfg_versions = {}
- sys_versions = systemversions.get_system_versions()
+ sys_versions = systemversions.get_system_component_version()
# save system component versions in json file for easy reference
self.save_json_record(sys_versions)
diff --git a/python/vyos/pki.py b/python/vyos/pki.py
index 68ad73bf2..0b916eaae 100644
--- a/python/vyos/pki.py
+++ b/python/vyos/pki.py
@@ -331,3 +331,29 @@ def verify_certificate(cert, ca_cert):
return True
except InvalidSignature:
return False
+
+# Certificate chain
+
+def find_parent(cert, ca_certs):
+ for ca_cert in ca_certs:
+ if verify_certificate(cert, ca_cert):
+ return ca_cert
+ return None
+
+def find_chain(cert, ca_certs):
+ remaining = ca_certs.copy()
+ chain = [cert]
+
+ while remaining:
+ parent = find_parent(chain[-1], remaining)
+ if parent is None:
+ # No parent in the list of remaining certificates or there's a circular dependency
+ break
+ elif parent == chain[-1]:
+ # Self-signed: must be root CA (end of chain)
+ break
+ else:
+ remaining.remove(parent)
+ chain.append(parent)
+
+ return chain
diff --git a/python/vyos/range_regex.py b/python/vyos/range_regex.py
new file mode 100644
index 000000000..a8190d140
--- /dev/null
+++ b/python/vyos/range_regex.py
@@ -0,0 +1,142 @@
+'''Copyright (c) 2013, Dmitry Voronin
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+
+2. 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.
+
+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.
+'''
+import math
+
+# coding=utf8
+
+# Split range to ranges that has its unique pattern.
+# Example for 12-345:
+#
+# 12- 19: 1[2-9]
+# 20- 99: [2-9]\d
+# 100-299: [1-2]\d{2}
+# 300-339: 3[0-3]\d
+# 340-345: 34[0-5]
+
+def range_to_regex(inpt_range):
+ if isinstance(inpt_range, str):
+ range_list = inpt_range.split('-')
+ # Check input arguments
+ if len(range_list) == 2:
+ # The first element in range must be higher then the second
+ if int(range_list[0]) < int(range_list[1]):
+ return regex_for_range(int(range_list[0]), int(range_list[1]))
+
+ return None
+
+def bounded_regex_for_range(min_, max_):
+ return r'\b({})\b'.format(regex_for_range(min_, max_))
+
+def regex_for_range(min_, max_):
+ """
+ > regex_for_range(12, 345)
+ '1[2-9]|[2-9]\d|[1-2]\d{2}|3[0-3]\d|34[0-5]'
+ """
+ positive_subpatterns = []
+ negative_subpatterns = []
+
+ if min_ < 0:
+ min__ = 1
+ if max_ < 0:
+ min__ = abs(max_)
+ max__ = abs(min_)
+
+ negative_subpatterns = split_to_patterns(min__, max__)
+ min_ = 0
+
+ if max_ >= 0:
+ positive_subpatterns = split_to_patterns(min_, max_)
+
+ negative_only_subpatterns = ['-' + val for val in negative_subpatterns if val not in positive_subpatterns]
+ positive_only_subpatterns = [val for val in positive_subpatterns if val not in negative_subpatterns]
+ intersected_subpatterns = ['-?' + val for val in negative_subpatterns if val in positive_subpatterns]
+
+ subpatterns = negative_only_subpatterns + intersected_subpatterns + positive_only_subpatterns
+ return '|'.join(subpatterns)
+
+
+def split_to_patterns(min_, max_):
+ subpatterns = []
+
+ start = min_
+ for stop in split_to_ranges(min_, max_):
+ subpatterns.append(range_to_pattern(start, stop))
+ start = stop + 1
+
+ return subpatterns
+
+
+def split_to_ranges(min_, max_):
+ stops = {max_}
+
+ nines_count = 1
+ stop = fill_by_nines(min_, nines_count)
+ while min_ <= stop < max_:
+ stops.add(stop)
+
+ nines_count += 1
+ stop = fill_by_nines(min_, nines_count)
+
+ zeros_count = 1
+ stop = fill_by_zeros(max_ + 1, zeros_count) - 1
+ while min_ < stop <= max_:
+ stops.add(stop)
+
+ zeros_count += 1
+ stop = fill_by_zeros(max_ + 1, zeros_count) - 1
+
+ stops = list(stops)
+ stops.sort()
+
+ return stops
+
+
+def fill_by_nines(integer, nines_count):
+ return int(str(integer)[:-nines_count] + '9' * nines_count)
+
+
+def fill_by_zeros(integer, zeros_count):
+ return integer - integer % 10 ** zeros_count
+
+
+def range_to_pattern(start, stop):
+ pattern = ''
+ any_digit_count = 0
+
+ for start_digit, stop_digit in zip(str(start), str(stop)):
+ if start_digit == stop_digit:
+ pattern += start_digit
+ elif start_digit != '0' or stop_digit != '9':
+ pattern += '[{}-{}]'.format(start_digit, stop_digit)
+ else:
+ any_digit_count += 1
+
+ if any_digit_count:
+ pattern += r'\d'
+
+ if any_digit_count > 1:
+ pattern += '{{{}}}'.format(any_digit_count)
+
+ return pattern \ No newline at end of file
diff --git a/python/vyos/remote.py b/python/vyos/remote.py
index 2419f8873..66044fa52 100644
--- a/python/vyos/remote.py
+++ b/python/vyos/remote.py
@@ -74,20 +74,6 @@ class SourceAdapter(HTTPAdapter):
num_pools=connections, maxsize=maxsize,
block=block, source_address=self._source_pair)
-class WrappedFile:
- def __init__(self, obj, size=None, chunk_size=CHUNK_SIZE):
- self._obj = obj
- self._progress = size and make_incremental_progressbar(chunk_size / size)
- def read(self, size=-1):
- if self._progress:
- next(self._progress)
- self._obj.read(size)
- def write(self, size=-1):
- if self._progress:
- next(self._progress)
- self._obj.write(size)
- def __getattr__(self, attr):
- return getattr(self._obj, attr)
def check_storage(path, size):
"""
@@ -97,8 +83,7 @@ def check_storage(path, size):
directory = path if os.path.isdir(path) else (os.path.dirname(os.path.expanduser(path)) or os.getcwd())
# `size` can be None or 0 to indicate unknown size.
if not size:
- print_error('Warning: Cannot determine size of remote file.')
- print_error('Bravely continuing regardless.')
+ print_error('Warning: Cannot determine size of remote file. Bravely continuing regardless.')
return
if size < 1024 * 1024:
@@ -236,9 +221,13 @@ class HttpC:
# Not only would it potentially mess up with the progress bar but
# `shutil.copyfileobj(request.raw, file)` does not handle automatic decoding.
s.headers.update({'Accept-Encoding': 'identity'})
- with s.head(self.urlstring) as r:
+ with s.head(self.urlstring, allow_redirects=True) as r:
# Abort early if the destination is inaccessible.
r.raise_for_status()
+ # If the request got redirected, keep the last URL we ended up with.
+ final_urlstring = r.url
+ if r.history and self.progressbar:
+ print_error('Redirecting to ' + final_urlstring)
# Check for the prospective file size.
try:
size = int(r.headers['Content-Length'])
@@ -247,7 +236,7 @@ class HttpC:
size = None
if self.check_space:
check_storage(location, size)
- with s.get(self.urlstring, stream=True) as r, open(location, 'wb') as f:
+ with s.get(final_urlstring, stream=True) as r, open(location, 'wb') as f:
if self.progressbar and size:
progress = make_incremental_progressbar(CHUNK_SIZE / size)
next(progress)
@@ -259,10 +248,9 @@ class HttpC:
shutil.copyfileobj(r.raw, f)
def upload(self, location: str):
- size = os.path.getsize(location) if self.progressbar else None
- # Keep in mind that `data` can be a file-like or iterable object.
- with self._establish() as s, file(location, 'rb') as f:
- s.post(self.urlstring, data=WrappedFile(f, size))
+ # Does not yet support progressbars.
+ with self._establish() as s, open(location, 'rb') as f:
+ s.post(self.urlstring, data=f, allow_redirects=True)
class TftpC:
@@ -324,15 +312,16 @@ def friendly_download(local_path, urlstring, source_host='', source_port=0):
print_error('Downloading...')
download(local_path, urlstring, True, True, source_host, source_port)
except KeyboardInterrupt:
- print_error('Download aborted by user.')
+ print_error('\nDownload aborted by user.')
sys.exit(1)
except:
import traceback
+ print_error(f'Failed to download {urlstring}.')
# There are a myriad different reasons a download could fail.
# SSH errors, FTP errors, I/O errors, HTTP errors (403, 404...)
# We omit the scary stack trace but print the error nevertheless.
- print_error(f'Failed to download {urlstring}.')
- traceback.print_exception(*sys.exc_info()[:2], None)
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ traceback.print_exception(exc_type, exc_value, None, 0, None, False)
sys.exit(1)
else:
print_error('Download complete.')
diff --git a/python/vyos/systemversions.py b/python/vyos/systemversions.py
index 9b3f4f413..f2da76d4f 100644
--- a/python/vyos/systemversions.py
+++ b/python/vyos/systemversions.py
@@ -17,7 +17,10 @@ import os
import re
import sys
import vyos.defaults
+from vyos.xml import component_version
+# legacy version, reading from the file names in
+# /opt/vyatta/etc/config-migrate/current
def get_system_versions():
"""
Get component versions from running system; critical failure if
@@ -37,3 +40,7 @@ def get_system_versions():
system_versions[pair[0]] = int(pair[1])
return system_versions
+
+# read from xml cache
+def get_system_component_version():
+ return component_version()
diff --git a/python/vyos/template.py b/python/vyos/template.py
index b32cafe74..132f5ddde 100644
--- a/python/vyos/template.py
+++ b/python/vyos/template.py
@@ -18,14 +18,16 @@ import os
from jinja2 import Environment
from jinja2 import FileSystemLoader
-
+from jinja2 import ChainableUndefined
from vyos.defaults import directories
from vyos.util import chmod
from vyos.util import chown
+from vyos.util import dict_search_args
from vyos.util import makedir
# Holds template filters registered via register_filter()
_FILTERS = {}
+_TESTS = {}
# reuse Environments with identical settings to improve performance
@functools.lru_cache(maxsize=2)
@@ -41,8 +43,10 @@ def _get_environment(location=None):
cache_size=100,
loader=loc_loader,
trim_blocks=True,
+ undefined=ChainableUndefined,
)
env.filters.update(_FILTERS)
+ env.tests.update(_TESTS)
return env
@@ -66,6 +70,26 @@ def register_filter(name, func=None):
_FILTERS[name] = func
return func
+def register_test(name, func=None):
+ """Register a function to be available as test in templates under given name.
+
+ It can also be used as a decorator, see below in this module for examples.
+
+ :raise RuntimeError:
+ when trying to register a test after a template has been rendered already
+ :raise ValueError: when trying to register a name which was taken already
+ """
+ if func is None:
+ return functools.partial(register_test, name)
+ if _get_environment.cache_info().currsize:
+ raise RuntimeError(
+ "Tests can only be registered before rendering the first template"
+ )
+ if name in _TESTS:
+ raise ValueError(f"A test with name {name!r} was registered already")
+ _TESTS[name] = func
+ return func
+
def render_to_string(template, content, formater=None, location=None):
"""Render a template from the template directory, raise on any errors.
@@ -126,6 +150,14 @@ def render(
##################################
# Custom template filters follow #
##################################
+@register_filter('force_to_list')
+def force_to_list(value):
+ """ Convert scalars to single-item lists and leave lists untouched """
+ if isinstance(value, list):
+ return value
+ else:
+ return [value]
+
@register_filter('ip_from_cidr')
def ip_from_cidr(prefix):
""" Take an IPv4/IPv6 CIDR host and strip cidr mask.
@@ -151,6 +183,16 @@ def bracketize_ipv6(address):
return f'[{address}]'
return address
+@register_filter('dot_colon_to_dash')
+def dot_colon_to_dash(text):
+ """ Replace dot and colon to dash for string
+ Example:
+ 192.0.2.1 => 192-0-2-1, 2001:db8::1 => 2001-db8--1
+ """
+ text = text.replace(":", "-")
+ text = text.replace(".", "-")
+ return text
+
@register_filter('netmask_from_cidr')
def netmask_from_cidr(prefix):
""" Take CIDR prefix and convert the prefix length to a "subnet mask".
@@ -479,3 +521,123 @@ def get_openvpn_ncp_ciphers(ciphers):
else:
out.append(cipher)
return ':'.join(out).upper()
+
+@register_filter('snmp_auth_oid')
+def snmp_auth_oid(type):
+ if type not in ['md5', 'sha', 'aes', 'des', 'none']:
+ raise ValueError()
+
+ OIDs = {
+ 'md5' : '.1.3.6.1.6.3.10.1.1.2',
+ 'sha' : '.1.3.6.1.6.3.10.1.1.3',
+ 'aes' : '.1.3.6.1.6.3.10.1.2.4',
+ 'des' : '.1.3.6.1.6.3.10.1.2.2',
+ 'none': '.1.3.6.1.6.3.10.1.2.1'
+ }
+ return OIDs[type]
+
+@register_filter('nft_action')
+def nft_action(vyos_action):
+ if vyos_action == 'accept':
+ return 'return'
+ return vyos_action
+
+@register_filter('nft_rule')
+def nft_rule(rule_conf, fw_name, rule_id, ip_name='ip'):
+ from vyos.firewall import parse_rule
+ return parse_rule(rule_conf, fw_name, rule_id, ip_name)
+
+@register_filter('nft_default_rule')
+def nft_default_rule(fw_conf, fw_name):
+ output = ['counter']
+ default_action = fw_conf.get('default_action', 'accept')
+
+ if 'enable_default_log' in fw_conf:
+ action_suffix = default_action[:1].upper()
+ output.append(f'log prefix "[{fw_name[:19]}-default-{action_suffix}] "')
+
+ output.append(nft_action(default_action))
+ output.append(f'comment "{fw_name} default-action {default_action}"')
+ return " ".join(output)
+
+@register_filter('nft_state_policy')
+def nft_state_policy(conf, state, ipv6=False):
+ out = [f'ct state {state}']
+
+ if 'log' in conf and 'enable' in conf['log']:
+ out.append('log')
+
+ out.append('counter')
+
+ if 'action' in conf:
+ out.append(conf['action'])
+
+ return " ".join(out)
+
+@register_filter('nft_intra_zone_action')
+def nft_intra_zone_action(zone_conf, ipv6=False):
+ if 'intra_zone_filtering' in zone_conf:
+ intra_zone = zone_conf['intra_zone_filtering']
+ fw_name = 'ipv6_name' if ipv6 else 'name'
+ name_prefix = 'NAME6_' if ipv6 else 'NAME_'
+
+ if 'action' in intra_zone:
+ if intra_zone['action'] == 'accept':
+ return 'return'
+ return intra_zone['action']
+ elif dict_search_args(intra_zone, 'firewall', fw_name):
+ name = dict_search_args(intra_zone, 'firewall', fw_name)
+ return f'jump {name_prefix}{name}'
+ return 'return'
+
+@register_test('vyos_defined')
+def vyos_defined(value, test_value=None, var_type=None):
+ """
+ Jinja2 plugin to test if a variable is defined and not none - vyos_defined
+ will test value if defined and is not none and return true or false.
+
+ If test_value is supplied, the value must also pass == test_value to return true.
+ If var_type is supplied, the value must also be of the specified class/type
+
+ Examples:
+ 1. Test if var is defined and not none:
+ {% if foo is vyos_defined %}
+ ...
+ {% endif %}
+
+ 2. Test if variable is defined, not none and has value "something"
+ {% if bar is vyos_defined("something") %}
+ ...
+ {% endif %}
+
+ Parameters
+ ----------
+ value : any
+ Value to test from ansible
+ test_value : any, optional
+ Value to test in addition of defined and not none, by default None
+ var_type : ['float', 'int', 'str', 'list', 'dict', 'tuple', 'bool'], optional
+ Type or Class to test for
+
+ Returns
+ -------
+ boolean
+ True if variable matches criteria, False in other cases.
+
+ Implementation inspired and re-used from https://github.com/aristanetworks/ansible-avd/
+ """
+
+ from jinja2 import Undefined
+
+ if isinstance(value, Undefined) or value is None:
+ # Invalid value - return false
+ return False
+ elif test_value is not None and value != test_value:
+ # Valid value but not matching the optional argument
+ return False
+ elif str(var_type).lower() in ['float', 'int', 'str', 'list', 'dict', 'tuple', 'bool'] and str(var_type).lower() != type(value).__name__:
+ # Invalid class - return false
+ return False
+ else:
+ # Valid value and is matching optional argument if provided - return true
+ return True
diff --git a/python/vyos/util.py b/python/vyos/util.py
index d8e83ab8d..de55e108b 100644
--- a/python/vyos/util.py
+++ b/python/vyos/util.py
@@ -774,6 +774,14 @@ def dict_search_recursive(dict_object, key):
for x in dict_search_recursive(j, key):
yield x
+def get_bridge_fdb(interface):
+ """ Returns the forwarding database entries for a given interface """
+ if not os.path.exists(f'/sys/class/net/{interface}'):
+ return None
+ from json import loads
+ tmp = loads(cmd(f'bridge -j fdb show dev {interface}'))
+ return tmp
+
def get_interface_config(interface):
""" Returns the used encapsulation protocol for given interface.
If interface does not exist, None is returned.
@@ -794,6 +802,24 @@ def get_interface_address(interface):
tmp = loads(cmd(f'ip -d -j addr show {interface}'))[0]
return tmp
+def get_interface_namespace(iface):
+ """
+ Returns wich netns the interface belongs to
+ """
+ from json import loads
+ # Check if netns exist
+ tmp = loads(cmd(f'ip --json netns ls'))
+ if len(tmp) == 0:
+ return None
+
+ for ns in tmp:
+ namespace = f'{ns["name"]}'
+ # Search interface in each netns
+ data = loads(cmd(f'ip netns exec {namespace} ip -j link show'))
+ for compare in data:
+ if iface == compare["ifname"]:
+ return namespace
+
def get_all_vrfs():
""" Return a dictionary of all system wide known VRF instances """
from json import loads
@@ -934,14 +960,23 @@ def install_into_config(conf, config_paths, override_prompt=True):
return None
count = 0
+ failed = []
for path in config_paths:
if override_prompt and conf.exists(path) and not conf.is_multi(path):
if not ask_yes_no(f'Config node "{node}" already exists. Do you want to overwrite it?'):
continue
- cmd(f'/opt/vyatta/sbin/my_set {path}')
- count += 1
+ try:
+ cmd(f'/opt/vyatta/sbin/my_set {path}')
+ count += 1
+ except:
+ failed.append(path)
+
+ if failed:
+ print(f'Failed to install {len(failed)} value(s). Commands to manually install:')
+ for path in failed:
+ print(f'set {path}')
if count > 0:
print(f'{count} value(s) installed. Use "compare" to see the pending changes, and "commit" to apply.')
@@ -954,6 +989,11 @@ def is_wwan_connected(interface):
if not interface.startswith('wwan'):
raise ValueError(f'Specified interface "{interface}" is not a WWAN interface')
+ # ModemManager is required for connection(s) - if service is not running,
+ # there won't be any connection at all!
+ if not is_systemd_service_active('ModemManager.service'):
+ return False
+
modem = interface.lstrip('wwan')
tmp = cmd(f'mmcli --modem {modem} --output-json')
@@ -961,3 +1001,26 @@ def is_wwan_connected(interface):
# return True/False if interface is in connected state
return dict_search('modem.generic.state', tmp) == 'connected'
+
+def boot_configuration_complete() -> bool:
+ """ Check if the boot config loader has completed
+ """
+ from vyos.defaults import config_status
+
+ if os.path.isfile(config_status):
+ return True
+ return False
+
+def sysctl_read(name):
+ """ Read and return current value of sysctl() option """
+ tmp = cmd(f'sysctl {name}')
+ return tmp.split()[-1]
+
+def sysctl_write(name, value):
+ """ Change value via sysctl() - return True if changed, False otherwise """
+ tmp = cmd(f'sysctl {name}')
+ # last list index contains the actual value - only write if value differs
+ if sysctl_read(name) != str(value):
+ call(f'sysctl -wq {name}={value}')
+ return True
+ return False
diff --git a/python/vyos/validate.py b/python/vyos/validate.py
index 0dad2a6cb..e005da0e4 100644
--- a/python/vyos/validate.py
+++ b/python/vyos/validate.py
@@ -43,19 +43,14 @@ def _are_same_ip(one, two):
s_two = AF_INET if is_ipv4(two) else AF_INET6
return inet_pton(f_one, one) == inet_pton(f_one, two)
-def is_intf_addr_assigned(intf, addr):
- if '/' in addr:
- ip,mask = addr.split('/')
- return _is_intf_addr_assigned(intf, ip, mask)
- return _is_intf_addr_assigned(intf, addr)
-
-def _is_intf_addr_assigned(intf, address, netmask=None):
+def is_intf_addr_assigned(intf, address) -> bool:
"""
Verify if the given IPv4/IPv6 address is assigned to specific interface.
It can check both a single IP address (e.g. 192.0.2.1 or a assigned CIDR
address 192.0.2.1/24.
"""
from vyos.template import is_ipv4
+
from netifaces import ifaddresses
from netifaces import AF_INET
from netifaces import AF_INET6
@@ -76,6 +71,9 @@ def _is_intf_addr_assigned(intf, address, netmask=None):
addr_type = AF_INET if is_ipv4(address) else AF_INET6
# Check every IP address on this interface for a match
+ netmask = None
+ if '/' in address:
+ address, netmask = address.split('/')
for ip in ifaces.get(addr_type,[]):
# ip can have the interface name in the 'addr' field, we need to remove it
# {'addr': 'fe80::a00:27ff:fec5:f821%eth2', 'netmask': 'ffff:ffff:ffff:ffff::'}
@@ -99,14 +97,20 @@ def _is_intf_addr_assigned(intf, address, netmask=None):
return False
-def is_addr_assigned(addr):
- """
- Verify if the given IPv4/IPv6 address is assigned to any interface
- """
+def is_addr_assigned(ip_address, vrf=None) -> bool:
+ """ Verify if the given IPv4/IPv6 address is assigned to any interfac """
from netifaces import interfaces
- for intf in interfaces():
- tmp = is_intf_addr_assigned(intf, addr)
- if tmp == True:
+ from vyos.util import get_interface_config
+ from vyos.util import dict_search
+ for interface in interfaces():
+ # Check if interface belongs to the requested VRF, if this is not the
+ # case there is no need to proceed with this data set - continue loop
+ # with next element
+ tmp = get_interface_config(interface)
+ if dict_search('master', tmp) != vrf:
+ continue
+
+ if is_intf_addr_assigned(interface, ip_address):
return True
return False
diff --git a/python/vyos/xml/__init__.py b/python/vyos/xml/__init__.py
index e0eacb2d1..6db446a40 100644
--- a/python/vyos/xml/__init__.py
+++ b/python/vyos/xml/__init__.py
@@ -46,8 +46,8 @@ def is_tag(lpath):
def is_leaf(lpath, flat=True):
return load_configuration().is_leaf(lpath, flat)
-def component_versions():
- return load_configuration().component_versions()
+def component_version():
+ return load_configuration().component_version()
def defaults(lpath, flat=False):
return load_configuration().defaults(lpath, flat)
diff --git a/python/vyos/xml/definition.py b/python/vyos/xml/definition.py
index 5e0d5282c..bc3892b42 100644
--- a/python/vyos/xml/definition.py
+++ b/python/vyos/xml/definition.py
@@ -249,10 +249,11 @@ class XML(dict):
# @lru_cache(maxsize=100)
# XXX: need to use cachetool instead - for later
- def component_versions(self) -> dict:
- sort_component = sorted(self[kw.component_version].items(),
- key = lambda kv: kv[0])
- return dict(sort_component)
+ def component_version(self) -> dict:
+ d = {}
+ for k in sorted(self[kw.component_version]):
+ d[k] = int(self[kw.component_version][k])
+ return d
def defaults(self, lpath, flat):
d = self[kw.default]
diff --git a/scripts/build-command-templates b/scripts/build-command-templates
index d8abb0a13..876f5877c 100755
--- a/scripts/build-command-templates
+++ b/scripts/build-command-templates
@@ -117,7 +117,7 @@ def collect_validators(ve):
return regex_args + " " + validator_args
-def get_properties(p):
+def get_properties(p, default=None):
props = {}
if p is None:
@@ -125,7 +125,12 @@ def get_properties(p):
# Get the help string
try:
- props["help"] = p.find("help").text
+ help = p.find("help").text
+ if default != None:
+ # DNS forwarding for instance has multiple defaults - specified as whitespace separated list
+ tmp = ', '.join(default.text.split())
+ help += f' (default: {tmp})'
+ props["help"] = help
except:
pass
@@ -134,7 +139,11 @@ def get_properties(p):
vhe = p.findall("valueHelp")
vh = []
for v in vhe:
- vh.append( (v.find("format").text, v.find("description").text) )
+ format = v.find("format").text
+ description = v.find("description").text
+ if default != None and default.text == format:
+ description += f' (default)'
+ vh.append( (format, description) )
props["val_help"] = vh
except:
props["val_help"] = []
@@ -271,7 +280,7 @@ def process_node(n, tmpl_dir):
print("Name of the node: {0}. Created directory: {1}\n".format(name, "/".join(my_tmpl_dir)), end="")
os.makedirs(make_path(my_tmpl_dir), exist_ok=True)
- props = get_properties(props_elem)
+ props = get_properties(props_elem, n.find("defaultValue"))
if owner:
props["owner"] = owner
# Type should not be set for non-tag, non-leaf nodes
diff --git a/smoketest/configs.no-load/firewall-big b/smoketest/configs.no-load/firewall-big
new file mode 100644
index 000000000..94b0c6dd5
--- /dev/null
+++ b/smoketest/configs.no-load/firewall-big
@@ -0,0 +1,43440 @@
+firewall {
+ all-ping enable
+ broadcast-ping disable
+ config-trap disable
+ group {
+ address-group CENTREON_SERVERS {
+ address 109.228.63.82
+ }
+ address-group CLUSTER_ADDRESSES {
+ address 10.255.255.4
+ address 10.255.255.5
+ address 77.68.76.16
+ address 77.68.77.16
+ address 172.16.255.254
+ address 77.68.76.14
+ address 77.68.77.14
+ address 77.68.76.13
+ address 77.68.77.13
+ address 77.68.76.12
+ address 77.68.77.12
+ address 77.68.77.67
+ address 77.68.77.103
+ address 77.68.77.130
+ address 77.68.76.245
+ address 77.68.77.85
+ address 77.68.76.45
+ address 77.68.77.144
+ address 77.68.77.105
+ address 77.68.76.122
+ address 77.68.76.104
+ address 77.68.77.115
+ address 77.68.77.178
+ address 77.68.76.239
+ address 77.68.76.30
+ address 77.68.77.249
+ address 77.68.76.59
+ address 77.68.77.44
+ address 77.68.77.200
+ address 77.68.77.228
+ address 77.68.76.191
+ address 77.68.76.102
+ address 77.68.77.26
+ address 77.68.76.152
+ address 77.68.77.212
+ address 77.68.76.142
+ address 77.68.76.60
+ address 77.68.77.253
+ address 77.68.76.54
+ address 77.68.76.33
+ address 77.68.77.114
+ address 77.68.77.176
+ address 77.68.77.219
+ address 77.68.77.19
+ address 77.68.77.22
+ address 77.68.77.248
+ address 77.68.76.161
+ address 77.68.77.56
+ address 77.68.77.129
+ address 77.68.77.140
+ address 77.68.76.177
+ address 77.68.77.117
+ address 77.68.77.108
+ address 77.68.76.50
+ address 77.68.76.217
+ address 77.68.77.160
+ address 77.68.77.30
+ address 77.68.77.21
+ address 77.68.76.29
+ address 77.68.76.158
+ address 77.68.76.203
+ address 77.68.77.243
+ address 77.68.77.54
+ address 77.68.76.22
+ address 77.68.76.25
+ address 77.68.76.21
+ address 77.68.77.221
+ address 77.68.77.76
+ address 77.68.76.127
+ address 77.68.77.139
+ address 77.68.77.240
+ address 77.68.76.39
+ address 77.68.76.149
+ address 77.68.77.57
+ address 77.68.77.185
+ address 77.68.76.116
+ address 77.68.76.160
+ address 77.68.77.70
+ address 77.68.77.149
+ address 77.68.76.57
+ address 77.68.76.115
+ address 77.68.76.200
+ address 77.68.76.23
+ address 77.68.77.46
+ address 77.68.76.198
+ address 77.68.77.141
+ address 77.68.77.50
+ address 77.68.77.128
+ address 77.68.77.88
+ address 77.68.76.80
+ address 77.68.76.35
+ address 77.68.77.204
+ address 77.68.77.201
+ address 77.68.77.97
+ address 77.68.76.195
+ address 77.68.76.202
+ address 77.68.76.157
+ address 77.68.77.159
+ address 77.68.76.118
+ address 77.68.76.38
+ address 77.68.77.203
+ address 77.68.77.233
+ address 77.68.77.163
+ address 77.68.77.49
+ address 77.68.76.58
+ address 77.68.77.171
+ address 77.68.77.150
+ address 77.68.77.199
+ address 77.68.76.220
+ address 77.68.77.156
+ address 77.68.76.248
+ address 77.68.76.171
+ address 77.68.76.212
+ address 77.68.77.132
+ address 77.68.77.81
+ address 77.68.76.37
+ address 77.68.76.197
+ address 77.68.76.20
+ address 77.68.76.99
+ address 77.68.77.211
+ address 77.68.77.236
+ address 77.68.76.252
+ address 77.68.77.32
+ address 77.68.77.247
+ address 77.68.76.209
+ address 77.68.77.202
+ address 77.68.76.247
+ address 77.68.77.99
+ address 77.68.76.169
+ address 77.68.76.95
+ address 77.68.76.187
+ address 77.68.77.222
+ address 77.68.77.53
+ address 77.68.77.124
+ address 77.68.76.61
+ address 77.68.77.43
+ address 77.68.76.94
+ address 77.68.77.165
+ address 77.68.77.152
+ address 77.68.76.44
+ address 77.68.76.47
+ address 77.68.76.74
+ address 77.68.76.55
+ address 77.68.77.75
+ address 77.68.77.239
+ address 77.68.76.75
+ address 77.68.77.71
+ address 77.68.76.145
+ address 77.68.77.145
+ address 77.68.77.68
+ address 77.68.76.126
+ address 77.68.76.88
+ address 77.68.77.181
+ address 77.68.76.112
+ address 77.68.77.33
+ address 77.68.77.137
+ address 77.68.77.92
+ address 77.68.76.111
+ address 77.68.76.185
+ address 77.68.76.208
+ address 77.68.76.150
+ address 77.68.77.208
+ address 77.68.76.42
+ address 77.68.76.164
+ address 77.68.77.207
+ address 77.68.76.49
+ address 77.68.77.227
+ address 77.68.76.136
+ address 77.68.76.77
+ address 77.68.76.123
+ address 77.68.76.31
+ address 77.68.76.148
+ address 77.68.77.120
+ address 77.68.76.183
+ address 77.68.77.107
+ address 77.68.76.141
+ address 77.68.76.105
+ address 77.68.76.251
+ address 77.68.76.249
+ address 77.68.77.59
+ address 77.68.77.37
+ address 77.68.77.65
+ address 77.68.76.231
+ address 77.68.77.24
+ address 77.68.77.63
+ address 77.68.76.234
+ address 77.68.76.93
+ address 77.68.77.77
+ address 77.68.77.151
+ address 77.68.76.235
+ address 77.68.77.95
+ address 77.68.77.190
+ address 77.68.76.91
+ address 77.68.77.79
+ address 77.68.77.100
+ address 77.68.76.241
+ address 77.68.77.209
+ address 77.68.76.110
+ address 77.68.76.40
+ address 77.68.76.76
+ address 77.68.76.124
+ address 77.68.77.234
+ address 77.68.76.219
+ address 77.68.77.90
+ address 77.68.76.107
+ address 77.68.76.26
+ address 77.68.76.211
+ address 77.68.76.19
+ address 77.68.77.231
+ address 77.68.76.254
+ address 77.68.77.251
+ address 77.68.77.74
+ address 77.68.77.192
+ address 77.68.76.253
+ address 77.68.77.214
+ address 77.68.76.92
+ address 77.68.76.250
+ address 77.68.77.215
+ address 77.68.76.165
+ address 77.68.77.254
+ address 77.68.76.120
+ address 77.68.76.228
+ address 77.68.77.157
+ address 77.68.77.205
+ address 77.68.76.138
+ address 77.68.77.102
+ address 77.68.76.181
+ address 77.68.76.139
+ address 77.68.76.243
+ address 77.68.76.244
+ address 77.68.76.114
+ address 77.68.77.72
+ address 77.68.77.161
+ address 77.68.77.38
+ address 77.68.77.62
+ address 77.68.92.186
+ address 77.68.91.195
+ address 77.68.23.35
+ address 77.68.84.155
+ address 77.68.17.26
+ address 77.68.76.96
+ address 77.68.28.145
+ address 77.68.76.48
+ address 109.228.56.185
+ address 77.68.84.147
+ address 77.68.23.64
+ address 77.68.26.166
+ address 77.68.29.178
+ address 77.68.12.195
+ address 77.68.21.78
+ address 77.68.5.166
+ address 77.68.5.187
+ address 77.68.4.111
+ address 77.68.4.22
+ address 77.68.7.227
+ address 77.68.4.24
+ address 77.68.4.74
+ address 77.68.6.202
+ address 77.68.5.241
+ address 77.68.7.222
+ address 77.68.4.39
+ address 77.68.4.25
+ address 77.68.7.160
+ address 77.68.27.211
+ address 77.68.89.183
+ address 77.68.24.59
+ address 77.68.7.114
+ address 77.68.75.113
+ address 77.68.81.44
+ address 77.68.90.106
+ address 77.68.94.181
+ address 77.68.30.164
+ address 77.68.30.133
+ address 77.68.7.67
+ address 77.68.77.174
+ address 77.68.27.54
+ address 77.68.4.136
+ address 77.68.72.202
+ address 77.68.112.83
+ address 77.68.85.172
+ address 77.68.23.158
+ address 77.68.112.75
+ address 77.68.24.112
+ address 77.68.112.213
+ address 77.68.72.254
+ address 77.68.20.161
+ address 77.68.26.216
+ address 77.68.112.184
+ address 77.68.79.82
+ address 77.68.27.57
+ address 77.68.20.231
+ address 77.68.118.17
+ address 77.68.118.120
+ address 77.68.117.51
+ address 77.68.118.102
+ address 77.68.116.119
+ address 77.68.117.45
+ address 77.68.116.220
+ address 77.68.116.232
+ address 77.68.117.222
+ address 77.68.118.15
+ address 77.68.116.221
+ address 77.68.116.183
+ address 77.68.119.14
+ address 77.68.112.91
+ address 77.68.117.202
+ address 77.68.118.104
+ address 77.68.7.172
+ address 77.68.83.41
+ address 77.68.15.95
+ address 77.68.4.57
+ address 77.68.85.27
+ address 77.68.86.40
+ address 77.68.88.164
+ address 109.228.56.26
+ address 77.68.7.123
+ address 77.68.112.248
+ address 109.228.60.215
+ address 109.228.55.82
+ address 77.68.7.186
+ address 77.68.6.210
+ address 77.68.77.238
+ address 77.68.10.142
+ address 77.68.31.144
+ address 77.68.93.246
+ address 77.68.121.127
+ address 77.68.121.94
+ address 77.68.120.241
+ address 77.68.121.106
+ address 77.68.122.195
+ address 77.68.122.89
+ address 77.68.120.146
+ address 77.68.120.249
+ address 77.68.122.241
+ address 77.68.119.92
+ address 77.68.120.26
+ address 77.68.81.141
+ address 77.68.79.206
+ address 77.68.116.52
+ address 77.68.88.100
+ address 77.68.6.105
+ address 77.68.78.229
+ address 77.68.6.32
+ address 77.68.10.170
+ address 77.68.76.229
+ address 77.68.95.42
+ address 77.68.28.207
+ address 77.68.17.186
+ address 77.68.4.252
+ address 77.68.24.220
+ address 77.68.2.215
+ address 77.68.91.128
+ address 77.68.22.146
+ address 77.68.23.112
+ address 77.68.75.245
+ address 77.68.125.218
+ address 77.68.125.32
+ address 77.68.12.250
+ address 109.228.37.174
+ address 77.68.127.151
+ address 109.228.37.114
+ address 109.228.36.229
+ address 109.228.37.240
+ address 109.228.61.31
+ address 109.228.35.110
+ address 109.228.39.157
+ address 109.228.39.249
+ address 109.228.38.171
+ address 109.228.40.226
+ address 109.228.40.207
+ address 109.228.40.247
+ address 77.68.126.51
+ address 77.68.117.214
+ address 77.68.113.117
+ address 77.68.117.142
+ address 77.68.17.200
+ address 77.68.4.242
+ address 77.68.86.148
+ address 109.228.39.151
+ address 109.228.40.194
+ address 77.68.114.183
+ address 77.68.90.132
+ address 77.68.16.247
+ address 77.68.6.110
+ address 109.228.36.37
+ address 77.68.127.172
+ address 77.68.14.88
+ address 77.68.120.229
+ address 213.171.212.203
+ address 213.171.213.41
+ address 213.171.213.175
+ address 213.171.213.97
+ address 213.171.212.171
+ address 213.171.212.89
+ address 213.171.214.96
+ address 213.171.212.172
+ address 213.171.215.252
+ address 213.171.213.242
+ address 213.171.213.31
+ address 213.171.212.71
+ address 213.171.208.58
+ address 77.68.25.130
+ address 213.171.215.184
+ address 77.68.13.76
+ address 109.228.56.242
+ address 77.68.25.146
+ address 109.228.46.81
+ address 77.68.77.69
+ address 213.171.210.19
+ address 77.68.120.45
+ address 77.68.116.36
+ address 213.171.211.128
+ address 77.68.25.124
+ address 109.228.48.249
+ address 213.171.210.59
+ address 213.171.215.43
+ address 109.228.40.195
+ address 109.228.52.186
+ address 77.68.113.164
+ address 77.68.114.93
+ address 77.68.75.253
+ address 109.228.53.243
+ address 109.228.36.194
+ address 77.68.28.147
+ address 77.68.123.250
+ address 185.132.36.24
+ address 185.132.39.129
+ address 185.132.36.142
+ address 185.132.39.68
+ address 185.132.36.17
+ address 185.132.36.148
+ address 185.132.37.101
+ address 185.132.39.44
+ address 185.132.39.37
+ address 185.132.37.102
+ address 185.132.38.142
+ address 185.132.38.114
+ address 185.132.38.95
+ address 185.132.37.83
+ address 185.132.36.7
+ address 109.228.40.222
+ address 77.68.119.188
+ address 77.68.74.85
+ address 77.68.91.22
+ address 213.171.212.136
+ address 185.132.38.216
+ address 77.68.120.31
+ address 77.68.95.212
+ address 109.228.42.232
+ address 77.68.13.137
+ address 77.68.85.73
+ address 77.68.85.115
+ address 109.228.36.174
+ address 77.68.9.186
+ address 77.68.27.18
+ address 77.68.27.27
+ address 77.68.27.28
+ address 77.68.3.80
+ address 77.68.3.121
+ address 77.68.3.144
+ address 77.68.3.161
+ address 77.68.3.194
+ address 77.68.3.247
+ address 77.68.28.139
+ address 77.68.81.218
+ address 77.68.93.125
+ address 77.68.74.39
+ address 77.68.78.73
+ address 77.68.5.95
+ address 77.68.74.152
+ address 77.68.87.212
+ address 77.68.3.52
+ address 77.68.114.136
+ address 77.68.125.60
+ address 213.171.214.167
+ address 77.68.114.234
+ address 213.171.213.42
+ address 109.228.59.247
+ address 185.132.39.99
+ address 185.132.39.145
+ address 109.228.35.84
+ address 185.132.36.60
+ address 185.132.40.11
+ address 185.132.39.219
+ address 77.68.26.221
+ address 185.132.40.56
+ address 77.68.117.29
+ address 185.132.40.90
+ address 109.228.38.201
+ address 185.132.40.244
+ address 77.68.11.140
+ address 213.171.210.155
+ address 185.132.37.23
+ address 213.171.214.234
+ address 77.68.77.29
+ address 77.68.20.217
+ address 185.132.40.152
+ address 77.68.9.75
+ address 213.171.210.177
+ address 185.132.41.72
+ address 185.132.41.73
+ address 77.68.5.155
+ address 185.132.43.6
+ address 77.68.75.45
+ address 109.228.46.196
+ address 185.132.43.28
+ address 77.68.89.72
+ address 185.132.43.98
+ address 77.68.76.176
+ address 185.132.43.164
+ address 185.132.43.157
+ address 77.68.6.119
+ address 77.68.92.92
+ address 77.68.10.152
+ address 77.68.73.73
+ address 77.68.32.43
+ address 185.132.38.248
+ address 77.68.120.218
+ address 77.68.32.31
+ address 77.68.32.254
+ address 77.68.32.118
+ address 77.68.82.157
+ address 77.68.121.119
+ address 77.68.74.209
+ address 77.68.33.68
+ address 77.68.24.172
+ address 77.68.33.197
+ address 77.68.33.48
+ address 77.68.34.26
+ address 77.68.34.28
+ address 77.68.79.89
+ address 77.68.76.137
+ address 77.68.33.216
+ address 77.68.32.83
+ address 77.68.32.86
+ address 77.68.32.89
+ address 77.68.34.138
+ address 77.68.34.139
+ address 77.68.123.177
+ address 77.68.35.116
+ address 77.68.33.171
+ address 213.171.208.40
+ address 77.68.118.86
+ address 77.68.48.81
+ address 77.68.48.89
+ address 77.68.48.105
+ address 77.68.85.18
+ address 77.68.26.228
+ address 77.68.49.4
+ address 77.68.80.26
+ address 77.68.80.97
+ address 77.68.126.101
+ address 77.68.126.14
+ address 77.68.49.12
+ address 77.68.117.173
+ address 77.68.8.144
+ address 77.68.82.147
+ address 77.68.24.134
+ address 77.68.112.167
+ address 77.68.49.126
+ address 77.68.49.178
+ address 77.68.50.91
+ address 77.68.50.90
+ address 77.68.24.63
+ address 109.228.37.187
+ address 77.68.50.193
+ address 77.68.50.198
+ address 77.68.50.142
+ address 77.68.114.237
+ address 77.68.115.17
+ address 77.68.49.159
+ address 77.68.49.160
+ address 213.171.208.176
+ address 77.68.116.84
+ address 77.68.126.160
+ address 185.132.36.56
+ address 77.68.49.161
+ address 77.68.34.50
+ address 185.132.41.240
+ address 77.68.51.214
+ address 77.68.51.202
+ address 185.132.37.133
+ address 77.68.77.42
+ address 77.68.100.132
+ address 77.68.100.134
+ address 77.68.100.150
+ address 185.132.41.148
+ address 77.68.101.64
+ address 213.171.210.25
+ address 77.68.101.124
+ address 77.68.101.125
+ address 77.68.89.247
+ address 185.132.39.109
+ address 77.68.100.167
+ address 77.68.5.125
+ address 77.68.4.80
+ address 77.68.49.152
+ address 77.68.12.45
+ address 77.68.4.180
+ address 213.171.214.102
+ address 77.68.126.22
+ address 77.68.114.205
+ address 109.228.36.119
+ address 213.171.212.90
+ address 77.68.33.37
+ address 185.132.43.71
+ address 185.132.43.113
+ address 77.68.48.202
+ address 185.132.40.166
+ address 77.68.112.90
+ address 77.68.112.175
+ address 77.68.103.19
+ address 77.68.103.120
+ address 77.68.33.24
+ address 77.68.103.147
+ address 109.228.47.223
+ address 109.228.58.134
+ address 109.228.56.97
+ address 77.68.31.96
+ address 77.68.103.227
+ address 88.208.196.91
+ address 88.208.196.92
+ address 88.208.196.154
+ address 88.208.197.10
+ address 77.68.87.164
+ address 77.68.93.164
+ address 185.132.37.47
+ address 77.68.75.64
+ address 88.208.197.118
+ address 88.208.197.135
+ address 88.208.197.150
+ address 88.208.197.155
+ address 88.208.197.160
+ address 88.208.197.60
+ address 109.228.37.10
+ address 88.208.215.61
+ address 77.68.102.129
+ address 88.208.196.123
+ address 109.228.36.79
+ address 185.132.38.182
+ address 88.208.215.62
+ address 88.208.215.157
+ address 88.208.198.251
+ address 88.208.215.19
+ address 88.208.198.39
+ address 109.228.38.117
+ address 77.68.29.65
+ address 88.208.215.121
+ address 77.68.115.142
+ address 77.68.76.108
+ address 88.208.198.64
+ address 88.208.198.66
+ address 77.68.3.61
+ address 88.208.198.92
+ address 77.68.74.232
+ address 77.68.118.88
+ address 77.68.100.77
+ address 77.68.48.14
+ address 88.208.198.69
+ address 88.208.197.23
+ address 88.208.199.249
+ address 213.171.212.114
+ address 109.228.39.41
+ address 88.208.199.141
+ address 77.68.21.171
+ address 88.208.199.233
+ address 88.208.212.31
+ address 77.68.102.5
+ address 88.208.212.94
+ address 109.228.61.37
+ address 88.208.199.46
+ address 77.68.78.113
+ address 88.208.212.182
+ address 88.208.212.188
+ address 185.132.40.124
+ address 213.171.209.217
+ address 77.68.103.56
+ address 88.208.197.208
+ address 88.208.197.129
+ }
+ address-group CMK_SATELLITES {
+ address 82.223.144.252
+ address 109.228.63.67
+ address 109.228.63.66
+ address 82.223.200.61
+ address 195.20.253.14
+ address 217.72.206.27
+ }
+ address-group DHCP_SERVERS {
+ address 10.255.241.13
+ address 10.255.241.14
+ address 10.255.242.13
+ address 10.255.242.14
+ address 10.255.243.13
+ address 10.255.243.14
+ address 10.255.244.13
+ address 10.255.244.14
+ address 10.255.245.13
+ address 10.255.245.14
+ address 10.255.246.13
+ address 10.255.246.14
+ address 10.255.247.13
+ address 10.255.247.14
+ address 10.255.248.13
+ address 10.255.248.14
+ address 10.255.249.13
+ address 10.255.249.14
+ address 77.68.76.14
+ address 77.68.77.14
+ address 77.68.76.13
+ address 77.68.77.13
+ }
+ address-group DNSCACHE_SERVERS {
+ address 10.255.255.4
+ address 10.255.255.5
+ address 77.68.76.12
+ address 77.68.77.12
+ }
+ address-group DT_BLOCKED {
+ address 172.16.255.254
+ }
+ address-group DT_FW0A5C4_1 {
+ address 185.132.40.56
+ }
+ address-group DT_FW0B352_1 {
+ address 77.68.77.238
+ }
+ address-group DT_FW0BB22_1 {
+ address 77.68.16.247
+ }
+ address-group DT_FW0BD92_3 {
+ address 109.228.36.79
+ }
+ address-group DT_FW0C2E6_4 {
+ address 77.68.76.110
+ }
+ address-group DT_FW0C8E1_1 {
+ address 77.68.77.103
+ }
+ address-group DT_FW0C25B_1 {
+ address 77.68.86.148
+ }
+ address-group DT_FW00D98_1 {
+ address 77.68.76.88
+ }
+ address-group DT_FW0E2EE_1 {
+ address 213.171.211.128
+ }
+ address-group DT_FW0E383_9 {
+ address 77.68.77.114
+ }
+ address-group DT_FW0EA3F_1 {
+ address 77.68.49.159
+ }
+ address-group DT_FW1ACD9_2 {
+ address 77.68.76.108
+ }
+ address-group DT_FW1C8F2_1 {
+ address 185.132.37.83
+ }
+ address-group DT_FW1CB16_1 {
+ address 77.68.29.178
+ }
+ address-group DT_FW1CC15_2 {
+ address 77.68.77.248
+ }
+ address-group DT_FW1D511_2 {
+ address 213.171.213.175
+ }
+ address-group DT_FW1F3D0_6 {
+ address 77.68.76.250
+ }
+ address-group DT_FW1F126_1 {
+ address 77.68.76.137
+ }
+ address-group DT_FW1FA8E_1 {
+ address 185.132.37.101
+ }
+ address-group DT_FW1FA9E_1 {
+ address 77.68.118.104
+ }
+ address-group DT_FW2ACFF_1 {
+ address 77.68.24.220
+ }
+ address-group DT_FW2B4BA_1 {
+ address 77.68.33.68
+ }
+ address-group DT_FW2B279_4 {
+ address 77.68.77.204
+ }
+ address-group DT_FW2BB8D_1 {
+ address 77.68.77.181
+ }
+ address-group DT_FW2BF20_3 {
+ address 77.68.76.187
+ }
+ address-group DT_FW2C5AE_1 {
+ address 77.68.76.228
+ }
+ address-group DT_FW2E8D4_1 {
+ address 77.68.77.249
+ }
+ address-group DT_FW2E060_1 {
+ address 77.68.77.215
+ }
+ address-group DT_FW2ED4D_2 {
+ address 109.228.39.151
+ }
+ address-group DT_FW2EF2C_1 {
+ address 77.68.11.140
+ }
+ address-group DT_FW2F868_6 {
+ address 77.68.76.254
+ }
+ address-group DT_FW2FB61_1 {
+ address 109.228.38.117
+ }
+ address-group DT_FW3A12F_1 {
+ address 77.68.5.95
+ }
+ address-group DT_FW3AD6F_1 {
+ address 77.68.120.241
+ }
+ address-group DT_FW03B35_1 {
+ address 77.68.125.60
+ }
+ address-group DT_FW3B068_2 {
+ address 77.68.77.63
+ }
+ address-group DT_FW3CAAB_1 {
+ address 77.68.76.234
+ }
+ address-group DT_FW3DBF8_9 {
+ address 77.68.76.198
+ }
+ address-group DT_FW3EBC8_1 {
+ address 77.68.13.76
+ }
+ address-group DT_FW03F2E_1 {
+ address 77.68.102.5
+ }
+ address-group DT_FW3F465_1 {
+ address 109.228.36.119
+ }
+ address-group DT_FW4AE7D_1 {
+ address 77.68.76.60
+ }
+ address-group DT_FW4C136_1 {
+ address 77.68.76.50
+ }
+ address-group DT_FW4D3E6_1 {
+ address 77.68.100.77
+ }
+ address-group DT_FW4DB0A_1 {
+ address 77.68.49.161
+ }
+ address-group DT_FW4E314_1 {
+ address 109.228.40.222
+ }
+ address-group DT_FW4E399_1 {
+ address 213.171.214.96
+ }
+ address-group DT_FW4F5EE_10 {
+ address 77.68.116.220
+ }
+ address-group DT_FW4F81F_4 {
+ address 77.68.77.43
+ }
+ address-group DT_FW5A5D7_3 {
+ address 77.68.77.205
+ }
+ address-group DT_FW5A77C_16 {
+ address 77.68.76.202
+ }
+ address-group DT_FW5A521_3 {
+ address 77.68.79.89
+ }
+ address-group DT_FW05AD0_2 {
+ address 77.68.77.72
+ }
+ address-group DT_FW5AE10_1 {
+ address 109.228.37.114
+ }
+ address-group DT_FW5CBB2_1 {
+ address 77.68.77.150
+ }
+ address-group DT_FW5D0FA_1 {
+ address 185.132.43.157
+ }
+ address-group DT_FW6A684_1 {
+ address 77.68.116.119
+ }
+ address-group DT_FW6B9B9_1 {
+ address 185.132.41.72
+ }
+ address-group DT_FW6B39D_1 {
+ address 77.68.4.111
+ address 77.68.77.174
+ }
+ address-group DT_FW6C992_1 {
+ address 77.68.85.27
+ }
+ address-group DT_FW6CD7E_2 {
+ address 77.68.76.148
+ }
+ address-group DT_FW6D0CD_1 {
+ address 77.68.76.241
+ }
+ address-group DT_FW6ECA4_1 {
+ address 77.68.117.51
+ }
+ address-group DT_FW6EFD7_1 {
+ address 77.68.84.147
+ }
+ address-group DT_FW6F539_1 {
+ address 77.68.76.217
+ }
+ address-group DT_FW7A9B0_9 {
+ address 77.68.76.47
+ }
+ address-group DT_FW7C4D9_14 {
+ address 109.228.36.37
+ }
+ address-group DT_FW7DAE2_3 {
+ address 185.132.38.216
+ }
+ address-group DT_FW7F28A_1 {
+ address 77.68.76.31
+ }
+ address-group DT_FW8A3FC_3 {
+ address 77.68.77.132
+ address 77.68.76.185
+ address 77.68.77.90
+ }
+ address-group DT_FW8A49A_1 {
+ address 77.68.77.85
+ }
+ address-group DT_FW8A57A_1 {
+ address 77.68.77.222
+ address 77.68.112.83
+ }
+ address-group DT_FW8AFF1_7 {
+ address 77.68.76.118
+ }
+ address-group DT_FW8B21D_1 {
+ address 77.68.23.64
+ }
+ address-group DT_FW8C72E_1 {
+ address 77.68.27.54
+ }
+ address-group DT_FW8C927_1 {
+ address 77.68.7.160
+ }
+ address-group DT_FW8EA04_1 {
+ address 77.68.20.161
+ }
+ address-group DT_FW8ECF4_1 {
+ address 77.68.2.215
+ }
+ address-group DT_FW9B6FB_1 {
+ address 77.68.4.242
+ }
+ address-group DT_FW9C682_3 {
+ address 213.171.212.203
+ }
+ address-group DT_FW9D5C7_1 {
+ address 77.68.115.17
+ }
+ address-group DT_FW9E550_1 {
+ address 213.171.212.71
+ }
+ address-group DT_FW9EEDD_1 {
+ address 77.68.4.80
+ address 77.68.49.152
+ }
+ address-group DT_FW10C3D_19 {
+ address 77.68.25.124
+ }
+ address-group DT_FW10FEE_1 {
+ address 77.68.122.89
+ }
+ address-group DT_FW12C32_1 {
+ address 77.68.4.25
+ address 77.68.7.114
+ }
+ address-group DT_FW013EF_2 {
+ address 77.68.77.26
+ }
+ address-group DT_FW15C99_6 {
+ address 77.68.114.237
+ }
+ address-group DT_FW18E6E_3 {
+ address 77.68.76.112
+ }
+ address-group DT_FW21A75_2 {
+ address 88.208.198.66
+ }
+ address-group DT_FW24AB7_1 {
+ address 213.171.213.242
+ }
+ address-group DT_FW26F0A_1 {
+ address 77.68.78.73
+ }
+ address-group DT_FW27A8F_1 {
+ address 77.68.76.219
+ }
+ address-group DT_FW028C0_2 {
+ address 77.68.26.221
+ }
+ address-group DT_FW28EC8_1 {
+ address 77.68.76.93
+ }
+ address-group DT_FW30D21_1 {
+ address 77.68.95.42
+ }
+ address-group DT_FW32EFF_16 {
+ address 77.68.118.120
+ }
+ address-group DT_FW32EFF_25 {
+ address 77.68.27.211
+ }
+ address-group DT_FW32EFF_49 {
+ address 109.228.37.187
+ }
+ address-group DT_FW34C91_3 {
+ address 77.68.76.142
+ }
+ address-group DT_FW35F7B_1 {
+ address 77.68.30.164
+ }
+ address-group DT_FW37E59_5 {
+ address 77.68.76.37
+ }
+ address-group DT_FW40AE4_1 {
+ address 77.68.79.206
+ }
+ address-group DT_FW42BC7_1 {
+ address 77.68.76.95
+ }
+ address-group DT_FW44BF9_1 {
+ address 77.68.77.200
+ }
+ address-group DT_FW45BEB_1 {
+ address 77.68.75.245
+ }
+ address-group DT_FW45F3D_1 {
+ address 109.228.40.247
+ }
+ address-group DT_FW45F87_1 {
+ address 77.68.77.207
+ }
+ address-group DT_FW46F4A_1 {
+ address 88.208.197.135
+ }
+ address-group DT_FW48A55_2 {
+ address 109.228.39.157
+ }
+ address-group DT_FW49C3D_4 {
+ address 77.68.76.149
+ }
+ address-group DT_FW49C3D_6 {
+ address 77.68.76.160
+ }
+ address-group DT_FW050AC_1 {
+ address 77.68.77.214
+ }
+ address-group DT_FW52F6F_1 {
+ address 77.68.82.147
+ }
+ address-group DT_FW53C72_1 {
+ address 88.208.197.118
+ }
+ address-group DT_FW58C69_4 {
+ address 77.68.76.141
+ }
+ address-group DT_FW59F39_1 {
+ address 77.68.87.212
+ }
+ address-group DT_FW60FD6_5 {
+ address 77.68.92.92
+ }
+ address-group DT_FW69D6D_2 {
+ address 77.68.77.221
+ }
+ address-group DT_FW72F37_1 {
+ address 77.68.77.100
+ }
+ address-group DT_FW73A64_1 {
+ address 77.68.118.15
+ }
+ address-group DT_FW75CA4_6 {
+ address 77.68.4.22
+ }
+ address-group DT_FW85A7C_1 {
+ address 77.68.6.210
+ }
+ address-group DT_FW85E02_11 {
+ address 77.68.77.233
+ }
+ address-group DT_FW90AE3_1 {
+ address 77.68.88.100
+ }
+ address-group DT_FW91B7A_1 {
+ address 77.68.76.40
+ }
+ address-group DT_FW138F8_1 {
+ address 77.68.50.193
+ }
+ address-group DT_FW0192C_1 {
+ address 185.132.39.68
+ }
+ address-group DT_FW197DB_1 {
+ address 77.68.77.240
+ }
+ address-group DT_FW210E2_8 {
+ address 77.68.94.181
+ }
+ address-group DT_FW274FD_1 {
+ address 185.132.36.24
+ }
+ address-group DT_FW310C6_3 {
+ address 88.208.198.39
+ }
+ address-group DT_FW364CF_1 {
+ address 77.68.76.203
+ address 77.68.77.97
+ }
+ address-group DT_FW406AB_1 {
+ address 109.228.47.223
+ }
+ address-group DT_FW444AF_1 {
+ address 185.132.37.102
+ }
+ address-group DT_FW481D7_1 {
+ address 77.68.76.243
+ }
+ address-group DT_FW539FB_1 {
+ address 77.68.21.171
+ }
+ address-group DT_FW578BE_1 {
+ address 109.228.56.185
+ }
+ address-group DT_FW597A6_1 {
+ address 77.68.5.125
+ address 88.208.196.123
+ address 88.208.212.31
+ }
+ address-group DT_FW608FA_1 {
+ address 77.68.74.232
+ }
+ address-group DT_FW633DD_1 {
+ address 77.68.121.119
+ }
+ address-group DT_FW672AB_1 {
+ address 213.171.213.41
+ }
+ address-group DT_FW0745F_5 {
+ address 77.68.117.222
+ }
+ address-group DT_FW748B7_1 {
+ address 77.68.120.249
+ }
+ address-group DT_FW825C8_19 {
+ address 77.68.76.111
+ address 77.68.76.42
+ }
+ address-group DT_FW825C8_24 {
+ address 77.68.77.120
+ address 77.68.76.183
+ }
+ address-group DT_FW826BA_3 {
+ address 77.68.77.152
+ }
+ address-group DT_FW856FA_1 {
+ address 77.68.77.151
+ }
+ address-group DT_FW883EB_1 {
+ address 77.68.76.152
+ }
+ address-group DT_FW930F3_1 {
+ address 77.68.85.73
+ }
+ address-group DT_FW930F3_3 {
+ address 77.68.114.234
+ }
+ address-group DT_FW934AE_1 {
+ address 77.68.5.166
+ }
+ address-group DT_FW0937A_1 {
+ address 77.68.6.119
+ }
+ address-group DT_FW0952B_1 {
+ address 77.68.93.125
+ }
+ address-group DT_FW996B4_2 {
+ address 77.68.76.157
+ }
+ address-group DT_FW1208C_1 {
+ address 77.68.77.33
+ }
+ address-group DT_FW1226C_3 {
+ address 77.68.117.45
+ }
+ address-group DT_FW1271A_2 {
+ address 77.68.76.102
+ }
+ address-group DT_FW2379F_14 {
+ address 213.171.212.89
+ address 77.68.76.44
+ address 77.68.77.239
+ address 213.171.212.114
+ address 77.68.103.56
+ }
+ address-group DT_FW4293B_1 {
+ address 77.68.76.57
+ }
+ address-group DT_FW4513E_1 {
+ address 77.68.77.75
+ }
+ address-group DT_FW4735F_1 {
+ address 77.68.77.74
+ }
+ address-group DT_FW05064_1 {
+ address 213.171.210.19
+ }
+ address-group DT_FW05339_1 {
+ address 185.132.40.152
+ }
+ address-group DT_FW5658C_1 {
+ address 77.68.77.185
+ }
+ address-group DT_FW5858F_1 {
+ address 77.68.121.127
+ }
+ address-group DT_FW06176_1 {
+ address 77.68.77.38
+ }
+ address-group DT_FW6187E_1 {
+ address 77.68.103.147
+ }
+ address-group DT_FW6863A_4 {
+ address 77.68.7.222
+ }
+ address-group DT_FW6906B_1 {
+ address 185.132.43.28
+ }
+ address-group DT_FW06940_3 {
+ address 77.68.33.216
+ address 77.68.33.37
+ address 77.68.50.90
+ }
+ address-group DT_FW7648D_1 {
+ address 77.68.76.77
+ }
+ address-group DT_FW08061_1 {
+ address 77.68.76.45
+ }
+ address-group DT_FW8428B_1 {
+ address 77.68.33.24
+ }
+ address-group DT_FW8871B_1 {
+ address 77.68.78.113
+ }
+ address-group DT_FW11082_1 {
+ address 77.68.113.117
+ }
+ address-group DT_FW16375_5 {
+ address 77.68.77.171
+ }
+ address-group DT_FW19987_4 {
+ address 77.68.77.54
+ }
+ address-group DT_FW20449_2 {
+ address 77.68.126.101
+ }
+ address-group DT_FW25843_1 {
+ address 77.68.24.59
+ }
+ address-group DT_FW26846_1 {
+ address 88.208.197.10
+ }
+ address-group DT_FW27947_1 {
+ address 77.68.77.102
+ }
+ address-group DT_FW27949_2 {
+ address 77.68.117.214
+ }
+ address-group DT_FW28892_1 {
+ address 77.68.77.144
+ }
+ address-group DT_FW31525_6 {
+ address 77.68.77.46
+ }
+ address-group DT_FW36425_1 {
+ address 77.68.119.14
+ }
+ address-group DT_FW40416_1 {
+ address 77.68.121.94
+ }
+ address-group DT_FW42661_3 {
+ address 77.68.77.202
+ }
+ address-group DT_FW44217_2 {
+ address 77.68.89.247
+ }
+ address-group DT_FW45000_1 {
+ address 77.68.24.172
+ }
+ address-group DT_FW48814_3 {
+ address 77.68.77.219
+ }
+ address-group DT_FW49897_1 {
+ address 185.132.36.7
+ }
+ address-group DT_FW56335_2 {
+ address 88.208.198.92
+ }
+ address-group DT_FW56496_1 {
+ address 77.68.51.202
+ address 77.68.101.64
+ }
+ address-group DT_FW62858_12 {
+ address 77.68.77.145
+ }
+ address-group DT_FW63230_1 {
+ address 77.68.76.220
+ }
+ address-group DT_FW66347_1 {
+ address 77.68.92.186
+ }
+ address-group DT_FW73215_1 {
+ address 213.171.209.217
+ }
+ address-group DT_FW73573_1 {
+ address 77.68.76.249
+ }
+ address-group DT_FW73573_2 {
+ address 77.68.77.62
+ }
+ address-group DT_FW78137_1 {
+ address 77.68.34.50
+ }
+ address-group DT_FW81138_1 {
+ address 77.68.77.59
+ }
+ address-group DT_FW81286_1 {
+ address 77.68.77.243
+ }
+ address-group DT_FW85040_1 {
+ address 77.68.5.187
+ }
+ address-group DT_FW85619_1 {
+ address 77.68.127.172
+ }
+ address-group DT_FW89619_1 {
+ address 77.68.76.253
+ }
+ address-group DT_FW98818_1 {
+ address 88.208.197.129
+ }
+ address-group DT_FWA0AA0_1 {
+ address 77.68.113.164
+ }
+ address-group DT_FWA0B7F_1 {
+ address 185.132.39.44
+ }
+ address-group DT_FWA2FF8_4 {
+ address 77.68.76.231
+ }
+ address-group DT_FWA3EA3_1 {
+ address 77.68.77.42
+ }
+ address-group DT_FWA4BC8_1 {
+ address 77.68.112.75
+ }
+ address-group DT_FWA5D67_1 {
+ address 185.132.37.133
+ }
+ address-group DT_FWA7A50_1 {
+ address 77.68.27.57
+ address 77.68.118.102
+ }
+ address-group DT_FWA69A0_1 {
+ address 213.171.212.90
+ }
+ address-group DT_FWA076E_1 {
+ address 77.68.76.19
+ }
+ address-group DT_FWA83DF_1 {
+ address 77.68.7.123
+ }
+ address-group DT_FWA86A4_1 {
+ address 109.228.56.97
+ }
+ address-group DT_FWA86ED_101 {
+ address 77.68.85.172
+ address 109.228.38.171
+ address 88.208.199.233
+ }
+ address-group DT_FWA373F_1 {
+ address 77.68.76.171
+ }
+ address-group DT_FWA0531_1 {
+ address 213.171.215.252
+ }
+ address-group DT_FWA884B_5 {
+ address 88.208.199.249
+ }
+ address-group DT_FWA7625_1 {
+ address 213.171.215.43
+ }
+ address-group DT_FWAA38E_1 {
+ address 77.68.93.164
+ }
+ address-group DT_FWAB44B_1 {
+ address 185.132.37.47
+ }
+ address-group DT_FWAE88B_1 {
+ address 77.68.125.218
+ }
+ address-group DT_FWAF6E8_1 {
+ address 77.68.76.115
+ }
+ address-group DT_FWAFF0A_1 {
+ address 77.68.91.195
+ }
+ address-group DT_FWB2CD2_1 {
+ address 77.68.72.254
+ }
+ address-group DT_FWB28B6_5 {
+ address 77.68.77.209
+ }
+ address-group DT_FWB36A0_1 {
+ address 77.68.77.108
+ }
+ address-group DT_FWB118A_1 {
+ address 77.68.48.14
+ }
+ address-group DT_FWB4438_2 {
+ address 88.208.215.61
+ }
+ address-group DT_FWB6101_1 {
+ address 88.208.215.62
+ }
+ address-group DT_FWB9699_7 {
+ address 77.68.76.123
+ }
+ address-group DT_FWB9699_11 {
+ address 77.68.77.165
+ }
+ address-group DT_FWBB718_1 {
+ address 77.68.77.71
+ }
+ address-group DT_FWBC8A6_1 {
+ address 77.68.112.175
+ }
+ address-group DT_FWBC280_1 {
+ address 77.68.100.167
+ }
+ address-group DT_FWBD9D0_1 {
+ address 77.68.120.31
+ }
+ address-group DT_FWBE878_1 {
+ address 213.171.212.172
+ }
+ address-group DT_FWBED52_1 {
+ address 77.68.112.213
+ }
+ address-group DT_FWBF494_1 {
+ address 77.68.76.209
+ }
+ address-group DT_FWBFC02_1 {
+ address 77.68.112.90
+ }
+ address-group DT_FWBFDED_1 {
+ address 77.68.76.30
+ }
+ address-group DT_FWC0CE0_1 {
+ address 77.68.112.184
+ }
+ address-group DT_FWC1ACD_1 {
+ address 77.68.85.18
+ }
+ address-group DT_FWC2D30_1 {
+ address 77.68.76.48
+ }
+ address-group DT_FWC2EF2_1 {
+ address 77.68.17.200
+ }
+ address-group DT_FWC2EF2_2 {
+ address 77.68.17.200
+ }
+ address-group DT_FWC7D36_1 {
+ address 77.68.76.126
+ }
+ address-group DT_FWC8E8E_1 {
+ address 77.68.28.207
+ }
+ address-group DT_FWC32BE_1 {
+ address 77.68.117.173
+ }
+ address-group DT_FWC37B9_1 {
+ address 77.68.28.139
+ }
+ address-group DT_FWC055A_1 {
+ address 77.68.77.30
+ }
+ address-group DT_FWC72E5_1 {
+ address 77.68.103.227
+ }
+ address-group DT_FWC96A1_1 {
+ address 77.68.75.253
+ }
+ address-group DT_FWC1315_1 {
+ address 77.68.4.57
+ }
+ address-group DT_FWC3921_1 {
+ address 77.68.76.164
+ }
+ address-group DT_FWC6301_1 {
+ address 77.68.34.26
+ }
+ address-group DT_FWCA628_1 {
+ address 185.132.39.99
+ }
+ address-group DT_FWCB0CF_7 {
+ address 77.68.77.163
+ }
+ address-group DT_FWCB29D_1 {
+ address 88.208.197.23
+ }
+ address-group DT_FWCC18F_2 {
+ address 77.68.76.59
+ }
+ address-group DT_FWCD7CE_1 {
+ address 77.68.77.56
+ }
+ address-group DT_FWCDBC7_1 {
+ address 77.68.77.141
+ }
+ address-group DT_FWCDD8B_1 {
+ address 185.132.37.23
+ }
+ address-group DT_FWCE020_1 {
+ address 77.68.48.202
+ }
+ address-group DT_FWD0E22_4 {
+ address 77.68.77.99
+ }
+ address-group DT_FWD4A27_1 {
+ address 77.68.76.244
+ }
+ address-group DT_FWD7EAB_1 {
+ address 77.68.7.67
+ }
+ address-group DT_FWD8DD1_2 {
+ address 213.171.210.155
+ }
+ address-group DT_FWD42CF_1 {
+ address 185.132.38.114
+ }
+ address-group DT_FWD56A2_1 {
+ address 213.171.213.31
+ }
+ address-group DT_FWD61BF_1 {
+ address 88.208.199.46
+ }
+ address-group DT_FWD338A_1 {
+ address 77.68.77.69
+ }
+ address-group DT_FWD498E_1 {
+ address 109.228.39.41
+ }
+ address-group DT_FWD2082_1 {
+ address 77.68.76.94
+ }
+ address-group DT_FWD2440_1 {
+ address 77.68.114.136
+ }
+ address-group DT_FWD3431_2 {
+ address 77.68.77.105
+ }
+ address-group DT_FWD7382_1 {
+ address 185.132.40.11
+ }
+ address-group DT_FWDA443_6 {
+ address 77.68.34.28
+ }
+ address-group DT_FWDAA4F_1 {
+ address 77.68.76.124
+ }
+ address-group DT_FWDAF47_1 {
+ address 77.68.23.35
+ }
+ address-group DT_FWDCA36_3 {
+ address 77.68.77.81
+ }
+ address-group DT_FWDD089_5 {
+ address 77.68.77.21
+ }
+ address-group DT_FWDEDB9_1 {
+ address 77.68.22.146
+ }
+ address-group DT_FWE2AB5_8 {
+ address 77.68.26.166
+ }
+ address-group DT_FWE3E77_1 {
+ address 77.68.76.49
+ }
+ address-group DT_FWE6AB2_1 {
+ address 185.132.40.166
+ }
+ address-group DT_FWE9F7D_1 {
+ address 77.68.32.118
+ }
+ address-group DT_FWE012D_1 {
+ address 77.68.77.190
+ }
+ address-group DT_FWE30A1_4 {
+ address 77.68.33.48
+ }
+ address-group DT_FWE32F2_8 {
+ address 77.68.82.157
+ }
+ address-group DT_FWE47DA_1 {
+ address 77.68.91.128
+ }
+ address-group DT_FWE57AD_1 {
+ address 109.228.56.26
+ }
+ address-group DT_FWE928F_1 {
+ address 77.68.77.129
+ }
+ address-group DT_FWE7180_1 {
+ address 77.68.123.177
+ }
+ address-group DT_FWEAE53_1 {
+ address 77.68.26.216
+ }
+ address-group DT_FWEB321_1 {
+ address 77.68.4.74
+ }
+ address-group DT_FWECBFB_14 {
+ address 77.68.77.44
+ }
+ address-group DT_FWEE03C_1 {
+ address 77.68.116.232
+ }
+ address-group DT_FWEEC75_1 {
+ address 77.68.76.29
+ }
+ address-group DT_FWEF92E_5 {
+ address 77.68.77.57
+ }
+ address-group DT_FWEF92E_6 {
+ address 77.68.77.70
+ }
+ address-group DT_FWEF92E_7 {
+ address 77.68.77.149
+ }
+ address-group DT_FWF3A1B_1 {
+ address 109.228.52.186
+ }
+ address-group DT_FWF7B68_1 {
+ address 77.68.77.231
+ }
+ address-group DT_FWF7BFA_1 {
+ address 77.68.120.45
+ }
+ address-group DT_FWF8E67_1 {
+ address 77.68.85.115
+ }
+ address-group DT_FWF8F85_1 {
+ address 109.228.36.229
+ }
+ address-group DT_FWF9C28_2 {
+ address 77.68.84.155
+ }
+ address-group DT_FWF9C28_4 {
+ address 77.68.28.145
+ }
+ address-group DT_FWF19FB_2 {
+ address 77.68.76.212
+ }
+ address-group DT_FWF30BD_1 {
+ address 77.68.14.88
+ }
+ address-group DT_FWF48EB_1 {
+ address 77.68.76.21
+ }
+ address-group DT_FWF0221_1 {
+ address 185.132.36.60
+ address 185.132.40.244
+ }
+ address-group DT_FWF323F_1 {
+ address 185.132.39.109
+ }
+ address-group DT_FWF699D_4 {
+ address 185.132.40.90
+ }
+ address-group DT_FWF791C_1 {
+ address 77.68.90.132
+ }
+ address-group DT_FWF879C_1 {
+ address 77.68.76.169
+ }
+ address-group DT_FWF3574_1 {
+ address 77.68.76.191
+ }
+ address-group DT_FWF4063_1 {
+ address 77.68.32.254
+ }
+ address-group DT_FWFD9AF_9 {
+ address 77.68.77.24
+ }
+ address-group DT_FWFDCC7_1 {
+ address 109.228.59.247
+ }
+ address-group DT_FWFDD94_15 {
+ address 77.68.76.161
+ }
+ address-group DT_FWFDE34_1 {
+ address 185.132.38.182
+ }
+ address-group DT_FWFEF05_1 {
+ address 88.208.197.150
+ }
+ address-group DT_H71F96 {
+ address 77.68.23.112
+ }
+ address-group DT_SMTP_BLOCKED {
+ address 172.16.255.254
+ address 77.68.77.209
+ address 77.68.76.148
+ address 77.68.77.211
+ address 77.68.21.78
+ address 77.68.77.247
+ address 77.68.77.203
+ address 77.68.77.68
+ address 77.68.77.43
+ address 77.68.77.165
+ address 77.68.76.145
+ address 77.68.76.239
+ address 77.68.77.67
+ address 77.68.76.177
+ address 77.68.77.117
+ address 77.68.76.50
+ address 77.68.76.158
+ address 77.68.76.22
+ address 77.68.76.123
+ address 77.68.76.251
+ address 77.68.77.63
+ address 77.68.7.186
+ address 77.68.93.246
+ address 77.68.4.252
+ address 77.68.76.30
+ address 77.68.76.77
+ address 77.68.76.31
+ address 77.68.77.248
+ address 77.68.3.52
+ address 77.68.76.88
+ address 213.171.214.234
+ address 185.132.39.219
+ address 77.68.5.155
+ address 77.68.80.97
+ address 77.68.101.124
+ address 77.68.76.111
+ address 77.68.76.42
+ address 77.68.77.120
+ address 77.68.76.183
+ address 88.208.197.160
+ address 88.208.197.10
+ address 77.68.76.250
+ address 77.68.77.219
+ address 77.68.77.152
+ address 77.68.76.60
+ }
+ address-group DT_VPN-2661 {
+ address 185.132.40.90
+ }
+ address-group DT_VPN-3575 {
+ address 77.68.77.202
+ }
+ address-group DT_VPN-6103 {
+ address 77.68.77.21
+ }
+ address-group DT_VPN-7030 {
+ address 77.68.77.44
+ }
+ address-group DT_VPN-7902 {
+ address 77.68.77.43
+ }
+ address-group DT_VPN-8159 {
+ address 77.68.77.163
+ }
+ address-group DT_VPN-8203 {
+ address 77.68.77.202
+ }
+ address-group DT_VPN-8625 {
+ address 77.68.94.181
+ }
+ address-group DT_VPN-9415 {
+ address 77.68.76.114
+ }
+ address-group DT_VPN-9484 {
+ address 77.68.77.76
+ address 77.68.76.120
+ }
+ address-group DT_VPN-9727 {
+ address 185.132.40.90
+ }
+ address-group DT_VPN-9749 {
+ address 213.171.212.89
+ address 77.68.76.44
+ address 77.68.77.239
+ address 213.171.212.114
+ address 77.68.103.56
+ }
+ address-group DT_VPN-9765 {
+ address 77.68.76.50
+ }
+ address-group DT_VPN-10131 {
+ address 77.68.76.110
+ }
+ address-group DT_VPN-11083 {
+ address 213.171.212.89
+ address 77.68.76.44
+ address 77.68.77.239
+ address 213.171.212.114
+ address 77.68.103.56
+ }
+ address-group DT_VPN-11913 {
+ address 77.68.76.60
+ }
+ address-group DT_VPN-12870 {
+ address 77.68.77.163
+ }
+ address-group DT_VPN-12899 {
+ address 77.68.77.95
+ }
+ address-group DT_VPN-13261 {
+ address 77.68.77.76
+ address 77.68.76.120
+ }
+ address-group DT_VPN-13983 {
+ address 77.68.3.52
+ }
+ address-group DT_VPN-14649 {
+ address 77.68.76.161
+ }
+ address-group DT_VPN-14657 {
+ address 77.68.76.161
+ }
+ address-group DT_VPN-14658 {
+ address 77.68.76.161
+ }
+ address-group DT_VPN-14673 {
+ address 77.68.76.161
+ }
+ address-group DT_VPN-15625 {
+ address 77.68.77.44
+ }
+ address-group DT_VPN-15950 {
+ address 77.68.101.124
+ }
+ address-group DT_VPN-15951 {
+ address 77.68.118.120
+ address 77.68.27.211
+ address 109.228.37.187
+ }
+ address-group DT_VPN-15960 {
+ address 77.68.101.124
+ }
+ address-group DT_VPN-16402 {
+ address 109.228.39.151
+ }
+ address-group DT_VPN-16450 {
+ address 77.68.77.163
+ }
+ address-group DT_VPN-17207 {
+ address 77.68.77.163
+ }
+ address-group DT_VPN-17558 {
+ address 77.68.77.163
+ }
+ address-group DT_VPN-18646 {
+ address 77.68.77.163
+ }
+ address-group DT_VPN-18647 {
+ address 77.68.77.163
+ }
+ address-group DT_VPN-18830 {
+ address 77.68.118.120
+ address 77.68.27.211
+ address 109.228.37.187
+ }
+ address-group DT_VPN-19135 {
+ address 109.228.39.151
+ }
+ address-group DT_VPN-19474 {
+ address 77.68.118.120
+ address 77.68.27.211
+ address 109.228.37.187
+ }
+ address-group DT_VPN-19807 {
+ address 77.68.76.198
+ }
+ address-group DT_VPN-19992 {
+ address 77.68.25.124
+ }
+ address-group DT_VPN-20306 {
+ address 77.68.77.248
+ }
+ address-group DT_VPN-21673 {
+ address 77.68.15.95
+ address 77.68.75.64
+ }
+ address-group DT_VPN-21821 {
+ address 77.68.15.95
+ address 77.68.75.64
+ }
+ address-group DT_VPN-21822 {
+ address 77.68.15.95
+ address 77.68.75.64
+ }
+ address-group DT_VPN-21876 {
+ address 77.68.77.163
+ }
+ address-group DT_VPN-21982 {
+ address 77.68.15.95
+ address 77.68.75.64
+ }
+ address-group DT_VPN-23209 {
+ address 77.68.77.24
+ }
+ address-group DT_VPN-23729 {
+ address 77.68.118.120
+ address 77.68.27.211
+ address 109.228.37.187
+ }
+ address-group DT_VPN-23733 {
+ address 77.68.118.120
+ address 77.68.27.211
+ address 109.228.37.187
+ }
+ address-group DT_VPN-23734 {
+ address 77.68.118.120
+ address 77.68.27.211
+ address 109.228.37.187
+ }
+ address-group DT_VPN-23738 {
+ address 77.68.118.120
+ address 77.68.27.211
+ address 109.228.37.187
+ }
+ address-group DT_VPN-23946 {
+ address 77.68.77.44
+ }
+ address-group DT_VPN-24398 {
+ address 77.68.76.118
+ }
+ address-group DT_VPN-24589 {
+ address 77.68.76.118
+ }
+ address-group DT_VPN-24591 {
+ address 77.68.76.118
+ }
+ address-group DT_VPN-24592 {
+ address 77.68.76.118
+ }
+ address-group DT_VPN-24593 {
+ address 77.68.76.118
+ }
+ address-group DT_VPN-24594 {
+ address 77.68.76.118
+ }
+ address-group DT_VPN-24595 {
+ address 77.68.76.118
+ }
+ address-group DT_VPN-25822 {
+ address 77.68.15.95
+ address 77.68.75.64
+ }
+ address-group DT_VPN-26124 {
+ address 77.68.77.163
+ }
+ address-group DT_VPN-26157 {
+ address 77.68.77.205
+ }
+ address-group DT_VPN-26772 {
+ address 185.132.40.90
+ }
+ address-group DT_VPN-28031 {
+ address 77.68.77.44
+ }
+ address-group DT_VPN-28484 {
+ address 77.68.118.120
+ address 77.68.27.211
+ address 109.228.37.187
+ }
+ address-group DT_VPN-28515 {
+ address 77.68.82.157
+ }
+ address-group DT_VPN-29631 {
+ address 77.68.77.44
+ }
+ address-group DT_VPN-30261 {
+ address 77.68.77.163
+ }
+ address-group DT_VPN-30262 {
+ address 77.68.77.163
+ }
+ address-group DT_VPN-30679 {
+ address 77.68.77.163
+ }
+ address-group DT_VPN-30791 {
+ address 77.68.118.120
+ address 77.68.27.211
+ address 109.228.37.187
+ }
+ address-group DT_VPN-31002 {
+ address 109.228.36.119
+ }
+ address-group DT_VPN-31301 {
+ address 88.208.197.10
+ }
+ address-group DT_VPN-32528 {
+ address 77.68.76.118
+ }
+ address-group DT_VPN-33204 {
+ address 77.68.77.163
+ }
+ address-group DT_VPN-34006 {
+ address 77.68.33.216
+ address 77.68.33.37
+ address 77.68.50.90
+ }
+ address-group DT_VPN-34122 {
+ address 77.68.114.237
+ }
+ address-group DT_VPN-34309 {
+ address 77.68.77.44
+ }
+ address-group DT_VPN-34501 {
+ address 77.68.50.142
+ }
+ address-group DT_VPN-34583 {
+ address 77.68.77.145
+ }
+ address-group G-ALL_OPEN {
+ address 172.16.255.254
+ address 77.68.76.208
+ address 77.68.77.251
+ address 109.228.36.174
+ address 77.68.89.72
+ address 77.68.77.29
+ address 185.132.43.6
+ address 109.228.46.196
+ address 185.132.43.98
+ address 185.132.41.148
+ address 77.68.49.126
+ address 77.68.49.178
+ address 77.68.116.84
+ address 185.132.36.56
+ address 77.68.126.160
+ address 213.171.208.176
+ address 88.208.197.155
+ address 88.208.198.69
+ address 77.68.29.65
+ }
+ address-group G-ICMP {
+ address 172.16.255.254
+ address 77.68.76.141
+ address 77.68.76.16
+ address 77.68.76.22
+ address 77.68.76.241
+ address 77.68.77.128
+ address 77.68.77.130
+ address 77.68.77.16
+ address 77.68.77.201
+ address 77.68.77.22
+ address 77.68.77.71
+ address 77.68.76.254
+ address 77.68.5.187
+ address 77.68.94.181
+ address 77.68.76.243
+ address 77.68.92.186
+ address 77.68.76.23
+ address 77.68.26.216
+ address 77.68.76.157
+ address 77.68.76.102
+ address 77.68.76.169
+ address 77.68.76.30
+ address 109.228.39.157
+ address 77.68.76.77
+ address 77.68.7.67
+ address 109.228.55.82
+ address 77.68.95.212
+ address 77.68.85.73
+ address 77.68.117.222
+ address 77.68.125.60
+ address 185.132.43.157
+ address 77.68.114.136
+ address 77.68.77.105
+ address 77.68.33.197
+ address 77.68.23.64
+ address 77.68.112.184
+ address 77.68.49.161
+ address 77.68.76.191
+ address 109.228.56.97
+ address 185.132.37.101
+ address 77.68.76.112
+ address 77.68.117.173
+ address 77.68.33.216
+ address 77.68.33.37
+ address 77.68.50.90
+ address 77.68.16.247
+ address 77.68.76.212
+ address 77.68.77.185
+ address 77.68.77.238
+ }
+ address-group G-20-TCP {
+ address 172.16.255.254
+ address 77.68.76.80
+ address 77.68.77.253
+ address 77.68.86.148
+ address 77.68.77.248
+ address 77.68.79.206
+ address 109.228.40.222
+ address 77.68.24.172
+ address 77.68.77.144
+ address 77.68.76.112
+ }
+ address-group G-21-TCP {
+ address 172.16.255.254
+ address 77.68.76.104
+ address 77.68.76.127
+ address 77.68.76.136
+ address 77.68.76.141
+ address 77.68.76.187
+ address 77.68.76.195
+ address 77.68.76.203
+ address 77.68.76.209
+ address 77.68.76.217
+ address 77.68.76.22
+ address 77.68.76.220
+ address 77.68.76.235
+ address 77.68.76.245
+ address 77.68.76.38
+ address 77.68.76.54
+ address 77.68.76.75
+ address 77.68.76.80
+ address 77.68.76.91
+ address 77.68.76.94
+ address 77.68.77.107
+ address 77.68.77.128
+ address 77.68.77.137
+ address 77.68.77.150
+ address 77.68.77.151
+ address 77.68.77.171
+ address 77.68.77.200
+ address 77.68.77.201
+ address 77.68.77.207
+ address 77.68.77.22
+ address 77.68.77.236
+ address 77.68.77.240
+ address 77.68.77.253
+ address 77.68.77.32
+ address 77.68.77.49
+ address 77.68.77.50
+ address 77.68.77.56
+ address 77.68.77.63
+ address 77.68.77.71
+ address 77.68.77.81
+ address 77.68.77.85
+ address 77.68.77.92
+ address 77.68.77.97
+ address 77.68.77.99
+ address 77.68.77.190
+ address 77.68.77.103
+ address 77.68.76.26
+ address 77.68.76.107
+ address 77.68.76.148
+ address 77.68.76.19
+ address 77.68.77.192
+ address 77.68.77.157
+ address 77.68.91.195
+ address 77.68.77.211
+ address 109.228.56.185
+ address 77.68.84.147
+ address 77.68.77.74
+ address 77.68.4.74
+ address 77.68.30.133
+ address 77.68.28.145
+ address 77.68.26.216
+ address 77.68.77.130
+ address 77.68.116.119
+ address 77.68.116.220
+ address 109.228.56.26
+ address 77.68.7.123
+ address 77.68.84.155
+ address 77.68.86.40
+ address 77.68.120.241
+ address 77.68.122.89
+ address 77.68.10.142
+ address 77.68.122.241
+ address 77.68.6.105
+ address 77.68.17.186
+ address 77.68.95.42
+ address 77.68.22.146
+ address 77.68.4.252
+ address 109.228.36.229
+ address 109.228.40.207
+ address 77.68.31.144
+ address 109.228.37.174
+ address 109.228.37.114
+ address 77.68.112.75
+ address 77.68.77.160
+ address 77.68.76.152
+ address 77.68.7.67
+ address 77.68.113.117
+ address 77.68.86.148
+ address 77.68.23.35
+ address 109.228.40.194
+ address 77.68.90.132
+ address 77.68.77.26
+ address 77.68.76.95
+ address 77.68.120.26
+ address 109.228.61.31
+ address 77.68.120.249
+ address 77.68.6.210
+ address 213.171.213.41
+ address 77.68.77.248
+ address 213.171.215.184
+ address 77.68.25.146
+ address 213.171.210.19
+ address 213.171.213.242
+ address 109.228.48.249
+ address 109.228.40.195
+ address 77.68.127.172
+ address 77.68.79.206
+ address 77.68.28.147
+ address 185.132.36.148
+ address 185.132.37.83
+ address 77.68.117.51
+ address 77.68.25.124
+ address 77.68.13.137
+ address 109.228.52.186
+ address 185.132.36.24
+ address 77.68.77.69
+ address 109.228.40.222
+ address 77.68.87.212
+ address 185.132.39.99
+ address 109.228.38.201
+ address 185.132.39.219
+ address 77.68.28.139
+ address 77.68.81.218
+ address 77.68.4.111
+ address 77.68.77.174
+ address 77.68.117.222
+ address 185.132.41.73
+ address 77.68.76.45
+ address 77.68.77.215
+ address 77.68.77.214
+ address 77.68.79.89
+ address 77.68.76.21
+ address 77.68.33.68
+ address 77.68.80.97
+ address 77.68.77.65
+ address 185.132.41.148
+ address 77.68.24.172
+ address 77.68.5.95
+ address 77.68.5.125
+ address 213.171.208.40
+ address 77.68.76.40
+ address 77.68.113.164
+ address 77.68.114.93
+ address 185.132.36.60
+ address 185.132.40.244
+ address 213.171.214.102
+ address 88.208.197.160
+ address 88.208.196.123
+ address 77.68.77.144
+ address 77.68.126.14
+ address 77.68.76.171
+ address 88.208.198.69
+ address 77.68.34.139
+ address 88.208.212.31
+ address 77.68.76.112
+ address 77.68.76.228
+ address 77.68.77.75
+ address 88.208.198.66
+ address 77.68.77.219
+ address 77.68.77.204
+ address 77.68.4.25
+ address 77.68.7.114
+ address 77.68.123.177
+ address 77.68.114.237
+ address 77.68.77.222
+ address 77.68.112.83
+ address 185.132.37.47
+ address 77.68.77.238
+ }
+ address-group G-22-TCP {
+ address 172.16.255.254
+ address 77.68.76.104
+ address 77.68.76.105
+ address 77.68.76.115
+ address 77.68.76.122
+ address 77.68.76.126
+ address 77.68.76.127
+ address 77.68.76.136
+ address 77.68.76.141
+ address 77.68.76.145
+ address 77.68.76.148
+ address 77.68.76.158
+ address 77.68.76.164
+ address 77.68.76.177
+ address 77.68.76.187
+ address 77.68.76.195
+ address 77.68.76.197
+ address 77.68.76.20
+ address 77.68.76.200
+ address 77.68.76.209
+ address 77.68.76.217
+ address 77.68.76.22
+ address 77.68.76.235
+ address 77.68.76.239
+ address 77.68.76.245
+ address 77.68.76.247
+ address 77.68.76.25
+ address 77.68.76.251
+ address 77.68.76.252
+ address 77.68.76.33
+ address 77.68.76.37
+ address 77.68.76.38
+ address 77.68.76.49
+ address 77.68.76.54
+ address 77.68.76.55
+ address 77.68.76.57
+ address 77.68.76.61
+ address 77.68.76.74
+ address 77.68.76.80
+ address 77.68.76.99
+ address 77.68.77.100
+ address 77.68.77.103
+ address 77.68.77.107
+ address 77.68.77.108
+ address 77.68.77.117
+ address 77.68.77.124
+ address 77.68.77.128
+ address 77.68.77.129
+ address 77.68.77.130
+ address 77.68.77.137
+ address 77.68.77.139
+ address 77.68.77.140
+ address 77.68.77.141
+ address 77.68.77.150
+ address 77.68.77.151
+ address 77.68.77.159
+ address 77.68.77.171
+ address 77.68.77.176
+ address 77.68.77.19
+ address 77.68.77.190
+ address 77.68.77.200
+ address 77.68.77.201
+ address 77.68.77.203
+ address 77.68.77.207
+ address 77.68.77.211
+ address 77.68.77.212
+ address 77.68.77.22
+ address 77.68.77.221
+ address 77.68.77.227
+ address 77.68.77.240
+ address 77.68.77.243
+ address 77.68.77.247
+ address 77.68.77.253
+ address 77.68.77.32
+ address 77.68.77.33
+ address 77.68.77.37
+ address 77.68.77.43
+ address 77.68.77.49
+ address 77.68.77.50
+ address 77.68.77.53
+ address 77.68.77.56
+ address 77.68.77.67
+ address 77.68.77.68
+ address 77.68.77.77
+ address 77.68.77.79
+ address 77.68.77.81
+ address 77.68.77.85
+ address 77.68.77.88
+ address 77.68.77.92
+ address 77.68.77.99
+ address 77.68.76.110
+ address 77.68.76.76
+ address 77.68.76.211
+ address 77.68.76.19
+ address 77.68.77.74
+ address 77.68.76.165
+ address 77.68.77.254
+ address 77.68.77.157
+ address 77.68.76.138
+ address 77.68.76.139
+ address 77.68.76.124
+ address 77.68.76.243
+ address 77.68.76.114
+ address 77.68.76.244
+ address 77.68.77.192
+ address 77.68.77.161
+ address 77.68.91.195
+ address 77.68.17.26
+ address 77.68.28.145
+ address 77.68.84.147
+ address 109.228.56.185
+ address 77.68.26.166
+ address 77.68.12.195
+ address 77.68.29.178
+ address 77.68.5.187
+ address 77.68.7.227
+ address 77.68.4.24
+ address 77.68.4.74
+ address 77.68.6.202
+ address 77.68.5.241
+ address 77.68.4.39
+ address 77.68.81.44
+ address 77.68.90.106
+ address 77.68.27.54
+ address 77.68.30.133
+ address 77.68.4.136
+ address 77.68.24.112
+ address 77.68.92.186
+ address 77.68.20.161
+ address 77.68.26.216
+ address 77.68.20.231
+ address 77.68.118.17
+ address 77.68.116.119
+ address 77.68.116.232
+ address 77.68.7.172
+ address 77.68.116.221
+ address 77.68.89.183
+ address 77.68.83.41
+ address 77.68.86.40
+ address 77.68.88.164
+ address 109.228.56.26
+ address 77.68.7.123
+ address 77.68.112.248
+ address 109.228.60.215
+ address 77.68.7.186
+ address 77.68.93.246
+ address 77.68.120.241
+ address 77.68.121.106
+ address 77.68.122.195
+ address 77.68.122.89
+ address 77.68.122.241
+ address 77.68.81.141
+ address 77.68.116.52
+ address 77.68.6.32
+ address 77.68.76.229
+ address 77.68.28.207
+ address 77.68.4.252
+ address 77.68.17.186
+ address 77.68.24.220
+ address 77.68.22.146
+ address 77.68.23.112
+ address 77.68.125.32
+ address 77.68.72.202
+ address 109.228.36.229
+ address 77.68.31.144
+ address 77.68.2.215
+ address 77.68.117.142
+ address 77.68.5.166
+ address 77.68.76.102
+ address 109.228.37.174
+ address 109.228.37.114
+ address 77.68.76.169
+ address 109.228.37.240
+ address 77.68.112.75
+ address 77.68.77.160
+ address 109.228.39.249
+ address 77.68.76.77
+ address 109.228.40.226
+ address 77.68.7.67
+ address 77.68.126.51
+ address 77.68.75.113
+ address 77.68.86.148
+ address 77.68.23.35
+ address 77.68.114.183
+ address 109.228.40.194
+ address 77.68.76.31
+ address 77.68.90.132
+ address 77.68.77.26
+ address 77.68.76.96
+ address 77.68.77.30
+ address 77.68.76.95
+ address 77.68.10.170
+ address 77.68.120.26
+ address 109.228.61.31
+ address 77.68.76.59
+ address 213.171.213.41
+ address 77.68.77.248
+ address 213.171.212.171
+ address 77.68.4.22
+ address 77.68.119.14
+ address 213.171.215.184
+ address 77.68.77.202
+ address 77.68.25.146
+ address 213.171.213.31
+ address 77.68.78.229
+ address 77.68.77.102
+ address 213.171.210.19
+ address 77.68.24.59
+ address 213.171.213.97
+ address 213.171.213.242
+ address 109.228.48.249
+ address 109.228.40.195
+ address 77.68.120.229
+ address 77.68.79.206
+ address 77.68.123.250
+ address 77.68.28.147
+ address 185.132.36.142
+ address 213.171.212.172
+ address 185.132.36.148
+ address 213.171.208.58
+ address 77.68.25.130
+ address 185.132.38.142
+ address 109.228.56.242
+ address 109.228.46.81
+ address 185.132.38.95
+ address 185.132.37.83
+ address 77.68.117.51
+ address 77.68.116.36
+ address 77.68.120.45
+ address 213.171.210.59
+ address 213.171.215.43
+ address 185.132.37.102
+ address 109.228.42.232
+ address 109.228.52.186
+ address 77.68.9.186
+ address 77.68.13.76
+ address 109.228.36.194
+ address 185.132.36.24
+ address 77.68.77.69
+ address 185.132.39.129
+ address 185.132.36.17
+ address 109.228.40.222
+ address 77.68.74.39
+ address 77.68.118.104
+ address 213.171.212.136
+ address 77.68.120.31
+ address 77.68.74.152
+ address 185.132.39.37
+ address 77.68.87.212
+ address 77.68.119.188
+ address 77.68.74.85
+ address 77.68.91.22
+ address 77.68.76.88
+ address 77.68.4.242
+ address 77.68.76.181
+ address 77.68.76.161
+ address 109.228.35.84
+ address 185.132.39.99
+ address 77.68.95.212
+ address 77.68.85.73
+ address 77.68.76.219
+ address 77.68.27.27
+ address 77.68.3.194
+ address 77.68.3.144
+ address 77.68.3.80
+ address 77.68.27.28
+ address 77.68.3.247
+ address 77.68.3.161
+ address 77.68.27.18
+ address 77.68.3.121
+ address 213.171.214.234
+ address 185.132.39.219
+ address 77.68.28.139
+ address 77.68.81.218
+ address 77.68.4.111
+ address 77.68.77.174
+ address 77.68.117.222
+ address 213.171.211.128
+ address 77.68.5.155
+ address 185.132.41.73
+ address 213.171.214.167
+ address 185.132.43.28
+ address 213.171.213.42
+ address 77.68.76.45
+ address 185.132.41.72
+ address 185.132.43.157
+ address 185.132.40.56
+ address 185.132.37.23
+ address 77.68.117.29
+ address 77.68.75.253
+ address 77.68.11.140
+ address 77.68.77.215
+ address 77.68.20.217
+ address 77.68.76.198
+ address 77.68.77.214
+ address 213.171.210.177
+ address 185.132.38.114
+ address 77.68.33.48
+ address 77.68.32.89
+ address 77.68.32.86
+ address 77.68.34.138
+ address 77.68.32.83
+ address 77.68.75.45
+ address 77.68.76.176
+ address 185.132.43.164
+ address 77.68.76.137
+ address 185.132.40.152
+ address 77.68.33.68
+ address 77.68.93.125
+ address 77.68.24.134
+ address 185.132.38.248
+ address 77.68.32.43
+ address 77.68.120.218
+ address 77.68.112.167
+ address 77.68.32.31
+ address 77.68.32.254
+ address 77.68.80.26
+ address 77.68.80.97
+ address 77.68.121.119
+ address 77.68.74.209
+ address 77.68.77.65
+ address 185.132.43.6
+ address 109.228.46.196
+ address 185.132.43.98
+ address 185.132.41.148
+ address 77.68.24.172
+ address 77.68.33.197
+ address 213.171.210.25
+ address 77.68.5.95
+ address 77.68.23.64
+ address 77.68.101.125
+ address 77.68.5.125
+ address 77.68.100.167
+ address 109.228.59.247
+ address 77.68.35.116
+ address 77.68.33.171
+ address 77.68.48.105
+ address 77.68.48.81
+ address 77.68.49.4
+ address 109.228.36.119
+ address 77.68.121.127
+ address 77.68.82.147
+ address 77.68.49.12
+ address 77.68.8.144
+ address 77.68.116.183
+ address 77.68.103.19
+ address 77.68.50.91
+ address 77.68.24.63
+ address 77.68.118.15
+ address 77.68.50.198
+ address 77.68.49.160
+ address 77.68.49.161
+ address 77.68.76.191
+ address 77.68.76.40
+ address 77.68.113.164
+ address 77.68.77.42
+ address 77.68.100.134
+ address 77.68.100.132
+ address 77.68.114.93
+ address 185.132.36.60
+ address 185.132.40.244
+ address 77.68.85.18
+ address 77.68.50.193
+ address 77.68.89.247
+ address 88.208.197.10
+ address 77.68.102.129
+ address 109.228.36.79
+ address 185.132.38.182
+ address 185.132.41.240
+ address 77.68.51.214
+ address 88.208.196.123
+ address 77.68.126.22
+ address 213.171.212.90
+ address 77.68.114.205
+ address 77.68.48.202
+ address 77.68.112.175
+ address 77.68.112.90
+ address 185.132.40.166
+ address 77.68.103.120
+ address 77.68.103.147
+ address 77.68.33.24
+ address 109.228.58.134
+ address 109.228.47.223
+ address 109.228.56.97
+ address 77.68.103.227
+ address 88.208.196.92
+ address 88.208.196.154
+ address 185.132.39.44
+ address 77.68.76.248
+ address 88.208.198.92
+ address 77.68.77.144
+ address 77.68.126.14
+ address 88.208.196.91
+ address 77.68.100.77
+ address 185.132.37.101
+ address 77.68.87.164
+ address 77.68.76.120
+ address 77.68.93.164
+ address 77.68.76.171
+ address 88.208.197.135
+ address 88.208.197.118
+ address 88.208.197.150
+ address 77.68.34.139
+ address 213.171.213.175
+ address 77.68.21.171
+ address 88.208.197.60
+ address 109.228.37.10
+ address 88.208.215.61
+ address 88.208.212.31
+ address 109.228.53.243
+ address 77.68.48.89
+ address 88.208.212.188
+ address 88.208.198.251
+ address 88.208.215.19
+ address 77.68.76.228
+ address 109.228.39.41
+ address 77.68.115.142
+ address 77.68.78.73
+ address 213.171.214.96
+ address 88.208.198.66
+ address 77.68.3.61
+ address 77.68.77.219
+ address 77.68.26.228
+ address 77.68.4.25
+ address 77.68.7.114
+ address 77.68.123.177
+ address 77.68.77.222
+ address 77.68.112.83
+ address 77.68.117.214
+ address 88.208.199.141
+ address 185.132.39.109
+ address 185.132.37.47
+ address 77.68.102.5
+ address 77.68.16.247
+ address 88.208.212.94
+ address 77.68.72.254
+ address 109.228.61.37
+ address 77.68.50.142
+ address 77.68.78.113
+ address 88.208.212.182
+ address 185.132.40.124
+ address 88.208.197.208
+ address 88.208.197.129
+ address 77.68.77.238
+ address 77.68.79.82
+ address 185.132.38.216
+ }
+ address-group G-25-TCP {
+ address 172.16.255.254
+ address 77.68.76.115
+ address 77.68.76.141
+ address 77.68.76.187
+ address 77.68.76.195
+ address 77.68.76.197
+ address 77.68.76.203
+ address 77.68.76.209
+ address 77.68.76.55
+ address 77.68.76.57
+ address 77.68.76.75
+ address 77.68.76.91
+ address 77.68.76.99
+ address 77.68.77.107
+ address 77.68.77.129
+ address 77.68.77.130
+ address 77.68.77.141
+ address 77.68.77.150
+ address 77.68.77.159
+ address 77.68.77.171
+ address 77.68.77.176
+ address 77.68.77.207
+ address 77.68.77.22
+ address 77.68.77.236
+ address 77.68.77.240
+ address 77.68.77.243
+ address 77.68.77.32
+ address 77.68.77.33
+ address 77.68.77.49
+ address 77.68.77.50
+ address 77.68.77.56
+ address 77.68.77.63
+ address 77.68.77.81
+ address 77.68.77.85
+ address 77.68.77.92
+ address 77.68.77.97
+ address 77.68.77.99
+ address 77.68.77.77
+ address 77.68.76.19
+ address 77.68.77.192
+ address 77.68.77.254
+ address 77.68.76.139
+ address 77.68.84.147
+ address 77.68.4.74
+ address 77.68.6.202
+ address 77.68.81.44
+ address 77.68.30.133
+ address 77.68.77.74
+ address 77.68.77.100
+ address 77.68.92.186
+ address 77.68.76.114
+ address 77.68.116.119
+ address 77.68.116.221
+ address 77.68.116.220
+ address 109.228.56.26
+ address 77.68.7.123
+ address 77.68.120.241
+ address 109.228.60.215
+ address 77.68.7.172
+ address 77.68.116.52
+ address 77.68.91.128
+ address 77.68.24.112
+ address 77.68.76.94
+ address 109.228.37.114
+ address 77.68.112.75
+ address 77.68.77.160
+ address 77.68.7.67
+ address 77.68.113.117
+ address 77.68.126.51
+ address 77.68.86.148
+ address 77.68.23.35
+ address 77.68.77.30
+ address 77.68.76.95
+ address 77.68.10.170
+ address 213.171.213.41
+ address 213.171.215.184
+ address 77.68.25.146
+ address 213.171.213.31
+ address 77.68.78.229
+ address 213.171.210.19
+ address 77.68.79.206
+ address 213.171.215.252
+ address 109.228.52.186
+ address 77.68.77.69
+ address 109.228.40.222
+ address 77.68.87.212
+ address 185.132.39.99
+ address 77.68.85.73
+ address 77.68.28.139
+ address 77.68.4.111
+ address 77.68.77.174
+ address 77.68.117.222
+ address 185.132.43.28
+ address 185.132.37.23
+ address 77.68.77.215
+ address 77.68.77.214
+ address 185.132.38.114
+ address 77.68.33.48
+ address 77.68.79.89
+ address 77.68.76.21
+ address 77.68.76.137
+ address 77.68.80.26
+ address 77.68.5.95
+ address 77.68.100.167
+ address 77.68.4.80
+ address 77.68.49.152
+ address 213.171.208.40
+ address 77.68.112.184
+ address 77.68.115.17
+ address 77.68.82.147
+ address 77.68.118.15
+ address 77.68.76.191
+ address 77.68.50.193
+ address 77.68.102.129
+ address 77.68.76.118
+ address 88.208.198.69
+ address 77.68.34.139
+ address 88.208.197.60
+ address 88.208.212.188
+ address 77.68.76.112
+ address 77.68.77.75
+ address 213.171.214.96
+ address 88.208.198.66
+ address 77.68.77.219
+ address 77.68.77.204
+ address 77.68.76.202
+ address 77.68.123.177
+ address 77.68.77.222
+ address 77.68.112.83
+ address 185.132.37.47
+ address 77.68.77.152
+ address 77.68.77.181
+ address 77.68.77.185
+ address 77.68.77.238
+ address 77.68.79.82
+ }
+ address-group G-53-TCP {
+ address 172.16.255.254
+ address 77.68.94.181
+ address 77.68.28.145
+ address 77.68.84.155
+ address 77.68.78.229
+ address 185.132.39.99
+ address 185.132.43.28
+ address 77.68.77.215
+ address 185.132.40.152
+ address 77.68.49.161
+ address 77.68.76.118
+ }
+ address-group G-53-UDP {
+ address 172.16.255.254
+ address 77.68.76.235
+ address 77.68.76.93
+ address 77.68.77.107
+ address 77.68.77.151
+ address 77.68.77.37
+ address 77.68.76.139
+ address 77.68.81.44
+ address 77.68.94.181
+ address 77.68.28.145
+ address 77.68.81.141
+ address 77.68.4.252
+ address 77.68.125.32
+ address 77.68.86.148
+ address 77.68.78.229
+ address 185.132.43.28
+ address 77.68.75.45
+ address 185.132.40.152
+ address 77.68.4.80
+ address 77.68.49.152
+ address 77.68.49.161
+ address 77.68.34.50
+ }
+ address-group G-80-TCP {
+ address 172.16.255.254
+ address 77.68.76.104
+ address 77.68.76.105
+ address 77.68.76.115
+ address 77.68.76.116
+ address 77.68.76.122
+ address 77.68.76.126
+ address 77.68.76.127
+ address 77.68.76.136
+ address 77.68.76.141
+ address 77.68.76.145
+ address 77.68.76.148
+ address 77.68.76.150
+ address 77.68.76.158
+ address 77.68.76.164
+ address 77.68.76.177
+ address 77.68.76.187
+ address 77.68.76.195
+ address 77.68.76.197
+ address 77.68.76.20
+ address 77.68.76.200
+ address 77.68.76.203
+ address 77.68.76.209
+ address 77.68.76.217
+ address 77.68.76.22
+ address 77.68.76.220
+ address 77.68.76.23
+ address 77.68.76.231
+ address 77.68.76.235
+ address 77.68.76.239
+ address 77.68.76.241
+ address 77.68.76.245
+ address 77.68.76.247
+ address 77.68.76.25
+ address 77.68.76.251
+ address 77.68.76.252
+ address 77.68.76.33
+ address 77.68.76.35
+ address 77.68.76.37
+ address 77.68.76.38
+ address 77.68.76.39
+ address 77.68.76.49
+ address 77.68.76.50
+ address 77.68.76.54
+ address 77.68.76.55
+ address 77.68.76.57
+ address 77.68.76.58
+ address 77.68.76.61
+ address 77.68.76.74
+ address 77.68.76.75
+ address 77.68.76.80
+ address 77.68.76.91
+ address 77.68.76.93
+ address 77.68.76.94
+ address 77.68.76.99
+ address 77.68.77.100
+ address 77.68.77.103
+ address 77.68.77.107
+ address 77.68.77.108
+ address 77.68.77.115
+ address 77.68.77.117
+ address 77.68.77.124
+ address 77.68.77.128
+ address 77.68.77.129
+ address 77.68.77.130
+ address 77.68.77.137
+ address 77.68.77.139
+ address 77.68.77.140
+ address 77.68.77.141
+ address 77.68.77.150
+ address 77.68.77.151
+ address 77.68.77.156
+ address 77.68.77.159
+ address 77.68.77.171
+ address 77.68.77.176
+ address 77.68.77.178
+ address 77.68.77.19
+ address 77.68.77.190
+ address 77.68.77.199
+ address 77.68.77.200
+ address 77.68.77.201
+ address 77.68.77.203
+ address 77.68.77.207
+ address 77.68.77.211
+ address 77.68.77.212
+ address 77.68.77.22
+ address 77.68.77.227
+ address 77.68.77.228
+ address 77.68.77.236
+ address 77.68.77.240
+ address 77.68.77.243
+ address 77.68.77.247
+ address 77.68.77.253
+ address 77.68.77.32
+ address 77.68.77.33
+ address 77.68.77.37
+ address 77.68.77.49
+ address 77.68.77.50
+ address 77.68.77.53
+ address 77.68.77.56
+ address 77.68.77.63
+ address 77.68.77.67
+ address 77.68.77.68
+ address 77.68.77.71
+ address 77.68.77.77
+ address 77.68.77.79
+ address 77.68.77.81
+ address 77.68.77.85
+ address 77.68.77.88
+ address 77.68.77.92
+ address 77.68.77.97
+ address 77.68.77.99
+ address 77.68.76.76
+ address 77.68.76.124
+ address 77.68.76.211
+ address 77.68.76.19
+ address 77.68.77.74
+ address 77.68.77.192
+ address 77.68.76.92
+ address 77.68.76.165
+ address 77.68.77.254
+ address 77.68.77.157
+ address 77.68.76.138
+ address 77.68.76.139
+ address 77.68.76.114
+ address 77.68.76.244
+ address 77.68.77.161
+ address 77.68.77.62
+ address 77.68.77.38
+ address 77.68.91.195
+ address 77.68.17.26
+ address 77.68.28.145
+ address 109.228.56.185
+ address 77.68.84.147
+ address 77.68.12.195
+ address 77.68.21.78
+ address 77.68.5.187
+ address 77.68.7.227
+ address 77.68.4.24
+ address 77.68.4.74
+ address 77.68.6.202
+ address 77.68.5.241
+ address 77.68.4.39
+ address 77.68.81.44
+ address 77.68.90.106
+ address 77.68.94.181
+ address 77.68.30.164
+ address 77.68.30.133
+ address 77.68.4.136
+ address 77.68.23.158
+ address 77.68.92.186
+ address 77.68.24.112
+ address 77.68.112.213
+ address 77.68.20.161
+ address 77.68.26.216
+ address 77.68.20.231
+ address 77.68.118.17
+ address 77.68.116.119
+ address 77.68.116.220
+ address 77.68.116.232
+ address 77.68.76.142
+ address 77.68.117.202
+ address 77.68.7.172
+ address 77.68.116.221
+ address 77.68.89.183
+ address 77.68.83.41
+ address 77.68.86.40
+ address 77.68.88.164
+ address 109.228.56.26
+ address 77.68.7.123
+ address 77.68.112.248
+ address 109.228.60.215
+ address 77.68.7.186
+ address 77.68.93.246
+ address 77.68.84.155
+ address 77.68.120.241
+ address 77.68.121.106
+ address 77.68.122.195
+ address 77.68.122.89
+ address 77.68.120.146
+ address 77.68.122.241
+ address 77.68.119.92
+ address 77.68.81.141
+ address 77.68.10.142
+ address 77.68.116.52
+ address 77.68.6.105
+ address 77.68.76.229
+ address 77.68.95.42
+ address 77.68.28.207
+ address 77.68.4.252
+ address 77.68.17.186
+ address 77.68.91.128
+ address 77.68.22.146
+ address 77.68.23.112
+ address 77.68.24.220
+ address 77.68.125.32
+ address 77.68.76.243
+ address 77.68.12.250
+ address 77.68.72.202
+ address 109.228.36.229
+ address 109.228.40.207
+ address 77.68.31.144
+ address 77.68.2.215
+ address 77.68.117.142
+ address 77.68.5.166
+ address 109.228.37.174
+ address 109.228.37.114
+ address 77.68.76.169
+ address 109.228.37.240
+ address 77.68.112.75
+ address 77.68.76.30
+ address 109.228.35.110
+ address 77.68.77.160
+ address 77.68.77.208
+ address 77.68.76.152
+ address 109.228.39.249
+ address 77.68.76.77
+ address 109.228.40.226
+ address 77.68.7.67
+ address 77.68.113.117
+ address 77.68.126.51
+ address 77.68.75.113
+ address 77.68.86.148
+ address 77.68.23.35
+ address 77.68.114.183
+ address 109.228.40.194
+ address 77.68.76.31
+ address 77.68.77.72
+ address 77.68.90.132
+ address 77.68.6.110
+ address 77.68.76.96
+ address 77.68.77.30
+ address 77.68.76.95
+ address 77.68.10.170
+ address 77.68.120.26
+ address 109.228.61.31
+ address 77.68.76.59
+ address 77.68.120.249
+ address 77.68.6.210
+ address 213.171.213.41
+ address 77.68.77.248
+ address 213.171.212.171
+ address 77.68.4.22
+ address 77.68.119.14
+ address 213.171.215.184
+ address 77.68.77.202
+ address 77.68.25.146
+ address 213.171.213.31
+ address 77.68.78.229
+ address 77.68.77.102
+ address 213.171.210.19
+ address 77.68.24.59
+ address 213.171.213.97
+ address 213.171.213.242
+ address 77.68.77.205
+ address 109.228.48.249
+ address 109.228.40.195
+ address 77.68.120.229
+ address 77.68.127.172
+ address 77.68.79.206
+ address 77.68.123.250
+ address 77.68.28.147
+ address 213.171.212.172
+ address 185.132.36.148
+ address 213.171.208.58
+ address 77.68.25.130
+ address 109.228.56.242
+ address 109.228.46.81
+ address 185.132.38.95
+ address 185.132.37.83
+ address 77.68.117.51
+ address 77.68.116.36
+ address 77.68.120.45
+ address 77.68.25.124
+ address 213.171.210.59
+ address 213.171.215.43
+ address 213.171.215.252
+ address 185.132.37.102
+ address 109.228.42.232
+ address 109.228.52.186
+ address 77.68.9.186
+ address 77.68.13.76
+ address 109.228.36.194
+ address 185.132.36.7
+ address 185.132.36.24
+ address 77.68.77.69
+ address 185.132.39.129
+ address 185.132.36.17
+ address 109.228.40.222
+ address 77.68.118.104
+ address 77.68.120.31
+ address 77.68.74.152
+ address 185.132.39.37
+ address 77.68.3.52
+ address 77.68.87.212
+ address 77.68.76.29
+ address 77.68.119.188
+ address 77.68.74.85
+ address 77.68.91.22
+ address 77.68.76.88
+ address 77.68.4.242
+ address 77.68.76.181
+ address 77.68.76.161
+ address 185.132.39.99
+ address 77.68.95.212
+ address 77.68.85.73
+ address 77.68.76.219
+ address 77.68.27.27
+ address 77.68.3.194
+ address 77.68.3.144
+ address 77.68.3.80
+ address 77.68.27.28
+ address 77.68.3.247
+ address 77.68.3.161
+ address 77.68.27.18
+ address 77.68.3.121
+ address 213.171.214.234
+ address 109.228.38.201
+ address 185.132.39.219
+ address 77.68.28.139
+ address 77.68.81.218
+ address 77.68.4.111
+ address 77.68.77.174
+ address 77.68.117.222
+ address 213.171.211.128
+ address 77.68.5.155
+ address 185.132.41.73
+ address 77.68.77.231
+ address 213.171.214.167
+ address 185.132.43.28
+ address 213.171.213.42
+ address 77.68.76.45
+ address 185.132.41.72
+ address 77.68.92.92
+ address 185.132.40.56
+ address 185.132.37.23
+ address 77.68.117.29
+ address 77.68.75.253
+ address 77.68.11.140
+ address 77.68.77.215
+ address 77.68.20.217
+ address 77.68.10.152
+ address 77.68.73.73
+ address 77.68.76.198
+ address 77.68.77.214
+ address 77.68.9.75
+ address 213.171.210.177
+ address 77.68.76.160
+ address 185.132.38.114
+ address 77.68.33.48
+ address 185.132.40.90
+ address 77.68.79.89
+ address 77.68.34.28
+ address 77.68.76.21
+ address 77.68.75.45
+ address 77.68.76.176
+ address 77.68.77.95
+ address 185.132.39.68
+ address 185.132.43.164
+ address 77.68.76.137
+ address 185.132.40.152
+ address 77.68.77.249
+ address 77.68.33.68
+ address 77.68.24.134
+ address 185.132.38.248
+ address 77.68.32.43
+ address 77.68.120.218
+ address 77.68.112.167
+ address 77.68.32.31
+ address 77.68.32.118
+ address 77.68.32.254
+ address 77.68.80.26
+ address 77.68.17.200
+ address 77.68.80.97
+ address 77.68.121.119
+ address 77.68.74.209
+ address 77.68.77.65
+ address 185.132.43.6
+ address 109.228.46.196
+ address 185.132.43.98
+ address 77.68.100.150
+ address 185.132.41.148
+ address 77.68.24.172
+ address 77.68.33.197
+ address 77.68.5.95
+ address 77.68.23.64
+ address 77.68.101.124
+ address 77.68.5.125
+ address 77.68.100.167
+ address 77.68.4.80
+ address 77.68.49.152
+ address 109.228.59.247
+ address 213.171.208.40
+ address 77.68.112.184
+ address 77.68.35.116
+ address 77.68.33.171
+ address 77.68.76.111
+ address 77.68.76.42
+ address 77.68.77.120
+ address 77.68.76.183
+ address 77.68.118.86
+ address 77.68.48.105
+ address 77.68.48.81
+ address 77.68.49.4
+ address 109.228.36.119
+ address 77.68.34.26
+ address 77.68.115.17
+ address 77.68.121.127
+ address 77.68.82.147
+ address 77.68.49.12
+ address 77.68.8.144
+ address 77.68.116.183
+ address 213.171.212.89
+ address 77.68.76.44
+ address 77.68.77.239
+ address 77.68.51.202
+ address 77.68.101.64
+ address 77.68.103.19
+ address 77.68.50.91
+ address 77.68.24.63
+ address 77.68.118.15
+ address 77.68.50.198
+ address 77.68.77.59
+ address 77.68.49.160
+ address 77.68.76.191
+ address 77.68.126.101
+ address 77.68.113.164
+ address 77.68.77.42
+ address 77.68.100.134
+ address 77.68.100.132
+ address 77.68.114.93
+ address 185.132.36.60
+ address 185.132.40.244
+ address 77.68.85.18
+ address 213.171.214.102
+ address 77.68.50.193
+ address 88.208.197.160
+ address 88.208.197.10
+ address 77.68.102.129
+ address 109.228.36.79
+ address 185.132.38.182
+ address 185.132.41.240
+ address 77.68.51.214
+ address 88.208.196.123
+ address 88.208.215.157
+ address 77.68.126.22
+ address 77.68.4.180
+ address 213.171.212.90
+ address 77.68.114.205
+ address 185.132.43.71
+ address 77.68.77.114
+ address 77.68.48.202
+ address 77.68.112.175
+ address 77.68.112.90
+ address 185.132.40.166
+ address 77.68.76.118
+ address 77.68.103.120
+ address 77.68.33.24
+ address 109.228.58.134
+ address 109.228.47.223
+ address 77.68.31.96
+ address 77.68.103.227
+ address 77.68.76.250
+ address 213.171.212.203
+ address 88.208.196.92
+ address 88.208.196.154
+ address 185.132.39.44
+ address 77.68.76.248
+ address 88.208.198.92
+ address 109.228.36.37
+ address 77.68.77.144
+ address 77.68.126.14
+ address 88.208.196.91
+ address 77.68.100.77
+ address 185.132.37.101
+ address 77.68.87.164
+ address 77.68.77.76
+ address 77.68.76.120
+ address 77.68.82.157
+ address 77.68.93.164
+ address 77.68.76.171
+ address 88.208.197.135
+ address 88.208.197.118
+ address 88.208.197.150
+ address 213.171.212.114
+ address 88.208.198.69
+ address 77.68.34.139
+ address 77.68.21.171
+ address 88.208.197.60
+ address 77.68.85.27
+ address 109.228.37.10
+ address 88.208.215.61
+ address 88.208.199.249
+ address 88.208.212.31
+ address 109.228.53.243
+ address 77.68.48.89
+ address 88.208.212.188
+ address 88.208.198.251
+ address 77.68.76.112
+ address 77.68.48.14
+ address 88.208.215.19
+ address 77.68.103.56
+ address 77.68.76.228
+ address 77.68.77.75
+ address 77.68.117.173
+ address 88.208.215.121
+ address 109.228.39.41
+ address 77.68.88.100
+ address 77.68.76.108
+ address 77.68.115.142
+ address 213.171.214.96
+ address 88.208.198.66
+ address 88.208.198.64
+ address 77.68.3.61
+ address 77.68.77.219
+ address 77.68.77.204
+ address 77.68.26.228
+ address 77.68.74.232
+ address 77.68.118.88
+ address 77.68.76.48
+ address 77.68.76.202
+ address 77.68.4.25
+ address 77.68.7.114
+ address 77.68.123.177
+ address 88.208.197.23
+ address 77.68.114.237
+ address 77.68.77.222
+ address 77.68.112.83
+ address 88.208.199.141
+ address 77.68.77.163
+ address 185.132.39.109
+ address 77.68.77.44
+ address 185.132.37.47
+ address 77.68.102.5
+ address 77.68.16.247
+ address 88.208.212.94
+ address 77.68.72.254
+ address 77.68.77.152
+ address 77.68.50.142
+ address 88.208.199.46
+ address 77.68.78.113
+ address 88.208.212.182
+ address 77.68.77.181
+ address 77.68.15.95
+ address 77.68.75.64
+ address 213.171.212.71
+ address 185.132.40.124
+ address 88.208.197.208
+ address 88.208.197.129
+ address 77.68.76.60
+ address 77.68.6.119
+ address 77.68.77.185
+ address 77.68.77.238
+ address 77.68.79.82
+ address 109.228.39.151
+ }
+ address-group G-110-TCP {
+ address 172.16.255.254
+ address 77.68.76.187
+ address 77.68.77.107
+ address 77.68.77.128
+ address 77.68.77.129
+ address 77.68.77.171
+ address 77.68.77.176
+ address 77.68.77.190
+ address 77.68.77.207
+ address 77.68.77.22
+ address 77.68.77.33
+ address 77.68.77.49
+ address 77.68.77.92
+ address 77.68.77.77
+ address 77.68.76.19
+ address 77.68.77.192
+ address 77.68.84.147
+ address 77.68.4.74
+ address 77.68.6.202
+ address 77.68.116.119
+ address 77.68.116.221
+ address 77.68.120.241
+ address 109.228.60.215
+ address 77.68.116.52
+ address 77.68.126.51
+ address 77.68.23.35
+ address 77.68.76.95
+ address 213.171.215.184
+ address 77.68.25.146
+ address 77.68.79.206
+ address 213.171.215.252
+ address 109.228.52.186
+ address 109.228.40.222
+ address 185.132.39.99
+ address 77.68.77.214
+ address 185.132.38.114
+ address 77.68.79.89
+ address 77.68.5.95
+ address 77.68.100.167
+ address 77.68.4.80
+ address 77.68.49.152
+ address 213.171.208.40
+ address 77.68.50.193
+ address 77.68.102.129
+ address 88.208.198.69
+ address 88.208.212.188
+ address 88.208.198.66
+ address 77.68.4.25
+ address 77.68.7.114
+ address 77.68.123.177
+ address 77.68.77.185
+ address 77.68.77.238
+ }
+ address-group G-143-TCP {
+ address 172.16.255.254
+ address 77.68.76.115
+ address 77.68.76.123
+ address 77.68.76.187
+ address 77.68.77.129
+ address 77.68.77.130
+ address 77.68.77.141
+ address 77.68.77.171
+ address 77.68.77.176
+ address 77.68.77.207
+ address 77.68.77.22
+ address 77.68.77.33
+ address 77.68.77.49
+ address 77.68.77.50
+ address 77.68.77.92
+ address 77.68.77.77
+ address 77.68.77.192
+ address 77.68.84.147
+ address 77.68.4.74
+ address 77.68.6.202
+ address 77.68.81.44
+ address 77.68.92.186
+ address 77.68.116.119
+ address 77.68.116.221
+ address 109.228.60.215
+ address 77.68.7.172
+ address 77.68.116.52
+ address 77.68.24.112
+ address 77.68.77.107
+ address 77.68.112.75
+ address 77.68.7.67
+ address 77.68.126.51
+ address 77.68.23.35
+ address 77.68.76.95
+ address 213.171.215.184
+ address 77.68.25.146
+ address 213.171.213.31
+ address 213.171.210.19
+ address 77.68.79.206
+ address 77.68.77.69
+ address 109.228.40.222
+ address 185.132.39.99
+ address 77.68.117.222
+ address 77.68.33.48
+ address 77.68.79.89
+ address 77.68.5.95
+ address 77.68.100.167
+ address 77.68.4.80
+ address 77.68.49.152
+ address 213.171.208.40
+ address 77.68.115.17
+ address 77.68.102.129
+ address 88.208.198.69
+ address 77.68.34.139
+ address 88.208.212.188
+ address 88.208.198.66
+ address 77.68.77.204
+ address 77.68.4.25
+ address 77.68.7.114
+ address 77.68.123.177
+ address 77.68.77.222
+ address 77.68.112.83
+ }
+ address-group G-443-TCP {
+ address 172.16.255.254
+ address 77.68.76.104
+ address 77.68.76.105
+ address 77.68.76.115
+ address 77.68.76.116
+ address 77.68.76.122
+ address 77.68.76.126
+ address 77.68.76.127
+ address 77.68.76.136
+ address 77.68.76.141
+ address 77.68.76.145
+ address 77.68.76.148
+ address 77.68.76.150
+ address 77.68.76.158
+ address 77.68.76.164
+ address 77.68.76.177
+ address 77.68.76.187
+ address 77.68.76.195
+ address 77.68.76.197
+ address 77.68.76.20
+ address 77.68.76.200
+ address 77.68.76.203
+ address 77.68.76.209
+ address 77.68.76.217
+ address 77.68.76.22
+ address 77.68.76.220
+ address 77.68.76.23
+ address 77.68.76.231
+ address 77.68.76.235
+ address 77.68.76.239
+ address 77.68.76.241
+ address 77.68.76.245
+ address 77.68.76.25
+ address 77.68.76.252
+ address 77.68.76.33
+ address 77.68.76.35
+ address 77.68.76.37
+ address 77.68.76.38
+ address 77.68.76.39
+ address 77.68.76.49
+ address 77.68.76.50
+ address 77.68.76.54
+ address 77.68.76.55
+ address 77.68.76.57
+ address 77.68.76.58
+ address 77.68.76.61
+ address 77.68.76.74
+ address 77.68.76.75
+ address 77.68.76.80
+ address 77.68.76.91
+ address 77.68.76.93
+ address 77.68.76.94
+ address 77.68.76.99
+ address 77.68.77.100
+ address 77.68.77.103
+ address 77.68.77.107
+ address 77.68.77.108
+ address 77.68.77.117
+ address 77.68.77.124
+ address 77.68.77.128
+ address 77.68.77.129
+ address 77.68.77.130
+ address 77.68.77.137
+ address 77.68.77.139
+ address 77.68.77.140
+ address 77.68.77.141
+ address 77.68.77.150
+ address 77.68.77.151
+ address 77.68.77.156
+ address 77.68.77.159
+ address 77.68.77.171
+ address 77.68.77.176
+ address 77.68.77.178
+ address 77.68.77.19
+ address 77.68.77.190
+ address 77.68.77.199
+ address 77.68.77.200
+ address 77.68.77.201
+ address 77.68.77.203
+ address 77.68.77.207
+ address 77.68.77.211
+ address 77.68.77.212
+ address 77.68.77.22
+ address 77.68.77.221
+ address 77.68.77.227
+ address 77.68.77.228
+ address 77.68.77.236
+ address 77.68.77.240
+ address 77.68.77.243
+ address 77.68.77.247
+ address 77.68.77.253
+ address 77.68.77.32
+ address 77.68.77.33
+ address 77.68.77.37
+ address 77.68.77.49
+ address 77.68.77.50
+ address 77.68.77.53
+ address 77.68.77.56
+ address 77.68.77.63
+ address 77.68.77.67
+ address 77.68.77.68
+ address 77.68.77.71
+ address 77.68.77.77
+ address 77.68.77.79
+ address 77.68.77.81
+ address 77.68.77.85
+ address 77.68.77.88
+ address 77.68.77.92
+ address 77.68.77.97
+ address 77.68.77.99
+ address 77.68.76.76
+ address 77.68.76.124
+ address 77.68.76.211
+ address 77.68.76.19
+ address 77.68.76.110
+ address 77.68.77.74
+ address 77.68.77.192
+ address 77.68.76.92
+ address 77.68.76.165
+ address 77.68.77.254
+ address 77.68.77.157
+ address 77.68.76.138
+ address 77.68.76.139
+ address 77.68.76.114
+ address 77.68.76.244
+ address 77.68.77.161
+ address 77.68.77.38
+ address 77.68.91.195
+ address 77.68.17.26
+ address 77.68.28.145
+ address 109.228.56.185
+ address 77.68.84.147
+ address 77.68.12.195
+ address 77.68.21.78
+ address 77.68.5.187
+ address 77.68.7.227
+ address 77.68.4.24
+ address 77.68.4.74
+ address 77.68.6.202
+ address 77.68.5.241
+ address 77.68.4.39
+ address 77.68.81.44
+ address 77.68.90.106
+ address 77.68.94.181
+ address 77.68.30.164
+ address 77.68.30.133
+ address 77.68.4.136
+ address 77.68.23.158
+ address 77.68.24.112
+ address 77.68.92.186
+ address 77.68.20.161
+ address 77.68.112.213
+ address 77.68.26.216
+ address 77.68.20.231
+ address 77.68.118.17
+ address 77.68.116.119
+ address 77.68.116.220
+ address 77.68.116.232
+ address 77.68.76.142
+ address 77.68.117.202
+ address 77.68.7.172
+ address 77.68.116.221
+ address 77.68.89.183
+ address 77.68.83.41
+ address 77.68.86.40
+ address 77.68.88.164
+ address 109.228.56.26
+ address 77.68.7.123
+ address 77.68.112.248
+ address 109.228.60.215
+ address 77.68.7.186
+ address 77.68.93.246
+ address 77.68.84.155
+ address 77.68.120.241
+ address 77.68.121.106
+ address 77.68.122.195
+ address 77.68.122.89
+ address 77.68.120.146
+ address 77.68.122.241
+ address 77.68.81.141
+ address 77.68.116.52
+ address 77.68.6.105
+ address 77.68.76.229
+ address 77.68.95.42
+ address 77.68.28.207
+ address 77.68.4.252
+ address 77.68.17.186
+ address 77.68.91.128
+ address 77.68.22.146
+ address 77.68.23.112
+ address 77.68.24.220
+ address 77.68.125.32
+ address 77.68.12.250
+ address 77.68.76.243
+ address 77.68.72.202
+ address 109.228.36.229
+ address 109.228.40.207
+ address 77.68.31.144
+ address 77.68.2.215
+ address 77.68.117.142
+ address 77.68.5.166
+ address 77.68.76.102
+ address 109.228.37.174
+ address 109.228.37.114
+ address 109.228.37.240
+ address 77.68.112.75
+ address 77.68.76.30
+ address 109.228.35.110
+ address 77.68.77.160
+ address 77.68.77.208
+ address 77.68.76.152
+ address 109.228.39.249
+ address 77.68.76.77
+ address 77.68.7.160
+ address 109.228.40.226
+ address 77.68.7.67
+ address 77.68.113.117
+ address 77.68.126.51
+ address 77.68.75.113
+ address 77.68.86.148
+ address 77.68.114.183
+ address 109.228.40.194
+ address 77.68.76.31
+ address 77.68.77.72
+ address 77.68.90.132
+ address 77.68.6.110
+ address 77.68.77.26
+ address 77.68.76.96
+ address 77.68.77.30
+ address 77.68.76.95
+ address 77.68.10.170
+ address 77.68.76.234
+ address 77.68.120.26
+ address 109.228.61.31
+ address 77.68.76.59
+ address 77.68.120.249
+ address 77.68.6.210
+ address 213.171.213.41
+ address 77.68.77.248
+ address 213.171.212.171
+ address 77.68.4.22
+ address 77.68.119.14
+ address 213.171.215.184
+ address 77.68.77.202
+ address 77.68.25.146
+ address 213.171.213.31
+ address 77.68.78.229
+ address 77.68.77.102
+ address 213.171.210.19
+ address 77.68.24.59
+ address 213.171.213.97
+ address 213.171.213.242
+ address 77.68.77.205
+ address 109.228.48.249
+ address 109.228.40.195
+ address 77.68.120.229
+ address 77.68.127.172
+ address 77.68.79.206
+ address 77.68.123.250
+ address 77.68.28.147
+ address 213.171.212.172
+ address 185.132.36.148
+ address 213.171.208.58
+ address 77.68.25.130
+ address 109.228.56.242
+ address 109.228.46.81
+ address 185.132.38.95
+ address 185.132.37.83
+ address 77.68.117.51
+ address 77.68.116.36
+ address 77.68.120.45
+ address 77.68.25.124
+ address 213.171.210.59
+ address 213.171.215.43
+ address 213.171.215.252
+ address 185.132.37.102
+ address 109.228.42.232
+ address 109.228.52.186
+ address 77.68.9.186
+ address 77.68.13.76
+ address 109.228.36.194
+ address 185.132.36.7
+ address 185.132.36.24
+ address 77.68.77.69
+ address 185.132.39.129
+ address 185.132.36.17
+ address 109.228.40.222
+ address 77.68.118.104
+ address 77.68.120.31
+ address 77.68.74.152
+ address 185.132.39.37
+ address 77.68.3.52
+ address 77.68.87.212
+ address 77.68.76.29
+ address 77.68.119.188
+ address 77.68.74.85
+ address 77.68.91.22
+ address 77.68.76.88
+ address 77.68.4.242
+ address 77.68.76.181
+ address 77.68.76.161
+ address 185.132.39.99
+ address 77.68.95.212
+ address 77.68.76.219
+ address 77.68.27.27
+ address 77.68.3.194
+ address 77.68.3.144
+ address 77.68.3.80
+ address 77.68.27.28
+ address 77.68.3.247
+ address 77.68.3.161
+ address 77.68.27.18
+ address 77.68.3.121
+ address 213.171.214.234
+ address 109.228.38.201
+ address 185.132.39.219
+ address 77.68.28.139
+ address 77.68.81.218
+ address 77.68.4.111
+ address 77.68.77.174
+ address 77.68.117.222
+ address 213.171.211.128
+ address 77.68.5.155
+ address 77.68.77.231
+ address 213.171.214.167
+ address 185.132.43.28
+ address 213.171.213.42
+ address 77.68.76.45
+ address 77.68.92.92
+ address 77.68.77.233
+ address 185.132.40.56
+ address 185.132.37.23
+ address 77.68.117.29
+ address 77.68.75.253
+ address 77.68.11.140
+ address 77.68.77.215
+ address 77.68.20.217
+ address 77.68.10.152
+ address 77.68.73.73
+ address 77.68.76.198
+ address 77.68.77.214
+ address 77.68.9.75
+ address 213.171.210.177
+ address 77.68.77.70
+ address 77.68.77.149
+ address 77.68.76.160
+ address 185.132.38.114
+ address 77.68.33.48
+ address 185.132.40.90
+ address 77.68.79.89
+ address 77.68.34.28
+ address 77.68.76.21
+ address 77.68.75.45
+ address 77.68.76.176
+ address 77.68.77.95
+ address 185.132.39.68
+ address 185.132.43.164
+ address 77.68.76.137
+ address 185.132.40.152
+ address 77.68.77.249
+ address 77.68.24.134
+ address 185.132.38.248
+ address 77.68.32.43
+ address 77.68.120.218
+ address 77.68.112.167
+ address 77.68.32.31
+ address 77.68.32.118
+ address 77.68.32.254
+ address 77.68.80.26
+ address 77.68.17.200
+ address 77.68.80.97
+ address 77.68.121.119
+ address 77.68.74.209
+ address 77.68.77.65
+ address 185.132.43.6
+ address 109.228.46.196
+ address 185.132.43.98
+ address 77.68.100.150
+ address 185.132.41.148
+ address 77.68.24.172
+ address 77.68.33.197
+ address 77.68.5.95
+ address 77.68.23.64
+ address 77.68.101.124
+ address 77.68.5.125
+ address 77.68.100.167
+ address 77.68.4.80
+ address 77.68.49.152
+ address 109.228.59.247
+ address 213.171.208.40
+ address 77.68.112.184
+ address 77.68.35.116
+ address 185.132.40.11
+ address 77.68.33.171
+ address 77.68.76.111
+ address 77.68.76.42
+ address 77.68.77.120
+ address 77.68.76.183
+ address 77.68.118.86
+ address 77.68.48.105
+ address 77.68.48.81
+ address 77.68.49.4
+ address 109.228.36.119
+ address 77.68.34.26
+ address 77.68.115.17
+ address 77.68.82.147
+ address 77.68.49.12
+ address 77.68.8.144
+ address 77.68.51.202
+ address 77.68.101.64
+ address 77.68.103.19
+ address 77.68.50.91
+ address 77.68.24.63
+ address 77.68.118.15
+ address 77.68.50.198
+ address 77.68.77.59
+ address 77.68.49.160
+ address 77.68.76.191
+ address 77.68.126.101
+ address 77.68.76.40
+ address 77.68.77.42
+ address 77.68.100.134
+ address 77.68.100.132
+ address 77.68.114.93
+ address 185.132.36.60
+ address 185.132.40.244
+ address 77.68.85.18
+ address 213.171.214.102
+ address 77.68.50.193
+ address 88.208.197.160
+ address 88.208.197.10
+ address 77.68.102.129
+ address 109.228.36.79
+ address 185.132.38.182
+ address 185.132.41.240
+ address 77.68.51.214
+ address 88.208.196.123
+ address 88.208.215.157
+ address 77.68.126.22
+ address 77.68.4.180
+ address 213.171.212.90
+ address 77.68.114.205
+ address 185.132.43.71
+ address 88.208.215.62
+ address 77.68.77.114
+ address 77.68.48.202
+ address 77.68.112.175
+ address 77.68.112.90
+ address 185.132.40.166
+ address 77.68.76.118
+ address 77.68.103.120
+ address 77.68.33.24
+ address 109.228.58.134
+ address 109.228.47.223
+ address 77.68.31.96
+ address 77.68.103.227
+ address 213.171.212.203
+ address 88.208.196.92
+ address 88.208.196.154
+ address 185.132.39.44
+ address 77.68.76.248
+ address 88.208.198.92
+ address 109.228.36.37
+ address 77.68.77.144
+ address 77.68.126.14
+ address 88.208.196.91
+ address 77.68.100.77
+ address 185.132.37.101
+ address 77.68.87.164
+ address 77.68.77.76
+ address 77.68.76.120
+ address 77.68.82.157
+ address 77.68.93.164
+ address 77.68.76.171
+ address 88.208.197.135
+ address 88.208.197.118
+ address 88.208.197.150
+ address 88.208.198.69
+ address 77.68.34.139
+ address 77.68.21.171
+ address 88.208.197.60
+ address 77.68.85.27
+ address 109.228.37.10
+ address 88.208.215.61
+ address 88.208.199.249
+ address 88.208.212.31
+ address 109.228.53.243
+ address 77.68.48.89
+ address 88.208.212.188
+ address 88.208.198.251
+ address 77.68.76.112
+ address 77.68.48.14
+ address 88.208.215.19
+ address 77.68.77.75
+ address 77.68.117.173
+ address 88.208.215.121
+ address 109.228.39.41
+ address 77.68.88.100
+ address 77.68.76.108
+ address 77.68.115.142
+ address 77.68.33.216
+ address 77.68.33.37
+ address 77.68.50.90
+ address 213.171.214.96
+ address 88.208.198.66
+ address 88.208.198.64
+ address 77.68.3.61
+ address 77.68.77.219
+ address 77.68.77.204
+ address 77.68.26.228
+ address 77.68.74.232
+ address 77.68.118.88
+ address 77.68.77.46
+ address 77.68.76.48
+ address 77.68.76.202
+ address 77.68.4.25
+ address 77.68.7.114
+ address 88.208.197.23
+ address 77.68.114.237
+ address 77.68.77.222
+ address 77.68.112.83
+ address 77.68.117.214
+ address 88.208.199.141
+ address 77.68.77.163
+ address 185.132.39.109
+ address 77.68.77.44
+ address 185.132.37.47
+ address 77.68.102.5
+ address 77.68.16.247
+ address 88.208.212.94
+ address 77.68.72.254
+ address 77.68.76.212
+ address 77.68.77.152
+ address 77.68.50.142
+ address 88.208.199.46
+ address 77.68.78.113
+ address 88.208.212.182
+ address 77.68.77.181
+ address 77.68.15.95
+ address 77.68.75.64
+ address 213.171.212.71
+ address 185.132.40.124
+ address 88.208.197.208
+ address 88.208.197.129
+ address 77.68.76.60
+ address 77.68.6.119
+ address 77.68.77.185
+ address 77.68.77.238
+ address 77.68.27.57
+ address 77.68.118.102
+ address 77.68.79.82
+ address 109.228.39.151
+ }
+ address-group G-465-TCP {
+ address 172.16.255.254
+ address 77.68.76.115
+ address 77.68.76.141
+ address 77.68.76.187
+ address 77.68.76.197
+ address 77.68.76.209
+ address 77.68.76.99
+ address 77.68.77.107
+ address 77.68.77.129
+ address 77.68.77.130
+ address 77.68.77.141
+ address 77.68.77.150
+ address 77.68.77.171
+ address 77.68.77.176
+ address 77.68.77.190
+ address 77.68.77.207
+ address 77.68.77.22
+ address 77.68.77.32
+ address 77.68.77.33
+ address 77.68.77.63
+ address 77.68.77.92
+ address 77.68.77.99
+ address 77.68.77.77
+ address 77.68.77.192
+ address 77.68.84.147
+ address 77.68.4.74
+ address 77.68.6.202
+ address 77.68.77.74
+ address 77.68.77.100
+ address 77.68.116.221
+ address 109.228.60.215
+ address 77.68.116.52
+ address 77.68.7.172
+ address 77.68.95.42
+ address 77.68.91.128
+ address 77.68.24.112
+ address 109.228.37.114
+ address 77.68.112.75
+ address 77.68.7.67
+ address 77.68.113.117
+ address 77.68.126.51
+ address 77.68.23.35
+ address 77.68.10.170
+ address 77.68.76.234
+ address 213.171.213.31
+ address 77.68.78.229
+ address 213.171.210.19
+ address 109.228.52.186
+ address 77.68.77.69
+ address 109.228.40.222
+ address 77.68.87.212
+ address 77.68.28.139
+ address 77.68.4.111
+ address 77.68.77.174
+ address 77.68.117.222
+ address 185.132.43.28
+ address 77.68.77.214
+ address 185.132.38.114
+ address 77.68.33.48
+ address 77.68.79.89
+ address 77.68.76.21
+ address 77.68.80.26
+ address 77.68.5.95
+ address 77.68.100.167
+ address 77.68.4.80
+ address 77.68.49.152
+ address 77.68.112.184
+ address 77.68.115.17
+ address 77.68.82.147
+ address 77.68.50.193
+ address 88.208.215.61
+ address 213.171.214.96
+ address 88.208.198.66
+ address 77.68.77.204
+ address 77.68.123.177
+ address 77.68.77.222
+ address 77.68.112.83
+ address 77.68.77.185
+ address 77.68.79.82
+ }
+ address-group G-587-TCP {
+ address 172.16.255.254
+ address 77.68.76.141
+ address 77.68.76.187
+ address 77.68.76.197
+ address 77.68.76.209
+ address 77.68.77.128
+ address 77.68.77.129
+ address 77.68.77.141
+ address 77.68.77.171
+ address 77.68.77.190
+ address 77.68.77.207
+ address 77.68.77.32
+ address 77.68.77.33
+ address 77.68.77.63
+ address 77.68.77.85
+ address 77.68.77.92
+ address 77.68.77.99
+ address 77.68.77.77
+ address 77.68.4.74
+ address 77.68.6.202
+ address 77.68.81.44
+ address 77.68.77.100
+ address 77.68.92.186
+ address 77.68.116.119
+ address 77.68.116.221
+ address 77.68.120.241
+ address 109.228.60.215
+ address 77.68.122.241
+ address 77.68.116.52
+ address 77.68.91.128
+ address 77.68.24.112
+ address 77.68.77.107
+ address 109.228.37.114
+ address 77.68.112.75
+ address 77.68.77.160
+ address 77.68.113.117
+ address 77.68.126.51
+ address 77.68.23.35
+ address 77.68.76.95
+ address 77.68.10.170
+ address 77.68.76.234
+ address 213.171.213.41
+ address 213.171.213.31
+ address 77.68.78.229
+ address 213.171.210.19
+ address 109.228.52.186
+ address 109.228.40.222
+ address 77.68.87.212
+ address 185.132.39.219
+ address 77.68.28.139
+ address 77.68.4.111
+ address 77.68.77.174
+ address 77.68.117.222
+ address 185.132.43.28
+ address 77.68.77.215
+ address 77.68.77.214
+ address 185.132.38.114
+ address 77.68.33.48
+ address 77.68.76.21
+ address 77.68.100.167
+ address 77.68.4.80
+ address 77.68.49.152
+ address 77.68.112.184
+ address 77.68.115.17
+ address 77.68.82.147
+ address 77.68.76.191
+ address 77.68.50.193
+ address 77.68.77.114
+ address 88.208.215.61
+ address 77.68.76.112
+ address 77.68.33.216
+ address 77.68.33.37
+ address 77.68.50.90
+ address 88.208.198.66
+ address 77.68.77.219
+ address 77.68.123.177
+ address 77.68.77.222
+ address 77.68.112.83
+ address 77.68.77.152
+ address 77.68.79.82
+ }
+ address-group G-993-TCP {
+ address 172.16.255.254
+ address 77.68.76.115
+ address 77.68.77.129
+ address 77.68.77.130
+ address 77.68.77.141
+ address 77.68.77.150
+ address 77.68.77.171
+ address 77.68.77.176
+ address 77.68.77.190
+ address 77.68.77.207
+ address 77.68.77.22
+ address 77.68.77.33
+ address 77.68.77.49
+ address 77.68.77.56
+ address 77.68.77.77
+ address 77.68.77.192
+ address 77.68.84.147
+ address 77.68.4.74
+ address 77.68.6.202
+ address 77.68.81.44
+ address 77.68.77.74
+ address 77.68.77.100
+ address 77.68.92.186
+ address 77.68.116.119
+ address 77.68.116.221
+ address 77.68.120.241
+ address 77.68.7.172
+ address 77.68.91.128
+ address 77.68.23.112
+ address 77.68.24.112
+ address 77.68.77.107
+ address 109.228.37.114
+ address 77.68.112.75
+ address 77.68.7.67
+ address 77.68.113.117
+ address 77.68.126.51
+ address 77.68.86.148
+ address 77.68.23.35
+ address 77.68.76.95
+ address 213.171.215.184
+ address 77.68.25.146
+ address 213.171.213.31
+ address 213.171.210.19
+ address 77.68.79.206
+ address 77.68.123.250
+ address 77.68.77.69
+ address 109.228.40.222
+ address 77.68.87.212
+ address 77.68.91.22
+ address 185.132.39.99
+ address 77.68.28.139
+ address 77.68.4.111
+ address 77.68.77.174
+ address 77.68.117.222
+ address 77.68.5.155
+ address 185.132.43.28
+ address 77.68.77.215
+ address 77.68.10.152
+ address 77.68.73.73
+ address 77.68.77.214
+ address 185.132.38.114
+ address 77.68.33.48
+ address 77.68.79.89
+ address 77.68.5.95
+ address 77.68.4.80
+ address 77.68.49.152
+ address 213.171.208.40
+ address 77.68.115.17
+ address 77.68.103.19
+ address 185.132.36.60
+ address 185.132.40.244
+ address 88.208.197.10
+ address 77.68.102.129
+ address 88.208.215.157
+ address 88.208.198.69
+ address 88.208.212.188
+ address 213.171.214.96
+ address 88.208.198.66
+ address 77.68.77.204
+ address 77.68.74.232
+ address 77.68.4.25
+ address 77.68.7.114
+ address 77.68.123.177
+ address 77.68.77.222
+ address 77.68.112.83
+ address 77.68.79.82
+ }
+ address-group G-995-TCP {
+ address 172.16.255.254
+ address 77.68.76.115
+ address 77.68.77.129
+ address 77.68.77.171
+ address 77.68.77.176
+ address 77.68.77.190
+ address 77.68.77.22
+ address 77.68.77.33
+ address 77.68.77.92
+ address 77.68.77.77
+ address 77.68.84.147
+ address 77.68.4.74
+ address 77.68.6.202
+ address 77.68.77.74
+ address 77.68.77.100
+ address 77.68.116.221
+ address 77.68.120.241
+ address 77.68.7.172
+ address 77.68.95.42
+ address 77.68.91.128
+ address 77.68.23.112
+ address 77.68.24.112
+ address 77.68.77.107
+ address 109.228.37.114
+ address 77.68.7.67
+ address 77.68.126.51
+ address 77.68.79.206
+ address 77.68.123.250
+ address 109.228.52.186
+ address 109.228.40.222
+ address 77.68.91.22
+ address 77.68.4.111
+ address 77.68.77.174
+ address 77.68.5.155
+ address 185.132.43.28
+ address 77.68.77.214
+ address 185.132.38.114
+ address 77.68.79.89
+ address 77.68.80.26
+ address 77.68.4.80
+ address 77.68.49.152
+ address 77.68.103.19
+ address 77.68.50.193
+ address 88.208.197.10
+ address 213.171.214.96
+ address 88.208.198.66
+ address 77.68.74.232
+ address 77.68.4.25
+ address 77.68.7.114
+ address 77.68.77.185
+ }
+ address-group G-1433-TCP {
+ address 172.16.255.254
+ address 77.68.76.94
+ address 77.68.30.164
+ address 77.68.10.142
+ address 77.68.77.95
+ address 77.68.126.101
+ address 77.68.76.118
+ address 77.68.77.75
+ }
+ address-group G-3306-TCP {
+ address 172.16.255.254
+ address 77.68.76.127
+ address 77.68.76.187
+ address 77.68.76.252
+ address 77.68.76.55
+ address 77.68.76.80
+ address 77.68.77.21
+ address 77.68.77.63
+ address 77.68.77.81
+ address 77.68.77.85
+ address 77.68.77.92
+ address 77.68.76.241
+ address 109.228.56.185
+ address 77.68.28.145
+ address 77.68.76.114
+ address 77.68.17.26
+ address 77.68.120.241
+ address 77.68.6.32
+ address 77.68.91.128
+ address 109.228.37.114
+ address 77.68.76.169
+ address 77.68.76.77
+ address 77.68.113.117
+ address 77.68.86.148
+ address 77.68.76.234
+ address 77.68.76.59
+ address 77.68.77.202
+ address 77.68.28.147
+ address 109.228.52.186
+ address 77.68.117.222
+ address 213.171.213.42
+ address 77.68.75.253
+ address 77.68.77.215
+ address 77.68.79.89
+ address 77.68.118.15
+ address 109.228.36.79
+ address 77.68.33.216
+ address 77.68.33.37
+ address 77.68.50.90
+ address 77.68.76.48
+ address 77.68.77.222
+ address 77.68.112.83
+ address 77.68.77.44
+ address 88.208.212.94
+ }
+ address-group G-3389-TCP {
+ address 172.16.255.254
+ address 77.68.76.116
+ address 77.68.76.150
+ address 77.68.76.203
+ address 77.68.76.220
+ address 77.68.76.23
+ address 77.68.76.241
+ address 77.68.76.35
+ address 77.68.76.39
+ address 77.68.76.47
+ address 77.68.76.49
+ address 77.68.76.50
+ address 77.68.76.58
+ address 77.68.76.75
+ address 77.68.76.91
+ address 77.68.76.93
+ address 77.68.76.94
+ address 77.68.76.99
+ address 77.68.77.115
+ address 77.68.77.156
+ address 77.68.77.178
+ address 77.68.77.199
+ address 77.68.77.236
+ address 77.68.77.63
+ address 77.68.77.71
+ address 77.68.77.97
+ address 77.68.77.99
+ address 77.68.76.107
+ address 77.68.76.26
+ address 77.68.76.92
+ address 77.68.77.38
+ address 77.68.21.78
+ address 77.68.94.181
+ address 77.68.30.164
+ address 77.68.23.158
+ address 77.68.27.54
+ address 77.68.76.142
+ address 77.68.117.202
+ address 77.68.116.220
+ address 77.68.84.155
+ address 77.68.120.146
+ address 77.68.119.92
+ address 77.68.10.142
+ address 77.68.6.105
+ address 77.68.4.252
+ address 77.68.127.151
+ address 77.68.77.228
+ address 109.228.40.207
+ address 77.68.77.24
+ address 109.228.35.110
+ address 77.68.76.152
+ address 77.68.76.77
+ address 77.68.113.117
+ address 77.68.6.110
+ address 77.68.76.96
+ address 77.68.127.172
+ address 185.132.37.83
+ address 77.68.25.124
+ address 77.68.3.52
+ address 77.68.114.234
+ address 77.68.85.73
+ address 109.228.38.201
+ address 77.68.26.221
+ address 77.68.10.152
+ address 77.68.73.73
+ address 77.68.76.198
+ address 77.68.9.75
+ address 77.68.79.89
+ address 77.68.77.95
+ address 77.68.77.65
+ address 77.68.100.150
+ address 77.68.101.125
+ address 77.68.101.124
+ address 213.171.208.40
+ address 77.68.12.45
+ address 77.68.118.86
+ address 77.68.77.59
+ address 77.68.126.101
+ address 213.171.214.102
+ address 88.208.197.160
+ address 88.208.215.157
+ address 77.68.4.180
+ address 185.132.43.71
+ address 77.68.31.96
+ address 109.228.36.37
+ address 77.68.77.76
+ address 77.68.82.157
+ address 109.228.37.10
+ address 77.68.77.75
+ address 77.68.117.173
+ address 88.208.215.121
+ address 77.68.115.142
+ address 77.68.33.216
+ address 77.68.33.37
+ address 77.68.50.90
+ address 88.208.198.64
+ address 77.68.118.88
+ address 77.68.114.237
+ address 77.68.50.142
+ address 77.68.15.95
+ address 77.68.75.64
+ address 77.68.77.238
+ }
+ address-group G-8080-TCP {
+ address 172.16.255.254
+ address 77.68.76.57
+ address 77.68.76.243
+ address 77.68.28.145
+ address 77.68.76.114
+ address 77.68.76.157
+ address 77.68.77.248
+ address 77.68.77.202
+ address 77.68.24.59
+ address 77.68.81.218
+ address 77.68.77.105
+ address 185.132.40.152
+ address 109.228.36.119
+ address 77.68.121.127
+ address 77.68.116.183
+ address 77.68.34.139
+ address 77.68.88.100
+ address 77.68.77.222
+ address 77.68.112.83
+ address 77.68.77.163
+ address 88.208.212.94
+ address 77.68.78.113
+ address 77.68.15.95
+ address 213.171.212.71
+ }
+ address-group G-8443-TCP {
+ address 172.16.255.254
+ address 77.68.76.104
+ address 77.68.76.105
+ address 77.68.76.127
+ address 77.68.76.136
+ address 77.68.76.141
+ address 77.68.76.148
+ address 77.68.76.150
+ address 77.68.76.158
+ address 77.68.76.187
+ address 77.68.76.195
+ address 77.68.76.197
+ address 77.68.76.20
+ address 77.68.76.200
+ address 77.68.76.209
+ address 77.68.76.217
+ address 77.68.76.22
+ address 77.68.76.231
+ address 77.68.76.235
+ address 77.68.76.239
+ address 77.68.76.245
+ address 77.68.76.247
+ address 77.68.76.249
+ address 77.68.76.25
+ address 77.68.76.251
+ address 77.68.76.252
+ address 77.68.76.33
+ address 77.68.76.37
+ address 77.68.76.57
+ address 77.68.76.61
+ address 77.68.76.74
+ address 77.68.76.80
+ address 77.68.76.93
+ address 77.68.77.100
+ address 77.68.77.103
+ address 77.68.77.107
+ address 77.68.77.108
+ address 77.68.77.115
+ address 77.68.77.117
+ address 77.68.77.128
+ address 77.68.77.130
+ address 77.68.77.137
+ address 77.68.77.139
+ address 77.68.77.140
+ address 77.68.77.141
+ address 77.68.77.151
+ address 77.68.77.159
+ address 77.68.77.176
+ address 77.68.77.190
+ address 77.68.77.200
+ address 77.68.77.201
+ address 77.68.77.207
+ address 77.68.77.211
+ address 77.68.77.22
+ address 77.68.77.227
+ address 77.68.77.240
+ address 77.68.77.247
+ address 77.68.77.253
+ address 77.68.77.32
+ address 77.68.77.37
+ address 77.68.77.49
+ address 77.68.77.50
+ address 77.68.77.56
+ address 77.68.77.68
+ address 77.68.77.81
+ address 77.68.77.85
+ address 77.68.77.88
+ address 77.68.77.92
+ address 77.68.77.99
+ address 77.68.76.211
+ address 77.68.76.19
+ address 77.68.77.192
+ address 77.68.77.254
+ address 77.68.77.157
+ address 77.68.76.138
+ address 77.68.76.139
+ address 77.68.76.243
+ address 77.68.77.38
+ address 77.68.77.62
+ address 77.68.91.195
+ address 77.68.17.26
+ address 77.68.84.147
+ address 109.228.56.185
+ address 77.68.5.187
+ address 77.68.4.24
+ address 77.68.4.74
+ address 77.68.6.202
+ address 77.68.5.241
+ address 77.68.77.74
+ address 77.68.76.115
+ address 77.68.81.44
+ address 77.68.90.106
+ address 77.68.94.181
+ address 77.68.30.133
+ address 77.68.4.136
+ address 77.68.28.145
+ address 77.68.24.112
+ address 77.68.92.186
+ address 77.68.26.216
+ address 77.68.20.231
+ address 77.68.118.17
+ address 77.68.116.119
+ address 77.68.76.142
+ address 77.68.7.172
+ address 77.68.116.221
+ address 77.68.89.183
+ address 77.68.83.41
+ address 77.68.86.40
+ address 77.68.88.164
+ address 109.228.56.26
+ address 77.68.7.123
+ address 77.68.116.220
+ address 109.228.60.215
+ address 77.68.7.186
+ address 77.68.93.246
+ address 77.68.120.241
+ address 77.68.122.195
+ address 77.68.122.89
+ address 77.68.81.141
+ address 77.68.116.52
+ address 77.68.6.105
+ address 77.68.76.229
+ address 77.68.4.252
+ address 77.68.17.186
+ address 77.68.91.128
+ address 77.68.22.146
+ address 77.68.125.32
+ address 109.228.36.229
+ address 77.68.31.144
+ address 77.68.117.142
+ address 109.228.37.174
+ address 109.228.37.114
+ address 77.68.76.169
+ address 77.68.112.75
+ address 77.68.77.160
+ address 109.228.39.249
+ address 77.68.7.67
+ address 77.68.113.117
+ address 77.68.126.51
+ address 77.68.86.148
+ address 77.68.114.183
+ address 109.228.40.194
+ address 77.68.90.132
+ address 77.68.77.26
+ address 77.68.76.96
+ address 77.68.77.30
+ address 77.68.76.95
+ address 77.68.10.170
+ address 77.68.120.26
+ address 109.228.61.31
+ address 77.68.76.59
+ address 77.68.120.249
+ address 213.171.213.41
+ address 77.68.119.14
+ address 213.171.215.184
+ address 77.68.77.202
+ address 77.68.25.146
+ address 213.171.213.31
+ address 77.68.77.102
+ address 213.171.210.19
+ address 213.171.213.97
+ address 109.228.48.249
+ address 109.228.40.195
+ address 77.68.127.172
+ address 77.68.79.206
+ address 109.228.56.242
+ address 109.228.46.81
+ address 185.132.38.95
+ address 77.68.116.36
+ address 77.68.120.45
+ address 185.132.37.102
+ address 77.68.13.137
+ address 109.228.36.194
+ address 185.132.36.7
+ address 185.132.36.24
+ address 77.68.77.69
+ address 185.132.39.129
+ address 77.68.87.212
+ address 77.68.76.29
+ address 77.68.76.88
+ address 77.68.76.181
+ address 77.68.76.161
+ address 77.68.85.73
+ address 77.68.76.219
+ address 109.228.38.201
+ address 185.132.39.219
+ address 77.68.28.139
+ address 77.68.81.218
+ address 77.68.4.111
+ address 77.68.77.174
+ address 77.68.117.222
+ address 77.68.76.45
+ address 185.132.40.56
+ address 77.68.75.253
+ address 77.68.10.152
+ address 77.68.73.73
+ address 77.68.77.214
+ address 185.132.38.114
+ address 185.132.40.90
+ address 77.68.79.89
+ address 77.68.76.21
+ address 77.68.75.45
+ address 77.68.24.134
+ address 77.68.32.43
+ address 77.68.80.26
+ address 77.68.17.200
+ address 77.68.80.97
+ address 77.68.74.209
+ address 77.68.77.65
+ address 77.68.33.197
+ address 77.68.5.95
+ address 77.68.23.64
+ address 77.68.5.125
+ address 77.68.100.167
+ address 77.68.4.80
+ address 77.68.49.152
+ address 77.68.48.105
+ address 77.68.48.81
+ address 77.68.49.12
+ address 213.171.212.89
+ address 77.68.76.44
+ address 77.68.77.239
+ address 77.68.77.59
+ address 77.68.126.101
+ address 77.68.76.40
+ address 77.68.114.93
+ address 77.68.50.193
+ address 88.208.197.160
+ address 109.228.36.79
+ address 185.132.38.182
+ address 88.208.196.123
+ address 88.208.215.157
+ address 77.68.76.118
+ address 77.68.103.227
+ address 88.208.196.92
+ address 185.132.39.44
+ address 88.208.198.92
+ address 77.68.126.14
+ address 88.208.196.91
+ address 77.68.100.77
+ address 185.132.37.101
+ address 77.68.76.120
+ address 213.171.212.114
+ address 77.68.34.139
+ address 88.208.215.61
+ address 88.208.212.31
+ address 109.228.53.243
+ address 77.68.103.56
+ address 213.171.214.96
+ address 88.208.198.66
+ address 77.68.77.219
+ address 77.68.4.25
+ address 77.68.7.114
+ address 77.68.77.222
+ address 77.68.112.83
+ address 77.68.77.44
+ address 77.68.72.254
+ address 77.68.78.113
+ address 213.171.212.71
+ address 185.132.40.124
+ address 88.208.197.208
+ address 77.68.77.238
+ address 77.68.79.82
+ }
+ address-group G-8447-TCP {
+ address 172.16.255.254
+ address 77.68.76.104
+ address 77.68.76.105
+ address 77.68.76.127
+ address 77.68.76.136
+ address 77.68.76.141
+ address 77.68.76.148
+ address 77.68.76.150
+ address 77.68.76.158
+ address 77.68.76.187
+ address 77.68.76.195
+ address 77.68.76.197
+ address 77.68.76.20
+ address 77.68.76.209
+ address 77.68.76.22
+ address 77.68.76.231
+ address 77.68.76.235
+ address 77.68.76.239
+ address 77.68.76.245
+ address 77.68.76.25
+ address 77.68.76.252
+ address 77.68.76.33
+ address 77.68.76.37
+ address 77.68.76.57
+ address 77.68.76.61
+ address 77.68.76.74
+ address 77.68.76.93
+ address 77.68.77.100
+ address 77.68.77.103
+ address 77.68.77.107
+ address 77.68.77.108
+ address 77.68.77.117
+ address 77.68.77.128
+ address 77.68.77.130
+ address 77.68.77.137
+ address 77.68.77.139
+ address 77.68.77.141
+ address 77.68.77.151
+ address 77.68.77.159
+ address 77.68.77.176
+ address 77.68.77.190
+ address 77.68.77.200
+ address 77.68.77.201
+ address 77.68.77.207
+ address 77.68.77.211
+ address 77.68.77.22
+ address 77.68.77.227
+ address 77.68.77.240
+ address 77.68.77.247
+ address 77.68.77.253
+ address 77.68.77.32
+ address 77.68.77.37
+ address 77.68.77.49
+ address 77.68.77.50
+ address 77.68.77.56
+ address 77.68.77.68
+ address 77.68.77.81
+ address 77.68.77.85
+ address 77.68.77.88
+ address 77.68.77.92
+ address 77.68.77.99
+ address 77.68.76.211
+ address 77.68.76.19
+ address 77.68.77.192
+ address 77.68.77.254
+ address 77.68.77.157
+ address 77.68.76.138
+ address 77.68.76.139
+ address 77.68.91.195
+ address 77.68.17.26
+ address 109.228.56.185
+ address 77.68.84.147
+ address 77.68.5.187
+ address 77.68.4.24
+ address 77.68.4.74
+ address 77.68.6.202
+ address 77.68.5.241
+ address 77.68.77.74
+ address 77.68.81.44
+ address 77.68.90.106
+ address 77.68.94.181
+ address 77.68.4.136
+ address 77.68.28.145
+ address 77.68.24.112
+ address 77.68.92.186
+ address 77.68.26.216
+ address 77.68.20.231
+ address 77.68.118.17
+ address 77.68.116.119
+ address 77.68.76.142
+ address 77.68.7.172
+ address 77.68.83.41
+ address 77.68.116.221
+ address 77.68.86.40
+ address 77.68.88.164
+ address 109.228.56.26
+ address 77.68.7.123
+ address 77.68.116.220
+ address 109.228.60.215
+ address 77.68.7.186
+ address 77.68.93.246
+ address 77.68.120.241
+ address 77.68.122.195
+ address 77.68.122.89
+ address 77.68.81.141
+ address 77.68.116.52
+ address 77.68.6.105
+ address 77.68.76.229
+ address 77.68.4.252
+ address 77.68.17.186
+ address 77.68.91.128
+ address 77.68.22.146
+ address 77.68.125.32
+ address 109.228.36.229
+ address 77.68.31.144
+ address 77.68.117.142
+ address 109.228.37.174
+ address 109.228.37.114
+ address 77.68.112.75
+ address 77.68.77.160
+ address 109.228.39.249
+ address 77.68.7.67
+ address 77.68.113.117
+ address 77.68.126.51
+ address 77.68.86.148
+ address 77.68.114.183
+ address 109.228.40.194
+ address 77.68.90.132
+ address 77.68.76.96
+ address 77.68.77.30
+ address 77.68.76.95
+ address 77.68.10.170
+ address 109.228.61.31
+ address 77.68.76.59
+ address 77.68.120.249
+ address 213.171.213.41
+ address 213.171.215.184
+ address 77.68.25.146
+ address 213.171.213.31
+ address 77.68.77.102
+ address 213.171.210.19
+ address 213.171.213.97
+ address 109.228.48.249
+ address 77.68.127.172
+ address 77.68.79.206
+ address 109.228.56.242
+ address 109.228.46.81
+ address 185.132.38.95
+ address 77.68.116.36
+ address 109.228.36.194
+ address 185.132.36.7
+ address 185.132.36.24
+ address 77.68.77.69
+ address 185.132.39.129
+ address 77.68.87.212
+ address 77.68.76.88
+ address 77.68.76.181
+ address 77.68.76.219
+ address 185.132.39.219
+ address 77.68.28.139
+ address 77.68.4.111
+ address 77.68.77.174
+ address 77.68.117.222
+ address 77.68.77.231
+ address 77.68.76.45
+ address 185.132.40.56
+ address 77.68.10.152
+ address 77.68.73.73
+ address 77.68.77.214
+ address 185.132.38.114
+ address 185.132.40.90
+ address 77.68.79.89
+ address 77.68.76.21
+ address 77.68.75.45
+ address 77.68.24.134
+ address 77.68.32.43
+ address 77.68.80.26
+ address 77.68.17.200
+ address 77.68.80.97
+ address 77.68.74.209
+ address 77.68.33.197
+ address 77.68.5.95
+ address 77.68.5.125
+ address 77.68.100.167
+ address 77.68.4.80
+ address 77.68.49.152
+ address 77.68.48.105
+ address 77.68.48.81
+ address 77.68.49.12
+ address 213.171.212.89
+ address 77.68.76.44
+ address 77.68.77.239
+ address 77.68.77.59
+ address 77.68.126.101
+ address 77.68.114.93
+ address 77.68.50.193
+ address 88.208.197.160
+ address 109.228.36.79
+ address 185.132.38.182
+ address 88.208.196.123
+ address 88.208.215.157
+ address 77.68.76.118
+ address 77.68.103.227
+ address 88.208.196.92
+ address 185.132.39.44
+ address 88.208.198.92
+ address 77.68.126.14
+ address 88.208.196.91
+ address 77.68.100.77
+ address 185.132.37.101
+ address 77.68.76.120
+ address 213.171.212.114
+ address 77.68.34.139
+ address 88.208.215.61
+ address 88.208.212.31
+ address 109.228.53.243
+ address 77.68.103.56
+ address 213.171.214.96
+ address 88.208.198.66
+ address 77.68.77.219
+ address 77.68.77.204
+ address 77.68.76.48
+ address 77.68.4.25
+ address 77.68.7.114
+ address 77.68.77.222
+ address 77.68.112.83
+ address 77.68.72.254
+ address 77.68.78.113
+ address 213.171.212.71
+ address 185.132.40.124
+ address 88.208.197.208
+ address 77.68.79.82
+ }
+ address-group G-10000-TCP {
+ address 172.16.255.254
+ address 77.68.76.177
+ address 77.68.76.54
+ address 77.68.30.133
+ address 77.68.76.114
+ address 77.68.11.140
+ address 77.68.76.112
+ address 77.68.78.113
+ }
+ address-group LAN_ADDRESSES {
+ address 10.255.255.2
+ address 10.255.255.3
+ }
+ address-group MANAGEMENT_ADDRESSES {
+ address 82.223.200.175
+ address 82.223.200.177
+ }
+ address-group NAGIOS_PROBES {
+ address 77.68.76.16
+ address 77.68.77.16
+ }
+ address-group NAS_ARRAYS {
+ address 10.7.197.251
+ address 10.7.197.252
+ address 10.7.197.253
+ address 10.7.197.254
+ }
+ address-group NAS_DOMAIN_CONTROLLERS {
+ address 10.7.197.16
+ address 10.7.197.17
+ }
+ address-group NLB_ADDRESSES {
+ address 109.228.63.15
+ address 109.228.63.16
+ address 109.228.63.132
+ address 109.228.63.133
+ }
+ network-group NAS_NETWORKS {
+ network 10.7.197.0/24
+ }
+ network-group RFC1918 {
+ network 10.0.0.0/8
+ network 172.16.0.0/12
+ network 192.168.0.0/16
+ }
+ network-group TRANSFER_NETS {
+ network 109.228.63.128/25
+ }
+ }
+ ipv6-receive-redirects disable
+ ipv6-src-route disable
+ ip-src-route disable
+ log-martians enable
+ name LAN-INBOUND {
+ default-action drop
+ rule 10 {
+ action drop
+ description "Anti-spoofing non-cluster addresses"
+ source {
+ group {
+ address-group !CLUSTER_ADDRESSES
+ }
+ }
+ }
+ rule 20 {
+ action drop
+ description "Drop traffic to datacenter transfer net"
+ destination {
+ group {
+ network-group TRANSFER_NETS
+ }
+ }
+ source {
+ group {
+ address-group CLUSTER_ADDRESSES
+ }
+ }
+ }
+ rule 400 {
+ action drop
+ description Anti-spoofing_10.255.255.2
+ source {
+ address 10.255.255.2
+ mac-address !00:50:56:af:61:20
+ }
+ }
+ rule 401 {
+ action drop
+ description Anti-spoofing_77.68.126.51
+ source {
+ address 77.68.126.51
+ mac-address !00:50:56:03:df:06
+ }
+ }
+ rule 402 {
+ action drop
+ description Anti-spoofing_109.228.36.37
+ source {
+ address 109.228.36.37
+ mac-address !00:50:56:38:c4:2c
+ }
+ }
+ rule 403 {
+ action drop
+ description Anti-spoofing_77.68.117.214
+ source {
+ address 77.68.117.214
+ mac-address !00:50:56:00:28:c3
+ }
+ }
+ rule 404 {
+ action drop
+ description Anti-spoofing_77.68.127.172
+ source {
+ address 77.68.127.172
+ mac-address !00:50:56:08:ce:ec
+ }
+ }
+ rule 405 {
+ action drop
+ description Anti-spoofing_77.68.117.142
+ source {
+ address 77.68.117.142
+ mac-address !00:50:56:1a:02:40
+ }
+ }
+ rule 406 {
+ action drop
+ description Anti-spoofing_77.68.14.88
+ source {
+ address 77.68.14.88
+ mac-address !00:50:56:3c:79:85
+ }
+ }
+ rule 407 {
+ action drop
+ description Anti-spoofing_77.68.17.200
+ source {
+ address 77.68.17.200
+ mac-address !00:50:56:0c:1b:57
+ }
+ }
+ rule 408 {
+ action drop
+ description Anti-spoofing_77.68.120.229
+ source {
+ address 77.68.120.229
+ mac-address !00:50:56:18:af:65
+ }
+ }
+ rule 410 {
+ action drop
+ description Anti-spoofing_10.255.255.3
+ source {
+ address 10.255.255.3
+ mac-address !00:50:56:af:cd:42
+ }
+ }
+ rule 411 {
+ action drop
+ description Anti-spoofing_77.68.4.242
+ source {
+ address 77.68.4.242
+ mac-address !00:50:56:25:d9:34
+ }
+ }
+ rule 412 {
+ action drop
+ description Anti-spoofing_77.68.113.117
+ source {
+ address 77.68.113.117
+ mac-address !00:50:56:36:ea:1d
+ }
+ }
+ rule 413 {
+ action drop
+ description Anti-spoofing_213.171.213.242
+ source {
+ address 213.171.213.242
+ mac-address !00:50:56:29:dd:5c
+ }
+ }
+ rule 414 {
+ action drop
+ description Anti-spoofing_77.68.86.148
+ source {
+ address 77.68.86.148
+ mac-address !00:50:56:01:91:19
+ }
+ }
+ rule 418 {
+ action drop
+ description Anti-spoofing_213.171.212.203
+ source {
+ address 213.171.212.203
+ mac-address !00:50:56:01:c3:39
+ }
+ }
+ rule 419 {
+ action drop
+ description Anti-spoofing_77.68.114.234
+ source {
+ address 77.68.114.234
+ mac-address !00:50:56:1b:72:cd
+ }
+ }
+ rule 420 {
+ action drop
+ description Anti-spoofing_10.255.255.4
+ source {
+ address 10.255.255.4
+ mac-address !00:50:56:af:09:7d
+ }
+ }
+ rule 421 {
+ action drop
+ description Anti-spoofing_213.171.212.171
+ source {
+ address 213.171.212.171
+ mac-address !00:50:56:12:54:58
+ }
+ }
+ rule 422 {
+ action drop
+ description Anti-spoofing_77.68.114.183
+ source {
+ address 77.68.114.183
+ mac-address !00:50:56:3d:9b:eb
+ }
+ }
+ rule 423 {
+ action drop
+ description Anti-spoofing_213.171.213.41
+ source {
+ address 213.171.213.41
+ mac-address !00:50:56:2a:ef:a2
+ }
+ }
+ rule 424 {
+ action drop
+ description Anti-spoofing_77.68.90.132
+ source {
+ address 77.68.90.132
+ mac-address !00:50:56:28:04:1e
+ }
+ }
+ rule 425 {
+ action drop
+ description Anti-spoofing_10.255.255.5
+ source {
+ address 10.255.255.5
+ mac-address !00:50:56:af:3b:bb
+ }
+ }
+ rule 426 {
+ action drop
+ description Anti-spoofing_213.171.213.175
+ source {
+ address 213.171.213.175
+ mac-address !00:50:56:0d:d4:b1
+ }
+ }
+ rule 427 {
+ action drop
+ description Anti-spoofing_109.228.39.151
+ source {
+ address 109.228.39.151
+ mac-address !00:50:56:39:67:8d
+ }
+ }
+ rule 428 {
+ action drop
+ description Anti-spoofing_77.68.112.167
+ source {
+ address 77.68.112.167
+ mac-address !00:50:56:32:24:c9
+ }
+ }
+ rule 429 {
+ action drop
+ description Anti-spoofing_109.228.40.194
+ source {
+ address 109.228.40.194
+ mac-address !00:50:56:19:49:71
+ }
+ }
+ rule 430 {
+ action drop
+ description Anti-spoofing_77.68.76.12
+ source {
+ address 77.68.76.12
+ mac-address !00:50:56:af:09:7d
+ }
+ }
+ rule 431 {
+ action drop
+ description Anti-spoofing_213.171.213.97
+ source {
+ address 213.171.213.97
+ mac-address !00:50:56:15:d9:89
+ }
+ }
+ rule 432 {
+ action drop
+ description Anti-spoofing_77.68.16.247
+ source {
+ address 77.68.16.247
+ mac-address !00:50:56:01:49:07
+ }
+ }
+ rule 433 {
+ action drop
+ description Anti-spoofing_77.68.33.48
+ source {
+ address 77.68.33.48
+ mac-address !00:50:56:11:0e:07
+ }
+ }
+ rule 434 {
+ action drop
+ description Anti-spoofing_77.68.6.110
+ source {
+ address 77.68.6.110
+ mac-address !00:50:56:31:76:8a
+ }
+ }
+ rule 435 {
+ action drop
+ description Anti-spoofing_77.68.77.12
+ source {
+ address 77.68.77.12
+ mac-address !00:50:56:af:3b:bb
+ }
+ }
+ rule 436 {
+ action drop
+ description Anti-spoofing_213.171.215.252
+ source {
+ address 213.171.215.252
+ mac-address !00:50:56:11:88:0a
+ }
+ }
+ rule 437 {
+ action drop
+ description Anti-spoofing_88.208.197.208
+ source {
+ address 88.208.197.208
+ mac-address !00:50:56:1d:97:93
+ }
+ }
+ rule 438 {
+ action drop
+ description Anti-spoofing_213.171.212.89
+ source {
+ address 213.171.212.89
+ mac-address !00:50:56:36:8d:bf
+ }
+ }
+ rule 439 {
+ action drop
+ description Anti-spoofing_77.68.93.125
+ source {
+ address 77.68.93.125
+ mac-address !00:50:56:19:f1:6f
+ }
+ }
+ rule 440 {
+ action drop
+ description Anti-spoofing_probe_77.68.76.16
+ source {
+ address 77.68.76.16
+ mac-address !00:50:56:aa:48:d4
+ }
+ }
+ rule 441 {
+ action drop
+ description Anti-spoofing_213.171.214.96
+ source {
+ address 213.171.214.96
+ mac-address !00:50:56:0c:45:b5
+ }
+ }
+ rule 442 {
+ action drop
+ description Anti-spoofing_77.68.76.176
+ source {
+ address 77.68.76.176
+ mac-address !00:50:56:2b:e6:f7
+ }
+ }
+ rule 444 {
+ action drop
+ description Anti-spoofing_213.171.212.172
+ source {
+ address 213.171.212.172
+ mac-address !00:50:56:35:ab:43
+ }
+ }
+ rule 446 {
+ action drop
+ description Anti-spoofing_185.132.38.95
+ source {
+ address 185.132.38.95
+ mac-address !00:50:56:07:a6:f7
+ }
+ }
+ rule 447 {
+ action drop
+ description Anti-spoofing_185.132.38.248
+ source {
+ address 185.132.38.248
+ mac-address !00:50:56:19:e5:16
+ }
+ }
+ rule 448 {
+ action drop
+ description Anti-spoofing_109.228.52.186
+ source {
+ address 109.228.52.186
+ mac-address !00:50:56:20:80:4f
+ }
+ }
+ rule 449 {
+ action drop
+ description Anti-spoofing_213.171.213.31
+ source {
+ address 213.171.213.31
+ mac-address !00:50:56:34:e3:61
+ }
+ }
+ rule 450 {
+ action drop
+ description Anti-spoofing_probe_77.68.77.16
+ source {
+ address 77.68.77.16
+ mac-address !00:50:56:aa:4a:32
+ }
+ }
+ rule 451 {
+ action drop
+ description Anti-spoofing_213.171.210.59
+ source {
+ address 213.171.210.59
+ mac-address !00:50:56:10:74:b6
+ }
+ }
+ rule 452 {
+ action drop
+ description Anti-spoofing_185.132.36.7
+ source {
+ address 185.132.36.7
+ mac-address !00:50:56:17:24:16
+ }
+ }
+ rule 453 {
+ action drop
+ description Anti-spoofing_213.171.212.71
+ source {
+ address 213.171.212.71
+ mac-address !00:50:56:1d:50:e0
+ }
+ }
+ rule 454 {
+ action drop
+ description Anti-spoofing_213.171.208.58
+ source {
+ address 213.171.208.58
+ mac-address !00:50:56:05:1c:70
+ }
+ }
+ rule 455 {
+ action drop
+ description Anti-spoofing_77.68.77.69
+ source {
+ address 77.68.77.69
+ mac-address !00:50:56:17:f9:d1
+ }
+ }
+ rule 456 {
+ action drop
+ description Anti-spoofing_77.68.25.130
+ source {
+ address 77.68.25.130
+ mac-address !00:50:56:3c:92:ff
+ }
+ }
+ rule 457 {
+ action drop
+ description Anti-spoofing_213.171.215.184
+ source {
+ address 213.171.215.184
+ mac-address !00:50:56:18:84:ff
+ }
+ }
+ rule 458 {
+ action drop
+ description Anti-spoofing_77.68.74.39
+ source {
+ address 77.68.74.39
+ mac-address !00:50:56:0a:41:ee
+ }
+ }
+ rule 459 {
+ action drop
+ description Anti-spoofing_109.228.56.242
+ source {
+ address 109.228.56.242
+ mac-address !00:50:56:28:8c:ff
+ }
+ }
+ rule 460 {
+ action drop
+ description Anti-spoofing_77.68.76.13
+ source {
+ address 77.68.76.13
+ mac-address !00:50:56:8f:62:1e
+ }
+ }
+ rule 461 {
+ action drop
+ description Anti-spoofing_77.68.13.76
+ source {
+ address 77.68.13.76
+ mac-address !00:50:56:2c:c7:38
+ }
+ }
+ rule 462 {
+ action drop
+ description Anti-spoofing_77.68.119.188
+ source {
+ address 77.68.119.188
+ mac-address !00:50:56:02:1c:16
+ }
+ }
+ rule 463 {
+ action drop
+ description Anti-spoofing_109.228.46.81
+ source {
+ address 109.228.46.81
+ mac-address !00:50:56:31:1f:8a
+ }
+ }
+ rule 464 {
+ action drop
+ description Anti-spoofing_77.68.25.146
+ source {
+ address 77.68.25.146
+ mac-address !00:50:56:07:cc:76
+ }
+ }
+ rule 465 {
+ action drop
+ description Anti-spoofing_77.68.76.14
+ source {
+ address 77.68.76.14
+ mac-address !00:50:56:8f:6a:24
+ }
+ }
+ rule 466 {
+ action drop
+ description Anti-spoofing_77.68.116.36
+ source {
+ address 77.68.116.36
+ mac-address !00:50:56:1c:c9:83
+ }
+ }
+ rule 467 {
+ action drop
+ description Anti-spoofing_185.132.43.113
+ source {
+ address 185.132.43.113
+ mac-address !00:50:56:22:79:ac
+ }
+ }
+ rule 468 {
+ action drop
+ description Anti-spoofing_213.171.210.19
+ source {
+ address 213.171.210.19
+ mac-address !00:50:56:32:6c:19
+ }
+ }
+ rule 469 {
+ action drop
+ description Anti-spoofing_77.68.113.164
+ source {
+ address 77.68.113.164
+ mac-address !00:50:56:07:28:41
+ }
+ }
+ rule 470 {
+ action drop
+ description Anti-spoofing_77.68.77.13
+ source {
+ address 77.68.77.13
+ mac-address !00:50:56:8f:62:1e
+ }
+ }
+ rule 471 {
+ action drop
+ description Anti-spoofing_213.171.211.128
+ source {
+ address 213.171.211.128
+ mac-address !00:50:56:37:b2:85
+ }
+ }
+ rule 472 {
+ action drop
+ description Anti-spoofing_77.68.120.45
+ source {
+ address 77.68.120.45
+ mac-address !00:50:56:13:5e:ca
+ }
+ }
+ rule 473 {
+ action drop
+ description Anti-spoofing_77.68.25.124
+ source {
+ address 77.68.25.124
+ mac-address !00:50:56:2f:27:08
+ }
+ }
+ rule 474 {
+ action drop
+ description Anti-spoofing_77.68.33.68
+ source {
+ address 77.68.33.68
+ mac-address !00:50:56:1c:96:48
+ }
+ }
+ rule 475 {
+ action drop
+ description Anti-spoofing_77.68.77.14
+ source {
+ address 77.68.77.14
+ mac-address !00:50:56:8f:6a:24
+ }
+ }
+ rule 476 {
+ action drop
+ description Anti-spoofing_109.228.48.249
+ source {
+ address 109.228.48.249
+ mac-address !00:50:56:06:32:ac
+ }
+ }
+ rule 477 {
+ action drop
+ description Anti-spoofing_109.228.40.195
+ source {
+ address 109.228.40.195
+ mac-address !00:50:56:21:46:3e
+ }
+ }
+ rule 478 {
+ action drop
+ description Anti-spoofing_213.171.215.43
+ source {
+ address 213.171.215.43
+ mac-address !00:50:56:24:c0:53
+ }
+ }
+ rule 479 {
+ action drop
+ description Anti-spoofing_185.132.37.101
+ source {
+ address 185.132.37.101
+ mac-address !00:50:56:2c:08:73
+ }
+ }
+ rule 480 {
+ action drop
+ description Anti-spoofing_109.228.53.243
+ source {
+ address 109.228.53.243
+ mac-address !00:50:56:31:d1:1a
+ }
+ }
+ rule 481 {
+ action drop
+ description Anti-spoofing_77.68.81.218
+ source {
+ address 77.68.81.218
+ mac-address !00:50:56:03:e1:62
+ }
+ }
+ rule 482 {
+ action drop
+ description Anti-spoofing_77.68.102.5
+ source {
+ address 77.68.102.5
+ mac-address !00:50:56:12:a3:05
+ }
+ }
+ rule 483 {
+ action drop
+ description Anti-spoofing_77.68.114.93
+ source {
+ address 77.68.114.93
+ mac-address !00:50:56:3c:d8:18
+ }
+ }
+ rule 485 {
+ action drop
+ description Anti-spoofing_77.68.76.137
+ source {
+ address 77.68.76.137
+ mac-address !00:50:56:25:38:78
+ }
+ }
+ rule 486 {
+ action drop
+ description Anti-spoofing_77.68.75.253
+ source {
+ address 77.68.75.253
+ mac-address !00:50:56:32:f9:d7
+ }
+ }
+ rule 487 {
+ action drop
+ description Anti-spoofing_77.68.6.119
+ source {
+ address 77.68.6.119
+ mac-address !00:50:56:2a:06:e0
+ }
+ }
+ rule 488 {
+ action drop
+ description Anti-spoofing_185.132.39.68
+ source {
+ address 185.132.39.68
+ mac-address !00:50:56:22:2e:b5
+ }
+ }
+ rule 489 {
+ action drop
+ description Anti-spoofing_77.68.5.95
+ source {
+ address 77.68.5.95
+ mac-address !00:50:56:34:d6:94
+ }
+ }
+ rule 490 {
+ action drop
+ description Anti-spoofing_109.228.36.194
+ source {
+ address 109.228.36.194
+ mac-address !00:50:56:02:d4:bb
+ }
+ }
+ rule 491 {
+ action drop
+ description Anti-spoofing_77.68.34.50
+ source {
+ address 77.68.34.50
+ mac-address !00:50:56:07:df:24
+ }
+ }
+ rule 492 {
+ action drop
+ description Anti-spoofing_77.68.27.18
+ source {
+ address 77.68.27.18
+ mac-address !00:50:56:1c:9d:9e
+ }
+ }
+ rule 493 {
+ action drop
+ description Anti-spoofing_77.68.28.147
+ source {
+ address 77.68.28.147
+ mac-address !00:50:56:29:e0:70
+ }
+ }
+ rule 494 {
+ action drop
+ description Anti-spoofing_77.68.123.250
+ source {
+ address 77.68.123.250
+ mac-address !00:50:56:0d:49:c0
+ }
+ }
+ rule 495 {
+ action drop
+ description Anti-spoofing_185.132.39.129
+ source {
+ address 185.132.39.129
+ mac-address !00:50:56:29:5a:4c
+ }
+ }
+ rule 496 {
+ action drop
+ description Anti-spoofing_185.132.36.24
+ source {
+ address 185.132.36.24
+ mac-address !00:50:56:12:df:2d
+ }
+ }
+ rule 497 {
+ action drop
+ description Anti-spoofing_185.132.38.114
+ source {
+ address 185.132.38.114
+ mac-address !00:50:56:1d:ce:df
+ }
+ }
+ rule 498 {
+ action drop
+ description Anti-spoofing_185.132.36.148
+ source {
+ address 185.132.36.148
+ mac-address !00:50:56:04:d1:7e
+ }
+ }
+ rule 499 {
+ action drop
+ description Anti-spoofing_185.132.36.142
+ source {
+ address 185.132.36.142
+ mac-address !00:50:56:13:22:d1
+ }
+ }
+ rule 500 {
+ action drop
+ description Anti-spoofing_77.68.77.67
+ source {
+ address 77.68.77.67
+ mac-address !00:50:56:26:3e:0a
+ }
+ }
+ rule 501 {
+ action drop
+ description Anti-spoofing_185.132.39.44
+ source {
+ address 185.132.39.44
+ mac-address !00:50:56:32:a0:22
+ }
+ }
+ rule 502 {
+ action drop
+ description Anti-spoofing_77.68.76.114
+ source {
+ address 77.68.76.114
+ mac-address !00:50:56:32:42:42
+ }
+ }
+ rule 503 {
+ action drop
+ description Anti-spoofing_77.68.77.103
+ source {
+ address 77.68.77.103
+ mac-address !00:50:56:1e:6d:9b
+ }
+ }
+ rule 504 {
+ action drop
+ description Anti-spoofing_77.68.77.130
+ source {
+ address 77.68.77.130
+ mac-address !00:50:56:24:79:76
+ }
+ }
+ rule 505 {
+ action drop
+ description Anti-spoofing_77.68.76.245
+ source {
+ address 77.68.76.245
+ mac-address !00:50:56:1d:0f:83
+ }
+ }
+ rule 506 {
+ action drop
+ description Anti-spoofing_77.68.118.17
+ source {
+ address 77.68.118.17
+ mac-address !00:50:56:18:d3:d1
+ }
+ }
+ rule 507 {
+ action drop
+ description Anti-spoofing_77.68.79.82
+ source {
+ address 77.68.79.82
+ mac-address !00:50:56:22:e9:9e
+ }
+ }
+ rule 509 {
+ action drop
+ description Anti-spoofing_77.68.77.85
+ source {
+ address 77.68.77.85
+ mac-address !00:50:56:1d:40:33
+ }
+ }
+ rule 510 {
+ action drop
+ description Anti-spoofing_77.68.76.45
+ source {
+ address 77.68.76.45
+ mac-address !00:50:56:18:dc:fe
+ }
+ }
+ rule 511 {
+ action drop
+ description Anti-spoofing_77.68.77.144
+ source {
+ address 77.68.77.144
+ mac-address !00:50:56:3c:9a:1a
+ }
+ }
+ rule 512 {
+ action drop
+ description Anti-spoofing_77.68.77.105
+ source {
+ address 77.68.77.105
+ mac-address !00:50:56:1f:f9:c9
+ }
+ }
+ rule 513 {
+ action drop
+ description Anti-spoofing_77.68.12.250
+ source {
+ address 77.68.12.250
+ mac-address !00:50:56:3e:06:ca
+ }
+ }
+ rule 514 {
+ action drop
+ description Anti-spoofing_77.68.76.76
+ source {
+ address 77.68.76.76
+ mac-address !00:50:56:03:1f:db
+ }
+ }
+ rule 515 {
+ action drop
+ description Anti-spoofing_185.132.36.17
+ source {
+ address 185.132.36.17
+ mac-address !00:50:56:36:7a:94
+ }
+ }
+ rule 516 {
+ action drop
+ description Anti-spoofing_77.68.76.122
+ source {
+ address 77.68.76.122
+ mac-address !00:50:56:20:3d:43
+ }
+ }
+ rule 517 {
+ action drop
+ description Anti-spoofing_77.68.76.104
+ source {
+ address 77.68.76.104
+ mac-address !00:50:56:3c:80:ff
+ }
+ }
+ rule 518 {
+ action drop
+ description Anti-spoofing_77.68.114.136
+ source {
+ address 77.68.114.136
+ mac-address !00:50:56:38:34:6e
+ }
+ }
+ rule 519 {
+ action drop
+ description Anti-spoofing_77.68.77.115
+ source {
+ address 77.68.77.115
+ mac-address !00:50:56:2c:ad:ee
+ }
+ }
+ rule 520 {
+ action drop
+ description Anti-spoofing_77.68.77.178
+ source {
+ address 77.68.77.178
+ mac-address !00:50:56:14:c1:42
+ }
+ }
+ rule 521 {
+ action drop
+ description Anti-spoofing_77.68.76.239
+ source {
+ address 77.68.76.239
+ mac-address !00:50:56:0d:5a:47
+ }
+ }
+ rule 522 {
+ action drop
+ description Anti-spoofing_77.68.87.164
+ source {
+ address 77.68.87.164
+ mac-address !00:50:56:11:19:46
+ }
+ }
+ rule 523 {
+ action drop
+ description Anti-spoofing_77.68.15.95
+ source {
+ address 77.68.15.95
+ mac-address !00:50:56:16:04:4e
+ }
+ }
+ rule 524 {
+ action drop
+ description Anti-spoofing_77.68.4.39
+ source {
+ address 77.68.4.39
+ mac-address !00:50:56:06:57:b6
+ }
+ }
+ rule 525 {
+ action drop
+ description Anti-spoofing_77.68.76.30
+ source {
+ address 77.68.76.30
+ mac-address !00:50:56:25:b8:e3
+ }
+ }
+ rule 526 {
+ action drop
+ description Anti-spoofing_77.68.77.249
+ source {
+ address 77.68.77.249
+ mac-address !00:50:56:36:5f:b3
+ }
+ }
+ rule 527 {
+ action drop
+ description Anti-spoofing_77.68.76.59
+ source {
+ address 77.68.76.59
+ mac-address !00:50:56:06:e8:bb
+ }
+ }
+ rule 528 {
+ action drop
+ description Anti-spoofing_77.68.8.144
+ source {
+ address 77.68.8.144
+ mac-address !00:50:56:28:58:e5
+ }
+ }
+ rule 529 {
+ action drop
+ description Anti-spoofing_77.68.77.44
+ source {
+ address 77.68.77.44
+ mac-address !00:50:56:31:c0:9d
+ }
+ }
+ rule 530 {
+ action drop
+ description Anti-spoofing_77.68.77.200
+ source {
+ address 77.68.77.200
+ mac-address !00:50:56:15:2e:a4
+ }
+ }
+ rule 531 {
+ action drop
+ description Anti-spoofing_77.68.77.228
+ source {
+ address 77.68.77.228
+ mac-address !00:50:56:23:e4:44
+ }
+ }
+ rule 532 {
+ action drop
+ description Anti-spoofing_77.68.4.25
+ source {
+ address 77.68.4.25
+ mac-address !00:50:56:33:0d:5e
+ }
+ }
+ rule 534 {
+ action drop
+ description Anti-spoofing_77.68.76.191
+ source {
+ address 77.68.76.191
+ mac-address !00:50:56:10:72:7c
+ }
+ }
+ rule 535 {
+ action drop
+ description Anti-spoofing_77.68.117.29
+ source {
+ address 77.68.117.29
+ mac-address !00:50:56:0c:e4:e3
+ }
+ }
+ rule 536 {
+ action drop
+ description Anti-spoofing_213.171.212.90
+ source {
+ address 213.171.212.90
+ mac-address !00:50:56:35:fc:da
+ }
+ }
+ rule 537 {
+ action drop
+ description Anti-spoofing_77.68.76.102
+ source {
+ address 77.68.76.102
+ mac-address !00:50:56:35:87:43
+ }
+ }
+ rule 538 {
+ action drop
+ description Anti-spoofing_185.132.39.37
+ source {
+ address 185.132.39.37
+ mac-address !00:50:56:21:72:64
+ }
+ }
+ rule 539 {
+ action drop
+ description Anti-spoofing_185.132.38.142
+ source {
+ address 185.132.38.142
+ mac-address !00:50:56:09:e8:30
+ }
+ }
+ rule 540 {
+ action drop
+ description Anti-spoofing_77.68.77.26
+ source {
+ address 77.68.77.26
+ mac-address !00:50:56:10:ec:c2
+ }
+ }
+ rule 541 {
+ action drop
+ description Anti-spoofing_77.68.76.152
+ source {
+ address 77.68.76.152
+ mac-address !00:50:56:2b:79:48
+ }
+ }
+ rule 542 {
+ action drop
+ description Anti-spoofing_185.132.37.83
+ source {
+ address 185.132.37.83
+ mac-address !00:50:56:09:b3:41
+ }
+ }
+ rule 543 {
+ action drop
+ description Anti-spoofing_77.68.77.212
+ source {
+ address 77.68.77.212
+ mac-address !00:50:56:07:ab:f2
+ }
+ }
+ rule 544 {
+ action drop
+ description Anti-spoofing_77.68.75.64
+ source {
+ address 77.68.75.64
+ mac-address !00:50:56:07:e2:85
+ }
+ }
+ rule 546 {
+ action drop
+ description Anti-spoofing_77.68.85.73
+ source {
+ address 77.68.85.73
+ mac-address !00:50:56:14:68:9c
+ }
+ }
+ rule 547 {
+ action drop
+ description Anti-spoofing_77.68.116.119
+ source {
+ address 77.68.116.119
+ mac-address !00:50:56:0f:68:91
+ }
+ }
+ rule 548 {
+ action drop
+ description Anti-spoofing_77.68.76.142
+ source {
+ address 77.68.76.142
+ mac-address !50:9a:4c:74:07:ea
+ }
+ }
+ rule 549 {
+ action drop
+ description Anti-spoofing_77.68.76.211
+ source {
+ address 77.68.76.211
+ mac-address !00:50:56:18:9d:15
+ }
+ }
+ rule 550 {
+ action drop
+ description Anti-spoofing_77.68.76.60
+ source {
+ address 77.68.76.60
+ mac-address !00:50:56:2b:07:02
+ }
+ }
+ rule 551 {
+ action drop
+ description Anti-spoofing_77.68.77.253
+ source {
+ address 77.68.77.253
+ mac-address !00:50:56:30:a5:77
+ }
+ }
+ rule 552 {
+ action drop
+ description Anti-spoofing_77.68.75.245
+ source {
+ address 77.68.75.245
+ mac-address !00:50:56:12:00:e9
+ }
+ }
+ rule 553 {
+ action drop
+ description Anti-spoofing_185.132.37.102
+ source {
+ address 185.132.37.102
+ mac-address !00:50:56:3d:ae:26
+ }
+ }
+ rule 554 {
+ action drop
+ description Anti-spoofing_77.68.120.31
+ source {
+ address 77.68.120.31
+ mac-address !00:50:56:1f:29:84
+ }
+ }
+ rule 555 {
+ action drop
+ description Anti-spoofing_77.68.76.54
+ source {
+ address 77.68.76.54
+ mac-address !00:50:56:30:b4:74
+ }
+ }
+ rule 556 {
+ action drop
+ description Anti-spoofing_88.208.196.154
+ source {
+ address 88.208.196.154
+ mac-address !00:50:56:14:6f:a8
+ }
+ }
+ rule 557 {
+ action drop
+ description Anti-spoofing_185.132.40.152
+ source {
+ address 185.132.40.152
+ mac-address !00:50:56:24:25:3c
+ }
+ }
+ rule 558 {
+ action drop
+ description Anti-spoofing_77.68.76.33
+ source {
+ address 77.68.76.33
+ mac-address !00:50:56:3c:9b:bc
+ }
+ }
+ rule 559 {
+ action drop
+ description Anti-spoofing_77.68.12.195
+ source {
+ address 77.68.12.195
+ mac-address !00:50:56:3d:52:1a
+ }
+ }
+ rule 560 {
+ action drop
+ description Anti-spoofing_77.68.77.114
+ source {
+ address 77.68.77.114
+ mac-address !00:50:56:06:80:89
+ }
+ }
+ rule 561 {
+ action drop
+ description Anti-spoofing_77.68.77.176
+ source {
+ address 77.68.77.176
+ mac-address !00:50:56:3e:2b:da
+ }
+ }
+ rule 562 {
+ action drop
+ description Anti-spoofing_109.228.40.222
+ source {
+ address 109.228.40.222
+ mac-address !00:50:56:0a:dc:63
+ }
+ }
+ rule 563 {
+ action drop
+ description Anti-spoofing_77.68.77.219
+ source {
+ address 77.68.77.219
+ mac-address !00:50:56:13:82:67
+ }
+ }
+ rule 564 {
+ action drop
+ description Anti-spoofing_77.68.77.19
+ source {
+ address 77.68.77.19
+ mac-address !00:50:56:36:e3:b1
+ }
+ }
+ rule 565 {
+ action drop
+ description Anti-spoofing_77.68.74.85
+ source {
+ address 77.68.74.85
+ mac-address !00:50:56:13:b7:2d
+ }
+ }
+ rule 566 {
+ action drop
+ description Anti-spoofing_77.68.116.221
+ source {
+ address 77.68.116.221
+ mac-address !00:50:56:24:67:bd
+ }
+ }
+ rule 567 {
+ action drop
+ description Anti-spoofing_77.68.77.22
+ source {
+ address 77.68.77.22
+ mac-address !00:50:56:07:09:ae
+ }
+ }
+ rule 568 {
+ action drop
+ description Anti-spoofing_77.68.112.184
+ source {
+ address 77.68.112.184
+ mac-address !00:50:56:2a:db:d3
+ }
+ }
+ rule 569 {
+ action drop
+ description Anti-spoofing_77.68.77.248
+ source {
+ address 77.68.77.248
+ mac-address !00:50:56:18:03:92
+ }
+ }
+ rule 570 {
+ action drop
+ description Anti-spoofing_77.68.76.161
+ source {
+ address 77.68.76.161
+ mac-address !00:50:56:34:57:75
+ }
+ }
+ rule 571 {
+ action drop
+ description Anti-spoofing_77.68.77.56
+ source {
+ address 77.68.77.56
+ mac-address !00:50:56:38:22:ae
+ }
+ }
+ rule 572 {
+ action drop
+ description Anti-spoofing_77.68.77.129
+ source {
+ address 77.68.77.129
+ mac-address !00:50:56:08:d9:20
+ }
+ }
+ rule 573 {
+ action drop
+ description Anti-spoofing_77.68.77.205
+ source {
+ address 77.68.77.205
+ mac-address !00:50:56:35:f1:c3
+ }
+ }
+ rule 574 {
+ action drop
+ description Anti-spoofing_77.68.77.140
+ source {
+ address 77.68.77.140
+ mac-address !00:50:56:1b:2d:c7
+ }
+ }
+ rule 575 {
+ action drop
+ description Anti-spoofing_77.68.120.146
+ source {
+ address 77.68.120.146
+ mac-address !00:50:56:0d:fb:7b
+ }
+ }
+ rule 576 {
+ action drop
+ description Anti-spoofing_77.68.78.73
+ source {
+ address 77.68.78.73
+ mac-address !00:50:56:14:4b:f4
+ }
+ }
+ rule 577 {
+ action drop
+ description Anti-spoofing_77.68.76.177
+ source {
+ address 77.68.76.177
+ mac-address !00:50:56:26:ac:11
+ }
+ }
+ rule 578 {
+ action drop
+ description Anti-spoofing_77.68.77.117
+ source {
+ address 77.68.77.117
+ mac-address !00:50:56:09:4d:ce
+ }
+ }
+ rule 579 {
+ action drop
+ description Anti-spoofing_77.68.77.108
+ source {
+ address 77.68.77.108
+ mac-address !00:50:56:3a:b7:59
+ }
+ }
+ rule 580 {
+ action drop
+ description Anti-spoofing_77.68.7.222
+ source {
+ address 77.68.7.222
+ mac-address !00:50:56:36:cc:37
+ }
+ }
+ rule 581 {
+ action drop
+ description Anti-spoofing_77.68.76.50
+ source {
+ address 77.68.76.50
+ mac-address !00:50:56:34:78:88
+ }
+ }
+ rule 582 {
+ action drop
+ description Anti-spoofing_77.68.77.192
+ source {
+ address 77.68.77.192
+ mac-address !00:50:56:0f:eb:a4
+ }
+ }
+ rule 583 {
+ action drop
+ description Anti-spoofing_77.68.76.217
+ source {
+ address 77.68.76.217
+ mac-address !00:50:56:29:6d:a9
+ }
+ }
+ rule 584 {
+ action drop
+ description Anti-spoofing_77.68.92.186
+ source {
+ address 77.68.92.186
+ mac-address !00:50:56:08:8b:d0
+ }
+ }
+ rule 585 {
+ action drop
+ description Anti-spoofing_77.68.76.165
+ source {
+ address 77.68.76.165
+ mac-address !00:50:56:19:74:17
+ }
+ }
+ rule 586 {
+ action drop
+ description Anti-spoofing_77.68.91.22
+ source {
+ address 77.68.91.22
+ mac-address !00:50:56:2e:2c:cb
+ }
+ }
+ rule 587 {
+ action drop
+ description Anti-spoofing_77.68.77.160
+ source {
+ address 77.68.77.160
+ mac-address !00:50:56:27:75:65
+ }
+ }
+ rule 588 {
+ action drop
+ description Anti-spoofing_77.68.77.30
+ source {
+ address 77.68.77.30
+ mac-address !00:50:56:3b:95:8f
+ }
+ }
+ rule 589 {
+ action drop
+ description Anti-spoofing_77.68.77.21
+ source {
+ address 77.68.77.21
+ mac-address !00:50:56:34:cd:82
+ }
+ }
+ rule 590 {
+ action drop
+ description Anti-spoofing_77.68.76.29
+ source {
+ address 77.68.76.29
+ mac-address !00:50:56:2f:a3:ef
+ }
+ }
+ rule 591 {
+ action drop
+ description Anti-spoofing_213.171.212.136
+ source {
+ address 213.171.212.136
+ mac-address !00:50:56:19:fb:be
+ }
+ }
+ rule 592 {
+ action drop
+ description Anti-spoofing_77.68.76.158
+ source {
+ address 77.68.76.158
+ mac-address !00:50:56:36:97:69
+ }
+ }
+ rule 593 {
+ action drop
+ description Anti-spoofing_77.68.76.203
+ source {
+ address 77.68.76.203
+ mac-address !00:50:56:2f:48:47
+ }
+ }
+ rule 594 {
+ action drop
+ description Anti-spoofing_77.68.77.243
+ source {
+ address 77.68.77.243
+ mac-address !00:50:56:20:1f:c4
+ }
+ }
+ rule 595 {
+ action drop
+ description Anti-spoofing_77.68.77.54
+ source {
+ address 77.68.77.54
+ mac-address !00:50:56:0e:da:e1
+ }
+ }
+ rule 596 {
+ action drop
+ description Anti-spoofing_77.68.76.22
+ source {
+ address 77.68.76.22
+ mac-address !00:50:56:1b:a3:e6
+ }
+ }
+ rule 597 {
+ action drop
+ description Anti-spoofing_77.68.103.120
+ source {
+ address 77.68.103.120
+ mac-address !00:50:56:1f:cb:8e
+ }
+ }
+ rule 598 {
+ action drop
+ description Anti-spoofing_109.228.37.174
+ source {
+ address 109.228.37.174
+ mac-address !00:50:56:1d:0f:a0
+ }
+ }
+ rule 599 {
+ action drop
+ description Anti-spoofing_77.68.17.26
+ source {
+ address 77.68.17.26
+ mac-address !00:50:56:13:4a:e1
+ }
+ }
+ rule 600 {
+ action drop
+ description Anti-spoofing_77.68.76.25
+ source {
+ address 77.68.76.25
+ mac-address !00:50:56:1f:54:d9
+ }
+ }
+ rule 601 {
+ action drop
+ description Anti-spoofing_77.68.76.21
+ source {
+ address 77.68.76.21
+ mac-address !00:50:56:15:a8:33
+ }
+ }
+ rule 602 {
+ action drop
+ description Anti-spoofing_77.68.77.221
+ source {
+ address 77.68.77.221
+ mac-address !00:50:56:06:2a:ae
+ }
+ }
+ rule 603 {
+ action drop
+ description Anti-spoofing_77.68.77.76
+ source {
+ address 77.68.77.76
+ mac-address !00:50:56:18:01:78
+ }
+ }
+ rule 604 {
+ action drop
+ description Anti-spoofing_77.68.76.127
+ source {
+ address 77.68.76.127
+ mac-address !00:50:56:24:a4:85
+ }
+ }
+ rule 605 {
+ action drop
+ description Anti-spoofing_77.68.77.139
+ source {
+ address 77.68.77.139
+ mac-address !00:50:56:3b:1e:be
+ }
+ }
+ rule 606 {
+ action drop
+ description Anti-spoofing_77.68.77.240
+ source {
+ address 77.68.77.240
+ mac-address !00:50:56:2b:d5:dd
+ }
+ }
+ rule 607 {
+ action drop
+ description Anti-spoofing_185.132.38.216
+ source {
+ address 185.132.38.216
+ mac-address !00:50:56:26:a7:47
+ }
+ }
+ rule 608 {
+ action drop
+ description Anti-spoofing_77.68.76.39
+ source {
+ address 77.68.76.39
+ mac-address !00:50:56:1e:0d:c1
+ }
+ }
+ rule 609 {
+ action drop
+ description Anti-spoofing_77.68.76.149
+ source {
+ address 77.68.76.149
+ mac-address !00:50:56:32:30:e7
+ }
+ }
+ rule 610 {
+ action drop
+ description Anti-spoofing_77.68.77.57
+ source {
+ address 77.68.77.57
+ mac-address !00:50:56:26:33:75
+ }
+ }
+ rule 611 {
+ action drop
+ description Anti-spoofing_77.68.77.185
+ source {
+ address 77.68.77.185
+ mac-address !00:50:56:22:72:c9
+ }
+ }
+ rule 612 {
+ action drop
+ description Anti-spoofing_77.68.76.116
+ source {
+ address 77.68.76.116
+ mac-address !00:50:56:09:f2:df
+ }
+ }
+ rule 613 {
+ action drop
+ description Anti-spoofing_77.68.95.212
+ source {
+ address 77.68.95.212
+ mac-address !00:50:56:21:4b:e6
+ }
+ }
+ rule 614 {
+ action drop
+ description Anti-spoofing_77.68.76.160
+ source {
+ address 77.68.76.160
+ mac-address !00:50:56:3a:fa:b3
+ }
+ }
+ rule 615 {
+ action drop
+ description Anti-spoofing_77.68.77.70
+ source {
+ address 77.68.77.70
+ mac-address !00:50:56:37:9d:47
+ }
+ }
+ rule 616 {
+ action drop
+ description Anti-spoofing_77.68.77.149
+ source {
+ address 77.68.77.149
+ mac-address !00:50:56:2c:f8:51
+ }
+ }
+ rule 617 {
+ action drop
+ description Anti-spoofing_77.68.76.57
+ source {
+ address 77.68.76.57
+ mac-address !00:50:56:32:d9:0f
+ }
+ }
+ rule 618 {
+ action drop
+ description Anti-spoofing_77.68.76.115
+ source {
+ address 77.68.76.115
+ mac-address !00:50:56:09:67:90
+ }
+ }
+ rule 619 {
+ action drop
+ description Anti-spoofing_185.132.41.72
+ source {
+ address 185.132.41.72
+ mac-address !00:50:56:2b:aa:79
+ }
+ }
+ rule 620 {
+ action drop
+ description Anti-spoofing_77.68.84.155
+ source {
+ address 77.68.84.155
+ mac-address !00:50:56:05:52:76
+ }
+ }
+ rule 621 {
+ action drop
+ description Anti-spoofing_77.68.76.200
+ source {
+ address 77.68.76.200
+ mac-address !00:50:56:00:5f:48
+ }
+ }
+ rule 622 {
+ action drop
+ description Anti-spoofing_77.68.76.23
+ source {
+ address 77.68.76.23
+ mac-address !00:50:56:27:eb:9b
+ }
+ }
+ rule 623 {
+ action drop
+ description Anti-spoofing_77.68.77.46
+ source {
+ address 77.68.77.46
+ mac-address !00:50:56:22:73:37
+ }
+ }
+ rule 624 {
+ action drop
+ description Anti-spoofing_77.68.91.195
+ source {
+ address 77.68.91.195
+ mac-address !00:50:56:09:f1:74
+ }
+ }
+ rule 625 {
+ action drop
+ description Anti-spoofing_77.68.76.198
+ source {
+ address 77.68.76.198
+ mac-address !00:50:56:05:4b:16
+ }
+ }
+ rule 626 {
+ action drop
+ description Anti-spoofing_77.68.77.141
+ source {
+ address 77.68.77.141
+ mac-address !00:50:56:0c:04:05
+ }
+ }
+ rule 627 {
+ action drop
+ description Anti-spoofing_77.68.77.50
+ source {
+ address 77.68.77.50
+ mac-address !00:50:56:2d:5b:c6
+ }
+ }
+ rule 628 {
+ action drop
+ description Anti-spoofing_77.68.77.128
+ source {
+ address 77.68.77.128
+ mac-address !00:50:56:27:0f:74
+ }
+ }
+ rule 629 {
+ action drop
+ description Anti-spoofing_77.68.115.142
+ source {
+ address 77.68.115.142
+ mac-address !00:50:56:1b:e1:25
+ }
+ }
+ rule 630 {
+ action drop
+ description Anti-spoofing_77.68.77.88
+ source {
+ address 77.68.77.88
+ mac-address !00:50:56:2b:db:7e
+ }
+ }
+ rule 631 {
+ action drop
+ description Anti-spoofing_77.68.4.74
+ source {
+ address 77.68.4.74
+ mac-address !00:50:56:0f:22:a5
+ }
+ }
+ rule 632 {
+ action drop
+ description Anti-spoofing_77.68.76.80
+ source {
+ address 77.68.76.80
+ mac-address !00:50:56:1f:17:01
+ }
+ }
+ rule 633 {
+ action drop
+ description Anti-spoofing_77.68.76.35
+ source {
+ address 77.68.76.35
+ mac-address !00:50:56:30:e3:a1
+ }
+ }
+ rule 634 {
+ action drop
+ description Anti-spoofing_77.68.77.204
+ source {
+ address 77.68.77.204
+ mac-address !00:50:56:23:70:3a
+ }
+ }
+ rule 635 {
+ action drop
+ description Anti-spoofing_77.68.77.201
+ source {
+ address 77.68.77.201
+ mac-address !50:9a:4c:74:06:06
+ }
+ }
+ rule 636 {
+ action drop
+ description Anti-spoofing_77.68.77.97
+ source {
+ address 77.68.77.97
+ mac-address !00:50:56:2f:48:47
+ }
+ }
+ rule 637 {
+ action drop
+ description Anti-spoofing_77.68.76.195
+ source {
+ address 77.68.76.195
+ mac-address !00:50:56:14:c5:49
+ }
+ }
+ rule 638 {
+ action drop
+ description Anti-spoofing_77.68.76.202
+ source {
+ address 77.68.76.202
+ mac-address !00:50:56:07:3c:3c
+ }
+ }
+ rule 640 {
+ action drop
+ description Anti-spoofing_77.68.76.157
+ source {
+ address 77.68.76.157
+ mac-address !00:50:56:35:c8:20
+ }
+ }
+ rule 641 {
+ action drop
+ description Anti-spoofing_213.171.212.114
+ source {
+ address 213.171.212.114
+ mac-address !00:50:56:11:7f:32
+ }
+ }
+ rule 642 {
+ action drop
+ description Anti-spoofing_77.68.77.159
+ source {
+ address 77.68.77.159
+ mac-address !00:50:56:14:d8:f0
+ }
+ }
+ rule 643 {
+ action drop
+ description Anti-spoofing_213.171.214.234
+ source {
+ address 213.171.214.234
+ mac-address !00:50:56:29:94:38
+ }
+ }
+ rule 644 {
+ action drop
+ description Anti-spoofing_77.68.76.48
+ source {
+ address 77.68.76.48
+ mac-address !00:50:56:33:38:d6
+ }
+ }
+ rule 645 {
+ action drop
+ description Anti-spoofing_77.68.76.118
+ source {
+ address 77.68.76.118
+ mac-address !00:50:56:1c:cd:d3
+ }
+ }
+ rule 646 {
+ action drop
+ description Anti-spoofing_77.68.76.38
+ source {
+ address 77.68.76.38
+ mac-address !00:50:56:01:59:2a
+ }
+ }
+ rule 647 {
+ action drop
+ description Anti-spoofing_77.68.31.144
+ source {
+ address 77.68.31.144
+ mac-address !00:50:56:01:89:fb
+ }
+ }
+ rule 648 {
+ action drop
+ description Anti-spoofing_77.68.23.35
+ source {
+ address 77.68.23.35
+ mac-address !00:50:56:3b:1f:ee
+ }
+ }
+ rule 649 {
+ action drop
+ description Anti-spoofing_77.68.4.80
+ source {
+ address 77.68.4.80
+ mac-address !00:50:56:1a:06:95
+ }
+ }
+ rule 650 {
+ action drop
+ description Anti-spoofing_77.68.127.151
+ source {
+ address 77.68.127.151
+ mac-address !00:50:56:32:48:a6
+ }
+ }
+ rule 651 {
+ action drop
+ description Anti-spoofing_77.68.77.203
+ source {
+ address 77.68.77.203
+ mac-address !00:50:56:11:05:40
+ }
+ }
+ rule 652 {
+ action drop
+ description Anti-spoofing_77.68.77.233
+ source {
+ address 77.68.77.233
+ mac-address !00:50:56:37:0e:b3
+ }
+ }
+ rule 653 {
+ action drop
+ description Anti-spoofing_77.68.77.163
+ source {
+ address 77.68.77.163
+ mac-address !00:50:56:08:a3:b4
+ }
+ }
+ rule 654 {
+ action drop
+ description Anti-spoofing_77.68.77.49
+ source {
+ address 77.68.77.49
+ mac-address !00:50:56:03:ba:26
+ }
+ }
+ rule 655 {
+ action drop
+ description Anti-spoofing_77.68.76.58
+ source {
+ address 77.68.76.58
+ mac-address !00:50:56:03:bd:d2
+ }
+ }
+ rule 656 {
+ action drop
+ description Anti-spoofing_77.68.77.171
+ source {
+ address 77.68.77.171
+ mac-address !00:50:56:22:3d:21
+ }
+ }
+ rule 657 {
+ action drop
+ description Anti-spoofing_77.68.116.220
+ source {
+ address 77.68.116.220
+ mac-address !00:50:56:2e:06:02
+ }
+ }
+ rule 658 {
+ action drop
+ description Anti-spoofing_77.68.77.150
+ source {
+ address 77.68.77.150
+ mac-address !00:50:56:23:ac:01
+ }
+ }
+ rule 659 {
+ action drop
+ description Anti-spoofing_77.68.121.106
+ source {
+ address 77.68.121.106
+ mac-address !00:50:56:38:2f:3f
+ }
+ }
+ rule 660 {
+ action drop
+ description Anti-spoofing_77.68.77.199
+ source {
+ address 77.68.77.199
+ mac-address !00:50:56:37:e8:23
+ }
+ }
+ rule 661 {
+ action drop
+ description Anti-spoofing_77.68.76.220
+ source {
+ address 77.68.76.220
+ mac-address !00:50:56:26:27:93
+ }
+ }
+ rule 662 {
+ action drop
+ description Anti-spoofing_77.68.85.172
+ source {
+ address 77.68.85.172
+ mac-address !00:50:56:24:a5:72
+ }
+ }
+ rule 663 {
+ action drop
+ description Anti-spoofing_109.228.42.232
+ source {
+ address 109.228.42.232
+ mac-address !00:50:56:2c:34:e5
+ }
+ }
+ rule 664 {
+ action drop
+ description Anti-spoofing_77.68.33.216
+ source {
+ address 77.68.33.216
+ mac-address !00:50:56:08:a3:d8
+ }
+ }
+ rule 665 {
+ action drop
+ description Anti-spoofing_109.228.35.110
+ source {
+ address 109.228.35.110
+ mac-address !00:50:56:20:bc:f6
+ }
+ }
+ rule 666 {
+ action drop
+ description Anti-spoofing_77.68.87.212
+ source {
+ address 77.68.87.212
+ mac-address !00:50:56:20:7a:5b
+ }
+ }
+ rule 667 {
+ action drop
+ description Anti-spoofing_109.228.36.174
+ source {
+ address 109.228.36.174
+ mac-address !00:50:56:05:73:0a
+ }
+ }
+ rule 668 {
+ action drop
+ description Anti-spoofing_77.68.122.241
+ source {
+ address 77.68.122.241
+ mac-address !00:50:56:3d:34:86
+ }
+ }
+ rule 669 {
+ action drop
+ description Anti-spoofing_77.68.10.170
+ source {
+ address 77.68.10.170
+ mac-address !00:50:56:2e:a7:d6
+ }
+ }
+ rule 670 {
+ action drop
+ description Anti-spoofing_109.228.59.247
+ source {
+ address 109.228.59.247
+ mac-address !00:50:56:11:77:61
+ }
+ }
+ rule 671 {
+ action drop
+ description Anti-spoofing_77.68.77.156
+ source {
+ address 77.68.77.156
+ mac-address !00:50:56:37:e8:23
+ }
+ }
+ rule 672 {
+ action drop
+ description Anti-spoofing_77.68.76.248
+ source {
+ address 77.68.76.248
+ mac-address !00:50:56:22:40:ae
+ }
+ }
+ rule 673 {
+ action drop
+ description Anti-spoofing_77.68.76.19
+ source {
+ address 77.68.76.19
+ mac-address !00:50:56:26:ce:06
+ }
+ }
+ rule 674 {
+ action drop
+ description Anti-spoofing_77.68.77.29
+ source {
+ address 77.68.77.29
+ mac-address !00:50:56:11:83:b8
+ }
+ }
+ rule 675 {
+ action drop
+ description Anti-spoofing_77.68.76.250
+ source {
+ address 77.68.76.250
+ mac-address !00:50:56:2d:ca:5b
+ }
+ }
+ rule 676 {
+ action drop
+ description Anti-spoofing_77.68.76.110
+ source {
+ address 77.68.76.110
+ mac-address !00:50:56:1e:db:08
+ }
+ }
+ rule 677 {
+ action drop
+ description Anti-spoofing_77.68.76.171
+ source {
+ address 77.68.76.171
+ mac-address !00:50:56:01:8b:92
+ }
+ }
+ rule 678 {
+ action drop
+ description Anti-spoofing_77.68.76.212
+ source {
+ address 77.68.76.212
+ mac-address !00:50:56:2b:28:99
+ }
+ }
+ rule 679 {
+ action drop
+ description Anti-spoofing_77.68.112.248
+ source {
+ address 77.68.112.248
+ mac-address !00:50:56:35:e3:48
+ }
+ }
+ rule 680 {
+ action drop
+ description Anti-spoofing_77.68.77.132
+ source {
+ address 77.68.77.132
+ mac-address !00:50:56:21:ab:ff
+ }
+ }
+ rule 681 {
+ action drop
+ description Anti-spoofing_77.68.120.218
+ source {
+ address 77.68.120.218
+ mac-address !00:50:56:10:a8:be
+ }
+ }
+ rule 682 {
+ action drop
+ description Anti-spoofing_77.68.120.249
+ source {
+ address 77.68.120.249
+ mac-address !00:50:56:2f:70:ed
+ }
+ }
+ rule 683 {
+ action drop
+ description Anti-spoofing_77.68.77.81
+ source {
+ address 77.68.77.81
+ mac-address !00:50:56:1e:9f:f8
+ }
+ }
+ rule 684 {
+ action drop
+ description Anti-spoofing_77.68.76.37
+ source {
+ address 77.68.76.37
+ mac-address !00:50:56:07:f8:48
+ }
+ }
+ rule 685 {
+ action drop
+ description Anti-spoofing_77.68.76.197
+ source {
+ address 77.68.76.197
+ mac-address !00:50:56:31:a0:ee
+ }
+ }
+ rule 686 {
+ action drop
+ description Anti-spoofing_77.68.76.20
+ source {
+ address 77.68.76.20
+ mac-address !00:50:56:18:a2:03
+ }
+ }
+ rule 687 {
+ action drop
+ description Anti-spoofing_77.68.76.108
+ source {
+ address 77.68.76.108
+ mac-address !00:50:56:0d:4d:25
+ }
+ }
+ rule 688 {
+ action drop
+ description Anti-spoofing_77.68.76.139
+ source {
+ address 77.68.76.139
+ mac-address !00:50:56:1c:52:a8
+ }
+ }
+ rule 689 {
+ action drop
+ description Anti-spoofing_77.68.76.99
+ source {
+ address 77.68.76.99
+ mac-address !00:50:56:2e:8d:48
+ }
+ }
+ rule 690 {
+ action drop
+ description Anti-spoofing_77.68.77.211
+ source {
+ address 77.68.77.211
+ mac-address !00:50:56:30:37:77
+ }
+ }
+ rule 691 {
+ action drop
+ description Anti-spoofing_77.68.77.236
+ source {
+ address 77.68.77.236
+ mac-address !00:50:56:18:13:8b
+ }
+ }
+ rule 692 {
+ action drop
+ description Anti-spoofing_77.68.76.252
+ source {
+ address 77.68.76.252
+ mac-address !00:50:56:16:03:6e
+ }
+ }
+ rule 693 {
+ action drop
+ description Anti-spoofing_77.68.122.89
+ source {
+ address 77.68.122.89
+ mac-address !00:50:56:25:66:5d
+ }
+ }
+ rule 694 {
+ action drop
+ description Anti-spoofing_77.68.76.120
+ source {
+ address 77.68.76.120
+ mac-address !00:50:56:39:de:31
+ }
+ }
+ rule 695 {
+ action drop
+ description Anti-spoofing_77.68.77.234
+ source {
+ address 77.68.77.234
+ mac-address !00:50:56:26:a1:9a
+ }
+ }
+ rule 696 {
+ action drop
+ description Anti-spoofing_77.68.77.32
+ source {
+ address 77.68.77.32
+ mac-address !00:50:56:38:e8:59
+ }
+ }
+ rule 697 {
+ action drop
+ description Anti-spoofing_77.68.77.247
+ source {
+ address 77.68.77.247
+ mac-address !00:50:56:27:8a:8b
+ }
+ }
+ rule 698 {
+ action drop
+ description Anti-spoofing_77.68.76.229
+ source {
+ address 77.68.76.229
+ mac-address !00:50:56:16:56:30
+ }
+ }
+ rule 699 {
+ action drop
+ description Anti-spoofing_77.68.76.209
+ source {
+ address 77.68.76.209
+ mac-address !00:50:56:19:24:73
+ }
+ }
+ rule 700 {
+ action drop
+ description Anti-spoofing_77.68.125.32
+ source {
+ address 77.68.125.32
+ mac-address !00:50:56:00:07:47
+ }
+ }
+ rule 701 {
+ action drop
+ description Anti-spoofing_77.68.76.219
+ source {
+ address 77.68.76.219
+ mac-address !00:50:56:2d:04:90
+ }
+ }
+ rule 702 {
+ action drop
+ description Anti-spoofing_77.68.76.253
+ source {
+ address 77.68.76.253
+ mac-address !00:50:56:12:7b:d8
+ }
+ }
+ rule 703 {
+ action drop
+ description Anti-spoofing_77.68.13.137
+ source {
+ address 77.68.13.137
+ mac-address !00:50:56:16:c6:86
+ }
+ }
+ rule 704 {
+ action drop
+ description Anti-spoofing_77.68.85.115
+ source {
+ address 77.68.85.115
+ mac-address !00:50:56:3c:51:df
+ }
+ }
+ rule 705 {
+ action drop
+ description Anti-spoofing_77.68.77.202
+ source {
+ address 77.68.77.202
+ mac-address !00:50:56:0c:94:82
+ }
+ }
+ rule 706 {
+ action drop
+ description Anti-spoofing_77.68.76.247
+ source {
+ address 77.68.76.247
+ mac-address !00:50:56:1b:f1:83
+ }
+ }
+ rule 707 {
+ action drop
+ description Anti-spoofing_77.68.9.75
+ source {
+ address 77.68.9.75
+ mac-address !00:50:56:21:9b:fe
+ }
+ }
+ rule 708 {
+ action drop
+ description Anti-spoofing_109.228.39.157
+ source {
+ address 109.228.39.157
+ mac-address !00:50:56:2b:55:32
+ }
+ }
+ rule 709 {
+ action drop
+ description Anti-spoofing_77.68.77.99
+ source {
+ address 77.68.77.99
+ mac-address !00:50:56:09:d5:e8
+ }
+ }
+ rule 710 {
+ action drop
+ description Anti-spoofing_77.68.23.158
+ source {
+ address 77.68.23.158
+ mac-address !00:50:56:15:8f:75
+ }
+ }
+ rule 711 {
+ action drop
+ description Anti-spoofing_77.68.76.169
+ source {
+ address 77.68.76.169
+ mac-address !00:50:56:0b:6d:e4
+ }
+ }
+ rule 712 {
+ action drop
+ description Anti-spoofing_77.68.76.95
+ source {
+ address 77.68.76.95
+ mac-address !00:50:56:17:08:c9
+ }
+ }
+ rule 713 {
+ action drop
+ description Anti-spoofing_77.68.76.187
+ source {
+ address 77.68.76.187
+ mac-address !00:50:56:14:79:08
+ }
+ }
+ rule 714 {
+ action drop
+ description Anti-spoofing_109.228.37.114
+ source {
+ address 109.228.37.114
+ mac-address !00:50:56:15:3d:4b
+ }
+ }
+ rule 715 {
+ action drop
+ description Anti-spoofing_77.68.5.187
+ source {
+ address 77.68.5.187
+ mac-address !00:50:56:07:60:de
+ }
+ }
+ rule 716 {
+ action drop
+ description Anti-spoofing_77.68.77.222
+ source {
+ address 77.68.77.222
+ mac-address !00:50:56:38:03:ce
+ }
+ }
+ rule 717 {
+ action drop
+ description Anti-spoofing_77.68.77.53
+ source {
+ address 77.68.77.53
+ mac-address !00:50:56:18:cc:5a
+ }
+ }
+ rule 718 {
+ action drop
+ description Anti-spoofing_77.68.77.124
+ source {
+ address 77.68.77.124
+ mac-address !00:50:56:21:67:74
+ }
+ }
+ rule 719 {
+ action drop
+ description Anti-spoofing_77.68.76.61
+ source {
+ address 77.68.76.61
+ mac-address !00:50:56:10:fa:46
+ }
+ }
+ rule 720 {
+ action drop
+ description Anti-spoofing_109.228.37.240
+ source {
+ address 109.228.37.240
+ mac-address !00:50:56:0a:d3:2d
+ }
+ }
+ rule 721 {
+ action drop
+ description Anti-spoofing_77.68.27.27
+ source {
+ address 77.68.27.27
+ mac-address !00:50:56:14:b0:2a
+ }
+ }
+ rule 722 {
+ action drop
+ description Anti-spoofing_77.68.77.43
+ source {
+ address 77.68.77.43
+ mac-address !00:50:56:30:92:94
+ }
+ }
+ rule 723 {
+ action drop
+ description Anti-spoofing_77.68.76.94
+ source {
+ address 77.68.76.94
+ mac-address !00:50:56:00:10:ce
+ }
+ }
+ rule 724 {
+ action drop
+ description Anti-spoofing_77.68.77.165
+ source {
+ address 77.68.77.165
+ mac-address !00:50:56:26:5f:42
+ }
+ }
+ rule 725 {
+ action drop
+ description Anti-spoofing_77.68.77.251
+ source {
+ address 77.68.77.251
+ mac-address !00:50:56:39:db:9e
+ }
+ }
+ rule 726 {
+ action drop
+ description Anti-spoofing_77.68.77.152
+ source {
+ address 77.68.77.152
+ mac-address !00:50:56:12:68:ca
+ }
+ }
+ rule 727 {
+ action drop
+ description Anti-spoofing_185.132.43.164
+ source {
+ address 185.132.43.164
+ mac-address !00:50:56:2f:98:9b
+ }
+ }
+ rule 728 {
+ action drop
+ description Anti-spoofing_77.68.9.186
+ source {
+ address 77.68.9.186
+ mac-address !00:50:56:06:07:22
+ }
+ }
+ rule 729 {
+ action drop
+ description Anti-spoofing_77.68.27.28
+ source {
+ address 77.68.27.28
+ mac-address !00:50:56:27:c6:2d
+ }
+ }
+ rule 730 {
+ action drop
+ description Anti-spoofing_77.68.84.147
+ source {
+ address 77.68.84.147
+ mac-address !00:50:56:28:d5:4d
+ }
+ }
+ rule 731 {
+ action drop
+ description Anti-spoofing_77.68.3.80
+ source {
+ address 77.68.3.80
+ mac-address !00:50:56:35:66:85
+ }
+ }
+ rule 732 {
+ action drop
+ description Anti-spoofing_77.68.76.44
+ source {
+ address 77.68.76.44
+ mac-address !00:50:56:2b:8f:62
+ }
+ }
+ rule 733 {
+ action drop
+ description Anti-spoofing_77.68.76.47
+ source {
+ address 77.68.76.47
+ mac-address !50:9a:4c:74:52:56
+ }
+ }
+ rule 734 {
+ action drop
+ description Anti-spoofing_77.68.76.74
+ source {
+ address 77.68.76.74
+ mac-address !00:50:56:30:a0:57
+ }
+ }
+ rule 735 {
+ action drop
+ description Anti-spoofing_77.68.5.166
+ source {
+ address 77.68.5.166
+ mac-address !00:50:56:17:e2:18
+ }
+ }
+ rule 736 {
+ action drop
+ description Anti-spoofing_77.68.76.55
+ source {
+ address 77.68.76.55
+ mac-address !00:50:56:0f:46:86
+ }
+ }
+ rule 737 {
+ action drop
+ description Anti-spoofing_77.68.10.142
+ source {
+ address 77.68.10.142
+ mac-address !00:50:56:19:04:d3
+ }
+ }
+ rule 738 {
+ action drop
+ description Anti-spoofing_77.68.77.75
+ source {
+ address 77.68.77.75
+ mac-address !00:50:56:0e:a6:a8
+ }
+ }
+ rule 739 {
+ action drop
+ description Anti-spoofing_77.68.77.239
+ source {
+ address 77.68.77.239
+ mac-address !00:50:56:26:f4:c8
+ }
+ }
+ rule 740 {
+ action drop
+ description Anti-spoofing_213.171.208.176
+ source {
+ address 213.171.208.176
+ mac-address !00:50:56:34:50:f7
+ }
+ }
+ rule 741 {
+ action drop
+ description Anti-spoofing_77.68.4.111
+ source {
+ address 77.68.4.111
+ mac-address !00:50:56:2a:61:0b
+ }
+ }
+ rule 742 {
+ action drop
+ description Anti-spoofing_77.68.118.120
+ source {
+ address 77.68.118.120
+ mac-address !00:50:56:3c:35:39
+ }
+ }
+ rule 743 {
+ action drop
+ description Anti-spoofing_77.68.76.75
+ source {
+ address 77.68.76.75
+ mac-address !00:50:56:2a:42:ca
+ }
+ }
+ rule 744 {
+ action drop
+ description Anti-spoofing_77.68.77.71
+ source {
+ address 77.68.77.71
+ mac-address !00:50:56:38:ae:bf
+ }
+ }
+ rule 745 {
+ action drop
+ description Anti-spoofing_77.68.76.138
+ source {
+ address 77.68.76.138
+ mac-address !00:50:56:14:c0:d8
+ }
+ }
+ rule 746 {
+ action drop
+ description Anti-spoofing_77.68.76.145
+ source {
+ address 77.68.76.145
+ mac-address !00:50:56:3b:e8:48
+ }
+ }
+ rule 747 {
+ action drop
+ description Anti-spoofing_77.68.77.145
+ source {
+ address 77.68.77.145
+ mac-address !00:50:56:12:b0:43
+ }
+ }
+ rule 748 {
+ action drop
+ description Anti-spoofing_77.68.3.121
+ source {
+ address 77.68.3.121
+ mac-address !00:50:56:03:7b:9d
+ }
+ }
+ rule 749 {
+ action drop
+ description Anti-spoofing_77.68.3.144
+ source {
+ address 77.68.3.144
+ mac-address !00:50:56:18:a0:ed
+ }
+ }
+ rule 750 {
+ action drop
+ description Anti-spoofing_77.68.77.68
+ source {
+ address 77.68.77.68
+ mac-address !00:50:56:3c:dc:4f
+ }
+ }
+ rule 751 {
+ action drop
+ description Anti-spoofing_77.68.76.126
+ source {
+ address 77.68.76.126
+ mac-address !00:50:56:0f:d0:ae
+ }
+ }
+ rule 752 {
+ action drop
+ description Anti-spoofing_77.68.76.88
+ source {
+ address 77.68.76.88
+ mac-address !00:50:56:15:d6:12
+ }
+ }
+ rule 753 {
+ action drop
+ description Anti-spoofing_77.68.77.254
+ source {
+ address 77.68.77.254
+ mac-address !00:50:56:0e:5e:74
+ }
+ }
+ rule 754 {
+ action drop
+ description Anti-spoofing_185.132.40.124
+ source {
+ address 185.132.40.124
+ mac-address !00:50:56:08:f8:6a
+ }
+ }
+ rule 755 {
+ action drop
+ description Anti-spoofing_77.68.20.231
+ source {
+ address 77.68.20.231
+ mac-address !00:50:56:05:35:ce
+ }
+ }
+ rule 756 {
+ action drop
+ description Anti-spoofing_77.68.77.181
+ source {
+ address 77.68.77.181
+ mac-address !00:50:56:20:03:6f
+ }
+ }
+ rule 757 {
+ action drop
+ description Anti-spoofing_77.68.22.146
+ source {
+ address 77.68.22.146
+ mac-address !00:50:56:0e:85:95
+ }
+ }
+ rule 758 {
+ action drop
+ description Anti-spoofing_77.68.112.75
+ source {
+ address 77.68.112.75
+ mac-address !00:50:56:09:33:e6
+ }
+ }
+ rule 759 {
+ action drop
+ description Anti-spoofing_77.68.4.22
+ source {
+ address 77.68.4.22
+ mac-address !00:50:56:14:be:3f
+ }
+ }
+ rule 760 {
+ action drop
+ description Anti-spoofing_77.68.76.96
+ source {
+ address 77.68.76.96
+ mac-address !00:50:56:32:91:fb
+ }
+ }
+ rule 761 {
+ action drop
+ description Anti-spoofing_77.68.3.161
+ source {
+ address 77.68.3.161
+ mac-address !00:50:56:12:82:40
+ }
+ }
+ rule 762 {
+ action drop
+ description Anti-spoofing_109.228.37.10
+ source {
+ address 109.228.37.10
+ mac-address !00:50:56:0a:ef:ab
+ }
+ }
+ rule 763 {
+ action drop
+ description Anti-spoofing_77.68.76.228
+ source {
+ address 77.68.76.228
+ mac-address !00:50:56:2b:39:b1
+ }
+ }
+ rule 764 {
+ action drop
+ description Anti-spoofing_77.68.121.94
+ source {
+ address 77.68.121.94
+ mac-address !00:50:56:0a:d7:68
+ }
+ }
+ rule 765 {
+ action drop
+ description Anti-spoofing_77.68.3.194
+ source {
+ address 77.68.3.194
+ mac-address !00:50:56:10:90:6a
+ }
+ }
+ rule 766 {
+ action drop
+ description Anti-spoofing_77.68.76.112
+ source {
+ address 77.68.76.112
+ mac-address !00:50:56:24:e2:52
+ }
+ }
+ rule 767 {
+ action drop
+ description Anti-spoofing_77.68.100.77
+ source {
+ address 77.68.100.77
+ mac-address !00:50:56:0e:f3:7a
+ }
+ }
+ rule 768 {
+ action drop
+ description Anti-spoofing_77.68.3.247
+ source {
+ address 77.68.3.247
+ mac-address !00:50:56:29:30:8a
+ }
+ }
+ rule 769 {
+ action drop
+ description Anti-spoofing_77.68.77.157
+ source {
+ address 77.68.77.157
+ mac-address !00:50:56:36:39:a5
+ }
+ }
+ rule 770 {
+ action drop
+ description Anti-spoofing_77.68.29.65
+ source {
+ address 77.68.29.65
+ mac-address !00:50:56:2e:1b:f9
+ }
+ }
+ rule 771 {
+ action drop
+ description Anti-spoofing_77.68.74.152
+ source {
+ address 77.68.74.152
+ mac-address !00:50:56:16:1d:31
+ }
+ }
+ rule 772 {
+ action drop
+ description Anti-spoofing_185.132.39.145
+ source {
+ address 185.132.39.145
+ mac-address !00:50:56:03:77:75
+ }
+ }
+ rule 773 {
+ action drop
+ description Anti-spoofing_77.68.28.139
+ source {
+ address 77.68.28.139
+ mac-address !00:50:56:25:a9:de
+ }
+ }
+ rule 774 {
+ action drop
+ description Anti-spoofing_77.68.77.33
+ source {
+ address 77.68.77.33
+ mac-address !00:50:56:09:16:76
+ }
+ }
+ rule 775 {
+ action drop
+ description Anti-spoofing_77.68.77.137
+ source {
+ address 77.68.77.137
+ mac-address !00:50:56:15:b6:84
+ }
+ }
+ rule 776 {
+ action drop
+ description Anti-spoofing_77.68.76.244
+ source {
+ address 77.68.76.244
+ mac-address !00:50:56:21:11:27
+ }
+ }
+ rule 777 {
+ action drop
+ description Anti-spoofing_77.68.77.92
+ source {
+ address 77.68.77.92
+ mac-address !00:50:56:11:58:f5
+ }
+ }
+ rule 778 {
+ action drop
+ description Anti-spoofing_77.68.7.227
+ source {
+ address 77.68.7.227
+ mac-address !00:50:56:34:a8:22
+ }
+ }
+ rule 779 {
+ action drop
+ description Anti-spoofing_77.68.76.111
+ source {
+ address 77.68.76.111
+ mac-address !00:50:56:3e:44:ea
+ }
+ }
+ rule 780 {
+ action drop
+ description Anti-spoofing_77.68.76.185
+ source {
+ address 77.68.76.185
+ mac-address !00:50:56:1b:75:e8
+ }
+ }
+ rule 781 {
+ action drop
+ description Anti-spoofing_77.68.76.208
+ source {
+ address 77.68.76.208
+ mac-address !50:9a:4c:98:c2:68
+ }
+ }
+ rule 782 {
+ action drop
+ description Anti-spoofing_77.68.76.150
+ source {
+ address 77.68.76.150
+ mac-address !50:9a:4c:98:5c:c0
+ }
+ }
+ rule 783 {
+ action drop
+ description Anti-spoofing_77.68.77.208
+ source {
+ address 77.68.77.208
+ mac-address !50:9a:4c:98:5c:c0
+ }
+ }
+ rule 784 {
+ action drop
+ description Anti-spoofing_77.68.103.56
+ source {
+ address 77.68.103.56
+ mac-address !00:50:56:05:2f:9e
+ }
+ }
+ rule 785 {
+ action drop
+ description Anti-spoofing_77.68.125.60
+ source {
+ address 77.68.125.60
+ mac-address !00:50:56:2a:4a:20
+ }
+ }
+ rule 786 {
+ action drop
+ description Anti-spoofing_77.68.76.42
+ source {
+ address 77.68.76.42
+ mac-address !00:50:56:3e:44:ea
+ }
+ }
+ rule 787 {
+ action drop
+ description Anti-spoofing_77.68.26.216
+ source {
+ address 77.68.26.216
+ mac-address !00:50:56:07:56:c4
+ }
+ }
+ rule 788 {
+ action drop
+ description Anti-spoofing_77.68.76.164
+ source {
+ address 77.68.76.164
+ mac-address !00:50:56:1c:df:57
+ }
+ }
+ rule 789 {
+ action drop
+ description Anti-spoofing_77.68.89.72
+ source {
+ address 77.68.89.72
+ mac-address !00:50:56:1b:84:5c
+ }
+ }
+ rule 790 {
+ action drop
+ description Anti-spoofing_77.68.76.181
+ source {
+ address 77.68.76.181
+ mac-address !00:50:56:36:5d:1e
+ }
+ }
+ rule 791 {
+ action drop
+ description Anti-spoofing_77.68.3.52
+ source {
+ address 77.68.3.52
+ mac-address !00:50:56:12:e2:00
+ }
+ }
+ rule 792 {
+ action drop
+ description Anti-spoofing_77.68.77.207
+ source {
+ address 77.68.77.207
+ mac-address !00:50:56:16:24:34
+ }
+ }
+ rule 793 {
+ action drop
+ description Anti-spoofing_77.68.81.44
+ source {
+ address 77.68.81.44
+ mac-address !00:50:56:1a:2f:81
+ }
+ }
+ rule 794 {
+ action drop
+ description Anti-spoofing_77.68.28.145
+ source {
+ address 77.68.28.145
+ mac-address !00:50:56:39:78:a6
+ }
+ }
+ rule 795 {
+ action drop
+ description Anti-spoofing_77.68.76.49
+ source {
+ address 77.68.76.49
+ mac-address !00:50:56:08:ae:5e
+ }
+ }
+ rule 796 {
+ action drop
+ description Anti-spoofing_77.68.77.227
+ source {
+ address 77.68.77.227
+ mac-address !ac:1f:6b:93:59:d4
+ }
+ }
+ rule 797 {
+ action drop
+ description Anti-spoofing_77.68.76.136
+ source {
+ address 77.68.76.136
+ mac-address !00:50:56:0b:b2:b0
+ }
+ }
+ rule 798 {
+ action drop
+ description Anti-spoofing_77.68.77.102
+ source {
+ address 77.68.77.102
+ mac-address !00:50:56:3d:91:75
+ }
+ }
+ rule 799 {
+ action drop
+ description Anti-spoofing_77.68.5.155
+ source {
+ address 77.68.5.155
+ mac-address !00:50:56:13:33:02
+ }
+ }
+ rule 801 {
+ action drop
+ description Anti-spoofing_77.68.88.100
+ source {
+ address 77.68.88.100
+ mac-address !00:50:56:08:dc:d0
+ }
+ }
+ rule 802 {
+ action drop
+ description Anti-spoofing_77.68.72.254
+ source {
+ address 77.68.72.254
+ mac-address !00:50:56:0c:c2:8d
+ }
+ }
+ rule 803 {
+ action drop
+ description Anti-spoofing_77.68.77.74
+ source {
+ address 77.68.77.74
+ mac-address !00:50:56:18:d8:12
+ }
+ }
+ rule 804 {
+ action drop
+ description Anti-spoofing_77.68.76.77
+ source {
+ address 77.68.76.77
+ mac-address !ac:1f:6b:4d:bd:60
+ }
+ }
+ rule 805 {
+ action drop
+ description Anti-spoofing_77.68.76.123
+ source {
+ address 77.68.76.123
+ mac-address !00:50:56:38:5b:9d
+ }
+ }
+ rule 806 {
+ action drop
+ description Anti-spoofing_77.68.4.24
+ source {
+ address 77.68.4.24
+ mac-address !00:50:56:16:54:a8
+ }
+ }
+ rule 807 {
+ action drop
+ description Anti-spoofing_213.171.214.167
+ source {
+ address 213.171.214.167
+ mac-address !00:50:56:13:7d:80
+ }
+ }
+ rule 808 {
+ action drop
+ description Anti-spoofing_77.68.112.213
+ source {
+ address 77.68.112.213
+ mac-address !00:50:56:0b:ec:f2
+ }
+ }
+ rule 809 {
+ action drop
+ description Anti-spoofing_185.132.40.166
+ source {
+ address 185.132.40.166
+ mac-address !00:50:56:22:c7:e0
+ }
+ }
+ rule 810 {
+ action drop
+ description Anti-spoofing_77.68.76.31
+ source {
+ address 77.68.76.31
+ mac-address !00:50:56:38:22:33
+ }
+ }
+ rule 811 {
+ action drop
+ description Anti-spoofing_77.68.76.148
+ source {
+ address 77.68.76.148
+ mac-address !00:50:56:16:6c:9c
+ }
+ }
+ rule 812 {
+ action drop
+ description Anti-spoofing_77.68.93.246
+ source {
+ address 77.68.93.246
+ mac-address !00:50:56:29:2c:65
+ }
+ }
+ rule 813 {
+ action drop
+ description Anti-spoofing_77.68.77.120
+ source {
+ address 77.68.77.120
+ mac-address !00:50:56:39:92:1c
+ }
+ }
+ rule 814 {
+ action drop
+ description Anti-spoofing_77.68.7.123
+ source {
+ address 77.68.7.123
+ mac-address !00:50:56:33:46:a6
+ }
+ }
+ rule 815 {
+ action drop
+ description Anti-spoofing_77.68.76.183
+ source {
+ address 77.68.76.183
+ mac-address !00:50:56:39:92:1c
+ }
+ }
+ rule 816 {
+ action drop
+ description Anti-spoofing_77.68.112.90
+ source {
+ address 77.68.112.90
+ mac-address !00:50:56:29:f8:91
+ }
+ }
+ rule 817 {
+ action drop
+ description Anti-spoofing_77.68.50.90
+ source {
+ address 77.68.50.90
+ mac-address !00:50:56:11:d5:cb
+ }
+ }
+ rule 818 {
+ action drop
+ description Anti-spoofing_77.68.3.61
+ source {
+ address 77.68.3.61
+ mac-address !00:50:56:03:0b:87
+ }
+ }
+ rule 819 {
+ action drop
+ description Anti-spoofing_213.171.213.42
+ source {
+ address 213.171.213.42
+ mac-address !00:50:56:37:90:bd
+ }
+ }
+ rule 820 {
+ action drop
+ description Anti-spoofing_77.68.77.107
+ source {
+ address 77.68.77.107
+ mac-address !00:50:56:1e:74:40
+ }
+ }
+ rule 821 {
+ action drop
+ description Anti-spoofing_77.68.89.183
+ source {
+ address 77.68.89.183
+ mac-address !00:50:56:04:b9:ce
+ }
+ }
+ rule 822 {
+ action drop
+ description Anti-spoofing_77.68.112.83
+ source {
+ address 77.68.112.83
+ mac-address !00:50:56:38:03:ce
+ }
+ }
+ rule 823 {
+ action drop
+ description Anti-spoofing_77.68.76.141
+ source {
+ address 77.68.76.141
+ mac-address !00:50:56:12:2e:7c
+ }
+ }
+ rule 825 {
+ action drop
+ description Anti-spoofing_77.68.76.105
+ source {
+ address 77.68.76.105
+ mac-address !00:50:56:00:0b:f6
+ }
+ }
+ rule 826 {
+ action drop
+ description Anti-spoofing_77.68.76.251
+ source {
+ address 77.68.76.251
+ mac-address !00:50:56:34:1e:f4
+ }
+ }
+ rule 827 {
+ action drop
+ description Anti-spoofing_77.68.6.202
+ source {
+ address 77.68.6.202
+ mac-address !00:50:56:17:65:5f
+ }
+ }
+ rule 828 {
+ action drop
+ description Anti-spoofing_88.208.198.92
+ source {
+ address 88.208.198.92
+ mac-address !00:50:56:0c:5d:98
+ }
+ }
+ rule 829 {
+ action drop
+ description Anti-spoofing_77.68.76.249
+ source {
+ address 77.68.76.249
+ mac-address !00:50:56:01:18:09
+ }
+ }
+ rule 830 {
+ action drop
+ description Anti-spoofing_77.68.30.164
+ source {
+ address 77.68.30.164
+ mac-address !00:50:56:3c:2a:3a
+ }
+ }
+ rule 831 {
+ action drop
+ description Anti-spoofing_77.68.77.59
+ source {
+ address 77.68.77.59
+ mac-address !00:50:56:18:09:81
+ }
+ }
+ rule 832 {
+ action drop
+ description Anti-spoofing_77.68.76.40
+ source {
+ address 77.68.76.40
+ mac-address !00:50:56:13:e6:96
+ }
+ }
+ rule 833 {
+ action drop
+ description Anti-spoofing_77.68.88.164
+ source {
+ address 77.68.88.164
+ mac-address !00:50:56:07:f9:c8
+ }
+ }
+ rule 834 {
+ action drop
+ description Anti-spoofing_77.68.77.37
+ source {
+ address 77.68.77.37
+ mac-address !00:50:56:2f:1e:7b
+ }
+ }
+ rule 835 {
+ action drop
+ description Anti-spoofing_185.132.39.99
+ source {
+ address 185.132.39.99
+ mac-address !00:50:56:1d:4e:dd
+ }
+ }
+ rule 836 {
+ action drop
+ description Anti-spoofing_77.68.121.127
+ source {
+ address 77.68.121.127
+ mac-address !00:50:56:29:fd:29
+ }
+ }
+ rule 837 {
+ action drop
+ description Anti-spoofing_77.68.77.65
+ source {
+ address 77.68.77.65
+ mac-address !00:50:56:30:1f:8b
+ }
+ }
+ rule 838 {
+ action drop
+ description Anti-spoofing_77.68.27.211
+ source {
+ address 77.68.27.211
+ mac-address !00:50:56:25:b4:d1
+ }
+ }
+ rule 839 {
+ action drop
+ description Anti-spoofing_77.68.24.112
+ source {
+ address 77.68.24.112
+ mac-address !00:50:56:06:50:e8
+ }
+ }
+ rule 840 {
+ action drop
+ description Anti-spoofing_109.228.38.201
+ source {
+ address 109.228.38.201
+ mac-address !00:50:56:36:33:0c
+ }
+ }
+ rule 841 {
+ action drop
+ description Anti-spoofing_77.68.115.17
+ source {
+ address 77.68.115.17
+ mac-address !00:50:56:16:da:60
+ }
+ }
+ rule 842 {
+ action drop
+ description Anti-spoofing_185.132.36.60
+ source {
+ address 185.132.36.60
+ mac-address !00:50:56:14:a7:b2
+ }
+ }
+ rule 843 {
+ action drop
+ description Anti-spoofing_77.68.76.231
+ source {
+ address 77.68.76.231
+ mac-address !00:50:56:03:c5:bc
+ }
+ }
+ rule 844 {
+ action drop
+ description Anti-spoofing_185.132.37.23
+ source {
+ address 185.132.37.23
+ mac-address !00:50:56:27:46:b8
+ }
+ }
+ rule 845 {
+ action drop
+ description Anti-spoofing_109.228.35.84
+ source {
+ address 109.228.35.84
+ mac-address !00:50:56:17:74:b7
+ }
+ }
+ rule 846 {
+ action drop
+ description Anti-spoofing_77.68.11.140
+ source {
+ address 77.68.11.140
+ mac-address !00:50:56:08:ce:61
+ }
+ }
+ rule 848 {
+ action drop
+ description Anti-spoofing_77.68.77.24
+ source {
+ address 77.68.77.24
+ mac-address !00:50:56:28:65:cb
+ }
+ }
+ rule 849 {
+ action drop
+ description Anti-spoofing_77.68.78.113
+ source {
+ address 77.68.78.113
+ mac-address !00:50:56:2c:5a:e3
+ }
+ }
+ rule 850 {
+ action drop
+ description Anti-spoofing_185.132.39.219
+ source {
+ address 185.132.39.219
+ mac-address !00:50:56:11:0d:fd
+ }
+ }
+ rule 851 {
+ action drop
+ description Anti-spoofing_185.132.40.11
+ source {
+ address 185.132.40.11
+ mac-address !00:50:56:27:50:a3
+ }
+ }
+ rule 852 {
+ action drop
+ description Anti-spoofing_77.68.23.64
+ source {
+ address 77.68.23.64
+ mac-address !00:50:56:0a:b2:3c
+ }
+ }
+ rule 853 {
+ action drop
+ description Anti-spoofing_185.132.37.133
+ source {
+ address 185.132.37.133
+ mac-address !00:50:56:0b:0a:21
+ }
+ }
+ rule 854 {
+ action drop
+ description Anti-spoofing_77.68.85.27
+ source {
+ address 77.68.85.27
+ mac-address !00:50:56:34:82:24
+ }
+ }
+ rule 855 {
+ action drop
+ description Anti-spoofing_77.68.26.221
+ source {
+ address 77.68.26.221
+ mac-address !00:50:56:30:56:a2
+ }
+ }
+ rule 856 {
+ action drop
+ description Anti-spoofing_77.68.76.243
+ source {
+ address 77.68.76.243
+ mac-address !00:50:56:1c:a0:2d
+ }
+ }
+ rule 857 {
+ action drop
+ description Anti-spoofing_77.68.116.52
+ source {
+ address 77.68.116.52
+ mac-address !00:50:56:2b:59:35
+ }
+ }
+ rule 858 {
+ action drop
+ description Anti-spoofing_77.68.120.26
+ source {
+ address 77.68.120.26
+ mac-address !00:50:56:07:3b:2b
+ }
+ }
+ rule 859 {
+ action drop
+ description Anti-spoofing_185.132.40.56
+ source {
+ address 185.132.40.56
+ mac-address !00:50:56:21:cb:e3
+ }
+ }
+ rule 860 {
+ action drop
+ description Anti-spoofing_213.171.210.155
+ source {
+ address 213.171.210.155
+ mac-address !00:50:56:2a:53:9f
+ }
+ }
+ rule 861 {
+ action drop
+ description Anti-spoofing_185.132.43.157
+ source {
+ address 185.132.43.157
+ mac-address !00:50:56:27:e6:d5
+ }
+ }
+ rule 862 {
+ action drop
+ description Anti-spoofing_77.68.4.252
+ source {
+ address 77.68.4.252
+ mac-address !00:50:56:08:ff:66
+ }
+ }
+ rule 863 {
+ action drop
+ description Anti-spoofing_77.68.77.63
+ source {
+ address 77.68.77.63
+ mac-address !00:50:56:10:9c:ca
+ }
+ }
+ rule 864 {
+ action drop
+ description Anti-spoofing_77.68.20.161
+ source {
+ address 77.68.20.161
+ mac-address !00:50:56:0d:06:6f
+ }
+ }
+ rule 865 {
+ action drop
+ description Anti-spoofing_77.68.117.45
+ source {
+ address 77.68.117.45
+ mac-address !00:50:56:05:e0:11
+ }
+ }
+ rule 866 {
+ action drop
+ description Anti-spoofing_77.68.76.234
+ source {
+ address 77.68.76.234
+ mac-address !00:50:56:3a:d3:9e
+ }
+ }
+ rule 867 {
+ action drop
+ description Anti-spoofing_185.132.40.90
+ source {
+ address 185.132.40.90
+ mac-address !00:50:56:2c:90:4f
+ }
+ }
+ rule 868 {
+ action drop
+ description Anti-spoofing_77.68.77.90
+ source {
+ address 77.68.77.90
+ mac-address !00:50:56:1d:ec:a2
+ }
+ }
+ rule 869 {
+ action drop
+ description Anti-spoofing_77.68.76.93
+ source {
+ address 77.68.76.93
+ mac-address !00:50:56:19:cb:e8
+ }
+ }
+ rule 870 {
+ action drop
+ description Anti-spoofing_77.68.26.166
+ source {
+ address 77.68.26.166
+ mac-address !00:50:56:1e:34:14
+ }
+ }
+ rule 871 {
+ action drop
+ description Anti-spoofing_185.132.40.244
+ source {
+ address 185.132.40.244
+ mac-address !00:50:56:14:a7:b2
+ }
+ }
+ rule 872 {
+ action drop
+ description Anti-spoofing_77.68.77.77
+ source {
+ address 77.68.77.77
+ mac-address !00:50:56:0c:9b:e1
+ }
+ }
+ rule 873 {
+ action drop
+ description Anti-spoofing_77.68.27.57
+ source {
+ address 77.68.27.57
+ mac-address !00:50:56:3e:06:ca
+ }
+ }
+ rule 874 {
+ action drop
+ description Anti-spoofing_77.68.7.114
+ source {
+ address 77.68.7.114
+ mac-address !00:50:56:33:0d:5e
+ }
+ }
+ rule 875 {
+ action drop
+ description Anti-spoofing_109.228.36.229
+ source {
+ address 109.228.36.229
+ mac-address !00:50:56:32:a6:83
+ }
+ }
+ rule 876 {
+ action drop
+ description Anti-spoofing_77.68.77.151
+ source {
+ address 77.68.77.151
+ mac-address !00:50:56:0a:e4:20
+ }
+ }
+ rule 877 {
+ action drop
+ description Anti-spoofing_77.68.76.92
+ source {
+ address 77.68.76.92
+ mac-address !00:50:56:2b:a5:38
+ }
+ }
+ rule 878 {
+ action drop
+ description Anti-spoofing_77.68.49.159
+ source {
+ address 77.68.49.159
+ mac-address !00:50:56:16:4f:24
+ }
+ }
+ rule 879 {
+ action drop
+ description Anti-spoofing_77.68.77.38
+ source {
+ address 77.68.77.38
+ mac-address !00:50:56:2c:fe:a1
+ }
+ }
+ rule 880 {
+ action drop
+ description Anti-spoofing_77.68.20.217
+ source {
+ address 77.68.20.217
+ mac-address !00:50:56:3a:61:47
+ }
+ }
+ rule 881 {
+ action drop
+ description Anti-spoofing_77.68.92.92
+ source {
+ address 77.68.92.92
+ mac-address !00:50:56:1b:64:85
+ }
+ }
+ rule 882 {
+ action drop
+ description Anti-spoofing_77.68.76.124
+ source {
+ address 77.68.76.124
+ mac-address !00:50:56:0e:c1:e4
+ }
+ }
+ rule 884 {
+ action drop
+ description Anti-spoofing_77.68.126.101
+ source {
+ address 77.68.126.101
+ mac-address !00:50:56:31:d1:a3
+ }
+ }
+ rule 885 {
+ action drop
+ description Anti-spoofing_77.68.76.235
+ source {
+ address 77.68.76.235
+ mac-address !00:50:56:15:d1:66
+ }
+ }
+ rule 886 {
+ action drop
+ description Anti-spoofing_77.68.77.95
+ source {
+ address 77.68.77.95
+ mac-address !00:50:56:39:c6:52
+ }
+ }
+ rule 887 {
+ action drop
+ description Anti-spoofing_77.68.26.228
+ source {
+ address 77.68.26.228
+ mac-address !00:50:56:03:ab:9e
+ }
+ }
+ rule 888 {
+ action drop
+ description Anti-spoofing_77.68.32.118
+ source {
+ address 77.68.32.118
+ mac-address !00:50:56:0e:db:9d
+ }
+ }
+ rule 889 {
+ action drop
+ description Anti-spoofing_77.68.24.172
+ source {
+ address 77.68.24.172
+ mac-address !00:50:56:0e:2a:9c
+ }
+ }
+ rule 891 {
+ action drop
+ description Anti-spoofing_77.68.77.190
+ source {
+ address 77.68.77.190
+ mac-address !00:50:56:31:e8:fb
+ }
+ }
+ rule 892 {
+ action drop
+ description Anti-spoofing_77.68.33.197
+ source {
+ address 77.68.33.197
+ mac-address !00:50:56:2b:27:c4
+ }
+ }
+ rule 893 {
+ action drop
+ description Anti-spoofing_213.171.210.177
+ source {
+ address 213.171.210.177
+ mac-address !00:50:56:04:96:31
+ }
+ }
+ rule 894 {
+ action drop
+ description Anti-spoofing_185.132.41.73
+ source {
+ address 185.132.41.73
+ mac-address !00:50:56:35:b4:a5
+ }
+ }
+ rule 895 {
+ action drop
+ description Anti-spoofing_77.68.21.78
+ source {
+ address 77.68.21.78
+ mac-address !00:50:56:23:87:f2
+ }
+ }
+ rule 896 {
+ action drop
+ description Anti-spoofing_77.68.77.209
+ source {
+ address 77.68.77.209
+ mac-address !00:50:56:3b:95:06
+ }
+ }
+ rule 897 {
+ action drop
+ description Anti-spoofing_88.208.215.19
+ source {
+ address 88.208.215.19
+ mac-address !00:50:56:1f:e1:4b
+ }
+ }
+ rule 898 {
+ action drop
+ description Anti-spoofing_77.68.77.214
+ source {
+ address 77.68.77.214
+ mac-address !00:50:56:2b:03:2b
+ }
+ }
+ rule 899 {
+ action drop
+ description Anti-spoofing_77.68.76.91
+ source {
+ address 77.68.76.91
+ mac-address !00:50:56:3b:3c:fb
+ }
+ }
+ rule 900 {
+ action drop
+ description Anti-spoofing_77.68.119.92
+ source {
+ address 77.68.119.92
+ mac-address !00:50:56:25:ba:8c
+ }
+ }
+ rule 901 {
+ action drop
+ description Anti-spoofing_77.68.77.79
+ source {
+ address 77.68.77.79
+ mac-address !00:50:56:28:f5:72
+ }
+ }
+ rule 902 {
+ action drop
+ description Anti-spoofing_77.68.75.45
+ source {
+ address 77.68.75.45
+ mac-address !00:50:56:04:51:74
+ }
+ }
+ rule 903 {
+ action drop
+ description Anti-spoofing_109.228.56.185
+ source {
+ address 109.228.56.185
+ mac-address !00:50:56:13:e5:07
+ }
+ }
+ rule 904 {
+ action drop
+ description Anti-spoofing_185.132.43.6
+ source {
+ address 185.132.43.6
+ mac-address !00:50:56:38:d1:d5
+ }
+ }
+ rule 905 {
+ action drop
+ description Anti-spoofing_77.68.117.202
+ source {
+ address 77.68.117.202
+ mac-address !00:50:56:01:b2:9f
+ }
+ }
+ rule 906 {
+ action drop
+ description Anti-spoofing_77.68.86.40
+ source {
+ address 77.68.86.40
+ mac-address !00:50:56:03:e2:49
+ }
+ }
+ rule 907 {
+ action drop
+ description Anti-spoofing_77.68.49.126
+ source {
+ address 77.68.49.126
+ mac-address !00:50:56:3b:47:f3
+ }
+ }
+ rule 909 {
+ action drop
+ description Anti-spoofing_77.68.77.100
+ source {
+ address 77.68.77.100
+ mac-address !00:50:56:34:d7:5b
+ }
+ }
+ rule 910 {
+ action drop
+ description Anti-spoofing_109.228.46.196
+ source {
+ address 109.228.46.196
+ mac-address !00:50:56:1a:a0:0e
+ }
+ }
+ rule 911 {
+ action drop
+ description Anti-spoofing_77.68.77.72
+ source {
+ address 77.68.77.72
+ mac-address !00:50:56:1e:67:f7
+ }
+ }
+ rule 912 {
+ action drop
+ description Anti-spoofing_185.132.43.28
+ source {
+ address 185.132.43.28
+ mac-address !00:50:56:35:a5:36
+ }
+ }
+ rule 913 {
+ action drop
+ description Anti-spoofing_77.68.103.19
+ source {
+ address 77.68.103.19
+ mac-address !00:50:56:27:34:a3
+ }
+ }
+ rule 914 {
+ action drop
+ description Anti-spoofing_77.68.118.104
+ source {
+ address 77.68.118.104
+ mac-address !00:50:56:2d:f8:d7
+ }
+ }
+ rule 915 {
+ action drop
+ description Anti-spoofing_77.68.116.183
+ source {
+ address 77.68.116.183
+ mac-address !00:50:56:17:23:d4
+ }
+ }
+ rule 916 {
+ action drop
+ description Anti-spoofing_77.68.76.107
+ source {
+ address 77.68.76.107
+ mac-address !00:50:56:36:c0:da
+ }
+ }
+ rule 917 {
+ action drop
+ description Anti-spoofing_77.68.93.164
+ source {
+ address 77.68.93.164
+ mac-address !00:50:56:36:cd:1a
+ }
+ }
+ rule 918 {
+ action drop
+ description Anti-spoofing_77.68.5.241
+ source {
+ address 77.68.5.241
+ mac-address !00:50:56:11:2d:22
+ }
+ }
+ rule 919 {
+ action drop
+ description Anti-spoofing_185.132.43.98
+ source {
+ address 185.132.43.98
+ mac-address !00:50:56:20:7b:87
+ }
+ }
+ rule 920 {
+ action drop
+ description Anti-spoofing_77.68.76.241
+ source {
+ address 77.68.76.241
+ mac-address !00:50:56:00:50:f6
+ }
+ }
+ rule 921 {
+ action drop
+ description Anti-spoofing_77.68.74.232
+ source {
+ address 77.68.74.232
+ mac-address !00:50:56:19:df:41
+ }
+ }
+ rule 922 {
+ action drop
+ description Anti-spoofing_77.68.76.26
+ source {
+ address 77.68.76.26
+ mac-address !00:50:56:36:c0:da
+ }
+ }
+ rule 923 {
+ action drop
+ description Anti-spoofing_77.68.28.207
+ source {
+ address 77.68.28.207
+ mac-address !00:50:56:36:41:da
+ }
+ }
+ rule 924 {
+ action drop
+ description Anti-spoofing_77.68.29.178
+ source {
+ address 77.68.29.178
+ mac-address !00:50:56:21:81:be
+ }
+ }
+ rule 925 {
+ action drop
+ description Anti-spoofing_77.68.121.119
+ source {
+ address 77.68.121.119
+ mac-address !00:50:56:0b:d8:e1
+ }
+ }
+ rule 926 {
+ action drop
+ description Anti-spoofing_77.68.126.22
+ source {
+ address 77.68.126.22
+ mac-address !00:50:56:32:62:56
+ }
+ }
+ rule 927 {
+ action drop
+ description Anti-spoofing_109.228.61.31
+ source {
+ address 109.228.61.31
+ mac-address !00:50:56:21:a0:04
+ }
+ }
+ rule 928 {
+ action drop
+ description Anti-spoofing_77.68.114.205
+ source {
+ address 77.68.114.205
+ mac-address !00:50:56:2a:f1:3f
+ }
+ }
+ rule 929 {
+ action drop
+ description Anti-spoofing_77.68.75.113
+ source {
+ address 77.68.75.113
+ mac-address !00:50:56:33:6c:b9
+ }
+ }
+ rule 930 {
+ action drop
+ description Anti-spoofing_77.68.79.206
+ source {
+ address 77.68.79.206
+ mac-address !00:50:56:36:86:66
+ }
+ }
+ rule 931 {
+ action drop
+ description Anti-spoofing_88.208.198.64
+ source {
+ address 88.208.198.64
+ mac-address !00:50:56:39:2c:fe
+ }
+ }
+ rule 932 {
+ action drop
+ description Anti-spoofing_77.68.77.161
+ source {
+ address 77.68.77.161
+ mac-address !00:50:56:0a:7e:6c
+ }
+ }
+ rule 933 {
+ action drop
+ description Anti-spoofing_77.68.114.237
+ source {
+ address 77.68.114.237
+ mac-address !00:50:56:16:f4:39
+ }
+ }
+ rule 934 {
+ action drop
+ description Anti-spoofing_109.228.36.119
+ source {
+ address 109.228.36.119
+ mac-address !00:50:56:28:63:37
+ }
+ }
+ rule 935 {
+ action drop
+ description Anti-spoofing_77.68.76.254
+ source {
+ address 77.68.76.254
+ mac-address !00:50:56:3b:49:08
+ }
+ }
+ rule 936 {
+ action drop
+ description Anti-spoofing_77.68.77.231
+ source {
+ address 77.68.77.231
+ mac-address !00:50:56:36:78:72
+ }
+ }
+ rule 937 {
+ action drop
+ description Anti-spoofing_77.68.7.172
+ source {
+ address 77.68.7.172
+ mac-address !00:50:56:19:39:45
+ }
+ }
+ rule 938 {
+ action drop
+ description Anti-spoofing_77.68.77.62
+ source {
+ address 77.68.77.62
+ mac-address !00:50:56:04:8c:b4
+ }
+ }
+ rule 939 {
+ action drop
+ description Anti-spoofing_77.68.77.215
+ source {
+ address 77.68.77.215
+ mac-address !00:50:56:35:f3:5a
+ }
+ }
+ rule 940 {
+ action drop
+ description Anti-spoofing_77.68.6.105
+ source {
+ address 77.68.6.105
+ mac-address !00:50:56:03:0e:07
+ }
+ }
+ rule 941 {
+ action drop
+ description Anti-spoofing_77.68.33.37
+ source {
+ address 77.68.33.37
+ mac-address !00:50:56:00:6b:a3
+ }
+ }
+ rule 942 {
+ action drop
+ description Anti-spoofing_77.68.4.180
+ source {
+ address 77.68.4.180
+ mac-address !00:50:56:11:6c:dc
+ }
+ }
+ rule 943 {
+ action drop
+ description Anti-spoofing_77.68.78.229
+ source {
+ address 77.68.78.229
+ mac-address !00:50:56:1e:58:2f
+ }
+ }
+ rule 944 {
+ action drop
+ description Anti-spoofing_77.68.73.73
+ source {
+ address 77.68.73.73
+ mac-address !00:50:56:38:d7:1a
+ }
+ }
+ rule 945 {
+ action drop
+ description Anti-spoofing_77.68.2.215
+ source {
+ address 77.68.2.215
+ mac-address !00:50:56:31:3c:87
+ }
+ }
+ rule 946 {
+ action drop
+ description Anti-spoofing_77.68.48.81
+ source {
+ address 77.68.48.81
+ mac-address !00:50:56:3a:13:df
+ }
+ }
+ rule 947 {
+ action drop
+ description Anti-spoofing_213.171.214.102
+ source {
+ address 213.171.214.102
+ mac-address !00:50:56:00:60:5a
+ }
+ }
+ rule 948 {
+ action drop
+ description Anti-spoofing_77.68.123.177
+ source {
+ address 77.68.123.177
+ mac-address !00:50:56:3c:07:ef
+ }
+ }
+ rule 949 {
+ action drop
+ description Anti-spoofing_77.68.7.160
+ source {
+ address 77.68.7.160
+ mac-address !00:50:56:09:6e:79
+ }
+ }
+ rule 950 {
+ action drop
+ description Anti-spoofing_77.68.24.59
+ source {
+ address 77.68.24.59
+ mac-address !00:50:56:3c:b7:c1
+ }
+ }
+ rule 951 {
+ action drop
+ description Anti-spoofing_77.68.80.97
+ source {
+ address 77.68.80.97
+ mac-address !00:50:56:15:cc:c6
+ }
+ }
+ rule 952 {
+ action drop
+ description Anti-spoofing_77.68.7.67
+ source {
+ address 77.68.7.67
+ mac-address !00:50:56:13:92:b7
+ }
+ }
+ rule 953 {
+ action drop
+ description Anti-spoofing_109.228.36.79
+ source {
+ address 109.228.36.79
+ mac-address !00:50:56:17:c9:65
+ }
+ }
+ rule 954 {
+ action drop
+ description Anti-spoofing_77.68.32.43
+ source {
+ address 77.68.32.43
+ mac-address !00:50:56:13:6d:02
+ }
+ }
+ rule 955 {
+ action drop
+ description Anti-spoofing_77.68.90.106
+ source {
+ address 77.68.90.106
+ mac-address !00:50:56:1b:6d:fb
+ }
+ }
+ rule 956 {
+ action drop
+ description Anti-spoofing_77.68.77.174
+ source {
+ address 77.68.77.174
+ mac-address !00:50:56:2a:61:0b
+ }
+ }
+ rule 957 {
+ action drop
+ description Anti-spoofing_77.68.94.181
+ source {
+ address 77.68.94.181
+ mac-address !00:50:56:0b:7c:cc
+ }
+ }
+ rule 958 {
+ action drop
+ description Anti-spoofing_77.68.4.136
+ source {
+ address 77.68.4.136
+ mac-address !00:50:56:10:4d:5c
+ }
+ }
+ rule 959 {
+ action drop
+ description Anti-spoofing_77.68.32.31
+ source {
+ address 77.68.32.31
+ mac-address !00:50:56:0a:f5:03
+ }
+ }
+ rule 960 {
+ action drop
+ description Anti-spoofing_77.68.30.133
+ source {
+ address 77.68.30.133
+ mac-address !00:50:56:3a:96:4e
+ }
+ }
+ rule 961 {
+ action drop
+ description Anti-spoofing_77.68.72.202
+ source {
+ address 77.68.72.202
+ mac-address !00:50:56:2e:ca:a2
+ }
+ }
+ rule 962 {
+ action drop
+ description Anti-spoofing_77.68.81.141
+ source {
+ address 77.68.81.141
+ mac-address !00:50:56:00:07:47
+ }
+ }
+ rule 963 {
+ action drop
+ description Anti-spoofing_77.68.27.54
+ source {
+ address 77.68.27.54
+ mac-address !00:50:56:37:ad:51
+ }
+ }
+ rule 964 {
+ action drop
+ description Anti-spoofing_77.68.32.254
+ source {
+ address 77.68.32.254
+ mac-address !00:50:56:2d:d0:36
+ }
+ }
+ rule 965 {
+ action drop
+ description Anti-spoofing_77.68.10.152
+ source {
+ address 77.68.10.152
+ mac-address !00:50:56:38:d7:1a
+ }
+ }
+ rule 967 {
+ action drop
+ description Anti-spoofing_109.228.47.223
+ source {
+ address 109.228.47.223
+ mac-address !00:50:56:02:f7:24
+ }
+ }
+ rule 968 {
+ action drop
+ description Anti-spoofing_77.68.5.125
+ source {
+ address 77.68.5.125
+ mac-address !00:50:56:16:21:98
+ }
+ }
+ rule 969 {
+ action drop
+ description Anti-spoofing_77.68.119.14
+ source {
+ address 77.68.119.14
+ mac-address !00:50:56:2e:87:33
+ }
+ }
+ rule 970 {
+ action drop
+ description Anti-spoofing_77.68.117.51
+ source {
+ address 77.68.117.51
+ mac-address !00:50:56:17:c0:6c
+ }
+ }
+ rule 971 {
+ action drop
+ description Anti-spoofing_77.68.118.102
+ source {
+ address 77.68.118.102
+ mac-address !00:50:56:3e:06:ca
+ }
+ }
+ rule 972 {
+ action drop
+ description Anti-spoofing_185.132.43.71
+ source {
+ address 185.132.43.71
+ mac-address !00:50:56:2d:6a:8d
+ }
+ }
+ rule 973 {
+ action drop
+ description Anti-spoofing_77.68.112.91
+ source {
+ address 77.68.112.91
+ mac-address !00:50:56:2b:c3:9f
+ }
+ }
+ rule 974 {
+ action drop
+ description Anti-spoofing_77.68.116.232
+ source {
+ address 77.68.116.232
+ mac-address !00:50:56:2a:f9:fd
+ }
+ }
+ rule 976 {
+ action drop
+ description Anti-spoofing_77.68.82.157
+ source {
+ address 77.68.82.157
+ mac-address !00:50:56:3d:81:41
+ }
+ }
+ rule 977 {
+ action drop
+ description Anti-spoofing_77.68.117.222
+ source {
+ address 77.68.117.222
+ mac-address !00:50:56:16:92:58
+ }
+ }
+ rule 978 {
+ action drop
+ description Anti-spoofing_77.68.118.15
+ source {
+ address 77.68.118.15
+ mac-address !00:50:56:28:28:de
+ }
+ }
+ rule 979 {
+ action drop
+ description Anti-spoofing_77.68.117.173
+ source {
+ address 77.68.117.173
+ mac-address !00:50:56:12:7a:57
+ }
+ }
+ rule 980 {
+ action drop
+ description Anti-spoofing_77.68.83.41
+ source {
+ address 77.68.83.41
+ mac-address !00:50:56:13:ef:0e
+ }
+ }
+ rule 981 {
+ action drop
+ description Anti-spoofing_77.68.4.57
+ source {
+ address 77.68.4.57
+ mac-address !00:50:56:23:f0:c3
+ }
+ }
+ rule 983 {
+ action drop
+ description Anti-spoofing_77.68.118.86
+ source {
+ address 77.68.118.86
+ mac-address !00:50:56:03:73:3d
+ }
+ }
+ rule 984 {
+ action drop
+ description Anti-spoofing_109.228.56.26
+ source {
+ address 109.228.56.26
+ mac-address !00:50:56:36:47:8c
+ }
+ }
+ rule 985 {
+ action drop
+ description Anti-spoofing_109.228.38.171
+ source {
+ address 109.228.38.171
+ mac-address !00:50:56:18:da:1c
+ }
+ }
+ rule 986 {
+ action drop
+ description Anti-spoofing_77.68.91.128
+ source {
+ address 77.68.91.128
+ mac-address !00:50:56:34:d0:41
+ }
+ }
+ rule 987 {
+ action drop
+ description Anti-spoofing_77.68.79.89
+ source {
+ address 77.68.79.89
+ mac-address !00:50:56:14:67:52
+ }
+ }
+ rule 988 {
+ action drop
+ description Anti-spoofing_88.208.198.66
+ source {
+ address 88.208.198.66
+ mac-address !00:50:56:3c:e0:8d
+ }
+ }
+ rule 989 {
+ action drop
+ description Anti-spoofing_77.68.118.88
+ source {
+ address 77.68.118.88
+ mac-address !00:50:56:2f:ac:5f
+ }
+ }
+ rule 990 {
+ action drop
+ description Anti-spoofing_109.228.60.215
+ source {
+ address 109.228.60.215
+ mac-address !00:50:56:2b:59:35
+ }
+ }
+ rule 991 {
+ action drop
+ description Anti-spoofing_109.228.55.82
+ source {
+ address 109.228.55.82
+ mac-address !00:50:56:32:15:bc
+ }
+ }
+ rule 992 {
+ action drop
+ description Anti-spoofing_77.68.48.14
+ source {
+ address 77.68.48.14
+ mac-address !00:50:56:2e:2e:5a
+ }
+ }
+ rule 993 {
+ action drop
+ description Anti-spoofing_77.68.7.186
+ source {
+ address 77.68.7.186
+ mac-address !00:50:56:06:63:ae
+ }
+ }
+ rule 994 {
+ action drop
+ description Anti-spoofing_77.68.74.209
+ source {
+ address 77.68.74.209
+ mac-address !00:50:56:01:c5:88
+ }
+ }
+ rule 995 {
+ action drop
+ description Anti-spoofing_77.68.6.32
+ source {
+ address 77.68.6.32
+ mac-address !00:50:56:19:b2:9e
+ }
+ }
+ rule 996 {
+ action drop
+ description Anti-spoofing_77.68.6.210
+ source {
+ address 77.68.6.210
+ mac-address !00:50:56:03:16:58
+ }
+ }
+ rule 997 {
+ action drop
+ description Anti-spoofing_77.68.34.26
+ source {
+ address 77.68.34.26
+ mac-address !00:50:56:16:f0:f3
+ }
+ }
+ rule 998 {
+ action drop
+ description Anti-spoofing_77.68.77.238
+ source {
+ address 77.68.77.238
+ mac-address !00:50:56:25:b8:e7
+ }
+ }
+ rule 999 {
+ action drop
+ description Anti-spoofing_77.68.35.116
+ source {
+ address 77.68.35.116
+ mac-address !00:50:56:22:c6:b9
+ }
+ }
+ rule 1000 {
+ action drop
+ description Anti-spoofing_77.68.23.112
+ source {
+ address 77.68.23.112
+ mac-address !00:50:56:1f:06:9f
+ }
+ }
+ rule 1001 {
+ action drop
+ description Anti-spoofing_77.68.120.241
+ source {
+ address 77.68.120.241
+ mac-address !00:50:56:18:1e:aa
+ }
+ }
+ rule 1002 {
+ action drop
+ description Anti-spoofing_77.68.34.28
+ source {
+ address 77.68.34.28
+ mac-address !00:50:56:24:5e:9a
+ }
+ }
+ rule 1003 {
+ action drop
+ description Anti-spoofing_77.68.122.195
+ source {
+ address 77.68.122.195
+ mac-address !00:50:56:0d:fd:66
+ }
+ }
+ rule 1004 {
+ action drop
+ description Anti-spoofing_77.68.126.14
+ source {
+ address 77.68.126.14
+ mac-address !00:50:56:02:46:82
+ }
+ }
+ rule 1005 {
+ action drop
+ description Anti-spoofing_109.228.38.117
+ source {
+ address 109.228.38.117
+ mac-address !00:50:56:05:55:f0
+ }
+ }
+ rule 1006 {
+ action drop
+ description Anti-spoofing_77.68.33.171
+ source {
+ address 77.68.33.171
+ mac-address !00:50:56:07:69:46
+ }
+ }
+ rule 1007 {
+ action drop
+ description Anti-spoofing_77.68.24.220
+ source {
+ address 77.68.24.220
+ mac-address !00:50:56:1f:53:df
+ }
+ }
+ rule 1008 {
+ action drop
+ description Anti-spoofing_88.208.197.23
+ source {
+ address 88.208.197.23
+ mac-address !00:50:56:23:fa:2f
+ }
+ }
+ rule 1009 {
+ action drop
+ description Anti-spoofing_77.68.80.26
+ source {
+ address 77.68.80.26
+ mac-address !00:50:56:21:23:8e
+ }
+ }
+ rule 1010 {
+ action drop
+ description Anti-spoofing_77.68.32.83
+ source {
+ address 77.68.32.83
+ mac-address !00:50:56:26:5d:1a
+ }
+ }
+ rule 1011 {
+ action drop
+ description Anti-spoofing_77.68.95.42
+ source {
+ address 77.68.95.42
+ mac-address !00:50:56:00:77:9a
+ }
+ }
+ rule 1012 {
+ action drop
+ description Anti-spoofing_213.171.209.217
+ source {
+ address 213.171.209.217
+ mac-address !00:50:56:18:7b:c2
+ }
+ }
+ rule 1014 {
+ action drop
+ description Anti-spoofing_109.228.39.249
+ source {
+ address 109.228.39.249
+ mac-address !00:50:56:0e:4b:f9
+ }
+ }
+ rule 1015 {
+ action drop
+ description Anti-spoofing_77.68.32.86
+ source {
+ address 77.68.32.86
+ mac-address !00:50:56:29:ff:6f
+ }
+ }
+ rule 1016 {
+ action drop
+ description Anti-spoofing_77.68.125.218
+ source {
+ address 77.68.125.218
+ mac-address !00:50:56:2f:4d:38
+ }
+ }
+ rule 1017 {
+ action drop
+ description Anti-spoofing_77.68.17.186
+ source {
+ address 77.68.17.186
+ mac-address !00:50:56:2e:6b:f3
+ }
+ }
+ rule 1018 {
+ action drop
+ description Anti-spoofing_77.68.12.45
+ source {
+ address 77.68.12.45
+ mac-address !00:50:56:15:e4:38
+ }
+ }
+ rule 1019 {
+ action drop
+ description Anti-spoofing_109.228.40.247
+ source {
+ address 109.228.40.247
+ mac-address !00:50:56:20:62:b7
+ }
+ }
+ rule 1020 {
+ action drop
+ description Anti-spoofing_77.68.32.89
+ source {
+ address 77.68.32.89
+ mac-address !00:50:56:2e:21:46
+ }
+ }
+ rule 1022 {
+ action drop
+ description Anti-spoofing_77.68.34.138
+ source {
+ address 77.68.34.138
+ mac-address !00:50:56:10:0a:08
+ }
+ }
+ rule 1023 {
+ action drop
+ description Anti-spoofing_77.68.34.139
+ source {
+ address 77.68.34.139
+ mac-address !00:50:56:0d:24:2f
+ }
+ }
+ rule 1024 {
+ action drop
+ description Anti-spoofing_213.171.208.40
+ source {
+ address 213.171.208.40
+ mac-address !00:50:56:07:df:6e
+ }
+ }
+ rule 1026 {
+ action drop
+ description Anti-spoofing_109.228.40.226
+ source {
+ address 109.228.40.226
+ mac-address !00:50:56:2d:c8:2a
+ }
+ }
+ rule 1028 {
+ action drop
+ description Anti-spoofing_185.132.39.109
+ source {
+ address 185.132.39.109
+ mac-address !00:50:56:2c:3e:98
+ }
+ }
+ rule 1029 {
+ action drop
+ description Anti-spoofing_109.228.40.207
+ source {
+ address 109.228.40.207
+ mac-address !00:50:56:04:ba:9c
+ }
+ }
+ rule 1030 {
+ action drop
+ description Anti-spoofing_77.68.48.89
+ source {
+ address 77.68.48.89
+ mac-address !00:50:56:33:b3:05
+ }
+ }
+ rule 1031 {
+ action drop
+ description Anti-spoofing_77.68.48.105
+ source {
+ address 77.68.48.105
+ mac-address !00:50:56:13:8d:55
+ }
+ }
+ rule 1032 {
+ action drop
+ description Anti-spoofing_77.68.50.142
+ source {
+ address 77.68.50.142
+ mac-address !00:50:56:2e:58:85
+ }
+ }
+ rule 1033 {
+ action drop
+ description Anti-spoofing_77.68.49.12
+ source {
+ address 77.68.49.12
+ mac-address !00:50:56:0f:ed:da
+ }
+ }
+ rule 1034 {
+ action drop
+ description Anti-spoofing_77.68.85.18
+ source {
+ address 77.68.85.18
+ mac-address !00:50:56:3b:0a:8b
+ }
+ }
+ rule 1035 {
+ action drop
+ description Anti-spoofing_77.68.49.4
+ source {
+ address 77.68.49.4
+ mac-address !00:50:56:05:e5:05
+ }
+ }
+ rule 1036 {
+ action drop
+ description Anti-spoofing_109.228.37.187
+ source {
+ address 109.228.37.187
+ mac-address !00:50:56:37:21:f0
+ }
+ }
+ rule 1037 {
+ action drop
+ description Anti-spoofing_77.68.49.178
+ source {
+ address 77.68.49.178
+ mac-address !00:50:56:26:00:f7
+ }
+ }
+ rule 1038 {
+ action drop
+ description Anti-spoofing_77.68.82.147
+ source {
+ address 77.68.82.147
+ mac-address !00:50:56:13:75:25
+ }
+ }
+ rule 1040 {
+ action drop
+ description Anti-spoofing_77.68.24.134
+ source {
+ address 77.68.24.134
+ mac-address !00:50:56:29:0b:02
+ }
+ }
+ rule 1041 {
+ action drop
+ description Anti-spoofing_77.68.24.63
+ source {
+ address 77.68.24.63
+ mac-address !00:50:56:08:7e:4a
+ }
+ }
+ rule 1042 {
+ action drop
+ description Anti-spoofing_77.68.50.91
+ source {
+ address 77.68.50.91
+ mac-address !00:50:56:35:b6:4f
+ }
+ }
+ rule 1043 {
+ action drop
+ description Anti-spoofing_77.68.49.160
+ source {
+ address 77.68.49.160
+ mac-address !00:50:56:0e:29:ce
+ }
+ }
+ rule 1044 {
+ action drop
+ description Anti-spoofing_77.68.116.84
+ source {
+ address 77.68.116.84
+ mac-address !00:50:56:2d:e7:75
+ }
+ }
+ rule 1045 {
+ action drop
+ description Anti-spoofing_77.68.126.160
+ source {
+ address 77.68.126.160
+ mac-address !00:50:56:19:a1:cf
+ }
+ }
+ rule 1046 {
+ action drop
+ description Anti-spoofing_185.132.41.240
+ source {
+ address 185.132.41.240
+ mac-address !00:50:56:08:f6:7c
+ }
+ }
+ rule 1047 {
+ action drop
+ description Anti-spoofing_77.68.50.193
+ source {
+ address 77.68.50.193
+ mac-address !00:50:56:0f:44:05
+ }
+ }
+ rule 1048 {
+ action drop
+ description Anti-spoofing_77.68.49.161
+ source {
+ address 77.68.49.161
+ mac-address !00:50:56:09:4a:87
+ }
+ }
+ rule 1049 {
+ action drop
+ description Anti-spoofing_109.228.58.134
+ source {
+ address 109.228.58.134
+ mac-address !00:50:56:06:82:eb
+ }
+ }
+ rule 1050 {
+ action drop
+ description Anti-spoofing_185.132.36.56
+ source {
+ address 185.132.36.56
+ mac-address !00:50:56:11:89:a1
+ }
+ }
+ rule 1051 {
+ action drop
+ description Anti-spoofing_77.68.50.198
+ source {
+ address 77.68.50.198
+ mac-address !00:50:56:21:8f:66
+ }
+ }
+ rule 1052 {
+ action drop
+ description Anti-spoofing_77.68.100.150
+ source {
+ address 77.68.100.150
+ mac-address !00:50:56:3a:15:0a
+ }
+ }
+ rule 1053 {
+ action drop
+ description Anti-spoofing_88.208.196.91
+ source {
+ address 88.208.196.91
+ mac-address !00:50:56:0a:06:31
+ }
+ }
+ rule 1054 {
+ action drop
+ description Anti-spoofing_185.132.41.148
+ source {
+ address 185.132.41.148
+ mac-address !00:50:56:3b:d9:ec
+ }
+ }
+ rule 1055 {
+ action drop
+ description Anti-spoofing_213.171.210.25
+ source {
+ address 213.171.210.25
+ mac-address !00:50:56:0a:b8:6c
+ }
+ }
+ rule 1056 {
+ action drop
+ description Anti-spoofing_77.68.51.214
+ source {
+ address 77.68.51.214
+ mac-address !00:50:56:16:29:41
+ }
+ }
+ rule 1057 {
+ action drop
+ description Anti-spoofing_77.68.51.202
+ source {
+ address 77.68.51.202
+ mac-address !00:50:56:24:5a:0f
+ }
+ }
+ rule 1058 {
+ action drop
+ description Anti-spoofing_77.68.100.132
+ source {
+ address 77.68.100.132
+ mac-address !00:50:56:27:18:b7
+ }
+ }
+ rule 1059 {
+ action drop
+ description Anti-spoofing_77.68.77.42
+ source {
+ address 77.68.77.42
+ mac-address !00:50:56:34:d1:d5
+ }
+ }
+ rule 1060 {
+ action drop
+ description Anti-spoofing_109.228.39.41
+ source {
+ address 109.228.39.41
+ mac-address !00:50:56:2e:6a:41
+ }
+ }
+ rule 1061 {
+ action drop
+ description Anti-spoofing_77.68.100.134
+ source {
+ address 77.68.100.134
+ mac-address !00:50:56:19:a0:13
+ }
+ }
+ rule 1062 {
+ action drop
+ description Anti-spoofing_77.68.89.247
+ source {
+ address 77.68.89.247
+ mac-address !00:50:56:2b:ed:68
+ }
+ }
+ rule 1063 {
+ action drop
+ description Anti-spoofing_77.68.101.64
+ source {
+ address 77.68.101.64
+ mac-address !00:50:56:24:5a:0f
+ }
+ }
+ rule 1064 {
+ action drop
+ description Anti-spoofing_88.208.199.249
+ source {
+ address 88.208.199.249
+ mac-address !00:50:56:16:3e:ed
+ }
+ }
+ rule 1065 {
+ action drop
+ description Anti-spoofing_77.68.101.124
+ source {
+ address 77.68.101.124
+ mac-address !00:50:56:15:0e:e0
+ }
+ }
+ rule 1066 {
+ action drop
+ description Anti-spoofing_77.68.101.125
+ source {
+ address 77.68.101.125
+ mac-address !00:50:56:33:ce:ff
+ }
+ }
+ rule 1068 {
+ action drop
+ description Anti-spoofing_77.68.100.167
+ source {
+ address 77.68.100.167
+ mac-address !00:50:56:34:b3:5d
+ }
+ }
+ rule 1069 {
+ action drop
+ description Anti-spoofing_77.68.49.152
+ source {
+ address 77.68.49.152
+ mac-address !00:50:56:1a:06:95
+ }
+ }
+ rule 1070 {
+ action drop
+ description Anti-spoofing_77.68.103.147
+ source {
+ address 77.68.103.147
+ mac-address !00:50:56:2e:52:7f
+ }
+ }
+ rule 1071 {
+ action drop
+ description Anti-spoofing_77.68.48.202
+ source {
+ address 77.68.48.202
+ mac-address !00:50:56:0b:da:01
+ }
+ }
+ rule 1072 {
+ action drop
+ description Anti-spoofing_77.68.112.175
+ source {
+ address 77.68.112.175
+ mac-address !00:50:56:05:9e:e5
+ }
+ }
+ rule 1073 {
+ action drop
+ description Anti-spoofing_109.228.56.97
+ source {
+ address 109.228.56.97
+ mac-address !00:50:56:36:cd:04
+ }
+ }
+ rule 1074 {
+ action drop
+ description Anti-spoofing_185.132.37.47
+ source {
+ address 185.132.37.47
+ mac-address !00:50:56:3a:de:38
+ }
+ }
+ rule 1075 {
+ action drop
+ description Anti-spoofing_77.68.31.96
+ source {
+ address 77.68.31.96
+ mac-address !00:50:56:07:d0:cf
+ }
+ }
+ rule 1076 {
+ action drop
+ description Anti-spoofing_109.228.61.37
+ source {
+ address 109.228.61.37
+ mac-address !00:50:56:1a:93:80
+ }
+ }
+ rule 1077 {
+ action drop
+ description Anti-spoofing_77.68.33.24
+ source {
+ address 77.68.33.24
+ mac-address !00:50:56:0d:ae:e8
+ }
+ }
+ rule 1078 {
+ action drop
+ description Anti-spoofing_88.208.197.135
+ source {
+ address 88.208.197.135
+ mac-address !00:50:56:3b:39:6b
+ }
+ }
+ rule 1079 {
+ action drop
+ description Anti-spoofing_77.68.103.227
+ source {
+ address 77.68.103.227
+ mac-address !00:50:56:28:cd:95
+ }
+ }
+ rule 1080 {
+ action drop
+ description Anti-spoofing_185.132.38.182
+ source {
+ address 185.132.38.182
+ mac-address !00:50:56:39:4b:e3
+ }
+ }
+ rule 1081 {
+ action drop
+ description Anti-spoofing_88.208.197.118
+ source {
+ address 88.208.197.118
+ mac-address !00:50:56:2c:cd:e3
+ }
+ }
+ rule 1082 {
+ action drop
+ description Anti-spoofing_88.208.196.92
+ source {
+ address 88.208.196.92
+ mac-address !00:50:56:05:77:19
+ }
+ }
+ rule 1083 {
+ action drop
+ description Anti-spoofing_88.208.197.150
+ source {
+ address 88.208.197.150
+ mac-address !00:50:56:0c:ae:6c
+ }
+ }
+ rule 1084 {
+ action drop
+ description Anti-spoofing_88.208.215.121
+ source {
+ address 88.208.215.121
+ mac-address !00:50:56:16:0b:60
+ }
+ }
+ rule 1085 {
+ action drop
+ description Anti-spoofing_88.208.197.10
+ source {
+ address 88.208.197.10
+ mac-address !00:50:56:1c:8b:fb
+ }
+ }
+ rule 1086 {
+ action drop
+ description Anti-spoofing_88.208.198.69
+ source {
+ address 88.208.198.69
+ mac-address !00:50:56:06:e7:eb
+ }
+ }
+ rule 1087 {
+ action drop
+ description Anti-spoofing_88.208.197.155
+ source {
+ address 88.208.197.155
+ mac-address !00:50:56:39:39:8e
+ }
+ }
+ rule 1088 {
+ action drop
+ description Anti-spoofing_88.208.198.39
+ source {
+ address 88.208.198.39
+ mac-address !00:50:56:22:2d:07
+ }
+ }
+ rule 1089 {
+ action drop
+ description Anti-spoofing_88.208.197.160
+ source {
+ address 88.208.197.160
+ mac-address !00:50:56:2e:03:9a
+ }
+ }
+ rule 1090 {
+ action drop
+ description Anti-spoofing_88.208.197.60
+ source {
+ address 88.208.197.60
+ mac-address !00:50:56:3e:59:7c
+ }
+ }
+ rule 1091 {
+ action drop
+ description Anti-spoofing_77.68.102.129
+ source {
+ address 77.68.102.129
+ mac-address !00:50:56:2c:9d:a5
+ }
+ }
+ rule 1092 {
+ action drop
+ description Anti-spoofing_88.208.196.123
+ source {
+ address 88.208.196.123
+ mac-address !00:50:56:21:ac:31
+ }
+ }
+ rule 1093 {
+ action drop
+ description Anti-spoofing_88.208.215.61
+ source {
+ address 88.208.215.61
+ mac-address !00:50:56:05:91:dd
+ }
+ }
+ rule 1094 {
+ action drop
+ description Anti-spoofing_88.208.215.62
+ source {
+ address 88.208.215.62
+ mac-address !00:50:56:2d:ff:f4
+ }
+ }
+ rule 1095 {
+ action drop
+ description Anti-spoofing_88.208.199.141
+ source {
+ address 88.208.199.141
+ mac-address !00:50:56:10:8f:10
+ }
+ }
+ rule 1096 {
+ action drop
+ description Anti-spoofing_88.208.215.157
+ source {
+ address 88.208.215.157
+ mac-address !00:50:56:38:d7:1a
+ }
+ }
+ rule 1097 {
+ action drop
+ description Anti-spoofing_77.68.21.171
+ source {
+ address 77.68.21.171
+ mac-address !00:50:56:29:e0:5f
+ }
+ }
+ rule 1098 {
+ action drop
+ description Anti-spoofing_88.208.198.251
+ source {
+ address 88.208.198.251
+ mac-address !00:50:56:2b:2a:6a
+ }
+ }
+ rule 1099 {
+ action drop
+ description Anti-spoofing_88.208.199.233
+ source {
+ address 88.208.199.233
+ mac-address !00:50:56:1e:bf:95
+ }
+ }
+ rule 1100 {
+ action drop
+ description Anti-spoofing_88.208.212.31
+ source {
+ address 88.208.212.31
+ mac-address !00:50:56:28:f4:aa
+ }
+ }
+ rule 1101 {
+ action drop
+ description Anti-spoofing_88.208.197.129
+ source {
+ address 88.208.197.129
+ mac-address !00:50:56:1f:71:bf
+ }
+ }
+ rule 1102 {
+ action drop
+ description Anti-spoofing_88.208.199.46
+ source {
+ address 88.208.199.46
+ mac-address !00:50:56:34:dc:e5
+ }
+ }
+ rule 1103 {
+ action drop
+ description Anti-spoofing_88.208.212.94
+ source {
+ address 88.208.212.94
+ mac-address !00:50:56:3d:f5:16
+ }
+ }
+ rule 1105 {
+ action drop
+ description Anti-spoofing_88.208.212.182
+ source {
+ address 88.208.212.182
+ mac-address !00:50:56:12:e4:1b
+ }
+ }
+ rule 1108 {
+ action drop
+ description Anti-spoofing_88.208.212.188
+ source {
+ address 88.208.212.188
+ mac-address !00:50:56:36:a8:9e
+ }
+ }
+ rule 1500 {
+ action drop
+ description "Block port 11211-udp"
+ protocol udp
+ source {
+ group {
+ address-group CLUSTER_ADDRESSES
+ }
+ port 11211
+ }
+ }
+ rule 1510 {
+ action drop
+ description "Test Drive - Outgoing traffic blocked"
+ destination {
+ group {
+ network-group !NAS_NETWORKS
+ }
+ }
+ source {
+ group {
+ address-group DT_BLOCKED
+ }
+ }
+ }
+ rule 1520 {
+ action drop
+ description "Deny outgoing SMTP to new contracts"
+ destination {
+ port smtp
+ }
+ protocol tcp
+ source {
+ group {
+ address-group DT_SMTP_BLOCKED
+ }
+ }
+ }
+ rule 1600 {
+ action accept
+ description "Allow unicast requests to DHCP servers"
+ destination {
+ group {
+ address-group DHCP_SERVERS
+ }
+ port bootps
+ }
+ protocol tcp_udp
+ source {
+ group {
+ address-group CLUSTER_ADDRESSES
+ }
+ }
+ }
+ rule 1610 {
+ action accept
+ description "Allow DNS queries to dnscache servers"
+ destination {
+ group {
+ address-group DNSCACHE_SERVERS
+ }
+ port 53
+ }
+ protocol tcp_udp
+ source {
+ group {
+ address-group CLUSTER_ADDRESSES
+ }
+ }
+ }
+ rule 1620 {
+ action accept
+ destination {
+ group {
+ address-group NAS_ARRAYS
+ }
+ }
+ source {
+ group {
+ address-group CLUSTER_ADDRESSES
+ }
+ }
+ }
+ rule 1630 {
+ action accept
+ description "Kerberos authentication to Domain Controllers"
+ destination {
+ group {
+ address-group NAS_DOMAIN_CONTROLLERS
+ }
+ port 88
+ }
+ protocol tcp_udp
+ source {
+ group {
+ address-group CLUSTER_ADDRESSES
+ }
+ }
+ }
+ rule 1640 {
+ action drop
+ description "Deny rest of the traffic to NAS"
+ destination {
+ group {
+ network-group NAS_NETWORKS
+ }
+ }
+ }
+ rule 2000 {
+ action accept
+ description "TOP port - SSH"
+ destination {
+ group {
+ address-group G-22-TCP
+ }
+ port ssh
+ }
+ protocol tcp
+ }
+ rule 2001 {
+ action accept
+ description "TOP port - RDESKTOP"
+ destination {
+ group {
+ address-group G-3389-TCP
+ }
+ port 3389
+ }
+ protocol tcp
+ }
+ rule 2002 {
+ action accept
+ description "TOP port - HTTP"
+ destination {
+ group {
+ address-group G-80-TCP
+ }
+ port http
+ }
+ protocol tcp
+ }
+ rule 2003 {
+ action accept
+ description "TOP port - HTTPS"
+ destination {
+ group {
+ address-group G-443-TCP
+ }
+ port https
+ }
+ protocol tcp
+ }
+ rule 2004 {
+ action accept
+ description "TOP port - DOMAIN TCP"
+ destination {
+ group {
+ address-group G-53-TCP
+ }
+ port domain
+ }
+ protocol tcp
+ }
+ rule 2005 {
+ action accept
+ description "TOP port - DOMAIN UDP"
+ destination {
+ group {
+ address-group G-53-UDP
+ }
+ port domain
+ }
+ protocol udp
+ }
+ rule 2006 {
+ action accept
+ description "TOP port - SMTP"
+ destination {
+ group {
+ address-group G-25-TCP
+ }
+ port smtp
+ }
+ protocol tcp
+ }
+ rule 2007 {
+ action accept
+ description "TOP port - IMAP"
+ destination {
+ group {
+ address-group G-143-TCP
+ }
+ port imap2
+ }
+ protocol tcp
+ }
+ rule 2008 {
+ action accept
+ description "TOP port - POP3"
+ destination {
+ group {
+ address-group G-110-TCP
+ }
+ port pop3
+ }
+ protocol tcp
+ }
+ rule 2009 {
+ action accept
+ description "TOP port - MSSQL TCP"
+ destination {
+ group {
+ address-group G-1433-TCP
+ }
+ port ms-sql-s
+ }
+ protocol tcp
+ }
+ rule 2010 {
+ action accept
+ description "TOP port - MYSQL TCP"
+ destination {
+ group {
+ address-group G-3306-TCP
+ }
+ port mysql
+ }
+ protocol tcp
+ }
+ rule 2011 {
+ action accept
+ description "TOP port - FTPDATA"
+ destination {
+ group {
+ address-group G-20-TCP
+ }
+ port ftp-data
+ }
+ protocol tcp
+ }
+ rule 2012 {
+ action accept
+ description "TOP port - FTP"
+ destination {
+ group {
+ address-group G-21-TCP
+ }
+ port ftp
+ }
+ protocol tcp
+ }
+ rule 2013 {
+ action accept
+ description "TOP port - SSMTP"
+ destination {
+ group {
+ address-group G-465-TCP
+ }
+ port ssmtp
+ }
+ protocol tcp
+ }
+ rule 2014 {
+ action accept
+ description "TOP port - SMTPS"
+ destination {
+ group {
+ address-group G-587-TCP
+ }
+ port 587
+ }
+ protocol tcp
+ }
+ rule 2015 {
+ action accept
+ description "TOP port - IMAPS"
+ destination {
+ group {
+ address-group G-993-TCP
+ }
+ port imaps
+ }
+ protocol tcp
+ }
+ rule 2016 {
+ action accept
+ description "TOP port - POP3S"
+ destination {
+ group {
+ address-group G-995-TCP
+ }
+ port pop3s
+ }
+ protocol tcp
+ }
+ rule 2017 {
+ action accept
+ description "TOP port - TOMCAT"
+ destination {
+ group {
+ address-group G-8080-TCP
+ }
+ port 8080
+ }
+ protocol tcp
+ }
+ rule 2018 {
+ action accept
+ description "TOP port - Alternative HTTPS"
+ destination {
+ group {
+ address-group G-8443-TCP
+ }
+ port 8443
+ }
+ protocol tcp
+ }
+ rule 2019 {
+ action accept
+ description "TOP port - 10000/TCP"
+ destination {
+ group {
+ address-group G-10000-TCP
+ }
+ port 10000
+ }
+ protocol tcp
+ }
+ rule 2020 {
+ action accept
+ description "TOP port - 8447/TCP"
+ destination {
+ group {
+ address-group G-8447-TCP
+ }
+ port 8447
+ }
+ protocol tcp
+ }
+ rule 2040 {
+ action accept
+ description "TOP port - All ports open"
+ destination {
+ group {
+ address-group G-ALL_OPEN
+ }
+ }
+ }
+ rule 2050 {
+ action accept
+ description "ICMP group"
+ destination {
+ group {
+ address-group G-ICMP
+ }
+ }
+ protocol icmp
+ }
+ rule 2100 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-104.192.143.2
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 7999,22
+ }
+ protocol tcp
+ source {
+ address 104.192.143.2
+ }
+ }
+ rule 2101 {
+ action accept
+ description FW19987_4-TCP-ALLOW-77.68.74.54
+ destination {
+ group {
+ address-group DT_FW19987_4
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 77.68.74.54
+ }
+ }
+ rule 2102 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-109.72.210.46
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 109.72.210.46
+ }
+ }
+ rule 2103 {
+ action accept
+ description FW5A77C_16-TCP-ALLOW-213.171.217.107
+ destination {
+ group {
+ address-group DT_FW5A77C_16
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.107
+ }
+ }
+ rule 2104 {
+ action accept
+ description FW826BA_3-TCP-ALLOW-164.177.156.192
+ destination {
+ group {
+ address-group DT_FW826BA_3
+ }
+ port 3389,1433,21
+ }
+ protocol tcp
+ source {
+ address 164.177.156.192
+ }
+ }
+ rule 2105 {
+ action accept
+ description FWDAA4F_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWDAA4F_1
+ }
+ port 22335
+ }
+ protocol tcp
+ }
+ rule 2106 {
+ action accept
+ description FW6D0CD_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6D0CD_1
+ }
+ port 6900,7000
+ }
+ protocol tcp
+ }
+ rule 2107 {
+ action accept
+ description FW6D0CD_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6D0CD_1
+ }
+ port 9001
+ }
+ protocol tcp_udp
+ }
+ rule 2108 {
+ action accept
+ description FW06176_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW06176_1
+ }
+ port 5900
+ }
+ protocol tcp
+ }
+ rule 2109 {
+ action accept
+ description FW19987_4-TCP-ALLOW-77.68.77.70
+ destination {
+ group {
+ address-group DT_FW19987_4
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 77.68.77.70
+ }
+ }
+ rule 2110 {
+ action accept
+ description FWF7B68_1-TCP-ALLOW-54.221.251.224
+ destination {
+ group {
+ address-group DT_FWF7B68_1
+ }
+ port 8443,3306,22,21,20
+ }
+ protocol tcp
+ source {
+ address 54.221.251.224
+ }
+ }
+ rule 2111 {
+ action accept
+ description FW05AD0_2-TCP-ALLOW-178.251.181.41
+ destination {
+ group {
+ address-group DT_FW05AD0_2
+ }
+ port 3389,1433,21
+ }
+ protocol tcp
+ source {
+ address 178.251.181.41
+ }
+ }
+ rule 2112 {
+ action accept
+ description FW05AD0_2-TCP-ALLOW-178.251.181.6
+ destination {
+ group {
+ address-group DT_FW05AD0_2
+ }
+ port 3389,1433,21
+ }
+ protocol tcp
+ source {
+ address 178.251.181.6
+ }
+ }
+ rule 2113 {
+ action accept
+ description VPN-7030-ANY-ALLOW-10.4.58.119
+ destination {
+ group {
+ address-group DT_VPN-7030
+ }
+ }
+ source {
+ address 10.4.58.119
+ }
+ }
+ rule 2114 {
+ action accept
+ description FW58C69_4-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW58C69_4
+ }
+ port 5666
+ }
+ protocol tcp
+ }
+ rule 2115 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-185.201.180.35
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 27017,5000,22
+ }
+ protocol tcp
+ source {
+ address 185.201.180.35
+ }
+ }
+ rule 2116 {
+ action accept
+ description FW19987_4-TCP-ALLOW-77.68.8.74
+ destination {
+ group {
+ address-group DT_FW19987_4
+ }
+ port 3389,445,443
+ }
+ protocol tcp
+ source {
+ address 77.68.8.74
+ }
+ }
+ rule 2117 {
+ action accept
+ description FW19987_4-TCP-ALLOW-87.224.33.215
+ destination {
+ group {
+ address-group DT_FW19987_4
+ }
+ port 3389,445,443
+ }
+ protocol tcp
+ source {
+ address 87.224.33.215
+ }
+ }
+ rule 2118 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-212.159.160.65
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 8443,3389,3306,22,21
+ }
+ protocol tcp
+ source {
+ address 212.159.160.65
+ }
+ }
+ rule 2119 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-79.78.20.149
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 8447,8443,3389,3306,993,143,22,21
+ }
+ protocol tcp
+ source {
+ address 79.78.20.149
+ }
+ }
+ rule 2120 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-77.68.77.185
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 77.68.77.185
+ }
+ }
+ rule 2121 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-82.165.232.19
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 8443,3389
+ }
+ protocol tcp
+ source {
+ address 82.165.232.19
+ }
+ }
+ rule 2122 {
+ action accept
+ description FW2C5AE_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2C5AE_1
+ }
+ port 30303,5717
+ }
+ protocol tcp_udp
+ }
+ rule 2123 {
+ action accept
+ description VPN-12899-ANY-ALLOW-10.4.58.207
+ destination {
+ group {
+ address-group DT_VPN-12899
+ }
+ }
+ source {
+ address 10.4.58.207
+ }
+ }
+ rule 2124 {
+ action accept
+ description FW7648D_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW7648D_1
+ }
+ port 8501,8050,7801,4444,1443
+ }
+ protocol tcp
+ }
+ rule 2125 {
+ action accept
+ description FW0C2E6_4-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0C2E6_4
+ }
+ port 1194
+ }
+ protocol udp
+ }
+ rule 2126 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-39.37.175.132
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 39.37.175.132
+ }
+ }
+ rule 2127 {
+ action accept
+ description FW826BA_3-TCP-ALLOW-165.255.242.223
+ destination {
+ group {
+ address-group DT_FW826BA_3
+ }
+ port 3389,1433,21
+ }
+ protocol tcp
+ source {
+ address 165.255.242.223
+ }
+ }
+ rule 2128 {
+ action accept
+ description VPN-10131-ANY-ALLOW-10.4.56.51
+ destination {
+ group {
+ address-group DT_VPN-10131
+ }
+ }
+ source {
+ address 10.4.56.51
+ }
+ }
+ rule 2129 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-212.227.84.142
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 212.227.84.142
+ }
+ }
+ rule 2130 {
+ action accept
+ description FW2BB8D_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 2131 {
+ action accept
+ description FWFDD94_15-TCP-ALLOW-90.29.180.234
+ destination {
+ group {
+ address-group DT_FWFDD94_15
+ }
+ port 5683,1883
+ }
+ protocol tcp
+ source {
+ address 90.29.180.234
+ }
+ }
+ rule 2132 {
+ action accept
+ description VPN-10131-ANY-ALLOW-10.4.57.51
+ destination {
+ group {
+ address-group DT_VPN-10131
+ }
+ }
+ source {
+ address 10.4.57.51
+ }
+ }
+ rule 2133 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-109.228.49.193
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 5000
+ }
+ protocol tcp
+ source {
+ address 109.228.49.193
+ }
+ }
+ rule 2134 {
+ action accept
+ description FW81138_1-ICMP-ALLOW-3.10.221.168
+ destination {
+ group {
+ address-group DT_FW81138_1
+ }
+ }
+ protocol icmp
+ source {
+ address 3.10.221.168
+ }
+ }
+ rule 2135 {
+ action accept
+ description FWB28B6_5-AH-ALLOW-77.68.36.46
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ }
+ protocol ah
+ source {
+ address 77.68.36.46
+ }
+ }
+ rule 2136 {
+ action accept
+ description FWB28B6_5-ESP-ALLOW-77.68.36.46
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ }
+ protocol esp
+ source {
+ address 77.68.36.46
+ }
+ }
+ rule 2137 {
+ action accept
+ description FW825C8_24-TCP-ALLOW-77.68.87.201
+ destination {
+ group {
+ address-group DT_FW825C8_24
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 77.68.87.201
+ }
+ }
+ rule 2138 {
+ action accept
+ description FWB28B6_5-AH-ALLOW-213.171.196.146
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ }
+ protocol ah
+ source {
+ address 213.171.196.146
+ }
+ }
+ rule 2139 {
+ action accept
+ description FWB28B6_5-ESP-ALLOW-213.171.196.146
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ }
+ protocol esp
+ source {
+ address 213.171.196.146
+ }
+ }
+ rule 2140 {
+ action accept
+ description FWB28B6_5-UDP-ALLOW-213.171.196.146
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ port 500,4500
+ }
+ protocol udp
+ source {
+ address 213.171.196.146
+ }
+ }
+ rule 2141 {
+ action accept
+ description FWB28B6_5-TCP_UDP-ALLOW-213.171.196.146
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ port 1701
+ }
+ protocol tcp_udp
+ source {
+ address 213.171.196.146
+ }
+ }
+ rule 2142 {
+ action accept
+ description FWB28B6_5-TCP_UDP-ALLOW-77.68.36.46
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ port 1701
+ }
+ protocol tcp_udp
+ source {
+ address 77.68.36.46
+ }
+ }
+ rule 2143 {
+ action accept
+ description FWB28B6_5-UDP-ALLOW-77.68.36.46
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ port 500,4500
+ }
+ protocol udp
+ source {
+ address 77.68.36.46
+ }
+ }
+ rule 2144 {
+ action accept
+ description VPN-12899-ANY-ALLOW-10.4.59.207
+ destination {
+ group {
+ address-group DT_VPN-12899
+ }
+ }
+ source {
+ address 10.4.59.207
+ }
+ }
+ rule 2145 {
+ action accept
+ description FWB28B6_5-TCP-ALLOW-81.130.141.175
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 81.130.141.175
+ }
+ }
+ rule 2146 {
+ action accept
+ description FWB28B6_5-UDP-ALLOW-77.68.38.195
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ port 4500,500
+ }
+ protocol udp
+ source {
+ address 77.68.38.195
+ }
+ }
+ rule 2147 {
+ action accept
+ description FWB28B6_5-AH-ALLOW-77.68.38.195
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ }
+ protocol ah
+ source {
+ address 77.68.38.195
+ }
+ }
+ rule 2148 {
+ action accept
+ description FWB28B6_5-ESP-ALLOW-77.68.38.195
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ }
+ protocol esp
+ source {
+ address 77.68.38.195
+ }
+ }
+ rule 2149 {
+ action accept
+ description FWB28B6_5-TCP_UDP-ALLOW-77.68.38.195
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ port 1701
+ }
+ protocol tcp_udp
+ source {
+ address 77.68.38.195
+ }
+ }
+ rule 2150 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-39.37.178.77
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 39.37.178.77
+ }
+ }
+ rule 2151 {
+ action accept
+ description FW5A77C_16-TCP-ALLOW-51.241.139.56
+ destination {
+ group {
+ address-group DT_FW5A77C_16
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 51.241.139.56
+ }
+ }
+ rule 2152 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-150.143.57.138
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 150.143.57.138
+ }
+ }
+ rule 2153 {
+ action accept
+ description FW6ECA4_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6ECA4_1
+ }
+ port 3939,3335,3334,3333,3000,999,444
+ }
+ protocol tcp_udp
+ }
+ rule 2154 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-39.45.13.20
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 39.45.13.20
+ }
+ }
+ rule 2155 {
+ action accept
+ description FW481D7_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW481D7_1
+ }
+ port 3478
+ }
+ protocol tcp_udp
+ }
+ rule 2156 {
+ action accept
+ description FW5A5D7_3-GRE-ALLOW-51.219.222.28
+ destination {
+ group {
+ address-group DT_FW5A5D7_3
+ }
+ }
+ protocol gre
+ source {
+ address 51.219.222.28
+ }
+ }
+ rule 2157 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-94.195.127.217
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389,443
+ }
+ protocol tcp
+ source {
+ address 94.195.127.217
+ }
+ }
+ rule 2158 {
+ action accept
+ description FW2E060_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2E060_1
+ }
+ port 49152-65535,8443-8447
+ }
+ protocol tcp
+ }
+ rule 2159 {
+ action accept
+ description FWFDD94_15-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWFDD94_15
+ }
+ port 9090,5080,1935
+ }
+ protocol tcp
+ }
+ rule 2160 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-39.45.190.224
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 39.45.190.224
+ }
+ }
+ rule 2161 {
+ action accept
+ description FW9E550_1-TCP-ALLOW-109.249.187.56
+ destination {
+ group {
+ address-group DT_FW9E550_1
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 109.249.187.56
+ }
+ }
+ rule 2162 {
+ action accept
+ description FW89619_1-TCP-ALLOW-81.133.80.114
+ destination {
+ group {
+ address-group DT_FW89619_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 81.133.80.114
+ }
+ }
+ rule 2163 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-212.227.72.218
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 212.227.72.218
+ }
+ }
+ rule 2164 {
+ action accept
+ description FW0E383_9-TCP-ALLOW-151.229.59.51
+ destination {
+ group {
+ address-group DT_FW0E383_9
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 151.229.59.51
+ }
+ }
+ rule 2165 {
+ action accept
+ description FW8AFF1_7-TCP-ALLOW-178.251.181.41
+ destination {
+ group {
+ address-group DT_FW8AFF1_7
+ }
+ port 1433,21
+ }
+ protocol tcp
+ source {
+ address 178.251.181.41
+ }
+ }
+ rule 2166 {
+ action accept
+ description FW3CAAB_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW3CAAB_1
+ }
+ port 49152-65535,30000-30400,8443-8447,5432,80-110,21-25
+ }
+ protocol tcp
+ }
+ rule 2167 {
+ action accept
+ description FW91B7A_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW91B7A_1
+ }
+ port 3389,80
+ }
+ protocol tcp_udp
+ }
+ rule 2168 {
+ action accept
+ description FW40416_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW40416_1
+ }
+ port 1-65535
+ }
+ protocol tcp
+ }
+ rule 2169 {
+ action accept
+ description FW5A77C_16-TCP-ALLOW-81.151.24.216
+ destination {
+ group {
+ address-group DT_FW5A77C_16
+ }
+ port 10000,22
+ }
+ protocol tcp
+ source {
+ address 81.151.24.216
+ }
+ }
+ rule 2170 {
+ action accept
+ description VPN-7030-ANY-ALLOW-10.4.59.119
+ destination {
+ group {
+ address-group DT_VPN-7030
+ }
+ }
+ source {
+ address 10.4.59.119
+ }
+ }
+ rule 2171 {
+ action accept
+ description FW0E383_9-TCP-ALLOW-62.252.94.138
+ destination {
+ group {
+ address-group DT_FW0E383_9
+ }
+ port 3389,1433
+ }
+ protocol tcp
+ source {
+ address 62.252.94.138
+ }
+ }
+ rule 2172 {
+ action accept
+ description FW89619_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW89619_1
+ }
+ port 5015,5001,5000
+ }
+ protocol tcp
+ }
+ rule 2173 {
+ action accept
+ description FW89619_1-TCP_UDP-ALLOW-167.98.162.142
+ destination {
+ group {
+ address-group DT_FW89619_1
+ }
+ port 5060
+ }
+ protocol tcp_udp
+ source {
+ address 167.98.162.142
+ }
+ }
+ rule 2174 {
+ action accept
+ description FW013EF_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW013EF_2
+ }
+ port 44445,7770-7800,5090,5060-5070,5015,5001,2000-2500
+ }
+ protocol tcp
+ }
+ rule 2175 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.12
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.12
+ }
+ }
+ rule 2176 {
+ action accept
+ description VPN-15625-ANY-ALLOW-10.4.88.79
+ destination {
+ group {
+ address-group DT_VPN-15625
+ }
+ }
+ source {
+ address 10.4.88.79
+ }
+ }
+ rule 2177 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-109.228.53.128
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306,22
+ }
+ protocol tcp
+ source {
+ address 109.228.53.128
+ }
+ }
+ rule 2178 {
+ action accept
+ description FW8AFF1_7-TCP-ALLOW-178.251.181.6
+ destination {
+ group {
+ address-group DT_FW8AFF1_7
+ }
+ port 3389,1433,21
+ }
+ protocol tcp
+ source {
+ address 178.251.181.6
+ }
+ }
+ rule 2179 {
+ action accept
+ description FW578BE_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW578BE_1
+ }
+ port 23,1521,1522
+ }
+ protocol tcp
+ }
+ rule 2180 {
+ action accept
+ description FWE012D_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE012D_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2181 {
+ action accept
+ description FW8AFF1_7-TCP-ALLOW-213.171.209.161
+ destination {
+ group {
+ address-group DT_FW8AFF1_7
+ }
+ port 3389,1433,21
+ }
+ protocol tcp
+ source {
+ address 213.171.209.161
+ }
+ }
+ rule 2182 {
+ action accept
+ description VPN-8203-ANY-ALLOW-10.4.58.109
+ destination {
+ group {
+ address-group DT_VPN-8203
+ }
+ }
+ source {
+ address 10.4.58.109
+ }
+ }
+ rule 2183 {
+ action accept
+ description VPN-9415-ANY-ALLOW-10.4.58.168
+ destination {
+ group {
+ address-group DT_VPN-9415
+ }
+ }
+ source {
+ address 10.4.58.168
+ }
+ }
+ rule 2184 {
+ action accept
+ description VPN-9415-ANY-ALLOW-10.4.59.168
+ destination {
+ group {
+ address-group DT_VPN-9415
+ }
+ }
+ source {
+ address 10.4.59.168
+ }
+ }
+ rule 2185 {
+ action accept
+ description FW27A8F_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW27A8F_1
+ }
+ port 9990,8458,8090,6543,5432
+ }
+ protocol tcp
+ }
+ rule 2186 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-77.68.11.224
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 5000
+ }
+ protocol tcp
+ source {
+ address 77.68.11.224
+ }
+ }
+ rule 2187 {
+ action accept
+ description VPN-15625-ANY-ALLOW-10.4.89.79
+ destination {
+ group {
+ address-group DT_VPN-15625
+ }
+ }
+ source {
+ address 10.4.89.79
+ }
+ }
+ rule 2188 {
+ action accept
+ description VPN-14649-ANY-ALLOW-10.4.86.35
+ destination {
+ group {
+ address-group DT_VPN-14649
+ }
+ }
+ source {
+ address 10.4.86.35
+ }
+ }
+ rule 2189 {
+ action accept
+ description VPN-14649-ANY-ALLOW-10.4.87.35
+ destination {
+ group {
+ address-group DT_VPN-14649
+ }
+ }
+ source {
+ address 10.4.87.35
+ }
+ }
+ rule 2190 {
+ action accept
+ description VPN-14657-ANY-ALLOW-10.4.86.38
+ destination {
+ group {
+ address-group DT_VPN-14657
+ }
+ }
+ source {
+ address 10.4.86.38
+ }
+ }
+ rule 2191 {
+ action accept
+ description VPN-14657-ANY-ALLOW-10.4.87.38
+ destination {
+ group {
+ address-group DT_VPN-14657
+ }
+ }
+ source {
+ address 10.4.87.38
+ }
+ }
+ rule 2192 {
+ action accept
+ description VPN-14658-ANY-ALLOW-10.4.88.38
+ destination {
+ group {
+ address-group DT_VPN-14658
+ }
+ }
+ source {
+ address 10.4.88.38
+ }
+ }
+ rule 2193 {
+ action accept
+ description VPN-14658-ANY-ALLOW-10.4.89.38
+ destination {
+ group {
+ address-group DT_VPN-14658
+ }
+ }
+ source {
+ address 10.4.89.38
+ }
+ }
+ rule 2194 {
+ action accept
+ description FW0BB22_1-GRE-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0BB22_1
+ }
+ }
+ protocol gre
+ }
+ rule 2195 {
+ action accept
+ description FW0BB22_1-ESP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0BB22_1
+ }
+ }
+ protocol esp
+ }
+ rule 2196 {
+ action accept
+ description FW1CC15_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1CC15_2
+ }
+ port 8089,8085,990,81
+ }
+ protocol tcp
+ }
+ rule 2197 {
+ action accept
+ description FW8AFF1_7-TCP-ALLOW-109.228.0.124
+ destination {
+ group {
+ address-group DT_FW8AFF1_7
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 109.228.0.124
+ }
+ }
+ rule 2198 {
+ action accept
+ description FW5A5D7_3-TCP-ALLOW-51.219.222.28
+ destination {
+ group {
+ address-group DT_FW5A5D7_3
+ }
+ port 8172,3389,1723,1701,47
+ }
+ protocol tcp
+ source {
+ address 51.219.222.28
+ }
+ }
+ rule 2199 {
+ action accept
+ description FW1CB16_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1CB16_1
+ }
+ port 3306,27017,53
+ }
+ protocol tcp_udp
+ }
+ rule 2200 {
+ action accept
+ description FWE47DA_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE47DA_1
+ }
+ port 7770-7800,44445
+ }
+ protocol tcp
+ }
+ rule 2201 {
+ action accept
+ description FW37E59_5-TCP-ALLOW-77.68.20.244
+ destination {
+ group {
+ address-group DT_FW37E59_5
+ }
+ port 30303
+ }
+ protocol tcp
+ source {
+ address 77.68.20.244
+ }
+ }
+ rule 2202 {
+ action accept
+ description FW274FD_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW274FD_1
+ }
+ port 49152-65534
+ }
+ protocol tcp
+ }
+ rule 2203 {
+ action accept
+ description FW6CD7E_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6CD7E_2
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2204 {
+ action accept
+ description FW826BA_3-TCP-ALLOW-178.17.252.59
+ destination {
+ group {
+ address-group DT_FW826BA_3
+ }
+ port 21
+ }
+ protocol tcp
+ source {
+ address 178.17.252.59
+ }
+ }
+ rule 2205 {
+ action accept
+ description FW89619_1-TCP_UDP-ALLOW-185.83.64.108
+ destination {
+ group {
+ address-group DT_FW89619_1
+ }
+ port 5060
+ }
+ protocol tcp_udp
+ source {
+ address 185.83.64.108
+ }
+ }
+ rule 2206 {
+ action accept
+ description FW0937A_1-TCP-ALLOW-83.135.134.13
+ destination {
+ group {
+ address-group DT_FW0937A_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 83.135.134.13
+ }
+ }
+ rule 2207 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-77.68.112.64
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 27017,5000
+ }
+ protocol tcp
+ source {
+ address 77.68.112.64
+ }
+ }
+ rule 2208 {
+ action accept
+ description FW6CD7E_2-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6CD7E_2
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 2209 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-194.73.17.47
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306,22
+ }
+ protocol tcp
+ source {
+ address 194.73.17.47
+ }
+ }
+ rule 2210 {
+ action accept
+ description FW0E383_9-TCP-ALLOW-77.68.115.33
+ destination {
+ group {
+ address-group DT_FW0E383_9
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 77.68.115.33
+ }
+ }
+ rule 2211 {
+ action accept
+ description FWA3EA3_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA3EA3_1
+ }
+ port 943
+ }
+ protocol tcp
+ }
+ rule 2212 {
+ action accept
+ description FW6863A_4-TCP-ALLOW-82.165.100.25
+ destination {
+ group {
+ address-group DT_FW6863A_4
+ }
+ port 21-10000
+ }
+ protocol tcp
+ source {
+ address 82.165.100.25
+ }
+ }
+ rule 2213 {
+ action accept
+ description FWECBFB_14-TCP-ALLOW-109.228.59.50
+ destination {
+ group {
+ address-group DT_FWECBFB_14
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 109.228.59.50
+ }
+ }
+ rule 2214 {
+ action accept
+ description FW2F868_6-TCP-ALLOW-213.171.217.100
+ destination {
+ group {
+ address-group DT_FW2F868_6
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.100
+ }
+ }
+ rule 2215 {
+ action accept
+ description FWD7EAB_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD7EAB_1
+ }
+ port 60000-60100
+ }
+ protocol tcp
+ }
+ rule 2216 {
+ action accept
+ description FWEB321_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWEB321_1
+ }
+ port 113,4190
+ }
+ protocol tcp
+ }
+ rule 2217 {
+ action accept
+ description FW9C682_3-TCP-ALLOW-195.206.180.132
+ destination {
+ group {
+ address-group DT_FW9C682_3
+ }
+ port 8443,22
+ }
+ protocol tcp
+ source {
+ address 195.206.180.132
+ }
+ }
+ rule 2218 {
+ action accept
+ description VPN-8159-ANY-ALLOW-10.4.58.91
+ destination {
+ group {
+ address-group DT_VPN-8159
+ }
+ }
+ source {
+ address 10.4.58.91
+ }
+ }
+ rule 2219 {
+ action accept
+ description VPN-21673-ANY-ALLOW-10.4.88.187
+ destination {
+ group {
+ address-group DT_VPN-21673
+ }
+ }
+ source {
+ address 10.4.88.187
+ }
+ }
+ rule 2220 {
+ action accept
+ description VPN-21673-ANY-ALLOW-10.4.89.187
+ destination {
+ group {
+ address-group DT_VPN-21673
+ }
+ }
+ source {
+ address 10.4.89.187
+ }
+ }
+ rule 2221 {
+ action accept
+ description VPN-21821-ANY-ALLOW-10.4.88.49
+ destination {
+ group {
+ address-group DT_VPN-21821
+ }
+ }
+ source {
+ address 10.4.88.49
+ }
+ }
+ rule 2222 {
+ action accept
+ description VPN-21821-ANY-ALLOW-10.4.89.49
+ destination {
+ group {
+ address-group DT_VPN-21821
+ }
+ }
+ source {
+ address 10.4.89.49
+ }
+ }
+ rule 2223 {
+ action accept
+ description FWECBFB_14-TCP-ALLOW-81.133.80.58
+ destination {
+ group {
+ address-group DT_FWECBFB_14
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 81.133.80.58
+ }
+ }
+ rule 2224 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.238
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.238
+ }
+ }
+ rule 2225 {
+ action accept
+ description FW826BA_3-TCP-ALLOW-185.212.168.51
+ destination {
+ group {
+ address-group DT_FW826BA_3
+ }
+ port 3389,1433,21
+ }
+ protocol tcp
+ source {
+ address 185.212.168.51
+ }
+ }
+ rule 2226 {
+ action accept
+ description FW8B21D_1-ANY-ALLOW-212.187.250.2
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ }
+ source {
+ address 212.187.250.2
+ }
+ }
+ rule 2227 {
+ action accept
+ description FW35F7B_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW35F7B_1
+ }
+ port 1434
+ }
+ protocol tcp_udp
+ }
+ rule 2228 {
+ action accept
+ description FWD338A_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD338A_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2229 {
+ action accept
+ description FW35F7B_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW35F7B_1
+ }
+ port 56791
+ }
+ protocol tcp
+ }
+ rule 2230 {
+ action accept
+ description FW0E383_9-TCP-ALLOW-77.68.77.114
+ destination {
+ group {
+ address-group DT_FW0E383_9
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 77.68.77.114
+ }
+ }
+ rule 2231 {
+ action accept
+ description FW90AE3_1-TCP-ALLOW-194.74.137.17
+ destination {
+ group {
+ address-group DT_FW90AE3_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 194.74.137.17
+ }
+ }
+ rule 2232 {
+ action accept
+ description FW52F6F_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW52F6F_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 2233 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-77.68.23.109
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306,22
+ }
+ protocol tcp
+ source {
+ address 77.68.23.109
+ }
+ }
+ rule 2234 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.247
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.247
+ }
+ }
+ rule 2235 {
+ action accept
+ description FW4E314_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4E314_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 2236 {
+ action accept
+ description FW73573_2-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW73573_2
+ }
+ port 25
+ }
+ protocol tcp_udp
+ }
+ rule 2237 {
+ action accept
+ description FW0E383_9-TCP-ALLOW-77.68.93.89
+ destination {
+ group {
+ address-group DT_FW0E383_9
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 77.68.93.89
+ }
+ }
+ rule 2238 {
+ action accept
+ description FW856FA_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW856FA_1
+ }
+ port 6003
+ }
+ protocol tcp
+ }
+ rule 2239 {
+ action accept
+ description FWECBFB_14-TCP-ALLOW-81.19.214.155
+ destination {
+ group {
+ address-group DT_FWECBFB_14
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 81.19.214.155
+ }
+ }
+ rule 2240 {
+ action accept
+ description FW826BA_3-TCP-ALLOW-51.219.168.170
+ destination {
+ group {
+ address-group DT_FW826BA_3
+ }
+ port 3389,1433,21
+ }
+ protocol tcp
+ source {
+ address 51.219.168.170
+ }
+ }
+ rule 2241 {
+ action accept
+ description FW30D21_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW30D21_1
+ }
+ port 2083-2087,53,2812,2096,25,993,587
+ }
+ protocol tcp_udp
+ }
+ rule 2242 {
+ action accept
+ description FWA076E_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA076E_1
+ }
+ port 2199,2197
+ }
+ protocol tcp
+ }
+ rule 2243 {
+ action accept
+ description FWA076E_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA076E_1
+ }
+ port 8000-8010
+ }
+ protocol tcp_udp
+ }
+ rule 2244 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-82.165.166.41
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 8447,8443,443,80,22
+ }
+ protocol tcp
+ source {
+ address 82.165.166.41
+ }
+ }
+ rule 2245 {
+ action accept
+ description FW2F868_6-TCP-ALLOW-213.171.217.180
+ destination {
+ group {
+ address-group DT_FW2F868_6
+ }
+ port 22,80
+ }
+ protocol tcp
+ source {
+ address 213.171.217.180
+ }
+ }
+ rule 2246 {
+ action accept
+ description FW2F868_6-TCP-ALLOW-213.171.217.184
+ destination {
+ group {
+ address-group DT_FW2F868_6
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.184
+ }
+ }
+ rule 2247 {
+ action accept
+ description FW2F868_6-TCP-ALLOW-213.171.217.185
+ destination {
+ group {
+ address-group DT_FW2F868_6
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.185
+ }
+ }
+ rule 2248 {
+ action accept
+ description FW2F868_6-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2F868_6
+ }
+ port 161
+ }
+ protocol udp
+ }
+ rule 2249 {
+ action accept
+ description FW2F868_6-TCP-ALLOW-213.171.217.102
+ destination {
+ group {
+ address-group DT_FW2F868_6
+ }
+ port 22,24
+ }
+ protocol tcp
+ source {
+ address 213.171.217.102
+ }
+ }
+ rule 2250 {
+ action accept
+ description FW9C682_3-TCP-ALLOW-80.194.78.162
+ destination {
+ group {
+ address-group DT_FW9C682_3
+ }
+ port 8443,22
+ }
+ protocol tcp
+ source {
+ address 80.194.78.162
+ }
+ }
+ rule 2251 {
+ action accept
+ description VPN-21822-ANY-ALLOW-10.4.54.47
+ destination {
+ group {
+ address-group DT_VPN-21822
+ }
+ }
+ source {
+ address 10.4.54.47
+ }
+ }
+ rule 2252 {
+ action accept
+ description FW825C8_19-TCP-ALLOW-77.68.75.244
+ destination {
+ group {
+ address-group DT_FW825C8_19
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 77.68.75.244
+ }
+ }
+ rule 2253 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-195.147.173.92
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 8443,22
+ }
+ protocol tcp
+ source {
+ address 195.147.173.92
+ }
+ }
+ rule 2254 {
+ action accept
+ description FW1D511_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1D511_2
+ }
+ port 8090
+ }
+ protocol tcp
+ }
+ rule 2255 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-85.17.25.47
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 85.17.25.47
+ }
+ }
+ rule 2256 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-77.68.89.209
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306,22
+ }
+ protocol tcp
+ source {
+ address 77.68.89.209
+ }
+ }
+ rule 2257 {
+ action accept
+ description FWE2AB5_8-TCP-ALLOW-213.171.217.184
+ destination {
+ group {
+ address-group DT_FWE2AB5_8
+ }
+ port 7000
+ }
+ protocol tcp
+ source {
+ address 213.171.217.184
+ }
+ }
+ rule 2258 {
+ action accept
+ description FW0E383_9-TCP-ALLOW-77.68.94.177
+ destination {
+ group {
+ address-group DT_FW0E383_9
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 77.68.94.177
+ }
+ }
+ rule 2259 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-77.68.95.129
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306,22
+ }
+ protocol tcp
+ source {
+ address 77.68.95.129
+ }
+ }
+ rule 2260 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-109.104.118.136
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 109.104.118.136
+ }
+ }
+ rule 2261 {
+ action accept
+ description FW1FA9E_1-TCP-ALLOW-78.88.254.99
+ destination {
+ group {
+ address-group DT_FW1FA9E_1
+ }
+ port 9000,8200,5601,4444
+ }
+ protocol tcp
+ source {
+ address 78.88.254.99
+ }
+ }
+ rule 2262 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-175.157.46.27
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 175.157.46.27
+ }
+ }
+ rule 2263 {
+ action accept
+ description FWA7A50_1-TCP-ALLOW-81.110.192.198
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 81.110.192.198
+ }
+ }
+ rule 2264 {
+ action accept
+ description VPN-21822-ANY-ALLOW-10.4.55.47
+ destination {
+ group {
+ address-group DT_VPN-21822
+ }
+ }
+ source {
+ address 10.4.55.47
+ }
+ }
+ rule 2265 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-77.68.31.195
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 27017,5000
+ }
+ protocol tcp
+ source {
+ address 77.68.31.195
+ }
+ }
+ rule 2266 {
+ action accept
+ description FW45BEB_1-TCP-ALLOW-62.3.71.238
+ destination {
+ group {
+ address-group DT_FW45BEB_1
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 62.3.71.238
+ }
+ }
+ rule 2267 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.113
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.113
+ }
+ }
+ rule 2268 {
+ action accept
+ description VPN-23946-ANY-ALLOW-10.4.58.13
+ destination {
+ group {
+ address-group DT_VPN-23946
+ }
+ }
+ source {
+ address 10.4.58.13
+ }
+ }
+ rule 2269 {
+ action accept
+ description FW98818_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW98818_1
+ }
+ port 27015
+ }
+ protocol tcp
+ }
+ rule 2270 {
+ action accept
+ description VPN-23946-ANY-ALLOW-10.4.59.13
+ destination {
+ group {
+ address-group DT_VPN-23946
+ }
+ }
+ source {
+ address 10.4.59.13
+ }
+ }
+ rule 2271 {
+ action accept
+ description VPN-28031-ANY-ALLOW-10.4.88.197
+ destination {
+ group {
+ address-group DT_VPN-28031
+ }
+ }
+ source {
+ address 10.4.88.197
+ }
+ }
+ rule 2272 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-109.104.118.231
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 109.104.118.231
+ }
+ }
+ rule 2273 {
+ action accept
+ description FW5A5D7_3-TCP_UDP-ALLOW-51.219.222.28
+ destination {
+ group {
+ address-group DT_FW5A5D7_3
+ }
+ port 500
+ }
+ protocol tcp_udp
+ source {
+ address 51.219.222.28
+ }
+ }
+ rule 2274 {
+ action accept
+ description FW32EFF_25-TCP-ALLOW-185.106.220.231
+ destination {
+ group {
+ address-group DT_FW32EFF_25
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 185.106.220.231
+ }
+ }
+ rule 2275 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-109.104.118.66
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 109.104.118.66
+ }
+ }
+ rule 2276 {
+ action accept
+ description FW934AE_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW934AE_1
+ }
+ port 1194
+ }
+ protocol udp
+ }
+ rule 2277 {
+ action accept
+ description VPN-28031-ANY-ALLOW-10.4.89.197
+ destination {
+ group {
+ address-group DT_VPN-28031
+ }
+ }
+ source {
+ address 10.4.89.197
+ }
+ }
+ rule 2278 {
+ action accept
+ description FW6863A_4-TCP_UDP-ALLOW-82.165.166.41
+ destination {
+ group {
+ address-group DT_FW6863A_4
+ }
+ port 21-10000
+ }
+ protocol tcp_udp
+ source {
+ address 82.165.166.41
+ }
+ }
+ rule 2279 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-109.104.119.162
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 109.104.119.162
+ }
+ }
+ rule 2280 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-109.74.199.143
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 109.74.199.143
+ }
+ }
+ rule 2281 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-185.92.25.48
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 185.92.25.48
+ }
+ }
+ rule 2282 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-207.148.2.40
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 207.148.2.40
+ }
+ }
+ rule 2283 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-45.76.235.62
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 45.76.235.62
+ }
+ }
+ rule 2284 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-45.76.236.93
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 45.76.236.93
+ }
+ }
+ rule 2285 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-45.76.59.5
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 45.76.59.5
+ }
+ }
+ rule 2286 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-77.68.15.134
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 4444,3306
+ }
+ protocol tcp
+ source {
+ address 77.68.15.134
+ }
+ }
+ rule 2287 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-77.68.22.208
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 4444,3306
+ }
+ protocol tcp
+ source {
+ address 77.68.22.208
+ }
+ }
+ rule 2288 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-77.68.23.108
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 77.68.23.108
+ }
+ }
+ rule 2289 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-77.68.23.54
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 77.68.23.54
+ }
+ }
+ rule 2290 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-77.68.30.45
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 77.68.30.45
+ }
+ }
+ rule 2291 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-77.68.7.198
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 77.68.7.198
+ }
+ }
+ rule 2292 {
+ action accept
+ description VPN-29631-ANY-ALLOW-10.4.54.76
+ destination {
+ group {
+ address-group DT_VPN-29631
+ }
+ }
+ source {
+ address 10.4.54.76
+ }
+ }
+ rule 2293 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-77.68.89.200
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 4444,3306
+ }
+ protocol tcp
+ source {
+ address 77.68.89.200
+ }
+ }
+ rule 2294 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-77.68.91.50
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 77.68.91.50
+ }
+ }
+ rule 2295 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-82.165.206.230
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 82.165.206.230
+ }
+ }
+ rule 2296 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-82.165.207.109
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 4444,3306
+ }
+ protocol tcp
+ source {
+ address 82.165.207.109
+ }
+ }
+ rule 2297 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-94.196.156.5
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 94.196.156.5
+ }
+ }
+ rule 2298 {
+ action accept
+ description FW1F3D0_6-TCP_UDP-ALLOW-77.68.15.134
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 4567-4568
+ }
+ protocol tcp_udp
+ source {
+ address 77.68.15.134
+ }
+ }
+ rule 2299 {
+ action accept
+ description FW1F3D0_6-TCP_UDP-ALLOW-77.68.22.208
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 4567-4568
+ }
+ protocol tcp_udp
+ source {
+ address 77.68.22.208
+ }
+ }
+ rule 2300 {
+ action accept
+ description FW1F3D0_6-TCP_UDP-ALLOW-77.68.23.109
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 4567-4568
+ }
+ protocol tcp_udp
+ source {
+ address 77.68.23.109
+ }
+ }
+ rule 2301 {
+ action accept
+ description FW1F3D0_6-TCP_UDP-ALLOW-77.68.89.200
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 4567-4568
+ }
+ protocol tcp_udp
+ source {
+ address 77.68.89.200
+ }
+ }
+ rule 2302 {
+ action accept
+ description FW05339_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW05339_1
+ }
+ port 8085,5055,5013,5005,444
+ }
+ protocol tcp
+ }
+ rule 2303 {
+ action accept
+ description FW32EFF_25-TCP-ALLOW-217.169.61.164
+ destination {
+ group {
+ address-group DT_FW32EFF_25
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 217.169.61.164
+ }
+ }
+ rule 2304 {
+ action accept
+ description FW89619_1-TCP_UDP-ALLOW-185.83.65.45
+ destination {
+ group {
+ address-group DT_FW89619_1
+ }
+ port 5060
+ }
+ protocol tcp_udp
+ source {
+ address 185.83.65.45
+ }
+ }
+ rule 2305 {
+ action accept
+ description VPN-13983-ANY-ALLOW-10.4.58.176
+ destination {
+ group {
+ address-group DT_VPN-13983
+ }
+ }
+ source {
+ address 10.4.58.176
+ }
+ }
+ rule 2306 {
+ action accept
+ description FWDAF47_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWDAF47_1
+ }
+ port 8090,7080,443,53
+ }
+ protocol tcp_udp
+ }
+ rule 2307 {
+ action accept
+ description VPN-29631-ANY-ALLOW-10.4.55.77
+ destination {
+ group {
+ address-group DT_VPN-29631
+ }
+ }
+ source {
+ address 10.4.55.77
+ }
+ }
+ rule 2308 {
+ action accept
+ description VPN-34309-ANY-ALLOW-10.4.58.142
+ destination {
+ group {
+ address-group DT_VPN-34309
+ }
+ }
+ source {
+ address 10.4.58.142
+ }
+ }
+ rule 2309 {
+ action accept
+ description FW27949_2-TCP-ALLOW-138.124.142.180
+ destination {
+ group {
+ address-group DT_FW27949_2
+ }
+ port 443,80
+ }
+ protocol tcp
+ source {
+ address 138.124.142.180
+ }
+ }
+ rule 2310 {
+ action accept
+ description FWF8F85_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF8F85_1
+ }
+ port 3306
+ }
+ protocol tcp_udp
+ }
+ rule 2311 {
+ action accept
+ description FWDAF47_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWDAF47_1
+ }
+ port 40110-40210
+ }
+ protocol tcp
+ }
+ rule 2312 {
+ action accept
+ description VPN-34309-ANY-ALLOW-10.4.59.142
+ destination {
+ group {
+ address-group DT_VPN-34309
+ }
+ }
+ source {
+ address 10.4.59.142
+ }
+ }
+ rule 2313 {
+ action accept
+ description FWA0531_1-TCP-ALLOW-87.224.39.220
+ destination {
+ group {
+ address-group DT_FWA0531_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 87.224.39.220
+ }
+ }
+ rule 2314 {
+ action accept
+ description FW5A5D7_3-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW5A5D7_3
+ }
+ port 1334
+ }
+ protocol tcp
+ }
+ rule 2315 {
+ action accept
+ description FW8C927_1-TCP_UDP-ALLOW-84.92.125.78
+ destination {
+ group {
+ address-group DT_FW8C927_1
+ }
+ port 3306,22
+ }
+ protocol tcp_udp
+ source {
+ address 84.92.125.78
+ }
+ }
+ rule 2316 {
+ action accept
+ description FW8C927_1-TCP_UDP-ALLOW-88.208.238.152
+ destination {
+ group {
+ address-group DT_FW8C927_1
+ }
+ port 3306,22
+ }
+ protocol tcp_udp
+ source {
+ address 88.208.238.152
+ }
+ }
+ rule 2317 {
+ action accept
+ description FW81138_1-ICMP-ALLOW-82.165.232.19
+ destination {
+ group {
+ address-group DT_FW81138_1
+ }
+ }
+ protocol icmp
+ source {
+ address 82.165.232.19
+ }
+ }
+ rule 2318 {
+ action accept
+ description FW28892_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW28892_1
+ }
+ port 7000
+ }
+ protocol tcp
+ }
+ rule 2319 {
+ action accept
+ description FWC96A1_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC96A1_1
+ }
+ port 222
+ }
+ protocol tcp
+ }
+ rule 2320 {
+ action accept
+ description VPN-13983-ANY-ALLOW-10.4.59.176
+ destination {
+ group {
+ address-group DT_VPN-13983
+ }
+ }
+ source {
+ address 10.4.59.176
+ }
+ }
+ rule 2321 {
+ action accept
+ description FW2FB61_1-TCP-ALLOW-5.183.104.15
+ destination {
+ group {
+ address-group DT_FW2FB61_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 5.183.104.15
+ }
+ }
+ rule 2322 {
+ action accept
+ description FW81138_1-ICMP-ALLOW-82.20.69.137
+ destination {
+ group {
+ address-group DT_FW81138_1
+ }
+ }
+ protocol icmp
+ source {
+ address 82.20.69.137
+ }
+ }
+ rule 2323 {
+ action accept
+ description FW72F37_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW72F37_1
+ }
+ port 7770-7800,44445
+ }
+ protocol tcp
+ }
+ rule 2324 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-81.111.155.34
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 81.111.155.34
+ }
+ }
+ rule 2325 {
+ action accept
+ description VPN-20306-ANY-ALLOW-10.4.88.173
+ destination {
+ group {
+ address-group DT_VPN-20306
+ }
+ }
+ source {
+ address 10.4.88.173
+ }
+ }
+ rule 2326 {
+ action accept
+ description FW6C992_1-TCP-ALLOW-89.33.185.0_24
+ destination {
+ group {
+ address-group DT_FW6C992_1
+ }
+ port 8447,8443,22
+ }
+ protocol tcp
+ source {
+ address 89.33.185.0/24
+ }
+ }
+ rule 2327 {
+ action accept
+ description FW2FB61_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2FB61_1
+ }
+ port 45000
+ }
+ protocol tcp
+ }
+ rule 2328 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-175.157.46.202
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 175.157.46.202
+ }
+ }
+ rule 2329 {
+ action accept
+ description FWF9C28_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF9C28_2
+ }
+ port 7770-7800,44445
+ }
+ protocol tcp
+ }
+ rule 2330 {
+ action accept
+ description FW3DBF8_9-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW3DBF8_9
+ }
+ port 8088,8080,5090,5060,3478,1935
+ }
+ protocol tcp_udp
+ }
+ rule 2331 {
+ action accept
+ description FW3DBF8_9-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW3DBF8_9
+ }
+ port 5062,5061,5015,5001
+ }
+ protocol tcp
+ }
+ rule 2332 {
+ action accept
+ description VPN-16402-ANY-ALLOW-10.4.88.60
+ destination {
+ group {
+ address-group DT_VPN-16402
+ }
+ }
+ source {
+ address 10.4.88.60
+ }
+ }
+ rule 2333 {
+ action accept
+ description FWC1315_1-TCP-ALLOW-62.3.71.238
+ destination {
+ group {
+ address-group DT_FWC1315_1
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 62.3.71.238
+ }
+ }
+ rule 2334 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 8001,80
+ }
+ protocol tcp_udp
+ }
+ rule 2335 {
+ action accept
+ description FWAFF0A_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWAFF0A_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2336 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-195.20.253.19
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 195.20.253.19
+ }
+ }
+ rule 2337 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.73
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.73
+ }
+ }
+ rule 2338 {
+ action accept
+ description VPN-16402-ANY-ALLOW-10.4.89.60
+ destination {
+ group {
+ address-group DT_VPN-16402
+ }
+ }
+ source {
+ address 10.4.89.60
+ }
+ }
+ rule 2339 {
+ action accept
+ description VPN-15951-ANY-ALLOW-10.4.86.90
+ destination {
+ group {
+ address-group DT_VPN-15951
+ }
+ }
+ source {
+ address 10.4.86.90
+ }
+ }
+ rule 2340 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-77.68.77.181
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 27017,5000
+ }
+ protocol tcp
+ source {
+ address 77.68.77.181
+ }
+ }
+ rule 2341 {
+ action accept
+ description FWE9F7D_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE9F7D_1
+ }
+ port 4035
+ }
+ protocol tcp
+ }
+ rule 2342 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.208.131
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.208.131
+ }
+ }
+ rule 2343 {
+ action accept
+ description VPN-15951-ANY-ALLOW-10.4.87.90
+ destination {
+ group {
+ address-group DT_VPN-15951
+ }
+ }
+ source {
+ address 10.4.87.90
+ }
+ }
+ rule 2344 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-77.68.93.190
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 27017,5000
+ }
+ protocol tcp
+ source {
+ address 77.68.93.190
+ }
+ }
+ rule 2345 {
+ action accept
+ description VPN-8159-ANY-ALLOW-10.4.59.91
+ destination {
+ group {
+ address-group DT_VPN-8159
+ }
+ }
+ source {
+ address 10.4.59.91
+ }
+ }
+ rule 2346 {
+ action accept
+ description VPN-12870-ANY-ALLOW-10.4.54.67
+ destination {
+ group {
+ address-group DT_VPN-12870
+ }
+ }
+ source {
+ address 10.4.54.67
+ }
+ }
+ rule 2347 {
+ action accept
+ description FW930F3_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW930F3_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 2348 {
+ action accept
+ description FW12C32_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW12C32_1
+ }
+ port 465,53,25
+ }
+ protocol tcp_udp
+ }
+ rule 2349 {
+ action accept
+ description FW28EC8_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW28EC8_1
+ }
+ port 20443
+ }
+ protocol tcp
+ }
+ rule 2350 {
+ action accept
+ description VPN-12870-ANY-ALLOW-10.4.55.68
+ destination {
+ group {
+ address-group DT_VPN-12870
+ }
+ }
+ source {
+ address 10.4.55.68
+ }
+ }
+ rule 2351 {
+ action accept
+ description FW934AE_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW934AE_1
+ }
+ port 32401,32400,8081
+ }
+ protocol tcp_udp
+ }
+ rule 2352 {
+ action accept
+ description FW6863A_4-TCP-ALLOW-185.173.161.154
+ destination {
+ group {
+ address-group DT_FW6863A_4
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 185.173.161.154
+ }
+ }
+ rule 2353 {
+ action accept
+ description FW013EF_2-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW013EF_2
+ }
+ port 10600-10998,9000-9398,5090,5060-5070
+ }
+ protocol udp
+ }
+ rule 2354 {
+ action accept
+ description FW85040_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW85040_1
+ }
+ port 3210
+ }
+ protocol tcp_udp
+ }
+ rule 2355 {
+ action accept
+ description FW8B21D_1-TCP_UDP-ALLOW-131.153.100.98
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ port 22
+ }
+ protocol tcp_udp
+ source {
+ address 131.153.100.98
+ }
+ }
+ rule 2356 {
+ action accept
+ description FW8B21D_1-TCP_UDP-ALLOW-213.133.99.176
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ port 22
+ }
+ protocol tcp_udp
+ source {
+ address 213.133.99.176
+ }
+ }
+ rule 2357 {
+ action accept
+ description FW6EFD7_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6EFD7_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2358 {
+ action accept
+ description FW8B21D_1-TCP_UDP-ALLOW-62.253.153.163
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ port 8443,22
+ }
+ protocol tcp_udp
+ source {
+ address 62.253.153.163
+ }
+ }
+ rule 2359 {
+ action accept
+ description FWCB0CF_7-TCP-ALLOW-212.159.153.201
+ destination {
+ group {
+ address-group DT_FWCB0CF_7
+ }
+ port 6443,5432-5434,5000-5100,3306-3308,990,989,22,21
+ }
+ protocol tcp
+ source {
+ address 212.159.153.201
+ }
+ }
+ rule 2360 {
+ action accept
+ description FW75CA4_6-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW75CA4_6
+ }
+ port 51472,3747,3420
+ }
+ protocol tcp
+ }
+ rule 2361 {
+ action accept
+ description FWF9C28_4-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF9C28_4
+ }
+ port 23,7770-7800,44445,6109
+ }
+ protocol tcp
+ }
+ rule 2362 {
+ action accept
+ description FW6B39D_1-TCP-ALLOW-120.72.95.88_29
+ destination {
+ group {
+ address-group DT_FW6B39D_1
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 120.72.95.88/29
+ }
+ }
+ rule 2363 {
+ action accept
+ description FW934AE_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW934AE_1
+ }
+ port 20000
+ }
+ protocol tcp
+ }
+ rule 2364 {
+ action accept
+ description FW12C32_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW12C32_1
+ }
+ port 2323,953
+ }
+ protocol tcp
+ }
+ rule 2365 {
+ action accept
+ description FW49897_1-TCP-ALLOW-2.121.90.207
+ destination {
+ group {
+ address-group DT_FW49897_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 2.121.90.207
+ }
+ }
+ rule 2366 {
+ action accept
+ description FW6B39D_1-TCP-ALLOW-120.72.91.104_29
+ destination {
+ group {
+ address-group DT_FW6B39D_1
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 120.72.91.104/29
+ }
+ }
+ rule 2367 {
+ action accept
+ description FW4F5EE_10-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4F5EE_10
+ }
+ port 83,86,82
+ }
+ protocol tcp
+ }
+ rule 2368 {
+ action accept
+ description FWF791C_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF791C_1
+ }
+ port 6001
+ }
+ protocol tcp
+ }
+ rule 2369 {
+ action accept
+ description FWEF92E_5-ESP-ALLOW-109.228.37.19
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol esp
+ source {
+ address 109.228.37.19
+ }
+ }
+ rule 2370 {
+ action accept
+ description FWE57AD_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE57AD_1
+ }
+ port 57000-58000
+ }
+ protocol tcp
+ }
+ rule 2371 {
+ action accept
+ description FWC0CE0_1-TCP-ALLOW-62.232.209.221
+ destination {
+ group {
+ address-group DT_FWC0CE0_1
+ }
+ port 49152-65535,8447,8443,22,21
+ }
+ protocol tcp
+ source {
+ address 62.232.209.221
+ }
+ }
+ rule 2372 {
+ action accept
+ description FW0192C_1-TCP-ALLOW-41.140.242.86
+ destination {
+ group {
+ address-group DT_FW0192C_1
+ }
+ port 3306,22
+ }
+ protocol tcp
+ source {
+ address 41.140.242.86
+ }
+ }
+ rule 2373 {
+ action accept
+ description FWEEC75_1-TCP-ALLOW-54.171.71.110
+ destination {
+ group {
+ address-group DT_FWEEC75_1
+ }
+ port 21
+ }
+ protocol tcp
+ source {
+ address 54.171.71.110
+ }
+ }
+ rule 2374 {
+ action accept
+ description FW8B21D_1-TCP_UDP-ALLOW-95.149.182.69
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ port 22
+ }
+ protocol tcp_udp
+ source {
+ address 95.149.182.69
+ }
+ }
+ rule 2375 {
+ action accept
+ description FW8B21D_1-TCP-ALLOW-185.201.16.0_22
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ port 25
+ }
+ protocol tcp
+ source {
+ address 185.201.16.0/22
+ }
+ }
+ rule 2376 {
+ action accept
+ description FW8B21D_1-TCP-ALLOW-213.133.99.176
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ port 25
+ }
+ protocol tcp
+ source {
+ address 213.133.99.176
+ }
+ }
+ rule 2377 {
+ action accept
+ description FW8B21D_1-TCP-ALLOW-95.211.160.147
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ port 25
+ }
+ protocol tcp
+ source {
+ address 95.211.160.147
+ }
+ }
+ rule 2378 {
+ action accept
+ description FW6863A_4-TCP-ALLOW-212.227.9.72
+ destination {
+ group {
+ address-group DT_FW6863A_4
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 212.227.9.72
+ }
+ }
+ rule 2379 {
+ action accept
+ description FW8B21D_1-ESP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ }
+ protocol esp
+ }
+ rule 2380 {
+ action accept
+ description FW8B21D_1-AH-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ }
+ protocol ah
+ }
+ rule 2381 {
+ action accept
+ description FW8B21D_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ port 8181,4500,1194,993,941,500,53
+ }
+ protocol tcp_udp
+ }
+ rule 2382 {
+ action accept
+ description FW6863A_4-TCP-ALLOW-85.17.25.47
+ destination {
+ group {
+ address-group DT_FW6863A_4
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 85.17.25.47
+ }
+ }
+ rule 2383 {
+ action accept
+ description FW6863A_4-TCP-ALLOW-91.232.105.39
+ destination {
+ group {
+ address-group DT_FW6863A_4
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 91.232.105.39
+ }
+ }
+ rule 2384 {
+ action accept
+ description FW6863A_4-TCP-ALLOW-93.190.142.120
+ destination {
+ group {
+ address-group DT_FW6863A_4
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 93.190.142.120
+ }
+ }
+ rule 2385 {
+ action accept
+ description FW6863A_4-TCP-ALLOW-95.168.171.130
+ destination {
+ group {
+ address-group DT_FW6863A_4
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 95.168.171.130
+ }
+ }
+ rule 2386 {
+ action accept
+ description FW6863A_4-TCP-ALLOW-95.168.171.157
+ destination {
+ group {
+ address-group DT_FW6863A_4
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 95.168.171.157
+ }
+ }
+ rule 2387 {
+ action accept
+ description FWD4A27_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD4A27_1
+ }
+ port 32400
+ }
+ protocol tcp
+ }
+ rule 2388 {
+ action accept
+ description FW2ACFF_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2ACFF_1
+ }
+ port 10299,60050-60055
+ }
+ protocol tcp_udp
+ }
+ rule 2389 {
+ action accept
+ description FWCB0CF_7-TCP-ALLOW-193.248.62.45
+ destination {
+ group {
+ address-group DT_FWCB0CF_7
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 193.248.62.45
+ }
+ }
+ rule 2390 {
+ action accept
+ description FWCB0CF_7-TCP-ALLOW-78.249.208.17
+ destination {
+ group {
+ address-group DT_FWCB0CF_7
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 78.249.208.17
+ }
+ }
+ rule 2391 {
+ action accept
+ description FWC8E8E_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC8E8E_1
+ }
+ port 6000
+ }
+ protocol tcp_udp
+ }
+ rule 2392 {
+ action accept
+ description FW30D21_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW30D21_1
+ }
+ port 2476
+ }
+ protocol tcp
+ }
+ rule 2393 {
+ action accept
+ description FW0192C_1-TCP-ALLOW-41.140.242.94
+ destination {
+ group {
+ address-group DT_FW0192C_1
+ }
+ port 3306,22
+ }
+ protocol tcp
+ source {
+ address 41.140.242.94
+ }
+ }
+ rule 2394 {
+ action accept
+ description FW59F39_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW59F39_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2395 {
+ action accept
+ description FWEF92E_7-ESP-ALLOW-77.68.77.57
+ destination {
+ group {
+ address-group DT_FWEF92E_7
+ }
+ }
+ protocol esp
+ source {
+ address 77.68.77.57
+ }
+ }
+ rule 2396 {
+ action accept
+ description FW826BA_3-TCP-ALLOW-51.219.47.177
+ destination {
+ group {
+ address-group DT_FW826BA_3
+ }
+ port 3389,21
+ }
+ protocol tcp
+ source {
+ address 51.219.47.177
+ }
+ }
+ rule 2397 {
+ action accept
+ description FW826BA_3-TCP-ALLOW-86.172.128.50
+ destination {
+ group {
+ address-group DT_FW826BA_3
+ }
+ port 1433,21
+ }
+ protocol tcp
+ source {
+ address 86.172.128.50
+ }
+ }
+ rule 2398 {
+ action accept
+ description FW826BA_3-TCP-ALLOW-88.105.1.20
+ destination {
+ group {
+ address-group DT_FW826BA_3
+ }
+ port 21
+ }
+ protocol tcp
+ source {
+ address 88.105.1.20
+ }
+ }
+ rule 2399 {
+ action accept
+ description FW6863A_4-TCP-ALLOW-95.211.243.198
+ destination {
+ group {
+ address-group DT_FW6863A_4
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 95.211.243.198
+ }
+ }
+ rule 2400 {
+ action accept
+ description FW25843_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW25843_1
+ }
+ port 9001,7070,5500,5488,5000,4500,4000,3500,3000,1883,1880
+ }
+ protocol tcp
+ }
+ rule 2401 {
+ action accept
+ description FW89619_1-TCP_UDP-ALLOW-185.83.65.46
+ destination {
+ group {
+ address-group DT_FW89619_1
+ }
+ port 5060
+ }
+ protocol tcp_udp
+ source {
+ address 185.83.65.46
+ }
+ }
+ rule 2402 {
+ action accept
+ description FW5858F_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW5858F_1
+ }
+ port 1883
+ }
+ protocol tcp
+ }
+ rule 2403 {
+ action accept
+ description FW826BA_3-TCP-ALLOW-95.147.108.173
+ destination {
+ group {
+ address-group DT_FW826BA_3
+ }
+ port 21
+ }
+ protocol tcp
+ source {
+ address 95.147.108.173
+ }
+ }
+ rule 2404 {
+ action accept
+ description FW9C682_3-TCP-ALLOW-52.56.193.88
+ destination {
+ group {
+ address-group DT_FW9C682_3
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 52.56.193.88
+ }
+ }
+ rule 2405 {
+ action accept
+ description FW0745F_5-TCP-ALLOW-109.228.63.82
+ destination {
+ group {
+ address-group DT_FW0745F_5
+ }
+ port 5666
+ }
+ protocol tcp
+ source {
+ address 109.228.63.82
+ }
+ }
+ rule 2406 {
+ action accept
+ description FWC0CE0_1-TCP-ALLOW-90.255.228.213
+ destination {
+ group {
+ address-group DT_FWC0CE0_1
+ }
+ port 49152-65535,8443,21
+ }
+ protocol tcp
+ source {
+ address 90.255.228.213
+ }
+ }
+ rule 2407 {
+ action accept
+ description FW210E2_8-AH-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW210E2_8
+ }
+ }
+ protocol ah
+ }
+ rule 2408 {
+ action accept
+ description FW210E2_8-ESP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW210E2_8
+ }
+ }
+ protocol esp
+ }
+ rule 2409 {
+ action accept
+ description FW210E2_8-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW210E2_8
+ }
+ port 41,62000,23,4500,50,9876,3391,88,135
+ }
+ protocol tcp
+ }
+ rule 2410 {
+ action accept
+ description FW210E2_8-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW210E2_8
+ }
+ port 500
+ }
+ protocol udp
+ }
+ rule 2411 {
+ action accept
+ description VPN-8625-ANY-ALLOW-10.4.54.103
+ destination {
+ group {
+ address-group DT_VPN-8625
+ }
+ }
+ source {
+ address 10.4.54.103
+ }
+ }
+ rule 2412 {
+ action accept
+ description VPN-8625-ANY-ALLOW-10.4.55.104
+ destination {
+ group {
+ address-group DT_VPN-8625
+ }
+ }
+ source {
+ address 10.4.55.104
+ }
+ }
+ rule 2413 {
+ action accept
+ description FW73A64_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW73A64_1
+ }
+ port 61616,8181,8161,8082,4244,4243,4242,4241
+ }
+ protocol tcp
+ }
+ rule 2414 {
+ action accept
+ description VPN-19135-ANY-ALLOW-10.4.86.165
+ destination {
+ group {
+ address-group DT_VPN-19135
+ }
+ }
+ source {
+ address 10.4.86.165
+ }
+ }
+ rule 2415 {
+ action accept
+ description FWCB0CF_7-TCP-ALLOW-82.65.107.3
+ destination {
+ group {
+ address-group DT_FWCB0CF_7
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 82.65.107.3
+ }
+ }
+ rule 2416 {
+ action accept
+ description FWCB0CF_7-TCP-ALLOW-195.2.139.221
+ destination {
+ group {
+ address-group DT_FWCB0CF_7
+ }
+ port 5432-5434,3306-3308
+ }
+ protocol tcp
+ source {
+ address 195.2.139.221
+ }
+ }
+ rule 2417 {
+ action accept
+ description VPN-19135-ANY-ALLOW-10.4.87.165
+ destination {
+ group {
+ address-group DT_VPN-19135
+ }
+ }
+ source {
+ address 10.4.87.165
+ }
+ }
+ rule 2418 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-87.75.109.83
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 27017,5000
+ }
+ protocol tcp
+ source {
+ address 87.75.109.83
+ }
+ }
+ rule 2419 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.83
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.83
+ }
+ }
+ rule 2420 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-84.92.65.192
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 84.92.65.192
+ }
+ }
+ rule 2421 {
+ action accept
+ description FW73A64_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW73A64_1
+ }
+ port 9200,5601,4247,4246,4245
+ }
+ protocol tcp_udp
+ }
+ rule 2422 {
+ action accept
+ description FW4735F_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4735F_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2423 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-109.176.154.238
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 7990,3389
+ }
+ protocol tcp
+ source {
+ address 109.176.154.238
+ }
+ }
+ rule 2424 {
+ action accept
+ description FW6863A_4-TCP-ALLOW-95.211.243.206
+ destination {
+ group {
+ address-group DT_FW6863A_4
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 95.211.243.206
+ }
+ }
+ rule 2425 {
+ action accept
+ description FW89619_1-TCP_UDP-ALLOW-81.133.80.114
+ destination {
+ group {
+ address-group DT_FW89619_1
+ }
+ port 5060
+ }
+ protocol tcp_udp
+ source {
+ address 81.133.80.114
+ }
+ }
+ rule 2426 {
+ action accept
+ description FW89619_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW89619_1
+ }
+ port 5090
+ }
+ protocol tcp_udp
+ }
+ rule 2427 {
+ action accept
+ description FW8A57A_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8A57A_1
+ }
+ port 49155,49154,7700,53,43
+ }
+ protocol tcp_udp
+ }
+ rule 2428 {
+ action accept
+ description FW8C72E_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8C72E_1
+ }
+ port 500,4500
+ }
+ protocol udp
+ }
+ rule 2429 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-18.135.66.162
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 18.135.66.162
+ }
+ }
+ rule 2430 {
+ action accept
+ description FW2C5AE_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2C5AE_1
+ }
+ port 58080,58008,8545,7175
+ }
+ protocol tcp
+ }
+ rule 2431 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-80.209.144.52
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 80.209.144.52
+ }
+ }
+ rule 2432 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-82.153.21.103
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 7990,3389
+ }
+ protocol tcp
+ source {
+ address 82.153.21.103
+ }
+ }
+ rule 2433 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.41
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.41
+ }
+ }
+ rule 2434 {
+ action accept
+ description FW0745F_5-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0745F_5
+ }
+ port 32770,8001,7801
+ }
+ protocol tcp
+ }
+ rule 2435 {
+ action accept
+ description FW85E02_11-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW85E02_11
+ }
+ port 5090,5060
+ }
+ protocol tcp_udp
+ }
+ rule 2436 {
+ action accept
+ description VPN-21982-ANY-ALLOW-10.4.58.43
+ destination {
+ group {
+ address-group DT_VPN-21982
+ }
+ }
+ source {
+ address 10.4.58.43
+ }
+ }
+ rule 2437 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-82.17.52.191
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 82.17.52.191
+ }
+ }
+ rule 2438 {
+ action accept
+ description FW66347_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW66347_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 2439 {
+ action accept
+ description FW11082_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW11082_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2440 {
+ action accept
+ description VPN-21982-ANY-ALLOW-10.4.59.43
+ destination {
+ group {
+ address-group DT_VPN-21982
+ }
+ }
+ source {
+ address 10.4.59.43
+ }
+ }
+ rule 2441 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-92.207.193.203
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 5000
+ }
+ protocol tcp
+ source {
+ address 92.207.193.203
+ }
+ }
+ rule 2442 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-77.99.253.161
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443,22,21
+ }
+ protocol tcp
+ source {
+ address 77.99.253.161
+ }
+ }
+ rule 2443 {
+ action accept
+ description FW0E383_9-TCP-ALLOW-77.99.245.103
+ destination {
+ group {
+ address-group DT_FW0E383_9
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 77.99.245.103
+ }
+ }
+ rule 2444 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-82.19.19.52
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 7990,3389
+ }
+ protocol tcp
+ source {
+ address 82.19.19.52
+ }
+ }
+ rule 2445 {
+ action accept
+ description FWEF92E_7-AH-ALLOW-77.68.77.57
+ destination {
+ group {
+ address-group DT_FWEF92E_7
+ }
+ }
+ protocol ah
+ source {
+ address 77.68.77.57
+ }
+ }
+ rule 2446 {
+ action accept
+ description VPN-16450-ANY-ALLOW-10.4.88.99
+ destination {
+ group {
+ address-group DT_VPN-16450
+ }
+ }
+ source {
+ address 10.4.88.99
+ }
+ }
+ rule 2447 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-82.2.186.129
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 82.2.186.129
+ }
+ }
+ rule 2448 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.157
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.157
+ }
+ }
+ rule 2449 {
+ action accept
+ description FW8EA04_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8EA04_1
+ }
+ port 1194
+ }
+ protocol udp
+ }
+ rule 2450 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-82.21.59.207
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 82.21.59.207
+ }
+ }
+ rule 2451 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-82.9.22.158
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443,21
+ }
+ protocol tcp
+ source {
+ address 82.9.22.158
+ }
+ }
+ rule 2452 {
+ action accept
+ description FWF3A1B_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF3A1B_1
+ }
+ port 1981,53
+ }
+ protocol tcp_udp
+ }
+ rule 2453 {
+ action accept
+ description FWEF92E_5-ESP-ALLOW-77.68.11.54
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol esp
+ source {
+ address 77.68.11.54
+ }
+ }
+ rule 2454 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-82.40.177.186
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 82.40.177.186
+ }
+ }
+ rule 2455 {
+ action accept
+ description FW0C25B_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0C25B_1
+ }
+ port 49152-65535,5224
+ }
+ protocol tcp
+ }
+ rule 2456 {
+ action accept
+ description FW85A7C_1-TCP-ALLOW-82.24.242.137
+ destination {
+ group {
+ address-group DT_FW85A7C_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 82.24.242.137
+ }
+ }
+ rule 2457 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-82.68.25.66
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 82.68.25.66
+ }
+ }
+ rule 2458 {
+ action accept
+ description FW826BA_3-TCP-ALLOW-51.89.148.173
+ destination {
+ group {
+ address-group DT_FW826BA_3
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 51.89.148.173
+ }
+ }
+ rule 2459 {
+ action accept
+ description FWA69A0_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA69A0_1
+ }
+ port 48402
+ }
+ protocol udp
+ }
+ rule 2460 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-82.69.79.85
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 82.69.79.85
+ }
+ }
+ rule 2461 {
+ action accept
+ description FWEF92E_5-ESP-ALLOW-77.68.77.149
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol esp
+ source {
+ address 77.68.77.149
+ }
+ }
+ rule 2462 {
+ action accept
+ description FWEF92E_6-ESP-ALLOW-77.68.77.57
+ destination {
+ group {
+ address-group DT_FWEF92E_6
+ }
+ }
+ protocol esp
+ source {
+ address 77.68.77.57
+ }
+ }
+ rule 2463 {
+ action accept
+ description FWEF92E_7-TCP-ALLOW-77.68.8.74
+ destination {
+ group {
+ address-group DT_FWEF92E_7
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 77.68.8.74
+ }
+ }
+ rule 2464 {
+ action accept
+ description FW49C3D_4-TCP-ALLOW-77.68.8.74
+ destination {
+ group {
+ address-group DT_FW49C3D_4
+ }
+ port 3389,445,443,80
+ }
+ protocol tcp
+ source {
+ address 77.68.8.74
+ }
+ }
+ rule 2465 {
+ action accept
+ description FW49C3D_6-TCP-ALLOW-77.68.8.74
+ destination {
+ group {
+ address-group DT_FW49C3D_6
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 77.68.8.74
+ }
+ }
+ rule 2466 {
+ action accept
+ description FW34C91_3-TCP-ALLOW-77.68.121.4
+ destination {
+ group {
+ address-group DT_FW34C91_3
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 77.68.121.4
+ }
+ }
+ rule 2467 {
+ action accept
+ description VPN-16450-ANY-ALLOW-10.4.89.99
+ destination {
+ group {
+ address-group DT_VPN-16450
+ }
+ }
+ source {
+ address 10.4.89.99
+ }
+ }
+ rule 2468 {
+ action accept
+ description FW0BB22_1-AH-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0BB22_1
+ }
+ }
+ protocol ah
+ }
+ rule 2469 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-86.139.57.116
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 86.139.57.116
+ }
+ }
+ rule 2470 {
+ action accept
+ description FW9E550_1-TCP-ALLOW-86.142.67.13
+ destination {
+ group {
+ address-group DT_FW9E550_1
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 86.142.67.13
+ }
+ }
+ rule 2471 {
+ action accept
+ description FW8B21D_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ port 2096,2095,2087,2086,2083,2082
+ }
+ protocol tcp
+ }
+ rule 2472 {
+ action accept
+ description FW050AC_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW050AC_1
+ }
+ port 2087
+ }
+ protocol tcp
+ }
+ rule 2473 {
+ action accept
+ description FW1FA9E_1-TCP-ALLOW-109.228.50.206
+ destination {
+ group {
+ address-group DT_FW1FA9E_1
+ }
+ port 5432
+ }
+ protocol tcp
+ source {
+ address 109.228.50.206
+ }
+ }
+ rule 2474 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-217.23.11.155
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 217.23.11.155
+ }
+ }
+ rule 2475 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-88.96.110.198
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 88.96.110.198
+ }
+ }
+ rule 2476 {
+ action accept
+ description FWEAE53_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWEAE53_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2477 {
+ action accept
+ description VPN-19474-ANY-ALLOW-10.4.88.161
+ destination {
+ group {
+ address-group DT_VPN-19474
+ }
+ }
+ source {
+ address 10.4.88.161
+ }
+ }
+ rule 2478 {
+ action accept
+ description VPN-19474-ANY-ALLOW-10.4.89.161
+ destination {
+ group {
+ address-group DT_VPN-19474
+ }
+ }
+ source {
+ address 10.4.89.161
+ }
+ }
+ rule 2479 {
+ action accept
+ description FW90AE3_1-TCP-ALLOW-68.33.220.233
+ destination {
+ group {
+ address-group DT_FW90AE3_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 68.33.220.233
+ }
+ }
+ rule 2480 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-86.10.163.127
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443,21
+ }
+ protocol tcp
+ source {
+ address 86.10.163.127
+ }
+ }
+ rule 2481 {
+ action accept
+ description FW2FB61_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2FB61_1
+ }
+ port 60182
+ }
+ protocol udp
+ }
+ rule 2482 {
+ action accept
+ description FW85A7C_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW85A7C_1
+ }
+ port 2457,2456
+ }
+ protocol tcp_udp
+ }
+ rule 2483 {
+ action accept
+ description FWBED52_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWBED52_1
+ }
+ port 1221,9000
+ }
+ protocol tcp
+ }
+ rule 2484 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-90.250.2.109
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389,443
+ }
+ protocol tcp
+ source {
+ address 90.250.2.109
+ }
+ }
+ rule 2485 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.49
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.49
+ }
+ }
+ rule 2486 {
+ action accept
+ description FWEF92E_5-ESP-ALLOW-77.68.77.70
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol esp
+ source {
+ address 77.68.77.70
+ }
+ }
+ rule 2487 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.250
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.250
+ }
+ }
+ rule 2488 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-95.168.171.131
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 95.168.171.131
+ }
+ }
+ rule 2489 {
+ action accept
+ description FW2379F_14-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2379F_14
+ }
+ port 48030,10997,10993,10992,10991,10902,1723,1701
+ }
+ protocol tcp
+ }
+ rule 2490 {
+ action accept
+ description FW8C927_1-TCP-ALLOW-84.92.125.78
+ destination {
+ group {
+ address-group DT_FW8C927_1
+ }
+ port 80
+ }
+ protocol tcp
+ source {
+ address 84.92.125.78
+ }
+ }
+ rule 2491 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-86.146.220.229
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443,21
+ }
+ protocol tcp
+ source {
+ address 86.146.220.229
+ }
+ }
+ rule 2492 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-2.218.5.59
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 8443,22
+ }
+ protocol tcp
+ source {
+ address 2.218.5.59
+ }
+ }
+ rule 2493 {
+ action accept
+ description VPN-18830-ANY-ALLOW-10.4.86.156
+ destination {
+ group {
+ address-group DT_VPN-18830
+ }
+ }
+ source {
+ address 10.4.86.156
+ }
+ }
+ rule 2494 {
+ action accept
+ description VPN-18830-ANY-ALLOW-10.4.87.156
+ destination {
+ group {
+ address-group DT_VPN-18830
+ }
+ }
+ source {
+ address 10.4.87.156
+ }
+ }
+ rule 2495 {
+ action accept
+ description FWEF92E_5-ESP-ALLOW-77.68.92.33
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol esp
+ source {
+ address 77.68.92.33
+ }
+ }
+ rule 2496 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-146.198.100.105
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389,443
+ }
+ protocol tcp
+ source {
+ address 146.198.100.105
+ }
+ }
+ rule 2497 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.55
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.55
+ }
+ }
+ rule 2498 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-123.231.84.113
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 123.231.84.113
+ }
+ }
+ rule 2499 {
+ action accept
+ description FW8C72E_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8C72E_1
+ }
+ port 60134,60135
+ }
+ protocol tcp
+ }
+ rule 2500 {
+ action accept
+ description FWAB44B_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWAB44B_1
+ }
+ port 3306
+ }
+ protocol tcp_udp
+ }
+ rule 2501 {
+ action accept
+ description FW2379F_14-TCP-ALLOW-51.148.87.29
+ destination {
+ group {
+ address-group DT_FW2379F_14
+ }
+ port 3389,21
+ }
+ protocol tcp
+ source {
+ address 51.148.87.29
+ }
+ }
+ rule 2502 {
+ action accept
+ description VPN-23738-ANY-ALLOW-10.4.56.13
+ destination {
+ group {
+ address-group DT_VPN-23738
+ }
+ }
+ source {
+ address 10.4.56.13
+ }
+ }
+ rule 2503 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.100
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.100
+ }
+ }
+ rule 2504 {
+ action accept
+ description FW996B4_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW996B4_2
+ }
+ port 43595,30160
+ }
+ protocol tcp
+ }
+ rule 2505 {
+ action accept
+ description FW8871B_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8871B_1
+ }
+ port 15672,8083,8082,8081,5672
+ }
+ protocol tcp
+ }
+ rule 2506 {
+ action accept
+ description FWAB44B_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWAB44B_1
+ }
+ port 9090,8069,5432
+ }
+ protocol tcp
+ }
+ rule 2507 {
+ action accept
+ description FW6187E_1-ICMP-ALLOW-85.214.201.250
+ destination {
+ group {
+ address-group DT_FW6187E_1
+ }
+ }
+ protocol icmp
+ source {
+ address 85.214.201.250
+ }
+ }
+ rule 2508 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-217.23.11.126
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 217.23.11.126
+ }
+ }
+ rule 2509 {
+ action accept
+ description FW78137_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW78137_1
+ }
+ port 1-65535
+ }
+ protocol tcp
+ }
+ rule 2510 {
+ action accept
+ description FW32EFF_25-TCP-ALLOW-46.252.65.10
+ destination {
+ group {
+ address-group DT_FW32EFF_25
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 46.252.65.10
+ }
+ }
+ rule 2511 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.50
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.50
+ }
+ }
+ rule 2512 {
+ action accept
+ description FW6A684_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6A684_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 2513 {
+ action accept
+ description FWF48EB_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF48EB_1
+ }
+ port 9204,9202,3395
+ }
+ protocol tcp
+ }
+ rule 2514 {
+ action accept
+ description FW44217_2-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW44217_2
+ }
+ port 443,80
+ }
+ protocol tcp_udp
+ }
+ rule 2515 {
+ action accept
+ description FW6187E_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6187E_1
+ }
+ port 2282
+ }
+ protocol tcp
+ }
+ rule 2516 {
+ action accept
+ description FW8AFF1_7-TCP-ALLOW-109.228.0.58
+ destination {
+ group {
+ address-group DT_FW8AFF1_7
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 109.228.0.58
+ }
+ }
+ rule 2517 {
+ action accept
+ description VPN-34501-ANY-ALLOW-10.4.86.235
+ destination {
+ group {
+ address-group DT_VPN-34501
+ }
+ }
+ source {
+ address 10.4.86.235
+ }
+ }
+ rule 2518 {
+ action accept
+ description FW1271A_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1271A_2
+ }
+ port 5090,5061,5060,5015,5001
+ }
+ protocol tcp
+ }
+ rule 2519 {
+ action accept
+ description FW1271A_2-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1271A_2
+ }
+ port 9000-10999,5090,5060
+ }
+ protocol udp
+ }
+ rule 2520 {
+ action accept
+ description FW1226C_3-TCP-ALLOW-216.113.160.71
+ destination {
+ group {
+ address-group DT_FW1226C_3
+ }
+ port 80,22
+ }
+ protocol tcp
+ source {
+ address 216.113.160.71
+ }
+ }
+ rule 2521 {
+ action accept
+ description FW32EFF_16-TCP-ALLOW-84.19.45.82
+ destination {
+ group {
+ address-group DT_FW32EFF_16
+ }
+ port 33888
+ }
+ protocol tcp
+ source {
+ address 84.19.45.82
+ }
+ }
+ rule 2522 {
+ action accept
+ description FW03F2E_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW03F2E_1
+ }
+ port 1194
+ }
+ protocol udp
+ }
+ rule 2523 {
+ action accept
+ description FW03F2E_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW03F2E_1
+ }
+ port 4432,4431,4430
+ }
+ protocol tcp
+ }
+ rule 2524 {
+ action accept
+ description FW1226C_3-TCP-ALLOW-216.113.162.65
+ destination {
+ group {
+ address-group DT_FW1226C_3
+ }
+ port 80,22
+ }
+ protocol tcp
+ source {
+ address 216.113.162.65
+ }
+ }
+ rule 2525 {
+ action accept
+ description VPN-20306-ANY-ALLOW-10.4.89.173
+ destination {
+ group {
+ address-group DT_VPN-20306
+ }
+ }
+ source {
+ address 10.4.89.173
+ }
+ }
+ rule 2526 {
+ action accept
+ description FW8A49A_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8A49A_1
+ }
+ port 2525,8448-65535
+ }
+ protocol tcp
+ }
+ rule 2527 {
+ action accept
+ description FWD3431_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD3431_2
+ }
+ port 43595,30377,30289
+ }
+ protocol tcp
+ }
+ rule 2528 {
+ action accept
+ description FW1226C_3-TCP-ALLOW-66.135.200.200
+ destination {
+ group {
+ address-group DT_FW1226C_3
+ }
+ port 80,22
+ }
+ protocol tcp
+ source {
+ address 66.135.200.200
+ }
+ }
+ rule 2529 {
+ action accept
+ description FW1226C_3-TCP-ALLOW-193.28.178.38
+ destination {
+ group {
+ address-group DT_FW1226C_3
+ }
+ port 80
+ }
+ protocol tcp
+ source {
+ address 193.28.178.38
+ }
+ }
+ rule 2530 {
+ action accept
+ description FWAE88B_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWAE88B_1
+ }
+ port 65432,8080,7300,1195,1194,993,587,465,443,442,143,110,80,53,22
+ }
+ protocol tcp_udp
+ }
+ rule 2531 {
+ action accept
+ description FW1226C_3-TCP-ALLOW-195.234.136.80
+ destination {
+ group {
+ address-group DT_FW1226C_3
+ }
+ port 80
+ }
+ protocol tcp
+ source {
+ address 195.234.136.80
+ }
+ }
+ rule 2532 {
+ action accept
+ description FW1226C_3-TCP-ALLOW-93.94.41.83
+ destination {
+ group {
+ address-group DT_FW1226C_3
+ }
+ port 80
+ }
+ protocol tcp
+ source {
+ address 93.94.41.83
+ }
+ }
+ rule 2533 {
+ action accept
+ description VPN-6103-ANY-ALLOW-10.4.56.102
+ destination {
+ group {
+ address-group DT_VPN-6103
+ }
+ }
+ source {
+ address 10.4.56.102
+ }
+ }
+ rule 2534 {
+ action accept
+ description VPN-6103-ANY-ALLOW-10.4.57.102
+ destination {
+ group {
+ address-group DT_VPN-6103
+ }
+ }
+ source {
+ address 10.4.57.102
+ }
+ }
+ rule 2535 {
+ action accept
+ description FW9E550_1-TCP-ALLOW-86.198.190.104
+ destination {
+ group {
+ address-group DT_FW9E550_1
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 86.198.190.104
+ }
+ }
+ rule 2536 {
+ action accept
+ description FW34C91_3-TCP-ALLOW-81.149.71.244
+ destination {
+ group {
+ address-group DT_FW34C91_3
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 81.149.71.244
+ }
+ }
+ rule 2537 {
+ action accept
+ description FW0BB22_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0BB22_1
+ }
+ port 27917,27017,9592,9092,1080,587
+ }
+ protocol tcp_udp
+ }
+ rule 2538 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-89.213.26.156
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443,21
+ }
+ protocol tcp
+ source {
+ address 89.213.26.156
+ }
+ }
+ rule 2539 {
+ action accept
+ description FW34C91_3-UDP-ALLOW-81.149.71.244
+ destination {
+ group {
+ address-group DT_FW34C91_3
+ }
+ port 1434
+ }
+ protocol udp
+ source {
+ address 81.149.71.244
+ }
+ }
+ rule 2540 {
+ action accept
+ description VPN-17207-ANY-ALLOW-10.4.86.121
+ destination {
+ group {
+ address-group DT_VPN-17207
+ }
+ }
+ source {
+ address 10.4.86.121
+ }
+ }
+ rule 2541 {
+ action accept
+ description FW0B352_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0B352_1
+ }
+ port 4500,500
+ }
+ protocol udp
+ }
+ rule 2542 {
+ action accept
+ description FW85E02_11-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW85E02_11
+ }
+ port 5854,5853,5061
+ }
+ protocol tcp
+ }
+ rule 2543 {
+ action accept
+ description FW0BB22_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0BB22_1
+ }
+ port 9200,8082
+ }
+ protocol tcp
+ }
+ rule 2544 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.140
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.140
+ }
+ }
+ rule 2545 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-91.125.244.28
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 21
+ }
+ protocol tcp
+ source {
+ address 91.125.244.28
+ }
+ }
+ rule 2546 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-86.172.252.221
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 80-3389
+ }
+ protocol tcp
+ source {
+ address 86.172.252.221
+ }
+ }
+ rule 2547 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-92.207.184.106
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443,21
+ }
+ protocol tcp
+ source {
+ address 92.207.184.106
+ }
+ }
+ rule 2548 {
+ action accept
+ description FW45F3D_1-ANY-ALLOW-146.255.0.198
+ destination {
+ group {
+ address-group DT_FW45F3D_1
+ }
+ }
+ source {
+ address 146.255.0.198
+ }
+ }
+ rule 2549 {
+ action accept
+ description FWBFDED_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWBFDED_1
+ }
+ port 1723,445
+ }
+ protocol tcp
+ }
+ rule 2550 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-212.227.9.72
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 212.227.9.72
+ }
+ }
+ rule 2551 {
+ action accept
+ description FWE928F_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE928F_1
+ }
+ port 2082,2083,2086,2087,2096
+ }
+ protocol tcp
+ }
+ rule 2552 {
+ action accept
+ description FW5CBB2_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW5CBB2_1
+ }
+ port 2082,2083,2086,2087
+ }
+ protocol tcp
+ }
+ rule 2553 {
+ action accept
+ description FW63230_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW63230_1
+ }
+ port 445,139
+ }
+ protocol tcp_udp
+ }
+ rule 2554 {
+ action accept
+ description FW90AE3_1-TCP-ALLOW-71.244.176.5
+ destination {
+ group {
+ address-group DT_FW90AE3_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 71.244.176.5
+ }
+ }
+ rule 2555 {
+ action accept
+ description FWA4BC8_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA4BC8_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2556 {
+ action accept
+ description VPN-17207-ANY-ALLOW-10.4.87.121
+ destination {
+ group {
+ address-group DT_VPN-17207
+ }
+ }
+ source {
+ address 10.4.87.121
+ }
+ }
+ rule 2557 {
+ action accept
+ description VPN-17558-ANY-ALLOW-10.4.86.143
+ destination {
+ group {
+ address-group DT_VPN-17558
+ }
+ }
+ source {
+ address 10.4.86.143
+ }
+ }
+ rule 2558 {
+ action accept
+ description FWB2CD2_1-TCP-ALLOW-86.167.68.241
+ destination {
+ group {
+ address-group DT_FWB2CD2_1
+ }
+ port 21
+ }
+ protocol tcp
+ source {
+ address 86.167.68.241
+ }
+ }
+ rule 2559 {
+ action accept
+ description FW32EFF_25-TCP-ALLOW-84.19.45.82
+ destination {
+ group {
+ address-group DT_FW32EFF_25
+ }
+ port 33888,443
+ }
+ protocol tcp
+ source {
+ address 84.19.45.82
+ }
+ }
+ rule 2560 {
+ action accept
+ description FW44217_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW44217_2
+ }
+ port 9001,7946,2376
+ }
+ protocol tcp
+ }
+ rule 2561 {
+ action accept
+ description FW7DAE2_3-TCP-ALLOW-212.227.253.11
+ destination {
+ group {
+ address-group DT_FW7DAE2_3
+ }
+ port 25,22
+ }
+ protocol tcp
+ source {
+ address 212.227.253.11
+ }
+ }
+ rule 2562 {
+ action accept
+ description FW7DAE2_3-TCP-ALLOW-217.160.126.118
+ destination {
+ group {
+ address-group DT_FW7DAE2_3
+ }
+ port 25,22
+ }
+ protocol tcp
+ source {
+ address 217.160.126.118
+ }
+ }
+ rule 2563 {
+ action accept
+ description FWAF6E8_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWAF6E8_1
+ }
+ port 2082,2083,2086,2087,2096
+ }
+ protocol tcp
+ }
+ rule 2564 {
+ action accept
+ description FWCD7CE_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWCD7CE_1
+ }
+ port 49152-65534
+ }
+ protocol tcp
+ }
+ rule 2565 {
+ action accept
+ description FW32EFF_16-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW32EFF_16
+ }
+ port 47779,47778,47777,47776
+ }
+ protocol tcp
+ }
+ rule 2566 {
+ action accept
+ description FW0745F_5-TCP-ALLOW-77.68.117.222
+ destination {
+ group {
+ address-group DT_FW0745F_5
+ }
+ port 49170
+ }
+ protocol tcp
+ source {
+ address 77.68.117.222
+ }
+ }
+ rule 2567 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-92.207.199.107
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443,22,21
+ }
+ protocol tcp
+ source {
+ address 92.207.199.107
+ }
+ }
+ rule 2568 {
+ action accept
+ description FW8AFF1_7-TCP-ALLOW-109.228.0.89
+ destination {
+ group {
+ address-group DT_FW8AFF1_7
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 109.228.0.89
+ }
+ }
+ rule 2569 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-190.2.130.41
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 190.2.130.41
+ }
+ }
+ rule 2570 {
+ action accept
+ description FWFDCC7_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWFDCC7_1
+ }
+ port 10000
+ }
+ protocol tcp_udp
+ }
+ rule 2571 {
+ action accept
+ description FWF19FB_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF19FB_2
+ }
+ port 43595,40001,30616-30631,30531,30204-30435
+ }
+ protocol tcp
+ }
+ rule 2572 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-213.171.217.107
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 8443,22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.107
+ }
+ }
+ rule 2573 {
+ action accept
+ description FW4E314_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4E314_1
+ }
+ port 21543,888
+ }
+ protocol tcp
+ }
+ rule 2574 {
+ action accept
+ description FW73215_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW73215_1
+ }
+ port 4380
+ }
+ protocol udp
+ }
+ rule 2575 {
+ action accept
+ description VPN-31301-ANY-ALLOW-10.4.86.223
+ destination {
+ group {
+ address-group DT_VPN-31301
+ }
+ }
+ source {
+ address 10.4.86.223
+ }
+ }
+ rule 2576 {
+ action accept
+ description FW8428B_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8428B_1
+ }
+ port 48402
+ }
+ protocol udp
+ }
+ rule 2577 {
+ action accept
+ description FWF3A1B_1-TCP_UDP-ALLOW-185.195.124.169
+ destination {
+ group {
+ address-group DT_FWF3A1B_1
+ }
+ port 2222
+ }
+ protocol tcp_udp
+ source {
+ address 185.195.124.169
+ }
+ }
+ rule 2578 {
+ action accept
+ description FW34C91_3-UDP-ALLOW-77.68.121.4
+ destination {
+ group {
+ address-group DT_FW34C91_3
+ }
+ port 1434
+ }
+ protocol udp
+ source {
+ address 77.68.121.4
+ }
+ }
+ rule 2579 {
+ action accept
+ description FW73215_1-TCP-ALLOW-82.38.58.135
+ destination {
+ group {
+ address-group DT_FW73215_1
+ }
+ port 10685
+ }
+ protocol tcp
+ source {
+ address 82.38.58.135
+ }
+ }
+ rule 2580 {
+ action accept
+ description FW52F6F_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW52F6F_1
+ }
+ port 8888
+ }
+ protocol tcp
+ }
+ rule 2581 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.86
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.86
+ }
+ }
+ rule 2582 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-123.231.125.13
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 123.231.125.13
+ }
+ }
+ rule 2583 {
+ action accept
+ description FWEE03C_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWEE03C_1
+ }
+ port 2087,2083
+ }
+ protocol tcp
+ }
+ rule 2584 {
+ action accept
+ description FW748B7_1-TCP-ALLOW-157.231.123.154
+ destination {
+ group {
+ address-group DT_FW748B7_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 157.231.123.154
+ }
+ }
+ rule 2585 {
+ action accept
+ description VPN-34501-ANY-ALLOW-10.4.87.235
+ destination {
+ group {
+ address-group DT_VPN-34501
+ }
+ }
+ source {
+ address 10.4.87.235
+ }
+ }
+ rule 2586 {
+ action accept
+ description FWE47DA_1-TCP-ALLOW-81.134.85.245
+ destination {
+ group {
+ address-group DT_FWE47DA_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 81.134.85.245
+ }
+ }
+ rule 2587 {
+ action accept
+ description FWD61BF_1-ANY-ALLOW-193.237.81.213_32
+ destination {
+ group {
+ address-group DT_FWD61BF_1
+ }
+ }
+ source {
+ address 193.237.81.213/32
+ }
+ }
+ rule 2588 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-23.106.238.241
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 8443,3306,22
+ }
+ protocol tcp
+ source {
+ address 23.106.238.241
+ }
+ }
+ rule 2589 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-35.204.202.196
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 8443,3306,22
+ }
+ protocol tcp
+ source {
+ address 35.204.202.196
+ }
+ }
+ rule 2590 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-35.242.141.128
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 8443,3306,22
+ }
+ protocol tcp
+ source {
+ address 35.242.141.128
+ }
+ }
+ rule 2591 {
+ action accept
+ description FWC2EF2_2-TCP-ALLOW-90.251.221.19
+ destination {
+ group {
+ address-group DT_FWC2EF2_2
+ }
+ port 995,993,587,465,143,110,25,22
+ }
+ protocol tcp
+ source {
+ address 90.251.221.19
+ }
+ }
+ rule 2592 {
+ action accept
+ description VPN-14673-ANY-ALLOW-10.4.88.44
+ destination {
+ group {
+ address-group DT_VPN-14673
+ }
+ }
+ source {
+ address 10.4.88.44
+ }
+ }
+ rule 2593 {
+ action accept
+ description FWA83DF_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA83DF_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2594 {
+ action accept
+ description FW31525_6-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW31525_6
+ }
+ port 35467
+ }
+ protocol tcp
+ }
+ rule 2595 {
+ action accept
+ description FW4293B_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4293B_1
+ }
+ port 9080,8888,8881,7815,8419
+ }
+ protocol tcp
+ }
+ rule 2596 {
+ action accept
+ description FW4AE7D_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4AE7D_1
+ }
+ port 8083,81
+ }
+ protocol tcp
+ }
+ rule 2597 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-143.52.53.22
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 143.52.53.22
+ }
+ }
+ rule 2598 {
+ action accept
+ description FW44217_2-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW44217_2
+ }
+ port 7946,4789
+ }
+ protocol udp
+ }
+ rule 2599 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-46.249.82.162
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 8443,22
+ }
+ protocol tcp
+ source {
+ address 46.249.82.162
+ }
+ }
+ rule 2600 {
+ action accept
+ description FW27949_2-TCP-ALLOW-80.95.202.106
+ destination {
+ group {
+ address-group DT_FW27949_2
+ }
+ port 443,80
+ }
+ protocol tcp
+ source {
+ address 80.95.202.106
+ }
+ }
+ rule 2601 {
+ action accept
+ description FWEF92E_5-ESP-ALLOW-77.68.93.82
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol esp
+ source {
+ address 77.68.93.82
+ }
+ }
+ rule 2602 {
+ action accept
+ description FW2ACFF_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2ACFF_1
+ }
+ port 8082,5093
+ }
+ protocol tcp
+ }
+ rule 2603 {
+ action accept
+ description FWC2EF2_2-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC2EF2_2
+ }
+ port 10000,953,53
+ }
+ protocol tcp_udp
+ }
+ rule 2604 {
+ action accept
+ description FW0C8E1_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0C8E1_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2605 {
+ action accept
+ description FWA86ED_101-TCP_UDP-ALLOW-82.5.189.5
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 1-65535
+ }
+ protocol tcp_udp
+ source {
+ address 82.5.189.5
+ }
+ }
+ rule 2606 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.208.179
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.208.179
+ }
+ }
+ rule 2607 {
+ action accept
+ description FWEF92E_5-ESP-ALLOW-88.208.198.93
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol esp
+ source {
+ address 88.208.198.93
+ }
+ }
+ rule 2608 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-39.45.43.109
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 39.45.43.109
+ }
+ }
+ rule 2609 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-5.67.3.195
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 5.67.3.195
+ }
+ }
+ rule 2610 {
+ action accept
+ description FWDCA36_3-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWDCA36_3
+ }
+ port 49152-65534,5901
+ }
+ protocol tcp
+ }
+ rule 2611 {
+ action accept
+ description FWE928F_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE928F_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 2612 {
+ action accept
+ description FW69D6D_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW69D6D_2
+ }
+ port 5001,5090,5060,5015
+ }
+ protocol tcp
+ }
+ rule 2613 {
+ action accept
+ description FW69D6D_2-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW69D6D_2
+ }
+ port 5090,5060,9000-9500
+ }
+ protocol udp
+ }
+ rule 2614 {
+ action accept
+ description VPN-9765-ANY-ALLOW-10.4.56.45
+ destination {
+ group {
+ address-group DT_VPN-9765
+ }
+ }
+ source {
+ address 10.4.56.45
+ }
+ }
+ rule 2615 {
+ action accept
+ description VPN-9765-ANY-ALLOW-10.4.57.45
+ destination {
+ group {
+ address-group DT_VPN-9765
+ }
+ }
+ source {
+ address 10.4.57.45
+ }
+ }
+ rule 2616 {
+ action accept
+ description FW4C136_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4C136_1
+ }
+ port 1194
+ }
+ protocol tcp_udp
+ }
+ rule 2617 {
+ action accept
+ description FW6F539_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6F539_1
+ }
+ port 49152-65534
+ }
+ protocol tcp
+ }
+ rule 2618 {
+ action accept
+ description FWDD089_5-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWDD089_5
+ }
+ port 5666-5667,12489
+ }
+ protocol tcp_udp
+ }
+ rule 2619 {
+ action accept
+ description FWDD089_5-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWDD089_5
+ }
+ port 161-162
+ }
+ protocol tcp
+ }
+ rule 2620 {
+ action accept
+ description FWEF92E_5-AH-ALLOW-109.228.37.19
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol ah
+ source {
+ address 109.228.37.19
+ }
+ }
+ rule 2621 {
+ action accept
+ description FW0A5C4_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0A5C4_1
+ }
+ port 9000,6697,6667,5000
+ }
+ protocol tcp
+ }
+ rule 2622 {
+ action accept
+ description FWEF92E_5-AH-ALLOW-77.68.11.54
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol ah
+ source {
+ address 77.68.11.54
+ }
+ }
+ rule 2623 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 7990
+ }
+ protocol tcp
+ }
+ rule 2624 {
+ action accept
+ description FWAF6E8_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWAF6E8_1
+ }
+ port 7770-7800,44445,53
+ }
+ protocol tcp_udp
+ }
+ rule 2625 {
+ action accept
+ description FW81286_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW81286_1
+ }
+ port 2082,2083,2086,2087,2096
+ }
+ protocol tcp
+ }
+ rule 2626 {
+ action accept
+ description FW05064_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW05064_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2627 {
+ action accept
+ description FWD7382_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD7382_1
+ }
+ port 4500,1701,500
+ }
+ protocol udp
+ }
+ rule 2628 {
+ action accept
+ description FWD7382_1-TCP-ALLOW-174.91.7.198
+ destination {
+ group {
+ address-group DT_FWD7382_1
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 174.91.7.198
+ }
+ }
+ rule 2629 {
+ action accept
+ description VPN-9484-ANY-ALLOW-10.4.56.164
+ destination {
+ group {
+ address-group DT_VPN-9484
+ }
+ }
+ source {
+ address 10.4.56.164
+ }
+ }
+ rule 2630 {
+ action accept
+ description VPN-9484-ANY-ALLOW-10.4.57.164
+ destination {
+ group {
+ address-group DT_VPN-9484
+ }
+ }
+ source {
+ address 10.4.57.164
+ }
+ }
+ rule 2631 {
+ action accept
+ description VPN-9749-ANY-ALLOW-10.4.58.144
+ destination {
+ group {
+ address-group DT_VPN-9749
+ }
+ }
+ source {
+ address 10.4.58.144
+ }
+ }
+ rule 2632 {
+ action accept
+ description FWEF92E_5-AH-ALLOW-77.68.77.149
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol ah
+ source {
+ address 77.68.77.149
+ }
+ }
+ rule 2633 {
+ action accept
+ description FW10FEE_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW10FEE_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2634 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-5.71.30.141
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 5.71.30.141
+ }
+ }
+ rule 2635 {
+ action accept
+ description VPN-9749-ANY-ALLOW-10.4.59.144
+ destination {
+ group {
+ address-group DT_VPN-9749
+ }
+ }
+ source {
+ address 10.4.59.144
+ }
+ }
+ rule 2636 {
+ action accept
+ description FWEF92E_5-AH-ALLOW-77.68.77.70
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol ah
+ source {
+ address 77.68.77.70
+ }
+ }
+ rule 2637 {
+ action accept
+ description FWEF92E_5-AH-ALLOW-77.68.92.33
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol ah
+ source {
+ address 77.68.92.33
+ }
+ }
+ rule 2638 {
+ action accept
+ description FWEF92E_5-AH-ALLOW-77.68.93.82
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol ah
+ source {
+ address 77.68.93.82
+ }
+ }
+ rule 2639 {
+ action accept
+ description FWEF92E_6-AH-ALLOW-77.68.77.57
+ destination {
+ group {
+ address-group DT_FWEF92E_6
+ }
+ }
+ protocol ah
+ source {
+ address 77.68.77.57
+ }
+ }
+ rule 2640 {
+ action accept
+ description FWEF92E_6-TCP-ALLOW-77.68.8.74
+ destination {
+ group {
+ address-group DT_FWEF92E_6
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 77.68.8.74
+ }
+ }
+ rule 2641 {
+ action accept
+ description FWEF92E_5-AH-ALLOW-88.208.198.93
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol ah
+ source {
+ address 88.208.198.93
+ }
+ }
+ rule 2642 {
+ action accept
+ description FWEF92E_7-TCP-ALLOW-87.224.33.215
+ destination {
+ group {
+ address-group DT_FWEF92E_7
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 87.224.33.215
+ }
+ }
+ rule 2643 {
+ action accept
+ description FWEF92E_7-TCP-ALLOW-87.224.6.174
+ destination {
+ group {
+ address-group DT_FWEF92E_7
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 87.224.6.174
+ }
+ }
+ rule 2644 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-109.228.37.19
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 109.228.37.19
+ }
+ }
+ rule 2645 {
+ action accept
+ description FW49C3D_4-TCP-ALLOW-87.224.33.215
+ destination {
+ group {
+ address-group DT_FW49C3D_4
+ }
+ port 3389,445,80
+ }
+ protocol tcp
+ source {
+ address 87.224.33.215
+ }
+ }
+ rule 2646 {
+ action accept
+ description FW49C3D_4-TCP-ALLOW-82.0.198.226
+ destination {
+ group {
+ address-group DT_FW49C3D_4
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 82.0.198.226
+ }
+ }
+ rule 2647 {
+ action accept
+ description FW49C3D_6-TCP-ALLOW-82.0.198.226
+ destination {
+ group {
+ address-group DT_FW49C3D_6
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 82.0.198.226
+ }
+ }
+ rule 2648 {
+ action accept
+ description FW49C3D_6-TCP-ALLOW-83.100.136.74
+ destination {
+ group {
+ address-group DT_FW49C3D_6
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 83.100.136.74
+ }
+ }
+ rule 2649 {
+ action accept
+ description FWEF92E_6-TCP-ALLOW-87.224.33.215
+ destination {
+ group {
+ address-group DT_FWEF92E_6
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 87.224.33.215
+ }
+ }
+ rule 2650 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-194.145.189.162
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 194.145.189.162
+ }
+ }
+ rule 2651 {
+ action accept
+ description FW3DBF8_9-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW3DBF8_9
+ }
+ port 9000-10999
+ }
+ protocol udp
+ }
+ rule 2652 {
+ action accept
+ description VPN-19807-ANY-ALLOW-10.4.86.172
+ destination {
+ group {
+ address-group DT_VPN-19807
+ }
+ }
+ source {
+ address 10.4.86.172
+ }
+ }
+ rule 2653 {
+ action accept
+ description FWEEC75_1-TCP-ALLOW-82.8.245.40
+ destination {
+ group {
+ address-group DT_FWEEC75_1
+ }
+ port 21
+ }
+ protocol tcp
+ source {
+ address 82.8.245.40
+ }
+ }
+ rule 2654 {
+ action accept
+ description FW3AD6F_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW3AD6F_1
+ }
+ port 53,465
+ }
+ protocol tcp_udp
+ }
+ rule 2655 {
+ action accept
+ description FWCDBC7_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWCDBC7_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 2656 {
+ action accept
+ description FWA373F_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA373F_1
+ }
+ port 2087,2086,2083,2082
+ }
+ protocol tcp
+ }
+ rule 2657 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-94.155.221.50
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 8443,22
+ }
+ protocol tcp
+ source {
+ address 94.155.221.50
+ }
+ }
+ rule 2658 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-213.171.217.107
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443,22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.107
+ }
+ }
+ rule 2659 {
+ action accept
+ description VPN-30791-ANY-ALLOW-10.4.88.215
+ destination {
+ group {
+ address-group DT_VPN-30791
+ }
+ }
+ source {
+ address 10.4.88.215
+ }
+ }
+ rule 2660 {
+ action accept
+ description VPN-30791-ANY-ALLOW-10.4.89.215
+ destination {
+ group {
+ address-group DT_VPN-30791
+ }
+ }
+ source {
+ address 10.4.89.215
+ }
+ }
+ rule 2661 {
+ action accept
+ description FW2EF2C_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2EF2C_1
+ }
+ port 10000,3478
+ }
+ protocol udp
+ }
+ rule 2662 {
+ action accept
+ description FW32EFF_49-TCP-ALLOW-195.217.232.0_26
+ destination {
+ group {
+ address-group DT_FW32EFF_49
+ }
+ port 5589
+ }
+ protocol tcp
+ source {
+ address 195.217.232.0/26
+ }
+ }
+ rule 2663 {
+ action accept
+ description FW4AE7D_1-TCP-ALLOW-81.136.8.24
+ destination {
+ group {
+ address-group DT_FW4AE7D_1
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 81.136.8.24
+ }
+ }
+ rule 2664 {
+ action accept
+ description FW2EF2C_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2EF2C_1
+ }
+ port 5222
+ }
+ protocol tcp_udp
+ }
+ rule 2665 {
+ action accept
+ description FW48A55_2-TCP-ALLOW-86.29.225.60
+ destination {
+ group {
+ address-group DT_FW48A55_2
+ }
+ port 443,80,22
+ }
+ protocol tcp
+ source {
+ address 86.29.225.60
+ }
+ }
+ rule 2666 {
+ action accept
+ description FW48A55_2-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW48A55_2
+ }
+ port 1337
+ }
+ protocol udp
+ }
+ rule 2667 {
+ action accept
+ description VPN-11913-ANY-ALLOW-10.4.56.191
+ destination {
+ group {
+ address-group DT_VPN-11913
+ }
+ }
+ source {
+ address 10.4.56.191
+ }
+ }
+ rule 2668 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-194.145.189.163
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 194.145.189.163
+ }
+ }
+ rule 2669 {
+ action accept
+ description FW8AFF1_7-TCP-ALLOW-109.228.0.90
+ destination {
+ group {
+ address-group DT_FW8AFF1_7
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 109.228.0.90
+ }
+ }
+ rule 2670 {
+ action accept
+ description FW8AFF1_7-TCP-ALLOW-109.228.24.66
+ destination {
+ group {
+ address-group DT_FW8AFF1_7
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 109.228.24.66
+ }
+ }
+ rule 2671 {
+ action accept
+ description VPN-11913-ANY-ALLOW-10.4.57.191
+ destination {
+ group {
+ address-group DT_VPN-11913
+ }
+ }
+ source {
+ address 10.4.57.191
+ }
+ }
+ rule 2672 {
+ action accept
+ description FW73573_2-TCP-ALLOW-86.9.185.195
+ destination {
+ group {
+ address-group DT_FW73573_2
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 86.9.185.195
+ }
+ }
+ rule 2673 {
+ action accept
+ description VPN-17558-ANY-ALLOW-10.4.87.143
+ destination {
+ group {
+ address-group DT_VPN-17558
+ }
+ }
+ source {
+ address 10.4.87.143
+ }
+ }
+ rule 2674 {
+ action accept
+ description FW748B7_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW748B7_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2675 {
+ action accept
+ description FW16375_5-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW16375_5
+ }
+ port 2082,2083,2086,2087
+ }
+ protocol tcp
+ }
+ rule 2676 {
+ action accept
+ description FW5A77C_16-TCP-ALLOW-88.98.204.68
+ destination {
+ group {
+ address-group DT_FW5A77C_16
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 88.98.204.68
+ }
+ }
+ rule 2677 {
+ action accept
+ description FW73573_1-TCP-ALLOW-86.9.185.195
+ destination {
+ group {
+ address-group DT_FW73573_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 86.9.185.195
+ }
+ }
+ rule 2678 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-194.145.190.4
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 194.145.190.4
+ }
+ }
+ rule 2679 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-140.82.112.0_20
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 140.82.112.0/20
+ }
+ }
+ rule 2680 {
+ action accept
+ description FW62858_12-ICMP-ALLOW-77.68.122.41
+ destination {
+ group {
+ address-group DT_FW62858_12
+ }
+ }
+ protocol icmp
+ source {
+ address 77.68.122.41
+ }
+ }
+ rule 2681 {
+ action accept
+ description FWB118A_1-TCP-ALLOW-147.148.96.136
+ destination {
+ group {
+ address-group DT_FWB118A_1
+ }
+ port 49152-65534,8447,8443,22,21,20
+ }
+ protocol tcp
+ source {
+ address 147.148.96.136
+ }
+ }
+ rule 2682 {
+ action accept
+ description FW5A77C_16-TCP-ALLOW-92.207.237.42
+ destination {
+ group {
+ address-group DT_FW5A77C_16
+ }
+ port 10000,22
+ }
+ protocol tcp
+ source {
+ address 92.207.237.42
+ }
+ }
+ rule 2683 {
+ action accept
+ description FW364CF_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW364CF_1
+ }
+ port 4022,8099
+ }
+ protocol tcp
+ }
+ rule 2684 {
+ action accept
+ description VPN-25822-ANY-ALLOW-10.4.54.42
+ destination {
+ group {
+ address-group DT_VPN-25822
+ }
+ }
+ source {
+ address 10.4.54.42
+ }
+ }
+ rule 2685 {
+ action accept
+ description FW7F28A_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW7F28A_1
+ }
+ port 10051,10050
+ }
+ protocol tcp
+ }
+ rule 2686 {
+ action accept
+ description FW8AFF1_7-TCP-ALLOW-109.228.53.159
+ destination {
+ group {
+ address-group DT_FW8AFF1_7
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 109.228.53.159
+ }
+ }
+ rule 2687 {
+ action accept
+ description FWE47DA_1-TCP-ALLOW-185.22.211.0_24
+ destination {
+ group {
+ address-group DT_FWE47DA_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 185.22.211.0/24
+ }
+ }
+ rule 2688 {
+ action accept
+ description FWC6301_1-TCP-ALLOW-95.34.208.4
+ destination {
+ group {
+ address-group DT_FWC6301_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 95.34.208.4
+ }
+ }
+ rule 2689 {
+ action accept
+ description FW45000_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW45000_1
+ }
+ port 990
+ }
+ protocol tcp
+ }
+ rule 2690 {
+ action accept
+ description FW481D7_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW481D7_1
+ }
+ port 6789
+ }
+ protocol tcp
+ }
+ rule 2691 {
+ action accept
+ description VPN-8203-ANY-ALLOW-10.4.59.109
+ destination {
+ group {
+ address-group DT_VPN-8203
+ }
+ }
+ source {
+ address 10.4.59.109
+ }
+ }
+ rule 2692 {
+ action accept
+ description VPN-3575-ANY-ALLOW-10.4.54.124
+ destination {
+ group {
+ address-group DT_VPN-3575
+ }
+ }
+ source {
+ address 10.4.54.124
+ }
+ }
+ rule 2693 {
+ action accept
+ description VPN-3575-ANY-ALLOW-10.4.55.125
+ destination {
+ group {
+ address-group DT_VPN-3575
+ }
+ }
+ source {
+ address 10.4.55.125
+ }
+ }
+ rule 2694 {
+ action accept
+ description FW42661_3-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW42661_3
+ }
+ port 44445,25672,15672,9876,7770-7800
+ }
+ protocol tcp
+ }
+ rule 2695 {
+ action accept
+ description FWBF494_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWBF494_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2696 {
+ action accept
+ description FWD0E22_4-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD0E22_4
+ }
+ port 8000,19005
+ }
+ protocol tcp
+ }
+ rule 2697 {
+ action accept
+ description FW98818_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW98818_1
+ }
+ port 27015
+ }
+ protocol udp
+ }
+ rule 2698 {
+ action accept
+ description FW62858_12-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW62858_12
+ }
+ port 5001,5000
+ }
+ protocol tcp
+ }
+ rule 2699 {
+ action accept
+ description VPN-34006-ANY-ALLOW-10.4.86.242
+ destination {
+ group {
+ address-group DT_VPN-34006
+ }
+ }
+ source {
+ address 10.4.86.242
+ }
+ }
+ rule 2700 {
+ action accept
+ description VPN-34006-ANY-ALLOW-10.4.87.242
+ destination {
+ group {
+ address-group DT_VPN-34006
+ }
+ }
+ source {
+ address 10.4.87.242
+ }
+ }
+ rule 2701 {
+ action accept
+ description FWF879C_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF879C_1
+ }
+ port 8888
+ }
+ protocol tcp
+ }
+ rule 2702 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-77.68.11.54
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 77.68.11.54
+ }
+ }
+ rule 2703 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-77.68.74.89
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 77.68.74.89
+ }
+ }
+ rule 2704 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-77.68.77.149
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 77.68.77.149
+ }
+ }
+ rule 2705 {
+ action accept
+ description FW8A57A_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8A57A_1
+ }
+ port 49153,5666
+ }
+ protocol tcp
+ }
+ rule 2706 {
+ action accept
+ description FW62858_12-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW62858_12
+ }
+ port 5090,5061,5060
+ }
+ protocol tcp_udp
+ }
+ rule 2707 {
+ action accept
+ description FW62858_12-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW62858_12
+ }
+ port 9000-10999
+ }
+ protocol udp
+ }
+ rule 2708 {
+ action accept
+ description FW0E2EE_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0E2EE_1
+ }
+ port 1024-65535
+ }
+ protocol tcp_udp
+ }
+ rule 2709 {
+ action accept
+ description FWEEC75_1-TCP-ALLOW-82.5.80.210
+ destination {
+ group {
+ address-group DT_FWEEC75_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 82.5.80.210
+ }
+ }
+ rule 2710 {
+ action accept
+ description FW4F81F_4-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4F81F_4
+ }
+ port 26900,27005,27015,51000,51005,51030
+ }
+ protocol tcp_udp
+ }
+ rule 2711 {
+ action accept
+ description VPN-7902-ANY-ALLOW-10.4.56.78
+ destination {
+ group {
+ address-group DT_VPN-7902
+ }
+ }
+ source {
+ address 10.4.56.78
+ }
+ }
+ rule 2712 {
+ action accept
+ description VPN-7902-ANY-ALLOW-10.4.57.78
+ destination {
+ group {
+ address-group DT_VPN-7902
+ }
+ }
+ source {
+ address 10.4.57.78
+ }
+ }
+ rule 2713 {
+ action accept
+ description FWB36A0_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWB36A0_1
+ }
+ port 20-21,990
+ }
+ protocol tcp_udp
+ }
+ rule 2714 {
+ action accept
+ description FWD2082_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD2082_1
+ }
+ port 8001,8002
+ }
+ protocol tcp
+ }
+ rule 2715 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-212.8.242.171
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 212.8.242.171
+ }
+ }
+ rule 2716 {
+ action accept
+ description FWB9699_11-TCP-ALLOW-213.171.217.184
+ destination {
+ group {
+ address-group DT_FWB9699_11
+ }
+ port 443,80,8800,22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.184
+ }
+ }
+ rule 2717 {
+ action accept
+ description VPN-11083-ANY-ALLOW-10.4.54.186
+ destination {
+ group {
+ address-group DT_VPN-11083
+ }
+ }
+ source {
+ address 10.4.54.186
+ }
+ }
+ rule 2718 {
+ action accept
+ description VPN-11083-ANY-ALLOW-10.4.55.187
+ destination {
+ group {
+ address-group DT_VPN-11083
+ }
+ }
+ source {
+ address 10.4.55.187
+ }
+ }
+ rule 2719 {
+ action accept
+ description VPN-34583-ANY-ALLOW-10.4.86.243
+ destination {
+ group {
+ address-group DT_VPN-34583
+ }
+ }
+ source {
+ address 10.4.86.243
+ }
+ }
+ rule 2720 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-123.231.84.155
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 123.231.84.155
+ }
+ }
+ rule 2721 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.117
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.117
+ }
+ }
+ rule 2722 {
+ action accept
+ description FW7A9B0_9-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW7A9B0_9
+ }
+ port 11112
+ }
+ protocol tcp
+ }
+ rule 2723 {
+ action accept
+ description FW3F465_1-TCP-ALLOW-77.68.127.177
+ destination {
+ group {
+ address-group DT_FW3F465_1
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 77.68.127.177
+ }
+ }
+ rule 2724 {
+ action accept
+ description VPN-34583-ANY-ALLOW-10.4.87.243
+ destination {
+ group {
+ address-group DT_VPN-34583
+ }
+ }
+ source {
+ address 10.4.87.243
+ }
+ }
+ rule 2725 {
+ action accept
+ description FW930F3_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW930F3_1
+ }
+ port 9089,5900,5666,5272
+ }
+ protocol tcp
+ }
+ rule 2726 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.165
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.165
+ }
+ }
+ rule 2727 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.140
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.140
+ }
+ }
+ rule 2728 {
+ action accept
+ description FW90AE3_1-TCP-ALLOW-82.11.114.136
+ destination {
+ group {
+ address-group DT_FW90AE3_1
+ }
+ port 3306,22
+ }
+ protocol tcp
+ source {
+ address 82.11.114.136
+ }
+ }
+ rule 2729 {
+ action accept
+ description FW73215_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW73215_1
+ }
+ port 27015
+ }
+ protocol tcp_udp
+ }
+ rule 2730 {
+ action accept
+ description FWC2EF2_1-TCP-ALLOW-18.130.156.250
+ destination {
+ group {
+ address-group DT_FWC2EF2_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 18.130.156.250
+ }
+ }
+ rule 2731 {
+ action accept
+ description FWC2EF2_1-TCP-ALLOW-90.251.221.19
+ destination {
+ group {
+ address-group DT_FWC2EF2_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 90.251.221.19
+ }
+ }
+ rule 2732 {
+ action accept
+ description FW90AE3_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW90AE3_1
+ }
+ port 8765,8001,8000
+ }
+ protocol tcp
+ }
+ rule 2733 {
+ action accept
+ description FWC2EF2_1-TCP-ALLOW-87.74.110.191
+ destination {
+ group {
+ address-group DT_FWC2EF2_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 87.74.110.191
+ }
+ }
+ rule 2734 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-77.68.77.70
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 77.68.77.70
+ }
+ }
+ rule 2735 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.93
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.93
+ }
+ }
+ rule 2736 {
+ action accept
+ description FW81138_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW81138_1
+ }
+ port 123
+ }
+ protocol udp
+ }
+ rule 2737 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.208.64
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.208.64
+ }
+ }
+ rule 2738 {
+ action accept
+ description FW03B35_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW03B35_1
+ }
+ port 1-65535
+ }
+ protocol tcp_udp
+ }
+ rule 2739 {
+ action accept
+ description VPN-19807-ANY-ALLOW-10.4.87.172
+ destination {
+ group {
+ address-group DT_VPN-19807
+ }
+ }
+ source {
+ address 10.4.87.172
+ }
+ }
+ rule 2740 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-94.12.73.154
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 8447
+ }
+ protocol tcp
+ source {
+ address 94.12.73.154
+ }
+ }
+ rule 2741 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2742 {
+ action accept
+ description FW0B352_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0B352_1
+ }
+ port 3443
+ }
+ protocol tcp_udp
+ }
+ rule 2743 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-77.68.8.74
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 3389,445,443
+ }
+ protocol tcp
+ source {
+ address 77.68.8.74
+ }
+ }
+ rule 2744 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-77.68.92.33
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 77.68.92.33
+ }
+ }
+ rule 2745 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-77.68.93.82
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 77.68.93.82
+ }
+ }
+ rule 2746 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.44
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.44
+ }
+ }
+ rule 2747 {
+ action accept
+ description FW34C91_3-TCP-ALLOW-188.220.176.104
+ destination {
+ group {
+ address-group DT_FW34C91_3
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 188.220.176.104
+ }
+ }
+ rule 2748 {
+ action accept
+ description FW3F465_1-TCP-ALLOW-77.68.16.101
+ destination {
+ group {
+ address-group DT_FW3F465_1
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 77.68.16.101
+ }
+ }
+ rule 2749 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-87.224.33.215
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 3389,445,443
+ }
+ protocol tcp
+ source {
+ address 87.224.33.215
+ }
+ }
+ rule 2750 {
+ action accept
+ description FW34C91_3-UDP-ALLOW-188.220.176.104
+ destination {
+ group {
+ address-group DT_FW34C91_3
+ }
+ port 1434
+ }
+ protocol udp
+ source {
+ address 188.220.176.104
+ }
+ }
+ rule 2751 {
+ action accept
+ description FWE47DA_1-TCP-ALLOW-185.22.208.0_25
+ destination {
+ group {
+ address-group DT_FWE47DA_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 185.22.208.0/25
+ }
+ }
+ rule 2752 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.187
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.187
+ }
+ }
+ rule 2753 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.84
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.84
+ }
+ }
+ rule 2754 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-116.206.246.52
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 116.206.246.52
+ }
+ }
+ rule 2755 {
+ action accept
+ description FW8AFF1_7-TCP-ALLOW-77.68.92.154
+ destination {
+ group {
+ address-group DT_FW8AFF1_7
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 77.68.92.154
+ }
+ }
+ rule 2756 {
+ action accept
+ description FW8AFF1_7-TCP-ALLOW-77.68.93.156
+ destination {
+ group {
+ address-group DT_FW8AFF1_7
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 77.68.93.156
+ }
+ }
+ rule 2757 {
+ action accept
+ description VPN-24398-ANY-ALLOW-10.4.88.151
+ destination {
+ group {
+ address-group DT_VPN-24398
+ }
+ }
+ source {
+ address 10.4.88.151
+ }
+ }
+ rule 2758 {
+ action accept
+ description VPN-24398-ANY-ALLOW-10.4.89.151
+ destination {
+ group {
+ address-group DT_VPN-24398
+ }
+ }
+ source {
+ address 10.4.89.151
+ }
+ }
+ rule 2759 {
+ action accept
+ description VPN-24589-ANY-ALLOW-10.4.56.9
+ destination {
+ group {
+ address-group DT_VPN-24589
+ }
+ }
+ source {
+ address 10.4.56.9
+ }
+ }
+ rule 2760 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.29
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.29
+ }
+ }
+ rule 2761 {
+ action accept
+ description FWC7D36_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC7D36_1
+ }
+ port 27017,11080
+ }
+ protocol tcp
+ }
+ rule 2762 {
+ action accept
+ description FWBB718_1-TCP_UDP-ALLOW-77.68.73.116
+ destination {
+ group {
+ address-group DT_FWBB718_1
+ }
+ port 1433
+ }
+ protocol tcp_udp
+ source {
+ address 77.68.73.116
+ }
+ }
+ rule 2763 {
+ action accept
+ description FWBB718_1-UDP-ALLOW-77.68.73.116
+ destination {
+ group {
+ address-group DT_FWBB718_1
+ }
+ port 1434
+ }
+ protocol udp
+ source {
+ address 77.68.73.116
+ }
+ }
+ rule 2764 {
+ action accept
+ description FWB9699_11-TCP-ALLOW-213.171.217.102
+ destination {
+ group {
+ address-group DT_FWB9699_11
+ }
+ port 22,80,443,8800
+ }
+ protocol tcp
+ source {
+ address 213.171.217.102
+ }
+ }
+ rule 2765 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-103.8.164.5
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 103.8.164.5
+ }
+ }
+ rule 2766 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.193
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.193
+ }
+ }
+ rule 2768 {
+ action accept
+ description FW26F0A_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW26F0A_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 2769 {
+ action accept
+ description FWCC18F_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWCC18F_2
+ }
+ port 8883,1883
+ }
+ protocol tcp
+ }
+ rule 2771 {
+ action accept
+ description FW633DD_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW633DD_1
+ }
+ port 28967,14002,9984,9983,9982,9981,8888,8884
+ }
+ protocol tcp
+ }
+ rule 2772 {
+ action accept
+ description FWDEDB9_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWDEDB9_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2773 {
+ action accept
+ description VPN-18646-ANY-ALLOW-10.4.88.109
+ destination {
+ group {
+ address-group DT_VPN-18646
+ }
+ }
+ source {
+ address 10.4.88.109
+ }
+ }
+ rule 2774 {
+ action accept
+ description VPN-18646-ANY-ALLOW-10.4.89.109
+ destination {
+ group {
+ address-group DT_VPN-18646
+ }
+ }
+ source {
+ address 10.4.89.109
+ }
+ }
+ rule 2775 {
+ action accept
+ description FWA0531_1-TCP-ALLOW-87.224.39.221
+ destination {
+ group {
+ address-group DT_FWA0531_1
+ }
+ port 8082,3003,22
+ }
+ protocol tcp
+ source {
+ address 87.224.39.221
+ }
+ }
+ rule 2776 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.94
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.94
+ }
+ }
+ rule 2777 {
+ action accept
+ description FWA0531_1-TCP-ALLOW-92.237.97.92
+ destination {
+ group {
+ address-group DT_FWA0531_1
+ }
+ port 8082,3003,22
+ }
+ protocol tcp
+ source {
+ address 92.237.97.92
+ }
+ }
+ rule 2778 {
+ action accept
+ description VPN-25822-ANY-ALLOW-10.4.55.42
+ destination {
+ group {
+ address-group DT_VPN-25822
+ }
+ }
+ source {
+ address 10.4.55.42
+ }
+ }
+ rule 2779 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.88
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.88
+ }
+ }
+ rule 2780 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-143.55.64.0_20
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 143.55.64.0/20
+ }
+ }
+ rule 2781 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-194.176.78.206
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 194.176.78.206
+ }
+ }
+ rule 2782 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-195.243.221.50
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 195.243.221.50
+ }
+ }
+ rule 2783 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-213.171.217.107
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.107
+ }
+ }
+ rule 2784 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-81.150.168.54
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 3306,22
+ }
+ protocol tcp
+ source {
+ address 81.150.168.54
+ }
+ }
+ rule 2785 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-89.197.133.235
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 89.197.133.235
+ }
+ }
+ rule 2786 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 60000-60100,873
+ }
+ protocol tcp
+ }
+ rule 2787 {
+ action accept
+ description FW2BF20_3-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2BF20_3
+ }
+ port 49152-65534,990
+ }
+ protocol tcp
+ }
+ rule 2788 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.98
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.98
+ }
+ }
+ rule 2789 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.65
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.65
+ }
+ }
+ rule 2791 {
+ action accept
+ description FW197DB_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW197DB_1
+ }
+ port 49152-65534
+ }
+ protocol tcp
+ }
+ rule 2792 {
+ action accept
+ description FW1208C_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1208C_1
+ }
+ port 2087,2083,2096
+ }
+ protocol tcp
+ }
+ rule 2793 {
+ action accept
+ description FW00D98_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW00D98_1
+ }
+ port 4430
+ }
+ protocol tcp
+ }
+ rule 2794 {
+ action accept
+ description FW03B35_1-ESP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW03B35_1
+ }
+ }
+ protocol esp
+ }
+ rule 2795 {
+ action accept
+ description FW03B35_1-AH-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW03B35_1
+ }
+ }
+ protocol ah
+ }
+ rule 2796 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-87.224.6.174
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 3389,445,443
+ }
+ protocol tcp
+ source {
+ address 87.224.6.174
+ }
+ }
+ rule 2797 {
+ action accept
+ description FW825C8_19-TCP-ALLOW-159.253.51.74
+ destination {
+ group {
+ address-group DT_FW825C8_19
+ }
+ port 3389,1433,995
+ }
+ protocol tcp
+ source {
+ address 159.253.51.74
+ }
+ }
+ rule 2798 {
+ action accept
+ description FW825C8_19-TCP-ALLOW-77.68.76.111
+ destination {
+ group {
+ address-group DT_FW825C8_19
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 77.68.76.111
+ }
+ }
+ rule 2799 {
+ action accept
+ description FW825C8_19-TCP-ALLOW-77.68.28.63
+ destination {
+ group {
+ address-group DT_FW825C8_19
+ }
+ port 995
+ }
+ protocol tcp
+ source {
+ address 77.68.28.63
+ }
+ }
+ rule 2801 {
+ action accept
+ description FW2EF2C_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2EF2C_1
+ }
+ port 5349
+ }
+ protocol tcp
+ }
+ rule 2802 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-88.208.198.93
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 88.208.198.93
+ }
+ }
+ rule 2803 {
+ action accept
+ description FWC3921_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC3921_1
+ }
+ port 25000,25001-25005,26000-26006
+ }
+ protocol tcp
+ }
+ rule 2804 {
+ action accept
+ description FWEF92E_5-UDP-ALLOW-109.228.37.19
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 500
+ }
+ protocol udp
+ source {
+ address 109.228.37.19
+ }
+ }
+ rule 2805 {
+ action accept
+ description FWEF92E_5-UDP-ALLOW-77.68.11.54
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 500
+ }
+ protocol udp
+ source {
+ address 77.68.11.54
+ }
+ }
+ rule 2806 {
+ action accept
+ description FW5AE10_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW5AE10_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 2810 {
+ action accept
+ description FW45F87_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW45F87_1
+ }
+ port 60000-60100
+ }
+ protocol tcp
+ }
+ rule 2811 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-123.231.108.158
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 123.231.108.158
+ }
+ }
+ rule 2813 {
+ action accept
+ description FW825C8_19-TCP-ALLOW-109.228.1.233
+ destination {
+ group {
+ address-group DT_FW825C8_19
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 109.228.1.233
+ }
+ }
+ rule 2814 {
+ action accept
+ description FW20449_2-ICMP-ALLOW-3.10.221.168
+ destination {
+ group {
+ address-group DT_FW20449_2
+ }
+ }
+ protocol icmp
+ source {
+ address 3.10.221.168
+ }
+ }
+ rule 2815 {
+ action accept
+ description FWB9699_7-TCP-ALLOW-213.171.217.100
+ destination {
+ group {
+ address-group DT_FWB9699_7
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.100
+ }
+ }
+ rule 2816 {
+ action accept
+ description FWB9699_7-TCP-ALLOW-213.171.217.180
+ destination {
+ group {
+ address-group DT_FWB9699_7
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.180
+ }
+ }
+ rule 2817 {
+ action accept
+ description FWB9699_7-TCP-ALLOW-213.171.217.184
+ destination {
+ group {
+ address-group DT_FWB9699_7
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.184
+ }
+ }
+ rule 2818 {
+ action accept
+ description FWB9699_7-TCP-ALLOW-213.171.217.185
+ destination {
+ group {
+ address-group DT_FWB9699_7
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.185
+ }
+ }
+ rule 2819 {
+ action accept
+ description FWB9699_7-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWB9699_7
+ }
+ port 161
+ }
+ protocol udp
+ }
+ rule 2820 {
+ action accept
+ description FWB9699_7-TCP-ALLOW-213.171.217.102
+ destination {
+ group {
+ address-group DT_FWB9699_7
+ }
+ port 22,8443
+ }
+ protocol tcp
+ source {
+ address 213.171.217.102
+ }
+ }
+ rule 2821 {
+ action accept
+ description FWB9699_7-TCP-ALLOW-213.171.217.103
+ destination {
+ group {
+ address-group DT_FWB9699_7
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.103
+ }
+ }
+ rule 2824 {
+ action accept
+ description FWE3E77_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE3E77_1
+ }
+ port 10010,10009
+ }
+ protocol tcp
+ }
+ rule 2825 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-93.190.142.120
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 93.190.142.120
+ }
+ }
+ rule 2826 {
+ action accept
+ description FW20449_2-ICMP-ALLOW-82.20.69.137
+ destination {
+ group {
+ address-group DT_FW20449_2
+ }
+ }
+ protocol icmp
+ source {
+ address 82.20.69.137
+ }
+ }
+ rule 2827 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-46.101.232.93
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 21-10000
+ }
+ protocol tcp
+ source {
+ address 46.101.232.93
+ }
+ }
+ rule 2828 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.5
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.5
+ }
+ }
+ rule 2829 {
+ action accept
+ description FWD2440_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD2440_1
+ }
+ port 1-65535
+ }
+ protocol tcp
+ }
+ rule 2831 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.105
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.105
+ }
+ }
+ rule 2833 {
+ action accept
+ description FW825C8_24-TCP-ALLOW-159.253.51.74
+ destination {
+ group {
+ address-group DT_FW825C8_24
+ }
+ port 3389,1433,995
+ }
+ protocol tcp
+ source {
+ address 159.253.51.74
+ }
+ }
+ rule 2834 {
+ action accept
+ description FW825C8_24-TCP-ALLOW-77.68.77.120
+ destination {
+ group {
+ address-group DT_FW825C8_24
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 77.68.77.120
+ }
+ }
+ rule 2839 {
+ action accept
+ description FWD2440_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD2440_1
+ }
+ port 1-65535
+ }
+ protocol udp
+ }
+ rule 2840 {
+ action accept
+ description FW1C8F2_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1C8F2_1
+ }
+ port 7000-10000,5554,5443,5080,1935,1111
+ }
+ protocol tcp
+ }
+ rule 2843 {
+ action accept
+ description FWE7180_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE7180_1
+ }
+ port 443,53
+ }
+ protocol tcp_udp
+ }
+ rule 2844 {
+ action accept
+ description FWC6301_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC6301_1
+ }
+ port 2456
+ }
+ protocol tcp_udp
+ }
+ rule 2845 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.113
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.113
+ }
+ }
+ rule 2846 {
+ action accept
+ description VPN-24589-ANY-ALLOW-10.4.57.9
+ destination {
+ group {
+ address-group DT_VPN-24589
+ }
+ }
+ source {
+ address 10.4.57.9
+ }
+ }
+ rule 2847 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.237
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.237
+ }
+ }
+ rule 2849 {
+ action accept
+ description FWFD9AF_9-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWFD9AF_9
+ }
+ port 445
+ }
+ protocol tcp_udp
+ }
+ rule 2850 {
+ action accept
+ description VPN-23209-ANY-ALLOW-10.4.58.8
+ destination {
+ group {
+ address-group DT_VPN-23209
+ }
+ }
+ source {
+ address 10.4.58.8
+ }
+ }
+ rule 2851 {
+ action accept
+ description VPN-23209-ANY-ALLOW-10.4.59.8
+ destination {
+ group {
+ address-group DT_VPN-23209
+ }
+ }
+ source {
+ address 10.4.59.8
+ }
+ }
+ rule 2853 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.29
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.29
+ }
+ }
+ rule 2854 {
+ action accept
+ description FW16375_5-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW16375_5
+ }
+ port 2096
+ }
+ protocol tcp_udp
+ }
+ rule 2856 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.173
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.173
+ }
+ }
+ rule 2858 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.208.35
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.208.35
+ }
+ }
+ rule 2859 {
+ action accept
+ description FW73573_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW73573_1
+ }
+ port 25
+ }
+ protocol tcp_udp
+ }
+ rule 2860 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-148.253.173.242
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 148.253.173.242
+ }
+ }
+ rule 2861 {
+ action accept
+ description FW8ECF4_1-TCP-ALLOW-77.68.2.215
+ destination {
+ group {
+ address-group DT_FW8ECF4_1
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 77.68.2.215
+ }
+ }
+ rule 2862 {
+ action accept
+ description FW8A3FC_3-TCP_UDP-ALLOW-82.165.100.25
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 21-10000
+ }
+ protocol tcp_udp
+ source {
+ address 82.165.100.25
+ }
+ }
+ rule 2863 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.235
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.235
+ }
+ }
+ rule 2864 {
+ action accept
+ description VPN-18647-ANY-ALLOW-10.4.86.114
+ destination {
+ group {
+ address-group DT_VPN-18647
+ }
+ }
+ source {
+ address 10.4.86.114
+ }
+ }
+ rule 2865 {
+ action accept
+ description VPN-18647-ANY-ALLOW-10.4.87.114
+ destination {
+ group {
+ address-group DT_VPN-18647
+ }
+ }
+ source {
+ address 10.4.87.114
+ }
+ }
+ rule 2867 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.107
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.107
+ }
+ }
+ rule 2868 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.208.239
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.208.239
+ }
+ }
+ rule 2869 {
+ action accept
+ description FWF699D_4-TCP-ALLOW-164.39.151.3
+ destination {
+ group {
+ address-group DT_FWF699D_4
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 164.39.151.3
+ }
+ }
+ rule 2870 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.245
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.245
+ }
+ }
+ rule 2873 {
+ action accept
+ description FWEF92E_6-TCP-ALLOW-87.224.6.174
+ destination {
+ group {
+ address-group DT_FWEF92E_6
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 87.224.6.174
+ }
+ }
+ rule 2874 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.130
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.130
+ }
+ }
+ rule 2875 {
+ action accept
+ description FW44BF9_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW44BF9_1
+ }
+ port 49160-49200
+ }
+ protocol tcp
+ }
+ rule 2876 {
+ action accept
+ description VPN-24591-ANY-ALLOW-10.4.86.4
+ destination {
+ group {
+ address-group DT_VPN-24591
+ }
+ }
+ source {
+ address 10.4.86.4
+ }
+ }
+ rule 2877 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.60
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.60
+ }
+ }
+ rule 2879 {
+ action accept
+ description FWEF92E_6-UDP-ALLOW-77.68.77.57
+ destination {
+ group {
+ address-group DT_FWEF92E_6
+ }
+ port 500
+ }
+ protocol udp
+ source {
+ address 77.68.77.57
+ }
+ }
+ rule 2880 {
+ action accept
+ description FWF699D_4-TCP-ALLOW-185.132.38.110
+ destination {
+ group {
+ address-group DT_FWF699D_4
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 185.132.38.110
+ }
+ }
+ rule 2881 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.208.216
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.208.216
+ }
+ }
+ rule 2882 {
+ action accept
+ description FWEF92E_5-UDP-ALLOW-77.68.77.149
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 500
+ }
+ protocol udp
+ source {
+ address 77.68.77.149
+ }
+ }
+ rule 2883 {
+ action accept
+ description FWA2FF8_4-TCP-ALLOW-80.229.18.102
+ destination {
+ group {
+ address-group DT_FWA2FF8_4
+ }
+ port 3306,21,22
+ }
+ protocol tcp
+ source {
+ address 80.229.18.102
+ }
+ }
+ rule 2884 {
+ action accept
+ description FWA2FF8_4-TCP-ALLOW-109.169.33.69
+ destination {
+ group {
+ address-group DT_FWA2FF8_4
+ }
+ port 3306,21,22
+ }
+ protocol tcp
+ source {
+ address 109.169.33.69
+ }
+ }
+ rule 2885 {
+ action accept
+ description FWA2FF8_4-TCP-ALLOW-46.102.209.35
+ destination {
+ group {
+ address-group DT_FWA2FF8_4
+ }
+ port 3306,21
+ }
+ protocol tcp
+ source {
+ address 46.102.209.35
+ }
+ }
+ rule 2886 {
+ action accept
+ description FWA2FF8_4-TCP-ALLOW-90.213.48.16
+ destination {
+ group {
+ address-group DT_FWA2FF8_4
+ }
+ port 3306,21
+ }
+ protocol tcp
+ source {
+ address 90.213.48.16
+ }
+ }
+ rule 2887 {
+ action accept
+ description FWA2FF8_4-TCP-ALLOW-77.68.76.129
+ destination {
+ group {
+ address-group DT_FWA2FF8_4
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 77.68.76.129
+ }
+ }
+ rule 2888 {
+ action accept
+ description FWA2FF8_4-TCP-ALLOW-109.228.50.145
+ destination {
+ group {
+ address-group DT_FWA2FF8_4
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 109.228.50.145
+ }
+ }
+ rule 2889 {
+ action accept
+ description FWA2FF8_4-TCP-ALLOW-77.68.76.231
+ destination {
+ group {
+ address-group DT_FWA2FF8_4
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 77.68.76.231
+ }
+ }
+ rule 2890 {
+ action accept
+ description FW4513E_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4513E_1
+ }
+ port 50000-50020,990
+ }
+ protocol tcp
+ }
+ rule 2893 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-175.157.40.7
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 175.157.40.7
+ }
+ }
+ rule 2894 {
+ action accept
+ description VPN-21876-ANY-ALLOW-10.4.88.96
+ destination {
+ group {
+ address-group DT_VPN-21876
+ }
+ }
+ source {
+ address 10.4.88.96
+ }
+ }
+ rule 2895 {
+ action accept
+ description VPN-21876-ANY-ALLOW-10.4.89.96
+ destination {
+ group {
+ address-group DT_VPN-21876
+ }
+ }
+ source {
+ address 10.4.89.96
+ }
+ }
+ rule 2896 {
+ action accept
+ description VPN-26124-ANY-ALLOW-10.4.54.75
+ destination {
+ group {
+ address-group DT_VPN-26124
+ }
+ }
+ source {
+ address 10.4.54.75
+ }
+ }
+ rule 2897 {
+ action accept
+ description VPN-26124-ANY-ALLOW-10.4.55.76
+ destination {
+ group {
+ address-group DT_VPN-26124
+ }
+ }
+ source {
+ address 10.4.55.76
+ }
+ }
+ rule 2898 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.21
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.21
+ }
+ }
+ rule 2899 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.213
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.213
+ }
+ }
+ rule 2901 {
+ action accept
+ description FWC6301_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC6301_1
+ }
+ port 5555
+ }
+ protocol udp
+ }
+ rule 2902 {
+ action accept
+ description VPN-13261-ANY-ALLOW-10.4.56.173
+ destination {
+ group {
+ address-group DT_VPN-13261
+ }
+ }
+ source {
+ address 10.4.56.173
+ }
+ }
+ rule 2903 {
+ action accept
+ description VPN-13261-ANY-ALLOW-10.4.57.173
+ destination {
+ group {
+ address-group DT_VPN-13261
+ }
+ }
+ source {
+ address 10.4.57.173
+ }
+ }
+ rule 2909 {
+ action accept
+ description VPN-24591-ANY-ALLOW-10.4.87.4
+ destination {
+ group {
+ address-group DT_VPN-24591
+ }
+ }
+ source {
+ address 10.4.87.4
+ }
+ }
+ rule 2911 {
+ action accept
+ description FWE7180_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE7180_1
+ }
+ port 40110-40210,8090
+ }
+ protocol tcp
+ }
+ rule 2914 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.247
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.247
+ }
+ }
+ rule 2915 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.129
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.129
+ }
+ }
+ rule 2916 {
+ action accept
+ description FWCB29D_1-TCP-ALLOW-51.146.16.162
+ destination {
+ group {
+ address-group DT_FWCB29D_1
+ }
+ port 8447,8443,22
+ }
+ protocol tcp
+ source {
+ address 51.146.16.162
+ }
+ }
+ rule 2917 {
+ action accept
+ description FW4E399_1-TCP-ALLOW-51.155.19.77
+ destination {
+ group {
+ address-group DT_FW4E399_1
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 51.155.19.77
+ }
+ }
+ rule 2919 {
+ action accept
+ description FWC72E5_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC72E5_1
+ }
+ port 9000-9100,6667
+ }
+ protocol tcp
+ }
+ rule 2922 {
+ action accept
+ description FW21A75_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW21A75_2
+ }
+ port 3000
+ }
+ protocol tcp
+ }
+ rule 2923 {
+ action accept
+ description FW3B068_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW3B068_2
+ }
+ port 990,60000-65000
+ }
+ protocol tcp
+ }
+ rule 2924 {
+ action accept
+ description FW48814_3-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW48814_3
+ }
+ port 3306
+ }
+ protocol tcp_udp
+ }
+ rule 2925 {
+ action accept
+ description FW48814_3-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW48814_3
+ }
+ port 49152-65534
+ }
+ protocol tcp
+ }
+ rule 2926 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-178.128.39.210
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 178.128.39.210
+ }
+ }
+ rule 2927 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-82.165.232.19
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 82.165.232.19
+ }
+ }
+ rule 2928 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-84.64.186.31
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 84.64.186.31
+ }
+ }
+ rule 2929 {
+ action accept
+ description FW1C8F2_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1C8F2_1
+ }
+ port 5000-65000
+ }
+ protocol udp
+ }
+ rule 2930 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2931 {
+ action accept
+ description FW608FA_1-TCP-ALLOW-195.10.106.114
+ destination {
+ group {
+ address-group DT_FW608FA_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 195.10.106.114
+ }
+ }
+ rule 2932 {
+ action accept
+ description FW608FA_1-TCP-ALLOW-213.137.25.134
+ destination {
+ group {
+ address-group DT_FW608FA_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 213.137.25.134
+ }
+ }
+ rule 2933 {
+ action accept
+ description FW608FA_1-TCP-ALLOW-92.39.202.189
+ destination {
+ group {
+ address-group DT_FW608FA_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 92.39.202.189
+ }
+ }
+ rule 2935 {
+ action accept
+ description FWC37B9_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC37B9_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2936 {
+ action accept
+ description FW15C99_6-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW15C99_6
+ }
+ port 32410-32414,1900
+ }
+ protocol udp
+ }
+ rule 2937 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-116.206.244.146
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 116.206.244.146
+ }
+ }
+ rule 2938 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.158
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.158
+ }
+ }
+ rule 2939 {
+ action accept
+ description FW15C99_6-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW15C99_6
+ }
+ port 32469,32400
+ }
+ protocol tcp
+ }
+ rule 2940 {
+ action accept
+ description FW0192C_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0192C_1
+ }
+ port 2053
+ }
+ protocol tcp
+ }
+ rule 2941 {
+ action accept
+ description FW27949_2-TCP-ALLOW-86.179.23.119
+ destination {
+ group {
+ address-group DT_FW27949_2
+ }
+ port 443,80
+ }
+ protocol tcp
+ source {
+ address 86.179.23.119
+ }
+ }
+ rule 2942 {
+ action accept
+ description FW27949_2-TCP-ALLOW-92.15.208.193
+ destination {
+ group {
+ address-group DT_FW27949_2
+ }
+ port 443,80
+ }
+ protocol tcp
+ source {
+ address 92.15.208.193
+ }
+ }
+ rule 2943 {
+ action accept
+ description VPN-34122-ANY-ALLOW-10.4.56.122
+ destination {
+ group {
+ address-group DT_VPN-34122
+ }
+ }
+ source {
+ address 10.4.56.122
+ }
+ }
+ rule 2944 {
+ action accept
+ description VPN-34122-ANY-ALLOW-10.4.57.122
+ destination {
+ group {
+ address-group DT_VPN-34122
+ }
+ }
+ source {
+ address 10.4.57.122
+ }
+ }
+ rule 2945 {
+ action accept
+ description FWF323F_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF323F_1
+ }
+ port 25565,9999,8080,5001,3306
+ }
+ protocol tcp_udp
+ }
+ rule 2946 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.132
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.132
+ }
+ }
+ rule 2948 {
+ action accept
+ description VPN-30261-ANY-ALLOW-10.4.86.110
+ destination {
+ group {
+ address-group DT_VPN-30261
+ }
+ }
+ source {
+ address 10.4.86.110
+ }
+ }
+ rule 2949 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.246
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.246
+ }
+ }
+ rule 2951 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-157.231.100.222
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 157.231.100.222
+ }
+ }
+ rule 2952 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-164.39.131.31
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 164.39.131.31
+ }
+ }
+ rule 2953 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-185.199.108.0_22
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 185.199.108.0/22
+ }
+ }
+ rule 2954 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-192.30.252.0_22
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 192.30.252.0/22
+ }
+ }
+ rule 2955 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-80.252.78.202
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 80.252.78.202
+ }
+ }
+ rule 2956 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-86.15.158.234
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 86.15.158.234
+ }
+ }
+ rule 2957 {
+ action accept
+ description VPN-30261-ANY-ALLOW-10.4.87.110
+ destination {
+ group {
+ address-group DT_VPN-30261
+ }
+ }
+ source {
+ address 10.4.87.110
+ }
+ }
+ rule 2958 {
+ action accept
+ description VPN-30262-ANY-ALLOW-10.4.88.36
+ destination {
+ group {
+ address-group DT_VPN-30262
+ }
+ }
+ source {
+ address 10.4.88.36
+ }
+ }
+ rule 2961 {
+ action accept
+ description VPN-15950-ANY-ALLOW-10.4.88.89
+ destination {
+ group {
+ address-group DT_VPN-15950
+ }
+ }
+ source {
+ address 10.4.88.89
+ }
+ }
+ rule 2962 {
+ action accept
+ description FWBFDED_1-TCP-ALLOW-78.141.24.164
+ destination {
+ group {
+ address-group DT_FWBFDED_1
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 78.141.24.164
+ }
+ }
+ rule 2963 {
+ action accept
+ description VPN-30262-ANY-ALLOW-10.4.89.36
+ destination {
+ group {
+ address-group DT_VPN-30262
+ }
+ }
+ source {
+ address 10.4.89.36
+ }
+ }
+ rule 2964 {
+ action accept
+ description FW1F126_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1F126_1
+ }
+ port 2087,2083
+ }
+ protocol tcp
+ }
+ rule 2965 {
+ action accept
+ description FWA7A50_1-ANY-ALLOW-40.120.53.80
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ }
+ source {
+ address 40.120.53.80
+ }
+ }
+ rule 2967 {
+ action accept
+ description VPN-23729-ANY-ALLOW-10.4.54.10
+ destination {
+ group {
+ address-group DT_VPN-23729
+ }
+ }
+ source {
+ address 10.4.54.10
+ }
+ }
+ rule 2968 {
+ action accept
+ description VPN-23729-ANY-ALLOW-10.4.55.10
+ destination {
+ group {
+ address-group DT_VPN-23729
+ }
+ }
+ source {
+ address 10.4.55.10
+ }
+ }
+ rule 2969 {
+ action accept
+ description VPN-23733-ANY-ALLOW-10.4.58.12
+ destination {
+ group {
+ address-group DT_VPN-23733
+ }
+ }
+ source {
+ address 10.4.58.12
+ }
+ }
+ rule 2970 {
+ action accept
+ description VPN-23733-ANY-ALLOW-10.4.59.12
+ destination {
+ group {
+ address-group DT_VPN-23733
+ }
+ }
+ source {
+ address 10.4.59.12
+ }
+ }
+ rule 2971 {
+ action accept
+ description VPN-23734-ANY-ALLOW-10.4.56.29
+ destination {
+ group {
+ address-group DT_VPN-23734
+ }
+ }
+ source {
+ address 10.4.56.29
+ }
+ }
+ rule 2972 {
+ action accept
+ description VPN-23734-ANY-ALLOW-10.4.57.29
+ destination {
+ group {
+ address-group DT_VPN-23734
+ }
+ }
+ source {
+ address 10.4.57.29
+ }
+ }
+ rule 2975 {
+ action accept
+ description VPN-23738-ANY-ALLOW-10.4.57.13
+ destination {
+ group {
+ address-group DT_VPN-23738
+ }
+ }
+ source {
+ address 10.4.57.13
+ }
+ }
+ rule 2976 {
+ action accept
+ description FWD8DD1_2-TCP-ALLOW-77.153.164.226
+ destination {
+ group {
+ address-group DT_FWD8DD1_2
+ }
+ port 3306,22
+ }
+ protocol tcp
+ source {
+ address 77.153.164.226
+ }
+ }
+ rule 2977 {
+ action accept
+ description FWE012D_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE012D_1
+ }
+ port 143,25
+ }
+ protocol tcp_udp
+ }
+ rule 2978 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-123.231.120.196
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 123.231.120.196
+ }
+ }
+ rule 2981 {
+ action accept
+ description FW24AB7_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW24AB7_1
+ }
+ port 40110-40210
+ }
+ protocol tcp_udp
+ }
+ rule 2985 {
+ action accept
+ description FW2379F_14-TCP-ALLOW-194.72.140.178
+ destination {
+ group {
+ address-group DT_FW2379F_14
+ }
+ port 3389,21
+ }
+ protocol tcp
+ source {
+ address 194.72.140.178
+ }
+ }
+ rule 2986 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.97
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.97
+ }
+ }
+ rule 2988 {
+ action accept
+ description FW883EB_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW883EB_1
+ }
+ port 5005,5004,5003,5002,5001
+ }
+ protocol tcp
+ }
+ rule 2992 {
+ action accept
+ description FW310C6_3-ANY-ALLOW-62.30.207.232
+ destination {
+ group {
+ address-group DT_FW310C6_3
+ }
+ }
+ source {
+ address 62.30.207.232
+ }
+ }
+ rule 2993 {
+ action accept
+ description VPN-15950-ANY-ALLOW-10.4.89.89
+ destination {
+ group {
+ address-group DT_VPN-15950
+ }
+ }
+ source {
+ address 10.4.89.89
+ }
+ }
+ rule 2994 {
+ action accept
+ description VPN-15960-ANY-ALLOW-10.4.88.90
+ destination {
+ group {
+ address-group DT_VPN-15960
+ }
+ }
+ source {
+ address 10.4.88.90
+ }
+ }
+ rule 2995 {
+ action accept
+ description FWEF92E_7-UDP-ALLOW-77.68.77.57
+ destination {
+ group {
+ address-group DT_FWEF92E_7
+ }
+ port 500
+ }
+ protocol udp
+ source {
+ address 77.68.77.57
+ }
+ }
+ rule 2996 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.135
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.135
+ }
+ }
+ rule 2998 {
+ action accept
+ description VPN-31002-ANY-ALLOW-10.4.88.126
+ destination {
+ group {
+ address-group DT_VPN-31002
+ }
+ }
+ source {
+ address 10.4.88.126
+ }
+ }
+ rule 2999 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-116.206.246.110
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 116.206.246.110
+ }
+ }
+ rule 3000 {
+ action accept
+ description FW08061_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW08061_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 3001 {
+ action accept
+ description VPN-15960-ANY-ALLOW-10.4.89.90
+ destination {
+ group {
+ address-group DT_VPN-15960
+ }
+ }
+ source {
+ address 10.4.89.90
+ }
+ }
+ rule 3003 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.56
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.56
+ }
+ }
+ rule 3004 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-175.157.47.47
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 175.157.47.47
+ }
+ }
+ rule 3005 {
+ action accept
+ description FW10C3D_19-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW10C3D_19
+ }
+ port 49152-65535,14147
+ }
+ protocol tcp
+ }
+ rule 3006 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.136
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.136
+ }
+ }
+ rule 3009 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-175.157.44.109
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 175.157.44.109
+ }
+ }
+ rule 3010 {
+ action accept
+ description VPN-24592-ANY-ALLOW-10.4.88.9
+ destination {
+ group {
+ address-group DT_VPN-24592
+ }
+ }
+ source {
+ address 10.4.88.9
+ }
+ }
+ rule 3011 {
+ action accept
+ description FW05AD0_2-TCP-ALLOW-213.171.209.161
+ destination {
+ group {
+ address-group DT_FW05AD0_2
+ }
+ port 3389,1433,21
+ }
+ protocol tcp
+ source {
+ address 213.171.209.161
+ }
+ }
+ rule 3012 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-123.231.86.254
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 123.231.86.254
+ }
+ }
+ rule 3014 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.16
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.16
+ }
+ }
+ rule 3018 {
+ action accept
+ description VPN-24592-ANY-ALLOW-10.4.89.9
+ destination {
+ group {
+ address-group DT_VPN-24592
+ }
+ }
+ source {
+ address 10.4.89.9
+ }
+ }
+ rule 3019 {
+ action accept
+ description VPN-24593-ANY-ALLOW-10.4.54.6
+ destination {
+ group {
+ address-group DT_VPN-24593
+ }
+ }
+ source {
+ address 10.4.54.6
+ }
+ }
+ rule 3020 {
+ action accept
+ description VPN-24593-ANY-ALLOW-10.4.55.6
+ destination {
+ group {
+ address-group DT_VPN-24593
+ }
+ }
+ source {
+ address 10.4.55.6
+ }
+ }
+ rule 3021 {
+ action accept
+ description VPN-24594-ANY-ALLOW-10.4.58.6
+ destination {
+ group {
+ address-group DT_VPN-24594
+ }
+ }
+ source {
+ address 10.4.58.6
+ }
+ }
+ rule 3022 {
+ action accept
+ description VPN-24594-ANY-ALLOW-10.4.59.6
+ destination {
+ group {
+ address-group DT_VPN-24594
+ }
+ }
+ source {
+ address 10.4.59.6
+ }
+ }
+ rule 3023 {
+ action accept
+ description VPN-24595-ANY-ALLOW-10.4.56.14
+ destination {
+ group {
+ address-group DT_VPN-24595
+ }
+ }
+ source {
+ address 10.4.56.14
+ }
+ }
+ rule 3024 {
+ action accept
+ description VPN-24595-ANY-ALLOW-10.4.57.14
+ destination {
+ group {
+ address-group DT_VPN-24595
+ }
+ }
+ source {
+ address 10.4.57.14
+ }
+ }
+ rule 3025 {
+ action accept
+ description VPN-32528-ANY-ALLOW-10.4.58.67
+ destination {
+ group {
+ address-group DT_VPN-32528
+ }
+ }
+ source {
+ address 10.4.58.67
+ }
+ }
+ rule 3026 {
+ action accept
+ description VPN-32528-ANY-ALLOW-10.4.59.67
+ destination {
+ group {
+ address-group DT_VPN-32528
+ }
+ }
+ source {
+ address 10.4.59.67
+ }
+ }
+ rule 3027 {
+ action accept
+ description FW6187E_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6187E_1
+ }
+ port 51195
+ }
+ protocol udp
+ }
+ rule 3028 {
+ action accept
+ description FW406AB_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW406AB_1
+ }
+ port 37013,25461,8881,8080,2095,2082,1992
+ }
+ protocol tcp_udp
+ }
+ rule 3029 {
+ action accept
+ description FWA86A4_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA86A4_1
+ }
+ port 30333,5666
+ }
+ protocol tcp
+ }
+ rule 3032 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.52
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.52
+ }
+ }
+ rule 3033 {
+ action accept
+ description FWC055A_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC055A_1
+ }
+ port 2195
+ }
+ protocol tcp
+ }
+ rule 3035 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.81
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.81
+ }
+ }
+ rule 3039 {
+ action accept
+ description FW42BC7_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW42BC7_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 3040 {
+ action accept
+ description FW42BC7_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW42BC7_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 3041 {
+ action accept
+ description FW310C6_3-ANY-ALLOW-88.208.198.39
+ destination {
+ group {
+ address-group DT_FW310C6_3
+ }
+ }
+ source {
+ address 88.208.198.39
+ }
+ }
+ rule 3042 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.235
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.235
+ }
+ }
+ rule 3043 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.205
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.205
+ }
+ }
+ rule 3044 {
+ action accept
+ description FWBE878_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWBE878_1
+ }
+ port 8989,5003,3000
+ }
+ protocol tcp_udp
+ }
+ rule 3045 {
+ action accept
+ description VPN-30679-ANY-ALLOW-10.4.58.195
+ destination {
+ group {
+ address-group DT_VPN-30679
+ }
+ }
+ source {
+ address 10.4.58.195
+ }
+ }
+ rule 3046 {
+ action accept
+ description FW6B9B9_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6B9B9_1
+ }
+ port 30006-65000,27017,7101,4200,2990-3009
+ }
+ protocol tcp
+ }
+ rule 3047 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.212
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.212
+ }
+ }
+ rule 3049 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-123.231.125.4
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 123.231.125.4
+ }
+ }
+ rule 3050 {
+ action accept
+ description FW49C3D_4-TCP-ALLOW-83.100.136.74
+ destination {
+ group {
+ address-group DT_FW49C3D_4
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 83.100.136.74
+ }
+ }
+ rule 3051 {
+ action accept
+ description FW49C3D_6-TCP-ALLOW-87.224.33.215
+ destination {
+ group {
+ address-group DT_FW49C3D_6
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 87.224.33.215
+ }
+ }
+ rule 3053 {
+ action accept
+ description FW89619_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW89619_1
+ }
+ port 9000-10999
+ }
+ protocol udp
+ }
+ rule 3054 {
+ action accept
+ description FWBD9D0_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWBD9D0_1
+ }
+ port 9090
+ }
+ protocol tcp
+ }
+ rule 3055 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-175.157.47.236
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 175.157.47.236
+ }
+ }
+ rule 3056 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-175.157.46.226
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 175.157.46.226
+ }
+ }
+ rule 3058 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.205
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.205
+ }
+ }
+ rule 3060 {
+ action accept
+ description FWF7B68_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF7B68_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 3061 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.253
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.253
+ }
+ }
+ rule 3063 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.0
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.0
+ }
+ }
+ rule 3065 {
+ action accept
+ description FW85619_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW85619_1
+ }
+ port 6433
+ }
+ protocol tcp
+ }
+ rule 3066 {
+ action accept
+ description FW5A5D7_3-TCP-ALLOW-188.66.79.94
+ destination {
+ group {
+ address-group DT_FW5A5D7_3
+ }
+ port 8172,3389
+ }
+ protocol tcp
+ source {
+ address 188.66.79.94
+ }
+ }
+ rule 3067 {
+ action accept
+ description FWF30BD_1-TCP-ALLOW-81.133.80.114
+ destination {
+ group {
+ address-group DT_FWF30BD_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 81.133.80.114
+ }
+ }
+ rule 3068 {
+ action accept
+ description FWF30BD_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF30BD_1
+ }
+ port 5061,5015,5001
+ }
+ protocol tcp
+ }
+ rule 3069 {
+ action accept
+ description FWBD9D0_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWBD9D0_1
+ }
+ port 51820
+ }
+ protocol udp
+ }
+ rule 3070 {
+ action accept
+ description FW7C4D9_14-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW7C4D9_14
+ }
+ port 25565,2456-2458
+ }
+ protocol tcp_udp
+ }
+ rule 3071 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.23
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.23
+ }
+ }
+ rule 3072 {
+ action accept
+ description FWEEC75_1-TCP-ALLOW-81.96.100.32
+ destination {
+ group {
+ address-group DT_FWEEC75_1
+ }
+ port 8447
+ }
+ protocol tcp
+ source {
+ address 81.96.100.32
+ }
+ }
+ rule 3073 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-95.168.164.208
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 95.168.164.208
+ }
+ }
+ rule 3074 {
+ action accept
+ description VPN-19992-ANY-ALLOW-10.4.86.158
+ destination {
+ group {
+ address-group DT_VPN-19992
+ }
+ }
+ source {
+ address 10.4.86.158
+ }
+ }
+ rule 3075 {
+ action accept
+ description FWF30BD_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF30BD_1
+ }
+ port 5090,5060
+ }
+ protocol tcp_udp
+ }
+ rule 3076 {
+ action accept
+ description VPN-30679-ANY-ALLOW-10.4.59.195
+ destination {
+ group {
+ address-group DT_VPN-30679
+ }
+ }
+ source {
+ address 10.4.59.195
+ }
+ }
+ rule 3077 {
+ action accept
+ description FW930F3_3-ANY-ALLOW-77.68.112.254
+ destination {
+ group {
+ address-group DT_FW930F3_3
+ }
+ }
+ source {
+ address 77.68.112.254
+ }
+ }
+ rule 3078 {
+ action accept
+ description FW672AB_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW672AB_1
+ }
+ port 5432
+ }
+ protocol tcp
+ }
+ rule 3079 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.252
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.252
+ }
+ }
+ rule 3080 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-123.231.86.192
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 123.231.86.192
+ }
+ }
+ rule 3081 {
+ action accept
+ description VPN-33204-ANY-ALLOW-10.4.56.176
+ destination {
+ group {
+ address-group DT_VPN-33204
+ }
+ }
+ source {
+ address 10.4.56.176
+ }
+ }
+ rule 3083 {
+ action accept
+ description FW1FA8E_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1FA8E_1
+ }
+ port 33434
+ }
+ protocol udp
+ }
+ rule 3084 {
+ action accept
+ description FWD2440_1-ESP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD2440_1
+ }
+ }
+ protocol esp
+ }
+ rule 3085 {
+ action accept
+ description FWA0531_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA0531_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 3090 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.70
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.70
+ }
+ }
+ rule 3091 {
+ action accept
+ description FWF7BFA_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF7BFA_1
+ }
+ port 8000,5901,5479,5478
+ }
+ protocol tcp
+ }
+ rule 3092 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.212
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.212
+ }
+ }
+ rule 3094 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.125
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.125
+ }
+ }
+ rule 3096 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.89
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.89
+ }
+ }
+ rule 3097 {
+ action accept
+ description FWD56A2_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD56A2_1
+ }
+ port 8001,8000
+ }
+ protocol tcp
+ }
+ rule 3098 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.109
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.109
+ }
+ }
+ rule 3099 {
+ action accept
+ description FW36425_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW36425_1
+ }
+ port 44445,7770-7800
+ }
+ protocol tcp
+ }
+ rule 3100 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.238
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.238
+ }
+ }
+ rule 3102 {
+ action accept
+ description FW6B39D_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6B39D_1
+ }
+ port 49216,49215
+ }
+ protocol tcp_udp
+ }
+ rule 3103 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.121
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.121
+ }
+ }
+ rule 3105 {
+ action accept
+ description FW2379F_14-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2379F_14
+ }
+ port 443
+ }
+ protocol tcp_udp
+ }
+ rule 3107 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.38
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.38
+ }
+ }
+ rule 3109 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.191
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.191
+ }
+ }
+ rule 3111 {
+ action accept
+ description FW27947_1-TCP-ALLOW-213.229.100.148
+ destination {
+ group {
+ address-group DT_FW27947_1
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 213.229.100.148
+ }
+ }
+ rule 3112 {
+ action accept
+ description FWD42CF_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD42CF_1
+ }
+ port 5432,5001,5000
+ }
+ protocol tcp
+ }
+ rule 3114 {
+ action accept
+ description FW3A12F_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW3A12F_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 3116 {
+ action accept
+ description FW5A5D7_3-TCP-ALLOW-194.62.184.87
+ destination {
+ group {
+ address-group DT_FW5A5D7_3
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 194.62.184.87
+ }
+ }
+ rule 3117 {
+ action accept
+ description FW5A5D7_3-TCP-ALLOW-51.219.31.78
+ destination {
+ group {
+ address-group DT_FW5A5D7_3
+ }
+ port 8172,3389
+ }
+ protocol tcp
+ source {
+ address 51.219.31.78
+ }
+ }
+ rule 3118 {
+ action accept
+ description VPN-26157-ANY-ALLOW-10.4.86.57
+ destination {
+ group {
+ address-group DT_VPN-26157
+ }
+ }
+ source {
+ address 10.4.86.57
+ }
+ }
+ rule 3119 {
+ action accept
+ description VPN-26157-ANY-ALLOW-10.4.87.57
+ destination {
+ group {
+ address-group DT_VPN-26157
+ }
+ }
+ source {
+ address 10.4.87.57
+ }
+ }
+ rule 3120 {
+ action accept
+ description FWA7625_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA7625_1
+ }
+ port 943
+ }
+ protocol tcp
+ }
+ rule 3121 {
+ action accept
+ description FWC96A1_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC96A1_1
+ }
+ port 1194
+ }
+ protocol udp
+ }
+ rule 3122 {
+ action accept
+ description FWA7625_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA7625_1
+ }
+ port 1194
+ }
+ protocol udp
+ }
+ rule 3123 {
+ action accept
+ description FWA7625_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA7625_1
+ }
+ port 32400,10108
+ }
+ protocol tcp_udp
+ }
+ rule 3125 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-185.173.161.154
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 185.173.161.154
+ }
+ }
+ rule 3127 {
+ action accept
+ description FW05339_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW05339_1
+ }
+ port 46961
+ }
+ protocol udp
+ }
+ rule 3130 {
+ action accept
+ description FWA0AA0_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA0AA0_1
+ }
+ port 1194
+ }
+ protocol udp
+ }
+ rule 3132 {
+ action accept
+ description FWD8DD1_2-TCP_UDP-ALLOW-77.153.164.226
+ destination {
+ group {
+ address-group DT_FWD8DD1_2
+ }
+ port 443,80
+ }
+ protocol tcp_udp
+ source {
+ address 77.153.164.226
+ }
+ }
+ rule 3134 {
+ action accept
+ description FW19987_4-TCP-ALLOW-87.224.6.174
+ destination {
+ group {
+ address-group DT_FW19987_4
+ }
+ port 3389,445,443
+ }
+ protocol tcp
+ source {
+ address 87.224.6.174
+ }
+ }
+ rule 3135 {
+ action accept
+ description FW40AE4_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW40AE4_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 3136 {
+ action accept
+ description VPN-33204-ANY-ALLOW-10.4.57.176
+ destination {
+ group {
+ address-group DT_VPN-33204
+ }
+ }
+ source {
+ address 10.4.57.176
+ }
+ }
+ rule 3137 {
+ action accept
+ description FWF3A1B_1-TCP_UDP-ALLOW-86.132.125.4
+ destination {
+ group {
+ address-group DT_FWF3A1B_1
+ }
+ port 2222
+ }
+ protocol tcp_udp
+ source {
+ address 86.132.125.4
+ }
+ }
+ rule 3138 {
+ action accept
+ description FWF3A1B_1-TCP_UDP-ALLOW-91.205.173.51
+ destination {
+ group {
+ address-group DT_FWF3A1B_1
+ }
+ port 2222
+ }
+ protocol tcp_udp
+ source {
+ address 91.205.173.51
+ }
+ }
+ rule 3143 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-109.149.121.73
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389,443
+ }
+ protocol tcp
+ source {
+ address 109.149.121.73
+ }
+ }
+ rule 3144 {
+ action accept
+ description FWA0AA0_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA0AA0_1
+ }
+ port 28083,28015-28016,1935
+ }
+ protocol tcp_udp
+ }
+ rule 3146 {
+ action accept
+ description FWF3A1B_1-TCP_UDP-ALLOW-92.233.27.144
+ destination {
+ group {
+ address-group DT_FWF3A1B_1
+ }
+ port 2222
+ }
+ protocol tcp_udp
+ source {
+ address 92.233.27.144
+ }
+ }
+ rule 3148 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-151.228.194.190
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389,443
+ }
+ protocol tcp
+ source {
+ address 151.228.194.190
+ }
+ }
+ rule 3149 {
+ action accept
+ description FW9B6FB_1-ICMP-ALLOW-77.68.89.115_32
+ destination {
+ group {
+ address-group DT_FW9B6FB_1
+ }
+ }
+ protocol icmp
+ source {
+ address 77.68.89.115/32
+ }
+ }
+ rule 3153 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.199
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.199
+ }
+ }
+ rule 3155 {
+ action accept
+ description FW45F3D_1-ANY-ALLOW-195.224.110.168
+ destination {
+ group {
+ address-group DT_FW45F3D_1
+ }
+ }
+ source {
+ address 195.224.110.168
+ }
+ }
+ rule 3156 {
+ action accept
+ description FWF8E67_1-TCP-ALLOW-82.14.188.35
+ destination {
+ group {
+ address-group DT_FWF8E67_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 82.14.188.35
+ }
+ }
+ rule 3157 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.58
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.58
+ }
+ }
+ rule 3158 {
+ action accept
+ description VPN-19992-ANY-ALLOW-10.4.87.158
+ destination {
+ group {
+ address-group DT_VPN-19992
+ }
+ }
+ source {
+ address 10.4.87.158
+ }
+ }
+ rule 3159 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-5.66.24.185
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389,443
+ }
+ protocol tcp
+ source {
+ address 5.66.24.185
+ }
+ }
+ rule 3160 {
+ action accept
+ description FWF8E67_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF8E67_1
+ }
+ port 3001
+ }
+ protocol tcp
+ }
+ rule 3161 {
+ action accept
+ description FWD2440_1-AH-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD2440_1
+ }
+ }
+ protocol ah
+ }
+ rule 3166 {
+ action accept
+ description FW3EBC8_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW3EBC8_1
+ }
+ port 9001-9900,9000
+ }
+ protocol tcp
+ }
+ rule 3167 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.244
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.244
+ }
+ }
+ rule 3168 {
+ action accept
+ description FWA0531_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA0531_1
+ }
+ port 3000
+ }
+ protocol tcp
+ }
+ rule 3170 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.137
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.137
+ }
+ }
+ rule 3173 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.104
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.104
+ }
+ }
+ rule 3176 {
+ action accept
+ description FW6906B_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6906B_1
+ }
+ port 4190
+ }
+ protocol tcp
+ }
+ rule 3177 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-116.206.246.230
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 116.206.246.230
+ }
+ }
+ rule 3178 {
+ action accept
+ description FW444AF_1-TCP-ALLOW-91.135.10.140
+ destination {
+ group {
+ address-group DT_FW444AF_1
+ }
+ port 27017
+ }
+ protocol tcp
+ source {
+ address 91.135.10.140
+ }
+ }
+ rule 3180 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-81.150.13.34
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389,443
+ }
+ protocol tcp
+ source {
+ address 81.150.13.34
+ }
+ }
+ rule 3181 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-82.10.14.73
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389,443
+ }
+ protocol tcp
+ source {
+ address 82.10.14.73
+ }
+ }
+ rule 3183 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.25
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.25
+ }
+ }
+ rule 3184 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.224
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.224
+ }
+ }
+ rule 3185 {
+ action accept
+ description FW9B6FB_1-TCP-ALLOW-77.68.89.115_32
+ destination {
+ group {
+ address-group DT_FW9B6FB_1
+ }
+ port 10050
+ }
+ protocol tcp
+ source {
+ address 77.68.89.115/32
+ }
+ }
+ rule 3186 {
+ action accept
+ description VPN-14673-ANY-ALLOW-10.4.89.44
+ destination {
+ group {
+ address-group DT_VPN-14673
+ }
+ }
+ source {
+ address 10.4.89.44
+ }
+ }
+ rule 3187 {
+ action accept
+ description FWCA628_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWCA628_1
+ }
+ port 2096,2095,2087,2086,2083,2082
+ }
+ protocol tcp
+ }
+ rule 3189 {
+ action accept
+ description VPN-28484-ANY-ALLOW-10.4.58.159
+ destination {
+ group {
+ address-group DT_VPN-28484
+ }
+ }
+ source {
+ address 10.4.58.159
+ }
+ }
+ rule 3190 {
+ action accept
+ description FW028C0_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW028C0_2
+ }
+ port 44491-44498,44474
+ }
+ protocol tcp
+ }
+ rule 3191 {
+ action accept
+ description VPN-28484-ANY-ALLOW-10.4.59.159
+ destination {
+ group {
+ address-group DT_VPN-28484
+ }
+ }
+ source {
+ address 10.4.59.159
+ }
+ }
+ rule 3192 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.119
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.119
+ }
+ }
+ rule 3194 {
+ action accept
+ description FWF699D_4-TCP-ALLOW-195.74.108.130
+ destination {
+ group {
+ address-group DT_FWF699D_4
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 195.74.108.130
+ }
+ }
+ rule 3195 {
+ action accept
+ description FWF699D_4-TCP-ALLOW-31.54.149.143
+ destination {
+ group {
+ address-group DT_FWF699D_4
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 31.54.149.143
+ }
+ }
+ rule 3196 {
+ action accept
+ description FWF699D_4-TCP-ALLOW-35.204.243.120
+ destination {
+ group {
+ address-group DT_FWF699D_4
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 35.204.243.120
+ }
+ }
+ rule 3197 {
+ action accept
+ description FWF699D_4-TCP-ALLOW-81.150.55.65
+ destination {
+ group {
+ address-group DT_FWF699D_4
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 81.150.55.65
+ }
+ }
+ rule 3198 {
+ action accept
+ description FWF699D_4-TCP-ALLOW-81.150.55.70
+ destination {
+ group {
+ address-group DT_FWF699D_4
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 81.150.55.70
+ }
+ }
+ rule 3199 {
+ action accept
+ description FWF699D_4-TCP-ALLOW-86.142.112.4
+ destination {
+ group {
+ address-group DT_FWF699D_4
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 86.142.112.4
+ }
+ }
+ rule 3200 {
+ action accept
+ description FWF699D_4-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF699D_4
+ }
+ port 8983
+ }
+ protocol tcp_udp
+ }
+ rule 3201 {
+ action accept
+ description FWF699D_4-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF699D_4
+ }
+ port 11009,10009
+ }
+ protocol tcp
+ }
+ rule 3202 {
+ action accept
+ description VPN-2661-ANY-ALLOW-10.4.54.24
+ destination {
+ group {
+ address-group DT_VPN-2661
+ }
+ }
+ source {
+ address 10.4.54.24
+ }
+ }
+ rule 3203 {
+ action accept
+ description VPN-2661-ANY-ALLOW-10.4.55.24
+ destination {
+ group {
+ address-group DT_VPN-2661
+ }
+ }
+ source {
+ address 10.4.55.24
+ }
+ }
+ rule 3204 {
+ action accept
+ description VPN-9727-ANY-ALLOW-10.4.54.118
+ destination {
+ group {
+ address-group DT_VPN-9727
+ }
+ }
+ source {
+ address 10.4.54.118
+ }
+ }
+ rule 3205 {
+ action accept
+ description VPN-9727-ANY-ALLOW-10.4.55.119
+ destination {
+ group {
+ address-group DT_VPN-9727
+ }
+ }
+ source {
+ address 10.4.55.119
+ }
+ }
+ rule 3207 {
+ action accept
+ description FWF0221_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF0221_1
+ }
+ port 65000,8099,8080
+ }
+ protocol tcp_udp
+ }
+ rule 3208 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.180
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.180
+ }
+ }
+ rule 3209 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-82.5.189.5
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 82.5.189.5
+ }
+ }
+ rule 3210 {
+ action accept
+ description FW60FD6_5-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW60FD6_5
+ }
+ port 1194
+ }
+ protocol udp
+ }
+ rule 3211 {
+ action accept
+ description FW60FD6_5-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW60FD6_5
+ }
+ port 9500,9191,9090,8090,2222
+ }
+ protocol tcp
+ }
+ rule 3212 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-84.65.217.114
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389,443
+ }
+ protocol tcp
+ source {
+ address 84.65.217.114
+ }
+ }
+ rule 3213 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-175.157.43.21
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 175.157.43.21
+ }
+ }
+ rule 3214 {
+ action accept
+ description FW45F3D_1-ANY-ALLOW-77.68.126.251
+ destination {
+ group {
+ address-group DT_FW45F3D_1
+ }
+ }
+ source {
+ address 77.68.126.251
+ }
+ }
+ rule 3215 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-86.14.23.23
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389,443
+ }
+ protocol tcp
+ source {
+ address 86.14.23.23
+ }
+ }
+ rule 3217 {
+ action accept
+ description FW85E02_11-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW85E02_11
+ }
+ port 9000-10999
+ }
+ protocol udp
+ }
+ rule 3218 {
+ action accept
+ description FW5D0FA_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW5D0FA_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 3222 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.141
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.141
+ }
+ }
+ rule 3223 {
+ action accept
+ description FWCDD8B_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWCDD8B_1
+ }
+ port 2222
+ }
+ protocol tcp
+ }
+ rule 3224 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.185
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.185
+ }
+ }
+ rule 3225 {
+ action accept
+ description FW06940_3-TCP_UDP-ALLOW-213.171.210.153
+ destination {
+ group {
+ address-group DT_FW06940_3
+ }
+ port 1-65535
+ }
+ protocol tcp_udp
+ source {
+ address 213.171.210.153
+ }
+ }
+ rule 3226 {
+ action accept
+ description FW06940_3-TCP_UDP-ALLOW-70.29.113.102
+ destination {
+ group {
+ address-group DT_FW06940_3
+ }
+ port 1-65535
+ }
+ protocol tcp_udp
+ source {
+ address 70.29.113.102
+ }
+ }
+ rule 3227 {
+ action accept
+ description FWC32BE_1-ANY-ALLOW-3.127.0.177
+ destination {
+ group {
+ address-group DT_FWC32BE_1
+ }
+ }
+ source {
+ address 3.127.0.177
+ }
+ }
+ rule 3228 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-93.115.195.58
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389,443
+ }
+ protocol tcp
+ source {
+ address 93.115.195.58
+ }
+ }
+ rule 3229 {
+ action accept
+ description FWE32F2_8-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE32F2_8
+ }
+ port 40120,30120,30110
+ }
+ protocol tcp
+ }
+ rule 3230 {
+ action accept
+ description VPN-28515-ANY-ALLOW-10.4.56.162
+ destination {
+ group {
+ address-group DT_VPN-28515
+ }
+ }
+ source {
+ address 10.4.56.162
+ }
+ }
+ rule 3231 {
+ action accept
+ description FW06940_3-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW06940_3
+ }
+ port 30000-30400,8443-8447,445,80-110,21-25
+ }
+ protocol tcp
+ }
+ rule 3232 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.134
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.134
+ }
+ }
+ rule 3236 {
+ action accept
+ description VPN-28515-ANY-ALLOW-10.4.57.162
+ destination {
+ group {
+ address-group DT_VPN-28515
+ }
+ }
+ source {
+ address 10.4.57.162
+ }
+ }
+ rule 3237 {
+ action accept
+ description FWF4063_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF4063_1
+ }
+ port 3000
+ }
+ protocol tcp
+ }
+ rule 3240 {
+ action accept
+ description FW06940_3-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW06940_3
+ }
+ port 49152-65535,6379,5666,5432-5454
+ }
+ protocol tcp_udp
+ }
+ rule 3242 {
+ action accept
+ description FW2E8D4_1-TCP-ALLOW-63.35.92.185
+ destination {
+ group {
+ address-group DT_FW2E8D4_1
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 63.35.92.185
+ }
+ }
+ rule 3244 {
+ action accept
+ description FWF30BD_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF30BD_1
+ }
+ port 9000-10999
+ }
+ protocol udp
+ }
+ rule 3245 {
+ action accept
+ description FWE30A1_4-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE30A1_4
+ }
+ port 65057
+ }
+ protocol tcp_udp
+ }
+ rule 3246 {
+ action accept
+ description VPN-26772-ANY-ALLOW-10.4.54.123
+ destination {
+ group {
+ address-group DT_VPN-26772
+ }
+ }
+ source {
+ address 10.4.54.123
+ }
+ }
+ rule 3249 {
+ action accept
+ description FW56496_1-ANY-ALLOW-77.68.82.49
+ destination {
+ group {
+ address-group DT_FW56496_1
+ }
+ }
+ source {
+ address 77.68.82.49
+ }
+ }
+ rule 3251 {
+ action accept
+ description FWDA443_6-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWDA443_6
+ }
+ port 30175,12050
+ }
+ protocol tcp
+ }
+ rule 3253 {
+ action accept
+ description FW5A521_3-TCP-ALLOW-88.98.75.17
+ destination {
+ group {
+ address-group DT_FW5A521_3
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 88.98.75.17
+ }
+ }
+ rule 3254 {
+ action accept
+ description FW5A521_3-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW5A521_3
+ }
+ port 161-162
+ }
+ protocol udp
+ }
+ rule 3255 {
+ action accept
+ description FW5A521_3-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW5A521_3
+ }
+ port 5900
+ }
+ protocol tcp
+ }
+ rule 3259 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.178
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.178
+ }
+ }
+ rule 3260 {
+ action accept
+ description VPN-26772-ANY-ALLOW-10.4.55.124
+ destination {
+ group {
+ address-group DT_VPN-26772
+ }
+ }
+ source {
+ address 10.4.55.124
+ }
+ }
+ rule 3262 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.114
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.114
+ }
+ }
+ rule 3272 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-116.206.246.30
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 116.206.246.30
+ }
+ }
+ rule 3273 {
+ action accept
+ description FW2B4BA_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2B4BA_1
+ }
+ port 30000-31000
+ }
+ protocol tcp
+ }
+ rule 3284 {
+ action accept
+ description FW06940_3-TCP-ALLOW-213.171.217.107
+ destination {
+ group {
+ address-group DT_FW06940_3
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 213.171.217.107
+ }
+ }
+ rule 3285 {
+ action accept
+ description FW0952B_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0952B_1
+ }
+ port 9030,9001
+ }
+ protocol tcp
+ }
+ rule 3286 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-123.231.85.35
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 123.231.85.35
+ }
+ }
+ rule 3290 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.208.232
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.208.232
+ }
+ }
+ rule 3294 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.21
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.21
+ }
+ }
+ rule 3295 {
+ action accept
+ description FW0EA3F_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0EA3F_1
+ }
+ port 1-65535
+ }
+ protocol tcp_udp
+ }
+ rule 3296 {
+ action accept
+ description FW9D5C7_1-TCP-ALLOW-209.97.176.108
+ destination {
+ group {
+ address-group DT_FW9D5C7_1
+ }
+ port 8447,8443,22
+ }
+ protocol tcp
+ source {
+ address 209.97.176.108
+ }
+ }
+ rule 3297 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.188
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.188
+ }
+ }
+ rule 3298 {
+ action accept
+ description FW9D5C7_1-TCP-ALLOW-165.227.231.227
+ destination {
+ group {
+ address-group DT_FW9D5C7_1
+ }
+ port 9117,9113,9104,9100
+ }
+ protocol tcp
+ source {
+ address 165.227.231.227
+ }
+ }
+ rule 3299 {
+ action accept
+ description FW4DB0A_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4DB0A_1
+ }
+ port 953
+ }
+ protocol tcp
+ }
+ rule 3300 {
+ action accept
+ description FW4DB0A_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4DB0A_1
+ }
+ port 953
+ }
+ protocol udp
+ }
+ rule 3301 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.91
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.91
+ }
+ }
+ rule 3303 {
+ action accept
+ description FW56496_1-TCP-ALLOW-176.255.93.149
+ destination {
+ group {
+ address-group DT_FW56496_1
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 176.255.93.149
+ }
+ }
+ rule 3304 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.79
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.79
+ }
+ }
+ rule 3305 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.43
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.43
+ }
+ }
+ rule 3306 {
+ action accept
+ description FW310C6_3-ANY-ALLOW-88.208.198.40
+ destination {
+ group {
+ address-group DT_FW310C6_3
+ }
+ }
+ source {
+ address 88.208.198.40
+ }
+ }
+ rule 3307 {
+ action accept
+ description FW597A6_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW597A6_1
+ }
+ port 49152-65535,990
+ }
+ protocol tcp
+ }
+ rule 3308 {
+ action accept
+ description FW597A6_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW597A6_1
+ }
+ port 3306
+ }
+ protocol tcp_udp
+ }
+ rule 3309 {
+ action accept
+ description FWBC280_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWBC280_1
+ }
+ port 49152-65535,20-21
+ }
+ protocol tcp
+ }
+ rule 3310 {
+ action accept
+ description VPN-31301-ANY-ALLOW-10.4.87.223
+ destination {
+ group {
+ address-group DT_VPN-31301
+ }
+ }
+ source {
+ address 10.4.87.223
+ }
+ }
+ rule 3311 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-148.253.173.243
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 148.253.173.243
+ }
+ }
+ rule 3312 {
+ action accept
+ description FW9EEDD_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW9EEDD_1
+ }
+ port 990,197,20-23
+ }
+ protocol tcp
+ }
+ rule 3313 {
+ action accept
+ description FW9EEDD_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW9EEDD_1
+ }
+ port 49152-65535
+ }
+ protocol tcp_udp
+ }
+ rule 3314 {
+ action accept
+ description VPN-31002-ANY-ALLOW-10.4.89.126
+ destination {
+ group {
+ address-group DT_VPN-31002
+ }
+ }
+ source {
+ address 10.4.89.126
+ }
+ }
+ rule 3316 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.11
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.11
+ }
+ }
+ rule 3317 {
+ action accept
+ description FW32EFF_49-TCP-ALLOW-195.59.191.128_25
+ destination {
+ group {
+ address-group DT_FW32EFF_49
+ }
+ port 5589
+ }
+ protocol tcp
+ source {
+ address 195.59.191.128/25
+ }
+ }
+ rule 3318 {
+ action accept
+ description FW32EFF_49-TCP-ALLOW-213.71.130.0_26
+ destination {
+ group {
+ address-group DT_FW32EFF_49
+ }
+ port 5589
+ }
+ protocol tcp
+ source {
+ address 213.71.130.0/26
+ }
+ }
+ rule 3319 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.88
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.88
+ }
+ }
+ rule 3320 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.173
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.173
+ }
+ }
+ rule 3321 {
+ action accept
+ description FW32EFF_49-TCP-ALLOW-84.19.45.82
+ destination {
+ group {
+ address-group DT_FW32EFF_49
+ }
+ port 5589
+ }
+ protocol tcp
+ source {
+ address 84.19.45.82
+ }
+ }
+ rule 3322 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-175.157.43.122
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 175.157.43.122
+ }
+ }
+ rule 3323 {
+ action accept
+ description FWC1ACD_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC1ACD_1
+ }
+ port 28061,28060,8080
+ }
+ protocol tcp_udp
+ }
+ rule 3324 {
+ action accept
+ description FWA5D67_1-TCP_UDP-ALLOW-84.74.32.74
+ destination {
+ group {
+ address-group DT_FWA5D67_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 84.74.32.74
+ }
+ }
+ rule 3325 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.169
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.169
+ }
+ }
+ rule 3326 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.89
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.89
+ }
+ }
+ rule 3329 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.35
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.35
+ }
+ }
+ rule 3330 {
+ action accept
+ description FWCE020_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWCE020_1
+ }
+ port 48402
+ }
+ protocol udp
+ }
+ rule 3333 {
+ action accept
+ description FWF3574_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF3574_1
+ }
+ port 8060,445,139
+ }
+ protocol tcp
+ }
+ rule 3334 {
+ action accept
+ description FWE6AB2_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE6AB2_1
+ }
+ port 44158,945,943
+ }
+ protocol tcp
+ }
+ rule 3335 {
+ action accept
+ description FWBFC02_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWBFC02_1
+ }
+ port 44158,945,943
+ }
+ protocol tcp
+ }
+ rule 3336 {
+ action accept
+ description FWBFC02_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWBFC02_1
+ }
+ port 1194
+ }
+ protocol udp
+ }
+ rule 3337 {
+ action accept
+ description FWE6AB2_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE6AB2_1
+ }
+ port 1194
+ }
+ protocol udp
+ }
+ rule 3338 {
+ action accept
+ description FWBC8A6_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWBC8A6_1
+ }
+ port 44158,945,943
+ }
+ protocol tcp
+ }
+ rule 3339 {
+ action accept
+ description FWBC8A6_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWBC8A6_1
+ }
+ port 1194
+ }
+ protocol udp
+ }
+ rule 3340 {
+ action accept
+ description FWA0AA0_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA0AA0_1
+ }
+ port 2302
+ }
+ protocol tcp
+ }
+ rule 3342 {
+ action accept
+ description FW56496_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW56496_1
+ }
+ port 22
+ }
+ protocol tcp_udp
+ }
+ rule 3343 {
+ action accept
+ description FW56496_1-TCP-ALLOW-157.231.178.162
+ destination {
+ group {
+ address-group DT_FW56496_1
+ }
+ port 21
+ }
+ protocol tcp
+ source {
+ address 157.231.178.162
+ }
+ }
+ rule 3344 {
+ action accept
+ description FW56496_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW56496_1
+ }
+ port 2443,1022
+ }
+ protocol tcp
+ }
+ rule 3345 {
+ action accept
+ description FW56496_1-TCP_UDP-ALLOW-46.16.211.142
+ destination {
+ group {
+ address-group DT_FW56496_1
+ }
+ port 3389,21
+ }
+ protocol tcp_udp
+ source {
+ address 46.16.211.142
+ }
+ }
+ rule 3347 {
+ action accept
+ description FW2379F_14-GRE-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2379F_14
+ }
+ }
+ protocol gre
+ }
+ rule 3348 {
+ action accept
+ description FW0E383_9-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0E383_9
+ }
+ port 52000
+ }
+ protocol tcp
+ }
+ rule 3350 {
+ action accept
+ description FWB4438_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWB4438_2
+ }
+ port 993-995,7
+ }
+ protocol tcp
+ }
+ rule 3351 {
+ action accept
+ description FW1F3D0_6-TCP_UDP-ALLOW-82.165.207.109
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 4567-4568
+ }
+ protocol tcp_udp
+ source {
+ address 82.165.207.109
+ }
+ }
+ rule 3352 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.77
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.77
+ }
+ }
+ rule 3358 {
+ action accept
+ description FW46F4A_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW46F4A_1
+ }
+ port 51820
+ }
+ protocol udp
+ }
+ rule 3359 {
+ action accept
+ description FW53C72_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW53C72_1
+ }
+ port 48402
+ }
+ protocol udp
+ }
+ rule 3360 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.251
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.251
+ }
+ }
+ rule 3362 {
+ action accept
+ description FWAA38E_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWAA38E_1
+ }
+ port 1001-65535
+ }
+ protocol tcp_udp
+ }
+ rule 3363 {
+ action accept
+ description FW138F8_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW138F8_1
+ }
+ port 21,20
+ }
+ protocol tcp_udp
+ }
+ rule 3364 {
+ action accept
+ description FW0BD92_3-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0BD92_3
+ }
+ port 18081,18080
+ }
+ protocol tcp
+ }
+ rule 3365 {
+ action accept
+ description FWFEF05_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWFEF05_1
+ }
+ port 1935
+ }
+ protocol tcp_udp
+ }
+ rule 3367 {
+ action accept
+ description FW26846_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW26846_1
+ }
+ port 8000
+ }
+ protocol tcp
+ }
+ rule 3368 {
+ action accept
+ description FWB4438_2-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWB4438_2
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 3369 {
+ action accept
+ description FWA884B_5-TCP-ALLOW-51.146.16.162
+ destination {
+ group {
+ address-group DT_FWA884B_5
+ }
+ port 8447,8443,22
+ }
+ protocol tcp
+ source {
+ address 51.146.16.162
+ }
+ }
+ rule 3370 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.22
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.22
+ }
+ }
+ rule 3371 {
+ action accept
+ description FWFDE34_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWFDE34_1
+ }
+ port 18081,18080
+ }
+ protocol tcp
+ }
+ rule 3373 {
+ action accept
+ description FWB6101_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWB6101_1
+ }
+ port 2280
+ }
+ protocol tcp
+ }
+ rule 3377 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-123.231.84.203
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 123.231.84.203
+ }
+ }
+ rule 3378 {
+ action accept
+ description FW1D511_2-TCP-ALLOW-92.29.46.47
+ destination {
+ group {
+ address-group DT_FW1D511_2
+ }
+ port 9090
+ }
+ protocol tcp
+ source {
+ address 92.29.46.47
+ }
+ }
+ rule 3386 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.208.175
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.208.175
+ }
+ }
+ rule 3387 {
+ action accept
+ description FW1ACD9_2-TCP-ALLOW-89.197.148.38
+ destination {
+ group {
+ address-group DT_FW1ACD9_2
+ }
+ port 5015,22
+ }
+ protocol tcp
+ source {
+ address 89.197.148.38
+ }
+ }
+ rule 3388 {
+ action accept
+ description FW1ACD9_2-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1ACD9_2
+ }
+ port 9000-10999,5090,5060
+ }
+ protocol udp
+ }
+ rule 3389 {
+ action accept
+ description FW1ACD9_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1ACD9_2
+ }
+ port 5090,5060-5062
+ }
+ protocol tcp
+ }
+ rule 3391 {
+ action accept
+ description FWA0B7F_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA0B7F_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 3392 {
+ action accept
+ description FW56335_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW56335_2
+ }
+ port 18081,18080
+ }
+ protocol tcp
+ }
+ rule 3395 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.90
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.90
+ }
+ }
+ rule 3396 {
+ action accept
+ description FW4D3E6_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4D3E6_1
+ }
+ port 18081,18080
+ }
+ protocol tcp
+ }
+ rule 3397 {
+ action accept
+ description FWB118A_1-TCP-ALLOW-188.65.177.58
+ destination {
+ group {
+ address-group DT_FWB118A_1
+ }
+ port 49152-65534,8447,8443,22,21,20
+ }
+ protocol tcp
+ source {
+ address 188.65.177.58
+ }
+ }
+ rule 3398 {
+ action accept
+ description FWB118A_1-TCP-ALLOW-77.68.103.13
+ destination {
+ group {
+ address-group DT_FWB118A_1
+ }
+ port 49152-65534,8447,8443,22,21,20
+ }
+ protocol tcp
+ source {
+ address 77.68.103.13
+ }
+ }
+ rule 3399 {
+ action accept
+ description FWB118A_1-TCP-ALLOW-80.5.71.130
+ destination {
+ group {
+ address-group DT_FWB118A_1
+ }
+ port 49152-65534,8447,8443,22,21,20
+ }
+ protocol tcp
+ source {
+ address 80.5.71.130
+ }
+ }
+ rule 3402 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.205
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.205
+ }
+ }
+ rule 3408 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.31
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.31
+ }
+ }
+ rule 3409 {
+ action accept
+ description FW539FB_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW539FB_1
+ }
+ port 389
+ }
+ protocol tcp
+ }
+ rule 3411 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.185
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.185
+ }
+ }
+ rule 3415 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-116.206.245.124
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 116.206.245.124
+ }
+ }
+ rule 3416 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.75
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.75
+ }
+ }
+ rule 3417 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.34
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.34
+ }
+ }
+ rule 3418 {
+ action accept
+ description FWEF92E_5-UDP-ALLOW-77.68.77.70
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 500
+ }
+ protocol udp
+ source {
+ address 77.68.77.70
+ }
+ }
+ rule 3419 {
+ action accept
+ description FWEF92E_5-UDP-ALLOW-77.68.92.33
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 500
+ }
+ protocol udp
+ source {
+ address 77.68.92.33
+ }
+ }
+ rule 3420 {
+ action accept
+ description FWEF92E_5-UDP-ALLOW-77.68.93.82
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 500
+ }
+ protocol udp
+ source {
+ address 77.68.93.82
+ }
+ }
+ rule 3421 {
+ action accept
+ description FWEF92E_5-UDP-ALLOW-88.208.198.93
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 500
+ }
+ protocol udp
+ source {
+ address 88.208.198.93
+ }
+ }
+ rule 3422 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.94
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.94
+ }
+ }
+ rule 3424 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-148.253.173.244
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 148.253.173.244
+ }
+ }
+ rule 3425 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-148.253.173.246
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 148.253.173.246
+ }
+ }
+ rule 3426 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-195.97.222.122
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 195.97.222.122
+ }
+ }
+ rule 3431 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.111
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.111
+ }
+ }
+ rule 3432 {
+ action accept
+ description FW06940_3-TCP_UDP-ALLOW-74.208.41.119
+ destination {
+ group {
+ address-group DT_FW06940_3
+ }
+ port 1-65535
+ }
+ protocol tcp_udp
+ source {
+ address 74.208.41.119
+ }
+ }
+ rule 3438 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.252
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.252
+ }
+ }
+ rule 3440 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.118
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.118
+ }
+ }
+ rule 3442 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.15
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.15
+ }
+ }
+ rule 3446 {
+ action accept
+ description FWC32BE_1-ANY-ALLOW-3.65.3.75
+ destination {
+ group {
+ address-group DT_FWC32BE_1
+ }
+ }
+ source {
+ address 3.65.3.75
+ }
+ }
+ rule 3447 {
+ action accept
+ description FWC32BE_1-TCP-ALLOW-217.155.2.52
+ destination {
+ group {
+ address-group DT_FWC32BE_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 217.155.2.52
+ }
+ }
+ rule 3448 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.243
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.243
+ }
+ }
+ rule 3449 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.117
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.117
+ }
+ }
+ rule 3450 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.4
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.4
+ }
+ }
+ rule 3452 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.177
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.177
+ }
+ }
+ rule 3454 {
+ action accept
+ description FWD498E_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD498E_1
+ }
+ port 44158
+ }
+ protocol tcp
+ }
+ rule 3455 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.147
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.147
+ }
+ }
+ rule 8500 {
+ action drop
+ description "Deny traffic to any private address"
+ destination {
+ group {
+ network-group RFC1918
+ }
+ }
+ source {
+ group {
+ address-group CLUSTER_ADDRESSES
+ }
+ }
+ }
+ rule 8510 {
+ action accept
+ description "Default allow rule"
+ destination {
+ group {
+ address-group !CLUSTER_ADDRESSES
+ }
+ }
+ source {
+ group {
+ address-group CLUSTER_ADDRESSES
+ }
+ }
+ }
+ }
+ name LOCAL-LAN {
+ default-action drop
+ rule 2 {
+ action accept
+ destination {
+ address 10.255.255.1
+ }
+ protocol icmp
+ source {
+ group {
+ address-group CLUSTER_ADDRESSES
+ }
+ }
+ }
+ rule 4 {
+ action accept
+ destination {
+ group {
+ address-group LAN_ADDRESSES
+ }
+ }
+ source {
+ group {
+ address-group LAN_ADDRESSES
+ }
+ }
+ }
+ rule 10 {
+ action accept
+ description "Multicast para VRRP"
+ destination {
+ address 224.0.0.18
+ }
+ source {
+ group {
+ address-group LAN_ADDRESSES
+ }
+ }
+ }
+ }
+ name LOCAL-SYNC {
+ default-action drop
+ rule 5 {
+ action accept
+ description "Permitir trafico sync entre nodos"
+ destination {
+ address 10.4.51.132/30
+ }
+ source {
+ address 10.4.51.132/30
+ }
+ }
+ }
+ name LOCAL-WAN {
+ default-action drop
+ description "External connections from VLAN2701 to this system"
+ rule 10 {
+ action accept
+ description "Allow intra-vlan connections"
+ destination {
+ address 109.228.63.128/25
+ }
+ source {
+ address 109.228.63.128/25
+ }
+ }
+ rule 20 {
+ action accept
+ description "Allow Arsys desktops to contact this system"
+ source {
+ group {
+ address-group MANAGEMENT_ADDRESSES
+ }
+ }
+ }
+ }
+ name WAN-INBOUND {
+ default-action drop
+ rule 10 {
+ action accept
+ description "Management from HN-ES"
+ source {
+ group {
+ address-group MANAGEMENT_ADDRESSES
+ }
+ }
+ }
+ rule 20 {
+ action accept
+ description "Connections from Load Balancer to Frontends - TCP Proxy"
+ destination {
+ group {
+ address-group CLUSTER_ADDRESSES
+ }
+ }
+ source {
+ group {
+ address-group NLB_ADDRESSES
+ }
+ }
+ }
+ rule 30 {
+ action accept
+ description "Allow external probes"
+ destination {
+ group {
+ address-group NAGIOS_PROBES
+ }
+ }
+ protocol icmp
+ }
+ rule 40 {
+ action accept
+ description "Allow Centreon servers traffic to VMs"
+ destination {
+ group {
+ address-group CLUSTER_ADDRESSES
+ }
+ }
+ source {
+ group {
+ address-group CENTREON_SERVERS
+ }
+ }
+ }
+ rule 50 {
+ action accept
+ description "Allow CMK to check dnscache servers - TCP"
+ destination {
+ group {
+ address-group DNSCACHE_SERVERS
+ }
+ port 22,53,6556
+ }
+ protocol tcp
+ source {
+ group {
+ address-group CMK_SATELLITES
+ }
+ }
+ }
+ rule 65 {
+ action accept
+ description "Allow CMK to check dnscache servers - UDP"
+ destination {
+ group {
+ address-group DNSCACHE_SERVERS
+ }
+ port 53
+ }
+ protocol udp
+ source {
+ group {
+ address-group CMK_SATELLITES
+ }
+ }
+ }
+ rule 70 {
+ action accept
+ description "Allow CMK to check dnscache servers - ICMP"
+ destination {
+ group {
+ address-group DNSCACHE_SERVERS
+ }
+ }
+ protocol icmp
+ source {
+ group {
+ address-group CMK_SATELLITES
+ }
+ }
+ }
+ rule 80 {
+ action accept
+ description "Allow CMK to check monitoring sensors - TCP"
+ destination {
+ group {
+ address-group NAGIOS_PROBES
+ }
+ port 6556
+ }
+ protocol tcp
+ source {
+ group {
+ address-group CMK_SATELLITES
+ }
+ }
+ }
+ rule 90 {
+ action accept
+ description "Allow CMK to check monitoring sensors - ICMP"
+ destination {
+ group {
+ address-group NAGIOS_PROBES
+ }
+ }
+ protocol icmp
+ source {
+ group {
+ address-group CMK_SATELLITES
+ }
+ }
+ }
+ rule 2000 {
+ action accept
+ description "TOP port - SSH"
+ destination {
+ group {
+ address-group G-22-TCP
+ }
+ port ssh
+ }
+ protocol tcp
+ }
+ rule 2001 {
+ action accept
+ description "TOP port - RDESKTOP"
+ destination {
+ group {
+ address-group G-3389-TCP
+ }
+ port 3389
+ }
+ protocol tcp
+ }
+ rule 2002 {
+ action accept
+ description "TOP port - HTTP"
+ destination {
+ group {
+ address-group G-80-TCP
+ }
+ port http
+ }
+ protocol tcp
+ }
+ rule 2003 {
+ action accept
+ description "TOP port - HTTPS"
+ destination {
+ group {
+ address-group G-443-TCP
+ }
+ port https
+ }
+ protocol tcp
+ }
+ rule 2004 {
+ action accept
+ description "TOP port - DOMAIN TCP"
+ destination {
+ group {
+ address-group G-53-TCP
+ }
+ port domain
+ }
+ protocol tcp
+ }
+ rule 2005 {
+ action accept
+ description "TOP port - DOMAIN UDP"
+ destination {
+ group {
+ address-group G-53-UDP
+ }
+ port domain
+ }
+ protocol udp
+ }
+ rule 2006 {
+ action accept
+ description "TOP port - SMTP"
+ destination {
+ group {
+ address-group G-25-TCP
+ }
+ port smtp
+ }
+ protocol tcp
+ }
+ rule 2007 {
+ action accept
+ description "TOP port - IMAP"
+ destination {
+ group {
+ address-group G-143-TCP
+ }
+ port imap2
+ }
+ protocol tcp
+ }
+ rule 2008 {
+ action accept
+ description "TOP port - POP3"
+ destination {
+ group {
+ address-group G-110-TCP
+ }
+ port pop3
+ }
+ protocol tcp
+ }
+ rule 2009 {
+ action accept
+ description "TOP port - MSSQL TCP"
+ destination {
+ group {
+ address-group G-1433-TCP
+ }
+ port ms-sql-s
+ }
+ protocol tcp
+ }
+ rule 2010 {
+ action accept
+ description "TOP port - MYSQL TCP"
+ destination {
+ group {
+ address-group G-3306-TCP
+ }
+ port mysql
+ }
+ protocol tcp
+ }
+ rule 2011 {
+ action accept
+ description "TOP port - FTPDATA"
+ destination {
+ group {
+ address-group G-20-TCP
+ }
+ port ftp-data
+ }
+ protocol tcp
+ }
+ rule 2012 {
+ action accept
+ description "TOP port - FTP"
+ destination {
+ group {
+ address-group G-21-TCP
+ }
+ port ftp
+ }
+ protocol tcp
+ }
+ rule 2013 {
+ action accept
+ description "TOP port - SSMTP"
+ destination {
+ group {
+ address-group G-465-TCP
+ }
+ port ssmtp
+ }
+ protocol tcp
+ }
+ rule 2014 {
+ action accept
+ description "TOP port - SMTPS"
+ destination {
+ group {
+ address-group G-587-TCP
+ }
+ port 587
+ }
+ protocol tcp
+ }
+ rule 2015 {
+ action accept
+ description "TOP port - IMAPS"
+ destination {
+ group {
+ address-group G-993-TCP
+ }
+ port imaps
+ }
+ protocol tcp
+ }
+ rule 2016 {
+ action accept
+ description "TOP port - POP3S"
+ destination {
+ group {
+ address-group G-995-TCP
+ }
+ port pop3s
+ }
+ protocol tcp
+ }
+ rule 2017 {
+ action accept
+ description "TOP port - TOMCAT"
+ destination {
+ group {
+ address-group G-8080-TCP
+ }
+ port 8080
+ }
+ protocol tcp
+ }
+ rule 2018 {
+ action accept
+ description "TOP port - Alternative HTTPS"
+ destination {
+ group {
+ address-group G-8443-TCP
+ }
+ port 8443
+ }
+ protocol tcp
+ }
+ rule 2019 {
+ action accept
+ description "TOP port - 10000/TCP"
+ destination {
+ group {
+ address-group G-10000-TCP
+ }
+ port 10000
+ }
+ protocol tcp
+ }
+ rule 2020 {
+ action accept
+ description "TOP port - 8447/TCP"
+ destination {
+ group {
+ address-group G-8447-TCP
+ }
+ port 8447
+ }
+ protocol tcp
+ }
+ rule 2040 {
+ action accept
+ description "TOP port - All ports open"
+ destination {
+ group {
+ address-group G-ALL_OPEN
+ }
+ }
+ }
+ rule 2050 {
+ action accept
+ description "ICMP group"
+ destination {
+ group {
+ address-group G-ICMP
+ }
+ }
+ protocol icmp
+ }
+ rule 2100 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-104.192.143.2
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 7999,22
+ }
+ protocol tcp
+ source {
+ address 104.192.143.2
+ }
+ }
+ rule 2101 {
+ action accept
+ description FW19987_4-TCP-ALLOW-77.68.74.54
+ destination {
+ group {
+ address-group DT_FW19987_4
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 77.68.74.54
+ }
+ }
+ rule 2102 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-109.72.210.46
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 109.72.210.46
+ }
+ }
+ rule 2103 {
+ action accept
+ description FW5A77C_16-TCP-ALLOW-213.171.217.107
+ destination {
+ group {
+ address-group DT_FW5A77C_16
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.107
+ }
+ }
+ rule 2104 {
+ action accept
+ description FW826BA_3-TCP-ALLOW-164.177.156.192
+ destination {
+ group {
+ address-group DT_FW826BA_3
+ }
+ port 3389,1433,21
+ }
+ protocol tcp
+ source {
+ address 164.177.156.192
+ }
+ }
+ rule 2105 {
+ action accept
+ description FWDAA4F_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWDAA4F_1
+ }
+ port 22335
+ }
+ protocol tcp
+ }
+ rule 2106 {
+ action accept
+ description FW6D0CD_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6D0CD_1
+ }
+ port 6900,7000
+ }
+ protocol tcp
+ }
+ rule 2107 {
+ action accept
+ description FW6D0CD_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6D0CD_1
+ }
+ port 9001
+ }
+ protocol tcp_udp
+ }
+ rule 2108 {
+ action accept
+ description FW06176_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW06176_1
+ }
+ port 5900
+ }
+ protocol tcp
+ }
+ rule 2109 {
+ action accept
+ description FW19987_4-TCP-ALLOW-77.68.77.70
+ destination {
+ group {
+ address-group DT_FW19987_4
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 77.68.77.70
+ }
+ }
+ rule 2110 {
+ action accept
+ description FWF7B68_1-TCP-ALLOW-54.221.251.224
+ destination {
+ group {
+ address-group DT_FWF7B68_1
+ }
+ port 8443,3306,22,21,20
+ }
+ protocol tcp
+ source {
+ address 54.221.251.224
+ }
+ }
+ rule 2111 {
+ action accept
+ description FW05AD0_2-TCP-ALLOW-178.251.181.41
+ destination {
+ group {
+ address-group DT_FW05AD0_2
+ }
+ port 3389,1433,21
+ }
+ protocol tcp
+ source {
+ address 178.251.181.41
+ }
+ }
+ rule 2112 {
+ action accept
+ description FW05AD0_2-TCP-ALLOW-178.251.181.6
+ destination {
+ group {
+ address-group DT_FW05AD0_2
+ }
+ port 3389,1433,21
+ }
+ protocol tcp
+ source {
+ address 178.251.181.6
+ }
+ }
+ rule 2113 {
+ action accept
+ description VPN-7030-ANY-ALLOW-10.4.58.119
+ destination {
+ group {
+ address-group DT_VPN-7030
+ }
+ }
+ source {
+ address 10.4.58.119
+ }
+ }
+ rule 2114 {
+ action accept
+ description FW58C69_4-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW58C69_4
+ }
+ port 5666
+ }
+ protocol tcp
+ }
+ rule 2115 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-185.201.180.35
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 27017,5000,22
+ }
+ protocol tcp
+ source {
+ address 185.201.180.35
+ }
+ }
+ rule 2116 {
+ action accept
+ description FW19987_4-TCP-ALLOW-77.68.8.74
+ destination {
+ group {
+ address-group DT_FW19987_4
+ }
+ port 3389,445,443
+ }
+ protocol tcp
+ source {
+ address 77.68.8.74
+ }
+ }
+ rule 2117 {
+ action accept
+ description FW19987_4-TCP-ALLOW-87.224.33.215
+ destination {
+ group {
+ address-group DT_FW19987_4
+ }
+ port 3389,445,443
+ }
+ protocol tcp
+ source {
+ address 87.224.33.215
+ }
+ }
+ rule 2118 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-212.159.160.65
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 8443,3389,3306,22,21
+ }
+ protocol tcp
+ source {
+ address 212.159.160.65
+ }
+ }
+ rule 2119 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-79.78.20.149
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 8447,8443,3389,3306,993,143,22,21
+ }
+ protocol tcp
+ source {
+ address 79.78.20.149
+ }
+ }
+ rule 2120 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-77.68.77.185
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 77.68.77.185
+ }
+ }
+ rule 2121 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-82.165.232.19
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 8443,3389
+ }
+ protocol tcp
+ source {
+ address 82.165.232.19
+ }
+ }
+ rule 2122 {
+ action accept
+ description FW2C5AE_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2C5AE_1
+ }
+ port 30303,5717
+ }
+ protocol tcp_udp
+ }
+ rule 2123 {
+ action accept
+ description VPN-12899-ANY-ALLOW-10.4.58.207
+ destination {
+ group {
+ address-group DT_VPN-12899
+ }
+ }
+ source {
+ address 10.4.58.207
+ }
+ }
+ rule 2124 {
+ action accept
+ description FW7648D_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW7648D_1
+ }
+ port 8501,8050,7801,4444,1443
+ }
+ protocol tcp
+ }
+ rule 2125 {
+ action accept
+ description FW0C2E6_4-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0C2E6_4
+ }
+ port 1194
+ }
+ protocol udp
+ }
+ rule 2126 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-39.37.175.132
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 39.37.175.132
+ }
+ }
+ rule 2127 {
+ action accept
+ description FW826BA_3-TCP-ALLOW-165.255.242.223
+ destination {
+ group {
+ address-group DT_FW826BA_3
+ }
+ port 3389,1433,21
+ }
+ protocol tcp
+ source {
+ address 165.255.242.223
+ }
+ }
+ rule 2128 {
+ action accept
+ description VPN-10131-ANY-ALLOW-10.4.56.51
+ destination {
+ group {
+ address-group DT_VPN-10131
+ }
+ }
+ source {
+ address 10.4.56.51
+ }
+ }
+ rule 2129 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-212.227.84.142
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 212.227.84.142
+ }
+ }
+ rule 2130 {
+ action accept
+ description FW2BB8D_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 2131 {
+ action accept
+ description FWFDD94_15-TCP-ALLOW-90.29.180.234
+ destination {
+ group {
+ address-group DT_FWFDD94_15
+ }
+ port 5683,1883
+ }
+ protocol tcp
+ source {
+ address 90.29.180.234
+ }
+ }
+ rule 2132 {
+ action accept
+ description VPN-10131-ANY-ALLOW-10.4.57.51
+ destination {
+ group {
+ address-group DT_VPN-10131
+ }
+ }
+ source {
+ address 10.4.57.51
+ }
+ }
+ rule 2133 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-109.228.49.193
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 5000
+ }
+ protocol tcp
+ source {
+ address 109.228.49.193
+ }
+ }
+ rule 2134 {
+ action accept
+ description FW81138_1-ICMP-ALLOW-3.10.221.168
+ destination {
+ group {
+ address-group DT_FW81138_1
+ }
+ }
+ protocol icmp
+ source {
+ address 3.10.221.168
+ }
+ }
+ rule 2135 {
+ action accept
+ description FWB28B6_5-AH-ALLOW-77.68.36.46
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ }
+ protocol ah
+ source {
+ address 77.68.36.46
+ }
+ }
+ rule 2136 {
+ action accept
+ description FWB28B6_5-ESP-ALLOW-77.68.36.46
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ }
+ protocol esp
+ source {
+ address 77.68.36.46
+ }
+ }
+ rule 2137 {
+ action accept
+ description FW825C8_24-TCP-ALLOW-77.68.87.201
+ destination {
+ group {
+ address-group DT_FW825C8_24
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 77.68.87.201
+ }
+ }
+ rule 2138 {
+ action accept
+ description FWB28B6_5-AH-ALLOW-213.171.196.146
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ }
+ protocol ah
+ source {
+ address 213.171.196.146
+ }
+ }
+ rule 2139 {
+ action accept
+ description FWB28B6_5-ESP-ALLOW-213.171.196.146
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ }
+ protocol esp
+ source {
+ address 213.171.196.146
+ }
+ }
+ rule 2140 {
+ action accept
+ description FWB28B6_5-UDP-ALLOW-213.171.196.146
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ port 500,4500
+ }
+ protocol udp
+ source {
+ address 213.171.196.146
+ }
+ }
+ rule 2141 {
+ action accept
+ description FWB28B6_5-TCP_UDP-ALLOW-213.171.196.146
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ port 1701
+ }
+ protocol tcp_udp
+ source {
+ address 213.171.196.146
+ }
+ }
+ rule 2142 {
+ action accept
+ description FWB28B6_5-TCP_UDP-ALLOW-77.68.36.46
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ port 1701
+ }
+ protocol tcp_udp
+ source {
+ address 77.68.36.46
+ }
+ }
+ rule 2143 {
+ action accept
+ description FWB28B6_5-UDP-ALLOW-77.68.36.46
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ port 500,4500
+ }
+ protocol udp
+ source {
+ address 77.68.36.46
+ }
+ }
+ rule 2144 {
+ action accept
+ description VPN-12899-ANY-ALLOW-10.4.59.207
+ destination {
+ group {
+ address-group DT_VPN-12899
+ }
+ }
+ source {
+ address 10.4.59.207
+ }
+ }
+ rule 2145 {
+ action accept
+ description FWB28B6_5-TCP-ALLOW-81.130.141.175
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 81.130.141.175
+ }
+ }
+ rule 2146 {
+ action accept
+ description FWB28B6_5-UDP-ALLOW-77.68.38.195
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ port 4500,500
+ }
+ protocol udp
+ source {
+ address 77.68.38.195
+ }
+ }
+ rule 2147 {
+ action accept
+ description FWB28B6_5-AH-ALLOW-77.68.38.195
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ }
+ protocol ah
+ source {
+ address 77.68.38.195
+ }
+ }
+ rule 2148 {
+ action accept
+ description FWB28B6_5-ESP-ALLOW-77.68.38.195
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ }
+ protocol esp
+ source {
+ address 77.68.38.195
+ }
+ }
+ rule 2149 {
+ action accept
+ description FWB28B6_5-TCP_UDP-ALLOW-77.68.38.195
+ destination {
+ group {
+ address-group DT_FWB28B6_5
+ }
+ port 1701
+ }
+ protocol tcp_udp
+ source {
+ address 77.68.38.195
+ }
+ }
+ rule 2150 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-39.37.178.77
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 39.37.178.77
+ }
+ }
+ rule 2151 {
+ action accept
+ description FW5A77C_16-TCP-ALLOW-51.241.139.56
+ destination {
+ group {
+ address-group DT_FW5A77C_16
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 51.241.139.56
+ }
+ }
+ rule 2152 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-150.143.57.138
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 150.143.57.138
+ }
+ }
+ rule 2153 {
+ action accept
+ description FW6ECA4_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6ECA4_1
+ }
+ port 3939,3335,3334,3333,3000,999,444
+ }
+ protocol tcp_udp
+ }
+ rule 2154 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-39.45.13.20
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 39.45.13.20
+ }
+ }
+ rule 2155 {
+ action accept
+ description FW481D7_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW481D7_1
+ }
+ port 3478
+ }
+ protocol tcp_udp
+ }
+ rule 2156 {
+ action accept
+ description FW5A5D7_3-GRE-ALLOW-51.219.222.28
+ destination {
+ group {
+ address-group DT_FW5A5D7_3
+ }
+ }
+ protocol gre
+ source {
+ address 51.219.222.28
+ }
+ }
+ rule 2157 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-94.195.127.217
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389,443
+ }
+ protocol tcp
+ source {
+ address 94.195.127.217
+ }
+ }
+ rule 2158 {
+ action accept
+ description FW2E060_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2E060_1
+ }
+ port 49152-65535,8443-8447
+ }
+ protocol tcp
+ }
+ rule 2159 {
+ action accept
+ description FWFDD94_15-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWFDD94_15
+ }
+ port 9090,5080,1935
+ }
+ protocol tcp
+ }
+ rule 2160 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-39.45.190.224
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 39.45.190.224
+ }
+ }
+ rule 2161 {
+ action accept
+ description FW9E550_1-TCP-ALLOW-109.249.187.56
+ destination {
+ group {
+ address-group DT_FW9E550_1
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 109.249.187.56
+ }
+ }
+ rule 2162 {
+ action accept
+ description FW89619_1-TCP-ALLOW-81.133.80.114
+ destination {
+ group {
+ address-group DT_FW89619_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 81.133.80.114
+ }
+ }
+ rule 2163 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-212.227.72.218
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 212.227.72.218
+ }
+ }
+ rule 2164 {
+ action accept
+ description FW0E383_9-TCP-ALLOW-151.229.59.51
+ destination {
+ group {
+ address-group DT_FW0E383_9
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 151.229.59.51
+ }
+ }
+ rule 2165 {
+ action accept
+ description FW8AFF1_7-TCP-ALLOW-178.251.181.41
+ destination {
+ group {
+ address-group DT_FW8AFF1_7
+ }
+ port 1433,21
+ }
+ protocol tcp
+ source {
+ address 178.251.181.41
+ }
+ }
+ rule 2166 {
+ action accept
+ description FW3CAAB_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW3CAAB_1
+ }
+ port 49152-65535,30000-30400,8443-8447,5432,80-110,21-25
+ }
+ protocol tcp
+ }
+ rule 2167 {
+ action accept
+ description FW91B7A_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW91B7A_1
+ }
+ port 3389,80
+ }
+ protocol tcp_udp
+ }
+ rule 2168 {
+ action accept
+ description FW40416_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW40416_1
+ }
+ port 1-65535
+ }
+ protocol tcp
+ }
+ rule 2169 {
+ action accept
+ description FW5A77C_16-TCP-ALLOW-81.151.24.216
+ destination {
+ group {
+ address-group DT_FW5A77C_16
+ }
+ port 10000,22
+ }
+ protocol tcp
+ source {
+ address 81.151.24.216
+ }
+ }
+ rule 2170 {
+ action accept
+ description VPN-7030-ANY-ALLOW-10.4.59.119
+ destination {
+ group {
+ address-group DT_VPN-7030
+ }
+ }
+ source {
+ address 10.4.59.119
+ }
+ }
+ rule 2171 {
+ action accept
+ description FW0E383_9-TCP-ALLOW-62.252.94.138
+ destination {
+ group {
+ address-group DT_FW0E383_9
+ }
+ port 3389,1433
+ }
+ protocol tcp
+ source {
+ address 62.252.94.138
+ }
+ }
+ rule 2172 {
+ action accept
+ description FW89619_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW89619_1
+ }
+ port 5015,5001,5000
+ }
+ protocol tcp
+ }
+ rule 2173 {
+ action accept
+ description FW89619_1-TCP_UDP-ALLOW-167.98.162.142
+ destination {
+ group {
+ address-group DT_FW89619_1
+ }
+ port 5060
+ }
+ protocol tcp_udp
+ source {
+ address 167.98.162.142
+ }
+ }
+ rule 2174 {
+ action accept
+ description FW013EF_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW013EF_2
+ }
+ port 44445,7770-7800,5090,5060-5070,5015,5001,2000-2500
+ }
+ protocol tcp
+ }
+ rule 2175 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.12
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.12
+ }
+ }
+ rule 2176 {
+ action accept
+ description VPN-15625-ANY-ALLOW-10.4.88.79
+ destination {
+ group {
+ address-group DT_VPN-15625
+ }
+ }
+ source {
+ address 10.4.88.79
+ }
+ }
+ rule 2177 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-109.228.53.128
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306,22
+ }
+ protocol tcp
+ source {
+ address 109.228.53.128
+ }
+ }
+ rule 2178 {
+ action accept
+ description FW8AFF1_7-TCP-ALLOW-178.251.181.6
+ destination {
+ group {
+ address-group DT_FW8AFF1_7
+ }
+ port 3389,1433,21
+ }
+ protocol tcp
+ source {
+ address 178.251.181.6
+ }
+ }
+ rule 2179 {
+ action accept
+ description FW578BE_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW578BE_1
+ }
+ port 23,1521,1522
+ }
+ protocol tcp
+ }
+ rule 2180 {
+ action accept
+ description FWE012D_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE012D_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2181 {
+ action accept
+ description FW8AFF1_7-TCP-ALLOW-213.171.209.161
+ destination {
+ group {
+ address-group DT_FW8AFF1_7
+ }
+ port 3389,1433,21
+ }
+ protocol tcp
+ source {
+ address 213.171.209.161
+ }
+ }
+ rule 2182 {
+ action accept
+ description VPN-8203-ANY-ALLOW-10.4.58.109
+ destination {
+ group {
+ address-group DT_VPN-8203
+ }
+ }
+ source {
+ address 10.4.58.109
+ }
+ }
+ rule 2183 {
+ action accept
+ description VPN-9415-ANY-ALLOW-10.4.58.168
+ destination {
+ group {
+ address-group DT_VPN-9415
+ }
+ }
+ source {
+ address 10.4.58.168
+ }
+ }
+ rule 2184 {
+ action accept
+ description VPN-9415-ANY-ALLOW-10.4.59.168
+ destination {
+ group {
+ address-group DT_VPN-9415
+ }
+ }
+ source {
+ address 10.4.59.168
+ }
+ }
+ rule 2185 {
+ action accept
+ description FW27A8F_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW27A8F_1
+ }
+ port 9990,8458,8090,6543,5432
+ }
+ protocol tcp
+ }
+ rule 2186 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-77.68.11.224
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 5000
+ }
+ protocol tcp
+ source {
+ address 77.68.11.224
+ }
+ }
+ rule 2187 {
+ action accept
+ description VPN-15625-ANY-ALLOW-10.4.89.79
+ destination {
+ group {
+ address-group DT_VPN-15625
+ }
+ }
+ source {
+ address 10.4.89.79
+ }
+ }
+ rule 2188 {
+ action accept
+ description VPN-14649-ANY-ALLOW-10.4.86.35
+ destination {
+ group {
+ address-group DT_VPN-14649
+ }
+ }
+ source {
+ address 10.4.86.35
+ }
+ }
+ rule 2189 {
+ action accept
+ description VPN-14649-ANY-ALLOW-10.4.87.35
+ destination {
+ group {
+ address-group DT_VPN-14649
+ }
+ }
+ source {
+ address 10.4.87.35
+ }
+ }
+ rule 2190 {
+ action accept
+ description VPN-14657-ANY-ALLOW-10.4.86.38
+ destination {
+ group {
+ address-group DT_VPN-14657
+ }
+ }
+ source {
+ address 10.4.86.38
+ }
+ }
+ rule 2191 {
+ action accept
+ description VPN-14657-ANY-ALLOW-10.4.87.38
+ destination {
+ group {
+ address-group DT_VPN-14657
+ }
+ }
+ source {
+ address 10.4.87.38
+ }
+ }
+ rule 2192 {
+ action accept
+ description VPN-14658-ANY-ALLOW-10.4.88.38
+ destination {
+ group {
+ address-group DT_VPN-14658
+ }
+ }
+ source {
+ address 10.4.88.38
+ }
+ }
+ rule 2193 {
+ action accept
+ description VPN-14658-ANY-ALLOW-10.4.89.38
+ destination {
+ group {
+ address-group DT_VPN-14658
+ }
+ }
+ source {
+ address 10.4.89.38
+ }
+ }
+ rule 2194 {
+ action accept
+ description FW0BB22_1-GRE-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0BB22_1
+ }
+ }
+ protocol gre
+ }
+ rule 2195 {
+ action accept
+ description FW0BB22_1-ESP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0BB22_1
+ }
+ }
+ protocol esp
+ }
+ rule 2196 {
+ action accept
+ description FW1CC15_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1CC15_2
+ }
+ port 8089,8085,990,81
+ }
+ protocol tcp
+ }
+ rule 2197 {
+ action accept
+ description FW8AFF1_7-TCP-ALLOW-109.228.0.124
+ destination {
+ group {
+ address-group DT_FW8AFF1_7
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 109.228.0.124
+ }
+ }
+ rule 2198 {
+ action accept
+ description FW5A5D7_3-TCP-ALLOW-51.219.222.28
+ destination {
+ group {
+ address-group DT_FW5A5D7_3
+ }
+ port 8172,3389,1723,1701,47
+ }
+ protocol tcp
+ source {
+ address 51.219.222.28
+ }
+ }
+ rule 2199 {
+ action accept
+ description FW1CB16_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1CB16_1
+ }
+ port 3306,27017,53
+ }
+ protocol tcp_udp
+ }
+ rule 2200 {
+ action accept
+ description FWE47DA_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE47DA_1
+ }
+ port 7770-7800,44445
+ }
+ protocol tcp
+ }
+ rule 2201 {
+ action accept
+ description FW37E59_5-TCP-ALLOW-77.68.20.244
+ destination {
+ group {
+ address-group DT_FW37E59_5
+ }
+ port 30303
+ }
+ protocol tcp
+ source {
+ address 77.68.20.244
+ }
+ }
+ rule 2202 {
+ action accept
+ description FW274FD_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW274FD_1
+ }
+ port 49152-65534
+ }
+ protocol tcp
+ }
+ rule 2203 {
+ action accept
+ description FW6CD7E_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6CD7E_2
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2204 {
+ action accept
+ description FW826BA_3-TCP-ALLOW-178.17.252.59
+ destination {
+ group {
+ address-group DT_FW826BA_3
+ }
+ port 21
+ }
+ protocol tcp
+ source {
+ address 178.17.252.59
+ }
+ }
+ rule 2205 {
+ action accept
+ description FW89619_1-TCP_UDP-ALLOW-185.83.64.108
+ destination {
+ group {
+ address-group DT_FW89619_1
+ }
+ port 5060
+ }
+ protocol tcp_udp
+ source {
+ address 185.83.64.108
+ }
+ }
+ rule 2206 {
+ action accept
+ description FW0937A_1-TCP-ALLOW-83.135.134.13
+ destination {
+ group {
+ address-group DT_FW0937A_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 83.135.134.13
+ }
+ }
+ rule 2207 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-77.68.112.64
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 27017,5000
+ }
+ protocol tcp
+ source {
+ address 77.68.112.64
+ }
+ }
+ rule 2208 {
+ action accept
+ description FW6CD7E_2-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6CD7E_2
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 2209 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-194.73.17.47
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306,22
+ }
+ protocol tcp
+ source {
+ address 194.73.17.47
+ }
+ }
+ rule 2210 {
+ action accept
+ description FW0E383_9-TCP-ALLOW-77.68.115.33
+ destination {
+ group {
+ address-group DT_FW0E383_9
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 77.68.115.33
+ }
+ }
+ rule 2211 {
+ action accept
+ description FWA3EA3_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA3EA3_1
+ }
+ port 943
+ }
+ protocol tcp
+ }
+ rule 2212 {
+ action accept
+ description FW6863A_4-TCP-ALLOW-82.165.100.25
+ destination {
+ group {
+ address-group DT_FW6863A_4
+ }
+ port 21-10000
+ }
+ protocol tcp
+ source {
+ address 82.165.100.25
+ }
+ }
+ rule 2213 {
+ action accept
+ description FWECBFB_14-TCP-ALLOW-109.228.59.50
+ destination {
+ group {
+ address-group DT_FWECBFB_14
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 109.228.59.50
+ }
+ }
+ rule 2214 {
+ action accept
+ description FW2F868_6-TCP-ALLOW-213.171.217.100
+ destination {
+ group {
+ address-group DT_FW2F868_6
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.100
+ }
+ }
+ rule 2215 {
+ action accept
+ description FWD7EAB_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD7EAB_1
+ }
+ port 60000-60100
+ }
+ protocol tcp
+ }
+ rule 2216 {
+ action accept
+ description FWEB321_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWEB321_1
+ }
+ port 113,4190
+ }
+ protocol tcp
+ }
+ rule 2217 {
+ action accept
+ description FW9C682_3-TCP-ALLOW-195.206.180.132
+ destination {
+ group {
+ address-group DT_FW9C682_3
+ }
+ port 8443,22
+ }
+ protocol tcp
+ source {
+ address 195.206.180.132
+ }
+ }
+ rule 2218 {
+ action accept
+ description VPN-8159-ANY-ALLOW-10.4.58.91
+ destination {
+ group {
+ address-group DT_VPN-8159
+ }
+ }
+ source {
+ address 10.4.58.91
+ }
+ }
+ rule 2219 {
+ action accept
+ description VPN-21673-ANY-ALLOW-10.4.88.187
+ destination {
+ group {
+ address-group DT_VPN-21673
+ }
+ }
+ source {
+ address 10.4.88.187
+ }
+ }
+ rule 2220 {
+ action accept
+ description VPN-21673-ANY-ALLOW-10.4.89.187
+ destination {
+ group {
+ address-group DT_VPN-21673
+ }
+ }
+ source {
+ address 10.4.89.187
+ }
+ }
+ rule 2221 {
+ action accept
+ description VPN-21821-ANY-ALLOW-10.4.88.49
+ destination {
+ group {
+ address-group DT_VPN-21821
+ }
+ }
+ source {
+ address 10.4.88.49
+ }
+ }
+ rule 2222 {
+ action accept
+ description VPN-21821-ANY-ALLOW-10.4.89.49
+ destination {
+ group {
+ address-group DT_VPN-21821
+ }
+ }
+ source {
+ address 10.4.89.49
+ }
+ }
+ rule 2223 {
+ action accept
+ description FWECBFB_14-TCP-ALLOW-81.133.80.58
+ destination {
+ group {
+ address-group DT_FWECBFB_14
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 81.133.80.58
+ }
+ }
+ rule 2224 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.238
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.238
+ }
+ }
+ rule 2225 {
+ action accept
+ description FW826BA_3-TCP-ALLOW-185.212.168.51
+ destination {
+ group {
+ address-group DT_FW826BA_3
+ }
+ port 3389,1433,21
+ }
+ protocol tcp
+ source {
+ address 185.212.168.51
+ }
+ }
+ rule 2226 {
+ action accept
+ description FW8B21D_1-ANY-ALLOW-212.187.250.2
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ }
+ source {
+ address 212.187.250.2
+ }
+ }
+ rule 2227 {
+ action accept
+ description FW35F7B_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW35F7B_1
+ }
+ port 1434
+ }
+ protocol tcp_udp
+ }
+ rule 2228 {
+ action accept
+ description FWD338A_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD338A_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2229 {
+ action accept
+ description FW35F7B_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW35F7B_1
+ }
+ port 56791
+ }
+ protocol tcp
+ }
+ rule 2230 {
+ action accept
+ description FW0E383_9-TCP-ALLOW-77.68.77.114
+ destination {
+ group {
+ address-group DT_FW0E383_9
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 77.68.77.114
+ }
+ }
+ rule 2231 {
+ action accept
+ description FW90AE3_1-TCP-ALLOW-194.74.137.17
+ destination {
+ group {
+ address-group DT_FW90AE3_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 194.74.137.17
+ }
+ }
+ rule 2232 {
+ action accept
+ description FW52F6F_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW52F6F_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 2233 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-77.68.23.109
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306,22
+ }
+ protocol tcp
+ source {
+ address 77.68.23.109
+ }
+ }
+ rule 2234 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.247
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.247
+ }
+ }
+ rule 2235 {
+ action accept
+ description FW4E314_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4E314_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 2236 {
+ action accept
+ description FW73573_2-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW73573_2
+ }
+ port 25
+ }
+ protocol tcp_udp
+ }
+ rule 2237 {
+ action accept
+ description FW0E383_9-TCP-ALLOW-77.68.93.89
+ destination {
+ group {
+ address-group DT_FW0E383_9
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 77.68.93.89
+ }
+ }
+ rule 2238 {
+ action accept
+ description FW856FA_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW856FA_1
+ }
+ port 6003
+ }
+ protocol tcp
+ }
+ rule 2239 {
+ action accept
+ description FWECBFB_14-TCP-ALLOW-81.19.214.155
+ destination {
+ group {
+ address-group DT_FWECBFB_14
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 81.19.214.155
+ }
+ }
+ rule 2240 {
+ action accept
+ description FW826BA_3-TCP-ALLOW-51.219.168.170
+ destination {
+ group {
+ address-group DT_FW826BA_3
+ }
+ port 3389,1433,21
+ }
+ protocol tcp
+ source {
+ address 51.219.168.170
+ }
+ }
+ rule 2241 {
+ action accept
+ description FW30D21_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW30D21_1
+ }
+ port 2083-2087,53,2812,2096,25,993,587
+ }
+ protocol tcp_udp
+ }
+ rule 2242 {
+ action accept
+ description FWA076E_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA076E_1
+ }
+ port 2199,2197
+ }
+ protocol tcp
+ }
+ rule 2243 {
+ action accept
+ description FWA076E_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA076E_1
+ }
+ port 8000-8010
+ }
+ protocol tcp_udp
+ }
+ rule 2244 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-82.165.166.41
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 8447,8443,443,80,22
+ }
+ protocol tcp
+ source {
+ address 82.165.166.41
+ }
+ }
+ rule 2245 {
+ action accept
+ description FW2F868_6-TCP-ALLOW-213.171.217.180
+ destination {
+ group {
+ address-group DT_FW2F868_6
+ }
+ port 22,80
+ }
+ protocol tcp
+ source {
+ address 213.171.217.180
+ }
+ }
+ rule 2246 {
+ action accept
+ description FW2F868_6-TCP-ALLOW-213.171.217.184
+ destination {
+ group {
+ address-group DT_FW2F868_6
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.184
+ }
+ }
+ rule 2247 {
+ action accept
+ description FW2F868_6-TCP-ALLOW-213.171.217.185
+ destination {
+ group {
+ address-group DT_FW2F868_6
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.185
+ }
+ }
+ rule 2248 {
+ action accept
+ description FW2F868_6-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2F868_6
+ }
+ port 161
+ }
+ protocol udp
+ }
+ rule 2249 {
+ action accept
+ description FW2F868_6-TCP-ALLOW-213.171.217.102
+ destination {
+ group {
+ address-group DT_FW2F868_6
+ }
+ port 22,24
+ }
+ protocol tcp
+ source {
+ address 213.171.217.102
+ }
+ }
+ rule 2250 {
+ action accept
+ description FW9C682_3-TCP-ALLOW-80.194.78.162
+ destination {
+ group {
+ address-group DT_FW9C682_3
+ }
+ port 8443,22
+ }
+ protocol tcp
+ source {
+ address 80.194.78.162
+ }
+ }
+ rule 2251 {
+ action accept
+ description VPN-21822-ANY-ALLOW-10.4.54.47
+ destination {
+ group {
+ address-group DT_VPN-21822
+ }
+ }
+ source {
+ address 10.4.54.47
+ }
+ }
+ rule 2252 {
+ action accept
+ description FW825C8_19-TCP-ALLOW-77.68.75.244
+ destination {
+ group {
+ address-group DT_FW825C8_19
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 77.68.75.244
+ }
+ }
+ rule 2253 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-195.147.173.92
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 8443,22
+ }
+ protocol tcp
+ source {
+ address 195.147.173.92
+ }
+ }
+ rule 2254 {
+ action accept
+ description FW1D511_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1D511_2
+ }
+ port 8090
+ }
+ protocol tcp
+ }
+ rule 2255 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-85.17.25.47
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 85.17.25.47
+ }
+ }
+ rule 2256 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-77.68.89.209
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306,22
+ }
+ protocol tcp
+ source {
+ address 77.68.89.209
+ }
+ }
+ rule 2257 {
+ action accept
+ description FWE2AB5_8-TCP-ALLOW-213.171.217.184
+ destination {
+ group {
+ address-group DT_FWE2AB5_8
+ }
+ port 7000
+ }
+ protocol tcp
+ source {
+ address 213.171.217.184
+ }
+ }
+ rule 2258 {
+ action accept
+ description FW0E383_9-TCP-ALLOW-77.68.94.177
+ destination {
+ group {
+ address-group DT_FW0E383_9
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 77.68.94.177
+ }
+ }
+ rule 2259 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-77.68.95.129
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306,22
+ }
+ protocol tcp
+ source {
+ address 77.68.95.129
+ }
+ }
+ rule 2260 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-109.104.118.136
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 109.104.118.136
+ }
+ }
+ rule 2261 {
+ action accept
+ description FW1FA9E_1-TCP-ALLOW-78.88.254.99
+ destination {
+ group {
+ address-group DT_FW1FA9E_1
+ }
+ port 9000,8200,5601,4444
+ }
+ protocol tcp
+ source {
+ address 78.88.254.99
+ }
+ }
+ rule 2262 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-175.157.46.27
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 175.157.46.27
+ }
+ }
+ rule 2263 {
+ action accept
+ description FWA7A50_1-TCP-ALLOW-81.110.192.198
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 81.110.192.198
+ }
+ }
+ rule 2264 {
+ action accept
+ description VPN-21822-ANY-ALLOW-10.4.55.47
+ destination {
+ group {
+ address-group DT_VPN-21822
+ }
+ }
+ source {
+ address 10.4.55.47
+ }
+ }
+ rule 2265 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-77.68.31.195
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 27017,5000
+ }
+ protocol tcp
+ source {
+ address 77.68.31.195
+ }
+ }
+ rule 2266 {
+ action accept
+ description FW45BEB_1-TCP-ALLOW-62.3.71.238
+ destination {
+ group {
+ address-group DT_FW45BEB_1
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 62.3.71.238
+ }
+ }
+ rule 2267 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.113
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.113
+ }
+ }
+ rule 2268 {
+ action accept
+ description VPN-23946-ANY-ALLOW-10.4.58.13
+ destination {
+ group {
+ address-group DT_VPN-23946
+ }
+ }
+ source {
+ address 10.4.58.13
+ }
+ }
+ rule 2269 {
+ action accept
+ description FW98818_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW98818_1
+ }
+ port 27015
+ }
+ protocol tcp
+ }
+ rule 2270 {
+ action accept
+ description VPN-23946-ANY-ALLOW-10.4.59.13
+ destination {
+ group {
+ address-group DT_VPN-23946
+ }
+ }
+ source {
+ address 10.4.59.13
+ }
+ }
+ rule 2271 {
+ action accept
+ description VPN-28031-ANY-ALLOW-10.4.88.197
+ destination {
+ group {
+ address-group DT_VPN-28031
+ }
+ }
+ source {
+ address 10.4.88.197
+ }
+ }
+ rule 2272 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-109.104.118.231
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 109.104.118.231
+ }
+ }
+ rule 2273 {
+ action accept
+ description FW5A5D7_3-TCP_UDP-ALLOW-51.219.222.28
+ destination {
+ group {
+ address-group DT_FW5A5D7_3
+ }
+ port 500
+ }
+ protocol tcp_udp
+ source {
+ address 51.219.222.28
+ }
+ }
+ rule 2274 {
+ action accept
+ description FW32EFF_25-TCP-ALLOW-185.106.220.231
+ destination {
+ group {
+ address-group DT_FW32EFF_25
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 185.106.220.231
+ }
+ }
+ rule 2275 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-109.104.118.66
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 109.104.118.66
+ }
+ }
+ rule 2276 {
+ action accept
+ description FW934AE_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW934AE_1
+ }
+ port 1194
+ }
+ protocol udp
+ }
+ rule 2277 {
+ action accept
+ description VPN-28031-ANY-ALLOW-10.4.89.197
+ destination {
+ group {
+ address-group DT_VPN-28031
+ }
+ }
+ source {
+ address 10.4.89.197
+ }
+ }
+ rule 2278 {
+ action accept
+ description FW6863A_4-TCP_UDP-ALLOW-82.165.166.41
+ destination {
+ group {
+ address-group DT_FW6863A_4
+ }
+ port 21-10000
+ }
+ protocol tcp_udp
+ source {
+ address 82.165.166.41
+ }
+ }
+ rule 2279 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-109.104.119.162
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 109.104.119.162
+ }
+ }
+ rule 2280 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-109.74.199.143
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 109.74.199.143
+ }
+ }
+ rule 2281 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-185.92.25.48
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 185.92.25.48
+ }
+ }
+ rule 2282 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-207.148.2.40
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 207.148.2.40
+ }
+ }
+ rule 2283 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-45.76.235.62
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 45.76.235.62
+ }
+ }
+ rule 2284 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-45.76.236.93
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 45.76.236.93
+ }
+ }
+ rule 2285 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-45.76.59.5
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 45.76.59.5
+ }
+ }
+ rule 2286 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-77.68.15.134
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 4444,3306
+ }
+ protocol tcp
+ source {
+ address 77.68.15.134
+ }
+ }
+ rule 2287 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-77.68.22.208
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 4444,3306
+ }
+ protocol tcp
+ source {
+ address 77.68.22.208
+ }
+ }
+ rule 2288 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-77.68.23.108
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 77.68.23.108
+ }
+ }
+ rule 2289 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-77.68.23.54
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 77.68.23.54
+ }
+ }
+ rule 2290 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-77.68.30.45
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 77.68.30.45
+ }
+ }
+ rule 2291 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-77.68.7.198
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 77.68.7.198
+ }
+ }
+ rule 2292 {
+ action accept
+ description VPN-29631-ANY-ALLOW-10.4.54.76
+ destination {
+ group {
+ address-group DT_VPN-29631
+ }
+ }
+ source {
+ address 10.4.54.76
+ }
+ }
+ rule 2293 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-77.68.89.200
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 4444,3306
+ }
+ protocol tcp
+ source {
+ address 77.68.89.200
+ }
+ }
+ rule 2294 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-77.68.91.50
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 77.68.91.50
+ }
+ }
+ rule 2295 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-82.165.206.230
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 82.165.206.230
+ }
+ }
+ rule 2296 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-82.165.207.109
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 4444,3306
+ }
+ protocol tcp
+ source {
+ address 82.165.207.109
+ }
+ }
+ rule 2297 {
+ action accept
+ description FW1F3D0_6-TCP-ALLOW-94.196.156.5
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 94.196.156.5
+ }
+ }
+ rule 2298 {
+ action accept
+ description FW1F3D0_6-TCP_UDP-ALLOW-77.68.15.134
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 4567-4568
+ }
+ protocol tcp_udp
+ source {
+ address 77.68.15.134
+ }
+ }
+ rule 2299 {
+ action accept
+ description FW1F3D0_6-TCP_UDP-ALLOW-77.68.22.208
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 4567-4568
+ }
+ protocol tcp_udp
+ source {
+ address 77.68.22.208
+ }
+ }
+ rule 2300 {
+ action accept
+ description FW1F3D0_6-TCP_UDP-ALLOW-77.68.23.109
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 4567-4568
+ }
+ protocol tcp_udp
+ source {
+ address 77.68.23.109
+ }
+ }
+ rule 2301 {
+ action accept
+ description FW1F3D0_6-TCP_UDP-ALLOW-77.68.89.200
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 4567-4568
+ }
+ protocol tcp_udp
+ source {
+ address 77.68.89.200
+ }
+ }
+ rule 2302 {
+ action accept
+ description FW05339_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW05339_1
+ }
+ port 8085,5055,5013,5005,444
+ }
+ protocol tcp
+ }
+ rule 2303 {
+ action accept
+ description FW32EFF_25-TCP-ALLOW-217.169.61.164
+ destination {
+ group {
+ address-group DT_FW32EFF_25
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 217.169.61.164
+ }
+ }
+ rule 2304 {
+ action accept
+ description FW89619_1-TCP_UDP-ALLOW-185.83.65.45
+ destination {
+ group {
+ address-group DT_FW89619_1
+ }
+ port 5060
+ }
+ protocol tcp_udp
+ source {
+ address 185.83.65.45
+ }
+ }
+ rule 2305 {
+ action accept
+ description VPN-13983-ANY-ALLOW-10.4.58.176
+ destination {
+ group {
+ address-group DT_VPN-13983
+ }
+ }
+ source {
+ address 10.4.58.176
+ }
+ }
+ rule 2306 {
+ action accept
+ description FWDAF47_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWDAF47_1
+ }
+ port 8090,7080,443,53
+ }
+ protocol tcp_udp
+ }
+ rule 2307 {
+ action accept
+ description VPN-29631-ANY-ALLOW-10.4.55.77
+ destination {
+ group {
+ address-group DT_VPN-29631
+ }
+ }
+ source {
+ address 10.4.55.77
+ }
+ }
+ rule 2308 {
+ action accept
+ description VPN-34309-ANY-ALLOW-10.4.58.142
+ destination {
+ group {
+ address-group DT_VPN-34309
+ }
+ }
+ source {
+ address 10.4.58.142
+ }
+ }
+ rule 2309 {
+ action accept
+ description FW27949_2-TCP-ALLOW-138.124.142.180
+ destination {
+ group {
+ address-group DT_FW27949_2
+ }
+ port 443,80
+ }
+ protocol tcp
+ source {
+ address 138.124.142.180
+ }
+ }
+ rule 2310 {
+ action accept
+ description FWF8F85_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF8F85_1
+ }
+ port 3306
+ }
+ protocol tcp_udp
+ }
+ rule 2311 {
+ action accept
+ description FWDAF47_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWDAF47_1
+ }
+ port 40110-40210
+ }
+ protocol tcp
+ }
+ rule 2312 {
+ action accept
+ description VPN-34309-ANY-ALLOW-10.4.59.142
+ destination {
+ group {
+ address-group DT_VPN-34309
+ }
+ }
+ source {
+ address 10.4.59.142
+ }
+ }
+ rule 2313 {
+ action accept
+ description FWA0531_1-TCP-ALLOW-87.224.39.220
+ destination {
+ group {
+ address-group DT_FWA0531_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 87.224.39.220
+ }
+ }
+ rule 2314 {
+ action accept
+ description FW5A5D7_3-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW5A5D7_3
+ }
+ port 1334
+ }
+ protocol tcp
+ }
+ rule 2315 {
+ action accept
+ description FW8C927_1-TCP_UDP-ALLOW-84.92.125.78
+ destination {
+ group {
+ address-group DT_FW8C927_1
+ }
+ port 3306,22
+ }
+ protocol tcp_udp
+ source {
+ address 84.92.125.78
+ }
+ }
+ rule 2316 {
+ action accept
+ description FW8C927_1-TCP_UDP-ALLOW-88.208.238.152
+ destination {
+ group {
+ address-group DT_FW8C927_1
+ }
+ port 3306,22
+ }
+ protocol tcp_udp
+ source {
+ address 88.208.238.152
+ }
+ }
+ rule 2317 {
+ action accept
+ description FW81138_1-ICMP-ALLOW-82.165.232.19
+ destination {
+ group {
+ address-group DT_FW81138_1
+ }
+ }
+ protocol icmp
+ source {
+ address 82.165.232.19
+ }
+ }
+ rule 2318 {
+ action accept
+ description FW28892_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW28892_1
+ }
+ port 7000
+ }
+ protocol tcp
+ }
+ rule 2319 {
+ action accept
+ description FWC96A1_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC96A1_1
+ }
+ port 222
+ }
+ protocol tcp
+ }
+ rule 2320 {
+ action accept
+ description VPN-13983-ANY-ALLOW-10.4.59.176
+ destination {
+ group {
+ address-group DT_VPN-13983
+ }
+ }
+ source {
+ address 10.4.59.176
+ }
+ }
+ rule 2321 {
+ action accept
+ description FW2FB61_1-TCP-ALLOW-5.183.104.15
+ destination {
+ group {
+ address-group DT_FW2FB61_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 5.183.104.15
+ }
+ }
+ rule 2322 {
+ action accept
+ description FW81138_1-ICMP-ALLOW-82.20.69.137
+ destination {
+ group {
+ address-group DT_FW81138_1
+ }
+ }
+ protocol icmp
+ source {
+ address 82.20.69.137
+ }
+ }
+ rule 2323 {
+ action accept
+ description FW72F37_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW72F37_1
+ }
+ port 7770-7800,44445
+ }
+ protocol tcp
+ }
+ rule 2324 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-81.111.155.34
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 81.111.155.34
+ }
+ }
+ rule 2325 {
+ action accept
+ description VPN-20306-ANY-ALLOW-10.4.88.173
+ destination {
+ group {
+ address-group DT_VPN-20306
+ }
+ }
+ source {
+ address 10.4.88.173
+ }
+ }
+ rule 2326 {
+ action accept
+ description FW6C992_1-TCP-ALLOW-89.33.185.0_24
+ destination {
+ group {
+ address-group DT_FW6C992_1
+ }
+ port 8447,8443,22
+ }
+ protocol tcp
+ source {
+ address 89.33.185.0/24
+ }
+ }
+ rule 2327 {
+ action accept
+ description FW2FB61_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2FB61_1
+ }
+ port 45000
+ }
+ protocol tcp
+ }
+ rule 2328 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-175.157.46.202
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 175.157.46.202
+ }
+ }
+ rule 2329 {
+ action accept
+ description FWF9C28_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF9C28_2
+ }
+ port 7770-7800,44445
+ }
+ protocol tcp
+ }
+ rule 2330 {
+ action accept
+ description FW3DBF8_9-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW3DBF8_9
+ }
+ port 8088,8080,5090,5060,3478,1935
+ }
+ protocol tcp_udp
+ }
+ rule 2331 {
+ action accept
+ description FW3DBF8_9-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW3DBF8_9
+ }
+ port 5062,5061,5015,5001
+ }
+ protocol tcp
+ }
+ rule 2332 {
+ action accept
+ description VPN-16402-ANY-ALLOW-10.4.88.60
+ destination {
+ group {
+ address-group DT_VPN-16402
+ }
+ }
+ source {
+ address 10.4.88.60
+ }
+ }
+ rule 2333 {
+ action accept
+ description FWC1315_1-TCP-ALLOW-62.3.71.238
+ destination {
+ group {
+ address-group DT_FWC1315_1
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 62.3.71.238
+ }
+ }
+ rule 2334 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 8001,80
+ }
+ protocol tcp_udp
+ }
+ rule 2335 {
+ action accept
+ description FWAFF0A_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWAFF0A_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2336 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-195.20.253.19
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 195.20.253.19
+ }
+ }
+ rule 2337 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.73
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.73
+ }
+ }
+ rule 2338 {
+ action accept
+ description VPN-16402-ANY-ALLOW-10.4.89.60
+ destination {
+ group {
+ address-group DT_VPN-16402
+ }
+ }
+ source {
+ address 10.4.89.60
+ }
+ }
+ rule 2339 {
+ action accept
+ description VPN-15951-ANY-ALLOW-10.4.86.90
+ destination {
+ group {
+ address-group DT_VPN-15951
+ }
+ }
+ source {
+ address 10.4.86.90
+ }
+ }
+ rule 2340 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-77.68.77.181
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 27017,5000
+ }
+ protocol tcp
+ source {
+ address 77.68.77.181
+ }
+ }
+ rule 2341 {
+ action accept
+ description FWE9F7D_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE9F7D_1
+ }
+ port 4035
+ }
+ protocol tcp
+ }
+ rule 2342 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.208.131
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.208.131
+ }
+ }
+ rule 2343 {
+ action accept
+ description VPN-15951-ANY-ALLOW-10.4.87.90
+ destination {
+ group {
+ address-group DT_VPN-15951
+ }
+ }
+ source {
+ address 10.4.87.90
+ }
+ }
+ rule 2344 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-77.68.93.190
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 27017,5000
+ }
+ protocol tcp
+ source {
+ address 77.68.93.190
+ }
+ }
+ rule 2345 {
+ action accept
+ description VPN-8159-ANY-ALLOW-10.4.59.91
+ destination {
+ group {
+ address-group DT_VPN-8159
+ }
+ }
+ source {
+ address 10.4.59.91
+ }
+ }
+ rule 2346 {
+ action accept
+ description VPN-12870-ANY-ALLOW-10.4.54.67
+ destination {
+ group {
+ address-group DT_VPN-12870
+ }
+ }
+ source {
+ address 10.4.54.67
+ }
+ }
+ rule 2347 {
+ action accept
+ description FW930F3_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW930F3_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 2348 {
+ action accept
+ description FW12C32_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW12C32_1
+ }
+ port 465,53,25
+ }
+ protocol tcp_udp
+ }
+ rule 2349 {
+ action accept
+ description FW28EC8_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW28EC8_1
+ }
+ port 20443
+ }
+ protocol tcp
+ }
+ rule 2350 {
+ action accept
+ description VPN-12870-ANY-ALLOW-10.4.55.68
+ destination {
+ group {
+ address-group DT_VPN-12870
+ }
+ }
+ source {
+ address 10.4.55.68
+ }
+ }
+ rule 2351 {
+ action accept
+ description FW934AE_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW934AE_1
+ }
+ port 32401,32400,8081
+ }
+ protocol tcp_udp
+ }
+ rule 2352 {
+ action accept
+ description FW6863A_4-TCP-ALLOW-185.173.161.154
+ destination {
+ group {
+ address-group DT_FW6863A_4
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 185.173.161.154
+ }
+ }
+ rule 2353 {
+ action accept
+ description FW013EF_2-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW013EF_2
+ }
+ port 10600-10998,9000-9398,5090,5060-5070
+ }
+ protocol udp
+ }
+ rule 2354 {
+ action accept
+ description FW85040_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW85040_1
+ }
+ port 3210
+ }
+ protocol tcp_udp
+ }
+ rule 2355 {
+ action accept
+ description FW8B21D_1-TCP_UDP-ALLOW-131.153.100.98
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ port 22
+ }
+ protocol tcp_udp
+ source {
+ address 131.153.100.98
+ }
+ }
+ rule 2356 {
+ action accept
+ description FW8B21D_1-TCP_UDP-ALLOW-213.133.99.176
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ port 22
+ }
+ protocol tcp_udp
+ source {
+ address 213.133.99.176
+ }
+ }
+ rule 2357 {
+ action accept
+ description FW6EFD7_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6EFD7_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2358 {
+ action accept
+ description FW8B21D_1-TCP_UDP-ALLOW-62.253.153.163
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ port 8443,22
+ }
+ protocol tcp_udp
+ source {
+ address 62.253.153.163
+ }
+ }
+ rule 2359 {
+ action accept
+ description FWCB0CF_7-TCP-ALLOW-212.159.153.201
+ destination {
+ group {
+ address-group DT_FWCB0CF_7
+ }
+ port 6443,5432-5434,5000-5100,3306-3308,990,989,22,21
+ }
+ protocol tcp
+ source {
+ address 212.159.153.201
+ }
+ }
+ rule 2360 {
+ action accept
+ description FW75CA4_6-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW75CA4_6
+ }
+ port 51472,3747,3420
+ }
+ protocol tcp
+ }
+ rule 2361 {
+ action accept
+ description FWF9C28_4-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF9C28_4
+ }
+ port 23,7770-7800,44445,6109
+ }
+ protocol tcp
+ }
+ rule 2362 {
+ action accept
+ description FW6B39D_1-TCP-ALLOW-120.72.95.88_29
+ destination {
+ group {
+ address-group DT_FW6B39D_1
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 120.72.95.88/29
+ }
+ }
+ rule 2363 {
+ action accept
+ description FW934AE_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW934AE_1
+ }
+ port 20000
+ }
+ protocol tcp
+ }
+ rule 2364 {
+ action accept
+ description FW12C32_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW12C32_1
+ }
+ port 2323,953
+ }
+ protocol tcp
+ }
+ rule 2365 {
+ action accept
+ description FW49897_1-TCP-ALLOW-2.121.90.207
+ destination {
+ group {
+ address-group DT_FW49897_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 2.121.90.207
+ }
+ }
+ rule 2366 {
+ action accept
+ description FW6B39D_1-TCP-ALLOW-120.72.91.104_29
+ destination {
+ group {
+ address-group DT_FW6B39D_1
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 120.72.91.104/29
+ }
+ }
+ rule 2367 {
+ action accept
+ description FW4F5EE_10-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4F5EE_10
+ }
+ port 83,86,82
+ }
+ protocol tcp
+ }
+ rule 2368 {
+ action accept
+ description FWF791C_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF791C_1
+ }
+ port 6001
+ }
+ protocol tcp
+ }
+ rule 2369 {
+ action accept
+ description FWEF92E_5-ESP-ALLOW-109.228.37.19
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol esp
+ source {
+ address 109.228.37.19
+ }
+ }
+ rule 2370 {
+ action accept
+ description FWE57AD_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE57AD_1
+ }
+ port 57000-58000
+ }
+ protocol tcp
+ }
+ rule 2371 {
+ action accept
+ description FWC0CE0_1-TCP-ALLOW-62.232.209.221
+ destination {
+ group {
+ address-group DT_FWC0CE0_1
+ }
+ port 49152-65535,8447,8443,22,21
+ }
+ protocol tcp
+ source {
+ address 62.232.209.221
+ }
+ }
+ rule 2372 {
+ action accept
+ description FW0192C_1-TCP-ALLOW-41.140.242.86
+ destination {
+ group {
+ address-group DT_FW0192C_1
+ }
+ port 3306,22
+ }
+ protocol tcp
+ source {
+ address 41.140.242.86
+ }
+ }
+ rule 2373 {
+ action accept
+ description FWEEC75_1-TCP-ALLOW-54.171.71.110
+ destination {
+ group {
+ address-group DT_FWEEC75_1
+ }
+ port 21
+ }
+ protocol tcp
+ source {
+ address 54.171.71.110
+ }
+ }
+ rule 2374 {
+ action accept
+ description FW8B21D_1-TCP_UDP-ALLOW-95.149.182.69
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ port 22
+ }
+ protocol tcp_udp
+ source {
+ address 95.149.182.69
+ }
+ }
+ rule 2375 {
+ action accept
+ description FW8B21D_1-TCP-ALLOW-185.201.16.0_22
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ port 25
+ }
+ protocol tcp
+ source {
+ address 185.201.16.0/22
+ }
+ }
+ rule 2376 {
+ action accept
+ description FW8B21D_1-TCP-ALLOW-213.133.99.176
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ port 25
+ }
+ protocol tcp
+ source {
+ address 213.133.99.176
+ }
+ }
+ rule 2377 {
+ action accept
+ description FW8B21D_1-TCP-ALLOW-95.211.160.147
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ port 25
+ }
+ protocol tcp
+ source {
+ address 95.211.160.147
+ }
+ }
+ rule 2378 {
+ action accept
+ description FW6863A_4-TCP-ALLOW-212.227.9.72
+ destination {
+ group {
+ address-group DT_FW6863A_4
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 212.227.9.72
+ }
+ }
+ rule 2379 {
+ action accept
+ description FW8B21D_1-ESP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ }
+ protocol esp
+ }
+ rule 2380 {
+ action accept
+ description FW8B21D_1-AH-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ }
+ protocol ah
+ }
+ rule 2381 {
+ action accept
+ description FW8B21D_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ port 8181,4500,1194,993,941,500,53
+ }
+ protocol tcp_udp
+ }
+ rule 2382 {
+ action accept
+ description FW6863A_4-TCP-ALLOW-85.17.25.47
+ destination {
+ group {
+ address-group DT_FW6863A_4
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 85.17.25.47
+ }
+ }
+ rule 2383 {
+ action accept
+ description FW6863A_4-TCP-ALLOW-91.232.105.39
+ destination {
+ group {
+ address-group DT_FW6863A_4
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 91.232.105.39
+ }
+ }
+ rule 2384 {
+ action accept
+ description FW6863A_4-TCP-ALLOW-93.190.142.120
+ destination {
+ group {
+ address-group DT_FW6863A_4
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 93.190.142.120
+ }
+ }
+ rule 2385 {
+ action accept
+ description FW6863A_4-TCP-ALLOW-95.168.171.130
+ destination {
+ group {
+ address-group DT_FW6863A_4
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 95.168.171.130
+ }
+ }
+ rule 2386 {
+ action accept
+ description FW6863A_4-TCP-ALLOW-95.168.171.157
+ destination {
+ group {
+ address-group DT_FW6863A_4
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 95.168.171.157
+ }
+ }
+ rule 2387 {
+ action accept
+ description FWD4A27_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD4A27_1
+ }
+ port 32400
+ }
+ protocol tcp
+ }
+ rule 2388 {
+ action accept
+ description FW2ACFF_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2ACFF_1
+ }
+ port 10299,60050-60055
+ }
+ protocol tcp_udp
+ }
+ rule 2389 {
+ action accept
+ description FWCB0CF_7-TCP-ALLOW-193.248.62.45
+ destination {
+ group {
+ address-group DT_FWCB0CF_7
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 193.248.62.45
+ }
+ }
+ rule 2390 {
+ action accept
+ description FWCB0CF_7-TCP-ALLOW-78.249.208.17
+ destination {
+ group {
+ address-group DT_FWCB0CF_7
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 78.249.208.17
+ }
+ }
+ rule 2391 {
+ action accept
+ description FWC8E8E_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC8E8E_1
+ }
+ port 6000
+ }
+ protocol tcp_udp
+ }
+ rule 2392 {
+ action accept
+ description FW30D21_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW30D21_1
+ }
+ port 2476
+ }
+ protocol tcp
+ }
+ rule 2393 {
+ action accept
+ description FW0192C_1-TCP-ALLOW-41.140.242.94
+ destination {
+ group {
+ address-group DT_FW0192C_1
+ }
+ port 3306,22
+ }
+ protocol tcp
+ source {
+ address 41.140.242.94
+ }
+ }
+ rule 2394 {
+ action accept
+ description FW59F39_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW59F39_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2395 {
+ action accept
+ description FWEF92E_7-ESP-ALLOW-77.68.77.57
+ destination {
+ group {
+ address-group DT_FWEF92E_7
+ }
+ }
+ protocol esp
+ source {
+ address 77.68.77.57
+ }
+ }
+ rule 2396 {
+ action accept
+ description FW826BA_3-TCP-ALLOW-51.219.47.177
+ destination {
+ group {
+ address-group DT_FW826BA_3
+ }
+ port 3389,21
+ }
+ protocol tcp
+ source {
+ address 51.219.47.177
+ }
+ }
+ rule 2397 {
+ action accept
+ description FW826BA_3-TCP-ALLOW-86.172.128.50
+ destination {
+ group {
+ address-group DT_FW826BA_3
+ }
+ port 1433,21
+ }
+ protocol tcp
+ source {
+ address 86.172.128.50
+ }
+ }
+ rule 2398 {
+ action accept
+ description FW826BA_3-TCP-ALLOW-88.105.1.20
+ destination {
+ group {
+ address-group DT_FW826BA_3
+ }
+ port 21
+ }
+ protocol tcp
+ source {
+ address 88.105.1.20
+ }
+ }
+ rule 2399 {
+ action accept
+ description FW6863A_4-TCP-ALLOW-95.211.243.198
+ destination {
+ group {
+ address-group DT_FW6863A_4
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 95.211.243.198
+ }
+ }
+ rule 2400 {
+ action accept
+ description FW25843_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW25843_1
+ }
+ port 9001,7070,5500,5488,5000,4500,4000,3500,3000,1883,1880
+ }
+ protocol tcp
+ }
+ rule 2401 {
+ action accept
+ description FW89619_1-TCP_UDP-ALLOW-185.83.65.46
+ destination {
+ group {
+ address-group DT_FW89619_1
+ }
+ port 5060
+ }
+ protocol tcp_udp
+ source {
+ address 185.83.65.46
+ }
+ }
+ rule 2402 {
+ action accept
+ description FW5858F_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW5858F_1
+ }
+ port 1883
+ }
+ protocol tcp
+ }
+ rule 2403 {
+ action accept
+ description FW826BA_3-TCP-ALLOW-95.147.108.173
+ destination {
+ group {
+ address-group DT_FW826BA_3
+ }
+ port 21
+ }
+ protocol tcp
+ source {
+ address 95.147.108.173
+ }
+ }
+ rule 2404 {
+ action accept
+ description FW9C682_3-TCP-ALLOW-52.56.193.88
+ destination {
+ group {
+ address-group DT_FW9C682_3
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 52.56.193.88
+ }
+ }
+ rule 2405 {
+ action accept
+ description FW0745F_5-TCP-ALLOW-109.228.63.82
+ destination {
+ group {
+ address-group DT_FW0745F_5
+ }
+ port 5666
+ }
+ protocol tcp
+ source {
+ address 109.228.63.82
+ }
+ }
+ rule 2406 {
+ action accept
+ description FWC0CE0_1-TCP-ALLOW-90.255.228.213
+ destination {
+ group {
+ address-group DT_FWC0CE0_1
+ }
+ port 49152-65535,8443,21
+ }
+ protocol tcp
+ source {
+ address 90.255.228.213
+ }
+ }
+ rule 2407 {
+ action accept
+ description FW210E2_8-AH-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW210E2_8
+ }
+ }
+ protocol ah
+ }
+ rule 2408 {
+ action accept
+ description FW210E2_8-ESP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW210E2_8
+ }
+ }
+ protocol esp
+ }
+ rule 2409 {
+ action accept
+ description FW210E2_8-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW210E2_8
+ }
+ port 41,62000,23,4500,50,9876,3391,88,135
+ }
+ protocol tcp
+ }
+ rule 2410 {
+ action accept
+ description FW210E2_8-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW210E2_8
+ }
+ port 500
+ }
+ protocol udp
+ }
+ rule 2411 {
+ action accept
+ description VPN-8625-ANY-ALLOW-10.4.54.103
+ destination {
+ group {
+ address-group DT_VPN-8625
+ }
+ }
+ source {
+ address 10.4.54.103
+ }
+ }
+ rule 2412 {
+ action accept
+ description VPN-8625-ANY-ALLOW-10.4.55.104
+ destination {
+ group {
+ address-group DT_VPN-8625
+ }
+ }
+ source {
+ address 10.4.55.104
+ }
+ }
+ rule 2413 {
+ action accept
+ description FW73A64_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW73A64_1
+ }
+ port 61616,8181,8161,8082,4244,4243,4242,4241
+ }
+ protocol tcp
+ }
+ rule 2414 {
+ action accept
+ description VPN-19135-ANY-ALLOW-10.4.86.165
+ destination {
+ group {
+ address-group DT_VPN-19135
+ }
+ }
+ source {
+ address 10.4.86.165
+ }
+ }
+ rule 2415 {
+ action accept
+ description FWCB0CF_7-TCP-ALLOW-82.65.107.3
+ destination {
+ group {
+ address-group DT_FWCB0CF_7
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 82.65.107.3
+ }
+ }
+ rule 2416 {
+ action accept
+ description FWCB0CF_7-TCP-ALLOW-195.2.139.221
+ destination {
+ group {
+ address-group DT_FWCB0CF_7
+ }
+ port 5432-5434,3306-3308
+ }
+ protocol tcp
+ source {
+ address 195.2.139.221
+ }
+ }
+ rule 2417 {
+ action accept
+ description VPN-19135-ANY-ALLOW-10.4.87.165
+ destination {
+ group {
+ address-group DT_VPN-19135
+ }
+ }
+ source {
+ address 10.4.87.165
+ }
+ }
+ rule 2418 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-87.75.109.83
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 27017,5000
+ }
+ protocol tcp
+ source {
+ address 87.75.109.83
+ }
+ }
+ rule 2419 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.83
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.83
+ }
+ }
+ rule 2420 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-84.92.65.192
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 84.92.65.192
+ }
+ }
+ rule 2421 {
+ action accept
+ description FW73A64_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW73A64_1
+ }
+ port 9200,5601,4247,4246,4245
+ }
+ protocol tcp_udp
+ }
+ rule 2422 {
+ action accept
+ description FW4735F_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4735F_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2423 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-109.176.154.238
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 7990,3389
+ }
+ protocol tcp
+ source {
+ address 109.176.154.238
+ }
+ }
+ rule 2424 {
+ action accept
+ description FW6863A_4-TCP-ALLOW-95.211.243.206
+ destination {
+ group {
+ address-group DT_FW6863A_4
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 95.211.243.206
+ }
+ }
+ rule 2425 {
+ action accept
+ description FW89619_1-TCP_UDP-ALLOW-81.133.80.114
+ destination {
+ group {
+ address-group DT_FW89619_1
+ }
+ port 5060
+ }
+ protocol tcp_udp
+ source {
+ address 81.133.80.114
+ }
+ }
+ rule 2426 {
+ action accept
+ description FW89619_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW89619_1
+ }
+ port 5090
+ }
+ protocol tcp_udp
+ }
+ rule 2427 {
+ action accept
+ description FW8A57A_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8A57A_1
+ }
+ port 49155,49154,7700,53,43
+ }
+ protocol tcp_udp
+ }
+ rule 2428 {
+ action accept
+ description FW8C72E_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8C72E_1
+ }
+ port 500,4500
+ }
+ protocol udp
+ }
+ rule 2429 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-18.135.66.162
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 18.135.66.162
+ }
+ }
+ rule 2430 {
+ action accept
+ description FW2C5AE_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2C5AE_1
+ }
+ port 58080,58008,8545,7175
+ }
+ protocol tcp
+ }
+ rule 2431 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-80.209.144.52
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 80.209.144.52
+ }
+ }
+ rule 2432 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-82.153.21.103
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 7990,3389
+ }
+ protocol tcp
+ source {
+ address 82.153.21.103
+ }
+ }
+ rule 2433 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.41
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.41
+ }
+ }
+ rule 2434 {
+ action accept
+ description FW0745F_5-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0745F_5
+ }
+ port 32770,8001,7801
+ }
+ protocol tcp
+ }
+ rule 2435 {
+ action accept
+ description FW85E02_11-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW85E02_11
+ }
+ port 5090,5060
+ }
+ protocol tcp_udp
+ }
+ rule 2436 {
+ action accept
+ description VPN-21982-ANY-ALLOW-10.4.58.43
+ destination {
+ group {
+ address-group DT_VPN-21982
+ }
+ }
+ source {
+ address 10.4.58.43
+ }
+ }
+ rule 2437 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-82.17.52.191
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 82.17.52.191
+ }
+ }
+ rule 2438 {
+ action accept
+ description FW66347_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW66347_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 2439 {
+ action accept
+ description FW11082_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW11082_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2440 {
+ action accept
+ description VPN-21982-ANY-ALLOW-10.4.59.43
+ destination {
+ group {
+ address-group DT_VPN-21982
+ }
+ }
+ source {
+ address 10.4.59.43
+ }
+ }
+ rule 2441 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-92.207.193.203
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 5000
+ }
+ protocol tcp
+ source {
+ address 92.207.193.203
+ }
+ }
+ rule 2442 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-77.99.253.161
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443,22,21
+ }
+ protocol tcp
+ source {
+ address 77.99.253.161
+ }
+ }
+ rule 2443 {
+ action accept
+ description FW0E383_9-TCP-ALLOW-77.99.245.103
+ destination {
+ group {
+ address-group DT_FW0E383_9
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 77.99.245.103
+ }
+ }
+ rule 2444 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-82.19.19.52
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 7990,3389
+ }
+ protocol tcp
+ source {
+ address 82.19.19.52
+ }
+ }
+ rule 2445 {
+ action accept
+ description FWEF92E_7-AH-ALLOW-77.68.77.57
+ destination {
+ group {
+ address-group DT_FWEF92E_7
+ }
+ }
+ protocol ah
+ source {
+ address 77.68.77.57
+ }
+ }
+ rule 2446 {
+ action accept
+ description VPN-16450-ANY-ALLOW-10.4.88.99
+ destination {
+ group {
+ address-group DT_VPN-16450
+ }
+ }
+ source {
+ address 10.4.88.99
+ }
+ }
+ rule 2447 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-82.2.186.129
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 82.2.186.129
+ }
+ }
+ rule 2448 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.157
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.157
+ }
+ }
+ rule 2449 {
+ action accept
+ description FW8EA04_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8EA04_1
+ }
+ port 1194
+ }
+ protocol udp
+ }
+ rule 2450 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-82.21.59.207
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 82.21.59.207
+ }
+ }
+ rule 2451 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-82.9.22.158
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443,21
+ }
+ protocol tcp
+ source {
+ address 82.9.22.158
+ }
+ }
+ rule 2452 {
+ action accept
+ description FWF3A1B_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF3A1B_1
+ }
+ port 1981,53
+ }
+ protocol tcp_udp
+ }
+ rule 2453 {
+ action accept
+ description FWEF92E_5-ESP-ALLOW-77.68.11.54
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol esp
+ source {
+ address 77.68.11.54
+ }
+ }
+ rule 2454 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-82.40.177.186
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 82.40.177.186
+ }
+ }
+ rule 2455 {
+ action accept
+ description FW0C25B_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0C25B_1
+ }
+ port 49152-65535,5224
+ }
+ protocol tcp
+ }
+ rule 2456 {
+ action accept
+ description FW85A7C_1-TCP-ALLOW-82.24.242.137
+ destination {
+ group {
+ address-group DT_FW85A7C_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 82.24.242.137
+ }
+ }
+ rule 2457 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-82.68.25.66
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 82.68.25.66
+ }
+ }
+ rule 2458 {
+ action accept
+ description FW826BA_3-TCP-ALLOW-51.89.148.173
+ destination {
+ group {
+ address-group DT_FW826BA_3
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 51.89.148.173
+ }
+ }
+ rule 2459 {
+ action accept
+ description FWA69A0_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA69A0_1
+ }
+ port 48402
+ }
+ protocol udp
+ }
+ rule 2460 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-82.69.79.85
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 82.69.79.85
+ }
+ }
+ rule 2461 {
+ action accept
+ description FWEF92E_5-ESP-ALLOW-77.68.77.149
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol esp
+ source {
+ address 77.68.77.149
+ }
+ }
+ rule 2462 {
+ action accept
+ description FWEF92E_6-ESP-ALLOW-77.68.77.57
+ destination {
+ group {
+ address-group DT_FWEF92E_6
+ }
+ }
+ protocol esp
+ source {
+ address 77.68.77.57
+ }
+ }
+ rule 2463 {
+ action accept
+ description FWEF92E_7-TCP-ALLOW-77.68.8.74
+ destination {
+ group {
+ address-group DT_FWEF92E_7
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 77.68.8.74
+ }
+ }
+ rule 2464 {
+ action accept
+ description FW49C3D_4-TCP-ALLOW-77.68.8.74
+ destination {
+ group {
+ address-group DT_FW49C3D_4
+ }
+ port 3389,445,443,80
+ }
+ protocol tcp
+ source {
+ address 77.68.8.74
+ }
+ }
+ rule 2465 {
+ action accept
+ description FW49C3D_6-TCP-ALLOW-77.68.8.74
+ destination {
+ group {
+ address-group DT_FW49C3D_6
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 77.68.8.74
+ }
+ }
+ rule 2466 {
+ action accept
+ description FW34C91_3-TCP-ALLOW-77.68.121.4
+ destination {
+ group {
+ address-group DT_FW34C91_3
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 77.68.121.4
+ }
+ }
+ rule 2467 {
+ action accept
+ description VPN-16450-ANY-ALLOW-10.4.89.99
+ destination {
+ group {
+ address-group DT_VPN-16450
+ }
+ }
+ source {
+ address 10.4.89.99
+ }
+ }
+ rule 2468 {
+ action accept
+ description FW0BB22_1-AH-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0BB22_1
+ }
+ }
+ protocol ah
+ }
+ rule 2469 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-86.139.57.116
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 86.139.57.116
+ }
+ }
+ rule 2470 {
+ action accept
+ description FW9E550_1-TCP-ALLOW-86.142.67.13
+ destination {
+ group {
+ address-group DT_FW9E550_1
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 86.142.67.13
+ }
+ }
+ rule 2471 {
+ action accept
+ description FW8B21D_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8B21D_1
+ }
+ port 2096,2095,2087,2086,2083,2082
+ }
+ protocol tcp
+ }
+ rule 2472 {
+ action accept
+ description FW050AC_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW050AC_1
+ }
+ port 2087
+ }
+ protocol tcp
+ }
+ rule 2473 {
+ action accept
+ description FW1FA9E_1-TCP-ALLOW-109.228.50.206
+ destination {
+ group {
+ address-group DT_FW1FA9E_1
+ }
+ port 5432
+ }
+ protocol tcp
+ source {
+ address 109.228.50.206
+ }
+ }
+ rule 2474 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-217.23.11.155
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 217.23.11.155
+ }
+ }
+ rule 2475 {
+ action accept
+ description FW2ED4D_2-TCP-ALLOW-88.96.110.198
+ destination {
+ group {
+ address-group DT_FW2ED4D_2
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 88.96.110.198
+ }
+ }
+ rule 2476 {
+ action accept
+ description FWEAE53_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWEAE53_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2477 {
+ action accept
+ description VPN-19474-ANY-ALLOW-10.4.88.161
+ destination {
+ group {
+ address-group DT_VPN-19474
+ }
+ }
+ source {
+ address 10.4.88.161
+ }
+ }
+ rule 2478 {
+ action accept
+ description VPN-19474-ANY-ALLOW-10.4.89.161
+ destination {
+ group {
+ address-group DT_VPN-19474
+ }
+ }
+ source {
+ address 10.4.89.161
+ }
+ }
+ rule 2479 {
+ action accept
+ description FW90AE3_1-TCP-ALLOW-68.33.220.233
+ destination {
+ group {
+ address-group DT_FW90AE3_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 68.33.220.233
+ }
+ }
+ rule 2480 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-86.10.163.127
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443,21
+ }
+ protocol tcp
+ source {
+ address 86.10.163.127
+ }
+ }
+ rule 2481 {
+ action accept
+ description FW2FB61_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2FB61_1
+ }
+ port 60182
+ }
+ protocol udp
+ }
+ rule 2482 {
+ action accept
+ description FW85A7C_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW85A7C_1
+ }
+ port 2457,2456
+ }
+ protocol tcp_udp
+ }
+ rule 2483 {
+ action accept
+ description FWBED52_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWBED52_1
+ }
+ port 1221,9000
+ }
+ protocol tcp
+ }
+ rule 2484 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-90.250.2.109
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389,443
+ }
+ protocol tcp
+ source {
+ address 90.250.2.109
+ }
+ }
+ rule 2485 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.49
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.49
+ }
+ }
+ rule 2486 {
+ action accept
+ description FWEF92E_5-ESP-ALLOW-77.68.77.70
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol esp
+ source {
+ address 77.68.77.70
+ }
+ }
+ rule 2487 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.250
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.250
+ }
+ }
+ rule 2488 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-95.168.171.131
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 95.168.171.131
+ }
+ }
+ rule 2489 {
+ action accept
+ description FW2379F_14-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2379F_14
+ }
+ port 48030,10997,10993,10992,10991,10902,1723,1701
+ }
+ protocol tcp
+ }
+ rule 2490 {
+ action accept
+ description FW8C927_1-TCP-ALLOW-84.92.125.78
+ destination {
+ group {
+ address-group DT_FW8C927_1
+ }
+ port 80
+ }
+ protocol tcp
+ source {
+ address 84.92.125.78
+ }
+ }
+ rule 2491 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-86.146.220.229
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443,21
+ }
+ protocol tcp
+ source {
+ address 86.146.220.229
+ }
+ }
+ rule 2492 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-2.218.5.59
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 8443,22
+ }
+ protocol tcp
+ source {
+ address 2.218.5.59
+ }
+ }
+ rule 2493 {
+ action accept
+ description VPN-18830-ANY-ALLOW-10.4.86.156
+ destination {
+ group {
+ address-group DT_VPN-18830
+ }
+ }
+ source {
+ address 10.4.86.156
+ }
+ }
+ rule 2494 {
+ action accept
+ description VPN-18830-ANY-ALLOW-10.4.87.156
+ destination {
+ group {
+ address-group DT_VPN-18830
+ }
+ }
+ source {
+ address 10.4.87.156
+ }
+ }
+ rule 2495 {
+ action accept
+ description FWEF92E_5-ESP-ALLOW-77.68.92.33
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol esp
+ source {
+ address 77.68.92.33
+ }
+ }
+ rule 2496 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-146.198.100.105
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389,443
+ }
+ protocol tcp
+ source {
+ address 146.198.100.105
+ }
+ }
+ rule 2497 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.55
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.55
+ }
+ }
+ rule 2498 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-123.231.84.113
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 123.231.84.113
+ }
+ }
+ rule 2499 {
+ action accept
+ description FW8C72E_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8C72E_1
+ }
+ port 60134,60135
+ }
+ protocol tcp
+ }
+ rule 2500 {
+ action accept
+ description FWAB44B_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWAB44B_1
+ }
+ port 3306
+ }
+ protocol tcp_udp
+ }
+ rule 2501 {
+ action accept
+ description FW2379F_14-TCP-ALLOW-51.148.87.29
+ destination {
+ group {
+ address-group DT_FW2379F_14
+ }
+ port 3389,21
+ }
+ protocol tcp
+ source {
+ address 51.148.87.29
+ }
+ }
+ rule 2502 {
+ action accept
+ description VPN-23738-ANY-ALLOW-10.4.56.13
+ destination {
+ group {
+ address-group DT_VPN-23738
+ }
+ }
+ source {
+ address 10.4.56.13
+ }
+ }
+ rule 2503 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.100
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.100
+ }
+ }
+ rule 2504 {
+ action accept
+ description FW996B4_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW996B4_2
+ }
+ port 43595,30160
+ }
+ protocol tcp
+ }
+ rule 2505 {
+ action accept
+ description FW8871B_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8871B_1
+ }
+ port 15672,8083,8082,8081,5672
+ }
+ protocol tcp
+ }
+ rule 2506 {
+ action accept
+ description FWAB44B_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWAB44B_1
+ }
+ port 9090,8069,5432
+ }
+ protocol tcp
+ }
+ rule 2507 {
+ action accept
+ description FW6187E_1-ICMP-ALLOW-85.214.201.250
+ destination {
+ group {
+ address-group DT_FW6187E_1
+ }
+ }
+ protocol icmp
+ source {
+ address 85.214.201.250
+ }
+ }
+ rule 2508 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-217.23.11.126
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 217.23.11.126
+ }
+ }
+ rule 2509 {
+ action accept
+ description FW78137_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW78137_1
+ }
+ port 1-65535
+ }
+ protocol tcp
+ }
+ rule 2510 {
+ action accept
+ description FW32EFF_25-TCP-ALLOW-46.252.65.10
+ destination {
+ group {
+ address-group DT_FW32EFF_25
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 46.252.65.10
+ }
+ }
+ rule 2511 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.50
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.50
+ }
+ }
+ rule 2512 {
+ action accept
+ description FW6A684_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6A684_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 2513 {
+ action accept
+ description FWF48EB_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF48EB_1
+ }
+ port 9204,9202,3395
+ }
+ protocol tcp
+ }
+ rule 2514 {
+ action accept
+ description FW44217_2-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW44217_2
+ }
+ port 443,80
+ }
+ protocol tcp_udp
+ }
+ rule 2515 {
+ action accept
+ description FW6187E_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6187E_1
+ }
+ port 2282
+ }
+ protocol tcp
+ }
+ rule 2516 {
+ action accept
+ description FW8AFF1_7-TCP-ALLOW-109.228.0.58
+ destination {
+ group {
+ address-group DT_FW8AFF1_7
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 109.228.0.58
+ }
+ }
+ rule 2517 {
+ action accept
+ description VPN-34501-ANY-ALLOW-10.4.86.235
+ destination {
+ group {
+ address-group DT_VPN-34501
+ }
+ }
+ source {
+ address 10.4.86.235
+ }
+ }
+ rule 2518 {
+ action accept
+ description FW1271A_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1271A_2
+ }
+ port 5090,5061,5060,5015,5001
+ }
+ protocol tcp
+ }
+ rule 2519 {
+ action accept
+ description FW1271A_2-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1271A_2
+ }
+ port 9000-10999,5090,5060
+ }
+ protocol udp
+ }
+ rule 2520 {
+ action accept
+ description FW1226C_3-TCP-ALLOW-216.113.160.71
+ destination {
+ group {
+ address-group DT_FW1226C_3
+ }
+ port 80,22
+ }
+ protocol tcp
+ source {
+ address 216.113.160.71
+ }
+ }
+ rule 2521 {
+ action accept
+ description FW32EFF_16-TCP-ALLOW-84.19.45.82
+ destination {
+ group {
+ address-group DT_FW32EFF_16
+ }
+ port 33888
+ }
+ protocol tcp
+ source {
+ address 84.19.45.82
+ }
+ }
+ rule 2522 {
+ action accept
+ description FW03F2E_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW03F2E_1
+ }
+ port 1194
+ }
+ protocol udp
+ }
+ rule 2523 {
+ action accept
+ description FW03F2E_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW03F2E_1
+ }
+ port 4432,4431,4430
+ }
+ protocol tcp
+ }
+ rule 2524 {
+ action accept
+ description FW1226C_3-TCP-ALLOW-216.113.162.65
+ destination {
+ group {
+ address-group DT_FW1226C_3
+ }
+ port 80,22
+ }
+ protocol tcp
+ source {
+ address 216.113.162.65
+ }
+ }
+ rule 2525 {
+ action accept
+ description VPN-20306-ANY-ALLOW-10.4.89.173
+ destination {
+ group {
+ address-group DT_VPN-20306
+ }
+ }
+ source {
+ address 10.4.89.173
+ }
+ }
+ rule 2526 {
+ action accept
+ description FW8A49A_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8A49A_1
+ }
+ port 2525,8448-65535
+ }
+ protocol tcp
+ }
+ rule 2527 {
+ action accept
+ description FWD3431_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD3431_2
+ }
+ port 43595,30377,30289
+ }
+ protocol tcp
+ }
+ rule 2528 {
+ action accept
+ description FW1226C_3-TCP-ALLOW-66.135.200.200
+ destination {
+ group {
+ address-group DT_FW1226C_3
+ }
+ port 80,22
+ }
+ protocol tcp
+ source {
+ address 66.135.200.200
+ }
+ }
+ rule 2529 {
+ action accept
+ description FW1226C_3-TCP-ALLOW-193.28.178.38
+ destination {
+ group {
+ address-group DT_FW1226C_3
+ }
+ port 80
+ }
+ protocol tcp
+ source {
+ address 193.28.178.38
+ }
+ }
+ rule 2530 {
+ action accept
+ description FWAE88B_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWAE88B_1
+ }
+ port 65432,8080,7300,1195,1194,993,587,465,443,442,143,110,80,53,22
+ }
+ protocol tcp_udp
+ }
+ rule 2531 {
+ action accept
+ description FW1226C_3-TCP-ALLOW-195.234.136.80
+ destination {
+ group {
+ address-group DT_FW1226C_3
+ }
+ port 80
+ }
+ protocol tcp
+ source {
+ address 195.234.136.80
+ }
+ }
+ rule 2532 {
+ action accept
+ description FW1226C_3-TCP-ALLOW-93.94.41.83
+ destination {
+ group {
+ address-group DT_FW1226C_3
+ }
+ port 80
+ }
+ protocol tcp
+ source {
+ address 93.94.41.83
+ }
+ }
+ rule 2533 {
+ action accept
+ description VPN-6103-ANY-ALLOW-10.4.56.102
+ destination {
+ group {
+ address-group DT_VPN-6103
+ }
+ }
+ source {
+ address 10.4.56.102
+ }
+ }
+ rule 2534 {
+ action accept
+ description VPN-6103-ANY-ALLOW-10.4.57.102
+ destination {
+ group {
+ address-group DT_VPN-6103
+ }
+ }
+ source {
+ address 10.4.57.102
+ }
+ }
+ rule 2535 {
+ action accept
+ description FW9E550_1-TCP-ALLOW-86.198.190.104
+ destination {
+ group {
+ address-group DT_FW9E550_1
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 86.198.190.104
+ }
+ }
+ rule 2536 {
+ action accept
+ description FW34C91_3-TCP-ALLOW-81.149.71.244
+ destination {
+ group {
+ address-group DT_FW34C91_3
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 81.149.71.244
+ }
+ }
+ rule 2537 {
+ action accept
+ description FW0BB22_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0BB22_1
+ }
+ port 27917,27017,9592,9092,1080,587
+ }
+ protocol tcp_udp
+ }
+ rule 2538 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-89.213.26.156
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443,21
+ }
+ protocol tcp
+ source {
+ address 89.213.26.156
+ }
+ }
+ rule 2539 {
+ action accept
+ description FW34C91_3-UDP-ALLOW-81.149.71.244
+ destination {
+ group {
+ address-group DT_FW34C91_3
+ }
+ port 1434
+ }
+ protocol udp
+ source {
+ address 81.149.71.244
+ }
+ }
+ rule 2540 {
+ action accept
+ description VPN-17207-ANY-ALLOW-10.4.86.121
+ destination {
+ group {
+ address-group DT_VPN-17207
+ }
+ }
+ source {
+ address 10.4.86.121
+ }
+ }
+ rule 2541 {
+ action accept
+ description FW0B352_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0B352_1
+ }
+ port 4500,500
+ }
+ protocol udp
+ }
+ rule 2542 {
+ action accept
+ description FW85E02_11-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW85E02_11
+ }
+ port 5854,5853,5061
+ }
+ protocol tcp
+ }
+ rule 2543 {
+ action accept
+ description FW0BB22_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0BB22_1
+ }
+ port 9200,8082
+ }
+ protocol tcp
+ }
+ rule 2544 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.140
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.140
+ }
+ }
+ rule 2545 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-91.125.244.28
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 21
+ }
+ protocol tcp
+ source {
+ address 91.125.244.28
+ }
+ }
+ rule 2546 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-86.172.252.221
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 80-3389
+ }
+ protocol tcp
+ source {
+ address 86.172.252.221
+ }
+ }
+ rule 2547 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-92.207.184.106
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443,21
+ }
+ protocol tcp
+ source {
+ address 92.207.184.106
+ }
+ }
+ rule 2548 {
+ action accept
+ description FW45F3D_1-ANY-ALLOW-146.255.0.198
+ destination {
+ group {
+ address-group DT_FW45F3D_1
+ }
+ }
+ source {
+ address 146.255.0.198
+ }
+ }
+ rule 2549 {
+ action accept
+ description FWBFDED_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWBFDED_1
+ }
+ port 1723,445
+ }
+ protocol tcp
+ }
+ rule 2550 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-212.227.9.72
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 212.227.9.72
+ }
+ }
+ rule 2551 {
+ action accept
+ description FWE928F_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE928F_1
+ }
+ port 2082,2083,2086,2087,2096
+ }
+ protocol tcp
+ }
+ rule 2552 {
+ action accept
+ description FW5CBB2_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW5CBB2_1
+ }
+ port 2082,2083,2086,2087
+ }
+ protocol tcp
+ }
+ rule 2553 {
+ action accept
+ description FW63230_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW63230_1
+ }
+ port 445,139
+ }
+ protocol tcp_udp
+ }
+ rule 2554 {
+ action accept
+ description FW90AE3_1-TCP-ALLOW-71.244.176.5
+ destination {
+ group {
+ address-group DT_FW90AE3_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 71.244.176.5
+ }
+ }
+ rule 2555 {
+ action accept
+ description FWA4BC8_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA4BC8_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2556 {
+ action accept
+ description VPN-17207-ANY-ALLOW-10.4.87.121
+ destination {
+ group {
+ address-group DT_VPN-17207
+ }
+ }
+ source {
+ address 10.4.87.121
+ }
+ }
+ rule 2557 {
+ action accept
+ description VPN-17558-ANY-ALLOW-10.4.86.143
+ destination {
+ group {
+ address-group DT_VPN-17558
+ }
+ }
+ source {
+ address 10.4.86.143
+ }
+ }
+ rule 2558 {
+ action accept
+ description FWB2CD2_1-TCP-ALLOW-86.167.68.241
+ destination {
+ group {
+ address-group DT_FWB2CD2_1
+ }
+ port 21
+ }
+ protocol tcp
+ source {
+ address 86.167.68.241
+ }
+ }
+ rule 2559 {
+ action accept
+ description FW32EFF_25-TCP-ALLOW-84.19.45.82
+ destination {
+ group {
+ address-group DT_FW32EFF_25
+ }
+ port 33888,443
+ }
+ protocol tcp
+ source {
+ address 84.19.45.82
+ }
+ }
+ rule 2560 {
+ action accept
+ description FW44217_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW44217_2
+ }
+ port 9001,7946,2376
+ }
+ protocol tcp
+ }
+ rule 2561 {
+ action accept
+ description FW7DAE2_3-TCP-ALLOW-212.227.253.11
+ destination {
+ group {
+ address-group DT_FW7DAE2_3
+ }
+ port 25,22
+ }
+ protocol tcp
+ source {
+ address 212.227.253.11
+ }
+ }
+ rule 2562 {
+ action accept
+ description FW7DAE2_3-TCP-ALLOW-217.160.126.118
+ destination {
+ group {
+ address-group DT_FW7DAE2_3
+ }
+ port 25,22
+ }
+ protocol tcp
+ source {
+ address 217.160.126.118
+ }
+ }
+ rule 2563 {
+ action accept
+ description FWAF6E8_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWAF6E8_1
+ }
+ port 2082,2083,2086,2087,2096
+ }
+ protocol tcp
+ }
+ rule 2564 {
+ action accept
+ description FWCD7CE_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWCD7CE_1
+ }
+ port 49152-65534
+ }
+ protocol tcp
+ }
+ rule 2565 {
+ action accept
+ description FW32EFF_16-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW32EFF_16
+ }
+ port 47779,47778,47777,47776
+ }
+ protocol tcp
+ }
+ rule 2566 {
+ action accept
+ description FW0745F_5-TCP-ALLOW-77.68.117.222
+ destination {
+ group {
+ address-group DT_FW0745F_5
+ }
+ port 49170
+ }
+ protocol tcp
+ source {
+ address 77.68.117.222
+ }
+ }
+ rule 2567 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-92.207.199.107
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443,22,21
+ }
+ protocol tcp
+ source {
+ address 92.207.199.107
+ }
+ }
+ rule 2568 {
+ action accept
+ description FW8AFF1_7-TCP-ALLOW-109.228.0.89
+ destination {
+ group {
+ address-group DT_FW8AFF1_7
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 109.228.0.89
+ }
+ }
+ rule 2569 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-190.2.130.41
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 190.2.130.41
+ }
+ }
+ rule 2570 {
+ action accept
+ description FWFDCC7_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWFDCC7_1
+ }
+ port 10000
+ }
+ protocol tcp_udp
+ }
+ rule 2571 {
+ action accept
+ description FWF19FB_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF19FB_2
+ }
+ port 43595,40001,30616-30631,30531,30204-30435
+ }
+ protocol tcp
+ }
+ rule 2572 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-213.171.217.107
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 8443,22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.107
+ }
+ }
+ rule 2573 {
+ action accept
+ description FW4E314_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4E314_1
+ }
+ port 21543,888
+ }
+ protocol tcp
+ }
+ rule 2574 {
+ action accept
+ description FW73215_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW73215_1
+ }
+ port 4380
+ }
+ protocol udp
+ }
+ rule 2575 {
+ action accept
+ description VPN-31301-ANY-ALLOW-10.4.86.223
+ destination {
+ group {
+ address-group DT_VPN-31301
+ }
+ }
+ source {
+ address 10.4.86.223
+ }
+ }
+ rule 2576 {
+ action accept
+ description FW8428B_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8428B_1
+ }
+ port 48402
+ }
+ protocol udp
+ }
+ rule 2577 {
+ action accept
+ description FWF3A1B_1-TCP_UDP-ALLOW-185.195.124.169
+ destination {
+ group {
+ address-group DT_FWF3A1B_1
+ }
+ port 2222
+ }
+ protocol tcp_udp
+ source {
+ address 185.195.124.169
+ }
+ }
+ rule 2578 {
+ action accept
+ description FW34C91_3-UDP-ALLOW-77.68.121.4
+ destination {
+ group {
+ address-group DT_FW34C91_3
+ }
+ port 1434
+ }
+ protocol udp
+ source {
+ address 77.68.121.4
+ }
+ }
+ rule 2579 {
+ action accept
+ description FW73215_1-TCP-ALLOW-82.38.58.135
+ destination {
+ group {
+ address-group DT_FW73215_1
+ }
+ port 10685
+ }
+ protocol tcp
+ source {
+ address 82.38.58.135
+ }
+ }
+ rule 2580 {
+ action accept
+ description FW52F6F_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW52F6F_1
+ }
+ port 8888
+ }
+ protocol tcp
+ }
+ rule 2581 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.86
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.86
+ }
+ }
+ rule 2582 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-123.231.125.13
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 123.231.125.13
+ }
+ }
+ rule 2583 {
+ action accept
+ description FWEE03C_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWEE03C_1
+ }
+ port 2087,2083
+ }
+ protocol tcp
+ }
+ rule 2584 {
+ action accept
+ description FW748B7_1-TCP-ALLOW-157.231.123.154
+ destination {
+ group {
+ address-group DT_FW748B7_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 157.231.123.154
+ }
+ }
+ rule 2585 {
+ action accept
+ description VPN-34501-ANY-ALLOW-10.4.87.235
+ destination {
+ group {
+ address-group DT_VPN-34501
+ }
+ }
+ source {
+ address 10.4.87.235
+ }
+ }
+ rule 2586 {
+ action accept
+ description FWE47DA_1-TCP-ALLOW-81.134.85.245
+ destination {
+ group {
+ address-group DT_FWE47DA_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 81.134.85.245
+ }
+ }
+ rule 2587 {
+ action accept
+ description FWD61BF_1-ANY-ALLOW-193.237.81.213_32
+ destination {
+ group {
+ address-group DT_FWD61BF_1
+ }
+ }
+ source {
+ address 193.237.81.213/32
+ }
+ }
+ rule 2588 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-23.106.238.241
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 8443,3306,22
+ }
+ protocol tcp
+ source {
+ address 23.106.238.241
+ }
+ }
+ rule 2589 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-35.204.202.196
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 8443,3306,22
+ }
+ protocol tcp
+ source {
+ address 35.204.202.196
+ }
+ }
+ rule 2590 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-35.242.141.128
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 8443,3306,22
+ }
+ protocol tcp
+ source {
+ address 35.242.141.128
+ }
+ }
+ rule 2591 {
+ action accept
+ description FWC2EF2_2-TCP-ALLOW-90.251.221.19
+ destination {
+ group {
+ address-group DT_FWC2EF2_2
+ }
+ port 995,993,587,465,143,110,25,22
+ }
+ protocol tcp
+ source {
+ address 90.251.221.19
+ }
+ }
+ rule 2592 {
+ action accept
+ description VPN-14673-ANY-ALLOW-10.4.88.44
+ destination {
+ group {
+ address-group DT_VPN-14673
+ }
+ }
+ source {
+ address 10.4.88.44
+ }
+ }
+ rule 2593 {
+ action accept
+ description FWA83DF_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA83DF_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2594 {
+ action accept
+ description FW31525_6-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW31525_6
+ }
+ port 35467
+ }
+ protocol tcp
+ }
+ rule 2595 {
+ action accept
+ description FW4293B_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4293B_1
+ }
+ port 9080,8888,8881,7815,8419
+ }
+ protocol tcp
+ }
+ rule 2596 {
+ action accept
+ description FW4AE7D_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4AE7D_1
+ }
+ port 8083,81
+ }
+ protocol tcp
+ }
+ rule 2597 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-143.52.53.22
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 143.52.53.22
+ }
+ }
+ rule 2598 {
+ action accept
+ description FW44217_2-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW44217_2
+ }
+ port 7946,4789
+ }
+ protocol udp
+ }
+ rule 2599 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-46.249.82.162
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 8443,22
+ }
+ protocol tcp
+ source {
+ address 46.249.82.162
+ }
+ }
+ rule 2600 {
+ action accept
+ description FW27949_2-TCP-ALLOW-80.95.202.106
+ destination {
+ group {
+ address-group DT_FW27949_2
+ }
+ port 443,80
+ }
+ protocol tcp
+ source {
+ address 80.95.202.106
+ }
+ }
+ rule 2601 {
+ action accept
+ description FWEF92E_5-ESP-ALLOW-77.68.93.82
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol esp
+ source {
+ address 77.68.93.82
+ }
+ }
+ rule 2602 {
+ action accept
+ description FW2ACFF_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2ACFF_1
+ }
+ port 8082,5093
+ }
+ protocol tcp
+ }
+ rule 2603 {
+ action accept
+ description FWC2EF2_2-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC2EF2_2
+ }
+ port 10000,953,53
+ }
+ protocol tcp_udp
+ }
+ rule 2604 {
+ action accept
+ description FW0C8E1_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0C8E1_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2605 {
+ action accept
+ description FWA86ED_101-TCP_UDP-ALLOW-82.5.189.5
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 1-65535
+ }
+ protocol tcp_udp
+ source {
+ address 82.5.189.5
+ }
+ }
+ rule 2606 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.208.179
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.208.179
+ }
+ }
+ rule 2607 {
+ action accept
+ description FWEF92E_5-ESP-ALLOW-88.208.198.93
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol esp
+ source {
+ address 88.208.198.93
+ }
+ }
+ rule 2608 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-39.45.43.109
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 39.45.43.109
+ }
+ }
+ rule 2609 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-5.67.3.195
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 5.67.3.195
+ }
+ }
+ rule 2610 {
+ action accept
+ description FWDCA36_3-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWDCA36_3
+ }
+ port 49152-65534,5901
+ }
+ protocol tcp
+ }
+ rule 2611 {
+ action accept
+ description FWE928F_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE928F_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 2612 {
+ action accept
+ description FW69D6D_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW69D6D_2
+ }
+ port 5001,5090,5060,5015
+ }
+ protocol tcp
+ }
+ rule 2613 {
+ action accept
+ description FW69D6D_2-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW69D6D_2
+ }
+ port 5090,5060,9000-9500
+ }
+ protocol udp
+ }
+ rule 2614 {
+ action accept
+ description VPN-9765-ANY-ALLOW-10.4.56.45
+ destination {
+ group {
+ address-group DT_VPN-9765
+ }
+ }
+ source {
+ address 10.4.56.45
+ }
+ }
+ rule 2615 {
+ action accept
+ description VPN-9765-ANY-ALLOW-10.4.57.45
+ destination {
+ group {
+ address-group DT_VPN-9765
+ }
+ }
+ source {
+ address 10.4.57.45
+ }
+ }
+ rule 2616 {
+ action accept
+ description FW4C136_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4C136_1
+ }
+ port 1194
+ }
+ protocol tcp_udp
+ }
+ rule 2617 {
+ action accept
+ description FW6F539_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6F539_1
+ }
+ port 49152-65534
+ }
+ protocol tcp
+ }
+ rule 2618 {
+ action accept
+ description FWDD089_5-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWDD089_5
+ }
+ port 5666-5667,12489
+ }
+ protocol tcp_udp
+ }
+ rule 2619 {
+ action accept
+ description FWDD089_5-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWDD089_5
+ }
+ port 161-162
+ }
+ protocol tcp
+ }
+ rule 2620 {
+ action accept
+ description FWEF92E_5-AH-ALLOW-109.228.37.19
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol ah
+ source {
+ address 109.228.37.19
+ }
+ }
+ rule 2621 {
+ action accept
+ description FW0A5C4_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0A5C4_1
+ }
+ port 9000,6697,6667,5000
+ }
+ protocol tcp
+ }
+ rule 2622 {
+ action accept
+ description FWEF92E_5-AH-ALLOW-77.68.11.54
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol ah
+ source {
+ address 77.68.11.54
+ }
+ }
+ rule 2623 {
+ action accept
+ description FW2BB8D_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2BB8D_1
+ }
+ port 7990
+ }
+ protocol tcp
+ }
+ rule 2624 {
+ action accept
+ description FWAF6E8_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWAF6E8_1
+ }
+ port 7770-7800,44445,53
+ }
+ protocol tcp_udp
+ }
+ rule 2625 {
+ action accept
+ description FW81286_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW81286_1
+ }
+ port 2082,2083,2086,2087,2096
+ }
+ protocol tcp
+ }
+ rule 2626 {
+ action accept
+ description FW05064_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW05064_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2627 {
+ action accept
+ description FWD7382_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD7382_1
+ }
+ port 4500,1701,500
+ }
+ protocol udp
+ }
+ rule 2628 {
+ action accept
+ description FWD7382_1-TCP-ALLOW-174.91.7.198
+ destination {
+ group {
+ address-group DT_FWD7382_1
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 174.91.7.198
+ }
+ }
+ rule 2629 {
+ action accept
+ description VPN-9484-ANY-ALLOW-10.4.56.164
+ destination {
+ group {
+ address-group DT_VPN-9484
+ }
+ }
+ source {
+ address 10.4.56.164
+ }
+ }
+ rule 2630 {
+ action accept
+ description VPN-9484-ANY-ALLOW-10.4.57.164
+ destination {
+ group {
+ address-group DT_VPN-9484
+ }
+ }
+ source {
+ address 10.4.57.164
+ }
+ }
+ rule 2631 {
+ action accept
+ description VPN-9749-ANY-ALLOW-10.4.58.144
+ destination {
+ group {
+ address-group DT_VPN-9749
+ }
+ }
+ source {
+ address 10.4.58.144
+ }
+ }
+ rule 2632 {
+ action accept
+ description FWEF92E_5-AH-ALLOW-77.68.77.149
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol ah
+ source {
+ address 77.68.77.149
+ }
+ }
+ rule 2633 {
+ action accept
+ description FW10FEE_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW10FEE_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2634 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-5.71.30.141
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 5.71.30.141
+ }
+ }
+ rule 2635 {
+ action accept
+ description VPN-9749-ANY-ALLOW-10.4.59.144
+ destination {
+ group {
+ address-group DT_VPN-9749
+ }
+ }
+ source {
+ address 10.4.59.144
+ }
+ }
+ rule 2636 {
+ action accept
+ description FWEF92E_5-AH-ALLOW-77.68.77.70
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol ah
+ source {
+ address 77.68.77.70
+ }
+ }
+ rule 2637 {
+ action accept
+ description FWEF92E_5-AH-ALLOW-77.68.92.33
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol ah
+ source {
+ address 77.68.92.33
+ }
+ }
+ rule 2638 {
+ action accept
+ description FWEF92E_5-AH-ALLOW-77.68.93.82
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol ah
+ source {
+ address 77.68.93.82
+ }
+ }
+ rule 2639 {
+ action accept
+ description FWEF92E_6-AH-ALLOW-77.68.77.57
+ destination {
+ group {
+ address-group DT_FWEF92E_6
+ }
+ }
+ protocol ah
+ source {
+ address 77.68.77.57
+ }
+ }
+ rule 2640 {
+ action accept
+ description FWEF92E_6-TCP-ALLOW-77.68.8.74
+ destination {
+ group {
+ address-group DT_FWEF92E_6
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 77.68.8.74
+ }
+ }
+ rule 2641 {
+ action accept
+ description FWEF92E_5-AH-ALLOW-88.208.198.93
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ }
+ protocol ah
+ source {
+ address 88.208.198.93
+ }
+ }
+ rule 2642 {
+ action accept
+ description FWEF92E_7-TCP-ALLOW-87.224.33.215
+ destination {
+ group {
+ address-group DT_FWEF92E_7
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 87.224.33.215
+ }
+ }
+ rule 2643 {
+ action accept
+ description FWEF92E_7-TCP-ALLOW-87.224.6.174
+ destination {
+ group {
+ address-group DT_FWEF92E_7
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 87.224.6.174
+ }
+ }
+ rule 2644 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-109.228.37.19
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 109.228.37.19
+ }
+ }
+ rule 2645 {
+ action accept
+ description FW49C3D_4-TCP-ALLOW-87.224.33.215
+ destination {
+ group {
+ address-group DT_FW49C3D_4
+ }
+ port 3389,445,80
+ }
+ protocol tcp
+ source {
+ address 87.224.33.215
+ }
+ }
+ rule 2646 {
+ action accept
+ description FW49C3D_4-TCP-ALLOW-82.0.198.226
+ destination {
+ group {
+ address-group DT_FW49C3D_4
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 82.0.198.226
+ }
+ }
+ rule 2647 {
+ action accept
+ description FW49C3D_6-TCP-ALLOW-82.0.198.226
+ destination {
+ group {
+ address-group DT_FW49C3D_6
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 82.0.198.226
+ }
+ }
+ rule 2648 {
+ action accept
+ description FW49C3D_6-TCP-ALLOW-83.100.136.74
+ destination {
+ group {
+ address-group DT_FW49C3D_6
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 83.100.136.74
+ }
+ }
+ rule 2649 {
+ action accept
+ description FWEF92E_6-TCP-ALLOW-87.224.33.215
+ destination {
+ group {
+ address-group DT_FWEF92E_6
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 87.224.33.215
+ }
+ }
+ rule 2650 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-194.145.189.162
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 194.145.189.162
+ }
+ }
+ rule 2651 {
+ action accept
+ description FW3DBF8_9-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW3DBF8_9
+ }
+ port 9000-10999
+ }
+ protocol udp
+ }
+ rule 2652 {
+ action accept
+ description VPN-19807-ANY-ALLOW-10.4.86.172
+ destination {
+ group {
+ address-group DT_VPN-19807
+ }
+ }
+ source {
+ address 10.4.86.172
+ }
+ }
+ rule 2653 {
+ action accept
+ description FWEEC75_1-TCP-ALLOW-82.8.245.40
+ destination {
+ group {
+ address-group DT_FWEEC75_1
+ }
+ port 21
+ }
+ protocol tcp
+ source {
+ address 82.8.245.40
+ }
+ }
+ rule 2654 {
+ action accept
+ description FW3AD6F_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW3AD6F_1
+ }
+ port 53,465
+ }
+ protocol tcp_udp
+ }
+ rule 2655 {
+ action accept
+ description FWCDBC7_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWCDBC7_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 2656 {
+ action accept
+ description FWA373F_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA373F_1
+ }
+ port 2087,2086,2083,2082
+ }
+ protocol tcp
+ }
+ rule 2657 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-94.155.221.50
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 8443,22
+ }
+ protocol tcp
+ source {
+ address 94.155.221.50
+ }
+ }
+ rule 2658 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-213.171.217.107
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443,22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.107
+ }
+ }
+ rule 2659 {
+ action accept
+ description VPN-30791-ANY-ALLOW-10.4.88.215
+ destination {
+ group {
+ address-group DT_VPN-30791
+ }
+ }
+ source {
+ address 10.4.88.215
+ }
+ }
+ rule 2660 {
+ action accept
+ description VPN-30791-ANY-ALLOW-10.4.89.215
+ destination {
+ group {
+ address-group DT_VPN-30791
+ }
+ }
+ source {
+ address 10.4.89.215
+ }
+ }
+ rule 2661 {
+ action accept
+ description FW2EF2C_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2EF2C_1
+ }
+ port 10000,3478
+ }
+ protocol udp
+ }
+ rule 2662 {
+ action accept
+ description FW32EFF_49-TCP-ALLOW-195.217.232.0_26
+ destination {
+ group {
+ address-group DT_FW32EFF_49
+ }
+ port 5589
+ }
+ protocol tcp
+ source {
+ address 195.217.232.0/26
+ }
+ }
+ rule 2663 {
+ action accept
+ description FW4AE7D_1-TCP-ALLOW-81.136.8.24
+ destination {
+ group {
+ address-group DT_FW4AE7D_1
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 81.136.8.24
+ }
+ }
+ rule 2664 {
+ action accept
+ description FW2EF2C_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2EF2C_1
+ }
+ port 5222
+ }
+ protocol tcp_udp
+ }
+ rule 2665 {
+ action accept
+ description FW48A55_2-TCP-ALLOW-86.29.225.60
+ destination {
+ group {
+ address-group DT_FW48A55_2
+ }
+ port 443,80,22
+ }
+ protocol tcp
+ source {
+ address 86.29.225.60
+ }
+ }
+ rule 2666 {
+ action accept
+ description FW48A55_2-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW48A55_2
+ }
+ port 1337
+ }
+ protocol udp
+ }
+ rule 2667 {
+ action accept
+ description VPN-11913-ANY-ALLOW-10.4.56.191
+ destination {
+ group {
+ address-group DT_VPN-11913
+ }
+ }
+ source {
+ address 10.4.56.191
+ }
+ }
+ rule 2668 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-194.145.189.163
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 194.145.189.163
+ }
+ }
+ rule 2669 {
+ action accept
+ description FW8AFF1_7-TCP-ALLOW-109.228.0.90
+ destination {
+ group {
+ address-group DT_FW8AFF1_7
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 109.228.0.90
+ }
+ }
+ rule 2670 {
+ action accept
+ description FW8AFF1_7-TCP-ALLOW-109.228.24.66
+ destination {
+ group {
+ address-group DT_FW8AFF1_7
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 109.228.24.66
+ }
+ }
+ rule 2671 {
+ action accept
+ description VPN-11913-ANY-ALLOW-10.4.57.191
+ destination {
+ group {
+ address-group DT_VPN-11913
+ }
+ }
+ source {
+ address 10.4.57.191
+ }
+ }
+ rule 2672 {
+ action accept
+ description FW73573_2-TCP-ALLOW-86.9.185.195
+ destination {
+ group {
+ address-group DT_FW73573_2
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 86.9.185.195
+ }
+ }
+ rule 2673 {
+ action accept
+ description VPN-17558-ANY-ALLOW-10.4.87.143
+ destination {
+ group {
+ address-group DT_VPN-17558
+ }
+ }
+ source {
+ address 10.4.87.143
+ }
+ }
+ rule 2674 {
+ action accept
+ description FW748B7_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW748B7_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2675 {
+ action accept
+ description FW16375_5-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW16375_5
+ }
+ port 2082,2083,2086,2087
+ }
+ protocol tcp
+ }
+ rule 2676 {
+ action accept
+ description FW5A77C_16-TCP-ALLOW-88.98.204.68
+ destination {
+ group {
+ address-group DT_FW5A77C_16
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 88.98.204.68
+ }
+ }
+ rule 2677 {
+ action accept
+ description FW73573_1-TCP-ALLOW-86.9.185.195
+ destination {
+ group {
+ address-group DT_FW73573_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 86.9.185.195
+ }
+ }
+ rule 2678 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-194.145.190.4
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 194.145.190.4
+ }
+ }
+ rule 2679 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-140.82.112.0_20
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 140.82.112.0/20
+ }
+ }
+ rule 2680 {
+ action accept
+ description FW62858_12-ICMP-ALLOW-77.68.122.41
+ destination {
+ group {
+ address-group DT_FW62858_12
+ }
+ }
+ protocol icmp
+ source {
+ address 77.68.122.41
+ }
+ }
+ rule 2681 {
+ action accept
+ description FWB118A_1-TCP-ALLOW-147.148.96.136
+ destination {
+ group {
+ address-group DT_FWB118A_1
+ }
+ port 49152-65534,8447,8443,22,21,20
+ }
+ protocol tcp
+ source {
+ address 147.148.96.136
+ }
+ }
+ rule 2682 {
+ action accept
+ description FW5A77C_16-TCP-ALLOW-92.207.237.42
+ destination {
+ group {
+ address-group DT_FW5A77C_16
+ }
+ port 10000,22
+ }
+ protocol tcp
+ source {
+ address 92.207.237.42
+ }
+ }
+ rule 2683 {
+ action accept
+ description FW364CF_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW364CF_1
+ }
+ port 4022,8099
+ }
+ protocol tcp
+ }
+ rule 2684 {
+ action accept
+ description VPN-25822-ANY-ALLOW-10.4.54.42
+ destination {
+ group {
+ address-group DT_VPN-25822
+ }
+ }
+ source {
+ address 10.4.54.42
+ }
+ }
+ rule 2685 {
+ action accept
+ description FW7F28A_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW7F28A_1
+ }
+ port 10051,10050
+ }
+ protocol tcp
+ }
+ rule 2686 {
+ action accept
+ description FW8AFF1_7-TCP-ALLOW-109.228.53.159
+ destination {
+ group {
+ address-group DT_FW8AFF1_7
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 109.228.53.159
+ }
+ }
+ rule 2687 {
+ action accept
+ description FWE47DA_1-TCP-ALLOW-185.22.211.0_24
+ destination {
+ group {
+ address-group DT_FWE47DA_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 185.22.211.0/24
+ }
+ }
+ rule 2688 {
+ action accept
+ description FWC6301_1-TCP-ALLOW-95.34.208.4
+ destination {
+ group {
+ address-group DT_FWC6301_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 95.34.208.4
+ }
+ }
+ rule 2689 {
+ action accept
+ description FW45000_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW45000_1
+ }
+ port 990
+ }
+ protocol tcp
+ }
+ rule 2690 {
+ action accept
+ description FW481D7_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW481D7_1
+ }
+ port 6789
+ }
+ protocol tcp
+ }
+ rule 2691 {
+ action accept
+ description VPN-8203-ANY-ALLOW-10.4.59.109
+ destination {
+ group {
+ address-group DT_VPN-8203
+ }
+ }
+ source {
+ address 10.4.59.109
+ }
+ }
+ rule 2692 {
+ action accept
+ description VPN-3575-ANY-ALLOW-10.4.54.124
+ destination {
+ group {
+ address-group DT_VPN-3575
+ }
+ }
+ source {
+ address 10.4.54.124
+ }
+ }
+ rule 2693 {
+ action accept
+ description VPN-3575-ANY-ALLOW-10.4.55.125
+ destination {
+ group {
+ address-group DT_VPN-3575
+ }
+ }
+ source {
+ address 10.4.55.125
+ }
+ }
+ rule 2694 {
+ action accept
+ description FW42661_3-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW42661_3
+ }
+ port 44445,25672,15672,9876,7770-7800
+ }
+ protocol tcp
+ }
+ rule 2695 {
+ action accept
+ description FWBF494_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWBF494_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2696 {
+ action accept
+ description FWD0E22_4-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD0E22_4
+ }
+ port 8000,19005
+ }
+ protocol tcp
+ }
+ rule 2697 {
+ action accept
+ description FW98818_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW98818_1
+ }
+ port 27015
+ }
+ protocol udp
+ }
+ rule 2698 {
+ action accept
+ description FW62858_12-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW62858_12
+ }
+ port 5001,5000
+ }
+ protocol tcp
+ }
+ rule 2699 {
+ action accept
+ description VPN-34006-ANY-ALLOW-10.4.86.242
+ destination {
+ group {
+ address-group DT_VPN-34006
+ }
+ }
+ source {
+ address 10.4.86.242
+ }
+ }
+ rule 2700 {
+ action accept
+ description VPN-34006-ANY-ALLOW-10.4.87.242
+ destination {
+ group {
+ address-group DT_VPN-34006
+ }
+ }
+ source {
+ address 10.4.87.242
+ }
+ }
+ rule 2701 {
+ action accept
+ description FWF879C_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF879C_1
+ }
+ port 8888
+ }
+ protocol tcp
+ }
+ rule 2702 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-77.68.11.54
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 77.68.11.54
+ }
+ }
+ rule 2703 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-77.68.74.89
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 77.68.74.89
+ }
+ }
+ rule 2704 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-77.68.77.149
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 77.68.77.149
+ }
+ }
+ rule 2705 {
+ action accept
+ description FW8A57A_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW8A57A_1
+ }
+ port 49153,5666
+ }
+ protocol tcp
+ }
+ rule 2706 {
+ action accept
+ description FW62858_12-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW62858_12
+ }
+ port 5090,5061,5060
+ }
+ protocol tcp_udp
+ }
+ rule 2707 {
+ action accept
+ description FW62858_12-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW62858_12
+ }
+ port 9000-10999
+ }
+ protocol udp
+ }
+ rule 2708 {
+ action accept
+ description FW0E2EE_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0E2EE_1
+ }
+ port 1024-65535
+ }
+ protocol tcp_udp
+ }
+ rule 2709 {
+ action accept
+ description FWEEC75_1-TCP-ALLOW-82.5.80.210
+ destination {
+ group {
+ address-group DT_FWEEC75_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 82.5.80.210
+ }
+ }
+ rule 2710 {
+ action accept
+ description FW4F81F_4-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4F81F_4
+ }
+ port 26900,27005,27015,51000,51005,51030
+ }
+ protocol tcp_udp
+ }
+ rule 2711 {
+ action accept
+ description VPN-7902-ANY-ALLOW-10.4.56.78
+ destination {
+ group {
+ address-group DT_VPN-7902
+ }
+ }
+ source {
+ address 10.4.56.78
+ }
+ }
+ rule 2712 {
+ action accept
+ description VPN-7902-ANY-ALLOW-10.4.57.78
+ destination {
+ group {
+ address-group DT_VPN-7902
+ }
+ }
+ source {
+ address 10.4.57.78
+ }
+ }
+ rule 2713 {
+ action accept
+ description FWB36A0_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWB36A0_1
+ }
+ port 20-21,990
+ }
+ protocol tcp_udp
+ }
+ rule 2714 {
+ action accept
+ description FWD2082_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD2082_1
+ }
+ port 8001,8002
+ }
+ protocol tcp
+ }
+ rule 2715 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-212.8.242.171
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 212.8.242.171
+ }
+ }
+ rule 2716 {
+ action accept
+ description FWB9699_11-TCP-ALLOW-213.171.217.184
+ destination {
+ group {
+ address-group DT_FWB9699_11
+ }
+ port 443,80,8800,22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.184
+ }
+ }
+ rule 2717 {
+ action accept
+ description VPN-11083-ANY-ALLOW-10.4.54.186
+ destination {
+ group {
+ address-group DT_VPN-11083
+ }
+ }
+ source {
+ address 10.4.54.186
+ }
+ }
+ rule 2718 {
+ action accept
+ description VPN-11083-ANY-ALLOW-10.4.55.187
+ destination {
+ group {
+ address-group DT_VPN-11083
+ }
+ }
+ source {
+ address 10.4.55.187
+ }
+ }
+ rule 2719 {
+ action accept
+ description VPN-34583-ANY-ALLOW-10.4.86.243
+ destination {
+ group {
+ address-group DT_VPN-34583
+ }
+ }
+ source {
+ address 10.4.86.243
+ }
+ }
+ rule 2720 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-123.231.84.155
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 123.231.84.155
+ }
+ }
+ rule 2721 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.117
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.117
+ }
+ }
+ rule 2722 {
+ action accept
+ description FW7A9B0_9-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW7A9B0_9
+ }
+ port 11112
+ }
+ protocol tcp
+ }
+ rule 2723 {
+ action accept
+ description FW3F465_1-TCP-ALLOW-77.68.127.177
+ destination {
+ group {
+ address-group DT_FW3F465_1
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 77.68.127.177
+ }
+ }
+ rule 2724 {
+ action accept
+ description VPN-34583-ANY-ALLOW-10.4.87.243
+ destination {
+ group {
+ address-group DT_VPN-34583
+ }
+ }
+ source {
+ address 10.4.87.243
+ }
+ }
+ rule 2725 {
+ action accept
+ description FW930F3_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW930F3_1
+ }
+ port 9089,5900,5666,5272
+ }
+ protocol tcp
+ }
+ rule 2726 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.165
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.165
+ }
+ }
+ rule 2727 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.140
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.140
+ }
+ }
+ rule 2728 {
+ action accept
+ description FW90AE3_1-TCP-ALLOW-82.11.114.136
+ destination {
+ group {
+ address-group DT_FW90AE3_1
+ }
+ port 3306,22
+ }
+ protocol tcp
+ source {
+ address 82.11.114.136
+ }
+ }
+ rule 2729 {
+ action accept
+ description FW73215_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW73215_1
+ }
+ port 27015
+ }
+ protocol tcp_udp
+ }
+ rule 2730 {
+ action accept
+ description FWC2EF2_1-TCP-ALLOW-18.130.156.250
+ destination {
+ group {
+ address-group DT_FWC2EF2_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 18.130.156.250
+ }
+ }
+ rule 2731 {
+ action accept
+ description FWC2EF2_1-TCP-ALLOW-90.251.221.19
+ destination {
+ group {
+ address-group DT_FWC2EF2_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 90.251.221.19
+ }
+ }
+ rule 2732 {
+ action accept
+ description FW90AE3_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW90AE3_1
+ }
+ port 8765,8001,8000
+ }
+ protocol tcp
+ }
+ rule 2733 {
+ action accept
+ description FWC2EF2_1-TCP-ALLOW-87.74.110.191
+ destination {
+ group {
+ address-group DT_FWC2EF2_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 87.74.110.191
+ }
+ }
+ rule 2734 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-77.68.77.70
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 77.68.77.70
+ }
+ }
+ rule 2735 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.93
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.93
+ }
+ }
+ rule 2736 {
+ action accept
+ description FW81138_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW81138_1
+ }
+ port 123
+ }
+ protocol udp
+ }
+ rule 2737 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.208.64
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.208.64
+ }
+ }
+ rule 2738 {
+ action accept
+ description FW03B35_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW03B35_1
+ }
+ port 1-65535
+ }
+ protocol tcp_udp
+ }
+ rule 2739 {
+ action accept
+ description VPN-19807-ANY-ALLOW-10.4.87.172
+ destination {
+ group {
+ address-group DT_VPN-19807
+ }
+ }
+ source {
+ address 10.4.87.172
+ }
+ }
+ rule 2740 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-94.12.73.154
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 8447
+ }
+ protocol tcp
+ source {
+ address 94.12.73.154
+ }
+ }
+ rule 2741 {
+ action accept
+ description FW5658C_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW5658C_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2742 {
+ action accept
+ description FW0B352_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0B352_1
+ }
+ port 3443
+ }
+ protocol tcp_udp
+ }
+ rule 2743 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-77.68.8.74
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 3389,445,443
+ }
+ protocol tcp
+ source {
+ address 77.68.8.74
+ }
+ }
+ rule 2744 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-77.68.92.33
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 77.68.92.33
+ }
+ }
+ rule 2745 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-77.68.93.82
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 77.68.93.82
+ }
+ }
+ rule 2746 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.44
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.44
+ }
+ }
+ rule 2747 {
+ action accept
+ description FW34C91_3-TCP-ALLOW-188.220.176.104
+ destination {
+ group {
+ address-group DT_FW34C91_3
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 188.220.176.104
+ }
+ }
+ rule 2748 {
+ action accept
+ description FW3F465_1-TCP-ALLOW-77.68.16.101
+ destination {
+ group {
+ address-group DT_FW3F465_1
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 77.68.16.101
+ }
+ }
+ rule 2749 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-87.224.33.215
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 3389,445,443
+ }
+ protocol tcp
+ source {
+ address 87.224.33.215
+ }
+ }
+ rule 2750 {
+ action accept
+ description FW34C91_3-UDP-ALLOW-188.220.176.104
+ destination {
+ group {
+ address-group DT_FW34C91_3
+ }
+ port 1434
+ }
+ protocol udp
+ source {
+ address 188.220.176.104
+ }
+ }
+ rule 2751 {
+ action accept
+ description FWE47DA_1-TCP-ALLOW-185.22.208.0_25
+ destination {
+ group {
+ address-group DT_FWE47DA_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 185.22.208.0/25
+ }
+ }
+ rule 2752 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.187
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.187
+ }
+ }
+ rule 2753 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.84
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.84
+ }
+ }
+ rule 2754 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-116.206.246.52
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 116.206.246.52
+ }
+ }
+ rule 2755 {
+ action accept
+ description FW8AFF1_7-TCP-ALLOW-77.68.92.154
+ destination {
+ group {
+ address-group DT_FW8AFF1_7
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 77.68.92.154
+ }
+ }
+ rule 2756 {
+ action accept
+ description FW8AFF1_7-TCP-ALLOW-77.68.93.156
+ destination {
+ group {
+ address-group DT_FW8AFF1_7
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 77.68.93.156
+ }
+ }
+ rule 2757 {
+ action accept
+ description VPN-24398-ANY-ALLOW-10.4.88.151
+ destination {
+ group {
+ address-group DT_VPN-24398
+ }
+ }
+ source {
+ address 10.4.88.151
+ }
+ }
+ rule 2758 {
+ action accept
+ description VPN-24398-ANY-ALLOW-10.4.89.151
+ destination {
+ group {
+ address-group DT_VPN-24398
+ }
+ }
+ source {
+ address 10.4.89.151
+ }
+ }
+ rule 2759 {
+ action accept
+ description VPN-24589-ANY-ALLOW-10.4.56.9
+ destination {
+ group {
+ address-group DT_VPN-24589
+ }
+ }
+ source {
+ address 10.4.56.9
+ }
+ }
+ rule 2760 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.29
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.29
+ }
+ }
+ rule 2761 {
+ action accept
+ description FWC7D36_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC7D36_1
+ }
+ port 27017,11080
+ }
+ protocol tcp
+ }
+ rule 2762 {
+ action accept
+ description FWBB718_1-TCP_UDP-ALLOW-77.68.73.116
+ destination {
+ group {
+ address-group DT_FWBB718_1
+ }
+ port 1433
+ }
+ protocol tcp_udp
+ source {
+ address 77.68.73.116
+ }
+ }
+ rule 2763 {
+ action accept
+ description FWBB718_1-UDP-ALLOW-77.68.73.116
+ destination {
+ group {
+ address-group DT_FWBB718_1
+ }
+ port 1434
+ }
+ protocol udp
+ source {
+ address 77.68.73.116
+ }
+ }
+ rule 2764 {
+ action accept
+ description FWB9699_11-TCP-ALLOW-213.171.217.102
+ destination {
+ group {
+ address-group DT_FWB9699_11
+ }
+ port 22,80,443,8800
+ }
+ protocol tcp
+ source {
+ address 213.171.217.102
+ }
+ }
+ rule 2765 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-103.8.164.5
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 103.8.164.5
+ }
+ }
+ rule 2766 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.193
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.193
+ }
+ }
+ rule 2768 {
+ action accept
+ description FW26F0A_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW26F0A_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 2769 {
+ action accept
+ description FWCC18F_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWCC18F_2
+ }
+ port 8883,1883
+ }
+ protocol tcp
+ }
+ rule 2771 {
+ action accept
+ description FW633DD_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW633DD_1
+ }
+ port 28967,14002,9984,9983,9982,9981,8888,8884
+ }
+ protocol tcp
+ }
+ rule 2772 {
+ action accept
+ description FWDEDB9_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWDEDB9_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2773 {
+ action accept
+ description VPN-18646-ANY-ALLOW-10.4.88.109
+ destination {
+ group {
+ address-group DT_VPN-18646
+ }
+ }
+ source {
+ address 10.4.88.109
+ }
+ }
+ rule 2774 {
+ action accept
+ description VPN-18646-ANY-ALLOW-10.4.89.109
+ destination {
+ group {
+ address-group DT_VPN-18646
+ }
+ }
+ source {
+ address 10.4.89.109
+ }
+ }
+ rule 2775 {
+ action accept
+ description FWA0531_1-TCP-ALLOW-87.224.39.221
+ destination {
+ group {
+ address-group DT_FWA0531_1
+ }
+ port 8082,3003,22
+ }
+ protocol tcp
+ source {
+ address 87.224.39.221
+ }
+ }
+ rule 2776 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.94
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.94
+ }
+ }
+ rule 2777 {
+ action accept
+ description FWA0531_1-TCP-ALLOW-92.237.97.92
+ destination {
+ group {
+ address-group DT_FWA0531_1
+ }
+ port 8082,3003,22
+ }
+ protocol tcp
+ source {
+ address 92.237.97.92
+ }
+ }
+ rule 2778 {
+ action accept
+ description VPN-25822-ANY-ALLOW-10.4.55.42
+ destination {
+ group {
+ address-group DT_VPN-25822
+ }
+ }
+ source {
+ address 10.4.55.42
+ }
+ }
+ rule 2779 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.88
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.88
+ }
+ }
+ rule 2780 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-143.55.64.0_20
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 143.55.64.0/20
+ }
+ }
+ rule 2781 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-194.176.78.206
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 194.176.78.206
+ }
+ }
+ rule 2782 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-195.243.221.50
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 195.243.221.50
+ }
+ }
+ rule 2783 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-213.171.217.107
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.107
+ }
+ }
+ rule 2784 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-81.150.168.54
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 3306,22
+ }
+ protocol tcp
+ source {
+ address 81.150.168.54
+ }
+ }
+ rule 2785 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-89.197.133.235
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 89.197.133.235
+ }
+ }
+ rule 2786 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 60000-60100,873
+ }
+ protocol tcp
+ }
+ rule 2787 {
+ action accept
+ description FW2BF20_3-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2BF20_3
+ }
+ port 49152-65534,990
+ }
+ protocol tcp
+ }
+ rule 2788 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.98
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.98
+ }
+ }
+ rule 2789 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.65
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.65
+ }
+ }
+ rule 2791 {
+ action accept
+ description FW197DB_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW197DB_1
+ }
+ port 49152-65534
+ }
+ protocol tcp
+ }
+ rule 2792 {
+ action accept
+ description FW1208C_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1208C_1
+ }
+ port 2087,2083,2096
+ }
+ protocol tcp
+ }
+ rule 2793 {
+ action accept
+ description FW00D98_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW00D98_1
+ }
+ port 4430
+ }
+ protocol tcp
+ }
+ rule 2794 {
+ action accept
+ description FW03B35_1-ESP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW03B35_1
+ }
+ }
+ protocol esp
+ }
+ rule 2795 {
+ action accept
+ description FW03B35_1-AH-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW03B35_1
+ }
+ }
+ protocol ah
+ }
+ rule 2796 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-87.224.6.174
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 3389,445,443
+ }
+ protocol tcp
+ source {
+ address 87.224.6.174
+ }
+ }
+ rule 2797 {
+ action accept
+ description FW825C8_19-TCP-ALLOW-159.253.51.74
+ destination {
+ group {
+ address-group DT_FW825C8_19
+ }
+ port 3389,1433,995
+ }
+ protocol tcp
+ source {
+ address 159.253.51.74
+ }
+ }
+ rule 2798 {
+ action accept
+ description FW825C8_19-TCP-ALLOW-77.68.76.111
+ destination {
+ group {
+ address-group DT_FW825C8_19
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 77.68.76.111
+ }
+ }
+ rule 2799 {
+ action accept
+ description FW825C8_19-TCP-ALLOW-77.68.28.63
+ destination {
+ group {
+ address-group DT_FW825C8_19
+ }
+ port 995
+ }
+ protocol tcp
+ source {
+ address 77.68.28.63
+ }
+ }
+ rule 2801 {
+ action accept
+ description FW2EF2C_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2EF2C_1
+ }
+ port 5349
+ }
+ protocol tcp
+ }
+ rule 2802 {
+ action accept
+ description FWEF92E_5-TCP-ALLOW-88.208.198.93
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 88.208.198.93
+ }
+ }
+ rule 2803 {
+ action accept
+ description FWC3921_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC3921_1
+ }
+ port 25000,25001-25005,26000-26006
+ }
+ protocol tcp
+ }
+ rule 2804 {
+ action accept
+ description FWEF92E_5-UDP-ALLOW-109.228.37.19
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 500
+ }
+ protocol udp
+ source {
+ address 109.228.37.19
+ }
+ }
+ rule 2805 {
+ action accept
+ description FWEF92E_5-UDP-ALLOW-77.68.11.54
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 500
+ }
+ protocol udp
+ source {
+ address 77.68.11.54
+ }
+ }
+ rule 2806 {
+ action accept
+ description FW5AE10_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW5AE10_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 2810 {
+ action accept
+ description FW45F87_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW45F87_1
+ }
+ port 60000-60100
+ }
+ protocol tcp
+ }
+ rule 2811 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-123.231.108.158
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 123.231.108.158
+ }
+ }
+ rule 2813 {
+ action accept
+ description FW825C8_19-TCP-ALLOW-109.228.1.233
+ destination {
+ group {
+ address-group DT_FW825C8_19
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 109.228.1.233
+ }
+ }
+ rule 2814 {
+ action accept
+ description FW20449_2-ICMP-ALLOW-3.10.221.168
+ destination {
+ group {
+ address-group DT_FW20449_2
+ }
+ }
+ protocol icmp
+ source {
+ address 3.10.221.168
+ }
+ }
+ rule 2815 {
+ action accept
+ description FWB9699_7-TCP-ALLOW-213.171.217.100
+ destination {
+ group {
+ address-group DT_FWB9699_7
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.100
+ }
+ }
+ rule 2816 {
+ action accept
+ description FWB9699_7-TCP-ALLOW-213.171.217.180
+ destination {
+ group {
+ address-group DT_FWB9699_7
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.180
+ }
+ }
+ rule 2817 {
+ action accept
+ description FWB9699_7-TCP-ALLOW-213.171.217.184
+ destination {
+ group {
+ address-group DT_FWB9699_7
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.184
+ }
+ }
+ rule 2818 {
+ action accept
+ description FWB9699_7-TCP-ALLOW-213.171.217.185
+ destination {
+ group {
+ address-group DT_FWB9699_7
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.185
+ }
+ }
+ rule 2819 {
+ action accept
+ description FWB9699_7-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWB9699_7
+ }
+ port 161
+ }
+ protocol udp
+ }
+ rule 2820 {
+ action accept
+ description FWB9699_7-TCP-ALLOW-213.171.217.102
+ destination {
+ group {
+ address-group DT_FWB9699_7
+ }
+ port 22,8443
+ }
+ protocol tcp
+ source {
+ address 213.171.217.102
+ }
+ }
+ rule 2821 {
+ action accept
+ description FWB9699_7-TCP-ALLOW-213.171.217.103
+ destination {
+ group {
+ address-group DT_FWB9699_7
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 213.171.217.103
+ }
+ }
+ rule 2824 {
+ action accept
+ description FWE3E77_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE3E77_1
+ }
+ port 10010,10009
+ }
+ protocol tcp
+ }
+ rule 2825 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-93.190.142.120
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 93.190.142.120
+ }
+ }
+ rule 2826 {
+ action accept
+ description FW20449_2-ICMP-ALLOW-82.20.69.137
+ destination {
+ group {
+ address-group DT_FW20449_2
+ }
+ }
+ protocol icmp
+ source {
+ address 82.20.69.137
+ }
+ }
+ rule 2827 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-46.101.232.93
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 21-10000
+ }
+ protocol tcp
+ source {
+ address 46.101.232.93
+ }
+ }
+ rule 2828 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.5
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.5
+ }
+ }
+ rule 2829 {
+ action accept
+ description FWD2440_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD2440_1
+ }
+ port 1-65535
+ }
+ protocol tcp
+ }
+ rule 2831 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.105
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.105
+ }
+ }
+ rule 2833 {
+ action accept
+ description FW825C8_24-TCP-ALLOW-159.253.51.74
+ destination {
+ group {
+ address-group DT_FW825C8_24
+ }
+ port 3389,1433,995
+ }
+ protocol tcp
+ source {
+ address 159.253.51.74
+ }
+ }
+ rule 2834 {
+ action accept
+ description FW825C8_24-TCP-ALLOW-77.68.77.120
+ destination {
+ group {
+ address-group DT_FW825C8_24
+ }
+ port 1433
+ }
+ protocol tcp
+ source {
+ address 77.68.77.120
+ }
+ }
+ rule 2839 {
+ action accept
+ description FWD2440_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD2440_1
+ }
+ port 1-65535
+ }
+ protocol udp
+ }
+ rule 2840 {
+ action accept
+ description FW1C8F2_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1C8F2_1
+ }
+ port 7000-10000,5554,5443,5080,1935,1111
+ }
+ protocol tcp
+ }
+ rule 2843 {
+ action accept
+ description FWE7180_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE7180_1
+ }
+ port 443,53
+ }
+ protocol tcp_udp
+ }
+ rule 2844 {
+ action accept
+ description FWC6301_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC6301_1
+ }
+ port 2456
+ }
+ protocol tcp_udp
+ }
+ rule 2845 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.113
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.113
+ }
+ }
+ rule 2846 {
+ action accept
+ description VPN-24589-ANY-ALLOW-10.4.57.9
+ destination {
+ group {
+ address-group DT_VPN-24589
+ }
+ }
+ source {
+ address 10.4.57.9
+ }
+ }
+ rule 2847 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.237
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.237
+ }
+ }
+ rule 2849 {
+ action accept
+ description FWFD9AF_9-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWFD9AF_9
+ }
+ port 445
+ }
+ protocol tcp_udp
+ }
+ rule 2850 {
+ action accept
+ description VPN-23209-ANY-ALLOW-10.4.58.8
+ destination {
+ group {
+ address-group DT_VPN-23209
+ }
+ }
+ source {
+ address 10.4.58.8
+ }
+ }
+ rule 2851 {
+ action accept
+ description VPN-23209-ANY-ALLOW-10.4.59.8
+ destination {
+ group {
+ address-group DT_VPN-23209
+ }
+ }
+ source {
+ address 10.4.59.8
+ }
+ }
+ rule 2853 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.29
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.29
+ }
+ }
+ rule 2854 {
+ action accept
+ description FW16375_5-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW16375_5
+ }
+ port 2096
+ }
+ protocol tcp_udp
+ }
+ rule 2856 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.173
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.173
+ }
+ }
+ rule 2858 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.208.35
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.208.35
+ }
+ }
+ rule 2859 {
+ action accept
+ description FW73573_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW73573_1
+ }
+ port 25
+ }
+ protocol tcp_udp
+ }
+ rule 2860 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-148.253.173.242
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 148.253.173.242
+ }
+ }
+ rule 2861 {
+ action accept
+ description FW8ECF4_1-TCP-ALLOW-77.68.2.215
+ destination {
+ group {
+ address-group DT_FW8ECF4_1
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 77.68.2.215
+ }
+ }
+ rule 2862 {
+ action accept
+ description FW8A3FC_3-TCP_UDP-ALLOW-82.165.100.25
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 21-10000
+ }
+ protocol tcp_udp
+ source {
+ address 82.165.100.25
+ }
+ }
+ rule 2863 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.235
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.235
+ }
+ }
+ rule 2864 {
+ action accept
+ description VPN-18647-ANY-ALLOW-10.4.86.114
+ destination {
+ group {
+ address-group DT_VPN-18647
+ }
+ }
+ source {
+ address 10.4.86.114
+ }
+ }
+ rule 2865 {
+ action accept
+ description VPN-18647-ANY-ALLOW-10.4.87.114
+ destination {
+ group {
+ address-group DT_VPN-18647
+ }
+ }
+ source {
+ address 10.4.87.114
+ }
+ }
+ rule 2867 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.107
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.107
+ }
+ }
+ rule 2868 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.208.239
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.208.239
+ }
+ }
+ rule 2869 {
+ action accept
+ description FWF699D_4-TCP-ALLOW-164.39.151.3
+ destination {
+ group {
+ address-group DT_FWF699D_4
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 164.39.151.3
+ }
+ }
+ rule 2870 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.245
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.245
+ }
+ }
+ rule 2873 {
+ action accept
+ description FWEF92E_6-TCP-ALLOW-87.224.6.174
+ destination {
+ group {
+ address-group DT_FWEF92E_6
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 87.224.6.174
+ }
+ }
+ rule 2874 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.130
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.130
+ }
+ }
+ rule 2875 {
+ action accept
+ description FW44BF9_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW44BF9_1
+ }
+ port 49160-49200
+ }
+ protocol tcp
+ }
+ rule 2876 {
+ action accept
+ description VPN-24591-ANY-ALLOW-10.4.86.4
+ destination {
+ group {
+ address-group DT_VPN-24591
+ }
+ }
+ source {
+ address 10.4.86.4
+ }
+ }
+ rule 2877 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.60
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.60
+ }
+ }
+ rule 2879 {
+ action accept
+ description FWEF92E_6-UDP-ALLOW-77.68.77.57
+ destination {
+ group {
+ address-group DT_FWEF92E_6
+ }
+ port 500
+ }
+ protocol udp
+ source {
+ address 77.68.77.57
+ }
+ }
+ rule 2880 {
+ action accept
+ description FWF699D_4-TCP-ALLOW-185.132.38.110
+ destination {
+ group {
+ address-group DT_FWF699D_4
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 185.132.38.110
+ }
+ }
+ rule 2881 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.208.216
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.208.216
+ }
+ }
+ rule 2882 {
+ action accept
+ description FWEF92E_5-UDP-ALLOW-77.68.77.149
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 500
+ }
+ protocol udp
+ source {
+ address 77.68.77.149
+ }
+ }
+ rule 2883 {
+ action accept
+ description FWA2FF8_4-TCP-ALLOW-80.229.18.102
+ destination {
+ group {
+ address-group DT_FWA2FF8_4
+ }
+ port 3306,21,22
+ }
+ protocol tcp
+ source {
+ address 80.229.18.102
+ }
+ }
+ rule 2884 {
+ action accept
+ description FWA2FF8_4-TCP-ALLOW-109.169.33.69
+ destination {
+ group {
+ address-group DT_FWA2FF8_4
+ }
+ port 3306,21,22
+ }
+ protocol tcp
+ source {
+ address 109.169.33.69
+ }
+ }
+ rule 2885 {
+ action accept
+ description FWA2FF8_4-TCP-ALLOW-46.102.209.35
+ destination {
+ group {
+ address-group DT_FWA2FF8_4
+ }
+ port 3306,21
+ }
+ protocol tcp
+ source {
+ address 46.102.209.35
+ }
+ }
+ rule 2886 {
+ action accept
+ description FWA2FF8_4-TCP-ALLOW-90.213.48.16
+ destination {
+ group {
+ address-group DT_FWA2FF8_4
+ }
+ port 3306,21
+ }
+ protocol tcp
+ source {
+ address 90.213.48.16
+ }
+ }
+ rule 2887 {
+ action accept
+ description FWA2FF8_4-TCP-ALLOW-77.68.76.129
+ destination {
+ group {
+ address-group DT_FWA2FF8_4
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 77.68.76.129
+ }
+ }
+ rule 2888 {
+ action accept
+ description FWA2FF8_4-TCP-ALLOW-109.228.50.145
+ destination {
+ group {
+ address-group DT_FWA2FF8_4
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 109.228.50.145
+ }
+ }
+ rule 2889 {
+ action accept
+ description FWA2FF8_4-TCP-ALLOW-77.68.76.231
+ destination {
+ group {
+ address-group DT_FWA2FF8_4
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 77.68.76.231
+ }
+ }
+ rule 2890 {
+ action accept
+ description FW4513E_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4513E_1
+ }
+ port 50000-50020,990
+ }
+ protocol tcp
+ }
+ rule 2893 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-175.157.40.7
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 175.157.40.7
+ }
+ }
+ rule 2894 {
+ action accept
+ description VPN-21876-ANY-ALLOW-10.4.88.96
+ destination {
+ group {
+ address-group DT_VPN-21876
+ }
+ }
+ source {
+ address 10.4.88.96
+ }
+ }
+ rule 2895 {
+ action accept
+ description VPN-21876-ANY-ALLOW-10.4.89.96
+ destination {
+ group {
+ address-group DT_VPN-21876
+ }
+ }
+ source {
+ address 10.4.89.96
+ }
+ }
+ rule 2896 {
+ action accept
+ description VPN-26124-ANY-ALLOW-10.4.54.75
+ destination {
+ group {
+ address-group DT_VPN-26124
+ }
+ }
+ source {
+ address 10.4.54.75
+ }
+ }
+ rule 2897 {
+ action accept
+ description VPN-26124-ANY-ALLOW-10.4.55.76
+ destination {
+ group {
+ address-group DT_VPN-26124
+ }
+ }
+ source {
+ address 10.4.55.76
+ }
+ }
+ rule 2898 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.21
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.21
+ }
+ }
+ rule 2899 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.213
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.213
+ }
+ }
+ rule 2901 {
+ action accept
+ description FWC6301_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC6301_1
+ }
+ port 5555
+ }
+ protocol udp
+ }
+ rule 2902 {
+ action accept
+ description VPN-13261-ANY-ALLOW-10.4.56.173
+ destination {
+ group {
+ address-group DT_VPN-13261
+ }
+ }
+ source {
+ address 10.4.56.173
+ }
+ }
+ rule 2903 {
+ action accept
+ description VPN-13261-ANY-ALLOW-10.4.57.173
+ destination {
+ group {
+ address-group DT_VPN-13261
+ }
+ }
+ source {
+ address 10.4.57.173
+ }
+ }
+ rule 2909 {
+ action accept
+ description VPN-24591-ANY-ALLOW-10.4.87.4
+ destination {
+ group {
+ address-group DT_VPN-24591
+ }
+ }
+ source {
+ address 10.4.87.4
+ }
+ }
+ rule 2911 {
+ action accept
+ description FWE7180_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE7180_1
+ }
+ port 40110-40210,8090
+ }
+ protocol tcp
+ }
+ rule 2914 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.247
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.247
+ }
+ }
+ rule 2915 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.129
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.129
+ }
+ }
+ rule 2916 {
+ action accept
+ description FWCB29D_1-TCP-ALLOW-51.146.16.162
+ destination {
+ group {
+ address-group DT_FWCB29D_1
+ }
+ port 8447,8443,22
+ }
+ protocol tcp
+ source {
+ address 51.146.16.162
+ }
+ }
+ rule 2917 {
+ action accept
+ description FW4E399_1-TCP-ALLOW-51.155.19.77
+ destination {
+ group {
+ address-group DT_FW4E399_1
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 51.155.19.77
+ }
+ }
+ rule 2919 {
+ action accept
+ description FWC72E5_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC72E5_1
+ }
+ port 9000-9100,6667
+ }
+ protocol tcp
+ }
+ rule 2922 {
+ action accept
+ description FW21A75_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW21A75_2
+ }
+ port 3000
+ }
+ protocol tcp
+ }
+ rule 2923 {
+ action accept
+ description FW3B068_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW3B068_2
+ }
+ port 990,60000-65000
+ }
+ protocol tcp
+ }
+ rule 2924 {
+ action accept
+ description FW48814_3-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW48814_3
+ }
+ port 3306
+ }
+ protocol tcp_udp
+ }
+ rule 2925 {
+ action accept
+ description FW48814_3-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW48814_3
+ }
+ port 49152-65534
+ }
+ protocol tcp
+ }
+ rule 2926 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-178.128.39.210
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 178.128.39.210
+ }
+ }
+ rule 2927 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-82.165.232.19
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 82.165.232.19
+ }
+ }
+ rule 2928 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-84.64.186.31
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 84.64.186.31
+ }
+ }
+ rule 2929 {
+ action accept
+ description FW1C8F2_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1C8F2_1
+ }
+ port 5000-65000
+ }
+ protocol udp
+ }
+ rule 2930 {
+ action accept
+ description FW2B279_4-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2B279_4
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2931 {
+ action accept
+ description FW608FA_1-TCP-ALLOW-195.10.106.114
+ destination {
+ group {
+ address-group DT_FW608FA_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 195.10.106.114
+ }
+ }
+ rule 2932 {
+ action accept
+ description FW608FA_1-TCP-ALLOW-213.137.25.134
+ destination {
+ group {
+ address-group DT_FW608FA_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 213.137.25.134
+ }
+ }
+ rule 2933 {
+ action accept
+ description FW608FA_1-TCP-ALLOW-92.39.202.189
+ destination {
+ group {
+ address-group DT_FW608FA_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 92.39.202.189
+ }
+ }
+ rule 2935 {
+ action accept
+ description FWC37B9_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC37B9_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 2936 {
+ action accept
+ description FW15C99_6-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW15C99_6
+ }
+ port 32410-32414,1900
+ }
+ protocol udp
+ }
+ rule 2937 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-116.206.244.146
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 116.206.244.146
+ }
+ }
+ rule 2938 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.158
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.158
+ }
+ }
+ rule 2939 {
+ action accept
+ description FW15C99_6-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW15C99_6
+ }
+ port 32469,32400
+ }
+ protocol tcp
+ }
+ rule 2940 {
+ action accept
+ description FW0192C_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0192C_1
+ }
+ port 2053
+ }
+ protocol tcp
+ }
+ rule 2941 {
+ action accept
+ description FW27949_2-TCP-ALLOW-86.179.23.119
+ destination {
+ group {
+ address-group DT_FW27949_2
+ }
+ port 443,80
+ }
+ protocol tcp
+ source {
+ address 86.179.23.119
+ }
+ }
+ rule 2942 {
+ action accept
+ description FW27949_2-TCP-ALLOW-92.15.208.193
+ destination {
+ group {
+ address-group DT_FW27949_2
+ }
+ port 443,80
+ }
+ protocol tcp
+ source {
+ address 92.15.208.193
+ }
+ }
+ rule 2943 {
+ action accept
+ description VPN-34122-ANY-ALLOW-10.4.56.122
+ destination {
+ group {
+ address-group DT_VPN-34122
+ }
+ }
+ source {
+ address 10.4.56.122
+ }
+ }
+ rule 2944 {
+ action accept
+ description VPN-34122-ANY-ALLOW-10.4.57.122
+ destination {
+ group {
+ address-group DT_VPN-34122
+ }
+ }
+ source {
+ address 10.4.57.122
+ }
+ }
+ rule 2945 {
+ action accept
+ description FWF323F_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF323F_1
+ }
+ port 25565,9999,8080,5001,3306
+ }
+ protocol tcp_udp
+ }
+ rule 2946 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.132
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.132
+ }
+ }
+ rule 2948 {
+ action accept
+ description VPN-30261-ANY-ALLOW-10.4.86.110
+ destination {
+ group {
+ address-group DT_VPN-30261
+ }
+ }
+ source {
+ address 10.4.86.110
+ }
+ }
+ rule 2949 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.246
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.246
+ }
+ }
+ rule 2951 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-157.231.100.222
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 157.231.100.222
+ }
+ }
+ rule 2952 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-164.39.131.31
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 164.39.131.31
+ }
+ }
+ rule 2953 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-185.199.108.0_22
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 185.199.108.0/22
+ }
+ }
+ rule 2954 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-192.30.252.0_22
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 192.30.252.0/22
+ }
+ }
+ rule 2955 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-80.252.78.202
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 80.252.78.202
+ }
+ }
+ rule 2956 {
+ action accept
+ description FWC2D30_1-TCP-ALLOW-86.15.158.234
+ destination {
+ group {
+ address-group DT_FWC2D30_1
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 86.15.158.234
+ }
+ }
+ rule 2957 {
+ action accept
+ description VPN-30261-ANY-ALLOW-10.4.87.110
+ destination {
+ group {
+ address-group DT_VPN-30261
+ }
+ }
+ source {
+ address 10.4.87.110
+ }
+ }
+ rule 2958 {
+ action accept
+ description VPN-30262-ANY-ALLOW-10.4.88.36
+ destination {
+ group {
+ address-group DT_VPN-30262
+ }
+ }
+ source {
+ address 10.4.88.36
+ }
+ }
+ rule 2961 {
+ action accept
+ description VPN-15950-ANY-ALLOW-10.4.88.89
+ destination {
+ group {
+ address-group DT_VPN-15950
+ }
+ }
+ source {
+ address 10.4.88.89
+ }
+ }
+ rule 2962 {
+ action accept
+ description FWBFDED_1-TCP-ALLOW-78.141.24.164
+ destination {
+ group {
+ address-group DT_FWBFDED_1
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 78.141.24.164
+ }
+ }
+ rule 2963 {
+ action accept
+ description VPN-30262-ANY-ALLOW-10.4.89.36
+ destination {
+ group {
+ address-group DT_VPN-30262
+ }
+ }
+ source {
+ address 10.4.89.36
+ }
+ }
+ rule 2964 {
+ action accept
+ description FW1F126_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1F126_1
+ }
+ port 2087,2083
+ }
+ protocol tcp
+ }
+ rule 2965 {
+ action accept
+ description FWA7A50_1-ANY-ALLOW-40.120.53.80
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ }
+ source {
+ address 40.120.53.80
+ }
+ }
+ rule 2967 {
+ action accept
+ description VPN-23729-ANY-ALLOW-10.4.54.10
+ destination {
+ group {
+ address-group DT_VPN-23729
+ }
+ }
+ source {
+ address 10.4.54.10
+ }
+ }
+ rule 2968 {
+ action accept
+ description VPN-23729-ANY-ALLOW-10.4.55.10
+ destination {
+ group {
+ address-group DT_VPN-23729
+ }
+ }
+ source {
+ address 10.4.55.10
+ }
+ }
+ rule 2969 {
+ action accept
+ description VPN-23733-ANY-ALLOW-10.4.58.12
+ destination {
+ group {
+ address-group DT_VPN-23733
+ }
+ }
+ source {
+ address 10.4.58.12
+ }
+ }
+ rule 2970 {
+ action accept
+ description VPN-23733-ANY-ALLOW-10.4.59.12
+ destination {
+ group {
+ address-group DT_VPN-23733
+ }
+ }
+ source {
+ address 10.4.59.12
+ }
+ }
+ rule 2971 {
+ action accept
+ description VPN-23734-ANY-ALLOW-10.4.56.29
+ destination {
+ group {
+ address-group DT_VPN-23734
+ }
+ }
+ source {
+ address 10.4.56.29
+ }
+ }
+ rule 2972 {
+ action accept
+ description VPN-23734-ANY-ALLOW-10.4.57.29
+ destination {
+ group {
+ address-group DT_VPN-23734
+ }
+ }
+ source {
+ address 10.4.57.29
+ }
+ }
+ rule 2975 {
+ action accept
+ description VPN-23738-ANY-ALLOW-10.4.57.13
+ destination {
+ group {
+ address-group DT_VPN-23738
+ }
+ }
+ source {
+ address 10.4.57.13
+ }
+ }
+ rule 2976 {
+ action accept
+ description FWD8DD1_2-TCP-ALLOW-77.153.164.226
+ destination {
+ group {
+ address-group DT_FWD8DD1_2
+ }
+ port 3306,22
+ }
+ protocol tcp
+ source {
+ address 77.153.164.226
+ }
+ }
+ rule 2977 {
+ action accept
+ description FWE012D_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE012D_1
+ }
+ port 143,25
+ }
+ protocol tcp_udp
+ }
+ rule 2978 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-123.231.120.196
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 123.231.120.196
+ }
+ }
+ rule 2981 {
+ action accept
+ description FW24AB7_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW24AB7_1
+ }
+ port 40110-40210
+ }
+ protocol tcp_udp
+ }
+ rule 2985 {
+ action accept
+ description FW2379F_14-TCP-ALLOW-194.72.140.178
+ destination {
+ group {
+ address-group DT_FW2379F_14
+ }
+ port 3389,21
+ }
+ protocol tcp
+ source {
+ address 194.72.140.178
+ }
+ }
+ rule 2986 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.97
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.97
+ }
+ }
+ rule 2988 {
+ action accept
+ description FW883EB_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW883EB_1
+ }
+ port 5005,5004,5003,5002,5001
+ }
+ protocol tcp
+ }
+ rule 2992 {
+ action accept
+ description FW310C6_3-ANY-ALLOW-62.30.207.232
+ destination {
+ group {
+ address-group DT_FW310C6_3
+ }
+ }
+ source {
+ address 62.30.207.232
+ }
+ }
+ rule 2993 {
+ action accept
+ description VPN-15950-ANY-ALLOW-10.4.89.89
+ destination {
+ group {
+ address-group DT_VPN-15950
+ }
+ }
+ source {
+ address 10.4.89.89
+ }
+ }
+ rule 2994 {
+ action accept
+ description VPN-15960-ANY-ALLOW-10.4.88.90
+ destination {
+ group {
+ address-group DT_VPN-15960
+ }
+ }
+ source {
+ address 10.4.88.90
+ }
+ }
+ rule 2995 {
+ action accept
+ description FWEF92E_7-UDP-ALLOW-77.68.77.57
+ destination {
+ group {
+ address-group DT_FWEF92E_7
+ }
+ port 500
+ }
+ protocol udp
+ source {
+ address 77.68.77.57
+ }
+ }
+ rule 2996 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.135
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.135
+ }
+ }
+ rule 2998 {
+ action accept
+ description VPN-31002-ANY-ALLOW-10.4.88.126
+ destination {
+ group {
+ address-group DT_VPN-31002
+ }
+ }
+ source {
+ address 10.4.88.126
+ }
+ }
+ rule 2999 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-116.206.246.110
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 116.206.246.110
+ }
+ }
+ rule 3000 {
+ action accept
+ description FW08061_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW08061_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 3001 {
+ action accept
+ description VPN-15960-ANY-ALLOW-10.4.89.90
+ destination {
+ group {
+ address-group DT_VPN-15960
+ }
+ }
+ source {
+ address 10.4.89.90
+ }
+ }
+ rule 3003 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.56
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.56
+ }
+ }
+ rule 3004 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-175.157.47.47
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 175.157.47.47
+ }
+ }
+ rule 3005 {
+ action accept
+ description FW10C3D_19-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW10C3D_19
+ }
+ port 49152-65535,14147
+ }
+ protocol tcp
+ }
+ rule 3006 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.136
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.136
+ }
+ }
+ rule 3009 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-175.157.44.109
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 175.157.44.109
+ }
+ }
+ rule 3010 {
+ action accept
+ description VPN-24592-ANY-ALLOW-10.4.88.9
+ destination {
+ group {
+ address-group DT_VPN-24592
+ }
+ }
+ source {
+ address 10.4.88.9
+ }
+ }
+ rule 3011 {
+ action accept
+ description FW05AD0_2-TCP-ALLOW-213.171.209.161
+ destination {
+ group {
+ address-group DT_FW05AD0_2
+ }
+ port 3389,1433,21
+ }
+ protocol tcp
+ source {
+ address 213.171.209.161
+ }
+ }
+ rule 3012 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-123.231.86.254
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 123.231.86.254
+ }
+ }
+ rule 3014 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.16
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.16
+ }
+ }
+ rule 3018 {
+ action accept
+ description VPN-24592-ANY-ALLOW-10.4.89.9
+ destination {
+ group {
+ address-group DT_VPN-24592
+ }
+ }
+ source {
+ address 10.4.89.9
+ }
+ }
+ rule 3019 {
+ action accept
+ description VPN-24593-ANY-ALLOW-10.4.54.6
+ destination {
+ group {
+ address-group DT_VPN-24593
+ }
+ }
+ source {
+ address 10.4.54.6
+ }
+ }
+ rule 3020 {
+ action accept
+ description VPN-24593-ANY-ALLOW-10.4.55.6
+ destination {
+ group {
+ address-group DT_VPN-24593
+ }
+ }
+ source {
+ address 10.4.55.6
+ }
+ }
+ rule 3021 {
+ action accept
+ description VPN-24594-ANY-ALLOW-10.4.58.6
+ destination {
+ group {
+ address-group DT_VPN-24594
+ }
+ }
+ source {
+ address 10.4.58.6
+ }
+ }
+ rule 3022 {
+ action accept
+ description VPN-24594-ANY-ALLOW-10.4.59.6
+ destination {
+ group {
+ address-group DT_VPN-24594
+ }
+ }
+ source {
+ address 10.4.59.6
+ }
+ }
+ rule 3023 {
+ action accept
+ description VPN-24595-ANY-ALLOW-10.4.56.14
+ destination {
+ group {
+ address-group DT_VPN-24595
+ }
+ }
+ source {
+ address 10.4.56.14
+ }
+ }
+ rule 3024 {
+ action accept
+ description VPN-24595-ANY-ALLOW-10.4.57.14
+ destination {
+ group {
+ address-group DT_VPN-24595
+ }
+ }
+ source {
+ address 10.4.57.14
+ }
+ }
+ rule 3025 {
+ action accept
+ description VPN-32528-ANY-ALLOW-10.4.58.67
+ destination {
+ group {
+ address-group DT_VPN-32528
+ }
+ }
+ source {
+ address 10.4.58.67
+ }
+ }
+ rule 3026 {
+ action accept
+ description VPN-32528-ANY-ALLOW-10.4.59.67
+ destination {
+ group {
+ address-group DT_VPN-32528
+ }
+ }
+ source {
+ address 10.4.59.67
+ }
+ }
+ rule 3027 {
+ action accept
+ description FW6187E_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6187E_1
+ }
+ port 51195
+ }
+ protocol udp
+ }
+ rule 3028 {
+ action accept
+ description FW406AB_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW406AB_1
+ }
+ port 37013,25461,8881,8080,2095,2082,1992
+ }
+ protocol tcp_udp
+ }
+ rule 3029 {
+ action accept
+ description FWA86A4_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA86A4_1
+ }
+ port 30333,5666
+ }
+ protocol tcp
+ }
+ rule 3032 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.52
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.52
+ }
+ }
+ rule 3033 {
+ action accept
+ description FWC055A_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC055A_1
+ }
+ port 2195
+ }
+ protocol tcp
+ }
+ rule 3035 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.81
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.81
+ }
+ }
+ rule 3039 {
+ action accept
+ description FW42BC7_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW42BC7_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 3040 {
+ action accept
+ description FW42BC7_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW42BC7_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 3041 {
+ action accept
+ description FW310C6_3-ANY-ALLOW-88.208.198.39
+ destination {
+ group {
+ address-group DT_FW310C6_3
+ }
+ }
+ source {
+ address 88.208.198.39
+ }
+ }
+ rule 3042 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.235
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.235
+ }
+ }
+ rule 3043 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.205
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.205
+ }
+ }
+ rule 3044 {
+ action accept
+ description FWBE878_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWBE878_1
+ }
+ port 8989,5003,3000
+ }
+ protocol tcp_udp
+ }
+ rule 3045 {
+ action accept
+ description VPN-30679-ANY-ALLOW-10.4.58.195
+ destination {
+ group {
+ address-group DT_VPN-30679
+ }
+ }
+ source {
+ address 10.4.58.195
+ }
+ }
+ rule 3046 {
+ action accept
+ description FW6B9B9_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6B9B9_1
+ }
+ port 30006-65000,27017,7101,4200,2990-3009
+ }
+ protocol tcp
+ }
+ rule 3047 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.212
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.212
+ }
+ }
+ rule 3049 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-123.231.125.4
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 123.231.125.4
+ }
+ }
+ rule 3050 {
+ action accept
+ description FW49C3D_4-TCP-ALLOW-83.100.136.74
+ destination {
+ group {
+ address-group DT_FW49C3D_4
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 83.100.136.74
+ }
+ }
+ rule 3051 {
+ action accept
+ description FW49C3D_6-TCP-ALLOW-87.224.33.215
+ destination {
+ group {
+ address-group DT_FW49C3D_6
+ }
+ port 3389,445
+ }
+ protocol tcp
+ source {
+ address 87.224.33.215
+ }
+ }
+ rule 3053 {
+ action accept
+ description FW89619_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW89619_1
+ }
+ port 9000-10999
+ }
+ protocol udp
+ }
+ rule 3054 {
+ action accept
+ description FWBD9D0_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWBD9D0_1
+ }
+ port 9090
+ }
+ protocol tcp
+ }
+ rule 3055 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-175.157.47.236
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 175.157.47.236
+ }
+ }
+ rule 3056 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-175.157.46.226
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 175.157.46.226
+ }
+ }
+ rule 3058 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.205
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.205
+ }
+ }
+ rule 3060 {
+ action accept
+ description FWF7B68_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF7B68_1
+ }
+ port 49152-65535
+ }
+ protocol tcp
+ }
+ rule 3061 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.253
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.253
+ }
+ }
+ rule 3063 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.0
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.0
+ }
+ }
+ rule 3065 {
+ action accept
+ description FW85619_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW85619_1
+ }
+ port 6433
+ }
+ protocol tcp
+ }
+ rule 3066 {
+ action accept
+ description FW5A5D7_3-TCP-ALLOW-188.66.79.94
+ destination {
+ group {
+ address-group DT_FW5A5D7_3
+ }
+ port 8172,3389
+ }
+ protocol tcp
+ source {
+ address 188.66.79.94
+ }
+ }
+ rule 3067 {
+ action accept
+ description FWF30BD_1-TCP-ALLOW-81.133.80.114
+ destination {
+ group {
+ address-group DT_FWF30BD_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 81.133.80.114
+ }
+ }
+ rule 3068 {
+ action accept
+ description FWF30BD_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF30BD_1
+ }
+ port 5061,5015,5001
+ }
+ protocol tcp
+ }
+ rule 3069 {
+ action accept
+ description FWBD9D0_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWBD9D0_1
+ }
+ port 51820
+ }
+ protocol udp
+ }
+ rule 3070 {
+ action accept
+ description FW7C4D9_14-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW7C4D9_14
+ }
+ port 25565,2456-2458
+ }
+ protocol tcp_udp
+ }
+ rule 3071 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.23
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.23
+ }
+ }
+ rule 3072 {
+ action accept
+ description FWEEC75_1-TCP-ALLOW-81.96.100.32
+ destination {
+ group {
+ address-group DT_FWEEC75_1
+ }
+ port 8447
+ }
+ protocol tcp
+ source {
+ address 81.96.100.32
+ }
+ }
+ rule 3073 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-95.168.164.208
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 95.168.164.208
+ }
+ }
+ rule 3074 {
+ action accept
+ description VPN-19992-ANY-ALLOW-10.4.86.158
+ destination {
+ group {
+ address-group DT_VPN-19992
+ }
+ }
+ source {
+ address 10.4.86.158
+ }
+ }
+ rule 3075 {
+ action accept
+ description FWF30BD_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF30BD_1
+ }
+ port 5090,5060
+ }
+ protocol tcp_udp
+ }
+ rule 3076 {
+ action accept
+ description VPN-30679-ANY-ALLOW-10.4.59.195
+ destination {
+ group {
+ address-group DT_VPN-30679
+ }
+ }
+ source {
+ address 10.4.59.195
+ }
+ }
+ rule 3077 {
+ action accept
+ description FW930F3_3-ANY-ALLOW-77.68.112.254
+ destination {
+ group {
+ address-group DT_FW930F3_3
+ }
+ }
+ source {
+ address 77.68.112.254
+ }
+ }
+ rule 3078 {
+ action accept
+ description FW672AB_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW672AB_1
+ }
+ port 5432
+ }
+ protocol tcp
+ }
+ rule 3079 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.252
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.252
+ }
+ }
+ rule 3080 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-123.231.86.192
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 123.231.86.192
+ }
+ }
+ rule 3081 {
+ action accept
+ description VPN-33204-ANY-ALLOW-10.4.56.176
+ destination {
+ group {
+ address-group DT_VPN-33204
+ }
+ }
+ source {
+ address 10.4.56.176
+ }
+ }
+ rule 3083 {
+ action accept
+ description FW1FA8E_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1FA8E_1
+ }
+ port 33434
+ }
+ protocol udp
+ }
+ rule 3084 {
+ action accept
+ description FWD2440_1-ESP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD2440_1
+ }
+ }
+ protocol esp
+ }
+ rule 3085 {
+ action accept
+ description FWA0531_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA0531_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 3090 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.70
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.70
+ }
+ }
+ rule 3091 {
+ action accept
+ description FWF7BFA_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF7BFA_1
+ }
+ port 8000,5901,5479,5478
+ }
+ protocol tcp
+ }
+ rule 3092 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.212
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.212
+ }
+ }
+ rule 3094 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.125
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.125
+ }
+ }
+ rule 3096 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.89
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.89
+ }
+ }
+ rule 3097 {
+ action accept
+ description FWD56A2_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD56A2_1
+ }
+ port 8001,8000
+ }
+ protocol tcp
+ }
+ rule 3098 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.109
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.109
+ }
+ }
+ rule 3099 {
+ action accept
+ description FW36425_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW36425_1
+ }
+ port 44445,7770-7800
+ }
+ protocol tcp
+ }
+ rule 3100 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.238
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.238
+ }
+ }
+ rule 3102 {
+ action accept
+ description FW6B39D_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6B39D_1
+ }
+ port 49216,49215
+ }
+ protocol tcp_udp
+ }
+ rule 3103 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.121
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.121
+ }
+ }
+ rule 3105 {
+ action accept
+ description FW2379F_14-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2379F_14
+ }
+ port 443
+ }
+ protocol tcp_udp
+ }
+ rule 3107 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.38
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.38
+ }
+ }
+ rule 3109 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.191
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.191
+ }
+ }
+ rule 3111 {
+ action accept
+ description FW27947_1-TCP-ALLOW-213.229.100.148
+ destination {
+ group {
+ address-group DT_FW27947_1
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 213.229.100.148
+ }
+ }
+ rule 3112 {
+ action accept
+ description FWD42CF_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD42CF_1
+ }
+ port 5432,5001,5000
+ }
+ protocol tcp
+ }
+ rule 3114 {
+ action accept
+ description FW3A12F_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW3A12F_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 3116 {
+ action accept
+ description FW5A5D7_3-TCP-ALLOW-194.62.184.87
+ destination {
+ group {
+ address-group DT_FW5A5D7_3
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 194.62.184.87
+ }
+ }
+ rule 3117 {
+ action accept
+ description FW5A5D7_3-TCP-ALLOW-51.219.31.78
+ destination {
+ group {
+ address-group DT_FW5A5D7_3
+ }
+ port 8172,3389
+ }
+ protocol tcp
+ source {
+ address 51.219.31.78
+ }
+ }
+ rule 3118 {
+ action accept
+ description VPN-26157-ANY-ALLOW-10.4.86.57
+ destination {
+ group {
+ address-group DT_VPN-26157
+ }
+ }
+ source {
+ address 10.4.86.57
+ }
+ }
+ rule 3119 {
+ action accept
+ description VPN-26157-ANY-ALLOW-10.4.87.57
+ destination {
+ group {
+ address-group DT_VPN-26157
+ }
+ }
+ source {
+ address 10.4.87.57
+ }
+ }
+ rule 3120 {
+ action accept
+ description FWA7625_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA7625_1
+ }
+ port 943
+ }
+ protocol tcp
+ }
+ rule 3121 {
+ action accept
+ description FWC96A1_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC96A1_1
+ }
+ port 1194
+ }
+ protocol udp
+ }
+ rule 3122 {
+ action accept
+ description FWA7625_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA7625_1
+ }
+ port 1194
+ }
+ protocol udp
+ }
+ rule 3123 {
+ action accept
+ description FWA7625_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA7625_1
+ }
+ port 32400,10108
+ }
+ protocol tcp_udp
+ }
+ rule 3125 {
+ action accept
+ description FW8A3FC_3-TCP-ALLOW-185.173.161.154
+ destination {
+ group {
+ address-group DT_FW8A3FC_3
+ }
+ port 465
+ }
+ protocol tcp
+ source {
+ address 185.173.161.154
+ }
+ }
+ rule 3127 {
+ action accept
+ description FW05339_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW05339_1
+ }
+ port 46961
+ }
+ protocol udp
+ }
+ rule 3130 {
+ action accept
+ description FWA0AA0_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA0AA0_1
+ }
+ port 1194
+ }
+ protocol udp
+ }
+ rule 3132 {
+ action accept
+ description FWD8DD1_2-TCP_UDP-ALLOW-77.153.164.226
+ destination {
+ group {
+ address-group DT_FWD8DD1_2
+ }
+ port 443,80
+ }
+ protocol tcp_udp
+ source {
+ address 77.153.164.226
+ }
+ }
+ rule 3134 {
+ action accept
+ description FW19987_4-TCP-ALLOW-87.224.6.174
+ destination {
+ group {
+ address-group DT_FW19987_4
+ }
+ port 3389,445,443
+ }
+ protocol tcp
+ source {
+ address 87.224.6.174
+ }
+ }
+ rule 3135 {
+ action accept
+ description FW40AE4_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW40AE4_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 3136 {
+ action accept
+ description VPN-33204-ANY-ALLOW-10.4.57.176
+ destination {
+ group {
+ address-group DT_VPN-33204
+ }
+ }
+ source {
+ address 10.4.57.176
+ }
+ }
+ rule 3137 {
+ action accept
+ description FWF3A1B_1-TCP_UDP-ALLOW-86.132.125.4
+ destination {
+ group {
+ address-group DT_FWF3A1B_1
+ }
+ port 2222
+ }
+ protocol tcp_udp
+ source {
+ address 86.132.125.4
+ }
+ }
+ rule 3138 {
+ action accept
+ description FWF3A1B_1-TCP_UDP-ALLOW-91.205.173.51
+ destination {
+ group {
+ address-group DT_FWF3A1B_1
+ }
+ port 2222
+ }
+ protocol tcp_udp
+ source {
+ address 91.205.173.51
+ }
+ }
+ rule 3143 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-109.149.121.73
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389,443
+ }
+ protocol tcp
+ source {
+ address 109.149.121.73
+ }
+ }
+ rule 3144 {
+ action accept
+ description FWA0AA0_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA0AA0_1
+ }
+ port 28083,28015-28016,1935
+ }
+ protocol tcp_udp
+ }
+ rule 3146 {
+ action accept
+ description FWF3A1B_1-TCP_UDP-ALLOW-92.233.27.144
+ destination {
+ group {
+ address-group DT_FWF3A1B_1
+ }
+ port 2222
+ }
+ protocol tcp_udp
+ source {
+ address 92.233.27.144
+ }
+ }
+ rule 3148 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-151.228.194.190
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389,443
+ }
+ protocol tcp
+ source {
+ address 151.228.194.190
+ }
+ }
+ rule 3149 {
+ action accept
+ description FW9B6FB_1-ICMP-ALLOW-77.68.89.115_32
+ destination {
+ group {
+ address-group DT_FW9B6FB_1
+ }
+ }
+ protocol icmp
+ source {
+ address 77.68.89.115/32
+ }
+ }
+ rule 3153 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.199
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.199
+ }
+ }
+ rule 3155 {
+ action accept
+ description FW45F3D_1-ANY-ALLOW-195.224.110.168
+ destination {
+ group {
+ address-group DT_FW45F3D_1
+ }
+ }
+ source {
+ address 195.224.110.168
+ }
+ }
+ rule 3156 {
+ action accept
+ description FWF8E67_1-TCP-ALLOW-82.14.188.35
+ destination {
+ group {
+ address-group DT_FWF8E67_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 82.14.188.35
+ }
+ }
+ rule 3157 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.58
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.58
+ }
+ }
+ rule 3158 {
+ action accept
+ description VPN-19992-ANY-ALLOW-10.4.87.158
+ destination {
+ group {
+ address-group DT_VPN-19992
+ }
+ }
+ source {
+ address 10.4.87.158
+ }
+ }
+ rule 3159 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-5.66.24.185
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389,443
+ }
+ protocol tcp
+ source {
+ address 5.66.24.185
+ }
+ }
+ rule 3160 {
+ action accept
+ description FWF8E67_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF8E67_1
+ }
+ port 3001
+ }
+ protocol tcp
+ }
+ rule 3161 {
+ action accept
+ description FWD2440_1-AH-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD2440_1
+ }
+ }
+ protocol ah
+ }
+ rule 3166 {
+ action accept
+ description FW3EBC8_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW3EBC8_1
+ }
+ port 9001-9900,9000
+ }
+ protocol tcp
+ }
+ rule 3167 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.244
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.244
+ }
+ }
+ rule 3168 {
+ action accept
+ description FWA0531_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA0531_1
+ }
+ port 3000
+ }
+ protocol tcp
+ }
+ rule 3170 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.137
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.137
+ }
+ }
+ rule 3173 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.104
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.104
+ }
+ }
+ rule 3176 {
+ action accept
+ description FW6906B_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW6906B_1
+ }
+ port 4190
+ }
+ protocol tcp
+ }
+ rule 3177 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-116.206.246.230
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 116.206.246.230
+ }
+ }
+ rule 3178 {
+ action accept
+ description FW444AF_1-TCP-ALLOW-91.135.10.140
+ destination {
+ group {
+ address-group DT_FW444AF_1
+ }
+ port 27017
+ }
+ protocol tcp
+ source {
+ address 91.135.10.140
+ }
+ }
+ rule 3180 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-81.150.13.34
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389,443
+ }
+ protocol tcp
+ source {
+ address 81.150.13.34
+ }
+ }
+ rule 3181 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-82.10.14.73
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389,443
+ }
+ protocol tcp
+ source {
+ address 82.10.14.73
+ }
+ }
+ rule 3183 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.25
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.25
+ }
+ }
+ rule 3184 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.224
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.224
+ }
+ }
+ rule 3185 {
+ action accept
+ description FW9B6FB_1-TCP-ALLOW-77.68.89.115_32
+ destination {
+ group {
+ address-group DT_FW9B6FB_1
+ }
+ port 10050
+ }
+ protocol tcp
+ source {
+ address 77.68.89.115/32
+ }
+ }
+ rule 3186 {
+ action accept
+ description VPN-14673-ANY-ALLOW-10.4.89.44
+ destination {
+ group {
+ address-group DT_VPN-14673
+ }
+ }
+ source {
+ address 10.4.89.44
+ }
+ }
+ rule 3187 {
+ action accept
+ description FWCA628_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWCA628_1
+ }
+ port 2096,2095,2087,2086,2083,2082
+ }
+ protocol tcp
+ }
+ rule 3189 {
+ action accept
+ description VPN-28484-ANY-ALLOW-10.4.58.159
+ destination {
+ group {
+ address-group DT_VPN-28484
+ }
+ }
+ source {
+ address 10.4.58.159
+ }
+ }
+ rule 3190 {
+ action accept
+ description FW028C0_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW028C0_2
+ }
+ port 44491-44498,44474
+ }
+ protocol tcp
+ }
+ rule 3191 {
+ action accept
+ description VPN-28484-ANY-ALLOW-10.4.59.159
+ destination {
+ group {
+ address-group DT_VPN-28484
+ }
+ }
+ source {
+ address 10.4.59.159
+ }
+ }
+ rule 3192 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.119
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.119
+ }
+ }
+ rule 3194 {
+ action accept
+ description FWF699D_4-TCP-ALLOW-195.74.108.130
+ destination {
+ group {
+ address-group DT_FWF699D_4
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 195.74.108.130
+ }
+ }
+ rule 3195 {
+ action accept
+ description FWF699D_4-TCP-ALLOW-31.54.149.143
+ destination {
+ group {
+ address-group DT_FWF699D_4
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 31.54.149.143
+ }
+ }
+ rule 3196 {
+ action accept
+ description FWF699D_4-TCP-ALLOW-35.204.243.120
+ destination {
+ group {
+ address-group DT_FWF699D_4
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 35.204.243.120
+ }
+ }
+ rule 3197 {
+ action accept
+ description FWF699D_4-TCP-ALLOW-81.150.55.65
+ destination {
+ group {
+ address-group DT_FWF699D_4
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 81.150.55.65
+ }
+ }
+ rule 3198 {
+ action accept
+ description FWF699D_4-TCP-ALLOW-81.150.55.70
+ destination {
+ group {
+ address-group DT_FWF699D_4
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 81.150.55.70
+ }
+ }
+ rule 3199 {
+ action accept
+ description FWF699D_4-TCP-ALLOW-86.142.112.4
+ destination {
+ group {
+ address-group DT_FWF699D_4
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 86.142.112.4
+ }
+ }
+ rule 3200 {
+ action accept
+ description FWF699D_4-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF699D_4
+ }
+ port 8983
+ }
+ protocol tcp_udp
+ }
+ rule 3201 {
+ action accept
+ description FWF699D_4-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF699D_4
+ }
+ port 11009,10009
+ }
+ protocol tcp
+ }
+ rule 3202 {
+ action accept
+ description VPN-2661-ANY-ALLOW-10.4.54.24
+ destination {
+ group {
+ address-group DT_VPN-2661
+ }
+ }
+ source {
+ address 10.4.54.24
+ }
+ }
+ rule 3203 {
+ action accept
+ description VPN-2661-ANY-ALLOW-10.4.55.24
+ destination {
+ group {
+ address-group DT_VPN-2661
+ }
+ }
+ source {
+ address 10.4.55.24
+ }
+ }
+ rule 3204 {
+ action accept
+ description VPN-9727-ANY-ALLOW-10.4.54.118
+ destination {
+ group {
+ address-group DT_VPN-9727
+ }
+ }
+ source {
+ address 10.4.54.118
+ }
+ }
+ rule 3205 {
+ action accept
+ description VPN-9727-ANY-ALLOW-10.4.55.119
+ destination {
+ group {
+ address-group DT_VPN-9727
+ }
+ }
+ source {
+ address 10.4.55.119
+ }
+ }
+ rule 3207 {
+ action accept
+ description FWF0221_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF0221_1
+ }
+ port 65000,8099,8080
+ }
+ protocol tcp_udp
+ }
+ rule 3208 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.180
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.180
+ }
+ }
+ rule 3209 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-82.5.189.5
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 443
+ }
+ protocol tcp
+ source {
+ address 82.5.189.5
+ }
+ }
+ rule 3210 {
+ action accept
+ description FW60FD6_5-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW60FD6_5
+ }
+ port 1194
+ }
+ protocol udp
+ }
+ rule 3211 {
+ action accept
+ description FW60FD6_5-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW60FD6_5
+ }
+ port 9500,9191,9090,8090,2222
+ }
+ protocol tcp
+ }
+ rule 3212 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-84.65.217.114
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389,443
+ }
+ protocol tcp
+ source {
+ address 84.65.217.114
+ }
+ }
+ rule 3213 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-175.157.43.21
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 175.157.43.21
+ }
+ }
+ rule 3214 {
+ action accept
+ description FW45F3D_1-ANY-ALLOW-77.68.126.251
+ destination {
+ group {
+ address-group DT_FW45F3D_1
+ }
+ }
+ source {
+ address 77.68.126.251
+ }
+ }
+ rule 3215 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-86.14.23.23
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389,443
+ }
+ protocol tcp
+ source {
+ address 86.14.23.23
+ }
+ }
+ rule 3217 {
+ action accept
+ description FW85E02_11-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW85E02_11
+ }
+ port 9000-10999
+ }
+ protocol udp
+ }
+ rule 3218 {
+ action accept
+ description FW5D0FA_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW5D0FA_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 3222 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.141
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.141
+ }
+ }
+ rule 3223 {
+ action accept
+ description FWCDD8B_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWCDD8B_1
+ }
+ port 2222
+ }
+ protocol tcp
+ }
+ rule 3224 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.185
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.185
+ }
+ }
+ rule 3225 {
+ action accept
+ description FW06940_3-TCP_UDP-ALLOW-213.171.210.153
+ destination {
+ group {
+ address-group DT_FW06940_3
+ }
+ port 1-65535
+ }
+ protocol tcp_udp
+ source {
+ address 213.171.210.153
+ }
+ }
+ rule 3226 {
+ action accept
+ description FW06940_3-TCP_UDP-ALLOW-70.29.113.102
+ destination {
+ group {
+ address-group DT_FW06940_3
+ }
+ port 1-65535
+ }
+ protocol tcp_udp
+ source {
+ address 70.29.113.102
+ }
+ }
+ rule 3227 {
+ action accept
+ description FWC32BE_1-ANY-ALLOW-3.127.0.177
+ destination {
+ group {
+ address-group DT_FWC32BE_1
+ }
+ }
+ source {
+ address 3.127.0.177
+ }
+ }
+ rule 3228 {
+ action accept
+ description FWA86ED_101-TCP-ALLOW-93.115.195.58
+ destination {
+ group {
+ address-group DT_FWA86ED_101
+ }
+ port 3389,443
+ }
+ protocol tcp
+ source {
+ address 93.115.195.58
+ }
+ }
+ rule 3229 {
+ action accept
+ description FWE32F2_8-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE32F2_8
+ }
+ port 40120,30120,30110
+ }
+ protocol tcp
+ }
+ rule 3230 {
+ action accept
+ description VPN-28515-ANY-ALLOW-10.4.56.162
+ destination {
+ group {
+ address-group DT_VPN-28515
+ }
+ }
+ source {
+ address 10.4.56.162
+ }
+ }
+ rule 3231 {
+ action accept
+ description FW06940_3-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW06940_3
+ }
+ port 30000-30400,8443-8447,445,80-110,21-25
+ }
+ protocol tcp
+ }
+ rule 3232 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.134
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.134
+ }
+ }
+ rule 3236 {
+ action accept
+ description VPN-28515-ANY-ALLOW-10.4.57.162
+ destination {
+ group {
+ address-group DT_VPN-28515
+ }
+ }
+ source {
+ address 10.4.57.162
+ }
+ }
+ rule 3237 {
+ action accept
+ description FWF4063_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF4063_1
+ }
+ port 3000
+ }
+ protocol tcp
+ }
+ rule 3240 {
+ action accept
+ description FW06940_3-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW06940_3
+ }
+ port 49152-65535,6379,5666,5432-5454
+ }
+ protocol tcp_udp
+ }
+ rule 3242 {
+ action accept
+ description FW2E8D4_1-TCP-ALLOW-63.35.92.185
+ destination {
+ group {
+ address-group DT_FW2E8D4_1
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 63.35.92.185
+ }
+ }
+ rule 3244 {
+ action accept
+ description FWF30BD_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF30BD_1
+ }
+ port 9000-10999
+ }
+ protocol udp
+ }
+ rule 3245 {
+ action accept
+ description FWE30A1_4-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE30A1_4
+ }
+ port 65057
+ }
+ protocol tcp_udp
+ }
+ rule 3246 {
+ action accept
+ description VPN-26772-ANY-ALLOW-10.4.54.123
+ destination {
+ group {
+ address-group DT_VPN-26772
+ }
+ }
+ source {
+ address 10.4.54.123
+ }
+ }
+ rule 3249 {
+ action accept
+ description FW56496_1-ANY-ALLOW-77.68.82.49
+ destination {
+ group {
+ address-group DT_FW56496_1
+ }
+ }
+ source {
+ address 77.68.82.49
+ }
+ }
+ rule 3251 {
+ action accept
+ description FWDA443_6-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWDA443_6
+ }
+ port 30175,12050
+ }
+ protocol tcp
+ }
+ rule 3253 {
+ action accept
+ description FW5A521_3-TCP-ALLOW-88.98.75.17
+ destination {
+ group {
+ address-group DT_FW5A521_3
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 88.98.75.17
+ }
+ }
+ rule 3254 {
+ action accept
+ description FW5A521_3-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW5A521_3
+ }
+ port 161-162
+ }
+ protocol udp
+ }
+ rule 3255 {
+ action accept
+ description FW5A521_3-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW5A521_3
+ }
+ port 5900
+ }
+ protocol tcp
+ }
+ rule 3259 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.178
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.178
+ }
+ }
+ rule 3260 {
+ action accept
+ description VPN-26772-ANY-ALLOW-10.4.55.124
+ destination {
+ group {
+ address-group DT_VPN-26772
+ }
+ }
+ source {
+ address 10.4.55.124
+ }
+ }
+ rule 3262 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.114
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.114
+ }
+ }
+ rule 3272 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-116.206.246.30
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 116.206.246.30
+ }
+ }
+ rule 3273 {
+ action accept
+ description FW2B4BA_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2B4BA_1
+ }
+ port 30000-31000
+ }
+ protocol tcp
+ }
+ rule 3284 {
+ action accept
+ description FW06940_3-TCP-ALLOW-213.171.217.107
+ destination {
+ group {
+ address-group DT_FW06940_3
+ }
+ port 8443
+ }
+ protocol tcp
+ source {
+ address 213.171.217.107
+ }
+ }
+ rule 3285 {
+ action accept
+ description FW0952B_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0952B_1
+ }
+ port 9030,9001
+ }
+ protocol tcp
+ }
+ rule 3286 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-123.231.85.35
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 123.231.85.35
+ }
+ }
+ rule 3290 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.208.232
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.208.232
+ }
+ }
+ rule 3294 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.21
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.21
+ }
+ }
+ rule 3295 {
+ action accept
+ description FW0EA3F_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0EA3F_1
+ }
+ port 1-65535
+ }
+ protocol tcp_udp
+ }
+ rule 3296 {
+ action accept
+ description FW9D5C7_1-TCP-ALLOW-209.97.176.108
+ destination {
+ group {
+ address-group DT_FW9D5C7_1
+ }
+ port 8447,8443,22
+ }
+ protocol tcp
+ source {
+ address 209.97.176.108
+ }
+ }
+ rule 3297 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.188
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.188
+ }
+ }
+ rule 3298 {
+ action accept
+ description FW9D5C7_1-TCP-ALLOW-165.227.231.227
+ destination {
+ group {
+ address-group DT_FW9D5C7_1
+ }
+ port 9117,9113,9104,9100
+ }
+ protocol tcp
+ source {
+ address 165.227.231.227
+ }
+ }
+ rule 3299 {
+ action accept
+ description FW4DB0A_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4DB0A_1
+ }
+ port 953
+ }
+ protocol tcp
+ }
+ rule 3300 {
+ action accept
+ description FW4DB0A_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4DB0A_1
+ }
+ port 953
+ }
+ protocol udp
+ }
+ rule 3301 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.91
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.91
+ }
+ }
+ rule 3303 {
+ action accept
+ description FW56496_1-TCP-ALLOW-176.255.93.149
+ destination {
+ group {
+ address-group DT_FW56496_1
+ }
+ port 3389
+ }
+ protocol tcp
+ source {
+ address 176.255.93.149
+ }
+ }
+ rule 3304 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.79
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.79
+ }
+ }
+ rule 3305 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.43
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.43
+ }
+ }
+ rule 3306 {
+ action accept
+ description FW310C6_3-ANY-ALLOW-88.208.198.40
+ destination {
+ group {
+ address-group DT_FW310C6_3
+ }
+ }
+ source {
+ address 88.208.198.40
+ }
+ }
+ rule 3307 {
+ action accept
+ description FW597A6_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW597A6_1
+ }
+ port 49152-65535,990
+ }
+ protocol tcp
+ }
+ rule 3308 {
+ action accept
+ description FW597A6_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW597A6_1
+ }
+ port 3306
+ }
+ protocol tcp_udp
+ }
+ rule 3309 {
+ action accept
+ description FWBC280_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWBC280_1
+ }
+ port 49152-65535,20-21
+ }
+ protocol tcp
+ }
+ rule 3310 {
+ action accept
+ description VPN-31301-ANY-ALLOW-10.4.87.223
+ destination {
+ group {
+ address-group DT_VPN-31301
+ }
+ }
+ source {
+ address 10.4.87.223
+ }
+ }
+ rule 3311 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-148.253.173.243
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 148.253.173.243
+ }
+ }
+ rule 3312 {
+ action accept
+ description FW9EEDD_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW9EEDD_1
+ }
+ port 990,197,20-23
+ }
+ protocol tcp
+ }
+ rule 3313 {
+ action accept
+ description FW9EEDD_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW9EEDD_1
+ }
+ port 49152-65535
+ }
+ protocol tcp_udp
+ }
+ rule 3314 {
+ action accept
+ description VPN-31002-ANY-ALLOW-10.4.89.126
+ destination {
+ group {
+ address-group DT_VPN-31002
+ }
+ }
+ source {
+ address 10.4.89.126
+ }
+ }
+ rule 3316 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.11
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.11
+ }
+ }
+ rule 3317 {
+ action accept
+ description FW32EFF_49-TCP-ALLOW-195.59.191.128_25
+ destination {
+ group {
+ address-group DT_FW32EFF_49
+ }
+ port 5589
+ }
+ protocol tcp
+ source {
+ address 195.59.191.128/25
+ }
+ }
+ rule 3318 {
+ action accept
+ description FW32EFF_49-TCP-ALLOW-213.71.130.0_26
+ destination {
+ group {
+ address-group DT_FW32EFF_49
+ }
+ port 5589
+ }
+ protocol tcp
+ source {
+ address 213.71.130.0/26
+ }
+ }
+ rule 3319 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.88
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.88
+ }
+ }
+ rule 3320 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.215.173
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.215.173
+ }
+ }
+ rule 3321 {
+ action accept
+ description FW32EFF_49-TCP-ALLOW-84.19.45.82
+ destination {
+ group {
+ address-group DT_FW32EFF_49
+ }
+ port 5589
+ }
+ protocol tcp
+ source {
+ address 84.19.45.82
+ }
+ }
+ rule 3322 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-175.157.43.122
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 175.157.43.122
+ }
+ }
+ rule 3323 {
+ action accept
+ description FWC1ACD_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWC1ACD_1
+ }
+ port 28061,28060,8080
+ }
+ protocol tcp_udp
+ }
+ rule 3324 {
+ action accept
+ description FWA5D67_1-TCP_UDP-ALLOW-84.74.32.74
+ destination {
+ group {
+ address-group DT_FWA5D67_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 84.74.32.74
+ }
+ }
+ rule 3325 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.169
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.169
+ }
+ }
+ rule 3326 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.89
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.89
+ }
+ }
+ rule 3329 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.35
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.35
+ }
+ }
+ rule 3330 {
+ action accept
+ description FWCE020_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWCE020_1
+ }
+ port 48402
+ }
+ protocol udp
+ }
+ rule 3333 {
+ action accept
+ description FWF3574_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWF3574_1
+ }
+ port 8060,445,139
+ }
+ protocol tcp
+ }
+ rule 3334 {
+ action accept
+ description FWE6AB2_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE6AB2_1
+ }
+ port 44158,945,943
+ }
+ protocol tcp
+ }
+ rule 3335 {
+ action accept
+ description FWBFC02_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWBFC02_1
+ }
+ port 44158,945,943
+ }
+ protocol tcp
+ }
+ rule 3336 {
+ action accept
+ description FWBFC02_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWBFC02_1
+ }
+ port 1194
+ }
+ protocol udp
+ }
+ rule 3337 {
+ action accept
+ description FWE6AB2_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWE6AB2_1
+ }
+ port 1194
+ }
+ protocol udp
+ }
+ rule 3338 {
+ action accept
+ description FWBC8A6_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWBC8A6_1
+ }
+ port 44158,945,943
+ }
+ protocol tcp
+ }
+ rule 3339 {
+ action accept
+ description FWBC8A6_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWBC8A6_1
+ }
+ port 1194
+ }
+ protocol udp
+ }
+ rule 3340 {
+ action accept
+ description FWA0AA0_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA0AA0_1
+ }
+ port 2302
+ }
+ protocol tcp
+ }
+ rule 3342 {
+ action accept
+ description FW56496_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW56496_1
+ }
+ port 22
+ }
+ protocol tcp_udp
+ }
+ rule 3343 {
+ action accept
+ description FW56496_1-TCP-ALLOW-157.231.178.162
+ destination {
+ group {
+ address-group DT_FW56496_1
+ }
+ port 21
+ }
+ protocol tcp
+ source {
+ address 157.231.178.162
+ }
+ }
+ rule 3344 {
+ action accept
+ description FW56496_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW56496_1
+ }
+ port 2443,1022
+ }
+ protocol tcp
+ }
+ rule 3345 {
+ action accept
+ description FW56496_1-TCP_UDP-ALLOW-46.16.211.142
+ destination {
+ group {
+ address-group DT_FW56496_1
+ }
+ port 3389,21
+ }
+ protocol tcp_udp
+ source {
+ address 46.16.211.142
+ }
+ }
+ rule 3347 {
+ action accept
+ description FW2379F_14-GRE-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW2379F_14
+ }
+ }
+ protocol gre
+ }
+ rule 3348 {
+ action accept
+ description FW0E383_9-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0E383_9
+ }
+ port 52000
+ }
+ protocol tcp
+ }
+ rule 3350 {
+ action accept
+ description FWB4438_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWB4438_2
+ }
+ port 993-995,7
+ }
+ protocol tcp
+ }
+ rule 3351 {
+ action accept
+ description FW1F3D0_6-TCP_UDP-ALLOW-82.165.207.109
+ destination {
+ group {
+ address-group DT_FW1F3D0_6
+ }
+ port 4567-4568
+ }
+ protocol tcp_udp
+ source {
+ address 82.165.207.109
+ }
+ }
+ rule 3352 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.77
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.77
+ }
+ }
+ rule 3358 {
+ action accept
+ description FW46F4A_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW46F4A_1
+ }
+ port 51820
+ }
+ protocol udp
+ }
+ rule 3359 {
+ action accept
+ description FW53C72_1-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW53C72_1
+ }
+ port 48402
+ }
+ protocol udp
+ }
+ rule 3360 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.251
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.251
+ }
+ }
+ rule 3362 {
+ action accept
+ description FWAA38E_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWAA38E_1
+ }
+ port 1001-65535
+ }
+ protocol tcp_udp
+ }
+ rule 3363 {
+ action accept
+ description FW138F8_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW138F8_1
+ }
+ port 21,20
+ }
+ protocol tcp_udp
+ }
+ rule 3364 {
+ action accept
+ description FW0BD92_3-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW0BD92_3
+ }
+ port 18081,18080
+ }
+ protocol tcp
+ }
+ rule 3365 {
+ action accept
+ description FWFEF05_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWFEF05_1
+ }
+ port 1935
+ }
+ protocol tcp_udp
+ }
+ rule 3367 {
+ action accept
+ description FW26846_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW26846_1
+ }
+ port 8000
+ }
+ protocol tcp
+ }
+ rule 3368 {
+ action accept
+ description FWB4438_2-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWB4438_2
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 3369 {
+ action accept
+ description FWA884B_5-TCP-ALLOW-51.146.16.162
+ destination {
+ group {
+ address-group DT_FWA884B_5
+ }
+ port 8447,8443,22
+ }
+ protocol tcp
+ source {
+ address 51.146.16.162
+ }
+ }
+ rule 3370 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.22
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.22
+ }
+ }
+ rule 3371 {
+ action accept
+ description FWFDE34_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWFDE34_1
+ }
+ port 18081,18080
+ }
+ protocol tcp
+ }
+ rule 3373 {
+ action accept
+ description FWB6101_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWB6101_1
+ }
+ port 2280
+ }
+ protocol tcp
+ }
+ rule 3377 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-123.231.84.203
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 123.231.84.203
+ }
+ }
+ rule 3378 {
+ action accept
+ description FW1D511_2-TCP-ALLOW-92.29.46.47
+ destination {
+ group {
+ address-group DT_FW1D511_2
+ }
+ port 9090
+ }
+ protocol tcp
+ source {
+ address 92.29.46.47
+ }
+ }
+ rule 3386 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.208.175
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.208.175
+ }
+ }
+ rule 3387 {
+ action accept
+ description FW1ACD9_2-TCP-ALLOW-89.197.148.38
+ destination {
+ group {
+ address-group DT_FW1ACD9_2
+ }
+ port 5015,22
+ }
+ protocol tcp
+ source {
+ address 89.197.148.38
+ }
+ }
+ rule 3388 {
+ action accept
+ description FW1ACD9_2-UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1ACD9_2
+ }
+ port 9000-10999,5090,5060
+ }
+ protocol udp
+ }
+ rule 3389 {
+ action accept
+ description FW1ACD9_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW1ACD9_2
+ }
+ port 5090,5060-5062
+ }
+ protocol tcp
+ }
+ rule 3391 {
+ action accept
+ description FWA0B7F_1-TCP_UDP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWA0B7F_1
+ }
+ port 53
+ }
+ protocol tcp_udp
+ }
+ rule 3392 {
+ action accept
+ description FW56335_2-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW56335_2
+ }
+ port 18081,18080
+ }
+ protocol tcp
+ }
+ rule 3395 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.90
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.90
+ }
+ }
+ rule 3396 {
+ action accept
+ description FW4D3E6_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW4D3E6_1
+ }
+ port 18081,18080
+ }
+ protocol tcp
+ }
+ rule 3397 {
+ action accept
+ description FWB118A_1-TCP-ALLOW-188.65.177.58
+ destination {
+ group {
+ address-group DT_FWB118A_1
+ }
+ port 49152-65534,8447,8443,22,21,20
+ }
+ protocol tcp
+ source {
+ address 188.65.177.58
+ }
+ }
+ rule 3398 {
+ action accept
+ description FWB118A_1-TCP-ALLOW-77.68.103.13
+ destination {
+ group {
+ address-group DT_FWB118A_1
+ }
+ port 49152-65534,8447,8443,22,21,20
+ }
+ protocol tcp
+ source {
+ address 77.68.103.13
+ }
+ }
+ rule 3399 {
+ action accept
+ description FWB118A_1-TCP-ALLOW-80.5.71.130
+ destination {
+ group {
+ address-group DT_FWB118A_1
+ }
+ port 49152-65534,8447,8443,22,21,20
+ }
+ protocol tcp
+ source {
+ address 80.5.71.130
+ }
+ }
+ rule 3402 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.205
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.205
+ }
+ }
+ rule 3408 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.211.31
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.211.31
+ }
+ }
+ rule 3409 {
+ action accept
+ description FW539FB_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FW539FB_1
+ }
+ port 389
+ }
+ protocol tcp
+ }
+ rule 3411 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.185
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.185
+ }
+ }
+ rule 3415 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-116.206.245.124
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 116.206.245.124
+ }
+ }
+ rule 3416 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.213.75
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.213.75
+ }
+ }
+ rule 3417 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.34
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.34
+ }
+ }
+ rule 3418 {
+ action accept
+ description FWEF92E_5-UDP-ALLOW-77.68.77.70
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 500
+ }
+ protocol udp
+ source {
+ address 77.68.77.70
+ }
+ }
+ rule 3419 {
+ action accept
+ description FWEF92E_5-UDP-ALLOW-77.68.92.33
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 500
+ }
+ protocol udp
+ source {
+ address 77.68.92.33
+ }
+ }
+ rule 3420 {
+ action accept
+ description FWEF92E_5-UDP-ALLOW-77.68.93.82
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 500
+ }
+ protocol udp
+ source {
+ address 77.68.93.82
+ }
+ }
+ rule 3421 {
+ action accept
+ description FWEF92E_5-UDP-ALLOW-88.208.198.93
+ destination {
+ group {
+ address-group DT_FWEF92E_5
+ }
+ port 500
+ }
+ protocol udp
+ source {
+ address 88.208.198.93
+ }
+ }
+ rule 3422 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.94
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.94
+ }
+ }
+ rule 3424 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-148.253.173.244
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 148.253.173.244
+ }
+ }
+ rule 3425 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-148.253.173.246
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 148.253.173.246
+ }
+ }
+ rule 3426 {
+ action accept
+ description FW18E6E_3-TCP-ALLOW-195.97.222.122
+ destination {
+ group {
+ address-group DT_FW18E6E_3
+ }
+ port 3306
+ }
+ protocol tcp
+ source {
+ address 195.97.222.122
+ }
+ }
+ rule 3431 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.111
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.111
+ }
+ }
+ rule 3432 {
+ action accept
+ description FW06940_3-TCP_UDP-ALLOW-74.208.41.119
+ destination {
+ group {
+ address-group DT_FW06940_3
+ }
+ port 1-65535
+ }
+ protocol tcp_udp
+ source {
+ address 74.208.41.119
+ }
+ }
+ rule 3438 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.252
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.252
+ }
+ }
+ rule 3440 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.118
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.118
+ }
+ }
+ rule 3442 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.209.15
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.209.15
+ }
+ }
+ rule 3446 {
+ action accept
+ description FWC32BE_1-ANY-ALLOW-3.65.3.75
+ destination {
+ group {
+ address-group DT_FWC32BE_1
+ }
+ }
+ source {
+ address 3.65.3.75
+ }
+ }
+ rule 3447 {
+ action accept
+ description FWC32BE_1-TCP-ALLOW-217.155.2.52
+ destination {
+ group {
+ address-group DT_FWC32BE_1
+ }
+ port 22
+ }
+ protocol tcp
+ source {
+ address 217.155.2.52
+ }
+ }
+ rule 3448 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.243
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.243
+ }
+ }
+ rule 3449 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.214.117
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000,3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.214.117
+ }
+ }
+ rule 3450 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.4
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.4
+ }
+ }
+ rule 3452 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.210.177
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 9000
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.210.177
+ }
+ }
+ rule 3454 {
+ action accept
+ description FWD498E_1-TCP-ALLOW-ANY
+ destination {
+ group {
+ address-group DT_FWD498E_1
+ }
+ port 44158
+ }
+ protocol tcp
+ }
+ rule 3455 {
+ action accept
+ description FWA7A50_1-TCP_UDP-ALLOW-112.134.212.147
+ destination {
+ group {
+ address-group DT_FWA7A50_1
+ }
+ port 3389
+ }
+ protocol tcp_udp
+ source {
+ address 112.134.212.147
+ }
+ }
+ }
+ receive-redirects disable
+ send-redirects disable
+ source-validation disable
+ state-policy {
+ established {
+ action accept
+ }
+ invalid {
+ action drop
+ }
+ related {
+ action accept
+ }
+ }
+ syn-cookies enable
+ twa-hazards-protection disable
+}
+high-availability {
+ vrrp {
+ group eth3-90 {
+ advertise-interval 3
+ authentication {
+ password Ng-1p90
+ type plaintext-password
+ }
+ interface eth3
+ preempt-delay 30
+ priority 10
+ virtual-address 10.255.255.1/32
+ virtual-address 169.254.169.254/32
+ vrid 90
+ }
+ sync-group VRRP-GROUP {
+ member eth3-90
+ }
+ }
+}
+interfaces {
+ ethernet eth0 {
+ address 10.4.35.105/24
+ description Management
+ duplex auto
+ smp-affinity auto
+ speed auto
+ }
+ ethernet eth1 {
+ description MicroVLANs
+ duplex auto
+ smp-affinity auto
+ speed auto
+ vif 3201 {
+ address 109.228.63.251/25
+ description "MicroVLAN publica"
+ firewall {
+ in {
+ name WAN-INBOUND
+ }
+ local {
+ name LOCAL-WAN
+ }
+ }
+ }
+ }
+ ethernet eth2 {
+ address 10.4.51.133/30
+ description Sync
+ duplex auto
+ firewall {
+ local {
+ name LOCAL-SYNC
+ }
+ }
+ smp-affinity auto
+ speed auto
+ }
+ ethernet eth3 {
+ address 10.255.255.2/20
+ description "Customers LAN"
+ duplex auto
+ firewall {
+ in {
+ name LAN-INBOUND
+ }
+ local {
+ name LOCAL-LAN
+ }
+ }
+ smp-affinity auto
+ speed auto
+ }
+ loopback lo {
+ address 10.4.35.105/32
+ }
+}
+nat {
+ destination {
+ rule 5 {
+ description cloud-init
+ destination {
+ address 169.254.169.254
+ port http
+ }
+ inbound-interface eth3
+ protocol tcp
+ translation {
+ address 82.223.45.35
+ }
+ }
+ rule 20 {
+ description "TEMPORARY NAT for dnscache removal in favor of anycns"
+ destination {
+ address 77.68.76.12
+ port domain
+ }
+ inbound-interface eth3
+ protocol tcp_udp
+ translation {
+ address 212.227.123.16
+ }
+ }
+ rule 25 {
+ description "TEMPORARY NAT for dnscache removal in favor of anycns"
+ destination {
+ address 77.68.77.12
+ port domain
+ }
+ inbound-interface eth3
+ protocol tcp_udp
+ translation {
+ address 212.227.123.17
+ }
+ }
+ }
+}
+policy {
+ community-list 100 {
+ rule 10 {
+ action permit
+ regex 65500:1001
+ }
+ }
+ community-list 200 {
+ rule 10 {
+ action permit
+ regex "65500:10**"
+ }
+ }
+ prefix-list Service-NETs {
+ rule 1 {
+ action permit
+ ge 32
+ prefix 0.0.0.0/0
+ }
+ }
+ route-map Any-Site-1 {
+ rule 10 {
+ action permit
+ match {
+ community {
+ community-list 200
+ }
+ }
+ }
+ rule 20 {
+ action deny
+ }
+ }
+ route-map CLOUD-Service-NETs {
+ rule 10 {
+ action permit
+ match {
+ ip {
+ address {
+ prefix-list Service-NETs
+ }
+ }
+ }
+ set {
+ community 65500:1027
+ }
+ }
+ rule 20 {
+ action deny
+ }
+ }
+ route-map None {
+ rule 10 {
+ action deny
+ }
+ }
+}
+protocols {
+ bgp 8560 {
+ address-family {
+ ipv4-unicast {
+ redistribute {
+ static {
+ }
+ }
+ }
+ }
+ neighbor 109.228.63.134 {
+ address-family {
+ ipv4-unicast {
+ route-map {
+ export CLOUD-Service-NETs
+ import Any-Site-1
+ }
+ weight 150
+ }
+ }
+ description RouteServer1-vyos
+ password VyOS123
+ remote-as 8560
+ timers {
+ holdtime 5
+ keepalive 1
+ }
+ }
+ neighbor 109.228.63.135 {
+ address-family {
+ ipv4-unicast {
+ route-map {
+ export CLOUD-Service-NETs
+ import Any-Site-1
+ }
+ weight 125
+ }
+ }
+ description RouteServer2-quagga
+ password VyOS123
+ remote-as 8560
+ }
+ neighbor 109.228.63.136 {
+ address-family {
+ ipv4-unicast {
+ route-map {
+ export CLOUD-Service-NETs
+ import Any-Site-1
+ }
+ weight 100
+ }
+ }
+ description RouteServer3-bird
+ password VyOS123
+ remote-as 8560
+ }
+ parameters {
+ log-neighbor-changes
+ router-id 10.4.35.105
+ }
+ }
+ static {
+ interface-route 77.68.2.215/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.3.52/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.3.61/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.3.80/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.3.121/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.3.144/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.3.161/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.3.194/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.3.247/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.4.22/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.4.24/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.4.25/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.4.39/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.4.57/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.4.74/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.4.80/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.4.111/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.4.136/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.4.180/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.4.242/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.4.252/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.5.95/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.5.125/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.5.155/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.5.166/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.5.187/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.5.241/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.6.32/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.6.105/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.6.110/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.6.119/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.6.202/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.6.210/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.7.67/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.7.114/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.7.123/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.7.160/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.7.172/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.7.186/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.7.222/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.7.227/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.8.144/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.9.75/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.9.186/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.10.142/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.10.152/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.10.170/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.11.140/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.12.45/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.12.195/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.12.250/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.13.76/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.13.137/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.14.88/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.15.95/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.16.247/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.17.26/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.17.186/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.17.200/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.20.161/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.20.217/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.20.231/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.21.78/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.21.171/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.22.146/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.23.35/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.23.64/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.23.112/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.23.158/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.24.59/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.24.63/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.24.112/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.24.134/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.24.172/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.24.220/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.25.124/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.25.130/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.25.146/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.26.166/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.26.216/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.26.221/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.26.228/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.27.18/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.27.27/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.27.28/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.27.54/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.27.57/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.27.211/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.28.139/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.28.145/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.28.147/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.28.207/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.29.65/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.29.178/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.30.133/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.30.164/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.31.96/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.31.144/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.32.31/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.32.43/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.32.83/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.32.86/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.32.89/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.32.118/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.32.254/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.33.24/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.33.37/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.33.48/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.33.68/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.33.171/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.33.197/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.33.216/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.34.26/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.34.28/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.34.50/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.34.138/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.34.139/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.35.116/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.48.14/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.48.81/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.48.89/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.48.105/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.48.202/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.49.4/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.49.12/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.49.126/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.49.152/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.49.159/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.49.160/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.49.161/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.49.178/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.50.90/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.50.91/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.50.142/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.50.193/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.50.198/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.51.202/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.51.214/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.72.202/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.72.254/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.73.73/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.74.39/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.74.85/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.74.152/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.74.209/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.74.232/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.75.45/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.75.64/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.75.113/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.75.245/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.75.253/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.12/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.13/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.14/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.16/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.19/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.20/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.21/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.22/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.23/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.25/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.26/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.29/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.30/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.31/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.33/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.35/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.37/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.38/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.39/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.40/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.42/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.44/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.45/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.47/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.48/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.49/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.50/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.54/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.55/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.57/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.58/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.59/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.60/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.61/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.74/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.75/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.76/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.77/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.80/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.88/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.91/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.92/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.93/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.94/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.95/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.96/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.99/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.102/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.104/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.105/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.107/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.108/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.110/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.111/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.112/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.114/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.115/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.116/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.118/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.120/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.122/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.123/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.124/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.126/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.127/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.136/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.137/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.138/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.139/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.141/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.142/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.145/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.148/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.149/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.150/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.152/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.157/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.158/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.160/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.161/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.164/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.165/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.169/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.171/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.176/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.177/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.181/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.183/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.185/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.187/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.191/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.195/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.197/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.198/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.200/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.202/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.203/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.208/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.209/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.211/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.212/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.217/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.219/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.220/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.228/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.229/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.231/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.234/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.235/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.239/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.241/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.243/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.244/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.245/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.247/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.248/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.249/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.250/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.251/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.252/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.253/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.76.254/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.12/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.13/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.14/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.16/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.19/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.21/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.22/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.24/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.26/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.29/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.30/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.32/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.33/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.37/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.38/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.42/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.43/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.44/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.46/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.49/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.50/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.53/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.54/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.56/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.57/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.59/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.62/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.63/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.65/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.67/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.68/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.69/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.70/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.71/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.72/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.74/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.75/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.76/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.77/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.79/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.81/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.85/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.88/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.90/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.92/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.95/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.97/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.99/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.100/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.102/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.103/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.105/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.107/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.108/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.114/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.115/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.117/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.120/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.124/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.128/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.129/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.130/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.132/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.137/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.139/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.140/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.141/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.144/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.145/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.149/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.150/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.151/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.152/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.156/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.157/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.159/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.160/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.161/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.163/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.165/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.171/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.174/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.176/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.178/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.181/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.185/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.190/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.192/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.199/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.200/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.201/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.202/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.203/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.204/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.205/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.207/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.208/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.209/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.211/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.212/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.214/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.215/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.219/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.221/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.222/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.227/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.228/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.231/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.233/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.234/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.236/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.238/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.239/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.240/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.243/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.247/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.248/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.249/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.251/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.253/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.77.254/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.78.73/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.78.113/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.78.229/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.79.82/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.79.89/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.79.206/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.80.26/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.80.97/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.81.44/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.81.141/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.81.218/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.82.147/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.82.157/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.83.41/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.84.147/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.84.155/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.85.18/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.85.27/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.85.73/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.85.115/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.85.172/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.86.40/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.86.148/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.87.164/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.87.212/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.88.100/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.88.164/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.89.72/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.89.183/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.89.247/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.90.106/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.90.132/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.91.22/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.91.128/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.91.195/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.92.92/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.92.186/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.93.125/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.93.164/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.93.246/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.94.181/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.95.42/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.95.212/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.100.77/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.100.132/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.100.134/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.100.150/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.100.167/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.101.64/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.101.124/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.101.125/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.102.5/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.102.129/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.103.19/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.103.56/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.103.120/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.103.147/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.103.227/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.112.75/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.112.83/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.112.90/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.112.91/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.112.167/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.112.175/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.112.184/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.112.213/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.112.248/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.113.117/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.113.164/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.114.93/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.114.136/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.114.183/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.114.205/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.114.234/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.114.237/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.115.17/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.115.142/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.116.36/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.116.52/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.116.84/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.116.119/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.116.183/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.116.220/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.116.221/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.116.232/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.117.29/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.117.45/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.117.51/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.117.142/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.117.173/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.117.202/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.117.214/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.117.222/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.118.15/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.118.17/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.118.86/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.118.88/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.118.102/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.118.104/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.118.120/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.119.14/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.119.92/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.119.188/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.120.26/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.120.31/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.120.45/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.120.146/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.120.218/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.120.229/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.120.241/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.120.249/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.121.94/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.121.106/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.121.119/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.121.127/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.122.89/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.122.195/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.122.241/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.123.177/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.123.250/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.125.32/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.125.60/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.125.218/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.126.14/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.126.22/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.126.51/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.126.101/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.126.160/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.127.151/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 77.68.127.172/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.196.91/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.196.92/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.196.123/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.196.154/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.197.10/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.197.23/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.197.60/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.197.118/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.197.129/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.197.135/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.197.150/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.197.155/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.197.160/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.197.208/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.198.39/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.198.64/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.198.66/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.198.69/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.198.92/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.198.251/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.199.46/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.199.141/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.199.233/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.199.249/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.212.31/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.212.94/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.212.182/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.212.188/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.215.19/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.215.61/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.215.62/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.215.121/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 88.208.215.157/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.35.84/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.35.110/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.36.37/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.36.79/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.36.119/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.36.174/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.36.194/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.36.229/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.37.10/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.37.114/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.37.174/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.37.187/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.37.240/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.38.117/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.38.171/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.38.201/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.39.41/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.39.151/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.39.157/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.39.249/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.40.194/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.40.195/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.40.207/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.40.222/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.40.226/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.40.247/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.42.232/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.46.81/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.46.196/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.47.223/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.48.249/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.52.186/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.53.243/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.55.82/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.56.26/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.56.97/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.56.185/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.56.242/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.58.134/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.59.247/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.60.215/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.61.31/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 109.228.61.37/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.36.7/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.36.17/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.36.24/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.36.56/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.36.60/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.36.142/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.36.148/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.37.23/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.37.47/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.37.83/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.37.101/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.37.102/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.37.133/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.38.95/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.38.114/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.38.142/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.38.182/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.38.216/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.38.248/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.39.37/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.39.44/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.39.68/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.39.99/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.39.109/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.39.129/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.39.145/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.39.219/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.40.11/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.40.56/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.40.90/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.40.124/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.40.152/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.40.166/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.40.244/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.41.72/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.41.73/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.41.148/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.41.240/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.43.6/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.43.28/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.43.71/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.43.98/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.43.113/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.43.157/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 185.132.43.164/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.208.40/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.208.58/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.208.176/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.209.217/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.210.19/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.210.25/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.210.59/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.210.155/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.210.177/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.211.128/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.212.71/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.212.89/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.212.90/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.212.114/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.212.136/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.212.171/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.212.172/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.212.203/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.213.31/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.213.41/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.213.42/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.213.97/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.213.175/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.213.242/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.214.96/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.214.102/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.214.167/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.214.234/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.215.43/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.215.184/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ interface-route 213.171.215.252/32 {
+ next-hop-interface eth3 {
+ }
+ }
+ route 0.0.0.0/0 {
+ next-hop 109.228.63.129 {
+ }
+ }
+ route 10.0.0.0/8 {
+ next-hop 10.4.35.1 {
+ }
+ }
+ route 10.7.197.0/24 {
+ next-hop 109.228.63.240 {
+ }
+ }
+ route 172.16.0.0/12 {
+ next-hop 10.4.35.1 {
+ }
+ }
+ route 192.168.0.0/16 {
+ next-hop 10.4.35.1 {
+ }
+ }
+ }
+}
+service {
+ lldp {
+ legacy-protocols {
+ cdp
+ }
+ snmp {
+ enable
+ }
+ }
+ snmp {
+ community 1Trpq25 {
+ authorization ro
+ }
+ contact network@arsys.es
+ description gb-glo-sg4ng1fw27-01
+ listen-address 10.4.35.105 {
+ port 161
+ }
+ location NGCS
+ trap-target 10.4.36.64 {
+ community 1Trpq25
+ port 162
+ }
+ trap-target 172.21.15.200 {
+ community 1Trpq25
+ port 162
+ }
+ }
+ ssh {
+ listen-address 10.4.35.105
+ listen-address 10.4.51.133
+ port 22
+ }
+}
+system {
+ config-management {
+ commit-revisions 20
+ }
+ conntrack {
+ expect-table-size 8192
+ hash-size 262144
+ modules {
+ sip {
+ disable
+ }
+ }
+ table-size 2097152
+ timeout {
+ icmp 30
+ other 120
+ tcp {
+ close 10
+ close-wait 60
+ established 3600
+ fin-wait 30
+ last-ack 30
+ syn-recv 5
+ syn-sent 5
+ time-wait 5
+ }
+ udp {
+ other 10
+ stream 10
+ }
+ }
+ }
+ console {
+ device ttyS0 {
+ speed 115200
+ }
+ }
+ host-name gb-glo-sg4ng1fw27-01
+ ip {
+ arp {
+ table-size 2048
+ }
+ }
+ ipv6 {
+ disable
+ }
+ login {
+ user vyos {
+ authentication {
+ encrypted-password $6$2Ta6TWHd/U$NmrX0x9kexCimeOcYK1MfhMpITF9ELxHcaBU/znBq.X2ukQOj61fVI2UYP/xBzP4QtiTcdkgs7WOQMHWsRymO/
+ plaintext-password ""
+ }
+ }
+ }
+ name-server 10.4.36.16
+ name-server 10.4.37.16
+ ntp {
+ server glo-ntp1.por-ngcs.lan {
+ }
+ server glo-ntp2.por-ngcs.lan {
+ }
+ }
+ syslog {
+ global {
+ facility all {
+ level notice
+ }
+ facility protocols {
+ level info
+ }
+ }
+ host 10.4.36.23 {
+ facility all {
+ level all
+ }
+ facility protocols {
+ level info
+ }
+ facility user {
+ level err
+ }
+ }
+ user all {
+ facility all {
+ level emerg
+ }
+ }
+ }
+ time-zone Europe/Madrid
+}
+
+
+/* Warning: Do not remove the following line. */
+/* === vyatta-config-version: "broadcast-relay@1:cluster@1:config-management@1:conntrack-sync@1:conntrack@1:dhcp-relay@2:dhcp-server@5:dns-forwarding@1:firewall@5:ipsec@5:l2tp@1:mdns@1:nat@4:ntp@1:pptp@1:qos@1:quagga@6:snmp@1:ssh@1:system@10:vrrp@2:wanloadbalance@3:webgui@1:webproxy@1:webproxy@2:zone-policy@1" === */
+/* Release version: 1.2.6-S1 */
+
diff --git a/smoketest/configs/basic-vyos b/smoketest/configs/basic-vyos
new file mode 100644
index 000000000..e6f89954f
--- /dev/null
+++ b/smoketest/configs/basic-vyos
@@ -0,0 +1,140 @@
+interfaces {
+ ethernet eth0 {
+ address 192.168.0.1/24
+ duplex auto
+ smp-affinity auto
+ speed auto
+ }
+ ethernet eth1 {
+ duplex auto
+ smp-affinity auto
+ speed auto
+ }
+ ethernet eth2 {
+ duplex auto
+ smp-affinity auto
+ speed auto
+ vif 100 {
+ address 100.100.0.1/24
+ }
+ vif-s 200 {
+ address 100.64.200.254/24
+ vif-c 201 {
+ address 100.64.201.254/24
+ }
+ vif-c 202 {
+ address 100.64.202.254/24
+ }
+ }
+ }
+ loopback lo {
+ }
+}
+protocols {
+ static {
+ arp 192.168.0.20 {
+ hwaddr 00:50:00:00:00:20
+ }
+ arp 192.168.0.30 {
+ hwaddr 00:50:00:00:00:30
+ }
+ arp 192.168.0.40 {
+ hwaddr 00:50:00:00:00:40
+ }
+ arp 100.100.0.2 {
+ hwaddr 00:50:00:00:02:02
+ }
+ arp 100.100.0.3 {
+ hwaddr 00:50:00:00:02:03
+ }
+ arp 100.100.0.4 {
+ hwaddr 00:50:00:00:02:04
+ }
+ arp 100.64.200.1 {
+ hwaddr 00:50:00:00:00:01
+ }
+ arp 100.64.200.2 {
+ hwaddr 00:50:00:00:00:02
+ }
+ arp 100.64.201.10 {
+ hwaddr 00:50:00:00:00:10
+ }
+ arp 100.64.201.20 {
+ hwaddr 00:50:00:00:00:20
+ }
+ arp 100.64.202.30 {
+ hwaddr 00:50:00:00:00:30
+ }
+ arp 100.64.202.40 {
+ hwaddr 00:50:00:00:00:40
+ }
+ route 0.0.0.0/0 {
+ next-hop 100.64.0.1 {
+ }
+ }
+ }
+}
+service {
+ dhcp-server {
+ shared-network-name LAN {
+ authoritative
+ subnet 192.168.0.0/24 {
+ default-router 192.168.0.1
+ dns-server 192.168.0.1
+ domain-name vyos.net
+ domain-search vyos.net
+ range LANDynamic {
+ start 192.168.0.20
+ stop 192.168.0.240
+ }
+ }
+ }
+ }
+ dns {
+ forwarding {
+ allow-from 192.168.0.0/16
+ cache-size 10000
+ dnssec off
+ listen-address 192.168.0.1
+ }
+ }
+ ssh {
+ ciphers aes128-ctr,aes192-ctr,aes256-ctr
+ ciphers chacha20-poly1305@openssh.com,rijndael-cbc@lysator.liu.se
+ listen-address 192.168.0.1
+ key-exchange curve25519-sha256@libssh.org
+ key-exchange diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256
+ port 22
+ }
+}
+system {
+ config-management {
+ commit-revisions 100
+ }
+ console {
+ device ttyS0 {
+ speed 115200
+ }
+ }
+ host-name vyos
+ login {
+ user vyos {
+ authentication {
+ encrypted-password $6$O5gJRlDYQpj$MtrCV9lxMnZPMbcxlU7.FI793MImNHznxGoMFgm3Q6QP3vfKJyOSRCt3Ka/GzFQyW1yZS4NS616NLHaIPPFHc0
+ plaintext-password ""
+ }
+ }
+ }
+ name-server 192.168.0.1
+ syslog {
+ global {
+ facility all {
+ level info
+ }
+ }
+ }
+ time-zone Europe/Berlin
+}
+/* Warning: Do not remove the following line. */
+/* === vyatta-config-version: "broadcast-relay@1:cluster@1:config-management@1:conntrack-sync@1:conntrack@1:dhcp-relay@2:dhcp-server@5:dns-forwarding@1:firewall@5:ipsec@5:l2tp@1:mdns@1:nat@4:ntp@1:pptp@1:qos@1:quagga@6:snmp@1:ssh@1:system@9:vrrp@2:wanloadbalance@3:webgui@1:webproxy@1:webproxy@2:zone-policy@1" === */
+/* Release version: 1.2.6 */
diff --git a/smoketest/configs/bgp-big-as-cloud b/smoketest/configs/bgp-big-as-cloud
index 694243d1e..65819256e 100644
--- a/smoketest/configs/bgp-big-as-cloud
+++ b/smoketest/configs/bgp-big-as-cloud
@@ -982,6 +982,10 @@ policy {
}
}
}
+ set {
+ as-path-exclude "100 200 300"
+ as-path-prepend "64512 64512 64512"
+ }
}
rule 100 {
action deny
@@ -1819,6 +1823,12 @@ system {
}
version 9
}
+ sflow {
+ agent-address auto
+ server 1.2.3.4 {
+ port 1234
+ }
+ }
syslog-facility daemon
}
host-name vyos
diff --git a/smoketest/configs/dialup-router-complex b/smoketest/configs/dialup-router-complex
index fef79ea56..ac5ff5e99 100644
--- a/smoketest/configs/dialup-router-complex
+++ b/smoketest/configs/dialup-router-complex
@@ -267,6 +267,22 @@ firewall {
}
protocol udp
}
+ rule 800 {
+ action drop
+ description "SSH anti brute force"
+ destination {
+ port ssh
+ }
+ log enable
+ protocol tcp
+ recent {
+ count 4
+ time 60
+ }
+ state {
+ new enable
+ }
+ }
}
name DMZ-WAN {
default-action accept
@@ -482,6 +498,9 @@ firewall {
destination {
port 110,995
}
+ limit {
+ rate "10/minute"
+ }
protocol tcp
}
rule 123 {
diff --git a/smoketest/configs/dialup-router-medium-vpn b/smoketest/configs/dialup-router-medium-vpn
index af7c075e4..63d955738 100644
--- a/smoketest/configs/dialup-router-medium-vpn
+++ b/smoketest/configs/dialup-router-medium-vpn
@@ -6,6 +6,15 @@ firewall {
ipv6-src-route disable
ip-src-route disable
log-martians enable
+ name test_tcp_flags {
+ rule 1 {
+ action drop
+ protocol tcp
+ tcp {
+ flags SYN,ACK,!RST,!FIN
+ }
+ }
+ }
options {
interface vtun0 {
adjust-mss 1380
@@ -83,6 +92,7 @@ interfaces {
}
policy {
route LAN-POLICY-BASED-ROUTING
+ ipv6-route LAN6-POLICY-BASED-ROUTING
}
smp-affinity auto
speed auto
@@ -383,6 +393,29 @@ nat {
}
}
policy {
+ ipv6-route LAN6-POLICY-BASED-ROUTING {
+ rule 10 {
+ destination {
+ }
+ disable
+ set {
+ table 10
+ }
+ source {
+ address 2002::1
+ }
+ }
+ rule 20 {
+ destination {
+ }
+ set {
+ table 100
+ }
+ source {
+ address 2008::f
+ }
+ }
+ }
prefix-list user2-routes {
rule 1 {
action permit
diff --git a/smoketest/configs/ipv6-disable b/smoketest/configs/ipv6-disable
new file mode 100644
index 000000000..da41e9020
--- /dev/null
+++ b/smoketest/configs/ipv6-disable
@@ -0,0 +1,83 @@
+interfaces {
+ ethernet eth0 {
+ duplex auto
+ smp-affinity auto
+ speed auto
+ vif 201 {
+ address 172.18.201.10/24
+ }
+ vif 202 {
+ address 172.18.202.10/24
+ }
+ vif 203 {
+ address 172.18.203.10/24
+ }
+ vif 204 {
+ address 172.18.204.10/24
+ }
+ }
+}
+protocols {
+ static {
+ route 0.0.0.0/0 {
+ next-hop 172.18.201.254 {
+ distance 10
+ }
+ next-hop 172.18.202.254 {
+ distance 20
+ }
+ next-hop 172.18.203.254 {
+ distance 30
+ }
+ next-hop 172.18.204.254 {
+ distance 40
+ }
+ }
+ }
+}
+system {
+ config-management {
+ commit-revisions 200
+ }
+ console {
+ device ttyS0 {
+ speed 115200
+ }
+ }
+ domain-name vyos.net
+ host-name vyos
+ ipv6 {
+ disable
+ }
+ login {
+ user vyos {
+ authentication {
+ encrypted-password $6$2Ta6TWHd/U$NmrX0x9kexCimeOcYK1MfhMpITF9ELxHcaBU/znBq.X2ukQOj61fVI2UYP/xBzP4QtiTcdkgs7WOQMHWsRymO/
+ plaintext-password ""
+ }
+ level admin
+ }
+ }
+ name-server 172.16.254.20
+ name-server 172.16.254.30
+ ntp {
+ server 172.16.254.20 {
+ }
+ server 172.16.254.30 {
+ }
+ }
+ syslog {
+ global {
+ facility all {
+ level info
+ }
+ facility protocols {
+ level debug
+ }
+ }
+ }
+}
+
+/* Warning: Do not remove the following line. */
+/* === vyatta-config-version: "broadcast-relay@1:cluster@1:config-management@1:conntrack-sync@1:conntrack@1:dhcp-relay@2:dhcp-server@5:dns-forwarding@1:firewall@5:ipsec@5:l2tp@1:mdns@1:nat@4:ntp@1:pptp@1:qos@1:quagga@6:snmp@1:ssh@1:system@9:vrrp@2:wanloadbalance@3:webgui@1:webproxy@1:webproxy@2:zone-policy@1" === */
+/* Release version: 1.2.6 */
diff --git a/smoketest/configs/qos-basic b/smoketest/configs/qos-basic
new file mode 100644
index 000000000..f94a5650d
--- /dev/null
+++ b/smoketest/configs/qos-basic
@@ -0,0 +1,205 @@
+interfaces {
+ ethernet eth0 {
+ address 10.1.1.100/24
+ traffic-policy {
+ out FS
+ }
+ }
+ ethernet eth1 {
+ address 10.2.1.1/24
+ traffic-policy {
+ out M2
+ }
+ }
+ ethernet eth2 {
+ address 10.9.9.1/24
+ traffic-policy {
+ out MY-HTB
+ }
+ }
+ loopback lo {
+ }
+}
+protocols {
+ static {
+ route 0.0.0.0/0 {
+ next-hop 10.9.9.2 {
+ }
+ next-hop 10.1.1.1 {
+ }
+ }
+ }
+}
+system {
+ config-management {
+ commit-revisions 10
+ }
+ conntrack {
+ modules {
+ ftp
+ h323
+ nfs
+ pptp
+ sip
+ sqlnet
+ tftp
+ }
+ }
+ console {
+ device ttyS0 {
+ speed 115200
+ }
+ }
+ host-name vyos
+ login {
+ user vyos {
+ authentication {
+ encrypted-password $6$r/Yw/07NXNY$/ZB.Rjf9jxEV.BYoDyLdH.kH14rU52pOBtrX.4S34qlPt77chflCHvpTCq9a6huLzwaMR50rEICzA5GoIRZlM0
+ plaintext-password ""
+ }
+ }
+ }
+ ntp {
+ server time1.vyos.net {
+ }
+ server time2.vyos.net {
+ }
+ server time3.vyos.net {
+ }
+ }
+ syslog {
+ global {
+ facility all {
+ level info
+ }
+ facility protocols {
+ level debug
+ }
+ }
+ }
+}
+traffic-policy {
+ shaper M2 {
+ bandwidth auto
+ class 10 {
+ bandwidth 100%
+ burst 15k
+ match ADDRESS10 {
+ ip {
+ dscp CS4
+ }
+ }
+ queue-type fair-queue
+ set-dscp CS5
+ }
+ default {
+ bandwidth 10mbit
+ burst 15k
+ queue-type fair-queue
+ }
+ }
+ shaper MY-HTB {
+ bandwidth 10mbit
+ class 30 {
+ bandwidth 10%
+ burst 15k
+ ceiling 50%
+ match ADDRESS30 {
+ ip {
+ source {
+ address 10.1.1.0/24
+ }
+ }
+ }
+ priority 5
+ queue-type fair-queue
+ }
+ class 40 {
+ bandwidth 90%
+ burst 15k
+ ceiling 100%
+ match ADDRESS40 {
+ ip {
+ dscp CS4
+ source {
+ address 10.2.1.0/24
+ }
+ }
+ }
+ priority 5
+ queue-type fair-queue
+ }
+ class 50 {
+ bandwidth 100%
+ burst 15k
+ match ADDRESS50 {
+ ip {
+ dscp CS5
+ }
+ }
+ queue-type fair-queue
+ set-dscp CS7
+ }
+ default {
+ bandwidth 10%
+ burst 15k
+ ceiling 100%
+ priority 7
+ queue-type fair-queue
+ set-dscp CS1
+ }
+ }
+ shaper FS {
+ bandwidth auto
+ class 10 {
+ bandwidth 100%
+ burst 15k
+ match ADDRESS10 {
+ ip {
+ source {
+ address 172.17.1.2/32
+ }
+ }
+ }
+ queue-type fair-queue
+ set-dscp CS4
+ }
+ class 20 {
+ bandwidth 100%
+ burst 15k
+ match ADDRESS20 {
+ ip {
+ source {
+ address 172.17.1.3/32
+ }
+ }
+ }
+ queue-type fair-queue
+ set-dscp CS5
+ }
+ class 30 {
+ bandwidth 100%
+ burst 15k
+ match ADDRESS30 {
+ ip {
+ source {
+ address 172.17.1.4/32
+ }
+ }
+ }
+ queue-type fair-queue
+ set-dscp CS6
+ }
+ default {
+ bandwidth 10%
+ burst 15k
+ ceiling 100%
+ priority 7
+ queue-type fair-queue
+ }
+ }
+}
+// Warning: Do not remove the following line.
+// vyos-config-version: "broadcast-relay@1:cluster@1:config-management@1:conntrack@3:conntrack-sync@2:dhcp-relay@2:dhcp-server@6:dhcpv6-server@1:dns-forwarding@3:firewall@5:https@2:interfaces@22:ipoe-server@1:ipsec@5:isis@1:l2tp@3:lldp@1:mdns@1:nat@5:ntp@1:pppoe-server@5:pptp@2:qos@1:quagga@8:rpki@1:salt@1:snmp@2:ssh@2:sstp@3:system@21:vrrp@2:vyos-accel-ppp@2:wanloadbalance@3:webproxy@2:zone-policy@1"
+// Release version: 1.3.1
+
diff --git a/smoketest/scripts/cli/base_interfaces_test.py b/smoketest/scripts/cli/base_interfaces_test.py
index 340ec4edd..816ba6dcd 100644
--- a/smoketest/scripts/cli/base_interfaces_test.py
+++ b/smoketest/scripts/cli/base_interfaces_test.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2019-2021 VyOS maintainers and contributors
+# Copyright (C) 2019-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -56,6 +56,7 @@ def is_mirrored_to(interface, mirror_if, qdisc):
class BasicInterfaceTest:
class TestCase(VyOSUnitTestSHIM.TestCase):
+ _test_dhcp = False
_test_ip = False
_test_mtu = False
_test_vlan = False
@@ -77,18 +78,25 @@ class BasicInterfaceTest:
# choose IPv6 minimum MTU value for tests - this must always work
_mtu = '1280'
- def setUp(self):
+ @classmethod
+ def setUpClass(cls):
+ super(BasicInterfaceTest.TestCase, cls).setUpClass()
+
# Setup mirror interfaces for SPAN (Switch Port Analyzer)
- for span in self._mirror_interfaces:
+ for span in cls._mirror_interfaces:
section = Section.section(span)
- self.cli_set(['interfaces', section, span])
+ cls.cli_set(cls, ['interfaces', section, span])
- def tearDown(self):
+ @classmethod
+ def tearDownClass(cls):
# Tear down mirror interfaces for SPAN (Switch Port Analyzer)
- for span in self._mirror_interfaces:
+ for span in cls._mirror_interfaces:
section = Section.section(span)
- self.cli_delete(['interfaces', section, span])
+ cls.cli_delete(cls, ['interfaces', section, span])
+
+ super(BasicInterfaceTest.TestCase, cls).tearDownClass()
+ def tearDown(self):
self.cli_delete(self._base_path)
self.cli_commit()
@@ -96,6 +104,35 @@ class BasicInterfaceTest:
for intf in self._interfaces:
self.assertNotIn(intf, interfaces())
+ # No daemon that was started during a test should remain running
+ for daemon in ['dhcp6c', 'dhclient']:
+ self.assertFalse(process_named_running(daemon))
+
+ def test_dhcp_disable_interface(self):
+ if not self._test_dhcp:
+ self.skipTest('not supported')
+
+ # When interface is configured as admin down, it must be admin down
+ # even when dhcpc starts on the given interface
+ for interface in self._interfaces:
+ self.cli_set(self._base_path + [interface, 'disable'])
+ for option in self._options.get(interface, []):
+ self.cli_set(self._base_path + [interface] + option.split())
+
+ self.cli_set(self._base_path + [interface, 'disable'])
+
+ # Also enable DHCP (ISC DHCP always places interface in admin up
+ # state so we check that we do not start DHCP client.
+ # https://phabricator.vyos.net/T2767
+ self.cli_set(self._base_path + [interface, 'address', 'dhcp'])
+
+ self.cli_commit()
+
+ # Validate interface state
+ for interface in self._interfaces:
+ flags = read_file(f'/sys/class/net/{interface}/flags')
+ self.assertEqual(int(flags, 16) & 1, 0)
+
def test_span_mirror(self):
if not self._mirror_interfaces:
self.skipTest('not supported')
@@ -171,10 +208,10 @@ class BasicInterfaceTest:
def test_add_multiple_ip_addresses(self):
# Add address
for intf in self._interfaces:
+ for option in self._options.get(intf, []):
+ self.cli_set(self._base_path + [intf] + option.split())
for addr in self._test_addr:
self.cli_set(self._base_path + [intf, 'address', addr])
- for option in self._options.get(intf, []):
- self.cli_set(self._base_path + [intf] + option.split())
self.cli_commit()
@@ -202,6 +239,7 @@ class BasicInterfaceTest:
self.cli_commit()
for interface in self._interfaces:
+ self.assertIn(AF_INET6, ifaddresses(interface))
for addr in ifaddresses(interface)[AF_INET6]:
self.assertTrue(is_ipv6_link_local(addr['addr']))
@@ -297,6 +335,23 @@ class BasicInterfaceTest:
self.assertEqual(Interface(vif).get_admin_state(), 'up')
+ # T4064: Delete interface addresses, keep VLAN interface
+ for interface in self._interfaces:
+ base = self._base_path + [interface]
+ for vlan in self._vlan_range:
+ base = self._base_path + [interface, 'vif', vlan]
+ self.cli_delete(base + ['address'])
+
+ self.cli_commit()
+
+ # Verify no IP address is assigned
+ for interface in self._interfaces:
+ for vlan in self._vlan_range:
+ vif = f'{intf}.{vlan}'
+ for address in self._test_addr:
+ self.assertFalse(is_intf_addr_assigned(vif, address))
+
+
def test_vif_8021q_mtu_limits(self):
# XXX: This testcase is not allowed to run as first testcase, reason
# is the Wireless test will first load the wifi kernel hwsim module
@@ -493,6 +548,24 @@ class BasicInterfaceTest:
tmp = get_interface_config(vif)
self.assertEqual(tmp['mtu'], int(self._mtu))
+
+ # T4064: Delete interface addresses, keep VLAN interface
+ for interface in self._interfaces:
+ base = self._base_path + [interface]
+ for vif_s in self._qinq_range:
+ for vif_c in self._vlan_range:
+ self.cli_delete(self._base_path + [interface, 'vif-s', vif_s, 'vif-c', vif_c, 'address'])
+
+ self.cli_commit()
+ # Verify no IP address is assigned
+ for interface in self._interfaces:
+ base = self._base_path + [interface]
+ for vif_s in self._qinq_range:
+ for vif_c in self._vlan_range:
+ vif = f'{interface}.{vif_s}.{vif_c}'
+ for address in self._test_addr:
+ self.assertFalse(is_intf_addr_assigned(vif, address))
+
# T3972: remove vif-c interfaces from vif-s
for interface in self._interfaces:
base = self._base_path + [interface]
@@ -572,11 +645,11 @@ class BasicInterfaceTest:
self.cli_commit()
for interface in self._interfaces:
- base_options = f'-A FORWARD -o {interface} -p tcp -m tcp --tcp-flags SYN,RST SYN'
- out = cmd('sudo iptables-save -t mangle')
+ base_options = f'oifname "{interface}"'
+ out = cmd('sudo nft list chain raw VYOS_TCP_MSS')
for line in out.splitlines():
if line.startswith(base_options):
- self.assertIn(f'--set-mss {mss}', line)
+ self.assertIn(f'tcp option maxseg size set {mss}', line)
tmp = read_file(f'/proc/sys/net/ipv4/neigh/{interface}/base_reachable_time_ms')
self.assertEqual(tmp, str((int(arp_tmo) * 1000))) # tmo value is in milli seconds
@@ -627,11 +700,11 @@ class BasicInterfaceTest:
self.cli_commit()
for interface in self._interfaces:
- base_options = f'-A FORWARD -o {interface} -p tcp -m tcp --tcp-flags SYN,RST SYN'
- out = cmd('sudo ip6tables-save -t mangle')
+ base_options = f'oifname "{interface}"'
+ out = cmd('sudo nft list chain ip6 raw VYOS_TCP_MSS')
for line in out.splitlines():
if line.startswith(base_options):
- self.assertIn(f'--set-mss {mss}', line)
+ self.assertIn(f'tcp option maxseg size set {mss}', line)
proc_base = f'/proc/sys/net/ipv6/conf/{interface}'
diff --git a/smoketest/scripts/cli/base_vyostest_shim.py b/smoketest/scripts/cli/base_vyostest_shim.py
index 50f80e7d1..7cfb53045 100644
--- a/smoketest/scripts/cli/base_vyostest_shim.py
+++ b/smoketest/scripts/cli/base_vyostest_shim.py
@@ -16,6 +16,7 @@ import os
import unittest
from time import sleep
+from typing import Type
from vyos.configsession import ConfigSession
from vyos.configsession import ConfigSessionError
@@ -73,7 +74,7 @@ class VyOSUnitTestSHIM:
def cli_commit(self):
self._session.commit()
# during a commit there is a process opening commit_lock, and run() returns 0
- while run(f'sudo lsof | grep -q {commit_lock}') == 0:
+ while run(f'sudo lsof -nP {commit_lock}') == 0:
sleep(0.250)
def getFRRconfig(self, string, end='$', endsection='^!', daemon=''):
@@ -85,3 +86,17 @@ class VyOSUnitTestSHIM:
print(f'\n\ncommand "{command}" returned:\n')
pprint.pprint(out)
return out
+
+# standard construction; typing suggestion: https://stackoverflow.com/a/70292317
+def ignore_warning(warning: Type[Warning]):
+ import warnings
+ from functools import wraps
+
+ def inner(f):
+ @wraps(f)
+ def wrapped(*args, **kwargs):
+ with warnings.catch_warnings():
+ warnings.simplefilter("ignore", category=warning)
+ return f(*args, **kwargs)
+ return wrapped
+ return inner
diff --git a/smoketest/scripts/cli/test_component_version.py b/smoketest/scripts/cli/test_component_version.py
new file mode 100755
index 000000000..777379bdd
--- /dev/null
+++ b/smoketest/scripts/cli/test_component_version.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import unittest
+
+from vyos.systemversions import get_system_versions, get_system_component_version
+
+# After T3474, component versions should be updated in the files in
+# vyos-1x/interface-definitions/include/version/
+# This test verifies that the legacy version in curver_DATA does not exceed
+# that in the xml cache.
+class TestComponentVersion(unittest.TestCase):
+ def setUp(self):
+ self.legacy_d = get_system_versions()
+ self.xml_d = get_system_component_version()
+
+ def test_component_version(self):
+ self.assertTrue(set(self.legacy_d).issubset(set(self.xml_d)))
+ for k, v in self.legacy_d.items():
+ self.assertTrue(v <= self.xml_d[k])
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_configd_init.py b/smoketest/scripts/cli/test_configd_init.py
new file mode 100755
index 000000000..5dec89963
--- /dev/null
+++ b/smoketest/scripts/cli/test_configd_init.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import unittest
+from time import sleep
+
+from vyos.util import cmd, is_systemd_service_running
+
+class TestConfigdInit(unittest.TestCase):
+ def setUp(self):
+ self.running_state = is_systemd_service_running('vyos-configd.service')
+
+ def test_configd_init(self):
+ if not self.running_state:
+ cmd('sudo systemctl start vyos-configd.service')
+ # allow time for init to succeed/fail
+ sleep(2)
+ self.assertTrue(is_systemd_service_running('vyos-configd.service'))
+
+ def tearDown(self):
+ if not self.running_state:
+ cmd('sudo systemctl stop vyos-configd.service')
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py
new file mode 100755
index 000000000..b8f944575
--- /dev/null
+++ b/smoketest/scripts/cli/test_firewall.py
@@ -0,0 +1,233 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021-2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import unittest
+
+from glob import glob
+
+from base_vyostest_shim import VyOSUnitTestSHIM
+
+from vyos.util import cmd
+
+sysfs_config = {
+ 'all_ping': {'sysfs': '/proc/sys/net/ipv4/icmp_echo_ignore_all', 'default': '0', 'test_value': 'disable'},
+ 'broadcast_ping': {'sysfs': '/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts', 'default': '1', 'test_value': 'enable'},
+ 'ip_src_route': {'sysfs': '/proc/sys/net/ipv4/conf/*/accept_source_route', 'default': '0', 'test_value': 'enable'},
+ 'ipv6_receive_redirects': {'sysfs': '/proc/sys/net/ipv6/conf/*/accept_redirects', 'default': '0', 'test_value': 'enable'},
+ 'ipv6_src_route': {'sysfs': '/proc/sys/net/ipv6/conf/*/accept_source_route', 'default': '-1', 'test_value': 'enable'},
+ 'log_martians': {'sysfs': '/proc/sys/net/ipv4/conf/all/log_martians', 'default': '1', 'test_value': 'disable'},
+ 'receive_redirects': {'sysfs': '/proc/sys/net/ipv4/conf/*/accept_redirects', 'default': '0', 'test_value': 'enable'},
+ 'send_redirects': {'sysfs': '/proc/sys/net/ipv4/conf/*/send_redirects', 'default': '1', 'test_value': 'disable'},
+ 'syn_cookies': {'sysfs': '/proc/sys/net/ipv4/tcp_syncookies', 'default': '1', 'test_value': 'disable'},
+ 'twa_hazards_protection': {'sysfs': '/proc/sys/net/ipv4/tcp_rfc1337', 'default': '0', 'test_value': 'enable'}
+}
+
+class TestFirewall(VyOSUnitTestSHIM.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ super(TestFirewall, cls).setUpClass()
+
+ # ensure we can also run this test on a live system - so lets clean
+ # out the current configuration :)
+ cls.cli_delete(cls, ['firewall'])
+
+ cls.cli_set(cls, ['interfaces', 'ethernet', 'eth0', 'address', '172.16.10.1/24'])
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.cli_delete(cls, ['interfaces', 'ethernet', 'eth0', 'address', '172.16.10.1/24'])
+ super(TestFirewall, cls).tearDownClass()
+
+ def tearDown(self):
+ self.cli_delete(['interfaces', 'ethernet', 'eth0', 'firewall'])
+ self.cli_delete(['firewall'])
+ self.cli_commit()
+
+ def test_groups(self):
+ self.cli_set(['firewall', 'group', 'mac-group', 'smoketest_mac', 'mac-address', '00:01:02:03:04:05'])
+ self.cli_set(['firewall', 'group', 'network-group', 'smoketest_network', 'network', '172.16.99.0/24'])
+ self.cli_set(['firewall', 'group', 'port-group', 'smoketest_port', 'port', '53'])
+ self.cli_set(['firewall', 'group', 'port-group', 'smoketest_port', 'port', '123'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'action', 'accept'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'source', 'group', 'network-group', 'smoketest_network'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'destination', 'address', '172.16.10.10'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'destination', 'group', 'port-group', 'smoketest_port'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'protocol', 'tcp_udp'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'action', 'accept'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'source', 'group', 'mac-group', 'smoketest_mac'])
+
+ self.cli_set(['interfaces', 'ethernet', 'eth0', 'firewall', 'in', 'name', 'smoketest'])
+
+ self.cli_commit()
+
+ nftables_search = [
+ ['iifname "eth0"', 'jump NAME_smoketest'],
+ ['ip saddr { 172.16.99.0/24 }', 'ip daddr 172.16.10.10', 'th dport { 53, 123 }', 'return'],
+ ['ether saddr { 00:01:02:03:04:05 }', 'return']
+ ]
+
+ nftables_output = cmd('sudo nft list table ip filter')
+
+ for search in nftables_search:
+ matched = False
+ for line in nftables_output.split("\n"):
+ if all(item in line for item in search):
+ matched = True
+ break
+ self.assertTrue(matched, msg=search)
+
+ def test_basic_rules(self):
+ self.cli_set(['firewall', 'name', 'smoketest', 'default-action', 'drop'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'action', 'accept'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'source', 'address', '172.16.20.10'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'destination', 'address', '172.16.10.10'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'action', 'reject'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'protocol', 'tcp'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'destination', 'port', '8888'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'tcp', 'flags', 'syn'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'tcp', 'flags', 'not', 'ack'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'action', 'accept'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'protocol', 'tcp'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'destination', 'port', '22'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'limit', 'rate', '5/minute'])
+
+ self.cli_set(['interfaces', 'ethernet', 'eth0', 'firewall', 'in', 'name', 'smoketest'])
+
+ self.cli_commit()
+
+ nftables_search = [
+ ['iifname "eth0"', 'jump NAME_smoketest'],
+ ['saddr 172.16.20.10', 'daddr 172.16.10.10', 'return'],
+ ['tcp flags & (syn | ack) == syn', 'tcp dport { 8888 }', 'reject'],
+ ['tcp dport { 22 }', 'limit rate 5/minute', 'return'],
+ ['smoketest default-action', 'drop']
+ ]
+
+ nftables_output = cmd('sudo nft list table ip filter')
+
+ for search in nftables_search:
+ matched = False
+ for line in nftables_output.split("\n"):
+ if all(item in line for item in search):
+ matched = True
+ break
+ self.assertTrue(matched, msg=search)
+
+ def test_basic_rules_ipv6(self):
+ self.cli_set(['firewall', 'ipv6-name', 'v6-smoketest', 'default-action', 'drop'])
+ self.cli_set(['firewall', 'ipv6-name', 'v6-smoketest', 'rule', '1', 'action', 'accept'])
+ self.cli_set(['firewall', 'ipv6-name', 'v6-smoketest', 'rule', '1', 'source', 'address', '2002::1'])
+ self.cli_set(['firewall', 'ipv6-name', 'v6-smoketest', 'rule', '1', 'destination', 'address', '2002::1:1'])
+ self.cli_set(['firewall', 'ipv6-name', 'v6-smoketest', 'rule', '2', 'action', 'reject'])
+ self.cli_set(['firewall', 'ipv6-name', 'v6-smoketest', 'rule', '2', 'protocol', 'tcp_udp'])
+ self.cli_set(['firewall', 'ipv6-name', 'v6-smoketest', 'rule', '2', 'destination', 'port', '8888'])
+
+ self.cli_set(['interfaces', 'ethernet', 'eth0', 'firewall', 'in', 'ipv6-name', 'v6-smoketest'])
+
+ self.cli_commit()
+
+ nftables_search = [
+ ['iifname "eth0"', 'jump NAME6_v6-smoketest'],
+ ['saddr 2002::1', 'daddr 2002::1:1', 'return'],
+ ['meta l4proto { tcp, udp }', 'th dport { 8888 }', 'reject'],
+ ['smoketest default-action', 'drop']
+ ]
+
+ nftables_output = cmd('sudo nft list table ip6 filter')
+
+ for search in nftables_search:
+ matched = False
+ for line in nftables_output.split("\n"):
+ if all(item in line for item in search):
+ matched = True
+ break
+ self.assertTrue(matched, msg=search)
+
+ def test_state_policy(self):
+ self.cli_set(['firewall', 'state-policy', 'established', 'action', 'accept'])
+ self.cli_set(['firewall', 'state-policy', 'related', 'action', 'accept'])
+ self.cli_set(['firewall', 'state-policy', 'invalid', 'action', 'drop'])
+
+ self.cli_commit()
+
+ chains = {
+ 'ip filter': ['VYOS_FW_FORWARD', 'VYOS_FW_OUTPUT', 'VYOS_FW_LOCAL'],
+ 'ip6 filter': ['VYOS_FW6_FORWARD', 'VYOS_FW6_OUTPUT', 'VYOS_FW6_LOCAL']
+ }
+
+ for table in ['ip filter', 'ip6 filter']:
+ for chain in chains[table]:
+ nftables_output = cmd(f'sudo nft list chain {table} {chain}')
+ self.assertTrue('jump VYOS_STATE_POLICY' in nftables_output)
+
+ def test_state_and_status_rules(self):
+ self.cli_set(['firewall', 'name', 'smoketest', 'default-action', 'drop'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'action', 'accept'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'state', 'established', 'enable'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'state', 'related', 'enable'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'action', 'reject'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'state', 'invalid', 'enable'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'action', 'accept'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'state', 'new', 'enable'])
+
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'connection-status', 'nat', 'destination'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '4', 'action', 'accept'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '4', 'state', 'new', 'enable'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '4', 'state', 'established', 'enable'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '4', 'connection-status', 'nat', 'source'])
+
+ self.cli_set(['interfaces', 'ethernet', 'eth0', 'firewall', 'in', 'name', 'smoketest'])
+
+ self.cli_commit()
+
+ nftables_search = [
+ ['iifname "eth0"', 'jump NAME_smoketest'],
+ ['ct state { established, related }', 'return'],
+ ['ct state { invalid }', 'reject'],
+ ['ct state { new }', 'ct status { dnat }', 'return'],
+ ['ct state { established, new }', 'ct status { snat }', 'return'],
+ ['smoketest default-action', 'drop']
+ ]
+
+ nftables_output = cmd('sudo nft list table ip filter')
+
+ for search in nftables_search:
+ matched = False
+ for line in nftables_output.split("\n"):
+ if all(item in line for item in search):
+ matched = True
+ break
+ self.assertTrue(matched, msg=search)
+
+ def test_sysfs(self):
+ for name, conf in sysfs_config.items():
+ paths = glob(conf['sysfs'])
+ for path in paths:
+ with open(path, 'r') as f:
+ self.assertEqual(f.read().strip(), conf['default'], msg=path)
+
+ self.cli_set(['firewall', name.replace("_", "-"), conf['test_value']])
+
+ self.cli_commit()
+
+ for name, conf in sysfs_config.items():
+ paths = glob(conf['sysfs'])
+ for path in paths:
+ with open(path, 'r') as f:
+ self.assertNotEqual(f.read().strip(), conf['default'], msg=path)
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_ha_virtual_server.py b/smoketest/scripts/cli/test_ha_virtual_server.py
new file mode 100755
index 000000000..e3a91283e
--- /dev/null
+++ b/smoketest/scripts/cli/test_ha_virtual_server.py
@@ -0,0 +1,146 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021-2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import unittest
+
+from base_vyostest_shim import VyOSUnitTestSHIM
+
+from vyos.configsession import ConfigSessionError
+from vyos.ifconfig.vrrp import VRRP
+from vyos.util import cmd
+from vyos.util import process_named_running
+from vyos.util import read_file
+from vyos.template import inc_ip
+
+PROCESS_NAME = 'keepalived'
+KEEPALIVED_CONF = VRRP.location['config']
+base_path = ['high-availability']
+vrrp_interface = 'eth1'
+
+class TestHAVirtualServer(VyOSUnitTestSHIM.TestCase):
+ def tearDown(self):
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+ self.cli_delete(['interfaces', 'ethernet', vrrp_interface, 'address'])
+ self.cli_delete(base_path)
+ self.cli_commit()
+
+ # Process must be terminated after deleting the config
+ self.assertFalse(process_named_running(PROCESS_NAME))
+
+ def test_01_ha_virtual_server(self):
+ algo = 'least-connection'
+ delay = '10'
+ method = 'nat'
+ persistence_timeout = '600'
+ vip = '203.0.113.111'
+ vport = '2222'
+ rservers = ['192.0.2.21', '192.0.2.22', '192.0.2.23']
+ rport = '22'
+ proto = 'tcp'
+ connection_timeout = '30'
+
+ vserver_base = base_path + ['virtual-server']
+
+ self.cli_set(vserver_base + [vip, 'algorithm', algo])
+ self.cli_set(vserver_base + [vip, 'delay-loop', delay])
+ self.cli_set(vserver_base + [vip, 'forward-method', method])
+ self.cli_set(vserver_base + [vip, 'persistence-timeout', persistence_timeout])
+ self.cli_set(vserver_base + [vip, 'port', vport])
+ self.cli_set(vserver_base + [vip, 'protocol', proto])
+ for rs in rservers:
+ self.cli_set(vserver_base + [vip, 'real-server', rs, 'connection-timeout', connection_timeout])
+ self.cli_set(vserver_base + [vip, 'real-server', rs, 'port', rport])
+
+ # commit changes
+ self.cli_commit()
+
+ config = read_file(KEEPALIVED_CONF)
+
+ self.assertIn(f'delay_loop {delay}', config)
+ self.assertIn(f'lb_algo lc', config)
+ self.assertIn(f'lb_kind {method.upper()}', config)
+ self.assertIn(f'persistence_timeout {persistence_timeout}', config)
+ self.assertIn(f'protocol {proto.upper()}', config)
+ for rs in rservers:
+ self.assertIn(f'real_server {rs} {rport}', config)
+ self.assertIn(f'{proto.upper()}_CHECK', config)
+ self.assertIn(f'connect_timeout {connection_timeout}', config)
+
+ def test_02_ha_virtual_server_and_vrrp(self):
+ algo = 'least-connection'
+ delay = '15'
+ method = 'nat'
+ persistence_timeout = '300'
+ vip = '203.0.113.222'
+ vport = '22322'
+ rservers = ['192.0.2.11', '192.0.2.12']
+ rport = '222'
+ proto = 'tcp'
+ connection_timeout = '23'
+ group = 'VyOS'
+ vrid = '99'
+
+ vrrp_base = base_path + ['vrrp', 'group']
+ vserver_base = base_path + ['virtual-server']
+
+ self.cli_set(['interfaces', 'ethernet', vrrp_interface, 'address', '203.0.113.10/24'])
+
+ # VRRP config
+ self.cli_set(vrrp_base + [group, 'description', group])
+ self.cli_set(vrrp_base + [group, 'interface', vrrp_interface])
+ self.cli_set(vrrp_base + [group, 'address', vip + '/24'])
+ self.cli_set(vrrp_base + [group, 'vrid', vrid])
+
+ # Virtual-server config
+ self.cli_set(vserver_base + [vip, 'algorithm', algo])
+ self.cli_set(vserver_base + [vip, 'delay-loop', delay])
+ self.cli_set(vserver_base + [vip, 'forward-method', method])
+ self.cli_set(vserver_base + [vip, 'persistence-timeout', persistence_timeout])
+ self.cli_set(vserver_base + [vip, 'port', vport])
+ self.cli_set(vserver_base + [vip, 'protocol', proto])
+ for rs in rservers:
+ self.cli_set(vserver_base + [vip, 'real-server', rs, 'connection-timeout', connection_timeout])
+ self.cli_set(vserver_base + [vip, 'real-server', rs, 'port', rport])
+
+ # commit changes
+ self.cli_commit()
+
+ config = read_file(KEEPALIVED_CONF)
+
+ # Keepalived vrrp
+ self.assertIn(f'# {group}', config)
+ self.assertIn(f'interface {vrrp_interface}', config)
+ self.assertIn(f'virtual_router_id {vrid}', config)
+ self.assertIn(f'priority 100', config) # default value
+ self.assertIn(f'advert_int 1', config) # default value
+ self.assertIn(f'preempt_delay 0', config) # default value
+
+ # Keepalived virtual-server
+ self.assertIn(f'delay_loop {delay}', config)
+ self.assertIn(f'lb_algo lc', config)
+ self.assertIn(f'lb_kind {method.upper()}', config)
+ self.assertIn(f'persistence_timeout {persistence_timeout}', config)
+ self.assertIn(f'protocol {proto.upper()}', config)
+ for rs in rservers:
+ self.assertIn(f'real_server {rs} {rport}', config)
+ self.assertIn(f'{proto.upper()}_CHECK', config)
+ self.assertIn(f'connect_timeout {connection_timeout}', config)
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_ha_vrrp.py b/smoketest/scripts/cli/test_ha_vrrp.py
index 2524bf2b1..68905e447 100755
--- a/smoketest/scripts/cli/test_ha_vrrp.py
+++ b/smoketest/scripts/cli/test_ha_vrrp.py
@@ -27,7 +27,7 @@ from vyos.template import inc_ip
PROCESS_NAME = 'keepalived'
KEEPALIVED_CONF = VRRP.location['config']
-base_path = ['high-availability', 'vrrp']
+base_path = ['high-availability']
vrrp_interface = 'eth1'
groups = ['VLAN77', 'VLAN78', 'VLAN201']
@@ -44,7 +44,7 @@ class TestVRRP(VyOSUnitTestSHIM.TestCase):
for group in groups:
vlan_id = group.lstrip('VLAN')
- self.cli_set(['interfaces', 'ethernet', vrrp_interface, 'vif', vlan_id])
+ self.cli_delete(['interfaces', 'ethernet', vrrp_interface, 'vif', vlan_id])
self.cli_delete(base_path)
self.cli_commit()
@@ -56,7 +56,7 @@ class TestVRRP(VyOSUnitTestSHIM.TestCase):
for group in groups:
vlan_id = group.lstrip('VLAN')
vip = f'100.64.{vlan_id}.1/24'
- group_base = base_path + ['group', group]
+ group_base = base_path + ['vrrp', 'group', group]
self.cli_set(['interfaces', 'ethernet', vrrp_interface, 'vif', vlan_id, 'address', inc_ip(vip, 1) + '/' + vip.split('/')[-1]])
@@ -91,7 +91,7 @@ class TestVRRP(VyOSUnitTestSHIM.TestCase):
for group in groups:
vlan_id = group.lstrip('VLAN')
vip = f'100.64.{vlan_id}.1/24'
- group_base = base_path + ['group', group]
+ group_base = base_path + ['vrrp', 'group', group]
self.cli_set(['interfaces', 'ethernet', vrrp_interface, 'vif', vlan_id, 'address', inc_ip(vip, 1) + '/' + vip.split('/')[-1]])
@@ -108,7 +108,7 @@ class TestVRRP(VyOSUnitTestSHIM.TestCase):
# Authentication
self.cli_set(group_base + ['authentication', 'type', 'plaintext-password'])
- self.cli_set(group_base + ['authentication', 'password', f'vyos-{group}'])
+ self.cli_set(group_base + ['authentication', 'password', f'{group}'])
# commit changes
self.cli_commit()
@@ -129,7 +129,7 @@ class TestVRRP(VyOSUnitTestSHIM.TestCase):
self.assertIn(f' {vip}', config)
# Authentication
- self.assertIn(f'auth_pass "vyos-{group}"', config)
+ self.assertIn(f'auth_pass "{group}"', config)
self.assertIn(f'auth_type PASS', config)
def test_03_sync_group(self):
@@ -138,7 +138,7 @@ class TestVRRP(VyOSUnitTestSHIM.TestCase):
for group in groups:
vlan_id = group.lstrip('VLAN')
vip = f'100.64.{vlan_id}.1/24'
- group_base = base_path + ['group', group]
+ group_base = base_path + ['vrrp', 'group', group]
self.cli_set(['interfaces', 'ethernet', vrrp_interface, 'vif', vlan_id, 'address', inc_ip(vip, 1) + '/' + vip.split('/')[-1]])
@@ -146,7 +146,7 @@ class TestVRRP(VyOSUnitTestSHIM.TestCase):
self.cli_set(group_base + ['address', vip])
self.cli_set(group_base + ['vrid', vlan_id])
- self.cli_set(base_path + ['sync-group', sync_group, 'member', group])
+ self.cli_set(base_path + ['vrrp', 'sync-group', sync_group, 'member', group])
# commit changes
self.cli_commit()
@@ -166,5 +166,35 @@ class TestVRRP(VyOSUnitTestSHIM.TestCase):
for group in groups:
self.assertIn(f'{group}', config)
+ def test_04_exclude_vrrp_interface(self):
+ group = 'VyOS-WAN'
+ none_vrrp_interface = 'eth2'
+ vlan_id = '24'
+ vip = '100.64.24.1/24'
+ vip_dev = '192.0.2.2/24'
+ vrid = '150'
+ group_base = base_path + ['vrrp', 'group', group]
+
+ self.cli_set(['interfaces', 'ethernet', vrrp_interface, 'vif', vlan_id, 'address', '100.64.24.11/24'])
+ self.cli_set(group_base + ['interface', f'{vrrp_interface}.{vlan_id}'])
+ self.cli_set(group_base + ['address', vip])
+ self.cli_set(group_base + ['address', vip_dev, 'interface', none_vrrp_interface])
+ self.cli_set(group_base + ['track', 'exclude-vrrp-interface'])
+ self.cli_set(group_base + ['track', 'interface', none_vrrp_interface])
+ self.cli_set(group_base + ['vrid', vrid])
+
+ # commit changes
+ self.cli_commit()
+
+ config = getConfig(f'vrrp_instance {group}')
+
+ self.assertIn(f'interface {vrrp_interface}.{vlan_id}', config)
+ self.assertIn(f'virtual_router_id {vrid}', config)
+ self.assertIn(f'dont_track_primary', config)
+ self.assertIn(f' {vip}', config)
+ self.assertIn(f' {vip_dev} dev {none_vrrp_interface}', config)
+ self.assertIn(f'track_interface', config)
+ self.assertIn(f' {none_vrrp_interface}', config)
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_interfaces_bonding.py b/smoketest/scripts/cli/test_interfaces_bonding.py
index 86000553e..237abb487 100755
--- a/smoketest/scripts/cli/test_interfaces_bonding.py
+++ b/smoketest/scripts/cli/test_interfaces_bonding.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright (C) 2020-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -28,6 +28,7 @@ from vyos.util import read_file
class BondingInterfaceTest(BasicInterfaceTest.TestCase):
@classmethod
def setUpClass(cls):
+ cls._test_dhcp = True
cls._test_ip = True
cls._test_ipv6 = True
cls._test_ipv6_pd = True
@@ -36,7 +37,6 @@ class BondingInterfaceTest(BasicInterfaceTest.TestCase):
cls._test_vlan = True
cls._test_qinq = True
cls._base_path = ['interfaces', 'bonding']
- cls._interfaces = ['bond0']
cls._mirror_interfaces = ['dum21354']
cls._members = []
@@ -52,9 +52,10 @@ class BondingInterfaceTest(BasicInterfaceTest.TestCase):
cls._options['bond0'] = []
for member in cls._members:
cls._options['bond0'].append(f'member interface {member}')
+ cls._interfaces = list(cls._options)
# call base-classes classmethod
- super(cls, cls).setUpClass()
+ super(BondingInterfaceTest, cls).setUpClass()
def test_add_single_ip_address(self):
super().test_add_single_ip_address()
@@ -150,5 +151,41 @@ class BondingInterfaceTest(BasicInterfaceTest.TestCase):
defined_policy = read_file(f'/sys/class/net/{interface}/bonding/xmit_hash_policy').split()
self.assertEqual(defined_policy[0], hash_policy)
+ def test_bonding_multi_use_member(self):
+ # Define available bonding hash policies
+ for interface in ['bond10', 'bond20']:
+ for member in self._members:
+ self.cli_set(self._base_path + [interface, 'member', 'interface', member])
+
+ # check validate() - can not use the same member interfaces multiple times
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ self.cli_delete(self._base_path + ['bond20'])
+
+ self.cli_commit()
+
+ def test_bonding_uniq_member_description(self):
+ ethernet_path = ['interfaces', 'ethernet']
+ for interface in self._interfaces:
+ for option in self._options.get(interface, []):
+ self.cli_set(self._base_path + [interface] + option.split())
+
+ self.cli_commit()
+
+ # Add any changes on bonding members
+ # For example add description on separate ethX interfaces
+ for interface in self._interfaces:
+ for member in self._members:
+ self.cli_set(ethernet_path + [member, 'description', member + '_interface'])
+
+ self.cli_commit()
+
+ # verify config
+ for interface in self._interfaces:
+ slaves = read_file(f'/sys/class/net/{interface}/bonding/slaves').split()
+ for member in self._members:
+ self.assertIn(member, slaves)
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_interfaces_bridge.py b/smoketest/scripts/cli/test_interfaces_bridge.py
index 4f7e03298..ca0ead9e8 100755
--- a/smoketest/scripts/cli/test_interfaces_bridge.py
+++ b/smoketest/scripts/cli/test_interfaces_bridge.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright (C) 2020-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -31,6 +31,7 @@ from vyos.validate import is_intf_addr_assigned
class BridgeInterfaceTest(BasicInterfaceTest.TestCase):
@classmethod
def setUpClass(cls):
+ cls._test_dhcp = True
cls._test_ip = True
cls._test_ipv6 = True
cls._test_ipv6_pd = True
@@ -55,7 +56,7 @@ class BridgeInterfaceTest(BasicInterfaceTest.TestCase):
cls._interfaces = list(cls._options)
# call base-classes classmethod
- super(cls, cls).setUpClass()
+ super(BridgeInterfaceTest, cls).setUpClass()
def tearDown(self):
for intf in self._interfaces:
diff --git a/smoketest/scripts/cli/test_interfaces_dummy.py b/smoketest/scripts/cli/test_interfaces_dummy.py
index dedc6fe05..d96ec2c5d 100755
--- a/smoketest/scripts/cli/test_interfaces_dummy.py
+++ b/smoketest/scripts/cli/test_interfaces_dummy.py
@@ -24,7 +24,7 @@ class DummyInterfaceTest(BasicInterfaceTest.TestCase):
cls._base_path = ['interfaces', 'dummy']
cls._interfaces = ['dum435', 'dum8677', 'dum0931', 'dum089']
# call base-classes classmethod
- super(cls, cls).setUpClass()
+ super(DummyInterfaceTest, cls).setUpClass()
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_interfaces_ethernet.py b/smoketest/scripts/cli/test_interfaces_ethernet.py
index 6d80e4c96..05d2ae5f5 100755
--- a/smoketest/scripts/cli/test_interfaces_ethernet.py
+++ b/smoketest/scripts/cli/test_interfaces_ethernet.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright (C) 2020-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -18,32 +18,82 @@ import os
import re
import unittest
+from netifaces import AF_INET
+from netifaces import AF_INET6
+from netifaces import ifaddresses
+
from base_interfaces_test import BasicInterfaceTest
from vyos.configsession import ConfigSessionError
from vyos.ifconfig import Section
+from vyos.pki import CERT_BEGIN
+from vyos.template import is_ipv6
from vyos.util import cmd
from vyos.util import process_named_running
from vyos.util import read_file
+from vyos.validate import is_ipv6_link_local
+
+server_ca_root_cert_data = """
+MIIBcTCCARagAwIBAgIUDcAf1oIQV+6WRaW7NPcSnECQ/lUwCgYIKoZIzj0EAwIw
+HjEcMBoGA1UEAwwTVnlPUyBzZXJ2ZXIgcm9vdCBDQTAeFw0yMjAyMTcxOTQxMjBa
+Fw0zMjAyMTUxOTQxMjBaMB4xHDAaBgNVBAMME1Z5T1Mgc2VydmVyIHJvb3QgQ0Ew
+WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQ0y24GzKQf4aM2Ir12tI9yITOIzAUj
+ZXyJeCmYI6uAnyAMqc4Q4NKyfq3nBi4XP87cs1jlC1P2BZ8MsjL5MdGWozIwMDAP
+BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRwC/YaieMEnjhYa7K3Flw/o0SFuzAK
+BggqhkjOPQQDAgNJADBGAiEAh3qEj8vScsjAdBy5shXzXDVVOKWCPTdGrPKnu8UW
+a2cCIQDlDgkzWmn5ujc5ATKz1fj+Se/aeqwh4QyoWCVTFLIxhQ==
+"""
-cert_data = """
-MIICFDCCAbugAwIBAgIUfMbIsB/ozMXijYgUYG80T1ry+mcwCgYIKoZIzj0EAwIw
-WTELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNv
-bWUtQ2l0eTENMAsGA1UECgwEVnlPUzESMBAGA1UEAwwJVnlPUyBUZXN0MB4XDTIx
-MDcyMDEyNDUxMloXDTI2MDcxOTEyNDUxMlowWTELMAkGA1UEBhMCR0IxEzARBgNV
-BAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlP
-UzESMBAGA1UEAwwJVnlPUyBUZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
-01HrLcNttqq4/PtoMua8rMWEkOdBu7vP94xzDO7A8C92ls1v86eePy4QllKCzIw3
-QxBIoCuH2peGRfWgPRdFsKNhMF8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
-BAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMB0GA1UdDgQWBBSu
-+JnU5ZC4mkuEpqg2+Mk4K79oeDAKBggqhkjOPQQDAgNHADBEAiBEFdzQ/Bc3Lftz
-ngrY605UhA6UprHhAogKgROv7iR4QgIgEFUxTtW3xXJcnUPWhhUFhyZoqfn8dE93
-+dm/LDnp7C0=
+server_ca_intermediate_cert_data = """
+MIIBmTCCAT+gAwIBAgIUNzrtHzLmi3QpPK57tUgCnJZhXXQwCgYIKoZIzj0EAwIw
+HjEcMBoGA1UEAwwTVnlPUyBzZXJ2ZXIgcm9vdCBDQTAeFw0yMjAyMTcxOTQxMjFa
+Fw0zMjAyMTUxOTQxMjFaMCYxJDAiBgNVBAMMG1Z5T1Mgc2VydmVyIGludGVybWVk
+aWF0ZSBDQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABEl2nJ1CzoqPV6hWII2m
+eGN/uieU6wDMECTk/LgG8CCCSYb488dibUiFN/1UFsmoLIdIhkx/6MUCYh62m8U2
+WNujUzBRMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMV3YwH88I5gFsFUibbQ
+kMR0ECPsMB8GA1UdIwQYMBaAFHAL9hqJ4wSeOFhrsrcWXD+jRIW7MAoGCCqGSM49
+BAMCA0gAMEUCIQC/ahujD9dp5pMMCd3SZddqGC9cXtOwMN0JR3e5CxP13AIgIMQm
+jMYrinFoInxmX64HfshYqnUY8608nK9D2BNPOHo=
"""
-key_data = """
-MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgPLpD0Ohhoq0g4nhx
-2KMIuze7ucKUt/lBEB2wc03IxXyhRANCAATTUestw222qrj8+2gy5rysxYSQ50G7
-u8/3jHMM7sDwL3aWzW/zp54/LhCWUoLMjDdDEEigK4fal4ZF9aA9F0Ww
+client_ca_root_cert_data = """
+MIIBcDCCARagAwIBAgIUZmoW2xVdwkZSvglnkCq0AHKa6zIwCgYIKoZIzj0EAwIw
+HjEcMBoGA1UEAwwTVnlPUyBjbGllbnQgcm9vdCBDQTAeFw0yMjAyMTcxOTQxMjFa
+Fw0zMjAyMTUxOTQxMjFaMB4xHDAaBgNVBAMME1Z5T1MgY2xpZW50IHJvb3QgQ0Ew
+WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATUpKXzQk2NOVKDN4VULk2yw4mOKPvn
+mg947+VY7lbpfOfAUD0QRg95qZWCw899eKnXp/U4TkAVrmEKhUb6OJTFozIwMDAP
+BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTXu6xGWUl25X3sBtrhm3BJSICIATAK
+BggqhkjOPQQDAgNIADBFAiEAnTzEwuTI9bz2Oae3LZbjP6f/f50KFJtjLZFDbQz7
+DpYCIDNRHV8zBUibC+zg5PqMpQBKd/oPfNU76nEv6xkp/ijO
+"""
+
+client_ca_intermediate_cert_data = """
+MIIBmDCCAT+gAwIBAgIUJEMdotgqA7wU4XXJvEzDulUAGqgwCgYIKoZIzj0EAwIw
+HjEcMBoGA1UEAwwTVnlPUyBjbGllbnQgcm9vdCBDQTAeFw0yMjAyMTcxOTQxMjJa
+Fw0zMjAyMTUxOTQxMjJaMCYxJDAiBgNVBAMMG1Z5T1MgY2xpZW50IGludGVybWVk
+aWF0ZSBDQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGyIVIi217s9j3O+WQ2b
+6R65/Z0ZjQpELxPjBRc0CA0GFCo+pI5EvwI+jNFArvTAJ5+ZdEWUJ1DQhBKDDQdI
+avCjUzBRMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOUS8oNJjChB1Rb9Blcl
+ETvziHJ9MB8GA1UdIwQYMBaAFNe7rEZZSXblfewG2uGbcElIgIgBMAoGCCqGSM49
+BAMCA0cAMEQCIArhaxWgRsAUbEeNHD/ULtstLHxw/P97qPUSROLQld53AiBjgiiz
+9pDfISmpekZYz6bIDWRIR0cXUToZEMFNzNMrQg==
+"""
+
+client_cert_data = """
+MIIBmTCCAUCgAwIBAgIUV5T77XdE/tV82Tk4Vzhp5BIFFm0wCgYIKoZIzj0EAwIw
+JjEkMCIGA1UEAwwbVnlPUyBjbGllbnQgaW50ZXJtZWRpYXRlIENBMB4XDTIyMDIx
+NzE5NDEyMloXDTMyMDIxNTE5NDEyMlowIjEgMB4GA1UEAwwXVnlPUyBjbGllbnQg
+Y2VydGlmaWNhdGUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARuyynqfc/qJj5e
+KJ03oOH8X4Z8spDeAPO9WYckMM0ldPj+9kU607szFzPwjaPWzPdgyIWz3hcN8yAh
+CIhytmJao1AwTjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBTIFKrxZ+PqOhYSUqnl
+TGCUmM7wTjAfBgNVHSMEGDAWgBTlEvKDSYwoQdUW/QZXJRE784hyfTAKBggqhkjO
+PQQDAgNHADBEAiAvO8/jvz05xqmP3OXD53XhfxDLMIxzN4KPoCkFqvjlhQIgIHq2
+/geVx3rAOtSps56q/jiDouN/aw01TdpmGKVAa9U=
+"""
+
+client_key_data = """
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgxaxAQsJwjoOCByQE
++qSYKtKtJzbdbOnTsKNSrfgkFH6hRANCAARuyynqfc/qJj5eKJ03oOH8X4Z8spDe
+APO9WYckMM0ldPj+9kU607szFzPwjaPWzPdgyIWz3hcN8yAhCIhytmJa
"""
def get_wpa_supplicant_value(interface, key):
@@ -51,9 +101,14 @@ def get_wpa_supplicant_value(interface, key):
tmp = re.findall(r'\n?{}=(.*)'.format(key), tmp)
return tmp[0]
+def get_certificate_count(interface, cert_type):
+ tmp = read_file(f'/run/wpa_supplicant/{interface}_{cert_type}.pem')
+ return tmp.count(CERT_BEGIN)
+
class EthernetInterfaceTest(BasicInterfaceTest.TestCase):
@classmethod
def setUpClass(cls):
+ cls._test_dhcp = True
cls._test_ip = True
cls._test_ipv6 = True
cls._test_ipv6_pd = True
@@ -79,7 +134,7 @@ class EthernetInterfaceTest(BasicInterfaceTest.TestCase):
cls._macs[interface] = read_file(f'/sys/class/net/{interface}/address')
# call base-classes classmethod
- super(cls, cls).setUpClass()
+ super(EthernetInterfaceTest, cls).setUpClass()
def tearDown(self):
for interface in self._interfaces:
@@ -91,30 +146,19 @@ class EthernetInterfaceTest(BasicInterfaceTest.TestCase):
self.cli_set(self._base_path + [interface, 'speed', 'auto'])
self.cli_set(self._base_path + [interface, 'hw-id', self._macs[interface]])
- # Tear down mirror interfaces for SPAN (Switch Port Analyzer)
- for span in self._mirror_interfaces:
- section = Section.section(span)
- self.cli_delete(['interfaces', section, span])
-
self.cli_commit()
- def test_dhcp_disable_interface(self):
- # When interface is configured as admin down, it must be admin down
- # even when dhcpc starts on the given interface
- for interface in self._interfaces:
- self.cli_set(self._base_path + [interface, 'disable'])
-
- # Also enable DHCP (ISC DHCP always places interface in admin up
- # state so we check that we do not start DHCP client.
- # https://phabricator.vyos.net/T2767
- self.cli_set(self._base_path + [interface, 'address', 'dhcp'])
-
- self.cli_commit()
-
- # Validate interface state
- for interface in self._interfaces:
- flags = read_file(f'/sys/class/net/{interface}/flags')
- self.assertEqual(int(flags, 16) & 1, 0)
+ # Verify that no address remains on the system as this is an eternal
+ # interface.
+ for intf in self._interfaces:
+ self.assertNotIn(AF_INET, ifaddresses(intf))
+ # required for IPv6 link-local address
+ self.assertIn(AF_INET6, ifaddresses(intf))
+ for addr in ifaddresses(intf)[AF_INET6]:
+ # checking link local addresses makes no sense
+ if is_ipv6_link_local(addr['addr']):
+ continue
+ self.assertFalse(is_intf_addr_assigned(intf, addr['addr']))
def test_offloading_rps(self):
# enable RPS on all available CPUs, RPS works woth a CPU bitmask,
@@ -165,16 +209,23 @@ class EthernetInterfaceTest(BasicInterfaceTest.TestCase):
self.cli_commit()
def test_eapol_support(self):
- ca_name = 'eapol'
- cert_name = 'eapol'
+ ca_certs = {
+ 'eapol-server-ca-root': server_ca_root_cert_data,
+ 'eapol-server-ca-intermediate': server_ca_intermediate_cert_data,
+ 'eapol-client-ca-root': client_ca_root_cert_data,
+ 'eapol-client-ca-intermediate': client_ca_intermediate_cert_data,
+ }
+ cert_name = 'eapol-client'
- self.cli_set(['pki', 'ca', ca_name, 'certificate', cert_data.replace('\n','')])
- self.cli_set(['pki', 'certificate', cert_name, 'certificate', cert_data.replace('\n','')])
- self.cli_set(['pki', 'certificate', cert_name, 'private', 'key', key_data.replace('\n','')])
+ for name, data in ca_certs.items():
+ self.cli_set(['pki', 'ca', name, 'certificate', data.replace('\n','')])
+
+ self.cli_set(['pki', 'certificate', cert_name, 'certificate', client_cert_data.replace('\n','')])
+ self.cli_set(['pki', 'certificate', cert_name, 'private', 'key', client_key_data.replace('\n','')])
for interface in self._interfaces:
# Enable EAPoL
- self.cli_set(self._base_path + [interface, 'eapol', 'ca-certificate', ca_name])
+ self.cli_set(self._base_path + [interface, 'eapol', 'ca-certificate', 'eapol-server-ca-intermediate'])
self.cli_set(self._base_path + [interface, 'eapol', 'certificate', cert_name])
self.cli_commit()
@@ -206,7 +257,12 @@ class EthernetInterfaceTest(BasicInterfaceTest.TestCase):
tmp = get_wpa_supplicant_value(interface, 'identity')
self.assertEqual(f'"{mac}"', tmp)
- self.cli_delete(['pki', 'ca', ca_name])
+ # Check certificate files have the full chain
+ self.assertEqual(get_certificate_count(interface, 'ca'), 2)
+ self.assertEqual(get_certificate_count(interface, 'cert'), 3)
+
+ for name in ca_certs:
+ self.cli_delete(['pki', 'ca', name])
self.cli_delete(['pki', 'certificate', cert_name])
if __name__ == '__main__':
diff --git a/smoketest/scripts/cli/test_interfaces_geneve.py b/smoketest/scripts/cli/test_interfaces_geneve.py
index 6233ade6e..0e5098aa7 100755
--- a/smoketest/scripts/cli/test_interfaces_geneve.py
+++ b/smoketest/scripts/cli/test_interfaces_geneve.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright (C) 2020-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -34,7 +34,7 @@ class GeneveInterfaceTest(BasicInterfaceTest.TestCase):
}
cls._interfaces = list(cls._options)
# call base-classes classmethod
- super(cls, cls).setUpClass()
+ super(GeneveInterfaceTest, cls).setUpClass()
def test_geneve_parameters(self):
tos = '40'
@@ -43,7 +43,7 @@ class GeneveInterfaceTest(BasicInterfaceTest.TestCase):
for option in self._options.get(intf, []):
self.cli_set(self._base_path + [intf] + option.split())
- self.cli_set(self._base_path + [intf, 'parameters', 'ip', 'dont-fragment'])
+ self.cli_set(self._base_path + [intf, 'parameters', 'ip', 'df', 'set'])
self.cli_set(self._base_path + [intf, 'parameters', 'ip', 'tos', tos])
self.cli_set(self._base_path + [intf, 'parameters', 'ip', 'ttl', str(ttl)])
ttl += 10
diff --git a/smoketest/scripts/cli/test_interfaces_l2tpv3.py b/smoketest/scripts/cli/test_interfaces_l2tpv3.py
index 06ced5c40..aed8e6f15 100755
--- a/smoketest/scripts/cli/test_interfaces_l2tpv3.py
+++ b/smoketest/scripts/cli/test_interfaces_l2tpv3.py
@@ -39,7 +39,7 @@ class L2TPv3InterfaceTest(BasicInterfaceTest.TestCase):
}
cls._interfaces = list(cls._options)
# call base-classes classmethod
- super(cls, cls).setUpClass()
+ super(L2TPv3InterfaceTest, cls).setUpClass()
def test_add_single_ip_address(self):
super().test_add_single_ip_address()
diff --git a/smoketest/scripts/cli/test_interfaces_loopback.py b/smoketest/scripts/cli/test_interfaces_loopback.py
index 85b5ca6d6..5ff9c250e 100755
--- a/smoketest/scripts/cli/test_interfaces_loopback.py
+++ b/smoketest/scripts/cli/test_interfaces_loopback.py
@@ -29,7 +29,7 @@ class LoopbackInterfaceTest(BasicInterfaceTest.TestCase):
cls._base_path = ['interfaces', 'loopback']
cls._interfaces = ['lo']
# call base-classes classmethod
- super(cls, cls).setUpClass()
+ super(LoopbackInterfaceTest, cls).setUpClass()
def tearDown(self):
self.cli_delete(self._base_path)
diff --git a/smoketest/scripts/cli/test_interfaces_macsec.py b/smoketest/scripts/cli/test_interfaces_macsec.py
index e4280a5b7..e5e5a558e 100755
--- a/smoketest/scripts/cli/test_interfaces_macsec.py
+++ b/smoketest/scripts/cli/test_interfaces_macsec.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright (C) 2020-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -40,6 +40,7 @@ def get_cipher(interface):
class MACsecInterfaceTest(BasicInterfaceTest.TestCase):
@classmethod
def setUpClass(cls):
+ cls._test_dhcp = True
cls._test_ip = True
cls._test_ipv6 = True
cls._base_path = ['interfaces', 'macsec']
@@ -52,7 +53,7 @@ class MACsecInterfaceTest(BasicInterfaceTest.TestCase):
cls._interfaces = list(cls._options)
# call base-classes classmethod
- super(cls, cls).setUpClass()
+ super(MACsecInterfaceTest, cls).setUpClass()
def test_macsec_encryption(self):
# MACsec can be operating in authentication and encryption mode - both
diff --git a/smoketest/scripts/cli/test_interfaces_netns.py b/smoketest/scripts/cli/test_interfaces_netns.py
new file mode 100755
index 000000000..9975a6b09
--- /dev/null
+++ b/smoketest/scripts/cli/test_interfaces_netns.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import re
+import os
+import json
+import unittest
+
+from netifaces import interfaces
+from base_vyostest_shim import VyOSUnitTestSHIM
+
+from vyos.configsession import ConfigSession
+from vyos.configsession import ConfigSessionError
+from vyos.ifconfig import Interface
+from vyos.ifconfig import Section
+from vyos.util import cmd
+
+base_path = ['netns']
+namespaces = ['mgmt', 'front', 'back', 'ams-ix']
+
+class NETNSTest(VyOSUnitTestSHIM.TestCase):
+
+ def setUp(self):
+ self._interfaces = ['dum10', 'dum12', 'dum50']
+
+ def test_create_netns(self):
+ for netns in namespaces:
+ base = base_path + ['name', netns]
+ self.cli_set(base)
+
+ # commit changes
+ self.cli_commit()
+
+ netns_list = cmd('ip netns ls')
+
+ # Verify NETNS configuration
+ for netns in namespaces:
+ self.assertTrue(netns in netns_list)
+
+
+ def test_netns_assign_interface(self):
+ netns = 'foo'
+ self.cli_set(['netns', 'name', netns])
+
+ # Set
+ for iface in self._interfaces:
+ self.cli_set(['interfaces', 'dummy', iface, 'netns', netns])
+
+ # commit changes
+ self.cli_commit()
+
+ netns_iface_list = cmd(f'sudo ip netns exec {netns} ip link show')
+
+ for iface in self._interfaces:
+ self.assertTrue(iface in netns_iface_list)
+
+ # Delete
+ for iface in self._interfaces:
+ self.cli_delete(['interfaces', 'dummy', iface, 'netns', netns])
+
+ # commit changes
+ self.cli_commit()
+
+ netns_iface_list = cmd(f'sudo ip netns exec {netns} ip link show')
+
+ for iface in self._interfaces:
+ self.assertNotIn(iface, netns_iface_list)
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_interfaces_openvpn.py b/smoketest/scripts/cli/test_interfaces_openvpn.py
index f8a6ae986..b2143d16e 100755
--- a/smoketest/scripts/cli/test_interfaces_openvpn.py
+++ b/smoketest/scripts/cli/test_interfaces_openvpn.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright (C) 2020-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -37,10 +37,46 @@ PROCESS_NAME = 'openvpn'
base_path = ['interfaces', 'openvpn']
-cert_data = 'MIICFDCCAbugAwIBAgIUfMbIsB/ozMXijYgUYG80T1ry+mcwCgYIKoZIzj0EAwIwWTELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzESMBAGA1UEAwwJVnlPUyBUZXN0MB4XDTIxMDcyMDEyNDUxMloXDTI2MDcxOTEyNDUxMlowWTELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzESMBAGA1UEAwwJVnlPUyBUZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE01HrLcNttqq4/PtoMua8rMWEkOdBu7vP94xzDO7A8C92ls1v86eePy4QllKCzIw3QxBIoCuH2peGRfWgPRdFsKNhMF8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMB0GA1UdDgQWBBSu+JnU5ZC4mkuEpqg2+Mk4K79oeDAKBggqhkjOPQQDAgNHADBEAiBEFdzQ/Bc3LftzngrY605UhA6UprHhAogKgROv7iR4QgIgEFUxTtW3xXJcnUPWhhUFhyZoqfn8dE93+dm/LDnp7C0='
-key_data = 'MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgPLpD0Ohhoq0g4nhx2KMIuze7ucKUt/lBEB2wc03IxXyhRANCAATTUestw222qrj8+2gy5rysxYSQ50G7u8/3jHMM7sDwL3aWzW/zp54/LhCWUoLMjDdDEEigK4fal4ZF9aA9F0Ww'
-dh_data = 'MIIBCAKCAQEApzGAPcQlLJiOyfGZgl1qxNgufXkdpjG7lMaOrO4TGr1giFe3jIFOFxJNC/G9Dn+KSukaWssVVR+Jwr/JesZFPawihS03wC7cZsccykNRIjiteqJDwYJZUHieOxyCuCeY4pqOUCl1uswRGjLvIFtwynpnXKKuz2YtjNifma90PEgv/vVWKix+Q0TAbdbzJzO5xp8UVn9DuYfSr10k3LbDqDM7w5ezHZxFk24S5pN/yoOpdbxB8TS67q3IYXxR3F+RseKu4J3AvkxXSP1j7COXddPpLnvbJT/SW8NrjuC/n0eKGvmeyqNv108Y89jnT79MxMMRQk66iwlsd1m4pa/OYwIBAg=='
-ovpn_key_data = '443f2a710ac411c36894b2531e62c4550b079b8f3f08997f4be57c64abfdaaa431d2396b01ecec3a2c0618959e8186d99f489742d25673ffb3268841ebb2e7042a2daabe584e79d51d2b1d7409bf8840f7e42efa3e660a521719b04ee88b9043e6315ae12da7c9abd55f67eeed71a9ee8c6e163b5d2661fc332cf90cb45658b4adf892f79537d37d3a3d90da283ce885adf325ffd2b5be92067cdf0345c7712c9d36b642c170351b6d9ce9f6230c7a2617b0c181121bce7d5373404fb68e65210b36e6d40ef2769cf8990503859f6f2db3c85ba74420430a6250d6a74ca51ece4b85124bfdfec0c8a530cefa7350378d81a4539f74bed832a902ae4798142e4a'
+cert_data = """
+MIICFDCCAbugAwIBAgIUfMbIsB/ozMXijYgUYG80T1ry+mcwCgYIKoZIzj0EAwIw
+WTELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNv
+bWUtQ2l0eTENMAsGA1UECgwEVnlPUzESMBAGA1UEAwwJVnlPUyBUZXN0MB4XDTIx
+MDcyMDEyNDUxMloXDTI2MDcxOTEyNDUxMlowWTELMAkGA1UEBhMCR0IxEzARBgNV
+BAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlP
+UzESMBAGA1UEAwwJVnlPUyBUZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
+01HrLcNttqq4/PtoMua8rMWEkOdBu7vP94xzDO7A8C92ls1v86eePy4QllKCzIw3
+QxBIoCuH2peGRfWgPRdFsKNhMF8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
+BAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMB0GA1UdDgQWBBSu
++JnU5ZC4mkuEpqg2+Mk4K79oeDAKBggqhkjOPQQDAgNHADBEAiBEFdzQ/Bc3Lftz
+ngrY605UhA6UprHhAogKgROv7iR4QgIgEFUxTtW3xXJcnUPWhhUFhyZoqfn8dE93
++dm/LDnp7C0=
+"""
+
+key_data = """
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgPLpD0Ohhoq0g4nhx
+2KMIuze7ucKUt/lBEB2wc03IxXyhRANCAATTUestw222qrj8+2gy5rysxYSQ50G7
+u8/3jHMM7sDwL3aWzW/zp54/LhCWUoLMjDdDEEigK4fal4ZF9aA9F0Ww
+"""
+
+dh_data = """
+MIIBCAKCAQEApzGAPcQlLJiOyfGZgl1qxNgufXkdpjG7lMaOrO4TGr1giFe3jIFO
+FxJNC/G9Dn+KSukaWssVVR+Jwr/JesZFPawihS03wC7cZsccykNRIjiteqJDwYJZ
+UHieOxyCuCeY4pqOUCl1uswRGjLvIFtwynpnXKKuz2YtjNifma90PEgv/vVWKix+
+Q0TAbdbzJzO5xp8UVn9DuYfSr10k3LbDqDM7w5ezHZxFk24S5pN/yoOpdbxB8TS6
+7q3IYXxR3F+RseKu4J3AvkxXSP1j7COXddPpLnvbJT/SW8NrjuC/n0eKGvmeyqNv
+108Y89jnT79MxMMRQk66iwlsd1m4pa/OYwIBAg==
+"""
+
+ovpn_key_data = """
+443f2a710ac411c36894b2531e62c4550b079b8f3f08997f4be57c64abfdaaa4
+31d2396b01ecec3a2c0618959e8186d99f489742d25673ffb3268841ebb2e704
+2a2daabe584e79d51d2b1d7409bf8840f7e42efa3e660a521719b04ee88b9043
+e6315ae12da7c9abd55f67eeed71a9ee8c6e163b5d2661fc332cf90cb45658b4
+adf892f79537d37d3a3d90da283ce885adf325ffd2b5be92067cdf0345c7712c
+9d36b642c170351b6d9ce9f6230c7a2617b0c181121bce7d5373404fb68e6521
+0b36e6d40ef2769cf8990503859f6f2db3c85ba74420430a6250d6a74ca51ece
+4b85124bfdfec0c8a530cefa7350378d81a4539f74bed832a902ae4798142e4a
+"""
remote_port = '1194'
protocol = 'udp'
@@ -59,20 +95,28 @@ def get_vrf(interface):
return tmp
class TestInterfacesOpenVPN(VyOSUnitTestSHIM.TestCase):
- def setUp(self):
- self.cli_set(['interfaces', 'dummy', dummy_if, 'address', '192.0.2.1/32'])
- self.cli_set(['vrf', 'name', vrf_name, 'table', '12345'])
+ @classmethod
+ def setUpClass(cls):
+ super(TestInterfacesOpenVPN, cls).setUpClass()
- self.cli_set(['pki', 'ca', 'ovpn_test', 'certificate', cert_data])
- self.cli_set(['pki', 'certificate', 'ovpn_test', 'certificate', cert_data])
- self.cli_set(['pki', 'certificate', 'ovpn_test', 'private', 'key', key_data])
- self.cli_set(['pki', 'dh', 'ovpn_test', 'parameters', dh_data])
- self.cli_set(['pki', 'openvpn', 'shared-secret', 'ovpn_test', 'key', ovpn_key_data])
+ cls.cli_set(cls, ['interfaces', 'dummy', dummy_if, 'address', '192.0.2.1/32'])
+ cls.cli_set(cls, ['vrf', 'name', vrf_name, 'table', '12345'])
+
+ cls.cli_set(cls, ['pki', 'ca', 'ovpn_test', 'certificate', cert_data.replace('\n','')])
+ cls.cli_set(cls, ['pki', 'certificate', 'ovpn_test', 'certificate', cert_data.replace('\n','')])
+ cls.cli_set(cls, ['pki', 'certificate', 'ovpn_test', 'private', 'key', key_data.replace('\n','')])
+ cls.cli_set(cls, ['pki', 'dh', 'ovpn_test', 'parameters', dh_data.replace('\n','')])
+ cls.cli_set(cls, ['pki', 'openvpn', 'shared-secret', 'ovpn_test', 'key', ovpn_key_data.replace('\n','')])
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.cli_delete(cls, ['interfaces', 'dummy', dummy_if])
+ cls.cli_delete(cls, ['vrf'])
+
+ super(TestInterfacesOpenVPN, cls).tearDownClass()
def tearDown(self):
self.cli_delete(base_path)
- self.cli_delete(['interfaces', 'dummy', dummy_if])
- self.cli_delete(['vrf'])
self.cli_commit()
def test_openvpn_client_verify(self):
@@ -532,6 +576,46 @@ class TestInterfacesOpenVPN(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
+ def test_openvpn_options(self):
+ # Ensure OpenVPN process restart on openvpn-option CLI node change
+
+ interface = 'vtun5001'
+ path = base_path + [interface]
+
+ self.cli_set(path + ['mode', 'site-to-site'])
+ self.cli_set(path + ['local-address', '10.0.0.2'])
+ self.cli_set(path + ['remote-address', '192.168.0.3'])
+ self.cli_set(path + ['shared-secret-key', 'ovpn_test'])
+
+ self.cli_commit()
+
+ # Now verify the OpenVPN "raw" option passing. Once an openvpn-option is
+ # added, modified or deleted from the CLI, OpenVPN daemon must be restarted
+ cur_pid = process_named_running('openvpn')
+ self.cli_set(path + ['openvpn-option', '--persist-tun'])
+ self.cli_commit()
+
+ # PID must be different as OpenVPN Must be restarted
+ new_pid = process_named_running('openvpn')
+ self.assertNotEqual(cur_pid, new_pid)
+ cur_pid = new_pid
+
+ self.cli_set(path + ['openvpn-option', '--persist-key'])
+ self.cli_commit()
+
+ # PID must be different as OpenVPN Must be restarted
+ new_pid = process_named_running('openvpn')
+ self.assertNotEqual(cur_pid, new_pid)
+ cur_pid = new_pid
+
+ self.cli_delete(path + ['openvpn-option'])
+ self.cli_commit()
+
+ # PID must be different as OpenVPN Must be restarted
+ new_pid = process_named_running('openvpn')
+ self.assertNotEqual(cur_pid, new_pid)
+ cur_pid = new_pid
+
def test_openvpn_site2site_interfaces_tun(self):
# Create two OpenVPN site-to-site interfaces
diff --git a/smoketest/scripts/cli/test_interfaces_pppoe.py b/smoketest/scripts/cli/test_interfaces_pppoe.py
index 4f1e1ee99..8927121a8 100755
--- a/smoketest/scripts/cli/test_interfaces_pppoe.py
+++ b/smoketest/scripts/cli/test_interfaces_pppoe.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2021 VyOS maintainers and contributors
+# Copyright (C) 2019-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -34,9 +34,12 @@ def get_config_value(interface, key):
# add a classmethod to setup a temporaray PPPoE server for "proper" validation
class PPPoEInterfaceTest(VyOSUnitTestSHIM.TestCase):
- def setUp(self):
- self._interfaces = ['pppoe10', 'pppoe20', 'pppoe30']
- self._source_interface = 'eth0'
+ @classmethod
+ def setUpClass(cls):
+ super(PPPoEInterfaceTest, cls).setUpClass()
+
+ cls._interfaces = ['pppoe10', 'pppoe20', 'pppoe30']
+ cls._source_interface = 'eth0'
def tearDown(self):
# Validate PPPoE client process
@@ -60,7 +63,6 @@ class PPPoEInterfaceTest(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + [interface, 'authentication', 'user', user])
self.cli_set(base_path + [interface, 'authentication', 'password', passwd])
- self.cli_set(base_path + [interface, 'default-route', 'auto'])
self.cli_set(base_path + [interface, 'mtu', mtu])
self.cli_set(base_path + [interface, 'no-peer-dns'])
@@ -136,7 +138,7 @@ class PPPoEInterfaceTest(VyOSUnitTestSHIM.TestCase):
for interface in self._interfaces:
self.cli_set(base_path + [interface, 'authentication', 'user', 'vyos'])
self.cli_set(base_path + [interface, 'authentication', 'password', 'vyos'])
- self.cli_set(base_path + [interface, 'default-route', 'none'])
+ self.cli_set(base_path + [interface, 'no-default-route'])
self.cli_set(base_path + [interface, 'no-peer-dns'])
self.cli_set(base_path + [interface, 'source-interface', self._source_interface])
self.cli_set(base_path + [interface, 'ipv6', 'address', 'autoconf'])
diff --git a/smoketest/scripts/cli/test_interfaces_pseudo_ethernet.py b/smoketest/scripts/cli/test_interfaces_pseudo_ethernet.py
index ae899cddd..a51b8d52c 100755
--- a/smoketest/scripts/cli/test_interfaces_pseudo_ethernet.py
+++ b/smoketest/scripts/cli/test_interfaces_pseudo_ethernet.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright (C) 2020-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -23,6 +23,7 @@ from base_interfaces_test import BasicInterfaceTest
class PEthInterfaceTest(BasicInterfaceTest.TestCase):
@classmethod
def setUpClass(cls):
+ cls._test_dhcp = True
cls._test_ip = True
cls._test_ipv6 = True
cls._test_ipv6_pd = True
@@ -47,7 +48,7 @@ class PEthInterfaceTest(BasicInterfaceTest.TestCase):
cls._interfaces = list(cls._options)
# call base-classes classmethod
- super(cls, cls).setUpClass()
+ super(PEthInterfaceTest, cls).setUpClass()
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_interfaces_tunnel.py b/smoketest/scripts/cli/test_interfaces_tunnel.py
index fc2e254d6..44bfbb5f0 100755
--- a/smoketest/scripts/cli/test_interfaces_tunnel.py
+++ b/smoketest/scripts/cli/test_interfaces_tunnel.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright (C) 2020-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -42,16 +42,16 @@ class TunnelInterfaceTest(BasicInterfaceTest.TestCase):
}
cls._interfaces = list(cls._options)
# call base-classes classmethod
- super(cls, cls).setUpClass()
+ super(TunnelInterfaceTest, cls).setUpClass()
- def setUp(self):
- super().setUp()
- self.cli_set(['interfaces', 'dummy', source_if, 'address', self.local_v4 + '/32'])
- self.cli_set(['interfaces', 'dummy', source_if, 'address', self.local_v6 + '/128'])
+ # create some test interfaces
+ cls.cli_set(cls, ['interfaces', 'dummy', source_if, 'address', cls.local_v4 + '/32'])
+ cls.cli_set(cls, ['interfaces', 'dummy', source_if, 'address', cls.local_v6 + '/128'])
- def tearDown(self):
- self.cli_delete(['interfaces', 'dummy', source_if])
- super().tearDown()
+ @classmethod
+ def tearDownClass(cls):
+ cls.cli_delete(cls, ['interfaces', 'dummy', source_if])
+ super().tearDownClass()
def test_ipv4_encapsulations(self):
# When running tests ensure that for certain encapsulation types the
@@ -202,7 +202,7 @@ class TunnelInterfaceTest(BasicInterfaceTest.TestCase):
self.assertEqual(encapsulation, conf['linkinfo']['info_kind'])
self.assertEqual(self.local_v4, conf['linkinfo']['info_data']['local'])
self.assertEqual(remote_ip4, conf['linkinfo']['info_data']['remote'])
- self.assertEqual(64, conf['linkinfo']['info_data']['ttl'])
+ self.assertEqual(64, conf['linkinfo']['info_data']['ttl'])
# Change remote ip address (inc host by 2
new_remote = inc_ip(remote_ip4, 2)
@@ -239,7 +239,7 @@ class TunnelInterfaceTest(BasicInterfaceTest.TestCase):
self.assertEqual(encapsulation, conf['linkinfo']['info_kind'])
self.assertEqual(self.local_v4, conf['linkinfo']['info_data']['local'])
self.assertEqual(remote_ip4, conf['linkinfo']['info_data']['remote'])
- self.assertEqual(64, conf['linkinfo']['info_data']['ttl'])
+ self.assertEqual(64, conf['linkinfo']['info_data']['ttl'])
self.assertEqual(f'0.0.0.{ip_key}', conf['linkinfo']['info_data']['ikey'])
self.assertEqual(f'0.0.0.{ip_key}', conf['linkinfo']['info_data']['okey'])
self.assertEqual(int(idx), conf['linkinfo']['info_data']['erspan_index'])
@@ -295,7 +295,7 @@ class TunnelInterfaceTest(BasicInterfaceTest.TestCase):
self.assertEqual(encapsulation, conf['linkinfo']['info_kind'])
self.assertEqual(self.local_v6, conf['linkinfo']['info_data']['local'])
self.assertEqual(remote_ip6, conf['linkinfo']['info_data']['remote'])
- self.assertEqual(64, conf['linkinfo']['info_data']['ttl'])
+ self.assertEqual(64, conf['linkinfo']['info_data']['ttl'])
self.assertEqual(f'0.0.0.{ip_key}', conf['linkinfo']['info_data']['ikey'])
self.assertEqual(f'0.0.0.{ip_key}', conf['linkinfo']['info_data']['okey'])
self.assertEqual(erspan_ver, conf['linkinfo']['info_data']['erspan_ver'])
@@ -312,5 +312,89 @@ class TunnelInterfaceTest(BasicInterfaceTest.TestCase):
conf = get_interface_config(interface)
self.assertEqual(new_remote, conf['linkinfo']['info_data']['remote'])
+ def test_tunnel_src_any_gre_key(self):
+ interface = f'tun1280'
+ encapsulation = 'gre'
+ src_addr = '0.0.0.0'
+ key = '127'
+
+ self.cli_set(self._base_path + [interface, 'encapsulation', encapsulation])
+ self.cli_set(self._base_path + [interface, 'source-address', src_addr])
+ # GRE key must be supplied with a 0.0.0.0 source address
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_set(self._base_path + [interface, 'parameters', 'ip', 'key', key])
+
+ self.cli_commit()
+
+ def test_multiple_gre_tunnel_same_remote(self):
+ tunnels = {
+ 'tun10' : {
+ 'encapsulation' : 'gre',
+ 'source_interface' : source_if,
+ 'remote' : '1.2.3.4',
+ },
+ 'tun20' : {
+ 'encapsulation' : 'gre',
+ 'source_interface' : source_if,
+ 'remote' : '1.2.3.4',
+ },
+ }
+
+ for tunnel, tunnel_config in tunnels.items():
+ self.cli_set(self._base_path + [tunnel, 'encapsulation', tunnel_config['encapsulation']])
+ if 'source_interface' in tunnel_config:
+ self.cli_set(self._base_path + [tunnel, 'source-interface', tunnel_config['source_interface']])
+ if 'remote' in tunnel_config:
+ self.cli_set(self._base_path + [tunnel, 'remote', tunnel_config['remote']])
+
+ # GRE key must be supplied when two or more tunnels are formed to the same desitnation
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ for tunnel, tunnel_config in tunnels.items():
+ self.cli_set(self._base_path + [tunnel, 'parameters', 'ip', 'key', tunnel.lstrip('tun')])
+
+ self.cli_commit()
+
+ for tunnel, tunnel_config in tunnels.items():
+ conf = get_interface_config(tunnel)
+ ip_key = tunnel.lstrip('tun')
+
+ self.assertEqual(tunnel_config['source_interface'], conf['link'])
+ self.assertEqual(tunnel_config['encapsulation'], conf['linkinfo']['info_kind'])
+ self.assertEqual(tunnel_config['remote'], conf['linkinfo']['info_data']['remote'])
+ self.assertEqual(f'0.0.0.{ip_key}', conf['linkinfo']['info_data']['ikey'])
+ self.assertEqual(f'0.0.0.{ip_key}', conf['linkinfo']['info_data']['okey'])
+
+ def test_multiple_gre_tunnel_different_remote(self):
+ tunnels = {
+ 'tun10' : {
+ 'encapsulation' : 'gre',
+ 'source_interface' : source_if,
+ 'remote' : '1.2.3.4',
+ },
+ 'tun20' : {
+ 'encapsulation' : 'gre',
+ 'source_interface' : source_if,
+ 'remote' : '1.2.3.5',
+ },
+ }
+
+ for tunnel, tunnel_config in tunnels.items():
+ self.cli_set(self._base_path + [tunnel, 'encapsulation', tunnel_config['encapsulation']])
+ if 'source_interface' in tunnel_config:
+ self.cli_set(self._base_path + [tunnel, 'source-interface', tunnel_config['source_interface']])
+ if 'remote' in tunnel_config:
+ self.cli_set(self._base_path + [tunnel, 'remote', tunnel_config['remote']])
+
+ self.cli_commit()
+
+ for tunnel, tunnel_config in tunnels.items():
+ conf = get_interface_config(tunnel)
+
+ self.assertEqual(tunnel_config['source_interface'], conf['link'])
+ self.assertEqual(tunnel_config['encapsulation'], conf['linkinfo']['info_kind'])
+ self.assertEqual(tunnel_config['remote'], conf['linkinfo']['info_data']['remote'])
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_interfaces_vxlan.py b/smoketest/scripts/cli/test_interfaces_vxlan.py
index f63c850d8..058f13721 100755
--- a/smoketest/scripts/cli/test_interfaces_vxlan.py
+++ b/smoketest/scripts/cli/test_interfaces_vxlan.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright (C) 2020-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -16,9 +16,11 @@
import unittest
+from vyos.configsession import ConfigSessionError
from vyos.ifconfig import Interface
+from vyos.util import get_bridge_fdb
from vyos.util import get_interface_config
-
+from vyos.template import is_ipv6
from base_interfaces_test import BasicInterfaceTest
class VXLANInterfaceTest(BasicInterfaceTest.TestCase):
@@ -32,10 +34,12 @@ class VXLANInterfaceTest(BasicInterfaceTest.TestCase):
'vxlan10': ['vni 10', 'remote 127.0.0.2'],
'vxlan20': ['vni 20', 'group 239.1.1.1', 'source-interface eth0'],
'vxlan30': ['vni 30', 'remote 2001:db8:2000::1', 'source-address 2001:db8:1000::1', 'parameters ipv6 flowlabel 0x1000'],
+ 'vxlan40': ['vni 40', 'remote 127.0.0.2', 'remote 127.0.0.3'],
+ 'vxlan50': ['vni 50', 'remote 2001:db8:2000::1', 'remote 2001:db8:2000::2', 'parameters ipv6 flowlabel 0x1000'],
}
cls._interfaces = list(cls._options)
# call base-classes classmethod
- super(cls, cls).setUpClass()
+ super(VXLANInterfaceTest, cls).setUpClass()
def test_vxlan_parameters(self):
tos = '40'
@@ -44,7 +48,7 @@ class VXLANInterfaceTest(BasicInterfaceTest.TestCase):
for option in self._options.get(intf, []):
self.cli_set(self._base_path + [intf] + option.split())
- self.cli_set(self._base_path + [intf, 'parameters', 'ip', 'dont-fragment'])
+ self.cli_set(self._base_path + [intf, 'parameters', 'ip', 'df', 'set'])
self.cli_set(self._base_path + [intf, 'parameters', 'ip', 'tos', tos])
self.cli_set(self._base_path + [intf, 'parameters', 'ip', 'ttl', str(ttl)])
ttl += 10
@@ -54,21 +58,34 @@ class VXLANInterfaceTest(BasicInterfaceTest.TestCase):
ttl = 20
for interface in self._interfaces:
options = get_interface_config(interface)
+ bridge = get_bridge_fdb(interface)
vni = options['linkinfo']['info_data']['id']
self.assertIn(f'vni {vni}', self._options[interface])
- if any('link' in s for s in self._options[interface]):
+ if any('source-interface' in s for s in self._options[interface]):
link = options['linkinfo']['info_data']['link']
self.assertIn(f'source-interface {link}', self._options[interface])
- if any('local6' in s for s in self._options[interface]):
- remote = options['linkinfo']['info_data']['local6']
- self.assertIn(f'source-address {local6}', self._options[interface])
-
- if any('remote6' in s for s in self._options[interface]):
- remote = options['linkinfo']['info_data']['remote6']
- self.assertIn(f'remote {remote}', self._options[interface])
+ # Verify source-address setting was properly configured on the Kernel
+ if any('source-address' in s for s in self._options[interface]):
+ for s in self._options[interface]:
+ if 'source-address' in s:
+ address = s.split()[-1]
+ if is_ipv6(address):
+ tmp = options['linkinfo']['info_data']['local6']
+ else:
+ tmp = options['linkinfo']['info_data']['local']
+ self.assertIn(f'source-address {tmp}', self._options[interface])
+
+ # Verify remote setting was properly configured on the Kernel
+ if any('remote' in s for s in self._options[interface]):
+ for s in self._options[interface]:
+ if 'remote' in s:
+ for fdb in bridge:
+ if 'mac' in fdb and fdb['mac'] == '00:00:00:00:00:00':
+ remote = fdb['dst']
+ self.assertIn(f'remote {remote}', self._options[interface])
if any('group' in s for s in self._options[interface]):
group = options['linkinfo']['info_data']['group']
@@ -78,6 +95,9 @@ class VXLANInterfaceTest(BasicInterfaceTest.TestCase):
label = options['linkinfo']['info_data']['label']
self.assertIn(f'parameters ipv6 flowlabel {label}', self._options[interface])
+ if any('external' in s for s in self._options[interface]):
+ self.assertTrue(options['linkinfo']['info_data']['external'])
+
self.assertEqual('vxlan', options['linkinfo']['info_kind'])
self.assertEqual('set', options['linkinfo']['info_data']['df'])
self.assertEqual(f'0x{tos}', options['linkinfo']['info_data']['tos'])
@@ -85,5 +105,36 @@ class VXLANInterfaceTest(BasicInterfaceTest.TestCase):
self.assertEqual(Interface(interface).get_admin_state(), 'up')
ttl += 10
+ def test_vxlan_external(self):
+ interface = 'vxlan0'
+ source_address = '192.0.2.1'
+ self.cli_set(self._base_path + [interface, 'external'])
+ self.cli_set(self._base_path + [interface, 'source-address', source_address])
+
+ # Both 'VNI' and 'external' can not be specified at the same time.
+ self.cli_set(self._base_path + [interface, 'vni', '111'])
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_delete(self._base_path + [interface, 'vni'])
+
+ # Now add some more interfaces - this must fail and a CLI error needs
+ # to be generated as Linux can only handle one VXLAN tunnel when using
+ # external mode.
+ for intf in self._interfaces:
+ for option in self._options.get(intf, []):
+ self.cli_set(self._base_path + [intf] + option.split())
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ # Remove those test interfaces again
+ for intf in self._interfaces:
+ self.cli_delete(self._base_path + [intf])
+
+ self.cli_commit()
+
+ options = get_interface_config(interface)
+ self.assertTrue(options['linkinfo']['info_data']['external'])
+ self.assertEqual('vxlan', options['linkinfo']['info_kind'])
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_interfaces_wireguard.py b/smoketest/scripts/cli/test_interfaces_wireguard.py
index aaf27a2c4..f3e9670f7 100755
--- a/smoketest/scripts/cli/test_interfaces_wireguard.py
+++ b/smoketest/scripts/cli/test_interfaces_wireguard.py
@@ -23,10 +23,13 @@ from vyos.configsession import ConfigSessionError
base_path = ['interfaces', 'wireguard']
class WireGuardInterfaceTest(VyOSUnitTestSHIM.TestCase):
- def setUp(self):
- self._test_addr = ['192.0.2.1/26', '192.0.2.255/31', '192.0.2.64/32',
+ @classmethod
+ def setUpClass(cls):
+ super(WireGuardInterfaceTest, cls).setUpClass()
+
+ cls._test_addr = ['192.0.2.1/26', '192.0.2.255/31', '192.0.2.64/32',
'2001:db8:1::ffff/64', '2001:db8:101::1/112']
- self._interfaces = ['wg0', 'wg1']
+ cls._interfaces = ['wg0', 'wg1']
def tearDown(self):
self.cli_delete(base_path)
diff --git a/smoketest/scripts/cli/test_interfaces_wireless.py b/smoketest/scripts/cli/test_interfaces_wireless.py
index 4f539a23c..a24f37d8d 100755
--- a/smoketest/scripts/cli/test_interfaces_wireless.py
+++ b/smoketest/scripts/cli/test_interfaces_wireless.py
@@ -48,7 +48,7 @@ class WirelessInterfaceTest(BasicInterfaceTest.TestCase):
}
cls._interfaces = list(cls._options)
# call base-classes classmethod
- super(cls, cls).setUpClass()
+ super(WirelessInterfaceTest, cls).setUpClass()
def test_wireless_add_single_ip_address(self):
# derived method to check if member interfaces are enslaved properly
diff --git a/smoketest/scripts/cli/test_nat.py b/smoketest/scripts/cli/test_nat.py
index 75c628244..408facfb3 100755
--- a/smoketest/scripts/cli/test_nat.py
+++ b/smoketest/scripts/cli/test_nat.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright (C) 2020-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -14,7 +14,6 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-import os
import jmespath
import json
import unittest
@@ -29,10 +28,13 @@ src_path = base_path + ['source']
dst_path = base_path + ['destination']
class TestNAT(VyOSUnitTestSHIM.TestCase):
- def setUp(self):
+ @classmethod
+ def setUpClass(cls):
+ super(TestNAT, cls).setUpClass()
+
# ensure we can also run this test on a live system - so lets clean
# out the current configuration :)
- self.cli_delete(base_path)
+ cls.cli_delete(cls, base_path)
def tearDown(self):
self.cli_delete(base_path)
@@ -57,36 +59,44 @@ class TestNAT(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
- tmp = cmd('sudo nft -j list table nat')
+ tmp = cmd('sudo nft -j list chain ip nat POSTROUTING')
data_json = jmespath.search('nftables[?rule].rule[?chain]', json.loads(tmp))
for idx in range(0, len(data_json)):
- rule = str(rules[idx])
data = data_json[idx]
- network = f'192.168.{rule}.0/24'
-
- self.assertEqual(data['chain'], 'POSTROUTING')
- self.assertEqual(data['comment'], f'SRC-NAT-{rule}')
- self.assertEqual(data['family'], 'ip')
- self.assertEqual(data['table'], 'nat')
-
- iface = dict_search('match.right', data['expr'][0])
- direction = dict_search('match.left.payload.field', data['expr'][1])
- address = dict_search('match.right.prefix.addr', data['expr'][1])
- mask = dict_search('match.right.prefix.len', data['expr'][1])
+ if idx == 0:
+ self.assertEqual(data['chain'], 'POSTROUTING')
+ self.assertEqual(data['family'], 'ip')
+ self.assertEqual(data['table'], 'nat')
- if int(rule) < 200:
- self.assertEqual(direction, 'saddr')
- self.assertEqual(iface, outbound_iface_100)
- # check for masquerade keyword
- self.assertIn('masquerade', data['expr'][3])
+ jump_target = dict_search('jump.target', data['expr'][1])
+ self.assertEqual(jump_target,'VYOS_PRE_SNAT_HOOK')
else:
- self.assertEqual(direction, 'daddr')
- self.assertEqual(iface, outbound_iface_200)
- # check for return keyword due to 'exclude'
- self.assertIn('return', data['expr'][3])
-
- self.assertEqual(f'{address}/{mask}', network)
+ rule = str(rules[idx - 1])
+ network = f'192.168.{rule}.0/24'
+
+ self.assertEqual(data['chain'], 'POSTROUTING')
+ self.assertEqual(data['comment'], f'SRC-NAT-{rule}')
+ self.assertEqual(data['family'], 'ip')
+ self.assertEqual(data['table'], 'nat')
+
+ iface = dict_search('match.right', data['expr'][0])
+ direction = dict_search('match.left.payload.field', data['expr'][1])
+ address = dict_search('match.right.prefix.addr', data['expr'][1])
+ mask = dict_search('match.right.prefix.len', data['expr'][1])
+
+ if int(rule) < 200:
+ self.assertEqual(direction, 'saddr')
+ self.assertEqual(iface, outbound_iface_100)
+ # check for masquerade keyword
+ self.assertIn('masquerade', data['expr'][3])
+ else:
+ self.assertEqual(direction, 'daddr')
+ self.assertEqual(iface, outbound_iface_200)
+ # check for return keyword due to 'exclude'
+ self.assertIn('return', data['expr'][3])
+
+ self.assertEqual(f'{address}/{mask}', network)
def test_dnat(self):
rules = ['100', '110', '120', '130', '200', '210', '220', '230']
@@ -109,33 +119,42 @@ class TestNAT(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
- tmp = cmd('sudo nft -j list table nat')
+ tmp = cmd('sudo nft -j list chain ip nat PREROUTING')
data_json = jmespath.search('nftables[?rule].rule[?chain]', json.loads(tmp))
for idx in range(0, len(data_json)):
- rule = str(rules[idx])
data = data_json[idx]
- port = int(f'10{rule}')
-
- self.assertEqual(data['chain'], 'PREROUTING')
- self.assertEqual(data['comment'].split()[0], f'DST-NAT-{rule}')
- self.assertEqual(data['family'], 'ip')
- self.assertEqual(data['table'], 'nat')
-
- iface = dict_search('match.right', data['expr'][0])
- direction = dict_search('match.left.payload.field', data['expr'][1])
- protocol = dict_search('match.left.payload.protocol', data['expr'][1])
- dnat_addr = dict_search('dnat.addr', data['expr'][3])
- dnat_port = dict_search('dnat.port', data['expr'][3])
-
- self.assertEqual(direction, 'sport')
- self.assertEqual(dnat_addr, '192.0.2.1')
- self.assertEqual(dnat_port, port)
- if int(rule) < 200:
- self.assertEqual(iface, inbound_iface_100)
- self.assertEqual(protocol, inbound_proto_100)
+ if idx == 0:
+ self.assertEqual(data['chain'], 'PREROUTING')
+ self.assertEqual(data['family'], 'ip')
+ self.assertEqual(data['table'], 'nat')
+
+ jump_target = dict_search('jump.target', data['expr'][1])
+ self.assertEqual(jump_target,'VYOS_PRE_DNAT_HOOK')
else:
- self.assertEqual(iface, inbound_iface_200)
+
+ rule = str(rules[idx - 1])
+ port = int(f'10{rule}')
+
+ self.assertEqual(data['chain'], 'PREROUTING')
+ self.assertEqual(data['comment'].split()[0], f'DST-NAT-{rule}')
+ self.assertEqual(data['family'], 'ip')
+ self.assertEqual(data['table'], 'nat')
+
+ iface = dict_search('match.right', data['expr'][0])
+ direction = dict_search('match.left.payload.field', data['expr'][1])
+ protocol = dict_search('match.left.payload.protocol', data['expr'][1])
+ dnat_addr = dict_search('dnat.addr', data['expr'][3])
+ dnat_port = dict_search('dnat.port', data['expr'][3])
+
+ self.assertEqual(direction, 'sport')
+ self.assertEqual(dnat_addr, '192.0.2.1')
+ self.assertEqual(dnat_port, port)
+ if int(rule) < 200:
+ self.assertEqual(iface, inbound_iface_100)
+ self.assertEqual(protocol, inbound_proto_100)
+ else:
+ self.assertEqual(iface, inbound_iface_200)
def test_snat_required_translation_address(self):
# T2813: Ensure translation address is specified
diff --git a/smoketest/scripts/cli/test_nat66.py b/smoketest/scripts/cli/test_nat66.py
index 8afe0da26..aac6a30f9 100755
--- a/smoketest/scripts/cli/test_nat66.py
+++ b/smoketest/scripts/cli/test_nat66.py
@@ -32,7 +32,7 @@ dst_path = base_path + ['destination']
class TestNAT66(VyOSUnitTestSHIM.TestCase):
@classmethod
def setUpClass(cls):
- super(cls, cls).setUpClass()
+ super(TestNAT66, cls).setUpClass()
# ensure we can also run this test on a live system - so lets clean
# out the current configuration :)
@@ -185,4 +185,4 @@ class TestNAT66(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
if __name__ == '__main__':
- unittest.main(verbosity=2, failfast=True)
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_pki.py b/smoketest/scripts/cli/test_pki.py
index 45a4bd61e..e92123dbc 100755
--- a/smoketest/scripts/cli/test_pki.py
+++ b/smoketest/scripts/cli/test_pki.py
@@ -129,8 +129,13 @@ xGsJxVHfSKeooUQn6q76sg==
"""
class TestPKI(VyOSUnitTestSHIM.TestCase):
- def setUp(self):
- self.cli_delete(base_path)
+ @classmethod
+ def setUpClass(cls):
+ super(TestPKI, cls).setUpClass()
+
+ # ensure we can also run this test on a live system - so lets clean
+ # out the current configuration :)
+ cls.cli_delete(cls, base_path)
def tearDown(self):
self.cli_delete(base_path)
diff --git a/smoketest/scripts/cli/test_policy.py b/smoketest/scripts/cli/test_policy.py
index 1286a768d..e8c6ff19b 100755
--- a/smoketest/scripts/cli/test_policy.py
+++ b/smoketest/scripts/cli/test_policy.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -307,7 +307,7 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
continue
for rule, rule_config in as_path_config['rule'].items():
- tmp = f'bgp as-path access-list {as_path}'
+ tmp = f'bgp as-path access-list {as_path} seq {rule}'
if rule_config['action'] == 'permit':
tmp += ' permit'
else:
@@ -665,6 +665,40 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
self.assertIn(tmp, config)
+ def test_prefix_list_duplicates(self):
+ # FRR does not allow to specify the same profix list rule multiple times
+ #
+ # vyos(config)# ip prefix-list foo seq 10 permit 192.0.2.0/24
+ # vyos(config)# ip prefix-list foo seq 20 permit 192.0.2.0/24
+ # % Configuration failed.
+ # Error type: validation
+ # Error description: duplicated prefix list value: 192.0.2.0/24
+
+ # There is also a VyOS verify() function to test this
+
+ prefix = '100.64.0.0/10'
+ prefix_list = 'duplicates'
+ test_range = range(20, 25)
+ path = base_path + ['prefix-list', prefix_list]
+
+ for rule in test_range:
+ self.cli_set(path + ['rule', str(rule), 'action', 'permit'])
+ self.cli_set(path + ['rule', str(rule), 'prefix', prefix])
+
+ # Duplicate prefixes
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ for rule in test_range:
+ self.cli_set(path + ['rule', str(rule), 'le', str(rule)])
+
+ self.cli_commit()
+
+ config = self.getFRRconfig('ip prefix-list', end='')
+ for rule in test_range:
+ tmp = f'ip prefix-list {prefix_list} seq {rule} permit {prefix} le {rule}'
+ self.assertIn(tmp, config)
+
def test_route_map(self):
access_list = '50'
as_path_list = '100'
@@ -766,27 +800,28 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
'10' : {
'action' : 'deny',
'set' : {
- 'aggregator-as' : '1234567890',
- 'aggregator-ip' : '10.255.255.0',
- 'as-path-exclude' : '1234',
- 'as-path-prepend' : '1234567890 987654321',
- 'atomic-aggregate' : '',
- 'distance' : '110',
- 'extcommunity-bw' : '20000',
- 'extcommunity-rt' : '123:456',
- 'extcommunity-soo' : '456:789',
- 'ipv6-next-hop-global': '2001::1',
- 'ipv6-next-hop-local' : 'fe80::1',
- 'ip-next-hop' : '192.168.1.1',
- 'large-community' : '100:200:300',
- 'local-preference' : '500',
- 'metric' : '150',
- 'metric-type' : 'type-1',
- 'origin' : 'incomplete',
- 'originator-id' : '172.16.10.1',
- 'src' : '100.0.0.1',
- 'tag' : '65530',
- 'weight' : '2',
+ 'aggregator-as' : '1234567890',
+ 'aggregator-ip' : '10.255.255.0',
+ 'as-path-exclude' : '1234',
+ 'as-path-prepend' : '1234567890 987654321',
+ 'as-path-prepend-last-as' : '5',
+ 'atomic-aggregate' : '',
+ 'distance' : '110',
+ 'extcommunity-bw' : '20000',
+ 'extcommunity-rt' : '123:456',
+ 'extcommunity-soo' : '456:789',
+ 'ipv6-next-hop-global' : '2001::1',
+ 'ipv6-next-hop-local' : 'fe80::1',
+ 'ip-next-hop' : '192.168.1.1',
+ 'large-community' : '100:200:300',
+ 'local-preference' : '500',
+ 'metric' : '150',
+ 'metric-type' : 'type-1',
+ 'origin' : 'incomplete',
+ 'originator-id' : '172.16.10.1',
+ 'src' : '100.0.0.1',
+ 'tag' : '65530',
+ 'weight' : '2',
},
},
},
@@ -814,6 +849,13 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
'evpn-vni' : '1234',
},
},
+ '20' : {
+ 'action' : 'permit',
+ 'set' : {
+ 'evpn-gateway-ipv4' : '192.0.2.99',
+ 'evpn-gateway-ipv6' : '2001:db8:f00::1',
+ },
+ },
},
},
}
@@ -924,9 +966,9 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
if 'aggregator-ip' in rule_config['set']:
self.cli_set(path + ['rule', rule, 'set', 'aggregator', 'ip', rule_config['set']['aggregator-ip']])
if 'as-path-exclude' in rule_config['set']:
- self.cli_set(path + ['rule', rule, 'set', 'as-path-exclude', rule_config['set']['as-path-exclude']])
+ self.cli_set(path + ['rule', rule, 'set', 'as-path', 'exclude', rule_config['set']['as-path-exclude']])
if 'as-path-prepend' in rule_config['set']:
- self.cli_set(path + ['rule', rule, 'set', 'as-path-prepend', rule_config['set']['as-path-prepend']])
+ self.cli_set(path + ['rule', rule, 'set', 'as-path', 'prepend', rule_config['set']['as-path-prepend']])
if 'atomic-aggregate' in rule_config['set']:
self.cli_set(path + ['rule', rule, 'set', 'atomic-aggregate'])
if 'distance' in rule_config['set']:
@@ -961,6 +1003,10 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
self.cli_set(path + ['rule', rule, 'set', 'tag', rule_config['set']['tag']])
if 'weight' in rule_config['set']:
self.cli_set(path + ['rule', rule, 'set', 'weight', rule_config['set']['weight']])
+ if 'evpn-gateway-ipv4' in rule_config['set']:
+ self.cli_set(path + ['rule', rule, 'set', 'evpn', 'gateway', 'ipv4', rule_config['set']['evpn-gateway-ipv4']])
+ if 'evpn-gateway-ipv6' in rule_config['set']:
+ self.cli_set(path + ['rule', rule, 'set', 'evpn', 'gateway', 'ipv6', rule_config['set']['evpn-gateway-ipv6']])
self.cli_commit()
@@ -1030,7 +1076,7 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
tmp = f'match ipv6 address prefix-list {rule_config["match"]["ipv6-address-pfx"]}'
self.assertIn(tmp, config)
if 'ipv6-nexthop' in rule_config['match']:
- tmp = f'match ipv6 next-hop {rule_config["match"]["ipv6-nexthop"]}'
+ tmp = f'match ipv6 next-hop address {rule_config["match"]["ipv6-nexthop"]}'
self.assertIn(tmp, config)
if 'large-community' in rule_config['match']:
tmp = f'match large-community {rule_config["match"]["large-community"]}'
@@ -1084,6 +1130,8 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
tmp += 'as-path exclude ' + rule_config['set']['as-path-exclude']
elif 'as-path-prepend' in rule_config['set']:
tmp += 'as-path prepend ' + rule_config['set']['as-path-prepend']
+ elif 'as-path-prepend-last-as' in rule_config['set']:
+ tmp += 'as-path prepend last-as' + rule_config['set']['as-path-prepend-last-as']
elif 'atomic-aggregate' in rule_config['set']:
tmp += 'atomic-aggregate'
elif 'distance' in rule_config['set']:
@@ -1118,6 +1166,10 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
tmp += 'tag ' + rule_config['set']['tag']
elif 'weight' in rule_config['set']:
tmp += 'weight ' + rule_config['set']['weight']
+ elif 'vpn-gateway-ipv4' in rule_config['set']:
+ tmp += 'evpn gateway ipv4 ' + rule_config['set']['vpn-gateway-ipv4']
+ elif 'vpn-gateway-ipv6' in rule_config['set']:
+ tmp += 'evpn gateway ipv6 ' + rule_config['set']['vpn-gateway-ipv6']
self.assertIn(tmp, config)
@@ -1135,18 +1187,13 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
- # Check generated configuration
-
- # Expected values
original = """
50: from 203.0.113.1 lookup 23
50: from 203.0.113.2 lookup 23
"""
tmp = cmd('ip rule show prio 50')
- original = original.split()
- tmp = tmp.split()
- self.assertEqual(tmp, original)
+ self.assertEqual(sort_ip(tmp), sort_ip(original))
# Test set table for fwmark
def test_fwmark_table_id(self):
@@ -1161,17 +1208,32 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
- # Check generated configuration
-
- # Expected values
original = """
101: from all fwmark 0x18 lookup 154
"""
tmp = cmd('ip rule show prio 101')
- original = original.split()
- tmp = tmp.split()
- self.assertEqual(tmp, original)
+ self.assertEqual(sort_ip(tmp), sort_ip(original))
+
+ # Test set table for destination
+ def test_destination_table_id(self):
+ path = base_path + ['local-route']
+
+ dst = '203.0.113.1'
+ rule = '102'
+ table = '154'
+
+ self.cli_set(path + ['rule', rule, 'set', 'table', table])
+ self.cli_set(path + ['rule', rule, 'destination', dst])
+
+ self.cli_commit()
+
+ original = """
+ 102: from all to 203.0.113.1 lookup 154
+ """
+ tmp = cmd('ip rule show prio 102')
+
+ self.assertEqual(sort_ip(tmp), sort_ip(original))
# Test set table for sources with fwmark
def test_fwmark_sources_table_id(self):
@@ -1188,18 +1250,301 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
- # Check generated configuration
-
- # Expected values
original = """
100: from 203.0.113.11 fwmark 0x17 lookup 150
100: from 203.0.113.12 fwmark 0x17 lookup 150
"""
tmp = cmd('ip rule show prio 100')
- original = original.split()
- tmp = tmp.split()
- self.assertEqual(tmp, original)
+ self.assertEqual(sort_ip(tmp), sort_ip(original))
+
+ # Test set table for sources with iif
+ def test_iif_sources_table_id(self):
+ path = base_path + ['local-route']
+
+ sources = ['203.0.113.11', '203.0.113.12']
+ iif = 'lo'
+ rule = '100'
+ table = '150'
+
+ self.cli_set(path + ['rule', rule, 'set', 'table', table])
+ self.cli_set(path + ['rule', rule, 'inbound-interface', iif])
+ for src in sources:
+ self.cli_set(path + ['rule', rule, 'source', src])
+
+ self.cli_commit()
+
+ # Check generated configuration
+ # Expected values
+ original = """
+ 100: from 203.0.113.11 iif lo lookup 150
+ 100: from 203.0.113.12 iif lo lookup 150
+ """
+ tmp = cmd('ip rule show prio 100')
+
+ self.assertEqual(sort_ip(tmp), sort_ip(original))
+
+ # Test set table for sources and destinations with fwmark
+ def test_fwmark_sources_destination_table_id(self):
+ path = base_path + ['local-route']
+
+ sources = ['203.0.113.11', '203.0.113.12']
+ destinations = ['203.0.113.13', '203.0.113.15']
+ fwmk = '23'
+ rule = '103'
+ table = '150'
+ for src in sources:
+ for dst in destinations:
+ self.cli_set(path + ['rule', rule, 'set', 'table', table])
+ self.cli_set(path + ['rule', rule, 'source', src])
+ self.cli_set(path + ['rule', rule, 'destination', dst])
+ self.cli_set(path + ['rule', rule, 'fwmark', fwmk])
+
+ self.cli_commit()
+
+ original = """
+ 103: from 203.0.113.11 to 203.0.113.13 fwmark 0x17 lookup 150
+ 103: from 203.0.113.11 to 203.0.113.15 fwmark 0x17 lookup 150
+ 103: from 203.0.113.12 to 203.0.113.13 fwmark 0x17 lookup 150
+ 103: from 203.0.113.12 to 203.0.113.15 fwmark 0x17 lookup 150
+ """
+ tmp = cmd('ip rule show prio 103')
+
+ self.assertEqual(sort_ip(tmp), sort_ip(original))
+
+ # Test set table ipv6 for some sources ipv6
+ def test_ipv6_table_id(self):
+ path = base_path + ['local-route6']
+
+ sources = ['2001:db8:123::/48', '2001:db8:126::/48']
+ rule = '50'
+ table = '23'
+ for src in sources:
+ self.cli_set(path + ['rule', rule, 'set', 'table', table])
+ self.cli_set(path + ['rule', rule, 'source', src])
+
+ self.cli_commit()
+
+ original = """
+ 50: from 2001:db8:123::/48 lookup 23
+ 50: from 2001:db8:126::/48 lookup 23
+ """
+ tmp = cmd('ip -6 rule show prio 50')
+
+ self.assertEqual(sort_ip(tmp), sort_ip(original))
+
+ # Test set table for fwmark ipv6
+ def test_fwmark_ipv6_table_id(self):
+ path = base_path + ['local-route6']
+
+ fwmk = '24'
+ rule = '100'
+ table = '154'
+
+ self.cli_set(path + ['rule', rule, 'set', 'table', table])
+ self.cli_set(path + ['rule', rule, 'fwmark', fwmk])
+
+ self.cli_commit()
+
+ original = """
+ 100: from all fwmark 0x18 lookup 154
+ """
+ tmp = cmd('ip -6 rule show prio 100')
+
+ self.assertEqual(sort_ip(tmp), sort_ip(original))
+
+ # Test set table for destination ipv6
+ def test_destination_ipv6_table_id(self):
+ path = base_path + ['local-route6']
+
+ dst = '2001:db8:1337::/126'
+ rule = '101'
+ table = '154'
+
+ self.cli_set(path + ['rule', rule, 'set', 'table', table])
+ self.cli_set(path + ['rule', rule, 'destination', dst])
+
+ self.cli_commit()
+
+ original = """
+ 101: from all to 2001:db8:1337::/126 lookup 154
+ """
+ tmp = cmd('ip -6 rule show prio 101')
+
+ self.assertEqual(sort_ip(tmp), sort_ip(original))
+
+ # Test set table for sources with fwmark ipv6
+ def test_fwmark_sources_ipv6_table_id(self):
+ path = base_path + ['local-route6']
+
+ sources = ['2001:db8:1338::/126', '2001:db8:1339::/126']
+ fwmk = '23'
+ rule = '102'
+ table = '150'
+ for src in sources:
+ self.cli_set(path + ['rule', rule, 'set', 'table', table])
+ self.cli_set(path + ['rule', rule, 'source', src])
+ self.cli_set(path + ['rule', rule, 'fwmark', fwmk])
+
+ self.cli_commit()
+
+ original = """
+ 102: from 2001:db8:1338::/126 fwmark 0x17 lookup 150
+ 102: from 2001:db8:1339::/126 fwmark 0x17 lookup 150
+ """
+ tmp = cmd('ip -6 rule show prio 102')
+
+ self.assertEqual(sort_ip(tmp), sort_ip(original))
+
+ # Test set table for sources with iif ipv6
+ def test_iif_sources_ipv6_table_id(self):
+ path = base_path + ['local-route6']
+
+ sources = ['2001:db8:1338::/126', '2001:db8:1339::/126']
+ iif = 'lo'
+ rule = '102'
+ table = '150'
+ for src in sources:
+ self.cli_set(path + ['rule', rule, 'set', 'table', table])
+ self.cli_set(path + ['rule', rule, 'source', src])
+ self.cli_set(path + ['rule', rule, 'inbound-interface', iif])
+
+ self.cli_commit()
+
+ # Check generated configuration
+ # Expected values
+ original = """
+ 102: from 2001:db8:1338::/126 iif lo lookup 150
+ 102: from 2001:db8:1339::/126 iif lo lookup 150
+ """
+ tmp = cmd('ip -6 rule show prio 102')
+
+ self.assertEqual(sort_ip(tmp), sort_ip(original))
+
+ # Test set table for sources and destinations with fwmark ipv6
+ def test_fwmark_sources_destination_ipv6_table_id(self):
+ path = base_path + ['local-route6']
+
+ sources = ['2001:db8:1338::/126', '2001:db8:1339::/56']
+ destinations = ['2001:db8:13::/48', '2001:db8:16::/48']
+ fwmk = '23'
+ rule = '103'
+ table = '150'
+ for src in sources:
+ for dst in destinations:
+ self.cli_set(path + ['rule', rule, 'set', 'table', table])
+ self.cli_set(path + ['rule', rule, 'source', src])
+ self.cli_set(path + ['rule', rule, 'destination', dst])
+ self.cli_set(path + ['rule', rule, 'fwmark', fwmk])
+
+ self.cli_commit()
+
+ original = """
+ 103: from 2001:db8:1338::/126 to 2001:db8:13::/48 fwmark 0x17 lookup 150
+ 103: from 2001:db8:1338::/126 to 2001:db8:16::/48 fwmark 0x17 lookup 150
+ 103: from 2001:db8:1339::/56 to 2001:db8:13::/48 fwmark 0x17 lookup 150
+ 103: from 2001:db8:1339::/56 to 2001:db8:16::/48 fwmark 0x17 lookup 150
+ """
+ tmp = cmd('ip -6 rule show prio 103')
+
+ self.assertEqual(sort_ip(tmp), sort_ip(original))
+
+ # Test delete table for sources and destination with fwmark ipv4/ipv6
+ def test_delete_ipv4_ipv6_table_id(self):
+ path = base_path + ['local-route']
+ path_v6 = base_path + ['local-route6']
+
+ sources = ['203.0.113.0/24', '203.0.114.5']
+ destinations = ['203.0.112.0/24', '203.0.116.5']
+ sources_v6 = ['2001:db8:1338::/126', '2001:db8:1339::/56']
+ destinations_v6 = ['2001:db8:13::/48', '2001:db8:16::/48']
+ fwmk = '23'
+ rule = '103'
+ table = '150'
+ for src in sources:
+ for dst in destinations:
+ self.cli_set(path + ['rule', rule, 'set', 'table', table])
+ self.cli_set(path + ['rule', rule, 'source', src])
+ self.cli_set(path + ['rule', rule, 'destination', dst])
+ self.cli_set(path + ['rule', rule, 'fwmark', fwmk])
+
+ for src in sources_v6:
+ for dst in destinations_v6:
+ self.cli_set(path_v6 + ['rule', rule, 'set', 'table', table])
+ self.cli_set(path_v6 + ['rule', rule, 'source', src])
+ self.cli_set(path_v6 + ['rule', rule, 'destination', dst])
+ self.cli_set(path_v6 + ['rule', rule, 'fwmark', fwmk])
+
+ self.cli_commit()
+
+ original = """
+ 103: from 203.0.113.0/24 to 203.0.116.5 fwmark 0x17 lookup 150
+ 103: from 203.0.114.5 to 203.0.112.0/24 fwmark 0x17 lookup 150
+ 103: from 203.0.114.5 to 203.0.116.5 fwmark 0x17 lookup 150
+ 103: from 203.0.113.0/24 to 203.0.112.0/24 fwmark 0x17 lookup 150
+ """
+ original_v6 = """
+ 103: from 2001:db8:1338::/126 to 2001:db8:16::/48 fwmark 0x17 lookup 150
+ 103: from 2001:db8:1339::/56 to 2001:db8:13::/48 fwmark 0x17 lookup 150
+ 103: from 2001:db8:1339::/56 to 2001:db8:16::/48 fwmark 0x17 lookup 150
+ 103: from 2001:db8:1338::/126 to 2001:db8:13::/48 fwmark 0x17 lookup 150
+ """
+ tmp = cmd('ip rule show prio 103')
+ tmp_v6 = cmd('ip -6 rule show prio 103')
+
+ self.assertEqual(sort_ip(tmp), sort_ip(original))
+ self.assertEqual(sort_ip(tmp_v6), sort_ip(original_v6))
+
+ self.cli_delete(path)
+ self.cli_delete(path_v6)
+ self.cli_commit()
+
+ tmp = cmd('ip rule show prio 103')
+ tmp_v6 = cmd('ip -6 rule show prio 103')
+
+ self.assertEqual(sort_ip(tmp), [])
+ self.assertEqual(sort_ip(tmp_v6), [])
+
+ # Test multiple commits ipv4
+ def test_multiple_commit_ipv4_table_id(self):
+ path = base_path + ['local-route']
+
+ sources = ['192.0.2.1', '192.0.2.2']
+ destination = '203.0.113.25'
+ rule = '105'
+ table = '151'
+ self.cli_set(path + ['rule', rule, 'set', 'table', table])
+ for src in sources:
+ self.cli_set(path + ['rule', rule, 'source', src])
+
+ self.cli_commit()
+
+ original_first = """
+ 105: from 192.0.2.1 lookup 151
+ 105: from 192.0.2.2 lookup 151
+ """
+ tmp = cmd('ip rule show prio 105')
+
+ self.assertEqual(sort_ip(tmp), sort_ip(original_first))
+
+ # Create second commit with added destination
+ self.cli_set(path + ['rule', rule, 'destination', destination])
+ self.cli_commit()
+
+ original_second = """
+ 105: from 192.0.2.1 to 203.0.113.25 lookup 151
+ 105: from 192.0.2.2 to 203.0.113.25 lookup 151
+ """
+ tmp = cmd('ip rule show prio 105')
+
+ self.assertEqual(sort_ip(tmp), sort_ip(original_second))
+
+
+def sort_ip(output):
+ o = '\n'.join([' '.join(line.strip().split()) for line in output.strip().splitlines()])
+ o = o.splitlines()
+ o.sort()
+ return o
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_policy_route.py b/smoketest/scripts/cli/test_policy_route.py
new file mode 100755
index 000000000..e2d70f289
--- /dev/null
+++ b/smoketest/scripts/cli/test_policy_route.py
@@ -0,0 +1,145 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021-2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import unittest
+
+from base_vyostest_shim import VyOSUnitTestSHIM
+
+from vyos.util import cmd
+
+mark = '100'
+table_mark_offset = 0x7fffffff
+table_id = '101'
+interface = 'eth0'
+interface_ip = '172.16.10.1/24'
+
+class TestPolicyRoute(VyOSUnitTestSHIM.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ super(TestPolicyRoute, cls).setUpClass()
+
+ cls.cli_set(cls, ['interfaces', 'ethernet', interface, 'address', interface_ip])
+ cls.cli_set(cls, ['protocols', 'static', 'table', table_id, 'route', '0.0.0.0/0', 'interface', interface])
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.cli_delete(cls, ['interfaces', 'ethernet', interface, 'address', interface_ip])
+ cls.cli_delete(cls, ['protocols', 'static', 'table', table_id])
+
+ super(TestPolicyRoute, cls).tearDownClass()
+
+ def tearDown(self):
+ self.cli_delete(['interfaces', 'ethernet', interface, 'policy'])
+ self.cli_delete(['policy', 'route'])
+ self.cli_delete(['policy', 'route6'])
+ self.cli_commit()
+
+ def test_pbr_mark(self):
+ self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'source', 'address', '172.16.20.10'])
+ self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'destination', 'address', '172.16.10.10'])
+ self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'set', 'mark', mark])
+
+ self.cli_set(['interfaces', 'ethernet', interface, 'policy', 'route', 'smoketest'])
+
+ self.cli_commit()
+
+ mark_hex = "{0:#010x}".format(int(mark))
+
+ nftables_search = [
+ [f'iifname "{interface}"','jump VYOS_PBR_smoketest'],
+ ['ip daddr 172.16.10.10', 'ip saddr 172.16.20.10', 'meta mark set ' + mark_hex],
+ ]
+
+ nftables_output = cmd('sudo nft list table ip mangle')
+
+ for search in nftables_search:
+ matched = False
+ for line in nftables_output.split("\n"):
+ if all(item in line for item in search):
+ matched = True
+ break
+ self.assertTrue(matched)
+
+ def test_pbr_table(self):
+ self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'protocol', 'tcp'])
+ self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'destination', 'port', '8888'])
+ self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'tcp', 'flags', 'syn'])
+ self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'tcp', 'flags', 'not', 'ack'])
+ self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'set', 'table', table_id])
+ self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '1', 'protocol', 'tcp_udp'])
+ self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '1', 'destination', 'port', '8888'])
+ self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '1', 'set', 'table', table_id])
+
+ self.cli_set(['interfaces', 'ethernet', interface, 'policy', 'route', 'smoketest'])
+ self.cli_set(['interfaces', 'ethernet', interface, 'policy', 'route6', 'smoketest6'])
+
+ self.cli_commit()
+
+ mark_hex = "{0:#010x}".format(table_mark_offset - int(table_id))
+
+ # IPv4
+
+ nftables_search = [
+ [f'iifname "{interface}"', 'jump VYOS_PBR_smoketest'],
+ ['tcp flags & (syn | ack) == syn', 'tcp dport { 8888 }', 'meta mark set ' + mark_hex]
+ ]
+
+ nftables_output = cmd('sudo nft list table ip mangle')
+
+ for search in nftables_search:
+ matched = False
+ for line in nftables_output.split("\n"):
+ if all(item in line for item in search):
+ matched = True
+ break
+ self.assertTrue(matched)
+
+ # IPv6
+
+ nftables6_search = [
+ [f'iifname "{interface}"', 'jump VYOS_PBR6_smoketest'],
+ ['meta l4proto { tcp, udp }', 'th dport { 8888 }', 'meta mark set ' + mark_hex]
+ ]
+
+ nftables6_output = cmd('sudo nft list table ip6 mangle')
+
+ for search in nftables6_search:
+ matched = False
+ for line in nftables6_output.split("\n"):
+ if all(item in line for item in search):
+ matched = True
+ break
+ self.assertTrue(matched)
+
+ # IP rule fwmark -> table
+
+ ip_rule_search = [
+ ['fwmark ' + hex(table_mark_offset - int(table_id)), 'lookup ' + table_id]
+ ]
+
+ ip_rule_output = cmd('ip rule show')
+
+ for search in ip_rule_search:
+ matched = False
+ for line in ip_rule_output.split("\n"):
+ if all(item in line for item in search):
+ matched = True
+ break
+ self.assertTrue(matched)
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_bfd.py b/smoketest/scripts/cli/test_protocols_bfd.py
index 297398d3c..fdc254a05 100755
--- a/smoketest/scripts/cli/test_protocols_bfd.py
+++ b/smoketest/scripts/cli/test_protocols_bfd.py
@@ -24,30 +24,35 @@ PROCESS_NAME = 'bfdd'
base_path = ['protocols', 'bfd']
dum_if = 'dum1001'
+vrf_name = 'red'
peers = {
'192.0.2.10' : {
'intv_rx' : '500',
'intv_tx' : '600',
'multihop' : '',
'source_addr': '192.0.2.254',
- },
+ 'profile' : 'foo-bar-baz',
+ },
'192.0.2.20' : {
'echo_mode' : '',
'intv_echo' : '100',
'intv_mult' : '100',
'intv_rx' : '222',
'intv_tx' : '333',
+ 'passive' : '',
'shutdown' : '',
+ 'profile' : 'foo',
'source_intf': dum_if,
- },
- '2001:db8::a' : {
+ },
+ '2001:db8::1000:1' : {
'source_addr': '2001:db8::1',
- 'source_intf': dum_if,
- },
- '2001:db8::b' : {
+ 'vrf' : vrf_name,
+ },
+ '2001:db8::2000:1' : {
'source_addr': '2001:db8::1',
'multihop' : '',
- },
+ 'profile' : 'baz_foo',
+ },
}
profiles = {
@@ -59,9 +64,15 @@ profiles = {
'intv_tx' : '333',
'shutdown' : '',
},
- 'bar' : {
+ 'foo-bar-baz' : {
+ 'intv_mult' : '4',
+ 'intv_rx' : '400',
+ 'intv_tx' : '400',
+ },
+ 'baz_foo' : {
'intv_mult' : '102',
'intv_rx' : '444',
+ 'passive' : '',
},
}
@@ -73,6 +84,8 @@ class TestProtocolsBFD(VyOSUnitTestSHIM.TestCase):
self.assertTrue(process_named_running(PROCESS_NAME))
def test_bfd_peer(self):
+ self.cli_set(['vrf', 'name', vrf_name, 'table', '1000'])
+
for peer, peer_config in peers.items():
if 'echo_mode' in peer_config:
self.cli_set(base_path + ['peer', peer, 'echo-mode'])
@@ -86,18 +99,22 @@ class TestProtocolsBFD(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + ['peer', peer, 'interval', 'transmit', peer_config["intv_tx"]])
if 'multihop' in peer_config:
self.cli_set(base_path + ['peer', peer, 'multihop'])
+ if 'passive' in peer_config:
+ self.cli_set(base_path + ['peer', peer, 'passive'])
if 'shutdown' in peer_config:
self.cli_set(base_path + ['peer', peer, 'shutdown'])
if 'source_addr' in peer_config:
self.cli_set(base_path + ['peer', peer, 'source', 'address', peer_config["source_addr"]])
if 'source_intf' in peer_config:
self.cli_set(base_path + ['peer', peer, 'source', 'interface', peer_config["source_intf"]])
+ if 'vrf' in peer_config:
+ self.cli_set(base_path + ['peer', peer, 'vrf', peer_config["vrf"]])
# commit changes
self.cli_commit()
# Verify FRR bgpd configuration
- frrconfig = self.getFRRconfig('bfd')
+ frrconfig = self.getFRRconfig('bfd', daemon=PROCESS_NAME)
for peer, peer_config in peers.items():
tmp = f'peer {peer}'
if 'multihop' in peer_config:
@@ -106,28 +123,33 @@ class TestProtocolsBFD(VyOSUnitTestSHIM.TestCase):
tmp += f' local-address {peer_config["source_addr"]}'
if 'source_intf' in peer_config:
tmp += f' interface {peer_config["source_intf"]}'
+ if 'vrf' in peer_config:
+ tmp += f' vrf {peer_config["vrf"]}'
self.assertIn(tmp, frrconfig)
- peerconfig = self.getFRRconfig(f' peer {peer}', end='')
+ peerconfig = self.getFRRconfig(f' peer {peer}', end='', daemon=PROCESS_NAME)
if 'echo_mode' in peer_config:
self.assertIn(f'echo-mode', peerconfig)
if 'intv_echo' in peer_config:
- self.assertIn(f'echo-interval {peer_config["intv_echo"]}', peerconfig)
+ self.assertIn(f'echo receive-interval {peer_config["intv_echo"]}', peerconfig)
+ self.assertIn(f'echo transmit-interval {peer_config["intv_echo"]}', peerconfig)
if 'intv_mult' in peer_config:
self.assertIn(f'detect-multiplier {peer_config["intv_mult"]}', peerconfig)
if 'intv_rx' in peer_config:
self.assertIn(f'receive-interval {peer_config["intv_rx"]}', peerconfig)
if 'intv_tx' in peer_config:
self.assertIn(f'transmit-interval {peer_config["intv_tx"]}', peerconfig)
+ if 'passive' in peer_config:
+ self.assertIn(f'passive-mode', peerconfig)
if 'shutdown' in peer_config:
self.assertIn(f'shutdown', peerconfig)
else:
self.assertNotIn(f'shutdown', peerconfig)
- def test_bfd_profile(self):
- peer = '192.0.2.10'
+ self.cli_delete(['vrf', 'name', vrf_name])
+ def test_bfd_profile(self):
for profile, profile_config in profiles.items():
if 'echo_mode' in profile_config:
self.cli_set(base_path + ['profile', profile, 'echo-mode'])
@@ -139,10 +161,25 @@ class TestProtocolsBFD(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + ['profile', profile, 'interval', 'receive', profile_config["intv_rx"]])
if 'intv_tx' in profile_config:
self.cli_set(base_path + ['profile', profile, 'interval', 'transmit', profile_config["intv_tx"]])
+ if 'passive' in profile_config:
+ self.cli_set(base_path + ['profile', profile, 'passive'])
if 'shutdown' in profile_config:
self.cli_set(base_path + ['profile', profile, 'shutdown'])
- self.cli_set(base_path + ['peer', peer, 'profile', list(profiles)[0]])
+ for peer, peer_config in peers.items():
+ if 'profile' in peer_config:
+ self.cli_set(base_path + ['peer', peer, 'profile', peer_config["profile"] + 'wrong'])
+ if 'source_addr' in peer_config:
+ self.cli_set(base_path + ['peer', peer, 'source', 'address', peer_config["source_addr"]])
+ if 'source_intf' in peer_config:
+ self.cli_set(base_path + ['peer', peer, 'source', 'interface', peer_config["source_intf"]])
+
+ # BFD profile does not exist!
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ for peer, peer_config in peers.items():
+ if 'profile' in peer_config:
+ self.cli_set(base_path + ['peer', peer, 'profile', peer_config["profile"]])
# commit changes
self.cli_commit()
@@ -151,19 +188,27 @@ class TestProtocolsBFD(VyOSUnitTestSHIM.TestCase):
for profile, profile_config in profiles.items():
config = self.getFRRconfig(f' profile {profile}', endsection='^ !')
if 'echo_mode' in profile_config:
- self.assertIn(f'echo-mode', config)
+ self.assertIn(f' echo-mode', config)
if 'intv_echo' in profile_config:
- self.assertIn(f'echo-interval {profile_config["intv_echo"]}', config)
+ self.assertIn(f' echo receive-interval {profile_config["intv_echo"]}', config)
+ self.assertIn(f' echo transmit-interval {profile_config["intv_echo"]}', config)
if 'intv_mult' in profile_config:
- self.assertIn(f'detect-multiplier {profile_config["intv_mult"]}', config)
+ self.assertIn(f' detect-multiplier {profile_config["intv_mult"]}', config)
if 'intv_rx' in profile_config:
- self.assertIn(f'receive-interval {profile_config["intv_rx"]}', config)
+ self.assertIn(f' receive-interval {profile_config["intv_rx"]}', config)
if 'intv_tx' in profile_config:
- self.assertIn(f'transmit-interval {profile_config["intv_tx"]}', config)
+ self.assertIn(f' transmit-interval {profile_config["intv_tx"]}', config)
+ if 'passive' in profile_config:
+ self.assertIn(f' passive-mode', config)
if 'shutdown' in profile_config:
- self.assertIn(f'shutdown', config)
+ self.assertIn(f' shutdown', config)
else:
self.assertNotIn(f'shutdown', config)
+ for peer, peer_config in peers.items():
+ peerconfig = self.getFRRconfig(f' peer {peer}', end='', daemon=PROCESS_NAME)
+ if 'profile' in peer_config:
+ self.assertIn(f' profile {peer_config["profile"]}', peerconfig)
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py
index 16284ed01..9c0c93779 100755
--- a/smoketest/scripts/cli/test_protocols_bgp.py
+++ b/smoketest/scripts/cli/test_protocols_bgp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -32,119 +32,154 @@ prefix_list_in = 'pfx-foo-in'
prefix_list_out = 'pfx-foo-out'
prefix_list_in6 = 'pfx-foo-in6'
prefix_list_out6 = 'pfx-foo-out6'
+bfd_profile = 'foo-bar-baz'
neighbor_config = {
'192.0.2.1' : {
- 'cap_dynamic' : '',
- 'cap_ext_next' : '',
- 'remote_as' : '100',
- 'adv_interv' : '400',
- 'passive' : '',
- 'password' : 'VyOS-Secure123',
- 'shutdown' : '',
- 'cap_over' : '',
- 'ttl_security' : '5',
- 'local_as' : '300',
- 'route_map_in' : route_map_in,
- 'route_map_out': route_map_out,
+ 'bfd' : '',
+ 'cap_dynamic' : '',
+ 'cap_ext_next' : '',
+ 'remote_as' : '100',
+ 'adv_interv' : '400',
+ 'passive' : '',
+ 'password' : 'VyOS-Secure123',
+ 'shutdown' : '',
+ 'cap_over' : '',
+ 'ttl_security' : '5',
+ 'local_as' : '300',
+ 'route_map_in' : route_map_in,
+ 'route_map_out' : route_map_out,
'no_send_comm_ext' : '',
- 'addpath_all' : '',
+ 'addpath_all' : '',
},
'192.0.2.2' : {
- 'remote_as' : '200',
- 'shutdown' : '',
- 'no_cap_nego' : '',
- 'port' : '667',
- 'cap_strict' : '',
- 'pfx_list_in' : prefix_list_in,
- 'pfx_list_out' : prefix_list_out,
+ 'bfd_profile' : bfd_profile,
+ 'remote_as' : '200',
+ 'shutdown' : '',
+ 'no_cap_nego' : '',
+ 'port' : '667',
+ 'cap_strict' : '',
+ 'advertise_map' : route_map_in,
+ 'non_exist_map' : route_map_out,
+ 'pfx_list_in' : prefix_list_in,
+ 'pfx_list_out' : prefix_list_out,
'no_send_comm_std' : '',
},
'192.0.2.3' : {
- 'description' : 'foo bar baz',
- 'remote_as' : '200',
- 'passive' : '',
- 'multi_hop' : '5',
- 'update_src' : 'lo',
+ 'advertise_map' : route_map_in,
+ 'description' : 'foo bar baz',
+ 'remote_as' : '200',
+ 'passive' : '',
+ 'multi_hop' : '5',
+ 'update_src' : 'lo',
+ 'peer_group' : 'foo',
+ 'graceful_rst' : '',
},
'2001:db8::1' : {
- 'cap_dynamic' : '',
- 'cap_ext_next' : '',
- 'remote_as' : '123',
- 'adv_interv' : '400',
- 'passive' : '',
- 'password' : 'VyOS-Secure123',
- 'shutdown' : '',
- 'cap_over' : '',
- 'ttl_security' : '5',
- 'local_as' : '300',
- 'solo' : '',
- 'route_map_in' : route_map_in,
- 'route_map_out': route_map_out,
+ 'advertise_map' : route_map_in,
+ 'exist_map' : route_map_out,
+ 'cap_dynamic' : '',
+ 'cap_ext_next' : '',
+ 'remote_as' : '123',
+ 'adv_interv' : '400',
+ 'passive' : '',
+ 'password' : 'VyOS-Secure123',
+ 'shutdown' : '',
+ 'cap_over' : '',
+ 'ttl_security' : '5',
+ 'local_as' : '300',
+ 'solo' : '',
+ 'route_map_in' : route_map_in,
+ 'route_map_out' : route_map_out,
'no_send_comm_std' : '',
'addpath_per_as' : '',
+ 'peer_group' : 'foo-bar',
},
'2001:db8::2' : {
- 'remote_as' : '456',
- 'shutdown' : '',
- 'no_cap_nego' : '',
- 'port' : '667',
- 'cap_strict' : '',
- 'pfx_list_in' : prefix_list_in6,
- 'pfx_list_out' : prefix_list_out6,
+ 'remote_as' : '456',
+ 'shutdown' : '',
+ 'no_cap_nego' : '',
+ 'port' : '667',
+ 'cap_strict' : '',
+ 'pfx_list_in' : prefix_list_in6,
+ 'pfx_list_out' : prefix_list_out6,
'no_send_comm_ext' : '',
+ 'peer_group' : 'foo-bar_baz',
+ 'graceful_rst_hlp' : ''
},
}
peer_group_config = {
'foo' : {
- 'remote_as' : '100',
- 'passive' : '',
- 'password' : 'VyOS-Secure123',
- 'shutdown' : '',
- 'cap_over' : '',
- 'ttl_security': '5',
+ 'advertise_map' : route_map_in,
+ 'exist_map' : route_map_out,
+ 'bfd' : '',
+ 'remote_as' : '100',
+ 'passive' : '',
+ 'password' : 'VyOS-Secure123',
+ 'shutdown' : '',
+ 'cap_over' : '',
+ 'ttl_security' : '5',
},
'bar' : {
- 'description' : 'foo peer bar group',
- 'remote_as' : '200',
- 'shutdown' : '',
- 'no_cap_nego' : '',
- 'local_as' : '300',
- 'pfx_list_in' : prefix_list_in,
- 'pfx_list_out' : prefix_list_out,
+ 'remote_as' : '111',
+ 'graceful_rst_no' : ''
+ },
+ 'foo-bar' : {
+ 'advertise_map' : route_map_in,
+ 'description' : 'foo peer bar group',
+ 'remote_as' : '200',
+ 'shutdown' : '',
+ 'no_cap_nego' : '',
+ 'local_as' : '300',
+ 'pfx_list_in' : prefix_list_in,
+ 'pfx_list_out' : prefix_list_out,
'no_send_comm_ext' : '',
},
- 'baz' : {
- 'cap_dynamic' : '',
- 'cap_ext_next' : '',
- 'remote_as' : '200',
- 'passive' : '',
- 'multi_hop' : '5',
- 'update_src' : 'lo',
- 'route_map_in' : route_map_in,
- 'route_map_out': route_map_out,
+ 'foo-bar_baz' : {
+ 'advertise_map' : route_map_in,
+ 'non_exist_map' : route_map_out,
+ 'bfd_profile' : bfd_profile,
+ 'cap_dynamic' : '',
+ 'cap_ext_next' : '',
+ 'remote_as' : '200',
+ 'passive' : '',
+ 'multi_hop' : '5',
+ 'update_src' : 'lo',
+ 'route_map_in' : route_map_in,
+ 'route_map_out' : route_map_out,
},
}
class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
- def setUp(self):
- self.cli_set(['policy', 'route-map', route_map_in, 'rule', '10', 'action', 'permit'])
- self.cli_set(['policy', 'route-map', route_map_out, 'rule', '10', 'action', 'permit'])
- self.cli_set(['policy', 'prefix-list', prefix_list_in, 'rule', '10', 'action', 'permit'])
- self.cli_set(['policy', 'prefix-list', prefix_list_in, 'rule', '10', 'prefix', '192.0.2.0/25'])
- self.cli_set(['policy', 'prefix-list', prefix_list_out, 'rule', '10', 'action', 'permit'])
- self.cli_set(['policy', 'prefix-list', prefix_list_out, 'rule', '10', 'prefix', '192.0.2.128/25'])
-
- self.cli_set(['policy', 'prefix-list6', prefix_list_in6, 'rule', '10', 'action', 'permit'])
- self.cli_set(['policy', 'prefix-list6', prefix_list_in6, 'rule', '10', 'prefix', '2001:db8:1000::/64'])
- self.cli_set(['policy', 'prefix-list6', prefix_list_out6, 'rule', '10', 'action', 'deny'])
- self.cli_set(['policy', 'prefix-list6', prefix_list_out6, 'rule', '10', 'prefix', '2001:db8:2000::/64'])
+ @classmethod
+ def setUpClass(cls):
+ super(TestProtocolsBGP, cls).setUpClass()
+
+ # ensure we can also run this test on a live system - so lets clean
+ # out the current configuration :)
+ cls.cli_delete(cls, base_path)
+
+ cls.cli_set(cls, ['policy', 'route-map', route_map_in, 'rule', '10', 'action', 'permit'])
+ cls.cli_set(cls, ['policy', 'route-map', route_map_out, 'rule', '10', 'action', 'permit'])
+ cls.cli_set(cls, ['policy', 'prefix-list', prefix_list_in, 'rule', '10', 'action', 'permit'])
+ cls.cli_set(cls, ['policy', 'prefix-list', prefix_list_in, 'rule', '10', 'prefix', '192.0.2.0/25'])
+ cls.cli_set(cls, ['policy', 'prefix-list', prefix_list_out, 'rule', '10', 'action', 'permit'])
+ cls.cli_set(cls, ['policy', 'prefix-list', prefix_list_out, 'rule', '10', 'prefix', '192.0.2.128/25'])
+
+ cls.cli_set(cls, ['policy', 'prefix-list6', prefix_list_in6, 'rule', '10', 'action', 'permit'])
+ cls.cli_set(cls, ['policy', 'prefix-list6', prefix_list_in6, 'rule', '10', 'prefix', '2001:db8:1000::/64'])
+ cls.cli_set(cls, ['policy', 'prefix-list6', prefix_list_out6, 'rule', '10', 'action', 'deny'])
+ cls.cli_set(cls, ['policy', 'prefix-list6', prefix_list_out6, 'rule', '10', 'prefix', '2001:db8:2000::/64'])
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.cli_delete(cls, ['policy'])
+ def setUp(self):
self.cli_set(base_path + ['local-as', ASN])
def tearDown(self):
- self.cli_delete(['policy'])
self.cli_delete(['vrf'])
self.cli_delete(base_path)
self.cli_commit()
@@ -154,6 +189,11 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
def verify_frr_config(self, peer, peer_config, frrconfig):
# recurring patterns to verify for both a simple neighbor and a peer-group
+ if 'bfd' in peer_config:
+ self.assertIn(f' neighbor {peer} bfd', frrconfig)
+ if 'bfd_profile' in peer_config:
+ self.assertIn(f' neighbor {peer} bfd profile {peer_config["bfd_profile"]}', frrconfig)
+ self.assertIn(f' neighbor {peer} bfd check-control-plane-failure', frrconfig)
if 'cap_dynamic' in peer_config:
self.assertIn(f' neighbor {peer} capability dynamic', frrconfig)
if 'cap_ext_next' in peer_config:
@@ -198,7 +238,19 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.assertIn(f' neighbor {peer} addpath-tx-all-paths', frrconfig)
if 'addpath_per_as' in peer_config:
self.assertIn(f' neighbor {peer} addpath-tx-bestpath-per-AS', frrconfig)
-
+ if 'advertise_map' in peer_config:
+ base = f' neighbor {peer} advertise-map {peer_config["advertise_map"]}'
+ if 'exist_map' in peer_config:
+ base = f'{base} exist-map {peer_config["exist_map"]}'
+ if 'non_exist_map' in peer_config:
+ base = f'{base} non-exist-map {peer_config["non_exist_map"]}'
+ self.assertIn(base, frrconfig)
+ if 'graceful_rst' in peer_config:
+ self.assertIn(f' neighbor {peer} graceful-restart', frrconfig)
+ if 'graceful_rst_no' in peer_config:
+ self.assertIn(f' neighbor {peer} graceful-restart-disable', frrconfig)
+ if 'graceful_rst_hlp' in peer_config:
+ self.assertIn(f' neighbor {peer} graceful-restart-helper', frrconfig)
def test_bgp_01_simple(self):
router_id = '127.0.0.1'
@@ -208,6 +260,8 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
max_path_v4ibgp = '4'
max_path_v6 = '8'
max_path_v6ibgp = '16'
+ cond_adv_timer = '30'
+ min_hold_time = '2'
self.cli_set(base_path + ['parameters', 'router-id', router_id])
self.cli_set(base_path + ['parameters', 'log-neighbor-changes'])
@@ -229,6 +283,14 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + ['parameters', 'bestpath', 'bandwidth', 'default-weight-for-missing'])
self.cli_set(base_path + ['parameters', 'bestpath', 'compare-routerid'])
+ self.cli_set(base_path + ['parameters', 'conditional-advertisement', 'timer', cond_adv_timer])
+ self.cli_set(base_path + ['parameters', 'fast-convergence'])
+ self.cli_set(base_path + ['parameters', 'minimum-holdtime', min_hold_time])
+ self.cli_set(base_path + ['parameters', 'no-suppress-duplicates'])
+ self.cli_set(base_path + ['parameters', 'reject-as-sets'])
+ self.cli_set(base_path + ['parameters', 'shutdown'])
+ self.cli_set(base_path + ['parameters', 'suppress-fib-pending'])
+
# AFI maximum path support
self.cli_set(base_path + ['address-family', 'ipv4-unicast', 'maximum-paths', 'ebgp', max_path_v4])
self.cli_set(base_path + ['address-family', 'ipv4-unicast', 'maximum-paths', 'ibgp', max_path_v4ibgp])
@@ -244,12 +306,19 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.assertIn(f' bgp router-id {router_id}', frrconfig)
self.assertIn(f' bgp log-neighbor-changes', frrconfig)
self.assertIn(f' bgp default local-preference {local_pref}', frrconfig)
+ self.assertIn(f' bgp conditional-advertisement timer {cond_adv_timer}', frrconfig)
+ self.assertIn(f' bgp fast-convergence', frrconfig)
self.assertIn(f' bgp graceful-restart stalepath-time {stalepath_time}', frrconfig)
self.assertIn(f' bgp graceful-shutdown', frrconfig)
self.assertIn(f' bgp bestpath as-path multipath-relax', frrconfig)
self.assertIn(f' bgp bestpath bandwidth default-weight-for-missing', frrconfig)
self.assertIn(f' bgp bestpath compare-routerid', frrconfig)
+ self.assertIn(f' bgp minimum-holdtime {min_hold_time}', frrconfig)
+ self.assertIn(f' bgp reject-as-sets', frrconfig)
+ self.assertIn(f' bgp shutdown', frrconfig)
+ self.assertIn(f' bgp suppress-fib-pending', frrconfig)
self.assertNotIn(f'bgp ebgp-requires-policy', frrconfig)
+ self.assertIn(f' no bgp suppress-duplicates', frrconfig)
afiv4_config = self.getFRRconfig(' address-family ipv4 unicast')
self.assertIn(f' maximum-paths {max_path_v4}', afiv4_config)
@@ -263,6 +332,8 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
def test_bgp_02_neighbors(self):
# Test out individual neighbor configuration items, not all of them are
# also available to a peer-group!
+ self.cli_set(base_path + ['parameters', 'deterministic-med'])
+
for peer, peer_config in neighbor_config.items():
afi = 'ipv4-unicast'
if is_ipv6(peer):
@@ -270,6 +341,11 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
if 'adv_interv' in peer_config:
self.cli_set(base_path + ['neighbor', peer, 'advertisement-interval', peer_config["adv_interv"]])
+ if 'bfd' in peer_config:
+ self.cli_set(base_path + ['neighbor', peer, 'bfd'])
+ if 'bfd_profile' in peer_config:
+ self.cli_set(base_path + ['neighbor', peer, 'bfd', 'profile', peer_config["bfd_profile"]])
+ self.cli_set(base_path + ['neighbor', peer, 'bfd', 'check-control-plane-failure'])
if 'cap_dynamic' in peer_config:
self.cli_set(base_path + ['neighbor', peer, 'capability', 'dynamic'])
if 'cap_ext_next' in peer_config:
@@ -318,6 +394,26 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'addpath-tx-all'])
if 'addpath_per_as' in peer_config:
self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'addpath-tx-per-as'])
+ if 'graceful_rst' in peer_config:
+ self.cli_set(base_path + ['neighbor', peer, 'graceful-restart', 'enable'])
+ if 'graceful_rst_no' in peer_config:
+ self.cli_set(base_path + ['neighbor', peer, 'graceful-restart', 'disable'])
+ if 'graceful_rst_hlp' in peer_config:
+ self.cli_set(base_path + ['neighbor', peer, 'graceful-restart', 'restart-helper'])
+
+ # Conditional advertisement
+ if 'advertise_map' in peer_config:
+ self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'conditionally-advertise', 'advertise-map', peer_config["advertise_map"]])
+ # Either exist-map or non-exist-map needs to be specified
+ if 'exist_map' not in peer_config and 'non_exist_map' not in peer_config:
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'conditionally-advertise', 'exist-map', route_map_in])
+
+ if 'exist_map' in peer_config:
+ self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'conditionally-advertise', 'exist-map', peer_config["exist_map"]])
+ if 'non_exist_map' in peer_config:
+ self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'conditionally-advertise', 'non-exist-map', peer_config["non_exist_map"]])
# commit changes
self.cli_commit()
@@ -339,6 +435,11 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
def test_bgp_03_peer_groups(self):
# Test out individual peer-group configuration items
for peer_group, config in peer_group_config.items():
+ if 'bfd' in config:
+ self.cli_set(base_path + ['peer-group', peer_group, 'bfd'])
+ if 'bfd_profile' in config:
+ self.cli_set(base_path + ['peer-group', peer_group, 'bfd', 'profile', config["bfd_profile"]])
+ self.cli_set(base_path + ['peer-group', peer_group, 'bfd', 'check-control-plane-failure'])
if 'cap_dynamic' in config:
self.cli_set(base_path + ['peer-group', peer_group, 'capability', 'dynamic'])
if 'cap_ext_next' in config:
@@ -381,6 +482,31 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'addpath-tx-all'])
if 'addpath_per_as' in config:
self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'addpath-tx-per-as'])
+ if 'graceful_rst' in config:
+ self.cli_set(base_path + ['peer-group', peer_group, 'graceful-restart', 'enable'])
+ if 'graceful_rst_no' in config:
+ self.cli_set(base_path + ['peer-group', peer_group, 'graceful-restart', 'disable'])
+ if 'graceful_rst_hlp' in config:
+ self.cli_set(base_path + ['peer-group', peer_group, 'graceful-restart', 'restart-helper'])
+
+ # Conditional advertisement
+ if 'advertise_map' in config:
+ self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'conditionally-advertise', 'advertise-map', config["advertise_map"]])
+ # Either exist-map or non-exist-map needs to be specified
+ if 'exist_map' not in config and 'non_exist_map' not in config:
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'conditionally-advertise', 'exist-map', route_map_in])
+
+ if 'exist_map' in config:
+ self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'conditionally-advertise', 'exist-map', config["exist_map"]])
+ if 'non_exist_map' in config:
+ self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'conditionally-advertise', 'non-exist-map', config["non_exist_map"]])
+
+ for peer, peer_config in neighbor_config.items():
+ if 'peer_group' in peer_config:
+ self.cli_set(base_path + ['neighbor', peer, 'peer-group', peer_config['peer_group']])
+
# commit changes
self.cli_commit()
@@ -393,6 +519,10 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.assertIn(f' neighbor {peer_group} peer-group', frrconfig)
self.verify_frr_config(peer, peer_config, frrconfig)
+ for peer, peer_config in neighbor_config.items():
+ if 'peer_group' in peer_config:
+ self.assertIn(f' neighbor {peer} peer-group {peer_config["peer_group"]}', frrconfig)
+
def test_bgp_04_afi_ipv4(self):
networks = {
@@ -752,5 +882,44 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.assertIn(f' rt vpn import {rt_import}', afi_config)
self.assertIn(f' exit-address-family', afi_config)
+ def test_bgp_14_remote_as_peer_group_override(self):
+ # Peer-group member cannot override remote-as of peer-group
+ remote_asn = str(int(ASN) + 150)
+ neighbor = '192.0.2.1'
+ peer_group = 'bar'
+ interface = 'eth0'
+
+ self.cli_set(base_path + ['local-as', ASN])
+ self.cli_set(base_path + ['neighbor', neighbor, 'remote-as', remote_asn])
+ self.cli_set(base_path + ['neighbor', neighbor, 'peer-group', peer_group])
+ self.cli_set(base_path + ['peer-group', peer_group, 'remote-as', remote_asn])
+
+ # Peer-group member cannot override remote-as of peer-group
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_delete(base_path + ['neighbor', neighbor, 'remote-as'])
+
+ # re-test with interface based peer-group
+ self.cli_set(base_path + ['neighbor', interface, 'interface', 'peer-group', peer_group])
+ self.cli_set(base_path + ['neighbor', interface, 'interface', 'remote-as', 'external'])
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_delete(base_path + ['neighbor', interface, 'interface', 'remote-as'])
+
+ # re-test with interface based v6only peer-group
+ self.cli_set(base_path + ['neighbor', interface, 'interface', 'v6only', 'peer-group', peer_group])
+ self.cli_set(base_path + ['neighbor', interface, 'interface', 'v6only', 'remote-as', 'external'])
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_delete(base_path + ['neighbor', interface, 'interface', 'v6only', 'remote-as'])
+
+ self.cli_commit()
+
+ frrconfig = self.getFRRconfig(f'router bgp {ASN}')
+ self.assertIn(f'router bgp {ASN}', frrconfig)
+ self.assertIn(f' neighbor {neighbor} peer-group {peer_group}', frrconfig)
+ self.assertIn(f' neighbor {peer_group} peer-group', frrconfig)
+ self.assertIn(f' neighbor {peer_group} remote-as {remote_asn}', frrconfig)
+
if __name__ == '__main__':
- unittest.main(verbosity=2) \ No newline at end of file
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_isis.py b/smoketest/scripts/cli/test_protocols_isis.py
index f4b0a690d..ee4be0b37 100755
--- a/smoketest/scripts/cli/test_protocols_isis.py
+++ b/smoketest/scripts/cli/test_protocols_isis.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -33,7 +33,11 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase):
cls._interfaces = Section.interfaces('ethernet')
# call base-classes classmethod
- super(cls, cls).setUpClass()
+ super(TestProtocolsISIS, cls).setUpClass()
+
+ # ensure we can also run this test on a live system - so lets clean
+ # out the current configuration :)
+ cls.cli_delete(cls, base_path)
def tearDown(self):
self.cli_delete(base_path)
@@ -71,13 +75,13 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify all changes
- tmp = self.getFRRconfig(f'router isis {domain}')
+ tmp = self.getFRRconfig(f'router isis {domain}', daemon='isisd')
self.assertIn(f' net {net}', tmp)
self.assertIn(f' log-adjacency-changes', tmp)
self.assertIn(f' redistribute ipv4 connected level-2 route-map {route_map}', tmp)
for interface in self._interfaces:
- tmp = self.getFRRconfig(f'interface {interface}')
+ tmp = self.getFRRconfig(f'interface {interface}', daemon='isisd')
self.assertIn(f' ip router isis {domain}', tmp)
self.assertIn(f' ipv6 router isis {domain}', tmp)
@@ -104,11 +108,11 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify FRR isisd configuration
- tmp = self.getFRRconfig(f'router isis {domain}')
+ tmp = self.getFRRconfig(f'router isis {domain}', daemon='isisd')
self.assertIn(f'router isis {domain}', tmp)
self.assertIn(f' net {net}', tmp)
- tmp = self.getFRRconfig(f'router isis {domain} vrf {vrf}')
+ tmp = self.getFRRconfig(f'router isis {domain} vrf {vrf}', daemon='isisd')
self.assertIn(f'router isis {domain} vrf {vrf}', tmp)
self.assertIn(f' net {net}', tmp)
@@ -124,22 +128,26 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase):
self.isis_base_config()
self.cli_set(base_path + ['redistribute', 'ipv4', 'connected', 'level-2', 'route-map', route_map])
self.cli_set(base_path + ['route-map', route_map])
+ self.cli_set(base_path + ['level', 'level-2'])
# commit changes
self.cli_commit()
# Verify FRR configuration
zebra_route_map = f'ip protocol isis route-map {route_map}'
- frrconfig = self.getFRRconfig(zebra_route_map)
+ frrconfig = self.getFRRconfig(zebra_route_map, daemon='zebra')
self.assertIn(zebra_route_map, frrconfig)
+ tmp = self.getFRRconfig(f'router isis {domain}', daemon='isisd')
+ self.assertIn(' is-type level-2-only', tmp)
+
# Remove the route-map again
self.cli_delete(base_path + ['route-map'])
# commit changes
self.cli_commit()
# Verify FRR configuration
- frrconfig = self.getFRRconfig(zebra_route_map)
+ frrconfig = self.getFRRconfig(zebra_route_map, daemon='zebra')
self.assertNotIn(zebra_route_map, frrconfig)
self.cli_delete(['policy', 'route-map', route_map])
@@ -159,7 +167,7 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify all changes
- tmp = self.getFRRconfig(f'router isis {domain}')
+ tmp = self.getFRRconfig(f'router isis {domain}', daemon='isisd')
self.assertIn(f' net {net}', tmp)
for afi in ['ipv4', 'ipv6']:
@@ -172,6 +180,8 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase):
password = 'foo'
self.isis_base_config()
+ for interface in self._interfaces:
+ self.cli_set(base_path + ['interface', interface, 'password', 'plaintext-password', f'{password}-{interface}'])
self.cli_set(base_path + ['area-password', 'plaintext-password', password])
self.cli_set(base_path + ['area-password', 'md5', password])
@@ -192,24 +202,28 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify all changes
- tmp = self.getFRRconfig(f'router isis {domain}')
+ tmp = self.getFRRconfig(f'router isis {domain}', daemon='isisd')
self.assertIn(f' net {net}', tmp)
self.assertIn(f' domain-password clear {password}', tmp)
self.assertIn(f' area-password clear {password}', tmp)
+ for interface in self._interfaces:
+ tmp = self.getFRRconfig(f'interface {interface}', daemon='isisd')
+ self.assertIn(f' isis password clear {password}-{interface}', tmp)
- def test_isis_06_spf_delay(self):
- self.isis_base_config()
-
+ def test_isis_06_spf_delay_bfd(self):
network = 'point-to-point'
holddown = '10'
init_delay = '50'
long_delay = '200'
short_delay = '100'
time_to_learn = '75'
+ bfd_profile = 'isis-bfd'
+ self.cli_set(base_path + ['net', net])
for interface in self._interfaces:
self.cli_set(base_path + ['interface', interface, 'network', network])
+ self.cli_set(base_path + ['interface', interface, 'bfd', 'profile', bfd_profile])
self.cli_set(base_path + ['spf-delay-ietf', 'holddown', holddown])
# verify() - All types of spf-delay must be configured
@@ -226,11 +240,6 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase):
with self.assertRaises(ConfigSessionError):
self.cli_commit()
- self.cli_set(base_path + ['spf-delay-ietf', 'long-delay', long_delay])
- # verify() - All types of spf-delay must be configured
- with self.assertRaises(ConfigSessionError):
- self.cli_commit()
-
self.cli_set(base_path + ['spf-delay-ietf', 'short-delay', short_delay])
# verify() - All types of spf-delay must be configured
with self.assertRaises(ConfigSessionError):
@@ -241,15 +250,17 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify all changes
- tmp = self.getFRRconfig(f'router isis {domain}')
+ tmp = self.getFRRconfig(f'router isis {domain}', daemon='isisd')
self.assertIn(f' net {net}', tmp)
self.assertIn(f' spf-delay-ietf init-delay {init_delay} short-delay {short_delay} long-delay {long_delay} holddown {holddown} time-to-learn {time_to_learn}', tmp)
for interface in self._interfaces:
- tmp = self.getFRRconfig(f'interface {interface}')
+ tmp = self.getFRRconfig(f'interface {interface}', daemon='isisd')
self.assertIn(f' ip router isis {domain}', tmp)
self.assertIn(f' ipv6 router isis {domain}', tmp)
self.assertIn(f' isis network {network}', tmp)
+ self.assertIn(f' isis bfd', tmp)
+ self.assertIn(f' isis bfd profile {bfd_profile}', tmp)
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_mpls.py b/smoketest/scripts/cli/test_protocols_mpls.py
new file mode 100755
index 000000000..76e6ca35a
--- /dev/null
+++ b/smoketest/scripts/cli/test_protocols_mpls.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import unittest
+
+from base_vyostest_shim import VyOSUnitTestSHIM
+from vyos.configsession import ConfigSessionError
+from vyos.ifconfig import Section
+from vyos.util import process_named_running
+
+PROCESS_NAME = 'ldpd'
+base_path = ['protocols', 'mpls', 'ldp']
+
+peers = {
+ '192.0.2.10' : {
+ 'intv_rx' : '500',
+ 'intv_tx' : '600',
+ 'multihop' : '',
+ 'source_addr': '192.0.2.254',
+ },
+ '192.0.2.20' : {
+ 'echo_mode' : '',
+ 'intv_echo' : '100',
+ 'intv_mult' : '100',
+ 'intv_rx' : '222',
+ 'intv_tx' : '333',
+ 'passive' : '',
+ 'shutdown' : '',
+ },
+ '2001:db8::a' : {
+ 'source_addr': '2001:db8::1',
+ },
+ '2001:db8::b' : {
+ 'source_addr': '2001:db8::1',
+ 'multihop' : '',
+ },
+}
+
+profiles = {
+ 'foo' : {
+ 'echo_mode' : '',
+ 'intv_echo' : '100',
+ 'intv_mult' : '101',
+ 'intv_rx' : '222',
+ 'intv_tx' : '333',
+ 'shutdown' : '',
+ },
+ 'bar' : {
+ 'intv_mult' : '102',
+ 'intv_rx' : '444',
+ 'passive' : '',
+ },
+}
+
+class TestProtocolsMPLS(VyOSUnitTestSHIM.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ super(TestProtocolsMPLS, cls).setUpClass()
+
+ # ensure we can also run this test on a live system - so lets clean
+ # out the current configuration :)
+ cls.cli_delete(cls, base_path)
+
+ def tearDown(self):
+ self.cli_delete(base_path)
+ self.cli_commit()
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+ def test_mpls_basic(self):
+ router_id = '1.2.3.4'
+ transport_ipv4_addr = '5.6.7.8'
+ interfaces = Section.interfaces('ethernet')
+
+ self.cli_set(base_path + ['router-id', router_id])
+
+ # At least one LDP interface must be configured
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ for interface in interfaces:
+ self.cli_set(base_path + ['interface', interface])
+
+ # LDP transport address missing
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_set(base_path + ['discovery', 'transport-ipv4-address', transport_ipv4_addr])
+
+ # Commit changes
+ self.cli_commit()
+
+ # Validate configuration
+ frrconfig = self.getFRRconfig('mpls ldp', daemon=PROCESS_NAME)
+ self.assertIn(f'mpls ldp', frrconfig)
+ self.assertIn(f' router-id {router_id}', frrconfig)
+
+ # Validate AFI IPv4
+ afiv4_config = self.getFRRconfig(' address-family ipv4', daemon=PROCESS_NAME)
+ self.assertIn(f' discovery transport-address {transport_ipv4_addr}', afiv4_config)
+ for interface in interfaces:
+ self.assertIn(f' interface {interface}', afiv4_config)
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_nhrp.py b/smoketest/scripts/cli/test_protocols_nhrp.py
index aa0ac268d..40b19fec7 100755
--- a/smoketest/scripts/cli/test_protocols_nhrp.py
+++ b/smoketest/scripts/cli/test_protocols_nhrp.py
@@ -18,6 +18,7 @@ import unittest
from base_vyostest_shim import VyOSUnitTestSHIM
+from vyos.firewall import find_nftables_rule
from vyos.util import call, process_named_running, read_file
tunnel_path = ['interfaces', 'tunnel']
@@ -91,6 +92,14 @@ class TestProtocolsNHRP(VyOSUnitTestSHIM.TestCase):
for line in opennhrp_lines:
self.assertIn(line, tmp_opennhrp_conf)
+ firewall_matches = [
+ 'ip protocol gre',
+ 'ip saddr 192.0.2.1',
+ 'ip daddr 224.0.0.0/4',
+ 'comment "VYOS_NHRP_tun100"'
+ ]
+
+ self.assertTrue(find_nftables_rule('ip filter', 'VYOS_FW_OUTPUT', firewall_matches) is not None)
self.assertTrue(process_named_running('opennhrp'))
if __name__ == '__main__':
diff --git a/smoketest/scripts/cli/test_protocols_ospf.py b/smoketest/scripts/cli/test_protocols_ospf.py
index 0529eefbd..e15ea478b 100755
--- a/smoketest/scripts/cli/test_protocols_ospf.py
+++ b/smoketest/scripts/cli/test_protocols_ospf.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -33,14 +33,25 @@ route_map = 'foo-bar-baz10'
log = logging.getLogger('TestProtocolsOSPF')
class TestProtocolsOSPF(VyOSUnitTestSHIM.TestCase):
- def setUp(self):
- self.cli_set(['policy', 'route-map', route_map, 'rule', '10', 'action', 'permit'])
- self.cli_set(['policy', 'route-map', route_map, 'rule', '20', 'action', 'permit'])
+ @classmethod
+ def setUpClass(cls):
+ super(TestProtocolsOSPF, cls).setUpClass()
+
+ cls.cli_set(cls, ['policy', 'route-map', route_map, 'rule', '10', 'action', 'permit'])
+ cls.cli_set(cls, ['policy', 'route-map', route_map, 'rule', '20', 'action', 'permit'])
+
+ # ensure we can also run this test on a live system - so lets clean
+ # out the current configuration :)
+ cls.cli_delete(cls, base_path)
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.cli_delete(cls, ['policy', 'route-map', route_map])
+ super(TestProtocolsOSPF, cls).tearDownClass()
def tearDown(self):
# Check for running process
self.assertTrue(process_named_running(PROCESS_NAME))
- self.cli_delete(['policy', 'route-map', route_map])
self.cli_delete(base_path)
self.cli_commit()
@@ -189,31 +200,7 @@ class TestProtocolsOSPF(VyOSUnitTestSHIM.TestCase):
for neighbor in neighbors:
self.assertIn(f' neighbor {neighbor} priority {priority} poll-interval {poll_interval}', frrconfig) # default
-
- def test_ospf_07_passive_interface(self):
- self.cli_set(base_path + ['passive-interface', 'default'])
- interfaces = Section.interfaces('ethernet')
- for interface in interfaces:
- self.cli_set(base_path + ['passive-interface-exclude', interface])
-
- # commit changes
- self.cli_commit()
-
- # Verify FRR ospfd configuration
- frrconfig = self.getFRRconfig('router ospf')
- try:
- self.assertIn(f'router ospf', frrconfig)
- self.assertIn(f' passive-interface default', frrconfig) # default
- for interface in interfaces:
- self.assertIn(f' no passive-interface {interface}', frrconfig) # default
- except:
- log.debug(frrconfig)
- log.debug(cmd('sudo dmesg'))
- log.debug(cmd('sudo cat /var/log/messages'))
- log.debug(cmd('vtysh -c "show run"'))
- self.fail('Now we can hopefully see why OSPF fails!')
-
- def test_ospf_08_redistribute(self):
+ def test_ospf_07_redistribute(self):
metric = '15'
metric_type = '1'
redistribute = ['bgp', 'connected', 'isis', 'kernel', 'rip', 'static']
@@ -223,9 +210,15 @@ class TestProtocolsOSPF(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + ['redistribute', protocol, 'route-map', route_map])
self.cli_set(base_path + ['redistribute', protocol, 'metric-type', metric_type])
+ # enable FRR debugging to find the root cause of failing testcases
+ cmd('touch /tmp/vyos.frr.debug')
+
# commit changes
self.cli_commit()
+ # disable FRR debugging
+ cmd('rm -f /tmp/vyos.frr.debug')
+
# Verify FRR ospfd configuration
frrconfig = self.getFRRconfig('router ospf')
try:
@@ -234,11 +227,10 @@ class TestProtocolsOSPF(VyOSUnitTestSHIM.TestCase):
self.assertIn(f' redistribute {protocol} metric {metric} metric-type {metric_type} route-map {route_map}', frrconfig)
except:
log.debug(frrconfig)
- log.debug(cmd('sudo cat /var/log/messages'))
- log.debug(cmd('vtysh -c "show run"'))
+ log.debug(cmd('sudo cat /tmp/vyos-configd-script-stdout'))
self.fail('Now we can hopefully see why OSPF fails!')
- def test_ospf_09_virtual_link(self):
+ def test_ospf_08_virtual_link(self):
networks = ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16']
area = '10'
shortcut = 'enable'
@@ -268,22 +260,26 @@ class TestProtocolsOSPF(VyOSUnitTestSHIM.TestCase):
self.assertIn(f' network {network} area {area}', frrconfig)
- def test_ospf_10_interface_configuration(self):
+ def test_ospf_09_interface_configuration(self):
interfaces = Section.interfaces('ethernet')
password = 'vyos1234'
bandwidth = '10000'
cost = '150'
network = 'point-to-point'
priority = '200'
+ bfd_profile = 'vyos-test'
+ self.cli_set(base_path + ['passive-interface', 'default'])
for interface in interfaces:
- self.cli_set(base_path + ['interface', interface, 'authentication', 'plaintext-password', password])
- self.cli_set(base_path + ['interface', interface, 'bandwidth', bandwidth])
- self.cli_set(base_path + ['interface', interface, 'bfd'])
- self.cli_set(base_path + ['interface', interface, 'cost', cost])
- self.cli_set(base_path + ['interface', interface, 'mtu-ignore'])
- self.cli_set(base_path + ['interface', interface, 'network', network])
- self.cli_set(base_path + ['interface', interface, 'priority', priority])
+ base_interface = base_path + ['interface', interface]
+ self.cli_set(base_interface + ['authentication', 'plaintext-password', password])
+ self.cli_set(base_interface + ['bandwidth', bandwidth])
+ self.cli_set(base_interface + ['bfd', 'profile', bfd_profile])
+ self.cli_set(base_interface + ['cost', cost])
+ self.cli_set(base_interface + ['mtu-ignore'])
+ self.cli_set(base_interface + ['network', network])
+ self.cli_set(base_interface + ['priority', priority])
+ self.cli_set(base_interface + ['passive', 'disable'])
# commit changes
self.cli_commit()
@@ -293,45 +289,15 @@ class TestProtocolsOSPF(VyOSUnitTestSHIM.TestCase):
self.assertIn(f'interface {interface}', config)
self.assertIn(f' ip ospf authentication-key {password}', config)
self.assertIn(f' ip ospf bfd', config)
+ self.assertIn(f' ip ospf bfd profile {bfd_profile}', config)
self.assertIn(f' ip ospf cost {cost}', config)
self.assertIn(f' ip ospf mtu-ignore', config)
self.assertIn(f' ip ospf network {network}', config)
self.assertIn(f' ip ospf priority {priority}', config)
+ self.assertIn(f' no ip ospf passive', config)
self.assertIn(f' bandwidth {bandwidth}', config)
-
- def test_ospf_11_vrfs(self):
- # It is safe to assume that when the basic VRF test works, all
- # other OSPF related features work, as we entirely inherit the CLI
- # templates and Jinja2 FRR template.
- table = '1000'
- vrf = 'blue'
- vrf_base = ['vrf', 'name', vrf]
- vrf_iface = 'eth1'
- self.cli_set(vrf_base + ['table', table])
- self.cli_set(vrf_base + ['protocols', 'ospf', 'interface', vrf_iface])
- self.cli_set(['interfaces', 'ethernet', vrf_iface, 'vrf', vrf])
-
- # Also set a default VRF OSPF config
- self.cli_set(base_path)
- self.cli_commit()
-
- # Verify FRR ospfd configuration
- frrconfig = self.getFRRconfig('router ospf')
- self.assertIn(f'router ospf', frrconfig)
- self.assertIn(f' auto-cost reference-bandwidth 100', frrconfig)
- self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults
-
- frrconfig = self.getFRRconfig(f'router ospf vrf {vrf}')
- self.assertIn(f'router ospf vrf {vrf}', frrconfig)
- self.assertIn(f' auto-cost reference-bandwidth 100', frrconfig)
- self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults
-
- self.cli_delete(['vrf', 'name', vrf])
- self.cli_delete(['interfaces', 'ethernet', vrf_iface, 'vrf'])
-
-
- def test_ospf_12_zebra_route_map(self):
+ def test_ospf_10_zebra_route_map(self):
# Implemented because of T3328
self.cli_set(base_path + ['route-map', route_map])
# commit changes
@@ -351,7 +317,7 @@ class TestProtocolsOSPF(VyOSUnitTestSHIM.TestCase):
frrconfig = self.getFRRconfig(zebra_route_map)
self.assertNotIn(zebra_route_map, frrconfig)
- def test_ospf_13_interface_area(self):
+ def test_ospf_11_interface_area(self):
area = '0'
interfaces = Section.interfaces('ethernet')
@@ -375,6 +341,61 @@ class TestProtocolsOSPF(VyOSUnitTestSHIM.TestCase):
self.assertIn(f'interface {interface}', config)
self.assertIn(f' ip ospf area {area}', config)
+ def test_ospf_12_vrfs(self):
+ # It is safe to assume that when the basic VRF test works, all
+ # other OSPF related features work, as we entirely inherit the CLI
+ # templates and Jinja2 FRR template.
+ table = '1000'
+ vrf = 'blue'
+ vrf_base = ['vrf', 'name', vrf]
+ vrf_iface = 'eth1'
+ self.cli_set(vrf_base + ['table', table])
+ self.cli_set(vrf_base + ['protocols', 'ospf', 'interface', vrf_iface])
+ self.cli_set(['interfaces', 'ethernet', vrf_iface, 'vrf', vrf])
+
+ # Also set a default VRF OSPF config
+ self.cli_set(base_path)
+ self.cli_commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = self.getFRRconfig('router ospf')
+ self.assertIn(f'router ospf', frrconfig)
+ self.assertIn(f' auto-cost reference-bandwidth 100', frrconfig)
+ self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults
+
+ frrconfig = self.getFRRconfig(f'router ospf vrf {vrf}')
+ self.assertIn(f'router ospf vrf {vrf}', frrconfig)
+ self.assertIn(f' auto-cost reference-bandwidth 100', frrconfig)
+ self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults
+
+ # cleanup
+ self.cli_delete(['vrf', 'name', vrf])
+ self.cli_delete(['interfaces', 'ethernet', vrf_iface, 'vrf'])
+
+ def test_ospf_13_export_list(self):
+ # Verify explort-list works on ospf-area
+ acl = '100'
+ seq = '10'
+ area = '0.0.0.10'
+ network = '10.0.0.0/8'
+
+
+ self.cli_set(['policy', 'access-list', acl, 'rule', seq, 'action', 'permit'])
+ self.cli_set(['policy', 'access-list', acl, 'rule', seq, 'source', 'any'])
+ self.cli_set(['policy', 'access-list', acl, 'rule', seq, 'destination', 'any'])
+ self.cli_set(base_path + ['area', area, 'network', network])
+ self.cli_set(base_path + ['area', area, 'export-list', acl])
+
+ # commit changes
+ self.cli_commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = self.getFRRconfig('router ospf')
+ self.assertIn(f'router ospf', frrconfig)
+ self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # default
+ self.assertIn(f' network {network} area {area}', frrconfig)
+ self.assertIn(f' area {area} export-list {acl}', frrconfig)
+
if __name__ == '__main__':
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_ospfv3.py b/smoketest/scripts/cli/test_protocols_ospfv3.py
index c0673629e..fa80ad555 100755
--- a/smoketest/scripts/cli/test_protocols_ospfv3.py
+++ b/smoketest/scripts/cli/test_protocols_ospfv3.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -18,16 +18,35 @@ import unittest
from base_vyostest_shim import VyOSUnitTestSHIM
+from vyos.configsession import ConfigSessionError
from vyos.ifconfig import Section
from vyos.util import process_named_running
PROCESS_NAME = 'ospf6d'
base_path = ['protocols', 'ospfv3']
+route_map = 'foo-bar-baz-0815'
+
router_id = '192.0.2.1'
default_area = '0'
class TestProtocolsOSPFv3(VyOSUnitTestSHIM.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ super(TestProtocolsOSPFv3, cls).setUpClass()
+
+ cls.cli_set(cls, ['policy', 'route-map', route_map, 'rule', '10', 'action', 'permit'])
+ cls.cli_set(cls, ['policy', 'route-map', route_map, 'rule', '20', 'action', 'permit'])
+
+ # ensure we can also run this test on a live system - so lets clean
+ # out the current configuration :)
+ cls.cli_delete(cls, base_path)
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.cli_delete(cls, ['policy', 'route-map', route_map])
+ super(TestProtocolsOSPFv3, cls).tearDownClass()
+
def tearDown(self):
# Check for running process
self.assertTrue(process_named_running(PROCESS_NAME))
@@ -49,13 +68,13 @@ class TestProtocolsOSPFv3(VyOSUnitTestSHIM.TestCase):
interfaces = Section.interfaces('ethernet')
for interface in interfaces:
- self.cli_set(base_path + ['area', default_area, 'interface', interface])
+ self.cli_set(base_path + ['interface', interface, 'area', default_area])
# commit changes
self.cli_commit()
# Verify FRR ospfd configuration
- frrconfig = self.getFRRconfig('router ospf6')
+ frrconfig = self.getFRRconfig('router ospf6', daemon='ospf6d')
self.assertIn(f'router ospf6', frrconfig)
self.assertIn(f' area {default_area} range {prefix}', frrconfig)
self.assertIn(f' ospf6 router-id {router_id}', frrconfig)
@@ -63,7 +82,8 @@ class TestProtocolsOSPFv3(VyOSUnitTestSHIM.TestCase):
self.assertIn(f' area {default_area} export-list {acl_name}', frrconfig)
for interface in interfaces:
- self.assertIn(f' interface {interface} area {default_area}', frrconfig)
+ if_config = self.getFRRconfig(f'interface {interface}', daemon='ospf6d')
+ self.assertIn(f'ipv6 ospf6 area {default_area}', if_config)
self.cli_delete(['policy', 'access-list6', acl_name])
@@ -83,7 +103,7 @@ class TestProtocolsOSPFv3(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify FRR ospfd configuration
- frrconfig = self.getFRRconfig('router ospf6')
+ frrconfig = self.getFRRconfig('router ospf6', daemon='ospf6d')
self.assertIn(f'router ospf6', frrconfig)
self.assertIn(f' distance {dist_global}', frrconfig)
self.assertIn(f' distance ospf6 intra-area {dist_intra_area} inter-area {dist_inter_area} external {dist_external}', frrconfig)
@@ -103,12 +123,14 @@ class TestProtocolsOSPFv3(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify FRR ospfd configuration
- frrconfig = self.getFRRconfig('router ospf6')
+ frrconfig = self.getFRRconfig('router ospf6', daemon='ospf6d')
self.assertIn(f'router ospf6', frrconfig)
for protocol in redistribute:
self.assertIn(f' redistribute {protocol} route-map {route_map}', frrconfig)
+
def test_ospfv3_04_interfaces(self):
+ bfd_profile = 'vyos-ipv6'
self.cli_set(base_path + ['parameters', 'router-id', router_id])
self.cli_set(base_path + ['area', default_area])
@@ -118,7 +140,7 @@ class TestProtocolsOSPFv3(VyOSUnitTestSHIM.TestCase):
interfaces = Section.interfaces('ethernet')
for interface in interfaces:
if_base = base_path + ['interface', interface]
- self.cli_set(if_base + ['bfd'])
+ self.cli_set(if_base + ['bfd', 'profile', bfd_profile])
self.cli_set(if_base + ['cost', cost])
self.cli_set(if_base + ['instance-id', '0'])
self.cli_set(if_base + ['mtu-ignore'])
@@ -132,15 +154,16 @@ class TestProtocolsOSPFv3(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify FRR ospfd configuration
- frrconfig = self.getFRRconfig('router ospf6')
+ frrconfig = self.getFRRconfig('router ospf6', daemon='ospf6d')
self.assertIn(f'router ospf6', frrconfig)
cost = '100'
priority = '10'
for interface in interfaces:
- if_config = self.getFRRconfig(f'interface {interface}')
+ if_config = self.getFRRconfig(f'interface {interface}', daemon='ospf6d')
self.assertIn(f'interface {interface}', if_config)
self.assertIn(f' ipv6 ospf6 bfd', if_config)
+ self.assertIn(f' ipv6 ospf6 bfd profile {bfd_profile}', if_config)
self.assertIn(f' ipv6 ospf6 cost {cost}', if_config)
self.assertIn(f' ipv6 ospf6 mtu-ignore', if_config)
self.assertIn(f' ipv6 ospf6 network point-to-point', if_config)
@@ -161,10 +184,102 @@ class TestProtocolsOSPFv3(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify FRR ospfd configuration
- frrconfig = self.getFRRconfig('router ospf6')
+ frrconfig = self.getFRRconfig('router ospf6', daemon='ospf6d')
self.assertIn(f'router ospf6', frrconfig)
self.assertIn(f' area {area_stub} stub', frrconfig)
self.assertIn(f' area {area_stub_nosum} stub no-summary', frrconfig)
+
+ def test_ospfv3_06_area_nssa(self):
+ area_nssa = '1.1.1.1'
+ area_nssa_nosum = '2.2.2.2'
+ area_nssa_default = '3.3.3.3'
+
+ self.cli_set(base_path + ['area', area_nssa, 'area-type', 'nssa'])
+ self.cli_set(base_path + ['area', area_nssa, 'area-type', 'stub'])
+ # can only set one area-type per OSPFv3 area
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_delete(base_path + ['area', area_nssa, 'area-type', 'stub'])
+
+ self.cli_set(base_path + ['area', area_nssa_nosum, 'area-type', 'nssa', 'no-summary'])
+ self.cli_set(base_path + ['area', area_nssa_nosum, 'area-type', 'nssa', 'default-information-originate'])
+ self.cli_set(base_path + ['area', area_nssa_default, 'area-type', 'nssa', 'default-information-originate'])
+
+ # commit changes
+ self.cli_commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = self.getFRRconfig('router ospf6', daemon='ospf6d')
+ self.assertIn(f'router ospf6', frrconfig)
+ self.assertIn(f' area {area_nssa} nssa', frrconfig)
+ self.assertIn(f' area {area_nssa_nosum} nssa default-information-originate no-summary', frrconfig)
+ self.assertIn(f' area {area_nssa_default} nssa default-information-originate', frrconfig)
+
+
+ def test_ospfv3_07_default_originate(self):
+ seq = '100'
+ metric = '50'
+ metric_type = '1'
+
+ self.cli_set(base_path + ['default-information', 'originate', 'metric', metric])
+ self.cli_set(base_path + ['default-information', 'originate', 'metric-type', metric_type])
+ self.cli_set(base_path + ['default-information', 'originate', 'route-map', route_map])
+
+ # commit changes
+ self.cli_commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = self.getFRRconfig('router ospf6', daemon='ospf6d')
+ self.assertIn(f'router ospf6', frrconfig)
+ self.assertIn(f' default-information originate metric {metric} metric-type {metric_type} route-map {route_map}', frrconfig)
+
+ # Now set 'always'
+ self.cli_set(base_path + ['default-information', 'originate', 'always'])
+ self.cli_commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = self.getFRRconfig('router ospf6', daemon='ospf6d')
+ self.assertIn(f' default-information originate always metric {metric} metric-type {metric_type} route-map {route_map}', frrconfig)
+
+
+ def test_ospfv3_08_vrfs(self):
+ # It is safe to assume that when the basic VRF test works, all
+ # other OSPF related features work, as we entirely inherit the CLI
+ # templates and Jinja2 FRR template.
+ table = '1000'
+ vrf = 'blue'
+ vrf_base = ['vrf', 'name', vrf]
+ vrf_iface = 'eth1'
+ router_id = '1.2.3.4'
+ router_id_vrf = '1.2.3.5'
+
+ self.cli_set(vrf_base + ['table', table])
+ self.cli_set(vrf_base + ['protocols', 'ospfv3', 'interface', vrf_iface, 'bfd'])
+ self.cli_set(vrf_base + ['protocols', 'ospfv3', 'parameters', 'router-id', router_id_vrf])
+
+ self.cli_set(['interfaces', 'ethernet', vrf_iface, 'vrf', vrf])
+
+ # Also set a default VRF OSPF config
+ self.cli_set(base_path + ['parameters', 'router-id', router_id])
+ self.cli_commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = self.getFRRconfig('router ospf6', daemon='ospf6d')
+ self.assertIn(f'router ospf6', frrconfig)
+ self.assertIn(f' ospf6 router-id {router_id}', frrconfig)
+
+ frrconfig = self.getFRRconfig(f'interface {vrf_iface}', daemon='ospf6d')
+ self.assertIn(f'interface {vrf_iface}', frrconfig)
+ self.assertIn(f' ipv6 ospf6 bfd', frrconfig)
+
+ frrconfig = self.getFRRconfig(f'router ospf6 vrf {vrf}', daemon='ospf6d')
+ self.assertIn(f'router ospf6 vrf {vrf}', frrconfig)
+ self.assertIn(f' ospf6 router-id {router_id_vrf}', frrconfig)
+
+ # cleanup
+ self.cli_delete(['vrf', 'name', vrf])
+ self.cli_delete(['interfaces', 'ethernet', vrf_iface, 'vrf'])
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_ripng.py b/smoketest/scripts/cli/test_protocols_ripng.py
index 40585e778..53336a533 100755
--- a/smoketest/scripts/cli/test_protocols_ripng.py
+++ b/smoketest/scripts/cli/test_protocols_ripng.py
@@ -54,7 +54,7 @@ class TestProtocolsRIPng(VyOSUnitTestSHIM.TestCase):
# Check for running process
self.assertTrue(process_named_running(PROCESS_NAME))
- def test_ripng(self):
+ def test_ripng_01_parameters(self):
metric = '8'
interfaces = Section.interfaces('ethernet')
aggregates = ['2001:db8:1000::/48', '2001:db8:2000::/48', '2001:db8:3000::/48']
@@ -121,5 +121,25 @@ class TestProtocolsRIPng(VyOSUnitTestSHIM.TestCase):
proto = 'ospf6'
self.assertIn(f' redistribute {proto} metric {metric} route-map {route_map}', frrconfig)
+ def test_ripng_02_zebra_route_map(self):
+ # Implemented because of T3328
+ self.cli_set(base_path + ['route-map', route_map])
+ # commit changes
+ self.cli_commit()
+
+ # Verify FRR configuration
+ zebra_route_map = f'ipv6 protocol ripng route-map {route_map}'
+ frrconfig = self.getFRRconfig(zebra_route_map)
+ self.assertIn(zebra_route_map, frrconfig)
+
+ # Remove the route-map again
+ self.cli_delete(base_path + ['route-map'])
+ # commit changes
+ self.cli_commit()
+
+ # Verify FRR configuration
+ frrconfig = self.getFRRconfig(zebra_route_map)
+ self.assertNotIn(zebra_route_map, frrconfig)
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_rpki.py b/smoketest/scripts/cli/test_protocols_rpki.py
index d9792ce8d..e5e45565b 100755
--- a/smoketest/scripts/cli/test_protocols_rpki.py
+++ b/smoketest/scripts/cli/test_protocols_rpki.py
@@ -36,8 +36,6 @@ class TestProtocolsRPKI(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Nothing RPKI specific should be left over in the config
- #
- # Disabled until T3266 is resolved
# frrconfig = self.getFRRconfig('rpki')
# self.assertNotIn('rpki', frrconfig)
diff --git a/smoketest/scripts/cli/test_protocols_static.py b/smoketest/scripts/cli/test_protocols_static.py
index 4c4eb5a7c..19efe7786 100755
--- a/smoketest/scripts/cli/test_protocols_static.py
+++ b/smoketest/scripts/cli/test_protocols_static.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -52,9 +52,16 @@ routes = {
},
'blackhole' : { 'distance' : '90' },
},
- '100.64.0.0/10' : {
+ '100.64.0.0/16' : {
'blackhole' : { },
},
+ '100.65.0.0/16' : {
+ 'reject' : { 'distance' : '10', 'tag' : '200' },
+ },
+ '100.66.0.0/16' : {
+ 'blackhole' : { },
+ 'reject' : { 'distance' : '10', 'tag' : '200' },
+ },
'2001:db8:100::/40' : {
'next_hop' : {
'2001:db8::1' : { 'distance' : '10' },
@@ -74,6 +81,9 @@ routes = {
},
'blackhole' : { 'distance' : '250', 'tag' : '500' },
},
+ '2001:db8:300::/40' : {
+ 'reject' : { 'distance' : '250', 'tag' : '500' },
+ },
'2001:db8::/32' : {
'blackhole' : { 'distance' : '200', 'tag' : '600' },
},
@@ -82,9 +92,15 @@ routes = {
tables = ['80', '81', '82']
class TestProtocolsStatic(VyOSUnitTestSHIM.TestCase):
- def setUp(self):
- # This is our "target" VRF when leaking routes:
- self.cli_set(['vrf', 'name', 'black', 'table', '43210'])
+ @classmethod
+ def setUpClass(cls):
+ super(TestProtocolsStatic, cls).setUpClass()
+ cls.cli_set(cls, ['vrf', 'name', 'black', 'table', '43210'])
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.cli_delete(cls, ['vrf'])
+ super(TestProtocolsStatic, cls).tearDownClass()
def tearDown(self):
for route, route_config in routes.items():
@@ -135,6 +151,20 @@ class TestProtocolsStatic(VyOSUnitTestSHIM.TestCase):
if 'tag' in route_config['blackhole']:
self.cli_set(base + ['blackhole', 'tag', route_config['blackhole']['tag']])
+ if 'reject' in route_config:
+ self.cli_set(base + ['reject'])
+ if 'distance' in route_config['reject']:
+ self.cli_set(base + ['reject', 'distance', route_config['reject']['distance']])
+ if 'tag' in route_config['reject']:
+ self.cli_set(base + ['reject', 'tag', route_config['reject']['tag']])
+
+ if {'blackhole', 'reject'} <= set(route_config):
+ # Can not use blackhole and reject at the same time
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_delete(base + ['blackhole'])
+ self.cli_delete(base + ['reject'])
+
# commit changes
self.cli_commit()
@@ -177,6 +207,11 @@ class TestProtocolsStatic(VyOSUnitTestSHIM.TestCase):
else:
self.assertIn(tmp, frrconfig)
+ if {'blackhole', 'reject'} <= set(route_config):
+ # Can not use blackhole and reject at the same time
+ # Config error validated above - skip this route
+ continue
+
if 'blackhole' in route_config:
tmp = f'{ip_ipv6} route {route} blackhole'
if 'tag' in route_config['blackhole']:
@@ -186,6 +221,15 @@ class TestProtocolsStatic(VyOSUnitTestSHIM.TestCase):
self.assertIn(tmp, frrconfig)
+ if 'reject' in route_config:
+ tmp = f'{ip_ipv6} route {route} reject'
+ if 'tag' in route_config['reject']:
+ tmp += ' tag ' + route_config['reject']['tag']
+ if 'distance' in route_config['reject']:
+ tmp += ' ' + route_config['reject']['distance']
+
+ self.assertIn(tmp, frrconfig)
+
def test_02_static_table(self):
for table in tables:
for route, route_config in routes.items():
@@ -389,11 +433,8 @@ class TestProtocolsStatic(VyOSUnitTestSHIM.TestCase):
self.assertIn(tmp, frrconfig)
- self.cli_delete(['vrf'])
-
def test_04_static_zebra_route_map(self):
# Implemented because of T3328
- self.debug = True
route_map = 'foo-static-in'
self.cli_set(['policy', 'route-map', route_map, 'rule', '10', 'action', 'permit'])
diff --git a/smoketest/scripts/cli/test_protocols_static_arp.py b/smoketest/scripts/cli/test_protocols_static_arp.py
new file mode 100755
index 000000000..b61d8f854
--- /dev/null
+++ b/smoketest/scripts/cli/test_protocols_static_arp.py
@@ -0,0 +1,88 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import json
+import unittest
+
+from base_vyostest_shim import VyOSUnitTestSHIM
+
+from vyos.util import cmd
+
+base_path = ['protocols', 'static', 'arp']
+interface = 'eth0'
+address = '192.0.2.1/24'
+
+class TestARP(VyOSUnitTestSHIM.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ super(TestARP, cls).setUpClass()
+
+ # ensure we can also run this test on a live system - so lets clean
+ # out the current configuration :)
+ cls.cli_delete(cls, base_path)
+
+ # we need a L2 interface with a L3 address to properly configure ARP entries
+ cls.cli_set(cls, ['interfaces', 'ethernet', interface, 'address', address])
+
+ @classmethod
+ def tearDownClass(cls):
+ # cleanuop L2 interface
+ cls.cli_delete(cls, ['interfaces', 'ethernet', interface, 'address', address])
+ cls.cli_commit(cls)
+
+ super(TestARP, cls).tearDownClass()
+
+ def tearDown(self):
+ # delete test config
+ self.cli_delete(base_path)
+ self.cli_commit()
+
+ def test_static_arp(self):
+ test_data = {
+ '192.0.2.10' : { 'mac' : '00:01:02:03:04:0a' },
+ '192.0.2.11' : { 'mac' : '00:01:02:03:04:0b' },
+ '192.0.2.12' : { 'mac' : '00:01:02:03:04:0c' },
+ '192.0.2.13' : { 'mac' : '00:01:02:03:04:0d' },
+ '192.0.2.14' : { 'mac' : '00:01:02:03:04:0e' },
+ '192.0.2.15' : { 'mac' : '00:01:02:03:04:0f' },
+ }
+
+ for host, host_config in test_data.items():
+ self.cli_set(base_path + ['interface', interface, 'address', host, 'mac', host_config['mac']])
+
+ self.cli_commit()
+
+ arp_table = json.loads(cmd('ip -j -4 neigh show'))
+ for host, host_config in test_data.items():
+ # As we search within a list of hosts we need to mark if it was
+ # found or not. This ensures all hosts from test_data are processed
+ found = False
+ for entry in arp_table:
+ # Other ARP entry - not related to this testcase
+ if entry['dst'] not in list(test_data):
+ continue
+
+ if entry['dst'] == host:
+ self.assertEqual(entry['lladdr'], host_config['mac'])
+ self.assertEqual(entry['dev'], interface)
+ found = True
+
+ if found == False:
+ print(entry)
+ self.assertTrue(found)
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_service_dhcp-server.py b/smoketest/scripts/cli/test_service_dhcp-server.py
index 14666db15..9c9d6d9f1 100755
--- a/smoketest/scripts/cli/test_service_dhcp-server.py
+++ b/smoketest/scripts/cli/test_service_dhcp-server.py
@@ -38,7 +38,7 @@ domain_name = 'vyos.net'
class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase):
@classmethod
def setUpClass(cls):
- super(cls, cls).setUpClass()
+ super(TestServiceDHCPServer, cls).setUpClass()
cidr_mask = subnet.split('/')[-1]
cls.cli_set(cls, ['interfaces', 'dummy', 'dum8765', 'address', f'{router}/{cidr_mask}'])
@@ -46,7 +46,7 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase):
@classmethod
def tearDownClass(cls):
cls.cli_delete(cls, ['interfaces', 'dummy', 'dum8765'])
- super(cls, cls).tearDownClass()
+ super(TestServiceDHCPServer, cls).tearDownClass()
def tearDown(self):
self.cli_delete(base_path)
@@ -461,12 +461,11 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase):
self.assertIn(f'mclt 1800;', config)
self.assertIn(f'mclt 1800;', config)
self.assertIn(f'split 128;', config)
- self.assertIn(f'port 520;', config)
- self.assertIn(f'peer port 520;', config)
+ self.assertIn(f'port 647;', config)
+ self.assertIn(f'peer port 647;', config)
self.assertIn(f'max-response-delay 30;', config)
self.assertIn(f'max-unacked-updates 10;', config)
self.assertIn(f'load balance max seconds 3;', config)
- self.assertIn(f'peer port 520;', config)
self.assertIn(f'address {failover_local};', config)
self.assertIn(f'peer address {failover_remote};', config)
diff --git a/smoketest/scripts/cli/test_service_dhcpv6-server.py b/smoketest/scripts/cli/test_service_dhcpv6-server.py
index 7177f1505..f83453323 100755
--- a/smoketest/scripts/cli/test_service_dhcpv6-server.py
+++ b/smoketest/scripts/cli/test_service_dhcpv6-server.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright (C) 2020-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -32,16 +32,24 @@ dns_1 = '2001:db8::1'
dns_2 = '2001:db8::2'
domain = 'vyos.net'
nis_servers = ['2001:db8:ffff::1', '2001:db8:ffff::2']
-interface = 'eth1'
+interface = 'eth0'
interface_addr = inc_ip(subnet, 1) + '/64'
-class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase):
- def setUp(self):
- self.cli_set(['interfaces', 'ethernet', interface, 'address', interface_addr])
+class TestServiceDHCPv6Server(VyOSUnitTestSHIM.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ super(TestServiceDHCPv6Server, cls).setUpClass()
+ cls.cli_set(cls, ['interfaces', 'ethernet', interface, 'address', interface_addr])
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.cli_delete(cls, ['interfaces', 'ethernet', interface, 'address', interface_addr])
+ cls.cli_commit(cls)
+
+ super(TestServiceDHCPv6Server, cls).tearDownClass()
def tearDown(self):
self.cli_delete(base_path)
- self.cli_delete(['interfaces', 'ethernet', interface, 'address', interface_addr])
self.cli_commit()
def test_single_pool(self):
diff --git a/smoketest/scripts/cli/test_service_https.py b/smoketest/scripts/cli/test_service_https.py
index 8e69efd9c..71fb3e177 100755
--- a/smoketest/scripts/cli/test_service_https.py
+++ b/smoketest/scripts/cli/test_service_https.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2020 VyOS maintainers and contributors
+# Copyright (C) 2019-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -16,14 +16,37 @@
import unittest
+from requests import request
+from urllib3.exceptions import InsecureRequestWarning
+
from base_vyostest_shim import VyOSUnitTestSHIM
+from base_vyostest_shim import ignore_warning
+from vyos.util import read_file
from vyos.util import run
base_path = ['service', 'https']
-
pki_base = ['pki']
-cert_data = 'MIICFDCCAbugAwIBAgIUfMbIsB/ozMXijYgUYG80T1ry+mcwCgYIKoZIzj0EAwIwWTELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzESMBAGA1UEAwwJVnlPUyBUZXN0MB4XDTIxMDcyMDEyNDUxMloXDTI2MDcxOTEyNDUxMlowWTELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzESMBAGA1UEAwwJVnlPUyBUZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE01HrLcNttqq4/PtoMua8rMWEkOdBu7vP94xzDO7A8C92ls1v86eePy4QllKCzIw3QxBIoCuH2peGRfWgPRdFsKNhMF8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMB0GA1UdDgQWBBSu+JnU5ZC4mkuEpqg2+Mk4K79oeDAKBggqhkjOPQQDAgNHADBEAiBEFdzQ/Bc3LftzngrY605UhA6UprHhAogKgROv7iR4QgIgEFUxTtW3xXJcnUPWhhUFhyZoqfn8dE93+dm/LDnp7C0='
-key_data = 'MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgPLpD0Ohhoq0g4nhx2KMIuze7ucKUt/lBEB2wc03IxXyhRANCAATTUestw222qrj8+2gy5rysxYSQ50G7u8/3jHMM7sDwL3aWzW/zp54/LhCWUoLMjDdDEEigK4fal4ZF9aA9F0Ww'
+
+cert_data = """
+MIICFDCCAbugAwIBAgIUfMbIsB/ozMXijYgUYG80T1ry+mcwCgYIKoZIzj0EAwIw
+WTELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNv
+bWUtQ2l0eTENMAsGA1UECgwEVnlPUzESMBAGA1UEAwwJVnlPUyBUZXN0MB4XDTIx
+MDcyMDEyNDUxMloXDTI2MDcxOTEyNDUxMlowWTELMAkGA1UEBhMCR0IxEzARBgNV
+BAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlP
+UzESMBAGA1UEAwwJVnlPUyBUZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
+01HrLcNttqq4/PtoMua8rMWEkOdBu7vP94xzDO7A8C92ls1v86eePy4QllKCzIw3
+QxBIoCuH2peGRfWgPRdFsKNhMF8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
+BAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMB0GA1UdDgQWBBSu
++JnU5ZC4mkuEpqg2+Mk4K79oeDAKBggqhkjOPQQDAgNHADBEAiBEFdzQ/Bc3Lftz
+ngrY605UhA6UprHhAogKgROv7iR4QgIgEFUxTtW3xXJcnUPWhhUFhyZoqfn8dE93
++dm/LDnp7C0=
+"""
+
+key_data = """
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgPLpD0Ohhoq0g4nhx
+2KMIuze7ucKUt/lBEB2wc03IxXyhRANCAATTUestw222qrj8+2gy5rysxYSQ50G7
+u8/3jHMM7sDwL3aWzW/zp54/LhCWUoLMjDdDEEigK4fal4ZF9aA9F0Ww
+"""
class TestHTTPSService(VyOSUnitTestSHIM.TestCase):
def setUp(self):
@@ -61,9 +84,13 @@ class TestHTTPSService(VyOSUnitTestSHIM.TestCase):
ret = run('sudo /usr/sbin/nginx -t')
self.assertEqual(ret, 0)
+ nginx_config = read_file('/etc/nginx/sites-enabled/default')
+ self.assertIn(f'listen {address}:{port} ssl;', nginx_config)
+ self.assertIn(f'ssl_protocols TLSv1.2 TLSv1.3;', nginx_config)
+
def test_certificate(self):
- self.cli_set(pki_base + ['certificate', 'test_https', 'certificate', cert_data])
- self.cli_set(pki_base + ['certificate', 'test_https', 'private', 'key', key_data])
+ self.cli_set(pki_base + ['certificate', 'test_https', 'certificate', cert_data.replace('\n','')])
+ self.cli_set(pki_base + ['certificate', 'test_https', 'private', 'key', key_data.replace('\n','')])
self.cli_set(base_path + ['certificates', 'certificate', 'test_https'])
@@ -72,5 +99,44 @@ class TestHTTPSService(VyOSUnitTestSHIM.TestCase):
ret = run('sudo /usr/sbin/nginx -t')
self.assertEqual(ret, 0)
+ @ignore_warning(InsecureRequestWarning)
+ def test_api_auth(self):
+ vhost_id = 'example'
+ address = '127.0.0.1'
+ port = '443'
+ name = 'localhost'
+
+ self.cli_set(base_path + ['api', 'socket'])
+ key = 'MySuperSecretVyOS'
+ self.cli_set(base_path + ['api', 'keys', 'id', 'key-01', 'key', key])
+
+ test_path = base_path + ['virtual-host', vhost_id]
+ self.cli_set(test_path + ['listen-address', address])
+ self.cli_set(test_path + ['listen-port', port])
+ self.cli_set(test_path + ['server-name', name])
+
+ self.cli_commit()
+
+ nginx_config = read_file('/etc/nginx/sites-enabled/default')
+ self.assertIn(f'listen {address}:{port} ssl;', nginx_config)
+ self.assertIn(f'ssl_protocols TLSv1.2 TLSv1.3;', nginx_config)
+
+ url = f'https://{address}/retrieve'
+ payload = {'data': '{"op": "showConfig", "path": []}', 'key': f'{key}'}
+ headers = {}
+ r = request('POST', url, verify=False, headers=headers, data=payload)
+ # Must get HTTP code 200 on success
+ self.assertEqual(r.status_code, 200)
+
+ payload_invalid = {'data': '{"op": "showConfig", "path": []}', 'key': 'invalid'}
+ r = request('POST', url, verify=False, headers=headers, data=payload_invalid)
+ # Must get HTTP code 401 on invalid key (Unauthorized)
+ self.assertEqual(r.status_code, 401)
+
+ payload_no_key = {'data': '{"op": "showConfig", "path": []}'}
+ r = request('POST', url, verify=False, headers=headers, data=payload_no_key)
+ # Must get HTTP code 401 on missing key (Unauthorized)
+ self.assertEqual(r.status_code, 401)
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_service_ids.py b/smoketest/scripts/cli/test_service_ids.py
new file mode 100755
index 000000000..18f1b8ec5
--- /dev/null
+++ b/smoketest/scripts/cli/test_service_ids.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import unittest
+
+from base_vyostest_shim import VyOSUnitTestSHIM
+
+from vyos.configsession import ConfigSessionError
+from vyos.util import process_named_running
+from vyos.util import read_file
+
+PROCESS_NAME = 'fastnetmon'
+FASTNETMON_CONF = '/etc/fastnetmon.conf'
+base_path = ['service', 'ids', 'ddos-protection']
+
+class TestServiceIDS(VyOSUnitTestSHIM.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ super(TestServiceIDS, cls).setUpClass()
+
+ # ensure we can also run this test on a live system - so lets clean
+ # out the current configuration :)
+ cls.cli_delete(cls, base_path)
+
+ def tearDown(self):
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+ # delete test config
+ self.cli_delete(base_path)
+ self.cli_commit()
+
+ self.assertFalse(os.path.exists(FASTNETMON_CONF))
+ self.assertFalse(process_named_running(PROCESS_NAME))
+
+ def test_fastnetmon(self):
+ networks = ['10.0.0.0/24', '10.5.5.0/24']
+ interfaces = ['eth0', 'eth1']
+ fps = '3500'
+ mbps = '300'
+ pps = '60000'
+
+ self.cli_set(base_path + ['mode', 'mirror'])
+ # Required network!
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ for tmp in networks:
+ self.cli_set(base_path + ['network', tmp])
+
+ # Required interface(s)!
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ for tmp in interfaces:
+ self.cli_set(base_path + ['listen-interface', tmp])
+
+ self.cli_set(base_path + ['direction', 'in'])
+ self.cli_set(base_path + ['threshold', 'fps', fps])
+ self.cli_set(base_path + ['threshold', 'pps', pps])
+ self.cli_set(base_path + ['threshold', 'mbps', mbps])
+
+ # commit changes
+ self.cli_commit()
+
+ # Check configured port
+ config = read_file(FASTNETMON_CONF)
+ self.assertIn(f'mirror_afpacket = on', config)
+ self.assertIn(f'process_incoming_traffic = on', config)
+ self.assertIn(f'process_outgoing_traffic = off', config)
+ self.assertIn(f'ban_for_flows = on', config)
+ self.assertIn(f'threshold_flows = {fps}', config)
+ self.assertIn(f'ban_for_bandwidth = on', config)
+ self.assertIn(f'threshold_mbps = {mbps}', config)
+ self.assertIn(f'ban_for_pps = on', config)
+ self.assertIn(f'threshold_pps = {pps}', config)
+
+ tmp = ','.join(interfaces)
+ self.assertIn(f'interfaces = {tmp}', config)
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_service_lldp.py b/smoketest/scripts/cli/test_service_lldp.py
new file mode 100755
index 000000000..439c96c33
--- /dev/null
+++ b/smoketest/scripts/cli/test_service_lldp.py
@@ -0,0 +1,127 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import re
+import os
+import unittest
+
+from base_vyostest_shim import VyOSUnitTestSHIM
+
+from vyos.configsession import ConfigSessionError
+from vyos.ifconfig import Section
+from vyos.util import cmd
+from vyos.util import process_named_running
+from vyos.util import read_file
+from vyos.version import get_version_data
+
+PROCESS_NAME = 'lldpd'
+LLDPD_CONF = '/etc/lldpd.d/01-vyos.conf'
+base_path = ['service', 'lldp']
+mgmt_if = 'dum83513'
+mgmt_addr = ['1.2.3.4', '1.2.3.5']
+
+class TestServiceLLDP(VyOSUnitTestSHIM.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ # call base-classes classmethod
+ super(TestServiceLLDP, cls).setUpClass()
+
+ # create a test interfaces
+ for addr in mgmt_addr:
+ cls.cli_set(cls, ['interfaces', 'dummy', mgmt_if, 'address', addr + '/32'])
+
+ # ensure we can also run this test on a live system - so lets clean
+ # out the current configuration :)
+ cls.cli_delete(cls, base_path)
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.cli_delete(cls, ['interfaces', 'dummy', mgmt_if])
+ super(TestServiceLLDP, cls).tearDownClass()
+
+ def tearDown(self):
+ # service must be running after it was configured
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+ # delete/stop LLDP service
+ self.cli_delete(base_path)
+ self.cli_commit()
+
+ # service is no longer allowed to run after it was removed
+ self.assertFalse(process_named_running(PROCESS_NAME))
+
+ def test_01_lldp_basic(self):
+ self.cli_set(base_path)
+ self.cli_commit()
+
+ config = read_file(LLDPD_CONF)
+ version_data = get_version_data()
+ version = version_data['version']
+ self.assertIn(f'configure system platform VyOS', config)
+ self.assertIn(f'configure system description "VyOS {version}"', config)
+
+ def test_02_lldp_mgmt_address(self):
+ for addr in mgmt_addr:
+ self.cli_set(base_path + ['management-address', addr])
+ self.cli_commit()
+
+ config = read_file(LLDPD_CONF)
+ self.assertIn(f'configure system ip management pattern {",".join(mgmt_addr)}', config)
+
+ def test_03_lldp_interfaces(self):
+ for interface in Section.interfaces('ethernet'):
+ if not '.' in interface:
+ self.cli_set(base_path + ['interface', interface])
+
+ # commit changes
+ self.cli_commit()
+
+ # verify configuration
+ config = read_file(LLDPD_CONF)
+
+ interface_list = []
+ for interface in Section.interfaces('ethernet'):
+ if not '.' in interface:
+ interface_list.append(interface)
+ tmp = ','.join(interface_list)
+ self.assertIn(f'configure system interface pattern "{tmp}"', config)
+
+ def test_04_lldp_all_interfaces(self):
+ self.cli_set(base_path + ['interface', 'all'])
+ # commit changes
+ self.cli_commit()
+
+ # verify configuration
+ config = read_file(LLDPD_CONF)
+ self.assertIn(f'configure system interface pattern "*"', config)
+
+ def test_05_lldp_location(self):
+ interface = 'eth0'
+ elin = '1234567890'
+ self.cli_set(base_path + ['interface', interface, 'location', 'elin', elin])
+
+ # commit changes
+ self.cli_commit()
+
+ # verify configuration
+ config = read_file(LLDPD_CONF)
+
+ self.assertIn(f'configure ports {interface} med location elin "{elin}"', config)
+ self.assertIn(f'configure system interface pattern "{interface}"', config)
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_service_monitoring_telegraf.py b/smoketest/scripts/cli/test_service_monitoring_telegraf.py
new file mode 100755
index 000000000..09937513e
--- /dev/null
+++ b/smoketest/scripts/cli/test_service_monitoring_telegraf.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import unittest
+
+from base_vyostest_shim import VyOSUnitTestSHIM
+
+from vyos.configsession import ConfigSession
+from vyos.configsession import ConfigSessionError
+from vyos.util import process_named_running
+from vyos.util import read_file
+
+PROCESS_NAME = 'telegraf'
+TELEGRAF_CONF = '/run/telegraf/vyos-telegraf.conf'
+base_path = ['service', 'monitoring', 'telegraf']
+org = 'log@in.local'
+token = 'GuRJc12tIzfjnYdKRAIYbxdWd2aTpOT9PVYNddzDnFV4HkAcD7u7-kndTFXjGuXzJN6TTxmrvPODB4mnFcseDV=='
+port = '8888'
+url = 'https://foo.local'
+bucket = 'main'
+inputs = ['cpu', 'disk', 'mem', 'net', 'system', 'kernel', 'interrupts', 'syslog']
+
+class TestMonitoringTelegraf(VyOSUnitTestSHIM.TestCase):
+ def tearDown(self):
+ self.cli_delete(base_path)
+ self.cli_commit()
+
+ def test_01_basic_config(self):
+ self.cli_set(base_path + ['authentication', 'organization', org])
+ self.cli_set(base_path + ['authentication', 'token', token])
+ self.cli_set(base_path + ['port', port])
+ self.cli_set(base_path + ['url', url])
+
+ # commit changes
+ self.cli_commit()
+
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+ config = read_file(TELEGRAF_CONF)
+
+ # Check telegraf config
+ self.assertIn(f'organization = "{org}"', config)
+ self.assertIn(f' token = "$INFLUX_TOKEN"', config)
+ self.assertIn(f'urls = ["{url}:{port}"]', config)
+ self.assertIn(f'bucket = "{bucket}"', config)
+
+ for input in inputs:
+ self.assertIn(input, config)
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_service_salt.py b/smoketest/scripts/cli/test_service_salt.py
new file mode 100755
index 000000000..00a4f2020
--- /dev/null
+++ b/smoketest/scripts/cli/test_service_salt.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import unittest
+
+from socket import gethostname
+from base_vyostest_shim import VyOSUnitTestSHIM
+
+from vyos.util import process_named_running
+from vyos.util import read_file
+from vyos.util import cmd
+
+PROCESS_NAME = 'salt-minion'
+SALT_CONF = '/etc/salt/minion'
+base_path = ['service', 'salt-minion']
+
+interface = 'dum4456'
+
+class TestServiceSALT(VyOSUnitTestSHIM.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ super(TestServiceSALT, cls).setUpClass()
+
+ # ensure we can also run this test on a live system - so lets clean
+ # out the current configuration :)
+ cls.cli_delete(cls, base_path)
+
+ cls.cli_set(cls, ['interfaces', 'dummy', interface, 'address', '100.64.0.1/16'])
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.cli_delete(cls, ['interfaces', 'dummy', interface])
+ super(TestServiceSALT, cls).tearDownClass()
+
+ def tearDown(self):
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+ # delete testing SALT config
+ self.cli_delete(base_path)
+ self.cli_commit()
+
+ # For an unknown reason on QEMU systems (e.g. where smoketests are executed
+ # from the CI) salt-minion process is not killed by systemd. Apparently
+ # no issue on VMWare.
+ if cmd('systemd-detect-virt') != 'kvm':
+ self.assertFalse(process_named_running(PROCESS_NAME))
+
+ def test_default(self):
+ servers = ['192.0.2.1', '192.0.2.2']
+
+ for server in servers:
+ self.cli_set(base_path + ['master', server])
+
+ self.cli_commit()
+
+ # commiconf = read_file() Check configured port
+ conf = read_file(SALT_CONF)
+ self.assertIn(f' - {server}', conf)
+
+ # defaults
+ hostname = gethostname()
+ self.assertIn(f'hash_type: sha256', conf)
+ self.assertIn(f'id: {hostname}', conf)
+ self.assertIn(f'mine_interval: 60', conf)
+
+ def test_options(self):
+ server = '192.0.2.3'
+ hash = 'sha1'
+ id = 'foo'
+ interval = '120'
+
+ self.cli_set(base_path + ['master', server])
+ self.cli_set(base_path + ['hash', hash])
+ self.cli_set(base_path + ['id', id])
+ self.cli_set(base_path + ['interval', interval])
+ self.cli_set(base_path + ['source-interface', interface])
+
+ self.cli_commit()
+
+ # commiconf = read_file() Check configured port
+ conf = read_file(SALT_CONF)
+ self.assertIn(f'- {server}', conf)
+
+ # defaults
+ self.assertIn(f'hash_type: {hash}', conf)
+ self.assertIn(f'id: {id}', conf)
+ self.assertIn(f'mine_interval: {interval}', conf)
+ self.assertIn(f'source_interface_name: {interface}', conf)
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_service_snmp.py b/smoketest/scripts/cli/test_service_snmp.py
index 058835c72..e80c689cc 100755
--- a/smoketest/scripts/cli/test_service_snmp.py
+++ b/smoketest/scripts/cli/test_service_snmp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2020 VyOS maintainers and contributors
+# Copyright (C) 2019-2021 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -22,14 +22,25 @@ from base_vyostest_shim import VyOSUnitTestSHIM
from vyos.configsession import ConfigSessionError
from vyos.template import is_ipv4
from vyos.template import address_from_cidr
+from vyos.util import call
+from vyos.util import DEVNULL
from vyos.util import read_file
from vyos.util import process_named_running
+from vyos.version import get_version_data
PROCESS_NAME = 'snmpd'
SNMPD_CONF = '/etc/snmp/snmpd.conf'
base_path = ['service', 'snmp']
+snmpv3_group = 'default_group'
+snmpv3_view = 'default_view'
+snmpv3_view_oid = '1'
+snmpv3_user = 'vyos'
+snmpv3_auth_pw = 'vyos12345678'
+snmpv3_priv_pw = 'vyos87654321'
+snmpv3_engine_id = '000000000000000000000002'
+
def get_config_value(key):
tmp = read_file(SNMPD_CONF)
tmp = re.findall(r'\n?{}\s+(.*)'.format(key), tmp)
@@ -38,20 +49,29 @@ def get_config_value(key):
class TestSNMPService(VyOSUnitTestSHIM.TestCase):
@classmethod
def setUpClass(cls):
- super(cls, cls).setUpClass()
+ super(TestSNMPService, cls).setUpClass()
# ensure we can also run this test on a live system - so lets clean
# out the current configuration :)
cls.cli_delete(cls, base_path)
def tearDown(self):
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
# delete testing SNMP config
self.cli_delete(base_path)
self.cli_commit()
+ # Check for running process
+ self.assertFalse(process_named_running(PROCESS_NAME))
+
def test_snmp_basic(self):
dummy_if = 'dum7312'
dummy_addr = '100.64.0.1/32'
+ contact = 'maintainers@vyos.io'
+ location = 'QEMU'
+
self.cli_set(['interfaces', 'dummy', dummy_if, 'address', dummy_addr])
# Check if SNMP can be configured and service runs
@@ -71,8 +91,8 @@ class TestSNMPService(VyOSUnitTestSHIM.TestCase):
for addr in listen:
self.cli_set(base_path + ['listen-address', addr, 'port', port])
- self.cli_set(base_path + ['contact', 'maintainers@vyos.io'])
- self.cli_set(base_path + ['location', 'qemu'])
+ self.cli_set(base_path + ['contact', contact])
+ self.cli_set(base_path + ['location', location])
self.cli_commit()
@@ -82,7 +102,6 @@ class TestSNMPService(VyOSUnitTestSHIM.TestCase):
config = get_config_value('agentaddress')
expected = 'unix:/run/snmpd.socket'
self.assertIn(expected, config)
-
for addr in listen:
if is_ipv4(addr):
expected = f'udp:{addr}:{port}'
@@ -90,6 +109,16 @@ class TestSNMPService(VyOSUnitTestSHIM.TestCase):
expected = f'udp6:[{addr}]:{port}'
self.assertIn(expected, config)
+ config = get_config_value('sysDescr')
+ version_data = get_version_data()
+ self.assertEqual('VyOS ' + version_data['version'], config)
+
+ config = get_config_value('SysContact')
+ self.assertEqual(contact, config)
+
+ config = get_config_value('SysLocation')
+ self.assertEqual(location, config)
+
# Check for running process
self.assertTrue(process_named_running(PROCESS_NAME))
self.cli_delete(['interfaces', 'dummy', dummy_if])
@@ -98,8 +127,7 @@ class TestSNMPService(VyOSUnitTestSHIM.TestCase):
def test_snmpv3_sha(self):
# Check if SNMPv3 can be configured with SHA authentication
# and service runs
-
- self.cli_set(base_path + ['v3', 'engineid', '000000000000000000000002'])
+ self.cli_set(base_path + ['v3', 'engineid', snmpv3_engine_id])
self.cli_set(base_path + ['v3', 'group', 'default', 'mode', 'ro'])
# check validate() - a view must be created before this can be committed
with self.assertRaises(ConfigSessionError):
@@ -109,46 +137,52 @@ class TestSNMPService(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + ['v3', 'group', 'default', 'view', 'default'])
# create user
- self.cli_set(base_path + ['v3', 'user', 'vyos', 'auth', 'plaintext-password', 'vyos12345678'])
- self.cli_set(base_path + ['v3', 'user', 'vyos', 'auth', 'type', 'sha'])
- self.cli_set(base_path + ['v3', 'user', 'vyos', 'privacy', 'plaintext-password', 'vyos12345678'])
- self.cli_set(base_path + ['v3', 'user', 'vyos', 'privacy', 'type', 'aes'])
- self.cli_set(base_path + ['v3', 'user', 'vyos', 'group', 'default'])
+ self.cli_set(base_path + ['v3', 'user', snmpv3_user, 'auth', 'plaintext-password', snmpv3_auth_pw])
+ self.cli_set(base_path + ['v3', 'user', snmpv3_user, 'auth', 'type', 'sha'])
+ self.cli_set(base_path + ['v3', 'user', snmpv3_user, 'privacy', 'plaintext-password', snmpv3_priv_pw])
+ self.cli_set(base_path + ['v3', 'user', snmpv3_user, 'privacy', 'type', 'aes'])
+ self.cli_set(base_path + ['v3', 'user', snmpv3_user, 'group', 'default'])
self.cli_commit()
# commit will alter the CLI values - check if they have been updated:
hashed_password = '4e52fe55fd011c9c51ae2c65f4b78ca93dcafdfe'
- tmp = self._session.show_config(base_path + ['v3', 'user', 'vyos', 'auth', 'encrypted-password']).split()[1]
+ tmp = self._session.show_config(base_path + ['v3', 'user', snmpv3_user, 'auth', 'encrypted-password']).split()[1]
self.assertEqual(tmp, hashed_password)
- tmp = self._session.show_config(base_path + ['v3', 'user', 'vyos', 'privacy', 'encrypted-password']).split()[1]
+ hashed_password = '54705c8de9e81fdf61ad7ac044fa8fe611ddff6b'
+ tmp = self._session.show_config(base_path + ['v3', 'user', snmpv3_user, 'privacy', 'encrypted-password']).split()[1]
self.assertEqual(tmp, hashed_password)
# TODO: read in config file and check values
- # Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
+ # Try SNMPv3 connection
+ tmp = call(f'snmpwalk -v 3 -u {snmpv3_user} -a SHA -A {snmpv3_auth_pw} -x AES -X {snmpv3_priv_pw} -l authPriv 127.0.0.1', stdout=DEVNULL)
+ self.assertEqual(tmp, 0)
def test_snmpv3_md5(self):
# Check if SNMPv3 can be configured with MD5 authentication
# and service runs
+ self.cli_set(base_path + ['v3', 'engineid', snmpv3_engine_id])
- self.cli_set(base_path + ['v3', 'engineid', '000000000000000000000002'])
- self.cli_set(base_path + ['v3', 'group', 'default', 'mode', 'ro'])
- # check validate() - a view must be created before this can be comitted
+ # create user
+ self.cli_set(base_path + ['v3', 'user', snmpv3_user, 'auth', 'plaintext-password', snmpv3_auth_pw])
+ self.cli_set(base_path + ['v3', 'user', snmpv3_user, 'auth', 'type', 'md5'])
+ self.cli_set(base_path + ['v3', 'user', snmpv3_user, 'privacy', 'plaintext-password', snmpv3_priv_pw])
+ self.cli_set(base_path + ['v3', 'user', snmpv3_user, 'privacy', 'type', 'des'])
+
+ # check validate() - user requires a group to be created
with self.assertRaises(ConfigSessionError):
self.cli_commit()
+ self.cli_set(base_path + ['v3', 'user', 'vyos', 'group', snmpv3_group])
- self.cli_set(base_path + ['v3', 'view', 'default', 'oid', '1'])
- self.cli_set(base_path + ['v3', 'group', 'default', 'view', 'default'])
+ self.cli_set(base_path + ['v3', 'group', snmpv3_group, 'mode', 'ro'])
+ # check validate() - a view must be created before this can be comitted
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
- # create user
- self.cli_set(base_path + ['v3', 'user', 'vyos', 'auth', 'plaintext-password', 'vyos12345678'])
- self.cli_set(base_path + ['v3', 'user', 'vyos', 'auth', 'type', 'md5'])
- self.cli_set(base_path + ['v3', 'user', 'vyos', 'privacy', 'plaintext-password', 'vyos12345678'])
- self.cli_set(base_path + ['v3', 'user', 'vyos', 'privacy', 'type', 'des'])
- self.cli_set(base_path + ['v3', 'user', 'vyos', 'group', 'default'])
+ self.cli_set(base_path + ['v3', 'view', snmpv3_view, 'oid', snmpv3_view_oid])
+ self.cli_set(base_path + ['v3', 'group', snmpv3_group, 'view', snmpv3_view])
self.cli_commit()
@@ -157,13 +191,21 @@ class TestSNMPService(VyOSUnitTestSHIM.TestCase):
tmp = self._session.show_config(base_path + ['v3', 'user', 'vyos', 'auth', 'encrypted-password']).split()[1]
self.assertEqual(tmp, hashed_password)
+ hashed_password = 'e11c83f2c510540a3c4de84ee66de440'
tmp = self._session.show_config(base_path + ['v3', 'user', 'vyos', 'privacy', 'encrypted-password']).split()[1]
self.assertEqual(tmp, hashed_password)
- # TODO: read in config file and check values
-
- # Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
+ tmp = read_file(SNMPD_CONF)
+ # views
+ self.assertIn(f'view {snmpv3_view} included .{snmpv3_view_oid}', tmp)
+ # group
+ self.assertIn(f'group {snmpv3_group} usm {snmpv3_user}', tmp)
+ # access
+ self.assertIn(f'access {snmpv3_group} "" usm auth exact {snmpv3_view} none none', tmp)
+
+ # Try SNMPv3 connection
+ tmp = call(f'snmpwalk -v 3 -u {snmpv3_user} -a MD5 -A {snmpv3_auth_pw} -x DES -X {snmpv3_priv_pw} -l authPriv 127.0.0.1', stdout=DEVNULL)
+ self.assertEqual(tmp, 0)
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_service_ssh.py b/smoketest/scripts/cli/test_service_ssh.py
index a54c03919..0b029dd00 100755
--- a/smoketest/scripts/cli/test_service_ssh.py
+++ b/smoketest/scripts/cli/test_service_ssh.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2020 VyOS maintainers and contributors
+# Copyright (C) 2019-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -15,13 +15,17 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
+import paramiko
import re
import unittest
+from pwd import getpwall
+
from base_vyostest_shim import VyOSUnitTestSHIM
from vyos.configsession import ConfigSessionError
from vyos.util import cmd
+from vyos.util import is_systemd_service_running
from vyos.util import process_named_running
from vyos.util import read_file
@@ -42,13 +46,16 @@ def get_config_value(key):
class TestServiceSSH(VyOSUnitTestSHIM.TestCase):
@classmethod
def setUpClass(cls):
- super(cls, cls).setUpClass()
+ super(TestServiceSSH, cls).setUpClass()
# ensure we can also run this test on a live system - so lets clean
# out the current configuration :)
cls.cli_delete(cls, base_path)
def tearDown(self):
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
# delete testing SSH config
self.cli_delete(base_path)
self.cli_commit()
@@ -57,6 +64,11 @@ class TestServiceSSH(VyOSUnitTestSHIM.TestCase):
self.assertTrue(os.path.isfile(key_dsa))
self.assertTrue(os.path.isfile(key_ed25519))
+ # Established SSH connections remains running after service is stopped.
+ # We can not use process_named_running here - we rather need to check
+ # that the systemd service is no longer running
+ self.assertFalse(is_systemd_service_running(PROCESS_NAME))
+
def test_ssh_default(self):
# Check if SSH service runs with default settings - used for checking
# behavior of <defaultValue> in XML definition
@@ -69,9 +81,6 @@ class TestServiceSSH(VyOSUnitTestSHIM.TestCase):
port = get_config_value('Port')[0]
self.assertEqual('22', port)
- # Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
-
def test_ssh_single_listen_address(self):
# Check if SSH service can be configured and runs
self.cli_set(base_path + ['port', '1234'])
@@ -108,9 +117,6 @@ class TestServiceSSH(VyOSUnitTestSHIM.TestCase):
keepalive = get_config_value('ClientAliveInterval')[0]
self.assertTrue("100" in keepalive)
- # Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
-
def test_ssh_multiple_listen_addresses(self):
# Check if SSH service can be configured and runs with multiple
# listen ports and listen-addresses
@@ -135,9 +141,6 @@ class TestServiceSSH(VyOSUnitTestSHIM.TestCase):
for address in addresses:
self.assertIn(address, tmp)
- # Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
-
def test_ssh_vrf(self):
# Check if SSH service can be bound to given VRF
port = '22'
@@ -157,9 +160,6 @@ class TestServiceSSH(VyOSUnitTestSHIM.TestCase):
tmp = get_config_value('Port')
self.assertIn(port, tmp)
- # Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
-
# Check for process in VRF
tmp = cmd(f'ip vrf pids {vrf}')
self.assertIn(PROCESS_NAME, tmp)
@@ -167,5 +167,100 @@ class TestServiceSSH(VyOSUnitTestSHIM.TestCase):
# delete VRF
self.cli_delete(['vrf', 'name', vrf])
+ def test_ssh_login(self):
+ # Perform SSH login and command execution with a predefined user. The
+ # result (output of uname -a) must match the output if the command is
+ # run natively.
+ #
+ # We also try to login as an invalid user - this is not allowed to work.
+
+ def ssh_send_cmd(command, username, password, host='localhost'):
+ """ SSH command execution helper """
+ # Try to login via SSH
+ ssh_client = paramiko.SSHClient()
+ ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+ ssh_client.connect(hostname='localhost', username=username, password=password)
+ _, stdout, stderr = ssh_client.exec_command(command)
+ output = stdout.read().decode().strip()
+ error = stderr.read().decode().strip()
+ ssh_client.close()
+ return output, error
+
+ test_user = 'ssh_test'
+ test_pass = 'v2i57DZs8idUwMN3VC92'
+ test_command = 'uname -a'
+
+ self.cli_set(base_path)
+ self.cli_set(['system', 'login', 'user', test_user, 'authentication', 'plaintext-password', test_pass])
+
+ # commit changes
+ self.cli_commit()
+
+ # Login with proper credentials
+ output, error = ssh_send_cmd(test_command, test_user, test_pass)
+ # verify login
+ self.assertFalse(error)
+ self.assertEqual(output, cmd(test_command))
+
+ # Login with invalid credentials
+ with self.assertRaises(paramiko.ssh_exception.AuthenticationException):
+ output, error = ssh_send_cmd(test_command, 'invalid_user', 'invalid_password')
+
+ self.cli_delete(['system', 'login', 'user', test_user])
+ self.cli_commit()
+
+ # After deletion the test user is not allowed to remain in /etc/passwd
+ usernames = [x[0] for x in getpwall()]
+ self.assertNotIn(test_user, usernames)
+
+ def test_ssh_dynamic_protection(self):
+ # check sshguard service
+
+ SSHGUARD_CONFIG = '/etc/sshguard/sshguard.conf'
+ SSHGUARD_WHITELIST = '/etc/sshguard/whitelist'
+ SSHGUARD_PROCESS = 'sshguard'
+ block_time = '123'
+ detect_time = '1804'
+ port = '22'
+ threshold = '10'
+ allow_list = ['192.0.2.0/24', '2001:db8::/48']
+
+ self.cli_set(base_path + ['dynamic-protection', 'block-time', block_time])
+ self.cli_set(base_path + ['dynamic-protection', 'detect-time', detect_time])
+ self.cli_set(base_path + ['dynamic-protection', 'threshold', threshold])
+ for allow in allow_list:
+ self.cli_set(base_path + ['dynamic-protection', 'allow-from', allow])
+
+ # commit changes
+ self.cli_commit()
+
+ # Check configured port
+ tmp = get_config_value('Port')
+ self.assertIn(port, tmp)
+
+ # Check sshgurad service
+ self.assertTrue(process_named_running(SSHGUARD_PROCESS))
+
+ sshguard_lines = [
+ f'THRESHOLD={threshold}',
+ f'BLOCK_TIME={block_time}',
+ f'DETECTION_TIME={detect_time}'
+ ]
+
+ tmp_sshguard_conf = read_file(SSHGUARD_CONFIG)
+ for line in sshguard_lines:
+ self.assertIn(line, tmp_sshguard_conf)
+
+ tmp_whitelist_conf = read_file(SSHGUARD_WHITELIST)
+ for allow in allow_list:
+ self.assertIn(allow, tmp_whitelist_conf)
+
+ # Delete service ssh dynamic-protection
+ # but not service ssh itself
+ self.cli_delete(base_path + ['dynamic-protection'])
+ self.cli_commit()
+
+ self.assertFalse(process_named_running(SSHGUARD_PROCESS))
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_service_tftp-server.py b/smoketest/scripts/cli/test_service_tftp-server.py
index 1a1bf0cdf..b57c33f26 100755
--- a/smoketest/scripts/cli/test_service_tftp-server.py
+++ b/smoketest/scripts/cli/test_service_tftp-server.py
@@ -20,6 +20,7 @@ from psutil import process_iter
from base_vyostest_shim import VyOSUnitTestSHIM
from vyos.configsession import ConfigSessionError
+from vyos.util import cmd
from vyos.util import read_file
from vyos.util import process_named_running
from vyos.template import is_ipv6
@@ -29,6 +30,7 @@ base_path = ['service', 'tftp-server']
dummy_if_path = ['interfaces', 'dummy', 'dum69']
address_ipv4 = '192.0.2.1'
address_ipv6 = '2001:db8::1'
+vrf = 'mgmt'
class TestServiceTFTPD(VyOSUnitTestSHIM.TestCase):
def setUp(self):
@@ -97,5 +99,42 @@ class TestServiceTFTPD(VyOSUnitTestSHIM.TestCase):
count += 1
self.assertEqual(count, len(address))
+ def test_03_tftpd_vrf(self):
+ directory = '/tmp'
+ port = '69' # default port
+
+ self.cli_set(base_path + ['allow-upload'])
+ self.cli_set(base_path + ['directory', directory])
+ self.cli_set(base_path + ['listen-address', address_ipv4, 'vrf', vrf])
+
+ # VRF does yet not exist - an error must be thrown
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ self.cli_set(['vrf', 'name', vrf, 'table', '1338'])
+ self.cli_set(dummy_if_path + ['vrf', vrf])
+
+ # commit changes
+ self.cli_commit()
+
+ config = read_file('/etc/default/tftpd0')
+ # verify listen IP address
+ self.assertIn(f'{address_ipv4}:{port} -4', config)
+ # verify directory
+ self.assertIn(directory, config)
+ # verify upload
+ self.assertIn('--create --umask 000', config)
+
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+ # Check for process in VRF
+ tmp = cmd(f'ip vrf pids {vrf}')
+ self.assertIn(PROCESS_NAME, tmp)
+
+ # delete VRF
+ self.cli_delete(dummy_if_path + ['vrf'])
+ self.cli_delete(['vrf', 'name', vrf])
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_service_upnp.py b/smoketest/scripts/cli/test_service_upnp.py
new file mode 100755
index 000000000..e4df88c1e
--- /dev/null
+++ b/smoketest/scripts/cli/test_service_upnp.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021-2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import re
+import unittest
+
+from base_vyostest_shim import VyOSUnitTestSHIM
+
+from vyos.configsession import ConfigSession
+from vyos.configsession import ConfigSessionError
+from vyos.template import ip_from_cidr
+from vyos.util import read_file
+from vyos.util import process_named_running
+
+UPNP_CONF = '/run/upnp/miniupnp.conf'
+DAEMON = 'miniupnpd'
+interface = 'eth0'
+base_path = ['service', 'upnp']
+address_base = ['interfaces', 'ethernet', interface, 'address']
+
+ipv4_addr = '100.64.0.1/24'
+ipv6_addr = '2001:db8::1/64'
+
+class TestServiceUPnP(VyOSUnitTestSHIM.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ super(TestServiceUPnP, cls).setUpClass()
+
+ # ensure we can also run this test on a live system - so lets clean
+ # out the current configuration :)
+ cls.cli_delete(cls, base_path)
+
+ cls.cli_set(cls, address_base + [ipv4_addr])
+ cls.cli_set(cls, address_base + [ipv6_addr])
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.cli_delete(cls, address_base)
+ cls._session.commit()
+
+ super(TestServiceUPnP, cls).tearDownClass()
+
+ def tearDown(self):
+ # Check for running process
+ self.assertTrue(process_named_running(DAEMON))
+
+ self.cli_delete(base_path)
+ self.cli_commit()
+
+ # Check for running process
+ self.assertFalse(process_named_running(DAEMON))
+
+ def test_ipv4_base(self):
+ self.cli_set(base_path + ['nat-pmp'])
+ self.cli_set(base_path + ['listen', interface])
+
+ # check validate() - WAN interface is mandatory
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_set(base_path + ['wan-interface', interface])
+
+ self.cli_commit()
+
+ config = read_file(UPNP_CONF)
+ self.assertIn(f'ext_ifname={interface}', config)
+ self.assertIn(f'listening_ip={interface}', config)
+ self.assertIn(f'enable_natpmp=yes', config)
+ self.assertIn(f'enable_upnp=yes', config)
+
+ def test_ipv6_base(self):
+ v6_addr = ip_from_cidr(ipv6_addr)
+
+ self.cli_set(base_path + ['nat-pmp'])
+ self.cli_set(base_path + ['listen', interface])
+ self.cli_set(base_path + ['listen', v6_addr])
+
+ # check validate() - WAN interface is mandatory
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_set(base_path + ['wan-interface', interface])
+
+ self.cli_commit()
+
+ config = read_file(UPNP_CONF)
+ self.assertIn(f'ext_ifname={interface}', config)
+ self.assertIn(f'listening_ip={interface}', config)
+ self.assertIn(f'ipv6_listening_ip={v6_addr}', config)
+ self.assertIn(f'enable_natpmp=yes', config)
+ self.assertIn(f'enable_upnp=yes', config)
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_service_webproxy.py b/smoketest/scripts/cli/test_service_webproxy.py
index 8a1a03ce7..772d6ab16 100755
--- a/smoketest/scripts/cli/test_service_webproxy.py
+++ b/smoketest/scripts/cli/test_service_webproxy.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright (C) 2020-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -30,11 +30,19 @@ listen_if = 'dum3632'
listen_ip = '192.0.2.1'
class TestServiceWebProxy(VyOSUnitTestSHIM.TestCase):
- def setUp(self):
- self.cli_set(['interfaces', 'dummy', listen_if, 'address', listen_ip + '/32'])
+ @classmethod
+ def setUpClass(cls):
+ # call base-classes classmethod
+ super(TestServiceWebProxy, cls).setUpClass()
+ # create a test interfaces
+ cls.cli_set(cls, ['interfaces', 'dummy', listen_if, 'address', listen_ip + '/32'])
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.cli_delete(cls, ['interfaces', 'dummy', listen_if])
+ super(TestServiceWebProxy, cls).tearDownClass()
def tearDown(self):
- self.cli_delete(['interfaces', 'dummy', listen_if])
self.cli_delete(base_path)
self.cli_commit()
diff --git a/smoketest/scripts/cli/test_system_conntrack.py b/smoketest/scripts/cli/test_system_conntrack.py
index b2934cf04..95c2a6c55 100755
--- a/smoketest/scripts/cli/test_system_conntrack.py
+++ b/smoketest/scripts/cli/test_system_conntrack.py
@@ -15,10 +15,12 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
+import re
import unittest
from base_vyostest_shim import VyOSUnitTestSHIM
+from vyos.firewall import find_nftables_rule
from vyos.util import cmd
from vyos.util import read_file
@@ -156,8 +158,8 @@ class TestSystemConntrack(VyOSUnitTestSHIM.TestCase):
'driver' : ['nf_nat_h323', 'nf_conntrack_h323'],
},
'nfs' : {
- 'iptables' : ['-A VYATTA_CT_HELPER -p udp -m udp --dport 111 -j CT --helper rpc',
- '-A VYATTA_CT_HELPER -p tcp -m tcp --dport 111 -j CT --helper rpc'],
+ 'nftables' : ['ct helper set "rpc_tcp"',
+ 'ct helper set "rpc_udp"']
},
'pptp' : {
'driver' : ['nf_nat_pptp', 'nf_conntrack_pptp'],
@@ -166,9 +168,7 @@ class TestSystemConntrack(VyOSUnitTestSHIM.TestCase):
'driver' : ['nf_nat_sip', 'nf_conntrack_sip'],
},
'sqlnet' : {
- 'iptables' : ['-A VYATTA_CT_HELPER -p tcp -m tcp --dport 1536 -j CT --helper tns',
- '-A VYATTA_CT_HELPER -p tcp -m tcp --dport 1525 -j CT --helper tns',
- '-A VYATTA_CT_HELPER -p tcp -m tcp --dport 1521 -j CT --helper tns'],
+ 'nftables' : ['ct helper set "tns_tcp"']
},
'tftp' : {
'driver' : ['nf_nat_tftp', 'nf_conntrack_tftp'],
@@ -187,10 +187,9 @@ class TestSystemConntrack(VyOSUnitTestSHIM.TestCase):
if 'driver' in module_options:
for driver in module_options['driver']:
self.assertTrue(os.path.isdir(f'/sys/module/{driver}'))
- if 'iptables' in module_options:
- rules = cmd('sudo iptables-save -t raw')
- for ruleset in module_options['iptables']:
- self.assertIn(ruleset, rules)
+ if 'nftables' in module_options:
+ for rule in module_options['nftables']:
+ self.assertTrue(find_nftables_rule('raw', 'VYOS_CT_HELPER', [rule]) != None)
# unload modules
for module in modules:
@@ -204,10 +203,9 @@ class TestSystemConntrack(VyOSUnitTestSHIM.TestCase):
if 'driver' in module_options:
for driver in module_options['driver']:
self.assertFalse(os.path.isdir(f'/sys/module/{driver}'))
- if 'iptables' in module_options:
- rules = cmd('sudo iptables-save -t raw')
- for ruleset in module_options['iptables']:
- self.assertNotIn(ruleset, rules)
+ if 'nftables' in module_options:
+ for rule in module_options['nftables']:
+ self.assertTrue(find_nftables_rule('raw', 'VYOS_CT_HELPER', [rule]) == None)
def test_conntrack_hash_size(self):
hash_size = '65536'
diff --git a/smoketest/scripts/cli/test_system_flow-accounting.py b/smoketest/scripts/cli/test_system_flow-accounting.py
index a2b5b1481..a6eef3fb6 100755
--- a/smoketest/scripts/cli/test_system_flow-accounting.py
+++ b/smoketest/scripts/cli/test_system_flow-accounting.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -20,6 +20,8 @@ from base_vyostest_shim import VyOSUnitTestSHIM
from vyos.configsession import ConfigSessionError
from vyos.ifconfig import Section
+from vyos.template import bracketize_ipv6
+from vyos.template import is_ipv6
from vyos.util import cmd
from vyos.util import process_named_running
from vyos.util import read_file
@@ -27,18 +29,21 @@ from vyos.util import read_file
PROCESS_NAME = 'uacctd'
base_path = ['system', 'flow-accounting']
-uacctd_conf = '/etc/pmacct/uacctd.conf'
+uacctd_conf = '/run/pmacct/uacctd.conf'
class TestSystemFlowAccounting(VyOSUnitTestSHIM.TestCase):
@classmethod
def setUpClass(cls):
- super(cls, cls).setUpClass()
+ super(TestSystemFlowAccounting, cls).setUpClass()
# ensure we can also run this test on a live system - so lets clean
# out the current configuration :)
cls.cli_delete(cls, base_path)
def tearDown(self):
+ # after service removal process must no longer run
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
self.cli_delete(base_path)
self.cli_commit()
@@ -47,7 +52,10 @@ class TestSystemFlowAccounting(VyOSUnitTestSHIM.TestCase):
def test_basic(self):
buffer_size = '5' # MiB
+ syslog = 'all'
+
self.cli_set(base_path + ['buffer-size', buffer_size])
+ self.cli_set(base_path + ['syslog-facility', syslog])
# You need to configure at least one interface for flow-accounting
with self.assertRaises(ConfigSessionError):
@@ -59,9 +67,20 @@ class TestSystemFlowAccounting(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# verify configuration
- tmp = cmd('sudo iptables-save -t raw')
+ nftables_output = cmd('sudo nft list chain raw VYOS_CT_PREROUTING_HOOK').splitlines()
for interface in Section.interfaces('ethernet'):
- self.assertIn(f'-A VYATTA_CT_PREROUTING_HOOK -i {interface} -m comment --comment FLOW_ACCOUNTING_RULE -j NFLOG --nflog-group 2 --nflog-size 128 --nflog-threshold 100', tmp)
+ rule_found = False
+ ifname_search = f'iifname "{interface}"'
+
+ for nftables_line in nftables_output:
+ if 'FLOW_ACCOUNTING_RULE' in nftables_line and ifname_search in nftables_line:
+ self.assertIn('group 2', nftables_line)
+ self.assertIn('snaplen 128', nftables_line)
+ self.assertIn('queue-threshold 100', nftables_line)
+ rule_found = True
+ break
+
+ self.assertTrue(rule_found)
uacctd = read_file(uacctd_conf)
# circular queue size - buffer_size
@@ -73,8 +92,205 @@ class TestSystemFlowAccounting(VyOSUnitTestSHIM.TestCase):
tmp //= 1000
self.assertIn(f'plugin_buffer_size: {tmp}', uacctd)
- # Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
+ # when 'disable-imt' is not configured on the CLI it must be present
+ self.assertIn(f'imt_path: /tmp/uacctd.pipe', uacctd)
+ self.assertIn(f'imt_mem_pools_number: 169', uacctd)
+ self.assertIn(f'syslog: {syslog}', uacctd)
+ self.assertIn(f'plugins: memory', uacctd)
+
+ def test_sflow(self):
+ sampling_rate = '4000'
+ source_address = '192.0.2.1'
+ dummy_if = 'dum3841'
+ agent_address = '192.0.2.2'
+
+ sflow_server = {
+ '1.2.3.4' : { },
+ '5.6.7.8' : { 'port' : '6000' },
+ }
+
+ self.cli_set(['interfaces', 'dummy', dummy_if, 'address', agent_address + '/32'])
+ self.cli_set(['interfaces', 'dummy', dummy_if, 'address', source_address + '/32'])
+ self.cli_set(base_path + ['disable-imt'])
+
+ # You need to configure at least one interface for flow-accounting
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ for interface in Section.interfaces('ethernet'):
+ self.cli_set(base_path + ['interface', interface])
+
+
+ # You need to configure at least one sFlow or NetFlow protocol, or not
+ # set "disable-imt" for flow-accounting
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ self.cli_set(base_path + ['sflow', 'agent-address', agent_address])
+ self.cli_set(base_path + ['sflow', 'sampling-rate', sampling_rate])
+ self.cli_set(base_path + ['sflow', 'source-address', source_address])
+ for server, server_config in sflow_server.items():
+ self.cli_set(base_path + ['sflow', 'server', server])
+ if 'port' in server_config:
+ self.cli_set(base_path + ['sflow', 'server', server, 'port', server_config['port']])
+
+ # commit changes
+ self.cli_commit()
+
+ uacctd = read_file(uacctd_conf)
+
+ # when 'disable-imt' is not configured on the CLI it must be present
+ self.assertNotIn(f'imt_path: /tmp/uacctd.pipe', uacctd)
+ self.assertNotIn(f'imt_mem_pools_number: 169', uacctd)
+ self.assertNotIn(f'plugins: memory', uacctd)
+
+ for server, server_config in sflow_server.items():
+ if 'port' in server_config:
+ self.assertIn(f'sfprobe_receiver[sf_{server}]: {server}', uacctd)
+ else:
+ self.assertIn(f'sfprobe_receiver[sf_{server}]: {server}:6343', uacctd)
+
+ self.assertIn(f'sfprobe_agentip[sf_{server}]: {agent_address}', uacctd)
+ self.assertIn(f'sampling_rate[sf_{server}]: {sampling_rate}', uacctd)
+ self.assertIn(f'sfprobe_source_ip[sf_{server}]: {source_address}', uacctd)
+
+ self.cli_delete(['interfaces', 'dummy', dummy_if])
+
+ def test_sflow_ipv6(self):
+ sampling_rate = '100'
+ sflow_server = {
+ '2001:db8::1' : { },
+ '2001:db8::2' : { 'port' : '6000' },
+ }
+
+ self.cli_set(base_path + ['disable-imt'])
+
+ # You need to configure at least one interface for flow-accounting
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ for interface in Section.interfaces('ethernet'):
+ self.cli_set(base_path + ['interface', interface])
+
+
+ # You need to configure at least one sFlow or NetFlow protocol, or not
+ # set "disable-imt" for flow-accounting
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ self.cli_set(base_path + ['sflow', 'sampling-rate', sampling_rate])
+ for server, server_config in sflow_server.items():
+ self.cli_set(base_path + ['sflow', 'server', server])
+ if 'port' in server_config:
+ self.cli_set(base_path + ['sflow', 'server', server, 'port', server_config['port']])
+
+ # commit changes
+ self.cli_commit()
+
+ uacctd = read_file(uacctd_conf)
+
+ # when 'disable-imt' is not configured on the CLI it must be present
+ self.assertNotIn(f'imt_path: /tmp/uacctd.pipe', uacctd)
+ self.assertNotIn(f'imt_mem_pools_number: 169', uacctd)
+ self.assertNotIn(f'plugins: memory', uacctd)
+
+ for server, server_config in sflow_server.items():
+ tmp_srv = server
+ if is_ipv6(tmp_srv):
+ tmp_srv = tmp_srv.replace(':', '.')
+
+ if 'port' in server_config:
+ self.assertIn(f'sfprobe_receiver[sf_{tmp_srv}]: {bracketize_ipv6(server)}', uacctd)
+ else:
+ self.assertIn(f'sfprobe_receiver[sf_{tmp_srv}]: {bracketize_ipv6(server)}:6343', uacctd)
+ self.assertIn(f'sampling_rate[sf_{tmp_srv}]: {sampling_rate}', uacctd)
+
+ def test_netflow(self):
+ engine_id = '33'
+ max_flows = '667'
+ sampling_rate = '100'
+ source_address = '192.0.2.1'
+ dummy_if = 'dum3842'
+ agent_address = '192.0.2.10'
+ version = '10'
+ tmo_expiry = '120'
+ tmo_flow = '1200'
+ tmo_icmp = '60'
+ tmo_max = '50000'
+ tmo_tcp_fin = '100'
+ tmo_tcp_generic = '120'
+ tmo_tcp_rst = '99'
+ tmo_udp = '10'
+
+ netflow_server = {
+ '11.22.33.44' : { },
+ '55.66.77.88' : { 'port' : '6000' },
+ '2001:db8::1' : { },
+ }
+
+ self.cli_set(['interfaces', 'dummy', dummy_if, 'address', agent_address + '/32'])
+ self.cli_set(['interfaces', 'dummy', dummy_if, 'address', source_address + '/32'])
+
+ for interface in Section.interfaces('ethernet'):
+ self.cli_set(base_path + ['interface', interface])
+
+ self.cli_set(base_path + ['netflow', 'engine-id', engine_id])
+ self.cli_set(base_path + ['netflow', 'max-flows', max_flows])
+ self.cli_set(base_path + ['netflow', 'sampling-rate', sampling_rate])
+ self.cli_set(base_path + ['netflow', 'source-address', source_address])
+ self.cli_set(base_path + ['netflow', 'version', version])
+
+ # timeouts
+ self.cli_set(base_path + ['netflow', 'timeout', 'expiry-interval', tmo_expiry])
+ self.cli_set(base_path + ['netflow', 'timeout', 'flow-generic', tmo_flow])
+ self.cli_set(base_path + ['netflow', 'timeout', 'icmp', tmo_icmp])
+ self.cli_set(base_path + ['netflow', 'timeout', 'max-active-life', tmo_max])
+ self.cli_set(base_path + ['netflow', 'timeout', 'tcp-fin', tmo_tcp_fin])
+ self.cli_set(base_path + ['netflow', 'timeout', 'tcp-generic', tmo_tcp_generic])
+ self.cli_set(base_path + ['netflow', 'timeout', 'tcp-rst', tmo_tcp_rst])
+ self.cli_set(base_path + ['netflow', 'timeout', 'udp', tmo_udp])
+
+ # You need to configure at least one netflow server
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ for server, server_config in netflow_server.items():
+ self.cli_set(base_path + ['netflow', 'server', server])
+ if 'port' in server_config:
+ self.cli_set(base_path + ['netflow', 'server', server, 'port', server_config['port']])
+
+ # commit changes
+ self.cli_commit()
+
+ uacctd = read_file(uacctd_conf)
+
+ tmp = []
+ for server, server_config in netflow_server.items():
+ tmp_srv = server
+ if is_ipv6(tmp_srv):
+ tmp_srv = tmp_srv.replace(':', '.')
+ tmp.append(f'nfprobe[nf_{tmp_srv}]')
+ tmp.append('memory')
+ self.assertIn('plugins: ' + ','.join(tmp), uacctd)
+
+ for server, server_config in netflow_server.items():
+ tmp_srv = server
+ if is_ipv6(tmp_srv):
+ tmp_srv = tmp_srv.replace(':', '.')
+
+ self.assertIn(f'nfprobe_engine[nf_{tmp_srv}]: {engine_id}', uacctd)
+ self.assertIn(f'nfprobe_maxflows[nf_{tmp_srv}]: {max_flows}', uacctd)
+ self.assertIn(f'sampling_rate[nf_{tmp_srv}]: {sampling_rate}', uacctd)
+ self.assertIn(f'nfprobe_source_ip[nf_{tmp_srv}]: {source_address}', uacctd)
+ self.assertIn(f'nfprobe_version[nf_{tmp_srv}]: {version}', uacctd)
+
+ if 'port' in server_config:
+ self.assertIn(f'nfprobe_receiver[nf_{tmp_srv}]: {bracketize_ipv6(server)}', uacctd)
+ else:
+ self.assertIn(f'nfprobe_receiver[nf_{tmp_srv}]: {bracketize_ipv6(server)}:2055', uacctd)
+
+ self.assertIn(f'nfprobe_timeouts[nf_{tmp_srv}]: expint={tmo_expiry}:general={tmo_flow}:icmp={tmo_icmp}:maxlife={tmo_max}:tcp.fin={tmo_tcp_fin}:tcp={tmo_tcp_generic}:tcp.rst={tmo_tcp_rst}:udp={tmo_udp}', uacctd)
+
+
+ self.cli_delete(['interfaces', 'dummy', dummy_if])
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_system_ipv6.py b/smoketest/scripts/cli/test_system_ipv6.py
index 1325d4b39..c8aea9100 100755
--- a/smoketest/scripts/cli/test_system_ipv6.py
+++ b/smoketest/scripts/cli/test_system_ipv6.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -17,12 +17,16 @@
import unittest
from base_vyostest_shim import VyOSUnitTestSHIM
+
+from vyos.template import is_ipv4
from vyos.util import read_file
+from vyos.util import get_interface_config
+from vyos.validate import is_intf_addr_assigned
base_path = ['system', 'ipv6']
file_forwarding = '/proc/sys/net/ipv6/conf/all/forwarding'
-file_disable = '/etc/modprobe.d/vyos_disable_ipv6.conf'
+file_disable = '/proc/sys/net/ipv6/conf/all/disable_ipv6'
file_dad = '/proc/sys/net/ipv6/conf/all/accept_dad'
file_multipath = '/proc/sys/net/ipv6/fib_multipath_hash_policy'
@@ -41,15 +45,6 @@ class TestSystemIPv6(VyOSUnitTestSHIM.TestCase):
self.assertEqual(read_file(file_forwarding), '0')
- def test_system_ipv6_disable(self):
- # Do not assign any IPv6 address on interfaces, this requires a reboot
- # which can not be tested, but we can read the config file :)
- self.cli_set(base_path + ['disable'])
- self.cli_commit()
-
- # Verify configuration file
- self.assertEqual(read_file(file_disable), 'options ipv6 disable_ipv6=1')
-
def test_system_ipv6_strict_dad(self):
# This defaults to 1
self.assertEqual(read_file(file_dad), '1')
diff --git a/smoketest/scripts/cli/test_system_login.py b/smoketest/scripts/cli/test_system_login.py
index 69a06eeac..1131b6f93 100755
--- a/smoketest/scripts/cli/test_system_login.py
+++ b/smoketest/scripts/cli/test_system_login.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2020 VyOS maintainers and contributors
+# Copyright (C) 2019-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -23,6 +23,7 @@ from base_vyostest_shim import VyOSUnitTestSHIM
from distutils.version import LooseVersion
from platform import release as kernel_version
from subprocess import Popen, PIPE
+from pwd import getpwall
from vyos.configsession import ConfigSessionError
from vyos.util import cmd
@@ -52,6 +53,11 @@ class TestSystemLogin(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
+ # After deletion, a user is not allowed to remain in /etc/passwd
+ usernames = [x[0] for x in getpwall()]
+ for user in users:
+ self.assertNotIn(user, usernames)
+
def test_add_linux_system_user(self):
# We are not allowed to re-use a username already taken by the Linux
# base system
@@ -235,4 +241,4 @@ class TestSystemLogin(VyOSUnitTestSHIM.TestCase):
self.assertTrue(tmp)
if __name__ == '__main__':
- unittest.main(verbosity=2, failfast=True)
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_system_logs.py b/smoketest/scripts/cli/test_system_logs.py
new file mode 100755
index 000000000..92fa9c3d9
--- /dev/null
+++ b/smoketest/scripts/cli/test_system_logs.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import re
+import unittest
+from base_vyostest_shim import VyOSUnitTestSHIM
+from vyos.util import read_file
+
+# path to logrotate configs
+logrotate_atop_file = '/etc/logrotate.d/vyos-atop'
+logrotate_rsyslog_file = '/etc/logrotate.d/vyos-rsyslog'
+# default values
+default_atop_maxsize = '10M'
+default_atop_rotate = '10'
+default_rsyslog_size = '1M'
+default_rsyslog_rotate = '10'
+
+base_path = ['system', 'logs']
+
+
+def logrotate_config_parse(file_path):
+ # read the file
+ logrotate_config = read_file(file_path)
+ # create regex for parsing options
+ regex_options = re.compile(
+ r'(^\s+(?P<option_name_script>postrotate|prerotate|firstaction|lastaction|preremove)\n(?P<option_value_script>((?!endscript).)*)\n\s+endscript\n)|(^\s+(?P<option_name>[\S]+)([ \t]+(?P<option_value>\S+))*$)',
+ re.M | re.S)
+ # create empty dict for config
+ logrotate_config_dict = {}
+ # fill dictionary with actual config
+ for option in regex_options.finditer(logrotate_config):
+ option_name = option.group('option_name')
+ option_value = option.group('option_value')
+ option_name_script = option.group('option_name_script')
+ option_value_script = option.group('option_value_script')
+ if option_name:
+ logrotate_config_dict[option_name] = option_value
+ if option_name_script:
+ logrotate_config_dict[option_name_script] = option_value_script
+
+ # return config dictionary
+ return (logrotate_config_dict)
+
+
+class TestSystemLogs(VyOSUnitTestSHIM.TestCase):
+
+ def tearDown(self):
+ self.cli_delete(base_path)
+ self.cli_commit()
+
+ def test_logs_defaults(self):
+ # test with empty section for default values
+ self.cli_set(base_path)
+ self.cli_commit()
+
+ # read the config file and check content
+ logrotate_config_atop = logrotate_config_parse(logrotate_atop_file)
+ logrotate_config_rsyslog = logrotate_config_parse(
+ logrotate_rsyslog_file)
+ self.assertEqual(logrotate_config_atop['maxsize'], default_atop_maxsize)
+ self.assertEqual(logrotate_config_atop['rotate'], default_atop_rotate)
+ self.assertEqual(logrotate_config_rsyslog['size'], default_rsyslog_size)
+ self.assertEqual(logrotate_config_rsyslog['rotate'],
+ default_rsyslog_rotate)
+
+ def test_logs_atop_maxsize(self):
+ # test for maxsize option
+ self.cli_set(base_path + ['logrotate', 'atop', 'max-size', '50'])
+ self.cli_commit()
+
+ # read the config file and check content
+ logrotate_config = logrotate_config_parse(logrotate_atop_file)
+ self.assertEqual(logrotate_config['maxsize'], '50M')
+
+ def test_logs_atop_rotate(self):
+ # test for rotate option
+ self.cli_set(base_path + ['logrotate', 'atop', 'rotate', '50'])
+ self.cli_commit()
+
+ # read the config file and check content
+ logrotate_config = logrotate_config_parse(logrotate_atop_file)
+ self.assertEqual(logrotate_config['rotate'], '50')
+
+ def test_logs_rsyslog_size(self):
+ # test for size option
+ self.cli_set(base_path + ['logrotate', 'messages', 'max-size', '50'])
+ self.cli_commit()
+
+ # read the config file and check content
+ logrotate_config = logrotate_config_parse(logrotate_rsyslog_file)
+ self.assertEqual(logrotate_config['size'], '50M')
+
+ def test_logs_rsyslog_rotate(self):
+ # test for rotate option
+ self.cli_set(base_path + ['logrotate', 'messages', 'rotate', '50'])
+ self.cli_commit()
+
+ # read the config file and check content
+ logrotate_config = logrotate_config_parse(logrotate_rsyslog_file)
+ self.assertEqual(logrotate_config['rotate'], '50')
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_system_ntp.py b/smoketest/scripts/cli/test_system_ntp.py
index e8cc64463..e2821687c 100755
--- a/smoketest/scripts/cli/test_system_ntp.py
+++ b/smoketest/scripts/cli/test_system_ntp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2020 VyOS maintainers and contributors
+# Copyright (C) 2019-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -14,7 +14,6 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-import re
import unittest
from base_vyostest_shim import VyOSUnitTestSHIM
@@ -29,17 +28,14 @@ PROCESS_NAME = 'ntpd'
NTP_CONF = '/run/ntpd/ntpd.conf'
base_path = ['system', 'ntp']
-def get_config_value(key):
- tmp = read_file(NTP_CONF)
- tmp = re.findall(r'\n?{}\s+(.*)'.format(key), tmp)
- # remove possible trailing whitespaces
- return [item.strip() for item in tmp]
-
class TestSystemNTP(VyOSUnitTestSHIM.TestCase):
- def setUp(self):
+ @classmethod
+ def setUpClass(cls):
+ super(TestSystemNTP, cls).setUpClass()
+
# ensure we can also run this test on a live system - so lets clean
# out the current configuration :)
- self.cli_delete(base_path)
+ cls.cli_delete(cls, base_path)
def tearDown(self):
self.cli_delete(base_path)
@@ -47,35 +43,38 @@ class TestSystemNTP(VyOSUnitTestSHIM.TestCase):
self.assertFalse(process_named_running(PROCESS_NAME))
- def test_ntp_options(self):
+ def test_01_ntp_options(self):
# Test basic NTP support with multiple servers and their options
servers = ['192.0.2.1', '192.0.2.2']
options = ['noselect', 'preempt', 'prefer']
- ntp_pool = 'pool.vyos.io'
+ pools = ['pool.vyos.io']
for server in servers:
for option in options:
self.cli_set(base_path + ['server', server, option])
# Test NTP pool
- self.cli_set(base_path + ['server', ntp_pool, 'pool'])
+ for pool in pools:
+ self.cli_set(base_path + ['server', pool, 'pool'])
# commit changes
self.cli_commit()
# Check generated configuration
- tmp = get_config_value('server')
- for server in servers:
- test = f'{server} iburst ' + ' '.join(options)
- self.assertTrue(test in tmp)
+ config = read_file(NTP_CONF)
+ self.assertIn('driftfile /var/lib/ntp/ntp.drift', config)
+ self.assertIn('restrict default noquery nopeer notrap nomodify', config)
+ self.assertIn('restrict source nomodify notrap noquery', config)
+ self.assertIn('restrict 127.0.0.1', config)
+ self.assertIn('restrict -6 ::1', config)
- tmp = get_config_value('pool')
- self.assertTrue(f'{ntp_pool} iburst' in tmp)
+ for server in servers:
+ self.assertIn(f'server {server} iburst ' + ' '.join(options), config)
- # Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
+ for pool in pools:
+ self.assertIn(f'pool {pool} iburst', config)
- def test_ntp_clients(self):
+ def test_02_ntp_clients(self):
# Test the allowed-networks statement
listen_address = ['127.0.0.1', '::1']
for listen in listen_address:
@@ -96,23 +95,18 @@ class TestSystemNTP(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Check generated client address configuration
+ config = read_file(NTP_CONF)
+ self.assertIn('restrict default ignore', config)
+
for network in networks:
network_address = address_from_cidr(network)
network_netmask = netmask_from_cidr(network)
-
- tmp = get_config_value(f'restrict {network_address}')[0]
- test = f'mask {network_netmask} nomodify notrap nopeer'
- self.assertTrue(tmp in test)
+ self.assertIn(f'restrict {network_address} mask {network_netmask} nomodify notrap nopeer', config)
# Check listen address
- tmp = get_config_value('interface')
- test = ['ignore wildcard']
+ self.assertIn('interface ignore wildcard', config)
for listen in listen_address:
- test.append(f'listen {listen}')
- self.assertEqual(tmp, test)
-
- # Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
+ self.assertIn(f'interface listen {listen}', config)
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_vpn_ipsec.py b/smoketest/scripts/cli/test_vpn_ipsec.py
index c710aec6e..8a6514d57 100755
--- a/smoketest/scripts/cli/test_vpn_ipsec.py
+++ b/smoketest/scripts/cli/test_vpn_ipsec.py
@@ -28,6 +28,7 @@ vti_path = ['interfaces', 'vti']
nhrp_path = ['protocols', 'nhrp']
base_path = ['vpn', 'ipsec']
+charon_file = '/etc/strongswan.d/charon.conf'
dhcp_waiting_file = '/tmp/ipsec_dhcp_waiting'
swanctl_file = '/etc/swanctl/swanctl.conf'
@@ -111,9 +112,21 @@ rgiyCHemtMepq57Pl1Nmj49eEA==
"""
class TestVPNIPsec(VyOSUnitTestSHIM.TestCase):
- def setUp(self):
- self.cli_set(base_path + ['interface', f'{interface}.{vif}'])
+ @classmethod
+ def setUpClass(cls):
+ super(TestVPNIPsec, cls).setUpClass()
+ # ensure we can also run this test on a live system - so lets clean
+ # out the current configuration :)
+ cls.cli_delete(cls, base_path)
+
+ cls.cli_set(cls, base_path + ['interface', f'{interface}.{vif}'])
+ @classmethod
+ def tearDownClass(cls):
+ super(TestVPNIPsec, cls).tearDownClass()
+ cls.cli_delete(cls, base_path + ['interface', f'{interface}.{vif}'])
+
+ def setUp(self):
# Set IKE/ESP Groups
self.cli_set(base_path + ['esp-group', esp_group, 'proposal', '1', 'encryption', 'aes128'])
self.cli_set(base_path + ['esp-group', esp_group, 'proposal', '1', 'hash', 'sha1'])
@@ -127,7 +140,6 @@ class TestVPNIPsec(VyOSUnitTestSHIM.TestCase):
self.cli_delete(base_path)
self.cli_delete(tunnel_path)
- self.cli_delete(ethernet_path)
self.cli_commit()
# Check for no longer running process
@@ -158,8 +170,14 @@ class TestVPNIPsec(VyOSUnitTestSHIM.TestCase):
# Site to site
local_address = '192.0.2.10'
+ priority = '20'
+ life_bytes = '100000'
+ life_packets = '2000000'
peer_base_path = base_path + ['site-to-site', 'peer', peer_ip]
+ self.cli_set(base_path + ['esp-group', esp_group, 'life-bytes', life_bytes])
+ self.cli_set(base_path + ['esp-group', esp_group, 'life-packets', life_packets])
+
self.cli_set(peer_base_path + ['authentication', 'mode', 'pre-shared-secret'])
self.cli_set(peer_base_path + ['authentication', 'pre-shared-secret', secret])
self.cli_set(peer_base_path + ['ike-group', ike_group])
@@ -173,6 +191,10 @@ class TestVPNIPsec(VyOSUnitTestSHIM.TestCase):
self.cli_set(peer_base_path + ['tunnel', '1', 'remote', 'prefix', '172.17.11.0/24'])
self.cli_set(peer_base_path + ['tunnel', '1', 'remote', 'port', '443'])
+ self.cli_set(peer_base_path + ['tunnel', '2', 'local', 'prefix', '10.1.0.0/16'])
+ self.cli_set(peer_base_path + ['tunnel', '2', 'remote', 'prefix', '10.2.0.0/16'])
+ self.cli_set(peer_base_path + ['tunnel', '2', 'priority', priority])
+
self.cli_commit()
# Verify strongSwan configuration
@@ -180,6 +202,8 @@ class TestVPNIPsec(VyOSUnitTestSHIM.TestCase):
swanctl_conf_lines = [
f'version = 2',
f'auth = psk',
+ f'life_bytes = {life_bytes}',
+ f'life_packets = {life_packets}',
f'rekey_time = 28800s', # default value
f'proposals = aes128-sha1-modp1024',
f'esp_proposals = aes128-sha1-modp1024',
@@ -187,8 +211,15 @@ class TestVPNIPsec(VyOSUnitTestSHIM.TestCase):
f'local_addrs = {local_address} # dhcp:no',
f'remote_addrs = {peer_ip}',
f'mode = tunnel',
+ f'peer_{peer_ip.replace(".","-")}_tunnel_1',
f'local_ts = 172.16.10.0/24[tcp/443],172.16.11.0/24[tcp/443]',
- f'remote_ts = 172.17.10.0/24[tcp/443],172.17.11.0/24[tcp/443]'
+ f'remote_ts = 172.17.10.0/24[tcp/443],172.17.11.0/24[tcp/443]',
+ f'mode = tunnel',
+ f'peer_{peer_ip.replace(".","-")}_tunnel_2',
+ f'local_ts = 10.1.0.0/16',
+ f'remote_ts = 10.2.0.0/16',
+ f'priority = {priority}',
+ f'mode = tunnel',
]
for line in swanctl_conf_lines:
self.assertIn(line, swanctl_conf)
@@ -213,6 +244,7 @@ class TestVPNIPsec(VyOSUnitTestSHIM.TestCase):
peer_base_path = base_path + ['site-to-site', 'peer', peer_ip]
self.cli_set(peer_base_path + ['authentication', 'mode', 'pre-shared-secret'])
self.cli_set(peer_base_path + ['authentication', 'pre-shared-secret', secret])
+ self.cli_set(peer_base_path + ['connection-type', 'none'])
self.cli_set(peer_base_path + ['ike-group', ike_group])
self.cli_set(peer_base_path + ['default-esp-group', esp_group])
self.cli_set(peer_base_path + ['local-address', local_address])
@@ -241,6 +273,7 @@ class TestVPNIPsec(VyOSUnitTestSHIM.TestCase):
f'mode = tunnel',
f'local_ts = 172.16.10.0/24,172.16.11.0/24',
f'remote_ts = 172.17.10.0/24,172.17.11.0/24',
+ f'start_action = none',
f'if_id_in = {if_id}', # will be 11 for vti10 - shifted by one
f'if_id_out = {if_id}',
f'updown = "/etc/ipsec.d/vti-up-down {vti}"'
@@ -392,5 +425,75 @@ class TestVPNIPsec(VyOSUnitTestSHIM.TestCase):
# There is only one VTI test so no need to delete this globally in tearDown()
self.cli_delete(vti_path)
+
+ def test_06_flex_vpn_vips(self):
+ local_address = '192.0.2.5'
+ local_id = 'vyos-r1'
+ remote_id = 'vyos-r2'
+ peer_base_path = base_path + ['site-to-site', 'peer', peer_ip]
+
+ self.cli_set(tunnel_path + ['tun1', 'encapsulation', 'gre'])
+ self.cli_set(tunnel_path + ['tun1', 'source-address', local_address])
+
+ self.cli_set(base_path + ['interface', interface])
+ self.cli_set(base_path + ['options', 'flexvpn'])
+ self.cli_set(base_path + ['options', 'interface', 'tun1'])
+ self.cli_set(base_path + ['ike-group', ike_group, 'ikev2-reauth', 'no'])
+ self.cli_set(base_path + ['ike-group', ike_group, 'key-exchange', 'ikev2'])
+
+ self.cli_set(peer_base_path + ['authentication', 'id', local_id])
+ self.cli_set(peer_base_path + ['authentication', 'mode', 'pre-shared-secret'])
+ self.cli_set(peer_base_path + ['authentication', 'pre-shared-secret', secret])
+ self.cli_set(peer_base_path + ['authentication', 'remote-id', remote_id])
+ self.cli_set(peer_base_path + ['connection-type', 'initiate'])
+ self.cli_set(peer_base_path + ['ike-group', ike_group])
+ self.cli_set(peer_base_path + ['default-esp-group', esp_group])
+ self.cli_set(peer_base_path + ['local-address', local_address])
+ self.cli_set(peer_base_path + ['tunnel', '1', 'protocol', 'gre'])
+
+ self.cli_set(peer_base_path + ['virtual-address', '203.0.113.55'])
+ self.cli_set(peer_base_path + ['virtual-address', '203.0.113.56'])
+
+ self.cli_commit()
+
+ # Verify strongSwan configuration
+ swanctl_conf = read_file(swanctl_file)
+ swanctl_conf_lines = [
+ f'version = 2',
+ f'vips = 203.0.113.55, 203.0.113.56',
+ f'life_time = 3600s', # default value
+ f'local_addrs = {local_address} # dhcp:no',
+ f'remote_addrs = {peer_ip}',
+ f'peer_{peer_ip.replace(".","-")}_tunnel_1',
+ f'mode = tunnel',
+ ]
+
+ for line in swanctl_conf_lines:
+ self.assertIn(line, swanctl_conf)
+
+ swanctl_secrets_lines = [
+ f'id-local = {local_address} # dhcp:no',
+ f'id-remote = {peer_ip}',
+ f'id-localid = {local_id}',
+ f'id-remoteid = {remote_id}',
+ f'secret = "{secret}"',
+ ]
+
+ for line in swanctl_secrets_lines:
+ self.assertIn(line, swanctl_conf)
+
+ # Verify charon configuration
+ charon_conf = read_file(charon_file)
+ charon_conf_lines = [
+ f'# Cisco FlexVPN',
+ f'cisco_flexvpn = yes',
+ f'install_virtual_ip = yes',
+ f'install_virtual_ip_on = tun1',
+ ]
+
+ for line in charon_conf_lines:
+ self.assertIn(line, charon_conf)
+
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_vpn_openconnect.py b/smoketest/scripts/cli/test_vpn_openconnect.py
index b0e859b5c..bda279342 100755
--- a/smoketest/scripts/cli/test_vpn_openconnect.py
+++ b/smoketest/scripts/cli/test_vpn_openconnect.py
@@ -24,8 +24,27 @@ OCSERV_CONF = '/run/ocserv/ocserv.conf'
base_path = ['vpn', 'openconnect']
pki_path = ['pki']
-cert_data = 'MIICFDCCAbugAwIBAgIUfMbIsB/ozMXijYgUYG80T1ry+mcwCgYIKoZIzj0EAwIwWTELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzESMBAGA1UEAwwJVnlPUyBUZXN0MB4XDTIxMDcyMDEyNDUxMloXDTI2MDcxOTEyNDUxMlowWTELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzESMBAGA1UEAwwJVnlPUyBUZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE01HrLcNttqq4/PtoMua8rMWEkOdBu7vP94xzDO7A8C92ls1v86eePy4QllKCzIw3QxBIoCuH2peGRfWgPRdFsKNhMF8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMB0GA1UdDgQWBBSu+JnU5ZC4mkuEpqg2+Mk4K79oeDAKBggqhkjOPQQDAgNHADBEAiBEFdzQ/Bc3LftzngrY605UhA6UprHhAogKgROv7iR4QgIgEFUxTtW3xXJcnUPWhhUFhyZoqfn8dE93+dm/LDnp7C0='
-key_data = 'MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgPLpD0Ohhoq0g4nhx2KMIuze7ucKUt/lBEB2wc03IxXyhRANCAATTUestw222qrj8+2gy5rysxYSQ50G7u8/3jHMM7sDwL3aWzW/zp54/LhCWUoLMjDdDEEigK4fal4ZF9aA9F0Ww'
+
+cert_data = """
+MIICFDCCAbugAwIBAgIUfMbIsB/ozMXijYgUYG80T1ry+mcwCgYIKoZIzj0EAwIw
+WTELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNv
+bWUtQ2l0eTENMAsGA1UECgwEVnlPUzESMBAGA1UEAwwJVnlPUyBUZXN0MB4XDTIx
+MDcyMDEyNDUxMloXDTI2MDcxOTEyNDUxMlowWTELMAkGA1UEBhMCR0IxEzARBgNV
+BAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlP
+UzESMBAGA1UEAwwJVnlPUyBUZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
+01HrLcNttqq4/PtoMua8rMWEkOdBu7vP94xzDO7A8C92ls1v86eePy4QllKCzIw3
+QxBIoCuH2peGRfWgPRdFsKNhMF8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
+BAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMB0GA1UdDgQWBBSu
++JnU5ZC4mkuEpqg2+Mk4K79oeDAKBggqhkjOPQQDAgNHADBEAiBEFdzQ/Bc3Lftz
+ngrY605UhA6UprHhAogKgROv7iR4QgIgEFUxTtW3xXJcnUPWhhUFhyZoqfn8dE93
++dm/LDnp7C0=
+"""
+
+key_data = """
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgPLpD0Ohhoq0g4nhx
+2KMIuze7ucKUt/lBEB2wc03IxXyhRANCAATTUestw222qrj8+2gy5rysxYSQ50G7
+u8/3jHMM7sDwL3aWzW/zp54/LhCWUoLMjDdDEEigK4fal4ZF9aA9F0Ww
+"""
class TestVpnOpenconnect(VyOSUnitTestSHIM.TestCase):
def tearDown(self):
@@ -37,18 +56,21 @@ class TestVpnOpenconnect(VyOSUnitTestSHIM.TestCase):
def test_vpn(self):
user = 'vyos_user'
password = 'vyos_pass'
+ otp = '37500000026900000000200000000000'
+
self.cli_delete(pki_path)
self.cli_delete(base_path)
- self.cli_set(pki_path + ['ca', 'openconnect', 'certificate', cert_data])
- self.cli_set(pki_path + ['certificate', 'openconnect', 'certificate', cert_data])
- self.cli_set(pki_path + ['certificate', 'openconnect', 'private', 'key', key_data])
+ self.cli_set(pki_path + ['ca', 'openconnect', 'certificate', cert_data.replace('\n','')])
+ self.cli_set(pki_path + ['certificate', 'openconnect', 'certificate', cert_data.replace('\n','')])
+ self.cli_set(pki_path + ['certificate', 'openconnect', 'private', 'key', key_data.replace('\n','')])
- self.cli_set(base_path + ["authentication", "local-users", "username", user, "password", password])
- self.cli_set(base_path + ["authentication", "mode", "local"])
- self.cli_set(base_path + ["network-settings", "client-ip-settings", "subnet", "192.0.2.0/24"])
- self.cli_set(base_path + ["ssl", "ca-certificate", 'openconnect'])
- self.cli_set(base_path + ["ssl", "certificate", 'openconnect'])
+ self.cli_set(base_path + ['authentication', 'local-users', 'username', user, 'password', password])
+ self.cli_set(base_path + ['authentication', 'local-users', 'username', user, 'otp', 'key', otp])
+ self.cli_set(base_path + ['authentication', 'mode', 'local', 'password-otp'])
+ self.cli_set(base_path + ['network-settings', 'client-ip-settings', 'subnet', '192.0.2.0/24'])
+ self.cli_set(base_path + ['ssl', 'ca-certificate', 'openconnect'])
+ self.cli_set(base_path + ['ssl', 'certificate', 'openconnect'])
self.cli_commit()
diff --git a/smoketest/scripts/cli/test_vrf.py b/smoketest/scripts/cli/test_vrf.py
index 5ffa9c086..176c095fb 100755
--- a/smoketest/scripts/cli/test_vrf.py
+++ b/smoketest/scripts/cli/test_vrf.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright (C) 2020-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -25,9 +25,10 @@ from base_vyostest_shim import VyOSUnitTestSHIM
from vyos.configsession import ConfigSessionError
from vyos.ifconfig import Interface
from vyos.ifconfig import Section
-from vyos.template import is_ipv6
+from vyos.template import is_ipv4
from vyos.util import cmd
from vyos.util import read_file
+from vyos.util import get_interface_config
from vyos.validate import is_intf_addr_assigned
base_path = ['vrf']
@@ -48,7 +49,7 @@ class VRFTest(VyOSUnitTestSHIM.TestCase):
if not '.' in tmp:
cls._interfaces.append(tmp)
# call base-classes classmethod
- super(cls, cls).setUpClass()
+ super(VRFTest, cls).setUpClass()
def tearDown(self):
# delete all VRFs
@@ -105,10 +106,13 @@ class VRFTest(VyOSUnitTestSHIM.TestCase):
frrconfig = self.getFRRconfig(f'vrf {vrf}')
self.assertIn(f' vni {table}', frrconfig)
+ tmp = get_interface_config(vrf)
+ self.assertEqual(int(table), tmp['linkinfo']['info_data']['table'])
+
# Increment table ID for the next run
table = str(int(table) + 1)
- def test_vrf_loopback_ips(self):
+ def test_vrf_loopbacks_ips(self):
table = '2000'
for vrf in vrfs:
base = base_path + ['name', vrf]
@@ -119,10 +123,16 @@ class VRFTest(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify VRF configuration
+ loopbacks = ['127.0.0.1', '::1']
for vrf in vrfs:
- self.assertTrue(vrf in interfaces())
- self.assertTrue(is_intf_addr_assigned(vrf, '127.0.0.1'))
- self.assertTrue(is_intf_addr_assigned(vrf, '::1'))
+ # Ensure VRF was created
+ self.assertIn(vrf, interfaces())
+ # Verify IP forwarding is 1 (enabled)
+ self.assertEqual(read_file(f'/proc/sys/net/ipv4/conf/{vrf}/forwarding'), '1')
+ self.assertEqual(read_file(f'/proc/sys/net/ipv6/conf/{vrf}/forwarding'), '1')
+ # Test for proper loopback IP assignment
+ for addr in loopbacks:
+ self.assertTrue(is_intf_addr_assigned(vrf, addr))
def test_vrf_bind_all(self):
table = '2000'
@@ -174,11 +184,11 @@ class VRFTest(VyOSUnitTestSHIM.TestCase):
# commit changes
self.cli_commit()
- # Verify & cleanup
+ # Verify VRF assignmant
for interface in self._interfaces:
- # os.readlink resolves to: '../../../../../virtual/net/foovrf'
- tmp = os.readlink(f'/sys/class/net/{interface}/master').split('/')[-1]
- self.assertEqual(tmp, vrf)
+ tmp = get_interface_config(interface)
+ self.assertEqual(vrf, tmp['master'])
+
# cleanup
section = Section.section(interface)
self.cli_delete(['interfaces', section, interface, 'vrf'])
@@ -220,5 +230,66 @@ class VRFTest(VyOSUnitTestSHIM.TestCase):
# Increment table ID for the next run
table = str(int(table) + 1)
+ def test_vrf_link_local_ip_addresses(self):
+ # Testcase for issue T4331
+ table = '100'
+ vrf = 'orange'
+ interface = 'dum9998'
+ addresses = ['192.0.2.1/26', '2001:db8:9998::1/64', 'fe80::1/64']
+
+ for address in addresses:
+ self.cli_set(['interfaces', 'dummy', interface, 'address', address])
+
+ # Create dummy interfaces
+ self.cli_commit()
+
+ # ... and verify IP addresses got assigned
+ for address in addresses:
+ self.assertTrue(is_intf_addr_assigned(interface, address))
+
+ # Move interface to VRF
+ self.cli_set(base_path + ['name', vrf, 'table', table])
+ self.cli_set(['interfaces', 'dummy', interface, 'vrf', vrf])
+
+ # Apply VRF config
+ self.cli_commit()
+ # Ensure VRF got created
+ self.assertIn(vrf, interfaces())
+ # ... and IP addresses are still assigned
+ for address in addresses:
+ self.assertTrue(is_intf_addr_assigned(interface, address))
+ # Verify VRF table ID
+ tmp = get_interface_config(vrf)
+ self.assertEqual(int(table), tmp['linkinfo']['info_data']['table'])
+
+ # Verify interface is assigned to VRF
+ tmp = get_interface_config(interface)
+ self.assertEqual(vrf, tmp['master'])
+
+ # Delete Interface
+ self.cli_delete(['interfaces', 'dummy', interface])
+ self.cli_commit()
+
+ def test_vrf_disable_forwarding(self):
+ table = '2000'
+ for vrf in vrfs:
+ base = base_path + ['name', vrf]
+ self.cli_set(base + ['table', table])
+ self.cli_set(base + ['ip', 'disable-forwarding'])
+ self.cli_set(base + ['ipv6', 'disable-forwarding'])
+ table = str(int(table) + 1)
+
+ # commit changes
+ self.cli_commit()
+
+ # Verify VRF configuration
+ loopbacks = ['127.0.0.1', '::1']
+ for vrf in vrfs:
+ # Ensure VRF was created
+ self.assertIn(vrf, interfaces())
+ # Verify IP forwarding is 0 (disabled)
+ self.assertEqual(read_file(f'/proc/sys/net/ipv4/conf/{vrf}/forwarding'), '0')
+ self.assertEqual(read_file(f'/proc/sys/net/ipv6/conf/{vrf}/forwarding'), '0')
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_zone_policy.py b/smoketest/scripts/cli/test_zone_policy.py
new file mode 100755
index 000000000..2c580e2f1
--- /dev/null
+++ b/smoketest/scripts/cli/test_zone_policy.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021-2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import unittest
+
+from base_vyostest_shim import VyOSUnitTestSHIM
+
+from vyos.util import cmd
+
+class TestZonePolicy(VyOSUnitTestSHIM.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ super(TestZonePolicy, cls).setUpClass()
+ cls.cli_set(cls, ['firewall', 'name', 'smoketest', 'default-action', 'drop'])
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.cli_delete(cls, ['firewall'])
+ super(TestZonePolicy, cls).tearDownClass()
+
+ def tearDown(self):
+ self.cli_delete(['zone-policy'])
+ self.cli_commit()
+
+ def test_basic_zone(self):
+ self.cli_set(['zone-policy', 'zone', 'smoketest-eth0', 'interface', 'eth0'])
+ self.cli_set(['zone-policy', 'zone', 'smoketest-eth0', 'from', 'smoketest-local', 'firewall', 'name', 'smoketest'])
+ self.cli_set(['zone-policy', 'zone', 'smoketest-local', 'local-zone'])
+ self.cli_set(['zone-policy', 'zone', 'smoketest-local', 'from', 'smoketest-eth0', 'firewall', 'name', 'smoketest'])
+
+ self.cli_commit()
+
+ nftables_search = [
+ ['chain VZONE_smoketest-eth0'],
+ ['chain VZONE_smoketest-local_IN'],
+ ['chain VZONE_smoketest-local_OUT'],
+ ['oifname { "eth0" }', 'jump VZONE_smoketest-eth0'],
+ ['jump VZONE_smoketest-local_IN'],
+ ['jump VZONE_smoketest-local_OUT'],
+ ['iifname { "eth0" }', 'jump NAME_smoketest'],
+ ['oifname { "eth0" }', 'jump NAME_smoketest']
+ ]
+
+ nftables_output = cmd('sudo nft list table ip filter')
+
+ for search in nftables_search:
+ matched = False
+ for line in nftables_output.split("\n"):
+ if all(item in line for item in search):
+ matched = True
+ break
+ self.assertTrue(matched)
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/src/conf_mode/arp.py b/src/conf_mode/arp.py
index aac07bd80..1cd8f5451 100755
--- a/src/conf_mode/arp.py
+++ b/src/conf_mode/arp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018 VyOS maintainers and contributors
+# Copyright (C) 2018-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -13,92 +13,62 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-#
-import sys
-import os
-import re
-import syslog as sl
+from sys import exit
from vyos.config import Config
+from vyos.configdict import node_changed
from vyos.util import call
from vyos import ConfigError
-
from vyos import airbag
airbag.enable()
-arp_cmd = '/usr/sbin/arp'
-
-def get_config():
- c = Config()
- if not c.exists('protocols static arp'):
- return None
-
- c.set_level('protocols static')
- config_data = {}
-
- for ip_addr in c.list_nodes('arp'):
- config_data.update(
- {
- ip_addr : c.return_value('arp ' + ip_addr + ' hwaddr')
- }
- )
+def get_config(config=None):
+ if config:
+ conf = config
+ else:
+ conf = Config()
- return config_data
+ base = ['protocols', 'static', 'arp']
+ arp = conf.get_config_dict(base, get_first_key=True)
-def generate(c):
- c_eff = Config()
- c_eff.set_level('protocols static')
- c_eff_cnf = {}
- for ip_addr in c_eff.list_effective_nodes('arp'):
- c_eff_cnf.update(
- {
- ip_addr : c_eff.return_effective_value('arp ' + ip_addr + ' hwaddr')
- }
- )
+ if 'interface' in arp:
+ for interface in arp['interface']:
+ tmp = node_changed(conf, base + ['interface', interface, 'address'], recursive=True)
+ if tmp: arp['interface'][interface].update({'address_old' : tmp})
- config_data = {
- 'remove' : [],
- 'update' : {}
- }
- ### removal
- if c == None:
- for ip_addr in c_eff_cnf:
- config_data['remove'].append(ip_addr)
- else:
- for ip_addr in c_eff_cnf:
- if not ip_addr in c or c[ip_addr] == None:
- config_data['remove'].append(ip_addr)
+ return arp
- ### add/update
- if c != None:
- for ip_addr in c:
- if not ip_addr in c_eff_cnf:
- config_data['update'][ip_addr] = c[ip_addr]
- if ip_addr in c_eff_cnf:
- if c[ip_addr] != c_eff_cnf[ip_addr] and c[ip_addr] != None:
- config_data['update'][ip_addr] = c[ip_addr]
+def verify(arp):
+ pass
- return config_data
+def generate(arp):
+ pass
-def apply(c):
- for ip_addr in c['remove']:
- sl.syslog(sl.LOG_NOTICE, "arp -d " + ip_addr)
- call(f'{arp_cmd} -d {ip_addr} >/dev/null 2>&1')
+def apply(arp):
+ if not arp:
+ return None
- for ip_addr in c['update']:
- sl.syslog(sl.LOG_NOTICE, "arp -s " + ip_addr + " " + c['update'][ip_addr])
- updated = c['update'][ip_addr]
- call(f'{arp_cmd} -s {ip_addr} {updated}')
+ if 'interface' in arp:
+ for interface, interface_config in arp['interface'].items():
+ # Delete old static ARP assignments first
+ if 'address_old' in interface_config:
+ for address in interface_config['address_old']:
+ call(f'ip neigh del {address} dev {interface}')
+ # Add new static ARP entries to interface
+ if 'address' not in interface_config:
+ continue
+ for address, address_config in interface_config['address'].items():
+ mac = address_config['mac']
+ call(f'ip neigh add {address} lladdr {mac} dev {interface}')
if __name__ == '__main__':
- try:
- c = get_config()
- ## syntax verification is done via cli
- config = generate(c)
- apply(config)
- except ConfigError as e:
- print(e)
- sys.exit(1)
+ try:
+ c = get_config()
+ verify(c)
+ generate(c)
+ apply(c)
+ except ConfigError as e:
+ print(e)
+ exit(1)
diff --git a/src/conf_mode/bcast_relay.py b/src/conf_mode/bcast_relay.py
index d93a2a8f4..39a2971ce 100755
--- a/src/conf_mode/bcast_relay.py
+++ b/src/conf_mode/bcast_relay.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2017-2020 VyOS maintainers and contributors
+# Copyright (C) 2017-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -78,7 +78,7 @@ def generate(relay):
continue
config['instance'] = instance
- render(config_file_base + instance, 'bcast-relay/udp-broadcast-relay.tmpl',
+ render(config_file_base + instance, 'bcast-relay/udp-broadcast-relay.j2',
config)
return None
diff --git a/src/conf_mode/conntrack.py b/src/conf_mode/conntrack.py
index 68877f794..82289526f 100755
--- a/src/conf_mode/conntrack.py
+++ b/src/conf_mode/conntrack.py
@@ -15,11 +15,14 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
+import re
from sys import exit
from vyos.config import Config
from vyos.configdict import dict_merge
+from vyos.firewall import find_nftables_rule
+from vyos.firewall import remove_nftables_rule
from vyos.util import cmd
from vyos.util import run
from vyos.util import process_named_running
@@ -32,6 +35,7 @@ airbag.enable()
conntrack_config = r'/etc/modprobe.d/vyatta_nf_conntrack.conf'
sysctl_file = r'/run/sysctl/10-vyos-conntrack.conf'
+nftables_ct_file = r'/run/nftables-ct.conf'
# Every ALG (Application Layer Gateway) consists of either a Kernel Object
# also called a Kernel Module/Driver or some rules present in iptables
@@ -43,8 +47,8 @@ module_map = {
'ko' : ['nf_nat_h323', 'nf_conntrack_h323'],
},
'nfs' : {
- 'iptables' : ['VYATTA_CT_HELPER --table raw --proto tcp --dport 111 --jump CT --helper rpc',
- 'VYATTA_CT_HELPER --table raw --proto udp --dport 111 --jump CT --helper rpc'],
+ 'nftables' : ['ct helper set "rpc_tcp" tcp dport "{111}" return',
+ 'ct helper set "rpc_udp" udp dport "{111}" return']
},
'pptp' : {
'ko' : ['nf_nat_pptp', 'nf_conntrack_pptp'],
@@ -53,9 +57,7 @@ module_map = {
'ko' : ['nf_nat_sip', 'nf_conntrack_sip'],
},
'sqlnet' : {
- 'iptables' : ['VYATTA_CT_HELPER --table raw --proto tcp --dport 1521 --jump CT --helper tns',
- 'VYATTA_CT_HELPER --table raw --proto tcp --dport 1525 --jump CT --helper tns',
- 'VYATTA_CT_HELPER --table raw --proto tcp --dport 1536 --jump CT --helper tns'],
+ 'nftables' : ['ct helper set "tns_tcp" tcp dport "{1521,1525,1536}" return']
},
'tftp' : {
'ko' : ['nf_nat_tftp', 'nf_conntrack_tftp'],
@@ -80,19 +82,49 @@ def get_config(config=None):
# We have gathered the dict representation of the CLI, but there are default
# options which we need to update into the dictionary retrived.
default_values = defaults(base)
+ # XXX: T2665: we can not safely rely on the defaults() when there are
+ # tagNodes in place, it is better to blend in the defaults manually.
+ if 'timeout' in default_values and 'custom' in default_values['timeout']:
+ del default_values['timeout']['custom']
conntrack = dict_merge(default_values, conntrack)
return conntrack
def verify(conntrack):
+ if dict_search('ignore.rule', conntrack) != None:
+ for rule, rule_config in conntrack['ignore']['rule'].items():
+ if dict_search('destination.port', rule_config) or \
+ dict_search('source.port', rule_config):
+ if 'protocol' not in rule_config or rule_config['protocol'] not in ['tcp', 'udp']:
+ raise ConfigError(f'Port requires tcp or udp as protocol in rule {rule}')
+
return None
def generate(conntrack):
- render(conntrack_config, 'conntrack/vyos_nf_conntrack.conf.tmpl', conntrack)
- render(sysctl_file, 'conntrack/sysctl.conf.tmpl', conntrack)
+ render(conntrack_config, 'conntrack/vyos_nf_conntrack.conf.j2', conntrack)
+ render(sysctl_file, 'conntrack/sysctl.conf.j2', conntrack)
+ render(nftables_ct_file, 'conntrack/nftables-ct.j2', conntrack)
+
+ # dry-run newly generated configuration
+ tmp = run(f'nft -c -f {nftables_ct_file}')
+ if tmp > 0:
+ if os.path.exists(nftables_ct_file):
+ os.unlink(nftables_ct_file)
+ raise ConfigError('Configuration file errors encountered!')
return None
+def find_nftables_ct_rule(rule):
+ helper_search = re.search('ct helper set "(\w+)"', rule)
+ if helper_search:
+ rule = helper_search[1]
+ return find_nftables_rule('raw', 'VYOS_CT_HELPER', [rule])
+
+def find_remove_rule(rule):
+ handle = find_nftables_ct_rule(rule)
+ if handle:
+ remove_nftables_rule('raw', 'VYOS_CT_HELPER', handle)
+
def apply(conntrack):
# Depending on the enable/disable state of the ALG (Application Layer Gateway)
# modules we need to either insmod or rmmod the helpers.
@@ -103,20 +135,20 @@ def apply(conntrack):
# Only remove the module if it's loaded
if os.path.exists(f'/sys/module/{mod}'):
cmd(f'rmmod {mod}')
- if 'iptables' in module_config:
- for rule in module_config['iptables']:
- # Only install iptables rule if it does not exist
- tmp = run(f'iptables --check {rule}')
- if tmp == 0: cmd(f'iptables --delete {rule}')
+ if 'nftables' in module_config:
+ for rule in module_config['nftables']:
+ find_remove_rule(rule)
else:
if 'ko' in module_config:
for mod in module_config['ko']:
cmd(f'modprobe {mod}')
- if 'iptables' in module_config:
- for rule in module_config['iptables']:
- # Only install iptables rule if it does not exist
- tmp = run(f'iptables --check {rule}')
- if tmp > 0: cmd(f'iptables --insert {rule}')
+ if 'nftables' in module_config:
+ for rule in module_config['nftables']:
+ if not find_nftables_ct_rule(rule):
+ cmd(f'nft insert rule ip raw VYOS_CT_HELPER {rule}')
+
+ # Load new nftables ruleset
+ cmd(f'nft -f {nftables_ct_file}')
if process_named_running('conntrackd'):
# Reload conntrack-sync daemon to fetch new sysctl values
diff --git a/src/conf_mode/conntrack_sync.py b/src/conf_mode/conntrack_sync.py
index f82a077e6..c4b2bb488 100755
--- a/src/conf_mode/conntrack_sync.py
+++ b/src/conf_mode/conntrack_sync.py
@@ -36,7 +36,7 @@ airbag.enable()
config_file = '/run/conntrackd/conntrackd.conf'
def resync_vrrp():
- tmp = run('/usr/libexec/vyos/conf_mode/vrrp.py')
+ tmp = run('/usr/libexec/vyos/conf_mode/high-availability.py')
if tmp > 0:
print('ERROR: error restarting VRRP daemon!')
@@ -93,9 +93,9 @@ def verify(conntrack):
raise ConfigError('Can not configure expect-sync "all" with other protocols!')
if 'listen_address' in conntrack:
- address = conntrack['listen_address']
- if not is_addr_assigned(address):
- raise ConfigError(f'Specified listen-address {address} not assigned to any interface!')
+ for address in conntrack['listen_address']:
+ if not is_addr_assigned(address):
+ raise ConfigError(f'Specified listen-address {address} not assigned to any interface!')
vrrp_group = dict_search('failover_mechanism.vrrp.sync_group', conntrack)
if vrrp_group == None:
@@ -111,11 +111,12 @@ def generate(conntrack):
os.unlink(config_file)
return None
- render(config_file, 'conntrackd/conntrackd.conf.tmpl', conntrack)
+ render(config_file, 'conntrackd/conntrackd.conf.j2', conntrack)
return None
def apply(conntrack):
+ systemd_service = 'conntrackd.service'
if not conntrack:
# Failover mechanism daemon should be indicated that it no longer needs
# to execute conntrackd actions on transition. This is only required
@@ -123,7 +124,7 @@ def apply(conntrack):
if process_named_running('conntrackd'):
resync_vrrp()
- call('systemctl stop conntrackd.service')
+ call(f'systemctl stop {systemd_service}')
return None
# Failover mechanism daemon should be indicated that it needs to execute
@@ -132,7 +133,7 @@ def apply(conntrack):
if not process_named_running('conntrackd'):
resync_vrrp()
- call('systemctl restart conntrackd.service')
+ call(f'systemctl reload-or-restart {systemd_service}')
return None
if __name__ == '__main__':
diff --git a/src/conf_mode/containers.py b/src/conf_mode/container.py
index 2e14e0b25..2110fd9e0 100755
--- a/src/conf_mode/containers.py
+++ b/src/conf_mode/container.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -15,20 +15,19 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
-import json
from ipaddress import ip_address
from ipaddress import ip_network
from time import sleep
from json import dumps as json_write
+from vyos.base import Warning
from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.configdict import node_changed
from vyos.util import call
from vyos.util import cmd
from vyos.util import run
-from vyos.util import read_file
from vyos.util import write_file
from vyos.template import inc_ip
from vyos.template import is_ipv4
@@ -42,6 +41,20 @@ airbag.enable()
config_containers_registry = '/etc/containers/registries.conf'
config_containers_storage = '/etc/containers/storage.conf'
+def _run_rerun(container_cmd):
+ counter = 0
+ while True:
+ if counter >= 10:
+ break
+ try:
+ _cmd(container_cmd)
+ break
+ except:
+ counter = counter +1
+ sleep(0.5)
+
+ return None
+
def _cmd(command):
if os.path.exists('/tmp/vyos.container.debug'):
print(command)
@@ -77,10 +90,10 @@ def get_config(config=None):
container['name'][name] = dict_merge(default_values, container['name'][name])
# Delete container network, delete containers
- tmp = node_changed(conf, ['container', 'network'])
+ tmp = node_changed(conf, base + ['container', 'network'])
if tmp: container.update({'network_remove' : tmp})
- tmp = node_changed(conf, ['container', 'name'])
+ tmp = node_changed(conf, base + ['container', 'name'])
if tmp: container.update({'container_remove' : tmp})
return container
@@ -93,6 +106,26 @@ def verify(container):
# Add new container
if 'name' in container:
for name, container_config in container['name'].items():
+ # Container image is a mandatory option
+ if 'image' not in container_config:
+ raise ConfigError(f'Container image for "{name}" is mandatory!')
+
+ # Check if requested container image exists locally. If it does not
+ # exist locally - inform the user. This is required as there is a
+ # shared container image storage accross all VyOS images. A user can
+ # delete a container image from the system, boot into another version
+ # of VyOS and then it would fail to boot. This is to prevent any
+ # configuration error when container images are deleted from the
+ # global storage. A per image local storage would be a super waste
+ # of diskspace as there will be a full copy (up tu several GB/image)
+ # on upgrade. This is the "cheapest" and fastest solution in terms
+ # of image upgrade and deletion.
+ image = container_config['image']
+ if run(f'podman image exists {image}') != 0:
+ Warning(f'Image "{image}" used in contianer "{name}" does not exist '\
+ f'locally. Please use "add container image {image}" to add it '\
+ f'to the system! Container "{name}" will not be started!')
+
if 'network' in container_config:
if len(container_config['network']) > 1:
raise ConfigError(f'Only one network can be specified for container "{name}"!')
@@ -122,6 +155,18 @@ def verify(container):
raise ConfigError(f'IP address "{address}" can not be used for a container, '\
'reserved for the container engine!')
+ if 'device' in container_config:
+ for dev, dev_config in container_config['device'].items():
+ if 'source' not in dev_config:
+ raise ConfigError(f'Device "{dev}" has no source path configured!')
+
+ if 'destination' not in dev_config:
+ raise ConfigError(f'Device "{dev}" has no destination path configured!')
+
+ source = dev_config['source']
+ if not os.path.exists(source):
+ raise ConfigError(f'Device "{dev}" source path "{source}" does not exist!')
+
if 'environment' in container_config:
for var, cfg in container_config['environment'].items():
if 'value' not in cfg:
@@ -139,10 +184,6 @@ def verify(container):
if not os.path.exists(source):
raise ConfigError(f'Volume "{volume}" source path "{source}" does not exist!')
- # Container image is a mandatory option
- if 'image' not in container_config:
- raise ConfigError(f'Container image for "{name}" is mandatory!')
-
# If 'allow-host-networks' or 'network' not set.
if 'allow_host_networks' not in container_config and 'network' not in container_config:
raise ConfigError(f'Must either set "network" or "allow-host-networks" for container "{name}"!')
@@ -182,6 +223,10 @@ def verify(container):
def generate(container):
# bail out early - looks like removal from running config
if not container:
+ if os.path.exists(config_containers_registry):
+ os.unlink(config_containers_registry)
+ if os.path.exists(config_containers_storage):
+ os.unlink(config_containers_storage)
return None
if 'network' in container:
@@ -215,8 +260,8 @@ def generate(container):
write_file(f'/etc/cni/net.d/{network}.conflist', json_write(tmp, indent=2))
- render(config_containers_registry, 'containers/registry.tmpl', container)
- render(config_containers_storage, 'containers/storage.tmpl', container)
+ render(config_containers_registry, 'container/registries.conf.j2', container)
+ render(config_containers_storage, 'container/storage.conf.j2', container)
return None
@@ -240,6 +285,11 @@ def apply(container):
for name, container_config in container['name'].items():
image = container_config['image']
+ if run(f'podman image exists {image}') != 0:
+ # container image does not exist locally - user already got
+ # informed by a WARNING in verfiy() - bail out early
+ continue
+
if 'disable' in container_config:
# check if there is a container by that name running
tmp = _cmd('podman ps -a --format "{{.Names}}"')
@@ -251,13 +301,6 @@ def apply(container):
memory = container_config['memory']
restart = container_config['restart']
- # Check if requested container image exists locally. If it does not, we
- # pull it. print() is the best way to have a good response from the
- # polling process to the user to display progress. If the image exists
- # locally, a user can update it running `update container image <name>`
- tmp = run(f'podman image exists {image}')
- if tmp != 0: print(os.system(f'podman pull {image}'))
-
# Add capability options. Should be in uppercase
cap_add = ''
if 'cap_add' in container_config:
@@ -266,6 +309,14 @@ def apply(container):
c = c.replace('-', '_')
cap_add += f' --cap-add={c}'
+ # Add a host device to the container /dev/x:/dev/x
+ device = ''
+ if 'device' in container_config:
+ for dev, dev_config in container_config['device'].items():
+ source_dev = dev_config['source']
+ dest_dev = dev_config['destination']
+ device += f' --device={source_dev}:{dest_dev}'
+
# Check/set environment options "-e foo=bar"
env_opt = ''
if 'environment' in container_config:
@@ -296,9 +347,9 @@ def apply(container):
container_base_cmd = f'podman run --detach --interactive --tty --replace {cap_add} ' \
f'--memory {memory}m --memory-swap 0 --restart {restart} ' \
- f'--name {name} {port} {volume} {env_opt}'
+ f'--name {name} {device} {port} {volume} {env_opt}'
if 'allow_host_networks' in container_config:
- _cmd(f'{container_base_cmd} --net host {image}')
+ _run_rerun(f'{container_base_cmd} --net host {image}')
else:
for network in container_config['network']:
ipparam = ''
@@ -306,16 +357,7 @@ def apply(container):
address = container_config['network'][network]['address']
ipparam = f'--ip {address}'
- counter = 0
- while True:
- if counter >= 10:
- break
- try:
- _cmd(f'{container_base_cmd} --net {network} {ipparam} {image}')
- break
- except:
- counter = counter +1
- sleep(0.5)
+ _run_rerun(f'{container_base_cmd} --net {network} {ipparam} {image}')
return None
diff --git a/src/conf_mode/dhcp_relay.py b/src/conf_mode/dhcp_relay.py
index 6352e0b4a..4de2ca2f3 100755
--- a/src/conf_mode/dhcp_relay.py
+++ b/src/conf_mode/dhcp_relay.py
@@ -66,18 +66,19 @@ def generate(relay):
if not relay:
return None
- render(config_file, 'dhcp-relay/dhcrelay.conf.tmpl', relay)
+ render(config_file, 'dhcp-relay/dhcrelay.conf.j2', relay)
return None
def apply(relay):
# bail out early - looks like removal from running config
+ service_name = 'isc-dhcp-relay.service'
if not relay:
- call('systemctl stop isc-dhcp-relay.service')
+ call(f'systemctl stop {service_name}')
if os.path.exists(config_file):
os.unlink(config_file)
return None
- call('systemctl restart isc-dhcp-relay.service')
+ call(f'systemctl restart {service_name}')
return None
diff --git a/src/conf_mode/dhcp_server.py b/src/conf_mode/dhcp_server.py
index a8cef5ebf..52b682d6d 100755
--- a/src/conf_mode/dhcp_server.py
+++ b/src/conf_mode/dhcp_server.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2021 VyOS maintainers and contributors
+# Copyright (C) 2018-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -109,7 +109,7 @@ def get_config(config=None):
if not conf.exists(base):
return None
- dhcp = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
+ dhcp = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True, no_tag_node_value_mangle=True)
# T2665: defaults include lease time per TAG node which need to be added to
# individual subnet definitions
default_values = defaults(base + ['shared-network-name', 'subnet'])
@@ -286,7 +286,7 @@ def generate(dhcp):
# Please see: https://phabricator.vyos.net/T1129 for quoting of the raw
# parameters we can pass to ISC DHCPd
tmp_file = '/tmp/dhcpd.conf'
- render(tmp_file, 'dhcp-server/dhcpd.conf.tmpl', dhcp,
+ render(tmp_file, 'dhcp-server/dhcpd.conf.j2', dhcp,
formater=lambda _: _.replace("&quot;", '"'))
# XXX: as we have the ability for a user to pass in "raw" options via VyOS
# CLI (see T3544) we now ask ISC dhcpd to test the newly rendered
@@ -299,7 +299,7 @@ def generate(dhcp):
# Now that we know that the newly rendered configuration is "good" we can
# render the "real" configuration
- render(config_file, 'dhcp-server/dhcpd.conf.tmpl', dhcp,
+ render(config_file, 'dhcp-server/dhcpd.conf.j2', dhcp,
formater=lambda _: _.replace("&quot;", '"'))
return None
diff --git a/src/conf_mode/dhcpv6_relay.py b/src/conf_mode/dhcpv6_relay.py
index aea2c3b73..c1bd51f62 100755
--- a/src/conf_mode/dhcpv6_relay.py
+++ b/src/conf_mode/dhcpv6_relay.py
@@ -82,19 +82,20 @@ def generate(relay):
if not relay:
return None
- render(config_file, 'dhcp-relay/dhcrelay6.conf.tmpl', relay)
+ render(config_file, 'dhcp-relay/dhcrelay6.conf.j2', relay)
return None
def apply(relay):
# bail out early - looks like removal from running config
+ service_name = 'isc-dhcp-relay6.service'
if not relay:
# DHCPv6 relay support is removed in the commit
- call('systemctl stop isc-dhcp-relay6.service')
+ call(f'systemctl stop {service_name}')
if os.path.exists(config_file):
os.unlink(config_file)
return None
- call('systemctl restart isc-dhcp-relay6.service')
+ call(f'systemctl restart {service_name}')
return None
diff --git a/src/conf_mode/dhcpv6_server.py b/src/conf_mode/dhcpv6_server.py
index e6a2e4486..078ff327c 100755
--- a/src/conf_mode/dhcpv6_server.py
+++ b/src/conf_mode/dhcpv6_server.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2020 VyOS maintainers and contributors
+# Copyright (C) 2018-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -41,7 +41,9 @@ def get_config(config=None):
if not conf.exists(base):
return None
- dhcpv6 = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
+ dhcpv6 = conf.get_config_dict(base, key_mangling=('-', '_'),
+ get_first_key=True,
+ no_tag_node_value_mangle=True)
return dhcpv6
def verify(dhcpv6):
@@ -51,7 +53,7 @@ def verify(dhcpv6):
# If DHCP is enabled we need one share-network
if 'shared_network_name' not in dhcpv6:
- raise ConfigError('No DHCPv6 shared networks configured. At least\n' \
+ raise ConfigError('No DHCPv6 shared networks configured. At least '\
'one DHCPv6 shared network must be configured.')
# Inspect shared-network/subnet
@@ -60,8 +62,9 @@ def verify(dhcpv6):
for network, network_config in dhcpv6['shared_network_name'].items():
# A shared-network requires a subnet definition
if 'subnet' not in network_config:
- raise ConfigError(f'No DHCPv6 lease subnets configured for "{network}". At least one\n' \
- 'lease subnet must be configured for each shared network!')
+ raise ConfigError(f'No DHCPv6 lease subnets configured for "{network}". '\
+ 'At least one lease subnet must be configured for '\
+ 'each shared network!')
for subnet, subnet_config in network_config['subnet'].items():
if 'address_range' in subnet_config:
@@ -83,20 +86,20 @@ def verify(dhcpv6):
# Stop address must be greater or equal to start address
if not ip_address(stop) >= ip_address(start):
- raise ConfigError(f'address-range stop address "{stop}" must be greater or equal\n' \
+ raise ConfigError(f'address-range stop address "{stop}" must be greater then or equal ' \
f'to the range start address "{start}"!')
# DHCPv6 range start address must be unique - two ranges can't
# start with the same address - makes no sense
if start in range6_start:
- raise ConfigError(f'Conflicting DHCPv6 lease range:\n' \
+ raise ConfigError(f'Conflicting DHCPv6 lease range: '\
f'Pool start address "{start}" defined multipe times!')
range6_start.append(start)
# DHCPv6 range stop address must be unique - two ranges can't
# end with the same address - makes no sense
if stop in range6_stop:
- raise ConfigError(f'Conflicting DHCPv6 lease range:\n' \
+ raise ConfigError(f'Conflicting DHCPv6 lease range: '\
f'Pool stop address "{stop}" defined multipe times!')
range6_stop.append(stop)
@@ -112,7 +115,7 @@ def verify(dhcpv6):
for prefix, prefix_config in subnet_config['prefix_delegation']['start'].items():
if 'stop' not in prefix_config:
- raise ConfigError(f'Stop address of delegated IPv6 prefix range "{prefix}"\n'
+ raise ConfigError(f'Stop address of delegated IPv6 prefix range "{prefix}" '\
f'must be configured')
if 'prefix_length' not in prefix_config:
@@ -126,6 +129,10 @@ def verify(dhcpv6):
if ip_address(mapping_config['ipv6_address']) not in ip_network(subnet):
raise ConfigError(f'static-mapping address for mapping "{mapping}" is not in subnet "{subnet}"!')
+ if 'vendor_option' in subnet_config:
+ if len(dict_search('vendor_option.cisco.tftp_server', subnet_config)) > 2:
+ raise ConfigError(f'No more then two Cisco tftp-servers should be defined for subnet "{subnet}"!')
+
# Subnets must be unique
if subnet in subnets:
raise ConfigError(f'DHCPv6 subnets must be unique! Subnet {subnet} defined multiple times!')
@@ -149,8 +156,8 @@ def verify(dhcpv6):
raise ConfigError('DHCPv6 conflicting subnet ranges: {0} overlaps {1}'.format(net, net2))
if not listen_ok:
- raise ConfigError('None of the DHCPv6 subnets are connected to a subnet6 on\n' \
- 'this machine. At least one subnet6 must be connected such that\n' \
+ raise ConfigError('None of the DHCPv6 subnets are connected to a subnet6 on '\
+ 'this machine. At least one subnet6 must be connected such that '\
'DHCPv6 listens on an interface!')
@@ -161,20 +168,20 @@ def generate(dhcpv6):
if not dhcpv6 or 'disable' in dhcpv6:
return None
- render(config_file, 'dhcp-server/dhcpdv6.conf.tmpl', dhcpv6)
+ render(config_file, 'dhcp-server/dhcpdv6.conf.j2', dhcpv6)
return None
def apply(dhcpv6):
# bail out early - looks like removal from running config
+ service_name = 'isc-dhcp-server6.service'
if not dhcpv6 or 'disable' in dhcpv6:
# DHCP server is removed in the commit
- call('systemctl stop isc-dhcp-server6.service')
+ call(f'systemctl stop {service_name}')
if os.path.exists(config_file):
os.unlink(config_file)
-
return None
- call('systemctl restart isc-dhcp-server6.service')
+ call(f'systemctl restart {service_name}')
return None
if __name__ == '__main__':
diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py
index 06366362a..f1c2d1f43 100755
--- a/src/conf_mode/dns_forwarding.py
+++ b/src/conf_mode/dns_forwarding.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2020 VyOS maintainers and contributors
+# Copyright (C) 2018-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -16,7 +16,9 @@
import os
+from netifaces import interfaces
from sys import exit
+from glob import glob
from vyos.config import Config
from vyos.configdict import dict_merge
@@ -50,10 +52,12 @@ def get_config(config=None):
if not conf.exists(base):
return None
- dns = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
+ dns = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True, no_tag_node_value_mangle=True)
# We have gathered the dict representation of the CLI, but there are default
- # options which we need to update into the dictionary retrived.
+ # options which we need to update into the dictionary retrieved.
default_values = defaults(base)
+ # T2665 due to how defaults under tag nodes work, we must clear these out before we merge
+ del default_values['authoritative_domain']
dns = dict_merge(default_values, dns)
# some additions to the default dictionary
@@ -62,9 +66,182 @@ def get_config(config=None):
if conf.exists(base_nameservers):
dns.update({'system_name_server': conf.return_values(base_nameservers)})
- base_nameservers_dhcp = ['system', 'name-servers-dhcp']
- if conf.exists(base_nameservers_dhcp):
- dns.update({'system_name_server_dhcp': conf.return_values(base_nameservers_dhcp)})
+ if 'authoritative_domain' in dns:
+ dns['authoritative_zones'] = []
+ dns['authoritative_zone_errors'] = []
+ for node in dns['authoritative_domain']:
+ zonedata = dns['authoritative_domain'][node]
+ if ('disable' in zonedata) or (not 'records' in zonedata):
+ continue
+ zone = {
+ 'name': node,
+ 'file': "{}/zone.{}.conf".format(pdns_rec_run_dir, node),
+ 'records': [],
+ }
+
+ recorddata = zonedata['records']
+
+ for rtype in [ 'a', 'aaaa', 'cname', 'mx', 'ptr', 'txt', 'spf', 'srv', 'naptr' ]:
+ if rtype not in recorddata:
+ continue
+ for subnode in recorddata[rtype]:
+ if 'disable' in recorddata[rtype][subnode]:
+ continue
+
+ rdata = recorddata[rtype][subnode]
+
+ if rtype in [ 'a', 'aaaa' ]:
+ rdefaults = defaults(base + ['authoritative-domain', 'records', rtype]) # T2665
+ rdata = dict_merge(rdefaults, rdata)
+
+ if not 'address' in rdata:
+ dns['authoritative_zone_errors'].append('{}.{}: at least one address is required'.format(subnode, node))
+ continue
+
+ for address in rdata['address']:
+ zone['records'].append({
+ 'name': subnode,
+ 'type': rtype.upper(),
+ 'ttl': rdata['ttl'],
+ 'value': address
+ })
+ elif rtype in ['cname', 'ptr']:
+ rdefaults = defaults(base + ['authoritative-domain', 'records', rtype]) # T2665
+ rdata = dict_merge(rdefaults, rdata)
+
+ if not 'target' in rdata:
+ dns['authoritative_zone_errors'].append('{}.{}: target is required'.format(subnode, node))
+ continue
+
+ zone['records'].append({
+ 'name': subnode,
+ 'type': rtype.upper(),
+ 'ttl': rdata['ttl'],
+ 'value': '{}.'.format(rdata['target'])
+ })
+ elif rtype == 'mx':
+ rdefaults = defaults(base + ['authoritative-domain', 'records', rtype]) # T2665
+ del rdefaults['server']
+ rdata = dict_merge(rdefaults, rdata)
+
+ if not 'server' in rdata:
+ dns['authoritative_zone_errors'].append('{}.{}: at least one server is required'.format(subnode, node))
+ continue
+
+ for servername in rdata['server']:
+ serverdata = rdata['server'][servername]
+ serverdefaults = defaults(base + ['authoritative-domain', 'records', rtype, 'server']) # T2665
+ serverdata = dict_merge(serverdefaults, serverdata)
+ zone['records'].append({
+ 'name': subnode,
+ 'type': rtype.upper(),
+ 'ttl': rdata['ttl'],
+ 'value': '{} {}.'.format(serverdata['priority'], servername)
+ })
+ elif rtype == 'txt':
+ rdefaults = defaults(base + ['authoritative-domain', 'records', rtype]) # T2665
+ rdata = dict_merge(rdefaults, rdata)
+
+ if not 'value' in rdata:
+ dns['authoritative_zone_errors'].append('{}.{}: at least one value is required'.format(subnode, node))
+ continue
+
+ for value in rdata['value']:
+ zone['records'].append({
+ 'name': subnode,
+ 'type': rtype.upper(),
+ 'ttl': rdata['ttl'],
+ 'value': "\"{}\"".format(value.replace("\"", "\\\""))
+ })
+ elif rtype == 'spf':
+ rdefaults = defaults(base + ['authoritative-domain', 'records', rtype]) # T2665
+ rdata = dict_merge(rdefaults, rdata)
+
+ if not 'value' in rdata:
+ dns['authoritative_zone_errors'].append('{}.{}: value is required'.format(subnode, node))
+ continue
+
+ zone['records'].append({
+ 'name': subnode,
+ 'type': rtype.upper(),
+ 'ttl': rdata['ttl'],
+ 'value': '"{}"'.format(rdata['value'].replace("\"", "\\\""))
+ })
+ elif rtype == 'srv':
+ rdefaults = defaults(base + ['authoritative-domain', 'records', rtype]) # T2665
+ del rdefaults['entry']
+ rdata = dict_merge(rdefaults, rdata)
+
+ if not 'entry' in rdata:
+ dns['authoritative_zone_errors'].append('{}.{}: at least one entry is required'.format(subnode, node))
+ continue
+
+ for entryno in rdata['entry']:
+ entrydata = rdata['entry'][entryno]
+ entrydefaults = defaults(base + ['authoritative-domain', 'records', rtype, 'entry']) # T2665
+ entrydata = dict_merge(entrydefaults, entrydata)
+
+ if not 'hostname' in entrydata:
+ dns['authoritative_zone_errors'].append('{}.{}: hostname is required for entry {}'.format(subnode, node, entryno))
+ continue
+
+ if not 'port' in entrydata:
+ dns['authoritative_zone_errors'].append('{}.{}: port is required for entry {}'.format(subnode, node, entryno))
+ continue
+
+ zone['records'].append({
+ 'name': subnode,
+ 'type': rtype.upper(),
+ 'ttl': rdata['ttl'],
+ 'value': '{} {} {} {}.'.format(entrydata['priority'], entrydata['weight'], entrydata['port'], entrydata['hostname'])
+ })
+ elif rtype == 'naptr':
+ rdefaults = defaults(base + ['authoritative-domain', 'records', rtype]) # T2665
+ del rdefaults['rule']
+ rdata = dict_merge(rdefaults, rdata)
+
+
+ if not 'rule' in rdata:
+ dns['authoritative_zone_errors'].append('{}.{}: at least one rule is required'.format(subnode, node))
+ continue
+
+ for ruleno in rdata['rule']:
+ ruledata = rdata['rule'][ruleno]
+ ruledefaults = defaults(base + ['authoritative-domain', 'records', rtype, 'rule']) # T2665
+ ruledata = dict_merge(ruledefaults, ruledata)
+ flags = ""
+ if 'lookup-srv' in ruledata:
+ flags += "S"
+ if 'lookup-a' in ruledata:
+ flags += "A"
+ if 'resolve-uri' in ruledata:
+ flags += "U"
+ if 'protocol-specific' in ruledata:
+ flags += "P"
+
+ if 'order' in ruledata:
+ order = ruledata['order']
+ else:
+ order = ruleno
+
+ if 'regexp' in ruledata:
+ regexp= ruledata['regexp'].replace("\"", "\\\"")
+ else:
+ regexp = ''
+
+ if ruledata['replacement']:
+ replacement = '{}.'.format(ruledata['replacement'])
+ else:
+ replacement = ''
+
+ zone['records'].append({
+ 'name': subnode,
+ 'type': rtype.upper(),
+ 'ttl': rdata['ttl'],
+ 'value': '{} {} "{}" "{}" "{}" {}'.format(order, ruledata['preference'], flags, ruledata['service'], regexp, replacement)
+ })
+
+ dns['authoritative_zones'].append(zone)
return dns
@@ -86,10 +263,14 @@ def verify(dns):
if 'server' not in dns['domain'][domain]:
raise ConfigError(f'No server configured for domain {domain}!')
+ if ('authoritative_zone_errors' in dns) and dns['authoritative_zone_errors']:
+ for error in dns['authoritative_zone_errors']:
+ print(error)
+ raise ConfigError('Invalid authoritative records have been defined')
+
if 'system' in dns:
- if not ('system_name_server' in dns or 'system_name_server_dhcp' in dns):
- print("Warning: No 'system name-server' or 'system " \
- "name-servers-dhcp' configured")
+ if not 'system_name_server' in dns:
+ print('Warning: No "system name-server" configured')
return None
@@ -98,12 +279,21 @@ def generate(dns):
if not dns:
return None
- render(pdns_rec_config_file, 'dns-forwarding/recursor.conf.tmpl',
+ render(pdns_rec_config_file, 'dns-forwarding/recursor.conf.j2',
dns, user=pdns_rec_user, group=pdns_rec_group)
- render(pdns_rec_lua_conf_file, 'dns-forwarding/recursor.conf.lua.tmpl',
+ render(pdns_rec_lua_conf_file, 'dns-forwarding/recursor.conf.lua.j2',
dns, user=pdns_rec_user, group=pdns_rec_group)
+ for zone_filename in glob(f'{pdns_rec_run_dir}/zone.*.conf'):
+ os.unlink(zone_filename)
+
+ if 'authoritative_zones' in dns:
+ for zone in dns['authoritative_zones']:
+ render(zone['file'], 'dns-forwarding/recursor.zone.conf.j2',
+ zone, user=pdns_rec_user, group=pdns_rec_group)
+
+
# if vyos-hostsd didn't create its files yet, create them (empty)
for file in [pdns_rec_hostsd_lua_conf_file, pdns_rec_hostsd_zones_file]:
with open(file, 'a'):
@@ -119,6 +309,9 @@ def apply(dns):
if os.path.isfile(pdns_rec_config_file):
os.unlink(pdns_rec_config_file)
+
+ for zone_filename in glob(f'{pdns_rec_run_dir}/zone.*.conf'):
+ os.unlink(zone_filename)
else:
### first apply vyos-hostsd config
hc = hostsd_client()
@@ -142,10 +335,15 @@ def apply(dns):
hc.delete_name_server_tags_recursor(['system'])
# add dhcp nameserver tags for configured interfaces
- if 'system_name_server_dhcp' in dns:
- for interface in dns['system_name_server_dhcp']:
- hc.add_name_server_tags_recursor(['dhcp-' + interface,
- 'dhcpv6-' + interface ])
+ if 'system_name_server' in dns:
+ for interface in dns['system_name_server']:
+ # system_name_server key contains both IP addresses and interface
+ # names (DHCP) to use DNS servers. We need to check if the
+ # value is an interface name - only if this is the case, add the
+ # interface based DNS forwarder.
+ if interface in interfaces():
+ hc.add_name_server_tags_recursor(['dhcp-' + interface,
+ 'dhcpv6-' + interface ])
# hostsd will generate the forward-zones file
# the list and keys() are required as get returns a dict, not list
@@ -153,6 +351,12 @@ def apply(dns):
if 'domain' in dns:
hc.add_forward_zones(dns['domain'])
+ # hostsd generates NTAs for the authoritative zones
+ # the list and keys() are required as get returns a dict, not list
+ hc.delete_authoritative_zones(list(hc.get_authoritative_zones()))
+ if 'authoritative_zones' in dns:
+ hc.add_authoritative_zones(list(map(lambda zone: zone['name'], dns['authoritative_zones'])))
+
# call hostsd to generate forward-zones and its lua-config-file
hc.apply()
diff --git a/src/conf_mode/dynamic_dns.py b/src/conf_mode/dynamic_dns.py
index a31e5ed75..06a2f7e15 100755
--- a/src/conf_mode/dynamic_dns.py
+++ b/src/conf_mode/dynamic_dns.py
@@ -131,7 +131,7 @@ def generate(dyndns):
if not dyndns:
return None
- render(config_file, 'dynamic-dns/ddclient.conf.tmpl', dyndns)
+ render(config_file, 'dynamic-dns/ddclient.conf.j2', dyndns)
return None
def apply(dyndns):
diff --git a/src/conf_mode/firewall-interface.py b/src/conf_mode/firewall-interface.py
new file mode 100755
index 000000000..9a5d278e9
--- /dev/null
+++ b/src/conf_mode/firewall-interface.py
@@ -0,0 +1,175 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import re
+
+from sys import argv
+from sys import exit
+
+from vyos.config import Config
+from vyos.configdict import leaf_node_changed
+from vyos.ifconfig import Section
+from vyos.template import render
+from vyos.util import cmd
+from vyos.util import dict_search_args
+from vyos.util import run
+from vyos import ConfigError
+from vyos import airbag
+airbag.enable()
+
+NAME_PREFIX = 'NAME_'
+NAME6_PREFIX = 'NAME6_'
+
+NFT_CHAINS = {
+ 'in': 'VYOS_FW_FORWARD',
+ 'out': 'VYOS_FW_FORWARD',
+ 'local': 'VYOS_FW_LOCAL'
+}
+NFT6_CHAINS = {
+ 'in': 'VYOS_FW6_FORWARD',
+ 'out': 'VYOS_FW6_FORWARD',
+ 'local': 'VYOS_FW6_LOCAL'
+}
+
+def get_config(config=None):
+ if config:
+ conf = config
+ else:
+ conf = Config()
+
+ ifname = argv[1]
+ ifpath = Section.get_config_path(ifname)
+ if_firewall_path = f'interfaces {ifpath} firewall'
+
+ if_firewall = conf.get_config_dict(if_firewall_path, key_mangling=('-', '_'), get_first_key=True,
+ no_tag_node_value_mangle=True)
+
+ if_firewall['ifname'] = ifname
+ if_firewall['firewall'] = conf.get_config_dict(['firewall'], key_mangling=('-', '_'), get_first_key=True,
+ no_tag_node_value_mangle=True)
+
+ return if_firewall
+
+def verify(if_firewall):
+ # bail out early - looks like removal from running config
+ if not if_firewall:
+ return None
+
+ for direction in ['in', 'out', 'local']:
+ if direction in if_firewall:
+ if 'name' in if_firewall[direction]:
+ name = if_firewall[direction]['name']
+
+ if 'name' not in if_firewall['firewall']:
+ raise ConfigError('Firewall name not configured')
+
+ if name not in if_firewall['firewall']['name']:
+ raise ConfigError(f'Invalid firewall name "{name}"')
+
+ if 'ipv6_name' in if_firewall[direction]:
+ name = if_firewall[direction]['ipv6_name']
+
+ if 'ipv6_name' not in if_firewall['firewall']:
+ raise ConfigError('Firewall ipv6-name not configured')
+
+ if name not in if_firewall['firewall']['ipv6_name']:
+ raise ConfigError(f'Invalid firewall ipv6-name "{name}"')
+
+ return None
+
+def generate(if_firewall):
+ return None
+
+def cleanup_rule(table, chain, prefix, ifname, new_name=None):
+ results = cmd(f'nft -a list chain {table} {chain}').split("\n")
+ retval = None
+ for line in results:
+ if f'{prefix}ifname "{ifname}"' in line:
+ if new_name and f'jump {new_name}' in line:
+ # new_name is used to clear rules for any previously referenced chains
+ # returns true when rule exists and doesn't need to be created
+ retval = True
+ continue
+
+ handle_search = re.search('handle (\d+)', line)
+ if handle_search:
+ run(f'nft delete rule {table} {chain} handle {handle_search[1]}')
+ return retval
+
+def state_policy_handle(table, chain):
+ # Find any state-policy rule to ensure interface rules are only inserted afterwards
+ results = cmd(f'nft -a list chain {table} {chain}').split("\n")
+ for line in results:
+ if 'jump VYOS_STATE_POLICY' in line:
+ handle_search = re.search('handle (\d+)', line)
+ if handle_search:
+ return handle_search[1]
+ return None
+
+def apply(if_firewall):
+ ifname = if_firewall['ifname']
+
+ for direction in ['in', 'out', 'local']:
+ chain = NFT_CHAINS[direction]
+ ipv6_chain = NFT6_CHAINS[direction]
+ if_prefix = 'i' if direction in ['in', 'local'] else 'o'
+
+ name = dict_search_args(if_firewall, direction, 'name')
+ if name:
+ rule_exists = cleanup_rule('ip filter', chain, if_prefix, ifname, f'{NAME_PREFIX}{name}')
+
+ if not rule_exists:
+ rule_action = 'insert'
+ rule_prefix = ''
+
+ handle = state_policy_handle('ip filter', chain)
+ if handle:
+ rule_action = 'add'
+ rule_prefix = f'position {handle}'
+
+ run(f'nft {rule_action} rule ip filter {chain} {rule_prefix} {if_prefix}ifname {ifname} counter jump {NAME_PREFIX}{name}')
+ else:
+ cleanup_rule('ip filter', chain, if_prefix, ifname)
+
+ ipv6_name = dict_search_args(if_firewall, direction, 'ipv6_name')
+ if ipv6_name:
+ rule_exists = cleanup_rule('ip6 filter', ipv6_chain, if_prefix, ifname, f'{NAME6_PREFIX}{ipv6_name}')
+
+ if not rule_exists:
+ rule_action = 'insert'
+ rule_prefix = ''
+
+ handle = state_policy_handle('ip6 filter', ipv6_chain)
+ if handle:
+ rule_action = 'add'
+ rule_prefix = f'position {handle}'
+
+ run(f'nft {rule_action} rule ip6 filter {ipv6_chain} {rule_prefix} {if_prefix}ifname {ifname} counter jump {NAME6_PREFIX}{ipv6_name}')
+ else:
+ cleanup_rule('ip6 filter', ipv6_chain, if_prefix, ifname)
+
+ return None
+
+if __name__ == '__main__':
+ try:
+ c = get_config()
+ verify(c)
+ generate(c)
+ apply(c)
+ except ConfigError as e:
+ print(e)
+ exit(1)
diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py
index 8e6ce5b14..6924bf555 100755
--- a/src/conf_mode/firewall.py
+++ b/src/conf_mode/firewall.py
@@ -15,51 +15,413 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
+import re
+from glob import glob
+from json import loads
from sys import exit
+from vyos.base import Warning
from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.configdict import node_changed
-from vyos.configdict import leaf_node_changed
+from vyos.configdiff import get_config_diff, Diff
from vyos.template import render
-from vyos.util import call
+from vyos.util import cmd
+from vyos.util import dict_search_args
+from vyos.util import process_named_running
+from vyos.util import run
+from vyos.xml import defaults
from vyos import ConfigError
from vyos import airbag
-from pprint import pprint
airbag.enable()
+policy_route_conf_script = '/usr/libexec/vyos/conf_mode/policy-route.py'
-def get_config(config=None):
+nftables_conf = '/run/nftables.conf'
+nftables_defines_conf = '/run/nftables_defines.conf'
+
+sysfs_config = {
+ 'all_ping': {'sysfs': '/proc/sys/net/ipv4/icmp_echo_ignore_all', 'enable': '0', 'disable': '1'},
+ 'broadcast_ping': {'sysfs': '/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts', 'enable': '0', 'disable': '1'},
+ 'ip_src_route': {'sysfs': '/proc/sys/net/ipv4/conf/*/accept_source_route'},
+ 'ipv6_receive_redirects': {'sysfs': '/proc/sys/net/ipv6/conf/*/accept_redirects'},
+ 'ipv6_src_route': {'sysfs': '/proc/sys/net/ipv6/conf/*/accept_source_route', 'enable': '0', 'disable': '-1'},
+ 'log_martians': {'sysfs': '/proc/sys/net/ipv4/conf/all/log_martians'},
+ 'receive_redirects': {'sysfs': '/proc/sys/net/ipv4/conf/*/accept_redirects'},
+ 'send_redirects': {'sysfs': '/proc/sys/net/ipv4/conf/*/send_redirects'},
+ 'source_validation': {'sysfs': '/proc/sys/net/ipv4/conf/*/rp_filter', 'disable': '0', 'strict': '1', 'loose': '2'},
+ 'syn_cookies': {'sysfs': '/proc/sys/net/ipv4/tcp_syncookies'},
+ 'twa_hazards_protection': {'sysfs': '/proc/sys/net/ipv4/tcp_rfc1337'}
+}
+
+NAME_PREFIX = 'NAME_'
+NAME6_PREFIX = 'NAME6_'
+
+preserve_chains = [
+ 'INPUT',
+ 'FORWARD',
+ 'OUTPUT',
+ 'VYOS_FW_FORWARD',
+ 'VYOS_FW_LOCAL',
+ 'VYOS_FW_OUTPUT',
+ 'VYOS_POST_FW',
+ 'VYOS_FRAG_MARK',
+ 'VYOS_FW6_FORWARD',
+ 'VYOS_FW6_LOCAL',
+ 'VYOS_FW6_OUTPUT',
+ 'VYOS_POST_FW6',
+ 'VYOS_FRAG6_MARK'
+]
+
+nft_iface_chains = ['VYOS_FW_FORWARD', 'VYOS_FW_OUTPUT', 'VYOS_FW_LOCAL']
+nft6_iface_chains = ['VYOS_FW6_FORWARD', 'VYOS_FW6_OUTPUT', 'VYOS_FW6_LOCAL']
+valid_groups = [
+ 'address_group',
+ 'network_group',
+ 'port_group'
+]
+
+snmp_change_type = {
+ 'unknown': 0,
+ 'add': 1,
+ 'delete': 2,
+ 'change': 3
+}
+snmp_event_source = 1
+snmp_trap_mib = 'VYATTA-TRAP-MIB'
+snmp_trap_name = 'mgmtEventTrap'
+
+def get_firewall_interfaces(conf):
+ out = {}
+ interfaces = conf.get_config_dict(['interfaces'], key_mangling=('-', '_'), get_first_key=True,
+ no_tag_node_value_mangle=True)
+ def find_interfaces(iftype_conf, output={}, prefix=''):
+ for ifname, if_conf in iftype_conf.items():
+ if 'firewall' in if_conf:
+ output[prefix + ifname] = if_conf['firewall']
+ for vif in ['vif', 'vif_s', 'vif_c']:
+ if vif in if_conf:
+ output.update(find_interfaces(if_conf[vif], output, f'{prefix}{ifname}.'))
+ return output
+ for iftype, iftype_conf in interfaces.items():
+ out.update(find_interfaces(iftype_conf))
+ return out
+
+def get_firewall_zones(conf):
+ used_v4 = []
+ used_v6 = []
+ zone_policy = conf.get_config_dict(['zone-policy'], key_mangling=('-', '_'), get_first_key=True,
+ no_tag_node_value_mangle=True)
+
+ if 'zone' in zone_policy:
+ for zone, zone_conf in zone_policy['zone'].items():
+ if 'from' in zone_conf:
+ for from_zone, from_conf in zone_conf['from'].items():
+ name = dict_search_args(from_conf, 'firewall', 'name')
+ if name:
+ used_v4.append(name)
+
+ ipv6_name = dict_search_args(from_conf, 'firewall', 'ipv6_name')
+ if ipv6_name:
+ used_v6.append(ipv6_name)
+
+ if 'intra_zone_filtering' in zone_conf:
+ name = dict_search_args(zone_conf, 'intra_zone_filtering', 'firewall', 'name')
+ if name:
+ used_v4.append(name)
+
+ ipv6_name = dict_search_args(zone_conf, 'intra_zone_filtering', 'firewall', 'ipv6_name')
+ if ipv6_name:
+ used_v6.append(ipv6_name)
+
+ return {'name': used_v4, 'ipv6_name': used_v6}
+
+def get_config(config=None):
if config:
conf = config
else:
conf = Config()
- base = ['nfirewall']
+ base = ['firewall']
+
firewall = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True,
no_tag_node_value_mangle=True)
- pprint(firewall)
+ default_values = defaults(base)
+ firewall = dict_merge(default_values, firewall)
+
+ firewall['policy_resync'] = bool('group' in firewall or node_changed(conf, base + ['group']))
+ firewall['interfaces'] = get_firewall_interfaces(conf)
+ firewall['zone_policy'] = get_firewall_zones(conf)
+
+ if 'config_trap' in firewall and firewall['config_trap'] == 'enable':
+ diff = get_config_diff(conf)
+ firewall['trap_diff'] = diff.get_child_nodes_diff_str(base)
+ firewall['trap_targets'] = conf.get_config_dict(['service', 'snmp', 'trap-target'],
+ key_mangling=('-', '_'), get_first_key=True,
+ no_tag_node_value_mangle=True)
+
return firewall
+def verify_rule(firewall, rule_conf, ipv6):
+ if 'action' not in rule_conf:
+ raise ConfigError('Rule action must be defined')
+
+ if 'fragment' in rule_conf:
+ if {'match_frag', 'match_non_frag'} <= set(rule_conf['fragment']):
+ raise ConfigError('Cannot specify both "match-frag" and "match-non-frag"')
+
+ if 'limit' in rule_conf:
+ if 'rate' in rule_conf['limit']:
+ rate_int = re.sub(r'\D', '', rule_conf['limit']['rate'])
+ if int(rate_int) < 1:
+ raise ConfigError('Limit rate integer cannot be less than 1')
+
+ if 'ipsec' in rule_conf:
+ if {'match_ipsec', 'match_non_ipsec'} <= set(rule_conf['ipsec']):
+ raise ConfigError('Cannot specify both "match-ipsec" and "match-non-ipsec"')
+
+ if 'recent' in rule_conf:
+ if not {'count', 'time'} <= set(rule_conf['recent']):
+ raise ConfigError('Recent "count" and "time" values must be defined')
+
+ tcp_flags = dict_search_args(rule_conf, 'tcp', 'flags')
+ if tcp_flags:
+ if dict_search_args(rule_conf, 'protocol') != 'tcp':
+ raise ConfigError('Protocol must be tcp when specifying tcp flags')
+
+ not_flags = dict_search_args(rule_conf, 'tcp', 'flags', 'not')
+ if not_flags:
+ duplicates = [flag for flag in tcp_flags if flag in not_flags]
+ if duplicates:
+ raise ConfigError(f'Cannot match a tcp flag as set and not set')
+
+ if 'protocol' in rule_conf:
+ if rule_conf['protocol'] == 'icmp' and ipv6:
+ raise ConfigError(f'Cannot match IPv4 ICMP protocol on IPv6, use ipv6-icmp')
+ if rule_conf['protocol'] == 'ipv6-icmp' and not ipv6:
+ raise ConfigError(f'Cannot match IPv6 ICMP protocol on IPv4, use icmp')
+
+ for side in ['destination', 'source']:
+ if side in rule_conf:
+ side_conf = rule_conf[side]
+
+ if 'group' in side_conf:
+ if {'address_group', 'network_group'} <= set(side_conf['group']):
+ raise ConfigError('Only one address-group or network-group can be specified')
+
+ for group in valid_groups:
+ if group in side_conf['group']:
+ group_name = side_conf['group'][group]
+
+ if group_name and group_name[0] == '!':
+ group_name = group_name[1:]
+
+ fw_group = f'ipv6_{group}' if ipv6 and group in ['address_group', 'network_group'] else group
+ error_group = fw_group.replace("_", "-")
+ group_obj = dict_search_args(firewall, 'group', fw_group, group_name)
+
+ if group_obj is None:
+ raise ConfigError(f'Invalid {error_group} "{group_name}" on firewall rule')
+
+ if not group_obj:
+ Warning(f'{error_group} "{group_name}" has no members!')
+
+ if 'port' in side_conf or dict_search_args(side_conf, 'group', 'port_group'):
+ if 'protocol' not in rule_conf:
+ raise ConfigError('Protocol must be defined if specifying a port or port-group')
+
+ if rule_conf['protocol'] not in ['tcp', 'udp', 'tcp_udp']:
+ raise ConfigError('Protocol must be tcp, udp, or tcp_udp when specifying a port or port-group')
+
def verify(firewall):
- # bail out early - looks like removal from running config
- if not firewall:
- return None
+ if 'config_trap' in firewall and firewall['config_trap'] == 'enable':
+ if not firewall['trap_targets']:
+ raise ConfigError(f'Firewall config-trap enabled but "service snmp trap-target" is not defined')
+
+ for name in ['name', 'ipv6_name']:
+ if name in firewall:
+ for name_id, name_conf in firewall[name].items():
+ if name_id in preserve_chains:
+ raise ConfigError(f'Firewall name "{name_id}" is reserved for VyOS')
+
+ if name_id.startswith("VZONE"):
+ raise ConfigError(f'Firewall name "{name_id}" uses reserved prefix')
+
+ if 'rule' in name_conf:
+ for rule_id, rule_conf in name_conf['rule'].items():
+ verify_rule(firewall, rule_conf, name == 'ipv6_name')
+
+ for ifname, if_firewall in firewall['interfaces'].items():
+ for direction in ['in', 'out', 'local']:
+ name = dict_search_args(if_firewall, direction, 'name')
+ ipv6_name = dict_search_args(if_firewall, direction, 'ipv6_name')
+
+ if name and dict_search_args(firewall, 'name', name) == None:
+ raise ConfigError(f'Firewall name "{name}" is still referenced on interface {ifname}')
+
+ if ipv6_name and dict_search_args(firewall, 'ipv6_name', ipv6_name) == None:
+ raise ConfigError(f'Firewall ipv6-name "{ipv6_name}" is still referenced on interface {ifname}')
+
+ for fw_name, used_names in firewall['zone_policy'].items():
+ for name in used_names:
+ if dict_search_args(firewall, fw_name, name) == None:
+ raise ConfigError(f'Firewall {fw_name.replace("_", "-")} "{name}" is still referenced in zone-policy')
return None
+def cleanup_rule(table, jump_chain):
+ commands = []
+ chains = nft_iface_chains if table == 'ip filter' else nft6_iface_chains
+ for chain in chains:
+ results = cmd(f'nft -a list chain {table} {chain}').split("\n")
+ for line in results:
+ if f'jump {jump_chain}' in line:
+ handle_search = re.search('handle (\d+)', line)
+ if handle_search:
+ commands.append(f'delete rule {table} {chain} handle {handle_search[1]}')
+ return commands
+
+def cleanup_commands(firewall):
+ commands = []
+ commands_end = []
+ for table in ['ip filter', 'ip6 filter']:
+ state_chain = 'VYOS_STATE_POLICY' if table == 'ip filter' else 'VYOS_STATE_POLICY6'
+ json_str = cmd(f'nft -j list table {table}')
+ obj = loads(json_str)
+ if 'nftables' not in obj:
+ continue
+ for item in obj['nftables']:
+ if 'chain' in item:
+ chain = item['chain']['name']
+ if chain in ['VYOS_STATE_POLICY', 'VYOS_STATE_POLICY6']:
+ if 'state_policy' not in firewall:
+ commands.append(f'delete chain {table} {chain}')
+ else:
+ commands.append(f'flush chain {table} {chain}')
+ elif chain not in preserve_chains and not chain.startswith("VZONE"):
+ if table == 'ip filter' and dict_search_args(firewall, 'name', chain.replace(NAME_PREFIX, "", 1)) != None:
+ commands.append(f'flush chain {table} {chain}')
+ elif table == 'ip6 filter' and dict_search_args(firewall, 'ipv6_name', chain.replace(NAME6_PREFIX, "", 1)) != None:
+ commands.append(f'flush chain {table} {chain}')
+ else:
+ commands += cleanup_rule(table, chain)
+ commands.append(f'delete chain {table} {chain}')
+ elif 'rule' in item:
+ rule = item['rule']
+ if rule['chain'] in ['VYOS_FW_FORWARD', 'VYOS_FW_OUTPUT', 'VYOS_FW_LOCAL', 'VYOS_FW6_FORWARD', 'VYOS_FW6_OUTPUT', 'VYOS_FW6_LOCAL']:
+ if 'expr' in rule and any([True for expr in rule['expr'] if dict_search_args(expr, 'jump', 'target') == state_chain]):
+ if 'state_policy' not in firewall:
+ chain = rule['chain']
+ handle = rule['handle']
+ commands.append(f'delete rule {table} {chain} handle {handle}')
+ elif 'set' in item:
+ set_name = item['set']['name']
+ commands_end.append(f'delete set {table} {set_name}')
+ return commands + commands_end
+
def generate(firewall):
- if not firewall:
- return None
+ if not os.path.exists(nftables_conf):
+ firewall['first_install'] = True
+ else:
+ firewall['cleanup_commands'] = cleanup_commands(firewall)
+ render(nftables_conf, 'firewall/nftables.j2', firewall)
+ render(nftables_defines_conf, 'firewall/nftables-defines.j2', firewall)
return None
-def apply(firewall):
- if not firewall:
+def apply_sysfs(firewall):
+ for name, conf in sysfs_config.items():
+ paths = glob(conf['sysfs'])
+ value = None
+
+ if name in firewall:
+ conf_value = firewall[name]
+
+ if conf_value in conf:
+ value = conf[conf_value]
+ elif conf_value == 'enable':
+ value = '1'
+ elif conf_value == 'disable':
+ value = '0'
+
+ if value:
+ for path in paths:
+ with open(path, 'w') as f:
+ f.write(value)
+
+def post_apply_trap(firewall):
+ if 'first_install' in firewall:
+ return None
+
+ if 'config_trap' not in firewall or firewall['config_trap'] != 'enable':
return None
+ if not process_named_running('snmpd'):
+ return None
+
+ trap_username = os.getlogin()
+
+ for host, target_conf in firewall['trap_targets'].items():
+ community = target_conf['community'] if 'community' in target_conf else 'public'
+ port = int(target_conf['port']) if 'port' in target_conf else 162
+
+ base_cmd = f'snmptrap -v2c -c {community} {host}:{port} 0 {snmp_trap_mib}::{snmp_trap_name} '
+
+ for change_type, changes in firewall['trap_diff'].items():
+ for path_str, value in changes.items():
+ objects = [
+ f'mgmtEventUser s "{trap_username}"',
+ f'mgmtEventSource i {snmp_event_source}',
+ f'mgmtEventType i {snmp_change_type[change_type]}'
+ ]
+
+ if change_type == 'add':
+ objects.append(f'mgmtEventCurrCfg s "{path_str} {value}"')
+ elif change_type == 'delete':
+ objects.append(f'mgmtEventPrevCfg s "{path_str} {value}"')
+ elif change_type == 'change':
+ objects.append(f'mgmtEventPrevCfg s "{path_str} {value[0]}"')
+ objects.append(f'mgmtEventCurrCfg s "{path_str} {value[1]}"')
+
+ cmd(base_cmd + ' '.join(objects))
+
+def state_policy_rule_exists():
+ # Determine if state policy rules already exist in nft
+ search_str = cmd(f'nft list chain ip filter VYOS_FW_FORWARD')
+ return 'VYOS_STATE_POLICY' in search_str
+
+def resync_policy_route():
+ # Update policy route as firewall groups were updated
+ tmp = run(policy_route_conf_script)
+ if tmp > 0:
+ Warning('Failed to re-apply policy route configuration!')
+
+def apply(firewall):
+ if 'first_install' in firewall:
+ run('nfct helper add rpc inet tcp')
+ run('nfct helper add rpc inet udp')
+ run('nfct helper add tns inet tcp')
+
+ install_result = run(f'nft -f {nftables_conf}')
+ if install_result == 1:
+ raise ConfigError('Failed to apply firewall')
+
+ if 'state_policy' in firewall and not state_policy_rule_exists():
+ for chain in ['VYOS_FW_FORWARD', 'VYOS_FW_OUTPUT', 'VYOS_FW_LOCAL']:
+ cmd(f'nft insert rule ip filter {chain} jump VYOS_STATE_POLICY')
+
+ for chain in ['VYOS_FW6_FORWARD', 'VYOS_FW6_OUTPUT', 'VYOS_FW6_LOCAL']:
+ cmd(f'nft insert rule ip6 filter {chain} jump VYOS_STATE_POLICY6')
+
+ apply_sysfs(firewall)
+
+ if firewall['policy_resync']:
+ resync_policy_route()
+
+ post_apply_trap(firewall)
+
return None
if __name__ == '__main__':
diff --git a/src/conf_mode/flow_accounting_conf.py b/src/conf_mode/flow_accounting_conf.py
index 0a4559ade..7750c1247 100755
--- a/src/conf_mode/flow_accounting_conf.py
+++ b/src/conf_mode/flow_accounting_conf.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2020 VyOS maintainers and contributors
+# Copyright (C) 2018-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -16,121 +16,87 @@
import os
import re
+
from sys import exit
import ipaddress
from ipaddress import ip_address
-from jinja2 import FileSystemLoader, Environment
+from vyos.base import Warning
+from vyos.config import Config
+from vyos.configdict import dict_merge
from vyos.ifconfig import Section
from vyos.ifconfig import Interface
-from vyos.config import Config
-from vyos import ConfigError
-from vyos.util import cmd
from vyos.template import render
-
+from vyos.util import call
+from vyos.util import cmd
+from vyos.validate import is_addr_assigned
+from vyos.xml import defaults
+from vyos import ConfigError
from vyos import airbag
airbag.enable()
-# default values
-default_sflow_server_port = 6343
-default_netflow_server_port = 2055
-default_plugin_pipe_size = 10
-default_captured_packet_size = 128
-default_netflow_version = '9'
-default_sflow_agentip = 'auto'
-uacctd_conf_path = '/etc/pmacct/uacctd.conf'
-iptables_nflog_table = 'raw'
-iptables_nflog_chain = 'VYATTA_CT_PREROUTING_HOOK'
-egress_iptables_nflog_table = 'mangle'
-egress_iptables_nflog_chain = 'FORWARD'
-
-# helper functions
-# check if node exists and return True if this is true
-def _node_exists(path):
- vyos_config = Config()
- if vyos_config.exists(path):
- return True
-
-# get sFlow agent-ip if agent-address is "auto" (default behaviour)
-def _sflow_default_agentip(config):
- # check if any of BGP, OSPF, OSPFv3 protocols are configured and use router-id from there
- if config.exists('protocols bgp'):
- bgp_router_id = config.return_value("protocols bgp {} parameters router-id".format(config.list_nodes('protocols bgp')[0]))
- if bgp_router_id:
- return bgp_router_id
- if config.return_value('protocols ospf parameters router-id'):
- return config.return_value('protocols ospf parameters router-id')
- if config.return_value('protocols ospfv3 parameters router-id'):
- return config.return_value('protocols ospfv3 parameters router-id')
-
- # if router-id was not found, use first available ip of any interface
- for iface in Section.interfaces():
- for address in Interface(iface).get_addr():
- # return an IP, if this is not loopback
- regex_filter = re.compile('^(?!(127)|(::1)|(fe80))(?P<ipaddr>[a-f\d\.:]+)/\d+$')
- if regex_filter.search(address):
- return regex_filter.search(address).group('ipaddr')
-
- # return nothing by default
- return None
-
-# get iptables rule dict for chain in table
-def _iptables_get_nflog(chain, table):
+uacctd_conf_path = '/run/pmacct/uacctd.conf'
+systemd_service = 'uacctd.service'
+systemd_override = f'/etc/systemd/system/{systemd_service}.d/override.conf'
+nftables_nflog_table = 'raw'
+nftables_nflog_chain = 'VYOS_CT_PREROUTING_HOOK'
+egress_nftables_nflog_table = 'inet mangle'
+egress_nftables_nflog_chain = 'FORWARD'
+
+# get nftables rule dict for chain in table
+def _nftables_get_nflog(chain, table):
# define list with rules
rules = []
# prepare regex for parsing rules
- rule_pattern = "^-A (?P<rule_definition>{0} (\-i|\-o) (?P<interface>[\w\.\*\-]+).*--comment FLOW_ACCOUNTING_RULE.* -j NFLOG.*$)".format(chain)
+ rule_pattern = '[io]ifname "(?P<interface>[\w\.\*\-]+)".*handle (?P<handle>[\d]+)'
rule_re = re.compile(rule_pattern)
- for iptables_variant in ['iptables', 'ip6tables']:
- # run iptables, save output and split it by lines
- iptables_command = f'{iptables_variant} -t {table} -S {chain}'
- tmp = cmd(iptables_command, message='Failed to get flows list')
-
- # parse each line and add information to list
- for current_rule in tmp.splitlines():
- current_rule_parsed = rule_re.search(current_rule)
- if current_rule_parsed:
- rules.append({ 'interface': current_rule_parsed.groupdict()["interface"], 'iptables_variant': iptables_variant, 'table': table, 'rule_definition': current_rule_parsed.groupdict()["rule_definition"] })
+ # run nftables, save output and split it by lines
+ nftables_command = f'nft -a list chain {table} {chain}'
+ tmp = cmd(nftables_command, message='Failed to get flows list')
+ # parse each line and add information to list
+ for current_rule in tmp.splitlines():
+ if 'FLOW_ACCOUNTING_RULE' not in current_rule:
+ continue
+ current_rule_parsed = rule_re.search(current_rule)
+ if current_rule_parsed:
+ groups = current_rule_parsed.groupdict()
+ rules.append({ 'interface': groups["interface"], 'table': table, 'handle': groups["handle"] })
# return list with rules
return rules
-# modify iptables rules
-def _iptables_config(configured_ifaces, direction):
- # define list of iptables commands to modify settings
- iptable_commands = []
- iptables_chain = iptables_nflog_chain
- iptables_table = iptables_nflog_table
+def _nftables_config(configured_ifaces, direction, length=None):
+ # define list of nftables commands to modify settings
+ nftable_commands = []
+ nftables_chain = nftables_nflog_chain
+ nftables_table = nftables_nflog_table
if direction == "egress":
- iptables_chain = egress_iptables_nflog_chain
- iptables_table = egress_iptables_nflog_table
+ nftables_chain = egress_nftables_nflog_chain
+ nftables_table = egress_nftables_nflog_table
# prepare extended list with configured interfaces
configured_ifaces_extended = []
for iface in configured_ifaces:
- configured_ifaces_extended.append({ 'iface': iface, 'iptables_variant': 'iptables' })
- configured_ifaces_extended.append({ 'iface': iface, 'iptables_variant': 'ip6tables' })
+ configured_ifaces_extended.append({ 'iface': iface })
- # get currently configured interfaces with iptables rules
- active_nflog_rules = _iptables_get_nflog(iptables_chain, iptables_table)
+ # get currently configured interfaces with nftables rules
+ active_nflog_rules = _nftables_get_nflog(nftables_chain, nftables_table)
# compare current active list with configured one and delete excessive interfaces, add missed
active_nflog_ifaces = []
for rule in active_nflog_rules:
- iptables = rule['iptables_variant']
interface = rule['interface']
if interface not in configured_ifaces:
table = rule['table']
- rule = rule['rule_definition']
- iptable_commands.append(f'{iptables} -t {table} -D {rule}')
+ handle = rule['handle']
+ nftable_commands.append(f'nft delete rule {table} {nftables_chain} handle {handle}')
else:
active_nflog_ifaces.append({
'iface': interface,
- 'iptables_variant': iptables,
})
# do not create new rules for already configured interfaces
@@ -141,244 +107,178 @@ def _iptables_config(configured_ifaces, direction):
# create missed rules
for iface_extended in configured_ifaces_extended:
iface = iface_extended['iface']
- iptables = iface_extended['iptables_variant']
- iptables_op = "-i"
- if direction == "egress":
- iptables_op = "-o"
-
- rule_definition = f'{iptables_chain} {iptables_op} {iface} -m comment --comment FLOW_ACCOUNTING_RULE -j NFLOG --nflog-group 2 --nflog-size {default_captured_packet_size} --nflog-threshold 100'
- iptable_commands.append(f'{iptables} -t {iptables_table} -I {rule_definition}')
-
- # change iptables
- for command in iptable_commands:
+ iface_prefix = "o" if direction == "egress" else "i"
+ rule_definition = f'{iface_prefix}ifname "{iface}" counter log group 2 snaplen {length} queue-threshold 100 comment "FLOW_ACCOUNTING_RULE"'
+ nftable_commands.append(f'nft insert rule {nftables_table} {nftables_chain} {rule_definition}')
+ # Also add IPv6 ingres logging
+ if nftables_table == nftables_nflog_table:
+ nftable_commands.append(f'nft insert rule ip6 {nftables_table} {nftables_chain} {rule_definition}')
+
+ # change nftables
+ for command in nftable_commands:
cmd(command, raising=ConfigError)
-def get_config():
- vc = Config()
- vc.set_level('')
- # Convert the VyOS config to an abstract internal representation
- flow_config = {
- 'flow-accounting-configured': vc.exists('system flow-accounting'),
- 'buffer-size': vc.return_value('system flow-accounting buffer-size'),
- 'enable-egress': _node_exists('system flow-accounting enable-egress'),
- 'disable-imt': _node_exists('system flow-accounting disable-imt'),
- 'syslog-facility': vc.return_value('system flow-accounting syslog-facility'),
- 'interfaces': None,
- 'sflow': {
- 'configured': vc.exists('system flow-accounting sflow'),
- 'agent-address': vc.return_value('system flow-accounting sflow agent-address'),
- 'sampling-rate': vc.return_value('system flow-accounting sflow sampling-rate'),
- 'servers': None
- },
- 'netflow': {
- 'configured': vc.exists('system flow-accounting netflow'),
- 'engine-id': vc.return_value('system flow-accounting netflow engine-id'),
- 'max-flows': vc.return_value('system flow-accounting netflow max-flows'),
- 'sampling-rate': vc.return_value('system flow-accounting netflow sampling-rate'),
- 'source-ip': vc.return_value('system flow-accounting netflow source-ip'),
- 'version': vc.return_value('system flow-accounting netflow version'),
- 'timeout': {
- 'expint': vc.return_value('system flow-accounting netflow timeout expiry-interval'),
- 'general': vc.return_value('system flow-accounting netflow timeout flow-generic'),
- 'icmp': vc.return_value('system flow-accounting netflow timeout icmp'),
- 'maxlife': vc.return_value('system flow-accounting netflow timeout max-active-life'),
- 'tcp.fin': vc.return_value('system flow-accounting netflow timeout tcp-fin'),
- 'tcp': vc.return_value('system flow-accounting netflow timeout tcp-generic'),
- 'tcp.rst': vc.return_value('system flow-accounting netflow timeout tcp-rst'),
- 'udp': vc.return_value('system flow-accounting netflow timeout udp')
- },
- 'servers': None
- }
- }
-
- # get interfaces list
- if vc.exists('system flow-accounting interface'):
- flow_config['interfaces'] = vc.return_values('system flow-accounting interface')
-
- # get sFlow collectors list
- if vc.exists('system flow-accounting sflow server'):
- flow_config['sflow']['servers'] = []
- sflow_collectors = vc.list_nodes('system flow-accounting sflow server')
- for collector in sflow_collectors:
- port = default_sflow_server_port
- if vc.return_value("system flow-accounting sflow server {} port".format(collector)):
- port = vc.return_value("system flow-accounting sflow server {} port".format(collector))
- flow_config['sflow']['servers'].append({ 'address': collector, 'port': port })
-
- # get NetFlow collectors list
- if vc.exists('system flow-accounting netflow server'):
- flow_config['netflow']['servers'] = []
- netflow_collectors = vc.list_nodes('system flow-accounting netflow server')
- for collector in netflow_collectors:
- port = default_netflow_server_port
- if vc.return_value("system flow-accounting netflow server {} port".format(collector)):
- port = vc.return_value("system flow-accounting netflow server {} port".format(collector))
- flow_config['netflow']['servers'].append({ 'address': collector, 'port': port })
-
- # get sflow agent-id
- if flow_config['sflow']['agent-address'] == None or flow_config['sflow']['agent-address'] == 'auto':
- flow_config['sflow']['agent-address'] = _sflow_default_agentip(vc)
-
- # get NetFlow version
- if not flow_config['netflow']['version']:
- flow_config['netflow']['version'] = default_netflow_version
-
- # convert NetFlow engine-id format, if this is necessary
- if flow_config['netflow']['engine-id'] and flow_config['netflow']['version'] == '5':
- regex_filter = re.compile('^\d+$')
- if regex_filter.search(flow_config['netflow']['engine-id']):
- flow_config['netflow']['engine-id'] = "{}:0".format(flow_config['netflow']['engine-id'])
-
- # return dict with flow-accounting configuration
- return flow_config
-
-def verify(config):
- # Verify that configuration is valid
- # skip all checks if flow-accounting was removed
- if not config['flow-accounting-configured']:
- return True
+def get_config(config=None):
+ if config:
+ conf = config
+ else:
+ conf = Config()
+ base = ['system', 'flow-accounting']
+ if not conf.exists(base):
+ return None
+
+ flow_accounting = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
+
+ # We have gathered the dict representation of the CLI, but there are default
+ # options which we need to update into the dictionary retrived.
+ default_values = defaults(base)
+
+ # delete individual flow type default - should only be added if user uses
+ # this feature
+ for flow_type in ['sflow', 'netflow']:
+ if flow_type in default_values:
+ del default_values[flow_type]
+ flow_accounting = dict_merge(default_values, flow_accounting)
+
+ for flow_type in ['sflow', 'netflow']:
+ if flow_type in flow_accounting:
+ default_values = defaults(base + [flow_type])
+ # we need to merge individual server configurations
+ if 'server' in default_values:
+ del default_values['server']
+ flow_accounting[flow_type] = dict_merge(default_values, flow_accounting[flow_type])
+
+ if 'server' in flow_accounting[flow_type]:
+ default_values = defaults(base + [flow_type, 'server'])
+ for server in flow_accounting[flow_type]['server']:
+ flow_accounting[flow_type]['server'][server] = dict_merge(
+ default_values,flow_accounting[flow_type]['server'][server])
+
+ return flow_accounting
+
+def verify(flow_config):
+ if not flow_config:
+ return None
# check if at least one collector is enabled
- if not (config['sflow']['configured'] or config['netflow']['configured'] or not config['disable-imt']):
- raise ConfigError("You need to configure at least one sFlow or NetFlow protocol, or not set \"disable-imt\" for flow-accounting")
+ if 'sflow' not in flow_config and 'netflow' not in flow_config and 'disable_imt' in flow_config:
+ raise ConfigError('You need to configure at least sFlow or NetFlow, ' \
+ 'or not set "disable-imt" for flow-accounting!')
# Check if at least one interface is configured
- if not config['interfaces']:
- raise ConfigError("You need to configure at least one interface for flow-accounting")
+ if 'interface' not in flow_config:
+ raise ConfigError('Flow accounting requires at least one interface to ' \
+ 'be configured!')
# check that all configured interfaces exists in the system
- for iface in config['interfaces']:
- if not iface in Section.interfaces():
- # chnged from error to warning to allow adding dynamic interfaces and interface templates
- # raise ConfigError("The {} interface is not presented in the system".format(iface))
- print("Warning: the {} interface is not presented in the system".format(iface))
+ for interface in flow_config['interface']:
+ if interface not in Section.interfaces():
+ # Changed from error to warning to allow adding dynamic interfaces
+ # and interface templates
+ Warning(f'Interface "{interface}" is not presented in the system')
# check sFlow configuration
- if config['sflow']['configured']:
- # check if at least one sFlow collector is configured if sFlow configuration is presented
- if not config['sflow']['servers']:
- raise ConfigError("You need to configure at least one sFlow server")
+ if 'sflow' in flow_config:
+ # check if at least one sFlow collector is configured
+ if 'server' not in flow_config['sflow']:
+ raise ConfigError('You need to configure at least one sFlow server!')
# check that all sFlow collectors use the same IP protocol version
sflow_collector_ipver = None
- for sflow_collector in config['sflow']['servers']:
+ for server in flow_config['sflow']['server']:
if sflow_collector_ipver:
- if sflow_collector_ipver != ip_address(sflow_collector['address']).version:
+ if sflow_collector_ipver != ip_address(server).version:
raise ConfigError("All sFlow servers must use the same IP protocol")
else:
- sflow_collector_ipver = ip_address(sflow_collector['address']).version
-
+ sflow_collector_ipver = ip_address(server).version
# check agent-id for sFlow: we should avoid mixing IPv4 agent-id with IPv6 collectors and vice-versa
- for sflow_collector in config['sflow']['servers']:
- if ip_address(sflow_collector['address']).version != ip_address(config['sflow']['agent-address']).version:
- raise ConfigError("Different IP address versions cannot be mixed in \"sflow agent-address\" and \"sflow server\". You need to set manually the same IP version for \"agent-address\" as for all sFlow servers")
-
- # check if configured sFlow agent-id exist in the system
- agent_id_presented = None
- for iface in Section.interfaces():
- for address in Interface(iface).get_addr():
- # check an IP, if this is not loopback
- regex_filter = re.compile('^(?!(127)|(::1)|(fe80))(?P<ipaddr>[a-f\d\.:]+)/\d+$')
- if regex_filter.search(address):
- if regex_filter.search(address).group('ipaddr') == config['sflow']['agent-address']:
- agent_id_presented = True
- break
- if not agent_id_presented:
- raise ConfigError("Your \"sflow agent-address\" does not exist in the system")
+ for server in flow_config['sflow']['server']:
+ if 'agent_address' in flow_config['sflow']:
+ if ip_address(server).version != ip_address(flow_config['sflow']['agent_address']).version:
+ raise ConfigError('IPv4 and IPv6 addresses can not be mixed in "sflow agent-address" and "sflow '\
+ 'server". You need to set the same IP version for both "agent-address" and '\
+ 'all sFlow servers')
+
+ if 'agent_address' in flow_config['sflow']:
+ tmp = flow_config['sflow']['agent_address']
+ if not is_addr_assigned(tmp):
+ raise ConfigError(f'Configured "sflow agent-address {tmp}" does not exist in the system!')
+
+ # Check if configured netflow source-address exist in the system
+ if 'source_address' in flow_config['sflow']:
+ if not is_addr_assigned(flow_config['sflow']['source_address']):
+ tmp = flow_config['sflow']['source_address']
+ raise ConfigError(f'Configured "sflow source-address {tmp}" does not exist on the system!')
# check NetFlow configuration
- if config['netflow']['configured']:
+ if 'netflow' in flow_config:
# check if at least one NetFlow collector is configured if NetFlow configuration is presented
- if not config['netflow']['servers']:
- raise ConfigError("You need to configure at least one NetFlow server")
-
- # check if configured netflow source-ip exist in the system
- if config['netflow']['source-ip']:
- source_ip_presented = None
- for iface in Section.interfaces():
- for address in Interface(iface).get_addr():
- # check an IP
- regex_filter = re.compile('^(?!(127)|(::1)|(fe80))(?P<ipaddr>[a-f\d\.:]+)/\d+$')
- if regex_filter.search(address):
- if regex_filter.search(address).group('ipaddr') == config['netflow']['source-ip']:
- source_ip_presented = True
- break
- if not source_ip_presented:
- print("Warning: your \"netflow source-ip\" does not exist in the system")
-
- # check if engine-id compatible with selected protocol version
- if config['netflow']['engine-id']:
+ if 'server' not in flow_config['netflow']:
+ raise ConfigError('You need to configure at least one NetFlow server!')
+
+ # Check if configured netflow source-address exist in the system
+ if 'source_address' in flow_config['netflow']:
+ if not is_addr_assigned(flow_config['netflow']['source_address']):
+ tmp = flow_config['netflow']['source_address']
+ raise ConfigError(f'Configured "netflow source-address {tmp}" does not exist on the system!')
+
+ # Check if engine-id compatible with selected protocol version
+ if 'engine_id' in flow_config['netflow']:
v5_filter = '^(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]):(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$'
v9v10_filter = '^(\d|[1-9]\d{1,8}|[1-3]\d{9}|4[01]\d{8}|42[0-8]\d{7}|429[0-3]\d{6}|4294[0-8]\d{5}|42949[0-5]\d{4}|429496[0-6]\d{3}|4294967[01]\d{2}|42949672[0-8]\d|429496729[0-5])$'
- if config['netflow']['version'] == '5':
+ engine_id = flow_config['netflow']['engine_id']
+ version = flow_config['netflow']['version']
+
+ if flow_config['netflow']['version'] == '5':
regex_filter = re.compile(v5_filter)
- if not regex_filter.search(config['netflow']['engine-id']):
- raise ConfigError("You cannot use NetFlow engine-id {} together with NetFlow protocol version {}".format(config['netflow']['engine-id'], config['netflow']['version']))
+ if not regex_filter.search(engine_id):
+ raise ConfigError(f'You cannot use NetFlow engine-id "{engine_id}" '\
+ f'together with NetFlow protocol version "{version}"!')
else:
regex_filter = re.compile(v9v10_filter)
- if not regex_filter.search(config['netflow']['engine-id']):
- raise ConfigError("You cannot use NetFlow engine-id {} together with NetFlow protocol version {}".format(config['netflow']['engine-id'], config['netflow']['version']))
+ if not regex_filter.search(flow_config['netflow']['engine_id']):
+ raise ConfigError(f'Can not use NetFlow engine-id "{engine_id}" together '\
+ f'with NetFlow protocol version "{version}"!')
# return True if all checks were passed
return True
-def generate(config):
- # skip all checks if flow-accounting was removed
- if not config['flow-accounting-configured']:
- return True
-
- # Calculate all necessary values
- if config['buffer-size']:
- # circular queue size
- config['plugin_pipe_size'] = int(config['buffer-size']) * 1024**2
- else:
- config['plugin_pipe_size'] = default_plugin_pipe_size * 1024**2
- # transfer buffer size
- # recommended value from pmacct developers 1/1000 of pipe size
- config['plugin_buffer_size'] = int(config['plugin_pipe_size'] / 1000)
-
- # Prepare a timeouts string
- timeout_string = ''
- for timeout_type, timeout_value in config['netflow']['timeout'].items():
- if timeout_value:
- if timeout_string == '':
- timeout_string = "{}{}={}".format(timeout_string, timeout_type, timeout_value)
- else:
- timeout_string = "{}:{}={}".format(timeout_string, timeout_type, timeout_value)
- config['netflow']['timeout_string'] = timeout_string
-
- render(uacctd_conf_path, 'netflow/uacctd.conf.tmpl', {
- 'templatecfg': config,
- 'snaplen': default_captured_packet_size,
- })
+def generate(flow_config):
+ if not flow_config:
+ return None
+ render(uacctd_conf_path, 'pmacct/uacctd.conf.j2', flow_config)
+ render(systemd_override, 'pmacct/override.conf.j2', flow_config)
+ # Reload systemd manager configuration
+ call('systemctl daemon-reload')
-def apply(config):
- # define variables
- command = None
+def apply(flow_config):
+ action = 'restart'
# Check if flow-accounting was removed and define command
- if not config['flow-accounting-configured']:
- command = 'systemctl stop uacctd.service'
- else:
- command = 'systemctl restart uacctd.service'
+ if not flow_config:
+ _nftables_config([], 'ingress')
+ _nftables_config([], 'egress')
+
+ # Stop flow-accounting daemon and remove configuration file
+ call(f'systemctl stop {systemd_service}')
+ if os.path.exists(uacctd_conf_path):
+ os.unlink(uacctd_conf_path)
+ return
- # run command to start or stop flow-accounting
- cmd(command, raising=ConfigError, message='Failed to start/stop flow-accounting')
+ # Start/reload flow-accounting daemon
+ call(f'systemctl restart {systemd_service}')
- # configure iptables rules for defined interfaces
- if config['interfaces']:
- _iptables_config(config['interfaces'], 'ingress')
+ # configure nftables rules for defined interfaces
+ if 'interface' in flow_config:
+ _nftables_config(flow_config['interface'], 'ingress', flow_config['packet_length'])
# configure egress the same way if configured otherwise remove it
- if config['enable-egress']:
- _iptables_config(config['interfaces'], 'egress')
+ if 'enable_egress' in flow_config:
+ _nftables_config(flow_config['interface'], 'egress', flow_config['packet_length'])
else:
- _iptables_config([], 'egress')
- else:
- _iptables_config([], 'ingress')
- _iptables_config([], 'egress')
+ _nftables_config([], 'egress')
if __name__ == '__main__':
try:
diff --git a/src/conf_mode/vrrp.py b/src/conf_mode/high-availability.py
index c72efc61f..e14050dd3 100755
--- a/src/conf_mode/vrrp.py
+++ b/src/conf_mode/high-availability.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2021 VyOS maintainers and contributors
+# Copyright (C) 2018-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -28,7 +28,6 @@ from vyos.template import render
from vyos.template import is_ipv4
from vyos.template import is_ipv6
from vyos.util import call
-from vyos.util import is_systemd_service_running
from vyos.xml import defaults
from vyos import ConfigError
from vyos import airbag
@@ -40,33 +39,41 @@ def get_config(config=None):
else:
conf = Config()
- base = ['high-availability', 'vrrp']
+ base = ['high-availability']
+ base_vrrp = ['high-availability', 'vrrp']
if not conf.exists(base):
return None
- vrrp = conf.get_config_dict(base, key_mangling=('-', '_'),
+ ha = conf.get_config_dict(base, key_mangling=('-', '_'),
get_first_key=True, no_tag_node_value_mangle=True)
# We have gathered the dict representation of the CLI, but there are default
# options which we need to update into the dictionary retrived.
- if 'group' in vrrp:
- default_values = defaults(base + ['group'])
- for group in vrrp['group']:
- vrrp['group'][group] = dict_merge(default_values, vrrp['group'][group])
+ if 'vrrp' in ha:
+ if 'group' in ha['vrrp']:
+ default_values_vrrp = defaults(base_vrrp + ['group'])
+ for group in ha['vrrp']['group']:
+ ha['vrrp']['group'][group] = dict_merge(default_values_vrrp, ha['vrrp']['group'][group])
+
+ # Merge per virtual-server default values
+ if 'virtual_server' in ha:
+ default_values = defaults(base + ['virtual-server'])
+ for vs in ha['virtual_server']:
+ ha['virtual_server'][vs] = dict_merge(default_values, ha['virtual_server'][vs])
## Get the sync group used for conntrack-sync
conntrack_path = ['service', 'conntrack-sync', 'failover-mechanism', 'vrrp', 'sync-group']
if conf.exists(conntrack_path):
- vrrp['conntrack_sync_group'] = conf.return_value(conntrack_path)
+ ha['conntrack_sync_group'] = conf.return_value(conntrack_path)
- return vrrp
+ return ha
-def verify(vrrp):
- if not vrrp:
+def verify(ha):
+ if not ha:
return None
used_vrid_if = []
- if 'group' in vrrp:
- for group, group_config in vrrp['group'].items():
+ if 'vrrp' in ha and 'group' in ha['vrrp']:
+ for group, group_config in ha['vrrp']['group'].items():
# Check required fields
if 'vrid' not in group_config:
raise ConfigError(f'VRID is required but not set in VRRP group "{group}"')
@@ -119,33 +126,41 @@ def verify(vrrp):
if is_ipv4(group_config['peer_address']):
raise ConfigError(f'VRRP group "{group}" uses IPv6 but peer-address is IPv4!')
# Check sync groups
- if 'sync_group' in vrrp:
- for sync_group, sync_config in vrrp['sync_group'].items():
+ if 'vrrp' in ha and 'sync_group' in ha['vrrp']:
+ for sync_group, sync_config in ha['vrrp']['sync_group'].items():
if 'member' in sync_config:
for member in sync_config['member']:
- if member not in vrrp['group']:
+ if member not in ha['vrrp']['group']:
raise ConfigError(f'VRRP sync-group "{sync_group}" refers to VRRP group "{member}", '\
'but it does not exist!')
-def generate(vrrp):
- if not vrrp:
+ # Virtual-server
+ if 'virtual_server' in ha:
+ for vs, vs_config in ha['virtual_server'].items():
+ if 'port' not in vs_config:
+ raise ConfigError(f'Port is required but not set for virtual-server "{vs}"')
+ if 'real_server' not in vs_config:
+ raise ConfigError(f'Real-server ip is required but not set for virtual-server "{vs}"')
+ # Real-server
+ for rs, rs_config in vs_config['real_server'].items():
+ if 'port' not in rs_config:
+ raise ConfigError(f'Port is required but not set for virtual-server "{vs}" real-server "{rs}"')
+
+
+def generate(ha):
+ if not ha:
return None
- render(VRRP.location['config'], 'vrrp/keepalived.conf.tmpl', vrrp)
+ render(VRRP.location['config'], 'high-availability/keepalived.conf.j2', ha)
return None
-def apply(vrrp):
+def apply(ha):
service_name = 'keepalived.service'
- if not vrrp:
+ if not ha:
call(f'systemctl stop {service_name}')
return None
- # XXX: T3944 - reload keepalived configuration if service is already running
- # to not cause any service disruption when applying changes.
- if is_systemd_service_running(service_name):
- call(f'systemctl reload {service_name}')
- else:
- call(f'systemctl restart {service_name}')
+ call(f'systemctl reload-or-restart {service_name}')
return None
if __name__ == '__main__':
diff --git a/src/conf_mode/host_name.py b/src/conf_mode/host_name.py
index 87bad0dc6..93f244f42 100755
--- a/src/conf_mode/host_name.py
+++ b/src/conf_mode/host_name.py
@@ -21,13 +21,14 @@ import copy
import vyos.util
import vyos.hostsd_client
-from vyos import ConfigError
+from vyos.base import Warning
from vyos.config import Config
from vyos.ifconfig import Section
from vyos.template import is_ip
from vyos.util import cmd
from vyos.util import call
from vyos.util import process_named_running
+from vyos import ConfigError
from vyos import airbag
airbag.enable()
@@ -113,7 +114,7 @@ def verify(hosts):
for interface, interface_config in hosts['nameservers_dhcp_interfaces'].items():
# Warnin user if interface does not have DHCP or DHCPv6 configured
if not set(interface_config).intersection(['dhcp', 'dhcpv6']):
- print(f'WARNING: "{interface}" is not a DHCP interface but uses DHCP name-server option!')
+ Warning(f'"{interface}" is not a DHCP interface but uses DHCP name-server option!')
return None
diff --git a/src/conf_mode/http-api.py b/src/conf_mode/http-api.py
index 7e4b117c8..4a7906c17 100755
--- a/src/conf_mode/http-api.py
+++ b/src/conf_mode/http-api.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019 VyOS maintainers and contributors
+# Copyright (C) 2019-2021 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -13,25 +13,26 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-#
import sys
import os
import json
-import time
+
+from time import sleep
from copy import deepcopy
import vyos.defaults
+
from vyos.config import Config
-from vyos import ConfigError
+from vyos.template import render
from vyos.util import cmd
from vyos.util import call
-
+from vyos import ConfigError
from vyos import airbag
airbag.enable()
-config_file = '/etc/vyos/http-api.conf'
+api_conf_file = '/etc/vyos/http-api.conf'
+systemd_service = '/run/systemd/system/vyos-http-api.service'
vyos_conf_scripts_dir=vyos.defaults.directories['conf_mode']
@@ -49,21 +50,44 @@ def get_config(config=None):
else:
conf = Config()
- if not conf.exists('service https api'):
+ base = ['service', 'https', 'api']
+ if not conf.exists(base):
return None
- else:
- conf.set_level('service https api')
+ # Do we run inside a VRF context?
+ vrf_path = ['service', 'https', 'vrf']
+ if conf.exists(vrf_path):
+ http_api['vrf'] = conf.return_value(vrf_path)
+
+ conf.set_level('service https api')
if conf.exists('strict'):
- http_api['strict'] = 'true'
+ http_api['strict'] = True
if conf.exists('debug'):
- http_api['debug'] = 'true'
+ http_api['debug'] = True
+
+ # this node is not available by CLI by default, and is reserved for
+ # the graphql tools. One can enable it for testing, with the warning
+ # that this will open an unauthenticated server. To do so
+ # mkdir /opt/vyatta/share/vyatta-cfg/templates/service/https/api/gql
+ # touch /opt/vyatta/share/vyatta-cfg/templates/service/https/api/gql/node.def
+ # and configure; editing the config alone is insufficient.
+ if conf.exists('gql'):
+ http_api['gql'] = True
+
+ if conf.exists('socket'):
+ http_api['socket'] = True
if conf.exists('port'):
port = conf.return_value('port')
http_api['port'] = port
+ if conf.exists('cors'):
+ http_api['cors'] = {}
+ if conf.exists('cors allow-origin'):
+ origins = conf.return_values('cors allow-origin')
+ http_api['cors']['origins'] = origins[:]
+
if conf.exists('keys'):
for name in conf.list_nodes('keys id'):
if conf.exists('keys id {0} key'.format(name)):
@@ -83,24 +107,31 @@ def verify(http_api):
def generate(http_api):
if http_api is None:
+ if os.path.exists(systemd_service):
+ os.unlink(systemd_service)
return None
if not os.path.exists('/etc/vyos'):
os.mkdir('/etc/vyos')
- with open(config_file, 'w') as f:
+ with open(api_conf_file, 'w') as f:
json.dump(http_api, f, indent=2)
+ render(systemd_service, 'https/vyos-http-api.service.j2', http_api)
return None
def apply(http_api):
+ # Reload systemd manager configuration
+ call('systemctl daemon-reload')
+ service_name = 'vyos-http-api.service'
+
if http_api is not None:
- call('systemctl restart vyos-http-api.service')
+ call(f'systemctl restart {service_name}')
else:
- call('systemctl stop vyos-http-api.service')
+ call(f'systemctl stop {service_name}')
# Let uvicorn settle before restarting Nginx
- time.sleep(2)
+ sleep(1)
cmd(f'{vyos_conf_scripts_dir}/https.py', raising=ConfigError)
diff --git a/src/conf_mode/https.py b/src/conf_mode/https.py
index 92dc4a410..3057357fc 100755
--- a/src/conf_mode/https.py
+++ b/src/conf_mode/https.py
@@ -23,6 +23,7 @@ import vyos.defaults
import vyos.certbot_util
from vyos.config import Config
+from vyos.configverify import verify_vrf
from vyos import ConfigError
from vyos.pki import wrap_certificate
from vyos.pki import wrap_private_key
@@ -34,6 +35,7 @@ from vyos import airbag
airbag.enable()
config_file = '/etc/nginx/sites-available/default'
+systemd_override = r'/etc/systemd/system/nginx.service.d/override.conf'
cert_dir = '/etc/ssl/certs'
key_dir = '/etc/ssl/private'
certbot_dir = vyos.defaults.directories['certbot']
@@ -59,10 +61,11 @@ def get_config(config=None):
else:
conf = Config()
- if not conf.exists('service https'):
+ base = ['service', 'https']
+ if not conf.exists(base):
return None
- https = conf.get_config_dict('service https', get_first_key=True)
+ https = conf.get_config_dict(base, get_first_key=True)
if https:
https['pki'] = conf.get_config_dict(['pki'], key_mangling=('-', '_'),
@@ -103,6 +106,8 @@ def verify(https):
if not domains_found:
raise ConfigError("At least one 'virtual-host <id> server-name' "
"matching the 'certbot domain-name' is required.")
+
+ verify_vrf(https)
return None
def generate(https):
@@ -143,7 +148,6 @@ def generate(https):
server_cert = str(wrap_certificate(pki_cert['certificate']))
if 'ca-certificate' in cert_dict:
ca_cert = cert_dict['ca-certificate']
- print(ca_cert)
server_cert += '\n' + str(wrap_certificate(https['pki']['ca'][ca_cert]['certificate']))
write_file(cert_path, server_cert)
@@ -188,6 +192,8 @@ def generate(https):
vhosts = https.get('api-restrict', {}).get('virtual-host', [])
if vhosts:
api_data['vhost'] = vhosts[:]
+ if 'socket' in list(api_settings):
+ api_data['socket'] = True
if api_data:
vhost_list = api_data.get('vhost', [])
@@ -208,11 +214,13 @@ def generate(https):
'certbot': certbot
}
- render(config_file, 'https/nginx.default.tmpl', data)
-
+ render(config_file, 'https/nginx.default.j2', data)
+ render(systemd_override, 'https/override.conf.j2', https)
return None
def apply(https):
+ # Reload systemd manager configuration
+ call('systemctl daemon-reload')
if https is not None:
call('systemctl restart nginx.service')
else:
diff --git a/src/conf_mode/igmp_proxy.py b/src/conf_mode/igmp_proxy.py
index fb030c9f3..de6a51c64 100755
--- a/src/conf_mode/igmp_proxy.py
+++ b/src/conf_mode/igmp_proxy.py
@@ -19,6 +19,7 @@ import os
from sys import exit
from netifaces import interfaces
+from vyos.base import Warning
from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.template import render
@@ -92,10 +93,10 @@ def generate(igmp_proxy):
# bail out early - service is disabled, but inform user
if 'disable' in igmp_proxy:
- print('WARNING: IGMP Proxy will be deactivated because it is disabled')
+ Warning('IGMP Proxy will be deactivated because it is disabled')
return None
- render(config_file, 'igmp-proxy/igmpproxy.conf.tmpl', igmp_proxy)
+ render(config_file, 'igmp-proxy/igmpproxy.conf.j2', igmp_proxy)
return None
diff --git a/src/conf_mode/interfaces-bonding.py b/src/conf_mode/interfaces-bonding.py
index 431d65f1f..4167594e3 100755
--- a/src/conf_mode/interfaces-bonding.py
+++ b/src/conf_mode/interfaces-bonding.py
@@ -27,8 +27,9 @@ from vyos.configdict import is_source_interface
from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_dhcpv6
-from vyos.configverify import verify_source_interface
+from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_mtu_ipv6
+from vyos.configverify import verify_source_interface
from vyos.configverify import verify_vlan_config
from vyos.configverify import verify_vrf
from vyos.ifconfig import BondIf
@@ -67,7 +68,7 @@ def get_config(config=None):
else:
conf = Config()
base = ['interfaces', 'bonding']
- bond = get_interface_dict(conf, base)
+ ifname, bond = get_interface_dict(conf, base)
# To make our own life easier transfor the list of member interfaces
# into a dictionary - we will use this to add additional information
@@ -80,14 +81,14 @@ def get_config(config=None):
if 'mode' in bond:
bond['mode'] = get_bond_mode(bond['mode'])
- tmp = leaf_node_changed(conf, ['mode'])
+ tmp = leaf_node_changed(conf, base + [ifname, 'mode'])
if tmp: bond.update({'shutdown_required': {}})
- tmp = leaf_node_changed(conf, ['lacp-rate'])
+ tmp = leaf_node_changed(conf, base + [ifname, 'lacp-rate'])
if tmp: bond.update({'shutdown_required': {}})
# determine which members have been removed
- interfaces_removed = leaf_node_changed(conf, ['member', 'interface'])
+ interfaces_removed = leaf_node_changed(conf, base + [ifname, 'member', 'interface'])
if interfaces_removed:
bond.update({'shutdown_required': {}})
if 'member' not in bond:
@@ -132,10 +133,10 @@ def verify(bond):
return None
if 'arp_monitor' in bond:
- if 'target' in bond['arp_monitor'] and len(int(bond['arp_monitor']['target'])) > 16:
+ if 'target' in bond['arp_monitor'] and len(bond['arp_monitor']['target']) > 16:
raise ConfigError('The maximum number of arp-monitor targets is 16')
- if 'interval' in bond['arp_monitor'] and len(int(bond['arp_monitor']['interval'])) > 0:
+ if 'interval' in bond['arp_monitor'] and int(bond['arp_monitor']['interval']) > 0:
if bond['mode'] in ['802.3ad', 'balance-tlb', 'balance-alb']:
raise ConfigError('ARP link monitoring does not work for mode 802.3ad, ' \
'transmit-load-balance or adaptive-load-balance')
@@ -149,6 +150,7 @@ def verify(bond):
verify_address(bond)
verify_dhcpv6(bond)
verify_vrf(bond)
+ verify_mirror_redirect(bond)
# use common function to verify VLAN configuration
verify_vlan_config(bond)
diff --git a/src/conf_mode/interfaces-bridge.py b/src/conf_mode/interfaces-bridge.py
index 4d3ebc587..38ae727c1 100755
--- a/src/conf_mode/interfaces-bridge.py
+++ b/src/conf_mode/interfaces-bridge.py
@@ -22,12 +22,12 @@ from netifaces import interfaces
from vyos.config import Config
from vyos.configdict import get_interface_dict
from vyos.configdict import node_changed
-from vyos.configdict import leaf_node_changed
from vyos.configdict import is_member
from vyos.configdict import is_source_interface
from vyos.configdict import has_vlan_subinterface_configured
from vyos.configdict import dict_merge
from vyos.configverify import verify_dhcpv6
+from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_vrf
from vyos.ifconfig import BridgeIf
from vyos.validate import has_address_configured
@@ -50,15 +50,15 @@ def get_config(config=None):
else:
conf = Config()
base = ['interfaces', 'bridge']
- bridge = get_interface_dict(conf, base)
+ ifname, bridge = get_interface_dict(conf, base)
# determine which members have been removed
- tmp = node_changed(conf, ['member', 'interface'], key_mangling=('-', '_'))
+ tmp = node_changed(conf, base + [ifname, 'member', 'interface'], key_mangling=('-', '_'))
if tmp:
if 'member' in bridge:
- bridge['member'].update({'interface_remove': tmp })
+ bridge['member'].update({'interface_remove' : tmp })
else:
- bridge.update({'member': {'interface_remove': tmp }})
+ bridge.update({'member' : {'interface_remove' : tmp }})
if dict_search('member.interface', bridge):
# XXX: T2665: we need a copy of the dict keys for iteration, else we will get:
@@ -106,6 +106,7 @@ def verify(bridge):
verify_dhcpv6(bridge)
verify_vrf(bridge)
+ verify_mirror_redirect(bridge)
ifname = bridge['ifname']
diff --git a/src/conf_mode/interfaces-dummy.py b/src/conf_mode/interfaces-dummy.py
index 55c783f38..e771581e1 100755
--- a/src/conf_mode/interfaces-dummy.py
+++ b/src/conf_mode/interfaces-dummy.py
@@ -21,6 +21,7 @@ from vyos.configdict import get_interface_dict
from vyos.configverify import verify_vrf
from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
+from vyos.configverify import verify_mirror_redirect
from vyos.ifconfig import DummyIf
from vyos import ConfigError
from vyos import airbag
@@ -36,7 +37,7 @@ def get_config(config=None):
else:
conf = Config()
base = ['interfaces', 'dummy']
- dummy = get_interface_dict(conf, base)
+ _, dummy = get_interface_dict(conf, base)
return dummy
def verify(dummy):
@@ -46,6 +47,7 @@ def verify(dummy):
verify_vrf(dummy)
verify_address(dummy)
+ verify_mirror_redirect(dummy)
return None
diff --git a/src/conf_mode/interfaces-ethernet.py b/src/conf_mode/interfaces-ethernet.py
index e7250fb49..fec4456fb 100755
--- a/src/conf_mode/interfaces-ethernet.py
+++ b/src/conf_mode/interfaces-ethernet.py
@@ -19,20 +19,23 @@ import os
from glob import glob
from sys import exit
+from vyos.base import Warning
from vyos.config import Config
from vyos.configdict import get_interface_dict
from vyos.configverify import verify_address
from vyos.configverify import verify_dhcpv6
from vyos.configverify import verify_eapol
from vyos.configverify import verify_interface_exists
-from vyos.configverify import verify_mirror
+from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_mtu
from vyos.configverify import verify_mtu_ipv6
from vyos.configverify import verify_vlan_config
from vyos.configverify import verify_vrf
from vyos.ethtool import Ethtool
from vyos.ifconfig import EthernetIf
-from vyos.pki import wrap_certificate
+from vyos.pki import find_chain
+from vyos.pki import encode_certificate
+from vyos.pki import load_certificate
from vyos.pki import wrap_private_key
from vyos.template import render
from vyos.util import call
@@ -62,7 +65,7 @@ def get_config(config=None):
get_first_key=True, no_tag_node_value_mangle=True)
base = ['interfaces', 'ethernet']
- ethernet = get_interface_dict(conf, base)
+ _, ethernet = get_interface_dict(conf, base)
if 'deleted' not in ethernet:
if pki: ethernet['pki'] = pki
@@ -81,7 +84,7 @@ def verify(ethernet):
verify_address(ethernet)
verify_vrf(ethernet)
verify_eapol(ethernet)
- verify_mirror(ethernet)
+ verify_mirror_redirect(ethernet)
ethtool = Ethtool(ifname)
# No need to check speed and duplex keys as both have default values.
@@ -140,8 +143,8 @@ def verify(ethernet):
raise ConfigError('XDP requires additional TX queues, too few available!')
if {'is_bond_member', 'mac'} <= set(ethernet):
- print(f'WARNING: changing mac address "{mac}" will be ignored as "{ifname}" '
- f'is a member of bond "{is_bond_member}"'.format(**ethernet))
+ Warning(f'changing mac address "{mac}" will be ignored as "{ifname}" ' \
+ f'is a member of bond "{is_bond_member}"'.format(**ethernet))
# use common function to verify VLAN configuration
verify_vlan_config(ethernet)
@@ -150,7 +153,7 @@ def verify(ethernet):
def generate(ethernet):
if 'eapol' in ethernet:
render(wpa_suppl_conf.format(**ethernet),
- 'ethernet/wpa_supplicant.conf.tmpl', ethernet)
+ 'ethernet/wpa_supplicant.conf.j2', ethernet)
ifname = ethernet['ifname']
cert_file_path = os.path.join(cfg_dir, f'{ifname}_cert.pem')
@@ -159,16 +162,26 @@ def generate(ethernet):
cert_name = ethernet['eapol']['certificate']
pki_cert = ethernet['pki']['certificate'][cert_name]
- write_file(cert_file_path, wrap_certificate(pki_cert['certificate']))
+ loaded_pki_cert = load_certificate(pki_cert['certificate'])
+ loaded_ca_certs = {load_certificate(c['certificate'])
+ for c in ethernet['pki']['ca'].values()}
+
+ cert_full_chain = find_chain(loaded_pki_cert, loaded_ca_certs)
+
+ write_file(cert_file_path,
+ '\n'.join(encode_certificate(c) for c in cert_full_chain))
write_file(cert_key_path, wrap_private_key(pki_cert['private']['key']))
if 'ca_certificate' in ethernet['eapol']:
ca_cert_file_path = os.path.join(cfg_dir, f'{ifname}_ca.pem')
ca_cert_name = ethernet['eapol']['ca_certificate']
- pki_ca_cert = ethernet['pki']['ca'][cert_name]
+ pki_ca_cert = ethernet['pki']['ca'][ca_cert_name]
+
+ loaded_ca_cert = load_certificate(pki_ca_cert['certificate'])
+ ca_full_chain = find_chain(loaded_ca_cert, loaded_ca_certs)
write_file(ca_cert_file_path,
- wrap_certificate(pki_ca_cert['certificate']))
+ '\n'.join(encode_certificate(c) for c in ca_full_chain))
else:
# delete configuration on interface removal
if os.path.isfile(wpa_suppl_conf.format(**ethernet)):
diff --git a/src/conf_mode/interfaces-geneve.py b/src/conf_mode/interfaces-geneve.py
index 2a63b60aa..b9cf2fa3c 100755
--- a/src/conf_mode/interfaces-geneve.py
+++ b/src/conf_mode/interfaces-geneve.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2020 VyOS maintainers and contributors
+# Copyright (C) 2019-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -21,9 +21,12 @@ from netifaces import interfaces
from vyos.config import Config
from vyos.configdict import get_interface_dict
+from vyos.configdict import leaf_node_changed
+from vyos.configdict import is_node_changed
from vyos.configverify import verify_address
from vyos.configverify import verify_mtu_ipv6
from vyos.configverify import verify_bridge_delete
+from vyos.configverify import verify_mirror_redirect
from vyos.ifconfig import GeneveIf
from vyos import ConfigError
@@ -40,7 +43,18 @@ def get_config(config=None):
else:
conf = Config()
base = ['interfaces', 'geneve']
- geneve = get_interface_dict(conf, base)
+ ifname, geneve = get_interface_dict(conf, base)
+
+ # GENEVE interfaces are picky and require recreation if certain parameters
+ # change. But a GENEVE interface should - of course - not be re-created if
+ # it's description or IP address is adjusted. Feels somehow logic doesn't it?
+ for cli_option in ['remote', 'vni']:
+ if leaf_node_changed(conf, base + [ifname, cli_option]):
+ geneve.update({'rebuild_required': {}})
+
+ if is_node_changed(conf, base + [ifname, 'parameters']):
+ geneve.update({'rebuild_required': {}})
+
return geneve
def verify(geneve):
@@ -50,6 +64,7 @@ def verify(geneve):
verify_mtu_ipv6(geneve)
verify_address(geneve)
+ verify_mirror_redirect(geneve)
if 'remote' not in geneve:
raise ConfigError('Remote side must be configured')
@@ -65,11 +80,12 @@ def generate(geneve):
def apply(geneve):
# Check if GENEVE interface already exists
- if geneve['ifname'] in interfaces():
- g = GeneveIf(geneve['ifname'])
- # GENEVE is super picky and the tunnel always needs to be recreated,
- # thus we can simply always delete it first.
- g.remove()
+ if 'rebuild_required' in geneve or 'delete' in geneve:
+ if geneve['ifname'] in interfaces():
+ g = GeneveIf(geneve['ifname'])
+ # GENEVE is super picky and the tunnel always needs to be recreated,
+ # thus we can simply always delete it first.
+ g.remove()
if 'deleted' not in geneve:
# Finally create the new interface
diff --git a/src/conf_mode/interfaces-l2tpv3.py b/src/conf_mode/interfaces-l2tpv3.py
index 9b6ddd5aa..6a486f969 100755
--- a/src/conf_mode/interfaces-l2tpv3.py
+++ b/src/conf_mode/interfaces-l2tpv3.py
@@ -25,6 +25,7 @@ from vyos.configdict import leaf_node_changed
from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_mtu_ipv6
+from vyos.configverify import verify_mirror_redirect
from vyos.ifconfig import L2TPv3If
from vyos.util import check_kmod
from vyos.validate import is_addr_assigned
@@ -44,15 +45,15 @@ def get_config(config=None):
else:
conf = Config()
base = ['interfaces', 'l2tpv3']
- l2tpv3 = get_interface_dict(conf, base)
+ ifname, l2tpv3 = get_interface_dict(conf, base)
# To delete an l2tpv3 interface we need the current tunnel and session-id
if 'deleted' in l2tpv3:
- tmp = leaf_node_changed(conf, ['tunnel-id'])
+ tmp = leaf_node_changed(conf, base + [ifname, 'tunnel-id'])
# leaf_node_changed() returns a list
l2tpv3.update({'tunnel_id': tmp[0]})
- tmp = leaf_node_changed(conf, ['session-id'])
+ tmp = leaf_node_changed(conf, base + [ifname, 'session-id'])
l2tpv3.update({'session_id': tmp[0]})
return l2tpv3
@@ -76,6 +77,7 @@ def verify(l2tpv3):
verify_mtu_ipv6(l2tpv3)
verify_address(l2tpv3)
+ verify_mirror_redirect(l2tpv3)
return None
def generate(l2tpv3):
diff --git a/src/conf_mode/interfaces-loopback.py b/src/conf_mode/interfaces-loopback.py
index 193334443..08d34477a 100755
--- a/src/conf_mode/interfaces-loopback.py
+++ b/src/conf_mode/interfaces-loopback.py
@@ -20,6 +20,7 @@ from sys import exit
from vyos.config import Config
from vyos.configdict import get_interface_dict
+from vyos.configverify import verify_mirror_redirect
from vyos.ifconfig import LoopbackIf
from vyos import ConfigError
from vyos import airbag
@@ -35,10 +36,11 @@ def get_config(config=None):
else:
conf = Config()
base = ['interfaces', 'loopback']
- loopback = get_interface_dict(conf, base)
+ _, loopback = get_interface_dict(conf, base)
return loopback
def verify(loopback):
+ verify_mirror_redirect(loopback)
return None
def generate(loopback):
diff --git a/src/conf_mode/interfaces-macsec.py b/src/conf_mode/interfaces-macsec.py
index eab69f36e..279dd119b 100755
--- a/src/conf_mode/interfaces-macsec.py
+++ b/src/conf_mode/interfaces-macsec.py
@@ -29,6 +29,7 @@ from vyos.configverify import verify_vrf
from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_mtu_ipv6
+from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_source_interface
from vyos import ConfigError
from vyos import airbag
@@ -47,7 +48,7 @@ def get_config(config=None):
else:
conf = Config()
base = ['interfaces', 'macsec']
- macsec = get_interface_dict(conf, base)
+ ifname, macsec = get_interface_dict(conf, base)
# Check if interface has been removed
if 'deleted' in macsec:
@@ -66,6 +67,7 @@ def verify(macsec):
verify_vrf(macsec)
verify_mtu_ipv6(macsec)
verify_address(macsec)
+ verify_mirror_redirect(macsec)
if not (('security' in macsec) and
('cipher' in macsec['security'])):
@@ -96,7 +98,7 @@ def verify(macsec):
def generate(macsec):
render(wpa_suppl_conf.format(**macsec),
- 'macsec/wpa_supplicant.conf.tmpl', macsec)
+ 'macsec/wpa_supplicant.conf.j2', macsec)
return None
diff --git a/src/conf_mode/interfaces-openvpn.py b/src/conf_mode/interfaces-openvpn.py
index 3b8fae710..4750ca3e8 100755
--- a/src/conf_mode/interfaces-openvpn.py
+++ b/src/conf_mode/interfaces-openvpn.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2021 VyOS maintainers and contributors
+# Copyright (C) 2019-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -32,8 +32,10 @@ from shutil import rmtree
from vyos.config import Config
from vyos.configdict import get_interface_dict
+from vyos.configdict import is_node_changed
from vyos.configverify import verify_vrf
from vyos.configverify import verify_bridge_delete
+from vyos.configverify import verify_mirror_redirect
from vyos.ifconfig import VTunIf
from vyos.pki import load_dh_parameters
from vyos.pki import load_private_key
@@ -47,6 +49,7 @@ from vyos.template import is_ipv4
from vyos.template import is_ipv6
from vyos.util import call
from vyos.util import chown
+from vyos.util import cmd
from vyos.util import dict_search
from vyos.util import dict_search_args
from vyos.util import makedir
@@ -82,10 +85,12 @@ def get_config(config=None):
tmp_pki = conf.get_config_dict(['pki'], key_mangling=('-', '_'),
get_first_key=True, no_tag_node_value_mangle=True)
- openvpn = get_interface_dict(conf, base)
+ ifname, openvpn = get_interface_dict(conf, base)
if 'deleted' not in openvpn:
openvpn['pki'] = tmp_pki
+ if is_node_changed(conf, base + [ifname, 'openvpn-option']):
+ openvpn.update({'restart_required': {}})
# We have to get the dict using 'get_config_dict' instead of 'get_interface_dict'
# as 'get_interface_dict' merges the defaults in, so we can not check for defaults in there.
@@ -225,11 +230,12 @@ def verify(openvpn):
if 'local_address' not in openvpn and 'is_bridge_member' not in openvpn:
raise ConfigError('Must specify "local-address" or add interface to bridge')
- if len([addr for addr in openvpn['local_address'] if is_ipv4(addr)]) > 1:
- raise ConfigError('Only one IPv4 local-address can be specified')
+ if 'local_address' in openvpn:
+ if len([addr for addr in openvpn['local_address'] if is_ipv4(addr)]) > 1:
+ raise ConfigError('Only one IPv4 local-address can be specified')
- if len([addr for addr in openvpn['local_address'] if is_ipv6(addr)]) > 1:
- raise ConfigError('Only one IPv6 local-address can be specified')
+ if len([addr for addr in openvpn['local_address'] if is_ipv6(addr)]) > 1:
+ raise ConfigError('Only one IPv6 local-address can be specified')
if openvpn['device_type'] == 'tun':
if 'remote_address' not in openvpn:
@@ -268,7 +274,7 @@ def verify(openvpn):
if dict_search('remote_host', openvpn) in dict_search('remote_address', openvpn):
raise ConfigError('"remote-address" and "remote-host" can not be the same')
- if openvpn['device_type'] == 'tap':
+ if openvpn['device_type'] == 'tap' and 'local_address' in openvpn:
# we can only have one local_address, this is ensured above
v4addr = None
for laddr in openvpn['local_address']:
@@ -423,8 +429,8 @@ def verify(openvpn):
# verify specified IP address is present on any interface on this system
if 'local_host' in openvpn:
if not is_addr_assigned(openvpn['local_host']):
- raise ConfigError('local-host IP address "{local_host}" not assigned' \
- ' to any interface'.format(**openvpn))
+ print('local-host IP address "{local_host}" not assigned' \
+ ' to any interface'.format(**openvpn))
# TCP active
if openvpn['protocol'] == 'tcp-active':
@@ -489,6 +495,7 @@ def verify(openvpn):
raise ConfigError('Username for authentication is missing')
verify_vrf(openvpn)
+ verify_mirror_redirect(openvpn)
return None
@@ -600,7 +607,7 @@ def generate(openvpn):
# Generate User/Password authentication file
if 'authentication' in openvpn:
- render(openvpn['auth_user_pass_file'], 'openvpn/auth.pw.tmpl', openvpn,
+ render(openvpn['auth_user_pass_file'], 'openvpn/auth.pw.j2', openvpn,
user=user, group=group, permission=0o600)
else:
# delete old auth file if present
@@ -616,16 +623,16 @@ def generate(openvpn):
# Our client need's to know its subnet mask ...
client_config['server_subnet'] = dict_search('server.subnet', openvpn)
- render(client_file, 'openvpn/client.conf.tmpl', client_config,
+ render(client_file, 'openvpn/client.conf.j2', client_config,
user=user, group=group)
# we need to support quoting of raw parameters from OpenVPN CLI
# see https://phabricator.vyos.net/T1632
- render(cfg_file.format(**openvpn), 'openvpn/server.conf.tmpl', openvpn,
+ render(cfg_file.format(**openvpn), 'openvpn/server.conf.j2', openvpn,
formater=lambda _: _.replace("&quot;", '"'), user=user, group=group)
# Render 20-override.conf for OpenVPN service
- render(service_file.format(**openvpn), 'openvpn/service-override.conf.tmpl', openvpn,
+ render(service_file.format(**openvpn), 'openvpn/service-override.conf.j2', openvpn,
formater=lambda _: _.replace("&quot;", '"'), user=user, group=group)
# Reload systemd services config to apply an override
call(f'systemctl daemon-reload')
@@ -647,9 +654,19 @@ def apply(openvpn):
return None
+ # verify specified IP address is present on any interface on this system
+ # Allow to bind service to nonlocal address, if it virtaual-vrrp address
+ # or if address will be assign later
+ if 'local_host' in openvpn:
+ if not is_addr_assigned(openvpn['local_host']):
+ cmd('sysctl -w net.ipv4.ip_nonlocal_bind=1')
+
# No matching OpenVPN process running - maybe it got killed or none
# existed - nevertheless, spawn new OpenVPN process
- call(f'systemctl reload-or-restart openvpn@{interface}.service')
+ action = 'reload-or-restart'
+ if 'restart_required' in openvpn:
+ action = 'restart'
+ call(f'systemctl {action} openvpn@{interface}.service')
o = VTunIf(**openvpn)
o.update(openvpn)
diff --git a/src/conf_mode/interfaces-pppoe.py b/src/conf_mode/interfaces-pppoe.py
index 584adc75e..e2fdc7a42 100755
--- a/src/conf_mode/interfaces-pppoe.py
+++ b/src/conf_mode/interfaces-pppoe.py
@@ -22,12 +22,15 @@ from netifaces import interfaces
from vyos.config import Config
from vyos.configdict import get_interface_dict
+from vyos.configdict import is_node_changed
from vyos.configdict import leaf_node_changed
+from vyos.configdict import get_pppoe_interfaces
from vyos.configverify import verify_authentication
from vyos.configverify import verify_source_interface
from vyos.configverify import verify_interface_exists
from vyos.configverify import verify_vrf
from vyos.configverify import verify_mtu_ipv6
+from vyos.configverify import verify_mirror_redirect
from vyos.ifconfig import PPPoEIf
from vyos.template import render
from vyos.util import call
@@ -46,33 +49,17 @@ def get_config(config=None):
else:
conf = Config()
base = ['interfaces', 'pppoe']
- pppoe = get_interface_dict(conf, base)
+ ifname, pppoe = get_interface_dict(conf, base)
# We should only terminate the PPPoE session if critical parameters change.
# All parameters that can be changed on-the-fly (like interface description)
# should not lead to a reconnect!
- tmp = leaf_node_changed(conf, ['access-concentrator'])
- if tmp: pppoe.update({'shutdown_required': {}})
-
- tmp = leaf_node_changed(conf, ['connect-on-demand'])
- if tmp: pppoe.update({'shutdown_required': {}})
-
- tmp = leaf_node_changed(conf, ['service-name'])
- if tmp: pppoe.update({'shutdown_required': {}})
-
- tmp = leaf_node_changed(conf, ['source-interface'])
- if tmp: pppoe.update({'shutdown_required': {}})
-
- tmp = leaf_node_changed(conf, ['vrf'])
- # leaf_node_changed() returns a list, as VRF is a non-multi node, there
- # will be only one list element
- if tmp: pppoe.update({'vrf_old': tmp[0]})
-
- tmp = leaf_node_changed(conf, ['authentication', 'user'])
- if tmp: pppoe.update({'shutdown_required': {}})
-
- tmp = leaf_node_changed(conf, ['authentication', 'password'])
- if tmp: pppoe.update({'shutdown_required': {}})
+ for options in ['access-concentrator', 'connect-on-demand', 'service-name',
+ 'source-interface', 'vrf', 'no-default-route', 'authentication']:
+ if is_node_changed(conf, base + [ifname, options]):
+ pppoe.update({'shutdown_required': {}})
+ # bail out early - no need to further process other nodes
+ break
return pppoe
@@ -85,6 +72,7 @@ def verify(pppoe):
verify_authentication(pppoe)
verify_vrf(pppoe)
verify_mtu_ipv6(pppoe)
+ verify_mirror_redirect(pppoe)
if {'connect_on_demand', 'vrf'} <= set(pppoe):
raise ConfigError('On-demand dialing and VRF can not be used at the same time')
@@ -104,7 +92,7 @@ def generate(pppoe):
return None
# Create PPP configuration files
- render(config_pppoe, 'pppoe/peer.tmpl', pppoe, permission=0o640)
+ render(config_pppoe, 'pppoe/peer.j2', pppoe, permission=0o640)
return None
@@ -118,7 +106,7 @@ def apply(pppoe):
return None
# reconnect should only be necessary when certain config options change,
- # like ACS name, authentication, no-peer-dns, source-interface
+ # like ACS name, authentication ... (see get_config() for details)
if ((not is_systemd_service_running(f'ppp@{ifname}.service')) or
'shutdown_required' in pppoe):
@@ -128,6 +116,9 @@ def apply(pppoe):
p.remove()
call(f'systemctl restart ppp@{ifname}.service')
+ # When interface comes "live" a hook is called:
+ # /etc/ppp/ip-up.d/99-vyos-pppoe-callback
+ # which triggers PPPoEIf.update()
else:
if os.path.isdir(f'/sys/class/net/{ifname}'):
p = PPPoEIf(ifname)
diff --git a/src/conf_mode/interfaces-pseudo-ethernet.py b/src/conf_mode/interfaces-pseudo-ethernet.py
index 945a2ea9c..1cd3fe276 100755
--- a/src/conf_mode/interfaces-pseudo-ethernet.py
+++ b/src/conf_mode/interfaces-pseudo-ethernet.py
@@ -18,13 +18,14 @@ from sys import exit
from vyos.config import Config
from vyos.configdict import get_interface_dict
-from vyos.configdict import leaf_node_changed
+from vyos.configdict import is_node_changed
from vyos.configverify import verify_vrf
from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_source_interface
from vyos.configverify import verify_vlan_config
from vyos.configverify import verify_mtu_parent
+from vyos.configverify import verify_mirror_redirect
from vyos.ifconfig import MACVLANIf
from vyos import ConfigError
@@ -41,14 +42,14 @@ def get_config(config=None):
else:
conf = Config()
base = ['interfaces', 'pseudo-ethernet']
- peth = get_interface_dict(conf, base)
+ ifname, peth = get_interface_dict(conf, base)
- mode = leaf_node_changed(conf, ['mode'])
- if mode: peth.update({'mode_old' : mode})
+ mode = is_node_changed(conf, ['mode'])
+ if mode: peth.update({'shutdown_required' : {}})
if 'source_interface' in peth:
- peth['parent'] = get_interface_dict(conf, ['interfaces', 'ethernet'],
- peth['source_interface'])
+ _, peth['parent'] = get_interface_dict(conf, ['interfaces', 'ethernet'],
+ peth['source_interface'])
return peth
def verify(peth):
@@ -60,6 +61,7 @@ def verify(peth):
verify_vrf(peth)
verify_address(peth)
verify_mtu_parent(peth, peth['parent'])
+ verify_mirror_redirect(peth)
# use common function to verify VLAN configuration
verify_vlan_config(peth)
diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py
index 30f57ec0c..eff7f373c 100755
--- a/src/conf_mode/interfaces-tunnel.py
+++ b/src/conf_mode/interfaces-tunnel.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2021 VyOS maintainers and contributors
+# Copyright (C) 2018-2022 yOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -18,24 +18,20 @@ import os
from sys import exit
from netifaces import interfaces
-from ipaddress import IPv4Address
from vyos.config import Config
-from vyos.configdict import dict_merge
from vyos.configdict import get_interface_dict
-from vyos.configdict import node_changed
from vyos.configdict import leaf_node_changed
from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_interface_exists
from vyos.configverify import verify_mtu_ipv6
+from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_vrf
from vyos.configverify import verify_tunnel
from vyos.ifconfig import Interface
from vyos.ifconfig import Section
from vyos.ifconfig import TunnelIf
-from vyos.template import is_ipv4
-from vyos.template import is_ipv6
from vyos.util import get_interface_config
from vyos.util import dict_search
from vyos import ConfigError
@@ -52,10 +48,26 @@ def get_config(config=None):
else:
conf = Config()
base = ['interfaces', 'tunnel']
- tunnel = get_interface_dict(conf, base)
-
- tmp = leaf_node_changed(conf, ['encapsulation'])
- if tmp: tunnel.update({'encapsulation_changed': {}})
+ ifname, tunnel = get_interface_dict(conf, base)
+
+ if 'deleted' not in tunnel:
+ tmp = leaf_node_changed(conf, base + [ifname, 'encapsulation'])
+ if tmp: tunnel.update({'encapsulation_changed': {}})
+
+ # We also need to inspect other configured tunnels as there are Kernel
+ # restrictions where we need to comply. E.g. GRE tunnel key can't be used
+ # twice, or with multiple GRE tunnels to the same location we must specify
+ # a GRE key
+ conf.set_level(base)
+ tunnel['other_tunnels'] = conf.get_config_dict([], key_mangling=('-', '_'),
+ get_first_key=True,
+ no_tag_node_value_mangle=True)
+ # delete our own instance from this dict
+ ifname = tunnel['ifname']
+ del tunnel['other_tunnels'][ifname]
+ # if only one tunnel is present on the system, no need to keep this key
+ if len(tunnel['other_tunnels']) == 0:
+ del tunnel['other_tunnels']
# We must check if our interface is configured to be a DMVPN member
nhrp_base = ['protocols', 'nhrp', 'tunnel']
@@ -96,35 +108,47 @@ def verify(tunnel):
if 'direction' not in tunnel['parameters']['erspan']:
raise ConfigError('ERSPAN version 2 requires direction to be set!')
- # If tunnel source address any and key not set
+ # If tunnel source is any and gre key is not set
+ interface = tunnel['ifname']
if tunnel['encapsulation'] in ['gre'] and \
dict_search('source_address', tunnel) == '0.0.0.0' and \
dict_search('parameters.ip.key', tunnel) == None:
- raise ConfigError('Tunnel parameters ip key must be set!')
-
- if tunnel['encapsulation'] in ['gre', 'gretap']:
- if dict_search('parameters.ip.key', tunnel) != None:
- # Check pairs tunnel source-address/encapsulation/key with exists tunnels.
- # Prevent the same key for 2 tunnels with same source-address/encap. T2920
- for tunnel_if in Section.interfaces('tunnel'):
- # It makes no sense to run the test for re-used GRE keys on our
- # own interface we are currently working on
- if tunnel['ifname'] == tunnel_if:
- continue
- tunnel_cfg = get_interface_config(tunnel_if)
- # no match on encapsulation - bail out
- if dict_search('linkinfo.info_kind', tunnel_cfg) != tunnel['encapsulation']:
- continue
- new_source_address = dict_search('source_address', tunnel)
- # Convert tunnel key to ip key, format "ip -j link show"
- # 1 => 0.0.0.1, 999 => 0.0.3.231
- orig_new_key = dict_search('parameters.ip.key', tunnel)
- new_key = IPv4Address(int(orig_new_key))
- new_key = str(new_key)
- if dict_search('address', tunnel_cfg) == new_source_address and \
- dict_search('linkinfo.info_data.ikey', tunnel_cfg) == new_key:
- raise ConfigError(f'Key "{orig_new_key}" for source-address "{new_source_address}" ' \
+ raise ConfigError(f'"parameters ip key" must be set for {interface} when '\
+ 'encapsulation is GRE!')
+
+ gre_encapsulations = ['gre', 'gretap']
+ if tunnel['encapsulation'] in gre_encapsulations and 'other_tunnels' in tunnel:
+ # Check pairs tunnel source-address/encapsulation/key with exists tunnels.
+ # Prevent the same key for 2 tunnels with same source-address/encap. T2920
+ for o_tunnel, o_tunnel_conf in tunnel['other_tunnels'].items():
+ # no match on encapsulation - bail out
+ our_encapsulation = tunnel['encapsulation']
+ their_encapsulation = o_tunnel_conf['encapsulation']
+ if our_encapsulation in gre_encapsulations and their_encapsulation \
+ not in gre_encapsulations:
+ continue
+
+ our_address = dict_search('source_address', tunnel)
+ our_key = dict_search('parameters.ip.key', tunnel)
+ their_address = dict_search('source_address', o_tunnel_conf)
+ their_key = dict_search('parameters.ip.key', o_tunnel_conf)
+ if our_key != None:
+ if their_address == our_address and their_key == our_key:
+ raise ConfigError(f'Key "{our_key}" for source-address "{our_address}" ' \
f'is already used for tunnel "{tunnel_if}"!')
+ else:
+ our_source_if = dict_search('source_interface', tunnel)
+ their_source_if = dict_search('source_interface', o_tunnel_conf)
+ our_remote = dict_search('remote', tunnel)
+ their_remote = dict_search('remote', o_tunnel_conf)
+ # If no IP GRE key is defined we can not have more then one GRE tunnel
+ # bound to any one interface/IP address and the same remote. This will
+ # result in a OS PermissionError: add tunnel "gre0" failed: File exists
+ if (their_address == our_address or our_source_if == their_source_if) and \
+ our_remote == their_remote:
+ raise ConfigError(f'Missing required "ip key" parameter when '\
+ 'running more then one GRE based tunnel on the '\
+ 'same source-interface/source-address')
# Keys are not allowed with ipip and sit tunnels
if tunnel['encapsulation'] in ['ipip', 'sit']:
@@ -134,6 +158,7 @@ def verify(tunnel):
verify_mtu_ipv6(tunnel)
verify_address(tunnel)
verify_vrf(tunnel)
+ verify_mirror_redirect(tunnel)
if 'source_interface' in tunnel:
verify_interface_exists(tunnel['source_interface'])
diff --git a/src/conf_mode/interfaces-vti.py b/src/conf_mode/interfaces-vti.py
index 57950ffea..f4b0436af 100755
--- a/src/conf_mode/interfaces-vti.py
+++ b/src/conf_mode/interfaces-vti.py
@@ -19,6 +19,7 @@ from sys import exit
from vyos.config import Config
from vyos.configdict import get_interface_dict
+from vyos.configverify import verify_mirror_redirect
from vyos.ifconfig import VTIIf
from vyos.util import dict_search
from vyos import ConfigError
@@ -35,10 +36,11 @@ def get_config(config=None):
else:
conf = Config()
base = ['interfaces', 'vti']
- vti = get_interface_dict(conf, base)
+ _, vti = get_interface_dict(conf, base)
return vti
def verify(vti):
+ verify_mirror_redirect(vti)
return None
def generate(vti):
diff --git a/src/conf_mode/interfaces-vxlan.py b/src/conf_mode/interfaces-vxlan.py
index 804f2d14f..f44d754ba 100755
--- a/src/conf_mode/interfaces-vxlan.py
+++ b/src/conf_mode/interfaces-vxlan.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2020 VyOS maintainers and contributors
+# Copyright (C) 2019-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -19,11 +19,15 @@ import os
from sys import exit
from netifaces import interfaces
+from vyos.base import Warning
from vyos.config import Config
from vyos.configdict import get_interface_dict
+from vyos.configdict import leaf_node_changed
+from vyos.configdict import is_node_changed
from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_mtu_ipv6
+from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_source_interface
from vyos.ifconfig import Interface
from vyos.ifconfig import VXLANIf
@@ -34,15 +38,40 @@ airbag.enable()
def get_config(config=None):
"""
- Retrive CLI config as dictionary. Dictionary can never be empty, as at least the
- interface name will be added or a deleted flag
+ Retrive CLI config as dictionary. Dictionary can never be empty, as at least
+ the interface name will be added or a deleted flag
"""
if config:
conf = config
else:
conf = Config()
base = ['interfaces', 'vxlan']
- vxlan = get_interface_dict(conf, base)
+ ifname, vxlan = get_interface_dict(conf, base)
+
+ # VXLAN interfaces are picky and require recreation if certain parameters
+ # change. But a VXLAN interface should - of course - not be re-created if
+ # it's description or IP address is adjusted. Feels somehow logic doesn't it?
+ for cli_option in ['external', 'gpe', 'group', 'port', 'remote',
+ 'source-address', 'source-interface', 'vni']:
+ if leaf_node_changed(conf, base + [ifname, cli_option]):
+ vxlan.update({'rebuild_required': {}})
+
+ if is_node_changed(conf, base + [ifname, 'parameters']):
+ vxlan.update({'rebuild_required': {}})
+
+ # We need to verify that no other VXLAN tunnel is configured when external
+ # mode is in use - Linux Kernel limitation
+ conf.set_level(base)
+ vxlan['other_tunnels'] = conf.get_config_dict([], key_mangling=('-', '_'),
+ get_first_key=True,
+ no_tag_node_value_mangle=True)
+
+ # This if-clause is just to be sure - it will always evaluate to true
+ ifname = vxlan['ifname']
+ if ifname in vxlan['other_tunnels']:
+ del vxlan['other_tunnels'][ifname]
+ if len(vxlan['other_tunnels']) == 0:
+ del vxlan['other_tunnels']
return vxlan
@@ -52,19 +81,31 @@ def verify(vxlan):
return None
if int(vxlan['mtu']) < 1500:
- print('WARNING: RFC7348 recommends VXLAN tunnels preserve a 1500 byte MTU')
+ Warning('RFC7348 recommends VXLAN tunnels preserve a 1500 byte MTU')
if 'group' in vxlan:
if 'source_interface' not in vxlan:
- raise ConfigError('Multicast VXLAN requires an underlaying interface ')
-
+ raise ConfigError('Multicast VXLAN requires an underlaying interface')
verify_source_interface(vxlan)
if not any(tmp in ['group', 'remote', 'source_address'] for tmp in vxlan):
raise ConfigError('Group, remote or source-address must be configured')
- if 'vni' not in vxlan:
- raise ConfigError('Must configure VNI for VXLAN')
+ if 'vni' not in vxlan and 'external' not in vxlan:
+ raise ConfigError(
+ 'Must either configure VXLAN "vni" or use "external" CLI option!')
+
+ if {'external', 'vni'} <= set(vxlan):
+ raise ConfigError('Can not specify both "external" and "VNI"!')
+
+ if {'external', 'other_tunnels'} <= set(vxlan):
+ other_tunnels = ', '.join(vxlan['other_tunnels'])
+ raise ConfigError(f'Only one VXLAN tunnel is supported when "external" '\
+ f'CLI option is used. Additional tunnels: {other_tunnels}')
+
+ if 'gpe' in vxlan and 'external' not in vxlan:
+ raise ConfigError(f'VXLAN-GPE is only supported when "external" '\
+ f'CLI option is used.')
if 'source_interface' in vxlan:
# VXLAN adds at least an overhead of 50 byte - we need to check the
@@ -81,22 +122,42 @@ def verify(vxlan):
raise ConfigError(f'Underlaying device MTU is to small ({lower_mtu} '\
f'bytes) for VXLAN overhead ({vxlan_overhead} bytes!)')
+ # Check for mixed IPv4 and IPv6 addresses
+ protocol = None
+ if 'source_address' in vxlan:
+ if is_ipv6(vxlan['source_address']):
+ protocol = 'ipv6'
+ else:
+ protocol = 'ipv4'
+
+ if 'remote' in vxlan:
+ error_msg = 'Can not mix both IPv4 and IPv6 for VXLAN underlay'
+ for remote in vxlan['remote']:
+ if is_ipv6(remote):
+ if protocol == 'ipv4':
+ raise ConfigError(error_msg)
+ protocol = 'ipv6'
+ else:
+ if protocol == 'ipv6':
+ raise ConfigError(error_msg)
+ protocol = 'ipv4'
+
verify_mtu_ipv6(vxlan)
verify_address(vxlan)
+ verify_mirror_redirect(vxlan)
return None
-
def generate(vxlan):
return None
-
def apply(vxlan):
# Check if the VXLAN interface already exists
- if vxlan['ifname'] in interfaces():
- v = VXLANIf(vxlan['ifname'])
- # VXLAN is super picky and the tunnel always needs to be recreated,
- # thus we can simply always delete it first.
- v.remove()
+ if 'rebuild_required' in vxlan or 'delete' in vxlan:
+ if vxlan['ifname'] in interfaces():
+ v = VXLANIf(vxlan['ifname'])
+ # VXLAN is super picky and the tunnel always needs to be recreated,
+ # thus we can simply always delete it first.
+ v.remove()
if 'deleted' not in vxlan:
# Finally create the new interface
@@ -105,7 +166,6 @@ def apply(vxlan):
return None
-
if __name__ == '__main__':
try:
c = get_config()
diff --git a/src/conf_mode/interfaces-wireguard.py b/src/conf_mode/interfaces-wireguard.py
index da64dd076..180ffa507 100755
--- a/src/conf_mode/interfaces-wireguard.py
+++ b/src/conf_mode/interfaces-wireguard.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2020 VyOS maintainers and contributors
+# Copyright (C) 2018-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -28,6 +28,7 @@ from vyos.configverify import verify_vrf
from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_mtu_ipv6
+from vyos.configverify import verify_mirror_redirect
from vyos.ifconfig import WireGuardIf
from vyos.util import check_kmod
from vyos.util import check_port_availability
@@ -45,17 +46,17 @@ def get_config(config=None):
else:
conf = Config()
base = ['interfaces', 'wireguard']
- wireguard = get_interface_dict(conf, base)
+ ifname, wireguard = get_interface_dict(conf, base)
# Check if a port was changed
- wireguard['port_changed'] = leaf_node_changed(conf, ['port'])
+ wireguard['port_changed'] = leaf_node_changed(conf, base + [ifname, 'port'])
# Determine which Wireguard peer has been removed.
# Peers can only be removed with their public key!
dict = {}
- tmp = node_changed(conf, ['peer'], key_mangling=('-', '_'))
+ tmp = node_changed(conf, base + [ifname, 'peer'], key_mangling=('-', '_'))
for peer in (tmp or []):
- public_key = leaf_node_changed(conf, ['peer', peer, 'public_key'])
+ public_key = leaf_node_changed(conf, base + [ifname, 'peer', peer, 'public_key'])
if public_key:
dict = dict_merge({'peer_remove' : {peer : {'public_key' : public_key[0]}}}, dict)
wireguard.update(dict)
@@ -70,6 +71,7 @@ def verify(wireguard):
verify_mtu_ipv6(wireguard)
verify_address(wireguard)
verify_vrf(wireguard)
+ verify_mirror_redirect(wireguard)
if 'private_key' not in wireguard:
raise ConfigError('Wireguard private-key not defined')
diff --git a/src/conf_mode/interfaces-wireless.py b/src/conf_mode/interfaces-wireless.py
index af35b5f03..d34297063 100755
--- a/src/conf_mode/interfaces-wireless.py
+++ b/src/conf_mode/interfaces-wireless.py
@@ -27,6 +27,7 @@ from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_dhcpv6
from vyos.configverify import verify_source_interface
+from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_vlan_config
from vyos.configverify import verify_vrf
from vyos.ifconfig import WiFiIf
@@ -75,15 +76,19 @@ def get_config(config=None):
conf = Config()
base = ['interfaces', 'wireless']
- wifi = get_interface_dict(conf, base)
+ ifname, wifi = get_interface_dict(conf, base)
# Cleanup "delete" default values when required user selectable values are
# not defined at all
- tmp = conf.get_config_dict([], key_mangling=('-', '_'), get_first_key=True)
+ tmp = conf.get_config_dict(base + [ifname], key_mangling=('-', '_'),
+ get_first_key=True)
if not (dict_search('security.wpa.passphrase', tmp) or
dict_search('security.wpa.radius', tmp)):
if 'deleted' not in wifi:
del wifi['security']['wpa']
+ # if 'security' key is empty, drop it too
+ if len(wifi['security']) == 0:
+ del wifi['security']
# defaults include RADIUS server specifics per TAG node which need to be
# added to individual RADIUS servers instead - so we can simply delete them
@@ -189,6 +194,7 @@ def verify(wifi):
verify_address(wifi)
verify_vrf(wifi)
+ verify_mirror_redirect(wifi)
# use common function to verify VLAN configuration
verify_vlan_config(wifi)
@@ -242,11 +248,11 @@ def generate(wifi):
# render appropriate new config files depending on access-point or station mode
if wifi['type'] == 'access-point':
- render(hostapd_conf.format(**wifi), 'wifi/hostapd.conf.tmpl',
+ render(hostapd_conf.format(**wifi), 'wifi/hostapd.conf.j2',
wifi)
elif wifi['type'] == 'station':
- render(wpa_suppl_conf.format(**wifi), 'wifi/wpa_supplicant.conf.tmpl',
+ render(wpa_suppl_conf.format(**wifi), 'wifi/wpa_supplicant.conf.j2',
wifi)
return None
diff --git a/src/conf_mode/interfaces-wwan.py b/src/conf_mode/interfaces-wwan.py
index f013e5411..e275ace84 100755
--- a/src/conf_mode/interfaces-wwan.py
+++ b/src/conf_mode/interfaces-wwan.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright (C) 2020-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -17,21 +17,29 @@
import os
from sys import exit
+from time import sleep
from vyos.config import Config
from vyos.configdict import get_interface_dict
+from vyos.configdict import is_node_changed
from vyos.configverify import verify_authentication
from vyos.configverify import verify_interface_exists
+from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_vrf
from vyos.ifconfig import WWANIf
from vyos.util import cmd
from vyos.util import call
from vyos.util import dict_search
from vyos.util import DEVNULL
+from vyos.util import is_systemd_service_active
+from vyos.util import write_file
from vyos import ConfigError
from vyos import airbag
airbag.enable()
+service_name = 'ModemManager.service'
+cron_script = '/etc/cron.d/vyos-wwan'
+
def get_config(config=None):
"""
Retrive CLI config as dictionary. Dictionary can never be empty, as at least the
@@ -42,7 +50,41 @@ def get_config(config=None):
else:
conf = Config()
base = ['interfaces', 'wwan']
- wwan = get_interface_dict(conf, base)
+ ifname, wwan = get_interface_dict(conf, base)
+
+ # We should only terminate the WWAN session if critical parameters change.
+ # All parameters that can be changed on-the-fly (like interface description)
+ # should not lead to a reconnect!
+ tmp = is_node_changed(conf, base + [ifname, 'address'])
+ if tmp: wwan.update({'shutdown_required': {}})
+
+ tmp = is_node_changed(conf, base + [ifname, 'apn'])
+ if tmp: wwan.update({'shutdown_required': {}})
+
+ tmp = is_node_changed(conf, base + [ifname, 'disable'])
+ if tmp: wwan.update({'shutdown_required': {}})
+
+ tmp = is_node_changed(conf, base + [ifname, 'vrf'])
+ if tmp: wwan.update({'shutdown_required': {}})
+
+ tmp = is_node_changed(conf, base + [ifname, 'authentication'])
+ if tmp: wwan.update({'shutdown_required': {}})
+
+ tmp = is_node_changed(conf, base + [ifname, 'ipv6', 'address', 'autoconf'])
+ if tmp: wwan.update({'shutdown_required': {}})
+
+ # We need to know the amount of other WWAN interfaces as ModemManager needs
+ # to be started or stopped.
+ conf.set_level(base)
+ _, wwan['other_interfaces'] = conf.get_config_dict([], key_mangling=('-', '_'),
+ get_first_key=True,
+ no_tag_node_value_mangle=True)
+
+ # This if-clause is just to be sure - it will always evaluate to true
+ if ifname in wwan['other_interfaces']:
+ del wwan['other_interfaces'][ifname]
+ if len(wwan['other_interfaces']) == 0:
+ del wwan['other_interfaces']
return wwan
@@ -57,42 +99,84 @@ def verify(wwan):
verify_interface_exists(ifname)
verify_authentication(wwan)
verify_vrf(wwan)
+ verify_mirror_redirect(wwan)
return None
def generate(wwan):
+ if 'deleted' in wwan:
+ # We are the last WWAN interface - there are no other ones remaining
+ # thus the cronjob needs to go away, too
+ if 'other_interfaces' not in wwan:
+ if os.path.exists(cron_script):
+ os.unlink(cron_script)
+ return None
+
+ # Install cron triggered helper script to re-dial WWAN interfaces on
+ # disconnect - e.g. happens during RF signal loss. The script watches every
+ # WWAN interface - so there is only one instance.
+ if not os.path.exists(cron_script):
+ write_file(cron_script, '*/5 * * * * root /usr/libexec/vyos/vyos-check-wwan.py')
+
return None
def apply(wwan):
- # we only need the modem number. wwan0 -> 0, wwan1 -> 1
- modem = wwan['ifname'].lstrip('wwan')
- base_cmd = f'mmcli --modem {modem}'
- # Number of bearers is limited - always disconnect first
- cmd(f'{base_cmd} --simple-disconnect')
+ # ModemManager is required to dial WWAN connections - one instance is
+ # required to serve all modems. Activate ModemManager on first invocation
+ # of any WWAN interface.
+ if not is_systemd_service_active(service_name):
+ cmd(f'systemctl start {service_name}')
+
+ counter = 100
+ # Wait until a modem is detected and then we can continue
+ while counter > 0:
+ counter -= 1
+ tmp = cmd('mmcli -L')
+ if tmp != 'No modems were found':
+ break
+ sleep(0.250)
+
+ if 'shutdown_required' in wwan:
+ # we only need the modem number. wwan0 -> 0, wwan1 -> 1
+ modem = wwan['ifname'].lstrip('wwan')
+ base_cmd = f'mmcli --modem {modem}'
+ # Number of bearers is limited - always disconnect first
+ cmd(f'{base_cmd} --simple-disconnect')
w = WWANIf(wwan['ifname'])
if 'deleted' in wwan or 'disable' in wwan:
w.remove()
+
+ # We are the last WWAN interface - there are no other WWAN interfaces
+ # remaining, thus we can stop ModemManager and free resources.
+ if 'other_interfaces' not in wwan:
+ cmd(f'systemctl stop {service_name}')
+ # Clean CRON helper script which is used for to re-connect when
+ # RF signal is lost
+ if os.path.exists(cron_script):
+ os.unlink(cron_script)
+
return None
- ip_type = 'ipv4'
- slaac = dict_search('ipv6.address.autoconf', wwan) != None
- if 'address' in wwan:
- if 'dhcp' in wwan['address'] and ('dhcpv6' in wwan['address'] or slaac):
- ip_type = 'ipv4v6'
- elif 'dhcpv6' in wwan['address'] or slaac:
- ip_type = 'ipv6'
- elif 'dhcp' in wwan['address']:
- ip_type = 'ipv4'
-
- options = f'ip-type={ip_type},apn=' + wwan['apn']
- if 'authentication' in wwan:
- options += ',user={user},password={password}'.format(**wwan['authentication'])
-
- command = f'{base_cmd} --simple-connect="{options}"'
- call(command, stdout=DEVNULL)
- w.update(wwan)
+ if 'shutdown_required' in wwan:
+ ip_type = 'ipv4'
+ slaac = dict_search('ipv6.address.autoconf', wwan) != None
+ if 'address' in wwan:
+ if 'dhcp' in wwan['address'] and ('dhcpv6' in wwan['address'] or slaac):
+ ip_type = 'ipv4v6'
+ elif 'dhcpv6' in wwan['address'] or slaac:
+ ip_type = 'ipv6'
+ elif 'dhcp' in wwan['address']:
+ ip_type = 'ipv4'
+
+ options = f'ip-type={ip_type},apn=' + wwan['apn']
+ if 'authentication' in wwan:
+ options += ',user={user},password={password}'.format(**wwan['authentication'])
+ command = f'{base_cmd} --simple-connect="{options}"'
+ call(command, stdout=DEVNULL)
+
+ w.update(wwan)
return None
if __name__ == '__main__':
diff --git a/src/conf_mode/lldp.py b/src/conf_mode/lldp.py
index 082c3e128..c703c1fe0 100755
--- a/src/conf_mode/lldp.py
+++ b/src/conf_mode/lldp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2017-2020 VyOS maintainers and contributors
+# Copyright (C) 2017-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -15,19 +15,20 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
-import re
-from copy import deepcopy
from sys import exit
+from vyos.base import Warning
from vyos.config import Config
+from vyos.configdict import dict_merge
from vyos.validate import is_addr_assigned
from vyos.validate import is_loopback_addr
from vyos.version import get_version_data
-from vyos import ConfigError
from vyos.util import call
+from vyos.util import dict_search
+from vyos.xml import defaults
from vyos.template import render
-
+from vyos import ConfigError
from vyos import airbag
airbag.enable()
@@ -35,178 +36,73 @@ config_file = "/etc/default/lldpd"
vyos_config_file = "/etc/lldpd.d/01-vyos.conf"
base = ['service', 'lldp']
-default_config_data = {
- "options": '',
- "interface_list": '',
- "location": ''
-}
-
-def get_options(config):
- options = {}
- config.set_level(base)
-
- options['listen_vlan'] = config.exists('listen-vlan')
- options['mgmt_addr'] = []
- for addr in config.return_values('management-address'):
- if is_addr_assigned(addr) and not is_loopback_addr(addr):
- options['mgmt_addr'].append(addr)
- else:
- message = 'WARNING: LLDP management address {0} invalid - '.format(addr)
- if is_loopback_addr(addr):
- message += '(loopback address).'
- else:
- message += 'address not found.'
- print(message)
-
- snmp = config.exists('snmp enable')
- options["snmp"] = snmp
- if snmp:
- config.set_level('')
- options["sys_snmp"] = config.exists('service snmp')
- config.set_level(base)
-
- config.set_level(base + ['legacy-protocols'])
- options['cdp'] = config.exists('cdp')
- options['edp'] = config.exists('edp')
- options['fdp'] = config.exists('fdp')
- options['sonmp'] = config.exists('sonmp')
-
- # start with an unknown version information
- version_data = get_version_data()
- options['description'] = version_data['version']
- options['listen_on'] = []
-
- return options
-
-def get_interface_list(config):
- config.set_level(base)
- intfs_names = config.list_nodes(['interface'])
- if len(intfs_names) < 0:
- return 0
-
- interface_list = []
- for name in intfs_names:
- config.set_level(base + ['interface', name])
- disable = config.exists(['disable'])
- intf = {
- 'name': name,
- 'disable': disable
- }
- interface_list.append(intf)
- return interface_list
-
-
-def get_location_intf(config, name):
- path = base + ['interface', name]
- config.set_level(path)
-
- config.set_level(path + ['location'])
- elin = ''
- coordinate_based = {}
-
- if config.exists('elin'):
- elin = config.return_value('elin')
-
- if config.exists('coordinate-based'):
- config.set_level(path + ['location', 'coordinate-based'])
-
- coordinate_based['latitude'] = config.return_value(['latitude'])
- coordinate_based['longitude'] = config.return_value(['longitude'])
-
- coordinate_based['altitude'] = '0'
- if config.exists(['altitude']):
- coordinate_based['altitude'] = config.return_value(['altitude'])
-
- coordinate_based['datum'] = 'WGS84'
- if config.exists(['datum']):
- coordinate_based['datum'] = config.return_value(['datum'])
-
- intf = {
- 'name': name,
- 'elin': elin,
- 'coordinate_based': coordinate_based
-
- }
- return intf
-
-
-def get_location(config):
- config.set_level(base)
- intfs_names = config.list_nodes(['interface'])
- if len(intfs_names) < 0:
- return 0
-
- if config.exists('disable'):
- return 0
-
- intfs_location = []
- for name in intfs_names:
- intf = get_location_intf(config, name)
- intfs_location.append(intf)
-
- return intfs_location
-
-
def get_config(config=None):
- lldp = deepcopy(default_config_data)
if config:
conf = config
else:
conf = Config()
+
if not conf.exists(base):
- return None
- else:
- lldp['options'] = get_options(conf)
- lldp['interface_list'] = get_interface_list(conf)
- lldp['location'] = get_location(conf)
+ return {}
- return lldp
+ lldp = conf.get_config_dict(base, key_mangling=('-', '_'),
+ get_first_key=True, no_tag_node_value_mangle=True)
+ if conf.exists(['service', 'snmp']):
+ lldp['system_snmp_enabled'] = ''
+
+ version_data = get_version_data()
+ lldp['version'] = version_data['version']
+
+ # We have gathered the dict representation of the CLI, but there are default
+ # options which we need to update into the dictionary retrived.
+ # location coordinates have a default value
+ if 'interface' in lldp:
+ for interface, interface_config in lldp['interface'].items():
+ default_values = defaults(base + ['interface'])
+ if dict_search('location.coordinate_based', interface_config) == None:
+ # no location specified - no need to add defaults
+ del default_values['location']['coordinate_based']['datum']
+ del default_values['location']['coordinate_based']['altitude']
+
+ # cleanup default_values dictionary from inner to outer
+ # this might feel overkill here, but it does support easy extension
+ # in the future with additional default values
+ if len(default_values['location']['coordinate_based']) == 0:
+ del default_values['location']['coordinate_based']
+ if len(default_values['location']) == 0:
+ del default_values['location']
+
+ lldp['interface'][interface] = dict_merge(default_values,
+ lldp['interface'][interface])
+
+ return lldp
def verify(lldp):
# bail out early - looks like removal from running config
if lldp is None:
return
- # check location
- for location in lldp['location']:
- # check coordinate-based
- if len(location['coordinate_based']) > 0:
- # check longitude and latitude
- if not location['coordinate_based']['longitude']:
- raise ConfigError('Must define longitude for interface {0}'.format(location['name']))
-
- if not location['coordinate_based']['latitude']:
- raise ConfigError('Must define latitude for interface {0}'.format(location['name']))
-
- if not re.match(r'^(\d+)(\.\d+)?[nNsS]$', location['coordinate_based']['latitude']):
- raise ConfigError('Invalid location for interface {0}:\n' \
- 'latitude should be a number followed by S or N'.format(location['name']))
-
- if not re.match(r'^(\d+)(\.\d+)?[eEwW]$', location['coordinate_based']['longitude']):
- raise ConfigError('Invalid location for interface {0}:\n' \
- 'longitude should be a number followed by E or W'.format(location['name']))
-
- # check altitude and datum if exist
- if location['coordinate_based']['altitude']:
- if not re.match(r'^[-+0-9\.]+$', location['coordinate_based']['altitude']):
- raise ConfigError('Invalid location for interface {0}:\n' \
- 'altitude should be a positive or negative number'.format(location['name']))
-
- if location['coordinate_based']['datum']:
- if not re.match(r'^(WGS84|NAD83|MLLW)$', location['coordinate_based']['datum']):
- raise ConfigError("Invalid location for interface {0}:\n' \
- 'datum should be WGS84, NAD83, or MLLW".format(location['name']))
-
- # check elin
- elif location['elin']:
- if not re.match(r'^[0-9]{10,25}$', location['elin']):
- raise ConfigError('Invalid location for interface {0}:\n' \
- 'ELIN number must be between 10-25 numbers'.format(location['name']))
+ if 'management_address' in lldp:
+ for address in lldp['management_address']:
+ message = f'LLDP management address "{address}" is invalid'
+ if is_loopback_addr(address):
+ Warning(f'{message} - loopback address')
+ elif not is_addr_assigned(address):
+ Warning(f'{message} - not assigned to any interface')
+
+ if 'interface' in lldp:
+ for interface, interface_config in lldp['interface'].items():
+ # bail out early if no location info present in interface config
+ if 'location' not in interface_config:
+ continue
+ if 'coordinate_based' in interface_config['location']:
+ if not {'latitude', 'latitude'} <= set(interface_config['location']['coordinate_based']):
+ raise ConfigError(f'Must define both longitude and latitude for "{interface}" location!')
# check options
- if lldp['options']['snmp']:
- if not lldp['options']['sys_snmp']:
+ if 'snmp' in lldp and 'enable' in lldp['snmp']:
+ if 'system_snmp_enabled' not in lldp:
raise ConfigError('SNMP must be configured to enable LLDP SNMP')
@@ -215,29 +111,17 @@ def generate(lldp):
if lldp is None:
return
- # generate listen on interfaces
- for intf in lldp['interface_list']:
- tmp = ''
- # add exclamation mark if interface is disabled
- if intf['disable']:
- tmp = '!'
-
- tmp += intf['name']
- lldp['options']['listen_on'].append(tmp)
-
- # generate /etc/default/lldpd
- render(config_file, 'lldp/lldpd.tmpl', lldp)
- # generate /etc/lldpd.d/01-vyos.conf
- render(vyos_config_file, 'lldp/vyos.conf.tmpl', lldp)
-
+ render(config_file, 'lldp/lldpd.j2', lldp)
+ render(vyos_config_file, 'lldp/vyos.conf.j2', lldp)
def apply(lldp):
+ systemd_service = 'lldpd.service'
if lldp:
# start/restart lldp service
- call('systemctl restart lldpd.service')
+ call(f'systemctl restart {systemd_service}')
else:
# LLDP service has been terminated
- call('systemctl stop lldpd.service')
+ call(f'systemctl stop {systemd_service}')
if os.path.isfile(config_file):
os.unlink(config_file)
if os.path.isfile(vyos_config_file):
diff --git a/src/conf_mode/nat.py b/src/conf_mode/nat.py
index 59939d0fb..85819a77e 100755
--- a/src/conf_mode/nat.py
+++ b/src/conf_mode/nat.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright (C) 2020-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -23,11 +23,13 @@ from platform import release as kernel_version
from sys import exit
from netifaces import interfaces
+from vyos.base import Warning
from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.template import render
from vyos.template import is_ip_network
from vyos.util import cmd
+from vyos.util import run
from vyos.util import check_kmod
from vyos.util import dict_search
from vyos.validate import is_addr_assigned
@@ -42,7 +44,7 @@ if LooseVersion(kernel_version()) > LooseVersion('5.1'):
else:
k_mod = ['nft_nat', 'nft_chain_nat_ipv4']
-iptables_nat_config = '/tmp/vyos-nat-rules.nft'
+nftables_nat_config = '/tmp/vyos-nat-rules.nft'
def get_handler(json, chain, target):
""" Get nftable rule handler number of given chain/target combination.
@@ -93,7 +95,6 @@ def get_config(config=None):
nat[direction]['rule'][rule] = dict_merge(default_values,
nat[direction]['rule'][rule])
-
# read in current nftable (once) for further processing
tmp = cmd('nft -j list table raw')
nftable_json = json.loads(tmp)
@@ -106,9 +107,9 @@ def get_config(config=None):
nat['helper_functions'] = 'remove'
# Retrieve current table handler positions
- nat['pre_ct_ignore'] = get_handler(condensed_json, 'PREROUTING', 'VYATTA_CT_HELPER')
+ nat['pre_ct_ignore'] = get_handler(condensed_json, 'PREROUTING', 'VYOS_CT_HELPER')
nat['pre_ct_conntrack'] = get_handler(condensed_json, 'PREROUTING', 'NAT_CONNTRACK')
- nat['out_ct_ignore'] = get_handler(condensed_json, 'OUTPUT', 'VYATTA_CT_HELPER')
+ nat['out_ct_ignore'] = get_handler(condensed_json, 'OUTPUT', 'VYOS_CT_HELPER')
nat['out_ct_conntrack'] = get_handler(condensed_json, 'OUTPUT', 'NAT_CONNTRACK')
nat['deleted'] = ''
return nat
@@ -119,10 +120,10 @@ def get_config(config=None):
nat['helper_functions'] = 'add'
# Retrieve current table handler positions
- nat['pre_ct_ignore'] = get_handler(condensed_json, 'PREROUTING', 'VYATTA_CT_IGNORE')
- nat['pre_ct_conntrack'] = get_handler(condensed_json, 'PREROUTING', 'VYATTA_CT_PREROUTING_HOOK')
- nat['out_ct_ignore'] = get_handler(condensed_json, 'OUTPUT', 'VYATTA_CT_IGNORE')
- nat['out_ct_conntrack'] = get_handler(condensed_json, 'OUTPUT', 'VYATTA_CT_OUTPUT_HOOK')
+ nat['pre_ct_ignore'] = get_handler(condensed_json, 'PREROUTING', 'VYOS_CT_IGNORE')
+ nat['pre_ct_conntrack'] = get_handler(condensed_json, 'PREROUTING', 'VYOS_CT_PREROUTING_HOOK')
+ nat['out_ct_ignore'] = get_handler(condensed_json, 'OUTPUT', 'VYOS_CT_IGNORE')
+ nat['out_ct_conntrack'] = get_handler(condensed_json, 'OUTPUT', 'VYOS_CT_OUTPUT_HOOK')
return nat
@@ -142,14 +143,14 @@ def verify(nat):
raise ConfigError(f'{err_msg} outbound-interface not specified')
if config['outbound_interface'] not in 'any' and config['outbound_interface'] not in interfaces():
- print(f'WARNING: rule "{rule}" interface "{config["outbound_interface"]}" does not exist on this system')
+ Warning(f'rule "{rule}" interface "{config["outbound_interface"]}" does not exist on this system')
addr = dict_search('translation.address', config)
if addr != None:
if addr != 'masquerade' and not is_ip_network(addr):
for ip in addr.split('-'):
if not is_addr_assigned(ip):
- print(f'WARNING: IP address {ip} does not exist on the system!')
+ Warning(f'IP address {ip} does not exist on the system!')
elif 'exclude' not in config:
raise ConfigError(f'{err_msg}\n' \
'translation address not specified')
@@ -167,7 +168,7 @@ def verify(nat):
'inbound-interface not specified')
else:
if config['inbound_interface'] not in 'any' and config['inbound_interface'] not in interfaces():
- print(f'WARNING: rule "{rule}" interface "{config["inbound_interface"]}" does not exist on this system')
+ Warning(f'rule "{rule}" interface "{config["inbound_interface"]}" does not exist on this system')
if dict_search('translation.address', config) == None and 'exclude' not in config:
@@ -180,14 +181,21 @@ def verify(nat):
return None
def generate(nat):
- render(iptables_nat_config, 'firewall/nftables-nat.tmpl', nat,
- permission=0o755)
+ render(nftables_nat_config, 'firewall/nftables-nat.j2', nat)
+
+ # dry-run newly generated configuration
+ tmp = run(f'nft -c -f {nftables_nat_config}')
+ if tmp > 0:
+ if os.path.exists(nftables_nat_config):
+ os.unlink(nftables_nat_config)
+ raise ConfigError('Configuration file errors encountered!')
+
return None
def apply(nat):
- cmd(f'{iptables_nat_config}')
- if os.path.isfile(iptables_nat_config):
- os.unlink(iptables_nat_config)
+ cmd(f'nft -f {nftables_nat_config}')
+ if os.path.isfile(nftables_nat_config):
+ os.unlink(nftables_nat_config)
return None
diff --git a/src/conf_mode/nat66.py b/src/conf_mode/nat66.py
index fb376a434..0972151a0 100755
--- a/src/conf_mode/nat66.py
+++ b/src/conf_mode/nat66.py
@@ -21,6 +21,7 @@ import os
from sys import exit
from netifaces import interfaces
+from vyos.base import Warning
from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.template import render
@@ -35,7 +36,7 @@ airbag.enable()
k_mod = ['nft_nat', 'nft_chain_nat']
-iptables_nat_config = '/tmp/vyos-nat66-rules.nft'
+nftables_nat66_config = '/tmp/vyos-nat66-rules.nft'
ndppd_config = '/run/ndppd/ndppd.conf'
def get_handler(json, chain, target):
@@ -79,9 +80,9 @@ def get_config(config=None):
if not conf.exists(base):
nat['helper_functions'] = 'remove'
- nat['pre_ct_ignore'] = get_handler(condensed_json, 'PREROUTING', 'VYATTA_CT_HELPER')
+ nat['pre_ct_ignore'] = get_handler(condensed_json, 'PREROUTING', 'VYOS_CT_HELPER')
nat['pre_ct_conntrack'] = get_handler(condensed_json, 'PREROUTING', 'NAT_CONNTRACK')
- nat['out_ct_ignore'] = get_handler(condensed_json, 'OUTPUT', 'VYATTA_CT_HELPER')
+ nat['out_ct_ignore'] = get_handler(condensed_json, 'OUTPUT', 'VYOS_CT_HELPER')
nat['out_ct_conntrack'] = get_handler(condensed_json, 'OUTPUT', 'NAT_CONNTRACK')
nat['deleted'] = ''
return nat
@@ -92,10 +93,10 @@ def get_config(config=None):
nat['helper_functions'] = 'add'
# Retrieve current table handler positions
- nat['pre_ct_ignore'] = get_handler(condensed_json, 'PREROUTING', 'VYATTA_CT_IGNORE')
- nat['pre_ct_conntrack'] = get_handler(condensed_json, 'PREROUTING', 'VYATTA_CT_PREROUTING_HOOK')
- nat['out_ct_ignore'] = get_handler(condensed_json, 'OUTPUT', 'VYATTA_CT_IGNORE')
- nat['out_ct_conntrack'] = get_handler(condensed_json, 'OUTPUT', 'VYATTA_CT_OUTPUT_HOOK')
+ nat['pre_ct_ignore'] = get_handler(condensed_json, 'PREROUTING', 'VYOS_CT_IGNORE')
+ nat['pre_ct_conntrack'] = get_handler(condensed_json, 'PREROUTING', 'VYOS_CT_PREROUTING_HOOK')
+ nat['out_ct_ignore'] = get_handler(condensed_json, 'OUTPUT', 'VYOS_CT_IGNORE')
+ nat['out_ct_conntrack'] = get_handler(condensed_json, 'OUTPUT', 'VYOS_CT_OUTPUT_HOOK')
else:
nat['helper_functions'] = 'has'
@@ -117,12 +118,12 @@ def verify(nat):
raise ConfigError(f'{err_msg} outbound-interface not specified')
if config['outbound_interface'] not in interfaces():
- raise ConfigError(f'WARNING: rule "{rule}" interface "{config["outbound_interface"]}" does not exist on this system')
+ raise ConfigError(f'rule "{rule}" interface "{config["outbound_interface"]}" does not exist on this system')
addr = dict_search('translation.address', config)
if addr != None:
if addr != 'masquerade' and not is_ipv6(addr):
- raise ConfigError(f'Warning: IPv6 address {addr} is not a valid address')
+ raise ConfigError(f'IPv6 address {addr} is not a valid address')
else:
raise ConfigError(f'{err_msg} translation address not specified')
@@ -140,27 +141,27 @@ def verify(nat):
'inbound-interface not specified')
else:
if config['inbound_interface'] not in 'any' and config['inbound_interface'] not in interfaces():
- print(f'WARNING: rule "{rule}" interface "{config["inbound_interface"]}" does not exist on this system')
+ Warning(f'rule "{rule}" interface "{config["inbound_interface"]}" does not exist on this system')
return None
def generate(nat):
- render(iptables_nat_config, 'firewall/nftables-nat66.tmpl', nat, permission=0o755)
- render(ndppd_config, 'ndppd/ndppd.conf.tmpl', nat, permission=0o755)
+ render(nftables_nat66_config, 'firewall/nftables-nat66.j2', nat, permission=0o755)
+ render(ndppd_config, 'ndppd/ndppd.conf.j2', nat, permission=0o755)
return None
def apply(nat):
if not nat:
return None
- cmd(f'{iptables_nat_config}')
+ cmd(f'{nftables_nat66_config}')
if 'deleted' in nat or not dict_search('source.rule', nat):
cmd('systemctl stop ndppd')
if os.path.isfile(ndppd_config):
os.unlink(ndppd_config)
else:
cmd('systemctl restart ndppd')
- if os.path.isfile(iptables_nat_config):
- os.unlink(iptables_nat_config)
+ if os.path.isfile(nftables_nat66_config):
+ os.unlink(nftables_nat66_config)
return None
diff --git a/src/conf_mode/netns.py b/src/conf_mode/netns.py
new file mode 100755
index 000000000..0924eb616
--- /dev/null
+++ b/src/conf_mode/netns.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+
+from sys import exit
+from tempfile import NamedTemporaryFile
+
+from vyos.config import Config
+from vyos.configdict import node_changed
+from vyos.ifconfig import Interface
+from vyos.util import call
+from vyos.util import dict_search
+from vyos.util import get_interface_config
+from vyos import ConfigError
+from vyos import airbag
+airbag.enable()
+
+
+def netns_interfaces(c, match):
+ """
+ get NETNS bound interfaces
+ """
+ matched = []
+ old_level = c.get_level()
+ c.set_level(['interfaces'])
+ section = c.get_config_dict([], get_first_key=True)
+ for type in section:
+ interfaces = section[type]
+ for name in interfaces:
+ interface = interfaces[name]
+ if 'netns' in interface:
+ v = interface.get('netns', '')
+ if v == match:
+ matched.append(name)
+
+ c.set_level(old_level)
+ return matched
+
+def get_config(config=None):
+ if config:
+ conf = config
+ else:
+ conf = Config()
+
+ base = ['netns']
+ netns = conf.get_config_dict(base, get_first_key=True,
+ no_tag_node_value_mangle=True)
+
+ # determine which NETNS has been removed
+ for name in node_changed(conf, base + ['name']):
+ if 'netns_remove' not in netns:
+ netns.update({'netns_remove' : {}})
+
+ netns['netns_remove'][name] = {}
+ # get NETNS bound interfaces
+ interfaces = netns_interfaces(conf, name)
+ if interfaces: netns['netns_remove'][name]['interface'] = interfaces
+
+ return netns
+
+def verify(netns):
+ # ensure NETNS is not assigned to any interface
+ if 'netns_remove' in netns:
+ for name, config in netns['netns_remove'].items():
+ if 'interface' in config:
+ raise ConfigError(f'Can not remove NETNS "{name}", it still has '\
+ f'member interfaces!')
+
+ if 'name' in netns:
+ for name, config in netns['name'].items():
+ print(name)
+
+ return None
+
+
+def generate(netns):
+ if not netns:
+ return None
+
+ return None
+
+
+def apply(netns):
+
+ for tmp in (dict_search('netns_remove', netns) or []):
+ if os.path.isfile(f'/run/netns/{tmp}'):
+ call(f'ip netns del {tmp}')
+
+ if 'name' in netns:
+ for name, config in netns['name'].items():
+ if not os.path.isfile(f'/run/netns/{name}'):
+ call(f'ip netns add {name}')
+
+ return None
+
+if __name__ == '__main__':
+ try:
+ c = get_config()
+ verify(c)
+ generate(c)
+ apply(c)
+ except ConfigError as e:
+ print(e)
+ exit(1)
diff --git a/src/conf_mode/ntp.py b/src/conf_mode/ntp.py
index 52070aabc..0d6ec9ace 100755
--- a/src/conf_mode/ntp.py
+++ b/src/conf_mode/ntp.py
@@ -56,8 +56,8 @@ def generate(ntp):
if not ntp:
return None
- render(config_file, 'ntp/ntpd.conf.tmpl', ntp)
- render(systemd_override, 'ntp/override.conf.tmpl', ntp)
+ render(config_file, 'ntp/ntpd.conf.j2', ntp)
+ render(systemd_override, 'ntp/override.conf.j2', ntp)
return None
diff --git a/src/conf_mode/policy-local-route.py b/src/conf_mode/policy-local-route.py
index 539189442..3f834f55c 100755
--- a/src/conf_mode/policy-local-route.py
+++ b/src/conf_mode/policy-local-route.py
@@ -18,6 +18,7 @@ import os
from sys import exit
+from netifaces import interfaces
from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.configdict import node_changed
@@ -35,35 +36,92 @@ def get_config(config=None):
conf = config
else:
conf = Config()
- base = ['policy', 'local-route']
+ base = ['policy']
+
pbr = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
- # delete policy local-route
- dict = {}
- tmp = node_changed(conf, ['policy', 'local-route', 'rule'], key_mangling=('-', '_'))
- if tmp:
- for rule in (tmp or []):
- src = leaf_node_changed(conf, ['policy', 'local-route', 'rule', rule, 'source'])
- fwmk = leaf_node_changed(conf, ['policy', 'local-route', 'rule', rule, 'fwmark'])
- if src:
- dict = dict_merge({'rule_remove' : {rule : {'source' : src}}}, dict)
- pbr.update(dict)
- if fwmk:
- dict = dict_merge({'rule_remove' : {rule : {'fwmark' : fwmk}}}, dict)
+ for route in ['local_route', 'local_route6']:
+ dict_id = 'rule_remove' if route == 'local_route' else 'rule6_remove'
+ route_key = 'local-route' if route == 'local_route' else 'local-route6'
+ base_rule = base + [route_key, 'rule']
+
+ # delete policy local-route
+ dict = {}
+ tmp = node_changed(conf, base_rule, key_mangling=('-', '_'))
+ if tmp:
+ for rule in (tmp or []):
+ src = leaf_node_changed(conf, base_rule + [rule, 'source'])
+ fwmk = leaf_node_changed(conf, base_rule + [rule, 'fwmark'])
+ iif = leaf_node_changed(conf, base_rule + [rule, 'inbound-interface'])
+ dst = leaf_node_changed(conf, base_rule + [rule, 'destination'])
+ rule_def = {}
+ if src:
+ rule_def = dict_merge({'source' : src}, rule_def)
+ if fwmk:
+ rule_def = dict_merge({'fwmark' : fwmk}, rule_def)
+ if iif:
+ rule_def = dict_merge({'inbound_interface' : iif}, rule_def)
+ if dst:
+ rule_def = dict_merge({'destination' : dst}, rule_def)
+ dict = dict_merge({dict_id : {rule : rule_def}}, dict)
pbr.update(dict)
- # delete policy local-route rule x source x.x.x.x
- # delete policy local-route rule x fwmark x
- if 'rule' in pbr:
- for rule in pbr['rule']:
- src = leaf_node_changed(conf, ['policy', 'local-route', 'rule', rule, 'source'])
- fwmk = leaf_node_changed(conf, ['policy', 'local-route', 'rule', rule, 'fwmark'])
- if src:
- dict = dict_merge({'rule_remove' : {rule : {'source' : src}}}, dict)
- pbr.update(dict)
- if fwmk:
- dict = dict_merge({'rule_remove' : {rule : {'fwmark' : fwmk}}}, dict)
- pbr.update(dict)
+ if not route in pbr:
+ continue
+
+ # delete policy local-route rule x source x.x.x.x
+ # delete policy local-route rule x fwmark x
+ # delete policy local-route rule x destination x.x.x.x
+ if 'rule' in pbr[route]:
+ for rule, rule_config in pbr[route]['rule'].items():
+ src = leaf_node_changed(conf, base_rule + [rule, 'source'])
+ fwmk = leaf_node_changed(conf, base_rule + [rule, 'fwmark'])
+ iif = leaf_node_changed(conf, base_rule + [rule, 'inbound-interface'])
+ dst = leaf_node_changed(conf, base_rule + [rule, 'destination'])
+ # keep track of changes in configuration
+ # otherwise we might remove an existing node although nothing else has changed
+ changed = False
+
+ rule_def = {}
+ # src is None if there are no changes to src
+ if src is None:
+ # if src hasn't changed, include it in the removal selector
+ # if a new selector is added, we have to remove all previous rules without this selector
+ # to make sure we remove all previous rules with this source(s), it will be included
+ if 'source' in rule_config:
+ rule_def = dict_merge({'source': rule_config['source']}, rule_def)
+ else:
+ # if src is not None, it's previous content will be returned
+ # this can be an empty array if it's just being set, or the previous value
+ # either way, something has to be changed and we only want to remove previous values
+ changed = True
+ # set the old value for removal if it's not empty
+ if len(src) > 0:
+ rule_def = dict_merge({'source' : src}, rule_def)
+ if fwmk is None:
+ if 'fwmark' in rule_config:
+ rule_def = dict_merge({'fwmark': rule_config['fwmark']}, rule_def)
+ else:
+ changed = True
+ if len(fwmk) > 0:
+ rule_def = dict_merge({'fwmark' : fwmk}, rule_def)
+ if iif is None:
+ if 'inbound_interface' in rule_config:
+ rule_def = dict_merge({'inbound_interface': rule_config['inbound_interface']}, rule_def)
+ else:
+ changed = True
+ if len(iif) > 0:
+ rule_def = dict_merge({'inbound_interface' : iif}, rule_def)
+ if dst is None:
+ if 'destination' in rule_config:
+ rule_def = dict_merge({'destination': rule_config['destination']}, rule_def)
+ else:
+ changed = True
+ if len(dst) > 0:
+ rule_def = dict_merge({'destination' : dst}, rule_def)
+ if changed:
+ dict = dict_merge({dict_id : {rule : rule_def}}, dict)
+ pbr.update(dict)
return pbr
@@ -72,13 +130,25 @@ def verify(pbr):
if not pbr:
return None
- if 'rule' in pbr:
- for rule in pbr['rule']:
- if 'source' not in pbr['rule'][rule] and 'fwmark' not in pbr['rule'][rule]:
- raise ConfigError('Source address or fwmark is required!')
- else:
- if 'set' not in pbr['rule'][rule] or 'table' not in pbr['rule'][rule]['set']:
- raise ConfigError('Table set is required!')
+ for route in ['local_route', 'local_route6']:
+ if not route in pbr:
+ continue
+
+ pbr_route = pbr[route]
+ if 'rule' in pbr_route:
+ for rule in pbr_route['rule']:
+ if 'source' not in pbr_route['rule'][rule] \
+ and 'destination' not in pbr_route['rule'][rule] \
+ and 'fwmark' not in pbr_route['rule'][rule] \
+ and 'inbound_interface' not in pbr_route['rule'][rule]:
+ raise ConfigError('Source or destination address or fwmark or inbound-interface is required!')
+ else:
+ if 'set' not in pbr_route['rule'][rule] or 'table' not in pbr_route['rule'][rule]['set']:
+ raise ConfigError('Table set is required!')
+ if 'inbound_interface' in pbr_route['rule'][rule]:
+ interface = pbr_route['rule'][rule]['inbound_interface']
+ if interface not in interfaces():
+ raise ConfigError(f'Interface "{interface}" does not exist')
return None
@@ -93,36 +163,51 @@ def apply(pbr):
return None
# Delete old rule if needed
- if 'rule_remove' in pbr:
- for rule in pbr['rule_remove']:
- if 'source' in pbr['rule_remove'][rule]:
- for src in pbr['rule_remove'][rule]['source']:
- call(f'ip rule del prio {rule} from {src}')
- if 'fwmark' in pbr['rule_remove'][rule]:
- for fwmk in pbr['rule_remove'][rule]['fwmark']:
- call(f'ip rule del prio {rule} from all fwmark {fwmk}')
+ for rule_rm in ['rule_remove', 'rule6_remove']:
+ if rule_rm in pbr:
+ v6 = " -6" if rule_rm == 'rule6_remove' else ""
+ for rule, rule_config in pbr[rule_rm].items():
+ rule_config['source'] = rule_config['source'] if 'source' in rule_config else ['']
+ for src in rule_config['source']:
+ f_src = '' if src == '' else f' from {src} '
+ rule_config['destination'] = rule_config['destination'] if 'destination' in rule_config else ['']
+ for dst in rule_config['destination']:
+ f_dst = '' if dst == '' else f' to {dst} '
+ rule_config['fwmark'] = rule_config['fwmark'] if 'fwmark' in rule_config else ['']
+ for fwmk in rule_config['fwmark']:
+ f_fwmk = '' if fwmk == '' else f' fwmark {fwmk} '
+ rule_config['inbound_interface'] = rule_config['inbound_interface'] if 'inbound_interface' in rule_config else ['']
+ for iif in rule_config['inbound_interface']:
+ f_iif = '' if iif == '' else f' iif {iif} '
+ call(f'ip{v6} rule del prio {rule} {f_src}{f_dst}{f_fwmk}{f_iif}')
# Generate new config
- if 'rule' in pbr:
- for rule in pbr['rule']:
- table = pbr['rule'][rule]['set']['table']
- # Only source in the rule
- # set policy local-route rule 100 source '203.0.113.1'
- if 'source' in pbr['rule'][rule] and not 'fwmark' in pbr['rule'][rule]:
- for src in pbr['rule'][rule]['source']:
- call(f'ip rule add prio {rule} from {src} lookup {table}')
- # Only fwmark in the rule
- # set policy local-route rule 101 fwmark '23'
- if 'fwmark' in pbr['rule'][rule] and not 'source' in pbr['rule'][rule]:
- fwmk = pbr['rule'][rule]['fwmark']
- call(f'ip rule add prio {rule} from all fwmark {fwmk} lookup {table}')
- # Source and fwmark in the rule
- # set policy local-route rule 100 source '203.0.113.1'
- # set policy local-route rule 100 fwmark '23'
- if 'source' in pbr['rule'][rule] and 'fwmark' in pbr['rule'][rule]:
- fwmk = pbr['rule'][rule]['fwmark']
- for src in pbr['rule'][rule]['source']:
- call(f'ip rule add prio {rule} from {src} fwmark {fwmk} lookup {table}')
+ for route in ['local_route', 'local_route6']:
+ if not route in pbr:
+ continue
+
+ v6 = " -6" if route == 'local_route6' else ""
+
+ pbr_route = pbr[route]
+ if 'rule' in pbr_route:
+ for rule, rule_config in pbr_route['rule'].items():
+ table = rule_config['set']['table']
+
+ rule_config['source'] = rule_config['source'] if 'source' in rule_config else ['all']
+ for src in rule_config['source'] or ['all']:
+ f_src = '' if src == '' else f' from {src} '
+ rule_config['destination'] = rule_config['destination'] if 'destination' in rule_config else ['all']
+ for dst in rule_config['destination']:
+ f_dst = '' if dst == '' else f' to {dst} '
+ f_fwmk = ''
+ if 'fwmark' in rule_config:
+ fwmk = rule_config['fwmark']
+ f_fwmk = f' fwmark {fwmk} '
+ f_iif = ''
+ if 'inbound_interface' in rule_config:
+ iif = rule_config['inbound_interface']
+ f_iif = f' iif {iif} '
+ call(f'ip{v6} rule add prio {rule} {f_src}{f_dst}{f_fwmk}{f_iif} lookup {table}')
return None
diff --git a/src/conf_mode/policy-route-interface.py b/src/conf_mode/policy-route-interface.py
new file mode 100755
index 000000000..1108aebe6
--- /dev/null
+++ b/src/conf_mode/policy-route-interface.py
@@ -0,0 +1,120 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import re
+
+from sys import argv
+from sys import exit
+
+from vyos.config import Config
+from vyos.ifconfig import Section
+from vyos.template import render
+from vyos.util import cmd
+from vyos import ConfigError
+from vyos import airbag
+airbag.enable()
+
+def get_config(config=None):
+ if config:
+ conf = config
+ else:
+ conf = Config()
+
+ ifname = argv[1]
+ ifpath = Section.get_config_path(ifname)
+ if_policy_path = f'interfaces {ifpath} policy'
+
+ if_policy = conf.get_config_dict(if_policy_path, key_mangling=('-', '_'), get_first_key=True,
+ no_tag_node_value_mangle=True)
+
+ if_policy['ifname'] = ifname
+ if_policy['policy'] = conf.get_config_dict(['policy'], key_mangling=('-', '_'), get_first_key=True,
+ no_tag_node_value_mangle=True)
+
+ return if_policy
+
+def verify(if_policy):
+ # bail out early - looks like removal from running config
+ if not if_policy:
+ return None
+
+ for route in ['route', 'route6']:
+ if route in if_policy:
+ if route not in if_policy['policy']:
+ raise ConfigError('Policy route not configured')
+
+ route_name = if_policy[route]
+
+ if route_name not in if_policy['policy'][route]:
+ raise ConfigError(f'Invalid policy route name "{name}"')
+
+ return None
+
+def generate(if_policy):
+ return None
+
+def cleanup_rule(table, chain, ifname, new_name=None):
+ results = cmd(f'nft -a list chain {table} {chain}').split("\n")
+ retval = None
+ for line in results:
+ if f'ifname "{ifname}"' in line:
+ if new_name and f'jump {new_name}' in line:
+ # new_name is used to clear rules for any previously referenced chains
+ # returns true when rule exists and doesn't need to be created
+ retval = True
+ continue
+
+ handle_search = re.search('handle (\d+)', line)
+ if handle_search:
+ cmd(f'nft delete rule {table} {chain} handle {handle_search[1]}')
+ return retval
+
+def apply(if_policy):
+ ifname = if_policy['ifname']
+
+ route_chain = 'VYOS_PBR_PREROUTING'
+ ipv6_route_chain = 'VYOS_PBR6_PREROUTING'
+
+ if 'route' in if_policy:
+ name = 'VYOS_PBR_' + if_policy['route']
+ rule_exists = cleanup_rule('ip mangle', route_chain, ifname, name)
+
+ if not rule_exists:
+ cmd(f'nft insert rule ip mangle {route_chain} iifname {ifname} counter jump {name}')
+ else:
+ cleanup_rule('ip mangle', route_chain, ifname)
+
+ if 'route6' in if_policy:
+ name = 'VYOS_PBR6_' + if_policy['route6']
+ rule_exists = cleanup_rule('ip6 mangle', ipv6_route_chain, ifname, name)
+
+ if not rule_exists:
+ cmd(f'nft insert rule ip6 mangle {ipv6_route_chain} iifname {ifname} counter jump {name}')
+ else:
+ cleanup_rule('ip6 mangle', ipv6_route_chain, ifname)
+
+ return None
+
+if __name__ == '__main__':
+ try:
+ c = get_config()
+ verify(c)
+ generate(c)
+ apply(c)
+ except ConfigError as e:
+ print(e)
+ exit(1)
diff --git a/src/conf_mode/policy-route.py b/src/conf_mode/policy-route.py
new file mode 100755
index 000000000..5de341beb
--- /dev/null
+++ b/src/conf_mode/policy-route.py
@@ -0,0 +1,262 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import re
+
+from json import loads
+from sys import exit
+
+from vyos.base import Warning
+from vyos.config import Config
+from vyos.template import render
+from vyos.util import cmd
+from vyos.util import dict_search_args
+from vyos.util import run
+from vyos import ConfigError
+from vyos import airbag
+airbag.enable()
+
+mark_offset = 0x7FFFFFFF
+nftables_conf = '/run/nftables_policy.conf'
+
+preserve_chains = [
+ 'VYOS_PBR_PREROUTING',
+ 'VYOS_PBR_POSTROUTING',
+ 'VYOS_PBR6_PREROUTING',
+ 'VYOS_PBR6_POSTROUTING'
+]
+
+valid_groups = [
+ 'address_group',
+ 'network_group',
+ 'port_group'
+]
+
+def get_policy_interfaces(conf):
+ out = {}
+ interfaces = conf.get_config_dict(['interfaces'], key_mangling=('-', '_'), get_first_key=True,
+ no_tag_node_value_mangle=True)
+ def find_interfaces(iftype_conf, output={}, prefix=''):
+ for ifname, if_conf in iftype_conf.items():
+ if 'policy' in if_conf:
+ output[prefix + ifname] = if_conf['policy']
+ for vif in ['vif', 'vif_s', 'vif_c']:
+ if vif in if_conf:
+ output.update(find_interfaces(if_conf[vif], output, f'{prefix}{ifname}.'))
+ return output
+ for iftype, iftype_conf in interfaces.items():
+ out.update(find_interfaces(iftype_conf))
+ return out
+
+def get_config(config=None):
+ if config:
+ conf = config
+ else:
+ conf = Config()
+ base = ['policy']
+
+ policy = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True,
+ no_tag_node_value_mangle=True)
+
+ policy['firewall_group'] = conf.get_config_dict(['firewall', 'group'], key_mangling=('-', '_'), get_first_key=True,
+ no_tag_node_value_mangle=True)
+ policy['interfaces'] = get_policy_interfaces(conf)
+
+ return policy
+
+def verify_rule(policy, name, rule_conf, ipv6):
+ icmp = 'icmp' if not ipv6 else 'icmpv6'
+ if icmp in rule_conf:
+ icmp_defined = False
+ if 'type_name' in rule_conf[icmp]:
+ icmp_defined = True
+ if 'code' in rule_conf[icmp] or 'type' in rule_conf[icmp]:
+ raise ConfigError(f'{name} rule {rule_id}: Cannot use ICMP type/code with ICMP type-name')
+ if 'code' in rule_conf[icmp]:
+ icmp_defined = True
+ if 'type' not in rule_conf[icmp]:
+ raise ConfigError(f'{name} rule {rule_id}: ICMP code can only be defined if ICMP type is defined')
+ if 'type' in rule_conf[icmp]:
+ icmp_defined = True
+
+ if icmp_defined and 'protocol' not in rule_conf or rule_conf['protocol'] != icmp:
+ raise ConfigError(f'{name} rule {rule_id}: ICMP type/code or type-name can only be defined if protocol is ICMP')
+
+ if 'set' in rule_conf:
+ if 'tcp_mss' in rule_conf['set']:
+ tcp_flags = dict_search_args(rule_conf, 'tcp', 'flags')
+ if not tcp_flags or 'syn' not in tcp_flags:
+ raise ConfigError(f'{name} rule {rule_id}: TCP SYN flag must be set to modify TCP-MSS')
+
+ tcp_flags = dict_search_args(rule_conf, 'tcp', 'flags')
+ if tcp_flags:
+ if dict_search_args(rule_conf, 'protocol') != 'tcp':
+ raise ConfigError('Protocol must be tcp when specifying tcp flags')
+
+ not_flags = dict_search_args(rule_conf, 'tcp', 'flags', 'not')
+ if not_flags:
+ duplicates = [flag for flag in tcp_flags if flag in not_flags]
+ if duplicates:
+ raise ConfigError(f'Cannot match a tcp flag as set and not set')
+
+ for side in ['destination', 'source']:
+ if side in rule_conf:
+ side_conf = rule_conf[side]
+
+ if 'group' in side_conf:
+ if {'address_group', 'network_group'} <= set(side_conf['group']):
+ raise ConfigError('Only one address-group or network-group can be specified')
+
+ for group in valid_groups:
+ if group in side_conf['group']:
+ group_name = side_conf['group'][group]
+
+ if group_name.startswith('!'):
+ group_name = group_name[1:]
+
+ fw_group = f'ipv6_{group}' if ipv6 and group in ['address_group', 'network_group'] else group
+ error_group = fw_group.replace("_", "-")
+ group_obj = dict_search_args(policy['firewall_group'], fw_group, group_name)
+
+ if group_obj is None:
+ raise ConfigError(f'Invalid {error_group} "{group_name}" on policy route rule')
+
+ if not group_obj:
+ Warning(f'{error_group} "{group_name}" has no members')
+
+ if 'port' in side_conf or dict_search_args(side_conf, 'group', 'port_group'):
+ if 'protocol' not in rule_conf:
+ raise ConfigError('Protocol must be defined if specifying a port or port-group')
+
+ if rule_conf['protocol'] not in ['tcp', 'udp', 'tcp_udp']:
+ raise ConfigError('Protocol must be tcp, udp, or tcp_udp when specifying a port or port-group')
+
+def verify(policy):
+ for route in ['route', 'route6']:
+ ipv6 = route == 'route6'
+ if route in policy:
+ for name, pol_conf in policy[route].items():
+ if 'rule' in pol_conf:
+ for rule_id, rule_conf in pol_conf['rule'].items():
+ verify_rule(policy, name, rule_conf, ipv6)
+
+ for ifname, if_policy in policy['interfaces'].items():
+ name = dict_search_args(if_policy, 'route')
+ ipv6_name = dict_search_args(if_policy, 'route6')
+
+ if name and not dict_search_args(policy, 'route', name):
+ raise ConfigError(f'Policy route "{name}" is still referenced on interface {ifname}')
+
+ if ipv6_name and not dict_search_args(policy, 'route6', ipv6_name):
+ raise ConfigError(f'Policy route6 "{ipv6_name}" is still referenced on interface {ifname}')
+
+ return None
+
+def cleanup_rule(table, jump_chain):
+ commands = []
+ results = cmd(f'nft -a list table {table}').split("\n")
+ for line in results:
+ if f'jump {jump_chain}' in line:
+ handle_search = re.search('handle (\d+)', line)
+ if handle_search:
+ commands.append(f'delete rule {table} {chain} handle {handle_search[1]}')
+ return commands
+
+def cleanup_commands(policy):
+ commands = []
+ for table in ['ip mangle', 'ip6 mangle']:
+ json_str = cmd(f'nft -j list table {table}')
+ obj = loads(json_str)
+ if 'nftables' not in obj:
+ continue
+ for item in obj['nftables']:
+ if 'chain' in item:
+ chain = item['chain']['name']
+ if not chain.startswith("VYOS_PBR"):
+ continue
+ if chain not in preserve_chains:
+ if table == 'ip mangle' and dict_search_args(policy, 'route', chain.replace("VYOS_PBR_", "", 1)):
+ commands.append(f'flush chain {table} {chain}')
+ elif table == 'ip6 mangle' and dict_search_args(policy, 'route6', chain.replace("VYOS_PBR6_", "", 1)):
+ commands.append(f'flush chain {table} {chain}')
+ else:
+ commands += cleanup_rule(table, chain)
+ commands.append(f'delete chain {table} {chain}')
+ return commands
+
+def generate(policy):
+ if not os.path.exists(nftables_conf):
+ policy['first_install'] = True
+ else:
+ policy['cleanup_commands'] = cleanup_commands(policy)
+
+ render(nftables_conf, 'firewall/nftables-policy.j2', policy)
+ return None
+
+def apply_table_marks(policy):
+ for route in ['route', 'route6']:
+ if route in policy:
+ cmd_str = 'ip' if route == 'route' else 'ip -6'
+ tables = []
+ for name, pol_conf in policy[route].items():
+ if 'rule' in pol_conf:
+ for rule_id, rule_conf in pol_conf['rule'].items():
+ set_table = dict_search_args(rule_conf, 'set', 'table')
+ if set_table:
+ if set_table == 'main':
+ set_table = '254'
+ if set_table in tables:
+ continue
+ tables.append(set_table)
+ table_mark = mark_offset - int(set_table)
+ cmd(f'{cmd_str} rule add pref {set_table} fwmark {table_mark} table {set_table}')
+
+def cleanup_table_marks():
+ for cmd_str in ['ip', 'ip -6']:
+ json_rules = cmd(f'{cmd_str} -j -N rule list')
+ rules = loads(json_rules)
+ for rule in rules:
+ if 'fwmark' not in rule or 'table' not in rule:
+ continue
+ fwmark = rule['fwmark']
+ table = int(rule['table'])
+ if fwmark[:2] == '0x':
+ fwmark = int(fwmark, 16)
+ if (int(fwmark) == (mark_offset - table)):
+ cmd(f'{cmd_str} rule del fwmark {fwmark} table {table}')
+
+def apply(policy):
+ install_result = run(f'nft -f {nftables_conf}')
+ if install_result == 1:
+ raise ConfigError('Failed to apply policy based routing')
+
+ if 'first_install' not in policy:
+ cleanup_table_marks()
+
+ apply_table_marks(policy)
+
+ return None
+
+if __name__ == '__main__':
+ try:
+ c = get_config()
+ verify(c)
+ generate(c)
+ apply(c)
+ except ConfigError as e:
+ print(e)
+ exit(1)
diff --git a/src/conf_mode/policy.py b/src/conf_mode/policy.py
index 1a03d520b..ef6008140 100755
--- a/src/conf_mode/policy.py
+++ b/src/conf_mode/policy.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -87,6 +87,7 @@ def verify(policy):
# human readable instance name (hypen instead of underscore)
policy_hr = policy_type.replace('_', '-')
+ entries = []
for rule, rule_config in instance_config['rule'].items():
mandatory_error = f'must be specified for "{policy_hr} {instance} rule {rule}"!'
if 'action' not in rule_config:
@@ -113,6 +114,10 @@ def verify(policy):
if 'prefix' not in rule_config:
raise ConfigError(f'A prefix {mandatory_error}')
+ if rule_config in entries:
+ raise ConfigError(f'Rule "{rule}" contains a duplicate prefix definition!')
+ entries.append(rule_config)
+
# route-maps tend to be a bit more complex so they get their own verify() section
if 'route_map' in policy:
@@ -171,10 +176,8 @@ def verify(policy):
def generate(policy):
if not policy:
- policy['new_frr_config'] = ''
return None
-
- policy['new_frr_config'] = render_to_string('frr/policy.frr.tmpl', policy)
+ policy['new_frr_config'] = render_to_string('frr/policy.frr.j2', policy)
return None
def apply(policy):
@@ -190,8 +193,9 @@ def apply(policy):
frr_cfg.modify_section(r'^bgp community-list .*')
frr_cfg.modify_section(r'^bgp extcommunity-list .*')
frr_cfg.modify_section(r'^bgp large-community-list .*')
- frr_cfg.modify_section(r'^route-map .*')
- frr_cfg.add_before('^line vty', policy['new_frr_config'])
+ frr_cfg.modify_section(r'^route-map .*', stop_pattern='^exit', remove_stop_mark=True)
+ if 'new_frr_config' in policy:
+ frr_cfg.add_before(frr.default_add_before, policy['new_frr_config'])
frr_cfg.commit_configuration(bgp_daemon)
# The route-map used for the FIB (zebra) is part of the zebra daemon
@@ -200,19 +204,11 @@ def apply(policy):
frr_cfg.modify_section(r'^ipv6 access-list .*')
frr_cfg.modify_section(r'^ip prefix-list .*')
frr_cfg.modify_section(r'^ipv6 prefix-list .*')
- frr_cfg.modify_section(r'^route-map .*')
- frr_cfg.add_before('^line vty', policy['new_frr_config'])
+ frr_cfg.modify_section(r'^route-map .*', stop_pattern='^exit', remove_stop_mark=True)
+ if 'new_frr_config' in policy:
+ frr_cfg.add_before(frr.default_add_before, policy['new_frr_config'])
frr_cfg.commit_configuration(zebra_daemon)
- # If FRR config is blank, rerun the blank commit x times due to frr-reload
- # behavior/bug not properly clearing out on one commit.
- if policy['new_frr_config'] == '':
- for a in range(5):
- frr_cfg.commit_configuration(zebra_daemon)
-
- # Save configuration to /run/frr/config/frr.conf
- frr.save_configuration()
-
return None
if __name__ == '__main__':
diff --git a/src/conf_mode/protocols_bfd.py b/src/conf_mode/protocols_bfd.py
index 539fd7b8e..0436abaf9 100755
--- a/src/conf_mode/protocols_bfd.py
+++ b/src/conf_mode/protocols_bfd.py
@@ -16,10 +16,9 @@
import os
-from sys import exit
-
from vyos.config import Config
from vyos.configdict import dict_merge
+from vyos.configverify import verify_vrf
from vyos.template import is_ipv6
from vyos.template import render_to_string
from vyos.validate import is_ipv6_link_local
@@ -35,8 +34,9 @@ def get_config(config=None):
else:
conf = Config()
base = ['protocols', 'bfd']
- bfd = conf.get_config_dict(base, get_first_key=True)
-
+ bfd = conf.get_config_dict(base, key_mangling=('-', '_'),
+ get_first_key=True,
+ no_tag_node_value_mangle=True)
# Bail out early if configuration tree does not exist
if not conf.exists(base):
return bfd
@@ -79,28 +79,37 @@ def verify(bfd):
# multihop and echo-mode cannot be used together
if 'echo_mode' in peer_config:
- raise ConfigError('Multihop and echo-mode cannot be used together')
+ raise ConfigError('BFD multihop and echo-mode cannot be used together')
# multihop doesn't accept interface names
if 'source' in peer_config and 'interface' in peer_config['source']:
- raise ConfigError('Multihop and source interface cannot be used together')
+ raise ConfigError('BFD multihop and source interface cannot be used together')
+
+ if 'profile' in peer_config:
+ profile_name = peer_config['profile']
+ if 'profile' not in bfd or profile_name not in bfd['profile']:
+ raise ConfigError(f'BFD profile "{profile_name}" does not exist!')
+
+ if 'vrf' in peer_config:
+ verify_vrf(peer_config)
return None
def generate(bfd):
if not bfd:
- bfd['new_frr_config'] = ''
return None
-
- bfd['new_frr_config'] = render_to_string('frr/bfdd.frr.tmpl', bfd)
+ bfd['new_frr_config'] = render_to_string('frr/bfdd.frr.j2', bfd)
def apply(bfd):
+ bfd_daemon = 'bfdd'
+
# Save original configuration prior to starting any commit actions
frr_cfg = frr.FRRConfig()
- frr_cfg.load_configuration()
- frr_cfg.modify_section('^bfd', '')
- frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', bfd['new_frr_config'])
- frr_cfg.commit_configuration()
+ frr_cfg.load_configuration(bfd_daemon)
+ frr_cfg.modify_section('^bfd', stop_pattern='^exit', remove_stop_mark=True)
+ if 'new_frr_config' in bfd:
+ frr_cfg.add_before(frr.default_add_before, bfd['new_frr_config'])
+ frr_cfg.commit_configuration(bfd_daemon)
return None
diff --git a/src/conf_mode/protocols_bgp.py b/src/conf_mode/protocols_bgp.py
index 68284e0f9..cd46cbcb4 100755
--- a/src/conf_mode/protocols_bgp.py
+++ b/src/conf_mode/protocols_bgp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright (C) 2020-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -138,13 +138,20 @@ def verify(bgp):
if asn == bgp['local_as']:
raise ConfigError('Cannot have local-as same as BGP AS number')
+ # Neighbor AS specified for local-as and remote-as can not be the same
+ if dict_search('remote_as', peer_config) == asn:
+ raise ConfigError(f'Neighbor "{peer}" has local-as specified which is '\
+ 'the same as remote-as, this is not allowed!')
+
# ttl-security and ebgp-multihop can't be used in the same configration
if 'ebgp_multihop' in peer_config and 'ttl_security' in peer_config:
raise ConfigError('You can not set both ebgp-multihop and ttl-security hops')
- # Check if neighbor has both override capability and strict capability match configured at the same time.
+ # Check if neighbor has both override capability and strict capability match
+ # configured at the same time.
if 'override_capability' in peer_config and 'strict_capability_match' in peer_config:
- raise ConfigError(f'Neighbor "{peer}" cannot have both override-capability and strict-capability-match configured at the same time!')
+ raise ConfigError(f'Neighbor "{peer}" cannot have both override-capability and '\
+ 'strict-capability-match configured at the same time!')
# Check spaces in the password
if 'password' in peer_config and ' ' in peer_config['password']:
@@ -157,15 +164,39 @@ def verify(bgp):
if not verify_remote_as(peer_config, bgp):
raise ConfigError(f'Neighbor "{peer}" remote-as must be set!')
+ # Peer-group member cannot override remote-as of peer-group
+ if 'peer_group' in peer_config:
+ peer_group = peer_config['peer_group']
+ if 'remote_as' in peer_config and 'remote_as' in bgp['peer_group'][peer_group]:
+ raise ConfigError(f'Peer-group member "{peer}" cannot override remote-as of peer-group "{peer_group}"!')
+ if 'interface' in peer_config:
+ if 'peer_group' in peer_config['interface']:
+ peer_group = peer_config['interface']['peer_group']
+ if 'remote_as' in peer_config['interface'] and 'remote_as' in bgp['peer_group'][peer_group]:
+ raise ConfigError(f'Peer-group member "{peer}" cannot override remote-as of peer-group "{peer_group}"!')
+ if 'v6only' in peer_config['interface']:
+ if 'peer_group' in peer_config['interface']['v6only']:
+ peer_group = peer_config['interface']['v6only']['peer_group']
+ if 'remote_as' in peer_config['interface']['v6only'] and 'remote_as' in bgp['peer_group'][peer_group]:
+ raise ConfigError(f'Peer-group member "{peer}" cannot override remote-as of peer-group "{peer_group}"!')
+
# Only checks for ipv4 and ipv6 neighbors
# Check if neighbor address is assigned as system interface address
- if is_ip(peer) and is_addr_assigned(peer):
- raise ConfigError(f'Can not configure a local address as neighbor "{peer}"')
+ vrf = None
+ vrf_error_msg = f' in default VRF!'
+ if 'vrf' in bgp:
+ vrf = bgp['vrf']
+ vrf_error_msg = f' in VRF "{vrf}"!'
+
+ if is_ip(peer) and is_addr_assigned(peer, vrf):
+ raise ConfigError(f'Can not configure local address as neighbor "{peer}"{vrf_error_msg}')
elif is_interface(peer):
if 'peer_group' in peer_config:
raise ConfigError(f'peer-group must be set under the interface node of "{peer}"')
if 'remote_as' in peer_config:
raise ConfigError(f'remote-as must be set under the interface node of "{peer}"')
+ if 'source_interface' in peer_config['interface']:
+ raise ConfigError(f'"source-interface" option not allowed for neighbor "{peer}"')
for afi in ['ipv4_unicast', 'ipv4_multicast', 'ipv4_labeled_unicast', 'ipv4_flowspec',
'ipv6_unicast', 'ipv6_multicast', 'ipv6_labeled_unicast', 'ipv6_flowspec',
@@ -183,6 +214,33 @@ def verify(bgp):
raise ConfigError(f'Neighbor "{peer}" cannot have both ipv6-unicast and ipv6-labeled-unicast configured at the same time!')
afi_config = peer_config['address_family'][afi]
+
+ if 'conditionally_advertise' in afi_config:
+ if 'advertise_map' not in afi_config['conditionally_advertise']:
+ raise ConfigError('Must speficy advertise-map when conditionally-advertise is in use!')
+ # Verify advertise-map (which is a route-map) exists
+ verify_route_map(afi_config['conditionally_advertise']['advertise_map'], bgp)
+
+ if ('exist_map' not in afi_config['conditionally_advertise'] and
+ 'non_exist_map' not in afi_config['conditionally_advertise']):
+ raise ConfigError('Must either speficy exist-map or non-exist-map when ' \
+ 'conditionally-advertise is in use!')
+
+ if {'exist_map', 'non_exist_map'} <= set(afi_config['conditionally_advertise']):
+ raise ConfigError('Can not specify both exist-map and non-exist-map for ' \
+ 'conditionally-advertise!')
+
+ if 'exist_map' in afi_config['conditionally_advertise']:
+ verify_route_map(afi_config['conditionally_advertise']['exist_map'], bgp)
+
+ if 'non_exist_map' in afi_config['conditionally_advertise']:
+ verify_route_map(afi_config['conditionally_advertise']['non_exist_map'], bgp)
+
+ # T4332: bgp deterministic-med cannot be disabled while addpath-tx-bestpath-per-AS is in use
+ if 'addpath_tx_per_as' in afi_config:
+ if dict_search('parameters.deterministic_med', bgp) == None:
+ raise ConfigError('addpath-tx-per-as requires BGP deterministic-med paramtere to be set!')
+
# Validate if configured Prefix list exists
if 'prefix_list' in afi_config:
for tmp in ['import', 'export']:
@@ -255,26 +313,16 @@ def verify(bgp):
tmp = dict_search(f'route_map.vpn.{export_import}', afi_config)
if tmp: verify_route_map(tmp, bgp)
- if afi in ['l2vpn_evpn'] and 'vrf' not in bgp:
- # Some L2VPN EVPN AFI options are only supported under VRF
- if 'vni' in afi_config:
- for vni, vni_config in afi_config['vni'].items():
- if 'rd' in vni_config:
- raise ConfigError('VNI route-distinguisher is only supported under EVPN VRF')
- if 'route_target' in vni_config:
- raise ConfigError('VNI route-target is only supported under EVPN VRF')
return None
def generate(bgp):
if not bgp or 'deleted' in bgp:
- bgp['frr_bgpd_config'] = ''
- bgp['frr_zebra_config'] = ''
return None
- bgp['protocol'] = 'bgp' # required for frr/vrf.route-map.frr.tmpl
- bgp['frr_zebra_config'] = render_to_string('frr/vrf.route-map.frr.tmpl', bgp)
- bgp['frr_bgpd_config'] = render_to_string('frr/bgpd.frr.tmpl', bgp)
+ bgp['protocol'] = 'bgp' # required for frr/vrf.route-map.frr.j2
+ bgp['frr_zebra_config'] = render_to_string('frr/vrf.route-map.frr.j2', bgp)
+ bgp['frr_bgpd_config'] = render_to_string('frr/bgpd.frr.j2', bgp)
return None
@@ -287,8 +335,9 @@ def apply(bgp):
# The route-map used for the FIB (zebra) is part of the zebra daemon
frr_cfg.load_configuration(zebra_daemon)
- frr_cfg.modify_section(r'(\s+)?ip protocol bgp route-map [-a-zA-Z0-9.]+$', '', '(\s|!)')
- frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', bgp['frr_zebra_config'])
+ frr_cfg.modify_section(r'(\s+)?ip protocol bgp route-map [-a-zA-Z0-9.]+', stop_pattern='(\s|!)')
+ if 'frr_zebra_config' in bgp:
+ frr_cfg.add_before(frr.default_add_before, bgp['frr_zebra_config'])
frr_cfg.commit_configuration(zebra_daemon)
# Generate empty helper string which can be ammended to FRR commands, it
@@ -298,13 +347,11 @@ def apply(bgp):
vrf = ' vrf ' + bgp['vrf']
frr_cfg.load_configuration(bgp_daemon)
- frr_cfg.modify_section(f'^router bgp \d+{vrf}$', '')
- frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', bgp['frr_bgpd_config'])
+ frr_cfg.modify_section(f'^router bgp \d+{vrf}', stop_pattern='^exit', remove_stop_mark=True)
+ if 'frr_bgpd_config' in bgp:
+ frr_cfg.add_before(frr.default_add_before, bgp['frr_bgpd_config'])
frr_cfg.commit_configuration(bgp_daemon)
- # Save configuration to /run/frr/config/frr.conf
- frr.save_configuration()
-
return None
if __name__ == '__main__':
diff --git a/src/conf_mode/protocols_igmp.py b/src/conf_mode/protocols_igmp.py
index 28d560d03..65cc2beba 100755
--- a/src/conf_mode/protocols_igmp.py
+++ b/src/conf_mode/protocols_igmp.py
@@ -108,7 +108,7 @@ def generate(igmp):
if igmp is None:
return None
- render(config_file, 'frr/igmp.frr.tmpl', igmp)
+ render(config_file, 'frr/igmp.frr.j2', igmp)
return None
def apply(igmp):
diff --git a/src/conf_mode/protocols_isis.py b/src/conf_mode/protocols_isis.py
index 4505e2496..5dafd26d0 100755
--- a/src/conf_mode/protocols_isis.py
+++ b/src/conf_mode/protocols_isis.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright (C) 2020-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -56,10 +56,10 @@ def get_config(config=None):
# instead of the VRF instance.
if vrf: isis['vrf'] = vrf
- # As we no re-use this Python handler for both VRF and non VRF instances for
- # IS-IS we need to find out if any interfaces changed so properly adjust
- # the FRR configuration and not by acctident change interfaces from a
- # different VRF.
+ # FRR has VRF support for different routing daemons. As interfaces belong
+ # to VRFs - or the global VRF, we need to check for changed interfaces so
+ # that they will be properly rendered for the FRR config. Also this eases
+ # removal of interfaces from the running configuration.
interfaces_removed = node_changed(conf, base + ['interface'])
if interfaces_removed:
isis['interface_removed'] = list(interfaces_removed)
@@ -169,40 +169,50 @@ def verify(isis):
# Segment routing checks
if dict_search('segment_routing.global_block', isis):
- high_label_value = dict_search('segment_routing.global_block.high_label_value', isis)
- low_label_value = dict_search('segment_routing.global_block.low_label_value', isis)
+ g_high_label_value = dict_search('segment_routing.global_block.high_label_value', isis)
+ g_low_label_value = dict_search('segment_routing.global_block.low_label_value', isis)
- # If segment routing global block high value is blank, throw error
- if (low_label_value and not high_label_value) or (high_label_value and not low_label_value):
- raise ConfigError('Segment routing global block requires both low and high value!')
+ # If segment routing global block high or low value is blank, throw error
+ if not (g_low_label_value or g_high_label_value):
+ raise ConfigError('Segment routing global-block requires both low and high value!')
# If segment routing global block low value is higher than the high value, throw error
- if int(low_label_value) > int(high_label_value):
- raise ConfigError('Segment routing global block low value must be lower than high value')
+ if int(g_low_label_value) > int(g_high_label_value):
+ raise ConfigError('Segment routing global-block low value must be lower than high value')
if dict_search('segment_routing.local_block', isis):
- high_label_value = dict_search('segment_routing.local_block.high_label_value', isis)
- low_label_value = dict_search('segment_routing.local_block.low_label_value', isis)
+ if dict_search('segment_routing.global_block', isis) == None:
+ raise ConfigError('Segment routing local-block requires global-block to be configured!')
- # If segment routing local block high value is blank, throw error
- if (low_label_value and not high_label_value) or (high_label_value and not low_label_value):
- raise ConfigError('Segment routing local block requires both high and low value!')
+ l_high_label_value = dict_search('segment_routing.local_block.high_label_value', isis)
+ l_low_label_value = dict_search('segment_routing.local_block.low_label_value', isis)
- # If segment routing local block low value is higher than the high value, throw error
- if int(low_label_value) > int(high_label_value):
- raise ConfigError('Segment routing local block low value must be lower than high value')
+ # If segment routing local-block high or low value is blank, throw error
+ if not (l_low_label_value or l_high_label_value):
+ raise ConfigError('Segment routing local-block requires both high and low value!')
+
+ # If segment routing local-block low value is higher than the high value, throw error
+ if int(l_low_label_value) > int(l_high_label_value):
+ raise ConfigError('Segment routing local-block low value must be lower than high value')
+
+ # local-block most live outside global block
+ global_range = range(int(g_low_label_value), int(g_high_label_value) +1)
+ local_range = range(int(l_low_label_value), int(l_high_label_value) +1)
+
+ # Check for overlapping ranges
+ if list(set(global_range) & set(local_range)):
+ raise ConfigError(f'Segment-Routing Global Block ({g_low_label_value}/{g_high_label_value}) '\
+ f'conflicts with Local Block ({l_low_label_value}/{l_high_label_value})!')
return None
def generate(isis):
if not isis or 'deleted' in isis:
- isis['frr_isisd_config'] = ''
- isis['frr_zebra_config'] = ''
return None
- isis['protocol'] = 'isis' # required for frr/vrf.route-map.frr.tmpl
- isis['frr_zebra_config'] = render_to_string('frr/vrf.route-map.frr.tmpl', isis)
- isis['frr_isisd_config'] = render_to_string('frr/isisd.frr.tmpl', isis)
+ isis['protocol'] = 'isis' # required for frr/vrf.route-map.frr.j2
+ isis['frr_zebra_config'] = render_to_string('frr/vrf.route-map.frr.j2', isis)
+ isis['frr_isisd_config'] = render_to_string('frr/isisd.frr.j2', isis)
return None
def apply(isis):
@@ -214,8 +224,9 @@ def apply(isis):
# The route-map used for the FIB (zebra) is part of the zebra daemon
frr_cfg.load_configuration(zebra_daemon)
- frr_cfg.modify_section(r'(\s+)?ip protocol isis route-map [-a-zA-Z0-9.]+$', '', '(\s|!)')
- frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', isis['frr_zebra_config'])
+ frr_cfg.modify_section('(\s+)?ip protocol isis route-map [-a-zA-Z0-9.]+', stop_pattern='(\s|!)')
+ if 'frr_zebra_config' in isis:
+ frr_cfg.add_before(frr.default_add_before, isis['frr_zebra_config'])
frr_cfg.commit_configuration(zebra_daemon)
# Generate empty helper string which can be ammended to FRR commands, it
@@ -225,19 +236,18 @@ def apply(isis):
vrf = ' vrf ' + isis['vrf']
frr_cfg.load_configuration(isis_daemon)
- frr_cfg.modify_section(f'^router isis VyOS{vrf}$', '')
+ frr_cfg.modify_section(f'^router isis VyOS{vrf}', stop_pattern='^exit', remove_stop_mark=True)
for key in ['interface', 'interface_removed']:
if key not in isis:
continue
for interface in isis[key]:
- frr_cfg.modify_section(f'^interface {interface}{vrf}$', '')
+ frr_cfg.modify_section(f'^interface {interface}{vrf}', stop_pattern='^exit', remove_stop_mark=True)
- frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', isis['frr_isisd_config'])
- frr_cfg.commit_configuration(isis_daemon)
+ if 'frr_isisd_config' in isis:
+ frr_cfg.add_before(frr.default_add_before, isis['frr_isisd_config'])
- # Save configuration to /run/frr/config/frr.conf
- frr.save_configuration()
+ frr_cfg.commit_configuration(isis_daemon)
return None
diff --git a/src/conf_mode/protocols_mpls.py b/src/conf_mode/protocols_mpls.py
index 3b27608da..5da8e7b06 100755
--- a/src/conf_mode/protocols_mpls.py
+++ b/src/conf_mode/protocols_mpls.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright (C) 2020-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -20,11 +20,10 @@ from sys import exit
from glob import glob
from vyos.config import Config
-from vyos.configdict import node_changed
from vyos.template import render_to_string
-from vyos.util import call
from vyos.util import dict_search
from vyos.util import read_file
+from vyos.util import sysctl_write
from vyos import ConfigError
from vyos import frr
from vyos import airbag
@@ -66,82 +65,70 @@ def verify(mpls):
def generate(mpls):
# If there's no MPLS config generated, create dictionary key with no value.
- if not mpls:
- mpls['new_frr_config'] = ''
+ if not mpls or 'deleted' in mpls:
return None
- mpls['new_frr_config'] = render_to_string('frr/ldpd.frr.tmpl', mpls)
+ mpls['frr_ldpd_config'] = render_to_string('frr/ldpd.frr.j2', mpls)
return None
def apply(mpls):
- # Define dictionary that will load FRR config
- frr_cfg = {}
+ ldpd_damon = 'ldpd'
+
# Save original configuration prior to starting any commit actions
- frr_cfg['original_config'] = frr.get_configuration(daemon='ldpd')
- frr_cfg['modified_config'] = frr.replace_section(frr_cfg['original_config'], mpls['new_frr_config'], from_re='mpls.*')
-
- # If FRR config is blank, rerun the blank commit three times due to frr-reload
- # behavior/bug not properly clearing out on one commit.
- if mpls['new_frr_config'] == '':
- for x in range(3):
- frr.reload_configuration(frr_cfg['modified_config'], daemon='ldpd')
- elif not 'ldp' in mpls:
- for x in range(3):
- frr.reload_configuration(frr_cfg['modified_config'], daemon='ldpd')
- else:
- # FRR mark configuration will test for syntax errors and throws an
- # exception if any syntax errors is detected
- frr.mark_configuration(frr_cfg['modified_config'])
+ frr_cfg = frr.FRRConfig()
+
+ frr_cfg.load_configuration(ldpd_damon)
+ frr_cfg.modify_section(f'^mpls ldp', stop_pattern='^exit', remove_stop_mark=True)
- # Commit resulting configuration to FRR, this will throw CommitError
- # on failure
- frr.reload_configuration(frr_cfg['modified_config'], daemon='ldpd')
+ if 'frr_ldpd_config' in mpls:
+ frr_cfg.add_before(frr.default_add_before, mpls['frr_ldpd_config'])
+ frr_cfg.commit_configuration(ldpd_damon)
# Set number of entries in the platform label tables
labels = '0'
if 'interface' in mpls:
labels = '1048575'
- call(f'sysctl -wq net.mpls.platform_labels={labels}')
+ sysctl_write('net.mpls.platform_labels', labels)
# Check for changes in global MPLS options
if 'parameters' in mpls:
# Choose whether to copy IP TTL to MPLS header TTL
if 'no_propagate_ttl' in mpls['parameters']:
- call('sysctl -wq net.mpls.ip_ttl_propagate=0')
+ sysctl_write('net.mpls.ip_ttl_propagate', 0)
# Choose whether to limit maximum MPLS header TTL
if 'maximum_ttl' in mpls['parameters']:
ttl = mpls['parameters']['maximum_ttl']
- call(f'sysctl -wq net.mpls.default_ttl={ttl}')
+ sysctl_write('net.mpls.default_ttl', ttl)
else:
# Set default global MPLS options if not defined.
- call('sysctl -wq net.mpls.ip_ttl_propagate=1')
- call('sysctl -wq net.mpls.default_ttl=255')
+ sysctl_write('net.mpls.ip_ttl_propagate', 1)
+ sysctl_write('net.mpls.default_ttl', 255)
# Enable and disable MPLS processing on interfaces per configuration
if 'interface' in mpls:
system_interfaces = []
# Populate system interfaces list with local MPLS capable interfaces
for interface in glob('/proc/sys/net/mpls/conf/*'):
- system_interfaces.append(os.path.basename(interface))
+ system_interfaces.append(os.path.basename(interface))
# This is where the comparison is done on if an interface needs to be enabled/disabled.
for system_interface in system_interfaces:
interface_state = read_file(f'/proc/sys/net/mpls/conf/{system_interface}/input')
if '1' in interface_state:
if system_interface not in mpls['interface']:
system_interface = system_interface.replace('.', '/')
- call(f'sysctl -wq net.mpls.conf.{system_interface}.input=0')
+ sysctl_write(f'net.mpls.conf.{system_interface}.input', 0)
elif '0' in interface_state:
if system_interface in mpls['interface']:
system_interface = system_interface.replace('.', '/')
- call(f'sysctl -wq net.mpls.conf.{system_interface}.input=1')
+ sysctl_write(f'net.mpls.conf.{system_interface}.input', 1)
else:
system_interfaces = []
# If MPLS interfaces are not configured, set MPLS processing disabled
for interface in glob('/proc/sys/net/mpls/conf/*'):
- system_interfaces.append(os.path.basename(interface))
+ system_interfaces.append(os.path.basename(interface))
for system_interface in system_interfaces:
system_interface = system_interface.replace('.', '/')
- call(f'sysctl -wq net.mpls.conf.{system_interface}.input=0')
+ sysctl_write(f'net.mpls.conf.{system_interface}.input', 0)
return None
diff --git a/src/conf_mode/protocols_nhrp.py b/src/conf_mode/protocols_nhrp.py
index 12dacdba0..56939955d 100755
--- a/src/conf_mode/protocols_nhrp.py
+++ b/src/conf_mode/protocols_nhrp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -16,6 +16,8 @@
from vyos.config import Config
from vyos.configdict import node_changed
+from vyos.firewall import find_nftables_rule
+from vyos.firewall import remove_nftables_rule
from vyos.template import render
from vyos.util import process_named_running
from vyos.util import run
@@ -79,36 +81,36 @@ def verify(nhrp):
for map_name, map_conf in nhrp_conf['dynamic_map'].items():
if 'nbma_domain_name' not in map_conf:
raise ConfigError(f'nbma-domain-name missing on dynamic-map {map_name} on tunnel {name}')
+
+ if 'cisco_authentication' in nhrp_conf:
+ if len(nhrp_conf['cisco_authentication']) > 8:
+ raise ConfigError('Maximum length of the secret is 8 characters!')
+
return None
def generate(nhrp):
- render(opennhrp_conf, 'nhrp/opennhrp.conf.tmpl', nhrp)
+ render(opennhrp_conf, 'nhrp/opennhrp.conf.j2', nhrp)
return None
def apply(nhrp):
if 'tunnel' in nhrp:
for tunnel, tunnel_conf in nhrp['tunnel'].items():
- if 'source_address' in tunnel_conf:
- chain = f'VYOS_NHRP_{tunnel}_OUT_HOOK'
- source_address = tunnel_conf['source_address']
+ if 'source_address' in nhrp['if_tunnel'][tunnel]:
+ comment = f'VYOS_NHRP_{tunnel}'
+ source_address = nhrp['if_tunnel'][tunnel]['source_address']
- chain_exists = run(f'sudo iptables --check {chain} -j RETURN') == 0
- if not chain_exists:
- run(f'sudo iptables --new {chain}')
- run(f'sudo iptables --append {chain} -p gre -s {source_address} -d 224.0.0.0/4 -j DROP')
- run(f'sudo iptables --append {chain} -j RETURN')
- run(f'sudo iptables --insert OUTPUT 2 -j {chain}')
+ rule_handle = find_nftables_rule('ip filter', 'VYOS_FW_OUTPUT', ['ip protocol gre', f'ip saddr {source_address}', 'ip daddr 224.0.0.0/4'])
+ if not rule_handle:
+ run(f'sudo nft insert rule ip filter VYOS_FW_OUTPUT ip protocol gre ip saddr {source_address} ip daddr 224.0.0.0/4 counter drop comment "{comment}"')
for tunnel in nhrp['del_tunnels']:
- chain = f'VYOS_NHRP_{tunnel}_OUT_HOOK'
- chain_exists = run(f'sudo iptables --check {chain} -j RETURN') == 0
- if chain_exists:
- run(f'sudo iptables --delete OUTPUT -j {chain}')
- run(f'sudo iptables --flush {chain}')
- run(f'sudo iptables --delete-chain {chain}')
+ comment = f'VYOS_NHRP_{tunnel}'
+ rule_handle = find_nftables_rule('ip filter', 'VYOS_FW_OUTPUT', [f'comment "{comment}"'])
+ if rule_handle:
+ remove_nftables_rule('ip filter', 'VYOS_FW_OUTPUT', rule_handle)
action = 'restart' if nhrp and 'tunnel' in nhrp else 'stop'
- run(f'systemctl {action} opennhrp')
+ run(f'systemctl {action} opennhrp.service')
return None
if __name__ == '__main__':
diff --git a/src/conf_mode/protocols_ospf.py b/src/conf_mode/protocols_ospf.py
index 6ccda2e5a..5b4874ba2 100755
--- a/src/conf_mode/protocols_ospf.py
+++ b/src/conf_mode/protocols_ospf.py
@@ -25,6 +25,7 @@ from vyos.configdict import node_changed
from vyos.configverify import verify_common_route_maps
from vyos.configverify import verify_route_map
from vyos.configverify import verify_interface_exists
+from vyos.configverify import verify_access_list
from vyos.template import render_to_string
from vyos.util import dict_search
from vyos.util import get_interface_config
@@ -56,10 +57,10 @@ def get_config(config=None):
# instead of the VRF instance.
if vrf: ospf['vrf'] = vrf
- # As we no re-use this Python handler for both VRF and non VRF instances for
- # OSPF we need to find out if any interfaces changed so properly adjust
- # the FRR configuration and not by acctident change interfaces from a
- # different VRF.
+ # FRR has VRF support for different routing daemons. As interfaces belong
+ # to VRFs - or the global VRF, we need to check for changed interfaces so
+ # that they will be properly rendered for the FRR config. Also this eases
+ # removal of interfaces from the running configuration.
interfaces_removed = node_changed(conf, base + ['interface'])
if interfaces_removed:
ospf['interface_removed'] = list(interfaces_removed)
@@ -159,6 +160,16 @@ def verify(ospf):
route_map_name = dict_search('default_information.originate.route_map', ospf)
if route_map_name: verify_route_map(route_map_name, ospf)
+ # Validate if configured Access-list exists
+ if 'area' in ospf:
+ for area, area_config in ospf['area'].items():
+ if 'import_list' in area_config:
+ acl_import = area_config['import_list']
+ if acl_import: verify_access_list(acl_import, ospf)
+ if 'export_list' in area_config:
+ acl_export = area_config['export_list']
+ if acl_export: verify_access_list(acl_export, ospf)
+
if 'interface' in ospf:
for interface, interface_config in ospf['interface'].items():
verify_interface_exists(interface)
@@ -177,11 +188,11 @@ def verify(ospf):
raise ConfigError('Can not use OSPF interface area and area ' \
'network configuration at the same time!')
- if 'vrf' in ospf:
# If interface specific options are set, we must ensure that the
# interface is bound to our requesting VRF. Due to the VyOS
# priorities the interface is bound to the VRF after creation of
# the VRF itself, and before any routing protocol is configured.
+ if 'vrf' in ospf:
vrf = ospf['vrf']
tmp = get_interface_config(interface)
if 'master' not in tmp or tmp['master'] != vrf:
@@ -191,13 +202,11 @@ def verify(ospf):
def generate(ospf):
if not ospf or 'deleted' in ospf:
- ospf['frr_ospfd_config'] = ''
- ospf['frr_zebra_config'] = ''
return None
- ospf['protocol'] = 'ospf' # required for frr/vrf.route-map.frr.tmpl
- ospf['frr_zebra_config'] = render_to_string('frr/vrf.route-map.frr.tmpl', ospf)
- ospf['frr_ospfd_config'] = render_to_string('frr/ospfd.frr.tmpl', ospf)
+ ospf['protocol'] = 'ospf' # required for frr/vrf.route-map.frr.j2
+ ospf['frr_zebra_config'] = render_to_string('frr/vrf.route-map.frr.j2', ospf)
+ ospf['frr_ospfd_config'] = render_to_string('frr/ospfd.frr.j2', ospf)
return None
def apply(ospf):
@@ -209,8 +218,9 @@ def apply(ospf):
# The route-map used for the FIB (zebra) is part of the zebra daemon
frr_cfg.load_configuration(zebra_daemon)
- frr_cfg.modify_section(r'(\s+)?ip protocol ospf route-map [-a-zA-Z0-9.]+$', '', '(\s|!)')
- frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', ospf['frr_zebra_config'])
+ frr_cfg.modify_section('(\s+)?ip protocol ospf route-map [-a-zA-Z0-9.]+', stop_pattern='(\s|!)')
+ if 'frr_zebra_config' in ospf:
+ frr_cfg.add_before(frr.default_add_before, ospf['frr_zebra_config'])
frr_cfg.commit_configuration(zebra_daemon)
# Generate empty helper string which can be ammended to FRR commands, it
@@ -220,20 +230,18 @@ def apply(ospf):
vrf = ' vrf ' + ospf['vrf']
frr_cfg.load_configuration(ospf_daemon)
- frr_cfg.modify_section(f'^router ospf{vrf}$', '')
+ frr_cfg.modify_section(f'^router ospf{vrf}', stop_pattern='^exit', remove_stop_mark=True)
for key in ['interface', 'interface_removed']:
if key not in ospf:
continue
for interface in ospf[key]:
- frr_cfg.modify_section(f'^interface {interface}{vrf}$', '')
+ frr_cfg.modify_section(f'^interface {interface}{vrf}', stop_pattern='^exit', remove_stop_mark=True)
- frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', ospf['frr_ospfd_config'])
+ if 'frr_ospfd_config' in ospf:
+ frr_cfg.add_before(frr.default_add_before, ospf['frr_ospfd_config'])
frr_cfg.commit_configuration(ospf_daemon)
- # Save configuration to /run/frr/config/frr.conf
- frr.save_configuration()
-
return None
if __name__ == '__main__':
diff --git a/src/conf_mode/protocols_ospfv3.py b/src/conf_mode/protocols_ospfv3.py
index 536ffa690..ee4eaf59d 100755
--- a/src/conf_mode/protocols_ospfv3.py
+++ b/src/conf_mode/protocols_ospfv3.py
@@ -17,32 +17,80 @@
import os
from sys import exit
+from sys import argv
from vyos.config import Config
from vyos.configdict import dict_merge
+from vyos.configdict import node_changed
from vyos.configverify import verify_common_route_maps
+from vyos.configverify import verify_route_map
+from vyos.configverify import verify_interface_exists
from vyos.template import render_to_string
from vyos.ifconfig import Interface
+from vyos.util import dict_search
+from vyos.util import get_interface_config
from vyos.xml import defaults
from vyos import ConfigError
from vyos import frr
from vyos import airbag
airbag.enable()
-frr_daemon = 'ospf6d'
-
def get_config(config=None):
if config:
conf = config
else:
conf = Config()
- base = ['protocols', 'ospfv3']
+
+ vrf = None
+ if len(argv) > 1:
+ vrf = argv[1]
+
+ base_path = ['protocols', 'ospfv3']
+
+ # eqivalent of the C foo ? 'a' : 'b' statement
+ base = vrf and ['vrf', 'name', vrf, 'protocols', 'ospfv3'] or base_path
ospfv3 = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
+ # Assign the name of our VRF context. This MUST be done before the return
+ # statement below, else on deletion we will delete the default instance
+ # instead of the VRF instance.
+ if vrf: ospfv3['vrf'] = vrf
+
+ # FRR has VRF support for different routing daemons. As interfaces belong
+ # to VRFs - or the global VRF, we need to check for changed interfaces so
+ # that they will be properly rendered for the FRR config. Also this eases
+ # removal of interfaces from the running configuration.
+ interfaces_removed = node_changed(conf, base + ['interface'])
+ if interfaces_removed:
+ ospfv3['interface_removed'] = list(interfaces_removed)
+
# Bail out early if configuration tree does not exist
if not conf.exists(base):
+ ospfv3.update({'deleted' : ''})
return ospfv3
+ # We have gathered the dict representation of the CLI, but there are default
+ # options which we need to update into the dictionary retrived.
+ # XXX: Note that we can not call defaults(base), as defaults does not work
+ # on an instance of a tag node. As we use the exact same CLI definition for
+ # both the non-vrf and vrf version this is absolutely safe!
+ default_values = defaults(base_path)
+
+ # We have to cleanup the default dict, as default values could enable features
+ # which are not explicitly enabled on the CLI. Example: default-information
+ # originate comes with a default metric-type of 2, which will enable the
+ # entire default-information originate tree, even when not set via CLI so we
+ # need to check this first and probably drop that key.
+ if dict_search('default_information.originate', ospfv3) is None:
+ del default_values['default_information']
+
+ # XXX: T2665: we currently have no nice way for defaults under tag nodes,
+ # clean them out and add them manually :(
+ del default_values['interface']
+
+ # merge in remaining default values
+ ospfv3 = dict_merge(default_values, ospfv3)
+
# We also need some additional information from the config, prefix-lists
# and route-maps for instance. They will be used in verify().
#
@@ -60,34 +108,68 @@ def verify(ospfv3):
verify_common_route_maps(ospfv3)
+ # As we can have a default-information route-map, we need to validate it!
+ route_map_name = dict_search('default_information.originate.route_map', ospfv3)
+ if route_map_name: verify_route_map(route_map_name, ospfv3)
+
+ if 'area' in ospfv3:
+ for area, area_config in ospfv3['area'].items():
+ if 'area_type' in area_config:
+ if len(area_config['area_type']) > 1:
+ raise ConfigError(f'Can only configure one area-type for OSPFv3 area "{area}"!')
+
if 'interface' in ospfv3:
- for ifname, if_config in ospfv3['interface'].items():
- if 'ifmtu' in if_config:
- mtu = Interface(ifname).get_mtu()
- if int(if_config['ifmtu']) > int(mtu):
+ for interface, interface_config in ospfv3['interface'].items():
+ verify_interface_exists(interface)
+ if 'ifmtu' in interface_config:
+ mtu = Interface(interface).get_mtu()
+ if int(interface_config['ifmtu']) > int(mtu):
raise ConfigError(f'OSPFv3 ifmtu can not exceed physical MTU of "{mtu}"')
+ # If interface specific options are set, we must ensure that the
+ # interface is bound to our requesting VRF. Due to the VyOS
+ # priorities the interface is bound to the VRF after creation of
+ # the VRF itself, and before any routing protocol is configured.
+ if 'vrf' in ospfv3:
+ vrf = ospfv3['vrf']
+ tmp = get_interface_config(interface)
+ if 'master' not in tmp or tmp['master'] != vrf:
+ raise ConfigError(f'Interface {interface} is not a member of VRF {vrf}!')
+
return None
def generate(ospfv3):
- if not ospfv3:
- ospfv3['new_frr_config'] = ''
+ if not ospfv3 or 'deleted' in ospfv3:
return None
- ospfv3['new_frr_config'] = render_to_string('frr/ospf6d.frr.tmpl', ospfv3)
+ ospfv3['new_frr_config'] = render_to_string('frr/ospf6d.frr.j2', ospfv3)
return None
def apply(ospfv3):
+ ospf6_daemon = 'ospf6d'
+
# Save original configuration prior to starting any commit actions
frr_cfg = frr.FRRConfig()
- frr_cfg.load_configuration(frr_daemon)
- frr_cfg.modify_section(r'^interface \S+', '')
- frr_cfg.modify_section('^router ospf6$', '')
- frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', ospfv3['new_frr_config'])
- frr_cfg.commit_configuration(frr_daemon)
-
- # Save configuration to /run/frr/config/frr.conf
- frr.save_configuration()
+
+ # Generate empty helper string which can be ammended to FRR commands, it
+ # will be either empty (default VRF) or contain the "vrf <name" statement
+ vrf = ''
+ if 'vrf' in ospfv3:
+ vrf = ' vrf ' + ospfv3['vrf']
+
+ frr_cfg.load_configuration(ospf6_daemon)
+ frr_cfg.modify_section(f'^router ospf6{vrf}', stop_pattern='^exit', remove_stop_mark=True)
+
+ for key in ['interface', 'interface_removed']:
+ if key not in ospfv3:
+ continue
+ for interface in ospfv3[key]:
+ frr_cfg.modify_section(f'^interface {interface}{vrf}', stop_pattern='^exit', remove_stop_mark=True)
+
+ if 'new_frr_config' in ospfv3:
+ frr_cfg.add_before(frr.default_add_before, ospfv3['new_frr_config'])
+
+ frr_cfg.commit_configuration(ospf6_daemon)
return None
diff --git a/src/conf_mode/protocols_pim.py b/src/conf_mode/protocols_pim.py
index df2e6f941..78df9b6f8 100755
--- a/src/conf_mode/protocols_pim.py
+++ b/src/conf_mode/protocols_pim.py
@@ -135,7 +135,7 @@ def generate(pim):
if pim is None:
return None
- render(config_file, 'frr/pimd.frr.tmpl', pim)
+ render(config_file, 'frr/pimd.frr.j2', pim)
return None
def apply(pim):
diff --git a/src/conf_mode/protocols_rip.py b/src/conf_mode/protocols_rip.py
index 6b78f6f2d..a76c1ce76 100755
--- a/src/conf_mode/protocols_rip.py
+++ b/src/conf_mode/protocols_rip.py
@@ -20,6 +20,7 @@ from sys import exit
from vyos.config import Config
from vyos.configdict import dict_merge
+from vyos.configdict import node_changed
from vyos.configverify import verify_common_route_maps
from vyos.configverify import verify_access_list
from vyos.configverify import verify_prefix_list
@@ -39,8 +40,17 @@ def get_config(config=None):
base = ['protocols', 'rip']
rip = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
+ # FRR has VRF support for different routing daemons. As interfaces belong
+ # to VRFs - or the global VRF, we need to check for changed interfaces so
+ # that they will be properly rendered for the FRR config. Also this eases
+ # removal of interfaces from the running configuration.
+ interfaces_removed = node_changed(conf, base + ['interface'])
+ if interfaces_removed:
+ rip['interface_removed'] = list(interfaces_removed)
+
# Bail out early if configuration tree does not exist
if not conf.exists(base):
+ rip.update({'deleted' : ''})
return rip
# We have gathered the dict representation of the CLI, but there are default
@@ -89,12 +99,10 @@ def verify(rip):
f'with "split-horizon disable" for "{interface}"!')
def generate(rip):
- if not rip:
- rip['new_frr_config'] = ''
+ if not rip or 'deleted' in rip:
return None
- rip['new_frr_config'] = render_to_string('frr/ripd.frr.tmpl', rip)
-
+ rip['new_frr_config'] = render_to_string('frr/ripd.frr.j2', rip)
return None
def apply(rip):
@@ -106,19 +114,22 @@ def apply(rip):
# The route-map used for the FIB (zebra) is part of the zebra daemon
frr_cfg.load_configuration(zebra_daemon)
- frr_cfg.modify_section(r'^ip protocol rip route-map [-a-zA-Z0-9.]+$', '')
+ frr_cfg.modify_section('^ip protocol rip route-map [-a-zA-Z0-9.]+', stop_pattern='(\s|!)')
frr_cfg.commit_configuration(zebra_daemon)
frr_cfg.load_configuration(rip_daemon)
- frr_cfg.modify_section(r'key chain \S+', '')
- frr_cfg.modify_section(r'interface \S+', '')
- frr_cfg.modify_section('^router rip$', '')
+ frr_cfg.modify_section('^key chain \S+', stop_pattern='^exit', remove_stop_mark=True)
+ frr_cfg.modify_section('^router rip', stop_pattern='^exit', remove_stop_mark=True)
- frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', rip['new_frr_config'])
- frr_cfg.commit_configuration(rip_daemon)
+ for key in ['interface', 'interface_removed']:
+ if key not in rip:
+ continue
+ for interface in rip[key]:
+ frr_cfg.modify_section(f'^interface {interface}', stop_pattern='^exit', remove_stop_mark=True)
- # Save configuration to /run/frr/config/frr.conf
- frr.save_configuration()
+ if 'new_frr_config' in rip:
+ frr_cfg.add_before(frr.default_add_before, rip['new_frr_config'])
+ frr_cfg.commit_configuration(rip_daemon)
return None
diff --git a/src/conf_mode/protocols_ripng.py b/src/conf_mode/protocols_ripng.py
index bc4954f63..21ff710b3 100755
--- a/src/conf_mode/protocols_ripng.py
+++ b/src/conf_mode/protocols_ripng.py
@@ -31,8 +31,6 @@ from vyos import frr
from vyos import airbag
airbag.enable()
-frr_daemon = 'ripngd'
-
def get_config(config=None):
if config:
conf = config
@@ -95,21 +93,28 @@ def generate(ripng):
ripng['new_frr_config'] = ''
return None
- ripng['new_frr_config'] = render_to_string('frr/ripngd.frr.tmpl', ripng)
+ ripng['new_frr_config'] = render_to_string('frr/ripngd.frr.j2', ripng)
return None
def apply(ripng):
+ ripng_daemon = 'ripngd'
+ zebra_daemon = 'zebra'
+
# Save original configuration prior to starting any commit actions
frr_cfg = frr.FRRConfig()
- frr_cfg.load_configuration(frr_daemon)
- frr_cfg.modify_section(r'key chain \S+', '')
- frr_cfg.modify_section(r'interface \S+', '')
- frr_cfg.modify_section('router ripng', '')
- frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', ripng['new_frr_config'])
- frr_cfg.commit_configuration(frr_daemon)
-
- # Save configuration to /run/frr/config/frr.conf
- frr.save_configuration()
+
+ # The route-map used for the FIB (zebra) is part of the zebra daemon
+ frr_cfg.load_configuration(zebra_daemon)
+ frr_cfg.modify_section('^ipv6 protocol ripng route-map [-a-zA-Z0-9.]+', stop_pattern='(\s|!)')
+ frr_cfg.commit_configuration(zebra_daemon)
+
+ frr_cfg.load_configuration(ripng_daemon)
+ frr_cfg.modify_section('key chain \S+', stop_pattern='^exit', remove_stop_mark=True)
+ frr_cfg.modify_section('interface \S+', stop_pattern='^exit', remove_stop_mark=True)
+ frr_cfg.modify_section('^router ripng', stop_pattern='^exit', remove_stop_mark=True)
+ if 'new_frr_config' in ripng:
+ frr_cfg.add_before(frr.default_add_before, ripng['new_frr_config'])
+ frr_cfg.commit_configuration(ripng_daemon)
return None
diff --git a/src/conf_mode/protocols_rpki.py b/src/conf_mode/protocols_rpki.py
index 947c8ab7a..62ea9c878 100755
--- a/src/conf_mode/protocols_rpki.py
+++ b/src/conf_mode/protocols_rpki.py
@@ -28,8 +28,6 @@ from vyos import frr
from vyos import airbag
airbag.enable()
-frr_daemon = 'bgpd'
-
def get_config(config=None):
if config:
conf = config
@@ -38,7 +36,9 @@ def get_config(config=None):
base = ['protocols', 'rpki']
rpki = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
+ # Bail out early if configuration tree does not exist
if not conf.exists(base):
+ rpki.update({'deleted' : ''})
return rpki
# We have gathered the dict representation of the CLI, but there are default
@@ -79,17 +79,22 @@ def verify(rpki):
return None
def generate(rpki):
- rpki['new_frr_config'] = render_to_string('frr/rpki.frr.tmpl', rpki)
+ if not rpki:
+ return
+ rpki['new_frr_config'] = render_to_string('frr/rpki.frr.j2', rpki)
return None
def apply(rpki):
+ bgp_daemon = 'bgpd'
+
# Save original configuration prior to starting any commit actions
frr_cfg = frr.FRRConfig()
- frr_cfg.load_configuration(frr_daemon)
- frr_cfg.modify_section('rpki', '')
- frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', rpki['new_frr_config'])
- frr_cfg.commit_configuration(frr_daemon)
+ frr_cfg.load_configuration(bgp_daemon)
+ frr_cfg.modify_section('^rpki', stop_pattern='^exit', remove_stop_mark=True)
+ if 'new_frr_config' in rpki:
+ frr_cfg.add_before(frr.default_add_before, rpki['new_frr_config'])
+ frr_cfg.commit_configuration(bgp_daemon)
return None
if __name__ == '__main__':
diff --git a/src/conf_mode/protocols_static.py b/src/conf_mode/protocols_static.py
index f010141e9..58e202928 100755
--- a/src/conf_mode/protocols_static.py
+++ b/src/conf_mode/protocols_static.py
@@ -22,6 +22,7 @@ from sys import argv
from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.configdict import get_dhcp_interfaces
+from vyos.configdict import get_pppoe_interfaces
from vyos.configverify import verify_common_route_maps
from vyos.configverify import verify_vrf
from vyos.template import render_to_string
@@ -59,7 +60,9 @@ def get_config(config=None):
# T3680 - get a list of all interfaces currently configured to use DHCP
tmp = get_dhcp_interfaces(conf, vrf)
- if tmp: static['dhcp'] = tmp
+ if tmp: static.update({'dhcp' : tmp})
+ tmp = get_pppoe_interfaces(conf, vrf)
+ if tmp: static.update({'pppoe' : tmp})
return static
@@ -82,10 +85,16 @@ def verify(static):
for interface, interface_config in prefix_options[type].items():
verify_vrf(interface_config)
+ if {'blackhole', 'reject'} <= set(prefix_options):
+ raise ConfigError(f'Can not use both blackhole and reject for '\
+ 'prefix "{prefix}"!')
+
return None
def generate(static):
- static['new_frr_config'] = render_to_string('frr/staticd.frr.tmpl', static)
+ if not static:
+ return None
+ static['new_frr_config'] = render_to_string('frr/staticd.frr.j2', static)
return None
def apply(static):
@@ -97,24 +106,21 @@ def apply(static):
# The route-map used for the FIB (zebra) is part of the zebra daemon
frr_cfg.load_configuration(zebra_daemon)
- frr_cfg.modify_section(r'^ip protocol static route-map [-a-zA-Z0-9.]+$', '')
+ frr_cfg.modify_section(r'^ip protocol static route-map [-a-zA-Z0-9.]+', '')
frr_cfg.commit_configuration(zebra_daemon)
-
frr_cfg.load_configuration(static_daemon)
if 'vrf' in static:
vrf = static['vrf']
- frr_cfg.modify_section(f'^vrf {vrf}$', '')
+ frr_cfg.modify_section(f'^vrf {vrf}', stop_pattern='^exit', remove_stop_mark=True)
else:
- frr_cfg.modify_section(r'^ip route .*', '')
- frr_cfg.modify_section(r'^ipv6 route .*', '')
+ frr_cfg.modify_section(r'^ip route .*')
+ frr_cfg.modify_section(r'^ipv6 route .*')
- frr_cfg.add_before(r'(interface .*|line vty)', static['new_frr_config'])
+ if 'new_frr_config' in static:
+ frr_cfg.add_before(frr.default_add_before, static['new_frr_config'])
frr_cfg.commit_configuration(static_daemon)
- # Save configuration to /run/frr/config/frr.conf
- frr.save_configuration()
-
return None
if __name__ == '__main__':
diff --git a/src/conf_mode/protocols_static_multicast.py b/src/conf_mode/protocols_static_multicast.py
index 99157835a..6afdf31f3 100755
--- a/src/conf_mode/protocols_static_multicast.py
+++ b/src/conf_mode/protocols_static_multicast.py
@@ -96,7 +96,7 @@ def generate(mroute):
if mroute is None:
return None
- render(config_file, 'frr/static_mcast.frr.tmpl', mroute)
+ render(config_file, 'frr/static_mcast.frr.j2', mroute)
return None
def apply(mroute):
diff --git a/src/conf_mode/qos.py b/src/conf_mode/qos.py
new file mode 100755
index 000000000..dbe3be225
--- /dev/null
+++ b/src/conf_mode/qos.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+from sys import exit
+
+from vyos.config import Config
+from vyos.configdict import dict_merge
+from vyos.xml import defaults
+from vyos import ConfigError
+from vyos import airbag
+airbag.enable()
+
+def get_config(config=None):
+ if config:
+ conf = config
+ else:
+ conf = Config()
+ base = ['qos']
+ if not conf.exists(base):
+ return None
+
+ qos = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
+
+ if 'policy' in qos:
+ for policy in qos['policy']:
+ # CLI mangles - to _ for better Jinja2 compatibility - do we need
+ # Jinja2 here?
+ policy = policy.replace('-','_')
+
+ default_values = defaults(base + ['policy', policy])
+
+ # class is another tag node which requires individual handling
+ class_default_values = defaults(base + ['policy', policy, 'class'])
+ if 'class' in default_values:
+ del default_values['class']
+
+ for p_name, p_config in qos['policy'][policy].items():
+ qos['policy'][policy][p_name] = dict_merge(
+ default_values, qos['policy'][policy][p_name])
+
+ if 'class' in p_config:
+ for p_class in p_config['class']:
+ qos['policy'][policy][p_name]['class'][p_class] = dict_merge(
+ class_default_values, qos['policy'][policy][p_name]['class'][p_class])
+
+ import pprint
+ pprint.pprint(qos)
+ return qos
+
+def verify(qos):
+ if not qos:
+ return None
+
+ # network policy emulator
+ # reorder rerquires delay to be set
+
+ raise ConfigError('123')
+ return None
+
+def generate(qos):
+ return None
+
+def apply(qos):
+ return None
+
+if __name__ == '__main__':
+ try:
+ c = get_config()
+ verify(c)
+ generate(c)
+ apply(c)
+ except ConfigError as e:
+ print(e)
+ exit(1)
diff --git a/src/conf_mode/salt-minion.py b/src/conf_mode/salt-minion.py
index 841bf6a39..00b889a11 100755
--- a/src/conf_mode/salt-minion.py
+++ b/src/conf_mode/salt-minion.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2020 VyOS maintainers and contributors
+# Copyright (C) 2018-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -16,14 +16,18 @@
import os
-from copy import deepcopy
from socket import gethostname
from sys import exit
from urllib3 import PoolManager
+from vyos.base import Warning
from vyos.config import Config
+from vyos.configdict import dict_merge
+from vyos.configverify import verify_interface_exists
from vyos.template import render
-from vyos.util import call, chown
+from vyos.util import call
+from vyos.util import chown
+from vyos.xml import defaults
from vyos import ConfigError
from vyos import airbag
@@ -32,20 +36,10 @@ airbag.enable()
config_file = r'/etc/salt/minion'
master_keyfile = r'/opt/vyatta/etc/config/salt/pki/minion/master_sign.pub'
-default_config_data = {
- 'hash': 'sha256',
- 'log_level': 'warning',
- 'master' : 'salt',
- 'user': 'minion',
- 'group': 'vyattacfg',
- 'salt_id': gethostname(),
- 'mine_interval': '60',
- 'verify_master_pubkey_sign': 'false',
- 'master_key': ''
-}
+user='minion'
+group='vyattacfg'
def get_config(config=None):
- salt = deepcopy(default_config_data)
if config:
conf = config
else:
@@ -54,44 +48,44 @@ def get_config(config=None):
if not conf.exists(base):
return None
- else:
- conf.set_level(base)
- if conf.exists(['hash']):
- salt['hash'] = conf.return_value(['hash'])
+ salt = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
+ # ID default is dynamic thus we can not use defaults()
+ if 'id' not in salt:
+ salt['id'] = gethostname()
+ # We have gathered the dict representation of the CLI, but there are default
+ # options which we need to update into the dictionary retrived.
+ default_values = defaults(base)
+ salt = dict_merge(default_values, salt)
- if conf.exists(['master']):
- salt['master'] = conf.return_values(['master'])
-
- if conf.exists(['id']):
- salt['salt_id'] = conf.return_value(['id'])
+ if not conf.exists(base):
+ return None
+ else:
+ conf.set_level(base)
- if conf.exists(['user']):
- salt['user'] = conf.return_value(['user'])
+ return salt
- if conf.exists(['interval']):
- salt['interval'] = conf.return_value(['interval'])
+def verify(salt):
+ if not salt:
+ return None
- if conf.exists(['master-key']):
- salt['master_key'] = conf.return_value(['master-key'])
- salt['verify_master_pubkey_sign'] = 'true'
+ if 'hash' in salt and salt['hash'] == 'sha1':
+ Warning('Do not use sha1 hashing algorithm, upgrade to sha256 or later!')
- return salt
+ if 'source_interface' in salt:
+ verify_interface_exists(salt['source_interface'])
-def verify(salt):
return None
def generate(salt):
if not salt:
return None
- render(config_file, 'salt-minion/minion.tmpl', salt,
- user=salt['user'], group=salt['group'])
+ render(config_file, 'salt-minion/minion.j2', salt, user=user, group=group)
if not os.path.exists(master_keyfile):
- if salt['master_key']:
+ if 'master_key' in salt:
req = PoolManager().request('GET', salt['master_key'], preload_content=False)
-
with open(master_keyfile, 'wb') as f:
while True:
data = req.read(1024)
@@ -100,18 +94,19 @@ def generate(salt):
f.write(data)
req.release_conn()
- chown(master_keyfile, salt['user'], salt['group'])
+ chown(master_keyfile, user, group)
return None
def apply(salt):
+ service_name = 'salt-minion.service'
if not salt:
# Salt removed from running config
- call('systemctl stop salt-minion.service')
+ call(f'systemctl stop {service_name}')
if os.path.exists(config_file):
os.unlink(config_file)
else:
- call('systemctl restart salt-minion.service')
+ call(f'systemctl restart {service_name}')
return None
diff --git a/src/conf_mode/service_console-server.py b/src/conf_mode/service_console-server.py
index 51050e702..a2e411e49 100755
--- a/src/conf_mode/service_console-server.py
+++ b/src/conf_mode/service_console-server.py
@@ -81,7 +81,7 @@ def generate(proxy):
if not proxy:
return None
- render(config_file, 'conserver/conserver.conf.tmpl', proxy)
+ render(config_file, 'conserver/conserver.conf.j2', proxy)
if 'device' in proxy:
for device, device_config in proxy['device'].items():
if 'ssh' not in device_config:
@@ -92,7 +92,7 @@ def generate(proxy):
'port' : device_config['ssh']['port'],
}
render(dropbear_systemd_file.format(**tmp),
- 'conserver/dropbear@.service.tmpl', tmp)
+ 'conserver/dropbear@.service.j2', tmp)
return None
diff --git a/src/conf_mode/service_ids_fastnetmon.py b/src/conf_mode/service_ids_fastnetmon.py
index 67edeb630..ae7e582ec 100755
--- a/src/conf_mode/service_ids_fastnetmon.py
+++ b/src/conf_mode/service_ids_fastnetmon.py
@@ -67,8 +67,8 @@ def generate(fastnetmon):
return
- render(config_file, 'ids/fastnetmon.tmpl', fastnetmon)
- render(networks_list, 'ids/fastnetmon_networks_list.tmpl', fastnetmon)
+ render(config_file, 'ids/fastnetmon.j2', fastnetmon)
+ render(networks_list, 'ids/fastnetmon_networks_list.j2', fastnetmon)
return None
diff --git a/src/conf_mode/service_ipoe-server.py b/src/conf_mode/service_ipoe-server.py
index f676fdbbe..559d1bcd5 100755
--- a/src/conf_mode/service_ipoe-server.py
+++ b/src/conf_mode/service_ipoe-server.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2020 VyOS maintainers and contributors
+# Copyright (C) 2018-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -41,6 +41,7 @@ default_config_data = {
'interfaces': [],
'dnsv4': [],
'dnsv6': [],
+ 'client_named_ip_pool': [],
'client_ipv6_pool': [],
'client_ipv6_delegate_prefix': [],
'radius_server': [],
@@ -219,6 +220,22 @@ def get_config(config=None):
conf.set_level(base_path)
+ # Named client-ip-pool
+ if conf.exists(['client-ip-pool', 'name']):
+ for name in conf.list_nodes(['client-ip-pool', 'name']):
+ tmp = {
+ 'name': name,
+ 'gateway_address': '',
+ 'subnet': ''
+ }
+
+ if conf.exists(['client-ip-pool', 'name', name, 'gateway-address']):
+ tmp['gateway_address'] += conf.return_value(['client-ip-pool', 'name', name, 'gateway-address'])
+ if conf.exists(['client-ip-pool', 'name', name, 'subnet']):
+ tmp['subnet'] += conf.return_value(['client-ip-pool', 'name', name, 'subnet'])
+
+ ipoe['client_named_ip_pool'].append(tmp)
+
if conf.exists(['client-ipv6-pool', 'prefix']):
for prefix in conf.list_nodes(['client-ipv6-pool', 'prefix']):
tmp = {
@@ -254,10 +271,6 @@ def verify(ipoe):
if not ipoe['interfaces']:
raise ConfigError('No IPoE interface configured')
- for interface in ipoe['interfaces']:
- if not interface['range']:
- raise ConfigError(f'No IPoE client subnet defined on interface "{ interface }"')
-
if len(ipoe['dnsv4']) > 2:
raise ConfigError('Not more then two IPv4 DNS name-servers can be configured')
@@ -283,10 +296,10 @@ def generate(ipoe):
if not ipoe:
return None
- render(ipoe_conf, 'accel-ppp/ipoe.config.tmpl', ipoe)
+ render(ipoe_conf, 'accel-ppp/ipoe.config.j2', ipoe)
if ipoe['auth_mode'] == 'local':
- render(ipoe_chap_secrets, 'accel-ppp/chap-secrets.ipoe.tmpl', ipoe)
+ render(ipoe_chap_secrets, 'accel-ppp/chap-secrets.ipoe.j2', ipoe)
os.chmod(ipoe_chap_secrets, S_IRUSR | S_IWUSR | S_IRGRP)
else:
diff --git a/src/conf_mode/service_mdns-repeater.py b/src/conf_mode/service_mdns-repeater.py
index d31a0c49e..2383a53fb 100755
--- a/src/conf_mode/service_mdns-repeater.py
+++ b/src/conf_mode/service_mdns-repeater.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2017-2020 VyOS maintainers and contributors
+# Copyright (C) 2017-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -92,7 +92,7 @@ def generate(mdns):
if len(mdns['interface']) < 2:
return None
- render(config_file, 'mdns-repeater/avahi-daemon.tmpl', mdns)
+ render(config_file, 'mdns-repeater/avahi-daemon.j2', mdns)
return None
def apply(mdns):
diff --git a/src/conf_mode/service_monitoring_telegraf.py b/src/conf_mode/service_monitoring_telegraf.py
new file mode 100755
index 000000000..daf75d740
--- /dev/null
+++ b/src/conf_mode/service_monitoring_telegraf.py
@@ -0,0 +1,229 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021-2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import json
+
+from sys import exit
+from shutil import rmtree
+
+from vyos.config import Config
+from vyos.configdict import dict_merge
+from vyos.ifconfig import Section
+from vyos.template import render
+from vyos.util import call
+from vyos.util import chown
+from vyos.util import cmd
+from vyos.xml import defaults
+from vyos import ConfigError
+from vyos import airbag
+airbag.enable()
+
+
+base_dir = '/run/telegraf'
+cache_dir = f'/etc/telegraf/.cache'
+config_telegraf = f'{base_dir}/vyos-telegraf.conf'
+custom_scripts_dir = '/etc/telegraf/custom_scripts'
+syslog_telegraf = '/etc/rsyslog.d/50-telegraf.conf'
+systemd_telegraf_service = '/etc/systemd/system/vyos-telegraf.service'
+systemd_telegraf_override_dir = '/etc/systemd/system/vyos-telegraf.service.d'
+systemd_override = f'{systemd_telegraf_override_dir}/10-override.conf'
+
+
+def get_interfaces(type='', vlan=True):
+ """
+ Get interfaces
+ get_interfaces()
+ ['dum0', 'eth0', 'eth1', 'eth1.5', 'lo', 'tun0']
+
+ get_interfaces("dummy")
+ ['dum0']
+ """
+ interfaces = []
+ ifaces = Section.interfaces(type)
+ for iface in ifaces:
+ if vlan == False and '.' in iface:
+ continue
+ interfaces.append(iface)
+
+ return interfaces
+
+def get_nft_filter_chains():
+ """
+ Get nft chains for table filter
+ """
+ nft = cmd('nft --json list table ip filter')
+ nft = json.loads(nft)
+ chain_list = []
+
+ for output in nft['nftables']:
+ if 'chain' in output:
+ chain = output['chain']['name']
+ chain_list.append(chain)
+
+ return chain_list
+
+
+def get_config(config=None):
+
+ if config:
+ conf = config
+ else:
+ conf = Config()
+ base = ['service', 'monitoring', 'telegraf']
+ if not conf.exists(base):
+ return None
+
+ monitoring = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True,
+ no_tag_node_value_mangle=True)
+
+ # We have gathered the dict representation of the CLI, but there are default
+ # options which we need to update into the dictionary retrived.
+ default_values = defaults(base)
+ monitoring = dict_merge(default_values, monitoring)
+
+ monitoring['custom_scripts_dir'] = custom_scripts_dir
+ monitoring['interfaces_ethernet'] = get_interfaces('ethernet', vlan=False)
+ monitoring['nft_chains'] = get_nft_filter_chains()
+
+ if 'authentication' in monitoring or \
+ 'url' in monitoring:
+ monitoring['influxdb_configured'] = True
+
+ # Redefine azure group-metrics 'single-table' and 'table-per-metric'
+ if 'azure_data_explorer' in monitoring:
+ if 'single-table' in monitoring['azure_data_explorer']['group_metrics']:
+ monitoring['azure_data_explorer']['group_metrics'] = 'SingleTable'
+ else:
+ monitoring['azure_data_explorer']['group_metrics'] = 'TablePerMetric'
+ # Set azure env
+ if 'authentication' in monitoring['azure_data_explorer']:
+ auth_config = monitoring['azure_data_explorer']['authentication']
+ if {'client_id', 'client_secret', 'tenant_id'} <= set(auth_config):
+ os.environ['AZURE_CLIENT_ID'] = auth_config['client_id']
+ os.environ['AZURE_CLIENT_SECRET'] = auth_config['client_secret']
+ os.environ['AZURE_TENANT_ID'] = auth_config['tenant_id']
+
+ # Ignore default XML values if config doesn't exists
+ # Delete key from dict
+ if not conf.exists(base + ['prometheus-client']):
+ del monitoring['prometheus_client']
+
+ if not conf.exists(base + ['azure-data-explorer']):
+ del monitoring['azure_data_explorer']
+
+ return monitoring
+
+def verify(monitoring):
+ # bail out early - looks like removal from running config
+ if not monitoring:
+ return None
+
+ if 'influxdb_configured' in monitoring:
+ if 'authentication' not in monitoring or \
+ 'organization' not in monitoring['authentication'] or \
+ 'token' not in monitoring['authentication']:
+ raise ConfigError(f'Authentication "organization and token" are mandatory!')
+
+ if 'url' not in monitoring:
+ raise ConfigError(f'Monitoring "url" is mandatory!')
+
+ # Verify azure-data-explorer
+ if 'azure_data_explorer' in monitoring:
+ if 'authentication' not in monitoring['azure_data_explorer'] or \
+ 'client_id' not in monitoring['azure_data_explorer']['authentication'] or \
+ 'client_secret' not in monitoring['azure_data_explorer']['authentication'] or \
+ 'tenant_id' not in monitoring['azure_data_explorer']['authentication']:
+ raise ConfigError(f'Authentication "client-id, client-secret and tenant-id" are mandatory!')
+
+ if 'database' not in monitoring['azure_data_explorer']:
+ raise ConfigError(f'Monitoring "database" is mandatory!')
+
+ if 'url' not in monitoring['azure_data_explorer']:
+ raise ConfigError(f'Monitoring "url" is mandatory!')
+
+ if monitoring['azure_data_explorer']['group_metrics'] == 'SingleTable' and \
+ 'table' not in monitoring['azure_data_explorer']:
+ raise ConfigError(f'Monitoring "table" name for single-table mode is mandatory!')
+
+ # Verify Splunk
+ if 'splunk' in monitoring:
+ if 'authentication' not in monitoring['splunk'] or \
+ 'token' not in monitoring['splunk']['authentication']:
+ raise ConfigError(f'Authentication "organization and token" are mandatory!')
+
+ if 'url' not in monitoring['splunk']:
+ raise ConfigError(f'Monitoring splunk "url" is mandatory!')
+
+ return None
+
+def generate(monitoring):
+ if not monitoring:
+ # Delete config and systemd files
+ config_files = [config_telegraf, systemd_telegraf_service, systemd_override, syslog_telegraf]
+ for file in config_files:
+ if os.path.isfile(file):
+ os.unlink(file)
+
+ # Delete old directories
+ if os.path.isdir(cache_dir):
+ rmtree(cache_dir, ignore_errors=True)
+
+ return None
+
+ # Create telegraf cache dir
+ if not os.path.exists(cache_dir):
+ os.makedirs(cache_dir)
+
+ chown(cache_dir, 'telegraf', 'telegraf')
+
+ # Create systemd override dir
+ if not os.path.exists(systemd_telegraf_override_dir):
+ os.mkdir(systemd_telegraf_override_dir)
+
+ # Create custome scripts dir
+ if not os.path.exists(custom_scripts_dir):
+ os.mkdir(custom_scripts_dir)
+
+ # Render telegraf configuration and systemd override
+ render(config_telegraf, 'monitoring/telegraf.j2', monitoring)
+ render(systemd_telegraf_service, 'monitoring/systemd_vyos_telegraf_service.j2', monitoring)
+ render(systemd_override, 'monitoring/override.conf.j2', monitoring, permission=0o640)
+ render(syslog_telegraf, 'monitoring/syslog_telegraf.j2', monitoring)
+
+ chown(base_dir, 'telegraf', 'telegraf')
+
+ return None
+
+def apply(monitoring):
+ # Reload systemd manager configuration
+ call('systemctl daemon-reload')
+ if monitoring:
+ call('systemctl restart vyos-telegraf.service')
+ else:
+ call('systemctl stop vyos-telegraf.service')
+ # Telegraf include custom rsyslog config changes
+ call('systemctl restart rsyslog')
+
+if __name__ == '__main__':
+ try:
+ c = get_config()
+ verify(c)
+ generate(c)
+ apply(c)
+ except ConfigError as e:
+ print(e)
+ exit(1)
diff --git a/src/conf_mode/service_pppoe-server.py b/src/conf_mode/service_pppoe-server.py
index 9fbd531da..6086ef859 100755
--- a/src/conf_mode/service_pppoe-server.py
+++ b/src/conf_mode/service_pppoe-server.py
@@ -24,8 +24,11 @@ from vyos.configverify import verify_accel_ppp_base_service
from vyos.template import render
from vyos.util import call
from vyos.util import dict_search
+from vyos.util import get_interface_config
from vyos import ConfigError
from vyos import airbag
+from vyos.range_regex import range_to_regex
+
airbag.enable()
pppoe_conf = r'/run/accel-pppd/pppoe.conf'
@@ -56,6 +59,11 @@ def verify(pppoe):
if 'interface' not in pppoe:
raise ConfigError('At least one listen interface must be defined!')
+ # Check is interface exists in the system
+ for iface in pppoe['interface']:
+ if not get_interface_config(iface):
+ raise ConfigError(f'Interface {iface} does not exist!')
+
# local ippool and gateway settings config checks
if not (dict_search('client_ip_pool.subnet', pppoe) or
(dict_search('client_ip_pool.start', pppoe) and
@@ -73,10 +81,17 @@ def generate(pppoe):
if not pppoe:
return None
- render(pppoe_conf, 'accel-ppp/pppoe.config.tmpl', pppoe)
+ # Generate special regex for dynamic interfaces
+ for iface in pppoe['interface']:
+ if 'vlan_range' in pppoe['interface'][iface]:
+ pppoe['interface'][iface]['regex'] = []
+ for vlan_range in pppoe['interface'][iface]['vlan_range']:
+ pppoe['interface'][iface]['regex'].append(range_to_regex(vlan_range))
+
+ render(pppoe_conf, 'accel-ppp/pppoe.config.j2', pppoe)
if dict_search('authentication.mode', pppoe) == 'local':
- render(pppoe_chap_secrets, 'accel-ppp/chap-secrets.config_dict.tmpl',
+ render(pppoe_chap_secrets, 'accel-ppp/chap-secrets.config_dict.j2',
pppoe, permission=0o640)
else:
if os.path.exists(pppoe_chap_secrets):
diff --git a/src/conf_mode/service_router-advert.py b/src/conf_mode/service_router-advert.py
index 9afcdd63e..71b758399 100755
--- a/src/conf_mode/service_router-advert.py
+++ b/src/conf_mode/service_router-advert.py
@@ -101,7 +101,7 @@ def generate(rtradv):
if not rtradv:
return None
- render(config_file, 'router-advert/radvd.conf.tmpl', rtradv, permission=0o644)
+ render(config_file, 'router-advert/radvd.conf.j2', rtradv, permission=0o644)
return None
def apply(rtradv):
diff --git a/src/conf_mode/service_upnp.py b/src/conf_mode/service_upnp.py
new file mode 100755
index 000000000..36f3e18a7
--- /dev/null
+++ b/src/conf_mode/service_upnp.py
@@ -0,0 +1,157 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021-2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+
+from sys import exit
+import uuid
+import netifaces
+from ipaddress import IPv4Network
+from ipaddress import IPv6Network
+
+from vyos.config import Config
+from vyos.configdict import dict_merge
+from vyos.configdict import get_interface_dict
+from vyos.configverify import verify_vrf
+from vyos.util import call
+from vyos.template import render
+from vyos.template import is_ipv4
+from vyos.template import is_ipv6
+from vyos.xml import defaults
+from vyos import ConfigError
+from vyos import airbag
+airbag.enable()
+
+config_file = r'/run/upnp/miniupnp.conf'
+
+def get_config(config=None):
+ if config:
+ conf = config
+ else:
+ conf = Config()
+
+ base = ['service', 'upnp']
+ upnpd = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
+
+ if not upnpd:
+ return None
+
+ if 'rule' in upnpd:
+ default_member_values = defaults(base + ['rule'])
+ for rule,rule_config in upnpd['rule'].items():
+ upnpd['rule'][rule] = dict_merge(default_member_values, upnpd['rule'][rule])
+
+ uuidgen = uuid.uuid1()
+ upnpd.update({'uuid': uuidgen})
+
+ return upnpd
+
+def get_all_interface_addr(prefix, filter_dev, filter_family):
+ list_addr = []
+ interfaces = netifaces.interfaces()
+
+ for interface in interfaces:
+ if filter_dev and interface in filter_dev:
+ continue
+ addrs = netifaces.ifaddresses(interface)
+ if netifaces.AF_INET in addrs.keys():
+ if netifaces.AF_INET in filter_family:
+ for addr in addrs[netifaces.AF_INET]:
+ if prefix:
+ # we need to manually assemble a list of IPv4 address/prefix
+ prefix = '/' + \
+ str(IPv4Network('0.0.0.0/' + addr['netmask']).prefixlen)
+ list_addr.append(addr['addr'] + prefix)
+ else:
+ list_addr.append(addr['addr'])
+ if netifaces.AF_INET6 in addrs.keys():
+ if netifaces.AF_INET6 in filter_family:
+ for addr in addrs[netifaces.AF_INET6]:
+ if prefix:
+ # we need to manually assemble a list of IPv4 address/prefix
+ bits = bin(int(addr['netmask'].replace(':', '').split('/')[0], 16)).count('1')
+ prefix = '/' + str(bits)
+ list_addr.append(addr['addr'] + prefix)
+ else:
+ list_addr.append(addr['addr'])
+
+ return list_addr
+
+def verify(upnpd):
+ if not upnpd:
+ return None
+
+ if 'wan_interface' not in upnpd:
+ raise ConfigError('To enable UPNP, you must have the "wan-interface" option!')
+
+ if 'rule' in upnpd:
+ for rule, rule_config in upnpd['rule'].items():
+ for option in ['external_port_range', 'internal_port_range', 'ip', 'action']:
+ if option not in rule_config:
+ tmp = option.replace('_', '-')
+ raise ConfigError(f'Every UPNP rule requires "{tmp}" to be set!')
+
+ if 'stun' in upnpd:
+ for option in ['host', 'port']:
+ if option not in upnpd['stun']:
+ raise ConfigError(f'A UPNP stun support must have an "{option}" option!')
+
+ # Check the validity of the IP address
+ listen_dev = []
+ system_addrs_cidr = get_all_interface_addr(True, [], [netifaces.AF_INET, netifaces.AF_INET6])
+ system_addrs = get_all_interface_addr(False, [], [netifaces.AF_INET, netifaces.AF_INET6])
+ for listen_if_or_addr in upnpd['listen']:
+ if listen_if_or_addr not in netifaces.interfaces():
+ listen_dev.append(listen_if_or_addr)
+ if (listen_if_or_addr not in system_addrs) and (listen_if_or_addr not in system_addrs_cidr) and (listen_if_or_addr not in netifaces.interfaces()):
+ if is_ipv4(listen_if_or_addr) and IPv4Network(listen_if_or_addr).is_multicast:
+ raise ConfigError(f'The address "{listen_if_or_addr}" is an address that is not allowed to listen on. It is not an interface address nor a multicast address!')
+ if is_ipv6(listen_if_or_addr) and IPv6Network(listen_if_or_addr).is_multicast:
+ raise ConfigError(f'The address "{listen_if_or_addr}" is an address that is not allowed to listen on. It is not an interface address nor a multicast address!')
+
+ system_listening_dev_addrs_cidr = get_all_interface_addr(True, listen_dev, [netifaces.AF_INET6])
+ system_listening_dev_addrs = get_all_interface_addr(False, listen_dev, [netifaces.AF_INET6])
+ for listen_if_or_addr in upnpd['listen']:
+ if listen_if_or_addr not in netifaces.interfaces() and (listen_if_or_addr not in system_listening_dev_addrs_cidr) and (listen_if_or_addr not in system_listening_dev_addrs) and is_ipv6(listen_if_or_addr) and (not IPv6Network(listen_if_or_addr).is_multicast):
+ raise ConfigError(f'{listen_if_or_addr} must listen on the interface of the network card')
+
+def generate(upnpd):
+ if not upnpd:
+ return None
+
+ if os.path.isfile(config_file):
+ os.unlink(config_file)
+
+ render(config_file, 'firewall/upnpd.conf.j2', upnpd)
+
+def apply(upnpd):
+ systemd_service_name = 'miniupnpd.service'
+ if not upnpd:
+ # Stop the UPNP service
+ call(f'systemctl stop {systemd_service_name}')
+ else:
+ # Start the UPNP service
+ call(f'systemctl restart {systemd_service_name}')
+
+if __name__ == '__main__':
+ try:
+ c = get_config()
+ verify(c)
+ generate(c)
+ apply(c)
+ except ConfigError as e:
+ print(e)
+ exit(1)
diff --git a/src/conf_mode/service_webproxy.py b/src/conf_mode/service_webproxy.py
index a16cc4aeb..32af31bde 100755
--- a/src/conf_mode/service_webproxy.py
+++ b/src/conf_mode/service_webproxy.py
@@ -61,7 +61,7 @@ def generate_sg_localdb(category, list_type, role, proxy):
user=user_group, group=user_group)
# temporary config file, deleted after generation
- render(sg_tmp_file, 'squid/sg_acl.conf.tmpl', tmp,
+ render(sg_tmp_file, 'squid/sg_acl.conf.j2', tmp,
user=user_group, group=user_group)
call(f'su - {user_group} -c "squidGuard -d -c {sg_tmp_file} -C {db_file}"')
@@ -166,8 +166,8 @@ def generate(proxy):
if not proxy:
return None
- render(squid_config_file, 'squid/squid.conf.tmpl', proxy)
- render(squidguard_config_file, 'squid/squidGuard.conf.tmpl', proxy)
+ render(squid_config_file, 'squid/squid.conf.j2', proxy)
+ render(squidguard_config_file, 'squid/squidGuard.conf.j2', proxy)
cat_dict = {
'local-block' : 'domains',
diff --git a/src/conf_mode/snmp.py b/src/conf_mode/snmp.py
index 6c6367045..5cd24db32 100755
--- a/src/conf_mode/snmp.py
+++ b/src/conf_mode/snmp.py
@@ -18,17 +18,20 @@ import os
from sys import exit
+from vyos.base import Warning
from vyos.config import Config
+from vyos.configdict import dict_merge
from vyos.configverify import verify_vrf
from vyos.snmpv3_hashgen import plaintext_to_md5
from vyos.snmpv3_hashgen import plaintext_to_sha1
from vyos.snmpv3_hashgen import random
from vyos.template import render
-from vyos.template import is_ipv4
from vyos.util import call
from vyos.util import chmod_755
+from vyos.util import dict_search
from vyos.validate import is_addr_assigned
from vyos.version import get_version_data
+from vyos.xml import defaults
from vyos import ConfigError
from vyos import airbag
airbag.enable()
@@ -37,57 +40,26 @@ config_file_client = r'/etc/snmp/snmp.conf'
config_file_daemon = r'/etc/snmp/snmpd.conf'
config_file_access = r'/usr/share/snmp/snmpd.conf'
config_file_user = r'/var/lib/snmp/snmpd.conf'
-default_script_dir = r'/config/user-data/'
systemd_override = r'/etc/systemd/system/snmpd.service.d/override.conf'
+systemd_service = 'snmpd.service'
-# SNMP OIDs used to mark auth/priv type
-OIDs = {
- 'md5' : '.1.3.6.1.6.3.10.1.1.2',
- 'sha' : '.1.3.6.1.6.3.10.1.1.3',
- 'aes' : '.1.3.6.1.6.3.10.1.2.4',
- 'des' : '.1.3.6.1.6.3.10.1.2.2',
- 'none': '.1.3.6.1.6.3.10.1.2.1'
-}
-
-default_config_data = {
- 'listen_on': [],
- 'listen_address': [],
- 'ipv6_enabled': 'True',
- 'communities': [],
- 'smux_peers': [],
- 'location' : '',
- 'protocol' : 'udp',
- 'description' : '',
- 'contact' : '',
- 'route_table': 'False',
- 'trap_source': '',
- 'trap_targets': [],
- 'vyos_user': '',
- 'vyos_user_pass': '',
- 'version': '',
- 'v3_enabled': 'False',
- 'v3_engineid': '',
- 'v3_groups': [],
- 'v3_traps': [],
- 'v3_users': [],
- 'v3_views': [],
- 'script_ext': []
-}
-
-def rmfile(file):
- if os.path.isfile(file):
- os.unlink(file)
-
-def get_config():
- snmp = default_config_data
- conf = Config()
- if not conf.exists('service snmp'):
- return None
+def get_config(config=None):
+ if config:
+ conf = config
else:
- if conf.exists('system ipv6 disable'):
- snmp['ipv6_enabled'] = False
+ conf = Config()
+ base = ['service', 'snmp']
- conf.set_level('service snmp')
+ snmp = conf.get_config_dict(base, key_mangling=('-', '_'),
+ get_first_key=True, no_tag_node_value_mangle=True)
+ if not conf.exists(base):
+ snmp.update({'deleted' : ''})
+
+ if conf.exists(['service', 'lldp', 'snmp', 'enable']):
+ snmp.update({'lldp_snmp' : ''})
+
+ if 'deleted' in snmp:
+ return snmp
version_data = get_version_data()
snmp['version'] = version_data['version']
@@ -96,477 +68,217 @@ def get_config():
snmp['vyos_user'] = 'vyos' + random(8)
snmp['vyos_user_pass'] = random(16)
- if conf.exists('community'):
- for name in conf.list_nodes('community'):
- community = {
- 'name': name,
- 'authorization': 'ro',
- 'network_v4': [],
- 'network_v6': [],
- 'has_source' : False
- }
-
- if conf.exists('community {0} authorization'.format(name)):
- community['authorization'] = conf.return_value('community {0} authorization'.format(name))
-
- # Subnet of SNMP client(s) allowed to contact system
- if conf.exists('community {0} network'.format(name)):
- for addr in conf.return_values('community {0} network'.format(name)):
- if is_ipv4(addr):
- community['network_v4'].append(addr)
- else:
- community['network_v6'].append(addr)
-
- # IP address of SNMP client allowed to contact system
- if conf.exists('community {0} client'.format(name)):
- for addr in conf.return_values('community {0} client'.format(name)):
- if is_ipv4(addr):
- community['network_v4'].append(addr)
- else:
- community['network_v6'].append(addr)
-
- if (len(community['network_v4']) > 0) or (len(community['network_v6']) > 0):
- community['has_source'] = True
-
- snmp['communities'].append(community)
-
- if conf.exists('contact'):
- snmp['contact'] = conf.return_value('contact')
-
- if conf.exists('description'):
- snmp['description'] = conf.return_value('description')
-
- if conf.exists('listen-address'):
- for addr in conf.list_nodes('listen-address'):
- port = '161'
- if conf.exists('listen-address {0} port'.format(addr)):
- port = conf.return_value('listen-address {0} port'.format(addr))
-
- snmp['listen_address'].append((addr, port))
+ # We have gathered the dict representation of the CLI, but there are default
+ # options which we need to update into the dictionary retrived.
+ default_values = defaults(base)
+
+ # We can not merge defaults for tagNodes - those need to be blended in
+ # per tagNode instance
+ if 'listen_address' in default_values:
+ del default_values['listen_address']
+ if 'community' in default_values:
+ del default_values['community']
+ if 'trap_target' in default_values:
+ del default_values['trap_target']
+ if 'v3' in default_values:
+ del default_values['v3']
+ snmp = dict_merge(default_values, snmp)
+
+ if 'listen_address' in snmp:
+ default_values = defaults(base + ['listen-address'])
+ for address in snmp['listen_address']:
+ snmp['listen_address'][address] = dict_merge(
+ default_values, snmp['listen_address'][address])
# Always listen on localhost if an explicit address has been configured
# This is a safety measure to not end up with invalid listen addresses
# that are not configured on this system. See https://phabricator.vyos.net/T850
- if not '127.0.0.1' in conf.list_nodes('listen-address'):
- snmp['listen_address'].append(('127.0.0.1', '161'))
-
- if not '::1' in conf.list_nodes('listen-address'):
- snmp['listen_address'].append(('::1', '161'))
-
- if conf.exists('location'):
- snmp['location'] = conf.return_value('location')
-
- if conf.exists('protocol'):
- snmp['protocol'] = conf.return_value('protocol')
-
- if conf.exists('smux-peer'):
- snmp['smux_peers'] = conf.return_values('smux-peer')
-
- if conf.exists('trap-source'):
- snmp['trap_source'] = conf.return_value('trap-source')
-
- if conf.exists('trap-target'):
- for target in conf.list_nodes('trap-target'):
- trap_tgt = {
- 'target': target,
- 'community': '',
- 'port': ''
- }
-
- if conf.exists('trap-target {0} community'.format(target)):
- trap_tgt['community'] = conf.return_value('trap-target {0} community'.format(target))
-
- if conf.exists('trap-target {0} port'.format(target)):
- trap_tgt['port'] = conf.return_value('trap-target {0} port'.format(target))
-
- snmp['trap_targets'].append(trap_tgt)
-
- if conf.exists('script-extensions'):
- for extname in conf.list_nodes('script-extensions extension-name'):
- conf_script = conf.return_value('script-extensions extension-name {} script'.format(extname))
- # if script has not absolute path, use pre configured path
- if "/" not in conf_script:
- conf_script = default_script_dir + conf_script
-
- extension = {
- 'name': extname,
- 'script' : conf_script
- }
-
- snmp['script_ext'].append(extension)
-
- if conf.exists('oid-enable route-table'):
- snmp['route_table'] = True
-
- if conf.exists('vrf'):
- # Append key to dict but don't place it in the default dictionary.
- # This is required to make the override.conf.tmpl work until we
- # migrate to get_config_dict().
- snmp['vrf'] = conf.return_value('vrf')
-
-
- #########################################################################
- # ____ _ _ __ __ ____ _____ #
- # / ___|| \ | | \/ | _ \ __ _|___ / #
- # \___ \| \| | |\/| | |_) | \ \ / / |_ \ #
- # ___) | |\ | | | | __/ \ V / ___) | #
- # |____/|_| \_|_| |_|_| \_/ |____/ #
- # #
- # now take care about the fancy SNMP v3 stuff, or bail out eraly #
- #########################################################################
- if not conf.exists('v3'):
- return snmp
- else:
- snmp['v3_enabled'] = True
-
- # 'set service snmp v3 engineid'
- if conf.exists('v3 engineid'):
- snmp['v3_engineid'] = conf.return_value('v3 engineid')
-
- # 'set service snmp v3 group'
- if conf.exists('v3 group'):
- for group in conf.list_nodes('v3 group'):
- v3_group = {
- 'name': group,
- 'mode': 'ro',
- 'seclevel': 'auth',
- 'view': ''
- }
-
- if conf.exists('v3 group {0} mode'.format(group)):
- v3_group['mode'] = conf.return_value('v3 group {0} mode'.format(group))
-
- if conf.exists('v3 group {0} seclevel'.format(group)):
- v3_group['seclevel'] = conf.return_value('v3 group {0} seclevel'.format(group))
-
- if conf.exists('v3 group {0} view'.format(group)):
- v3_group['view'] = conf.return_value('v3 group {0} view'.format(group))
-
- snmp['v3_groups'].append(v3_group)
-
- # 'set service snmp v3 trap-target'
- if conf.exists('v3 trap-target'):
- for trap in conf.list_nodes('v3 trap-target'):
- trap_cfg = {
- 'ipAddr': trap,
- 'secName': '',
- 'authProtocol': 'md5',
- 'authPassword': '',
- 'authMasterKey': '',
- 'privProtocol': 'des',
- 'privPassword': '',
- 'privMasterKey': '',
- 'ipProto': 'udp',
- 'ipPort': '162',
- 'type': '',
- 'secLevel': 'noAuthNoPriv'
- }
-
- if conf.exists('v3 trap-target {0} user'.format(trap)):
- # Set the securityName used for authenticated SNMPv3 messages.
- trap_cfg['secName'] = conf.return_value('v3 trap-target {0} user'.format(trap))
-
- if conf.exists('v3 trap-target {0} auth type'.format(trap)):
- # Set the authentication protocol (MD5 or SHA) used for authenticated SNMPv3 messages
- # cmdline option '-a'
- trap_cfg['authProtocol'] = conf.return_value('v3 trap-target {0} auth type'.format(trap))
-
- if conf.exists('v3 trap-target {0} auth plaintext-password'.format(trap)):
- # Set the authentication pass phrase used for authenticated SNMPv3 messages.
- # cmdline option '-A'
- trap_cfg['authPassword'] = conf.return_value('v3 trap-target {0} auth plaintext-password'.format(trap))
-
- if conf.exists('v3 trap-target {0} auth encrypted-password'.format(trap)):
- # Sets the keys to be used for SNMPv3 transactions. These options allow you to set the master authentication keys.
- # cmdline option '-3m'
- trap_cfg['authMasterKey'] = conf.return_value('v3 trap-target {0} auth encrypted-password'.format(trap))
-
- if conf.exists('v3 trap-target {0} privacy type'.format(trap)):
- # Set the privacy protocol (DES or AES) used for encrypted SNMPv3 messages.
- # cmdline option '-x'
- trap_cfg['privProtocol'] = conf.return_value('v3 trap-target {0} privacy type'.format(trap))
-
- if conf.exists('v3 trap-target {0} privacy plaintext-password'.format(trap)):
- # Set the privacy pass phrase used for encrypted SNMPv3 messages.
- # cmdline option '-X'
- trap_cfg['privPassword'] = conf.return_value('v3 trap-target {0} privacy plaintext-password'.format(trap))
-
- if conf.exists('v3 trap-target {0} privacy encrypted-password'.format(trap)):
- # Sets the keys to be used for SNMPv3 transactions. These options allow you to set the master encryption keys.
- # cmdline option '-3M'
- trap_cfg['privMasterKey'] = conf.return_value('v3 trap-target {0} privacy encrypted-password'.format(trap))
-
- if conf.exists('v3 trap-target {0} protocol'.format(trap)):
- trap_cfg['ipProto'] = conf.return_value('v3 trap-target {0} protocol'.format(trap))
-
- if conf.exists('v3 trap-target {0} port'.format(trap)):
- trap_cfg['ipPort'] = conf.return_value('v3 trap-target {0} port'.format(trap))
-
- if conf.exists('v3 trap-target {0} type'.format(trap)):
- trap_cfg['type'] = conf.return_value('v3 trap-target {0} type'.format(trap))
-
- # Determine securityLevel used for SNMPv3 messages (noAuthNoPriv|authNoPriv|authPriv).
- # Appropriate pass phrase(s) must provided when using any level higher than noAuthNoPriv.
- if trap_cfg['authPassword'] or trap_cfg['authMasterKey']:
- if trap_cfg['privProtocol'] or trap_cfg['privPassword']:
- trap_cfg['secLevel'] = 'authPriv'
- else:
- trap_cfg['secLevel'] = 'authNoPriv'
-
- snmp['v3_traps'].append(trap_cfg)
-
- # 'set service snmp v3 user'
- if conf.exists('v3 user'):
- for user in conf.list_nodes('v3 user'):
- user_cfg = {
- 'name': user,
- 'authMasterKey': '',
- 'authPassword': '',
- 'authProtocol': 'md5',
- 'authOID': 'none',
- 'group': '',
- 'mode': 'ro',
- 'privMasterKey': '',
- 'privPassword': '',
- 'privOID': '',
- 'privProtocol': 'des'
- }
-
- # v3 user {0} auth
- if conf.exists('v3 user {0} auth encrypted-password'.format(user)):
- user_cfg['authMasterKey'] = conf.return_value('v3 user {0} auth encrypted-password'.format(user))
-
- if conf.exists('v3 user {0} auth plaintext-password'.format(user)):
- user_cfg['authPassword'] = conf.return_value('v3 user {0} auth plaintext-password'.format(user))
-
- # load default value
- type = user_cfg['authProtocol']
- if conf.exists('v3 user {0} auth type'.format(user)):
- type = conf.return_value('v3 user {0} auth type'.format(user))
-
- # (re-)update with either default value or value from CLI
- user_cfg['authProtocol'] = type
- user_cfg['authOID'] = OIDs[type]
-
- # v3 user {0} group
- if conf.exists('v3 user {0} group'.format(user)):
- user_cfg['group'] = conf.return_value('v3 user {0} group'.format(user))
-
- # v3 user {0} mode
- if conf.exists('v3 user {0} mode'.format(user)):
- user_cfg['mode'] = conf.return_value('v3 user {0} mode'.format(user))
-
- # v3 user {0} privacy
- if conf.exists('v3 user {0} privacy encrypted-password'.format(user)):
- user_cfg['privMasterKey'] = conf.return_value('v3 user {0} privacy encrypted-password'.format(user))
-
- if conf.exists('v3 user {0} privacy plaintext-password'.format(user)):
- user_cfg['privPassword'] = conf.return_value('v3 user {0} privacy plaintext-password'.format(user))
-
- # load default value
- type = user_cfg['privProtocol']
- if conf.exists('v3 user {0} privacy type'.format(user)):
- type = conf.return_value('v3 user {0} privacy type'.format(user))
-
- # (re-)update with either default value or value from CLI
- user_cfg['privProtocol'] = type
- user_cfg['privOID'] = OIDs[type]
-
- snmp['v3_users'].append(user_cfg)
-
- # 'set service snmp v3 view'
- if conf.exists('v3 view'):
- for view in conf.list_nodes('v3 view'):
- view_cfg = {
- 'name': view,
- 'oids': []
- }
-
- if conf.exists('v3 view {0} oid'.format(view)):
- for oid in conf.list_nodes('v3 view {0} oid'.format(view)):
- oid_cfg = {
- 'oid': oid
- }
- view_cfg['oids'].append(oid_cfg)
- snmp['v3_views'].append(view_cfg)
+ if '127.0.0.1' not in snmp['listen_address']:
+ tmp = {'127.0.0.1': {'port': '161'}}
+ snmp['listen_address'] = dict_merge(tmp, snmp['listen_address'])
+
+ if '::1' not in snmp['listen_address']:
+ tmp = {'::1': {'port': '161'}}
+ snmp['listen_address'] = dict_merge(tmp, snmp['listen_address'])
+
+ if 'community' in snmp:
+ default_values = defaults(base + ['community'])
+ for community in snmp['community']:
+ snmp['community'][community] = dict_merge(
+ default_values, snmp['community'][community])
+
+ if 'trap_target' in snmp:
+ default_values = defaults(base + ['trap-target'])
+ for trap in snmp['trap_target']:
+ snmp['trap_target'][trap] = dict_merge(
+ default_values, snmp['trap_target'][trap])
+
+ if 'v3' in snmp:
+ default_values = defaults(base + ['v3'])
+ # tagNodes need to be merged in individually later on
+ for tmp in ['user', 'group', 'trap_target']:
+ del default_values[tmp]
+ snmp['v3'] = dict_merge(default_values, snmp['v3'])
+
+ for user_group in ['user', 'group']:
+ if user_group in snmp['v3']:
+ default_values = defaults(base + ['v3', user_group])
+ for tmp in snmp['v3'][user_group]:
+ snmp['v3'][user_group][tmp] = dict_merge(
+ default_values, snmp['v3'][user_group][tmp])
+
+ if 'trap_target' in snmp['v3']:
+ default_values = defaults(base + ['v3', 'trap-target'])
+ for trap in snmp['v3']['trap_target']:
+ snmp['v3']['trap_target'][trap] = dict_merge(
+ default_values, snmp['v3']['trap_target'][trap])
return snmp
def verify(snmp):
- if snmp is None:
- # we can not delete SNMP when LLDP is configured with SNMP
- conf = Config()
- if conf.exists('service lldp snmp enable'):
- raise ConfigError('Can not delete SNMP service, as LLDP still uses SNMP!')
-
+ if not snmp:
return None
+ if {'deleted', 'lldp_snmp'} <= set(snmp):
+ raise ConfigError('Can not delete SNMP service, as LLDP still uses SNMP!')
+
### check if the configured script actually exist
- if snmp['script_ext']:
- for ext in snmp['script_ext']:
- if not os.path.isfile(ext['script']):
- print ("WARNING: script: {} doesn't exist".format(ext['script']))
+ if 'script_extensions' in snmp and 'extension_name' in snmp['script_extensions']:
+ for extension, extension_opt in snmp['script_extensions']['extension_name'].items():
+ if 'script' not in extension_opt:
+ raise ConfigError(f'Script extension "{extension}" requires an actual script to be configured!')
+
+ tmp = extension_opt['script']
+ if not os.path.isfile(tmp):
+ Warning(f'script "{tmp}" does not exist!')
else:
- chmod_755(ext['script'])
-
- for listen in snmp['listen_address']:
- addr = listen[0]
- port = listen[1]
- protocol = snmp['protocol']
-
- tmp = None
- if is_ipv4(addr):
- # example: udp:127.0.0.1:161
- tmp = f'{protocol}:{addr}:{port}'
- elif snmp['ipv6_enabled']:
- # example: udp6:[::1]:161
- tmp = f'{protocol}6:[{addr}]:{port}'
-
- # We only wan't to configure addresses that exist on the system.
- # Hint the user if they don't exist
- if is_addr_assigned(addr):
- if tmp: snmp['listen_on'].append(tmp)
- else:
- print(f'WARNING: SNMP listen address {addr} not configured!')
+ chmod_755(extension_opt['script'])
+
+ if 'listen_address' in snmp:
+ for address in snmp['listen_address']:
+ # We only wan't to configure addresses that exist on the system.
+ # Hint the user if they don't exist
+ if not is_addr_assigned(address):
+ Warning(f'SNMP listen address "{address}" not configured!')
+
+ if 'trap_target' in snmp:
+ for trap, trap_config in snmp['trap_target'].items():
+ if 'community' not in trap_config:
+ raise ConfigError(f'Trap target "{trap}" requires a community to be set!')
verify_vrf(snmp)
# bail out early if SNMP v3 is not configured
- if not snmp['v3_enabled']:
+ if 'v3' not in snmp:
return None
- if 'v3_groups' in snmp.keys():
- for group in snmp['v3_groups']:
- #
- # A view must exist prior to mapping it into a group
- #
- if 'view' in group.keys():
- error = True
- if 'v3_views' in snmp.keys():
- for view in snmp['v3_views']:
- if view['name'] == group['view']:
- error = False
- if error:
- raise ConfigError('You must create view "{0}" first'.format(group['view']))
- else:
- raise ConfigError('"view" must be specified')
-
- if not 'mode' in group.keys():
- raise ConfigError('"mode" must be specified')
-
- if not 'seclevel' in group.keys():
- raise ConfigError('"seclevel" must be specified')
-
- if 'v3_traps' in snmp.keys():
- for trap in snmp['v3_traps']:
- if trap['authPassword'] and trap['authMasterKey']:
- raise ConfigError('Must specify only one of encrypted-password/plaintext-key for trap auth')
-
- if trap['authPassword'] == '' and trap['authMasterKey'] == '':
- raise ConfigError('Must specify encrypted-password or plaintext-key for trap auth')
-
- if trap['privPassword'] and trap['privMasterKey']:
- raise ConfigError('Must specify only one of encrypted-password/plaintext-key for trap privacy')
+ if 'user' in snmp['v3']:
+ for user, user_config in snmp['v3']['user'].items():
+ if 'group' not in user_config:
+ raise ConfigError(f'Group membership required for user "{user}"!')
- if trap['privPassword'] == '' and trap['privMasterKey'] == '':
- raise ConfigError('Must specify encrypted-password or plaintext-key for trap privacy')
+ if 'plaintext_password' not in user_config['auth'] and 'encrypted_password' not in user_config['auth']:
+ raise ConfigError(f'Must specify authentication encrypted-password or plaintext-password for user "{user}"!')
- if not 'type' in trap.keys():
- raise ConfigError('v3 trap: "type" must be specified')
+ if 'plaintext_password' not in user_config['privacy'] and 'encrypted_password' not in user_config['privacy']:
+ raise ConfigError(f'Must specify privacy encrypted-password or plaintext-password for user "{user}"!')
- if not 'authPassword' and 'authMasterKey' in trap.keys():
- raise ConfigError('v3 trap: "auth" must be specified')
+ if 'group' in snmp['v3']:
+ for group, group_config in snmp['v3']['group'].items():
+ if 'seclevel' not in group_config:
+ raise ConfigError(f'Must configure "seclevel" for group "{group}"!')
+ if 'view' not in group_config:
+ raise ConfigError(f'Must configure "view" for group "{group}"!')
- if not 'authProtocol' in trap.keys():
- raise ConfigError('v3 trap: "protocol" must be specified')
+ # Check if 'view' exists
+ view = group_config['view']
+ if 'view' not in snmp['v3'] or view not in snmp['v3']['view']:
+ raise ConfigError(f'You must create view "{view}" first!')
- if not 'privPassword' and 'privMasterKey' in trap.keys():
- raise ConfigError('v3 trap: "user" must be specified')
+ if 'view' in snmp['v3']:
+ for view, view_config in snmp['v3']['view'].items():
+ if 'oid' not in view_config:
+ raise ConfigError(f'Must configure an "oid" for view "{view}"!')
- if 'v3_users' in snmp.keys():
- for user in snmp['v3_users']:
- #
- # Group must exist prior to mapping it into a group
- # seclevel will be extracted from group
- #
- if user['group']:
- error = True
- if 'v3_groups' in snmp.keys():
- for group in snmp['v3_groups']:
- if group['name'] == user['group']:
- seclevel = group['seclevel']
- error = False
+ if 'trap_target' in snmp['v3']:
+ for trap, trap_config in snmp['v3']['trap_target'].items():
+ if 'plaintext_password' not in trap_config['auth'] and 'encrypted_password' not in trap_config['auth']:
+ raise ConfigError(f'Must specify one of authentication encrypted-password or plaintext-password for trap "{trap}"!')
- if error:
- raise ConfigError('You must create group "{0}" first'.format(user['group']))
+ if {'plaintext_password', 'encrypted_password'} <= set(trap_config['auth']):
+ raise ConfigError(f'Can not specify both authentication encrypted-password and plaintext-password for trap "{trap}"!')
- # Depending on the configured security level the user has to provide additional info
- if (not user['authPassword'] and not user['authMasterKey']):
- raise ConfigError('Must specify encrypted-password or plaintext-key for user auth')
+ if 'plaintext_password' not in trap_config['privacy'] and 'encrypted_password' not in trap_config['privacy']:
+ raise ConfigError(f'Must specify one of privacy encrypted-password or plaintext-password for trap "{trap}"!')
- if user['privPassword'] == '' and user['privMasterKey'] == '':
- raise ConfigError('Must specify encrypted-password or plaintext-key for user privacy')
+ if {'plaintext_password', 'encrypted_password'} <= set(trap_config['privacy']):
+ raise ConfigError(f'Can not specify both privacy encrypted-password and plaintext-password for trap "{trap}"!')
- if user['mode'] == '':
- raise ConfigError('Must specify user mode ro/rw')
-
- if 'v3_views' in snmp.keys():
- for view in snmp['v3_views']:
- if not view['oids']:
- raise ConfigError('Must configure an oid')
+ if 'type' not in trap_config:
+ raise ConfigError('SNMP v3 trap "type" must be specified!')
return None
def generate(snmp):
+
#
# As we are manipulating the snmpd user database we have to stop it first!
# This is even save if service is going to be removed
- call('systemctl stop snmpd.service')
- config_files = [config_file_client, config_file_daemon, config_file_access,
- config_file_user, systemd_override]
+ call(f'systemctl stop {systemd_service}')
+ # Clean config files
+ config_files = [config_file_client, config_file_daemon,
+ config_file_access, config_file_user, systemd_override]
for file in config_files:
- rmfile(file)
+ if os.path.isfile(file):
+ os.unlink(file)
if not snmp:
return None
- if 'v3_users' in snmp.keys():
+ if 'v3' in snmp:
# net-snmp is now regenerating the configuration file in the background
# thus we need to re-open and re-read the file as the content changed.
# After that we can no read the encrypted password from the config and
# replace the CLI plaintext password with its encrypted version.
- os.environ["vyos_libexec_dir"] = "/usr/libexec/vyos"
+ os.environ['vyos_libexec_dir'] = '/usr/libexec/vyos'
- for user in snmp['v3_users']:
- if user['authProtocol'] == 'sha':
- hash = plaintext_to_sha1
- else:
- hash = plaintext_to_md5
+ if 'user' in snmp['v3']:
+ for user, user_config in snmp['v3']['user'].items():
+ if dict_search('auth.type', user_config) == 'sha':
+ hash = plaintext_to_sha1
+ else:
+ hash = plaintext_to_md5
+
+ if dict_search('auth.plaintext_password', user_config) is not None:
+ tmp = hash(dict_search('auth.plaintext_password', user_config),
+ dict_search('v3.engineid', snmp))
+
+ snmp['v3']['user'][user]['auth']['encrypted_password'] = tmp
+ del snmp['v3']['user'][user]['auth']['plaintext_password']
- if user['authPassword']:
- user['authMasterKey'] = hash(user['authPassword'], snmp['v3_engineid'])
- user['authPassword'] = ''
+ call(f'/opt/vyatta/sbin/my_set service snmp v3 user "{user}" auth encrypted-password "{tmp}" > /dev/null')
+ call(f'/opt/vyatta/sbin/my_delete service snmp v3 user "{user}" auth plaintext-password > /dev/null')
- call('/opt/vyatta/sbin/my_set service snmp v3 user "{name}" auth encrypted-password "{authMasterKey}" > /dev/null'.format(**user))
- call('/opt/vyatta/sbin/my_delete service snmp v3 user "{name}" auth plaintext-password > /dev/null'.format(**user))
+ if dict_search('privacy.plaintext_password', user_config) is not None:
+ tmp = hash(dict_search('privacy.plaintext_password', user_config),
+ dict_search('v3.engineid', snmp))
- if user['privPassword']:
- user['privMasterKey'] = hash(user['privPassword'], snmp['v3_engineid'])
- user['privPassword'] = ''
+ snmp['v3']['user'][user]['privacy']['encrypted_password'] = tmp
+ del snmp['v3']['user'][user]['privacy']['plaintext_password']
- call('/opt/vyatta/sbin/my_set service snmp v3 user "{name}" privacy encrypted-password "{privMasterKey}" > /dev/null'.format(**user))
- call('/opt/vyatta/sbin/my_delete service snmp v3 user "{name}" privacy plaintext-password > /dev/null'.format(**user))
+ call(f'/opt/vyatta/sbin/my_set service snmp v3 user "{user}" privacy encrypted-password "{tmp}" > /dev/null')
+ call(f'/opt/vyatta/sbin/my_delete service snmp v3 user "{user}" privacy plaintext-password > /dev/null')
# Write client config file
- render(config_file_client, 'snmp/etc.snmp.conf.tmpl', snmp)
+ render(config_file_client, 'snmp/etc.snmp.conf.j2', snmp)
# Write server config file
- render(config_file_daemon, 'snmp/etc.snmpd.conf.tmpl', snmp)
+ render(config_file_daemon, 'snmp/etc.snmpd.conf.j2', snmp)
# Write access rights config file
- render(config_file_access, 'snmp/usr.snmpd.conf.tmpl', snmp)
+ render(config_file_access, 'snmp/usr.snmpd.conf.j2', snmp)
# Write access rights config file
- render(config_file_user, 'snmp/var.snmpd.conf.tmpl', snmp)
+ render(config_file_user, 'snmp/var.snmpd.conf.j2', snmp)
# Write daemon configuration file
- render(systemd_override, 'snmp/override.conf.tmpl', snmp)
+ render(systemd_override, 'snmp/override.conf.j2', snmp)
return None
@@ -578,7 +290,7 @@ def apply(snmp):
return None
# start SNMP daemon
- call('systemctl restart snmpd.service')
+ call(f'systemctl restart {systemd_service}')
# Enable AgentX in FRR
# This should be done for each daemon individually because common command
diff --git a/src/conf_mode/ssh.py b/src/conf_mode/ssh.py
index 67724b043..28669694b 100755
--- a/src/conf_mode/ssh.py
+++ b/src/conf_mode/ssh.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2021 VyOS maintainers and contributors
+# Copyright (C) 2018-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -33,6 +33,9 @@ airbag.enable()
config_file = r'/run/sshd/sshd_config'
systemd_override = r'/etc/systemd/system/ssh.service.d/override.conf'
+sshguard_config_file = '/etc/sshguard/sshguard.conf'
+sshguard_whitelist = '/etc/sshguard/whitelist'
+
key_rsa = '/etc/ssh/ssh_host_rsa_key'
key_dsa = '/etc/ssh/ssh_host_dsa_key'
key_ed25519 = '/etc/ssh/ssh_host_ed25519_key'
@@ -54,6 +57,11 @@ def get_config(config=None):
# pass config file path - used in override template
ssh['config_file'] = config_file
+ # Ignore default XML values if config doesn't exists
+ # Delete key from dict
+ if not conf.exists(base + ['dynamic-protection']):
+ del ssh['dynamic_protection']
+
return ssh
def verify(ssh):
@@ -84,8 +92,12 @@ def generate(ssh):
syslog(LOG_INFO, 'SSH ed25519 host key not found, generating new key!')
call(f'ssh-keygen -q -N "" -t ed25519 -f {key_ed25519}')
- render(config_file, 'ssh/sshd_config.tmpl', ssh)
- render(systemd_override, 'ssh/override.conf.tmpl', ssh)
+ render(config_file, 'ssh/sshd_config.j2', ssh)
+ render(systemd_override, 'ssh/override.conf.j2', ssh)
+
+ if 'dynamic_protection' in ssh:
+ render(sshguard_config_file, 'ssh/sshguard_config.j2', ssh)
+ render(sshguard_whitelist, 'ssh/sshguard_whitelist.j2', ssh)
# Reload systemd manager configuration
call('systemctl daemon-reload')
@@ -95,7 +107,12 @@ def apply(ssh):
if not ssh:
# SSH access is removed in the commit
call('systemctl stop ssh.service')
+ call('systemctl stop sshguard.service')
return None
+ if 'dynamic_protection' not in ssh:
+ call('systemctl stop sshguard.service')
+ else:
+ call('systemctl restart sshguard.service')
call('systemctl restart ssh.service')
return None
diff --git a/src/conf_mode/system-ip.py b/src/conf_mode/system-ip.py
index 32cb2f036..05fc3a97a 100755
--- a/src/conf_mode/system-ip.py
+++ b/src/conf_mode/system-ip.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2020 VyOS maintainers and contributors
+# Copyright (C) 2019-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -20,14 +20,13 @@ from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.util import call
from vyos.util import dict_search
+from vyos.util import sysctl_write
+from vyos.util import write_file
from vyos.xml import defaults
from vyos import ConfigError
from vyos import airbag
airbag.enable()
-def sysctl(name, value):
- call(f'sysctl -wq {name}={value}')
-
def get_config(config=None):
if config:
conf = config
@@ -50,29 +49,29 @@ def generate(opt):
pass
def apply(opt):
+ # Apply ARP threshold values
+ # table_size has a default value - thus the key always exists
size = int(dict_search('arp.table_size', opt))
- if size:
- # apply ARP threshold values
- sysctl('net.ipv4.neigh.default.gc_thresh3', str(size))
- sysctl('net.ipv4.neigh.default.gc_thresh2', str(size // 2))
- sysctl('net.ipv4.neigh.default.gc_thresh1', str(size // 8))
+ # Amount upon reaching which the records begin to be cleared immediately
+ sysctl_write('net.ipv4.neigh.default.gc_thresh3', size)
+ # Amount after which the records begin to be cleaned after 5 seconds
+ sysctl_write('net.ipv4.neigh.default.gc_thresh2', size // 2)
+ # Minimum number of stored records is indicated which is not cleared
+ sysctl_write('net.ipv4.neigh.default.gc_thresh1', size // 8)
# enable/disable IPv4 forwarding
- tmp = '1'
- if 'disable_forwarding' in opt:
- tmp = '0'
- sysctl('net.ipv4.conf.all.forwarding', tmp)
+ tmp = dict_search('disable_forwarding', opt)
+ value = '0' if (tmp != None) else '1'
+ write_file('/proc/sys/net/ipv4/conf/all/forwarding', value)
- tmp = '0'
- # configure multipath - dict_search() returns an empty dict if key was found
- if isinstance(dict_search('multipath.ignore_unreachable_nexthops', opt), dict):
- tmp = '1'
- sysctl('net.ipv4.fib_multipath_use_neigh', tmp)
+ # configure multipath
+ tmp = dict_search('multipath.ignore_unreachable_nexthops', opt)
+ value = '1' if (tmp != None) else '0'
+ sysctl_write('net.ipv4.fib_multipath_use_neigh', value)
- tmp = '0'
- if isinstance(dict_search('multipath.layer4_hashing', opt), dict):
- tmp = '1'
- sysctl('net.ipv4.fib_multipath_hash_policy', tmp)
+ tmp = dict_search('multipath.layer4_hashing', opt)
+ value = '1' if (tmp != None) else '0'
+ sysctl_write('net.ipv4.fib_multipath_hash_policy', value)
if __name__ == '__main__':
try:
diff --git a/src/conf_mode/system-ipv6.py b/src/conf_mode/system-ipv6.py
index f70ec2631..26aacf46b 100755
--- a/src/conf_mode/system-ipv6.py
+++ b/src/conf_mode/system-ipv6.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019 VyOS maintainers and contributors
+# Copyright (C) 2019-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -15,95 +15,68 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
-import sys
from sys import exit
-from copy import deepcopy
from vyos.config import Config
+from vyos.configdict import dict_merge
+from vyos.util import dict_search
+from vyos.util import sysctl_write
+from vyos.util import write_file
+from vyos.xml import defaults
from vyos import ConfigError
-from vyos.util import call
-
from vyos import airbag
airbag.enable()
-ipv6_disable_file = '/etc/modprobe.d/vyos_disable_ipv6.conf'
-
-default_config_data = {
- 'reboot_message': False,
- 'ipv6_forward': '1',
- 'disable_addr_assignment': False,
- 'mp_layer4_hashing': '0',
- 'neighbor_cache': 8192,
- 'strict_dad': '1'
-
-}
-
-def sysctl(name, value):
- call('sysctl -wq {}={}'.format(name, value))
-
def get_config(config=None):
- ip_opt = deepcopy(default_config_data)
if config:
conf = config
else:
conf = Config()
- conf.set_level('system ipv6')
- if conf.exists(''):
- ip_opt['disable_addr_assignment'] = conf.exists('disable')
- if conf.exists_effective('disable') != conf.exists('disable'):
- ip_opt['reboot_message'] = True
-
- if conf.exists('disable-forwarding'):
- ip_opt['ipv6_forward'] = '0'
+ base = ['system', 'ipv6']
- if conf.exists('multipath layer4-hashing'):
- ip_opt['mp_layer4_hashing'] = '1'
+ opt = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
- if conf.exists('neighbor table-size'):
- ip_opt['neighbor_cache'] = int(conf.return_value('neighbor table-size'))
+ # We have gathered the dict representation of the CLI, but there are default
+ # options which we need to update into the dictionary retrived.
+ default_values = defaults(base)
+ opt = dict_merge(default_values, opt)
- if conf.exists('strict-dad'):
- ip_opt['strict_dad'] = 2
+ return opt
- return ip_opt
-
-def verify(ip_opt):
+def verify(opt):
pass
-def generate(ip_opt):
+def generate(opt):
pass
-def apply(ip_opt):
- # disable IPv6 address assignment
- if ip_opt['disable_addr_assignment']:
- with open(ipv6_disable_file, 'w') as f:
- f.write('options ipv6 disable_ipv6=1')
- else:
- if os.path.exists(ipv6_disable_file):
- os.unlink(ipv6_disable_file)
-
- if ip_opt['reboot_message']:
- print('Changing IPv6 disable parameter will only take affect\n' \
- 'when the system is rebooted.')
-
+def apply(opt):
# configure multipath
- sysctl('net.ipv6.fib_multipath_hash_policy', ip_opt['mp_layer4_hashing'])
-
- # apply neighbor table threshold values
- sysctl('net.ipv6.neigh.default.gc_thresh3', ip_opt['neighbor_cache'])
- sysctl('net.ipv6.neigh.default.gc_thresh2', ip_opt['neighbor_cache'] // 2)
- sysctl('net.ipv6.neigh.default.gc_thresh1', ip_opt['neighbor_cache'] // 8)
+ tmp = dict_search('multipath.layer4_hashing', opt)
+ value = '1' if (tmp != None) else '0'
+ sysctl_write('net.ipv6.fib_multipath_hash_policy', value)
+
+ # Apply ND threshold values
+ # table_size has a default value - thus the key always exists
+ size = int(dict_search('neighbor.table_size', opt))
+ # Amount upon reaching which the records begin to be cleared immediately
+ sysctl_write('net.ipv6.neigh.default.gc_thresh3', size)
+ # Amount after which the records begin to be cleaned after 5 seconds
+ sysctl_write('net.ipv6.neigh.default.gc_thresh2', size // 2)
+ # Minimum number of stored records is indicated which is not cleared
+ sysctl_write('net.ipv6.neigh.default.gc_thresh1', size // 8)
# enable/disable IPv6 forwarding
- with open('/proc/sys/net/ipv6/conf/all/forwarding', 'w') as f:
- f.write(ip_opt['ipv6_forward'])
+ tmp = dict_search('disable_forwarding', opt)
+ value = '0' if (tmp != None) else '1'
+ write_file('/proc/sys/net/ipv6/conf/all/forwarding', value)
# configure IPv6 strict-dad
+ tmp = dict_search('strict_dad', opt)
+ value = '2' if (tmp != None) else '1'
for root, dirs, files in os.walk('/proc/sys/net/ipv6/conf'):
for name in files:
- if name == "accept_dad":
- with open(os.path.join(root, name), 'w') as f:
- f.write(str(ip_opt['strict_dad']))
+ if name == 'accept_dad':
+ write_file(os.path.join(root, name), value)
if __name__ == '__main__':
try:
diff --git a/src/conf_mode/system-login-banner.py b/src/conf_mode/system-login-banner.py
index 2220d7b66..a521c9834 100755
--- a/src/conf_mode/system-login-banner.py
+++ b/src/conf_mode/system-login-banner.py
@@ -15,22 +15,20 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from sys import exit
+from copy import deepcopy
+
from vyos.config import Config
+from vyos.util import write_file
from vyos import ConfigError
-
from vyos import airbag
airbag.enable()
-motd="""
-Check out project news at https://blog.vyos.io
-and feel free to report bugs at https://phabricator.vyos.net
-
-You can change this banner using "set system login banner post-login" command.
-
-VyOS is a free software distribution that includes multiple components,
-you can check individual component licenses under /usr/share/doc/*/copyright
-
-"""
+try:
+ with open('/usr/share/vyos/default_motd') as f:
+ motd = f.read()
+except:
+ # Use an empty banner if the default banner file cannot be read
+ motd = "\n"
PRELOGIN_FILE = r'/etc/issue'
PRELOGIN_NET_FILE = r'/etc/issue.net'
@@ -38,12 +36,12 @@ POSTLOGIN_FILE = r'/etc/motd'
default_config_data = {
'issue': 'Welcome to VyOS - \\n \\l\n\n',
- 'issue_net': 'Welcome to VyOS\n',
+ 'issue_net': '',
'motd': motd
}
def get_config(config=None):
- banner = default_config_data
+ banner = deepcopy(default_config_data)
if config:
conf = config
else:
@@ -92,14 +90,9 @@ def generate(banner):
pass
def apply(banner):
- with open(PRELOGIN_FILE, 'w') as f:
- f.write(banner['issue'])
-
- with open(PRELOGIN_NET_FILE, 'w') as f:
- f.write(banner['issue_net'])
-
- with open(POSTLOGIN_FILE, 'w') as f:
- f.write(banner['motd'])
+ write_file(PRELOGIN_FILE, banner['issue'])
+ write_file(PRELOGIN_NET_FILE, banner['issue_net'])
+ write_file(POSTLOGIN_FILE, banner['motd'])
return None
diff --git a/src/conf_mode/system-login.py b/src/conf_mode/system-login.py
index 4dd7f936d..c717286ae 100755
--- a/src/conf_mode/system-login.py
+++ b/src/conf_mode/system-login.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright (C) 2020-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -23,6 +23,7 @@ from pwd import getpwall
from pwd import getpwnam
from spwd import getspnam
from sys import exit
+from time import sleep
from vyos.config import Config
from vyos.configdict import dict_merge
@@ -31,6 +32,7 @@ from vyos.template import render
from vyos.template import is_ipv4
from vyos.util import cmd
from vyos.util import call
+from vyos.util import run
from vyos.util import DEVNULL
from vyos.util import dict_search
from vyos.xml import defaults
@@ -195,7 +197,7 @@ def generate(login):
pass
if 'radius' in login:
- render(radius_config_file, 'login/pam_radius_auth.conf.tmpl', login,
+ render(radius_config_file, 'login/pam_radius_auth.conf.j2', login,
permission=0o600, user='root', group='root')
else:
if os.path.isfile(radius_config_file):
@@ -239,7 +241,7 @@ def apply(login):
#
# XXX: Should we deny using root at all?
home_dir = getpwnam(user).pw_dir
- render(f'{home_dir}/.ssh/authorized_keys', 'login/authorized_keys.tmpl',
+ render(f'{home_dir}/.ssh/authorized_keys', 'login/authorized_keys.j2',
user_config, permission=0o600,
formater=lambda _: _.replace("&quot;", '"'),
user=user, group='users')
@@ -250,13 +252,22 @@ def apply(login):
if 'rm_users' in login:
for user in login['rm_users']:
try:
+ # Disable user to prevent re-login
+ call(f'usermod -s /sbin/nologin {user}')
+
# Logout user if he is still logged in
if user in list(set([tmp[0] for tmp in users()])):
print(f'{user} is logged in, forcing logout!')
- call(f'pkill -HUP -u {user}')
-
- # Remove user account but leave home directory to be safe
- call(f'userdel --remove {user}', stderr=DEVNULL)
+ # re-run command until user is logged out
+ while run(f'pkill -HUP -u {user}'):
+ sleep(0.250)
+
+ # Remove user account but leave home directory in place. Re-run
+ # command until user is removed - userdel might return 8 as
+ # SSH sessions are not all yet properly cleaned away, thus we
+ # simply re-run the command until the account wen't away
+ while run(f'userdel --remove {user}', stderr=DEVNULL):
+ sleep(0.250)
except Exception as e:
raise ConfigError(f'Deleting user "{user}" raised exception: {e}')
diff --git a/src/conf_mode/system-logs.py b/src/conf_mode/system-logs.py
new file mode 100755
index 000000000..c71938a79
--- /dev/null
+++ b/src/conf_mode/system-logs.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+from sys import exit
+
+from vyos import ConfigError
+from vyos import airbag
+from vyos.config import Config
+from vyos.configdict import dict_merge
+from vyos.logger import syslog
+from vyos.template import render
+from vyos.util import dict_search
+from vyos.xml import defaults
+airbag.enable()
+
+# path to logrotate configs
+logrotate_atop_file = '/etc/logrotate.d/vyos-atop'
+logrotate_rsyslog_file = '/etc/logrotate.d/vyos-rsyslog'
+
+
+def get_config(config=None):
+ if config:
+ conf = config
+ else:
+ conf = Config()
+
+ base = ['system', 'logs']
+ default_values = defaults(base)
+ logs_config = conf.get_config_dict(base,
+ key_mangling=('-', '_'),
+ get_first_key=True)
+ logs_config = dict_merge(default_values, logs_config)
+
+ return logs_config
+
+
+def verify(logs_config):
+ # Nothing to verify here
+ pass
+
+
+def generate(logs_config):
+ # get configuration for logrotate atop
+ logrotate_atop = dict_search('logrotate.atop', logs_config)
+ # generate new config file for atop
+ syslog.debug('Adding logrotate config for atop')
+ render(logrotate_atop_file, 'logs/logrotate/vyos-atop.j2', logrotate_atop)
+
+ # get configuration for logrotate rsyslog
+ logrotate_rsyslog = dict_search('logrotate.messages', logs_config)
+ # generate new config file for rsyslog
+ syslog.debug('Adding logrotate config for rsyslog')
+ render(logrotate_rsyslog_file, 'logs/logrotate/vyos-rsyslog.j2',
+ logrotate_rsyslog)
+
+
+def apply(logs_config):
+ # No further actions needed
+ pass
+
+
+if __name__ == '__main__':
+ try:
+ c = get_config()
+ verify(c)
+ generate(c)
+ apply(c)
+ except ConfigError as e:
+ print(e)
+ exit(1)
diff --git a/src/conf_mode/system-option.py b/src/conf_mode/system-option.py
index b1c63e316..36dbf155b 100755
--- a/src/conf_mode/system-option.py
+++ b/src/conf_mode/system-option.py
@@ -74,8 +74,8 @@ def verify(options):
return None
def generate(options):
- render(curlrc_config, 'system/curlrc.tmpl', options)
- render(ssh_config, 'system/ssh_config.tmpl', options)
+ render(curlrc_config, 'system/curlrc.j2', options)
+ render(ssh_config, 'system/ssh_config.j2', options)
return None
def apply(options):
diff --git a/src/conf_mode/system-proxy.py b/src/conf_mode/system-proxy.py
index 02536c2ab..079c43e7e 100755
--- a/src/conf_mode/system-proxy.py
+++ b/src/conf_mode/system-proxy.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018 VyOS maintainers and contributors
+# Copyright (C) 2018-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -13,83 +13,59 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-#
-import sys
import os
-import re
-from vyos import ConfigError
-from vyos.config import Config
+from sys import exit
+from vyos.config import Config
+from vyos.template import render
+from vyos import ConfigError
from vyos import airbag
airbag.enable()
proxy_def = r'/etc/profile.d/vyos-system-proxy.sh'
-
-def get_config():
- c = Config()
- if not c.exists('system proxy'):
+def get_config(config=None):
+ if config:
+ conf = config
+ else:
+ conf = Config()
+ base = ['system', 'proxy']
+ if not conf.exists(base):
return None
- c.set_level('system proxy')
+ proxy = conf.get_config_dict(base, get_first_key=True)
+ return proxy
- cnf = {
- 'url': None,
- 'port': None,
- 'usr': None,
- 'passwd': None
- }
+def verify(proxy):
+ if not proxy:
+ return
- if c.exists('url'):
- cnf['url'] = c.return_value('url')
- if c.exists('port'):
- cnf['port'] = c.return_value('port')
- if c.exists('username'):
- cnf['usr'] = c.return_value('username')
- if c.exists('password'):
- cnf['passwd'] = c.return_value('password')
+ if 'url' not in proxy or 'port' not in proxy:
+ raise ConfigError('Proxy URL and port require a value')
- return cnf
+ if ('username' in proxy and 'password' not in proxy) or \
+ ('username' not in proxy and 'password' in proxy):
+ raise ConfigError('Both username and password need to be defined!')
+def generate(proxy):
+ if not proxy:
+ if os.path.isfile(proxy_def):
+ os.unlink(proxy_def)
+ return
-def verify(c):
- if not c:
- return None
- if not c['url'] or not c['port']:
- raise ConfigError("proxy url and port requires a value")
- elif c['usr'] and not c['passwd']:
- raise ConfigError("proxy password requires a value")
- elif not c['usr'] and c['passwd']:
- raise ConfigError("proxy username requires a value")
-
+ render(proxy_def, 'system/proxy.j2', proxy, permission=0o755)
-def generate(c):
- if not c:
- return None
- if not c['usr']:
- return str("export http_proxy={url}:{port}\nexport https_proxy=$http_proxy\nexport ftp_proxy=$http_proxy"
- .format(url=c['url'], port=c['port']))
- else:
- return str("export http_proxy=http://{usr}:{passwd}@{url}:{port}\nexport https_proxy=$http_proxy\nexport ftp_proxy=$http_proxy"
- .format(url=re.sub('http://', '', c['url']), port=c['port'], usr=c['usr'], passwd=c['passwd']))
-
-
-def apply(ln):
- if not ln and os.path.exists(proxy_def):
- os.remove(proxy_def)
- else:
- open(proxy_def, 'w').write(
- "# generated by system-proxy.py\n{}\n".format(ln))
+def apply(proxy):
+ pass
if __name__ == '__main__':
try:
c = get_config()
verify(c)
- ln = generate(c)
- apply(ln)
+ generate(c)
+ apply(c)
except ConfigError as e:
print(e)
- sys.exit(1)
+ exit(1)
diff --git a/src/conf_mode/system-syslog.py b/src/conf_mode/system-syslog.py
index 3d8a51cd8..a9d3bbe31 100755
--- a/src/conf_mode/system-syslog.py
+++ b/src/conf_mode/system-syslog.py
@@ -17,6 +17,7 @@
import os
import re
+from pathlib import Path
from sys import exit
from vyos.config import Config
@@ -89,7 +90,7 @@ def get_config(config=None):
filename: {
'log-file': '/var/log/user/' + filename,
'max-files': '5',
- 'action-on-max-size': '/usr/sbin/logrotate /etc/logrotate.d/' + filename,
+ 'action-on-max-size': '/usr/sbin/logrotate /etc/logrotate.d/vyos-rsyslog-generated-' + filename,
'selectors': '*.err',
'max-size': 262144
}
@@ -203,12 +204,19 @@ def generate(c):
return None
conf = '/etc/rsyslog.d/vyos-rsyslog.conf'
- render(conf, 'syslog/rsyslog.conf.tmpl', c)
+ render(conf, 'syslog/rsyslog.conf.j2', c)
+
+ # cleanup current logrotate config files
+ logrotate_files = Path('/etc/logrotate.d/').glob('vyos-rsyslog-generated-*')
+ for file in logrotate_files:
+ file.unlink()
# eventually write for each file its own logrotate file, since size is
# defined it shouldn't matter
- conf = '/etc/logrotate.d/vyos-rsyslog'
- render(conf, 'syslog/logrotate.tmpl', c)
+ for filename, fileconfig in c.get('files', {}).items():
+ if fileconfig['log-file'].startswith('/var/log/user/'):
+ conf = '/etc/logrotate.d/vyos-rsyslog-generated-' + filename
+ render(conf, 'syslog/logrotate.j2', { 'config_render': fileconfig })
def verify(c):
diff --git a/src/conf_mode/system_console.py b/src/conf_mode/system_console.py
index 19b252513..86985d765 100755
--- a/src/conf_mode/system_console.py
+++ b/src/conf_mode/system_console.py
@@ -103,7 +103,7 @@ def generate(console):
config_file = base_dir + f'/serial-getty@{device}.service'
getty_wants_symlink = base_dir + f'/getty.target.wants/serial-getty@{device}.service'
- render(config_file, 'getty/serial-getty.service.tmpl', device_config)
+ render(config_file, 'getty/serial-getty.service.j2', device_config)
os.symlink(config_file, getty_wants_symlink)
# GRUB
diff --git a/src/conf_mode/system_lcd.py b/src/conf_mode/system_lcd.py
index b5ce32beb..3341dd738 100755
--- a/src/conf_mode/system_lcd.py
+++ b/src/conf_mode/system_lcd.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright 2020 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright 2020-2022 VyOS maintainers and contributors <maintainers@vyos.io>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -61,9 +61,9 @@ def generate(lcd):
lcd['device'] = find_device_file(lcd['device'])
# Render config file for daemon LCDd
- render(lcdd_conf, 'lcd/LCDd.conf.tmpl', lcd)
+ render(lcdd_conf, 'lcd/LCDd.conf.j2', lcd)
# Render config file for client lcdproc
- render(lcdproc_conf, 'lcd/lcdproc.conf.tmpl', lcd)
+ render(lcdproc_conf, 'lcd/lcdproc.conf.j2', lcd)
return None
diff --git a/src/conf_mode/system_sysctl.py b/src/conf_mode/system_sysctl.py
index 4f16d1ed6..2e0004ffa 100755
--- a/src/conf_mode/system_sysctl.py
+++ b/src/conf_mode/system_sysctl.py
@@ -50,7 +50,7 @@ def generate(sysctl):
os.unlink(config_file)
return None
- render(config_file, 'system/sysctl.conf.tmpl', sysctl)
+ render(config_file, 'system/sysctl.conf.j2', sysctl)
return None
def apply(sysctl):
diff --git a/src/conf_mode/tftp_server.py b/src/conf_mode/tftp_server.py
index 2409eec1f..c5daccb7f 100755
--- a/src/conf_mode/tftp_server.py
+++ b/src/conf_mode/tftp_server.py
@@ -22,8 +22,10 @@ from copy import deepcopy
from glob import glob
from sys import exit
+from vyos.base import Warning
from vyos.config import Config
from vyos.configdict import dict_merge
+from vyos.configverify import verify_vrf
from vyos.template import render
from vyos.template import is_ipv4
from vyos.util import call
@@ -65,10 +67,11 @@ def verify(tftpd):
if 'listen_address' not in tftpd:
raise ConfigError('TFTP server listen address must be configured!')
- for address in tftpd['listen_address']:
+ for address, address_config in tftpd['listen_address'].items():
if not is_addr_assigned(address):
- print(f'WARNING: TFTP server listen address "{address}" not ' \
- 'assigned to any interface!')
+ Warning(f'TFTP server listen address "{address}" not ' \
+ 'assigned to any interface!')
+ verify_vrf(address_config)
return None
@@ -83,7 +86,7 @@ def generate(tftpd):
return None
idx = 0
- for address in tftpd['listen_address']:
+ for address, address_config in tftpd['listen_address'].items():
config = deepcopy(tftpd)
port = tftpd['port']
if is_ipv4(address):
@@ -91,8 +94,11 @@ def generate(tftpd):
else:
config['listen_address'] = f'[{address}]:{port} -6'
+ if 'vrf' in address_config:
+ config['vrf'] = address_config['vrf']
+
file = config_file + str(idx)
- render(file, 'tftp-server/default.tmpl', config)
+ render(file, 'tftp-server/default.j2', config)
idx = idx + 1
return None
diff --git a/src/conf_mode/vpn_ipsec.py b/src/conf_mode/vpn_ipsec.py
index 99b82ca2d..bad9cfbd8 100755
--- a/src/conf_mode/vpn_ipsec.py
+++ b/src/conf_mode/vpn_ipsec.py
@@ -503,7 +503,7 @@ def generate(ipsec):
charon_radius_conf, interface_conf, swanctl_conf]:
if os.path.isfile(config_file):
os.unlink(config_file)
- render(charon_conf, 'ipsec/charon.tmpl', {'install_routes': default_install_routes})
+ render(charon_conf, 'ipsec/charon.j2', {'install_routes': default_install_routes})
return
if ipsec['dhcp_no_address']:
@@ -553,25 +553,27 @@ def generate(ipsec):
if not local_prefixes or not remote_prefixes:
continue
- passthrough = []
+ passthrough = None
for local_prefix in local_prefixes:
for remote_prefix in remote_prefixes:
local_net = ipaddress.ip_network(local_prefix)
remote_net = ipaddress.ip_network(remote_prefix)
if local_net.overlaps(remote_net):
+ if passthrough is None:
+ passthrough = []
passthrough.append(local_prefix)
ipsec['site_to_site']['peer'][peer]['tunnel'][tunnel]['passthrough'] = passthrough
- render(ipsec_conf, 'ipsec/ipsec.conf.tmpl', ipsec)
- render(ipsec_secrets, 'ipsec/ipsec.secrets.tmpl', ipsec)
- render(charon_conf, 'ipsec/charon.tmpl', ipsec)
- render(charon_dhcp_conf, 'ipsec/charon/dhcp.conf.tmpl', ipsec)
- render(charon_radius_conf, 'ipsec/charon/eap-radius.conf.tmpl', ipsec)
- render(interface_conf, 'ipsec/interfaces_use.conf.tmpl', ipsec)
- render(swanctl_conf, 'ipsec/swanctl.conf.tmpl', ipsec)
+ render(ipsec_conf, 'ipsec/ipsec.conf.j2', ipsec)
+ render(ipsec_secrets, 'ipsec/ipsec.secrets.j2', ipsec)
+ render(charon_conf, 'ipsec/charon.j2', ipsec)
+ render(charon_dhcp_conf, 'ipsec/charon/dhcp.conf.j2', ipsec)
+ render(charon_radius_conf, 'ipsec/charon/eap-radius.conf.j2', ipsec)
+ render(interface_conf, 'ipsec/interfaces_use.conf.j2', ipsec)
+ render(swanctl_conf, 'ipsec/swanctl.conf.j2', ipsec)
def resync_nhrp(ipsec):
if ipsec and not ipsec['nhrp_exists']:
diff --git a/src/conf_mode/vpn_l2tp.py b/src/conf_mode/vpn_l2tp.py
index 818e8fa0b..fd5a4acd8 100755
--- a/src/conf_mode/vpn_l2tp.py
+++ b/src/conf_mode/vpn_l2tp.py
@@ -358,10 +358,10 @@ def generate(l2tp):
if not l2tp:
return None
- render(l2tp_conf, 'accel-ppp/l2tp.config.tmpl', l2tp)
+ render(l2tp_conf, 'accel-ppp/l2tp.config.j2', l2tp)
if l2tp['auth_mode'] == 'local':
- render(l2tp_chap_secrets, 'accel-ppp/chap-secrets.tmpl', l2tp)
+ render(l2tp_chap_secrets, 'accel-ppp/chap-secrets.j2', l2tp)
os.chmod(l2tp_chap_secrets, S_IRUSR | S_IWUSR | S_IRGRP)
else:
diff --git a/src/conf_mode/vpn_openconnect.py b/src/conf_mode/vpn_openconnect.py
index f6db196dc..8e0e30bbf 100755
--- a/src/conf_mode/vpn_openconnect.py
+++ b/src/conf_mode/vpn_openconnect.py
@@ -23,9 +23,12 @@ from vyos.pki import wrap_certificate
from vyos.pki import wrap_private_key
from vyos.template import render
from vyos.util import call
+from vyos.util import is_systemd_service_running
+from vyos.util import dict_search
from vyos.xml import defaults
from vyos import ConfigError
from crypt import crypt, mksalt, METHOD_SHA512
+from time import sleep
from vyos import airbag
airbag.enable()
@@ -33,6 +36,7 @@ airbag.enable()
cfg_dir = '/run/ocserv'
ocserv_conf = cfg_dir + '/ocserv.conf'
ocserv_passwd = cfg_dir + '/ocpasswd'
+ocserv_otp_usr = cfg_dir + '/users.oath'
radius_cfg = cfg_dir + '/radiusclient.conf'
radius_servers = cfg_dir + '/radius_servers'
@@ -52,6 +56,16 @@ def get_config():
default_values = defaults(base)
ocserv = dict_merge(default_values, ocserv)
+ # workaround a "know limitation" - https://phabricator.vyos.net/T2665
+ del ocserv['authentication']['local_users']['username']['otp']
+ if not ocserv["authentication"]["local_users"]["username"]:
+ raise ConfigError('openconnect mode local required at least one user')
+ default_ocserv_usr_values = default_values['authentication']['local_users']['username']['otp']
+ for user, params in ocserv['authentication']['local_users']['username'].items():
+ # Not every configuration requires OTP settings
+ if ocserv['authentication']['local_users']['username'][user].get('otp'):
+ ocserv['authentication']['local_users']['username'][user]['otp'] = dict_merge(default_ocserv_usr_values, ocserv['authentication']['local_users']['username'][user]['otp'])
+
if ocserv:
ocserv['pki'] = conf.get_config_dict(['pki'], key_mangling=('-', '_'),
get_first_key=True, no_tag_node_value_mangle=True)
@@ -61,17 +75,34 @@ def get_config():
def verify(ocserv):
if ocserv is None:
return None
-
# Check authentication
if "authentication" in ocserv:
if "mode" in ocserv["authentication"]:
if "local" in ocserv["authentication"]["mode"]:
- if not ocserv["authentication"]["local_users"] or not ocserv["authentication"]["local_users"]["username"]:
- raise ConfigError('openconnect mode local required at leat one user')
+ if "radius" in ocserv["authentication"]["mode"]:
+ raise ConfigError('OpenConnect authentication modes are mutually-exclusive, remove either local or radius from your configuration')
+ if not ocserv["authentication"]["local_users"]:
+ raise ConfigError('openconnect mode local required at least one user')
+ if not ocserv["authentication"]["local_users"]["username"]:
+ raise ConfigError('openconnect mode local required at least one user')
else:
- for user in ocserv["authentication"]["local_users"]["username"]:
- if not "password" in ocserv["authentication"]["local_users"]["username"][user]:
- raise ConfigError(f'password required for user {user}')
+ # For OTP mode: verify that each local user has an OTP key
+ if "otp" in ocserv["authentication"]["mode"]["local"]:
+ users_wo_key = []
+ for user, user_config in ocserv["authentication"]["local_users"]["username"].items():
+ # User has no OTP key defined
+ if dict_search('otp.key', user_config) == None:
+ users_wo_key.append(user)
+ if users_wo_key:
+ raise ConfigError(f'OTP enabled, but no OTP key is configured for these users:\n{users_wo_key}')
+ # For password (and default) mode: verify that each local user has password
+ if "password" in ocserv["authentication"]["mode"]["local"] or "otp" not in ocserv["authentication"]["mode"]["local"]:
+ users_wo_pswd = []
+ for user in ocserv["authentication"]["local_users"]["username"]:
+ if not "password" in ocserv["authentication"]["local_users"]["username"][user]:
+ users_wo_pswd.append(user)
+ if users_wo_pswd:
+ raise ConfigError(f'password required for users:\n{users_wo_pswd}')
else:
raise ConfigError('openconnect authentication mode required')
else:
@@ -120,22 +151,57 @@ def verify(ocserv):
else:
raise ConfigError('openconnect network settings required')
-
def generate(ocserv):
if not ocserv:
return None
if "radius" in ocserv["authentication"]["mode"]:
# Render radius client configuration
- render(radius_cfg, 'ocserv/radius_conf.tmpl', ocserv["authentication"]["radius"])
+ render(radius_cfg, 'ocserv/radius_conf.j2', ocserv["authentication"]["radius"])
# Render radius servers
- render(radius_servers, 'ocserv/radius_servers.tmpl', ocserv["authentication"]["radius"])
+ render(radius_servers, 'ocserv/radius_servers.j2', ocserv["authentication"]["radius"])
+ elif "local" in ocserv["authentication"]["mode"]:
+ # if mode "OTP", generate OTP users file parameters
+ if "otp" in ocserv["authentication"]["mode"]["local"]:
+ if "local_users" in ocserv["authentication"]:
+ for user in ocserv["authentication"]["local_users"]["username"]:
+ # OTP token type from CLI parameters:
+ otp_interval = str(ocserv["authentication"]["local_users"]["username"][user]["otp"].get("interval"))
+ token_type = ocserv["authentication"]["local_users"]["username"][user]["otp"].get("token_type")
+ otp_length = str(ocserv["authentication"]["local_users"]["username"][user]["otp"].get("otp_length"))
+ if token_type == "hotp-time":
+ otp_type = "HOTP/T" + otp_interval
+ elif token_type == "hotp-event":
+ otp_type = "HOTP/E"
+ else:
+ otp_type = "HOTP/T" + otp_interval
+ ocserv["authentication"]["local_users"]["username"][user]["otp"]["token_tmpl"] = otp_type + "/" + otp_length
+ # if there is a password, generate hash
+ if "password" in ocserv["authentication"]["mode"]["local"] or not "otp" in ocserv["authentication"]["mode"]["local"]:
+ if "local_users" in ocserv["authentication"]:
+ for user in ocserv["authentication"]["local_users"]["username"]:
+ ocserv["authentication"]["local_users"]["username"][user]["hash"] = get_hash(ocserv["authentication"]["local_users"]["username"][user]["password"])
+
+ if "password-otp" in ocserv["authentication"]["mode"]["local"]:
+ # Render local users ocpasswd
+ render(ocserv_passwd, 'ocserv/ocserv_passwd.j2', ocserv["authentication"]["local_users"])
+ # Render local users OTP keys
+ render(ocserv_otp_usr, 'ocserv/ocserv_otp_usr.j2', ocserv["authentication"]["local_users"])
+ elif "password" in ocserv["authentication"]["mode"]["local"]:
+ # Render local users ocpasswd
+ render(ocserv_passwd, 'ocserv/ocserv_passwd.j2', ocserv["authentication"]["local_users"])
+ elif "otp" in ocserv["authentication"]["mode"]["local"]:
+ # Render local users OTP keys
+ render(ocserv_otp_usr, 'ocserv/ocserv_otp_usr.j2', ocserv["authentication"]["local_users"])
+ else:
+ # Render local users ocpasswd
+ render(ocserv_passwd, 'ocserv/ocserv_passwd.j2', ocserv["authentication"]["local_users"])
else:
if "local_users" in ocserv["authentication"]:
for user in ocserv["authentication"]["local_users"]["username"]:
ocserv["authentication"]["local_users"]["username"][user]["hash"] = get_hash(ocserv["authentication"]["local_users"]["username"][user]["password"])
# Render local users
- render(ocserv_passwd, 'ocserv/ocserv_passwd.tmpl', ocserv["authentication"]["local_users"])
+ render(ocserv_passwd, 'ocserv/ocserv_passwd.j2', ocserv["authentication"]["local_users"])
if "ssl" in ocserv:
cert_file_path = os.path.join(cfg_dir, 'cert.pem')
@@ -161,17 +227,27 @@ def generate(ocserv):
f.write(wrap_certificate(pki_ca_cert['certificate']))
# Render config
- render(ocserv_conf, 'ocserv/ocserv_config.tmpl', ocserv)
+ render(ocserv_conf, 'ocserv/ocserv_config.j2', ocserv)
def apply(ocserv):
if not ocserv:
call('systemctl stop ocserv.service')
- for file in [ocserv_conf, ocserv_passwd]:
+ for file in [ocserv_conf, ocserv_passwd, ocserv_otp_usr]:
if os.path.exists(file):
os.unlink(file)
else:
call('systemctl restart ocserv.service')
+ counter = 0
+ while True:
+ # exit early when service runs
+ if is_systemd_service_running("ocserv.service"):
+ break
+ sleep(0.250)
+ if counter > 5:
+ raise ConfigError('openconnect failed to start, check the logs for details')
+ break
+ counter += 1
if __name__ == '__main__':
diff --git a/src/conf_mode/vpn_pptp.py b/src/conf_mode/vpn_pptp.py
index 30abe4782..7550c411e 100755
--- a/src/conf_mode/vpn_pptp.py
+++ b/src/conf_mode/vpn_pptp.py
@@ -264,10 +264,10 @@ def generate(pptp):
if not pptp:
return None
- render(pptp_conf, 'accel-ppp/pptp.config.tmpl', pptp)
+ render(pptp_conf, 'accel-ppp/pptp.config.j2', pptp)
if pptp['local_users']:
- render(pptp_chap_secrets, 'accel-ppp/chap-secrets.tmpl', pptp)
+ render(pptp_chap_secrets, 'accel-ppp/chap-secrets.j2', pptp)
os.chmod(pptp_chap_secrets, S_IRUSR | S_IWUSR | S_IRGRP)
else:
if os.path.exists(pptp_chap_secrets):
diff --git a/src/conf_mode/vpn_sstp.py b/src/conf_mode/vpn_sstp.py
index 68980e5ab..db53463cf 100755
--- a/src/conf_mode/vpn_sstp.py
+++ b/src/conf_mode/vpn_sstp.py
@@ -114,7 +114,7 @@ def generate(sstp):
return None
# accel-cmd reload doesn't work so any change results in a restart of the daemon
- render(sstp_conf, 'accel-ppp/sstp.config.tmpl', sstp)
+ render(sstp_conf, 'accel-ppp/sstp.config.j2', sstp)
cert_name = sstp['ssl']['certificate']
pki_cert = sstp['pki']['certificate'][cert_name]
@@ -127,7 +127,7 @@ def generate(sstp):
write_file(ca_cert_file_path, wrap_certificate(pki_ca['certificate']))
if dict_search('authentication.mode', sstp) == 'local':
- render(sstp_chap_secrets, 'accel-ppp/chap-secrets.config_dict.tmpl',
+ render(sstp_chap_secrets, 'accel-ppp/chap-secrets.config_dict.j2',
sstp, permission=0o640)
else:
if os.path.exists(sstp_chap_secrets):
diff --git a/src/conf_mode/vrf.py b/src/conf_mode/vrf.py
index 38c0c4463..972d0289b 100755
--- a/src/conf_mode/vrf.py
+++ b/src/conf_mode/vrf.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright (C) 2020-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -29,6 +29,7 @@ from vyos.util import dict_search
from vyos.util import get_interface_config
from vyos.util import popen
from vyos.util import run
+from vyos.util import sysctl_write
from vyos import ConfigError
from vyos import frr
from vyos import airbag
@@ -37,10 +38,16 @@ airbag.enable()
config_file = '/etc/iproute2/rt_tables.d/vyos-vrf.conf'
nft_vrf_config = '/tmp/nftables-vrf-zones'
-def list_rules():
- command = 'ip -j -4 rule show'
- answer = loads(cmd(command))
- return [_ for _ in answer if _]
+def has_rule(af : str, priority : int, table : str):
+ """ Check if a given ip rule exists """
+ if af not in ['-4', '-6']:
+ raise ValueError()
+ command = f'ip -j {af} rule show'
+ for tmp in loads(cmd(command)):
+ if {'priority', 'table'} <= set(tmp):
+ if tmp['priority'] == priority and tmp['table'] == table:
+ return True
+ return False
def vrf_interfaces(c, match):
matched = []
@@ -69,7 +76,6 @@ def vrf_routing(c, match):
c.set_level(old_level)
return matched
-
def get_config(config=None):
if config:
conf = config
@@ -77,7 +83,8 @@ def get_config(config=None):
conf = Config()
base = ['vrf']
- vrf = conf.get_config_dict(base, get_first_key=True)
+ vrf = conf.get_config_dict(base, key_mangling=('-', '_'),
+ no_tag_node_value_mangle=True, get_first_key=True)
# determine which VRF has been removed
for name in node_changed(conf, base + ['name']):
@@ -127,10 +134,10 @@ def verify(vrf):
def generate(vrf):
- render(config_file, 'vrf/vrf.conf.tmpl', vrf)
+ render(config_file, 'vrf/vrf.conf.j2', vrf)
# Render nftables zones config
- render(nft_vrf_config, 'firewall/nftables-vrf-zones.tmpl', vrf)
+ render(nft_vrf_config, 'firewall/nftables-vrf-zones.j2', vrf)
return None
@@ -146,15 +153,13 @@ def apply(vrf):
# set the default VRF global behaviour
bind_all = '0'
- if 'bind-to-all' in vrf:
+ if 'bind_to_all' in vrf:
bind_all = '1'
- call(f'sysctl -wq net.ipv4.tcp_l3mdev_accept={bind_all}')
- call(f'sysctl -wq net.ipv4.udp_l3mdev_accept={bind_all}')
+ sysctl_write('net.ipv4.tcp_l3mdev_accept', bind_all)
+ sysctl_write('net.ipv4.udp_l3mdev_accept', bind_all)
for tmp in (dict_search('vrf_remove', vrf) or []):
if os.path.isdir(f'/sys/class/net/{tmp}'):
- call(f'ip -4 route del vrf {tmp} unreachable default metric 4278198272')
- call(f'ip -6 route del vrf {tmp} unreachable default metric 4278198272')
call(f'ip link delete dev {tmp}')
# Remove nftables conntrack zone map item
nft_del_element = f'delete element inet vrf_zones ct_iface_map {{ "{tmp}" }}'
@@ -165,31 +170,68 @@ def apply(vrf):
# check if table already exists
_, err = popen('nft list table inet vrf_zones')
# If not, create a table
- if err:
- if os.path.exists(nft_vrf_config):
- cmd(f'nft -f {nft_vrf_config}')
- os.unlink(nft_vrf_config)
+ if err and os.path.exists(nft_vrf_config):
+ cmd(f'nft -f {nft_vrf_config}')
+ os.unlink(nft_vrf_config)
+
+ # Linux routing uses rules to find tables - routing targets are then
+ # looked up in those tables. If the lookup got a matching route, the
+ # process ends.
+ #
+ # TL;DR; first table with a matching entry wins!
+ #
+ # You can see your routing table lookup rules using "ip rule", sadly the
+ # local lookup is hit before any VRF lookup. Pinging an addresses from the
+ # VRF will usually find a hit in the local table, and never reach the VRF
+ # routing table - this is usually not what you want. Thus we will
+ # re-arrange the tables and move the local lookup further down once VRFs
+ # are enabled.
+ #
+ # Thanks to https://stbuehler.de/blog/article/2020/02/29/using_vrf__virtual_routing_and_forwarding__on_linux.html
+
+ for afi in ['-4', '-6']:
+ # move lookup local to pref 32765 (from 0)
+ if not has_rule(afi, 32765, 'local'):
+ call(f'ip {afi} rule add pref 32765 table local')
+ if has_rule(afi, 0, 'local'):
+ call(f'ip {afi} rule del pref 0')
+ # make sure that in VRFs after failed lookup in the VRF specific table
+ # nothing else is reached
+ if not has_rule(afi, 1000, 'l3mdev'):
+ # this should be added by the kernel when a VRF is created
+ # add it here for completeness
+ call(f'ip {afi} rule add pref 1000 l3mdev protocol kernel')
+
+ # add another rule with an unreachable target which only triggers in VRF context
+ # if a route could not be reached
+ if not has_rule(afi, 2000, 'l3mdev'):
+ call(f'ip {afi} rule add pref 2000 l3mdev unreachable')
for name, config in vrf['name'].items():
table = config['table']
-
if not os.path.isdir(f'/sys/class/net/{name}'):
# For each VRF apart from your default context create a VRF
# interface with a separate routing table
call(f'ip link add {name} type vrf table {table}')
- # The kernel Documentation/networking/vrf.txt also recommends
- # adding unreachable routes to the VRF routing tables so that routes
- # afterwards are taken.
- call(f'ip -4 route add vrf {name} unreachable default metric 4278198272')
- call(f'ip -6 route add vrf {name} unreachable default metric 4278198272')
- # We also should add proper loopback IP addresses to the newly
- # created VRFs for services bound to the loopback address (SNMP, NTP)
- call(f'ip -4 addr add 127.0.0.1/8 dev {name}')
- call(f'ip -6 addr add ::1/128 dev {name}')
# set VRF description for e.g. SNMP monitoring
vrf_if = Interface(name)
+ # We also should add proper loopback IP addresses to the newly added
+ # VRF for services bound to the loopback address (SNMP, NTP)
+ vrf_if.add_addr('127.0.0.1/8')
+ vrf_if.add_addr('::1/128')
+ # add VRF description if available
vrf_if.set_alias(config.get('description', ''))
+
+ # Enable/Disable IPv4 forwarding
+ tmp = dict_search('ip.disable_forwarding', config)
+ value = '0' if (tmp != None) else '1'
+ vrf_if.set_ipv4_forwarding(value)
+ # Enable/Disable IPv6 forwarding
+ tmp = dict_search('ipv6.disable_forwarding', config)
+ value = '0' if (tmp != None) else '1'
+ vrf_if.set_ipv6_forwarding(value)
+
# Enable/Disable of an interface must always be done at the end of the
# derived class to make use of the ref-counting set_admin_state()
# function. We will only enable the interface if 'up' was called as
@@ -203,37 +245,9 @@ def apply(vrf):
nft_add_element = f'add element inet vrf_zones ct_iface_map {{ "{name}" : {table} }}'
cmd(f'nft {nft_add_element}')
- # Linux routing uses rules to find tables - routing targets are then
- # looked up in those tables. If the lookup got a matching route, the
- # process ends.
- #
- # TL;DR; first table with a matching entry wins!
- #
- # You can see your routing table lookup rules using "ip rule", sadly the
- # local lookup is hit before any VRF lookup. Pinging an addresses from the
- # VRF will usually find a hit in the local table, and never reach the VRF
- # routing table - this is usually not what you want. Thus we will
- # re-arrange the tables and move the local lookup furhter down once VRFs
- # are enabled.
-
- # get current preference on local table
- local_pref = [r.get('priority') for r in list_rules() if r.get('table') == 'local'][0]
-
- # change preference when VRFs are enabled and local lookup table is default
- if not local_pref and 'name' in vrf:
- for af in ['-4', '-6']:
- call(f'ip {af} rule add pref 32765 table local')
- call(f'ip {af} rule del pref 0')
# return to default lookup preference when no VRF is configured
if 'name' not in vrf:
- for af in ['-4', '-6']:
- call(f'ip {af} rule add pref 0 table local')
- call(f'ip {af} rule del pref 32765')
-
- # clean out l3mdev-table rule if present
- if 1000 in [r.get('priority') for r in list_rules() if r.get('priority') == 1000]:
- call(f'ip {af} rule del pref 1000')
# Remove VRF zones table from nftables
tmp = run('nft list table inet vrf_zones')
if tmp == 0:
diff --git a/src/conf_mode/vrf_vni.py b/src/conf_mode/vrf_vni.py
index 50d60f0dc..585fdbebf 100755
--- a/src/conf_mode/vrf_vni.py
+++ b/src/conf_mode/vrf_vni.py
@@ -40,20 +40,18 @@ def verify(vrf):
return None
def generate(vrf):
- vrf['new_frr_config'] = render_to_string('frr/vrf-vni.frr.tmpl', vrf)
+ vrf['new_frr_config'] = render_to_string('frr/vrf-vni.frr.j2', vrf)
return None
def apply(vrf):
# add configuration to FRR
frr_cfg = frr.FRRConfig()
frr_cfg.load_configuration(frr_daemon)
- frr_cfg.modify_section(f'^vrf .+$', '')
- frr_cfg.add_before(r'(interface .*|line vty)', vrf['new_frr_config'])
+ frr_cfg.modify_section(f'^vrf .+', stop_pattern='^exit-vrf', remove_stop_mark=True)
+ if 'new_frr_config' in vrf:
+ frr_cfg.add_before(frr.default_add_before, vrf['new_frr_config'])
frr_cfg.commit_configuration(frr_daemon)
- # Save configuration to /run/frr/config/frr.conf
- frr.save_configuration()
-
return None
if __name__ == '__main__':
diff --git a/src/conf_mode/zone_policy.py b/src/conf_mode/zone_policy.py
new file mode 100755
index 000000000..070a4deea
--- /dev/null
+++ b/src/conf_mode/zone_policy.py
@@ -0,0 +1,213 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021-2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+
+from json import loads
+from sys import exit
+
+from vyos.config import Config
+from vyos.configdict import dict_merge
+from vyos.template import render
+from vyos.util import cmd
+from vyos.util import dict_search_args
+from vyos.util import run
+from vyos.xml import defaults
+from vyos import ConfigError
+from vyos import airbag
+airbag.enable()
+
+nftables_conf = '/run/nftables_zone.conf'
+
+def get_config(config=None):
+ if config:
+ conf = config
+ else:
+ conf = Config()
+ base = ['zone-policy']
+ zone_policy = conf.get_config_dict(base, key_mangling=('-', '_'),
+ get_first_key=True,
+ no_tag_node_value_mangle=True)
+
+ zone_policy['firewall'] = conf.get_config_dict(['firewall'],
+ key_mangling=('-', '_'),
+ get_first_key=True,
+ no_tag_node_value_mangle=True)
+
+ if 'zone' in zone_policy:
+ # We have gathered the dict representation of the CLI, but there are default
+ # options which we need to update into the dictionary retrived.
+ default_values = defaults(base + ['zone'])
+ for zone in zone_policy['zone']:
+ zone_policy['zone'][zone] = dict_merge(default_values,
+ zone_policy['zone'][zone])
+
+ return zone_policy
+
+def verify(zone_policy):
+ # bail out early - looks like removal from running config
+ if not zone_policy:
+ return None
+
+ local_zone = False
+ interfaces = []
+
+ if 'zone' in zone_policy:
+ for zone, zone_conf in zone_policy['zone'].items():
+ if 'local_zone' not in zone_conf and 'interface' not in zone_conf:
+ raise ConfigError(f'Zone "{zone}" has no interfaces and is not the local zone')
+
+ if 'local_zone' in zone_conf:
+ if local_zone:
+ raise ConfigError('There cannot be multiple local zones')
+ if 'interface' in zone_conf:
+ raise ConfigError('Local zone cannot have interfaces assigned')
+ if 'intra_zone_filtering' in zone_conf:
+ raise ConfigError('Local zone cannot use intra-zone-filtering')
+ local_zone = True
+
+ if 'interface' in zone_conf:
+ found_duplicates = [intf for intf in zone_conf['interface'] if intf in interfaces]
+
+ if found_duplicates:
+ raise ConfigError(f'Interfaces cannot be assigned to multiple zones')
+
+ interfaces += zone_conf['interface']
+
+ if 'intra_zone_filtering' in zone_conf:
+ intra_zone = zone_conf['intra_zone_filtering']
+
+ if len(intra_zone) > 1:
+ raise ConfigError('Only one intra-zone-filtering action must be specified')
+
+ if 'firewall' in intra_zone:
+ v4_name = dict_search_args(intra_zone, 'firewall', 'name')
+ if v4_name and not dict_search_args(zone_policy, 'firewall', 'name', v4_name):
+ raise ConfigError(f'Firewall name "{v4_name}" does not exist')
+
+ v6_name = dict_search_args(intra_zone, 'firewall', 'ipv6-name')
+ if v6_name and not dict_search_args(zone_policy, 'firewall', 'ipv6-name', v6_name):
+ raise ConfigError(f'Firewall ipv6-name "{v6_name}" does not exist')
+
+ if not v4_name and not v6_name:
+ raise ConfigError('No firewall names specified for intra-zone-filtering')
+
+ if 'from' in zone_conf:
+ for from_zone, from_conf in zone_conf['from'].items():
+ if from_zone not in zone_policy['zone']:
+ raise ConfigError(f'Zone "{zone}" refers to a non-existent or deleted zone "{from_zone}"')
+
+ v4_name = dict_search_args(from_conf, 'firewall', 'name')
+ if v4_name:
+ if 'name' not in zone_policy['firewall']:
+ raise ConfigError(f'Firewall name "{v4_name}" does not exist')
+
+ if not dict_search_args(zone_policy, 'firewall', 'name', v4_name):
+ raise ConfigError(f'Firewall name "{v4_name}" does not exist')
+
+ v6_name = dict_search_args(from_conf, 'firewall', 'v6_name')
+ if v6_name:
+ if 'ipv6_name' not in zone_policy['firewall']:
+ raise ConfigError(f'Firewall ipv6-name "{v6_name}" does not exist')
+
+ if not dict_search_args(zone_policy, 'firewall', 'ipv6_name', v6_name):
+ raise ConfigError(f'Firewall ipv6-name "{v6_name}" does not exist')
+
+ return None
+
+def has_ipv4_fw(zone_conf):
+ if 'from' not in zone_conf:
+ return False
+ zone_from = zone_conf['from']
+ return any([True for fz in zone_from if dict_search_args(zone_from, fz, 'firewall', 'name')])
+
+def has_ipv6_fw(zone_conf):
+ if 'from' not in zone_conf:
+ return False
+ zone_from = zone_conf['from']
+ return any([True for fz in zone_from if dict_search_args(zone_from, fz, 'firewall', 'ipv6_name')])
+
+def get_local_from(zone_policy, local_zone_name):
+ # Get all zone firewall names from the local zone
+ out = {}
+ for zone, zone_conf in zone_policy['zone'].items():
+ if zone == local_zone_name:
+ continue
+ if 'from' not in zone_conf:
+ continue
+ if local_zone_name in zone_conf['from']:
+ out[zone] = zone_conf['from'][local_zone_name]
+ return out
+
+def cleanup_commands():
+ commands = []
+ for table in ['ip filter', 'ip6 filter']:
+ json_str = cmd(f'nft -j list table {table}')
+ obj = loads(json_str)
+ if 'nftables' not in obj:
+ continue
+ for item in obj['nftables']:
+ if 'rule' in item:
+ chain = item['rule']['chain']
+ handle = item['rule']['handle']
+ if 'expr' not in item['rule']:
+ continue
+ for expr in item['rule']['expr']:
+ target = dict_search_args(expr, 'jump', 'target')
+ if not target:
+ continue
+ if target.startswith("VZONE") or target.startswith("VYOS_STATE_POLICY"):
+ commands.append(f'delete rule {table} {chain} handle {handle}')
+ for item in obj['nftables']:
+ if 'chain' in item:
+ if item['chain']['name'].startswith("VZONE"):
+ chain = item['chain']['name']
+ commands.append(f'delete chain {table} {chain}')
+ return commands
+
+def generate(zone_policy):
+ data = zone_policy or {}
+
+ if os.path.exists(nftables_conf): # Check to see if we've run before
+ data['cleanup_commands'] = cleanup_commands()
+
+ if 'zone' in data:
+ for zone, zone_conf in data['zone'].items():
+ zone_conf['ipv4'] = has_ipv4_fw(zone_conf)
+ zone_conf['ipv6'] = has_ipv6_fw(zone_conf)
+
+ if 'local_zone' in zone_conf:
+ zone_conf['from_local'] = get_local_from(data, zone)
+
+ render(nftables_conf, 'zone_policy/nftables.j2', data)
+ return None
+
+def apply(zone_policy):
+ install_result = run(f'nft -f {nftables_conf}')
+ if install_result != 0:
+ raise ConfigError('Failed to apply zone-policy')
+
+ return None
+
+if __name__ == '__main__':
+ try:
+ c = get_config()
+ verify(c)
+ generate(c)
+ apply(c)
+ except ConfigError as e:
+ print(e)
+ exit(1)
diff --git a/src/etc/cron.d/check-wwan b/src/etc/cron.d/check-wwan
deleted file mode 100644
index 28190776f..000000000
--- a/src/etc/cron.d/check-wwan
+++ /dev/null
@@ -1 +0,0 @@
-*/5 * * * * root /usr/libexec/vyos/vyos-check-wwan.py
diff --git a/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper b/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper
index 74a7e83bf..5d879471d 100644
--- a/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper
+++ b/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper
@@ -26,7 +26,7 @@ function iptovtysh () {
local VTYSH_GATEWAY=""
local VTYSH_DEV=""
local VTYSH_TAG="210"
- local VTYSH_DISTANCE=""
+ local VTYSH_DISTANCE=$IF_METRIC
# convert default route to 0.0.0.0/0
if [ "$4" == "default" ] ; then
VTYSH_NETADDR="0.0.0.0/0"
diff --git a/src/etc/dhcp/dhclient-enter-hooks.d/04-vyos-resolvconf b/src/etc/dhcp/dhclient-enter-hooks.d/04-vyos-resolvconf
index 24090e2a8..b1902b585 100644
--- a/src/etc/dhcp/dhclient-enter-hooks.d/04-vyos-resolvconf
+++ b/src/etc/dhcp/dhclient-enter-hooks.d/04-vyos-resolvconf
@@ -1,44 +1,48 @@
-# modified make_resolv_conf () for VyOS
-make_resolv_conf() {
- hostsd_client="/usr/bin/vyos-hostsd-client"
- hostsd_changes=
+# modified make_resolv_conf() for VyOS
+# should be used only if vyos-hostsd is running
- if [ -n "$new_domain_name" ]; then
- logmsg info "Deleting search domains with tag \"dhcp-$interface\" via vyos-hostsd-client"
- $hostsd_client --delete-search-domains --tag "dhcp-$interface"
- logmsg info "Adding domain name \"$new_domain_name\" as search domain with tag \"dhcp-$interface\" via vyos-hostsd-client"
- $hostsd_client --add-search-domains "$new_domain_name" --tag "dhcp-$interface"
- hostsd_changes=y
- fi
+if /usr/bin/systemctl -q is-active vyos-hostsd; then
+ make_resolv_conf() {
+ hostsd_client="/usr/bin/vyos-hostsd-client"
+ hostsd_changes=
- if [ -n "$new_dhcp6_domain_search" ]; then
- logmsg info "Deleting search domains with tag \"dhcpv6-$interface\" via vyos-hostsd-client"
- $hostsd_client --delete-search-domains --tag "dhcpv6-$interface"
- logmsg info "Adding search domain \"$new_dhcp6_domain_search\" with tag \"dhcpv6-$interface\" via vyos-hostsd-client"
- $hostsd_client --add-search-domains "$new_dhcp6_domain_search" --tag "dhcpv6-$interface"
- hostsd_changes=y
- fi
+ if [ -n "$new_domain_name" ]; then
+ logmsg info "Deleting search domains with tag \"dhcp-$interface\" via vyos-hostsd-client"
+ $hostsd_client --delete-search-domains --tag "dhcp-$interface"
+ logmsg info "Adding domain name \"$new_domain_name\" as search domain with tag \"dhcp-$interface\" via vyos-hostsd-client"
+ $hostsd_client --add-search-domains "$new_domain_name" --tag "dhcp-$interface"
+ hostsd_changes=y
+ fi
- if [ -n "$new_domain_name_servers" ]; then
- logmsg info "Deleting nameservers with tag \"dhcp-$interface\" via vyos-hostsd-client"
- $hostsd_client --delete-name-servers --tag "dhcp-$interface"
- logmsg info "Adding nameservers \"$new_domain_name_servers\" with tag \"dhcp-$interface\" via vyos-hostsd-client"
- $hostsd_client --add-name-servers $new_domain_name_servers --tag "dhcp-$interface"
- hostsd_changes=y
- fi
+ if [ -n "$new_dhcp6_domain_search" ]; then
+ logmsg info "Deleting search domains with tag \"dhcpv6-$interface\" via vyos-hostsd-client"
+ $hostsd_client --delete-search-domains --tag "dhcpv6-$interface"
+ logmsg info "Adding search domain \"$new_dhcp6_domain_search\" with tag \"dhcpv6-$interface\" via vyos-hostsd-client"
+ $hostsd_client --add-search-domains "$new_dhcp6_domain_search" --tag "dhcpv6-$interface"
+ hostsd_changes=y
+ fi
- if [ -n "$new_dhcp6_name_servers" ]; then
- logmsg info "Deleting nameservers with tag \"dhcpv6-$interface\" via vyos-hostsd-client"
- $hostsd_client --delete-name-servers --tag "dhcpv6-$interface"
- logmsg info "Adding nameservers \"$new_dhcpv6_name_servers\" with tag \"dhcpv6-$interface\" via vyos-hostsd-client"
- $hostsd_client --add-name-servers $new_dhcpv6_name_servers --tag "dhcpv6-$interface"
- hostsd_changes=y
- fi
+ if [ -n "$new_domain_name_servers" ]; then
+ logmsg info "Deleting nameservers with tag \"dhcp-$interface\" via vyos-hostsd-client"
+ $hostsd_client --delete-name-servers --tag "dhcp-$interface"
+ logmsg info "Adding nameservers \"$new_domain_name_servers\" with tag \"dhcp-$interface\" via vyos-hostsd-client"
+ $hostsd_client --add-name-servers $new_domain_name_servers --tag "dhcp-$interface"
+ hostsd_changes=y
+ fi
- if [ $hostsd_changes ]; then
- logmsg info "Applying changes via vyos-hostsd-client"
- $hostsd_client --apply
- else
- logmsg info "No changes to apply via vyos-hostsd-client"
- fi
-}
+ if [ -n "$new_dhcp6_name_servers" ]; then
+ logmsg info "Deleting nameservers with tag \"dhcpv6-$interface\" via vyos-hostsd-client"
+ $hostsd_client --delete-name-servers --tag "dhcpv6-$interface"
+ logmsg info "Adding nameservers \"$new_dhcpv6_name_servers\" with tag \"dhcpv6-$interface\" via vyos-hostsd-client"
+ $hostsd_client --add-name-servers $new_dhcpv6_name_servers --tag "dhcpv6-$interface"
+ hostsd_changes=y
+ fi
+
+ if [ $hostsd_changes ]; then
+ logmsg info "Applying changes via vyos-hostsd-client"
+ $hostsd_client --apply
+ else
+ logmsg info "No changes to apply via vyos-hostsd-client"
+ fi
+ }
+fi
diff --git a/src/etc/dhcp/dhclient-exit-hooks.d/01-vyos-cleanup b/src/etc/dhcp/dhclient-exit-hooks.d/01-vyos-cleanup
index fec792b64..ad6a1d5eb 100644
--- a/src/etc/dhcp/dhclient-exit-hooks.d/01-vyos-cleanup
+++ b/src/etc/dhcp/dhclient-exit-hooks.d/01-vyos-cleanup
@@ -4,14 +4,19 @@
# NOTE: here we use 'ip' wrapper, therefore a route will be actually deleted via /usr/sbin/ip or vtysh, according to the system state
hostsd_client="/usr/bin/vyos-hostsd-client"
hostsd_changes=
+# check vyos-hostsd status
+/usr/bin/systemctl -q is-active vyos-hostsd
+hostsd_status=$?
if [[ $reason =~ (EXPIRE|FAIL|RELEASE|STOP) ]]; then
- # delete search domains and nameservers via vyos-hostsd
- logmsg info "Deleting search domains with tag \"dhcp-$interface\" via vyos-hostsd-client"
- $hostsd_client --delete-search-domains --tag "dhcp-$interface"
- logmsg info "Deleting nameservers with tag \"dhcp-${interface}\" via vyos-hostsd-client"
- $hostsd_client --delete-name-servers --tag "dhcp-${interface}"
- hostsd_changes=y
+ if [[ $hostsd_status -eq 0 ]]; then
+ # delete search domains and nameservers via vyos-hostsd
+ logmsg info "Deleting search domains with tag \"dhcp-$interface\" via vyos-hostsd-client"
+ $hostsd_client --delete-search-domains --tag "dhcp-$interface"
+ logmsg info "Deleting nameservers with tag \"dhcp-${interface}\" via vyos-hostsd-client"
+ $hostsd_client --delete-name-servers --tag "dhcp-${interface}"
+ hostsd_changes=y
+ fi
if_metric="$IF_METRIC"
@@ -92,12 +97,14 @@ if [[ $reason =~ (EXPIRE|FAIL|RELEASE|STOP) ]]; then
fi
if [[ $reason =~ (EXPIRE6|RELEASE6|STOP6) ]]; then
- # delete search domains and nameservers via vyos-hostsd
- logmsg info "Deleting search domains with tag \"dhcpv6-$interface\" via vyos-hostsd-client"
- $hostsd_client --delete-search-domains --tag "dhcpv6-$interface"
- logmsg info "Deleting nameservers with tag \"dhcpv6-${interface}\" via vyos-hostsd-client"
- $hostsd_client --delete-name-servers --tag "dhcpv6-${interface}"
- hostsd_changes=y
+ if [[ $hostsd_status -eq 0 ]]; then
+ # delete search domains and nameservers via vyos-hostsd
+ logmsg info "Deleting search domains with tag \"dhcpv6-$interface\" via vyos-hostsd-client"
+ $hostsd_client --delete-search-domains --tag "dhcpv6-$interface"
+ logmsg info "Deleting nameservers with tag \"dhcpv6-${interface}\" via vyos-hostsd-client"
+ $hostsd_client --delete-name-servers --tag "dhcpv6-${interface}"
+ hostsd_changes=y
+ fi
fi
if [ $hostsd_changes ]; then
diff --git a/src/etc/logrotate.d/conntrackd b/src/etc/logrotate.d/conntrackd
new file mode 100644
index 000000000..b0b09dec1
--- /dev/null
+++ b/src/etc/logrotate.d/conntrackd
@@ -0,0 +1,9 @@
+/var/log/conntrackd-stats.log {
+ weekly
+ rotate 2
+ missingok
+
+ postrotate
+ systemctl restart conntrackd.service > /dev/null
+ endscript
+}
diff --git a/src/etc/logrotate.d/vyos-rsyslog b/src/etc/logrotate.d/vyos-rsyslog
new file mode 100644
index 000000000..3c087b94e
--- /dev/null
+++ b/src/etc/logrotate.d/vyos-rsyslog
@@ -0,0 +1,12 @@
+/var/log/messages {
+ create
+ missingok
+ nomail
+ notifempty
+ rotate 10
+ size 1M
+ postrotate
+ # inform rsyslog service about rotation
+ /usr/lib/rsyslog/rsyslog-rotate
+ endscript
+}
diff --git a/src/etc/ppp/ip-up.d/99-vyos-pppoe-callback b/src/etc/ppp/ip-up.d/99-vyos-pppoe-callback
index bb918a468..fa1917ab1 100755
--- a/src/etc/ppp/ip-up.d/99-vyos-pppoe-callback
+++ b/src/etc/ppp/ip-up.d/99-vyos-pppoe-callback
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -23,14 +23,9 @@
from sys import argv
from sys import exit
-from syslog import syslog
-from syslog import openlog
-from syslog import LOG_PID
-from syslog import LOG_INFO
-
from vyos.configquery import ConfigTreeQuery
+from vyos.configdict import get_interface_dict
from vyos.ifconfig import PPPoEIf
-from vyos.util import read_file
# When the ppp link comes up, this script is called with the following
# parameters
@@ -45,15 +40,10 @@ if (len(argv) < 7):
exit(1)
interface = argv[6]
-dialer_pid = read_file(f'/var/run/{interface}.pid')
-
-openlog(ident=f'pppd[{dialer_pid}]', facility=LOG_INFO)
-syslog('executing ' + argv[0])
conf = ConfigTreeQuery()
-pppoe = conf.get_config_dict(['interfaces', 'pppoe', argv[6]],
- get_first_key=True, key_mangling=('-', '_'))
-pppoe['ifname'] = argv[6]
+_, pppoe = get_interface_dict(conf.config, ['interfaces', 'pppoe'], interface)
-p = PPPoEIf(pppoe['ifname'])
+# Update the config
+p = PPPoEIf(interface)
p.update(pppoe)
diff --git a/src/etc/systemd/system/keepalived.service.d/override.conf b/src/etc/systemd/system/keepalived.service.d/override.conf
deleted file mode 100644
index 1c68913f2..000000000
--- a/src/etc/systemd/system/keepalived.service.d/override.conf
+++ /dev/null
@@ -1,13 +0,0 @@
-[Unit]
-ConditionPathExists=
-ConditionPathExists=/run/keepalived/keepalived.conf
-After=
-After=vyos-router.service
-
-[Service]
-KillMode=process
-EnvironmentFile=
-ExecStart=
-ExecStart=/usr/sbin/keepalived --use-file /run/keepalived/keepalived.conf --pid /run/keepalived/keepalived.pid --dont-fork --snmp
-PIDFile=
-PIDFile=/run/keepalived/keepalived.pid
diff --git a/src/etc/telegraf/custom_scripts/show_firewall_input_filter.py b/src/etc/telegraf/custom_scripts/show_firewall_input_filter.py
new file mode 100755
index 000000000..bf4bfd05d
--- /dev/null
+++ b/src/etc/telegraf/custom_scripts/show_firewall_input_filter.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python3
+
+import json
+import re
+import time
+
+from vyos.util import cmd
+
+
+def get_nft_filter_chains():
+ """
+ Get list of nft chains for table filter
+ """
+ nft = cmd('/usr/sbin/nft --json list table ip filter')
+ nft = json.loads(nft)
+ chain_list = []
+
+ for output in nft['nftables']:
+ if 'chain' in output:
+ chain = output['chain']['name']
+ chain_list.append(chain)
+
+ return chain_list
+
+
+def get_nftables_details(name):
+ """
+ Get dict, counters packets and bytes for chain
+ """
+ command = f'/usr/sbin/nft list chain ip filter {name}'
+ try:
+ results = cmd(command)
+ except:
+ return {}
+
+ # Trick to remove 'NAME_' from chain name in the comment
+ # It was added to any chain T4218
+ # counter packets 0 bytes 0 return comment "FOO default-action accept"
+ comment_name = name.replace("NAME_", "")
+ out = {}
+ for line in results.split('\n'):
+ comment_search = re.search(rf'{comment_name}[\- ](\d+|default-action)', line)
+ if not comment_search:
+ continue
+
+ rule = {}
+ rule_id = comment_search[1]
+ counter_search = re.search(r'counter packets (\d+) bytes (\d+)', line)
+ if counter_search:
+ rule['packets'] = counter_search[1]
+ rule['bytes'] = counter_search[2]
+
+ rule['conditions'] = re.sub(r'(\b(counter packets \d+ bytes \d+|drop|reject|return|log)\b|comment "[\w\-]+")', '', line).strip()
+ out[rule_id] = rule
+ return out
+
+
+def get_nft_telegraf(name):
+ """
+ Get data for telegraf in influxDB format
+ """
+ for rule, rule_config in get_nftables_details(name).items():
+ print(f'nftables,table=filter,chain={name},'
+ f'ruleid={rule} '
+ f'pkts={rule_config["packets"]}i,'
+ f'bytes={rule_config["bytes"]}i '
+ f'{str(int(time.time()))}000000000')
+
+
+chains = get_nft_filter_chains()
+
+for chain in chains:
+ get_nft_telegraf(chain)
diff --git a/src/etc/telegraf/custom_scripts/show_interfaces_input_filter.py b/src/etc/telegraf/custom_scripts/show_interfaces_input_filter.py
new file mode 100755
index 000000000..0c7474156
--- /dev/null
+++ b/src/etc/telegraf/custom_scripts/show_interfaces_input_filter.py
@@ -0,0 +1,88 @@
+#!/usr/bin/env python3
+
+from vyos.ifconfig import Section
+from vyos.ifconfig import Interface
+
+import time
+
+def get_interfaces(type='', vlan=True):
+ """
+ Get interfaces:
+ ['dum0', 'eth0', 'eth1', 'eth1.5', 'lo', 'tun0']
+ """
+ interfaces = []
+ ifaces = Section.interfaces(type)
+ for iface in ifaces:
+ if vlan == False and '.' in iface:
+ continue
+ interfaces.append(iface)
+
+ return interfaces
+
+def get_interface_addresses(iface, link_local_v6=False):
+ """
+ Get IP and IPv6 addresses from interface in one string
+ By default don't get IPv6 link-local addresses
+ If interface doesn't have address, return "-"
+ """
+ addresses = []
+ addrs = Interface(iface).get_addr()
+
+ for addr in addrs:
+ if link_local_v6 == False:
+ if addr.startswith('fe80::'):
+ continue
+ addresses.append(addr)
+
+ if not addresses:
+ return "-"
+
+ return (" ".join(addresses))
+
+def get_interface_description(iface):
+ """
+ Get interface description
+ If none return "empty"
+ """
+ description = Interface(iface).get_alias()
+
+ if not description:
+ return "empty"
+
+ return description
+
+def get_interface_admin_state(iface):
+ """
+ Interface administrative state
+ up => 0, down => 2
+ """
+ state = Interface(iface).get_admin_state()
+ if state == 'up':
+ admin_state = 0
+ if state == 'down':
+ admin_state = 2
+
+ return admin_state
+
+def get_interface_oper_state(iface):
+ """
+ Interface operational state
+ up => 0, down => 1
+ """
+ state = Interface(iface).operational.get_state()
+ if state == 'down':
+ oper_state = 1
+ else:
+ oper_state = 0
+
+ return oper_state
+
+interfaces = get_interfaces()
+
+for iface in interfaces:
+ print(f'show_interfaces,interface={iface} '
+ f'ip_addresses="{get_interface_addresses(iface)}",'
+ f'state={get_interface_admin_state(iface)}i,'
+ f'link={get_interface_oper_state(iface)}i,'
+ f'description="{get_interface_description(iface)}" '
+ f'{str(int(time.time()))}000000000')
diff --git a/src/etc/telegraf/custom_scripts/vyos_services_input_filter.py b/src/etc/telegraf/custom_scripts/vyos_services_input_filter.py
new file mode 100755
index 000000000..df4eed131
--- /dev/null
+++ b/src/etc/telegraf/custom_scripts/vyos_services_input_filter.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+import time
+from vyos.configquery import ConfigTreeQuery
+from vyos.util import is_systemd_service_running, process_named_running
+
+# Availible services and prouceses
+# 1 - service
+# 2 - process
+services = {
+ "protocols bgp" : "bgpd",
+ "protocols ospf" : "ospfd",
+ "protocols ospfv3" : "ospf6d",
+ "protocols rip" : "ripd",
+ "protocols ripng" : "ripngd",
+ "protocols isis" : "isisd",
+ "service pppoe" : "accel-ppp@pppoe.service",
+ "vpn l2tp remote-access" : "accel-ppp@l2tp.service",
+ "vpn pptp remote-access" : "accel-ppp@pptp.service",
+ "vpn sstp" : "accel-ppp@sstp.service",
+ "vpn ipsec" : "charon"
+}
+
+# Configured services
+conf_services = {
+ 'zebra' : 0,
+ 'staticd' : 0,
+}
+# Get configured service and create list to check if process running
+config = ConfigTreeQuery()
+for service in services:
+ if config.exists(service):
+ conf_services[services[service]] = 0
+
+for conf_service in conf_services:
+ status = 0
+ if ".service" in conf_service:
+ # Check systemd service
+ if is_systemd_service_running(conf_service):
+ status = 1
+ else:
+ # Check process
+ if process_named_running(conf_service):
+ status = 1
+ print(f'vyos_services,service="{conf_service}" '
+ f'status={str(status)}i {str(int(time.time()))}000000000')
diff --git a/src/helpers/strip-private.py b/src/helpers/strip-private.py
index e4e1fe11d..eb584edaf 100755
--- a/src/helpers/strip-private.py
+++ b/src/helpers/strip-private.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-# Copyright 2021 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright 2021-2022 VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -111,6 +111,10 @@ if __name__ == "__main__":
(True, re.compile(r'public-keys \S+'), 'public-keys xxxx@xxx.xxx'),
(True, re.compile(r'type \'ssh-(rsa|dss)\''), 'type ssh-xxx'),
(True, re.compile(r' key \S+'), ' key xxxxxx'),
+ # Strip bucket
+ (True, re.compile(r' bucket \S+'), ' bucket xxxxxx'),
+ # Strip tokens
+ (True, re.compile(r' token \S+'), ' token xxxxxx'),
# Strip OpenVPN secrets
(True, re.compile(r'(shared-secret-key-file|ca-cert-file|cert-file|dh-file|key-file|client) (\S+)'), r'\1 xxxxxx'),
# Strip IPSEC secrets
@@ -123,8 +127,8 @@ if __name__ == "__main__":
# Strip MAC addresses
(args.mac, re.compile(r'([0-9a-fA-F]{2}\:){5}([0-9a-fA-F]{2}((\:{0,1})){3})'), r'xx:xx:xx:xx:xx:\2'),
- # Strip host-name, domain-name, and domain-search
- (args.hostname, re.compile(r'(host-name|domain-name|domain-search) \S+'), r'\1 xxxxxx'),
+ # Strip host-name, domain-name, domain-search and url
+ (args.hostname, re.compile(r'(host-name|domain-name|domain-search|url) \S+'), r'\1 xxxxxx'),
# Strip user-names
(args.username, re.compile(r'(user|username|user-id) \S+'), r'\1 xxxxxx'),
diff --git a/src/helpers/system-versions-foot.py b/src/helpers/system-versions-foot.py
index c33e41d79..2aa687221 100755
--- a/src/helpers/system-versions-foot.py
+++ b/src/helpers/system-versions-foot.py
@@ -21,7 +21,7 @@ import vyos.systemversions as systemversions
import vyos.defaults
import vyos.version
-sys_versions = systemversions.get_system_versions()
+sys_versions = systemversions.get_system_component_version()
component_string = formatversions.format_versions_string(sys_versions)
diff --git a/src/helpers/vyos-boot-config-loader.py b/src/helpers/vyos-boot-config-loader.py
index c5bf22f10..b9cc87bfa 100755
--- a/src/helpers/vyos-boot-config-loader.py
+++ b/src/helpers/vyos-boot-config-loader.py
@@ -23,12 +23,12 @@ import grp
import traceback
from datetime import datetime
-from vyos.defaults import directories
+from vyos.defaults import directories, config_status
from vyos.configsession import ConfigSession, ConfigSessionError
from vyos.configtree import ConfigTree
from vyos.util import cmd
-STATUS_FILE = '/tmp/vyos-config-status'
+STATUS_FILE = config_status
TRACE_FILE = '/tmp/boot-config-trace'
CFG_GROUP = 'vyattacfg'
diff --git a/src/helpers/vyos-check-wwan.py b/src/helpers/vyos-check-wwan.py
index c6e6c54b7..2ff9a574f 100755
--- a/src/helpers/vyos-check-wwan.py
+++ b/src/helpers/vyos-check-wwan.py
@@ -18,7 +18,6 @@ from vyos.configquery import VbashOpRun
from vyos.configquery import ConfigTreeQuery
from vyos.util import is_wwan_connected
-from vyos.util import call
conf = ConfigTreeQuery()
dict = conf.get_config_dict(['interfaces', 'wwan'], key_mangling=('-', '_'),
@@ -30,8 +29,7 @@ for interface, interface_config in dict.items():
# do not restart this interface as it's disabled by the user
continue
- #op = VbashOpRun()
- #op.run(['connect', 'interface', interface])
- call(f'VYOS_TAGNODE_VALUE={interface} /usr/libexec/vyos/conf_mode/interfaces-wwan.py')
+ op = VbashOpRun()
+ op.run(['connect', 'interface', interface])
exit(0)
diff --git a/src/helpers/vyos-vrrp-conntracksync.sh b/src/helpers/vyos-vrrp-conntracksync.sh
index 4501aa63e..0cc718938 100755
--- a/src/helpers/vyos-vrrp-conntracksync.sh
+++ b/src/helpers/vyos-vrrp-conntracksync.sh
@@ -14,12 +14,10 @@
# Modified by : Mohit Mehta <mohit@vyatta.com>
# Slight modifications were made to this script for running with Vyatta
# The original script came from 0.9.14 debian conntrack-tools package
-#
-#
CONNTRACKD_BIN=/usr/sbin/conntrackd
CONNTRACKD_LOCK=/var/lock/conntrack.lock
-CONNTRACKD_CONFIG=/etc/conntrackd/conntrackd.conf
+CONNTRACKD_CONFIG=/run/conntrackd/conntrackd.conf
FACILITY=daemon
LEVEL=notice
TAG=conntrack-tools
@@ -29,6 +27,10 @@ FAILOVER_STATE="/var/run/vyatta-conntrackd-failover-state"
$LOGCMD "vyatta-vrrp-conntracksync invoked at `date`"
+if ! systemctl is-active --quiet conntrackd.service; then
+ echo "conntrackd service not running"
+ exit 1
+fi
if [ ! -e $FAILOVER_STATE ]; then
mkdir -p /var/run
diff --git a/src/helpers/vyos_net_name b/src/helpers/vyos_net_name
index e21d8c9ff..1798e92db 100755
--- a/src/helpers/vyos_net_name
+++ b/src/helpers/vyos_net_name
@@ -20,19 +20,20 @@ import os
import re
import time
import logging
+import tempfile
import threading
from sys import argv
from vyos.configtree import ConfigTree
from vyos.defaults import directories
-from vyos.util import cmd
+from vyos.util import cmd, boot_configuration_complete
+from vyos.migrator import VirtualMigrator
vyos_udev_dir = directories['vyos_udev_dir']
vyos_log_dir = '/run/udev/log'
vyos_log_file = os.path.join(vyos_log_dir, 'vyos-net-name')
config_path = '/opt/vyatta/etc/config/config.boot'
-config_status = '/tmp/vyos-config-status'
lock = threading.Lock()
@@ -43,13 +44,6 @@ except FileExistsError:
logging.basicConfig(filename=vyos_log_file, level=logging.DEBUG)
-def boot_configuration_complete() -> bool:
- """ Check if vyos-router has completed, hence hotplug event
- """
- if os.path.isfile(config_status):
- return True
- return False
-
def is_available(intfs: dict, intf_name: str) -> bool:
""" Check if interface name is already assigned
"""
@@ -147,14 +141,20 @@ def get_configfile_interfaces() -> dict:
try:
config = ConfigTree(config_file)
except Exception:
- logging.debug(f"updating component version string syntax")
try:
- # this will update the component version string in place, for
- # updates 1.2 --> 1.3/1.4
- os.system(f'/usr/libexec/vyos/run-config-migration.py {config_path} --virtual --set-vintage=vyos')
- with open(config_path) as f:
- config_file = f.read()
+ logging.debug(f"updating component version string syntax")
+ # this will update the component version string syntax,
+ # required for updates 1.2 --> 1.3/1.4
+ with tempfile.NamedTemporaryFile() as fp:
+ with open(fp.name, 'w') as fd:
+ fd.write(config_file)
+ virtual_migration = VirtualMigrator(fp.name)
+ virtual_migration.run()
+ with open(fp.name) as fd:
+ config_file = fd.read()
+
config = ConfigTree(config_file)
+
except Exception as e:
logging.critical(f"ConfigTree error: {e}")
@@ -254,4 +254,3 @@ if not boot_configuration_complete():
else:
logging.debug("boot configuration complete")
lock.release()
-
diff --git a/src/migration-scripts/bgp/0-to-1 b/src/migration-scripts/bgp/0-to-1
index b1d5a6514..5e9dffe1f 100755
--- a/src/migration-scripts/bgp/0-to-1
+++ b/src/migration-scripts/bgp/0-to-1
@@ -33,7 +33,7 @@ with open(file_name, 'r') as f:
base = ['protocols', 'bgp']
config = ConfigTree(config_file)
-if not config.exists(base):
+if not config.exists(base) or not config.is_tag(base):
# Nothing to do
exit(0)
diff --git a/src/migration-scripts/bgp/1-to-2 b/src/migration-scripts/bgp/1-to-2
index 4c6d5ceb8..e2d3fcd33 100755
--- a/src/migration-scripts/bgp/1-to-2
+++ b/src/migration-scripts/bgp/1-to-2
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -20,7 +20,6 @@ from sys import argv
from sys import exit
from vyos.configtree import ConfigTree
-from vyos.template import is_ipv4
if (len(argv) < 1):
print("Must specify file name!")
@@ -51,23 +50,21 @@ if config.exists(base + ['parameters', 'default', 'no-ipv4-unicast']):
# Check if the "default" node is now empty, if so - remove it
if len(config.list_nodes(base + ['parameters'])) == 0:
config.delete(base + ['parameters'])
+else:
+ # As we now install a new default option into BGP we need to migrate all
+ # existing BGP neighbors and restore the old behavior
+ if config.exists(base + ['neighbor']):
+ for neighbor in config.list_nodes(base + ['neighbor']):
+ peer_group = base + ['neighbor', neighbor, 'peer-group']
+ if config.exists(peer_group):
+ peer_group_name = config.return_value(peer_group)
+ # peer group enables old behavior for neighbor - bail out
+ if config.exists(base + ['peer-group', peer_group_name, 'address-family', 'ipv4-unicast']):
+ continue
- exit(0)
-
-# As we now install a new default option into BGP we need to migrate all
-# existing BGP neighbors and restore the old behavior
-if config.exists(base + ['neighbor']):
- for neighbor in config.list_nodes(base + ['neighbor']):
- peer_group = base + ['neighbor', neighbor, 'peer-group']
- if config.exists(peer_group):
- peer_group_name = config.return_value(peer_group)
- # peer group enables old behavior for neighbor - bail out
- if config.exists(base + ['peer-group', peer_group_name, 'address-family', 'ipv4-unicast']):
- continue
-
- afi_ipv4 = base + ['neighbor', neighbor, 'address-family', 'ipv4-unicast']
- if not config.exists(afi_ipv4):
- config.set(afi_ipv4)
+ afi_ipv4 = base + ['neighbor', neighbor, 'address-family', 'ipv4-unicast']
+ if not config.exists(afi_ipv4):
+ config.set(afi_ipv4)
try:
with open(file_name, 'w') as f:
diff --git a/src/migration-scripts/dns-forwarding/1-to-2 b/src/migration-scripts/dns-forwarding/1-to-2
index ba10c26f2..a8c930be7 100755
--- a/src/migration-scripts/dns-forwarding/1-to-2
+++ b/src/migration-scripts/dns-forwarding/1-to-2
@@ -16,7 +16,7 @@
#
# This migration script will remove the deprecated 'listen-on' statement
-# from the dns forwarding service and will add the corresponding
+# from the dns forwarding service and will add the corresponding
# listen-address nodes instead. This is required as PowerDNS can only listen
# on interface addresses and not on interface names.
@@ -37,53 +37,50 @@ with open(file_name, 'r') as f:
config = ConfigTree(config_file)
base = ['service', 'dns', 'forwarding']
-if not config.exists(base):
+if not config.exists(base + ['listen-on']):
# Nothing to do
exit(0)
-if config.exists(base + ['listen-on']):
- listen_intf = config.return_values(base + ['listen-on'])
- # Delete node with abandoned command
- config.delete(base + ['listen-on'])
+listen_intf = config.return_values(base + ['listen-on'])
+# Delete node with abandoned command
+config.delete(base + ['listen-on'])
- # retrieve interface addresses for every configured listen-on interface
- listen_addr = []
- for intf in listen_intf:
- # we need to evaluate the interface section before manipulating the 'intf' variable
- section = Interface.section(intf)
- if not section:
- raise ValueError(f'Invalid interface name {intf}')
+# retrieve interface addresses for every configured listen-on interface
+listen_addr = []
+for intf in listen_intf:
+ # we need to evaluate the interface section before manipulating the 'intf' variable
+ section = Interface.section(intf)
+ if not section:
+ raise ValueError(f'Invalid interface name {intf}')
- # we need to treat vif and vif-s interfaces differently,
- # both "real interfaces" use dots for vlan identifiers - those
- # need to be exchanged with vif and vif-s identifiers
- if intf.count('.') == 1:
- # this is a regular VLAN interface
- intf = intf.split('.')[0] + ' vif ' + intf.split('.')[1]
- elif intf.count('.') == 2:
- # this is a QinQ VLAN interface
- intf = intf.split('.')[0] + ' vif-s ' + intf.split('.')[1] + ' vif-c ' + intf.split('.')[2]
-
- # retrieve corresponding interface addresses in CIDR format
- # those need to be converted in pure IP addresses without network information
- path = ['interfaces', section, intf, 'address']
- try:
- for addr in config.return_values(path):
- listen_addr.append( ip_interface(addr).ip )
- except:
- # Some interface types do not use "address" option (e.g. OpenVPN)
- # and may not even have a fixed address
- print("Could not retrieve the address of the interface {} from the config".format(intf))
- print("You will need to update your DNS forwarding configuration manually")
-
- for addr in listen_addr:
- config.set(base + ['listen-address'], value=addr, replace=False)
+ # we need to treat vif and vif-s interfaces differently,
+ # both "real interfaces" use dots for vlan identifiers - those
+ # need to be exchanged with vif and vif-s identifiers
+ if intf.count('.') == 1:
+ # this is a regular VLAN interface
+ intf = intf.split('.')[0] + ' vif ' + intf.split('.')[1]
+ elif intf.count('.') == 2:
+ # this is a QinQ VLAN interface
+ intf = intf.split('.')[0] + ' vif-s ' + intf.split('.')[1] + ' vif-c ' + intf.split('.')[2]
+ # retrieve corresponding interface addresses in CIDR format
+ # those need to be converted in pure IP addresses without network information
+ path = ['interfaces', section, intf, 'address']
try:
- with open(file_name, 'w') as f:
- f.write(config.to_string())
- except OSError as e:
- print("Failed to save the modified config: {}".format(e))
- exit(1)
+ for addr in config.return_values(path):
+ listen_addr.append( ip_interface(addr).ip )
+ except:
+ # Some interface types do not use "address" option (e.g. OpenVPN)
+ # and may not even have a fixed address
+ print("Could not retrieve the address of the interface {} from the config".format(intf))
+ print("You will need to update your DNS forwarding configuration manually")
-exit(0)
+for addr in listen_addr:
+ config.set(base + ['listen-address'], value=addr, replace=False)
+
+try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+except OSError as e:
+ print(f'Failed to save the modified config: {e}')
+ exit(1)
diff --git a/src/migration-scripts/firewall/6-to-7 b/src/migration-scripts/firewall/6-to-7
new file mode 100755
index 000000000..5f4cff90d
--- /dev/null
+++ b/src/migration-scripts/firewall/6-to-7
@@ -0,0 +1,226 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# T2199: Remove unavailable nodes due to XML/Python implementation using nftables
+# monthdays: nftables does not have a monthdays equivalent
+# utc: nftables userspace uses localtime and calculates the UTC offset automatically
+# icmp/v6: migrate previously available `type-name` to valid type/code
+# T4178: Update tcp flags to use multi value node
+
+import re
+
+from sys import argv
+from sys import exit
+
+from vyos.configtree import ConfigTree
+from vyos.ifconfig import Section
+
+if (len(argv) < 1):
+ print("Must specify file name!")
+ exit(1)
+
+file_name = argv[1]
+
+with open(file_name, 'r') as f:
+ config_file = f.read()
+
+base = ['firewall']
+config = ConfigTree(config_file)
+
+if not config.exists(base):
+ # Nothing to do
+ exit(0)
+
+icmp_remove = ['any']
+icmp_translations = {
+ 'ping': 'echo-request',
+ 'pong': 'echo-reply',
+ 'ttl-exceeded': 'time-exceeded',
+ # Network Unreachable
+ 'network-unreachable': [3, 0],
+ 'host-unreachable': [3, 1],
+ 'protocol-unreachable': [3, 2],
+ 'port-unreachable': [3, 3],
+ 'fragmentation-needed': [3, 4],
+ 'source-route-failed': [3, 5],
+ 'network-unknown': [3, 6],
+ 'host-unknown': [3, 7],
+ 'network-prohibited': [3, 9],
+ 'host-prohibited': [3, 10],
+ 'TOS-network-unreachable': [3, 11],
+ 'TOS-host-unreachable': [3, 12],
+ 'communication-prohibited': [3, 13],
+ 'host-precedence-violation': [3, 14],
+ 'precedence-cutoff': [3, 15],
+ # Redirect
+ 'network-redirect': [5, 0],
+ 'host-redirect': [5, 1],
+ 'TOS-network-redirect': [5, 2],
+ 'TOS host-redirect': [5, 3],
+ # Time Exceeded
+ 'ttl-zero-during-transit': [11, 0],
+ 'ttl-zero-during-reassembly': [11, 1],
+ # Parameter Problem
+ 'ip-header-bad': [12, 0],
+ 'required-option-missing': [12, 1]
+}
+
+icmpv6_remove = []
+icmpv6_translations = {
+ 'ping': 'echo-request',
+ 'pong': 'echo-reply',
+ # Destination Unreachable
+ 'no-route': [1, 0],
+ 'communication-prohibited': [1, 1],
+ 'address-unreachble': [1, 3],
+ 'port-unreachable': [1, 4],
+ # Redirect
+ 'redirect': 'nd-redirect',
+ # Time Exceeded
+ 'ttl-zero-during-transit': [3, 0],
+ 'ttl-zero-during-reassembly': [3, 1],
+ # Parameter Problem
+ 'bad-header': [4, 0],
+ 'unknown-header-type': [4, 1],
+ 'unknown-option': [4, 2]
+}
+
+if config.exists(base + ['name']):
+ for name in config.list_nodes(base + ['name']):
+ if not config.exists(base + ['name', name, 'rule']):
+ continue
+
+ for rule in config.list_nodes(base + ['name', name, 'rule']):
+ rule_recent = base + ['name', name, 'rule', rule, 'recent']
+ rule_time = base + ['name', name, 'rule', rule, 'time']
+ rule_tcp_flags = base + ['name', name, 'rule', rule, 'tcp', 'flags']
+ rule_icmp = base + ['name', name, 'rule', rule, 'icmp']
+
+ if config.exists(rule_time + ['monthdays']):
+ config.delete(rule_time + ['monthdays'])
+
+ if config.exists(rule_time + ['utc']):
+ config.delete(rule_time + ['utc'])
+
+ if config.exists(rule_recent + ['time']):
+ tmp = int(config.return_value(rule_recent + ['time']))
+ unit = 'minute'
+ if tmp > 600:
+ unit = 'hour'
+ elif tmp < 10:
+ unit = 'second'
+ config.set(rule_recent + ['time'], value=unit)
+
+ if config.exists(rule_tcp_flags):
+ tmp = config.return_value(rule_tcp_flags)
+ config.delete(rule_tcp_flags)
+ for flag in tmp.split(","):
+ if flag[0] == '!':
+ config.set(rule_tcp_flags + ['not', flag[1:].lower()])
+ else:
+ config.set(rule_tcp_flags + [flag.lower()])
+
+ if config.exists(rule_icmp + ['type-name']):
+ tmp = config.return_value(rule_icmp + ['type-name'])
+ if tmp in icmp_remove:
+ config.delete(rule_icmp + ['type-name'])
+ elif tmp in icmp_translations:
+ translate = icmp_translations[tmp]
+ if isinstance(translate, str):
+ config.set(rule_icmp + ['type-name'], value=translate)
+ elif isinstance(translate, list):
+ config.delete(rule_icmp + ['type-name'])
+ config.set(rule_icmp + ['type'], value=translate[0])
+ config.set(rule_icmp + ['code'], value=translate[1])
+
+ for src_dst in ['destination', 'source']:
+ pg_base = base + ['name', name, 'rule', rule, src_dst, 'group', 'port-group']
+ proto_base = base + ['name', name, 'rule', rule, 'protocol']
+ if config.exists(pg_base) and not config.exists(proto_base):
+ config.set(proto_base, value='tcp_udp')
+
+if config.exists(base + ['ipv6-name']):
+ for name in config.list_nodes(base + ['ipv6-name']):
+ if not config.exists(base + ['ipv6-name', name, 'rule']):
+ continue
+
+ for rule in config.list_nodes(base + ['ipv6-name', name, 'rule']):
+ rule_recent = base + ['ipv6-name', name, 'rule', rule, 'recent']
+ rule_time = base + ['ipv6-name', name, 'rule', rule, 'time']
+ rule_tcp_flags = base + ['ipv6-name', name, 'rule', rule, 'tcp', 'flags']
+ rule_icmp = base + ['ipv6-name', name, 'rule', rule, 'icmpv6']
+
+ if config.exists(rule_time + ['monthdays']):
+ config.delete(rule_time + ['monthdays'])
+
+ if config.exists(rule_time + ['utc']):
+ config.delete(rule_time + ['utc'])
+
+ if config.exists(rule_recent + ['time']):
+ tmp = int(config.return_value(rule_recent + ['time']))
+ unit = 'minute'
+ if tmp > 600:
+ unit = 'hour'
+ elif tmp < 10:
+ unit = 'second'
+ config.set(rule_recent + ['time'], value=unit)
+
+ if config.exists(rule_tcp_flags):
+ tmp = config.return_value(rule_tcp_flags)
+ config.delete(rule_tcp_flags)
+ for flag in tmp.split(","):
+ if flag[0] == '!':
+ config.set(rule_tcp_flags + ['not', flag[1:].lower()])
+ else:
+ config.set(rule_tcp_flags + [flag.lower()])
+
+ if config.exists(base + ['ipv6-name', name, 'rule', rule, 'protocol']):
+ tmp = config.return_value(base + ['ipv6-name', name, 'rule', rule, 'protocol'])
+ if tmp == 'icmpv6':
+ config.set(base + ['ipv6-name', name, 'rule', rule, 'protocol'], value='ipv6-icmp')
+
+ if config.exists(rule_icmp + ['type']):
+ tmp = config.return_value(rule_icmp + ['type'])
+ type_code_match = re.match(r'^(\d+)/(\d+)$', tmp)
+
+ if type_code_match:
+ config.set(rule_icmp + ['type'], value=type_code_match[1])
+ config.set(rule_icmp + ['code'], value=type_code_match[2])
+ elif tmp in icmpv6_remove:
+ config.delete(rule_icmp + ['type'])
+ elif tmp in icmpv6_translations:
+ translate = icmpv6_translations[tmp]
+ if isinstance(translate, str):
+ config.delete(rule_icmp + ['type'])
+ config.set(rule_icmp + ['type-name'], value=translate)
+ elif isinstance(translate, list):
+ config.set(rule_icmp + ['type'], value=translate[0])
+ config.set(rule_icmp + ['code'], value=translate[1])
+ else:
+ config.rename(rule_icmp + ['type'], 'type-name')
+
+ for src_dst in ['destination', 'source']:
+ pg_base = base + ['ipv6-name', name, 'rule', rule, src_dst, 'group', 'port-group']
+ proto_base = base + ['ipv6-name', name, 'rule', rule, 'protocol']
+ if config.exists(pg_base) and not config.exists(proto_base):
+ config.set(proto_base, value='tcp_udp')
+
+try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+except OSError as e:
+ print("Failed to save the modified config: {}".format(e))
+ exit(1)
diff --git a/src/migration-scripts/flow-accounting/0-to-1 b/src/migration-scripts/flow-accounting/0-to-1
new file mode 100755
index 000000000..72cce77b0
--- /dev/null
+++ b/src/migration-scripts/flow-accounting/0-to-1
@@ -0,0 +1,69 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# T4099: flow-accounting: sync "source-ip" and "source-address" between netflow
+# and sflow ion CLI
+# T4105: flow-accounting: drop "sflow agent-address auto"
+
+from sys import argv
+from vyos.configtree import ConfigTree
+
+if (len(argv) < 1):
+ print("Must specify file name!")
+ exit(1)
+
+file_name = argv[1]
+
+with open(file_name, 'r') as f:
+ config_file = f.read()
+
+base = ['system', 'flow-accounting']
+config = ConfigTree(config_file)
+
+if not config.exists(base):
+ # Nothing to do
+ exit(0)
+
+# T4099
+tmp = base + ['netflow', 'source-ip']
+if config.exists(tmp):
+ config.rename(tmp, 'source-address')
+
+# T4105
+tmp = base + ['sflow', 'agent-address']
+if config.exists(tmp):
+ value = config.return_value(tmp)
+ if value == 'auto':
+ # delete the "auto"
+ config.delete(tmp)
+
+ # 1) check if BGP router-id is set
+ # 2) check if OSPF router-id is set
+ # 3) check if OSPFv3 router-id is set
+ router_id = None
+ for protocol in ['bgp', 'ospf', 'ospfv3']:
+ if config.exists(['protocols', protocol, 'parameters', 'router-id']):
+ router_id = config.return_value(['protocols', protocol, 'parameters', 'router-id'])
+ break
+ if router_id:
+ config.set(tmp, value=router_id)
+
+try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+except OSError as e:
+ print("Failed to save the modified config: {}".format(e))
+ exit(1)
diff --git a/src/migration-scripts/interfaces/25-to-26 b/src/migration-scripts/interfaces/25-to-26
new file mode 100755
index 000000000..a8936235e
--- /dev/null
+++ b/src/migration-scripts/interfaces/25-to-26
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# T4384: pppoe: replace default-route CLI option with common CLI nodes already
+# present for DHCP
+
+from sys import argv
+
+from vyos.ethtool import Ethtool
+from vyos.configtree import ConfigTree
+
+if (len(argv) < 1):
+ print("Must specify file name!")
+ exit(1)
+
+file_name = argv[1]
+with open(file_name, 'r') as f:
+ config_file = f.read()
+
+base = ['interfaces', 'pppoe']
+config = ConfigTree(config_file)
+
+if not config.exists(base):
+ exit(0)
+
+for ifname in config.list_nodes(base):
+ tmp_config = base + [ifname, 'default-route']
+ if config.exists(tmp_config):
+ # Retrieve current config value
+ value = config.return_value(tmp_config)
+ # Delete old Config node
+ config.delete(tmp_config)
+ if value == 'none':
+ config.set(base + [ifname, 'no-default-route'])
+
+try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+except OSError as e:
+ print(f'Failed to save the modified config: {e}')
+ exit(1)
diff --git a/src/migration-scripts/ipsec/8-to-9 b/src/migration-scripts/ipsec/8-to-9
new file mode 100755
index 000000000..eb44b6216
--- /dev/null
+++ b/src/migration-scripts/ipsec/8-to-9
@@ -0,0 +1,48 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+from sys import argv
+from sys import exit
+
+from vyos.configtree import ConfigTree
+
+if (len(argv) < 1):
+ print("Must specify file name!")
+ exit(1)
+
+file_name = argv[1]
+
+with open(file_name, 'r') as f:
+ config_file = f.read()
+
+base = ['vpn', 'ipsec', 'ike-group']
+config = ConfigTree(config_file)
+
+if not config.exists(base):
+ # Nothing to do
+ exit(0)
+else:
+ for ike_group in config.list_nodes(base):
+ base_closeaction = base + [ike_group, 'close-action']
+ if config.exists(base_closeaction) and config.return_value(base_closeaction) == 'clear':
+ config.set(base_closeaction, 'none', replace=True)
+
+try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+except OSError as e:
+ print(f'Failed to save the modified config: {e}')
+ exit(1)
diff --git a/src/migration-scripts/openconnect/1-to-2 b/src/migration-scripts/openconnect/1-to-2
new file mode 100755
index 000000000..7031fb252
--- /dev/null
+++ b/src/migration-scripts/openconnect/1-to-2
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Delete depricated outside-nexthop address
+
+import sys
+
+from vyos.configtree import ConfigTree
+
+if (len(sys.argv) < 1):
+ print("Must specify file name!")
+ sys.exit(1)
+
+file_name = sys.argv[1]
+
+with open(file_name, 'r') as f:
+ config_file = f.read()
+
+config = ConfigTree(config_file)
+
+cfg_base = ['vpn', 'openconnect']
+
+if not config.exists(cfg_base):
+ # Nothing to do
+ sys.exit(0)
+else:
+ if config.exists(cfg_base + ['authentication', 'mode']):
+ if config.return_value(cfg_base + ['authentication', 'mode']) == 'radius':
+ # if "mode value radius", change to "tag node mode + valueless node radius"
+ config.delete(cfg_base + ['authentication','mode', 'radius'])
+ config.set(cfg_base + ['authentication', 'mode', 'radius'], value=None, replace=True)
+ elif not config.exists(cfg_base + ['authentication', 'mode', 'local']):
+ # if "mode local", change to "tag node mode + node local value password"
+ config.delete(cfg_base + ['authentication', 'mode', 'local'])
+ config.set(cfg_base + ['authentication', 'mode', 'local'], value='password', replace=True)
+ try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+ except OSError as e:
+ print("Failed to save the modified config: {}".format(e))
+ sys.exit(1)
diff --git a/src/migration-scripts/ospf/0-to-1 b/src/migration-scripts/ospf/0-to-1
new file mode 100755
index 000000000..678569d9e
--- /dev/null
+++ b/src/migration-scripts/ospf/0-to-1
@@ -0,0 +1,81 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# T3753: upgrade to FRR8 and move CLI options to better fit with the new FRR CLI
+
+from sys import argv
+from vyos.configtree import ConfigTree
+
+def ospf_passive_migration(config, ospf_base):
+ if config.exists(ospf_base):
+ if config.exists(ospf_base + ['passive-interface']):
+ default = False
+ for interface in config.return_values(ospf_base + ['passive-interface']):
+ if interface == 'default':
+ default = True
+ continue
+ config.set(ospf_base + ['interface', interface, 'passive'])
+
+ config.delete(ospf_base + ['passive-interface'])
+ config.set(ospf_base + ['passive-interface'], value='default')
+
+ if config.exists(ospf_base + ['passive-interface-exclude']):
+ for interface in config.return_values(ospf_base + ['passive-interface-exclude']):
+ config.set(ospf_base + ['interface', interface, 'passive', 'disable'])
+ config.delete(ospf_base + ['passive-interface-exclude'])
+
+if (len(argv) < 1):
+ print("Must specify file name!")
+ exit(1)
+
+file_name = argv[1]
+
+with open(file_name, 'r') as f:
+ config_file = f.read()
+
+config = ConfigTree(config_file)
+
+ospfv3_base = ['protocols', 'ospfv3']
+if config.exists(ospfv3_base):
+ area_base = ospfv3_base + ['area']
+ if config.exists(area_base):
+ for area in config.list_nodes(area_base):
+ if not config.exists(area_base + [area, 'interface']):
+ continue
+
+ for interface in config.return_values(area_base + [area, 'interface']):
+ config.set(ospfv3_base + ['interface', interface, 'area'], value=area)
+ config.set_tag(ospfv3_base + ['interface'])
+
+ config.delete(area_base + [area, 'interface'])
+
+# Migrate OSPF syntax in default VRF
+ospf_base = ['protocols', 'ospf']
+ospf_passive_migration(config, ospf_base)
+
+vrf_base = ['vrf', 'name']
+if config.exists(vrf_base):
+ for vrf in config.list_nodes(vrf_base):
+ vrf_ospf_base = vrf_base + [vrf, 'protocols', 'ospf']
+ if config.exists(vrf_ospf_base):
+ ospf_passive_migration(config, vrf_ospf_base)
+
+try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+except OSError as e:
+ print(f'Failed to save the modified config: {e}')
+ exit(1)
diff --git a/src/migration-scripts/policy/1-to-2 b/src/migration-scripts/policy/1-to-2
new file mode 100755
index 000000000..eebbf9d41
--- /dev/null
+++ b/src/migration-scripts/policy/1-to-2
@@ -0,0 +1,86 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# T4170: rename "policy ipv6-route" to "policy route6" to match common
+# IPv4/IPv6 schema
+# T4178: Update tcp flags to use multi value node
+
+from sys import argv
+from sys import exit
+
+from vyos.configtree import ConfigTree
+
+if (len(argv) < 1):
+ print("Must specify file name!")
+ exit(1)
+
+file_name = argv[1]
+
+with open(file_name, 'r') as f:
+ config_file = f.read()
+
+base = ['policy', 'ipv6-route']
+config = ConfigTree(config_file)
+
+if not config.exists(base):
+ # Nothing to do
+ exit(0)
+
+config.rename(base, 'route6')
+config.set_tag(['policy', 'route6'])
+
+for route in ['route', 'route6']:
+ route_path = ['policy', route]
+ if config.exists(route_path):
+ for name in config.list_nodes(route_path):
+ if config.exists(route_path + [name, 'rule']):
+ for rule in config.list_nodes(route_path + [name, 'rule']):
+ rule_tcp_flags = route_path + [name, 'rule', rule, 'tcp', 'flags']
+
+ if config.exists(rule_tcp_flags):
+ tmp = config.return_value(rule_tcp_flags)
+ config.delete(rule_tcp_flags)
+ for flag in tmp.split(","):
+ for flag in tmp.split(","):
+ if flag[0] == '!':
+ config.set(rule_tcp_flags + ['not', flag[1:].lower()])
+ else:
+ config.set(rule_tcp_flags + [flag.lower()])
+
+if config.exists(['interfaces']):
+ def if_policy_rename(config, path):
+ if config.exists(path + ['policy', 'ipv6-route']):
+ config.rename(path + ['policy', 'ipv6-route'], 'route6')
+
+ for if_type in config.list_nodes(['interfaces']):
+ for ifname in config.list_nodes(['interfaces', if_type]):
+ if_path = ['interfaces', if_type, ifname]
+ if_policy_rename(config, if_path)
+
+ for vif_type in ['vif', 'vif-s']:
+ if config.exists(if_path + [vif_type]):
+ for vifname in config.list_nodes(if_path + [vif_type]):
+ if_policy_rename(config, if_path + [vif_type, vifname])
+
+ if config.exists(if_path + [vif_type, vifname, 'vif-c']):
+ for vifcname in config.list_nodes(if_path + [vif_type, vifname, 'vif-c']):
+ if_policy_rename(config, if_path + [vif_type, vifname, 'vif-c', vifcname])
+try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+except OSError as e:
+ print(f'Failed to save the modified config: {e}')
+ exit(1)
diff --git a/src/migration-scripts/quagga/9-to-10 b/src/migration-scripts/quagga/9-to-10
new file mode 100755
index 000000000..249738822
--- /dev/null
+++ b/src/migration-scripts/quagga/9-to-10
@@ -0,0 +1,62 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# re-organize route-map as-path
+
+from sys import argv
+from sys import exit
+
+from vyos.configtree import ConfigTree
+
+if (len(argv) < 2):
+ print("Must specify file name!")
+ exit(1)
+
+file_name = argv[1]
+
+with open(file_name, 'r') as f:
+ config_file = f.read()
+
+base = ['policy', 'route-map']
+
+config = ConfigTree(config_file)
+if not config.exists(base):
+ # Nothing to do
+ exit(0)
+
+for route_map in config.list_nodes(base):
+ # Bail out Early
+ if not config.exists(base + [route_map, 'rule']):
+ continue
+
+ for rule in config.list_nodes(base + [route_map, 'rule']):
+ rule_base = base + [route_map, 'rule', rule]
+ if config.exists(rule_base + ['set', 'as-path-exclude']):
+ tmp = config.return_value(rule_base + ['set', 'as-path-exclude'])
+ config.delete(rule_base + ['set', 'as-path-exclude'])
+ config.set(rule_base + ['set', 'as-path', 'exclude'], value=tmp)
+
+ if config.exists(rule_base + ['set', 'as-path-prepend']):
+ tmp = config.return_value(rule_base + ['set', 'as-path-prepend'])
+ config.delete(rule_base + ['set', 'as-path-prepend'])
+ config.set(rule_base + ['set', 'as-path', 'prepend'], value=tmp)
+
+try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+except OSError as e:
+ print("Failed to save the modified config: {}".format(e))
+ exit(1)
diff --git a/src/migration-scripts/ssh/1-to-2 b/src/migration-scripts/ssh/1-to-2
index bc8815753..31c40df16 100755
--- a/src/migration-scripts/ssh/1-to-2
+++ b/src/migration-scripts/ssh/1-to-2
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright (C) 2020-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -30,26 +30,52 @@ file_name = argv[1]
with open(file_name, 'r') as f:
config_file = f.read()
-base = ['service', 'ssh', 'loglevel']
+base = ['service', 'ssh']
config = ConfigTree(config_file)
if not config.exists(base):
# Nothing to do
exit(0)
-else:
- # red in configured loglevel and convert it to lower case
- tmp = config.return_value(base).lower()
+path_loglevel = base + ['loglevel']
+if config.exists(path_loglevel):
+ # red in configured loglevel and convert it to lower case
+ tmp = config.return_value(path_loglevel).lower()
# VyOS 1.2 had no proper value validation on the CLI thus the
# user could use any arbitrary values - sanitize them
if tmp not in ['quiet', 'fatal', 'error', 'info', 'verbose']:
tmp = 'info'
+ config.set(path_loglevel, value=tmp)
+
+# T4273: migrate ssh cipher list to multi node
+path_ciphers = base + ['ciphers']
+if config.exists(path_ciphers):
+ tmp = []
+ # get curtrent cipher list - comma delimited
+ for cipher in config.return_values(path_ciphers):
+ tmp.extend(cipher.split(','))
+ # delete old cipher suite representation
+ config.delete(path_ciphers)
- config.set(base, value=tmp)
+ for cipher in tmp:
+ config.set(path_ciphers, value=cipher, replace=False)
- try:
- with open(file_name, 'w') as f:
- f.write(config.to_string())
- except OSError as e:
- print("Failed to save the modified config: {}".format(e))
- exit(1)
+# T4273: migrate ssh key-exchange list to multi node
+path_kex = base + ['key-exchange']
+if config.exists(path_kex):
+ tmp = []
+ # get curtrent cipher list - comma delimited
+ for kex in config.return_values(path_kex):
+ tmp.extend(kex.split(','))
+ # delete old cipher suite representation
+ config.delete(path_kex)
+
+ for kex in tmp:
+ config.set(path_kex, value=kex, replace=False)
+
+try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+except OSError as e:
+ print("Failed to save the modified config: {}".format(e))
+ exit(1)
diff --git a/src/migration-scripts/system/22-to-23 b/src/migration-scripts/system/22-to-23
new file mode 100755
index 000000000..7f832e48a
--- /dev/null
+++ b/src/migration-scripts/system/22-to-23
@@ -0,0 +1,50 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+
+from sys import exit, argv
+from vyos.configtree import ConfigTree
+
+if (len(argv) < 1):
+ print("Must specify file name!")
+ exit(1)
+
+file_name = argv[1]
+with open(file_name, 'r') as f:
+ config_file = f.read()
+
+base = ['system', 'ipv6']
+config = ConfigTree(config_file)
+
+if not config.exists(base):
+ # Nothing to do
+ exit(0)
+
+# T4346: drop support to disbale IPv6 address family within the OS Kernel
+if config.exists(base + ['disable']):
+ config.delete(base + ['disable'])
+ # IPv6 address family disable was the only CLI option set - we can cleanup
+ # the entire tree
+ if len(config.list_nodes(base)) == 0:
+ config.delete(base)
+
+try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+except OSError as e:
+ print(f'Failed to save the modified config: {e}')
+ exit(1)
diff --git a/src/migration-scripts/system/23-to-24 b/src/migration-scripts/system/23-to-24
new file mode 100755
index 000000000..5ea71d51a
--- /dev/null
+++ b/src/migration-scripts/system/23-to-24
@@ -0,0 +1,85 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+
+from ipaddress import ip_interface
+from ipaddress import ip_address
+from sys import exit, argv
+from vyos.configtree import ConfigTree
+
+if (len(argv) < 1):
+ print("Must specify file name!")
+ exit(1)
+
+file_name = argv[1]
+with open(file_name, 'r') as f:
+ config_file = f.read()
+
+base = ['protocols', 'static', 'arp']
+tmp_base = ['protocols', 'static', 'arp-tmp']
+config = ConfigTree(config_file)
+
+def fixup_cli(config, path, interface):
+ if config.exists(path + ['address']):
+ for address in config.return_values(path + ['address']):
+ tmp = ip_interface(address)
+ if ip_address(host) in tmp.network.hosts():
+ mac = config.return_value(tmp_base + [host, 'hwaddr'])
+ iface_path = ['protocols', 'static', 'arp', 'interface']
+ config.set(iface_path + [interface, 'address', host, 'mac'], value=mac)
+ config.set_tag(iface_path)
+ config.set_tag(iface_path + [interface, 'address'])
+ continue
+
+if not config.exists(base):
+ # Nothing to do
+ exit(0)
+
+# We need a temporary copy of the config tree as the original one needs to be
+# deleted first due to a change iun thge tagNode structure.
+config.copy(base, tmp_base)
+config.delete(base)
+
+for host in config.list_nodes(tmp_base):
+ for type in config.list_nodes(['interfaces']):
+ for interface in config.list_nodes(['interfaces', type]):
+ if_base = ['interfaces', type, interface]
+ fixup_cli(config, if_base, interface)
+
+ if config.exists(if_base + ['vif']):
+ for vif in config.list_nodes(if_base + ['vif']):
+ vif_base = ['interfaces', type, interface, 'vif', vif]
+ fixup_cli(config, vif_base, f'{interface}.{vif}')
+
+ if config.exists(if_base + ['vif-s']):
+ for vif_s in config.list_nodes(if_base + ['vif-s']):
+ vif_s_base = ['interfaces', type, interface, 'vif-s', vif_s]
+ fixup_cli(config, vif_s_base, f'{interface}.{vif_s}')
+
+ if config.exists(if_base + ['vif-s', vif_s, 'vif-c']):
+ for vif_c in config.list_nodes(if_base + ['vif-s', vif_s, 'vif-c']):
+ vif_c_base = ['interfaces', type, interface, 'vif-s', vif_s, 'vif-c', vif_c]
+ fixup_cli(config, vif_c_base, f'{interface}.{vif_s}.{vif_c}')
+
+config.delete(tmp_base)
+
+try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+except OSError as e:
+ print(f'Failed to save the modified config: {e}')
+ exit(1)
diff --git a/src/op_mode/conntrack_sync.py b/src/op_mode/conntrack_sync.py
index 66ecf8439..e45c38f07 100755
--- a/src/op_mode/conntrack_sync.py
+++ b/src/op_mode/conntrack_sync.py
@@ -20,12 +20,15 @@ import xmltodict
from argparse import ArgumentParser
from vyos.configquery import CliShellApiConfigQuery
+from vyos.configquery import ConfigTreeQuery
+from vyos.util import call
from vyos.util import cmd
from vyos.util import run
from vyos.template import render_to_string
conntrackd_bin = '/usr/sbin/conntrackd'
conntrackd_config = '/run/conntrackd/conntrackd.conf'
+failover_state_file = '/var/run/vyatta-conntrackd-failover-state'
parser = ArgumentParser(description='Conntrack Sync')
group = parser.add_mutually_exclusive_group()
@@ -36,6 +39,8 @@ group.add_argument('--show-internal', help='Show internal (main) tracking cache'
group.add_argument('--show-external', help='Show external (main) tracking cache', action='store_true')
group.add_argument('--show-internal-expect', help='Show internal (expect) tracking cache', action='store_true')
group.add_argument('--show-external-expect', help='Show external (expect) tracking cache', action='store_true')
+group.add_argument('--show-statistics', help='Show connection syncing statistics', action='store_true')
+group.add_argument('--show-status', help='Show conntrack-sync status', action='store_true')
def is_configured():
""" Check if conntrack-sync service is configured """
@@ -72,7 +77,7 @@ def xml_to_stdout(xml):
parsed = xmltodict.parse(line)
out.append(parsed)
- print(render_to_string('conntrackd/conntrackd.op-mode.tmpl', {'data' : out}))
+ print(render_to_string('conntrackd/conntrackd.op-mode.j2', {'data' : out}))
if __name__ == '__main__':
args = parser.parse_args()
@@ -131,6 +136,46 @@ if __name__ == '__main__':
out = cmd(f'sudo {conntrackd_bin} -C {conntrackd_config} {opt} -x')
xml_to_stdout(out)
+ elif args.show_statistics:
+ is_configured()
+ config = ConfigTreeQuery()
+ print('\nMain Table Statistics:\n')
+ call(f'sudo {conntrackd_bin} -C {conntrackd_config} -s')
+ print()
+ if config.exists(['service', 'conntrack-sync', 'expect-sync']):
+ print('\nExpect Table Statistics:\n')
+ call(f'sudo {conntrackd_bin} -C {conntrackd_config} -s exp')
+ print()
+
+ elif args.show_status:
+ is_configured()
+ config = ConfigTreeQuery()
+ ct_sync_intf = config.list_nodes(['service', 'conntrack-sync', 'interface'])
+ ct_sync_intf = ', '.join(ct_sync_intf)
+ failover_state = "no transition yet!"
+ expect_sync_protocols = "disabled"
+
+ if config.exists(['service', 'conntrack-sync', 'failover-mechanism', 'vrrp']):
+ failover_mechanism = "vrrp"
+ vrrp_sync_grp = config.value(['service', 'conntrack-sync', 'failover-mechanism', 'vrrp', 'sync-group'])
+
+ if os.path.isfile(failover_state_file):
+ with open(failover_state_file, "r") as f:
+ failover_state = f.readline()
+
+ if config.exists(['service', 'conntrack-sync', 'expect-sync']):
+ expect_sync_protocols = config.values(['service', 'conntrack-sync', 'expect-sync'])
+ if 'all' in expect_sync_protocols:
+ expect_sync_protocols = ["ftp", "sip", "h323", "nfs", "sqlnet"]
+ expect_sync_protocols = ', '.join(expect_sync_protocols)
+
+ show_status = (f'\nsync-interface : {ct_sync_intf}\n'
+ f'failover-mechanism : {failover_mechanism} [sync-group {vrrp_sync_grp}]\n'
+ f'last state transition : {failover_state}'
+ f'ExpectationSync : {expect_sync_protocols}')
+
+ print(show_status)
+
else:
parser.print_help()
exit(1)
diff --git a/src/op_mode/containers_op.py b/src/op_mode/containers_op.py
deleted file mode 100755
index bc317029c..000000000
--- a/src/op_mode/containers_op.py
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (C) 2021 VyOS maintainers and contributors
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 or later as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import argparse
-
-from getpass import getuser
-from vyos.configquery import ConfigTreeQuery
-from vyos.util import cmd
-
-parser = argparse.ArgumentParser()
-parser.add_argument("-a", "--all", action="store_true", help="Show all containers")
-parser.add_argument("-i", "--image", action="store_true", help="Show container images")
-parser.add_argument("-n", "--networks", action="store_true", help="Show container images")
-parser.add_argument("-p", "--pull", action="store", help="Pull image for container")
-parser.add_argument("-d", "--remove", action="store", help="Delete container image")
-parser.add_argument("-u", "--update", action="store", help="Update given container image")
-
-config = ConfigTreeQuery()
-base = ['container']
-if not config.exists(base):
- print('Containers not configured')
- exit(0)
-
-if getuser() != 'root':
- raise OSError('This functions needs to be run as root to return correct results!')
-
-if __name__ == '__main__':
- args = parser.parse_args()
-
- if args.all:
- print(cmd('podman ps --all'))
-
- elif args.image:
- print(cmd('podman image ls'))
-
- elif args.networks:
- print(cmd('podman network ls'))
-
- elif args.pull:
- image = args.pull
- try:
- print(cmd(f'podman image pull {image}'))
- except:
- print(f'Can\'t find or download image "{image}"')
-
- elif args.remove:
- image = args.remove
- try:
- print(cmd(f'podman image rm {image}'))
- except:
- print(f'Can\'t delete image "{image}"')
-
- elif args.update:
- tmp = config.get_config_dict(base + ['name', args.update],
- key_mangling=('-', '_'), get_first_key=True)
- try:
- image = tmp['image']
- print(cmd(f'podman image pull {image}'))
- except:
- print(f'Can\'t find or download image "{image}"')
- else:
- parser.print_help()
- exit(1)
-
- exit(0)
diff --git a/src/op_mode/cpu_summary.py b/src/op_mode/cpu_summary.py
index cfd321522..3bdf5a718 100755
--- a/src/op_mode/cpu_summary.py
+++ b/src/op_mode/cpu_summary.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018 VyOS maintainers and contributors
+# Copyright (C) 2018-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -19,18 +19,30 @@ from vyos.util import colon_separated_to_dict
FILE_NAME = '/proc/cpuinfo'
-with open(FILE_NAME, 'r') as f:
- data_raw = f.read()
+def get_raw_data():
+ with open(FILE_NAME, 'r') as f:
+ data_raw = f.read()
-data = colon_separated_to_dict(data_raw)
+ data = colon_separated_to_dict(data_raw)
-# Accumulate all data in a dict for future support for machine-readable output
-cpu_data = {}
-cpu_data['cpu_number'] = len(data['processor'])
-cpu_data['models'] = list(set(data['model name']))
+ # Accumulate all data in a dict for future support for machine-readable output
+ cpu_data = {}
+ cpu_data['cpu_number'] = len(data['processor'])
+ cpu_data['models'] = list(set(data['model name']))
-# Strip extra whitespace from CPU model names, /proc/cpuinfo is prone to that
-cpu_data['models'] = map(lambda s: re.sub(r'\s+', ' ', s), cpu_data['models'])
+ # Strip extra whitespace from CPU model names, /proc/cpuinfo is prone to that
+ cpu_data['models'] = list(map(lambda s: re.sub(r'\s+', ' ', s), cpu_data['models']))
+
+ return cpu_data
+
+def get_formatted_output():
+ cpu_data = get_raw_data()
+
+ out = "CPU(s): {0}\n".format(cpu_data['cpu_number'])
+ out += "CPU model(s): {0}".format(",".join(cpu_data['models']))
+
+ return out
+
+if __name__ == '__main__':
+ print(get_formatted_output())
-print("CPU(s): {0}".format(cpu_data['cpu_number']))
-print("CPU model(s): {0}".format(",".join(cpu_data['models'])))
diff --git a/src/op_mode/firewall.py b/src/op_mode/firewall.py
new file mode 100755
index 000000000..3146fc357
--- /dev/null
+++ b/src/op_mode/firewall.py
@@ -0,0 +1,361 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import argparse
+import ipaddress
+import json
+import re
+import tabulate
+
+from vyos.config import Config
+from vyos.util import cmd
+from vyos.util import dict_search_args
+
+def get_firewall_interfaces(conf, firewall, name=None, ipv6=False):
+ interfaces = conf.get_config_dict(['interfaces'], key_mangling=('-', '_'),
+ get_first_key=True, no_tag_node_value_mangle=True)
+
+ directions = ['in', 'out', 'local']
+
+ def parse_if(ifname, if_conf):
+ if 'firewall' in if_conf:
+ for direction in directions:
+ if direction in if_conf['firewall']:
+ fw_conf = if_conf['firewall'][direction]
+ name_str = f'({ifname},{direction})'
+
+ if 'name' in fw_conf:
+ fw_name = fw_conf['name']
+
+ if not name:
+ firewall['name'][fw_name]['interface'].append(name_str)
+ elif not ipv6 and name == fw_name:
+ firewall['interface'].append(name_str)
+
+ if 'ipv6_name' in fw_conf:
+ fw_name = fw_conf['ipv6_name']
+
+ if not name:
+ firewall['ipv6_name'][fw_name]['interface'].append(name_str)
+ elif ipv6 and name == fw_name:
+ firewall['interface'].append(name_str)
+
+ for iftype in ['vif', 'vif_s', 'vif_c']:
+ if iftype in if_conf:
+ for vifname, vif_conf in if_conf[iftype].items():
+ parse_if(f'{ifname}.{vifname}', vif_conf)
+
+ for iftype, iftype_conf in interfaces.items():
+ for ifname, if_conf in iftype_conf.items():
+ parse_if(ifname, if_conf)
+
+ return firewall
+
+def get_config_firewall(conf, name=None, ipv6=False, interfaces=True):
+ config_path = ['firewall']
+ if name:
+ config_path += ['ipv6-name' if ipv6 else 'name', name]
+
+ firewall = conf.get_config_dict(config_path, key_mangling=('-', '_'),
+ get_first_key=True, no_tag_node_value_mangle=True)
+ if firewall and interfaces:
+ if name:
+ firewall['interface'] = []
+ else:
+ if 'name' in firewall:
+ for fw_name, name_conf in firewall['name'].items():
+ name_conf['interface'] = []
+
+ if 'ipv6_name' in firewall:
+ for fw_name, name_conf in firewall['ipv6_name'].items():
+ name_conf['interface'] = []
+
+ get_firewall_interfaces(conf, firewall, name, ipv6)
+ return firewall
+
+def get_nftables_details(name, ipv6=False):
+ suffix = '6' if ipv6 else ''
+ name_prefix = 'NAME6_' if ipv6 else 'NAME_'
+ command = f'sudo nft list chain ip{suffix} filter {name_prefix}{name}'
+ try:
+ results = cmd(command)
+ except:
+ return {}
+
+ out = {}
+ for line in results.split('\n'):
+ comment_search = re.search(rf'{name}[\- ](\d+|default-action)', line)
+ if not comment_search:
+ continue
+
+ rule = {}
+ rule_id = comment_search[1]
+ counter_search = re.search(r'counter packets (\d+) bytes (\d+)', line)
+ if counter_search:
+ rule['packets'] = counter_search[1]
+ rule['bytes'] = counter_search[2]
+
+ rule['conditions'] = re.sub(r'(\b(counter packets \d+ bytes \d+|drop|reject|return|log)\b|comment "[\w\-]+")', '', line).strip()
+ out[rule_id] = rule
+ return out
+
+def output_firewall_name(name, name_conf, ipv6=False, single_rule_id=None):
+ ip_str = 'IPv6' if ipv6 else 'IPv4'
+ print(f'\n---------------------------------\n{ip_str} Firewall "{name}"\n')
+
+ if name_conf['interface']:
+ print('Active on: {0}\n'.format(" ".join(name_conf['interface'])))
+
+ details = get_nftables_details(name, ipv6)
+ rows = []
+
+ if 'rule' in name_conf:
+ for rule_id, rule_conf in name_conf['rule'].items():
+ if single_rule_id and rule_id != single_rule_id:
+ continue
+
+ if 'disable' in rule_conf:
+ continue
+
+ row = [rule_id, rule_conf['action'], rule_conf['protocol'] if 'protocol' in rule_conf else 'all']
+ if rule_id in details:
+ rule_details = details[rule_id]
+ row.append(rule_details.get('packets', 0))
+ row.append(rule_details.get('bytes', 0))
+ row.append(rule_details['conditions'])
+ rows.append(row)
+
+ if 'default_action' in name_conf and not single_rule_id:
+ row = ['default', name_conf['default_action'], 'all']
+ if 'default-action' in details:
+ rule_details = details['default-action']
+ row.append(rule_details.get('packets', 0))
+ row.append(rule_details.get('bytes', 0))
+ rows.append(row)
+
+ if rows:
+ header = ['Rule', 'Action', 'Protocol', 'Packets', 'Bytes', 'Conditions']
+ print(tabulate.tabulate(rows, header) + '\n')
+
+def output_firewall_name_statistics(name, name_conf, ipv6=False, single_rule_id=None):
+ ip_str = 'IPv6' if ipv6 else 'IPv4'
+ print(f'\n---------------------------------\n{ip_str} Firewall "{name}"\n')
+
+ if name_conf['interface']:
+ print('Active on: {0}\n'.format(" ".join(name_conf['interface'])))
+
+ details = get_nftables_details(name, ipv6)
+ rows = []
+
+ if 'rule' in name_conf:
+ for rule_id, rule_conf in name_conf['rule'].items():
+ if single_rule_id and rule_id != single_rule_id:
+ continue
+
+ if 'disable' in rule_conf:
+ continue
+
+ source_addr = dict_search_args(rule_conf, 'source', 'address') or '0.0.0.0/0'
+ dest_addr = dict_search_args(rule_conf, 'destination', 'address') or '0.0.0.0/0'
+
+ row = [rule_id]
+ if rule_id in details:
+ rule_details = details[rule_id]
+ row.append(rule_details.get('packets', 0))
+ row.append(rule_details.get('bytes', 0))
+ else:
+ row.append('0')
+ row.append('0')
+ row.append(rule_conf['action'])
+ row.append(source_addr)
+ row.append(dest_addr)
+ rows.append(row)
+
+ if 'default_action' in name_conf and not single_rule_id:
+ row = ['default']
+ if 'default-action' in details:
+ rule_details = details['default-action']
+ row.append(rule_details.get('packets', 0))
+ row.append(rule_details.get('bytes', 0))
+ else:
+ row.append('0')
+ row.append('0')
+ row.append(name_conf['default_action'])
+ row.append('0.0.0.0/0') # Source
+ row.append('0.0.0.0/0') # Dest
+ rows.append(row)
+
+ if rows:
+ header = ['Rule', 'Packets', 'Bytes', 'Action', 'Source', 'Destination']
+ print(tabulate.tabulate(rows, header) + '\n')
+
+def show_firewall():
+ print('Rulesets Information')
+
+ conf = Config()
+ firewall = get_config_firewall(conf)
+
+ if not firewall:
+ return
+
+ if 'name' in firewall:
+ for name, name_conf in firewall['name'].items():
+ output_firewall_name(name, name_conf, ipv6=False)
+
+ if 'ipv6_name' in firewall:
+ for name, name_conf in firewall['ipv6_name'].items():
+ output_firewall_name(name, name_conf, ipv6=True)
+
+def show_firewall_name(name, ipv6=False):
+ print('Ruleset Information')
+
+ conf = Config()
+ firewall = get_config_firewall(conf, name, ipv6)
+ if firewall:
+ output_firewall_name(name, firewall, ipv6)
+
+def show_firewall_rule(name, rule_id, ipv6=False):
+ print('Rule Information')
+
+ conf = Config()
+ firewall = get_config_firewall(conf, name, ipv6)
+ if firewall:
+ output_firewall_name(name, firewall, ipv6, rule_id)
+
+def show_firewall_group(name=None):
+ conf = Config()
+ firewall = get_config_firewall(conf, interfaces=False)
+
+ if 'group' not in firewall:
+ return
+
+ def find_references(group_type, group_name):
+ out = []
+ for name_type in ['name', 'ipv6_name']:
+ if name_type not in firewall:
+ continue
+ for name, name_conf in firewall[name_type].items():
+ if 'rule' not in name_conf:
+ continue
+ for rule_id, rule_conf in name_conf['rule'].items():
+ source_group = dict_search_args(rule_conf, 'source', 'group', group_type)
+ dest_group = dict_search_args(rule_conf, 'destination', 'group', group_type)
+ if source_group and group_name == source_group:
+ out.append(f'{name}-{rule_id}')
+ elif dest_group and group_name == dest_group:
+ out.append(f'{name}-{rule_id}')
+ return out
+
+ header = ['Name', 'Type', 'References', 'Members']
+ rows = []
+
+ for group_type, group_type_conf in firewall['group'].items():
+ for group_name, group_conf in group_type_conf.items():
+ if name and name != group_name:
+ continue
+
+ references = find_references(group_type, group_name)
+ row = [group_name, group_type, '\n'.join(references) or 'N/A']
+ if 'address' in group_conf:
+ row.append("\n".join(sorted(group_conf['address'], key=ipaddress.ip_address)))
+ elif 'network' in group_conf:
+ row.append("\n".join(sorted(group_conf['network'], key=ipaddress.ip_network)))
+ elif 'mac_address' in group_conf:
+ row.append("\n".join(sorted(group_conf['mac_address'])))
+ elif 'port' in group_conf:
+ row.append("\n".join(sorted(group_conf['port'])))
+ else:
+ row.append('N/A')
+ rows.append(row)
+
+ if rows:
+ print('Firewall Groups\n')
+ print(tabulate.tabulate(rows, header))
+
+def show_summary():
+ print('Ruleset Summary')
+
+ conf = Config()
+ firewall = get_config_firewall(conf)
+
+ if not firewall:
+ return
+
+ header = ['Ruleset Name', 'Description', 'References']
+ v4_out = []
+ v6_out = []
+
+ if 'name' in firewall:
+ for name, name_conf in firewall['name'].items():
+ description = name_conf.get('description', '')
+ interfaces = ", ".join(name_conf['interface'])
+ v4_out.append([name, description, interfaces])
+
+ if 'ipv6_name' in firewall:
+ for name, name_conf in firewall['ipv6_name'].items():
+ description = name_conf.get('description', '')
+ interfaces = ", ".join(name_conf['interface'])
+ v6_out.append([name, description, interfaces or 'N/A'])
+
+ if v6_out:
+ print('\nIPv6 name:\n')
+ print(tabulate.tabulate(v6_out, header) + '\n')
+
+ if v4_out:
+ print('\nIPv4 name:\n')
+ print(tabulate.tabulate(v4_out, header) + '\n')
+
+ show_firewall_group()
+
+def show_statistics():
+ print('Rulesets Statistics')
+
+ conf = Config()
+ firewall = get_config_firewall(conf)
+
+ if not firewall:
+ return
+
+ if 'name' in firewall:
+ for name, name_conf in firewall['name'].items():
+ output_firewall_name_statistics(name, name_conf, ipv6=False)
+
+ if 'ipv6_name' in firewall:
+ for name, name_conf in firewall['ipv6_name'].items():
+ output_firewall_name_statistics(name, name_conf, ipv6=True)
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--action', help='Action', required=False)
+ parser.add_argument('--name', help='Firewall name', required=False, action='store', nargs='?', default='')
+ parser.add_argument('--rule', help='Firewall Rule ID', required=False)
+ parser.add_argument('--ipv6', help='IPv6 toggle', action='store_true')
+
+ args = parser.parse_args()
+
+ if args.action == 'show':
+ if not args.rule:
+ show_firewall_name(args.name, args.ipv6)
+ else:
+ show_firewall_rule(args.name, args.rule, args.ipv6)
+ elif args.action == 'show_all':
+ show_firewall()
+ elif args.action == 'show_group':
+ show_firewall_group(args.name)
+ elif args.action == 'show_statistics':
+ show_statistics()
+ elif args.action == 'show_summary':
+ show_summary()
diff --git a/src/op_mode/format_disk.py b/src/op_mode/format_disk.py
index df4486bce..b3ba44e87 100755
--- a/src/op_mode/format_disk.py
+++ b/src/op_mode/format_disk.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019 VyOS maintainers and contributors
+# Copyright (C) 2019-2021 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -17,11 +17,10 @@
import argparse
import os
import re
-import sys
+
from datetime import datetime
-from time import sleep
-from vyos.util import is_admin, ask_yes_no
+from vyos.util import ask_yes_no
from vyos.util import call
from vyos.util import cmd
from vyos.util import DEVNULL
@@ -38,16 +37,17 @@ def list_disks():
def is_busy(disk: str):
"""Check if given disk device is busy by re-reading it's partition table"""
- return call(f'sudo blockdev --rereadpt /dev/{disk}', stderr=DEVNULL) != 0
+ return call(f'blockdev --rereadpt /dev/{disk}', stderr=DEVNULL) != 0
def backup_partitions(disk: str):
"""Save sfdisk partitions output to a backup file"""
- device_path = '/dev/' + disk
- backup_ts = datetime.now().strftime('%Y-%m-%d-%H:%M')
- backup_file = '/var/tmp/backup_{}.{}'.format(disk, backup_ts)
- cmd(f'sudo /sbin/sfdisk -d {device_path} > {backup_file}')
+ device_path = f'/dev/{disk}'
+ backup_ts = datetime.now().strftime('%Y%m%d-%H%M')
+ backup_file = f'/var/tmp/backup_{disk}.{backup_ts}'
+ call(f'sfdisk -d {device_path} > {backup_file}')
+ print(f'Partition table backup saved to {backup_file}')
def list_partitions(disk: str):
@@ -65,11 +65,11 @@ def list_partitions(disk: str):
def delete_partition(disk: str, partition_idx: int):
- cmd(f'sudo /sbin/parted /dev/{disk} rm {partition_idx}')
+ cmd(f'parted /dev/{disk} rm {partition_idx}')
def format_disk_like(target: str, proto: str):
- cmd(f'sudo /sbin/sfdisk -d /dev/{proto} | sudo /sbin/sfdisk --force /dev/{target}')
+ cmd(f'sfdisk -d /dev/{proto} | sfdisk --force /dev/{target}')
if __name__ == '__main__':
@@ -79,10 +79,6 @@ if __name__ == '__main__':
group.add_argument('-p', '--proto', type=str, required=True, help='Prototype device to use as reference')
args = parser.parse_args()
- if not is_admin():
- print('Must be admin or root to format disk')
- sys.exit(1)
-
target_disk = args.target
eligible_target_disks = list_disks()
@@ -90,54 +86,48 @@ if __name__ == '__main__':
eligible_proto_disks = eligible_target_disks.copy()
eligible_proto_disks.remove(target_disk)
- fmt = {
- 'target_disk': target_disk,
- 'proto_disk': proto_disk,
- }
-
if proto_disk == target_disk:
print('The two disk drives must be different.')
- sys.exit(1)
+ exit(1)
- if not os.path.exists('/dev/' + proto_disk):
- print('Device /dev/{proto_disk} does not exist'.format_map(fmt))
- sys.exit(1)
+ if not os.path.exists(f'/dev/{proto_disk}'):
+ print(f'Device /dev/{proto_disk} does not exist')
+ exit(1)
if not os.path.exists('/dev/' + target_disk):
- print('Device /dev/{target_disk} does not exist'.format_map(fmt))
- sys.exit(1)
+ print(f'Device /dev/{target_disk} does not exist')
+ exit(1)
if target_disk not in eligible_target_disks:
- print('Device {target_disk} can not be formatted'.format_map(fmt))
- sys.exit(1)
+ print(f'Device {target_disk} can not be formatted')
+ exit(1)
if proto_disk not in eligible_proto_disks:
- print('Device {proto_disk} can not be used as a prototype for {target_disk}'.format_map(fmt))
- sys.exit(1)
+ print(f'Device {proto_disk} can not be used as a prototype for {target_disk}')
+ exit(1)
if is_busy(target_disk):
- print("Disk device {target_disk} is busy. Can't format it now".format_map(fmt))
- sys.exit(1)
+ print(f'Disk device {target_disk} is busy, unable to format')
+ exit(1)
- print('This will re-format disk {target_disk} so that it has the same disk\n'
- 'partion sizes and offsets as {proto_disk}. This will not copy\n'
- 'data from {proto_disk} to {target_disk}. But this will erase all\n'
- 'data on {target_disk}.\n'.format_map(fmt))
+ print(f'\nThis will re-format disk {target_disk} so that it has the same disk'
+ f'\npartion sizes and offsets as {proto_disk}. This will not copy'
+ f'\ndata from {proto_disk} to {target_disk}. But this will erase all'
+ f'\ndata on {target_disk}.\n')
- if not ask_yes_no("Do you wish to proceed?"):
- print('OK. Disk drive {target_disk} will not be re-formated'.format_map(fmt))
- sys.exit(0)
+ if not ask_yes_no('Do you wish to proceed?'):
+ print(f'Disk drive {target_disk} will not be re-formated')
+ exit(0)
- print('OK. Re-formating disk drive {target_disk}...'.format_map(fmt))
+ print(f'Re-formating disk drive {target_disk}...')
print('Making backup copy of partitions...')
backup_partitions(target_disk)
- sleep(1)
print('Deleting old partitions...')
for p in list_partitions(target_disk):
delete_partition(disk=target_disk, partition_idx=p)
- print('Creating new partitions on {target_disk} based on {proto_disk}...'.format_map(fmt))
+ print(f'Creating new partitions on {target_disk} based on {proto_disk}...')
format_disk_like(target=target_disk, proto=proto_disk)
- print('Done.')
+ print('Done!')
diff --git a/src/op_mode/generate_openconnect_otp_key.py b/src/op_mode/generate_openconnect_otp_key.py
new file mode 100755
index 000000000..363bcf3ea
--- /dev/null
+++ b/src/op_mode/generate_openconnect_otp_key.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import argparse
+import os
+
+from vyos.util import popen
+from secrets import token_hex
+from base64 import b32encode
+
+if os.geteuid() != 0:
+ exit("You need to have root privileges to run this script.\nPlease try again, this time using 'sudo'. Exiting.")
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-u", "--username", type=str, help='Username used for authentication', required=True)
+ parser.add_argument("-i", "--interval", type=str, help='Duration of single time interval', default="30", required=False)
+ parser.add_argument("-d", "--digits", type=str, help='The number of digits in the one-time password', default="6", required=False)
+ args = parser.parse_args()
+
+ hostname = os.uname()[1]
+ username = args.username
+ digits = args.digits
+ period = args.interval
+
+ # check variables:
+ if int(digits) < 6 or int(digits) > 8:
+ print("")
+ quit("The number of digits in the one-time password must be between '6' and '8'")
+
+ if int(period) < 5 or int(period) > 86400:
+ print("")
+ quit("Time token interval must be between '5' and '86400' seconds")
+
+ # generate OTP key, URL & QR:
+ key_hex = token_hex(20)
+ key_base32 = b32encode(bytes.fromhex(key_hex)).decode()
+
+ otp_url=''.join(["otpauth://totp/",username,"@",hostname,"?secret=",key_base32,"&digits=",digits,"&period=",period])
+ qrcode,err = popen('qrencode -t ansiutf8', input=otp_url)
+
+ print("# You can share it with the user, he just needs to scan the QR in his OTP app")
+ print("# username: ", username)
+ print("# OTP KEY: ", key_base32)
+ print("# OTP URL: ", otp_url)
+ print(qrcode)
+ print('# To add this OTP key to configuration, run the following commands:')
+ print(f"set vpn openconnect authentication local-users username {username} otp key '{key_hex}'")
+ if period != "30":
+ print(f"set vpn openconnect authentication local-users username {username} otp interval '{period}'")
+ if digits != "6":
+ print(f"set vpn openconnect authentication local-users username {username} otp otp-length '{digits}'")
diff --git a/src/op_mode/generate_ovpn_client_file.py b/src/op_mode/generate_ovpn_client_file.py
new file mode 100755
index 000000000..0628e6135
--- /dev/null
+++ b/src/op_mode/generate_ovpn_client_file.py
@@ -0,0 +1,149 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import argparse
+import os
+
+from jinja2 import Template
+from textwrap import fill
+
+from vyos.configquery import ConfigTreeQuery
+from vyos.ifconfig import Section
+from vyos.util import cmd
+
+
+client_config = """
+
+client
+nobind
+remote {{ remote_host }} {{ port }}
+remote-cert-tls server
+proto {{ 'tcp-client' if protocol == 'tcp-active' else 'udp' }}
+dev {{ device }}
+dev-type {{ device }}
+persist-key
+persist-tun
+verb 3
+
+# Encryption options
+{% if encryption is defined and encryption is not none %}
+{% if encryption.cipher is defined and encryption.cipher is not none %}
+cipher {{ encryption.cipher }}
+{% if encryption.cipher == 'bf128' %}
+keysize 128
+{% elif encryption.cipher == 'bf256' %}
+keysize 256
+{% endif %}
+{% endif %}
+{% if encryption.ncp_ciphers is defined and encryption.ncp_ciphers is not none %}
+data-ciphers {{ encryption.ncp_ciphers }}
+{% endif %}
+{% endif %}
+
+{% if hash is defined and hash is not none %}
+auth {{ hash }}
+{% endif %}
+keysize 256
+comp-lzo {{ '' if use_lzo_compression is defined else 'no' }}
+
+<ca>
+-----BEGIN CERTIFICATE-----
+{{ ca }}
+-----END CERTIFICATE-----
+
+</ca>
+
+<cert>
+-----BEGIN CERTIFICATE-----
+{{ cert }}
+-----END CERTIFICATE-----
+
+</cert>
+
+<key>
+-----BEGIN PRIVATE KEY-----
+{{ key }}
+-----END PRIVATE KEY-----
+
+</key>
+
+"""
+
+config = ConfigTreeQuery()
+base = ['interfaces', 'openvpn']
+
+if not config.exists(base):
+ print('OpenVPN not configured')
+ exit(0)
+
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-i", "--interface", type=str, help='OpenVPN interface the client is connecting to', required=True)
+ parser.add_argument("-a", "--ca", type=str, help='OpenVPN CA cerificate', required=True)
+ parser.add_argument("-c", "--cert", type=str, help='OpenVPN client cerificate', required=True)
+ parser.add_argument("-k", "--key", type=str, help='OpenVPN client cerificate key', action="store")
+ args = parser.parse_args()
+
+ interface = args.interface
+ ca = args.ca
+ cert = args.cert
+ key = args.key
+ if not key:
+ key = args.cert
+
+ if interface not in Section.interfaces('openvpn'):
+ exit(f'OpenVPN interface "{interface}" does not exist!')
+
+ if not config.exists(['pki', 'ca', ca, 'certificate']):
+ exit(f'OpenVPN CA certificate "{ca}" does not exist!')
+
+ if not config.exists(['pki', 'certificate', cert, 'certificate']):
+ exit(f'OpenVPN certificate "{cert}" does not exist!')
+
+ if not config.exists(['pki', 'certificate', cert, 'private', 'key']):
+ exit(f'OpenVPN certificate key "{key}" does not exist!')
+
+ ca = config.value(['pki', 'ca', ca, 'certificate'])
+ ca = fill(ca, width=64)
+ cert = config.value(['pki', 'certificate', cert, 'certificate'])
+ cert = fill(cert, width=64)
+ key = config.value(['pki', 'certificate', key, 'private', 'key'])
+ key = fill(key, width=64)
+ remote_host = config.value(base + [interface, 'local-host'])
+
+ ovpn_conf = config.get_config_dict(base + [interface], key_mangling=('-', '_'), get_first_key=True)
+
+ port = '1194' if 'local_port' not in ovpn_conf else ovpn_conf['local_port']
+ proto = 'udp' if 'protocol' not in ovpn_conf else ovpn_conf['protocol']
+ device = 'tun' if 'device_type' not in ovpn_conf else ovpn_conf['device_type']
+
+ config = {
+ 'interface' : interface,
+ 'ca' : ca,
+ 'cert' : cert,
+ 'key' : key,
+ 'device' : device,
+ 'port' : port,
+ 'proto' : proto,
+ 'remote_host' : remote_host,
+ 'address' : [],
+ }
+
+# Clear out terminal first
+print('\x1b[2J\x1b[H')
+client = Template(client_config, trim_blocks=True).render(config)
+print(client)
diff --git a/src/op_mode/generate_public_key_command.py b/src/op_mode/generate_public_key_command.py
index 7a7b6c923..f071ae350 100755
--- a/src/op_mode/generate_public_key_command.py
+++ b/src/op_mode/generate_public_key_command.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -29,8 +29,12 @@ def get_key(path):
key_string = vyos.remote.get_remote_config(path)
return key_string.split()
-username = sys.argv[1]
-algorithm, key, identifier = get_key(sys.argv[2])
+try:
+ username = sys.argv[1]
+ algorithm, key, identifier = get_key(sys.argv[2])
+except Exception as e:
+ print("Failed to retrieve the public key: {}".format(e))
+ sys.exit(1)
print('# To add this key as an embedded key, run the following commands:')
print('configure')
@@ -39,3 +43,4 @@ print(f'set system login user {username} authentication public-keys {identifier}
print('commit')
print('save')
print('exit')
+
diff --git a/src/op_mode/ikev2_profile_generator.py b/src/op_mode/ikev2_profile_generator.py
index 990b06c12..21561d16f 100755
--- a/src/op_mode/ikev2_profile_generator.py
+++ b/src/op_mode/ikev2_profile_generator.py
@@ -222,9 +222,9 @@ except KeyboardInterrupt:
print('\n\n==== <snip> ====')
if args.os == 'ios':
- print(render_to_string('ipsec/ios_profile.tmpl', data))
+ print(render_to_string('ipsec/ios_profile.j2', data))
print('==== </snip> ====\n')
print('Save the XML from above to a new file named "vyos.mobileconfig" and E-Mail it to your phone.')
elif args.os == 'windows':
- print(render_to_string('ipsec/windows_profile.tmpl', data))
+ print(render_to_string('ipsec/windows_profile.j2', data))
print('==== </snip> ====\n')
diff --git a/src/op_mode/lldp_op.py b/src/op_mode/lldp_op.py
index 731e71891..17f6bf552 100755
--- a/src/op_mode/lldp_op.py
+++ b/src/op_mode/lldp_op.py
@@ -54,12 +54,15 @@ def parse_data(data, interface):
for local_if, values in neighbor.items():
if interface is not None and local_if != interface:
continue
+ cap = ''
for chassis, c_value in values.get('chassis', {}).items():
+ # bail out early if no capabilities found
+ if 'capability' not in c_value:
+ continue
capabilities = c_value['capability']
if isinstance(capabilities, dict):
capabilities = [capabilities]
- cap = ''
for capability in capabilities:
if capability['enabled']:
if capability['type'] == 'Router':
diff --git a/src/op_mode/monitor_bandwidth_test.sh b/src/op_mode/monitor_bandwidth_test.sh
index 900223bca..a6ad0b42c 100755
--- a/src/op_mode/monitor_bandwidth_test.sh
+++ b/src/op_mode/monitor_bandwidth_test.sh
@@ -24,6 +24,9 @@ elif [[ $(dig $1 AAAA +short | grep -v '\.$' | wc -l) -gt 0 ]]; then
# Set address family to IPv6 when FQDN has at least one AAAA record
OPT="-V"
+else
+ # It's not IPv6, no option needed
+ OPT=""
fi
/usr/bin/iperf $OPT -c $1 $2
diff --git a/src/op_mode/policy_route.py b/src/op_mode/policy_route.py
new file mode 100755
index 000000000..5be40082f
--- /dev/null
+++ b/src/op_mode/policy_route.py
@@ -0,0 +1,189 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import argparse
+import re
+import tabulate
+
+from vyos.config import Config
+from vyos.util import cmd
+from vyos.util import dict_search_args
+
+def get_policy_interfaces(conf, policy, name=None, ipv6=False):
+ interfaces = conf.get_config_dict(['interfaces'], key_mangling=('-', '_'),
+ get_first_key=True, no_tag_node_value_mangle=True)
+
+ routes = ['route', 'route6']
+
+ def parse_if(ifname, if_conf):
+ if 'policy' in if_conf:
+ for route in routes:
+ if route in if_conf['policy']:
+ route_name = if_conf['policy'][route]
+ name_str = f'({ifname},{route})'
+
+ if not name:
+ policy[route][route_name]['interface'].append(name_str)
+ elif not ipv6 and name == route_name:
+ policy['interface'].append(name_str)
+
+ for iftype in ['vif', 'vif_s', 'vif_c']:
+ if iftype in if_conf:
+ for vifname, vif_conf in if_conf[iftype].items():
+ parse_if(f'{ifname}.{vifname}', vif_conf)
+
+ for iftype, iftype_conf in interfaces.items():
+ for ifname, if_conf in iftype_conf.items():
+ parse_if(ifname, if_conf)
+
+def get_config_policy(conf, name=None, ipv6=False, interfaces=True):
+ config_path = ['policy']
+ if name:
+ config_path += ['route6' if ipv6 else 'route', name]
+
+ policy = conf.get_config_dict(config_path, key_mangling=('-', '_'),
+ get_first_key=True, no_tag_node_value_mangle=True)
+ if policy and interfaces:
+ if name:
+ policy['interface'] = []
+ else:
+ if 'route' in policy:
+ for route_name, route_conf in policy['route'].items():
+ route_conf['interface'] = []
+
+ if 'route6' in policy:
+ for route_name, route_conf in policy['route6'].items():
+ route_conf['interface'] = []
+
+ get_policy_interfaces(conf, policy, name, ipv6)
+
+ return policy
+
+def get_nftables_details(name, ipv6=False):
+ suffix = '6' if ipv6 else ''
+ command = f'sudo nft list chain ip{suffix} mangle VYOS_PBR{suffix}_{name}'
+ try:
+ results = cmd(command)
+ except:
+ return {}
+
+ out = {}
+ for line in results.split('\n'):
+ comment_search = re.search(rf'{name}[\- ](\d+|default-action)', line)
+ if not comment_search:
+ continue
+
+ rule = {}
+ rule_id = comment_search[1]
+ counter_search = re.search(r'counter packets (\d+) bytes (\d+)', line)
+ if counter_search:
+ rule['packets'] = counter_search[1]
+ rule['bytes'] = counter_search[2]
+
+ rule['conditions'] = re.sub(r'(\b(counter packets \d+ bytes \d+|drop|reject|return|log)\b|comment "[\w\-]+")', '', line).strip()
+ out[rule_id] = rule
+ return out
+
+def output_policy_route(name, route_conf, ipv6=False, single_rule_id=None):
+ ip_str = 'IPv6' if ipv6 else 'IPv4'
+ print(f'\n---------------------------------\n{ip_str} Policy Route "{name}"\n')
+
+ if route_conf['interface']:
+ print('Active on: {0}\n'.format(" ".join(route_conf['interface'])))
+
+ details = get_nftables_details(name, ipv6)
+ rows = []
+
+ if 'rule' in route_conf:
+ for rule_id, rule_conf in route_conf['rule'].items():
+ if single_rule_id and rule_id != single_rule_id:
+ continue
+
+ if 'disable' in rule_conf:
+ continue
+
+ action = rule_conf['action'] if 'action' in rule_conf else 'set'
+ protocol = rule_conf['protocol'] if 'protocol' in rule_conf else 'all'
+
+ row = [rule_id, action, protocol]
+ if rule_id in details:
+ rule_details = details[rule_id]
+ row.append(rule_details.get('packets', 0))
+ row.append(rule_details.get('bytes', 0))
+ row.append(rule_details['conditions'])
+ rows.append(row)
+
+ if 'default_action' in route_conf and not single_rule_id:
+ row = ['default', route_conf['default_action'], 'all']
+ if 'default-action' in details:
+ rule_details = details['default-action']
+ row.append(rule_details.get('packets', 0))
+ row.append(rule_details.get('bytes', 0))
+ rows.append(row)
+
+ if rows:
+ header = ['Rule', 'Action', 'Protocol', 'Packets', 'Bytes', 'Conditions']
+ print(tabulate.tabulate(rows, header) + '\n')
+
+def show_policy(ipv6=False):
+ print('Ruleset Information')
+
+ conf = Config()
+ policy = get_config_policy(conf)
+
+ if not policy:
+ return
+
+ if not ipv6 and 'route' in policy:
+ for route, route_conf in policy['route'].items():
+ output_policy_route(route, route_conf, ipv6=False)
+
+ if ipv6 and 'route6' in policy:
+ for route, route_conf in policy['route6'].items():
+ output_policy_route(route, route_conf, ipv6=True)
+
+def show_policy_name(name, ipv6=False):
+ print('Ruleset Information')
+
+ conf = Config()
+ policy = get_config_policy(conf, name, ipv6)
+ if policy:
+ output_policy_route(name, policy, ipv6)
+
+def show_policy_rule(name, rule_id, ipv6=False):
+ print('Rule Information')
+
+ conf = Config()
+ policy = get_config_policy(conf, name, ipv6)
+ if policy:
+ output_policy_route(name, policy, ipv6, rule_id)
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--action', help='Action', required=False)
+ parser.add_argument('--name', help='Policy name', required=False, action='store', nargs='?', default='')
+ parser.add_argument('--rule', help='Policy Rule ID', required=False)
+ parser.add_argument('--ipv6', help='IPv6 toggle', action='store_true')
+
+ args = parser.parse_args()
+
+ if args.action == 'show':
+ if not args.rule:
+ show_policy_name(args.name, args.ipv6)
+ else:
+ show_policy_rule(args.name, args.rule, args.ipv6)
+ elif args.action == 'show_all':
+ show_policy(args.ipv6)
diff --git a/src/op_mode/powerctrl.py b/src/op_mode/powerctrl.py
index 679b03c0b..fd4f86d88 100755
--- a/src/op_mode/powerctrl.py
+++ b/src/op_mode/powerctrl.py
@@ -33,10 +33,12 @@ def utc2local(datetime):
def parse_time(s):
try:
- if re.match(r'^\d{1,2}$', s):
- if (int(s) > 59):
+ if re.match(r'^\d{1,9999}$', s):
+ if (int(s) > 59) and (int(s) < 1440):
s = str(int(s)//60) + ":" + str(int(s)%60)
return datetime.strptime(s, "%H:%M").time()
+ if (int(s) >= 1440):
+ return s.split()
else:
return datetime.strptime(s, "%M").time()
else:
@@ -141,7 +143,7 @@ def execute_shutdown(time, reboot=True, ask=True):
cmd(f'/usr/bin/wall "{wall_msg}"')
else:
if not ts:
- exit(f'Invalid time "{time[0]}". The valid format is HH:MM')
+ exit(f'Invalid time "{time[0]}". Uses 24 Hour Clock format')
else:
exit(f'Invalid date "{time[1]}". A valid format is YYYY-MM-DD [HH:MM]')
else:
@@ -172,7 +174,12 @@ def main():
action.add_argument("--reboot", "-r",
help="Reboot the system",
nargs="*",
- metavar="Minutes|HH:MM")
+ metavar="HH:MM")
+
+ action.add_argument("--reboot_in", "-i",
+ help="Reboot the system",
+ nargs="*",
+ metavar="Minutes")
action.add_argument("--poweroff", "-p",
help="Poweroff the system",
@@ -190,7 +197,17 @@ def main():
try:
if args.reboot is not None:
+ for r in args.reboot:
+ if ':' not in r and '/' not in r and '.' not in r:
+ print("Incorrect format! Use HH:MM")
+ exit(1)
execute_shutdown(args.reboot, reboot=True, ask=args.yes)
+ if args.reboot_in is not None:
+ for i in args.reboot_in:
+ if ':' in i:
+ print("Incorrect format! Use Minutes")
+ exit(1)
+ execute_shutdown(args.reboot_in, reboot=True, ask=args.yes)
if args.poweroff is not None:
execute_shutdown(args.poweroff, reboot=False, ask=args.yes)
if args.cancel:
diff --git a/src/op_mode/ppp-server-ctrl.py b/src/op_mode/ppp-server-ctrl.py
index 670cdf879..e93963fdd 100755
--- a/src/op_mode/ppp-server-ctrl.py
+++ b/src/op_mode/ppp-server-ctrl.py
@@ -60,7 +60,7 @@ def main():
output, err = popen(cmd_dict['cmd_base'].format(cmd_dict['vpn_types'][args.proto]) + args.action + ses_pattern, stderr=DEVNULL, decode='utf-8')
if not err:
try:
- print(output)
+ print(f' {output}')
except:
sys.exit(0)
else:
diff --git a/src/op_mode/restart_frr.py b/src/op_mode/restart_frr.py
index 109c8dd7b..91b25567a 100755
--- a/src/op_mode/restart_frr.py
+++ b/src/op_mode/restart_frr.py
@@ -22,6 +22,7 @@ import psutil
from logging.handlers import SysLogHandler
from shutil import rmtree
+from vyos.base import Warning
from vyos.util import call
from vyos.util import ask_yes_no
from vyos.util import process_named_running
@@ -138,7 +139,7 @@ def _reload_config(daemon):
# define program arguments
cmd_args_parser = argparse.ArgumentParser(description='restart frr daemons')
cmd_args_parser.add_argument('--action', choices=['restart'], required=True, help='action to frr daemons')
-cmd_args_parser.add_argument('--daemon', choices=['bfdd', 'bgpd', 'ospfd', 'ospf6d', 'isisd', 'ripd', 'ripngd', 'staticd', 'zebra'], required=False, nargs='*', help='select single or multiple daemons')
+cmd_args_parser.add_argument('--daemon', choices=['bfdd', 'bgpd', 'ldpd', 'ospfd', 'ospf6d', 'isisd', 'ripd', 'ripngd', 'staticd', 'zebra'], required=False, nargs='*', help='select single or multiple daemons')
# parse arguments
cmd_args = cmd_args_parser.parse_args()
@@ -163,7 +164,7 @@ if cmd_args.action == 'restart':
if cmd_args.daemon != ['']:
for daemon in cmd_args.daemon:
if not process_named_running(daemon):
- print('WARNING: some of listed daemons are not running!')
+ Warning('some of listed daemons are not running!')
# run command to restart daemon
for daemon in cmd_args.daemon:
diff --git a/src/op_mode/show_configuration_json.py b/src/op_mode/show_configuration_json.py
new file mode 100755
index 000000000..fdece533b
--- /dev/null
+++ b/src/op_mode/show_configuration_json.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import argparse
+import json
+
+from vyos.configquery import ConfigTreeQuery
+
+
+config = ConfigTreeQuery()
+c = config.get_config_dict()
+
+parser = argparse.ArgumentParser()
+parser.add_argument("-p", "--pretty", action="store_true", help="Show pretty configuration in JSON format")
+
+
+if __name__ == '__main__':
+ args = parser.parse_args()
+
+ if args.pretty:
+ print(json.dumps(c, indent=4))
+ else:
+ print(json.dumps(c))
diff --git a/src/op_mode/show_cpu.py b/src/op_mode/show_cpu.py
index 0040e950d..9973d9789 100755
--- a/src/op_mode/show_cpu.py
+++ b/src/op_mode/show_cpu.py
@@ -21,7 +21,7 @@ from sys import exit
from vyos.util import popen, DEVNULL
OUT_TMPL_SRC = """
-{% if cpu %}
+{%- if cpu -%}
{% if 'vendor' in cpu %}CPU Vendor: {{cpu.vendor}}{% endif %}
{% if 'model' in cpu %}Model: {{cpu.model}}{% endif %}
{% if 'cpus' in cpu %}Total CPUs: {{cpu.cpus}}{% endif %}
@@ -31,31 +31,42 @@ OUT_TMPL_SRC = """
{% if 'mhz' in cpu %}Current MHz: {{cpu.mhz}}{% endif %}
{% if 'mhz_min' in cpu %}Minimum MHz: {{cpu.mhz_min}}{% endif %}
{% if 'mhz_max' in cpu %}Maximum MHz: {{cpu.mhz_max}}{% endif %}
-{% endif %}
+{%- endif -%}
"""
-cpu = {}
-cpu_json, code = popen('lscpu -J', stderr=DEVNULL)
-
-if code == 0:
- cpu_info = json.loads(cpu_json)
- if len(cpu_info) > 0 and 'lscpu' in cpu_info:
- for prop in cpu_info['lscpu']:
- if (prop['field'].find('Thread(s)') > -1): cpu['threads'] = prop['data']
- if (prop['field'].find('Core(s)')) > -1: cpu['cores'] = prop['data']
- if (prop['field'].find('Socket(s)')) > -1: cpu['sockets'] = prop['data']
- if (prop['field'].find('CPU(s):')) > -1: cpu['cpus'] = prop['data']
- if (prop['field'].find('CPU MHz')) > -1: cpu['mhz'] = prop['data']
- if (prop['field'].find('CPU min MHz')) > -1: cpu['mhz_min'] = prop['data']
- if (prop['field'].find('CPU max MHz')) > -1: cpu['mhz_max'] = prop['data']
- if (prop['field'].find('Vendor ID')) > -1: cpu['vendor'] = prop['data']
- if (prop['field'].find('Model name')) > -1: cpu['model'] = prop['data']
-
-if len(cpu) > 0:
- tmp = { 'cpu':cpu }
+def get_raw_data():
+ cpu = {}
+ cpu_json, code = popen('lscpu -J', stderr=DEVNULL)
+
+ if code == 0:
+ cpu_info = json.loads(cpu_json)
+ if len(cpu_info) > 0 and 'lscpu' in cpu_info:
+ for prop in cpu_info['lscpu']:
+ if (prop['field'].find('Thread(s)') > -1): cpu['threads'] = prop['data']
+ if (prop['field'].find('Core(s)')) > -1: cpu['cores'] = prop['data']
+ if (prop['field'].find('Socket(s)')) > -1: cpu['sockets'] = prop['data']
+ if (prop['field'].find('CPU(s):')) > -1: cpu['cpus'] = prop['data']
+ if (prop['field'].find('CPU MHz')) > -1: cpu['mhz'] = prop['data']
+ if (prop['field'].find('CPU min MHz')) > -1: cpu['mhz_min'] = prop['data']
+ if (prop['field'].find('CPU max MHz')) > -1: cpu['mhz_max'] = prop['data']
+ if (prop['field'].find('Vendor ID')) > -1: cpu['vendor'] = prop['data']
+ if (prop['field'].find('Model name')) > -1: cpu['model'] = prop['data']
+
+ return cpu
+
+def get_formatted_output():
+ cpu = get_raw_data()
+
+ tmp = {'cpu':cpu}
tmpl = Template(OUT_TMPL_SRC)
- print(tmpl.render(tmp))
- exit(0)
-else:
- print('CPU information could not be determined\n')
- exit(1)
+ return tmpl.render(tmp)
+
+if __name__ == '__main__':
+ cpu = get_raw_data()
+
+ if len(cpu) > 0:
+ print(get_formatted_output())
+ else:
+ print('CPU information could not be determined\n')
+ exit(1)
+
diff --git a/src/op_mode/show_dhcp.py b/src/op_mode/show_dhcp.py
index cd6e8ed43..4b1758eea 100755
--- a/src/op_mode/show_dhcp.py
+++ b/src/op_mode/show_dhcp.py
@@ -26,6 +26,7 @@ from datetime import datetime
from isc_dhcp_leases import Lease, IscDhcpLeases
+from vyos.base import Warning
from vyos.config import Config
from vyos.util import is_systemd_service_running
@@ -213,7 +214,7 @@ if __name__ == '__main__':
# if dhcp server is down, inactive leases may still be shown as active, so warn the user.
if not is_systemd_service_running('isc-dhcp-server.service'):
- print("WARNING: DHCP server is configured but not started. Data may be stale.")
+ Warning('DHCP server is configured but not started. Data may be stale.')
if args.leases:
leases = get_leases(conf, lease_file, args.state, args.pool, args.sort)
diff --git a/src/op_mode/show_dhcpv6.py b/src/op_mode/show_dhcpv6.py
index 1f987ff7b..b34b730e6 100755
--- a/src/op_mode/show_dhcpv6.py
+++ b/src/op_mode/show_dhcpv6.py
@@ -26,6 +26,7 @@ from datetime import datetime
from isc_dhcp_leases import Lease, IscDhcpLeases
+from vyos.base import Warning
from vyos.config import Config
from vyos.util import is_systemd_service_running
@@ -203,7 +204,7 @@ if __name__ == '__main__':
# if dhcp server is down, inactive leases may still be shown as active, so warn the user.
if not is_systemd_service_running('isc-dhcp-server6.service'):
- print("WARNING: DHCPv6 server is configured but not started. Data may be stale.")
+ Warning('DHCPv6 server is configured but not started. Data may be stale.')
if args.leases:
leases = get_leases(conf, lease_file, args.state, args.pool, args.sort)
diff --git a/src/op_mode/show_ipsec_sa.py b/src/op_mode/show_ipsec_sa.py
index e72f0f965..5b8f00dba 100755
--- a/src/op_mode/show_ipsec_sa.py
+++ b/src/op_mode/show_ipsec_sa.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019 VyOS maintainers and contributors
+# Copyright (C) 2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -14,119 +14,117 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-import re
-import sys
+from re import split as re_split
+from sys import exit
-import vici
-import tabulate
-import hurry.filesize
+from hurry import filesize
+from tabulate import tabulate
+from vici import Session as vici_session
+
+from vyos.util import seconds_to_human
-import vyos.util
def convert(text):
return int(text) if text.isdigit() else text.lower()
+
def alphanum_key(key):
- return [convert(c) for c in re.split('([0-9]+)', str(key))]
+ return [convert(c) for c in re_split('([0-9]+)', str(key))]
-def format_output(conns, sas):
+
+def format_output(sas):
sa_data = []
- for peer, parent_conn in conns.items():
- if peer not in sas:
- continue
-
- parent_sa = sas[peer]
- child_sas = parent_sa['child-sas']
- installed_sas = {v['name'].decode(): v for k, v in child_sas.items() if v["state"] == b"INSTALLED"}
-
- # parent_sa["state"] = IKE state, child_sas["state"] = ESP state
- state = 'down'
- uptime = 'N/A'
-
- if parent_sa["state"] == b"ESTABLISHED" and installed_sas:
- state = "up"
-
- remote_host = parent_sa["remote-host"].decode()
- remote_id = parent_sa["remote-id"].decode()
-
- if remote_host == remote_id:
- remote_id = "N/A"
-
- # The counters can only be obtained from the child SAs
- for child_conn in parent_conn['children']:
- if child_conn not in installed_sas:
- data = [child_conn, "down", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A"]
- sa_data.append(data)
- continue
-
- isa = installed_sas[child_conn]
- csa_name = isa['name']
- csa_name = csa_name.decode()
-
- bytes_in = hurry.filesize.size(int(isa["bytes-in"].decode()))
- bytes_out = hurry.filesize.size(int(isa["bytes-out"].decode()))
- bytes_str = "{0}/{1}".format(bytes_in, bytes_out)
-
- pkts_in = hurry.filesize.size(int(isa["packets-in"].decode()), system=hurry.filesize.si)
- pkts_out = hurry.filesize.size(int(isa["packets-out"].decode()), system=hurry.filesize.si)
- pkts_str = "{0}/{1}".format(pkts_in, pkts_out)
- # Remove B from <1K values
- pkts_str = re.sub(r'B', r'', pkts_str)
-
- uptime = vyos.util.seconds_to_human(isa['install-time'].decode())
-
- enc = isa["encr-alg"].decode()
- if "encr-keysize" in isa:
- key_size = isa["encr-keysize"].decode()
- else:
- key_size = ""
- if "integ-alg" in isa:
- hash = isa["integ-alg"].decode()
- else:
- hash = ""
- if "dh-group" in isa:
- dh_group = isa["dh-group"].decode()
- else:
- dh_group = ""
-
- proposal = enc
- if key_size:
- proposal = "{0}_{1}".format(proposal, key_size)
- if hash:
- proposal = "{0}/{1}".format(proposal, hash)
- if dh_group:
- proposal = "{0}/{1}".format(proposal, dh_group)
-
- data = [csa_name, state, uptime, bytes_str, pkts_str, remote_host, remote_id, proposal]
- sa_data.append(data)
+ for sa in sas:
+ for parent_sa in sa.values():
+ # create an item for each child-sa
+ for child_sa in parent_sa.get('child-sas', {}).values():
+ # prepare a list for output data
+ sa_out_name = sa_out_state = sa_out_uptime = sa_out_bytes = sa_out_packets = sa_out_remote_addr = sa_out_remote_id = sa_out_proposal = 'N/A'
+
+ # collect raw data
+ sa_name = child_sa.get('name')
+ sa_state = child_sa.get('state')
+ sa_uptime = child_sa.get('install-time')
+ sa_bytes_in = child_sa.get('bytes-in')
+ sa_bytes_out = child_sa.get('bytes-out')
+ sa_packets_in = child_sa.get('packets-in')
+ sa_packets_out = child_sa.get('packets-out')
+ sa_remote_addr = parent_sa.get('remote-host')
+ sa_remote_id = parent_sa.get('remote-id')
+ sa_proposal_encr_alg = child_sa.get('encr-alg')
+ sa_proposal_integ_alg = child_sa.get('integ-alg')
+ sa_proposal_encr_keysize = child_sa.get('encr-keysize')
+ sa_proposal_dh_group = child_sa.get('dh-group')
+
+ # format data to display
+ if sa_name:
+ sa_out_name = sa_name.decode()
+ if sa_state:
+ if sa_state == b'INSTALLED':
+ sa_out_state = 'up'
+ else:
+ sa_out_state = 'down'
+ if sa_uptime:
+ sa_out_uptime = seconds_to_human(sa_uptime.decode())
+ if sa_bytes_in and sa_bytes_out:
+ bytes_in = filesize.size(int(sa_bytes_in.decode()))
+ bytes_out = filesize.size(int(sa_bytes_out.decode()))
+ sa_out_bytes = f'{bytes_in}/{bytes_out}'
+ if sa_packets_in and sa_packets_out:
+ packets_in = filesize.size(int(sa_packets_in.decode()),
+ system=filesize.si)
+ packets_out = filesize.size(int(sa_packets_out.decode()),
+ system=filesize.si)
+ sa_out_packets = f'{packets_in}/{packets_out}'
+ if sa_remote_addr:
+ sa_out_remote_addr = sa_remote_addr.decode()
+ if sa_remote_id:
+ sa_out_remote_id = sa_remote_id.decode()
+ # format proposal
+ if sa_proposal_encr_alg:
+ sa_out_proposal = sa_proposal_encr_alg.decode()
+ if sa_proposal_encr_keysize:
+ sa_proposal_encr_keysize_str = sa_proposal_encr_keysize.decode()
+ sa_out_proposal = f'{sa_out_proposal}_{sa_proposal_encr_keysize_str}'
+ if sa_proposal_integ_alg:
+ sa_proposal_integ_alg_str = sa_proposal_integ_alg.decode()
+ sa_out_proposal = f'{sa_out_proposal}/{sa_proposal_integ_alg_str}'
+ if sa_proposal_dh_group:
+ sa_proposal_dh_group_str = sa_proposal_dh_group.decode()
+ sa_out_proposal = f'{sa_out_proposal}/{sa_proposal_dh_group_str}'
+
+ # add a new item to output data
+ sa_data.append([
+ sa_out_name, sa_out_state, sa_out_uptime, sa_out_bytes,
+ sa_out_packets, sa_out_remote_addr, sa_out_remote_id,
+ sa_out_proposal
+ ])
+
+ # return output data
return sa_data
+
if __name__ == '__main__':
try:
- session = vici.Session()
- conns = {}
- sas = {}
+ session = vici_session()
+ sas = list(session.list_sas())
- for conn in session.list_conns():
- for key in conn:
- conns[key] = conn[key]
-
- for sa in session.list_sas():
- for key in sa:
- sas[key] = sa[key]
-
- headers = ["Connection", "State", "Uptime", "Bytes In/Out", "Packets In/Out", "Remote address", "Remote ID", "Proposal"]
- sa_data = format_output(conns, sas)
+ sa_data = format_output(sas)
sa_data = sorted(sa_data, key=alphanum_key)
- output = tabulate.tabulate(sa_data, headers)
+
+ headers = [
+ "Connection", "State", "Uptime", "Bytes In/Out", "Packets In/Out",
+ "Remote address", "Remote ID", "Proposal"
+ ]
+ output = tabulate(sa_data, headers)
print(output)
except PermissionError:
print("You do not have a permission to connect to the IPsec daemon")
- sys.exit(1)
+ exit(1)
except ConnectionRefusedError:
print("IPsec is not runing")
- sys.exit(1)
+ exit(1)
except Exception as e:
print("An error occured: {0}".format(e))
- sys.exit(1)
+ exit(1)
diff --git a/src/op_mode/show_nat_rules.py b/src/op_mode/show_nat_rules.py
index d68def26a..98adb31dd 100755
--- a/src/op_mode/show_nat_rules.py
+++ b/src/op_mode/show_nat_rules.py
@@ -32,7 +32,7 @@ args = parser.parse_args()
if args.source or args.destination:
tmp = cmd('sudo nft -j list table ip nat')
tmp = json.loads(tmp)
-
+
format_nat_rule = '{0: <10} {1: <50} {2: <50} {3: <10}'
print(format_nat_rule.format("Rule", "Source" if args.source else "Destination", "Translation", "Outbound Interface" if args.source else "Inbound Interface"))
print(format_nat_rule.format("----", "------" if args.source else "-----------", "-----------", "------------------" if args.source else "-----------------"))
@@ -40,7 +40,7 @@ if args.source or args.destination:
data_json = jmespath.search('nftables[?rule].rule[?chain]', tmp)
for idx in range(0, len(data_json)):
data = data_json[idx]
-
+
# The following key values must exist
# When the rule JSON does not have some keys, this is not a rule we can work with
continue_rule = False
@@ -50,9 +50,9 @@ if args.source or args.destination:
continue
if continue_rule:
continue
-
+
comment = data['comment']
-
+
# Check the annotation to see if the annotation format is created by VYOS
continue_rule = True
for comment_prefix in ['SRC-NAT-', 'DST-NAT-']:
@@ -60,7 +60,7 @@ if args.source or args.destination:
continue_rule = False
if continue_rule:
continue
-
+
rule = int(''.join(list(filter(str.isdigit, comment))))
chain = data['chain']
if not ((args.source and chain == 'POSTROUTING') or (not args.source and chain == 'PREROUTING')):
@@ -88,7 +88,7 @@ if args.source or args.destination:
else:
port_range = srcdest_json['set'][0]['range']
srcdest += 'port ' + str(port_range[0]) + '-' + str(port_range[1]) + ' '
-
+
tran_addr_json = dict_search('snat' if args.source else 'dnat', data['expr'][i])
if tran_addr_json:
if isinstance(tran_addr_json['addr'],str):
@@ -98,10 +98,10 @@ if args.source or args.destination:
len_tmp = dict_search('snat.addr.prefix.len' if args.source else 'dnat.addr.prefix.len', data['expr'][3])
if addr_tmp and len_tmp:
tran_addr += addr_tmp + '/' + str(len_tmp) + ' '
-
+
if isinstance(tran_addr_json['port'],int):
- tran_addr += 'port ' + tran_addr_json['port']
-
+ tran_addr += 'port ' + str(tran_addr_json['port'])
+
else:
if 'masquerade' in data['expr'][i]:
tran_addr = 'masquerade'
@@ -112,10 +112,10 @@ if args.source or args.destination:
srcdests.append(srcdest)
srcdest = ''
print(format_nat_rule.format(rule, srcdests[0], tran_addr, interface))
-
+
for i in range(1, len(srcdests)):
print(format_nat_rule.format(' ', srcdests[i], ' ', ' '))
-
+
exit(0)
else:
parser.print_help()
diff --git a/src/op_mode/show_openvpn.py b/src/op_mode/show_openvpn.py
index f7b99cc0d..9a5adcffb 100755
--- a/src/op_mode/show_openvpn.py
+++ b/src/op_mode/show_openvpn.py
@@ -26,10 +26,10 @@ outp_tmpl = """
{% if clients %}
OpenVPN status on {{ intf }}
-Client CN Remote Host Local Host TX bytes RX bytes Connected Since
---------- ----------- ---------- -------- -------- ---------------
+Client CN Remote Host Tunnel IP Local Host TX bytes RX bytes Connected Since
+--------- ----------- --------- ---------- -------- -------- ---------------
{% for c in clients %}
-{{ "%-15s"|format(c.name) }} {{ "%-21s"|format(c.remote) }} {{ "%-21s"|format(local) }} {{ "%-9s"|format(c.tx_bytes) }} {{ "%-9s"|format(c.rx_bytes) }} {{ c.online_since }}
+{{ "%-15s"|format(c.name) }} {{ "%-21s"|format(c.remote) }} {{ "%-15s"|format(c.tunnel) }} {{ "%-21s"|format(local) }} {{ "%-9s"|format(c.tx_bytes) }} {{ "%-9s"|format(c.rx_bytes) }} {{ c.online_since }}
{% endfor %}
{% endif %}
"""
@@ -50,6 +50,19 @@ def bytes2HR(size):
output="{0:.1f} {1}".format(size, suff[suffIdx])
return output
+def get_vpn_tunnel_address(peer, interface):
+ lst = []
+ status_file = '/var/run/openvpn/{}.status'.format(interface)
+
+ with open(status_file, 'r') as f:
+ lines = f.readlines()
+ for line in lines:
+ if peer in line:
+ lst.append(line)
+ tunnel_ip = lst[1].split(',')[0]
+
+ return tunnel_ip
+
def get_status(mode, interface):
status_file = '/var/run/openvpn/{}.status'.format(interface)
# this is an empirical value - I assume we have no more then 999999
@@ -110,7 +123,7 @@ def get_status(mode, interface):
'tx_bytes': bytes2HR(line.split(',')[3]),
'online_since': line.split(',')[4]
}
-
+ client["tunnel"] = get_vpn_tunnel_address(client['remote'], interface)
data['clients'].append(client)
continue
else:
@@ -173,5 +186,7 @@ if __name__ == '__main__':
if len(remote_host) >= 1:
client['remote'] = str(remote_host[0]) + ':' + remote_port
+ client['tunnel'] = 'N/A'
+
tmpl = jinja2.Template(outp_tmpl)
print(tmpl.render(data))
diff --git a/src/op_mode/show_ram.py b/src/op_mode/show_ram.py
index 5818ec132..2b0be3965 100755
--- a/src/op_mode/show_ram.py
+++ b/src/op_mode/show_ram.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -55,10 +55,17 @@ def get_system_memory_human():
return mem
-if __name__ == '__main__':
- mem = get_system_memory_human()
+def get_raw_data():
+ return get_system_memory_human()
+
+def get_formatted_output():
+ mem = get_raw_data()
- print("Total: {}".format(mem["total"]))
- print("Free: {}".format(mem["free"]))
- print("Used: {}".format(mem["used"]))
+ out = "Total: {}\n".format(mem["total"])
+ out += "Free: {}\n".format(mem["free"])
+ out += "Used: {}".format(mem["used"])
+ return out
+
+if __name__ == '__main__':
+ print(get_formatted_output())
diff --git a/src/op_mode/show_uptime.py b/src/op_mode/show_uptime.py
index c3dea52e6..b70c60cf8 100755
--- a/src/op_mode/show_uptime.py
+++ b/src/op_mode/show_uptime.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
@@ -26,25 +26,41 @@ def get_uptime_seconds():
def get_load_averages():
from re import search
from vyos.util import cmd
+ from vyos.cpu import get_core_count
data = cmd("uptime")
matches = search(r"load average:\s*(?P<one>[0-9\.]+)\s*,\s*(?P<five>[0-9\.]+)\s*,\s*(?P<fifteen>[0-9\.]+)\s*", data)
+ core_count = get_core_count()
+
res = {}
- res[1] = float(matches["one"])
- res[5] = float(matches["five"])
- res[15] = float(matches["fifteen"])
+ res[1] = float(matches["one"]) / core_count
+ res[5] = float(matches["five"]) / core_count
+ res[15] = float(matches["fifteen"]) / core_count
return res
-if __name__ == '__main__':
+def get_raw_data():
from vyos.util import seconds_to_human
- print("Uptime: {}\n".format(seconds_to_human(get_uptime_seconds())))
+ res = {}
+ res["uptime_seconds"] = get_uptime_seconds()
+ res["uptime"] = seconds_to_human(get_uptime_seconds())
+ res["load_average"] = get_load_averages()
+
+ return res
+
+def get_formatted_output():
+ data = get_raw_data()
- avgs = get_load_averages()
+ out = "Uptime: {}\n\n".format(data["uptime"])
+ avgs = data["load_average"]
+ out += "Load averages:\n"
+ out += "1 minute: {:.01f}%\n".format(avgs[1]*100)
+ out += "5 minutes: {:.01f}%\n".format(avgs[5]*100)
+ out += "15 minutes: {:.01f}%\n".format(avgs[15]*100)
- print("Load averages:")
- print("1 minute: {:.02f}%".format(avgs[1]*100))
- print("5 minutes: {:.02f}%".format(avgs[5]*100))
- print("15 minutes: {:.02f}%".format(avgs[15]*100))
+ return out
+
+if __name__ == '__main__':
+ print(get_formatted_output())
diff --git a/src/op_mode/show_version.py b/src/op_mode/show_version.py
index 7962e1e7b..b82ab6eca 100755
--- a/src/op_mode/show_version.py
+++ b/src/op_mode/show_version.py
@@ -26,10 +26,6 @@ from jinja2 import Template
from sys import exit
from vyos.util import call
-parser = argparse.ArgumentParser()
-parser.add_argument("-f", "--funny", action="store_true", help="Add something funny to the output")
-parser.add_argument("-j", "--json", action="store_true", help="Produce JSON output")
-
version_output_tmpl = """
Version: VyOS {{version}}
Release train: {{release_train}}
@@ -51,7 +47,20 @@ Hardware UUID: {{hardware_uuid}}
Copyright: VyOS maintainers and contributors
"""
+def get_raw_data():
+ version_data = vyos.version.get_full_version_data()
+ return version_data
+
+def get_formatted_output():
+ version_data = get_raw_data()
+ tmpl = Template(version_output_tmpl)
+ return tmpl.render(version_data)
+
if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-f", "--funny", action="store_true", help="Add something funny to the output")
+ parser.add_argument("-j", "--json", action="store_true", help="Produce JSON output")
+
args = parser.parse_args()
version_data = vyos.version.get_full_version_data()
@@ -60,9 +69,8 @@ if __name__ == '__main__':
import json
print(json.dumps(version_data))
exit(0)
-
- tmpl = Template(version_output_tmpl)
- print(tmpl.render(version_data))
+ else:
+ print(get_formatted_output())
if args.funny:
print(vyos.limericks.get_random())
diff --git a/src/op_mode/show_virtual_server.py b/src/op_mode/show_virtual_server.py
new file mode 100755
index 000000000..377180dec
--- /dev/null
+++ b/src/op_mode/show_virtual_server.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+from vyos.configquery import ConfigTreeQuery
+from vyos.util import call
+
+def is_configured():
+ """ Check if high-availability virtual-server is configured """
+ config = ConfigTreeQuery()
+ if not config.exists(['high-availability', 'virtual-server']):
+ return False
+ return True
+
+if __name__ == '__main__':
+
+ if is_configured() == False:
+ print('Virtual server not configured!')
+ exit(0)
+
+ call('sudo ipvsadm --list --numeric')
diff --git a/src/op_mode/traceroute.py b/src/op_mode/traceroute.py
new file mode 100755
index 000000000..4299d6e5f
--- /dev/null
+++ b/src/op_mode/traceroute.py
@@ -0,0 +1,207 @@
+#! /usr/bin/env python3
+
+# Copyright (C) 2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import sys
+import socket
+import ipaddress
+
+options = {
+ 'backward-hops': {
+ 'traceroute': '{command} --back',
+ 'type': 'noarg',
+ 'help': 'Display number of backward hops when they different from the forwarded path'
+ },
+ 'bypass': {
+ 'traceroute': '{command} -r',
+ 'type': 'noarg',
+ 'help': 'Bypass the normal routing tables and send directly to a host on an attached network'
+ },
+ 'do-not-fragment': {
+ 'traceroute': '{command} -F',
+ 'type': 'noarg',
+ 'help': 'Do not fragment probe packets.'
+ },
+ 'first-ttl': {
+ 'traceroute': '{command} -f {value}',
+ 'type': '<ttl>',
+ 'help': 'Specifies with what TTL to start. Defaults to 1.'
+ },
+ 'icmp': {
+ 'traceroute': '{command} -I',
+ 'type': 'noarg',
+ 'help': 'Use ICMP ECHO for tracerouting'
+ },
+ 'interface': {
+ 'traceroute': '{command} -i {value}',
+ 'type': '<interface>',
+ 'help': 'Source interface'
+ },
+ 'lookup-as': {
+ 'traceroute': '{command} -A',
+ 'type': 'noarg',
+ 'help': 'Perform AS path lookups'
+ },
+ 'mark': {
+ 'traceroute': '{command} --fwmark={value}',
+ 'type': '<fwmark>',
+ 'help': 'Set the firewall mark for outgoing packets'
+ },
+ 'no-resolve': {
+ 'traceroute': '{command} -n',
+ 'type': 'noarg',
+ 'help': 'Do not resolve hostnames'
+ },
+ 'port': {
+ 'traceroute': '{command} -p {value}',
+ 'type': '<port>',
+ 'help': 'Destination port'
+ },
+ 'source-address': {
+ 'traceroute': '{command} -s {value}',
+ 'type': '<x.x.x.x> <h:h:h:h:h:h:h:h>',
+ 'help': 'Specify source IP v4/v6 address'
+ },
+ 'tcp': {
+ 'traceroute': '{command} -T',
+ 'type': 'noarg',
+ 'help': 'Use TCP SYN for tracerouting (default port is 80)'
+ },
+ 'tos': {
+ 'traceroute': '{commad} -t {value}',
+ 'type': '<tos>',
+ 'help': 'Mark packets with specified TOS'
+ },
+ 'ttl': {
+ 'traceroute': '{command} -m {value}',
+ 'type': '<ttl>',
+ 'help': 'Maximum number of hops'
+ },
+ 'udp': {
+ 'traceroute': '{command} -U',
+ 'type': 'noarg',
+ 'help': 'Use UDP to particular port for tracerouting (default port is 53)'
+ },
+ 'vrf': {
+ 'traceroute': 'sudo ip vrf exec {value} {command}',
+ 'type': '<vrf>',
+ 'help': 'Use specified VRF table',
+ 'dflt': 'default'}
+}
+
+traceroute = {
+ 4: '/bin/traceroute -4',
+ 6: '/bin/traceroute -6',
+}
+
+
+class List (list):
+ def first (self):
+ return self.pop(0) if self else ''
+
+ def last(self):
+ return self.pop() if self else ''
+
+ def prepend(self,value):
+ self.insert(0,value)
+
+
+def expension_failure(option, completions):
+ reason = 'Ambiguous' if completions else 'Invalid'
+ sys.stderr.write('\n\n {} command: {} [{}]\n\n'.format(reason,' '.join(sys.argv), option))
+ if completions:
+ sys.stderr.write(' Possible completions:\n ')
+ sys.stderr.write('\n '.join(completions))
+ sys.stderr.write('\n')
+ sys.stdout.write('<nocomps>')
+ sys.exit(1)
+
+
+def complete(prefix):
+ return [o for o in options if o.startswith(prefix)]
+
+
+def convert(command, args):
+ while args:
+ shortname = args.first()
+ longnames = complete(shortname)
+ if len(longnames) != 1:
+ expension_failure(shortname, longnames)
+ longname = longnames[0]
+ if options[longname]['type'] == 'noarg':
+ command = options[longname]['traceroute'].format(
+ command=command, value='')
+ elif not args:
+ sys.exit(f'traceroute: missing argument for {longname} option')
+ else:
+ command = options[longname]['traceroute'].format(
+ command=command, value=args.first())
+ return command
+
+
+if __name__ == '__main__':
+ args = List(sys.argv[1:])
+ host = args.first()
+
+ if not host:
+ sys.exit("traceroute: Missing host")
+
+ if host == '--get-options':
+ args.first() # pop traceroute
+ args.first() # pop IP
+ while args:
+ option = args.first()
+
+ matched = complete(option)
+ if not args:
+ sys.stdout.write(' '.join(matched))
+ sys.exit(0)
+
+ if len(matched) > 1 :
+ sys.stdout.write(' '.join(matched))
+ sys.exit(0)
+
+ if options[matched[0]]['type'] == 'noarg':
+ continue
+
+ value = args.first()
+ if not args:
+ matched = complete(option)
+ sys.stdout.write(options[matched[0]]['type'])
+ sys.exit(0)
+
+ for name,option in options.items():
+ if 'dflt' in option and name not in args:
+ args.append(name)
+ args.append(option['dflt'])
+
+ try:
+ ip = socket.gethostbyname(host)
+ except UnicodeError:
+ sys.exit(f'tracroute: Unknown host: {host}')
+ except socket.gaierror:
+ ip = host
+
+ try:
+ version = ipaddress.ip_address(ip).version
+ except ValueError:
+ sys.exit(f'traceroute: Unknown host: {host}')
+
+ command = convert(traceroute[version],args)
+
+ # print(f'{command} {host}')
+ os.system(f'{command} {host}')
+
diff --git a/src/op_mode/vpn_ipsec.py b/src/op_mode/vpn_ipsec.py
index 40854fa8f..8955e5a59 100755
--- a/src/op_mode/vpn_ipsec.py
+++ b/src/op_mode/vpn_ipsec.py
@@ -88,7 +88,22 @@ def reset_profile(profile, tunnel):
def debug_peer(peer, tunnel):
if not peer or peer == "all":
- call('sudo /usr/sbin/ipsec statusall')
+ debug_commands = [
+ "sudo ipsec statusall",
+ "sudo swanctl -L",
+ "sudo swanctl -l",
+ "sudo swanctl -P",
+ "sudo ip x sa show",
+ "sudo ip x policy show",
+ "sudo ip tunnel show",
+ "sudo ip address",
+ "sudo ip rule show",
+ "sudo ip route | head -100",
+ "sudo ip route show table 220"
+ ]
+ for debug_cmd in debug_commands:
+ print(f'\n### {debug_cmd} ###')
+ call(debug_cmd)
return
if not tunnel or tunnel == 'all':
diff --git a/src/op_mode/vrrp.py b/src/op_mode/vrrp.py
index 2c1db20bf..dab146d28 100755
--- a/src/op_mode/vrrp.py
+++ b/src/op_mode/vrrp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018 VyOS maintainers and contributors
+# Copyright (C) 2018-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -23,6 +23,7 @@ import tabulate
import vyos.util
+from vyos.configquery import ConfigTreeQuery
from vyos.ifconfig.vrrp import VRRP
from vyos.ifconfig.vrrp import VRRPError, VRRPNoData
@@ -35,7 +36,17 @@ group.add_argument("-d", "--data", action="store_true", help="Print detailed VRR
args = parser.parse_args()
+def is_configured():
+ """ Check if VRRP is configured """
+ config = ConfigTreeQuery()
+ if not config.exists(['high-availability', 'vrrp', 'group']):
+ return False
+ return True
+
# Exit early if VRRP is dead or not configured
+if is_configured() == False:
+ print('VRRP not configured!')
+ exit(0)
if not VRRP.is_running():
print('VRRP is not running')
sys.exit(0)
diff --git a/src/op_mode/zone_policy.py b/src/op_mode/zone_policy.py
new file mode 100755
index 000000000..7b43018c2
--- /dev/null
+++ b/src/op_mode/zone_policy.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import argparse
+import tabulate
+
+from vyos.config import Config
+from vyos.util import dict_search_args
+
+def get_config_zone(conf, name=None):
+ config_path = ['zone-policy']
+ if name:
+ config_path += ['zone', name]
+
+ zone_policy = conf.get_config_dict(config_path, key_mangling=('-', '_'),
+ get_first_key=True, no_tag_node_value_mangle=True)
+ return zone_policy
+
+def output_zone_name(zone, zone_conf):
+ print(f'\n---------------------------------\nZone: "{zone}"\n')
+
+ interfaces = ', '.join(zone_conf['interface']) if 'interface' in zone_conf else ''
+ if 'local_zone' in zone_conf:
+ interfaces = 'LOCAL'
+
+ print(f'Interfaces: {interfaces}\n')
+
+ header = ['From Zone', 'Firewall']
+ rows = []
+
+ if 'from' in zone_conf:
+ for from_name, from_conf in zone_conf['from'].items():
+ row = [from_name]
+ v4_name = dict_search_args(from_conf, 'firewall', 'name')
+ v6_name = dict_search_args(from_conf, 'firewall', 'ipv6_name')
+
+ if v4_name:
+ rows.append(row + [v4_name])
+
+ if v6_name:
+ rows.append(row + [f'{v6_name} [IPv6]'])
+
+ if rows:
+ print('From Zones:\n')
+ print(tabulate.tabulate(rows, header))
+
+def show_zone_policy(zone):
+ conf = Config()
+ zone_policy = get_config_zone(conf, zone)
+
+ if not zone_policy:
+ return
+
+ if 'zone' in zone_policy:
+ for zone, zone_conf in zone_policy['zone'].items():
+ output_zone_name(zone, zone_conf)
+ elif zone:
+ output_zone_name(zone, zone_policy)
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--action', help='Action', required=False)
+ parser.add_argument('--name', help='Zone name', required=False, action='store', nargs='?', default='')
+
+ args = parser.parse_args()
+
+ if args.action == 'show':
+ show_zone_policy(args.name)
diff --git a/src/services/api/graphql/README.graphql b/src/services/api/graphql/README.graphql
index 29f58f709..1133d79ed 100644
--- a/src/services/api/graphql/README.graphql
+++ b/src/services/api/graphql/README.graphql
@@ -1,7 +1,12 @@
+The following examples are in the form as entered in the GraphQL
+'playground', which is found at:
+
+https://{{ host_address }}/graphql
+
Example using GraphQL mutations to configure a DHCP server:
-This assumes that the http-api is running:
+All examples assume that the http-api is running:
'set service https api'
@@ -58,8 +63,8 @@ N.B. fileName can be empty (fileName: "") or data can be empty (data: {}) to
save to /config/config.boot; to save to an alternative path, specify
fileName.
-Similarly, using the same 'endpoint' (meaning the form of the request and
-resolver; the actual enpoint for all GraphQL requests is
+Similarly, using an analogous 'endpoint' (meaning the form of the request
+and resolver; the actual enpoint for all GraphQL requests is
https://hostname/graphql), one can load an arbitrary config file from a
path.
@@ -73,17 +78,73 @@ mutation {
}
}
+Op-mode 'show' commands may be requested by path, e.g.:
+
+query {
+ Show (data: {path: ["interfaces", "ethernet", "detail"]}) {
+ success
+ errors
+ data {
+ result
+ }
+ }
+}
-The GraphQL playground will be found at:
+N.B. to see the output the 'data' field 'result' must be present in the
+request.
-https://{{ host_address }}/graphql
+Mutations to manipulate firewall address groups:
-An equivalent curl command to the first example above would be:
+mutation {
+ CreateFirewallAddressGroup (data: {name: "ADDR-GRP", address: "10.0.0.1"}) {
+ success
+ errors
+ }
+}
+
+mutation {
+ UpdateFirewallAddressGroupMembers (data: {name: "ADDR-GRP",
+ address: ["10.0.0.1-10.0.0.8", "192.168.0.1"]}) {
+ success
+ errors
+ }
+}
+
+mutation {
+ RemoveFirewallAddressGroupMembers (data: {name: "ADDR-GRP",
+ address: "192.168.0.1"}) {
+ success
+ errors
+ }
+}
+
+N.B. The schema for the above specify that 'address' be of the form 'list of
+strings' (SDL type [String!]! for UpdateFirewallAddressGroupMembers, where
+the ! indicates that the input is required; SDL type [String] in
+CreateFirewallAddressGroup, since a group may be created without any
+addresses). However, notice that a single string may be passed without being
+a member of a list, in which case the specification allows for 'input
+coercion':
+
+http://spec.graphql.org/October2021/#sec-Scalars.Input-Coercion
+
+Similarly, IPv6 versions of the above:
+
+CreateFirewallAddressIpv6Group
+UpdateFirewallAddressIpv6GroupMembers
+RemoveFirewallAddressIpv6GroupMembers
+
+
+Instead of using the GraphQL playground, an equivalent curl command to the
+first example above would be:
curl -k 'https://192.168.100.168/graphql' -H 'Content-Type: application/json' --data-binary '{"query": "mutation {createInterfaceEthernet (data: {interface: \"eth1\", address: \"192.168.0.1/24\", description: \"BOB\"}) {success errors data {address}}}"}'
Note that the 'mutation' term is prefaced by 'query' in the curl command.
+Curl equivalents may be read from within the GraphQL playground at the 'copy
+curl' button.
+
What's here:
services
@@ -97,15 +158,22 @@ services
│   │   └── schema
│   │   ├── config_file.graphql
│   │   ├── dhcp_server.graphql
+│   │   ├── firewall_group.graphql
│   │   ├── interface_ethernet.graphql
-│   │   └── schema.graphql
+│   │   ├── schema.graphql
+│   │   ├── show_config.graphql
+│   │   └── show.graphql
│   ├── README.graphql
│   ├── recipes
│   │   ├── __init__.py
+│   │   ├── remove_firewall_address_group_members.py
│   │   ├── session.py
│   │   └── templates
│   │   ├── create_dhcp_server.tmpl
-│   │   └── create_interface_ethernet.tmpl
+│   │   ├── create_firewall_address_group.tmpl
+│   │   ├── create_interface_ethernet.tmpl
+│   │   ├── remove_firewall_address_group_members.tmpl
+│   │   └── update_firewall_address_group_members.tmpl
│   └── state.py
├── vyos-configd
├── vyos-hostsd
diff --git a/src/services/api/graphql/bindings.py b/src/services/api/graphql/bindings.py
index 1fbe13d0c..84d719fda 100644
--- a/src/services/api/graphql/bindings.py
+++ b/src/services/api/graphql/bindings.py
@@ -1,4 +1,20 @@
+# Copyright 2021 VyOS maintainers and contributors <maintainers@vyos.io>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
+
import vyos.defaults
+from . graphql.queries import query
from . graphql.mutations import mutation
from . graphql.directives import directives_dict
from ariadne import make_executable_schema, load_schema_from_path, snake_case_fallback_resolvers
@@ -8,6 +24,6 @@ def generate_schema():
type_defs = load_schema_from_path(api_schema_dir)
- schema = make_executable_schema(type_defs, mutation, snake_case_fallback_resolvers, directives=directives_dict)
+ schema = make_executable_schema(type_defs, query, mutation, snake_case_fallback_resolvers, directives=directives_dict)
return schema
diff --git a/src/services/api/graphql/graphql/directives.py b/src/services/api/graphql/graphql/directives.py
index f5cd88acd..0a9298f55 100644
--- a/src/services/api/graphql/graphql/directives.py
+++ b/src/services/api/graphql/graphql/directives.py
@@ -1,5 +1,21 @@
+# Copyright 2021 VyOS maintainers and contributors <maintainers@vyos.io>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
+
from ariadne import SchemaDirectiveVisitor, ObjectType
-from . mutations import make_configure_resolver, make_config_file_resolver
+from . queries import *
+from . mutations import *
def non(arg):
pass
@@ -19,19 +35,45 @@ class VyosDirective(SchemaDirectiveVisitor):
class ConfigureDirective(VyosDirective):
"""
Class providing implementation of 'configure' directive in schema.
-
"""
def visit_field_definition(self, field, object_type):
super().visit_field_definition(field, object_type,
make_resolver=make_configure_resolver)
+class ShowConfigDirective(VyosDirective):
+ """
+ Class providing implementation of 'show' directive in schema.
+ """
+ def visit_field_definition(self, field, object_type):
+ super().visit_field_definition(field, object_type,
+ make_resolver=make_show_config_resolver)
+
class ConfigFileDirective(VyosDirective):
"""
Class providing implementation of 'configfile' directive in schema.
-
"""
def visit_field_definition(self, field, object_type):
super().visit_field_definition(field, object_type,
make_resolver=make_config_file_resolver)
-directives_dict = {"configure": ConfigureDirective, "configfile": ConfigFileDirective}
+class ShowDirective(VyosDirective):
+ """
+ Class providing implementation of 'show' directive in schema.
+ """
+ def visit_field_definition(self, field, object_type):
+ super().visit_field_definition(field, object_type,
+ make_resolver=make_show_resolver)
+
+class ImageDirective(VyosDirective):
+ """
+ Class providing implementation of 'image' directive in schema.
+ """
+ def visit_field_definition(self, field, object_type):
+ super().visit_field_definition(field, object_type,
+ make_resolver=make_image_resolver)
+
+directives_dict = {"configure": ConfigureDirective,
+ "showconfig": ShowConfigDirective,
+ "configfile": ConfigFileDirective,
+ "show": ShowDirective,
+ "image": ImageDirective}
diff --git a/src/services/api/graphql/graphql/mutations.py b/src/services/api/graphql/graphql/mutations.py
index 8a28b13d7..0c3eb702a 100644
--- a/src/services/api/graphql/graphql/mutations.py
+++ b/src/services/api/graphql/graphql/mutations.py
@@ -1,3 +1,17 @@
+# Copyright 2021 VyOS maintainers and contributors <maintainers@vyos.io>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
from importlib import import_module
from typing import Any, Dict
@@ -10,7 +24,7 @@ from api.graphql.recipes.session import Session
mutation = ObjectType("Mutation")
-def make_resolver(mutation_name, class_name, session_func):
+def make_mutation_resolver(mutation_name, class_name, session_func):
"""Dynamically generate a resolver for the mutation named in the
schema by 'mutation_name'.
@@ -51,7 +65,8 @@ def make_resolver(mutation_name, class_name, session_func):
klass = type(class_name, (Session,), {})
k = klass(session, data)
method = getattr(k, session_func)
- method()
+ result = method()
+ data['result'] = result
return {
"success": True,
@@ -65,16 +80,20 @@ def make_resolver(mutation_name, class_name, session_func):
return func_impl
+def make_prefix_resolver(mutation_name, prefix=[]):
+ for pre in prefix:
+ Pre = pre.capitalize()
+ if Pre in mutation_name:
+ class_name = mutation_name.replace(Pre, '', 1)
+ return make_mutation_resolver(mutation_name, class_name, pre)
+ raise Exception
+
def make_configure_resolver(mutation_name):
class_name = mutation_name
- return make_resolver(mutation_name, class_name, 'configure')
+ return make_mutation_resolver(mutation_name, class_name, 'configure')
def make_config_file_resolver(mutation_name):
- if 'Save' in mutation_name:
- class_name = mutation_name.replace('Save', '', 1)
- return make_resolver(mutation_name, class_name, 'save')
- elif 'Load' in mutation_name:
- class_name = mutation_name.replace('Load', '', 1)
- return make_resolver(mutation_name, class_name, 'load')
- else:
- raise Exception
+ return make_prefix_resolver(mutation_name, prefix=['save', 'load'])
+
+def make_image_resolver(mutation_name):
+ return make_prefix_resolver(mutation_name, prefix=['add', 'delete'])
diff --git a/src/services/api/graphql/graphql/queries.py b/src/services/api/graphql/graphql/queries.py
new file mode 100644
index 000000000..e1868091e
--- /dev/null
+++ b/src/services/api/graphql/graphql/queries.py
@@ -0,0 +1,89 @@
+# Copyright 2021 VyOS maintainers and contributors <maintainers@vyos.io>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
+
+from importlib import import_module
+from typing import Any, Dict
+from ariadne import ObjectType, convert_kwargs_to_snake_case, convert_camel_case_to_snake
+from graphql import GraphQLResolveInfo
+from makefun import with_signature
+
+from .. import state
+from api.graphql.recipes.session import Session
+
+query = ObjectType("Query")
+
+def make_query_resolver(query_name, class_name, session_func):
+ """Dynamically generate a resolver for the query named in the
+ schema by 'query_name'.
+
+ Dynamic generation is provided using the package 'makefun' (via the
+ decorator 'with_signature'), which provides signature-preserving
+ function wrappers; it provides several improvements over, say,
+ functools.wraps.
+
+ :raise Exception:
+ raising ConfigErrors, or internal errors
+ """
+
+ func_base_name = convert_camel_case_to_snake(class_name)
+ resolver_name = f'resolve_{func_base_name}'
+ func_sig = '(obj: Any, info: GraphQLResolveInfo, data: Dict)'
+
+ @query.field(query_name)
+ @convert_kwargs_to_snake_case
+ @with_signature(func_sig, func_name=resolver_name)
+ async def func_impl(*args, **kwargs):
+ try:
+ if 'data' not in kwargs:
+ return {
+ "success": False,
+ "errors": ['missing data']
+ }
+
+ data = kwargs['data']
+ session = state.settings['app'].state.vyos_session
+
+ # one may override the session functions with a local subclass
+ try:
+ mod = import_module(f'api.graphql.recipes.{func_base_name}')
+ klass = getattr(mod, class_name)
+ except ImportError:
+ # otherwise, dynamically generate subclass to invoke subclass
+ # name based templates
+ klass = type(class_name, (Session,), {})
+ k = klass(session, data)
+ method = getattr(k, session_func)
+ result = method()
+ data['result'] = result
+
+ return {
+ "success": True,
+ "data": data
+ }
+ except Exception as error:
+ return {
+ "success": False,
+ "errors": [str(error)]
+ }
+
+ return func_impl
+
+def make_show_config_resolver(query_name):
+ class_name = query_name
+ return make_query_resolver(query_name, class_name, 'show_config')
+
+def make_show_resolver(query_name):
+ class_name = query_name
+ return make_query_resolver(query_name, class_name, 'show')
diff --git a/src/services/api/graphql/graphql/schema/firewall_group.graphql b/src/services/api/graphql/graphql/schema/firewall_group.graphql
index efe7de632..d89904b9e 100644
--- a/src/services/api/graphql/graphql/schema/firewall_group.graphql
+++ b/src/services/api/graphql/graphql/schema/firewall_group.graphql
@@ -45,3 +45,51 @@ type RemoveFirewallAddressGroupMembersResult {
success: Boolean!
errors: [String]
}
+
+input CreateFirewallAddressIpv6GroupInput {
+ name: String!
+ address: [String]
+}
+
+type CreateFirewallAddressIpv6Group {
+ name: String!
+ address: [String]
+}
+
+type CreateFirewallAddressIpv6GroupResult {
+ data: CreateFirewallAddressIpv6Group
+ success: Boolean!
+ errors: [String]
+}
+
+input UpdateFirewallAddressIpv6GroupMembersInput {
+ name: String!
+ address: [String!]!
+}
+
+type UpdateFirewallAddressIpv6GroupMembers {
+ name: String!
+ address: [String!]!
+}
+
+type UpdateFirewallAddressIpv6GroupMembersResult {
+ data: UpdateFirewallAddressIpv6GroupMembers
+ success: Boolean!
+ errors: [String]
+}
+
+input RemoveFirewallAddressIpv6GroupMembersInput {
+ name: String!
+ address: [String!]!
+}
+
+type RemoveFirewallAddressIpv6GroupMembers {
+ name: String!
+ address: [String!]!
+}
+
+type RemoveFirewallAddressIpv6GroupMembersResult {
+ data: RemoveFirewallAddressIpv6GroupMembers
+ success: Boolean!
+ errors: [String]
+}
diff --git a/src/services/api/graphql/graphql/schema/image.graphql b/src/services/api/graphql/graphql/schema/image.graphql
new file mode 100644
index 000000000..7d1b4f9d0
--- /dev/null
+++ b/src/services/api/graphql/graphql/schema/image.graphql
@@ -0,0 +1,29 @@
+input AddSystemImageInput {
+ location: String!
+}
+
+type AddSystemImage {
+ location: String
+ result: String
+}
+
+type AddSystemImageResult {
+ data: AddSystemImage
+ success: Boolean!
+ errors: [String]
+}
+
+input DeleteSystemImageInput {
+ name: String!
+}
+
+type DeleteSystemImage {
+ name: String
+ result: String
+}
+
+type DeleteSystemImageResult {
+ data: DeleteSystemImage
+ success: Boolean!
+ errors: [String]
+}
diff --git a/src/services/api/graphql/graphql/schema/schema.graphql b/src/services/api/graphql/graphql/schema/schema.graphql
index 9e97a0d60..952e46f34 100644
--- a/src/services/api/graphql/graphql/schema/schema.graphql
+++ b/src/services/api/graphql/graphql/schema/schema.graphql
@@ -3,12 +3,16 @@ schema {
mutation: Mutation
}
-type Query {
- _dummy: String
-}
-
directive @configure on FIELD_DEFINITION
directive @configfile on FIELD_DEFINITION
+directive @show on FIELD_DEFINITION
+directive @showconfig on FIELD_DEFINITION
+directive @image on FIELD_DEFINITION
+
+type Query {
+ Show(data: ShowInput) : ShowResult @show
+ ShowConfig(data: ShowConfigInput) : ShowConfigResult @showconfig
+}
type Mutation {
CreateDhcpServer(data: DhcpServerConfigInput) : CreateDhcpServerResult @configure
@@ -16,6 +20,11 @@ type Mutation {
CreateFirewallAddressGroup(data: CreateFirewallAddressGroupInput) : CreateFirewallAddressGroupResult @configure
UpdateFirewallAddressGroupMembers(data: UpdateFirewallAddressGroupMembersInput) : UpdateFirewallAddressGroupMembersResult @configure
RemoveFirewallAddressGroupMembers(data: RemoveFirewallAddressGroupMembersInput) : RemoveFirewallAddressGroupMembersResult @configure
+ CreateFirewallAddressIpv6Group(data: CreateFirewallAddressIpv6GroupInput) : CreateFirewallAddressIpv6GroupResult @configure
+ UpdateFirewallAddressIpv6GroupMembers(data: UpdateFirewallAddressIpv6GroupMembersInput) : UpdateFirewallAddressIpv6GroupMembersResult @configure
+ RemoveFirewallAddressIpv6GroupMembers(data: RemoveFirewallAddressIpv6GroupMembersInput) : RemoveFirewallAddressIpv6GroupMembersResult @configure
SaveConfigFile(data: SaveConfigFileInput) : SaveConfigFileResult @configfile
LoadConfigFile(data: LoadConfigFileInput) : LoadConfigFileResult @configfile
+ AddSystemImage(data: AddSystemImageInput) : AddSystemImageResult @image
+ DeleteSystemImage(data: DeleteSystemImageInput) : DeleteSystemImageResult @image
}
diff --git a/src/services/api/graphql/graphql/schema/show.graphql b/src/services/api/graphql/graphql/schema/show.graphql
new file mode 100644
index 000000000..c7709e48b
--- /dev/null
+++ b/src/services/api/graphql/graphql/schema/show.graphql
@@ -0,0 +1,14 @@
+input ShowInput {
+ path: [String!]!
+}
+
+type Show {
+ path: [String]
+ result: String
+}
+
+type ShowResult {
+ data: Show
+ success: Boolean!
+ errors: [String]
+}
diff --git a/src/services/api/graphql/graphql/schema/show_config.graphql b/src/services/api/graphql/graphql/schema/show_config.graphql
new file mode 100644
index 000000000..34afd2aa9
--- /dev/null
+++ b/src/services/api/graphql/graphql/schema/show_config.graphql
@@ -0,0 +1,21 @@
+"""
+Use 'scalar Generic' for show config output, to avoid attempts to
+JSON-serialize in case of JSON output.
+"""
+scalar Generic
+
+input ShowConfigInput {
+ path: [String!]!
+ configFormat: String
+}
+
+type ShowConfig {
+ path: [String]
+ result: Generic
+}
+
+type ShowConfigResult {
+ data: ShowConfig
+ success: Boolean!
+ errors: [String]
+}
diff --git a/src/services/api/graphql/recipes/remove_firewall_address_group_members.py b/src/services/api/graphql/recipes/remove_firewall_address_group_members.py
index cde30c27a..b91932e14 100644
--- a/src/services/api/graphql/recipes/remove_firewall_address_group_members.py
+++ b/src/services/api/graphql/recipes/remove_firewall_address_group_members.py
@@ -1,3 +1,17 @@
+# Copyright 2021 VyOS maintainers and contributors <maintainers@vyos.io>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
from . session import Session
diff --git a/src/services/api/graphql/recipes/session.py b/src/services/api/graphql/recipes/session.py
index b96cc1753..1f844ff70 100644
--- a/src/services/api/graphql/recipes/session.py
+++ b/src/services/api/graphql/recipes/session.py
@@ -1,9 +1,33 @@
+# Copyright 2021 VyOS maintainers and contributors <maintainers@vyos.io>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
+
+import json
+
from ariadne import convert_camel_case_to_snake
+
import vyos.defaults
from vyos.config import Config
+from vyos.configtree import ConfigTree
from vyos.template import render
-class Session(object):
+class Session:
+ """
+ Wrapper for calling configsession functions based on GraphQL requests.
+ Non-nullable fields in the respective schema allow avoiding a key check
+ in 'data'.
+ """
def __init__(self, session, data):
self._session = session
self._data = data
@@ -43,6 +67,21 @@ class Session(object):
session.delete(path)
session.commit()
+ def show_config(self):
+ session = self._session
+ data = self._data
+ out = ''
+
+ try:
+ out = session.show_config(data['path'])
+ if data.get('config_format', '') == 'json':
+ config_tree = vyos.configtree.ConfigTree(out)
+ out = json.loads(config_tree.to_json())
+ except Exception as error:
+ raise error
+
+ return out
+
def save(self):
session = self._session
data = self._data
@@ -63,3 +102,37 @@ class Session(object):
session.commit()
except Exception as error:
raise error
+
+ def show(self):
+ session = self._session
+ data = self._data
+ out = ''
+
+ try:
+ out = session.show(data['path'])
+ except Exception as error:
+ raise error
+
+ return out
+
+ def add(self):
+ session = self._session
+ data = self._data
+
+ try:
+ res = session.install_image(data['location'])
+ except Exception as error:
+ raise error
+
+ return res
+
+ def delete(self):
+ session = self._session
+ data = self._data
+
+ try:
+ res = session.remove_image(data['name'])
+ except Exception as error:
+ raise error
+
+ return res
diff --git a/src/services/api/graphql/recipes/templates/create_firewall_address_ipv_6_group.tmpl b/src/services/api/graphql/recipes/templates/create_firewall_address_ipv_6_group.tmpl
new file mode 100644
index 000000000..e9b660722
--- /dev/null
+++ b/src/services/api/graphql/recipes/templates/create_firewall_address_ipv_6_group.tmpl
@@ -0,0 +1,4 @@
+set firewall group ipv6-address-group {{ name }}
+{% for add in address %}
+set firewall group ipv6-address-group {{ name }} address {{ add }}
+{% endfor %}
diff --git a/src/services/api/graphql/recipes/templates/remove_firewall_address_ipv_6_group_members.tmpl b/src/services/api/graphql/recipes/templates/remove_firewall_address_ipv_6_group_members.tmpl
new file mode 100644
index 000000000..0efa0b226
--- /dev/null
+++ b/src/services/api/graphql/recipes/templates/remove_firewall_address_ipv_6_group_members.tmpl
@@ -0,0 +1,3 @@
+{% for add in address %}
+delete firewall group ipv6-address-group {{ name }} address {{ add }}
+{% endfor %}
diff --git a/src/services/api/graphql/recipes/templates/update_firewall_address_ipv_6_group_members.tmpl b/src/services/api/graphql/recipes/templates/update_firewall_address_ipv_6_group_members.tmpl
new file mode 100644
index 000000000..f98a5517c
--- /dev/null
+++ b/src/services/api/graphql/recipes/templates/update_firewall_address_ipv_6_group_members.tmpl
@@ -0,0 +1,3 @@
+{% for add in address %}
+set firewall group ipv6-address-group {{ name }} address {{ add }}
+{% endfor %}
diff --git a/src/services/vyos-configd b/src/services/vyos-configd
index 670b6e66a..48c9135e2 100755
--- a/src/services/vyos-configd
+++ b/src/services/vyos-configd
@@ -28,6 +28,7 @@ import zmq
from contextlib import contextmanager
from vyos.defaults import directories
+from vyos.util import boot_configuration_complete
from vyos.configsource import ConfigSourceString, ConfigSourceError
from vyos.config import Config
from vyos import ConfigError
@@ -186,7 +187,7 @@ def initialization(socket):
session_out = None
# if not a 'live' session, for example on boot, write to file
- if not session_out or not os.path.isfile('/tmp/vyos-config-status'):
+ if not session_out or not boot_configuration_complete():
session_out = script_stdout_log
session_mode = 'a'
diff --git a/src/services/vyos-hostsd b/src/services/vyos-hostsd
index f4b1d0fc2..9ae7b1ea9 100755
--- a/src/services/vyos-hostsd
+++ b/src/services/vyos-hostsd
@@ -139,6 +139,27 @@
# }
#
#
+### authoritative_zones
+## Additional zones hosted authoritatively by pdns-recursor.
+## We add NTAs for these zones but do not do much else here.
+#
+# { 'type': 'authoritative_zones',
+# 'op': 'add',
+# 'data': ['<str zone>', ...]
+# }
+#
+# { 'type': 'authoritative_zones',
+# 'op': 'delete',
+# 'data': ['<str zone>', ...]
+# }
+#
+# { 'type': 'authoritative_zones',
+# 'op': 'get',
+# }
+# response:
+# { 'data': ['<str zone>', ...] }
+#
+#
### search_domains
#
# { 'type': 'search_domains',
@@ -255,6 +276,7 @@ STATE = {
"name_server_tags_recursor": [],
"name_server_tags_system": [],
"forward_zones": {},
+ "authoritative_zones": [],
"hosts": {},
"host_name": "vyos",
"domain_name": "",
@@ -267,7 +289,8 @@ base_schema = Schema({
Required('op'): Any('add', 'delete', 'set', 'get', 'apply'),
'type': Any('name_servers',
'name_server_tags_recursor', 'name_server_tags_system',
- 'forward_zones', 'search_domains', 'hosts', 'host_name'),
+ 'forward_zones', 'authoritative_zones', 'search_domains',
+ 'hosts', 'host_name'),
'data': Any(list, dict),
'tag': str,
'tag_regex': str
@@ -347,6 +370,11 @@ msg_schema_map = {
'delete': data_list_schema,
'get': op_type_schema
},
+ 'authoritative_zones': {
+ 'add': data_list_schema,
+ 'delete': data_list_schema,
+ 'get': op_type_schema
+ },
'search_domains': {
'add': data_dict_list_schema,
'delete': data_list_schema,
@@ -393,12 +421,12 @@ def pdns_rec_control(command):
def make_resolv_conf(state):
logger.info(f"Writing {RESOLV_CONF_FILE}")
- render(RESOLV_CONF_FILE, 'vyos-hostsd/resolv.conf.tmpl', state,
+ render(RESOLV_CONF_FILE, 'vyos-hostsd/resolv.conf.j2', state,
user='root', group='root')
def make_hosts(state):
logger.info(f"Writing {HOSTS_FILE}")
- render(HOSTS_FILE, 'vyos-hostsd/hosts.tmpl', state,
+ render(HOSTS_FILE, 'vyos-hostsd/hosts.j2', state,
user='root', group='root')
def make_pdns_rec_conf(state):
@@ -409,12 +437,12 @@ def make_pdns_rec_conf(state):
chmod_755(PDNS_REC_RUN_DIR)
render(PDNS_REC_LUA_CONF_FILE,
- 'dns-forwarding/recursor.vyos-hostsd.conf.lua.tmpl',
+ 'dns-forwarding/recursor.vyos-hostsd.conf.lua.j2',
state, user=PDNS_REC_USER, group=PDNS_REC_GROUP)
logger.info(f"Writing {PDNS_REC_ZONES_FILE}")
render(PDNS_REC_ZONES_FILE,
- 'dns-forwarding/recursor.forward-zones.conf.tmpl',
+ 'dns-forwarding/recursor.forward-zones.conf.j2',
state, user=PDNS_REC_USER, group=PDNS_REC_GROUP)
def set_host_name(state, data):
@@ -522,7 +550,7 @@ def handle_message(msg):
data = get_option(msg, 'data')
if _type in ['name_servers', 'forward_zones', 'search_domains', 'hosts']:
delete_items_from_dict(STATE[_type], data)
- elif _type in ['name_server_tags_recursor', 'name_server_tags_system']:
+ elif _type in ['name_server_tags_recursor', 'name_server_tags_system', 'authoritative_zones']:
delete_items_from_list(STATE[_type], data)
else:
raise ValueError(f'Operation "{op}" unknown data type "{_type}"')
@@ -534,7 +562,7 @@ def handle_message(msg):
elif _type in ['forward_zones', 'hosts']:
add_items_to_dict(STATE[_type], data)
# maybe we need to rec_control clear-nta each domain that was removed here?
- elif _type in ['name_server_tags_recursor', 'name_server_tags_system']:
+ elif _type in ['name_server_tags_recursor', 'name_server_tags_system', 'authoritative_zones']:
add_items_to_list(STATE[_type], data)
else:
raise ValueError(f'Operation "{op}" unknown data type "{_type}"')
@@ -550,7 +578,7 @@ def handle_message(msg):
if _type in ['name_servers', 'search_domains', 'hosts']:
tag_regex = get_option(msg, 'tag_regex')
result = get_items_from_dict_regex(STATE[_type], tag_regex)
- elif _type in ['name_server_tags_recursor', 'name_server_tags_system', 'forward_zones']:
+ elif _type in ['name_server_tags_recursor', 'name_server_tags_system', 'forward_zones', 'authoritative_zones']:
result = STATE[_type]
else:
raise ValueError(f'Operation "{op}" unknown data type "{_type}"')
diff --git a/src/services/vyos-http-api-server b/src/services/vyos-http-api-server
index aa7ac6708..c1b595412 100755
--- a/src/services/vyos-http-api-server
+++ b/src/services/vyos-http-api-server
@@ -32,6 +32,7 @@ from fastapi.responses import HTMLResponse
from fastapi.exceptions import RequestValidationError
from fastapi.routing import APIRoute
from pydantic import BaseModel, StrictStr, validator
+from starlette.middleware.cors import CORSMiddleware
from starlette.datastructures import FormData
from starlette.formparsers import FormParser, MultiPartParser
from multipart.multipart import parse_options_header
@@ -351,7 +352,7 @@ class MultipartRoute(APIRoute):
return error(e.status_code, e.detail)
except Exception as e:
if request.ERR_MISSING_KEY:
- return error(422, "Valid API key is required")
+ return error(401, "Valid API key is required")
if request.ERR_MISSING_DATA:
return error(422, "Non-empty data field is required")
if request.ERR_NOT_JSON:
@@ -610,13 +611,19 @@ def show_op(data: ShowModel):
# GraphQL integration
###
-from api.graphql.bindings import generate_schema
+def graphql_init(fast_api_app):
+ from api.graphql.bindings import generate_schema
-api.graphql.state.init()
+ api.graphql.state.init()
+ api.graphql.state.settings['app'] = app
-schema = generate_schema()
+ schema = generate_schema()
-app.add_route('/graphql', GraphQL(schema, debug=True))
+ if app.state.vyos_origins:
+ origins = app.state.vyos_origins
+ app.add_route('/graphql', CORSMiddleware(GraphQL(schema, debug=True), allow_origins=origins, allow_methods=("GET", "POST", "OPTIONS")))
+ else:
+ app.add_route('/graphql', GraphQL(schema, debug=True))
###
@@ -640,15 +647,22 @@ if __name__ == '__main__':
app.state.vyos_session = config_session
app.state.vyos_keys = server_config['api_keys']
- app.state.vyos_debug = bool(server_config['debug'] == 'true')
- app.state.vyos_strict = bool(server_config['strict'] == 'true')
+ app.state.vyos_debug = server_config['debug']
+ app.state.vyos_gql = server_config['gql']
+ app.state.vyos_strict = server_config['strict']
+ app.state.vyos_origins = server_config.get('cors', {}).get('origins', [])
- api.graphql.state.settings['app'] = app
+ if app.state.vyos_gql:
+ graphql_init(app)
try:
- uvicorn.run(app, host=server_config["listen_address"],
- port=int(server_config["port"]),
- proxy_headers=True)
+ if not server_config['socket']:
+ uvicorn.run(app, host=server_config["listen_address"],
+ port=int(server_config["port"]),
+ proxy_headers=True)
+ else:
+ uvicorn.run(app, uds="/run/api.sock",
+ proxy_headers=True)
except OSError as err:
logger.critical(f"OSError {err}")
sys.exit(1)
diff --git a/src/system/keepalived-fifo.py b/src/system/keepalived-fifo.py
index 1fba0d75b..a8df232ae 100755
--- a/src/system/keepalived-fifo.py
+++ b/src/system/keepalived-fifo.py
@@ -29,6 +29,7 @@ from logging.handlers import SysLogHandler
from vyos.ifconfig.vrrp import VRRP
from vyos.configquery import ConfigTreeQuery
from vyos.util import cmd
+from vyos.util import dict_search
# configure logging
logger = logging.getLogger(__name__)
@@ -69,22 +70,11 @@ class KeepalivedFifo:
raise ValueError()
# Read VRRP configuration directly from CLI
- vrrp_config_dict = conf.get_config_dict(base, key_mangling=('-', '_'),
- get_first_key=True)
- self.vrrp_config = {'vrrp_groups': {}, 'sync_groups': {}}
- for key in ['group', 'sync_group']:
- if key not in vrrp_config_dict:
- continue
- for group, group_config in vrrp_config_dict[key].items():
- if 'transition_script' not in group_config:
- continue
- self.vrrp_config['vrrp_groups'][group] = {
- 'STOP': group_config['transition_script'].get('stop'),
- 'FAULT': group_config['transition_script'].get('fault'),
- 'BACKUP': group_config['transition_script'].get('backup'),
- 'MASTER': group_config['transition_script'].get('master'),
- }
- logger.info(f'Loaded configuration: {self.vrrp_config}')
+ self.vrrp_config_dict = conf.get_config_dict(base,
+ key_mangling=('-', '_'), get_first_key=True,
+ no_tag_node_value_mangle=True)
+
+ logger.debug(f'Loaded configuration: {self.vrrp_config_dict}')
except Exception as err:
logger.error(f'Unable to load configuration: {err}')
@@ -129,20 +119,17 @@ class KeepalivedFifo:
if os.path.exists(mdns_running_file):
cmd(mdns_update_command)
- if n_name in self.vrrp_config['vrrp_groups'] and n_state in self.vrrp_config['vrrp_groups'][n_name]:
- n_script = self.vrrp_config['vrrp_groups'][n_name].get(n_state)
- if n_script:
- self._run_command(n_script)
+ tmp = dict_search(f'group.{n_name}.transition_script.{n_state.lower()}', self.vrrp_config_dict)
+ if tmp != None:
+ self._run_command(tmp)
# check and run commands for VRRP sync groups
- # currently, this is not available in VyOS CLI
- if n_type == 'GROUP':
+ elif n_type == 'GROUP':
if os.path.exists(mdns_running_file):
cmd(mdns_update_command)
- if n_name in self.vrrp_config['sync_groups'] and n_state in self.vrrp_config['sync_groups'][n_name]:
- n_script = self.vrrp_config['sync_groups'][n_name].get(n_state)
- if n_script:
- self._run_command(n_script)
+ tmp = dict_search(f'sync_group.{n_name}.transition_script.{n_state.lower()}', self.vrrp_config_dict)
+ if tmp != None:
+ self._run_command(tmp)
# mark task in queue as done
self.message_queue.task_done()
except Exception as err:
diff --git a/src/systemd/keepalived.service b/src/systemd/keepalived.service
new file mode 100644
index 000000000..a462d8614
--- /dev/null
+++ b/src/systemd/keepalived.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Keepalive Daemon (LVS and VRRP)
+After=vyos-router.service
+# Only start if there is a configuration file
+ConditionFileNotEmpty=/run/keepalived/keepalived.conf
+
+[Service]
+KillMode=process
+Type=simple
+# Read configuration variable file if it is present
+ExecStart=/usr/sbin/keepalived --use-file /run/keepalived/keepalived.conf --pid /run/keepalived/keepalived.pid --dont-fork --snmp
+ExecReload=/bin/kill -HUP $MAINPID
+PIDFile=/run/keepalived/keepalived.pid
diff --git a/src/systemd/miniupnpd.service b/src/systemd/miniupnpd.service
new file mode 100644
index 000000000..51cb2eed8
--- /dev/null
+++ b/src/systemd/miniupnpd.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=UPnP service
+ConditionPathExists=/run/upnp/miniupnp.conf
+After=vyos-router.service
+StartLimitIntervalSec=0
+
+[Service]
+WorkingDirectory=/run/upnp
+Type=simple
+ExecStart=/usr/sbin/miniupnpd -d -f /run/upnp/miniupnp.conf
+PrivateTmp=yes
+PIDFile=/run/miniupnpd.pid
+Restart=on-failure
diff --git a/src/systemd/tftpd@.service b/src/systemd/tftpd@.service
index 266bc0962..a674bf598 100644
--- a/src/systemd/tftpd@.service
+++ b/src/systemd/tftpd@.service
@@ -7,7 +7,7 @@ RequiresMountsFor=/run
Type=forking
#NotifyAccess=main
EnvironmentFile=-/etc/default/tftpd%I
-ExecStart=/usr/sbin/in.tftpd "$DAEMON_ARGS"
+ExecStart=/bin/sh -c "${VRF_ARGS} /usr/sbin/in.tftpd ${DAEMON_ARGS}"
Restart=on-failure
[Install]
diff --git a/src/systemd/vyos-hostsd.service b/src/systemd/vyos-hostsd.service
index b77335778..4da55f518 100644
--- a/src/systemd/vyos-hostsd.service
+++ b/src/systemd/vyos-hostsd.service
@@ -7,7 +7,7 @@ DefaultDependencies=no
# Seemingly sensible way to say "as early as the system is ready"
# All vyos-hostsd needs is read/write mounted root
-After=systemd-remount-fs.service
+After=systemd-remount-fs.service cloud-init.service
[Service]
WorkingDirectory=/run/vyos-hostsd
diff --git a/src/systemd/vyos-http-api.service b/src/systemd/vyos-http-api.service
deleted file mode 100644
index ba5df5984..000000000
--- a/src/systemd/vyos-http-api.service
+++ /dev/null
@@ -1,23 +0,0 @@
-[Unit]
-Description=VyOS HTTP API service
-After=auditd.service systemd-user-sessions.service time-sync.target vyos-router.service
-Requires=vyos-router.service
-
-[Service]
-ExecStartPre=/usr/libexec/vyos/init/vyos-config
-ExecStart=/usr/libexec/vyos/services/vyos-http-api-server
-Type=idle
-
-SyslogIdentifier=vyos-http-api
-SyslogFacility=daemon
-
-Restart=on-failure
-
-# Does't work but leave it here
-User=root
-Group=vyattacfg
-
-[Install]
-# Installing in a earlier target leaves ExecStartPre waiting
-WantedBy=getty.target
-
diff --git a/src/tests/test_util.py b/src/tests/test_util.py
index 9bd27adc0..8ac9a500a 100644
--- a/src/tests/test_util.py
+++ b/src/tests/test_util.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright (C) 2020-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -23,3 +23,6 @@ class TestVyOSUtil(TestCase):
expected_data = {"foo_bar": {"baz_quux": None}}
new_data = mangle_dict_keys(data, '-', '_')
self.assertEqual(new_data, expected_data)
+
+ def test_sysctl_read(self):
+ self.assertEqual(sysctl_read('net.ipv4.conf.lo.forwarding'), '1')
diff --git a/src/tests/test_validate.py b/src/tests/test_validate.py
index b43dbd97e..68a257d25 100644
--- a/src/tests/test_validate.py
+++ b/src/tests/test_validate.py
@@ -30,8 +30,12 @@ class TestVyOSValidate(TestCase):
self.assertFalse(vyos.validate.is_ipv6_link_local('169.254.0.1'))
self.assertTrue(vyos.validate.is_ipv6_link_local('fe80::'))
self.assertTrue(vyos.validate.is_ipv6_link_local('fe80::affe:1'))
+ self.assertTrue(vyos.validate.is_ipv6_link_local('fe80::affe:1%eth0'))
self.assertFalse(vyos.validate.is_ipv6_link_local('2001:db8::'))
+ self.assertFalse(vyos.validate.is_ipv6_link_local('2001:db8::%eth0'))
self.assertFalse(vyos.validate.is_ipv6_link_local('VyOS'))
+ self.assertFalse(vyos.validate.is_ipv6_link_local('::1'))
+ self.assertFalse(vyos.validate.is_ipv6_link_local('::1%lo'))
def test_is_ipv6_link_local(self):
self.assertTrue(vyos.validate.is_loopback_addr('127.0.0.1'))
diff --git a/src/utils/vyos-hostsd-client b/src/utils/vyos-hostsd-client
index d4d38315a..a0515951a 100755
--- a/src/utils/vyos-hostsd-client
+++ b/src/utils/vyos-hostsd-client
@@ -129,7 +129,8 @@ try:
params = h.split(",")
if len(params) < 2:
raise ValueError("Malformed host entry")
- entry['address'] = params[1]
+ # Address needs to be a list because of changes made in T2683
+ entry['address'] = [params[1]]
entry['aliases'] = params[2:]
data[params[0]] = entry
client.add_hosts({args.tag: data})
diff --git a/src/validators/as-number-list b/src/validators/as-number-list
new file mode 100755
index 000000000..432d44180
--- /dev/null
+++ b/src/validators/as-number-list
@@ -0,0 +1,29 @@
+#!/bin/sh
+#
+# Copyright (C) 2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+if [ $# -lt 1 ]; then
+ echo "Illegal number of parameters"
+ exit 1
+fi
+
+for var in "$@"; do
+ ${vyos_validators_dir}/numeric --range 1-4294967294 $var
+ if [ $? -ne 0 ]; then
+ exit 1
+ fi
+done
+
+exit 0
diff --git a/src/validators/bgp-route-target b/src/validators/bgp-rd-rt
index e7e4d403f..b2b69c9be 100755
--- a/src/validators/bgp-route-target
+++ b/src/validators/bgp-rd-rt
@@ -19,29 +19,37 @@ from vyos.template import is_ipv4
parser = ArgumentParser()
group = parser.add_mutually_exclusive_group()
-group.add_argument('--single', action='store', help='Validate and allow only one route-target')
-group.add_argument('--multi', action='store', help='Validate multiple, whitespace separated route-targets')
+group.add_argument('--route-distinguisher', action='store', help='Validate BGP route distinguisher')
+group.add_argument('--route-target', action='store', help='Validate one BGP route-target')
+group.add_argument('--route-target-multi', action='store', help='Validate multiple, whitespace separated BGP route-targets')
args = parser.parse_args()
-def is_valid_rt(rt):
- # every route target needs to have a colon and must consists of two parts
+def is_valid(rt):
+ """ Verify BGP RD/RT - both can be verified using the same logic """
+ # every RD/RT (route distinguisher/route target) needs to have a colon and
+ # must consists of two parts
value = rt.split(':')
if len(value) != 2:
return False
- # A route target must either be only numbers, or the first part must be an
- # IPv4 address
+
+ # An RD/RT must either be only numbers, or the first part must be an IPv4
+ # address
if (is_ipv4(value[0]) or value[0].isdigit()) and value[1].isdigit():
return True
return False
if __name__ == '__main__':
- if args.single:
- if not is_valid_rt(args.single):
+ if args.route_distinguisher:
+ if not is_valid(args.route_distinguisher):
+ exit(1)
+
+ elif args.route_target:
+ if not is_valid(args.route_target):
exit(1)
- elif args.multi:
- for rt in args.multi.split(' '):
- if not is_valid_rt(rt):
+ elif args.route_target_multi:
+ for rt in args.route_target_multi.split(' '):
+ if not is_valid(rt):
exit(1)
else:
diff --git a/src/validators/ip-address b/src/validators/ip-address
index 51fb72c85..11d6df09e 100755
--- a/src/validators/ip-address
+++ b/src/validators/ip-address
@@ -1,3 +1,10 @@
#!/bin/sh
ipaddrcheck --is-any-single $1
+
+if [ $? -gt 0 ]; then
+ echo "Error: $1 is not a valid IP address"
+ exit 1
+fi
+
+exit 0 \ No newline at end of file
diff --git a/src/validators/ip-cidr b/src/validators/ip-cidr
index 987bf84ca..60d2ac295 100755
--- a/src/validators/ip-cidr
+++ b/src/validators/ip-cidr
@@ -1,3 +1,10 @@
#!/bin/sh
ipaddrcheck --is-any-cidr $1
+
+if [ $? -gt 0 ]; then
+ echo "Error: $1 is not a valid IP CIDR"
+ exit 1
+fi
+
+exit 0 \ No newline at end of file
diff --git a/src/validators/ip-host b/src/validators/ip-host
index f2906e8cf..77c578fa2 100755
--- a/src/validators/ip-host
+++ b/src/validators/ip-host
@@ -1,3 +1,10 @@
#!/bin/sh
ipaddrcheck --is-any-host $1
+
+if [ $? -gt 0 ]; then
+ echo "Error: $1 is not a valid IP host"
+ exit 1
+fi
+
+exit 0 \ No newline at end of file
diff --git a/src/validators/ip-prefix b/src/validators/ip-prefix
index e58aad395..e5a64fea8 100755
--- a/src/validators/ip-prefix
+++ b/src/validators/ip-prefix
@@ -1,3 +1,10 @@
#!/bin/sh
ipaddrcheck --is-any-net $1
+
+if [ $? -gt 0 ]; then
+ echo "Error: $1 is not a valid IP prefix"
+ exit 1
+fi
+
+exit 0 \ No newline at end of file
diff --git a/src/validators/ip-protocol b/src/validators/ip-protocol
index 078f8e319..c4c882502 100755
--- a/src/validators/ip-protocol
+++ b/src/validators/ip-protocol
@@ -31,11 +31,12 @@ if __name__ == '__main__':
pattern = "!?\\b(all|ip|hopopt|icmp|igmp|ggp|ipencap|st|tcp|egp|igp|pup|udp|" \
"tcp_udp|hmp|xns-idp|rdp|iso-tp4|dccp|xtp|ddp|idpr-cmtp|ipv6|" \
- "ipv6-route|ipv6-frag|idrp|rsvp|gre|esp|ah|skip|ipv6-icmp|" \
+ "ipv6-route|ipv6-frag|idrp|rsvp|gre|esp|ah|skip|ipv6-icmp|icmpv6|" \
"ipv6-nonxt|ipv6-opts|rspf|vmtp|eigrp|ospf|ax.25|ipip|etherip|" \
"encap|99|pim|ipcomp|vrrp|l2tp|isis|sctp|fc|mobility-header|" \
"udplite|mpls-in-ip|manet|hip|shim6|wesp|rohc)\\b"
if re.match(pattern, input):
exit(0)
+ print(f'Error: {input} is not a valid IP protocol')
exit(1)
diff --git a/src/validators/ipv4 b/src/validators/ipv4
index 53face090..8676d5800 100755
--- a/src/validators/ipv4
+++ b/src/validators/ipv4
@@ -1,3 +1,10 @@
#!/bin/sh
ipaddrcheck --is-ipv4 $1
+
+if [ $? -gt 0 ]; then
+ echo "Error: $1 is not IPv4"
+ exit 1
+fi
+
+exit 0 \ No newline at end of file
diff --git a/src/validators/ipv4-address b/src/validators/ipv4-address
index 872a7645a..058db088b 100755
--- a/src/validators/ipv4-address
+++ b/src/validators/ipv4-address
@@ -1,3 +1,10 @@
#!/bin/sh
ipaddrcheck --is-ipv4-single $1
+
+if [ $? -gt 0 ]; then
+ echo "Error: $1 is not a valid IPv4 address"
+ exit 1
+fi
+
+exit 0 \ No newline at end of file
diff --git a/src/validators/ipv4-host b/src/validators/ipv4-host
index f42feffa4..74b8c36a7 100755
--- a/src/validators/ipv4-host
+++ b/src/validators/ipv4-host
@@ -1,3 +1,10 @@
#!/bin/sh
ipaddrcheck --is-ipv4-host $1
+
+if [ $? -gt 0 ]; then
+ echo "Error: $1 is not a valid IPv4 host"
+ exit 1
+fi
+
+exit 0 \ No newline at end of file
diff --git a/src/validators/ipv4-multicast b/src/validators/ipv4-multicast
index e5cbc9532..3f28c51db 100755
--- a/src/validators/ipv4-multicast
+++ b/src/validators/ipv4-multicast
@@ -1,3 +1,10 @@
#!/bin/sh
-ipaddrcheck --is-ipv4-multicast $1
+ipaddrcheck --is-ipv4-multicast $1 && ipaddrcheck --is-ipv4-single $1
+
+if [ $? -gt 0 ]; then
+ echo "Error: $1 is not a valid IPv4 multicast address"
+ exit 1
+fi
+
+exit 0 \ No newline at end of file
diff --git a/src/validators/ipv4-prefix b/src/validators/ipv4-prefix
index 8ec8a2c45..7e1e0e8dd 100755
--- a/src/validators/ipv4-prefix
+++ b/src/validators/ipv4-prefix
@@ -1,3 +1,10 @@
#!/bin/sh
ipaddrcheck --is-ipv4-net $1
+
+if [ $? -gt 0 ]; then
+ echo "Error: $1 is not a valid IPv4 prefix"
+ exit 1
+fi
+
+exit 0 \ No newline at end of file
diff --git a/src/validators/ipv4-range b/src/validators/ipv4-range
index cc59039f1..6492bfc52 100755
--- a/src/validators/ipv4-range
+++ b/src/validators/ipv4-range
@@ -7,6 +7,11 @@ ip2dec () {
printf '%d\n' "$((a * 256 ** 3 + b * 256 ** 2 + c * 256 + d))"
}
+error_exit() {
+ echo "Error: $1 is not a valid IPv4 address range"
+ exit 1
+}
+
# Only run this if there is a hypen present in $1
if [[ "$1" =~ "-" ]]; then
# This only works with real bash (<<<) - split IP addresses into array with
@@ -15,21 +20,21 @@ if [[ "$1" =~ "-" ]]; then
ipaddrcheck --is-ipv4-single ${strarr[0]}
if [ $? -gt 0 ]; then
- exit 1
+ error_exit $1
fi
ipaddrcheck --is-ipv4-single ${strarr[1]}
if [ $? -gt 0 ]; then
- exit 1
+ error_exit $1
fi
start=$(ip2dec ${strarr[0]})
stop=$(ip2dec ${strarr[1]})
if [ $start -ge $stop ]; then
- exit 1
+ error_exit $1
fi
exit 0
fi
-exit 1
+error_exit $1
diff --git a/src/validators/ipv6 b/src/validators/ipv6
index f18d4a63e..4ae130eb5 100755
--- a/src/validators/ipv6
+++ b/src/validators/ipv6
@@ -1,3 +1,10 @@
#!/bin/sh
ipaddrcheck --is-ipv6 $1
+
+if [ $? -gt 0 ]; then
+ echo "Error: $1 is not IPv6"
+ exit 1
+fi
+
+exit 0 \ No newline at end of file
diff --git a/src/validators/ipv6-address b/src/validators/ipv6-address
index e5d68d756..1fca77668 100755
--- a/src/validators/ipv6-address
+++ b/src/validators/ipv6-address
@@ -1,3 +1,10 @@
#!/bin/sh
ipaddrcheck --is-ipv6-single $1
+
+if [ $? -gt 0 ]; then
+ echo "Error: $1 is not a valid IPv6 address"
+ exit 1
+fi
+
+exit 0 \ No newline at end of file
diff --git a/src/validators/ipv6-host b/src/validators/ipv6-host
index f7a745077..7085809a9 100755
--- a/src/validators/ipv6-host
+++ b/src/validators/ipv6-host
@@ -1,3 +1,10 @@
#!/bin/sh
ipaddrcheck --is-ipv6-host $1
+
+if [ $? -gt 0 ]; then
+ echo "Error: $1 is not a valid IPv6 host"
+ exit 1
+fi
+
+exit 0 \ No newline at end of file
diff --git a/src/validators/ipv6-link-local b/src/validators/ipv6-link-local
new file mode 100755
index 000000000..05e693b77
--- /dev/null
+++ b/src/validators/ipv6-link-local
@@ -0,0 +1,12 @@
+#!/usr/bin/python3
+
+import sys
+from vyos.validate import is_ipv6_link_local
+
+if __name__ == '__main__':
+ if len(sys.argv)>1:
+ addr = sys.argv[1]
+ if not is_ipv6_link_local(addr):
+ sys.exit(1)
+
+ sys.exit(0)
diff --git a/src/validators/ipv6-multicast b/src/validators/ipv6-multicast
index 66cd90c9c..5aa7d734a 100755
--- a/src/validators/ipv6-multicast
+++ b/src/validators/ipv6-multicast
@@ -1,3 +1,10 @@
#!/bin/sh
-ipaddrcheck --is-ipv6-multicast $1
+ipaddrcheck --is-ipv6-multicast $1 && ipaddrcheck --is-ipv6-single $1
+
+if [ $? -gt 0 ]; then
+ echo "Error: $1 is not a valid IPv6 multicast address"
+ exit 1
+fi
+
+exit 0 \ No newline at end of file
diff --git a/src/validators/ipv6-prefix b/src/validators/ipv6-prefix
index e43616350..890dda723 100755
--- a/src/validators/ipv6-prefix
+++ b/src/validators/ipv6-prefix
@@ -1,3 +1,10 @@
#!/bin/sh
ipaddrcheck --is-ipv6-net $1
+
+if [ $? -gt 0 ]; then
+ echo "Error: $1 is not a valid IPv6 prefix"
+ exit 1
+fi
+
+exit 0 \ No newline at end of file
diff --git a/src/validators/ipv6-range b/src/validators/ipv6-range
index 033b6461b..7080860c4 100755
--- a/src/validators/ipv6-range
+++ b/src/validators/ipv6-range
@@ -1,16 +1,20 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
-import sys
-import re
-from vyos.template import is_ipv6
+from ipaddress import IPv6Address
+from sys import argv, exit
if __name__ == '__main__':
- if len(sys.argv)>1:
- ipv6_range = sys.argv[1]
- # Regex for ipv6-ipv6 https://regexr.com/
- if re.search('([a-f0-9:]+:+)+[a-f0-9]+-([a-f0-9:]+:+)+[a-f0-9]+', ipv6_range):
- for tmp in ipv6_range.split('-'):
- if not is_ipv6(tmp):
- sys.exit(1)
-
- sys.exit(0)
+ if len(argv) > 1:
+ # try to pass validation and raise an error if failed
+ try:
+ ipv6_range = argv[1]
+ range_left = ipv6_range.split('-')[0]
+ range_right = ipv6_range.split('-')[1]
+ if not IPv6Address(range_left) < IPv6Address(range_right):
+ raise ValueError(f'left element {range_left} must be less than right element {range_right}')
+ except Exception as err:
+ print(f'Error: {ipv6_range} is not a valid IPv6 range: {err}')
+ exit(1)
+ else:
+ print('Error: an IPv6 range argument must be provided')
+ exit(1)
diff --git a/src/validators/mac-address-firewall b/src/validators/mac-address-firewall
new file mode 100755
index 000000000..70551f86d
--- /dev/null
+++ b/src/validators/mac-address-firewall
@@ -0,0 +1,27 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2018-2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import re
+import sys
+
+pattern = "^!?([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$"
+
+if __name__ == '__main__':
+ if len(sys.argv) != 2:
+ sys.exit(1)
+ if not re.match(pattern, sys.argv[1]):
+ sys.exit(1)
+ sys.exit(0)
diff --git a/src/validators/port-multi b/src/validators/port-multi
new file mode 100755
index 000000000..bd6f0ef60
--- /dev/null
+++ b/src/validators/port-multi
@@ -0,0 +1,52 @@
+#!/usr/bin/python3
+
+from sys import argv
+from sys import exit
+import re
+
+from vyos.util import read_file
+
+services_file = '/etc/services'
+
+def get_services():
+ names = []
+ service_data = read_file(services_file, "")
+ for line in service_data.split("\n"):
+ if not line or line[0] == '#':
+ continue
+ tmp = line.split()
+ names.append(tmp[0])
+ if len(tmp) > 2:
+ # Add port aliases to service list, too
+ names.extend(tmp[2:])
+ # remove duplicate entries (e.g. echo) from list
+ names = list(dict.fromkeys(names))
+ return names
+
+if __name__ == '__main__':
+ if len(argv)>1:
+ ports = argv[1].split(",")
+ services = get_services()
+
+ for port in ports:
+ if port and port[0] == '!':
+ port = port[1:]
+ if re.match('^[0-9]{1,5}-[0-9]{1,5}$', port):
+ port_1, port_2 = port.split('-')
+ if int(port_1) not in range(1, 65536) or int(port_2) not in range(1, 65536):
+ print(f'Error: {port} is not a valid port range')
+ exit(1)
+ if int(port_1) > int(port_2):
+ print(f'Error: {port} is not a valid port range')
+ exit(1)
+ elif port.isnumeric():
+ if int(port) not in range(1, 65536):
+ print(f'Error: {port} is not a valid port')
+ exit(1)
+ elif port not in services:
+ print(f'Error: {port} is not a valid service name')
+ exit(1)
+ else:
+ exit(2)
+
+ exit(0)
diff --git a/src/validators/port-range b/src/validators/port-range
index abf0b09d5..5468000a7 100755
--- a/src/validators/port-range
+++ b/src/validators/port-range
@@ -3,16 +3,37 @@
import sys
import re
+from vyos.util import read_file
+
+services_file = '/etc/services'
+
+def get_services():
+ names = []
+ service_data = read_file(services_file, "")
+ for line in service_data.split("\n"):
+ if not line or line[0] == '#':
+ continue
+ names.append(line.split(None, 1)[0])
+ return names
+
+def error(port_range):
+ print(f'Error: {port_range} is not a valid port or port range')
+ sys.exit(1)
+
if __name__ == '__main__':
if len(sys.argv)>1:
port_range = sys.argv[1]
- if re.search('[0-9]{1,5}-[0-9]{1,5}', port_range):
- for tmp in port_range.split('-'):
- if int(tmp) not in range(1, 65535):
- sys.exit(1)
- else:
- if int(port_range) not in range(1, 65535):
- sys.exit(1)
+ if re.match('^[0-9]{1,5}-[0-9]{1,5}$', port_range):
+ port_1, port_2 = port_range.split('-')
+ if int(port_1) not in range(1, 65536) or int(port_2) not in range(1, 65536):
+ error(port_range)
+ if int(port_1) > int(port_2):
+ error(port_range)
+ elif port_range.isnumeric() and int(port_range) not in range(1, 65536):
+ error(port_range)
+ elif not port_range.isnumeric() and port_range not in get_services():
+ print(f'Error: {port_range} is not a valid service name')
+ sys.exit(1)
else:
sys.exit(2)
diff --git a/src/validators/range b/src/validators/range
new file mode 100755
index 000000000..d4c25f3c4
--- /dev/null
+++ b/src/validators/range
@@ -0,0 +1,56 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import re
+import sys
+import argparse
+
+class MalformedRange(Exception):
+ pass
+
+def validate_range(value, min=None, max=None):
+ try:
+ lower, upper = re.match(r'^(\d+)-(\d+)$', value).groups()
+
+ lower, upper = int(lower), int(upper)
+
+ if int(lower) > int(upper):
+ raise MalformedRange("the lower bound exceeds the upper bound".format(value))
+
+ if min is not None:
+ if lower < min:
+ raise MalformedRange("the lower bound must not be less than {}".format(min))
+
+ if max is not None:
+ if upper > max:
+ raise MalformedRange("the upper bound must not be greater than {}".format(max))
+
+ except (AttributeError, ValueError):
+ raise MalformedRange("range syntax error")
+
+parser = argparse.ArgumentParser(description='Range validator.')
+parser.add_argument('--min', type=int, action='store')
+parser.add_argument('--max', type=int, action='store')
+parser.add_argument('value', action='store')
+
+if __name__ == '__main__':
+ args = parser.parse_args()
+
+ try:
+ validate_range(args.value, min=args.min, max=args.max)
+ except MalformedRange as e:
+ print("Incorrect range '{}': {}".format(args.value, e))
+ sys.exit(1)
diff --git a/src/validators/script b/src/validators/script
index 1d8a27e5c..4ffdeb2a0 100755
--- a/src/validators/script
+++ b/src/validators/script
@@ -36,7 +36,7 @@ if __name__ == '__main__':
# File outside the config dir is just a warning
if not vyos.util.file_is_persistent(script):
- sys.exit(
- f'Warning: file {path} is outside the / config directory\n'
+ sys.exit(0)(
+ f'Warning: file {script} is outside the "/config" directory\n'
'It will not be automatically migrated to a new image on system update'
)
diff --git a/src/validators/tcp-flag b/src/validators/tcp-flag
new file mode 100755
index 000000000..1496b904a
--- /dev/null
+++ b/src/validators/tcp-flag
@@ -0,0 +1,17 @@
+#!/usr/bin/python3
+
+import sys
+import re
+
+if __name__ == '__main__':
+ if len(sys.argv)>1:
+ flag = sys.argv[1]
+ if flag and flag[0] == '!':
+ flag = flag[1:]
+ if flag not in ['syn', 'ack', 'rst', 'fin', 'urg', 'psh', 'ecn', 'cwr']:
+ print(f'Error: {flag} is not a valid TCP flag')
+ sys.exit(1)
+ else:
+ sys.exit(2)
+
+ sys.exit(0)
diff --git a/test-requirements.txt b/test-requirements.txt
index 9348520b5..a475e0a16 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -3,3 +3,4 @@ lxml
pylint
nose
coverage
+jinja2