From d4fe8992a566a9d84318dbb868e26e1e374aa9ed Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Tue, 8 Dec 2020 10:01:46 -0500 Subject: [PATCH] Fixes for 4.14 Signed-off-by: Sasha Levin --- ...l-ip-header-before-ecn-decapsulation.patch | 124 +++++++++++++ ...-fix-pin-being-driven-low-for-a-whil.patch | 174 ++++++++++++++++++ ...-replace-warn-with-dev_info_once-whe.patch | 63 +++++++ queue-4.14/series | 4 + ...-vlan-parsing-code-and-limit-max-par.patch | 122 ++++++++++++ 5 files changed, 487 insertions(+) create mode 100644 queue-4.14/geneve-pull-ip-header-before-ecn-decapsulation.patch create mode 100644 queue-4.14/pinctrl-baytrail-fix-pin-being-driven-low-for-a-whil.patch create mode 100644 queue-4.14/pinctrl-baytrail-replace-warn-with-dev_info_once-whe.patch create mode 100644 queue-4.14/series create mode 100644 queue-4.14/vlan-consolidate-vlan-parsing-code-and-limit-max-par.patch diff --git a/queue-4.14/geneve-pull-ip-header-before-ecn-decapsulation.patch b/queue-4.14/geneve-pull-ip-header-before-ecn-decapsulation.patch new file mode 100644 index 00000000000..e30902df864 --- /dev/null +++ b/queue-4.14/geneve-pull-ip-header-before-ecn-decapsulation.patch @@ -0,0 +1,124 @@ +From b4bbb28bdf8efd5679eacd0d9069437492e0d63f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Dec 2020 01:05:07 -0800 +Subject: geneve: pull IP header before ECN decapsulation + +From: Eric Dumazet + +IP_ECN_decapsulate() and IP6_ECN_decapsulate() assume +IP header is already pulled. + +geneve does not ensure this yet. + +Fixing this generically in IP_ECN_decapsulate() and +IP6_ECN_decapsulate() is not possible, since callers +pass a pointer that might be freed by pskb_may_pull() + +syzbot reported : + +BUG: KMSAN: uninit-value in __INET_ECN_decapsulate include/net/inet_ecn.h:238 [inline] +BUG: KMSAN: uninit-value in INET_ECN_decapsulate+0x345/0x1db0 include/net/inet_ecn.h:260 +CPU: 1 PID: 8941 Comm: syz-executor.0 Not tainted 5.10.0-rc4-syzkaller #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Call Trace: + + __dump_stack lib/dump_stack.c:77 [inline] + dump_stack+0x21c/0x280 lib/dump_stack.c:118 + kmsan_report+0xf7/0x1e0 mm/kmsan/kmsan_report.c:118 + __msan_warning+0x5f/0xa0 mm/kmsan/kmsan_instr.c:197 + __INET_ECN_decapsulate include/net/inet_ecn.h:238 [inline] + INET_ECN_decapsulate+0x345/0x1db0 include/net/inet_ecn.h:260 + geneve_rx+0x2103/0x2980 include/net/inet_ecn.h:306 + geneve_udp_encap_recv+0x105c/0x1340 drivers/net/geneve.c:377 + udp_queue_rcv_one_skb+0x193a/0x1af0 net/ipv4/udp.c:2093 + udp_queue_rcv_skb+0x282/0x1050 net/ipv4/udp.c:2167 + udp_unicast_rcv_skb net/ipv4/udp.c:2325 [inline] + __udp4_lib_rcv+0x399d/0x5880 net/ipv4/udp.c:2394 + udp_rcv+0x5c/0x70 net/ipv4/udp.c:2564 + ip_protocol_deliver_rcu+0x572/0xc50 net/ipv4/ip_input.c:204 + ip_local_deliver_finish net/ipv4/ip_input.c:231 [inline] + NF_HOOK include/linux/netfilter.h:301 [inline] + ip_local_deliver+0x583/0x8d0 net/ipv4/ip_input.c:252 + dst_input include/net/dst.h:449 [inline] + ip_rcv_finish net/ipv4/ip_input.c:428 [inline] + NF_HOOK include/linux/netfilter.h:301 [inline] + ip_rcv+0x5c3/0x840 net/ipv4/ip_input.c:539 + __netif_receive_skb_one_core net/core/dev.c:5315 [inline] + __netif_receive_skb+0x1ec/0x640 net/core/dev.c:5429 + process_backlog+0x523/0xc10 net/core/dev.c:6319 + napi_poll+0x420/0x1010 net/core/dev.c:6763 + net_rx_action+0x35c/0xd40 net/core/dev.c:6833 + __do_softirq+0x1a9/0x6fa kernel/softirq.c:298 + asm_call_irq_on_stack+0xf/0x20 + + __run_on_irqstack arch/x86/include/asm/irq_stack.h:26 [inline] + run_on_irqstack_cond arch/x86/include/asm/irq_stack.h:77 [inline] + do_softirq_own_stack+0x6e/0x90 arch/x86/kernel/irq_64.c:77 + do_softirq kernel/softirq.c:343 [inline] + __local_bh_enable_ip+0x184/0x1d0 kernel/softirq.c:195 + local_bh_enable+0x36/0x40 include/linux/bottom_half.h:32 + rcu_read_unlock_bh include/linux/rcupdate.h:730 [inline] + __dev_queue_xmit+0x3a9b/0x4520 net/core/dev.c:4167 + dev_queue_xmit+0x4b/0x60 net/core/dev.c:4173 + packet_snd net/packet/af_packet.c:2992 [inline] + packet_sendmsg+0x86f9/0x99d0 net/packet/af_packet.c:3017 + sock_sendmsg_nosec net/socket.c:651 [inline] + sock_sendmsg net/socket.c:671 [inline] + __sys_sendto+0x9dc/0xc80 net/socket.c:1992 + __do_sys_sendto net/socket.c:2004 [inline] + __se_sys_sendto+0x107/0x130 net/socket.c:2000 + __x64_sys_sendto+0x6e/0x90 net/socket.c:2000 + do_syscall_64+0x9f/0x140 arch/x86/entry/common.c:48 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +Fixes: 2d07dc79fe04 ("geneve: add initial netdev driver for GENEVE tunnels") +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Link: https://lore.kernel.org/r/20201201090507.4137906-1-eric.dumazet@gmail.com +Signed-off-by: Jakub Kicinski +--- + drivers/net/geneve.c | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c +index f48006c22a8a6..5eb7f409dc10b 100644 +--- a/drivers/net/geneve.c ++++ b/drivers/net/geneve.c +@@ -254,11 +254,21 @@ static void geneve_rx(struct geneve_dev *geneve, struct geneve_sock *gs, + skb_dst_set(skb, &tun_dst->dst); + + /* Ignore packet loops (and multicast echo) */ +- if (ether_addr_equal(eth_hdr(skb)->h_source, geneve->dev->dev_addr)) { +- geneve->dev->stats.rx_errors++; +- goto drop; ++ if (ether_addr_equal(eth_hdr(skb)->h_source, geneve->dev->dev_addr)) ++ goto rx_error; ++ ++ switch (skb_protocol(skb, true)) { ++ case htons(ETH_P_IP): ++ if (pskb_may_pull(skb, sizeof(struct iphdr))) ++ goto rx_error; ++ break; ++ case htons(ETH_P_IPV6): ++ if (pskb_may_pull(skb, sizeof(struct ipv6hdr))) ++ goto rx_error; ++ break; ++ default: ++ goto rx_error; + } +- + oiph = skb_network_header(skb); + skb_reset_network_header(skb); + +@@ -299,6 +309,8 @@ static void geneve_rx(struct geneve_dev *geneve, struct geneve_sock *gs, + u64_stats_update_end(&stats->syncp); + } + return; ++rx_error: ++ geneve->dev->stats.rx_errors++; + drop: + /* Consume bad packet */ + kfree_skb(skb); +-- +2.27.0 + diff --git a/queue-4.14/pinctrl-baytrail-fix-pin-being-driven-low-for-a-whil.patch b/queue-4.14/pinctrl-baytrail-fix-pin-being-driven-low-for-a-whil.patch new file mode 100644 index 00000000000..4c2c1a6df16 --- /dev/null +++ b/queue-4.14/pinctrl-baytrail-fix-pin-being-driven-low-for-a-whil.patch @@ -0,0 +1,174 @@ +From a2224f379978cf16e03c8dcfd33e5cd3bdd1bfe9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 6 Jun 2020 11:31:50 +0200 +Subject: pinctrl: baytrail: Fix pin being driven low for a while on + gpiod_get(..., GPIOD_OUT_HIGH) + +From: Hans de Goede + +commit 156abe2961601d60a8c2a60c6dc8dd6ce7adcdaf upstream + +The pins on the Bay Trail SoC have separate input-buffer and output-buffer +enable bits and a read of the level bit of the value register will always +return the value from the input-buffer. + +The BIOS of a device may configure a pin in output-only mode, only enabling +the output buffer, and write 1 to the level bit to drive the pin high. +This 1 written to the level bit will be stored inside the data-latch of the +output buffer. + +But a subsequent read of the value register will return 0 for the level bit +because the input-buffer is disabled. This causes a read-modify-write as +done by byt_gpio_set_direction() to write 0 to the level bit, driving the +pin low! + +Before this commit byt_gpio_direction_output() relied on +pinctrl_gpio_direction_output() to set the direction, followed by a call +to byt_gpio_set() to apply the selected value. This causes the pin to +go low between the pinctrl_gpio_direction_output() and byt_gpio_set() +calls. + +Change byt_gpio_direction_output() to directly make the register +modifications itself instead. Replacing the 2 subsequent writes to the +value register with a single write. + +Note that the pinctrl code does not keep track internally of the direction, +so not going through pinctrl_gpio_direction_output() is not an issue. + +This issue was noticed on a Trekstor SurfTab Twin 10.1. When the panel is +already on at boot (no external monitor connected), then the i915 driver +does a gpiod_get(..., GPIOD_OUT_HIGH) for the panel-enable GPIO. The +temporarily going low of that GPIO was causing the panel to reset itself +after which it would not show an image until it was turned off and back on +again (until a full modeset was done on it). This commit fixes this. + +This commit also updates the byt_gpio_direction_input() to use direct +register accesses instead of going through pinctrl_gpio_direction_input(), +to keep it consistent with byt_gpio_direction_output(). + +Note for backporting, this commit depends on: +commit e2b74419e5cc ("pinctrl: baytrail: Replace WARN with dev_info_once +when setting direct-irq pin to output") + +Cc: stable@vger.kernel.org +Fixes: 86e3ef812fe3 ("pinctrl: baytrail: Update gpio chip operations") +Signed-off-by: Hans de Goede +Acked-by: Mika Westerberg +Signed-off-by: Andy Shevchenko +[sudip: use byt_gpio and vg->pdev->dev for dev_info()] +Signed-off-by: Sudip Mukherjee +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/intel/pinctrl-baytrail.c | 67 +++++++++++++++++++----- + 1 file changed, 53 insertions(+), 14 deletions(-) + +diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c +index d86c4c51769e4..62eac76be9f66 100644 +--- a/drivers/pinctrl/intel/pinctrl-baytrail.c ++++ b/drivers/pinctrl/intel/pinctrl-baytrail.c +@@ -1017,6 +1017,21 @@ static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev, + pm_runtime_put(&vg->pdev->dev); + } + ++static void byt_gpio_direct_irq_check(struct byt_gpio *vg, ++ unsigned int offset) ++{ ++ void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); ++ ++ /* ++ * Before making any direction modifications, do a check if gpio is set ++ * for direct IRQ. On Bay Trail, setting GPIO to output does not make ++ * sense, so let's at least inform the caller before they shoot ++ * themselves in the foot. ++ */ ++ if (readl(conf_reg) & BYT_DIRECT_IRQ_EN) ++ dev_info_once(&vg->pdev->dev, "Potential Error: Setting GPIO with direct_irq_en to output"); ++} ++ + static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, + struct pinctrl_gpio_range *range, + unsigned int offset, +@@ -1024,7 +1039,6 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, + { + struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); + void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); +- void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); + unsigned long flags; + u32 value; + +@@ -1034,14 +1048,8 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, + value &= ~BYT_DIR_MASK; + if (input) + value |= BYT_OUTPUT_EN; +- else if (readl(conf_reg) & BYT_DIRECT_IRQ_EN) +- /* +- * Before making any direction modifications, do a check if gpio +- * is set for direct IRQ. On baytrail, setting GPIO to output +- * does not make sense, so let's at least inform the caller before +- * they shoot themselves in the foot. +- */ +- dev_info_once(vg->dev, "Potential Error: Setting GPIO with direct_irq_en to output"); ++ else ++ byt_gpio_direct_irq_check(vg, offset); + + writel(value, val_reg); + +@@ -1382,19 +1390,50 @@ static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) + + static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) + { +- return pinctrl_gpio_direction_input(chip->base + offset); ++ struct byt_gpio *vg = gpiochip_get_data(chip); ++ void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); ++ unsigned long flags; ++ u32 reg; ++ ++ raw_spin_lock_irqsave(&byt_lock, flags); ++ ++ reg = readl(val_reg); ++ reg &= ~BYT_DIR_MASK; ++ reg |= BYT_OUTPUT_EN; ++ writel(reg, val_reg); ++ ++ raw_spin_unlock_irqrestore(&byt_lock, flags); ++ return 0; + } + ++/* ++ * Note despite the temptation this MUST NOT be converted into a call to ++ * pinctrl_gpio_direction_output() + byt_gpio_set() that does not work this ++ * MUST be done as a single BYT_VAL_REG register write. ++ * See the commit message of the commit adding this comment for details. ++ */ + static int byt_gpio_direction_output(struct gpio_chip *chip, + unsigned int offset, int value) + { +- int ret = pinctrl_gpio_direction_output(chip->base + offset); ++ struct byt_gpio *vg = gpiochip_get_data(chip); ++ void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); ++ unsigned long flags; ++ u32 reg; + +- if (ret) +- return ret; ++ raw_spin_lock_irqsave(&byt_lock, flags); + +- byt_gpio_set(chip, offset, value); ++ byt_gpio_direct_irq_check(vg, offset); + ++ reg = readl(val_reg); ++ reg &= ~BYT_DIR_MASK; ++ if (value) ++ reg |= BYT_LEVEL; ++ else ++ reg &= ~BYT_LEVEL; ++ ++ writel(reg, val_reg); ++ ++ raw_spin_unlock_irqrestore(&byt_lock, flags); + return 0; + } + +-- +2.27.0 + diff --git a/queue-4.14/pinctrl-baytrail-replace-warn-with-dev_info_once-whe.patch b/queue-4.14/pinctrl-baytrail-replace-warn-with-dev_info_once-whe.patch new file mode 100644 index 00000000000..ff777c53039 --- /dev/null +++ b/queue-4.14/pinctrl-baytrail-replace-warn-with-dev_info_once-whe.patch @@ -0,0 +1,63 @@ +From 74b957413328fdb5a78da7c1a5f0b8ff9ddeb84d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Jan 2020 15:52:43 +0100 +Subject: pinctrl: baytrail: Replace WARN with dev_info_once when setting + direct-irq pin to output + +From: Hans de Goede + +commit e2b74419e5cc7cfc58f3e785849f73f8fa0af5b3 upstream + +Suspending Goodix touchscreens requires changing the interrupt pin to +output before sending them a power-down command. Followed by wiggling +the interrupt pin to wake the device up, after which it is put back +in input mode. + +On Cherry Trail device the interrupt pin is listed as a GpioInt ACPI +resource so we can do this without problems as long as we release the +IRQ before changing the pin to output mode. + +On Bay Trail devices with a Goodix touchscreen direct-irq mode is used +in combination with listing the pin as a normal GpioIo resource. This +works fine, but this triggers the WARN in byt_gpio_set_direction-s output +path because direct-irq support is enabled on the pin. + +This commit replaces the WARN call with a dev_info_once call, fixing a +bunch of WARN splats in dmesg on each suspend/resume cycle. + +Signed-off-by: Hans de Goede +Acked-by: Mika Westerberg +Signed-off-by: Andy Shevchenko +Signed-off-by: Sudip Mukherjee +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/intel/pinctrl-baytrail.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c +index 2ea4bb9ce6e16..d86c4c51769e4 100644 +--- a/drivers/pinctrl/intel/pinctrl-baytrail.c ++++ b/drivers/pinctrl/intel/pinctrl-baytrail.c +@@ -1034,15 +1034,15 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, + value &= ~BYT_DIR_MASK; + if (input) + value |= BYT_OUTPUT_EN; +- else ++ else if (readl(conf_reg) & BYT_DIRECT_IRQ_EN) + /* + * Before making any direction modifications, do a check if gpio + * is set for direct IRQ. On baytrail, setting GPIO to output +- * does not make sense, so let's at least warn the caller before ++ * does not make sense, so let's at least inform the caller before + * they shoot themselves in the foot. + */ +- WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN, +- "Potential Error: Setting GPIO with direct_irq_en to output"); ++ dev_info_once(vg->dev, "Potential Error: Setting GPIO with direct_irq_en to output"); ++ + writel(value, val_reg); + + raw_spin_unlock_irqrestore(&byt_lock, flags); +-- +2.27.0 + diff --git a/queue-4.14/series b/queue-4.14/series new file mode 100644 index 00000000000..40ad532edbb --- /dev/null +++ b/queue-4.14/series @@ -0,0 +1,4 @@ +pinctrl-baytrail-replace-warn-with-dev_info_once-whe.patch +pinctrl-baytrail-fix-pin-being-driven-low-for-a-whil.patch +vlan-consolidate-vlan-parsing-code-and-limit-max-par.patch +geneve-pull-ip-header-before-ecn-decapsulation.patch diff --git a/queue-4.14/vlan-consolidate-vlan-parsing-code-and-limit-max-par.patch b/queue-4.14/vlan-consolidate-vlan-parsing-code-and-limit-max-par.patch new file mode 100644 index 00000000000..0119cf95450 --- /dev/null +++ b/queue-4.14/vlan-consolidate-vlan-parsing-code-and-limit-max-par.patch @@ -0,0 +1,122 @@ +From 7097329f79576052474d81fdb68e00834131abeb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Jul 2020 13:03:25 +0200 +Subject: vlan: consolidate VLAN parsing code and limit max parsing depth +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Toke Høiland-Jørgensen + +[ Upstream commit 469aceddfa3ed16e17ee30533fae45e90f62efd8 ] + +Toshiaki pointed out that we now have two very similar functions to extract +the L3 protocol number in the presence of VLAN tags. And Daniel pointed out +that the unbounded parsing loop makes it possible for maliciously crafted +packets to loop through potentially hundreds of tags. + +Fix both of these issues by consolidating the two parsing functions and +limiting the VLAN tag parsing to a max depth of 8 tags. As part of this, +switch over __vlan_get_protocol() to use skb_header_pointer() instead of +pskb_may_pull(), to avoid the possible side effects of the latter and keep +the skb pointer 'const' through all the parsing functions. + +v2: +- Use limit of 8 tags instead of 32 (matching XMIT_RECURSION_LIMIT) + +Reported-by: Toshiaki Makita +Reported-by: Daniel Borkmann +Fixes: d7bf2ebebc2b ("sched: consistently handle layer3 header accesses in the presence of VLANs") +Signed-off-by: Toke Høiland-Jørgensen +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + include/linux/if_vlan.h | 29 ++++++++++++++++++++++------- + include/net/inet_ecn.h | 1 + + 2 files changed, 23 insertions(+), 7 deletions(-) + +diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h +index 87b8c20d5b27c..af4f2a7f8e9a0 100644 +--- a/include/linux/if_vlan.h ++++ b/include/linux/if_vlan.h +@@ -30,6 +30,8 @@ + #define VLAN_ETH_DATA_LEN 1500 /* Max. octets in payload */ + #define VLAN_ETH_FRAME_LEN 1518 /* Max. octets in frame sans FCS */ + ++#define VLAN_MAX_DEPTH 8 /* Max. number of nested VLAN tags parsed */ ++ + /* + * struct vlan_hdr - vlan header + * @h_vlan_TCI: priority and VLAN ID +@@ -534,10 +536,10 @@ static inline int vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci) + * Returns the EtherType of the packet, regardless of whether it is + * vlan encapsulated (normal or hardware accelerated) or not. + */ +-static inline __be16 __vlan_get_protocol(struct sk_buff *skb, __be16 type, ++static inline __be16 __vlan_get_protocol(const struct sk_buff *skb, __be16 type, + int *depth) + { +- unsigned int vlan_depth = skb->mac_len; ++ unsigned int vlan_depth = skb->mac_len, parse_depth = VLAN_MAX_DEPTH; + + /* if type is 802.1Q/AD then the header should already be + * present at mac_len - VLAN_HLEN (if mac_len > 0), or at +@@ -552,13 +554,12 @@ static inline __be16 __vlan_get_protocol(struct sk_buff *skb, __be16 type, + vlan_depth = ETH_HLEN; + } + do { +- struct vlan_hdr *vh; ++ struct vlan_hdr vhdr, *vh; + +- if (unlikely(!pskb_may_pull(skb, +- vlan_depth + VLAN_HLEN))) ++ vh = skb_header_pointer(skb, vlan_depth, sizeof(vhdr), &vhdr); ++ if (unlikely(!vh || !--parse_depth)) + return 0; + +- vh = (struct vlan_hdr *)(skb->data + vlan_depth); + type = vh->h_vlan_encapsulated_proto; + vlan_depth += VLAN_HLEN; + } while (eth_type_vlan(type)); +@@ -577,11 +578,25 @@ static inline __be16 __vlan_get_protocol(struct sk_buff *skb, __be16 type, + * Returns the EtherType of the packet, regardless of whether it is + * vlan encapsulated (normal or hardware accelerated) or not. + */ +-static inline __be16 vlan_get_protocol(struct sk_buff *skb) ++static inline __be16 vlan_get_protocol(const struct sk_buff *skb) + { + return __vlan_get_protocol(skb, skb->protocol, NULL); + } + ++/* A getter for the SKB protocol field which will handle VLAN tags consistently ++ * whether VLAN acceleration is enabled or not. ++ */ ++static inline __be16 skb_protocol(const struct sk_buff *skb, bool skip_vlan) ++{ ++ if (!skip_vlan) ++ /* VLAN acceleration strips the VLAN header from the skb and ++ * moves it to skb->vlan_proto ++ */ ++ return skb_vlan_tag_present(skb) ? skb->vlan_proto : skb->protocol; ++ ++ return vlan_get_protocol(skb); ++} ++ + static inline void vlan_set_encap_proto(struct sk_buff *skb, + struct vlan_hdr *vhdr) + { +diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h +index d30e4c869438c..09ed8a48b4548 100644 +--- a/include/net/inet_ecn.h ++++ b/include/net/inet_ecn.h +@@ -4,6 +4,7 @@ + + #include + #include ++#include + + #include + #include +-- +2.27.0 + -- 2.47.3