Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 499a2425 authored by Roopa Prabhu's avatar Roopa Prabhu Committed by David S. Miller
Browse files

lwtunnel: infrastructure for handling light weight tunnels like mpls



Provides infrastructure to parse/dump/store encap information for
light weight tunnels like mpls. Encap information for such tunnels
is associated with fib routes.

This infrastructure is based on previous suggestions from
Eric Biederman to follow the xfrm infrastructure.

Signed-off-by: default avatarRoopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a0d9a860
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
#ifndef _LINUX_LWTUNNEL_H_
#define _LINUX_LWTUNNEL_H_

#include <uapi/linux/lwtunnel.h>

#endif /* _LINUX_LWTUNNEL_H_ */

include/net/lwtunnel.h

0 → 100644
+132 −0
Original line number Diff line number Diff line
#ifndef __NET_LWTUNNEL_H
#define __NET_LWTUNNEL_H 1

#include <linux/lwtunnel.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/types.h>
#include <net/route.h>

#define LWTUNNEL_HASH_BITS   7
#define LWTUNNEL_HASH_SIZE   (1 << LWTUNNEL_HASH_BITS)

/* lw tunnel state flags */
#define LWTUNNEL_STATE_OUTPUT_REDIRECT 0x1

struct lwtunnel_state {
	__u16		type;
	__u16		flags;
	atomic_t	refcnt;
	int             len;
	__u8            data[0];
};

struct lwtunnel_encap_ops {
	int (*build_state)(struct net_device *dev, struct nlattr *encap,
			   struct lwtunnel_state **ts);
	int (*output)(struct sock *sk, struct sk_buff *skb);
	int (*fill_encap)(struct sk_buff *skb,
			  struct lwtunnel_state *lwtstate);
	int (*get_encap_size)(struct lwtunnel_state *lwtstate);
	int (*cmp_encap)(struct lwtunnel_state *a, struct lwtunnel_state *b);
};

extern const struct lwtunnel_encap_ops __rcu *
		lwtun_encaps[LWTUNNEL_ENCAP_MAX+1];

#ifdef CONFIG_LWTUNNEL
static inline void lwtunnel_state_get(struct lwtunnel_state *lws)
{
	atomic_inc(&lws->refcnt);
}

static inline void lwtunnel_state_put(struct lwtunnel_state *lws)
{
	if (!lws)
		return;

	if (atomic_dec_and_test(&lws->refcnt))
		kfree(lws);
}

static inline bool lwtunnel_output_redirect(struct lwtunnel_state *lwtstate)
{
	if (lwtstate && (lwtstate->flags & LWTUNNEL_STATE_OUTPUT_REDIRECT))
		return true;

	return false;
}

int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *op,
			   unsigned int num);
int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
			   unsigned int num);
int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
			 struct nlattr *encap,
			 struct lwtunnel_state **lws);
int lwtunnel_fill_encap(struct sk_buff *skb,
			struct lwtunnel_state *lwtstate);
int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate);
struct lwtunnel_state *lwtunnel_state_alloc(int hdr_len);
int lwtunnel_cmp_encap(struct lwtunnel_state *a, struct lwtunnel_state *b);

#else

static inline void lwtunnel_state_get(struct lwtunnel_state *lws)
{
}

static inline void lwtunnel_state_put(struct lwtunnel_state *lws)
{
}

static inline bool lwtunnel_output_redirect(struct lwtunnel_state *lwtstate)
{
	return false;
}

static inline int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *op,
					 unsigned int num)
{
	return -EOPNOTSUPP;

}

static inline int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
					 unsigned int num)
{
	return -EOPNOTSUPP;
}

static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
				       struct nlattr *encap,
				       struct lwtunnel_state **lws)
{
	return -EOPNOTSUPP;
}

static inline int lwtunnel_fill_encap(struct sk_buff *skb,
				      struct lwtunnel_state *lwtstate)
{
	return 0;
}

static inline int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate)
{
	return 0;
}

static inline struct lwtunnel_state *lwtunnel_state_alloc(int hdr_len)
{
	return NULL;
}

static inline int lwtunnel_cmp_encap(struct lwtunnel_state *a,
				     struct lwtunnel_state *b)
{
	return 0;
}

#endif

#endif /* __NET_LWTUNNEL_H */
+15 −0
Original line number Diff line number Diff line
#ifndef _UAPI_LWTUNNEL_H_
#define _UAPI_LWTUNNEL_H_

#include <linux/types.h>

enum lwtunnel_encap_types {
	LWTUNNEL_ENCAP_NONE,
	LWTUNNEL_ENCAP_MPLS,
	__LWTUNNEL_ENCAP_MAX,
};

#define LWTUNNEL_ENCAP_MAX (__LWTUNNEL_ENCAP_MAX - 1)


#endif /* _UAPI_LWTUNNEL_H_ */
+7 −0
Original line number Diff line number Diff line
@@ -374,6 +374,13 @@ source "net/caif/Kconfig"
source "net/ceph/Kconfig"
source "net/nfc/Kconfig"

config LWTUNNEL
	bool "Network light weight tunnels"
	---help---
	  This feature provides an infrastructure to support light weight
	  tunnels like mpls. There is no netdevice associated with a light
	  weight tunnel endpoint. Tunnel encapsulation parameters are stored
	  with light weight tunnel state associated with fib routes.

endif   # if NET

+1 −0
Original line number Diff line number Diff line
@@ -23,3 +23,4 @@ obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += timestamping.o
obj-$(CONFIG_NET_PTP_CLASSIFY) += ptp_classifier.o
obj-$(CONFIG_CGROUP_NET_PRIO) += netprio_cgroup.o
obj-$(CONFIG_CGROUP_NET_CLASSID) += netclassid_cgroup.o
obj-$(CONFIG_LWTUNNEL) += lwtunnel.o
Loading