Commit 6f555635 authored by David S. Miller's avatar David S. Miller

Merge branch 'vxlan-gpe'

Jiri Benc says:

====================
vxlan: implement Generic Protocol Extension (GPE)

v3: just rebased on top of the current net-next, no changes

This patchset implements VXLAN-GPE. It follows the same model as the tun/tap
driver: depending on the chosen mode, the vxlan interface is created either
as ARPHRD_ETHER (non-GPE) or ARPHRD_NONE (GPE).

Note that the internal fdb control plane cannot be used together with
VXLAN-GPE and attempt to configure it will be rejected by the driver. In
fact, COLLECT_METADATA is required to be set for now. This can be relaxed in
the future by adding support for static PtP configuration; it will be
backward compatible and won't affect existing users.

The previous version of the patchset supported two GPE modes, L2 and L3. The
L2 mode (now called "ether mode" in the code) was removed from this version.
It can be easily added later if there's demand. The L3 mode is now called
"raw mode" and supports also encapsulated Ethernet headers (via ETH_P_TEB).

The only limitation of not having "ether mode" for GPE is for ip route based
encapsulation: with such setup, only IP packets can be encapsulated. Meaning
no Ethernet encapsulation. It seems there's not much use for this, though.
If it turns out to be useful, we'll add it.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 8a21ec4e e1e5314d
This diff is collapsed.
...@@ -295,8 +295,15 @@ static inline u8 ip_tunnel_ecn_encap(u8 tos, const struct iphdr *iph, ...@@ -295,8 +295,15 @@ static inline u8 ip_tunnel_ecn_encap(u8 tos, const struct iphdr *iph,
return INET_ECN_encapsulate(tos, inner); return INET_ECN_encapsulate(tos, inner);
} }
int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto, int __iptunnel_pull_header(struct sk_buff *skb, int hdr_len,
bool xnet); __be16 inner_proto, bool raw_proto, bool xnet);
static inline int iptunnel_pull_header(struct sk_buff *skb, int hdr_len,
__be16 inner_proto, bool xnet)
{
return __iptunnel_pull_header(skb, hdr_len, inner_proto, false, xnet);
}
void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb, void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
__be32 src, __be32 dst, u8 proto, __be32 src, __be32 dst, u8 proto,
u8 tos, u8 ttl, __be16 df, bool xnet); u8 tos, u8 ttl, __be16 df, bool xnet);
......
...@@ -119,6 +119,64 @@ struct vxlanhdr_gbp { ...@@ -119,6 +119,64 @@ struct vxlanhdr_gbp {
#define VXLAN_GBP_POLICY_APPLIED (BIT(3) << 16) #define VXLAN_GBP_POLICY_APPLIED (BIT(3) << 16)
#define VXLAN_GBP_ID_MASK (0xFFFF) #define VXLAN_GBP_ID_MASK (0xFFFF)
/*
* VXLAN Generic Protocol Extension (VXLAN_F_GPE):
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |R|R|Ver|I|P|R|O| Reserved |Next Protocol |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | VXLAN Network Identifier (VNI) | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* Ver = Version. Indicates VXLAN GPE protocol version.
*
* P = Next Protocol Bit. The P bit is set to indicate that the
* Next Protocol field is present.
*
* O = OAM Flag Bit. The O bit is set to indicate that the packet
* is an OAM packet.
*
* Next Protocol = This 8 bit field indicates the protocol header
* immediately following the VXLAN GPE header.
*
* https://tools.ietf.org/html/draft-ietf-nvo3-vxlan-gpe-01
*/
struct vxlanhdr_gpe {
#if defined(__LITTLE_ENDIAN_BITFIELD)
u8 oam_flag:1,
reserved_flags1:1,
np_applied:1,
instance_applied:1,
version:2,
reserved_flags2:2;
#elif defined(__BIG_ENDIAN_BITFIELD)
u8 reserved_flags2:2,
version:2,
instance_applied:1,
np_applied:1,
reserved_flags1:1,
oam_flag:1;
#endif
u8 reserved_flags3;
u8 reserved_flags4;
u8 next_protocol;
__be32 vx_vni;
};
/* VXLAN-GPE header flags. */
#define VXLAN_HF_VER cpu_to_be32(BIT(29) | BIT(28))
#define VXLAN_HF_NP cpu_to_be32(BIT(26))
#define VXLAN_HF_OAM cpu_to_be32(BIT(24))
#define VXLAN_GPE_USED_BITS (VXLAN_HF_VER | VXLAN_HF_NP | VXLAN_HF_OAM | \
cpu_to_be32(0xff))
/* VXLAN-GPE header Next Protocol. */
#define VXLAN_GPE_NP_IPV4 0x01
#define VXLAN_GPE_NP_IPV6 0x02
#define VXLAN_GPE_NP_ETHERNET 0x03
#define VXLAN_GPE_NP_NSH 0x04
struct vxlan_metadata { struct vxlan_metadata {
u32 gbp; u32 gbp;
}; };
...@@ -206,16 +264,26 @@ struct vxlan_dev { ...@@ -206,16 +264,26 @@ struct vxlan_dev {
#define VXLAN_F_GBP 0x800 #define VXLAN_F_GBP 0x800
#define VXLAN_F_REMCSUM_NOPARTIAL 0x1000 #define VXLAN_F_REMCSUM_NOPARTIAL 0x1000
#define VXLAN_F_COLLECT_METADATA 0x2000 #define VXLAN_F_COLLECT_METADATA 0x2000
#define VXLAN_F_GPE 0x4000
/* Flags that are used in the receive path. These flags must match in /* Flags that are used in the receive path. These flags must match in
* order for a socket to be shareable * order for a socket to be shareable
*/ */
#define VXLAN_F_RCV_FLAGS (VXLAN_F_GBP | \ #define VXLAN_F_RCV_FLAGS (VXLAN_F_GBP | \
VXLAN_F_GPE | \
VXLAN_F_UDP_ZERO_CSUM6_RX | \ VXLAN_F_UDP_ZERO_CSUM6_RX | \
VXLAN_F_REMCSUM_RX | \ VXLAN_F_REMCSUM_RX | \
VXLAN_F_REMCSUM_NOPARTIAL | \ VXLAN_F_REMCSUM_NOPARTIAL | \
VXLAN_F_COLLECT_METADATA) VXLAN_F_COLLECT_METADATA)
/* Flags that can be set together with VXLAN_F_GPE. */
#define VXLAN_F_ALLOWED_GPE (VXLAN_F_GPE | \
VXLAN_F_IPV6 | \
VXLAN_F_UDP_ZERO_CSUM_TX | \
VXLAN_F_UDP_ZERO_CSUM6_TX | \
VXLAN_F_UDP_ZERO_CSUM6_RX | \
VXLAN_F_COLLECT_METADATA)
struct net_device *vxlan_dev_create(struct net *net, const char *name, struct net_device *vxlan_dev_create(struct net *net, const char *name,
u8 name_assign_type, struct vxlan_config *conf); u8 name_assign_type, struct vxlan_config *conf);
......
...@@ -488,6 +488,7 @@ enum { ...@@ -488,6 +488,7 @@ enum {
IFLA_VXLAN_REMCSUM_NOPARTIAL, IFLA_VXLAN_REMCSUM_NOPARTIAL,
IFLA_VXLAN_COLLECT_METADATA, IFLA_VXLAN_COLLECT_METADATA,
IFLA_VXLAN_LABEL, IFLA_VXLAN_LABEL,
IFLA_VXLAN_GPE,
__IFLA_VXLAN_MAX __IFLA_VXLAN_MAX
}; };
#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1) #define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
......
...@@ -86,15 +86,15 @@ void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb, ...@@ -86,15 +86,15 @@ void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
} }
EXPORT_SYMBOL_GPL(iptunnel_xmit); EXPORT_SYMBOL_GPL(iptunnel_xmit);
int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto, int __iptunnel_pull_header(struct sk_buff *skb, int hdr_len,
bool xnet) __be16 inner_proto, bool raw_proto, bool xnet)
{ {
if (unlikely(!pskb_may_pull(skb, hdr_len))) if (unlikely(!pskb_may_pull(skb, hdr_len)))
return -ENOMEM; return -ENOMEM;
skb_pull_rcsum(skb, hdr_len); skb_pull_rcsum(skb, hdr_len);
if (inner_proto == htons(ETH_P_TEB)) { if (!raw_proto && inner_proto == htons(ETH_P_TEB)) {
struct ethhdr *eh; struct ethhdr *eh;
if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
...@@ -117,7 +117,7 @@ int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto, ...@@ -117,7 +117,7 @@ int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto,
return iptunnel_pull_offloads(skb); return iptunnel_pull_offloads(skb);
} }
EXPORT_SYMBOL_GPL(iptunnel_pull_header); EXPORT_SYMBOL_GPL(__iptunnel_pull_header);
struct metadata_dst *iptunnel_metadata_reply(struct metadata_dst *md, struct metadata_dst *iptunnel_metadata_reply(struct metadata_dst *md,
gfp_t flags) gfp_t flags)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment