]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/ipv4/ip_vti.c
Merge v5.4-rc4 into drm-next
[linux.git] / net / ipv4 / ip_vti.c
index 35d8346742e2cc2bd7dd242501870a7681da0f96..cfb0256067936839888b9c910997ff1a784021d1 100644 (file)
@@ -1,15 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  *     Linux NET3: IP/IP protocol decoder modified to support
  *                 virtual tunnel interface
  *
  *     Authors:
  *             Saurabh Mohan (saurabh.mohan@vyatta.com) 05/07/2012
- *
- *     This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     as published by the Free Software Foundation; either version
- *     2 of the License, or (at your option) any later version.
- *
  */
 
 /*
@@ -50,7 +45,7 @@ static unsigned int vti_net_id __read_mostly;
 static int vti_tunnel_init(struct net_device *dev);
 
 static int vti_input(struct sk_buff *skb, int nexthdr, __be32 spi,
-                    int encap_type)
+                    int encap_type, bool update_skb_dev)
 {
        struct ip_tunnel *tunnel;
        const struct iphdr *iph = ip_hdr(skb);
@@ -65,6 +60,9 @@ static int vti_input(struct sk_buff *skb, int nexthdr, __be32 spi,
 
                XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = tunnel;
 
+               if (update_skb_dev)
+                       skb->dev = tunnel->dev;
+
                return xfrm_input(skb, nexthdr, spi, encap_type);
        }
 
@@ -74,47 +72,28 @@ static int vti_input(struct sk_buff *skb, int nexthdr, __be32 spi,
        return 0;
 }
 
-static int vti_input_ipip(struct sk_buff *skb, int nexthdr, __be32 spi,
-                    int encap_type)
+static int vti_input_proto(struct sk_buff *skb, int nexthdr, __be32 spi,
+                          int encap_type)
 {
-       struct ip_tunnel *tunnel;
-       const struct iphdr *iph = ip_hdr(skb);
-       struct net *net = dev_net(skb->dev);
-       struct ip_tunnel_net *itn = net_generic(net, vti_net_id);
-
-       tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY,
-                                 iph->saddr, iph->daddr, 0);
-       if (tunnel) {
-               if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
-                       goto drop;
-
-               XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = tunnel;
-
-               skb->dev = tunnel->dev;
-
-               return xfrm_input(skb, nexthdr, spi, encap_type);
-       }
-
-       return -EINVAL;
-drop:
-       kfree_skb(skb);
-       return 0;
+       return vti_input(skb, nexthdr, spi, encap_type, false);
 }
 
-static int vti_rcv(struct sk_buff *skb)
+static int vti_rcv(struct sk_buff *skb, __be32 spi, bool update_skb_dev)
 {
        XFRM_SPI_SKB_CB(skb)->family = AF_INET;
        XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
 
-       return vti_input(skb, ip_hdr(skb)->protocol, 0, 0);
+       return vti_input(skb, ip_hdr(skb)->protocol, spi, 0, update_skb_dev);
 }
 
-static int vti_rcv_ipip(struct sk_buff *skb)
+static int vti_rcv_proto(struct sk_buff *skb)
 {
-       XFRM_SPI_SKB_CB(skb)->family = AF_INET;
-       XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
+       return vti_rcv(skb, 0, false);
+}
 
-       return vti_input_ipip(skb, ip_hdr(skb)->protocol, ip_hdr(skb)->saddr, 0);
+static int vti_rcv_tunnel(struct sk_buff *skb)
+{
+       return vti_rcv(skb, ip_hdr(skb)->saddr, true);
 }
 
 static int vti_rcv_cb(struct sk_buff *skb, int err)
@@ -123,7 +102,7 @@ static int vti_rcv_cb(struct sk_buff *skb, int err)
        struct net_device *dev;
        struct pcpu_sw_netstats *tstats;
        struct xfrm_state *x;
-       struct xfrm_mode *inner_mode;
+       const struct xfrm_mode *inner_mode;
        struct ip_tunnel *tunnel = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4;
        u32 orig_mark = skb->mark;
        int ret;
@@ -142,7 +121,7 @@ static int vti_rcv_cb(struct sk_buff *skb, int err)
 
        x = xfrm_input_state(skb);
 
-       inner_mode = x->inner_mode;
+       inner_mode = &x->inner_mode;
 
        if (x->sel.family == AF_UNSPEC) {
                inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol);
@@ -153,7 +132,7 @@ static int vti_rcv_cb(struct sk_buff *skb, int err)
                }
        }
 
-       family = inner_mode->afinfo->family;
+       family = inner_mode->family;
 
        skb->mark = be32_to_cpu(tunnel->parms.i_key);
        ret = xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family);
@@ -447,31 +426,31 @@ static void __net_init vti_fb_tunnel_init(struct net_device *dev)
 }
 
 static struct xfrm4_protocol vti_esp4_protocol __read_mostly = {
-       .handler        =       vti_rcv,
-       .input_handler  =       vti_input,
+       .handler        =       vti_rcv_proto,
+       .input_handler  =       vti_input_proto,
        .cb_handler     =       vti_rcv_cb,
        .err_handler    =       vti4_err,
        .priority       =       100,
 };
 
 static struct xfrm4_protocol vti_ah4_protocol __read_mostly = {
-       .handler        =       vti_rcv,
-       .input_handler  =       vti_input,
+       .handler        =       vti_rcv_proto,
+       .input_handler  =       vti_input_proto,
        .cb_handler     =       vti_rcv_cb,
        .err_handler    =       vti4_err,
        .priority       =       100,
 };
 
 static struct xfrm4_protocol vti_ipcomp4_protocol __read_mostly = {
-       .handler        =       vti_rcv,
-       .input_handler  =       vti_input,
+       .handler        =       vti_rcv_proto,
+       .input_handler  =       vti_input_proto,
        .cb_handler     =       vti_rcv_cb,
        .err_handler    =       vti4_err,
        .priority       =       100,
 };
 
 static struct xfrm_tunnel ipip_handler __read_mostly = {
-       .handler        =       vti_rcv_ipip,
+       .handler        =       vti_rcv_tunnel,
        .err_handler    =       vti4_err,
        .priority       =       0,
 };