/*
- * Copyright (c) 2010 Nicira Networks.
+ * Copyright (c) 2010, 2011 Nicira Networks.
* Distributed under the terms of the GNU GPL version 2.
*
* Significant portions of this file may be copied from parts of the Linux
__be16 protocol;
};
-static int gre_hdr_len(const struct tnl_port_config *port_config)
+static int gre_hdr_len(const struct tnl_mutable_config *mutable)
{
int len;
len = GRE_HEADER_SECTION;
- if (port_config->flags & TNL_F_CSUM)
+ if (mutable->flags & TNL_F_CSUM)
len += GRE_HEADER_SECTION;
- if (port_config->out_key ||
- port_config->flags & TNL_F_OUT_KEY_ACTION)
+ if (mutable->out_key || mutable->flags & TNL_F_OUT_KEY_ACTION)
len += GRE_HEADER_SECTION;
return len;
}
+/* Returns the least-significant 32 bits of a __be64. */
+static __be32 be64_get_low32(__be64 x)
+{
+#ifdef __BIG_ENDIAN
+ return (__force __be32)x;
+#else
+ return (__force __be32)((__force u64)x >> 32);
+#endif
+}
+
static void gre_build_header(const struct vport *vport,
const struct tnl_mutable_config *mutable,
void *header)
greh->protocol = htons(ETH_P_TEB);
greh->flags = 0;
- if (mutable->port_config.flags & TNL_F_CSUM) {
+ if (mutable->flags & TNL_F_CSUM) {
greh->flags |= GRE_CSUM;
*options = 0;
options++;
}
- if (mutable->port_config.out_key ||
- mutable->port_config.flags & TNL_F_OUT_KEY_ACTION)
+ if (mutable->out_key || mutable->flags & TNL_F_OUT_KEY_ACTION)
greh->flags |= GRE_KEY;
- if (mutable->port_config.out_key)
- *options = mutable->port_config.out_key;
+ if (mutable->out_key)
+ *options = be64_get_low32(mutable->out_key);
}
static struct sk_buff *gre_update_header(const struct vport *vport,
- GRE_HEADER_SECTION);
/* Work backwards over the options so the checksum is last. */
- if (mutable->port_config.flags & TNL_F_OUT_KEY_ACTION) {
- *options = OVS_CB(skb)->tun_id;
+ if (mutable->flags & TNL_F_OUT_KEY_ACTION) {
+ *options = be64_get_low32(OVS_CB(skb)->tun_id);
options--;
}
- if (mutable->port_config.flags & TNL_F_CSUM)
+ if (mutable->flags & TNL_F_CSUM)
*(__sum16 *)options = csum_fold(skb_checksum(skb,
skb_transport_offset(skb),
skb->len - skb_transport_offset(skb),
return skb;
}
-static int parse_header(struct iphdr *iph, __be16 *flags, __be32 *key)
+/* Zero-extends a __be32 into the least-significant 32 bits of a __be64. */
+static __be64 be32_extend_to_be64(__be32 x)
+{
+#ifdef __BIG_ENDIAN
+ return (__force __be64)x;
+#else
+ return (__force __be64)((__force u64)x << 32);
+#endif
+}
+
+static int parse_header(struct iphdr *iph, __be16 *flags, __be64 *key)
{
/* IP and ICMP protocol handlers check that the IHL is valid. */
struct gre_base_hdr *greh = (struct gre_base_hdr *)((u8 *)iph + (iph->ihl << 2));
if (greh->flags & GRE_KEY) {
hdr_len += GRE_HEADER_SECTION;
- *key = *options;
+ *key = be32_extend_to_be64(*options);
options++;
} else
*key = 0;
struct iphdr *iph;
__be16 flags;
- __be32 key;
+ __be64 key;
int tunnel_hdr_len, tot_hdr_len;
unsigned int orig_mac_header;
unsigned int orig_nw_header;
* out key as if it were the in key and then check to see if the input
* and output keys are the same.
*/
- if (mutable->port_config.in_key != mutable->port_config.out_key)
+ if (mutable->in_key != mutable->out_key)
return;
- if (!!(mutable->port_config.flags & TNL_F_IN_KEY_MATCH) !=
- !!(mutable->port_config.flags & TNL_F_OUT_KEY_ACTION))
+ if (!!(mutable->flags & TNL_F_IN_KEY_MATCH) !=
+ !!(mutable->flags & TNL_F_OUT_KEY_ACTION))
return;
- if ((mutable->port_config.flags & TNL_F_CSUM) && !(flags & GRE_CSUM))
+ if ((mutable->flags & TNL_F_CSUM) && !(flags & GRE_CSUM))
return;
tunnel_hdr_len += iph->ihl << 2;
int hdr_len;
struct iphdr *iph;
__be16 flags;
- __be32 key;
+ __be64 key;
if (unlikely(!pskb_may_pull(skb, sizeof(struct gre_base_hdr) + ETH_HLEN)))
goto error;
goto error;
}
- if (mutable->port_config.flags & TNL_F_IN_KEY_MATCH)
+ if (mutable->flags & TNL_F_IN_KEY_MATCH)
OVS_CB(skb)->tun_id = key;
else
OVS_CB(skb)->tun_id = 0;
}
const struct vport_ops gre_vport_ops = {
- .type = "gre",
+ .type = ODP_VPORT_TYPE_GRE,
.flags = VPORT_F_GEN_STATS | VPORT_F_TUN_ID,
.init = gre_init,
.exit = gre_exit,
.create = gre_create,
- .modify = tnl_modify,
.destroy = tnl_destroy,
- .set_mtu = tnl_set_mtu,
.set_addr = tnl_set_addr,
.get_name = tnl_get_name,
.get_addr = tnl_get_addr,
+ .get_options = tnl_get_options,
+ .set_options = tnl_set_options,
.get_dev_flags = vport_gen_get_dev_flags,
.is_running = vport_gen_is_running,
.get_operstate = vport_gen_get_operstate,
- .get_mtu = tnl_get_mtu,
.send = tnl_send,
};