[ovs-dev] [packet_in v2 15/18] flow: Create new flow_metadata structure for packet_in messages.

Ethan Jackson ethan at nicira.com
Mon Jan 9 22:34:51 UTC 2012


Oops, didn't mean to send this one again.  You may ignore it.

On Mon, Jan 9, 2012 at 14:33, Ethan Jackson <ethan at nicira.com> wrote:
> This will ease the implementation of future patches.
>
> Signed-off-by: Ethan Jackson <ethan at nicira.com>
> ---
>  lib/flow.c             |   13 +++++++++++++
>  lib/flow.h             |   14 ++++++++++++++
>  lib/ofp-print.c        |   19 ++++++++++++++++++-
>  lib/ofp-util.c         |    4 ++--
>  lib/ofp-util.h         |    3 ++-
>  ofproto/ofproto-dpif.c |   15 +++++++++++++--
>  6 files changed, 62 insertions(+), 6 deletions(-)
>
> diff --git a/lib/flow.c b/lib/flow.c
> index cffb59f..29714b1 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 32492e8..44eb977 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 c4f0b8a..e8e1c2c 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 17b3cc7..6873842 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 1837f32..c3fafba 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 03bf368..f81fbd9 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);
>  }
>
> --
> 1.7.7.1
>



More information about the dev mailing list