In the 3GPP TS 29.061, here is a description as follows:
"In order to avoid any conflict between the link-local address
of the MS and that of the GGSN, the Interface-Identifier used by
the MS to build its link-local address shall be assigned by the
GGSN. The GGSN ensures the uniqueness of this Interface-Identifier.
The MT shall then enforce the use of this Interface-Identifier by
the TE"
In other words, in the cellular network, GGSN determines whether
to reply a solicited RA message by identifying the bottom 64 bits
of the source address of the received RS message. Therefore,
cellular network device's ipv6 link-local address should be set
as the format of fe80::(GGSN assigned IID).
To meet the above spec requirement, this patch adds two new
addr_gen_mode:
1) IN6_ADDR_GEN_MODE_STABLE_PRIVACY_NO_LLA, this mode is suitable
for cellular networks that support RFC7217. In this mode, the
kernel doesn't generate a link-local address for the cellular
NIC, and generates an ipv6 stable privacy global address after
receiving the RA message.
2) IN6_ADDR_GEN_MODE_RANDOM_NO_LLA, in this mode, the kernel
doesn't generate a link-local address for the cellular NIC,
and will use the bottom 64 bits of the link-local address(same
as the IID assigned by GGSN) to form an ipv6 global address
after receiveing the RA message.
Signed-off-by: Rocco Yue <redacted>
---
v1->v2: Add new addr_gen_mode instead of adding a separate sysctl.
v1 link:
https://patchwork.kernel.org/patch/12353465
---
include/uapi/linux/if_link.h | 2 ++
net/ipv6/addrconf.c | 22 ++++++++++++++++------
tools/include/uapi/linux/if_link.h | 2 ++
3 files changed, 20 insertions(+), 6 deletions(-)
@@ -3331,6 +3333,8 @@ static void addrconf_addr_gen(struct inet6_dev *idev, bool prefix_route)0,0,GFP_KERNEL);break;caseIN6_ADDR_GEN_MODE_NONE:+caseIN6_ADDR_GEN_MODE_RANDOM_NO_LLA:+caseIN6_ADDR_GEN_MODE_STABLE_PRIVACY_NO_LLA:default:/* will not add any link local address */break;
@@ -5798,7 +5802,9 @@ static int check_addr_gen_mode(int mode)if(mode!=IN6_ADDR_GEN_MODE_EUI64&&mode!=IN6_ADDR_GEN_MODE_NONE&&mode!=IN6_ADDR_GEN_MODE_STABLE_PRIVACY&&-mode!=IN6_ADDR_GEN_MODE_RANDOM)+mode!=IN6_ADDR_GEN_MODE_RANDOM&&+mode!=IN6_ADDR_GEN_MODE_STABLE_PRIVACY_NO_LLA&&+mode!=IN6_ADDR_GEN_MODE_RANDOM_NO_LLA)return-EINVAL;return1;}
@@ -6428,15 +6434,19 @@ static int addrconf_sysctl_stable_secret(struct ctl_table *ctl, int write,for_each_netdev(net,dev){structinet6_dev*idev=__in6_dev_get(dev);-if(idev){+if(idev&&idev->cnf.addr_gen_mode!=+IN6_ADDR_GEN_MODE_STABLE_PRIVACY_NO_LLA){idev->cnf.addr_gen_mode=IN6_ADDR_GEN_MODE_STABLE_PRIVACY;}}}else{structinet6_dev*idev=ctl->extra1;--idev->cnf.addr_gen_mode=IN6_ADDR_GEN_MODE_STABLE_PRIVACY;+if(idev->cnf.addr_gen_mode!=+IN6_ADDR_GEN_MODE_STABLE_PRIVACY_NO_LLA){+idev->cnf.addr_gen_mode=+IN6_ADDR_GEN_MODE_STABLE_PRIVACY;+}}out:
From: David Ahern <hidden> Date: 2021-11-16 20:21:19
On 11/15/21 11:09 PM, Rocco Yue wrote:
In the 3GPP TS 29.061, here is a description as follows:
"In order to avoid any conflict between the link-local address
of the MS and that of the GGSN, the Interface-Identifier used by
the MS to build its link-local address shall be assigned by the
GGSN. The GGSN ensures the uniqueness of this Interface-Identifier.
The MT shall then enforce the use of this Interface-Identifier by
the TE"
In other words, in the cellular network, GGSN determines whether
to reply a solicited RA message by identifying the bottom 64 bits
of the source address of the received RS message. Therefore,
cellular network device's ipv6 link-local address should be set
as the format of fe80::(GGSN assigned IID).
To meet the above spec requirement, this patch adds two new
addr_gen_mode:
1) IN6_ADDR_GEN_MODE_STABLE_PRIVACY_NO_LLA, this mode is suitable
for cellular networks that support RFC7217. In this mode, the
kernel doesn't generate a link-local address for the cellular
NIC, and generates an ipv6 stable privacy global address after
receiving the RA message.
2) IN6_ADDR_GEN_MODE_RANDOM_NO_LLA, in this mode, the kernel
doesn't generate a link-local address for the cellular NIC,
and will use the bottom 64 bits of the link-local address(same
as the IID assigned by GGSN) to form an ipv6 global address
after receiveing the RA message.
Signed-off-by: Rocco Yue <redacted>
---
v1->v2: Add new addr_gen_mode instead of adding a separate sysctl.
v1 link:
https://patchwork.kernel.org/patch/12353465
---
include/uapi/linux/if_link.h | 2 ++
net/ipv6/addrconf.c | 22 ++++++++++++++++------
tools/include/uapi/linux/if_link.h | 2 ++
3 files changed, 20 insertions(+), 6 deletions(-)
Reviewed-by: David Ahern <dsahern@kernel.org>
you should add tests under tools/testing/selftests/net.
From: Lorenzo Colitti <hidden> Date: 2021-11-17 05:09:39
On Tue, Nov 16, 2021 at 3:15 PM Rocco Yue [off-list ref] wrote:
In the 3GPP TS 29.061, here is a description as follows:
"In order to avoid any conflict between the link-local address
of the MS and that of the GGSN, the Interface-Identifier used by
the MS to build its link-local address shall be assigned by the
GGSN.
[...]
1) IN6_ADDR_GEN_MODE_STABLE_PRIVACY_NO_LLA, this mode is suitable
for cellular networks that support RFC7217. In this mode, the
kernel doesn't generate a link-local address for the cellular
NIC, and generates an ipv6 stable privacy global address after
receiving the RA message.
It sounds like this would violate RFC 4291 section 2.1 which says "All
interfaces are required to have at least one Link-Local unicast
address. It is also not what 3GPP requires. 3GPP *does* require a
link-local address. It just requires that that the bottom 64 bits of
that link-local address be assigned by the network, not randomly.
Given that the kernel already supports tokenized interface addresses,
a better option here would be to add new addrgen modes where the
link-local address is formed from the interface token (idev->token),
and the other addresses are formed randomly or via RFC7217. These
modes could be called IN6_ADDR_GEN_MODE_RANDOM_LL_TOKEN and
IN6_ADDR_GEN_MODE_STABLE_PRIVACY_LL_TOKEN. When setting up the
interface, userspace could set disable_ipv6 to 1, then set the
interface token and the address generation mode via RTM_SETLINK, then
set disable_ipv6 to 0 to start autoconf. The kernel would then form
the link-local address via the token (which comes from the network),
and then set the global addresses either randomly or via RFC 7217.
On Wed, 2021-11-17 at 13:09 +0800, Lorenzo Colitti wrote:
On Tue, Nov 16, 2021 at 3:15 PM Rocco Yue [off-list ref]
wrote:
quoted
In the 3GPP TS 29.061, here is a description as follows:
"In order to avoid any conflict between the link-local address
of the MS and that of the GGSN, the Interface-Identifier used by
the MS to build its link-local address shall be assigned by the
GGSN.
[...]
1) IN6_ADDR_GEN_MODE_STABLE_PRIVACY_NO_LLA, this mode is suitable
for cellular networks that support RFC7217. In this mode, the
kernel doesn't generate a link-local address for the cellular
NIC, and generates an ipv6 stable privacy global address after
receiving the RA message.
It sounds like this would violate RFC 4291 section 2.1 which says
"All
interfaces are required to have at least one Link-Local unicast
address. It is also not what 3GPP requires. 3GPP *does* require a
link-local address. It just requires that that the bottom 64 bits of
that link-local address be assigned by the network, not randomly.
Hi Lorenzo,
Thanks for your reply. :-)
Disabling the kernel's automatic link-local address generation
doesn't mean that it violates RFC 4291, because an appropriate
link-local addr can be added to the cellulal NIC through ioctl.
In fact, the current kernel has similar precedents. For example,
when device type is ARPHRD_NONE, and its addr_gen_mode is NONE,
the kernel will never generate a link-local addr for such interface.
Given that the kernel already supports tokenized interface addresses,
a better option here would be to add new addrgen modes where the
link-local address is formed from the interface token (idev->token),
and the other addresses are formed randomly or via RFC7217. These
modes could be called IN6_ADDR_GEN_MODE_RANDOM_LL_TOKEN and
IN6_ADDR_GEN_MODE_STABLE_PRIVACY_LL_TOKEN. When setting up the
interface, userspace could set disable_ipv6 to 1, then set the
interface token and the address generation mode via RTM_SETLINK, then
set disable_ipv6 to 0 to start autoconf. The kernel would then form
the link-local address via the token (which comes from the network),
and then set the global addresses either randomly or via RFC 7217.
The method you mentioned can also solve the current problem, but it
seems to introduce more logic:
(1) set the cellular interface addr_gen_mode to RANDOM_LL_TOKEN or PRIVACY_LL_TOKEN;
(2) set the cellular interface up;
(3) disable ipv6 first;
(4) set token addr through netlink;
(5) autoconf through the kernel;
(6) kernel trigger send RS message;
For the current patch, it is simpler, the configure process as follows:
(1) set the cellular NIC addr_gen_mode to RANDOM_NO_LLA or PRIVACY_NO_LLA;
(2) set the cellular interface up;
(3) configure the link-local addr for the NIC by ioctl;
(4) kernel trigger send RS message;
I wonder to hear what you and David think.
Thanks,
Rocco
From: Lorenzo Colitti <hidden> Date: 2021-11-17 08:37:01
On Wed, Nov 17, 2021 at 4:22 PM Rocco Yue [off-list ref] wrote:
Disabling the kernel's automatic link-local address generation
doesn't mean that it violates RFC 4291, because an appropriate
link-local addr can be added to the cellulal NIC through ioctl.
Well, it would mean that the kernel requires additional work from
userspace to respect the RFC.
The method you mentioned can also solve the current problem, but it
seems to introduce more logic:
(1) set the cellular interface addr_gen_mode to RANDOM_LL_TOKEN or PRIVACY_LL_TOKEN;
(2) set the cellular interface up;
(3) disable ipv6 first;
I don't think you need to set the interface up to disable IPv6. Also I
think that if the interface is down autoconf won't run so you don't
actually need to do this.
(4) set token addr through netlink;
Can't 4 be the same as 3? The same netlink message can configure both
the addr_gen_mode and the token, no?
It seems to me that the following should work, and would be much simpler.
1. Bring the interface down. All addresses are deleted.
2. Send a netlink request to set addr_gen_mode RANDOM_LL_TOKEN or
PRIVACY_LL_TOKEN and set the token.
3. Bring the interface up. Autoconf runs. The link-local address is
generated from the token. An RS is sent. When the RA is received, the
global address is generated using RFC 7217 or randomly.
Cheers,
Lorenzo
From: Maciej Żenczykowski <hidden> Date: 2021-11-17 09:51:15
Can't 4 be the same as 3? The same netlink message can configure both
the addr_gen_mode and the token, no?
It seems to me that the following should work, and would be much simpler.
1. Bring the interface down. All addresses are deleted.
2. Send a netlink request to set addr_gen_mode RANDOM_LL_TOKEN or
PRIVACY_LL_TOKEN and set the token.
3. Bring the interface up. Autoconf runs. The link-local address is
generated from the token. An RS is sent. When the RA is received, the
global address is generated using RFC 7217 or randomly.
Could you simply manually add an ipv6 link local address to the
interface while it is down (ip -6 addr add fe80::..../64 dev X), then
bring the interface up (ip link set dev X up)...
All that would need to happen is the automatic link local generation
would need to be suppressed if there's already a link local ip
configured - which sounds like a good idea anyway, since why have two?
(btw. even a manually added link local ip will get deleted when the
interface gets brought back down)