Received: by 2002:a05:6a10:1d13:0:0:0:0 with SMTP id pp19csp981275pxb; Tue, 17 Aug 2021 00:28:02 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyQd7otAjBw/xuZXXrs3MLjdUseBzFUD0iiKMgIrPBDp9j/Xr47geYUSX+1Rv2Ew/QRtCvL X-Received: by 2002:a02:970d:: with SMTP id x13mr1725045jai.57.1629185282721; Tue, 17 Aug 2021 00:28:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1629185282; cv=none; d=google.com; s=arc-20160816; b=Q1IDj17QUX51xpy4sxRs5MbqDKGST9fi22f0CmFJ27U7eK1YLUIshXa1ftTqRdca1f 98L3ltyDzmB5syJBlCk7OTr+mBnVrV6e/QyJnLcY3A7STlo7HR7tlmHSWlcxLAgMMc7U sAEluWIyOiiikO59yLdwjsLipL4BpWFssBxSdd2MQ0jmNDAUo8Oj/n5f2MwW9pQ6l4j3 HyAMwu9m2rYSs+Y0jg4peSkFNYXXJAp37pstICio/94r8Z7rKuBLYqIfsVb+dwxyoJiX KvwzPQoW3OIod+H6JyuRzrvL8yRZ5JHkEUCyFvft/Q2iYgJ+Z70RYVvx4WaVFNVAKbGd OJcQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:message-id:date:subject:cc:to:from; bh=8Jimc5EIfOJwRvp0QWiTKvMKJSmGw/qjIIHzANaN1Gg=; b=VQGNRuMj/msK4DiPIt2QuN3LGchN/Bni1dnkR3Gu85RK7J5HLhDQGiDkrhSjWx5cBo Ctxwq/w1BTPyTpkoZO8dk6IrGTQfyqyZPoAW89J2i/VvoJ9VnHyqjsUOG6SwfS+3Vzc3 uDLGVqAN3+viUWkIV1UPAT9XDFqmqQGLv1M4/IWaBfIrbiBLcm2CMFT5jvJct13V/se5 2Qs8juVTUExB1jHoN6DaHBAsytF9DZ8Sd3XvPpYcsB0ldVD8cLi9vKyKwrk/ZLOuire5 91OcCdffPGNn4O19KSsFTKyCyAHrFu9d5fCp9kIXTfNBrKqHvCRc8KWUWHf2rED+KRpz 60Dg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=mediatek.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id x6si804455ilu.80.2021.08.17.00.27.49; Tue, 17 Aug 2021 00:28:02 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=mediatek.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234785AbhHQH1M (ORCPT + 99 others); Tue, 17 Aug 2021 03:27:12 -0400 Received: from mailgw02.mediatek.com ([210.61.82.184]:42204 "EHLO mailgw02.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S234688AbhHQH1L (ORCPT ); Tue, 17 Aug 2021 03:27:11 -0400 X-UUID: 276bcab462b14cb4988800f34bb6f703-20210817 X-UUID: 276bcab462b14cb4988800f34bb6f703-20210817 Received: from mtkexhb02.mediatek.inc [(172.21.101.103)] by mailgw02.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 1566255698; Tue, 17 Aug 2021 15:26:32 +0800 Received: from MTKCAS06.mediatek.inc (172.21.101.30) by mtkmbs02n2.mediatek.inc (172.21.101.101) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 17 Aug 2021 15:26:31 +0800 Received: from localhost.localdomain (10.15.20.246) by MTKCAS06.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Tue, 17 Aug 2021 15:26:30 +0800 From: Rocco Yue To: "David S . Miller" , Jakub Kicinski , Hideaki YOSHIFUJI , David Ahern , Matthias Brugger CC: , , , , , , , Rocco Yue Subject: [PATCH net-next v4] ipv6: add IFLA_INET6_RA_MTU to expose mtu value in the RA message Date: Tue, 17 Aug 2021 15:26:09 +0800 Message-ID: <20210817072609.2110-1-rocco.yue@mediatek.com> X-Mailer: git-send-email 2.18.0 MIME-Version: 1.0 Content-Type: text/plain X-MTK: N Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The kernel provides a "/proc/sys/net/ipv6/conf//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//mtu) is updeated, mtu6 (/proc/sys/net/ipv6/conf//mtu) will be updated to the value of interface mtu; (2) mtu6 (/proc/sys/net/ipv6/conf//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 correctly by reading mtu6. After this patch set, if a RA message carries the mtu option, you can send a netlink msg which nlmsg_type is RTM_GETLINK, and then by parsing the attribute of IFLA_INET6_RA_MTU to get the mtu value carried in the RA message received on the inet6 device. In addition, you can also get a link notification when ra_mtu is updated so it doesn't have to poll. 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 can obtain the correct ipv6 ra_mtu value and compare 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 --- include/net/if_inet6.h | 2 ++ include/uapi/linux/if_link.h | 1 + net/ipv6/addrconf.c | 8 ++++++++ net/ipv6/ndisc.c | 17 +++++++++++------ tools/include/uapi/linux/if_link.h | 1 + 5 files changed, 23 insertions(+), 6 deletions(-) diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h index 42235c178b06..653e7d0f65cb 100644 --- a/include/net/if_inet6.h +++ b/include/net/if_inet6.h @@ -210,6 +210,8 @@ struct inet6_dev { unsigned long tstamp; /* ipv6InterfaceTable update timestamp */ struct rcu_head rcu; + + unsigned int ra_mtu; }; static inline void ipv6_eth_mc_map(const struct in6_addr *addr, char *buf) diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index 5310003523ce..957ec9873e70 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -417,6 +417,7 @@ enum { IFLA_INET6_ICMP6STATS, /* statistics (icmpv6) */ IFLA_INET6_TOKEN, /* device token */ IFLA_INET6_ADDR_GEN_MODE, /* implicit address generator mode */ + IFLA_INET6_RA_MTU, /* mtu carried in the RA message */ __IFLA_INET6_MAX }; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 8381288a0d6e..3eb957777b31 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -394,6 +394,7 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev) ndev->cnf.addr_gen_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY; ndev->cnf.mtu6 = dev->mtu; + ndev->ra_mtu = U32_MIN; ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl); if (!ndev->nd_parms) { kfree(ndev); @@ -5543,6 +5544,7 @@ static inline size_t inet6_ifla6_size(void) + nla_total_size(ICMP6_MIB_MAX * 8) /* IFLA_INET6_ICMP6STATS */ + nla_total_size(sizeof(struct in6_addr)) /* IFLA_INET6_TOKEN */ + nla_total_size(1) /* IFLA_INET6_ADDR_GEN_MODE */ + + nla_total_size(4) /* IFLA_INET6_RA_MTU */ + 0; } @@ -5651,6 +5653,9 @@ static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev, if (nla_put_u8(skb, IFLA_INET6_ADDR_GEN_MODE, idev->cnf.addr_gen_mode)) goto nla_put_failure; + if (nla_put_u32(skb, IFLA_INET6_RA_MTU, idev->ra_mtu)) + goto nla_put_failure; + return 0; nla_put_failure: @@ -5767,6 +5772,9 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token, static const struct nla_policy inet6_af_policy[IFLA_INET6_MAX + 1] = { [IFLA_INET6_ADDR_GEN_MODE] = { .type = NLA_U8 }, [IFLA_INET6_TOKEN] = { .len = sizeof(struct in6_addr) }, + [IFLA_INET6_RA_MTU] = { .type = NLA_REJECT, + .reject_message = + "IFLA_INET6_RA_MTU can't be set" }, }; static int check_addr_gen_mode(int mode) diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index c467c6419893..23e690769857 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1391,12 +1391,6 @@ static void ndisc_router_discovery(struct sk_buff *skb) } } - /* - * Send a notify if RA changed managed/otherconf flags or timer settings - */ - if (send_ifinfo_notify) - inet6_ifinfo_notify(RTM_NEWLINK, in6_dev); - skip_linkparms: /* @@ -1496,6 +1490,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->ra_mtu != mtu) { + in6_dev->ra_mtu = mtu; + send_ifinfo_notify = true; + } + 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) { @@ -1519,6 +1518,12 @@ static void ndisc_router_discovery(struct sk_buff *skb) ND_PRINTK(2, warn, "RA: invalid RA options\n"); } out: + /* Send a notify if RA changed managed/otherconf flags or timer + * settings or ra_mtu value + */ + if (send_ifinfo_notify) + inet6_ifinfo_notify(RTM_NEWLINK, in6_dev); + fib6_info_release(rt); if (neigh) neigh_release(neigh); diff --git a/tools/include/uapi/linux/if_link.h b/tools/include/uapi/linux/if_link.h index eb15f319aa57..b3610fdd1fee 100644 --- a/tools/include/uapi/linux/if_link.h +++ b/tools/include/uapi/linux/if_link.h @@ -230,6 +230,7 @@ enum { IFLA_INET6_ICMP6STATS, /* statistics (icmpv6) */ IFLA_INET6_TOKEN, /* device token */ IFLA_INET6_ADDR_GEN_MODE, /* implicit address generator mode */ + IFLA_INET6_RA_MTU, /* mtu carried in the RA message */ __IFLA_INET6_MAX }; -- 2.18.0