From: Ethan Jackson Date: Thu, 5 Jan 2012 00:40:13 +0000 (-0800) Subject: flow: Create new flow_metadata structure for packet_in messages. X-Git-Tag: sliver-openvswitch-0.1-1~491 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=5d6c3af0fbff6c67f36c34f6e4c885f54de1bfe3;p=sliver-openvswitch.git flow: Create new flow_metadata structure for packet_in messages. This will ease the implementation of future patches. Signed-off-by: Ethan Jackson --- diff --git a/lib/flow.c b/lib/flow.c index cffb59fb0..29714b1ce 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -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) { diff --git a/lib/flow.h b/lib/flow.h index 32492e8fc..44eb9775e 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -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 *); diff --git a/lib/ofp-print.c b/lib/ofp-print.c index c4f0b8a66..98791f4bb 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -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)"); diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 17b3cc75e..687384244 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -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)); diff --git a/lib/ofp-util.h b/lib/ofp-util.h index 1837f327e..c3fafbaa8 100644 --- a/lib/ofp-util.h +++ b/lib/ofp-util.h @@ -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 *, diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 03bf36840..f81fbd96f 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -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); }