ip_tunnel: add mpls over gre support
authorAmine Kherbouche <amine.kherbouche@6wind.com>
Wed, 4 Oct 2017 17:35:57 +0000 (19:35 +0200)
committerDavid S. Miller <davem@davemloft.net>
Sat, 7 Oct 2017 20:38:31 +0000 (21:38 +0100)
This commit introduces the MPLSoGRE support (RFC 4023), using ip tunnel
API by simply adding ipgre_tunnel_encap_(add|del)_mpls_ops() and the new
tunnel type TUNNEL_ENCAP_MPLS.

Signed-off-by: Amine Kherbouche <amine.kherbouche@6wind.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/uapi/linux/if_tunnel.h
net/mpls/af_mpls.c

index 2e52088..a2f48c0 100644 (file)
@@ -84,6 +84,7 @@ enum tunnel_encap_types {
        TUNNEL_ENCAP_NONE,
        TUNNEL_ENCAP_FOU,
        TUNNEL_ENCAP_GUE,
+       TUNNEL_ENCAP_MPLS,
 };
 
 #define TUNNEL_ENCAP_FLAG_CSUM         (1<<0)
index c5b9ce4..9745e8f 100644 (file)
@@ -16,6 +16,7 @@
 #include <net/arp.h>
 #include <net/ip_fib.h>
 #include <net/netevent.h>
+#include <net/ip_tunnels.h>
 #include <net/netns/generic.h>
 #if IS_ENABLED(CONFIG_IPV6)
 #include <net/ipv6.h>
@@ -39,6 +40,36 @@ static int one = 1;
 static int label_limit = (1 << 20) - 1;
 static int ttl_max = 255;
 
+#if IS_ENABLED(CONFIG_NET_IP_TUNNEL)
+size_t ipgre_mpls_encap_hlen(struct ip_tunnel_encap *e)
+{
+       return sizeof(struct mpls_shim_hdr);
+}
+
+static const struct ip_tunnel_encap_ops mpls_iptun_ops = {
+       .encap_hlen     = ipgre_mpls_encap_hlen,
+};
+
+static int ipgre_tunnel_encap_add_mpls_ops(void)
+{
+       return ip_tunnel_encap_add_ops(&mpls_iptun_ops, TUNNEL_ENCAP_MPLS);
+}
+
+static void ipgre_tunnel_encap_del_mpls_ops(void)
+{
+       ip_tunnel_encap_del_ops(&mpls_iptun_ops, TUNNEL_ENCAP_MPLS);
+}
+#else
+static int ipgre_tunnel_encap_add_mpls_ops(void)
+{
+       return 0;
+}
+
+static void ipgre_tunnel_encap_del_mpls_ops(void)
+{
+}
+#endif
+
 static void rtmsg_lfib(int event, u32 label, struct mpls_route *rt,
                       struct nlmsghdr *nlh, struct net *net, u32 portid,
                       unsigned int nlm_flags);
@@ -2485,6 +2516,10 @@ static int __init mpls_init(void)
                      0);
        rtnl_register(PF_MPLS, RTM_GETNETCONF, mpls_netconf_get_devconf,
                      mpls_netconf_dump_devconf, 0);
+       err = ipgre_tunnel_encap_add_mpls_ops();
+       if (err)
+               pr_err("Can't add mpls over gre tunnel ops\n");
+
        err = 0;
 out:
        return err;
@@ -2502,6 +2537,7 @@ static void __exit mpls_exit(void)
        dev_remove_pack(&mpls_packet_type);
        unregister_netdevice_notifier(&mpls_dev_notifier);
        unregister_pernet_subsys(&mpls_net_ops);
+       ipgre_tunnel_encap_del_mpls_ops();
 }
 module_exit(mpls_exit);