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

Commit 1d8fff90 authored by Thomas Graf's avatar Thomas Graf Committed by David S. Miller
Browse files

ip_tunnel: Make ovs_tunnel_info and ovs_key_ipv4_tunnel generic



Rename the tunnel metadata data structures currently internal to
OVS and make them generic for use by all IP tunnels.

Both structures are kernel internal and will stay that way. Their
members are exposed to user space through individual Netlink
attributes by OVS. It will therefore be possible to extend/modify
these structures without affecting user ABI.

Signed-off-by: default avatarThomas Graf <tgraf@suug.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e3e4712e
Loading
Loading
Loading
Loading
+63 −0
Original line number Diff line number Diff line
@@ -22,6 +22,28 @@
/* Keep error state on tunnel for 30 sec */
#define IPTUNNEL_ERR_TIMEO	(30*HZ)

/* Used to memset ip_tunnel padding. */
#define IP_TUNNEL_KEY_SIZE					\
	(offsetof(struct ip_tunnel_key, tp_dst) +		\
	 FIELD_SIZEOF(struct ip_tunnel_key, tp_dst))

struct ip_tunnel_key {
	__be64			tun_id;
	__be32			ipv4_src;
	__be32			ipv4_dst;
	__be16			tun_flags;
	__u8			ipv4_tos;
	__u8			ipv4_ttl;
	__be16			tp_src;
	__be16			tp_dst;
} __packed __aligned(4); /* Minimize padding. */

struct ip_tunnel_info {
	struct ip_tunnel_key	key;
	const void		*options;
	u8			options_len;
};

/* 6rd prefix/relay information */
#ifdef CONFIG_IPV6_SIT_6RD
struct ip_tunnel_6rd_parm {
@@ -136,6 +158,47 @@ int ip_tunnel_encap_add_ops(const struct ip_tunnel_encap_ops *op,
int ip_tunnel_encap_del_ops(const struct ip_tunnel_encap_ops *op,
			    unsigned int num);

static inline void __ip_tunnel_info_init(struct ip_tunnel_info *tun_info,
					 __be32 saddr, __be32 daddr,
					 u8 tos, u8 ttl,
					 __be16 tp_src, __be16 tp_dst,
					 __be64 tun_id, __be16 tun_flags,
					 const void *opts, u8 opts_len)
{
	tun_info->key.tun_id = tun_id;
	tun_info->key.ipv4_src = saddr;
	tun_info->key.ipv4_dst = daddr;
	tun_info->key.ipv4_tos = tos;
	tun_info->key.ipv4_ttl = ttl;
	tun_info->key.tun_flags = tun_flags;

	/* For the tunnel types on the top of IPsec, the tp_src and tp_dst of
	 * the upper tunnel are used.
	 * E.g: GRE over IPSEC, the tp_src and tp_port are zero.
	 */
	tun_info->key.tp_src = tp_src;
	tun_info->key.tp_dst = tp_dst;

	/* Clear struct padding. */
	if (sizeof(tun_info->key) != IP_TUNNEL_KEY_SIZE)
		memset((unsigned char *)&tun_info->key + IP_TUNNEL_KEY_SIZE,
		       0, sizeof(tun_info->key) - IP_TUNNEL_KEY_SIZE);

	tun_info->options = opts;
	tun_info->options_len = opts_len;
}

static inline void ip_tunnel_info_init(struct ip_tunnel_info *tun_info,
				       const struct iphdr *iph,
				       __be16 tp_src, __be16 tp_dst,
				       __be64 tun_id, __be16 tun_flags,
				       const void *opts, u8 opts_len)
{
	__ip_tunnel_info_init(tun_info, iph->saddr, iph->daddr,
			      iph->tos, iph->ttl, tp_src, tp_dst,
			      tun_id, tun_flags, opts, opts_len);
}

#ifdef CONFIG_INET

int ip_tunnel_init(struct net_device *dev);
+1 −1
Original line number Diff line number Diff line
@@ -321,7 +321,7 @@ enum ovs_key_attr {
				 * the accepted length of the array. */

#ifdef __KERNEL__
	OVS_KEY_ATTR_TUNNEL_INFO,  /* struct ovs_tunnel_info */
	OVS_KEY_ATTR_TUNNEL_INFO,  /* struct ip_tunnel_info */
#endif
	__OVS_KEY_ATTR_MAX
};
+1 −1
Original line number Diff line number Diff line
@@ -611,7 +611,7 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb,
			    struct sw_flow_key *key, const struct nlattr *attr,
			    const struct nlattr *actions, int actions_len)
{
	struct ovs_tunnel_info info;
	struct ip_tunnel_info info;
	struct dp_upcall_info upcall;
	const struct nlattr *a;
	int rem;
+3 −2
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/u64_stats_sync.h>
#include <net/ip_tunnels.h>

#include "flow.h"
#include "flow_table.h"
@@ -98,7 +99,7 @@ struct datapath {
 * when a packet is received by OVS.
 */
struct ovs_skb_cb {
	struct ovs_tunnel_info  *egress_tun_info;
	struct ip_tunnel_info  *egress_tun_info;
	struct vport		*input_vport;
};
#define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb)
@@ -114,7 +115,7 @@ struct ovs_skb_cb {
 * @egress_tun_info: If nonnull, becomes %OVS_PACKET_ATTR_EGRESS_TUN_KEY.
 */
struct dp_upcall_info {
	const struct ovs_tunnel_info *egress_tun_info;
	const struct ip_tunnel_info *egress_tun_info;
	const struct nlattr *userdata;
	const struct nlattr *actions;
	int actions_len;
+2 −2
Original line number Diff line number Diff line
@@ -682,12 +682,12 @@ int ovs_flow_key_update(struct sk_buff *skb, struct sw_flow_key *key)
	return key_extract(skb, key);
}

int ovs_flow_key_extract(const struct ovs_tunnel_info *tun_info,
int ovs_flow_key_extract(const struct ip_tunnel_info *tun_info,
			 struct sk_buff *skb, struct sw_flow_key *key)
{
	/* Extract metadata from packet. */
	if (tun_info) {
		memcpy(&key->tun_key, &tun_info->tunnel, sizeof(key->tun_key));
		memcpy(&key->tun_key, &tun_info->key, sizeof(key->tun_key));

		if (tun_info->options) {
			BUILD_BUG_ON((1 << (sizeof(tun_info->options_len) *
Loading