diff options
author | Guillaume Nault <gnault@redhat.com> | 2021-06-25 15:33:08 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-06-28 12:44:17 -0700 |
commit | 730eed2772e740c30229d03e3d578cc00a5ae304 (patch) | |
tree | 9a2cb74aaa158dab88e2dfb5d31f684bdee20cf4 /net/ipv6 | |
parent | 7ad136fd288c0e0177eb29e04ec289e1b873b270 (diff) | |
download | linux-stable-730eed2772e740c30229d03e3d578cc00a5ae304.tar.gz linux-stable-730eed2772e740c30229d03e3d578cc00a5ae304.tar.bz2 linux-stable-730eed2772e740c30229d03e3d578cc00a5ae304.zip |
sit: allow redirecting ip6ip, ipip and mplsip packets to eth devices
Even though sit transports L3 data (IPv6, IPv4 or MPLS) packets, it
needs to reset the mac_header pointer, so that other parts of the stack
don't mistakenly access the outer header after the packet has been
decapsulated. There are two rx handlers to modify: ipip6_rcv() for the
ip6ip mode and sit_tunnel_rcv() which is used to re-implement the ipip
and mplsip modes of ipip.ko.
This allows to push an Ethernet header to sit packets and redirect
them to an Ethernet device:
$ tc filter add dev sit0 ingress matchall \
action vlan push_eth dst_mac 00:00:5e:00:53:01 \
src_mac 00:00:5e:00:53:00 \
action mirred egress redirect dev eth0
Without this patch, push_eth refuses to add an ethernet header because
the skb appears to already have a MAC header.
Signed-off-by: Guillaume Nault <gnault@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/sit.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index e0a39b0bb4c1..df5bea818410 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -710,6 +710,8 @@ static int ipip6_rcv(struct sk_buff *skb) * old iph is no longer valid */ iph = (const struct iphdr *)skb_mac_header(skb); + skb_reset_mac_header(skb); + err = IP_ECN_decapsulate(iph, skb); if (unlikely(err)) { if (log_ecn_error) @@ -780,6 +782,8 @@ static int sit_tunnel_rcv(struct sk_buff *skb, u8 ipproto) tpi = &ipip_tpi; if (iptunnel_pull_header(skb, 0, tpi->proto, false)) goto drop; + skb_reset_mac_header(skb); + return ip_tunnel_rcv(tunnel, skb, tpi, NULL, log_ecn_error); } |