2021-07-29 09:20:19

by Rocco Yue

[permalink] [raw]
Subject: [PATCH net-next] net: ipv6: add IFLA_RA_MTU to expose mtu value in the RA message

The kernel provides a "/proc/sys/net/ipv6/conf/<iface>/mtu"
file, which can temporarily record the mtu value of the last
received RA message when the RA mtu value is lower than the
interface mtu, but this proc has following limitations:
(1) when the interface mtu (/sys/class/net/<iface>/mtu) is
updeated, mtu6 (/proc/sys/net/ipv6/conf/<iface>/mtu) will be
updated to the value of interface mtu;
(2) mtu6 (/proc/sys/net/ipv6/conf/<iface>/mtu) only affect
ipv6 connection, and not affect ipv4.

Therefore, when the mtu option is carried in the RA message,
there will be a problem that the user sometimes cannot obtain
RA mtu value by reading mtu6.

After this patch set, if a RA message carries the mtu option,
you can use RTM_GETLINK to get the mtu value carried in the
RA message received on the interface.

In this way, If the MTU values that the device receives from the
network in the PCO IPv4 and the RA IPv6 procedures are different,
the user space process can read ra_mtu to get the mtu value carried
in the RA message without worrying about the issue of ipv4 being
stuck due to the late arrival of RA message. After comparing the
value of ra_mtu and ipv4 mtu, then the device can use the lower
MTU value for both IPv4 and IPv6.

Signed-off-by: Rocco Yue <[email protected]>
---
include/linux/ipv6.h | 3 +++
include/uapi/linux/if_link.h | 2 +-
include/uapi/linux/ipv6.h | 1 +
net/core/rtnetlink.c | 7 +++++--
net/ipv6/addrconf.c | 13 +++++++++++++
net/ipv6/ndisc.c | 5 +++++
tools/include/uapi/linux/if_link.h | 1 +
7 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 70b2ad3b9884..71aa0a3853f8 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -76,6 +76,7 @@ struct ipv6_devconf {
__s32 disable_policy;
__s32 ndisc_tclass;
__s32 rpl_seg_enabled;
+ __s32 ra_mtu;

struct ctl_table_header *sysctl_header;
};
@@ -321,6 +322,8 @@ struct tcp6_timewait_sock {
struct tcp_timewait_sock tcp6tw_tcp;
};

+u32 inet6_dev_ramtu(struct net_device *dev);
+
#if IS_ENABLED(CONFIG_IPV6)
bool ipv6_mod_enabled(void);

diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 4882e81514b6..ea6c872c5f2c 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -347,7 +347,7 @@ enum {
*/
IFLA_PARENT_DEV_NAME,
IFLA_PARENT_DEV_BUS_NAME,
-
+ IFLA_RA_MTU,
__IFLA_MAX
};

diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h
index 70603775fe91..3dbcf212b766 100644
--- a/include/uapi/linux/ipv6.h
+++ b/include/uapi/linux/ipv6.h
@@ -190,6 +190,7 @@ enum {
DEVCONF_NDISC_TCLASS,
DEVCONF_RPL_SEG_ENABLED,
DEVCONF_RA_DEFRTR_METRIC,
+ DEVCONF_RA_MTU,
DEVCONF_MAX
};

diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index f6af3e74fc44..3f660bbbd7b8 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -37,7 +37,7 @@
#include <linux/pci.h>
#include <linux/etherdevice.h>
#include <linux/bpf.h>
-
+#include <linux/ipv6.h>
#include <linux/uaccess.h>

#include <linux/inet.h>
@@ -1063,6 +1063,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
+ nla_total_size(4) /* IFLA_MAX_MTU */
+ rtnl_prop_list_size(dev)
+ nla_total_size(MAX_ADDR_LEN) /* IFLA_PERM_ADDRESS */
+ + nla_total_size(4) /* IFLA_RA_MTU */
+ 0;
}

@@ -1753,7 +1754,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb,
nla_put_u32(skb, IFLA_CARRIER_UP_COUNT,
atomic_read(&dev->carrier_up_count)) ||
nla_put_u32(skb, IFLA_CARRIER_DOWN_COUNT,
- atomic_read(&dev->carrier_down_count)))
+ atomic_read(&dev->carrier_down_count)) ||
+ nla_put_u32(skb, IFLA_RA_MTU, inet6_dev_ramtu(dev)))
goto nla_put_failure;

if (rtnl_fill_proto_down(skb, dev))
@@ -1891,6 +1893,7 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
[IFLA_PROTO_DOWN_REASON] = { .type = NLA_NESTED },
[IFLA_NEW_IFINDEX] = NLA_POLICY_MIN(NLA_S32, 1),
[IFLA_PARENT_DEV_NAME] = { .type = NLA_NUL_STRING },
+ [IFLA_RA_MTU] = { .type = NLA_U32 },
};

static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 3bf685fe64b9..d213400ee8a0 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -237,6 +237,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = {
.addr_gen_mode = IN6_ADDR_GEN_MODE_EUI64,
.disable_policy = 0,
.rpl_seg_enabled = 0,
+ .ra_mtu = 0,
};

static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
@@ -293,6 +294,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
.addr_gen_mode = IN6_ADDR_GEN_MODE_EUI64,
.disable_policy = 0,
.rpl_seg_enabled = 0,
+ .ra_mtu = 0,
};

/* Check if link is ready: is it up and is a valid qdisc available */
@@ -5526,6 +5528,17 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
array[DEVCONF_DISABLE_POLICY] = cnf->disable_policy;
array[DEVCONF_NDISC_TCLASS] = cnf->ndisc_tclass;
array[DEVCONF_RPL_SEG_ENABLED] = cnf->rpl_seg_enabled;
+ array[DEVCONF_RA_MTU] = cnf->ra_mtu;
+}
+
+u32 inet6_dev_ramtu(struct net_device *dev)
+{
+ struct inet6_dev *idev = __in6_dev_get(dev);
+
+ if (idev)
+ return idev->cnf.ra_mtu;
+
+ return 0;
}

static inline size_t inet6_ifla6_size(void)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index c467c6419893..1da626267662 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1496,6 +1496,11 @@ static void ndisc_router_discovery(struct sk_buff *skb)
memcpy(&n, ((u8 *)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
mtu = ntohl(n);

+ if (in6_dev->cnf.ra_mtu != mtu) {
+ in6_dev->cnf.ra_mtu = mtu;
+ ND_PRINTK(2, info, "update ra_mtu to %d\n", in6_dev->cnf.ra_mtu);
+ }
+
if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
ND_PRINTK(2, warn, "RA: invalid mtu: %d\n", mtu);
} else if (in6_dev->cnf.mtu6 != mtu) {
diff --git a/tools/include/uapi/linux/if_link.h b/tools/include/uapi/linux/if_link.h
index d208b2af697f..abc3607b7bab 100644
--- a/tools/include/uapi/linux/if_link.h
+++ b/tools/include/uapi/linux/if_link.h
@@ -170,6 +170,7 @@ enum {
IFLA_PROP_LIST,
IFLA_ALT_IFNAME, /* Alternative ifname */
IFLA_PERM_ADDRESS,
+ IFLA_RA_MTU,
__IFLA_MAX
};

--
2.18.0



2021-07-29 14:43:54

by David Ahern

[permalink] [raw]
Subject: Re: [PATCH net-next] net: ipv6: add IFLA_RA_MTU to expose mtu value in the RA message

On 7/29/21 3:02 AM, Rocco Yue wrote:
> diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
> index 4882e81514b6..ea6c872c5f2c 100644
> --- a/include/uapi/linux/if_link.h
> +++ b/include/uapi/linux/if_link.h
> @@ -347,7 +347,7 @@ enum {
> */
> IFLA_PARENT_DEV_NAME,
> IFLA_PARENT_DEV_BUS_NAME,
> -
> + IFLA_RA_MTU,
> __IFLA_MAX
> };
>
> diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h
> index 70603775fe91..3dbcf212b766 100644
> --- a/include/uapi/linux/ipv6.h
> +++ b/include/uapi/linux/ipv6.h
> @@ -190,6 +190,7 @@ enum {
> DEVCONF_NDISC_TCLASS,
> DEVCONF_RPL_SEG_ENABLED,
> DEVCONF_RA_DEFRTR_METRIC,
> + DEVCONF_RA_MTU,
> DEVCONF_MAX
> };
>

you do not need both IFLA and DEVCONF. Drop the DEVCONF completely. IFLA
attribute can be used for both inspection and notification on change.

2021-07-29 14:47:44

by David Ahern

[permalink] [raw]
Subject: Re: [PATCH net-next] net: ipv6: add IFLA_RA_MTU to expose mtu value in the RA message

Also do not add mailing lists that cause bounces. Specifically, you tend
to add [email protected] as a cc and every response to you
generates a bounce message for this address.

2021-07-29 16:03:55

by Rocco Yue

[permalink] [raw]
Subject: Re: [PATCH net-next] net: ipv6: add IFLA_RA_MTU to expose mtu value in the RA message

On Thu, 2021-07-29 at 08:41 -0600, David Ahern wrote:
> On 7/29/21 3:02 AM, Rocco Yue wrote:
>> diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
>> index 4882e81514b6..ea6c872c5f2c 100644
>> --- a/include/uapi/linux/if_link.h
>> +++ b/include/uapi/linux/if_link.h
>> @@ -347,7 +347,7 @@ enum {
>> */
>> IFLA_PARENT_DEV_NAME,
>> IFLA_PARENT_DEV_BUS_NAME,
>> -
>> + IFLA_RA_MTU,
>> __IFLA_MAX
>> };
>>
>> diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h
>> index 70603775fe91..3dbcf212b766 100644
>> --- a/include/uapi/linux/ipv6.h
>> +++ b/include/uapi/linux/ipv6.h
>> @@ -190,6 +190,7 @@ enum {
>> DEVCONF_NDISC_TCLASS,
>> DEVCONF_RPL_SEG_ENABLED,
>> DEVCONF_RA_DEFRTR_METRIC,
>> + DEVCONF_RA_MTU,
>> DEVCONF_MAX
>> };
>>
>
> you do not need both IFLA and DEVCONF. Drop the DEVCONF completely. IFLA
> attribute can be used for both inspection and notification on change.

Hi David,

Thanks for your review.

Because the purpose of this patch is for userspace to correctly read the
ra_mtu value of different network device, if the DEVCONF is completely dropped,
does that mean I can add the "ra_mtu" member in the "struct net_device" .

> Also do not add mailing lists that cause bounces. Specifically, you tend
> to add [email protected] as a cc and every response to you
> generates a bounce message for this address.

Thanks for pointing out the problem, I will remove it from the mailing list.

Best Regards,
Rocco

2021-07-29 16:48:11

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH net-next] net: ipv6: add IFLA_RA_MTU to expose mtu value in the RA message

Hi Rocco,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on net/master]
[also build test ERROR on linus/master v5.14-rc3]
[cannot apply to net-next/master next-20210728]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Rocco-Yue/net-ipv6-add-IFLA_RA_MTU-to-expose-mtu-value-in-the-RA-message/20210729-172047
base: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git fc16a5322ee6c30ea848818722eee5d352f8d127
config: mips-randconfig-r025-20210728 (attached as .config)
compiler: mips-linux-gcc (GCC) 10.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/c2c81e86202db50af376f5135ec853ad3f4deb82
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Rocco-Yue/net-ipv6-add-IFLA_RA_MTU-to-expose-mtu-value-in-the-RA-message/20210729-172047
git checkout c2c81e86202db50af376f5135ec853ad3f4deb82
# save the attached .config to linux build tree
mkdir build_dir
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-10.3.0 make.cross O=build_dir ARCH=mips SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

All errors (new ones prefixed by >>):

mips-linux-ld: net/core/rtnetlink.o: in function `rtnl_fill_ifinfo.constprop.0.isra.0':
>> rtnetlink.c:(.text.rtnl_fill_ifinfo.constprop.0.isra.0+0x5ac): undefined reference to `inet6_dev_ramtu'

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (1.90 kB)
.config.gz (36.82 kB)
Download all attachments

2021-07-29 17:33:05

by David Ahern

[permalink] [raw]
Subject: Re: [PATCH net-next] net: ipv6: add IFLA_RA_MTU to expose mtu value in the RA message

On 7/29/21 9:42 AM, Rocco Yue wrote:
> Because the purpose of this patch is for userspace to correctly read the
> ra_mtu value of different network device, if the DEVCONF is completely dropped,
> does that mean I can add the "ra_mtu" member in the "struct net_device" .

good point. IFLA is the wrong attribute. It should be IFLA_INET6_RA_MTU,
stored in inet6_dev and added to the link message in
inet6_fill_ifla6_attrs.


2021-07-29 18:35:19

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH net-next] net: ipv6: add IFLA_RA_MTU to expose mtu value in the RA message

Hi Rocco,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on net/master]
[also build test ERROR on linus/master v5.14-rc3]
[cannot apply to net-next/master next-20210728]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Rocco-Yue/net-ipv6-add-IFLA_RA_MTU-to-expose-mtu-value-in-the-RA-message/20210729-172047
base: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git fc16a5322ee6c30ea848818722eee5d352f8d127
config: parisc-randconfig-r032-20210728 (attached as .config)
compiler: hppa-linux-gcc (GCC) 10.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/c2c81e86202db50af376f5135ec853ad3f4deb82
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Rocco-Yue/net-ipv6-add-IFLA_RA_MTU-to-expose-mtu-value-in-the-RA-message/20210729-172047
git checkout c2c81e86202db50af376f5135ec853ad3f4deb82
# save the attached .config to linux build tree
mkdir build_dir
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-10.3.0 make.cross O=build_dir ARCH=parisc SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

All errors (new ones prefixed by >>):

hppa-linux-ld: net/core/rtnetlink.o: in function `rtnl_fill_ifinfo.constprop.0.isra.0':
>> net/core/rtnetlink.o:(.text+0xa098): undefined reference to `inet6_dev_ramtu'

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (1.88 kB)
.config.gz (45.54 kB)
Download all attachments

2021-07-30 17:58:07

by Rocco Yue

[permalink] [raw]
Subject: Re: [PATCH net-next] net: ipv6: add IFLA_RA_MTU to expose mtu value in the RA message

On Thu, 2021-07-29 at 11:28 -0600, David Ahern wrote:
On 7/29/21 9:42 AM, Rocco Yue wrote:
>> Because the purpose of this patch is for userspace to correctly read the
>> ra_mtu value of different network device, if the DEVCONF is completely dropped,
>> does that mean I can add the "ra_mtu" member in the "struct net_device" .
>
> good point. IFLA is the wrong attribute. It should be IFLA_INET6_RA_MTU,
> stored in inet6_dev and added to the link message in
> inet6_fill_ifla6_attrs.

will do, thanks for your suggestion.