aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/uapi/linux/if_tunnel.h1
-rw-r--r--net/mpls/af_mpls.c36
2 files changed, 37 insertions, 0 deletions
diff --git a/include/uapi/linux/if_tunnel.h b/include/uapi/linux/if_tunnel.h
index 2e520883c054..a2f48c01365e 100644
--- a/include/uapi/linux/if_tunnel.h
+++ b/include/uapi/linux/if_tunnel.h
@@ -84,6 +84,7 @@ enum tunnel_encap_types {
84 TUNNEL_ENCAP_NONE, 84 TUNNEL_ENCAP_NONE,
85 TUNNEL_ENCAP_FOU, 85 TUNNEL_ENCAP_FOU,
86 TUNNEL_ENCAP_GUE, 86 TUNNEL_ENCAP_GUE,
87 TUNNEL_ENCAP_MPLS,
87}; 88};
88 89
89#define TUNNEL_ENCAP_FLAG_CSUM (1<<0) 90#define TUNNEL_ENCAP_FLAG_CSUM (1<<0)
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
index c5b9ce41d66f..9745e8f69810 100644
--- a/net/mpls/af_mpls.c
+++ b/net/mpls/af_mpls.c
@@ -16,6 +16,7 @@
16#include <net/arp.h> 16#include <net/arp.h>
17#include <net/ip_fib.h> 17#include <net/ip_fib.h>
18#include <net/netevent.h> 18#include <net/netevent.h>
19#include <net/ip_tunnels.h>
19#include <net/netns/generic.h> 20#include <net/netns/generic.h>
20#if IS_ENABLED(CONFIG_IPV6) 21#if IS_ENABLED(CONFIG_IPV6)
21#include <net/ipv6.h> 22#include <net/ipv6.h>
@@ -39,6 +40,36 @@ static int one = 1;
39static int label_limit = (1 << 20) - 1; 40static int label_limit = (1 << 20) - 1;
40static int ttl_max = 255; 41static int ttl_max = 255;
41 42
43#if IS_ENABLED(CONFIG_NET_IP_TUNNEL)
44size_t ipgre_mpls_encap_hlen(struct ip_tunnel_encap *e)
45{
46 return sizeof(struct mpls_shim_hdr);
47}
48
49static const struct ip_tunnel_encap_ops mpls_iptun_ops = {
50 .encap_hlen = ipgre_mpls_encap_hlen,
51};
52
53static int ipgre_tunnel_encap_add_mpls_ops(void)
54{
55 return ip_tunnel_encap_add_ops(&mpls_iptun_ops, TUNNEL_ENCAP_MPLS);
56}
57
58static void ipgre_tunnel_encap_del_mpls_ops(void)
59{
60 ip_tunnel_encap_del_ops(&mpls_iptun_ops, TUNNEL_ENCAP_MPLS);
61}
62#else
63static int ipgre_tunnel_encap_add_mpls_ops(void)
64{
65 return 0;
66}
67
68static void ipgre_tunnel_encap_del_mpls_ops(void)
69{
70}
71#endif
72
42static void rtmsg_lfib(int event, u32 label, struct mpls_route *rt, 73static void rtmsg_lfib(int event, u32 label, struct mpls_route *rt,
43 struct nlmsghdr *nlh, struct net *net, u32 portid, 74 struct nlmsghdr *nlh, struct net *net, u32 portid,
44 unsigned int nlm_flags); 75 unsigned int nlm_flags);
@@ -2485,6 +2516,10 @@ static int __init mpls_init(void)
2485 0); 2516 0);
2486 rtnl_register(PF_MPLS, RTM_GETNETCONF, mpls_netconf_get_devconf, 2517 rtnl_register(PF_MPLS, RTM_GETNETCONF, mpls_netconf_get_devconf,
2487 mpls_netconf_dump_devconf, 0); 2518 mpls_netconf_dump_devconf, 0);
2519 err = ipgre_tunnel_encap_add_mpls_ops();
2520 if (err)
2521 pr_err("Can't add mpls over gre tunnel ops\n");
2522
2488 err = 0; 2523 err = 0;
2489out: 2524out:
2490 return err; 2525 return err;
@@ -2502,6 +2537,7 @@ static void __exit mpls_exit(void)
2502 dev_remove_pack(&mpls_packet_type); 2537 dev_remove_pack(&mpls_packet_type);
2503 unregister_netdevice_notifier(&mpls_dev_notifier); 2538 unregister_netdevice_notifier(&mpls_dev_notifier);
2504 unregister_pernet_subsys(&mpls_net_ops); 2539 unregister_pernet_subsys(&mpls_net_ops);
2540 ipgre_tunnel_encap_del_mpls_ops();
2505} 2541}
2506module_exit(mpls_exit); 2542module_exit(mpls_exit);
2507 2543