[ovs-dev] [PATCH] gre: Use struct for parsing GRE header.

Jesse Gross jesse at nicira.com
Thu Jul 15 20:07:11 UTC 2010


GRE is a somewhat annoying protocol because the header is variable
length.  However, it does have a few fields that are always present
so we can make the parsing seem less magical by using a struct for
those fields instead of building it up field by field.
---
 datapath/vport-gre.c |   33 ++++++++++++++++++---------------
 1 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/datapath/vport-gre.c b/datapath/vport-gre.c
index 41d3c96..60542a4 100644
--- a/datapath/vport-gre.c
+++ b/datapath/vport-gre.c
@@ -44,6 +44,11 @@
  * number of options. */
 #define GRE_HEADER_SECTION 4
 
+struct gre_base_hdr {
+	__u16 flags;
+	__be16 protocol;
+};
+
 struct mutable_config {
 	struct rcu_head rcu;
 
@@ -580,18 +585,17 @@ static void
 create_gre_header(struct sk_buff *skb, const struct mutable_config *mutable)
 {
 	struct iphdr *iph = ip_hdr(skb);
-	__be16 *flags = (__be16 *)(iph + 1);
-	__be16 *protocol = flags + 1;
+	struct gre_base_hdr *greh = (struct gre_base_hdr *)(iph + 1);
 	__be32 *options = (__be32 *)((u8 *)iph + mutable->tunnel_hlen
 					       - GRE_HEADER_SECTION);
 
-	*protocol = htons(ETH_P_TEB);
-	*flags = 0;
+	greh->protocol = htons(ETH_P_TEB);
+	greh->flags = 0;
 
 	/* Work backwards over the options so the checksum is last. */
 	if (mutable->port_config.out_key ||
 	    mutable->port_config.flags & GRE_F_OUT_KEY_ACTION) {
-		*flags |= GRE_KEY;
+		greh->flags |= GRE_KEY;
 
 		if (mutable->port_config.flags & GRE_F_OUT_KEY_ACTION)
 			*options = OVS_CB(skb)->tun_id;
@@ -602,7 +606,7 @@ create_gre_header(struct sk_buff *skb, const struct mutable_config *mutable)
 	}
 
 	if (mutable->port_config.flags & GRE_F_OUT_CSUM) {
-		*flags |= GRE_CSUM;
+		greh->flags |= GRE_CSUM;
 
 		*options = 0;
 		*(__sum16 *)options = csum_fold(skb_checksum(skb,
@@ -643,27 +647,26 @@ static int
 parse_gre_header(struct iphdr *iph, __be16 *flags, __be32 *key)
 {
 	/* IP and ICMP protocol handlers check that the IHL is valid. */
-	__be16 *flagsp = (__be16 *)((u8 *)iph + (iph->ihl << 2));
-	__be16 *protocol = flagsp + 1;
-	__be32 *options = (__be32 *)(protocol + 1);
+	struct gre_base_hdr *greh = (struct gre_base_hdr *)((u8 *)iph + (iph->ihl << 2));
+	__be32 *options = (__be32 *)(greh + 1);
 	int hdr_len;
 
-	*flags = *flagsp;
+	*flags = greh->flags;
 
-	if (*flags & (GRE_VERSION | GRE_ROUTING))
+	if (greh->flags & (GRE_VERSION | GRE_ROUTING))
 		return -EINVAL;
 
-	if (*protocol != htons(ETH_P_TEB))
+	if (greh->protocol != htons(ETH_P_TEB))
 		return -EINVAL;
 
 	hdr_len = GRE_HEADER_SECTION;
 
-	if (*flags & GRE_CSUM) {
+	if (greh->flags & GRE_CSUM) {
 		hdr_len += GRE_HEADER_SECTION;
 		options++;
 	}
 
-	if (*flags & GRE_KEY) {
+	if (greh->flags & GRE_KEY) {
 		hdr_len += GRE_HEADER_SECTION;
 
 		*key = *options;
@@ -671,7 +674,7 @@ parse_gre_header(struct iphdr *iph, __be16 *flags, __be32 *key)
 	} else
 		*key = 0;
 
-	if (*flags & GRE_SEQ)
+	if (greh->flags & GRE_SEQ)
 		hdr_len += GRE_HEADER_SECTION;
 
 	return hdr_len;
-- 
1.7.0.4





More information about the dev mailing list