Commit 6b2e04bc authored by Praveen Chaudhary's avatar Praveen Chaudhary Committed by Jakub Kicinski
Browse files

net: allow user to set metric on default route learned via Router Advertisement



For IPv4, default route is learned via DHCPv4 and user is allowed to change
metric using config etc/network/interfaces. But for IPv6, default route can
be learned via RA, for which, currently a fixed metric value 1024 is used.

Ideally, user should be able to configure metric on default route for IPv6
similar to IPv4. This patch adds sysctl for the same.

Logs:

For IPv4:

Config in etc/network/interfaces:
auto eth0
iface eth0 inet dhcp
    metric 4261413864

IPv4 Kernel Route Table:
$ ip route list
default via 172.21.47.1 dev eth0 metric 4261413864

FRR Table, if a static route is configured:
[In real scenario, it is useful to prefer BGP learned default route over DHCPv4 default route.]
Codes: K - kernel route, C - connected, S - static, R - RIP,
       O - OSPF, I - IS-IS, B - BGP, P - PIM, E - EIGRP, N - NHRP,
       T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
       > - selected route, * - FIB route

S>* 0.0.0.0/0 [20/0] is directly connected, eth0, 00:00:03
K   0.0.0.0/0 [254/1000] via 172.21.47.1, eth0, 6d08h51m

i.e. User can prefer Default Router learned via Routing Protocol in IPv4.
Similar behavior is not possible for IPv6, without this fix.

After fix [for IPv6]:
sudo sysctl -w net.ipv6.conf.eth0.net.ipv6.conf.eth0.ra_defrtr_metric=1996489705

IP monitor: [When IPv6 RA is received]
default via fe80::xx16:xxxx:feb3:ce8e dev eth0 proto ra metric 1996489705  pref high

Kernel IPv6 routing table
$ ip -6 route list
default via fe80::be16:65ff:feb3:ce8e dev eth0 proto ra metric 1996489705 expires 21sec hoplimit 64 pref high

FRR Table, if a static route is configured:
[In real scenario, it is useful to prefer BGP learned default route over IPv6 RA default route.]
Codes: K - kernel route, C - connected, S - static, R - RIPng,
       O - OSPFv3, I - IS-IS, B - BGP, N - NHRP, T - Table,
       v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
       > - selected route, * - FIB route

S>* ::/0 [20/0] is directly connected, eth0, 00:00:06
K   ::/0 [119/1001] via fe80::xx16:xxxx:feb3:ce8e, eth0, 6d07h43m

If the metric is changed later, the effect will be seen only when next IPv6
RA is received, because the default route must be fully controlled by RA msg.
Below metric is changed from 1996489705 to 1996489704.

$ sudo sysctl -w net.ipv6.conf.eth0.ra_defrtr_metric=1996489704
net.ipv6.conf.eth0.ra_defrtr_metric = 1996489704

IP monitor:
[On next IPv6 RA msg, Kernel deletes prev route and installs new route with updated metric]

Deleted default via fe80::xx16:xxxx:feb3:ce8e dev eth0 proto ra metric 1996489705 expires 3sec hoplimit 64 pref high
default via fe80::xx16:xxxx:feb3:ce8e dev eth0 proto ra metric 1996489704 pref high

Signed-off-by: default avatarPraveen Chaudhary <pchaudhary@linkedin.com>
Signed-off-by: default avatarZhenggen Xu <zxu@linkedin.com>
Reviewed-by: default avatarDavid Ahern <dsahern@kernel.org>
Link: https://lore.kernel.org/r/20210125214430.24079-1-pchaudhary@linkedin.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 6626a026
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -1871,6 +1871,16 @@ accept_ra_defrtr - BOOLEAN
		- enabled if accept_ra is enabled.
		- disabled if accept_ra is disabled.

ra_defrtr_metric - UNSIGNED INTEGER
	Route metric for default route learned in Router Advertisement. This value
	will be assigned as metric for the default route learned via IPv6 Router
	Advertisement. Takes affect only if accept_ra_defrtr is enabled.

	Possible values:
		1 to 0xFFFFFFFF

		Default: IP6_RT_PRIO_USER i.e. 1024.

accept_ra_from_local - BOOLEAN
	Accept RA with source-address that is found on local machine
	if the RA is otherwise proper and able to be accepted.
+1 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ struct ipv6_devconf {
	__s32		max_desync_factor;
	__s32		max_addresses;
	__s32		accept_ra_defrtr;
	__u32		ra_defrtr_metric;
	__s32		accept_ra_min_hop_limit;
	__s32		accept_ra_pinfo;
	__s32		ignore_routes_with_linkdown;
+2 −1
Original line number Diff line number Diff line
@@ -174,7 +174,8 @@ struct fib6_info *rt6_get_dflt_router(struct net *net,
				     struct net_device *dev);
struct fib6_info *rt6_add_dflt_router(struct net *net,
				     const struct in6_addr *gwaddr,
				     struct net_device *dev, unsigned int pref);
				     struct net_device *dev, unsigned int pref,
				     u32 defrtr_usr_metric);

void rt6_purge_dflt_routers(struct net *net);

+1 −0
Original line number Diff line number Diff line
@@ -189,6 +189,7 @@ enum {
	DEVCONF_ACCEPT_RA_RT_INFO_MIN_PLEN,
	DEVCONF_NDISC_TCLASS,
	DEVCONF_RPL_SEG_ENABLED,
	DEVCONF_RA_DEFRTR_METRIC,
	DEVCONF_MAX
};

+1 −0
Original line number Diff line number Diff line
@@ -571,6 +571,7 @@ enum {
	NET_IPV6_ACCEPT_SOURCE_ROUTE=25,
	NET_IPV6_ACCEPT_RA_FROM_LOCAL=26,
	NET_IPV6_ACCEPT_RA_RT_INFO_MIN_PLEN=27,
	NET_IPV6_RA_DEFRTR_METRIC=28,
	__NET_IPV6_MAX
};

Loading