| From ee201011c1e1563c114a55c86eb164b236f18e84 Mon Sep 17 00:00:00 2001 |
| From: Stephen Suryaputra <ssuryaextr@gmail.com> |
| Date: Tue, 30 Nov 2021 11:26:37 -0500 |
| Subject: vrf: Reset IPCB/IP6CB when processing outbound pkts in vrf dev xmit |
| |
| From: Stephen Suryaputra <ssuryaextr@gmail.com> |
| |
| commit ee201011c1e1563c114a55c86eb164b236f18e84 upstream. |
| |
| IPCB/IP6CB need to be initialized when processing outbound v4 or v6 pkts |
| in the codepath of vrf device xmit function so that leftover garbage |
| doesn't cause futher code that uses the CB to incorrectly process the |
| pkt. |
| |
| One occasion of the issue might occur when MPLS route uses the vrf |
| device as the outgoing device such as when the route is added using "ip |
| -f mpls route add <label> dev <vrf>" command. |
| |
| The problems seems to exist since day one. Hence I put the day one |
| commits on the Fixes tags. |
| |
| Fixes: 193125dbd8eb ("net: Introduce VRF device driver") |
| Fixes: 35402e313663 ("net: Add IPv6 support to VRF device") |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Stephen Suryaputra <ssuryaextr@gmail.com> |
| Reviewed-by: David Ahern <dsahern@kernel.org> |
| Link: https://lore.kernel.org/r/20211130162637.3249-1-ssuryaextr@gmail.com |
| Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/net/vrf.c | 2 ++ |
| 1 file changed, 2 insertions(+) |
| |
| --- a/drivers/net/vrf.c |
| +++ b/drivers/net/vrf.c |
| @@ -497,6 +497,7 @@ static netdev_tx_t vrf_process_v6_outbou |
| /* strip the ethernet header added for pass through VRF device */ |
| __skb_pull(skb, skb_network_offset(skb)); |
| |
| + memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); |
| ret = vrf_ip6_local_out(net, skb->sk, skb); |
| if (unlikely(net_xmit_eval(ret))) |
| dev->stats.tx_errors++; |
| @@ -580,6 +581,7 @@ static netdev_tx_t vrf_process_v4_outbou |
| RT_SCOPE_LINK); |
| } |
| |
| + memset(IPCB(skb), 0, sizeof(*IPCB(skb))); |
| ret = vrf_ip_local_out(dev_net(skb_dst(skb)->dev), skb->sk, skb); |
| if (unlikely(net_xmit_eval(ret))) |
| vrf_dev->stats.tx_errors++; |