Page MenuHomeVyOS Platform

Enable DHCP option 121 processing
Closed, ResolvedPublicFEATURE REQUEST

Description

Hello!
In VyOS 1.2.1 and 1.2.0-rolling+201905130337 if you are configure address dhcp for some interface, configuration scripts create dedicated dhclient.conf for this interface, located in /var/lib/dhcp/. For example:

root@test-06:/home/vyos# cat /var/lib/dhcp/dhclient_eth0.conf 
#
# autogenerated by vyatta-interfaces.pl on Tue May 14 14:32:15 UTC 2019
#
interface "eth0" {
	send host-name "test-06";
	request subnet-mask, broadcast-address, routers, domain-name-servers, domain-name, interface-mtu;
}

Then, this configuration used by the dhclient to obtain an IP address.
But, with this autogenerated configuration system can't handle DHCP option 121, which can be processed with default /etc/dhcp/dhclient.conf. To make DHCP option 121 operable, we need to apply the next changes:

  1. Generate dhclient.conf with rfc3442-classless-static-routes option.
  2. Patch rfc3442-classless-static-routes hook to process routes with FRRouting, and not "ip" command.

This can be done with the following changes:

diff -Naur origin/etc/dhcp/dhclient-exit-hooks.d/rfc3442-classless-routes option-121/etc/dhcp/dhclient-exit-hooks.d/rfc3442-classless-routes
--- origin/etc/dhcp/dhclient-exit-hooks.d/rfc3442-classless-routes	2019-05-14 19:37:38.003209345 +0300
+++ option-121/etc/dhcp/dhclient-exit-hooks.d/rfc3442-classless-routes	2019-05-14 19:50:40.574760057 +0300
@@ -55,8 +55,7 @@
 				fi
 
 				# set route (ip detects host routes automatically)
-				ip -4 route add "${net_address}/${net_length}" \
-					${via_arg} dev "${interface}" >/dev/null 2>&1
+				vtysh -c "configure terminal" -c "ip route ${net_address}/${net_length} ${via_arg} ${interface}" >/dev/null 2>&1
 			done
 		fi
 	fi
diff -Naur origin/opt/vyatta/sbin/vyatta-interfaces.pl option-121/opt/vyatta/sbin/vyatta-interfaces.pl
--- origin/opt/vyatta/sbin/vyatta-interfaces.pl	2019-05-14 19:36:17.968076176 +0300
+++ option-121/opt/vyatta/sbin/vyatta-interfaces.pl	2019-05-14 19:46:13.641637198 +0300
@@ -163,11 +163,12 @@
   my $output = dhcp_conf_header();
   my $hostname = get_hostname();
 
+  $output .= "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n";
   $output .= "interface \"$intf\" {\n";
   if (defined($hostname)) {
     $output .= "\tsend host-name \"$hostname\";\n";
   }
-  $output .= "\trequest subnet-mask, broadcast-address, routers, domain-name-servers";
+  $output .= "\trequest subnet-mask, broadcast-address, routers, domain-name-servers, rfc3442-classless-static-routes";
   my $domainname = is_domain_name_set();
   if (!defined($domainname)) {
     $output .= ", domain-name";

Affected files:
https://github.com/vyos/vyos-replace/blob/current/files/dhclient-script
https://github.com/vyos/vyatta-cfg-system/blob/current/scripts/vyatta-interfaces.pl
/etc/dhcp/dhclient-exit-hooks.d/rfc3442-classless-routes

We need to implement this to solve T1369.

Details

Difficulty level
Easy (less than an hour)
Version
-
Why the issue appeared?
Will be filled on close

Related Objects

Event Timeline

zsdc created this task.May 14 2019, 5:10 PM
zsdc changed the task status from Open to Confirmed.May 14 2019, 5:14 PM
zsdc assigned this task to hagbard.
zsdc triaged this task as High priority.
zsdc updated the task description. (Show Details)
zsdc changed Difficulty level from Unknown (require assessment) to Easy (less than an hour).
hagbard removed hagbard as the assignee of this task.May 14 2019, 5:58 PM
hagbard added a subscriber: hagbard.
pasik added a subscriber: pasik.May 14 2019, 6:04 PM
hagbard assigned this task to UnicronNL.May 14 2019, 8:38 PM
joshua added a subscriber: joshua.May 15 2019, 2:55 PM
syncer lowered the priority of this task from High to Normal.Jun 2 2019, 4:06 PM
syncer edited projects, added VyOS 1.3 Equuleus; removed VyOS 1.2 Crux.
zsdc raised the priority of this task from Normal to High.Jul 10 2019, 2:33 PM
syncer reassigned this task from UnicronNL to dmbaturin.Aug 31 2019, 12:35 AM
syncer added a subscriber: UnicronNL.
zsdc reassigned this task from dmbaturin to g.skupien.Apr 10 2020, 8:36 PM
zsdc added a subscriber: dmbaturin.

Test results on the VyOS 1.3-rolling-202004020117:
Basically, the DHCP option 121 is handled as expected but two issues were observed i.e.:

  1. Static routes advertised by the DHCP server in option 121 are not automatically removed from the FIB when the "address dhcp" setting is removed from the interface. Disable/enable the interface doesn't change anything. The only option to get rid of them is to restart the router.

A similar behavior is observed when the "address dhcp" config is replaced with static IP address in one go. In that case disable/enable the interface at least makes them removed from the FIB but they are still present in the FRR as "inactive" . The only option to get rid of them is to restart the router.

Example:
Networks 1.1.1.0/24 and 3.0.0.0/8 are being advertised by the DHCP option 121.

vyos@vyos:~$ show configuration commands | match eth0
set interfaces ethernet eth0 address 'dhcp'
set interfaces ethernet eth0 hw-id '0c:e2:df:b8:cc:00'

vyos@vyos:~$ show ip route 
Codes: K - kernel route, C - connected, S - static, R - RIP,
       O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
       T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
       F - PBR, f - OpenFabric,
       > - selected route, * - FIB route, q - queued route, r - rejected route

S>* 1.1.1.0/24 [210/0] via 172.16.0.100, eth0, 00:01:38
S>* 3.0.0.0/8 [210/0] via 172.16.0.101, eth0, 00:01:38
C>* 172.16.0.0/24 is directly connected, eth0, 00:01:39

then the "dhcp" is removed and a new static ip address is configured as 192.168.0.1/24:

vyos@vyos:~$ show configuration commands | match eth0
set interfaces ethernet eth0 address '192.168.0.1/24'
set interfaces ethernet eth0 hw-id '0c:e2:df:b8:cc:00'

vyos@vyos:~$ show ip route 
Codes: K - kernel route, C - connected, S - static, R - RIP,
       O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
       T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
       F - PBR, f - OpenFabric,
       > - selected route, * - FIB route, q - queued route, r - rejected route

S>* 1.1.1.0/24 [210/0] via 172.16.0.100, eth0 onlink, 00:00:21
S>* 3.0.0.0/8 [210/0] via 172.16.0.101, eth0 onlink, 00:00:21
C>* 192.168.0.0/24 is directly connected, eth0, 00:00:21

and after disable/enable the interface we get:

vyos@vyos# run show ip route 
Codes: K - kernel route, C - connected, S - static, R - RIP,
       O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
       T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
       F - PBR, f - OpenFabric,
       > - selected route, * - FIB route, q - queued route, r - rejected route

S   1.1.1.0/24 [210/0] via 172.16.0.100, eth0 inactive, 00:00:04
S   3.0.0.0/8 [210/0] via 172.16.0.101, eth0 inactive, 00:00:04
C>* 192.168.0.0/24 is directly connected, eth0, 00:00:04

Proposed solution: delete all routes associated with the interface configured with the "address dhcp" just after this setting is removed from that interface.

  1. Next-hop IP addresses advertised by the DHCP server in option 121 are not being validated in a matter of its reachability. As a result it is possible to inject a route with the next-hop IP address that is not reachable directly from the router. These routes as marked as "inactive" in the FRR and are not being injected into the kernel.

Proposed solution: check if the next-hop ip address belongs to the same network as set on the interface.

g.skupien closed this task as Resolved.Apr 27 2020, 7:26 PM

The issue has been solved by the above merge.

c-po moved this task from Need Triage to Finished on the VyOS 1.3 Equuleus board.May 21 2020, 5:26 PM