This will ease the implementation of future patches.
Signed-off-by: Ethan Jackson <ethan@nicira.com>
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)
{
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)
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 *);
{
struct ofputil_packet_in pin;
int error;
+ int i;
error = ofputil_decode_packet_in(&pin, oh);
if (error) {
}
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)");
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);
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));
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 *,
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);
}
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);
}