ecki / net-tools

Linux base networking tools

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

route command differs from ip command when adding ipv6 route

gaoxingwang opened this issue · comments

In the following special scenarios, the ip command denies the following second route addition, but route does not。
Example:

$ip -6 route add 2409:8080:5a0a:60c7::7/128 via 2409:8080:5a0a:60c7::7 dev eth2
$ip -6 route add 2409:8080:5a0a:60c7::8/128 via 2409:8080:5a0a:60c7::7 dev eth2
RTNETLINK answers: No route to host
$ route -A inet6 add 2409:8080:5a0a:60c7::8/128 gw 2409:8080:5a0a:60c7::7 dev eth2
$
$ route -6n
Kernel IPv6 routing table
Destination Next Hop Flag Met Ref Use If
2409:8080:5a0a:60c7::7/128 2409:8080:5a0a:60c7::7 UG 1024 2 0 eth2
2409:8080:5a0a:60c7::8/128 2409:8080:5a0a:60c7::7 UGH 1 1 0 eth2
2409:8080:5a0a:60c7::/120 :: U 102 1 0 eth2

Can route command be the same with ip command?

Thanks for the patch and report. Maybe it’s too early for me, but why does the kernel deny the second host route?

I also wonder why ip doesn’t set the host flag on /128 - is the flag generally not used anymore?

Thanks for the patch and report. Maybe it’s too early for me, but why does the kernel deny the second host route?

I've sent an email to the kernel mailing list for advice, but no one has responded.
https://lore.kernel.org/all/20240105094255.1498461-1-gaoxingwang1@huawei.com/

I also wonder why ip doesn’t set the host flag on /128 - is the flag generally not used anymore?

There is no document to declare that RTF_HOST is no longer used.
The ip uses the netlink mechanism and seems to have a similar flag called RT_SCOPE_HOST. But in this scenario, I don't find that ip has this flag set.
Run the strace command to capture the netlink message sent by the IP command. The following figure shows the netlink message.

{
	msg_name = {
		sa_family = AF_NETLINK,
		nl_pid = 0,
		nl_groups = 00000000
	}, msg_namelen = 12, msg_iov = [{
		iov_base = {
			{
				len = 76, type = RTM_NEWROUTE, flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE, seq = 1704721827, pid = 0
			},
			{
				rtm_family = AF_INET6,
				rtm_dst_len = 128,
				rtm_src_len = 0,
				rtm_tos = 0,
				rtm_table = RT_TABLE_MAIN,
				rtm_protocol = RTPROT_BOOT,
				rtm_scope = RT_SCOPE_UNIVERSE,
				rtm_type = RTN_UNICAST,
				rtm_flags = 0
			},
			[{
				{
					nla_len = 20, nla_type = RTA_DST
				},
				inet_pton(AF_INET6, "2409:8080:5a0a:60c7::8")
			}, {
				{
					nla_len = 20, nla_type = RTA_GATEWAY
				},
				inet_pton(AF_INET6, "2409:8080:5a0a:60c7::7")
			}, {
				{
					nla_len = 8, nla_type = RTA_OIF
				},
				if_nametoindex("eth2")
			}]
		},
		iov_len = 76
	}], msg_iovlen = 1, msg_controllen = 0, msg_flags = 0
}

I think the host flag was mostly related to routing protocols (announcements), so not setting it bydefaul but offering a -host switch might be an option, I am just not sure how problematic such changed behavior is.

On the other hand rejecting the second host route is a weird kernel behavior, I wonder if this is because it interpreted it as a peer-to-peer interface.