--- /dev/null
+From 9b0401382acbca9fb60758d88d0c7cc788b8fb5a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jul 2023 11:27:26 +0800
+Subject: benet: fix return value check in be_lancer_xmit_workarounds()
+
+From: Yuanjun Gong <ruc_gongyuanjun@163.com>
+
+[ Upstream commit 5c85f7065718a949902b238a6abd8fc907c5d3e0 ]
+
+in be_lancer_xmit_workarounds(), it should go to label 'tx_drop'
+if an unexpected value is returned by pskb_trim().
+
+Fixes: 93040ae5cc8d ("be2net: Fix to trim skb for padded vlan packets to workaround an ASIC Bug")
+Signed-off-by: Yuanjun Gong <ruc_gongyuanjun@163.com>
+Link: https://lore.kernel.org/r/20230725032726.15002-1-ruc_gongyuanjun@163.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/emulex/benet/be_main.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index f1cce7636722e..a7a3e2ee06768 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -1140,7 +1140,8 @@ static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter,
+ (lancer_chip(adapter) || BE3_chip(adapter) ||
+ skb_vlan_tag_present(skb)) && is_ipv4_pkt(skb)) {
+ ip = (struct iphdr *)ip_hdr(skb);
+- pskb_trim(skb, eth_hdr_len + ntohs(ip->tot_len));
++ if (unlikely(pskb_trim(skb, eth_hdr_len + ntohs(ip->tot_len))))
++ goto tx_drop;
+ }
+
+ /* If vlan tag is already inlined in the packet, skip HW VLAN
+--
+2.39.2
+
--- /dev/null
+From f115fd4126da673eb2b5fa3627efbeb459b06a6d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Jul 2023 12:03:55 +0800
+Subject: bonding: reset bond's flags when down link is P2P device
+
+From: Hangbin Liu <liuhangbin@gmail.com>
+
+[ Upstream commit da19a2b967cf1e2c426f50d28550d1915214a81d ]
+
+When adding a point to point downlink to the bond, we neglected to reset
+the bond's flags, which were still using flags like BROADCAST and
+MULTICAST. Consequently, this would initiate ARP/DAD for P2P downlink
+interfaces, such as when adding a GRE device to the bonding.
+
+To address this issue, let's reset the bond's flags for P2P interfaces.
+
+Before fix:
+7: gre0@NONE: <POINTOPOINT,NOARP,SLAVE,UP,LOWER_UP> mtu 1500 qdisc noqueue master bond0 state UNKNOWN group default qlen 1000
+ link/gre6 2006:70:10::1 peer 2006:70:10::2 permaddr 167f:18:f188::
+8: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
+ link/gre6 2006:70:10::1 brd 2006:70:10::2
+ inet6 fe80::200:ff:fe00:0/64 scope link
+ valid_lft forever preferred_lft forever
+
+After fix:
+7: gre0@NONE: <POINTOPOINT,NOARP,SLAVE,UP,LOWER_UP> mtu 1500 qdisc noqueue master bond2 state UNKNOWN group default qlen 1000
+ link/gre6 2006:70:10::1 peer 2006:70:10::2 permaddr c29e:557a:e9d9::
+8: bond0: <POINTOPOINT,NOARP,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
+ link/gre6 2006:70:10::1 peer 2006:70:10::2
+ inet6 fe80::1/64 scope link
+ valid_lft forever preferred_lft forever
+
+Reported-by: Liang Li <liali@redhat.com>
+Closes: https://bugzilla.redhat.com/show_bug.cgi?id=2221438
+Fixes: 872254dd6b1f ("net/bonding: Enable bonding to enslave non ARPHRD_ETHER")
+Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_main.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index cdb9efae6032d..dcaefb47d1f2d 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -1153,6 +1153,11 @@ static void bond_setup_by_slave(struct net_device *bond_dev,
+
+ memcpy(bond_dev->broadcast, slave_dev->broadcast,
+ slave_dev->addr_len);
++
++ if (slave_dev->flags & IFF_POINTOPOINT) {
++ bond_dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST);
++ bond_dev->flags |= (IFF_POINTOPOINT | IFF_NOARP);
++ }
+ }
+
+ /* On bonding slaves other than the currently active slave, suppress
+--
+2.39.2
+
--- /dev/null
+From c3982e83a6e2c53b7de75e959cf91333fe7d6ab1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Jul 2023 22:42:19 +0800
+Subject: ethernet: atheros: fix return value check in atl1e_tso_csum()
+
+From: Yuanjun Gong <ruc_gongyuanjun@163.com>
+
+[ Upstream commit 69a184f7a372aac588babfb0bd681aaed9779f5b ]
+
+in atl1e_tso_csum, it should check the return value of pskb_trim(),
+and return an error code if an unexpected value is returned
+by pskb_trim().
+
+Fixes: a6a5325239c2 ("atl1e: Atheros L1E Gigabit Ethernet driver")
+Signed-off-by: Yuanjun Gong <ruc_gongyuanjun@163.com>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Link: https://lore.kernel.org/r/20230720144219.39285-1-ruc_gongyuanjun@163.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
+index 4f7b65825c159..6bdd79a057190 100644
+--- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
++++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
+@@ -1638,8 +1638,11 @@ static int atl1e_tso_csum(struct atl1e_adapter *adapter,
+ real_len = (((unsigned char *)ip_hdr(skb) - skb->data)
+ + ntohs(ip_hdr(skb)->tot_len));
+
+- if (real_len < skb->len)
+- pskb_trim(skb, real_len);
++ if (real_len < skb->len) {
++ err = pskb_trim(skb, real_len);
++ if (err)
++ return err;
++ }
+
+ hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
+ if (unlikely(skb->len == hdr_len)) {
+--
+2.39.2
+
--- /dev/null
+From f521525c5f66bcde8d42d96b8b2344aa257bd19e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Jul 2023 09:42:39 +0800
+Subject: i40e: Fix an NULL vs IS_ERR() bug for debugfs_create_dir()
+
+From: Wang Ming <machel@vivo.com>
+
+[ Upstream commit 043b1f185fb0f3939b7427f634787706f45411c4 ]
+
+The debugfs_create_dir() function returns error pointers.
+It never returns NULL. Most incorrect error checks were fixed,
+but the one in i40e_dbg_init() was forgotten.
+
+Fix the remaining error check.
+
+Fixes: 02e9c290814c ("i40e: debugfs interface")
+Signed-off-by: Wang Ming <machel@vivo.com>
+Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e_debugfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
+index 276f04c0e51d6..31f60657f5321 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
+@@ -1755,7 +1755,7 @@ void i40e_dbg_pf_exit(struct i40e_pf *pf)
+ void i40e_dbg_init(void)
+ {
+ i40e_dbg_root = debugfs_create_dir(i40e_driver_name, NULL);
+- if (!i40e_dbg_root)
++ if (IS_ERR(i40e_dbg_root))
+ pr_info("init of debugfs failed\n");
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 569584fbe75516f613e8fd510589c096ec94ae7d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Jul 2023 09:00:22 -0700
+Subject: ipv6 addrconf: fix bug where deleting a mngtmpaddr can create a new
+ temporary address
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maciej Żenczykowski <maze@google.com>
+
+[ Upstream commit 69172f0bcb6a09110c5d2a6d792627f5095a9018 ]
+
+currently on 6.4 net/main:
+
+ # ip link add dummy1 type dummy
+ # echo 1 > /proc/sys/net/ipv6/conf/dummy1/use_tempaddr
+ # ip link set dummy1 up
+ # ip -6 addr add 2000::1/64 mngtmpaddr dev dummy1
+ # ip -6 addr show dev dummy1
+
+ 11: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
+ inet6 2000::44f3:581c:8ca:3983/64 scope global temporary dynamic
+ valid_lft 604800sec preferred_lft 86172sec
+ inet6 2000::1/64 scope global mngtmpaddr
+ valid_lft forever preferred_lft forever
+ inet6 fe80::e8a8:a6ff:fed5:56d4/64 scope link
+ valid_lft forever preferred_lft forever
+
+ # ip -6 addr del 2000::44f3:581c:8ca:3983/64 dev dummy1
+
+ (can wait a few seconds if you want to, the above delete isn't [directly] the problem)
+
+ # ip -6 addr show dev dummy1
+
+ 11: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
+ inet6 2000::1/64 scope global mngtmpaddr
+ valid_lft forever preferred_lft forever
+ inet6 fe80::e8a8:a6ff:fed5:56d4/64 scope link
+ valid_lft forever preferred_lft forever
+
+ # ip -6 addr del 2000::1/64 mngtmpaddr dev dummy1
+ # ip -6 addr show dev dummy1
+
+ 11: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
+ inet6 2000::81c9:56b7:f51a:b98f/64 scope global temporary dynamic
+ valid_lft 604797sec preferred_lft 86169sec
+ inet6 fe80::e8a8:a6ff:fed5:56d4/64 scope link
+ valid_lft forever preferred_lft forever
+
+This patch prevents this new 'global temporary dynamic' address from being
+created by the deletion of the related (same subnet prefix) 'mngtmpaddr'
+(which is triggered by there already being no temporary addresses).
+
+Cc: Jiri Pirko <jiri@resnulli.us>
+Fixes: 53bd67491537 ("ipv6 addrconf: introduce IFA_F_MANAGETEMPADDR to tell kernel to manage temporary addresses")
+Reported-by: Xiao Ma <xiaom@google.com>
+Signed-off-by: Maciej Żenczykowski <maze@google.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://lore.kernel.org/r/20230720160022.1887942-1-maze@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/addrconf.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index 46e3c939958bb..a4c3cb72bdc6a 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -2541,12 +2541,18 @@ static void manage_tempaddrs(struct inet6_dev *idev,
+ ipv6_ifa_notify(0, ift);
+ }
+
+- if ((create || list_empty(&idev->tempaddr_list)) &&
+- idev->cnf.use_tempaddr > 0) {
++ /* Also create a temporary address if it's enabled but no temporary
++ * address currently exists.
++ * However, we get called with valid_lft == 0, prefered_lft == 0, create == false
++ * as part of cleanup (ie. deleting the mngtmpaddr).
++ * We don't want that to result in creating a new temporary ip address.
++ */
++ if (list_empty(&idev->tempaddr_list) && (valid_lft || prefered_lft))
++ create = true;
++
++ if (create && idev->cnf.use_tempaddr > 0) {
+ /* When a new public address is created as described
+ * in [ADDRCONF], also create a new temporary address.
+- * Also create a temporary address if it's enabled but
+- * no temporary address currently exists.
+ */
+ read_unlock_bh(&idev->lock);
+ ipv6_create_tempaddr(ifp, NULL, false);
+--
+2.39.2
+
--- /dev/null
+From f5d14d18f2767bad0547a6beef9dfdc4bde5b851 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Apr 2023 21:01:51 +0300
+Subject: net/sched: mqprio: add extack to mqprio_parse_nlattr()
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 57f21bf85400abadac0cb2a4db5de1d663f8863f ]
+
+Netlink attribute parsing in mqprio is a minesweeper game, with many
+options having the possibility of being passed incorrectly and the user
+being none the wiser.
+
+Try to make errors less sour by giving user space some information
+regarding what went wrong.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Ferenc Fejes <fejes@inf.elte.hu>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 6c58c8816abb ("net/sched: mqprio: Add length check for TCA_MQPRIO_{MAX/MIN}_RATE64")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_mqprio.c | 30 +++++++++++++++++++++++-------
+ 1 file changed, 23 insertions(+), 7 deletions(-)
+
+diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c
+index a5df5604e0150..4ec222a5530d1 100644
+--- a/net/sched/sch_mqprio.c
++++ b/net/sched/sch_mqprio.c
+@@ -131,7 +131,8 @@ static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla,
+ }
+
+ static int mqprio_parse_nlattr(struct Qdisc *sch, struct tc_mqprio_qopt *qopt,
+- struct nlattr *opt)
++ struct nlattr *opt,
++ struct netlink_ext_ack *extack)
+ {
+ struct mqprio_sched *priv = qdisc_priv(sch);
+ struct nlattr *tb[TCA_MQPRIO_MAX + 1];
+@@ -143,8 +144,11 @@ static int mqprio_parse_nlattr(struct Qdisc *sch, struct tc_mqprio_qopt *qopt,
+ if (err < 0)
+ return err;
+
+- if (!qopt->hw)
++ if (!qopt->hw) {
++ NL_SET_ERR_MSG(extack,
++ "mqprio TCA_OPTIONS can only contain netlink attributes in hardware mode");
+ return -EINVAL;
++ }
+
+ if (tb[TCA_MQPRIO_MODE]) {
+ priv->flags |= TC_MQPRIO_F_MODE;
+@@ -157,13 +161,19 @@ static int mqprio_parse_nlattr(struct Qdisc *sch, struct tc_mqprio_qopt *qopt,
+ }
+
+ if (tb[TCA_MQPRIO_MIN_RATE64]) {
+- if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE)
++ if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) {
++ NL_SET_ERR_MSG_ATTR(extack, tb[TCA_MQPRIO_MIN_RATE64],
++ "min_rate accepted only when shaper is in bw_rlimit mode");
+ return -EINVAL;
++ }
+ i = 0;
+ nla_for_each_nested(attr, tb[TCA_MQPRIO_MIN_RATE64],
+ rem) {
+- if (nla_type(attr) != TCA_MQPRIO_MIN_RATE64)
++ if (nla_type(attr) != TCA_MQPRIO_MIN_RATE64) {
++ NL_SET_ERR_MSG_ATTR(extack, attr,
++ "Attribute type expected to be TCA_MQPRIO_MIN_RATE64");
+ return -EINVAL;
++ }
+ if (i >= qopt->num_tc)
+ break;
+ priv->min_rate[i] = *(u64 *)nla_data(attr);
+@@ -173,13 +183,19 @@ static int mqprio_parse_nlattr(struct Qdisc *sch, struct tc_mqprio_qopt *qopt,
+ }
+
+ if (tb[TCA_MQPRIO_MAX_RATE64]) {
+- if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE)
++ if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) {
++ NL_SET_ERR_MSG_ATTR(extack, tb[TCA_MQPRIO_MAX_RATE64],
++ "max_rate accepted only when shaper is in bw_rlimit mode");
+ return -EINVAL;
++ }
+ i = 0;
+ nla_for_each_nested(attr, tb[TCA_MQPRIO_MAX_RATE64],
+ rem) {
+- if (nla_type(attr) != TCA_MQPRIO_MAX_RATE64)
++ if (nla_type(attr) != TCA_MQPRIO_MAX_RATE64) {
++ NL_SET_ERR_MSG_ATTR(extack, attr,
++ "Attribute type expected to be TCA_MQPRIO_MAX_RATE64");
+ return -EINVAL;
++ }
+ if (i >= qopt->num_tc)
+ break;
+ priv->max_rate[i] = *(u64 *)nla_data(attr);
+@@ -224,7 +240,7 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt,
+
+ len = nla_len(opt) - NLA_ALIGN(sizeof(*qopt));
+ if (len > 0) {
+- err = mqprio_parse_nlattr(sch, qopt, opt);
++ err = mqprio_parse_nlattr(sch, qopt, opt, extack);
+ if (err)
+ return err;
+ }
+--
+2.39.2
+
--- /dev/null
+From 8c381c928e69a251d4d9302636f04e879347048b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jul 2023 10:42:27 +0800
+Subject: net/sched: mqprio: Add length check for TCA_MQPRIO_{MAX/MIN}_RATE64
+
+From: Lin Ma <linma@zju.edu.cn>
+
+[ Upstream commit 6c58c8816abb7b93b21fa3b1d0c1726402e5e568 ]
+
+The nla_for_each_nested parsing in function mqprio_parse_nlattr() does
+not check the length of the nested attribute. This can lead to an
+out-of-attribute read and allow a malformed nlattr (e.g., length 0) to
+be viewed as 8 byte integer and passed to priv->max_rate/min_rate.
+
+This patch adds the check based on nla_len() when check the nla_type(),
+which ensures that the length of these two attribute must equals
+sizeof(u64).
+
+Fixes: 4e8b86c06269 ("mqprio: Introduce new hardware offload mode and shaper in mqprio")
+Reviewed-by: Victor Nogueira <victor@mojatatu.com>
+Signed-off-by: Lin Ma <linma@zju.edu.cn>
+Link: https://lore.kernel.org/r/20230725024227.426561-1-linma@zju.edu.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_mqprio.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c
+index 4ec222a5530d1..56d3dc5e95c7c 100644
+--- a/net/sched/sch_mqprio.c
++++ b/net/sched/sch_mqprio.c
+@@ -174,6 +174,13 @@ static int mqprio_parse_nlattr(struct Qdisc *sch, struct tc_mqprio_qopt *qopt,
+ "Attribute type expected to be TCA_MQPRIO_MIN_RATE64");
+ return -EINVAL;
+ }
++
++ if (nla_len(attr) != sizeof(u64)) {
++ NL_SET_ERR_MSG_ATTR(extack, attr,
++ "Attribute TCA_MQPRIO_MIN_RATE64 expected to have 8 bytes length");
++ return -EINVAL;
++ }
++
+ if (i >= qopt->num_tc)
+ break;
+ priv->min_rate[i] = *(u64 *)nla_data(attr);
+@@ -196,6 +203,13 @@ static int mqprio_parse_nlattr(struct Qdisc *sch, struct tc_mqprio_qopt *qopt,
+ "Attribute type expected to be TCA_MQPRIO_MAX_RATE64");
+ return -EINVAL;
+ }
++
++ if (nla_len(attr) != sizeof(u64)) {
++ NL_SET_ERR_MSG_ATTR(extack, attr,
++ "Attribute TCA_MQPRIO_MAX_RATE64 expected to have 8 bytes length");
++ return -EINVAL;
++ }
++
+ if (i >= qopt->num_tc)
+ break;
+ priv->max_rate[i] = *(u64 *)nla_data(attr);
+--
+2.39.2
+
--- /dev/null
+From ebb82c4e69bb82febb2a619428242e747ecaaf03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Feb 2023 15:52:55 +0200
+Subject: net/sched: mqprio: refactor nlattr parsing to a separate function
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit feb2cf3dcfb930aec2ca65c66d1365543d5ba943 ]
+
+mqprio_init() is quite large and unwieldy to add more code to.
+Split the netlink attribute parsing to a dedicated function.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 6c58c8816abb ("net/sched: mqprio: Add length check for TCA_MQPRIO_{MAX/MIN}_RATE64")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_mqprio.c | 114 +++++++++++++++++++++++------------------
+ 1 file changed, 63 insertions(+), 51 deletions(-)
+
+diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c
+index 50e15add6068f..a5df5604e0150 100644
+--- a/net/sched/sch_mqprio.c
++++ b/net/sched/sch_mqprio.c
+@@ -130,6 +130,67 @@ static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla,
+ return 0;
+ }
+
++static int mqprio_parse_nlattr(struct Qdisc *sch, struct tc_mqprio_qopt *qopt,
++ struct nlattr *opt)
++{
++ struct mqprio_sched *priv = qdisc_priv(sch);
++ struct nlattr *tb[TCA_MQPRIO_MAX + 1];
++ struct nlattr *attr;
++ int i, rem, err;
++
++ err = parse_attr(tb, TCA_MQPRIO_MAX, opt, mqprio_policy,
++ sizeof(*qopt));
++ if (err < 0)
++ return err;
++
++ if (!qopt->hw)
++ return -EINVAL;
++
++ if (tb[TCA_MQPRIO_MODE]) {
++ priv->flags |= TC_MQPRIO_F_MODE;
++ priv->mode = *(u16 *)nla_data(tb[TCA_MQPRIO_MODE]);
++ }
++
++ if (tb[TCA_MQPRIO_SHAPER]) {
++ priv->flags |= TC_MQPRIO_F_SHAPER;
++ priv->shaper = *(u16 *)nla_data(tb[TCA_MQPRIO_SHAPER]);
++ }
++
++ if (tb[TCA_MQPRIO_MIN_RATE64]) {
++ if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE)
++ return -EINVAL;
++ i = 0;
++ nla_for_each_nested(attr, tb[TCA_MQPRIO_MIN_RATE64],
++ rem) {
++ if (nla_type(attr) != TCA_MQPRIO_MIN_RATE64)
++ return -EINVAL;
++ if (i >= qopt->num_tc)
++ break;
++ priv->min_rate[i] = *(u64 *)nla_data(attr);
++ i++;
++ }
++ priv->flags |= TC_MQPRIO_F_MIN_RATE;
++ }
++
++ if (tb[TCA_MQPRIO_MAX_RATE64]) {
++ if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE)
++ return -EINVAL;
++ i = 0;
++ nla_for_each_nested(attr, tb[TCA_MQPRIO_MAX_RATE64],
++ rem) {
++ if (nla_type(attr) != TCA_MQPRIO_MAX_RATE64)
++ return -EINVAL;
++ if (i >= qopt->num_tc)
++ break;
++ priv->max_rate[i] = *(u64 *)nla_data(attr);
++ i++;
++ }
++ priv->flags |= TC_MQPRIO_F_MAX_RATE;
++ }
++
++ return 0;
++}
++
+ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt,
+ struct netlink_ext_ack *extack)
+ {
+@@ -139,9 +200,6 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt,
+ struct Qdisc *qdisc;
+ int i, err = -EOPNOTSUPP;
+ struct tc_mqprio_qopt *qopt = NULL;
+- struct nlattr *tb[TCA_MQPRIO_MAX + 1];
+- struct nlattr *attr;
+- int rem;
+ int len;
+
+ BUILD_BUG_ON(TC_MAX_QUEUE != TC_QOPT_MAX_QUEUE);
+@@ -166,55 +224,9 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt,
+
+ len = nla_len(opt) - NLA_ALIGN(sizeof(*qopt));
+ if (len > 0) {
+- err = parse_attr(tb, TCA_MQPRIO_MAX, opt, mqprio_policy,
+- sizeof(*qopt));
+- if (err < 0)
++ err = mqprio_parse_nlattr(sch, qopt, opt);
++ if (err)
+ return err;
+-
+- if (!qopt->hw)
+- return -EINVAL;
+-
+- if (tb[TCA_MQPRIO_MODE]) {
+- priv->flags |= TC_MQPRIO_F_MODE;
+- priv->mode = *(u16 *)nla_data(tb[TCA_MQPRIO_MODE]);
+- }
+-
+- if (tb[TCA_MQPRIO_SHAPER]) {
+- priv->flags |= TC_MQPRIO_F_SHAPER;
+- priv->shaper = *(u16 *)nla_data(tb[TCA_MQPRIO_SHAPER]);
+- }
+-
+- if (tb[TCA_MQPRIO_MIN_RATE64]) {
+- if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE)
+- return -EINVAL;
+- i = 0;
+- nla_for_each_nested(attr, tb[TCA_MQPRIO_MIN_RATE64],
+- rem) {
+- if (nla_type(attr) != TCA_MQPRIO_MIN_RATE64)
+- return -EINVAL;
+- if (i >= qopt->num_tc)
+- break;
+- priv->min_rate[i] = *(u64 *)nla_data(attr);
+- i++;
+- }
+- priv->flags |= TC_MQPRIO_F_MIN_RATE;
+- }
+-
+- if (tb[TCA_MQPRIO_MAX_RATE64]) {
+- if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE)
+- return -EINVAL;
+- i = 0;
+- nla_for_each_nested(attr, tb[TCA_MQPRIO_MAX_RATE64],
+- rem) {
+- if (nla_type(attr) != TCA_MQPRIO_MAX_RATE64)
+- return -EINVAL;
+- if (i >= qopt->num_tc)
+- break;
+- priv->max_rate[i] = *(u64 *)nla_data(attr);
+- i++;
+- }
+- priv->flags |= TC_MQPRIO_F_MAX_RATE;
+- }
+ }
+
+ /* pre-allocate qdisc, attachment can't fail */
+--
+2.39.2
+
--- /dev/null
+From 30bc2a85e4980476ef6a1d6f4b00be6d17ab9ec7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Jul 2023 02:05:55 -0700
+Subject: phy: hisilicon: Fix an out of bounds check in hisi_inno_phy_probe()
+
+From: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+
+[ Upstream commit 13c088cf3657d70893d75cf116be937f1509cc0f ]
+
+The size of array 'priv->ports[]' is INNO_PHY_PORT_NUM.
+
+In the for loop, 'i' is used as the index for array 'priv->ports[]'
+with a check (i > INNO_PHY_PORT_NUM) which indicates that
+INNO_PHY_PORT_NUM is allowed value for 'i' in the same loop.
+
+This > comparison needs to be changed to >=, otherwise it potentially leads
+to an out of bounds write on the next iteration through the loop
+
+Fixes: ba8b0ee81fbb ("phy: add inno-usb2-phy driver for hi3798cv200 SoC")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+Link: https://lore.kernel.org/r/20230721090558.3588613-1-harshit.m.mogalapalli@oracle.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/hisilicon/phy-hisi-inno-usb2.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/phy/hisilicon/phy-hisi-inno-usb2.c b/drivers/phy/hisilicon/phy-hisi-inno-usb2.c
+index 9b16f13b5ab29..96162b9a2e53d 100644
+--- a/drivers/phy/hisilicon/phy-hisi-inno-usb2.c
++++ b/drivers/phy/hisilicon/phy-hisi-inno-usb2.c
+@@ -155,7 +155,7 @@ static int hisi_inno_phy_probe(struct platform_device *pdev)
+ phy_set_drvdata(phy, &priv->ports[i]);
+ i++;
+
+- if (i > INNO_PHY_PORT_NUM) {
++ if (i >= INNO_PHY_PORT_NUM) {
+ dev_warn(dev, "Support %d ports in maximum\n", i);
+ break;
+ }
+--
+2.39.2
+
--- /dev/null
+From ad64e552e66dcafbb43c6e178000a97dfc861f32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Jul 2023 17:54:23 +0300
+Subject: platform/x86: msi-laptop: Fix rfkill out-of-sync on MSI Wind U100
+
+From: Maxim Mikityanskiy <maxtram95@gmail.com>
+
+[ Upstream commit ad084a6d99bc182bf109c190c808e2ea073ec57b ]
+
+Only the HW rfkill state is toggled on laptops with quirks->ec_read_only
+(so far only MSI Wind U90/U100). There are, however, a few issues with
+the implementation:
+
+1. The initial HW state is always unblocked, regardless of the actual
+ state on boot, because msi_init_rfkill only sets the SW state,
+ regardless of ec_read_only.
+
+2. The initial SW state corresponds to the actual state on boot, but it
+ can't be changed afterwards, because set_device_state returns
+ -EOPNOTSUPP. It confuses the userspace, making Wi-Fi and/or Bluetooth
+ unusable if it was blocked on boot, and breaking the airplane mode if
+ the rfkill was unblocked on boot.
+
+Address the above issues by properly initializing the HW state on
+ec_read_only laptops and by allowing the userspace to toggle the SW
+state. Don't set the SW state ourselves and let the userspace fully
+control it. Toggling the SW state is a no-op, however, it allows the
+userspace to properly toggle the airplane mode. The actual SW radio
+disablement is handled by the corresponding rtl818x_pci and btusb
+drivers that have their own rfkills.
+
+Tested on MSI Wind U100 Plus, BIOS ver 1.0G, EC ver 130.
+
+Fixes: 0816392b97d4 ("msi-laptop: merge quirk tables to one")
+Fixes: 0de6575ad0a8 ("msi-laptop: Add MSI Wind U90/U100 support")
+Signed-off-by: Maxim Mikityanskiy <maxtram95@gmail.com>
+Link: https://lore.kernel.org/r/20230721145423.161057-1-maxtram95@gmail.com
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/msi-laptop.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c
+index 0e804b6c2d242..dfb4af759aa75 100644
+--- a/drivers/platform/x86/msi-laptop.c
++++ b/drivers/platform/x86/msi-laptop.c
+@@ -210,7 +210,7 @@ static ssize_t set_device_state(const char *buf, size_t count, u8 mask)
+ return -EINVAL;
+
+ if (quirks->ec_read_only)
+- return -EOPNOTSUPP;
++ return 0;
+
+ /* read current device state */
+ result = ec_read(MSI_STANDARD_EC_COMMAND_ADDRESS, &rdata);
+@@ -841,15 +841,15 @@ static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str,
+ static void msi_init_rfkill(struct work_struct *ignored)
+ {
+ if (rfk_wlan) {
+- rfkill_set_sw_state(rfk_wlan, !wlan_s);
++ msi_rfkill_set_state(rfk_wlan, !wlan_s);
+ rfkill_wlan_set(NULL, !wlan_s);
+ }
+ if (rfk_bluetooth) {
+- rfkill_set_sw_state(rfk_bluetooth, !bluetooth_s);
++ msi_rfkill_set_state(rfk_bluetooth, !bluetooth_s);
+ rfkill_bluetooth_set(NULL, !bluetooth_s);
+ }
+ if (rfk_threeg) {
+- rfkill_set_sw_state(rfk_threeg, !threeg_s);
++ msi_rfkill_set_state(rfk_threeg, !threeg_s);
+ rfkill_threeg_set(NULL, !threeg_s);
+ }
+ }
+--
+2.39.2
+
uapi-general-notification-queue-definitions.patch
keys-fix-linking-a-duplicate-key-to-a-keyring-s-asso.patch
ext4-fix-to-check-return-value-of-freeze_bdev-in-ext.patch
+i40e-fix-an-null-vs-is_err-bug-for-debugfs_create_di.patch
+vxlan-calculate-correct-header-length-for-gpe.patch
+phy-hisilicon-fix-an-out-of-bounds-check-in-hisi_inn.patch
+ethernet-atheros-fix-return-value-check-in-atl1e_tso.patch
+ipv6-addrconf-fix-bug-where-deleting-a-mngtmpaddr-ca.patch
+tcp-reduce-chance-of-collisions-in-inet6_hashfn.patch
+bonding-reset-bond-s-flags-when-down-link-is-p2p-dev.patch
+team-reset-team-s-flags-when-down-link-is-p2p-device.patch
+platform-x86-msi-laptop-fix-rfkill-out-of-sync-on-ms.patch
+net-sched-mqprio-refactor-nlattr-parsing-to-a-separa.patch
+net-sched-mqprio-add-extack-to-mqprio_parse_nlattr.patch
+net-sched-mqprio-add-length-check-for-tca_mqprio_-ma.patch
+benet-fix-return-value-check-in-be_lancer_xmit_worka.patch
--- /dev/null
+From c06dfeca7a9b75758512603f5bc28e57eb405726 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Jul 2023 15:24:10 -0700
+Subject: tcp: Reduce chance of collisions in inet6_hashfn().
+
+From: Stewart Smith <trawets@amazon.com>
+
+[ Upstream commit d11b0df7ddf1831f3e170972f43186dad520bfcc ]
+
+For both IPv4 and IPv6 incoming TCP connections are tracked in a hash
+table with a hash over the source & destination addresses and ports.
+However, the IPv6 hash is insufficient and can lead to a high rate of
+collisions.
+
+The IPv6 hash used an XOR to fit everything into the 96 bits for the
+fast jenkins hash, meaning it is possible for an external entity to
+ensure the hash collides, thus falling back to a linear search in the
+bucket, which is slow.
+
+We take the approach of hash the full length of IPv6 address in
+__ipv6_addr_jhash() so that all users can benefit from a more secure
+version.
+
+While this may look like it adds overhead, the reality of modern CPUs
+means that this is unmeasurable in real world scenarios.
+
+In simulating with llvm-mca, the increase in cycles for the hashing
+code was ~16 cycles on Skylake (from a base of ~155), and an extra ~9
+on Nehalem (base of ~173).
+
+In commit dd6d2910c5e0 ("netfilter: conntrack: switch to siphash")
+netfilter switched from a jenkins hash to a siphash, but even the faster
+hsiphash is a more significant overhead (~20-30%) in some preliminary
+testing. So, in this patch, we keep to the more conservative approach to
+ensure we don't add much overhead per SYN.
+
+In testing, this results in a consistently even spread across the
+connection buckets. In both testing and real-world scenarios, we have
+not found any measurable performance impact.
+
+Fixes: 08dcdbf6a7b9 ("ipv6: use a stronger hash for tcp")
+Signed-off-by: Stewart Smith <trawets@amazon.com>
+Signed-off-by: Samuel Mendoza-Jonas <samjonas@amazon.com>
+Suggested-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://lore.kernel.org/r/20230721222410.17914-1-kuniyu@amazon.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/ipv6.h | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/include/net/ipv6.h b/include/net/ipv6.h
+index 0e031a4fef408..8c454509f299f 100644
+--- a/include/net/ipv6.h
++++ b/include/net/ipv6.h
+@@ -660,12 +660,8 @@ static inline u32 ipv6_addr_hash(const struct in6_addr *a)
+ /* more secured version of ipv6_addr_hash() */
+ static inline u32 __ipv6_addr_jhash(const struct in6_addr *a, const u32 initval)
+ {
+- u32 v = (__force u32)a->s6_addr32[0] ^ (__force u32)a->s6_addr32[1];
+-
+- return jhash_3words(v,
+- (__force u32)a->s6_addr32[2],
+- (__force u32)a->s6_addr32[3],
+- initval);
++ return jhash2((__force const u32 *)a->s6_addr32,
++ ARRAY_SIZE(a->s6_addr32), initval);
+ }
+
+ static inline bool ipv6_addr_loopback(const struct in6_addr *a)
+--
+2.39.2
+
--- /dev/null
+From 80afbe8c0b2a439e0ef419a03711cfe70fc4900e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Jul 2023 12:03:56 +0800
+Subject: team: reset team's flags when down link is P2P device
+
+From: Hangbin Liu <liuhangbin@gmail.com>
+
+[ Upstream commit fa532bee17d15acf8bba4bc8e2062b7a093ba801 ]
+
+When adding a point to point downlink to team device, we neglected to reset
+the team's flags, which were still using flags like BROADCAST and
+MULTICAST. Consequently, this would initiate ARP/DAD for P2P downlink
+interfaces, such as when adding a GRE device to team device. Fix this by
+remove multicast/broadcast flags and add p2p and noarp flags.
+
+After removing the none ethernet interface and adding an ethernet interface
+to team, we need to reset team interface flags. Unlike bonding interface,
+team do not need restore IFF_MASTER, IFF_SLAVE flags.
+
+Reported-by: Liang Li <liali@redhat.com>
+Closes: https://bugzilla.redhat.com/show_bug.cgi?id=2221438
+Fixes: 1d76efe1577b ("team: add support for non-ethernet devices")
+Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/team/team.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
+index 227d97b4dc224..5c72e9ac4804d 100644
+--- a/drivers/net/team/team.c
++++ b/drivers/net/team/team.c
+@@ -2129,6 +2129,15 @@ static void team_setup_by_port(struct net_device *dev,
+ dev->mtu = port_dev->mtu;
+ memcpy(dev->broadcast, port_dev->broadcast, port_dev->addr_len);
+ eth_hw_addr_inherit(dev, port_dev);
++
++ if (port_dev->flags & IFF_POINTOPOINT) {
++ dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST);
++ dev->flags |= (IFF_POINTOPOINT | IFF_NOARP);
++ } else if ((port_dev->flags & (IFF_BROADCAST | IFF_MULTICAST)) ==
++ (IFF_BROADCAST | IFF_MULTICAST)) {
++ dev->flags |= (IFF_BROADCAST | IFF_MULTICAST);
++ dev->flags &= ~(IFF_POINTOPOINT | IFF_NOARP);
++ }
+ }
+
+ static int team_dev_type_check_change(struct net_device *dev,
+--
+2.39.2
+
--- /dev/null
+From 88ab33b1bc4252164f70f897371328b77d76d3e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Jul 2023 11:05:56 +0200
+Subject: vxlan: calculate correct header length for GPE
+
+From: Jiri Benc <jbenc@redhat.com>
+
+[ Upstream commit 94d166c5318c6edd1e079df8552233443e909c33 ]
+
+VXLAN-GPE does not add an extra inner Ethernet header. Take that into
+account when calculating header length.
+
+This causes problems in skb_tunnel_check_pmtu, where incorrect PMTU is
+cached.
+
+In the collect_md mode (which is the only mode that VXLAN-GPE
+supports), there's no magic auto-setting of the tunnel interface MTU.
+It can't be, since the destination and thus the underlying interface
+may be different for each packet.
+
+So, the administrator is responsible for setting the correct tunnel
+interface MTU. Apparently, the administrators are capable enough to
+calculate that the maximum MTU for VXLAN-GPE is (their_lower_MTU - 36).
+They set the tunnel interface MTU to 1464. If you run a TCP stream over
+such interface, it's then segmented according to the MTU 1464, i.e.
+producing 1514 bytes frames. Which is okay, this still fits the lower
+MTU.
+
+However, skb_tunnel_check_pmtu (called from vxlan_xmit_one) uses 50 as
+the header size and thus incorrectly calculates the frame size to be
+1528. This leads to ICMP too big message being generated (locally),
+PMTU of 1450 to be cached and the TCP stream to be resegmented.
+
+The fix is to use the correct actual header size, especially for
+skb_tunnel_check_pmtu calculation.
+
+Fixes: e1e5314de08ba ("vxlan: implement GPE")
+Signed-off-by: Jiri Benc <jbenc@redhat.com>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +-
+ drivers/net/vxlan.c | 22 ++++++++-----------
+ include/net/vxlan.h | 13 +++++++----
+ 3 files changed, 19 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+index a864b91065e33..567bb7792f8fe 100644
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+@@ -8423,7 +8423,7 @@ static void ixgbe_atr(struct ixgbe_ring *ring,
+ struct ixgbe_adapter *adapter = q_vector->adapter;
+
+ if (unlikely(skb_tail_pointer(skb) < hdr.network +
+- VXLAN_HEADROOM))
++ vxlan_headroom(0)))
+ return;
+
+ /* verify the port is recognized as VXLAN */
+diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
+index f4869b1836f30..1e3e075454f33 100644
+--- a/drivers/net/vxlan.c
++++ b/drivers/net/vxlan.c
+@@ -2550,7 +2550,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
+ }
+
+ ndst = &rt->dst;
+- skb_tunnel_check_pmtu(skb, ndst, VXLAN_HEADROOM);
++ skb_tunnel_check_pmtu(skb, ndst, vxlan_headroom(flags & VXLAN_F_GPE));
+
+ tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
+ ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
+@@ -2590,7 +2590,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
+ goto out_unlock;
+ }
+
+- skb_tunnel_check_pmtu(skb, ndst, VXLAN6_HEADROOM);
++ skb_tunnel_check_pmtu(skb, ndst, vxlan_headroom((flags & VXLAN_F_GPE) | VXLAN_F_IPV6));
+
+ tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
+ ttl = ttl ? : ip6_dst_hoplimit(ndst);
+@@ -2908,14 +2908,12 @@ static int vxlan_change_mtu(struct net_device *dev, int new_mtu)
+ struct vxlan_rdst *dst = &vxlan->default_dst;
+ struct net_device *lowerdev = __dev_get_by_index(vxlan->net,
+ dst->remote_ifindex);
+- bool use_ipv6 = !!(vxlan->cfg.flags & VXLAN_F_IPV6);
+
+ /* This check is different than dev->max_mtu, because it looks at
+ * the lowerdev->mtu, rather than the static dev->max_mtu
+ */
+ if (lowerdev) {
+- int max_mtu = lowerdev->mtu -
+- (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
++ int max_mtu = lowerdev->mtu - vxlan_headroom(vxlan->cfg.flags);
+ if (new_mtu > max_mtu)
+ return -EINVAL;
+ }
+@@ -3514,11 +3512,11 @@ static void vxlan_config_apply(struct net_device *dev,
+ struct vxlan_dev *vxlan = netdev_priv(dev);
+ struct vxlan_rdst *dst = &vxlan->default_dst;
+ unsigned short needed_headroom = ETH_HLEN;
+- bool use_ipv6 = !!(conf->flags & VXLAN_F_IPV6);
+ int max_mtu = ETH_MAX_MTU;
++ u32 flags = conf->flags;
+
+ if (!changelink) {
+- if (conf->flags & VXLAN_F_GPE)
++ if (flags & VXLAN_F_GPE)
+ vxlan_raw_setup(dev);
+ else
+ vxlan_ether_setup(dev);
+@@ -3544,8 +3542,7 @@ static void vxlan_config_apply(struct net_device *dev,
+
+ dev->needed_tailroom = lowerdev->needed_tailroom;
+
+- max_mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM :
+- VXLAN_HEADROOM);
++ max_mtu = lowerdev->mtu - vxlan_headroom(flags);
+ if (max_mtu < ETH_MIN_MTU)
+ max_mtu = ETH_MIN_MTU;
+
+@@ -3556,10 +3553,9 @@ static void vxlan_config_apply(struct net_device *dev,
+ if (dev->mtu > max_mtu)
+ dev->mtu = max_mtu;
+
+- if (use_ipv6 || conf->flags & VXLAN_F_COLLECT_METADATA)
+- needed_headroom += VXLAN6_HEADROOM;
+- else
+- needed_headroom += VXLAN_HEADROOM;
++ if (flags & VXLAN_F_COLLECT_METADATA)
++ flags |= VXLAN_F_IPV6;
++ needed_headroom += vxlan_headroom(flags);
+ dev->needed_headroom = needed_headroom;
+
+ memcpy(&vxlan->cfg, conf, sizeof(*conf));
+diff --git a/include/net/vxlan.h b/include/net/vxlan.h
+index 373aadcfea21d..d79ee21d7932a 100644
+--- a/include/net/vxlan.h
++++ b/include/net/vxlan.h
+@@ -323,10 +323,15 @@ static inline netdev_features_t vxlan_features_check(struct sk_buff *skb,
+ return features;
+ }
+
+-/* IP header + UDP + VXLAN + Ethernet header */
+-#define VXLAN_HEADROOM (20 + 8 + 8 + 14)
+-/* IPv6 header + UDP + VXLAN + Ethernet header */
+-#define VXLAN6_HEADROOM (40 + 8 + 8 + 14)
++static inline int vxlan_headroom(u32 flags)
++{
++ /* VXLAN: IP4/6 header + UDP + VXLAN + Ethernet header */
++ /* VXLAN-GPE: IP4/6 header + UDP + VXLAN */
++ return (flags & VXLAN_F_IPV6 ? sizeof(struct ipv6hdr) :
++ sizeof(struct iphdr)) +
++ sizeof(struct udphdr) + sizeof(struct vxlanhdr) +
++ (flags & VXLAN_F_GPE ? 0 : ETH_HLEN);
++}
+
+ static inline struct vxlanhdr *vxlan_hdr(struct sk_buff *skb)
+ {
+--
+2.39.2
+