diff --git a/src/sonic-yang-models/doc/Configuration.md b/src/sonic-yang-models/doc/Configuration.md index 151b7bb7f7d..643c1fce7a8 100644 --- a/src/sonic-yang-models/doc/Configuration.md +++ b/src/sonic-yang-models/doc/Configuration.md @@ -31,6 +31,7 @@ * [Device Metadata](#device-metadata) * [Device neighbor metada](#device-neighbor-metada) * [DHCP_RELAY](#dhcp_relay) + * [DHCPV4_RELAY](#dhcpv4_relay) * [DHCP Server IPV4](#dhcp_server_ipv4) * [BMP](#bmp) * [DSCP_TO_TC_MAP](#dscp_to_tc_map) @@ -1138,6 +1139,28 @@ instance is supported in SONiC. ``` +### DHCPV4_RELAY + +``` +{ +"DHCPV4_RELAY": { + "Vlan1000": { + "dhcpv4_servers": [ + "192.168.0.1", + "192.168.0.2" + ], + "server_vrf": "Vrf_RED", + "source_interface": "Loopback0", + "link_selection": "enable", + "vrf_selection": "enable", + "server_id_override": "enable", + "agent_relay_mode": "append", + "max_hop_count": 10 + } +} + +``` + ### BMP BMP related configuration are defined in **bgp_neighbor_table**,**bgp_rib_in_table**, **bgp_rib_out_table** tables. diff --git a/src/sonic-yang-models/setup.py b/src/sonic-yang-models/setup.py index f20afc884e1..2860cf5a9a6 100644 --- a/src/sonic-yang-models/setup.py +++ b/src/sonic-yang-models/setup.py @@ -45,6 +45,7 @@ 'sonic-device_neighbor.yang', 'sonic-device_neighbor_metadata.yang', 'sonic-dhcp-server.yang', + 'sonic-dhcpv4-relay.yang', 'sonic-dhcpv6-relay.yang', 'sonic-dns.yang', 'sonic-events-bgp.yang', diff --git a/src/sonic-yang-models/tests/files/sample_config_db.json b/src/sonic-yang-models/tests/files/sample_config_db.json index 7ec3ba41ed4..ee2ff74feae 100644 --- a/src/sonic-yang-models/tests/files/sample_config_db.json +++ b/src/sonic-yang-models/tests/files/sample_config_db.json @@ -2142,6 +2142,36 @@ "interface_id": "true" } }, + "DHCPV4_RELAY": { + "Vlan111": { + "dhcpv4_servers": [ + "10.222.72.116" + ], + "server_vrf": "Vrf_blue", + "source_interface": "Loopback0", + "link_selection": "enable", + "vrf_selection": "enable", + "server_id_override": "enable", + "agent_relay_mode": "forward_untouched", + "max_hop_count": "4" + }, + "Vlan222": { + "dhcpv4_servers": [ + "10.222.72.116", + "10.222.82.226" + ] + }, + "Vlan777": { + "dhcpv4_servers": [ + "10.222.82.226" + ], + "source_interface": "Loopback0", + "link_selection": "enable", + "vrf_selection": "disable", + "server_id_override": "disable", + "agent_relay_mode": "discard" + } + }, "DHCP_SERVER_IPV4": { "Vlan100": { "gateway": "100.1.1.1", diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/dhcpv4_relay.json b/src/sonic-yang-models/tests/yang_model_tests/tests/dhcpv4_relay.json new file mode 100644 index 00000000000..8bfb0481a36 --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests/dhcpv4_relay.json @@ -0,0 +1,40 @@ +{ + "DHCPv4_RELAY_VALID_FORMAT_BASE": { + "desc": "Add dhcpv4 relay with minimum config." + }, + "DHCPv4_RELAY_WITH_MULTIPLE_SERVERS": { + "desc": "Add dhcpv4 relay with multiple servers." + }, + "DHCPv4_RELAY_WITH_SERVER_VRF": { + "desc": "Add dhcpv4 relay with server VRF and required options." + }, + "DHCPv4_RELAY_WITH_LINK_SELECT": { + "desc": "Add dhcpv4 relay with link-select option enabled." + }, + "DHCPv4_RELAY_WITH_AGENT_RELAY_MODE_DISCARD": { + "desc": "Add dhcpv4 relay with minimum config." + }, + "DHCPv4_RELAY_WITH_VALID_MAX_HOP_CNT": { + "desc": "Add dhcpv4 relay with valid max_hop_cnt." + }, + "DHCPv4_RELAY_WITH_MISSING_SERVER_IP": { + "desc": "Add dhcpv4 relay with missing server_ip.", + "eStrKey": "MinElements" + }, + "DHCPv4_RELAY_WITH_SERVER_VRF_AND_MISSING_LINK_SELECT_OPTION": { + "desc": "Add dhcpv4 relay with server_vrf and missing link-selection option.", + "eStrKey": "Must" + }, + "DHCPv4_RELAY_WITH_SERVER_VRF_AND_MISSING_VRF_SELECT_OPTION": { + "desc": "Add dhcpv4 relay with server_vrf and missing vrf-selection option.", + "eStrKey": "Must" + }, + "DHCPv4_RELAY_WITH_SERVER_VRF_AND_MISSING_SERVER_OVERRIDE_OPTION": { + "desc": "Add dhcpv4 relay with server_vrf and missing lserver-override option.", + "eStrKey": "Must" + }, + "DHCPv4_RELAY_WITH_SERVER_VRF_AND_MISSING_SOURCE_INTERFACE_OPTION": { + "desc": "Add dhcpv4 relay with server_vrf and missing source-interface option.", + "eStrKey": "Must" + } +} diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/dhcpv4_relay.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/dhcpv4_relay.json new file mode 100644 index 00000000000..390c26653a9 --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/dhcpv4_relay.json @@ -0,0 +1,293 @@ +{ + "DHCPv4_RELAY_VALID_FORMAT_BASE": { + "sonic-dhcpv4-relay:sonic-dhcpv4-relay": { + "sonic-dhcpv4-relay:DHCPV4_RELAY": { + "DHCPV4_RELAY_LIST": [ + { + "name": "Vlan777", + "dhcpv4_servers": [ + "192.168.20.100" + ] + } + ] + } + } + }, + "DHCPv4_RELAY_WITH_MULTIPLE_SERVERS": { + "sonic-dhcpv4-relay:sonic-dhcpv4-relay": { + "sonic-dhcpv4-relay:DHCPV4_RELAY": { + "DHCPV4_RELAY_LIST": [ + { + "name": "Vlan777", + "dhcpv4_servers": [ + "192.168.20.100", + "10.11.12.13" + ] + } + ] + } + } + }, + "DHCPv4_RELAY_WITH_SERVER_VRF": { + "sonic-vrf:sonic-vrf": { + "sonic-vrf:VRF": { + "VRF_LIST": [ + { + "name": "Vrf1" + } + ] + } + }, + "sonic-loopback-interface:sonic-loopback-interface": { + "sonic-loopback-interface:LOOPBACK_INTERFACE": { + "LOOPBACK_INTERFACE_LIST": [ + { + "name": "Loopback0" + } + ] + } + }, + "sonic-dhcpv4-relay:sonic-dhcpv4-relay": { + "sonic-dhcpv4-relay:DHCPV4_RELAY": { + "DHCPV4_RELAY_LIST": [ + { + "name": "Vlan888", + "dhcpv4_servers": [ + "192.168.20.100" + ], + "server_vrf": "Vrf1", + "source_interface": "Loopback0", + "link_selection": "enable", + "vrf_selection": "enable", + "server_id_override": "enable" + } + ] + } + } + }, + "DHCPv4_RELAY_WITH_LINK_SELECT": { + "sonic-loopback-interface:sonic-loopback-interface": { + "sonic-loopback-interface:LOOPBACK_INTERFACE": { + "LOOPBACK_INTERFACE_LIST": [ + { + "name": "Loopback0" + } + ] + } + }, + "sonic-dhcpv4-relay:sonic-dhcpv4-relay": { + "sonic-dhcpv4-relay:DHCPV4_RELAY": { + "DHCPV4_RELAY_LIST": [ + { + "name": "Vlan777", + "dhcpv4_servers": [ + "192.168.20.100" + ], + "link_selection": "enable", + "source_interface": "Loopback0" + } + ] + } + } + }, + "DHCPv4_RELAY_WITH_AGENT_RELAY_MODE_DISCARD": { + "sonic-dhcpv4-relay:sonic-dhcpv4-relay": { + "sonic-dhcpv4-relay:DHCPV4_RELAY": { + "DHCPV4_RELAY_LIST": [ + { + "name": "Vlan777", + "dhcpv4_servers": [ + "192.168.20.100" + ], + "agent_relay_mode": "discard" + } + ] + } + } + }, + "DHCPv4_RELAY_WITH_VALID_MAX_HOP_CNT": { + "sonic-dhcpv4-relay:sonic-dhcpv4-relay": { + "sonic-dhcpv4-relay:DHCPV4_RELAY": { + "DHCPV4_RELAY_LIST": [ + { + "name": "Vlan777", + "dhcpv4_servers": [ + "192.168.20.100" + ], + "max_hop_count": 16 + } + ] + } + } + }, + "DHCPv4_RELAY_WITH_MISSING_SERVER_IP": { + "sonic-dhcpv4-relay:sonic-dhcpv4-relay": { + "sonic-dhcpv4-relay:DHCPV4_RELAY": { + "DHCPV4_RELAY_LIST": [ + { + "name": "Vlan777" + } + ] + } + } + }, + "DHCPv4_RELAY_WITH_SERVER_VRF_AND_MISSING_LINK_SELECT_OPTION": { + "sonic-loopback-interface:sonic-loopback-interface": { + "sonic-loopback-interface:LOOPBACK_INTERFACE": { + "LOOPBACK_INTERFACE_LIST": [ + { + "name": "Loopback0" + } + ] + } + }, + "sonic-vrf:sonic-vrf": { + "sonic-vrf:VRF": { + "VRF_LIST": [ + { + "name": "Vrf1" + } + ] + } + }, + "sonic-dhcpv4-relay:sonic-dhcpv4-relay": { + "sonic-dhcpv4-relay:DHCPV4_RELAY": { + "DHCPV4_RELAY_LIST": [ + { + "name": "Vlan888", + "dhcpv4_servers": [ + "192.168.20.100" + ], + "server_vrf": "Vrf1", + "source_interface": "Loopback0", + "vrf_selection": "enable", + "server_id_override": "enable" + } + ] + } + } + }, + "DHCPv4_RELAY_WITH_SERVER_VRF_AND_MISSING_VRF_SELECT_OPTION": { + "sonic-loopback-interface:sonic-loopback-interface": { + "sonic-loopback-interface:LOOPBACK_INTERFACE": { + "LOOPBACK_INTERFACE_LIST": [ + { + "name": "Loopback0" + } + ] + } + }, + "sonic-vrf:sonic-vrf": { + "sonic-vrf:VRF": { + "VRF_LIST": [ + { + "name": "Vrf1" + } + ] + } + }, + "sonic-dhcpv4-relay:sonic-dhcpv4-relay": { + "sonic-dhcpv4-relay:DHCPV4_RELAY": { + "DHCPV4_RELAY_LIST": [ + { + "name": "Vlan888", + "dhcpv4_servers": [ + "192.168.20.100" + ], + "server_vrf": "Vrf1", + "source_interface": "Loopback0", + "server_id_override": "enable", + "link_selection": "enable" + } + ] + } + } + }, + "DHCPv4_RELAY_WITH_SERVER_VRF_AND_MISSING_SERVER_OVERRIDE_OPTION": { + "sonic-loopback-interface:sonic-loopback-interface": { + "sonic-loopback-interface:LOOPBACK_INTERFACE": { + "LOOPBACK_INTERFACE_LIST": [ + { + "name": "Loopback0" + } + ] + } + }, + "sonic-vrf:sonic-vrf": { + "sonic-vrf:VRF": { + "VRF_LIST": [ + { + "name": "Vrf1" + } + ] + } + }, + "sonic-dhcpv4-relay:sonic-dhcpv4-relay": { + "sonic-dhcpv4-relay:DHCPV4_RELAY": { + "DHCPV4_RELAY_LIST": [ + { + "name": "Vlan888", + "dhcpv4_servers": [ + "192.168.20.100" + ], + "server_vrf": "Vrf1", + "source_interface": "Loopback0", + "vrf_selection": "enable", + "link_selection": "enable" + } + ] + } + } + }, + "DHCPv4_RELAY_WITH_SERVER_VRF_AND_MISSING_SOURCE_INTERFACE_OPTION": { + "sonic-loopback-interface:sonic-loopback-interface": { + "sonic-loopback-interface:LOOPBACK_INTERFACE": { + "LOOPBACK_INTERFACE_LIST": [ + { + "name": "Loopback0" + } + ] + } + }, + "sonic-vrf:sonic-vrf": { + "sonic-vrf:VRF": { + "VRF_LIST": [ + { + "name": "Vrf1" + } + ] + } + }, + "sonic-dhcpv4-relay:sonic-dhcpv4-relay": { + "sonic-dhcpv4-relay:DHCPV4_RELAY": { + "DHCPV4_RELAY_LIST": [ + { + "name": "Vlan888", + "dhcpv4_servers": [ + "192.168.20.100" + ], + "server_vrf": "Vrf1", + "vrf_selection": "enable", + "server_id_override": "enable", + "link_selection": "enable" + } + ] + } + } + }, + "DHCPv4_RELAY_WITH_INVALID_MAX_HOP_CNT": { + "sonic-dhcpv4-relay:sonic-dhcpv4-relay": { + "sonic-dhcpv4-relay:DHCPV4_RELAY": { + "DHCPV4_RELAY_LIST": [ + { + "name": "Vlan999", + "dhcpv4_servers": [ + "192.168.20.100" + ], + "max_hop_count": 17 + } + ] + } + } + } +} diff --git a/src/sonic-yang-models/yang-models/sonic-dhcpv4-relay.yang b/src/sonic-yang-models/yang-models/sonic-dhcpv4-relay.yang new file mode 100644 index 00000000000..38269bc963f --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-dhcpv4-relay.yang @@ -0,0 +1,138 @@ +module sonic-dhcpv4-relay { + + namespace "http://github.com/sonic-net/sonic-dhcpv4-relay"; + prefix dhcpv4relay; + yang-version 1.1; + + import ietf-inet-types { + prefix inet; + } + + import sonic-types { + prefix stypes; + } + + import sonic-vrf { + prefix vrf; + } + + import sonic-port { + prefix port; + } + + import sonic-portchannel { + prefix lag; + } + + import sonic-loopback-interface { + prefix loopback; + } + + organization "SONiC"; + contact "SONiC"; + description "DHCPv4 Relay yang Module for SONiC OS"; + + revision 2024-12-30 { + description "First Revision"; + } + + container sonic-dhcpv4-relay { + container DHCPV4_RELAY { + description "DHCPV4_RELAY part of config_db.json"; + + list DHCPV4_RELAY_LIST { + key "name"; + + leaf name { + description "VLAN ID"; + type union { + // Comment VLAN leaf reference here until libyang back-links issue is resolved and use VLAN string pattern + // type leafref { + // path "/vlan:sonic-vlan/vlan:VLAN/vlan:VLAN_LIST/vlan:name"; + // } + type string { + pattern 'Vlan([0-9]{1,3}|[1-3][0-9]{3}|[4][0][0-8][0-9]|[4][0][9][0-4])'; + } + } + } + + leaf-list dhcpv4_servers { + description "Server IPv4 address list"; + min-elements 1; + type inet:ipv4-address; + } + + leaf server_vrf { + description "Server VRF"; + type leafref { + path "/vrf:sonic-vrf/vrf:VRF/vrf:VRF_LIST/vrf:name"; + } + must "(current()/../server_id_override = 'enable' and + current()/../link_selection = 'enable')" { + description "when server_vrf is set, link_selection and server_id_override must be enabled"; + } + must "current()/../vrf_selection = 'enable'" { + description "if vrf_selection is enabled, server-vrf must be set"; + } + } + + leaf source_interface { + description "Used to determine the source IP address of the relayed packet"; + type union { + type leafref { + path "/port:sonic-port/port:PORT/port:PORT_LIST/port:name"; + } + type leafref { + path "/lag:sonic-portchannel/lag:PORTCHANNEL/lag:PORTCHANNEL_LIST/lag:name"; + } + type string { + pattern 'Vlan([0-9]{1,3}|[1-3][0-9]{3}|[4][0][0-8][0-9]|[4][0][9][0-4])'; + } + type leafref { + path "/loopback:sonic-loopback-interface/loopback:LOOPBACK_INTERFACE/loopback:LOOPBACK_INTERFACE_LIST/loopback:name"; + } + } + } + + leaf link_selection { + description "Enable link selection"; + type stypes:mode-status; + default disable; + must "current() = 'disable' or current()/../source_interface != ''" { + description "if link_selection is enabled, source_interface must be set"; + } + } + + leaf vrf_selection { + description "Enable VRF selection"; + type stypes:mode-status; + default disable; + } + + leaf server_id_override { + description "Enable server id override"; + type stypes:mode-status; + default disable; + } + + leaf agent_relay_mode { + description "How to forward packets that already have a relay option"; + type stypes:relay-agent-mode; + default forward_untouched; + } + + leaf max_hop_count { + description "Maximum hop count for relayed packets"; + type uint8 { + range "1..16"; + } + default 4; + } + } + /* end of DHCPV4_RELAY_LIST */ + } + /* end of container DHCPV4_RELAY */ + } + /* end of container sonic-dhcpv4-relay */ +} +/* end of module sonic-dhcpv4-relay */ diff --git a/src/sonic-yang-models/yang-templates/sonic-types.yang.j2 b/src/sonic-yang-models/yang-templates/sonic-types.yang.j2 index 5ccc06fd43a..8a003d545c1 100644 --- a/src/sonic-yang-models/yang-templates/sonic-types.yang.j2 +++ b/src/sonic-yang-models/yang-templates/sonic-types.yang.j2 @@ -470,6 +470,24 @@ module sonic-types { enum EGRESS_VLAN_FILTER; } } + + typedef relay-agent-mode { + type enumeration { + enum forward_and_append { + description "Forward and append our own relay option"; + } + enum forward_and_replace { + description "Forward, but replace theirs with ours"; + } + enum forward_untouched { + description "Forward without changes"; + } + enum discard { + description "Discard the packet"; + } + } + description "This enumeration type defines what to do about a dhcp packets that already has a relay option."; + } {% if yang_model_type == "cvl" %} /* Required for CVL */