flow: Create new flow_metadata structure for packet_in messages.
authorEthan Jackson <ethan@nicira.com>
Thu, 5 Jan 2012 00:40:13 +0000 (16:40 -0800)
committerEthan Jackson <ethan@nicira.com>
Tue, 10 Jan 2012 22:30:15 +0000 (14:30 -0800)
This will ease the implementation of future patches.

Signed-off-by: Ethan Jackson <ethan@nicira.com>
lib/flow.c
lib/flow.h
lib/ofp-print.c
lib/ofp-util.c
lib/ofp-util.h
ofproto/ofproto-dpif.c

index cffb59f..29714b1 100644 (file)
@@ -507,6 +507,19 @@ flow_zero_wildcards(struct flow *flow, const struct flow_wildcards *wildcards)
     flow->skb_priority = 0;
 }
 
+/* Initializes 'fmd' with the metadata found in 'flow'. */
+void
+flow_get_metadata(const struct flow *flow, struct flow_metadata *fmd)
+{
+    fmd->tun_id = flow->tun_id;
+    fmd->tun_id_mask = htonll(UINT64_MAX);
+
+    memcpy(fmd->regs, flow->regs, sizeof fmd->regs);
+    memset(fmd->reg_masks, 0xff, sizeof fmd->reg_masks);
+
+    fmd->in_port = flow->in_port;
+}
+
 char *
 flow_to_string(const struct flow *flow)
 {
index 32492e8..44eb977 100644 (file)
@@ -78,6 +78,19 @@ struct flow {
     uint8_t reserved[6];        /* Reserved for 64-bit packing. */
 };
 
+/* Represents the metadata fields of struct flow.  The masks are used to
+ * indicate which metadata fields are relevant in a given context.  Typically
+ * they will be all 1 or all 0. */
+struct flow_metadata {
+    ovs_be64 tun_id;                 /* Encapsulating tunnel ID. */
+    ovs_be64 tun_id_mask;            /* 1-bit in each significant tun_id bit.*/
+
+    uint32_t regs[FLOW_N_REGS];      /* Registers. */
+    uint32_t reg_masks[FLOW_N_REGS]; /* 1-bit in each significant regs bit. */
+
+    uint16_t in_port;                /* OpenFlow port or zero. */
+};
+
 /* Assert that there are FLOW_SIG_SIZE bytes of significant data in "struct
  * flow", followed by FLOW_PAD_SIZE bytes of padding. */
 #define FLOW_SIG_SIZE (110 + FLOW_N_REGS * 4)
@@ -92,6 +105,7 @@ BUILD_ASSERT_DECL(FLOW_SIG_SIZE == 130 && FLOW_WC_SEQ == 7);
 void flow_extract(struct ofpbuf *, uint32_t priority, ovs_be64 tun_id,
                   uint16_t in_port, struct flow *);
 void flow_zero_wildcards(struct flow *, const struct flow_wildcards *);
+void flow_get_metadata(const struct flow *, struct flow_metadata *);
 
 char *flow_to_string(const struct flow *);
 void flow_format(struct ds *, const struct flow *);
index c4f0b8a..98791f4 100644 (file)
@@ -84,6 +84,7 @@ ofp_print_packet_in(struct ds *string, const struct ofp_header *oh,
 {
     struct ofputil_packet_in pin;
     int error;
+    int i;
 
     error = ofputil_decode_packet_in(&pin, oh);
     if (error) {
@@ -92,7 +93,23 @@ ofp_print_packet_in(struct ds *string, const struct ofp_header *oh,
     }
 
     ds_put_format(string, " total_len=%"PRIu16" in_port=", pin.total_len);
-    ofputil_format_port(pin.in_port, string);
+    ofputil_format_port(pin.fmd.in_port, string);
+
+    if (pin.fmd.tun_id_mask) {
+        ds_put_format(string, " tun_id=0x%"PRIx64, ntohll(pin.fmd.tun_id));
+        if (pin.fmd.tun_id_mask != htonll(UINT64_MAX)) {
+            ds_put_format(string, "/0x%"PRIx64, ntohll(pin.fmd.tun_id_mask));
+        }
+    }
+
+    for (i = 0; i < FLOW_N_REGS; i++) {
+        if (pin.fmd.reg_masks[i]) {
+            ds_put_format(string, " reg%d=0x%"PRIx32, i, pin.fmd.regs[i]);
+            if (pin.fmd.reg_masks[i] != UINT32_MAX) {
+                ds_put_format(string, "/0x%"PRIx32, pin.fmd.reg_masks[i]);
+            }
+        }
+    }
 
     if (pin.reason == OFPR_ACTION) {
         ds_put_cstr(string, " (via action)");
index 17b3cc7..6873842 100644 (file)
@@ -1560,7 +1560,7 @@ ofputil_decode_packet_in(struct ofputil_packet_in *pin,
         pin->packet_len = ntohs(opi->header.length)
             - offsetof(struct ofp_packet_in, data);
 
-        pin->in_port = ntohs(opi->in_port);
+        pin->fmd.in_port = ntohs(opi->in_port);
         pin->reason = opi->reason;
         pin->buffer_id = ntohl(opi->buffer_id);
         pin->total_len = ntohs(opi->total_len);
@@ -1588,7 +1588,7 @@ ofputil_encode_packet_in(const struct ofputil_packet_in *pin)
     opi.header.version = OFP_VERSION;
     opi.header.type = OFPT_PACKET_IN;
     opi.total_len = htons(pin->packet_len);
-    opi.in_port = htons(pin->in_port);
+    opi.in_port = htons(pin->fmd.in_port);
     opi.reason = pin->reason;
     opi.buffer_id = htonl(pin->buffer_id);
     ofpbuf_push(rw_packet, &opi, offsetof(struct ofp_packet_in, data));
index 1837f32..c3fafba 100644 (file)
@@ -217,12 +217,13 @@ struct ofputil_packet_in {
     const void *packet;
     size_t packet_len;
 
-    uint16_t in_port;
     uint8_t reason;             /* One of OFPR_*. */
 
     uint32_t buffer_id;
     int send_len;
     uint16_t total_len;         /* Full length of frame. */
+
+    struct flow_metadata fmd;   /* Metadata at creation time. */
 };
 
 int ofputil_decode_packet_in(struct ofputil_packet_in *,
index 03bf368..f81fbd9 100644 (file)
@@ -2420,10 +2420,15 @@ send_packet_in_miss(struct ofproto_dpif *ofproto, struct ofpbuf *packet,
     pin.packet = packet->data;
     pin.packet_len = packet->size;
     pin.total_len = packet->size;
-    pin.in_port = flow->in_port;
     pin.reason = OFPR_NO_MATCH;
     pin.buffer_id = 0;          /* not yet known */
     pin.send_len = 0;           /* not used for flow table misses */
+
+    flow_get_metadata(flow, &pin.fmd);
+
+    /* Registers aren't meaningful on a miss. */
+    memset(pin.fmd.reg_masks, 0, sizeof pin.fmd.reg_masks);
+
     connmgr_send_packet_in(ofproto->up.connmgr, &pin, flow);
 }
 
@@ -2445,10 +2450,16 @@ send_packet_in_action(struct ofproto_dpif *ofproto, struct ofpbuf *packet,
     pin.packet = packet->data;
     pin.packet_len = packet->size;
     pin.total_len = packet->size;
-    pin.in_port = flow->in_port;
     pin.reason = OFPR_ACTION;
     pin.buffer_id = 0;          /* not yet known */
     pin.send_len = cookie.data;
+
+    flow_get_metadata(flow, &pin.fmd);
+
+    /* Metadata may not be accurate at this time. */
+    memset(pin.fmd.reg_masks, 0, sizeof pin.fmd.reg_masks);
+    pin.fmd.tun_id_mask = 0;
+
     connmgr_send_packet_in(ofproto->up.connmgr, &pin, flow);
 }