cfd6b1457c0e2cbfd294bcdf7e249a194d049360
[openwrt/staging/981213.git] /
1 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2 From: "Jason A. Donenfeld" <Jason@zx2c4.com>
3 Date: Mon, 29 Jun 2020 19:06:18 -0600
4 Subject: [PATCH] net: ip_tunnel: add header_ops for layer 3 devices
5
6 commit 2606aff916854b61234bf85001be9777bab2d5f8 upstream.
7
8 Some devices that take straight up layer 3 packets benefit from having a
9 shared header_ops so that AF_PACKET sockets can inject packets that are
10 recognized. This shared infrastructure will be used by other drivers
11 that currently can't inject packets using AF_PACKET. It also exposes the
12 parser function, as it is useful in standalone form too.
13
14 Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
15 Acked-by: Willem de Bruijn <willemb@google.com>
16 Signed-off-by: David S. Miller <davem@davemloft.net>
17 Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
18 ---
19 include/net/ip_tunnels.h | 3 +++
20 net/ipv4/ip_tunnel_core.c | 18 ++++++++++++++++++
21 2 files changed, 21 insertions(+)
22
23 --- a/include/net/ip_tunnels.h
24 +++ b/include/net/ip_tunnels.h
25 @@ -289,6 +289,9 @@ int ip_tunnel_newlink(struct net_device
26 struct ip_tunnel_parm *p, __u32 fwmark);
27 void ip_tunnel_setup(struct net_device *dev, unsigned int net_id);
28
29 +extern const struct header_ops ip_tunnel_header_ops;
30 +__be16 ip_tunnel_parse_protocol(const struct sk_buff *skb);
31 +
32 struct ip_tunnel_encap_ops {
33 size_t (*encap_hlen)(struct ip_tunnel_encap *e);
34 int (*build_header)(struct sk_buff *skb, struct ip_tunnel_encap *e,
35 --- a/net/ipv4/ip_tunnel_core.c
36 +++ b/net/ipv4/ip_tunnel_core.c
37 @@ -446,3 +446,21 @@ void ip_tunnel_unneed_metadata(void)
38 static_branch_dec(&ip_tunnel_metadata_cnt);
39 }
40 EXPORT_SYMBOL_GPL(ip_tunnel_unneed_metadata);
41 +
42 +/* Returns either the correct skb->protocol value, or 0 if invalid. */
43 +__be16 ip_tunnel_parse_protocol(const struct sk_buff *skb)
44 +{
45 + if (skb_network_header(skb) >= skb->head &&
46 + (skb_network_header(skb) + sizeof(struct iphdr)) <= skb_tail_pointer(skb) &&
47 + ip_hdr(skb)->version == 4)
48 + return htons(ETH_P_IP);
49 + if (skb_network_header(skb) >= skb->head &&
50 + (skb_network_header(skb) + sizeof(struct ipv6hdr)) <= skb_tail_pointer(skb) &&
51 + ipv6_hdr(skb)->version == 6)
52 + return htons(ETH_P_IPV6);
53 + return 0;
54 +}
55 +EXPORT_SYMBOL(ip_tunnel_parse_protocol);
56 +
57 +const struct header_ops ip_tunnel_header_ops = { .parse_protocol = ip_tunnel_parse_protocol };
58 +EXPORT_SYMBOL(ip_tunnel_header_ops);