From: Greg Kroah-Hartman Date: Sat, 2 Feb 2019 11:20:04 +0000 (+0100) Subject: 4.14-stable patches X-Git-Tag: v4.20.7~42 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=149fc7c678fbd185170e1cb3aa01d5d85a1fa130;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: ipv6-consider-sk_bound_dev_if-when-binding-a-socket-to-an-address.patch ipv6-sr-clear-ip6cb-skb-on-srh-ip4ip6-encapsulation.patch ipvlan-l3mdev-fix-broken-l3s-mode-wrt-local-routes.patch l2tp-copy-4-more-bytes-to-linear-part-if-necessary.patch l2tp-fix-reading-optional-fields-of-l2tpv3.patch l2tp-remove-l2specific_len-dependency-in-l2tp_core.patch net-mlx4_core-add-masking-for-a-few-queries-on-hca-caps.patch net-mlx5e-allow-mac-invalidation-while-spoofchk-is-on.patch net-rose-fix-null-ax25_cb-kernel-panic.patch net-set-default-network-namespace-in-init_dummy_netdev.patch netrom-switch-to-sock-timer-api.patch revert-net-mlx5e-e-switch-initialize-eswitch-only-if-eswitch-manager.patch sctp-improve-the-events-for-sctp-stream-adding.patch sctp-improve-the-events-for-sctp-stream-reset.patch ucc_geth-reset-bql-queue-when-stopping-device.patch virtio_net-don-t-call-free_old_xmit_skbs-for-xdp_frames.patch virtio_net-don-t-enable-napi-when-interface-is-down.patch virtio_net-fix-not-restoring-real_num_rx_queues.patch --- diff --git a/queue-4.14/ipv6-consider-sk_bound_dev_if-when-binding-a-socket-to-an-address.patch b/queue-4.14/ipv6-consider-sk_bound_dev_if-when-binding-a-socket-to-an-address.patch new file mode 100644 index 00000000000..80b2f752a97 --- /dev/null +++ b/queue-4.14/ipv6-consider-sk_bound_dev_if-when-binding-a-socket-to-an-address.patch @@ -0,0 +1,37 @@ +From foo@baz Sat Feb 2 10:57:42 CET 2019 +From: David Ahern +Date: Wed, 2 Jan 2019 18:57:09 -0800 +Subject: ipv6: Consider sk_bound_dev_if when binding a socket to an address + +From: David Ahern + +[ Upstream commit c5ee066333ebc322a24a00a743ed941a0c68617e ] + +IPv6 does not consider if the socket is bound to a device when binding +to an address. The result is that a socket can be bound to eth0 and then +bound to the address of eth1. If the device is a VRF, the result is that +a socket can only be bound to an address in the default VRF. + +Resolve by considering the device if sk_bound_dev_if is set. + +This problem exists from the beginning of git history. + +Signed-off-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/af_inet6.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/ipv6/af_inet6.c ++++ b/net/ipv6/af_inet6.c +@@ -370,6 +370,9 @@ int inet6_bind(struct socket *sock, stru + err = -EINVAL; + goto out_unlock; + } ++ } ++ ++ if (sk->sk_bound_dev_if) { + dev = dev_get_by_index_rcu(net, sk->sk_bound_dev_if); + if (!dev) { + err = -ENODEV; diff --git a/queue-4.14/ipv6-sr-clear-ip6cb-skb-on-srh-ip4ip6-encapsulation.patch b/queue-4.14/ipv6-sr-clear-ip6cb-skb-on-srh-ip4ip6-encapsulation.patch new file mode 100644 index 00000000000..caf0afe0d5d --- /dev/null +++ b/queue-4.14/ipv6-sr-clear-ip6cb-skb-on-srh-ip4ip6-encapsulation.patch @@ -0,0 +1,37 @@ +From foo@baz Sat Feb 2 10:57:42 CET 2019 +From: Yohei Kanemaru +Date: Tue, 29 Jan 2019 15:52:34 +0900 +Subject: ipv6: sr: clear IP6CB(skb) on SRH ip4ip6 encapsulation + +From: Yohei Kanemaru + +[ Upstream commit ef489749aae508e6f17886775c075f12ff919fb1 ] + +skb->cb may contain data from previous layers (in an observed case +IPv4 with L3 Master Device). In the observed scenario, the data in +IPCB(skb)->frags was misinterpreted as IP6CB(skb)->frag_max_size, +eventually caused an unexpected IPv6 fragmentation in ip6_fragment() +through ip6_finish_output(). + +This patch clears IP6CB(skb), which potentially contains garbage data, +on the SRH ip4ip6 encapsulation. + +Fixes: 32d99d0b6702 ("ipv6: sr: add support for ip4ip6 encapsulation") +Signed-off-by: Yohei Kanemaru +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/seg6_iptunnel.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/ipv6/seg6_iptunnel.c ++++ b/net/ipv6/seg6_iptunnel.c +@@ -126,6 +126,8 @@ int seg6_do_srh_encap(struct sk_buff *sk + } else { + ip6_flow_hdr(hdr, 0, 0); + hdr->hop_limit = ip6_dst_hoplimit(skb_dst(skb)); ++ ++ memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); + } + + hdr->nexthdr = NEXTHDR_ROUTING; diff --git a/queue-4.14/ipvlan-l3mdev-fix-broken-l3s-mode-wrt-local-routes.patch b/queue-4.14/ipvlan-l3mdev-fix-broken-l3s-mode-wrt-local-routes.patch new file mode 100644 index 00000000000..c3d7ed25993 --- /dev/null +++ b/queue-4.14/ipvlan-l3mdev-fix-broken-l3s-mode-wrt-local-routes.patch @@ -0,0 +1,147 @@ +From foo@baz Sat Feb 2 10:57:42 CET 2019 +From: Daniel Borkmann +Date: Wed, 30 Jan 2019 12:49:48 +0100 +Subject: ipvlan, l3mdev: fix broken l3s mode wrt local routes + +From: Daniel Borkmann + +[ Upstream commit d5256083f62e2720f75bb3c5a928a0afe47d6bc3 ] + +While implementing ipvlan l3 and l3s mode for kubernetes CNI plugin, +I ran into the issue that while l3 mode is working fine, l3s mode +does not have any connectivity to kube-apiserver and hence all pods +end up in Error state as well. The ipvlan master device sits on +top of a bond device and hostns traffic to kube-apiserver (also running +in hostns) is DNATed from 10.152.183.1:443 to 139.178.29.207:37573 +where the latter is the address of the bond0. While in l3 mode, a +curl to https://10.152.183.1:443 or to https://139.178.29.207:37573 +works fine from hostns, neither of them do in case of l3s. In the +latter only a curl to https://127.0.0.1:37573 appeared to work where +for local addresses of bond0 I saw kernel suddenly starting to emit +ARP requests to query HW address of bond0 which remained unanswered +and neighbor entries in INCOMPLETE state. These ARP requests only +happen while in l3s. + +Debugging this further, I found the issue is that l3s mode is piggy- +backing on l3 master device, and in this case local routes are using +l3mdev_master_dev_rcu(dev) instead of net->loopback_dev as per commit +f5a0aab84b74 ("net: ipv4: dst for local input routes should use l3mdev +if relevant") and 5f02ce24c269 ("net: l3mdev: Allow the l3mdev to be +a loopback"). I found that reverting them back into using the +net->loopback_dev fixed ipvlan l3s connectivity and got everything +working for the CNI. + +Now judging from 4fbae7d83c98 ("ipvlan: Introduce l3s mode") and the +l3mdev paper in [0] the only sole reason why ipvlan l3s is relying +on l3 master device is to get the l3mdev_ip_rcv() receive hook for +setting the dst entry of the input route without adding its own +ipvlan specific hacks into the receive path, however, any l3 domain +semantics beyond just that are breaking l3s operation. Note that +ipvlan also has the ability to dynamically switch its internal +operation from l3 to l3s for all ports via ipvlan_set_port_mode() +at runtime. In any case, l3 vs l3s soley distinguishes itself by +'de-confusing' netfilter through switching skb->dev to ipvlan slave +device late in NF_INET_LOCAL_IN before handing the skb to L4. + +Minimal fix taken here is to add a IFF_L3MDEV_RX_HANDLER flag which, +if set from ipvlan setup, gets us only the wanted l3mdev_l3_rcv() hook +without any additional l3mdev semantics on top. This should also have +minimal impact since dev->priv_flags is already hot in cache. With +this set, l3s mode is working fine and I also get things like +masquerading pod traffic on the ipvlan master properly working. + + [0] https://netdevconf.org/1.2/papers/ahern-what-is-l3mdev-paper.pdf + +Fixes: f5a0aab84b74 ("net: ipv4: dst for local input routes should use l3mdev if relevant") +Fixes: 5f02ce24c269 ("net: l3mdev: Allow the l3mdev to be a loopback") +Fixes: 4fbae7d83c98 ("ipvlan: Introduce l3s mode") +Signed-off-by: Daniel Borkmann +Cc: Mahesh Bandewar +Cc: David Ahern +Cc: Florian Westphal +Cc: Martynas Pumputis +Acked-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ipvlan/ipvlan_main.c | 6 +++--- + include/linux/netdevice.h | 8 ++++++++ + include/net/l3mdev.h | 3 ++- + 3 files changed, 13 insertions(+), 4 deletions(-) + +--- a/drivers/net/ipvlan/ipvlan_main.c ++++ b/drivers/net/ipvlan/ipvlan_main.c +@@ -95,12 +95,12 @@ static int ipvlan_set_port_mode(struct i + err = ipvlan_register_nf_hook(read_pnet(&port->pnet)); + if (!err) { + mdev->l3mdev_ops = &ipvl_l3mdev_ops; +- mdev->priv_flags |= IFF_L3MDEV_MASTER; ++ mdev->priv_flags |= IFF_L3MDEV_RX_HANDLER; + } else + goto fail; + } else if (port->mode == IPVLAN_MODE_L3S) { + /* Old mode was L3S */ +- mdev->priv_flags &= ~IFF_L3MDEV_MASTER; ++ mdev->priv_flags &= ~IFF_L3MDEV_RX_HANDLER; + ipvlan_unregister_nf_hook(read_pnet(&port->pnet)); + mdev->l3mdev_ops = NULL; + } +@@ -172,7 +172,7 @@ static void ipvlan_port_destroy(struct n + + dev->priv_flags &= ~IFF_IPVLAN_MASTER; + if (port->mode == IPVLAN_MODE_L3S) { +- dev->priv_flags &= ~IFF_L3MDEV_MASTER; ++ dev->priv_flags &= ~IFF_L3MDEV_RX_HANDLER; + ipvlan_unregister_nf_hook(dev_net(dev)); + dev->l3mdev_ops = NULL; + } +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -1356,6 +1356,7 @@ struct net_device_ops { + * @IFF_PHONY_HEADROOM: the headroom value is controlled by an external + * entity (i.e. the master device for bridged veth) + * @IFF_MACSEC: device is a MACsec device ++ * @IFF_L3MDEV_RX_HANDLER: only invoke the rx handler of L3 master device + */ + enum netdev_priv_flags { + IFF_802_1Q_VLAN = 1<<0, +@@ -1386,6 +1387,7 @@ enum netdev_priv_flags { + IFF_RXFH_CONFIGURED = 1<<25, + IFF_PHONY_HEADROOM = 1<<26, + IFF_MACSEC = 1<<27, ++ IFF_L3MDEV_RX_HANDLER = 1<<28, + }; + + #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN +@@ -1415,6 +1417,7 @@ enum netdev_priv_flags { + #define IFF_TEAM IFF_TEAM + #define IFF_RXFH_CONFIGURED IFF_RXFH_CONFIGURED + #define IFF_MACSEC IFF_MACSEC ++#define IFF_L3MDEV_RX_HANDLER IFF_L3MDEV_RX_HANDLER + + /** + * struct net_device - The DEVICE structure. +@@ -4206,6 +4209,11 @@ static inline bool netif_supports_nofcs( + return dev->priv_flags & IFF_SUPP_NOFCS; + } + ++static inline bool netif_has_l3_rx_handler(const struct net_device *dev) ++{ ++ return dev->priv_flags & IFF_L3MDEV_RX_HANDLER; ++} ++ + static inline bool netif_is_l3_master(const struct net_device *dev) + { + return dev->priv_flags & IFF_L3MDEV_MASTER; +--- a/include/net/l3mdev.h ++++ b/include/net/l3mdev.h +@@ -142,7 +142,8 @@ struct sk_buff *l3mdev_l3_rcv(struct sk_ + + if (netif_is_l3_slave(skb->dev)) + master = netdev_master_upper_dev_get_rcu(skb->dev); +- else if (netif_is_l3_master(skb->dev)) ++ else if (netif_is_l3_master(skb->dev) || ++ netif_has_l3_rx_handler(skb->dev)) + master = skb->dev; + + if (master && master->l3mdev_ops->l3mdev_l3_rcv) diff --git a/queue-4.14/l2tp-copy-4-more-bytes-to-linear-part-if-necessary.patch b/queue-4.14/l2tp-copy-4-more-bytes-to-linear-part-if-necessary.patch new file mode 100644 index 00000000000..fc7cc1ff552 --- /dev/null +++ b/queue-4.14/l2tp-copy-4-more-bytes-to-linear-part-if-necessary.patch @@ -0,0 +1,51 @@ +From foo@baz Sat Feb 2 10:57:42 CET 2019 +From: Jacob Wen +Date: Thu, 31 Jan 2019 15:18:56 +0800 +Subject: l2tp: copy 4 more bytes to linear part if necessary + +From: Jacob Wen + +[ Upstream commit 91c524708de6207f59dd3512518d8a1c7b434ee3 ] + +The size of L2TPv2 header with all optional fields is 14 bytes. +l2tp_udp_recv_core only moves 10 bytes to the linear part of a +skb. This may lead to l2tp_recv_common read data outside of a skb. + +This patch make sure that there is at least 14 bytes in the linear +part of a skb to meet the maximum need of l2tp_udp_recv_core and +l2tp_recv_common. The minimum size of both PPP HDLC-like frame and +Ethernet frame is larger than 14 bytes, so we are safe to do so. + +Also remove L2TP_HDR_SIZE_NOSEQ, it is unused now. + +Fixes: fd558d186df2 ("l2tp: Split pppol2tp patch into separate l2tp and ppp parts") +Suggested-by: Guillaume Nault +Signed-off-by: Jacob Wen +Acked-by: Guillaume Nault +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/l2tp/l2tp_core.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/net/l2tp/l2tp_core.c ++++ b/net/l2tp/l2tp_core.c +@@ -83,8 +83,7 @@ + #define L2TP_SLFLAG_S 0x40000000 + #define L2TP_SL_SEQ_MASK 0x00ffffff + +-#define L2TP_HDR_SIZE_SEQ 10 +-#define L2TP_HDR_SIZE_NOSEQ 6 ++#define L2TP_HDR_SIZE_MAX 14 + + /* Default trace flags */ + #define L2TP_DEFAULT_DEBUG_FLAGS 0 +@@ -907,7 +906,7 @@ static int l2tp_udp_recv_core(struct l2t + __skb_pull(skb, sizeof(struct udphdr)); + + /* Short packet? */ +- if (!pskb_may_pull(skb, L2TP_HDR_SIZE_SEQ)) { ++ if (!pskb_may_pull(skb, L2TP_HDR_SIZE_MAX)) { + l2tp_info(tunnel, L2TP_MSG_DATA, + "%s: recv short packet (len=%d)\n", + tunnel->name, skb->len); diff --git a/queue-4.14/l2tp-fix-reading-optional-fields-of-l2tpv3.patch b/queue-4.14/l2tp-fix-reading-optional-fields-of-l2tpv3.patch new file mode 100644 index 00000000000..5ec86ae4a5b --- /dev/null +++ b/queue-4.14/l2tp-fix-reading-optional-fields-of-l2tpv3.patch @@ -0,0 +1,112 @@ +From foo@baz Sat Feb 2 10:57:42 CET 2019 +From: Jacob Wen +Date: Wed, 30 Jan 2019 14:55:14 +0800 +Subject: l2tp: fix reading optional fields of L2TPv3 + +From: Jacob Wen + +[ Upstream commit 4522a70db7aa5e77526a4079628578599821b193 ] + +Use pskb_may_pull() to make sure the optional fields are in skb linear +parts, so we can safely read them later. + +It's easy to reproduce the issue with a net driver that supports paged +skb data. Just create a L2TPv3 over IP tunnel and then generates some +network traffic. +Once reproduced, rx err in /sys/kernel/debug/l2tp/tunnels will increase. + +Changes in v4: +1. s/l2tp_v3_pull_opt/l2tp_v3_ensure_opt_in_linear/ +2. s/tunnel->version != L2TP_HDR_VER_2/tunnel->version == L2TP_HDR_VER_3/ +3. Add 'Fixes' in commit messages. + +Changes in v3: +1. To keep consistency, move the code out of l2tp_recv_common. +2. Use "net" instead of "net-next", since this is a bug fix. + +Changes in v2: +1. Only fix L2TPv3 to make code simple. + To fix both L2TPv3 and L2TPv2, we'd better refactor l2tp_recv_common. + It's complicated to do so. +2. Reloading pointers after pskb_may_pull + +Fixes: f7faffa3ff8e ("l2tp: Add L2TPv3 protocol support") +Fixes: 0d76751fad77 ("l2tp: Add L2TPv3 IP encapsulation (no UDP) support") +Fixes: a32e0eec7042 ("l2tp: introduce L2TPv3 IP encapsulation support for IPv6") +Signed-off-by: Jacob Wen +Acked-by: Guillaume Nault +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/l2tp/l2tp_core.c | 4 ++++ + net/l2tp/l2tp_core.h | 20 ++++++++++++++++++++ + net/l2tp/l2tp_ip.c | 3 +++ + net/l2tp/l2tp_ip6.c | 3 +++ + 4 files changed, 30 insertions(+) + +--- a/net/l2tp/l2tp_core.c ++++ b/net/l2tp/l2tp_core.c +@@ -983,6 +983,10 @@ static int l2tp_udp_recv_core(struct l2t + goto error; + } + ++ if (tunnel->version == L2TP_HDR_VER_3 && ++ l2tp_v3_ensure_opt_in_linear(session, skb, &ptr, &optr)) ++ goto error; ++ + l2tp_recv_common(session, skb, ptr, optr, hdrflags, length, payload_hook); + l2tp_session_dec_refcount(session); + +--- a/net/l2tp/l2tp_core.h ++++ b/net/l2tp/l2tp_core.h +@@ -331,6 +331,26 @@ static inline int l2tp_get_l2specific_le + } + } + ++static inline int l2tp_v3_ensure_opt_in_linear(struct l2tp_session *session, struct sk_buff *skb, ++ unsigned char **ptr, unsigned char **optr) ++{ ++ int opt_len = session->peer_cookie_len + l2tp_get_l2specific_len(session); ++ ++ if (opt_len > 0) { ++ int off = *ptr - *optr; ++ ++ if (!pskb_may_pull(skb, off + opt_len)) ++ return -1; ++ ++ if (skb->data != *optr) { ++ *optr = skb->data; ++ *ptr = skb->data + off; ++ } ++ } ++ ++ return 0; ++} ++ + #define l2tp_printk(ptr, type, func, fmt, ...) \ + do { \ + if (((ptr)->debug) & (type)) \ +--- a/net/l2tp/l2tp_ip.c ++++ b/net/l2tp/l2tp_ip.c +@@ -165,6 +165,9 @@ static int l2tp_ip_recv(struct sk_buff * + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); + } + ++ if (l2tp_v3_ensure_opt_in_linear(session, skb, &ptr, &optr)) ++ goto discard_sess; ++ + l2tp_recv_common(session, skb, ptr, optr, 0, skb->len, tunnel->recv_payload_hook); + l2tp_session_dec_refcount(session); + +--- a/net/l2tp/l2tp_ip6.c ++++ b/net/l2tp/l2tp_ip6.c +@@ -178,6 +178,9 @@ static int l2tp_ip6_recv(struct sk_buff + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); + } + ++ if (l2tp_v3_ensure_opt_in_linear(session, skb, &ptr, &optr)) ++ goto discard_sess; ++ + l2tp_recv_common(session, skb, ptr, optr, 0, skb->len, + tunnel->recv_payload_hook); + l2tp_session_dec_refcount(session); diff --git a/queue-4.14/l2tp-remove-l2specific_len-dependency-in-l2tp_core.patch b/queue-4.14/l2tp-remove-l2specific_len-dependency-in-l2tp_core.patch new file mode 100644 index 00000000000..8332e04b099 --- /dev/null +++ b/queue-4.14/l2tp-remove-l2specific_len-dependency-in-l2tp_core.patch @@ -0,0 +1,119 @@ +From 62e7b6a57c7b9bf3c6fd99418eeec05b08a85c38 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 16 Jan 2018 23:01:55 +0100 +Subject: l2tp: remove l2specific_len dependency in l2tp_core + +From: Lorenzo Bianconi + +commit 62e7b6a57c7b9bf3c6fd99418eeec05b08a85c38 upstream. + +Remove l2specific_len dependency while building l2tpv3 header or +parsing the received frame since default L2-Specific Sublayer is +always four bytes long and we don't need to rely on a user supplied +value. +Moreover in l2tp netlink code there are no sanity checks to +enforce the relation between l2specific_len and l2specific_type, +so sending a malformed netlink message is possible to set +l2specific_type to L2TP_L2SPECTYPE_DEFAULT (or even +L2TP_L2SPECTYPE_NONE) and set l2specific_len to a value greater than +4 leaking memory on the wire and sending corrupted frames. + +Reviewed-by: Guillaume Nault +Tested-by: Guillaume Nault +Signed-off-by: Lorenzo Bianconi +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/l2tp/l2tp_core.c | 34 ++++++++++++++++------------------ + net/l2tp/l2tp_core.h | 11 +++++++++++ + 2 files changed, 27 insertions(+), 18 deletions(-) + +--- a/net/l2tp/l2tp_core.c ++++ b/net/l2tp/l2tp_core.c +@@ -758,11 +758,9 @@ void l2tp_recv_common(struct l2tp_sessio + "%s: recv data ns=%u, session nr=%u\n", + session->name, ns, session->nr); + } ++ ptr += 4; + } + +- /* Advance past L2-specific header, if present */ +- ptr += session->l2specific_len; +- + if (L2TP_SKB_CB(skb)->has_seq) { + /* Received a packet with sequence numbers. If we're the LNS, + * check if we sre sending sequence numbers and if not, +@@ -1084,21 +1082,20 @@ static int l2tp_build_l2tpv3_header(stru + memcpy(bufp, &session->cookie[0], session->cookie_len); + bufp += session->cookie_len; + } +- if (session->l2specific_len) { +- if (session->l2specific_type == L2TP_L2SPECTYPE_DEFAULT) { +- u32 l2h = 0; +- if (session->send_seq) { +- l2h = 0x40000000 | session->ns; +- session->ns++; +- session->ns &= 0xffffff; +- l2tp_dbg(session, L2TP_MSG_SEQ, +- "%s: updated ns to %u\n", +- session->name, session->ns); +- } ++ if (session->l2specific_type == L2TP_L2SPECTYPE_DEFAULT) { ++ u32 l2h = 0; + +- *((__be32 *) bufp) = htonl(l2h); ++ if (session->send_seq) { ++ l2h = 0x40000000 | session->ns; ++ session->ns++; ++ session->ns &= 0xffffff; ++ l2tp_dbg(session, L2TP_MSG_SEQ, ++ "%s: updated ns to %u\n", ++ session->name, session->ns); + } +- bufp += session->l2specific_len; ++ ++ *((__be32 *)bufp) = htonl(l2h); ++ bufp += 4; + } + + return bufp - optr; +@@ -1764,7 +1761,7 @@ int l2tp_session_delete(struct l2tp_sess + EXPORT_SYMBOL_GPL(l2tp_session_delete); + + /* We come here whenever a session's send_seq, cookie_len or +- * l2specific_len parameters are set. ++ * l2specific_type parameters are set. + */ + void l2tp_session_set_header_len(struct l2tp_session *session, int version) + { +@@ -1773,7 +1770,8 @@ void l2tp_session_set_header_len(struct + if (session->send_seq) + session->hdr_len += 4; + } else { +- session->hdr_len = 4 + session->cookie_len + session->l2specific_len; ++ session->hdr_len = 4 + session->cookie_len; ++ session->hdr_len += l2tp_get_l2specific_len(session); + if (session->tunnel->encap == L2TP_ENCAPTYPE_UDP) + session->hdr_len += 4; + } +--- a/net/l2tp/l2tp_core.h ++++ b/net/l2tp/l2tp_core.h +@@ -320,6 +320,17 @@ do { \ + #define l2tp_session_dec_refcount(s) l2tp_session_dec_refcount_1(s) + #endif + ++static inline int l2tp_get_l2specific_len(struct l2tp_session *session) ++{ ++ switch (session->l2specific_type) { ++ case L2TP_L2SPECTYPE_DEFAULT: ++ return 4; ++ case L2TP_L2SPECTYPE_NONE: ++ default: ++ return 0; ++ } ++} ++ + #define l2tp_printk(ptr, type, func, fmt, ...) \ + do { \ + if (((ptr)->debug) & (type)) \ diff --git a/queue-4.14/net-mlx4_core-add-masking-for-a-few-queries-on-hca-caps.patch b/queue-4.14/net-mlx4_core-add-masking-for-a-few-queries-on-hca-caps.patch new file mode 100644 index 00000000000..3687d3f3d5f --- /dev/null +++ b/queue-4.14/net-mlx4_core-add-masking-for-a-few-queries-on-hca-caps.patch @@ -0,0 +1,142 @@ +From foo@baz Sat Feb 2 10:57:42 CET 2019 +From: Aya Levin +Date: Tue, 22 Jan 2019 15:19:44 +0200 +Subject: net/mlx4_core: Add masking for a few queries on HCA caps + +From: Aya Levin + +[ Upstream commit a40ded6043658444ee4dd6ee374119e4e98b33fc ] + +Driver reads the query HCA capabilities without the corresponding masks. +Without the correct masks, the base addresses of the queues are +unaligned. In addition some reserved bits were wrongly read. Using the +correct masks, ensures alignment of the base addresses and allows future +firmware versions safe use of the reserved bits. + +Fixes: ab9c17a009ee ("mlx4_core: Modify driver initialization flow to accommodate SRIOV for Ethernet") +Fixes: 0ff1fb654bec ("{NET, IB}/mlx4: Add device managed flow steering firmware API") +Signed-off-by: Aya Levin +Signed-off-by: Tariq Toukan +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlx4/fw.c | 75 +++++++++++++++++++------------- + 1 file changed, 46 insertions(+), 29 deletions(-) + +--- a/drivers/net/ethernet/mellanox/mlx4/fw.c ++++ b/drivers/net/ethernet/mellanox/mlx4/fw.c +@@ -2048,9 +2048,11 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev, + { + struct mlx4_cmd_mailbox *mailbox; + __be32 *outbox; ++ u64 qword_field; + u32 dword_field; +- int err; ++ u16 word_field; + u8 byte_field; ++ int err; + static const u8 a0_dmfs_query_hw_steering[] = { + [0] = MLX4_STEERING_DMFS_A0_DEFAULT, + [1] = MLX4_STEERING_DMFS_A0_DYNAMIC, +@@ -2078,19 +2080,32 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev, + + /* QPC/EEC/CQC/EQC/RDMARC attributes */ + +- MLX4_GET(param->qpc_base, outbox, INIT_HCA_QPC_BASE_OFFSET); +- MLX4_GET(param->log_num_qps, outbox, INIT_HCA_LOG_QP_OFFSET); +- MLX4_GET(param->srqc_base, outbox, INIT_HCA_SRQC_BASE_OFFSET); +- MLX4_GET(param->log_num_srqs, outbox, INIT_HCA_LOG_SRQ_OFFSET); +- MLX4_GET(param->cqc_base, outbox, INIT_HCA_CQC_BASE_OFFSET); +- MLX4_GET(param->log_num_cqs, outbox, INIT_HCA_LOG_CQ_OFFSET); +- MLX4_GET(param->altc_base, outbox, INIT_HCA_ALTC_BASE_OFFSET); +- MLX4_GET(param->auxc_base, outbox, INIT_HCA_AUXC_BASE_OFFSET); +- MLX4_GET(param->eqc_base, outbox, INIT_HCA_EQC_BASE_OFFSET); +- MLX4_GET(param->log_num_eqs, outbox, INIT_HCA_LOG_EQ_OFFSET); +- MLX4_GET(param->num_sys_eqs, outbox, INIT_HCA_NUM_SYS_EQS_OFFSET); +- MLX4_GET(param->rdmarc_base, outbox, INIT_HCA_RDMARC_BASE_OFFSET); +- MLX4_GET(param->log_rd_per_qp, outbox, INIT_HCA_LOG_RD_OFFSET); ++ MLX4_GET(qword_field, outbox, INIT_HCA_QPC_BASE_OFFSET); ++ param->qpc_base = qword_field & ~((u64)0x1f); ++ MLX4_GET(byte_field, outbox, INIT_HCA_LOG_QP_OFFSET); ++ param->log_num_qps = byte_field & 0x1f; ++ MLX4_GET(qword_field, outbox, INIT_HCA_SRQC_BASE_OFFSET); ++ param->srqc_base = qword_field & ~((u64)0x1f); ++ MLX4_GET(byte_field, outbox, INIT_HCA_LOG_SRQ_OFFSET); ++ param->log_num_srqs = byte_field & 0x1f; ++ MLX4_GET(qword_field, outbox, INIT_HCA_CQC_BASE_OFFSET); ++ param->cqc_base = qword_field & ~((u64)0x1f); ++ MLX4_GET(byte_field, outbox, INIT_HCA_LOG_CQ_OFFSET); ++ param->log_num_cqs = byte_field & 0x1f; ++ MLX4_GET(qword_field, outbox, INIT_HCA_ALTC_BASE_OFFSET); ++ param->altc_base = qword_field; ++ MLX4_GET(qword_field, outbox, INIT_HCA_AUXC_BASE_OFFSET); ++ param->auxc_base = qword_field; ++ MLX4_GET(qword_field, outbox, INIT_HCA_EQC_BASE_OFFSET); ++ param->eqc_base = qword_field & ~((u64)0x1f); ++ MLX4_GET(byte_field, outbox, INIT_HCA_LOG_EQ_OFFSET); ++ param->log_num_eqs = byte_field & 0x1f; ++ MLX4_GET(word_field, outbox, INIT_HCA_NUM_SYS_EQS_OFFSET); ++ param->num_sys_eqs = word_field & 0xfff; ++ MLX4_GET(qword_field, outbox, INIT_HCA_RDMARC_BASE_OFFSET); ++ param->rdmarc_base = qword_field & ~((u64)0x1f); ++ MLX4_GET(byte_field, outbox, INIT_HCA_LOG_RD_OFFSET); ++ param->log_rd_per_qp = byte_field & 0x7; + + MLX4_GET(dword_field, outbox, INIT_HCA_FLAGS_OFFSET); + if (dword_field & (1 << INIT_HCA_DEVICE_MANAGED_FLOW_STEERING_EN)) { +@@ -2109,22 +2124,21 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev, + /* steering attributes */ + if (param->steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED) { + MLX4_GET(param->mc_base, outbox, INIT_HCA_FS_BASE_OFFSET); +- MLX4_GET(param->log_mc_entry_sz, outbox, +- INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET); +- MLX4_GET(param->log_mc_table_sz, outbox, +- INIT_HCA_FS_LOG_TABLE_SZ_OFFSET); +- MLX4_GET(byte_field, outbox, +- INIT_HCA_FS_A0_OFFSET); ++ MLX4_GET(byte_field, outbox, INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET); ++ param->log_mc_entry_sz = byte_field & 0x1f; ++ MLX4_GET(byte_field, outbox, INIT_HCA_FS_LOG_TABLE_SZ_OFFSET); ++ param->log_mc_table_sz = byte_field & 0x1f; ++ MLX4_GET(byte_field, outbox, INIT_HCA_FS_A0_OFFSET); + param->dmfs_high_steer_mode = + a0_dmfs_query_hw_steering[(byte_field >> 6) & 3]; + } else { + MLX4_GET(param->mc_base, outbox, INIT_HCA_MC_BASE_OFFSET); +- MLX4_GET(param->log_mc_entry_sz, outbox, +- INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET); +- MLX4_GET(param->log_mc_hash_sz, outbox, +- INIT_HCA_LOG_MC_HASH_SZ_OFFSET); +- MLX4_GET(param->log_mc_table_sz, outbox, +- INIT_HCA_LOG_MC_TABLE_SZ_OFFSET); ++ MLX4_GET(byte_field, outbox, INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET); ++ param->log_mc_entry_sz = byte_field & 0x1f; ++ MLX4_GET(byte_field, outbox, INIT_HCA_LOG_MC_HASH_SZ_OFFSET); ++ param->log_mc_hash_sz = byte_field & 0x1f; ++ MLX4_GET(byte_field, outbox, INIT_HCA_LOG_MC_TABLE_SZ_OFFSET); ++ param->log_mc_table_sz = byte_field & 0x1f; + } + + /* CX3 is capable of extending CQEs/EQEs from 32 to 64 bytes */ +@@ -2148,15 +2162,18 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev, + /* TPT attributes */ + + MLX4_GET(param->dmpt_base, outbox, INIT_HCA_DMPT_BASE_OFFSET); +- MLX4_GET(param->mw_enabled, outbox, INIT_HCA_TPT_MW_OFFSET); +- MLX4_GET(param->log_mpt_sz, outbox, INIT_HCA_LOG_MPT_SZ_OFFSET); ++ MLX4_GET(byte_field, outbox, INIT_HCA_TPT_MW_OFFSET); ++ param->mw_enabled = byte_field >> 7; ++ MLX4_GET(byte_field, outbox, INIT_HCA_LOG_MPT_SZ_OFFSET); ++ param->log_mpt_sz = byte_field & 0x3f; + MLX4_GET(param->mtt_base, outbox, INIT_HCA_MTT_BASE_OFFSET); + MLX4_GET(param->cmpt_base, outbox, INIT_HCA_CMPT_BASE_OFFSET); + + /* UAR attributes */ + + MLX4_GET(param->uar_page_sz, outbox, INIT_HCA_UAR_PAGE_SZ_OFFSET); +- MLX4_GET(param->log_uar_sz, outbox, INIT_HCA_LOG_UAR_SZ_OFFSET); ++ MLX4_GET(byte_field, outbox, INIT_HCA_LOG_UAR_SZ_OFFSET); ++ param->log_uar_sz = byte_field & 0xf; + + /* phv_check enable */ + MLX4_GET(byte_field, outbox, INIT_HCA_CACHELINE_SZ_OFFSET); diff --git a/queue-4.14/net-mlx5e-allow-mac-invalidation-while-spoofchk-is-on.patch b/queue-4.14/net-mlx5e-allow-mac-invalidation-while-spoofchk-is-on.patch new file mode 100644 index 00000000000..8f8d9a8314a --- /dev/null +++ b/queue-4.14/net-mlx5e-allow-mac-invalidation-while-spoofchk-is-on.patch @@ -0,0 +1,67 @@ +From foo@baz Sat Feb 2 10:57:42 CET 2019 +From: Aya Levin +Date: Mon, 24 Dec 2018 09:48:42 +0200 +Subject: net/mlx5e: Allow MAC invalidation while spoofchk is ON + +From: Aya Levin + +[ Upstream commit 9d2cbdc5d334967c35b5f58c7bf3208e17325647 ] + +Prior to this patch the driver prohibited spoof checking on invalid MAC. +Now the user can set this configuration if it wishes to. + +This is required since libvirt might invalidate the VF Mac by setting it +to zero, while spoofcheck is ON. + +Fixes: 1ab2068a4c66 ("net/mlx5: Implement vports admin state backup/restore") +Signed-off-by: Aya Levin +Reviewed-by: Eran Ben Elisha +Signed-off-by: Saeed Mahameed +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 18 ++++++------------ + 1 file changed, 6 insertions(+), 12 deletions(-) + +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +@@ -1126,13 +1126,6 @@ static int esw_vport_ingress_config(stru + int err = 0; + u8 *smac_v; + +- if (vport->info.spoofchk && !is_valid_ether_addr(vport->info.mac)) { +- mlx5_core_warn(esw->dev, +- "vport[%d] configure ingress rules failed, illegal mac with spoofchk\n", +- vport->vport); +- return -EPERM; +- } +- + esw_vport_cleanup_ingress_rules(esw, vport); + + if (!vport->info.vlan && !vport->info.qos && !vport->info.spoofchk) { +@@ -1734,13 +1727,10 @@ int mlx5_eswitch_set_vport_mac(struct ml + mutex_lock(&esw->state_lock); + evport = &esw->vports[vport]; + +- if (evport->info.spoofchk && !is_valid_ether_addr(mac)) { ++ if (evport->info.spoofchk && !is_valid_ether_addr(mac)) + mlx5_core_warn(esw->dev, +- "MAC invalidation is not allowed when spoofchk is on, vport(%d)\n", ++ "Set invalid MAC while spoofchk is on, vport(%d)\n", + vport); +- err = -EPERM; +- goto unlock; +- } + + err = mlx5_modify_nic_vport_mac_address(esw->dev, vport, mac); + if (err) { +@@ -1886,6 +1876,10 @@ int mlx5_eswitch_set_vport_spoofchk(stru + evport = &esw->vports[vport]; + pschk = evport->info.spoofchk; + evport->info.spoofchk = spoofchk; ++ if (pschk && !is_valid_ether_addr(evport->info.mac)) ++ mlx5_core_warn(esw->dev, ++ "Spoofchk in set while MAC is invalid, vport(%d)\n", ++ evport->vport); + if (evport->enabled && esw->mode == SRIOV_LEGACY) + err = esw_vport_ingress_config(esw, evport); + if (err) diff --git a/queue-4.14/net-rose-fix-null-ax25_cb-kernel-panic.patch b/queue-4.14/net-rose-fix-null-ax25_cb-kernel-panic.patch new file mode 100644 index 00000000000..be3250fa685 --- /dev/null +++ b/queue-4.14/net-rose-fix-null-ax25_cb-kernel-panic.patch @@ -0,0 +1,66 @@ +From foo@baz Sat Feb 2 10:57:42 CET 2019 +From: Bernard Pidoux +Date: Fri, 25 Jan 2019 11:46:40 +0100 +Subject: net/rose: fix NULL ax25_cb kernel panic + +From: Bernard Pidoux + +[ Upstream commit b0cf029234f9b18e10703ba5147f0389c382bccc ] + +When an internally generated frame is handled by rose_xmit(), +rose_route_frame() is called: + + if (!rose_route_frame(skb, NULL)) { + dev_kfree_skb(skb); + stats->tx_errors++; + return NETDEV_TX_OK; + } + +We have the same code sequence in Net/Rom where an internally generated +frame is handled by nr_xmit() calling nr_route_frame(skb, NULL). +However, in this function NULL argument is tested while it is not in +rose_route_frame(). +Then kernel panic occurs later on when calling ax25cmp() with a NULL +ax25_cb argument as reported many times and recently with syzbot. + +We need to test if ax25 is NULL before using it. + +Testing: +Built kernel with CONFIG_ROSE=y. + +Signed-off-by: Bernard Pidoux +Acked-by: Dmitry Vyukov +Reported-by: syzbot+1a2c456a1ea08fa5b5f7@syzkaller.appspotmail.com +Cc: "David S. Miller" +Cc: Ralf Baechle +Cc: Bernard Pidoux +Cc: linux-hams@vger.kernel.org +Cc: netdev@vger.kernel.org +Cc: linux-kernel@vger.kernel.org +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/rose/rose_route.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/net/rose/rose_route.c ++++ b/net/rose/rose_route.c +@@ -848,6 +848,7 @@ void rose_link_device_down(struct net_de + + /* + * Route a frame to an appropriate AX.25 connection. ++ * A NULL ax25_cb indicates an internally generated frame. + */ + int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25) + { +@@ -865,6 +866,10 @@ int rose_route_frame(struct sk_buff *skb + + if (skb->len < ROSE_MIN_LEN) + return res; ++ ++ if (!ax25) ++ return rose_loopback_queue(skb, NULL); ++ + frametype = skb->data[2]; + lci = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF); + if (frametype == ROSE_CALL_REQUEST && diff --git a/queue-4.14/net-set-default-network-namespace-in-init_dummy_netdev.patch b/queue-4.14/net-set-default-network-namespace-in-init_dummy_netdev.patch new file mode 100644 index 00000000000..780882fa5b0 --- /dev/null +++ b/queue-4.14/net-set-default-network-namespace-in-init_dummy_netdev.patch @@ -0,0 +1,43 @@ +From foo@baz Sat Feb 2 10:57:42 CET 2019 +From: Josh Elsasser +Date: Sat, 26 Jan 2019 14:38:33 -0800 +Subject: net: set default network namespace in init_dummy_netdev() + +From: Josh Elsasser + +[ Upstream commit 35edfdc77f683c8fd27d7732af06cf6489af60a5 ] + +Assign a default net namespace to netdevs created by init_dummy_netdev(). +Fixes a NULL pointer dereference caused by busy-polling a socket bound to +an iwlwifi wireless device, which bumps the per-net BUSYPOLLRXPACKETS stat +if napi_poll() received packets: + + BUG: unable to handle kernel NULL pointer dereference at 0000000000000190 + IP: napi_busy_loop+0xd6/0x200 + Call Trace: + sock_poll+0x5e/0x80 + do_sys_poll+0x324/0x5a0 + SyS_poll+0x6c/0xf0 + do_syscall_64+0x6b/0x1f0 + entry_SYSCALL_64_after_hwframe+0x3d/0xa2 + +Fixes: 7db6b048da3b ("net: Commonize busy polling code to focus on napi_id instead of socket") +Signed-off-by: Josh Elsasser +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/dev.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -7748,6 +7748,9 @@ int init_dummy_netdev(struct net_device + set_bit(__LINK_STATE_PRESENT, &dev->state); + set_bit(__LINK_STATE_START, &dev->state); + ++ /* napi_busy_loop stats accounting wants this */ ++ dev_net_set(dev, &init_net); ++ + /* Note : We dont allocate pcpu_refcnt for dummy devices, + * because users of this 'device' dont need to change + * its refcount. diff --git a/queue-4.14/netrom-switch-to-sock-timer-api.patch b/queue-4.14/netrom-switch-to-sock-timer-api.patch new file mode 100644 index 00000000000..c84a3c98902 --- /dev/null +++ b/queue-4.14/netrom-switch-to-sock-timer-api.patch @@ -0,0 +1,95 @@ +From foo@baz Sat Feb 2 10:57:42 CET 2019 +From: Cong Wang +Date: Thu, 24 Jan 2019 14:18:18 -0800 +Subject: netrom: switch to sock timer API + +From: Cong Wang + +[ Upstream commit 63346650c1a94a92be61a57416ac88c0a47c4327 ] + +sk_reset_timer() and sk_stop_timer() properly handle +sock refcnt for timer function. Switching to them +could fix a refcounting bug reported by syzbot. + +Reported-and-tested-by: syzbot+defa700d16f1bd1b9a05@syzkaller.appspotmail.com +Cc: Ralf Baechle +Cc: linux-hams@vger.kernel.org +Signed-off-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/netrom/nr_timer.c | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +--- a/net/netrom/nr_timer.c ++++ b/net/netrom/nr_timer.c +@@ -53,21 +53,21 @@ void nr_start_t1timer(struct sock *sk) + { + struct nr_sock *nr = nr_sk(sk); + +- mod_timer(&nr->t1timer, jiffies + nr->t1); ++ sk_reset_timer(sk, &nr->t1timer, jiffies + nr->t1); + } + + void nr_start_t2timer(struct sock *sk) + { + struct nr_sock *nr = nr_sk(sk); + +- mod_timer(&nr->t2timer, jiffies + nr->t2); ++ sk_reset_timer(sk, &nr->t2timer, jiffies + nr->t2); + } + + void nr_start_t4timer(struct sock *sk) + { + struct nr_sock *nr = nr_sk(sk); + +- mod_timer(&nr->t4timer, jiffies + nr->t4); ++ sk_reset_timer(sk, &nr->t4timer, jiffies + nr->t4); + } + + void nr_start_idletimer(struct sock *sk) +@@ -75,37 +75,37 @@ void nr_start_idletimer(struct sock *sk) + struct nr_sock *nr = nr_sk(sk); + + if (nr->idle > 0) +- mod_timer(&nr->idletimer, jiffies + nr->idle); ++ sk_reset_timer(sk, &nr->idletimer, jiffies + nr->idle); + } + + void nr_start_heartbeat(struct sock *sk) + { +- mod_timer(&sk->sk_timer, jiffies + 5 * HZ); ++ sk_reset_timer(sk, &sk->sk_timer, jiffies + 5 * HZ); + } + + void nr_stop_t1timer(struct sock *sk) + { +- del_timer(&nr_sk(sk)->t1timer); ++ sk_stop_timer(sk, &nr_sk(sk)->t1timer); + } + + void nr_stop_t2timer(struct sock *sk) + { +- del_timer(&nr_sk(sk)->t2timer); ++ sk_stop_timer(sk, &nr_sk(sk)->t2timer); + } + + void nr_stop_t4timer(struct sock *sk) + { +- del_timer(&nr_sk(sk)->t4timer); ++ sk_stop_timer(sk, &nr_sk(sk)->t4timer); + } + + void nr_stop_idletimer(struct sock *sk) + { +- del_timer(&nr_sk(sk)->idletimer); ++ sk_stop_timer(sk, &nr_sk(sk)->idletimer); + } + + void nr_stop_heartbeat(struct sock *sk) + { +- del_timer(&sk->sk_timer); ++ sk_stop_timer(sk, &sk->sk_timer); + } + + int nr_t1timer_running(struct sock *sk) diff --git a/queue-4.14/revert-net-mlx5e-e-switch-initialize-eswitch-only-if-eswitch-manager.patch b/queue-4.14/revert-net-mlx5e-e-switch-initialize-eswitch-only-if-eswitch-manager.patch new file mode 100644 index 00000000000..012441e5c0e --- /dev/null +++ b/queue-4.14/revert-net-mlx5e-e-switch-initialize-eswitch-only-if-eswitch-manager.patch @@ -0,0 +1,54 @@ +From foo@baz Sat Feb 2 10:57:42 CET 2019 +From: Bodong Wang +Date: Sun, 13 Jan 2019 22:47:26 -0600 +Subject: Revert "net/mlx5e: E-Switch, Initialize eswitch only if eswitch manager" + +From: Bodong Wang + +[ Upstream commit 4e046de0f50e04acd48eb373d6a9061ddf014e0c ] + +This reverts commit 5f5991f36dce1e69dd8bd7495763eec2e28f08e7. + +With the original commit, eswitch instance will not be initialized for +a function which is vport group manager but not eswitch manager such as +host PF on SmartNIC (BlueField) card. This will result in a kernel crash +when such a vport group manager is trying to access vports in its group. +E.g, PF vport manager (not eswitch manager) tries to configure the MAC +of its VF vport, a kernel trace will happen similar as bellow: + + BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 + ... + RIP: 0010:mlx5_eswitch_get_vport_config+0xc/0x180 [mlx5_core] + ... + +Fixes: 5f5991f36dce ("net/mlx5e: E-Switch, Initialize eswitch only if eswitch manager") +Signed-off-by: Bodong Wang +Reported-by: Yuval Avnery +Reviewed-by: Daniel Jurgens +Reviewed-by: Or Gerlitz +Signed-off-by: Saeed Mahameed +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +@@ -1607,7 +1607,7 @@ int mlx5_eswitch_init(struct mlx5_core_d + int vport_num; + int err; + +- if (!MLX5_ESWITCH_MANAGER(dev)) ++ if (!MLX5_VPORT_MANAGER(dev)) + return 0; + + esw_info(dev, +@@ -1680,7 +1680,7 @@ abort: + + void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw) + { +- if (!esw || !MLX5_ESWITCH_MANAGER(esw->dev)) ++ if (!esw || !MLX5_VPORT_MANAGER(esw->dev)) + return; + + esw_info(esw->dev, "cleanup\n"); diff --git a/queue-4.14/sctp-improve-the-events-for-sctp-stream-adding.patch b/queue-4.14/sctp-improve-the-events-for-sctp-stream-adding.patch new file mode 100644 index 00000000000..9373df905f7 --- /dev/null +++ b/queue-4.14/sctp-improve-the-events-for-sctp-stream-adding.patch @@ -0,0 +1,75 @@ +From foo@baz Sat Feb 2 10:57:42 CET 2019 +From: Xin Long +Date: Tue, 22 Jan 2019 02:40:12 +0800 +Subject: sctp: improve the events for sctp stream adding + +From: Xin Long + +[ Upstream commit 8220c870cb0f4eaa4e335c9645dbd9a1c461c1dd ] + +This patch is to improve sctp stream adding events in 2 places: + + 1. In sctp_process_strreset_addstrm_out(), move up SCTP_MAX_STREAM + and in stream allocation failure checks, as the adding has to + succeed after reconf_timer stops for the in stream adding + request retransmission. + + 3. In sctp_process_strreset_addstrm_in(), no event should be sent, + as no in or out stream is added here. + +Fixes: 50a41591f110 ("sctp: implement receiver-side procedures for the Add Outgoing Streams Request Parameter") +Fixes: c5c4ebb3ab87 ("sctp: implement receiver-side procedures for the Add Incoming Streams Request Parameter") +Reported-by: Ying Xu +Signed-off-by: Xin Long +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sctp/stream.c | 23 ++++++++++------------- + 1 file changed, 10 insertions(+), 13 deletions(-) + +--- a/net/sctp/stream.c ++++ b/net/sctp/stream.c +@@ -642,6 +642,16 @@ struct sctp_chunk *sctp_process_strreset + if (!(asoc->strreset_enable & SCTP_ENABLE_CHANGE_ASSOC_REQ)) + goto out; + ++ in = ntohs(addstrm->number_of_streams); ++ incnt = stream->incnt + in; ++ if (!in || incnt > SCTP_MAX_STREAM) ++ goto out; ++ ++ streamin = krealloc(stream->in, incnt * sizeof(*streamin), ++ GFP_ATOMIC); ++ if (!streamin) ++ goto out; ++ + if (asoc->strreset_chunk) { + if (!sctp_chunk_lookup_strreset_param( + asoc, 0, SCTP_PARAM_RESET_ADD_IN_STREAMS)) { +@@ -665,16 +675,6 @@ struct sctp_chunk *sctp_process_strreset + } + } + +- in = ntohs(addstrm->number_of_streams); +- incnt = stream->incnt + in; +- if (!in || incnt > SCTP_MAX_STREAM) +- goto out; +- +- streamin = krealloc(stream->in, incnt * sizeof(*streamin), +- GFP_ATOMIC); +- if (!streamin) +- goto out; +- + memset(streamin + stream->incnt, 0, in * sizeof(*streamin)); + stream->in = streamin; + stream->incnt = incnt; +@@ -750,9 +750,6 @@ struct sctp_chunk *sctp_process_strreset + + result = SCTP_STRRESET_PERFORMED; + +- *evp = sctp_ulpevent_make_stream_change_event(asoc, +- 0, 0, ntohs(addstrm->number_of_streams), GFP_ATOMIC); +- + out: + sctp_update_strreset_result(asoc, result); + err: diff --git a/queue-4.14/sctp-improve-the-events-for-sctp-stream-reset.patch b/queue-4.14/sctp-improve-the-events-for-sctp-stream-reset.patch new file mode 100644 index 00000000000..11e88497e89 --- /dev/null +++ b/queue-4.14/sctp-improve-the-events-for-sctp-stream-reset.patch @@ -0,0 +1,131 @@ +From foo@baz Sat Feb 2 10:57:42 CET 2019 +From: Xin Long +Date: Tue, 22 Jan 2019 02:39:34 +0800 +Subject: sctp: improve the events for sctp stream reset + +From: Xin Long + +[ Upstream commit 2e6dc4d95110becfe0ff4c3d4749c33ea166e9e7 ] + +This patch is to improve sctp stream reset events in 4 places: + + 1. In sctp_process_strreset_outreq(), the flag should always be set with + SCTP_STREAM_RESET_INCOMING_SSN instead of OUTGOING, as receiver's in + stream is reset here. + 2. In sctp_process_strreset_outreq(), move up SCTP_STRRESET_ERR_WRONG_SSN + check, as the reset has to succeed after reconf_timer stops for the + in stream reset request retransmission. + 3. In sctp_process_strreset_inreq(), no event should be sent, as no in + or out stream is reset here. + 4. In sctp_process_strreset_resp(), SCTP_STREAM_RESET_INCOMING_SSN or + OUTGOING event should always be sent for stream reset requests, no + matter it fails or succeeds to process the request. + +Fixes: 810544764536 ("sctp: implement receiver-side procedures for the Outgoing SSN Reset Request Parameter") +Fixes: 16e1a91965b0 ("sctp: implement receiver-side procedures for the Incoming SSN Reset Request Parameter") +Fixes: 11ae76e67a17 ("sctp: implement receiver-side procedures for the Reconf Response Parameter") +Reported-by: Ying Xu +Signed-off-by: Xin Long +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sctp/stream.c | 39 +++++++++++++++++---------------------- + 1 file changed, 17 insertions(+), 22 deletions(-) + +--- a/net/sctp/stream.c ++++ b/net/sctp/stream.c +@@ -360,9 +360,9 @@ struct sctp_chunk *sctp_process_strreset + struct sctp_strreset_outreq *outreq = param.v; + struct sctp_stream *stream = &asoc->stream; + __u32 result = SCTP_STRRESET_DENIED; +- __u16 i, nums, flags = 0; + __be16 *str_p = NULL; + __u32 request_seq; ++ __u16 i, nums; + + request_seq = ntohl(outreq->request_seq); + +@@ -390,6 +390,15 @@ struct sctp_chunk *sctp_process_strreset + if (!(asoc->strreset_enable & SCTP_ENABLE_RESET_STREAM_REQ)) + goto out; + ++ nums = (ntohs(param.p->length) - sizeof(*outreq)) / sizeof(__u16); ++ str_p = outreq->list_of_streams; ++ for (i = 0; i < nums; i++) { ++ if (ntohs(str_p[i]) >= stream->incnt) { ++ result = SCTP_STRRESET_ERR_WRONG_SSN; ++ goto out; ++ } ++ } ++ + if (asoc->strreset_chunk) { + if (!sctp_chunk_lookup_strreset_param( + asoc, outreq->response_seq, +@@ -412,32 +421,19 @@ struct sctp_chunk *sctp_process_strreset + sctp_chunk_put(asoc->strreset_chunk); + asoc->strreset_chunk = NULL; + } +- +- flags = SCTP_STREAM_RESET_INCOMING_SSN; + } + +- nums = (ntohs(param.p->length) - sizeof(*outreq)) / 2; +- if (nums) { +- str_p = outreq->list_of_streams; +- for (i = 0; i < nums; i++) { +- if (ntohs(str_p[i]) >= stream->incnt) { +- result = SCTP_STRRESET_ERR_WRONG_SSN; +- goto out; +- } +- } +- ++ if (nums) + for (i = 0; i < nums; i++) + stream->in[ntohs(str_p[i])].ssn = 0; +- } else { ++ else + for (i = 0; i < stream->incnt; i++) + stream->in[i].ssn = 0; +- } + + result = SCTP_STRRESET_PERFORMED; + + *evp = sctp_ulpevent_make_stream_reset_event(asoc, +- flags | SCTP_STREAM_RESET_OUTGOING_SSN, nums, str_p, +- GFP_ATOMIC); ++ SCTP_STREAM_RESET_INCOMING_SSN, nums, str_p, GFP_ATOMIC); + + out: + sctp_update_strreset_result(asoc, result); +@@ -507,9 +503,6 @@ struct sctp_chunk *sctp_process_strreset + + result = SCTP_STRRESET_PERFORMED; + +- *evp = sctp_ulpevent_make_stream_reset_event(asoc, +- SCTP_STREAM_RESET_INCOMING_SSN, nums, str_p, GFP_ATOMIC); +- + out: + sctp_update_strreset_result(asoc, result); + err: +@@ -802,10 +795,10 @@ struct sctp_chunk *sctp_process_strreset + for (i = 0; i < stream->outcnt; i++) + stream->out[i].ssn = 0; + } +- +- flags = SCTP_STREAM_RESET_OUTGOING_SSN; + } + ++ flags |= SCTP_STREAM_RESET_OUTGOING_SSN; ++ + for (i = 0; i < stream->outcnt; i++) + stream->out[i].state = SCTP_STREAM_OPEN; + +@@ -823,6 +816,8 @@ struct sctp_chunk *sctp_process_strreset + str_p = inreq->list_of_streams; + nums = (ntohs(inreq->param_hdr.length) - sizeof(*inreq)) / 2; + ++ flags |= SCTP_STREAM_RESET_INCOMING_SSN; ++ + *evp = sctp_ulpevent_make_stream_reset_event(asoc, flags, + nums, str_p, GFP_ATOMIC); + } else if (req->type == SCTP_PARAM_RESET_TSN_REQUEST) { diff --git a/queue-4.14/series b/queue-4.14/series index dd28db7345b..c187e2d535f 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -1 +1,19 @@ fix-net-ipv4-do-not-handle-duplicate-fragments-as-overlapping.patch +ipv6-consider-sk_bound_dev_if-when-binding-a-socket-to-an-address.patch +ipv6-sr-clear-ip6cb-skb-on-srh-ip4ip6-encapsulation.patch +l2tp-copy-4-more-bytes-to-linear-part-if-necessary.patch +net-mlx4_core-add-masking-for-a-few-queries-on-hca-caps.patch +netrom-switch-to-sock-timer-api.patch +net-rose-fix-null-ax25_cb-kernel-panic.patch +net-set-default-network-namespace-in-init_dummy_netdev.patch +ucc_geth-reset-bql-queue-when-stopping-device.patch +net-mlx5e-allow-mac-invalidation-while-spoofchk-is-on.patch +revert-net-mlx5e-e-switch-initialize-eswitch-only-if-eswitch-manager.patch +virtio_net-don-t-enable-napi-when-interface-is-down.patch +virtio_net-don-t-call-free_old_xmit_skbs-for-xdp_frames.patch +virtio_net-fix-not-restoring-real_num_rx_queues.patch +sctp-improve-the-events-for-sctp-stream-adding.patch +sctp-improve-the-events-for-sctp-stream-reset.patch +l2tp-remove-l2specific_len-dependency-in-l2tp_core.patch +l2tp-fix-reading-optional-fields-of-l2tpv3.patch +ipvlan-l3mdev-fix-broken-l3s-mode-wrt-local-routes.patch diff --git a/queue-4.14/ucc_geth-reset-bql-queue-when-stopping-device.patch b/queue-4.14/ucc_geth-reset-bql-queue-when-stopping-device.patch new file mode 100644 index 00000000000..c60bb1ab0bb --- /dev/null +++ b/queue-4.14/ucc_geth-reset-bql-queue-when-stopping-device.patch @@ -0,0 +1,33 @@ +From foo@baz Sat Feb 2 10:57:42 CET 2019 +From: Mathias Thore +Date: Mon, 28 Jan 2019 10:07:47 +0100 +Subject: ucc_geth: Reset BQL queue when stopping device + +From: Mathias Thore + +[ Upstream commit e15aa3b2b1388c399c1a2ce08550d2cc4f7e3e14 ] + +After a timeout event caused by for example a broadcast storm, when +the MAC and PHY are reset, the BQL TX queue needs to be reset as +well. Otherwise, the device will exhibit severe performance issues +even after the storm has ended. + +Co-authored-by: David Gounaris +Signed-off-by: Mathias Thore +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/freescale/ucc_geth.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/ethernet/freescale/ucc_geth.c ++++ b/drivers/net/ethernet/freescale/ucc_geth.c +@@ -1888,6 +1888,8 @@ static void ucc_geth_free_tx(struct ucc_ + u16 i, j; + u8 __iomem *bd; + ++ netdev_reset_queue(ugeth->ndev); ++ + ug_info = ugeth->ug_info; + uf_info = &ug_info->uf_info; + diff --git a/queue-4.14/virtio_net-don-t-call-free_old_xmit_skbs-for-xdp_frames.patch b/queue-4.14/virtio_net-don-t-call-free_old_xmit_skbs-for-xdp_frames.patch new file mode 100644 index 00000000000..2fc39077ec9 --- /dev/null +++ b/queue-4.14/virtio_net-don-t-call-free_old_xmit_skbs-for-xdp_frames.patch @@ -0,0 +1,143 @@ +From foo@baz Sat Feb 2 10:57:42 CET 2019 +From: Toshiaki Makita +Date: Tue, 29 Jan 2019 09:45:54 +0900 +Subject: virtio_net: Don't call free_old_xmit_skbs for xdp_frames + +From: Toshiaki Makita + +[ Upstream commit 534da5e856334fb54cb0272a9fb3afec28ea3aed ] + +When napi_tx is enabled, virtnet_poll_cleantx() called +free_old_xmit_skbs() even for xdp send queue. +This is bogus since the queue has xdp_frames, not sk_buffs, thus mangled +device tx bytes counters because skb->len is meaningless value, and even +triggered oops due to general protection fault on freeing them. + +Since xdp send queues do not aquire locks, old xdp_frames should be +freed only in virtnet_xdp_xmit(), so just skip free_old_xmit_skbs() for +xdp send queues. + +Similarly virtnet_poll_tx() called free_old_xmit_skbs(). This NAPI +handler is called even without calling start_xmit() because cb for tx is +by default enabled. Once the handler is called, it enabled the cb again, +and then the handler would be called again. We don't need this handler +for XDP, so don't enable cb as well as not calling free_old_xmit_skbs(). + +Also, we need to disable tx NAPI when disabling XDP, so +virtnet_poll_tx() can safely access curr_queue_pairs and +xdp_queue_pairs, which are not atomically updated while disabling XDP. + +Fixes: b92f1e6751a6 ("virtio-net: transmit napi") +Fixes: 7b0411ef4aa6 ("virtio-net: clean tx descriptors from rx napi") +Signed-off-by: Toshiaki Makita +Acked-by: Jason Wang +Acked-by: Michael S. Tsirkin +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/virtio_net.c | 49 +++++++++++++++++++++++++++++++---------------- + 1 file changed, 33 insertions(+), 16 deletions(-) + +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -1149,6 +1149,16 @@ static void free_old_xmit_skbs(struct se + u64_stats_update_end(&stats->tx_syncp); + } + ++static bool is_xdp_raw_buffer_queue(struct virtnet_info *vi, int q) ++{ ++ if (q < (vi->curr_queue_pairs - vi->xdp_queue_pairs)) ++ return false; ++ else if (q < vi->curr_queue_pairs) ++ return true; ++ else ++ return false; ++} ++ + static void virtnet_poll_cleantx(struct receive_queue *rq) + { + struct virtnet_info *vi = rq->vq->vdev->priv; +@@ -1156,7 +1166,7 @@ static void virtnet_poll_cleantx(struct + struct send_queue *sq = &vi->sq[index]; + struct netdev_queue *txq = netdev_get_tx_queue(vi->dev, index); + +- if (!sq->napi.weight) ++ if (!sq->napi.weight || is_xdp_raw_buffer_queue(vi, index)) + return; + + if (__netif_tx_trylock(txq)) { +@@ -1206,8 +1216,16 @@ static int virtnet_poll_tx(struct napi_s + { + struct send_queue *sq = container_of(napi, struct send_queue, napi); + struct virtnet_info *vi = sq->vq->vdev->priv; +- struct netdev_queue *txq = netdev_get_tx_queue(vi->dev, vq2txq(sq->vq)); ++ unsigned int index = vq2txq(sq->vq); ++ struct netdev_queue *txq; + ++ if (unlikely(is_xdp_raw_buffer_queue(vi, index))) { ++ /* We don't need to enable cb for XDP */ ++ napi_complete_done(napi, 0); ++ return 0; ++ } ++ ++ txq = netdev_get_tx_queue(vi->dev, index); + __netif_tx_lock(txq, raw_smp_processor_id()); + free_old_xmit_skbs(sq); + __netif_tx_unlock(txq); +@@ -2006,9 +2024,12 @@ static int virtnet_xdp_set(struct net_de + } + + /* Make sure NAPI is not using any XDP TX queues for RX. */ +- if (netif_running(dev)) +- for (i = 0; i < vi->max_queue_pairs; i++) ++ if (netif_running(dev)) { ++ for (i = 0; i < vi->max_queue_pairs; i++) { + napi_disable(&vi->rq[i].napi); ++ virtnet_napi_tx_disable(&vi->sq[i].napi); ++ } ++ } + + netif_set_real_num_rx_queues(dev, curr_qp + xdp_qp); + err = _virtnet_set_queues(vi, curr_qp + xdp_qp); +@@ -2027,16 +2048,22 @@ static int virtnet_xdp_set(struct net_de + } + if (old_prog) + bpf_prog_put(old_prog); +- if (netif_running(dev)) ++ if (netif_running(dev)) { + virtnet_napi_enable(vi->rq[i].vq, &vi->rq[i].napi); ++ virtnet_napi_tx_enable(vi, vi->sq[i].vq, ++ &vi->sq[i].napi); ++ } + } + + return 0; + + err: + if (netif_running(dev)) { +- for (i = 0; i < vi->max_queue_pairs; i++) ++ for (i = 0; i < vi->max_queue_pairs; i++) { + virtnet_napi_enable(vi->rq[i].vq, &vi->rq[i].napi); ++ virtnet_napi_tx_enable(vi, vi->sq[i].vq, ++ &vi->sq[i].napi); ++ } + } + if (prog) + bpf_prog_sub(prog, vi->max_queue_pairs - 1); +@@ -2178,16 +2205,6 @@ static void free_receive_page_frags(stru + put_page(vi->rq[i].alloc_frag.page); + } + +-static bool is_xdp_raw_buffer_queue(struct virtnet_info *vi, int q) +-{ +- if (q < (vi->curr_queue_pairs - vi->xdp_queue_pairs)) +- return false; +- else if (q < vi->curr_queue_pairs) +- return true; +- else +- return false; +-} +- + static void free_unused_bufs(struct virtnet_info *vi) + { + void *buf; diff --git a/queue-4.14/virtio_net-don-t-enable-napi-when-interface-is-down.patch b/queue-4.14/virtio_net-don-t-enable-napi-when-interface-is-down.patch new file mode 100644 index 00000000000..2ff3b355e94 --- /dev/null +++ b/queue-4.14/virtio_net-don-t-enable-napi-when-interface-is-down.patch @@ -0,0 +1,42 @@ +From foo@baz Sat Feb 2 10:57:42 CET 2019 +From: Toshiaki Makita +Date: Tue, 29 Jan 2019 09:45:53 +0900 +Subject: virtio_net: Don't enable NAPI when interface is down + +From: Toshiaki Makita + +[ Upstream commit 8be4d9a492f88b96d4d3a06c6cbedbc40ca14c83 ] + +Commit 4e09ff536284 ("virtio-net: disable NAPI only when enabled during +XDP set") tried to fix inappropriate NAPI enabling/disabling when +!netif_running(), but was not complete. + +On error path virtio_net could enable NAPI even when !netif_running(). +This can cause enabling NAPI twice on virtnet_open(), which would +trigger BUG_ON() in napi_enable(). + +Fixes: 4941d472bf95b ("virtio-net: do not reset during XDP set") +Signed-off-by: Toshiaki Makita +Acked-by: Jason Wang +Acked-by: Michael S. Tsirkin +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/virtio_net.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -2034,8 +2034,10 @@ static int virtnet_xdp_set(struct net_de + return 0; + + err: +- for (i = 0; i < vi->max_queue_pairs; i++) +- virtnet_napi_enable(vi->rq[i].vq, &vi->rq[i].napi); ++ if (netif_running(dev)) { ++ for (i = 0; i < vi->max_queue_pairs; i++) ++ virtnet_napi_enable(vi->rq[i].vq, &vi->rq[i].napi); ++ } + if (prog) + bpf_prog_sub(prog, vi->max_queue_pairs - 1); + return err; diff --git a/queue-4.14/virtio_net-fix-not-restoring-real_num_rx_queues.patch b/queue-4.14/virtio_net-fix-not-restoring-real_num_rx_queues.patch new file mode 100644 index 00000000000..e7e49428622 --- /dev/null +++ b/queue-4.14/virtio_net-fix-not-restoring-real_num_rx_queues.patch @@ -0,0 +1,38 @@ +From foo@baz Sat Feb 2 10:57:42 CET 2019 +From: Toshiaki Makita +Date: Tue, 29 Jan 2019 09:45:55 +0900 +Subject: virtio_net: Fix not restoring real_num_rx_queues + +From: Toshiaki Makita + +[ Upstream commit 188313c137c4f76afd0862f50dbc185b198b9e2a ] + +When _virtnet_set_queues() failed we did not restore real_num_rx_queues. +Fix this by placing the change of real_num_rx_queues after +_virtnet_set_queues(). +This order is also in line with virtnet_set_channels(). + +Fixes: 4941d472bf95 ("virtio-net: do not reset during XDP set") +Signed-off-by: Toshiaki Makita +Acked-by: Jason Wang +Acked-by: Michael S. Tsirkin +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/virtio_net.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -2031,10 +2031,10 @@ static int virtnet_xdp_set(struct net_de + } + } + +- netif_set_real_num_rx_queues(dev, curr_qp + xdp_qp); + err = _virtnet_set_queues(vi, curr_qp + xdp_qp); + if (err) + goto err; ++ netif_set_real_num_rx_queues(dev, curr_qp + xdp_qp); + vi->xdp_queue_pairs = xdp_qp; + + for (i = 0; i < vi->max_queue_pairs; i++) {