Issues during assigning addresses on point to point interfaces

7 messages, 3 authors, 2021-06-25 · open the first message on its own page

Issues during assigning addresses on point to point interfaces

From: Pali Rohár <pali@kernel.org>
Date: 2021-06-06 15:10:15

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

Re: Issues during assigning addresses on point to point interfaces

From: Marek Behún <kabel@kernel.org>
Date: 2021-06-24 10:45:53

On Sun, 6 Jun 2021 17:10:08 +0200
Pali Rohár [off-list ref] 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

Re: Issues during assigning addresses on point to point interfaces

From: Nicolas Dichtel <hidden>
Date: 2021-06-24 12:57:50

Le 24/06/2021 à 12:45, Marek Behún a écrit :
On Sun, 6 Jun 2021 17:10:08 +0200
Pali Rohár [off-list ref] wrote:
quoted
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

Re: Issues during assigning addresses on point to point interfaces

From: Pali Rohár <pali@kernel.org>
Date: 2021-06-25 08:40:42

On Thursday 24 June 2021 14:57:41 Nicolas Dichtel wrote:
Le 24/06/2021 à 12:45, Marek Behún a écrit :
quoted
On Sun, 6 Jun 2021 17:10:08 +0200
Pali Rohár [off-list ref] wrote:
quoted
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?

Re: Issues during assigning addresses on point to point interfaces

From: Nicolas Dichtel <hidden>
Date: 2021-06-25 15:06:27

Le 25/06/2021 à 10:40, Pali Rohár a écrit :
On Thursday 24 June 2021 14:57:41 Nicolas Dichtel wrote:
quoted
Le 24/06/2021 à 12:45, Marek Behún a écrit :
quoted
On Sun, 6 Jun 2021 17:10:08 +0200
Pali Rohár [off-list ref] wrote:
quoted
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?

Re: Issues during assigning addresses on point to point interfaces

From: Pali Rohár <pali@kernel.org>
Date: 2021-06-25 15:27:45

On Friday 25 June 2021 17:06:21 Nicolas Dichtel wrote:
Le 25/06/2021 à 10:40, Pali Rohár a écrit :
quoted
On Thursday 24 June 2021 14:57:41 Nicolas Dichtel wrote:
quoted
Le 24/06/2021 à 12:45, Marek Behún a écrit :
quoted
On Sun, 6 Jun 2021 17:10:08 +0200
Pali Rohár [off-list ref] wrote:
quoted
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

Re: Issues during assigning addresses on point to point interfaces

From: Nicolas Dichtel <hidden>
Date: 2021-06-25 15:32:14

Le 25/06/2021 à 17:27, Pali Rohár a écrit :
[snip]
quoted
quoted
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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help