2021-06-06 15:14:52

by Pali Rohár

[permalink] [raw]
Subject: Issues during assigning addresses on point to point interfaces

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


2021-06-24 10:47:43

by Marek Behún

[permalink] [raw]
Subject: Re: Issues during assigning addresses on point to point interfaces

On Sun, 6 Jun 2021 17:10:08 +0200
Pali Rohár <[email protected]> wrote:

> 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
>

Adding some other people to Cc in order to get their opinions.

It seems this bug is there from the beginning, from commit
caeaba79009c2 ("ipv6: add support of peer address")
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=caeaba79009c2

Maybe some older user-space utilities use IFA_ADDRESS instead of
IFA_LOCAL, and this was done in order to be compatible with them?

Marek

2021-06-24 12:59:05

by Nicolas Dichtel

[permalink] [raw]
Subject: Re: Issues during assigning addresses on point to point interfaces

Le 24/06/2021 à 12:45, Marek Behún a écrit :
> On Sun, 6 Jun 2021 17:10:08 +0200
> Pali Rohár <[email protected]> wrote:
>
>> 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
>>
>
> Adding some other people to Cc in order to get their opinions.
>
> It seems this bug is there from the beginning, from commit
> caeaba79009c2 ("ipv6: add support of peer address")
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=caeaba79009c2
>
> Maybe some older user-space utilities use IFA_ADDRESS instead of
> IFA_LOCAL, and this was done in order to be compatible with them?
If I remember well, there was an issue in the uAPI.
IFA_LOCAL is supposed to be the address of the interface and IFA_ADDRESS is
supposed to be the endpoint of a point-to-point interface.
However, in case of IPv6, it was not the case. In netlink messages generated by
the kernel, IFA_ADDRESS was used instead of IFA_LOCAL.
The patch tried to keep the backward compatibility and the symmetry between msg
from userland and notification from the kernel.


Regards,
Nicolas

2021-06-25 08:42:39

by Pali Rohár

[permalink] [raw]
Subject: Re: Issues during assigning addresses on point to point interfaces

On Thursday 24 June 2021 14:57:41 Nicolas Dichtel wrote:
> Le 24/06/2021 à 12:45, Marek Behún a écrit :
> > On Sun, 6 Jun 2021 17:10:08 +0200
> > Pali Rohár <[email protected]> wrote:
> >
> >> 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
> >>
> >
> > Adding some other people to Cc in order to get their opinions.
> >
> > It seems this bug is there from the beginning, from commit
> > caeaba79009c2 ("ipv6: add support of peer address")
> > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=caeaba79009c2
> >
> > Maybe some older user-space utilities use IFA_ADDRESS instead of
> > IFA_LOCAL, and this was done in order to be compatible with them?
> If I remember well, there was an issue in the uAPI.
> IFA_LOCAL is supposed to be the address of the interface and IFA_ADDRESS is
> supposed to be the endpoint of a point-to-point interface.
> However, in case of IPv6, it was not the case. In netlink messages generated by
> the kernel, IFA_ADDRESS was used instead of IFA_LOCAL.
> The patch tried to keep the backward compatibility and the symmetry between msg
> from userland and notification from the kernel.

Hello Nicolas!

See my original email where I put also rtnetlink packets (how strace see
them). Seems that there is a bug in handling them (or bug in iproute2)
as setting just peer (remote) IPv6 address is ignored:
https://lore.kernel.org/netdev/20210606151008.7dwx5ukrlvxt4t3k@pali/

Do you have any idea if this is affected by that "issue in the uAPI"?
And what is the way how to fix it?

2021-06-25 15:09:55

by Nicolas Dichtel

[permalink] [raw]
Subject: Re: Issues during assigning addresses on point to point interfaces

Le 25/06/2021 à 10:40, Pali Rohár a écrit :
> On Thursday 24 June 2021 14:57:41 Nicolas Dichtel wrote:
>> Le 24/06/2021 à 12:45, Marek Behún a écrit :
>>> On Sun, 6 Jun 2021 17:10:08 +0200
>>> Pali Rohár <[email protected]> wrote:
>>>
>>>> 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
>>>>
>>>
>>> Adding some other people to Cc in order to get their opinions.
>>>
>>> It seems this bug is there from the beginning, from commit
>>> caeaba79009c2 ("ipv6: add support of peer address")
>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=caeaba79009c2
>>>
>>> Maybe some older user-space utilities use IFA_ADDRESS instead of
>>> IFA_LOCAL, and this was done in order to be compatible with them?
>> If I remember well, there was an issue in the uAPI.
>> IFA_LOCAL is supposed to be the address of the interface and IFA_ADDRESS is
>> supposed to be the endpoint of a point-to-point interface.
>> However, in case of IPv6, it was not the case. In netlink messages generated by
>> the kernel, IFA_ADDRESS was used instead of IFA_LOCAL.
>> The patch tried to keep the backward compatibility and the symmetry between msg
>> from userland and notification from the kernel.
>
> Hello Nicolas!
>
> See my original email where I put also rtnetlink packets (how strace see
> them). Seems that there is a bug in handling them (or bug in iproute2)
> as setting just peer (remote) IPv6 address is ignored:
> https://lore.kernel.org/netdev/20210606151008.7dwx5ukrlvxt4t3k@pali/
>
> Do you have any idea if this is affected by that "issue in the uAPI"?
> And what is the way how to fix it?
What about forcing IFA_LOCAL address to :: in your case?

2021-06-25 15:28:32

by Pali Rohár

[permalink] [raw]
Subject: Re: Issues during assigning addresses on point to point interfaces

On Friday 25 June 2021 17:06:21 Nicolas Dichtel wrote:
> Le 25/06/2021 à 10:40, Pali Rohár a écrit :
> > On Thursday 24 June 2021 14:57:41 Nicolas Dichtel wrote:
> >> Le 24/06/2021 à 12:45, Marek Behún a écrit :
> >>> On Sun, 6 Jun 2021 17:10:08 +0200
> >>> Pali Rohár <[email protected]> wrote:
> >>>
> >>>> 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
> >>>>
> >>>
> >>> Adding some other people to Cc in order to get their opinions.
> >>>
> >>> It seems this bug is there from the beginning, from commit
> >>> caeaba79009c2 ("ipv6: add support of peer address")
> >>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=caeaba79009c2
> >>>
> >>> Maybe some older user-space utilities use IFA_ADDRESS instead of
> >>> IFA_LOCAL, and this was done in order to be compatible with them?
> >> If I remember well, there was an issue in the uAPI.
> >> IFA_LOCAL is supposed to be the address of the interface and IFA_ADDRESS is
> >> supposed to be the endpoint of a point-to-point interface.
> >> However, in case of IPv6, it was not the case. In netlink messages generated by
> >> the kernel, IFA_ADDRESS was used instead of IFA_LOCAL.
> >> The patch tried to keep the backward compatibility and the symmetry between msg
> >> from userland and notification from the kernel.
> >
> > Hello Nicolas!
> >
> > See my original email where I put also rtnetlink packets (how strace see
> > them). Seems that there is a bug in handling them (or bug in iproute2)
> > as setting just peer (remote) IPv6 address is ignored:
> > https://lore.kernel.org/netdev/20210606151008.7dwx5ukrlvxt4t3k@pali/
> >
> > Do you have any idea if this is affected by that "issue in the uAPI"?
> > And what is the way how to fix it?
> What about forcing IFA_LOCAL address to :: in your case?

It does not work. ip address returns error:

$ sudo ip address add :: peer fe80::8 dev ppp0
RTNETLINK answers: Cannot assign requested address

Here is strace output:

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=1624633811,
pid=0
},
{
ifa_family=AF_INET6,
ifa_prefixlen=128,
ifa_flags=0,
ifa_scope=RT_SCOPE_UNIVERSE,
ifa_index=if_nametoindex("ppp0")
},
[
{
{
nla_len=20,
nla_type=IFA_LOCAL
},
inet_pton(AF_INET6, "::")
},
{
{
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

recvmsg(3, {
msg_name={
sa_family=AF_NETLINK,
nl_pid=0,
nl_groups=00000000
},
msg_namelen=12,
msg_iov=[{
iov_base=NULL,
iov_len=0
}],
msg_iovlen=1,
msg_controllen=0,
msg_flags=MSG_TRUNC
}, MSG_PEEK|MSG_TRUNC) = 84

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

2021-06-25 15:32:57

by Nicolas Dichtel

[permalink] [raw]
Subject: Re: Issues during assigning addresses on point to point interfaces

Le 25/06/2021 à 17:27, Pali Rohár a écrit :
[snip]
>>> Hello Nicolas!
>>>
>>> See my original email where I put also rtnetlink packets (how strace see
>>> them). Seems that there is a bug in handling them (or bug in iproute2)
>>> as setting just peer (remote) IPv6 address is ignored:
>>> https://lore.kernel.org/netdev/20210606151008.7dwx5ukrlvxt4t3k@pali/
>>>
>>> Do you have any idea if this is affected by that "issue in the uAPI"?
>>> And what is the way how to fix it?
>> What about forcing IFA_LOCAL address to :: in your case?
>
> It does not work. ip address returns error:
>
> $ sudo ip address add :: peer fe80::8 dev ppp0
> RTNETLINK answers: Cannot assign requested address
So this trick could probably be used to handle your case, without breaking
anything, as it's not a valid command today.


Regards,
Nicolas