Issues during assigning addresses on point to point interfaces

From: Pali Rohár
Date: Sun Jun 06 2021 - 11:10:34 EST


Hello!

Seems that there is a bug during assigning IP addresses on point to
point interfaces.

Assigning just one local address works fine:

ip address add fe80::6 dev ppp1 --> inet6 fe80::6/128 scope link

Assigning both local and remote peer address also works fine:

ip address add fe80::7 peer fe80::8 dev ppp1 ---> inet6 fe80::7 peer fe80::8/128 scope link

But trying to assign just remote peer address does not work. Moreover
"ip address" call does not fail, it returns zero but instead of setting
remote peer address, it sets local address:

ip address add peer fe80::5 dev ppp1 --> inet6 fe80::5/128 scope link

I suspect that this is a bug either in iproute2 "ip" utility or in
kernel how it parse and process netlink messages.

strace for the last command see this netlink packet:

sendmsg(3, {
msg_name={
sa_family=AF_NETLINK,
nl_pid=0,
nl_groups=00000000
},
msg_namelen=12,
msg_iov=[{
iov_base={
{
len=44,
type=RTM_NEWADDR,
flags=NLM_F_REQUEST|NLM_F_ACK|NLM_F_EXCL|NLM_F_CREATE,
seq=1622990155,
pid=0
},
{
ifa_family=AF_INET6,
ifa_prefixlen=128,
ifa_flags=0,
ifa_scope=RT_SCOPE_UNIVERSE,
ifa_index=if_nametoindex("ppp1")
},
{
{
nla_len=20,
nla_type=IFA_ADDRESS
},
inet_pton(AF_INET6, "fe80::5")
}
},
iov_len=44
}],
msg_iovlen=1,
msg_controllen=0,
msg_flags=0
}, 0) = 44

On the other hand strace for the first command (which assigns only local
address) see following netlink packet:

sendmsg(3, {
msg_name={
sa_family=AF_NETLINK,
nl_pid=0,
nl_groups=00000000
},
msg_namelen=12,
msg_iov=[{
iov_base={
{
len=64,
type=RTM_NEWADDR,
flags=NLM_F_REQUEST|NLM_F_ACK|NLM_F_EXCL|NLM_F_CREATE,
seq=1622990488,
pid=0
},
{
ifa_family=AF_INET6,
ifa_prefixlen=128,
ifa_flags=0,
ifa_scope=RT_SCOPE_UNIVERSE,
ifa_index=if_nametoindex("ppp1")
},
[
{
{
nla_len=20,
nla_type=IFA_LOCAL
},
inet_pton(AF_INET6, "fe80::6")
},
{
{
nla_len=20,
nla_type=IFA_ADDRESS
},
inet_pton(AF_INET6, "fe80::6")
}
]
},
iov_len=64
}],
msg_iovlen=1,
msg_controllen=0,
msg_flags=0
}, 0) = 64

So it sends two addresses, one IFA_LOCAL, one IFA_ADDRESS, but both are
same.

For completeness here is strace output when assigning both local and
remote peer address:

sendmsg(3, {
msg_name={
sa_family=AF_NETLINK,
nl_pid=0,
nl_groups=00000000
},
msg_namelen=12,
msg_iov=[{
iov_base={
{
len=64,
type=RTM_NEWADDR,
flags=NLM_F_REQUEST|NLM_F_ACK|NLM_F_EXCL|NLM_F_CREATE,
seq=1622990883,
pid=0
},
{
ifa_family=AF_INET6,
ifa_prefixlen=128,
ifa_flags=0,
ifa_scope=RT_SCOPE_UNIVERSE,
ifa_index=if_nametoindex("ppp1")
},
[
{
{
nla_len=20,
nla_type=IFA_LOCAL
},
inet_pton(AF_INET6, "fe80::7")
},
{
{
nla_len=20,
nla_type=IFA_ADDRESS
},
inet_pton(AF_INET6, "fe80::8")
}
]
},
iov_len=64
}],
msg_iovlen=1,
msg_controllen=0,
msg_flags=0
}, 0) = 64

Which means that IFA_LOCAL sets local address and IFA_ADDRESS sets
remote peer address on point point interface.

Therefore there are two suspicious things about address configuration on
point to point interfaces:

1) "ip address add fe80::6 dev ppp1" is trying to set not only local but
also remote peer address to fe80::6

2) kernel does not configure remote peer address from IFA_ADDRESS when
local address via IFA_LOCAL is not specified in netlink packet


For tests I used:

ip -V --> ip utility, iproute2-ss190107
uname -r -v -m --> 4.19.0-16-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) x86_64