blob: 3bc22cd0fc5496367464dfa5a11b2d50872ead31 [file] [log] [blame]
.. SPDX-FileCopyrightText: 2021 Open Networking Foundation <info@opennetworking.org>
.. SPDX-License-Identifier: Apache-2.0
DHCP Relay
==========
.. tip::
We strongly recommend you to setup DHCP relay and configure the hosts to
**obtain address via DHCP**.
See `Alternative: Configure static IP`_ if you want to statically configure
IP address on each host.
Overview
--------
The DHCP relay app used in SD-Fabric is an L3 relay.
That is, it support relaying DHCP packets from/to a server that's not in the
same subnet of the client.
Here's a list of features supported:
- DHCPv4 and DHCPv6
- DHCP server directly attached to fabric leaves, or indirectly connected via
upstream router
- DHCP client directly attached to fabric leaves, or indirectly connected via
`LDRA (Light-weight DHCP Relay Agent) <https://tools.ietf.org/html/rfc6221>`_
- Multiple DHCP servers for HA
.. note::
Please pay attention to the definition of **direct/indirect server/client**.
You will find them many times later in this section.
Configure DHCP Relay
--------------------
Server directly connected to fabric
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. image:: ../../images/config-dhcp.png
In this case, the configuration involves first configuring the switch interface
with the VLAN/subnet the DHCP service is part of.
For example, if I have a switch ``of:205`` with a DHCP server on port 24 on
VLAN 20, the port config looks like:
.. code-block:: json
{
"ports": {
"of:0000000000000205/24" : {
"interfaces" : [ {
"name" : "dhcp-server-intf",
"ips" : [ "10.0.2.254/24", "2001:db8:1::254/64" ],
"vlan-tagged" : [ 20 ]
} ]
}
}
}
A second part of the configuration for the DHCP relay app requires a json
configuration under the key apps:
.. code-block:: json
{
"apps" : {
"org.onosproject.dhcp-relay" : {
"default" : [
{
"dhcpServerConnectPoint": "of:0000000000000205/24",
"serverIps": ["10.0.2.253", "2001:db8:2::2"]
}
]
}
}
}
Note that the ``dhcprelay`` app is configured with location of the DHCP server (the
switch port to which it is connected to the fabric).
It is also configured with the DHCP server IP, but it is no longer necessary to
configure the MAC address of the server.
ONOS will automatically learn the MAC and VLAN corresponding to the ``serverIP``.
Server reachable via external router
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In this case, it is actually the external router that is directly connected to
the fabric.
This external router is already configured in the ports section of
network-config (for vRouter functionality).
For example, if the external router is connected to switch ``of:205`` on port 1
.. code-block:: json
{
"ports": {
"of:0000000000000205/1" : {
"interfaces" : [ {
"ips" : [ "192.168.101.2/30", "2000::c0a8:6402/120" ],
"mac" : "a2:9b:32:9d:7f:b3",
"name" : "internet-router"
} ]
}
}
}
As before the ``ips`` and ``mac`` configured on port 1, actually correspond to
the addresses configured in Quagga.
The app config in this case, includes an additional field necessary to inform
the ``dhcprelay`` app of the ``gatewayIP`` through which the DHCP server can be
reached.
.. code-block:: json
{
"apps" : {
"org.onosproject.dhcp-relay" : {
"default" : [
{
"dhcpServerConnectPoint": "of:0000000000000205/1",
"serverIps": ["10.0.2.253", "2001:db8:2::2"],
"gatewayIps": ["192.168.101.1", "1000::100:1"]
}
]
}
}
}
.. note::
Note that the ``dhcpserverConnectPoint`` should now be the switch port to
which the external router is connected to the fabric.
Setup DHCP server
-----------------
Install DHCP server
^^^^^^^^^^^^^^^^^^^
Modern DHCP servers should support relayed DHCP request.
However, the way to configure them are probably different case to case.
Here we use **isc-dhcp-server** on Ubuntu as an example.
To install the DHCP server, simply run:
.. code-block:: console
$ sudo apt-get install isc-dhcp-server
Configure DHCP Server
^^^^^^^^^^^^^^^^^^^^^
Two configuration files are required by DHCP server.
First, we need to specify which network interface the DHCP server should listen on.
To do that, we need to modify ``/etc/default/isc-dhcp-server`` and change the following line.
.. code-block:: text
INTERFACES="eth1"
Next, we need to specify the subnet we want to lease.
To do that, we need to modify ``/etc/dhcp/dhcpd.conf`` and add the following lines.
Note that the subnet of ``eth1`` needs to be included.
Otherwise, the DHCP server will not listen to the interface even though we have
specified that in ``/etc/default/isc-dhcp-server``.
.. code-block:: text
subnet 10.0.1.0 netmask 255.255.255.0 {
range 10.0.1.1 10.0.1.240;
option routers 10.0.1.254;
}
# A subnet that matches the interface IP address is required by isc-dhcp-server
subnet 10.0.2.0 netmask 255.255.255.0 {
range 10.0.2.1 10.0.2.240;
option routers 10.0.2.254;
}
It's similar to configure DHCPv6.
.. code-block:: text
subnet6 2001:db8:1::/64 {
# Range for clients
range6 2001:db8:1::129 2001:db8:1::250;
# Range for clients requesting a temporary address
range6 2001:db8:1::/64 temporary;
}
# A subnet that matches the interface IP address is required by isc-dhcp-server
subnet6 2001:db8:2::/64 {
# Range for clients
range6 2001:db8:2::129 2001:db8:2::254;
# Range for clients requesting a temporary address
range6 2001:db8:2::/64 temporary;
# Prefix range for delegation to sub-routers
prefix6 2001:db8:1:: 2001:db8:10:: /56;
}
Finally, restart the DHCP server.
.. code-block:: console
$ sudo service isc-dhcp-server restart
Testing
-------
The host should be able to obtain an IP address from the pool we specified.
Try to run ``dhclient`` and see if the host can get an IP address.
.. code-block:: console
sudo dhclient eth1
It's similar to test DHCPv6
.. code-block:: console
sudo dhclient -6 -N eth1 # for obtaining ip address
sudo dhclient -6 -P -N eth1 # for obtaining ip address and prefix together
sudo dhclient -6 -r eth1 # for releasing ip address
sudo dhclient -6 -P -r eth1 # for releasing prefix
If something goes wrong, check ``/var/log/syslog`` for DHCP server log and run
``tcpdump`` on DHCP server to see if the DHCP packets from the host reach the
server correctly.
Additional Features
-------------------
DHCP Relay store
^^^^^^^^^^^^^^^^
DHCP relay application stores information from DHCP packet which processed by
the app, administrator can use CLI command ``dhcp-relay`` to query these
information.
The store provides these functionality:
- Latest state of DHCP client (e.g. client location, last seen time, DHCP
type...), for debugging purpose
- For direct host, ONOS can find location and VLAN from relay agent option,
however, for indirect host, ONOS need to query last state from the store to
find correct destination.
DHCPv6 Relay counter
^^^^^^^^^^^^^^^^^^^^
There are two DHCPv6 packet counters which are Host basis counters and Global counters.
Host basis counters count and record DHCPv6 packets received on this host.
It can be displayed by ``dhcp-relay counter``. These counters can be reset by
typing ``dhcp-relay counter reset``.
.. code-block:: console
onos> dhcp-relay counter
DHCP Relay Counters :
Counters for id=00:AA:BB:00:00:01/None, locations=[of:0000000000000204/3]
SOLICIT ............................ 4 packets
REQUEST ............................ 4 packets
ADVERTISE ............................ 4 packets
RENEW ............................ 1000 packets
REPLY ............................ 1004 packets
Counters for id=00:AA:00:00:00:01/None, locations=[of:0000000000000205/3][D]
SOLICIT ............................ 2 packets
REQUEST ............................ 2 packets
ADVERTISE ............................ 2 packets
RENEW ............................ 500 packets
CONFIRM ............................ 2 packets
REPLY ............................ 500 packets
onos> dhcp-relay counter reset
Global counters counts and records all DHCPv6 packets received in ONOS.
It can be displayed by ``dhcp-relay-agg-counters``. These counters can be reset
by typing ``dhcp-relay-agg-counters reset``.
.. code-block:: console
onos> dhcp-relay-agg-counters
DHCP Relay Aggregate Counters :
SOLICIT ............................ 12 packets
REQUEST ............................ 12 packets
ADVERTISE ............................ 12 packets
REBIND ............................ 4 packets
RENEW ............................ 3026 packets
CONFIRM ............................ 4 packets
REPLY ............................ 3044 packets
onos> dhcp-relay-agg-counters reset
Indirect client support
^^^^^^^^^^^^^^^^^^^^^^^
DHCP relay can support hosts which do not directly connect to SD-Fabric.
These hosts usually connected to another LDRA, the LDRA will forward DHCP
packet to/from SD-Fabric.
For **DHCPv4**, packets from the LDRA includes a valid DHCP relay agent option
(option 82).
DHCP Relay application checks relay agent option and determine the DHCP packet
comes from direct or indirect host.
.. image:: ../../images/config-dhcp-indirect.jpg
ONOS uses circuit id option in relay agent option with specific format if DHCP
packet comes without relay agent option, the format of circuit will be:
``ConnectPoint:VlanId``
For example, the DHCP request/discover packet comes from
``of:000000000000001/1`` with ``VLAN 100``, the circuit ONOS put will be
``of:000000000000001/1:100`` and send DHCP packet to DHCP server.
Indirect host won't put into host store. DHCP relay app will put IP address of
indirect host to the route store, and use IP address of relay agent as next
hop.
**DHCPv6** clients will be handled similar to DHCPv4.
One major difference is that DHCPv6 supports ``RELAY-FORWARD`` message type and
``InterfaceId`` option natively, so we utilize those fields to encode
information.
Overwrite relay agent IP
^^^^^^^^^^^^^^^^^^^^^^^^
The DHCP relay can overwrite the relay agent address (``giaddr`` in **DHCPv4**,
``link-addr`` in **DHCPv6**) in DHCP message for different device.
If ``relayAgentIps`` is configured, the app will overwrite ``giaddr`` or
``link-addr`` before it forward the DHCP message to the server.
Otherwise, it will retain the original relay agent IP.
An example configuration is shown below:
.. code-block:: json
{
"apps" : {
"org.onosproject.dhcprelay" : {
"default": [{
"dhcpServerConnectPoint": "of:0000000000000002/2",
"serverIps": ["172.168.10.2", "2000::200:1"],
"gatewayIps": ["192.168.10.254", "1000::100:1"],
"relayAgentIps": {
"of:0000000000000001": {
"ipv4": "10.0.0.10",
"ipv6": "2000::10"
},
"of:0000000000000002": {
"ipv4": "10.0.1.10",
"ipv6": "2000::1:10"
}
}
}]
}
}
}
Configure multiple servers
^^^^^^^^^^^^^^^^^^^^^^^^^^
DHCP server HA can be achieved by specifying additional server configuration
objects.
Client initiated packets like ``SOLICIT`` or ``REBIND`` shall be replicated and
sent to all server objects.
Below is an example of multiple server configuration:
.. code-block:: json
{
"apps" : {
"org.onosproject.dhcprelay" : {
"default": [
{
"dhcpServerConnectPoint": "of:0000000000000205/5",
"serverIps": ["10.0.3.252", "2002:4::253"],
"gatewayIps": ["10.0.3.100","2001:3::100"],
"relayAgentIps": {
"of:0000000000000204": {
"ipv4": "10.0.2.254",
"ipv6": "2001:2::254"
}
}
},
{
"dhcpServerConnectPoint": "of:0000000000000206/3",
"serverIps": ["2002:5::253"],
"gatewayIps": ["2001:4::100"],
"relayAgentIps": {
"of:0000000000000204": {
"ipv4": "10.0.2.254",
"ipv6": "2001:2::254"
}
}
}
],
"indirect": [
{
"dhcpServerConnectPoint": "of:0000000000000205/5",
"serverIps": ["10.0.3.252", "2002:4::253"],
"gatewayIps": ["10.0.3.100", "2001:3::100"],
"relayAgentIps": {
"of:0000000000000204": {
"ipv4": "10.0.2.254",
"ipv6": "2001:2::254"
}
}
},
{
"dhcpServerConnectPoint": "of:0000000000000205/5",
"serverIps": ["10.0.3.252", "2002:5::253"],
"gatewayIps": ["10.0.3.100", "2001:3::100"],
"relayAgentIps": {
"of:0000000000000204": {
"ipv4": "10.0.2.254",
"ipv6": "2001:2::254"
}
}
},
{
"dhcpServerConnectPoint": "of:0000000000000206/3",
"serverIps": ["2002:5::253"],
"gatewayIps": ["2001:4::100"],
"relayAgentIps": {
"of:0000000000000204": {
"ipv4": "10.0.2.254",
"ipv6": "2001:2::254"
}
}
},
{
"dhcpServerConnectPoint": "of:0000000000000206/3",
"serverIps": ["2002:4::253"],
"gatewayIps": ["2001:4::100"],
"relayAgentIps": {
"of:0000000000000204": {
"ipv4": "10.0.2.254",
"ipv6": "2001:2::254"
}
}
}
]
}
}
}
- ``dhcpServerConnectPoint``: represent the location of DHCP server
- ``serverIps``: IP address of the DHCP server, contains at least one IP address of DHCP server.
IP address can be IPv4 or IPv6 for different version of DHCP.
Will use first address if multiple IPv4 or IPv6 address configured.
- ``gatewayIps``: Optional. Should be configured if the DHCP server is not
directly connected to the SD-Fabric. It tells which gateway we need to
send to reach the server.
.. note::
- If ``indirect`` server configuration is not configured, the app will use
``default`` configuration for all cases.
Ignoring DHCP relay on a particular VLAN
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In some cases, it may be necessary to avoid punting DHCP packets to the
controller, and letting them be forwarded normally through the data plane.
In such cases, the DHCP relay application can be configured to avoid punting
DHCP packets on a particular VLAN on a particular switch.
.. code-block:: json
{
"apps" : {
"org.onosproject.dhcprelay" : {
"ignoreDhcp" : [
{ "deviceId": "of:0000000000000205", "vlan":24 },
{ "deviceId": "of:0000000000000206", "vlan":24 }
]
}
}
}
In the example shown above, DHCP packets on VLAAN 24 are not punted to the
controller from switches of:205 and of:206
DHCPv6 Prefix Delegation (PD) Pushing
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. note::
This feature requires both ``dhcprelay`` and ``fpm`` apps to be activated
PD pushing allows IPv6 prefixes from DhcpRelay to be sent over the FPM
connection to Quagga where they will be configured as a static route.
Prior to PD Pushing, the FPM connection was only used by Quagga in one
direction to push routes to FPM. PD pushing is disabled by default in DHCP
Relay and FPM.
To enable in DHCP relay:
.. code-block:: console
onos> cfg set org.onosproject.dhcprelay.DhcpRelayManager DhcpFpmEnabled true
To display PD's stored in DHCP relay, execute the following CLI command:
.. code-block:: console
onos> dhcp-fpm-routes
When PD pushing is enabled in FPM, by default the next-hop to be used for all
prefixes pushed to Quagga will be retrieved from the first interface with
``RUR`` in the name in ONOS.
Next-hop may also be configured using FPM component config. This will override
a ``RUR`` interface if present.
If there is no interface with ``RUR`` in the name and the next-hop is not
configured, no prefixes can be pushed to Quagga even if PD pushing is enabled.
For DhcpRelay, only the IPv6 next-hop is needed.
To enable in FPM:
.. code-block:: console
onos> cfg set org.onosproject.routing.fpm.FpmManager pdPushNextHopIPv4 124.200.1.60
onos> cfg set org.onosproject.routing.fpm.FpmManager pdPushNextHopIPv6 2001:a08::2
onos> cfg set org.onosproject.routing.fpm.FpmManager pdPushEnabled true
To verify that PD pushing is enabled:
.. code-block:: console
onos> fpm-connections
PD Pushing is enabled.
peer 124.200.3.42:48640 connected to 127.0.0.1 since 2m23s ago * (2 routes locally)
Prefixes pushed to Quagga can be displayed in ``vtysh`` using ``show ip route`` and ``show ipv6 route``.
If the output is not as expected, check the Quagga log to see if it was received from FPM.
.. note::
Quagga requires a patch to be able to receive Netlink Messages from FPM.
Clean up expired address and PD prefix
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
DHCPv6 relay cleans up stale IP address and pd prefix based on timer whose
default interval is 24 hours (24 * 3600 secs = 86400 secs).
If the preferred life time of ip address or pd prefix exceeds 1/2 of poll
interval, they will be removed from ONOS.
The poll interval can be modified by ``cfg set
org.onosproject.dhcprelay.DhcpRelayManager dhcpPollInterval <newVal>``
.. code-block:: console
onos> cfg get org.onosproject.dhcprelay.DhcpRelayManager
org.onosproject.dhcprelay.DhcpRelayManager
name=dhcpPollInterval, type=integer, value=86400, defaultValue=86400, description=dhcp relay poll interval
onos> cfg set org.onosproject.dhcprelay.DhcpRelayManager dhcpPollInterval 60
onos> cfg get org.onosproject.dhcprelay.DhcpRelayManager
org.onosproject.dhcprelay.DhcpRelayManager
name=dhcpPollInterval, type=integer, value=60, defaultValue=86400, description=dhcp relay poll interval
Alternative: Configure static IP
--------------------------------
Although we strongly recommend to use `DHCP Relay`_ for IP assignment, it is
also possible to statically configure the IP address and route on the host.
1. **Configure the IP address and subnet mask**
Make sure the IP address and the subnet mask on the fabric network interface
of the host is consistent with the information in the Network Configuration
section. For example, you can run
.. code-block:: console
# ip addr add 10.0.0.1/24 dev mlx0
2. **Configure the default route**
Make sure you change the default route of the host to the interface IP of
the leaf switch it connects to. For example, you can run
.. code-block:: console
# ip route add default via 10.0.0.254
.. note::
In the case that you want to keep default route through the management network,
you need to add routes to all other subnets in the network one by one.
3. **Trigger host learning**
We need to let ONOS learn the host in order to program corresponding flows
and groups.
This is automatically done as part of the DHCP process.
However, we need to manually triggers it by sending an ARP or ND packet if
the host is configured to use static IP.
.. code-block:: console
# arping -c 1 ${GATEWAY_IP}
.. code-block:: console
# ndsend ${HOST_IP} ${INTF}
Reference
---------
- https://www.cisco.com/c/en/us/support/docs/security/adaptive-security-appliance-asa-software/116265-configure-product-00.html