Merge branch 'drm-rockchip-next-fixes-2016-03-28' of https://github.com/markyzq/kerne...
[deliverable/linux.git] / include / net / vxlan.h
index 0fb86442544b26627fb5871f26d1ede748f9d6d9..73ed2e951c020d28c21457d907c55764ea7b3d88 100644 (file)
@@ -9,17 +9,71 @@
 #include <linux/udp.h>
 #include <net/dst_metadata.h>
 
+/* VXLAN protocol (RFC 7348) header:
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |R|R|R|R|I|R|R|R|               Reserved                        |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                VXLAN Network Identifier (VNI) |   Reserved    |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * I = VXLAN Network Identifier (VNI) present.
+ */
+struct vxlanhdr {
+       __be32 vx_flags;
+       __be32 vx_vni;
+};
+
+/* VXLAN header flags. */
+#define VXLAN_HF_VNI   cpu_to_be32(BIT(27))
+
+#define VXLAN_N_VID     (1u << 24)
+#define VXLAN_VID_MASK  (VXLAN_N_VID - 1)
+#define VXLAN_VNI_MASK cpu_to_be32(VXLAN_VID_MASK << 8)
+#define VXLAN_HLEN (sizeof(struct udphdr) + sizeof(struct vxlanhdr))
+
 #define VNI_HASH_BITS  10
 #define VNI_HASH_SIZE  (1<<VNI_HASH_BITS)
+#define FDB_HASH_BITS  8
+#define FDB_HASH_SIZE  (1<<FDB_HASH_BITS)
+
+/* Remote checksum offload for VXLAN (VXLAN_F_REMCSUM_[RT]X):
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |R|R|R|R|I|R|R|R|R|R|C|              Reserved                   |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |           VXLAN Network Identifier (VNI)      |O| Csum start  |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * C = Remote checksum offload bit. When set indicates that the
+ *     remote checksum offload data is present.
+ *
+ * O = Offset bit. Indicates the checksum offset relative to
+ *     checksum start.
+ *
+ * Csum start = Checksum start divided by two.
+ *
+ * http://tools.ietf.org/html/draft-herbert-vxlan-rco
+ */
+
+/* VXLAN-RCO header flags. */
+#define VXLAN_HF_RCO   cpu_to_be32(BIT(21))
+
+/* Remote checksum offload header option */
+#define VXLAN_RCO_MASK cpu_to_be32(0x7f)  /* Last byte of vni field */
+#define VXLAN_RCO_UDP  cpu_to_be32(0x80)  /* Indicate UDP RCO (TCP when not set *) */
+#define VXLAN_RCO_SHIFT        1                  /* Left shift of start */
+#define VXLAN_RCO_SHIFT_MASK ((1 << VXLAN_RCO_SHIFT) - 1)
+#define VXLAN_MAX_REMCSUM_START (0x7f << VXLAN_RCO_SHIFT)
 
 /*
- * VXLAN Group Based Policy Extension:
+ * VXLAN Group Based Policy Extension (VXLAN_F_GBP):
  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |1|-|-|-|1|-|-|-|R|D|R|R|A|R|R|R|        Group Policy ID        |
+ * |G|R|R|R|I|R|R|R|R|D|R|R|A|R|R|R|        Group Policy ID        |
  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  * |                VXLAN Network Identifier (VNI) |   Reserved    |
  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *
+ * G = Group Policy ID present.
+ *
  * D = Don't Learn bit. When set, this bit indicates that the egress
  *     VTEP MUST NOT learn the source address of the encapsulated frame.
  *
  *     this packet. Policies MUST NOT be applied by devices when the
  *     A bit is set.
  *
- * [0] https://tools.ietf.org/html/draft-smith-vxlan-group-policy
+ * https://tools.ietf.org/html/draft-smith-vxlan-group-policy
  */
 struct vxlanhdr_gbp {
-       __u8    vx_flags;
+       u8      vx_flags;
 #ifdef __LITTLE_ENDIAN_BITFIELD
-       __u8    reserved_flags1:3,
+       u8      reserved_flags1:3,
                policy_applied:1,
                reserved_flags2:2,
                dont_learn:1,
                reserved_flags3:1;
 #elif defined(__BIG_ENDIAN_BITFIELD)
-       __u8    reserved_flags1:1,
+       u8      reserved_flags1:1,
                dont_learn:1,
                reserved_flags2:2,
                policy_applied:1,
@@ -50,7 +104,10 @@ struct vxlanhdr_gbp {
        __be32  vx_vni;
 };
 
-#define VXLAN_GBP_USED_BITS (VXLAN_HF_GBP | 0xFFFFFF)
+/* VXLAN-GBP header flags. */
+#define VXLAN_HF_GBP   cpu_to_be32(BIT(31))
+
+#define VXLAN_GBP_USED_BITS (VXLAN_HF_GBP | cpu_to_be32(0xFFFFFF))
 
 /* skb->mark mapping
  *
@@ -62,44 +119,6 @@ struct vxlanhdr_gbp {
 #define VXLAN_GBP_POLICY_APPLIED       (BIT(3) << 16)
 #define VXLAN_GBP_ID_MASK              (0xFFFF)
 
-/* VXLAN protocol header:
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |G|R|R|R|I|R|R|C|               Reserved                        |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |                VXLAN Network Identifier (VNI) |   Reserved    |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * G = 1       Group Policy (VXLAN-GBP)
- * I = 1       VXLAN Network Identifier (VNI) present
- * C = 1       Remote checksum offload (RCO)
- */
-struct vxlanhdr {
-       __be32 vx_flags;
-       __be32 vx_vni;
-};
-
-/* VXLAN header flags. */
-#define VXLAN_HF_RCO BIT(21)
-#define VXLAN_HF_VNI BIT(27)
-#define VXLAN_HF_GBP BIT(31)
-
-/* Remote checksum offload header option */
-#define VXLAN_RCO_MASK  0x7f    /* Last byte of vni field */
-#define VXLAN_RCO_UDP   0x80    /* Indicate UDP RCO (TCP when not set *) */
-#define VXLAN_RCO_SHIFT 1       /* Left shift of start */
-#define VXLAN_RCO_SHIFT_MASK ((1 << VXLAN_RCO_SHIFT) - 1)
-#define VXLAN_MAX_REMCSUM_START (VXLAN_RCO_MASK << VXLAN_RCO_SHIFT)
-
-#define VXLAN_N_VID     (1u << 24)
-#define VXLAN_VID_MASK  (VXLAN_N_VID - 1)
-#define VXLAN_VNI_MASK  (VXLAN_VID_MASK << 8)
-#define VXLAN_HLEN (sizeof(struct udphdr) + sizeof(struct vxlanhdr))
-
-#define VNI_HASH_BITS  10
-#define VNI_HASH_SIZE  (1<<VNI_HASH_BITS)
-#define FDB_HASH_BITS  8
-#define FDB_HASH_SIZE  (1<<FDB_HASH_BITS)
-
 struct vxlan_metadata {
        u32             gbp;
 };
@@ -125,23 +144,25 @@ union vxlan_addr {
 struct vxlan_rdst {
        union vxlan_addr         remote_ip;
        __be16                   remote_port;
-       u32                      remote_vni;
+       __be32                   remote_vni;
        u32                      remote_ifindex;
        struct list_head         list;
        struct rcu_head          rcu;
+       struct dst_cache         dst_cache;
 };
 
 struct vxlan_config {
        union vxlan_addr        remote_ip;
        union vxlan_addr        saddr;
-       u32                     vni;
+       __be32                  vni;
        int                     remote_ifindex;
        int                     mtu;
        __be16                  dst_port;
-       __u16                   port_min;
-       __u16                   port_max;
-       __u8                    tos;
-       __u8                    ttl;
+       u16                     port_min;
+       u16                     port_max;
+       u8                      tos;
+       u8                      ttl;
+       __be32                  label;
        u32                     flags;
        unsigned long           age_interval;
        unsigned int            addrmax;
@@ -177,7 +198,7 @@ struct vxlan_dev {
 #define VXLAN_F_L2MISS                 0x08
 #define VXLAN_F_L3MISS                 0x10
 #define VXLAN_F_IPV6                   0x20
-#define VXLAN_F_UDP_CSUM               0x40
+#define VXLAN_F_UDP_ZERO_CSUM_TX       0x40
 #define VXLAN_F_UDP_ZERO_CSUM6_TX      0x80
 #define VXLAN_F_UDP_ZERO_CSUM6_RX      0x100
 #define VXLAN_F_REMCSUM_TX             0x200
@@ -242,6 +263,68 @@ static inline netdev_features_t vxlan_features_check(struct sk_buff *skb,
 /* IPv6 header + UDP + VXLAN + Ethernet header */
 #define VXLAN6_HEADROOM (40 + 8 + 8 + 14)
 
+static inline struct vxlanhdr *vxlan_hdr(struct sk_buff *skb)
+{
+       return (struct vxlanhdr *)(udp_hdr(skb) + 1);
+}
+
+static inline __be32 vxlan_vni(__be32 vni_field)
+{
+#if defined(__BIG_ENDIAN)
+       return (__force __be32)((__force u32)vni_field >> 8);
+#else
+       return (__force __be32)((__force u32)(vni_field & VXLAN_VNI_MASK) << 8);
+#endif
+}
+
+static inline __be32 vxlan_vni_field(__be32 vni)
+{
+#if defined(__BIG_ENDIAN)
+       return (__force __be32)((__force u32)vni << 8);
+#else
+       return (__force __be32)((__force u32)vni >> 8);
+#endif
+}
+
+static inline __be32 vxlan_tun_id_to_vni(__be64 tun_id)
+{
+#if defined(__BIG_ENDIAN)
+       return (__force __be32)tun_id;
+#else
+       return (__force __be32)((__force u64)tun_id >> 32);
+#endif
+}
+
+static inline __be64 vxlan_vni_to_tun_id(__be32 vni)
+{
+#if defined(__BIG_ENDIAN)
+       return (__force __be64)vni;
+#else
+       return (__force __be64)((u64)(__force u32)vni << 32);
+#endif
+}
+
+static inline size_t vxlan_rco_start(__be32 vni_field)
+{
+       return be32_to_cpu(vni_field & VXLAN_RCO_MASK) << VXLAN_RCO_SHIFT;
+}
+
+static inline size_t vxlan_rco_offset(__be32 vni_field)
+{
+       return (vni_field & VXLAN_RCO_UDP) ?
+               offsetof(struct udphdr, check) :
+               offsetof(struct tcphdr, check);
+}
+
+static inline __be32 vxlan_compute_rco(unsigned int start, unsigned int offset)
+{
+       __be32 vni_field = cpu_to_be32(start >> VXLAN_RCO_SHIFT);
+
+       if (offset == offsetof(struct udphdr, check))
+               vni_field |= VXLAN_RCO_UDP;
+       return vni_field;
+}
+
 #if IS_ENABLED(CONFIG_VXLAN)
 void vxlan_get_rx_port(struct net_device *netdev);
 #else
This page took 0.026241 seconds and 5 git commands to generate.