[ovs-dev] [PATCH 18/19] ofp-util: Allow encoding of Open Flow 1.2 Packet In Messages

Simon Horman horms at verge.net.au
Wed Jun 13 23:52:06 UTC 2012


Signed-off-by: Simon Horman <horms at verge.net.au>
---
 lib/ofp-util.c | 82 ++++++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 59 insertions(+), 23 deletions(-)

diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index 1b31b8a..2bc0af0 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -1596,6 +1596,17 @@ oputil_of12_put_match(struct ofpbuf *msg, const struct cls_rule *cr,
     omh->length = htons(match_len + sizeof *omh);
 }
 
+static int
+oputil_put_match(struct ofpbuf *msg, bool oxm, const struct cls_rule *cr,
+                 ovs_be64 cookie, ovs_be64 cookie_mask)
+{
+    if (!oxm) {
+        return nx_put_match(msg, false, cr, cookie, cookie_mask);
+    }
+    oputil_of12_put_match(msg, cr, cookie, cookie_mask);
+    return 0;
+}
+
 /* Converts an OFPT_FLOW_MOD or NXT_FLOW_MOD message 'oh' into an abstract
  * flow_mod in 'fm'.  Returns 0 if successful, otherwise an OpenFlow error
  * code.
@@ -2462,6 +2473,40 @@ ofputil_decode_packet_in(struct ofputil_packet_in *pin,
     return 0;
 }
 
+static size_t
+ofputil_encode_packet_in_tail(const struct ofputil_packet_in *pin,
+                              struct ofpbuf **packet, size_t hdr_len,
+                              bool oxm) {
+    size_t send_len = MIN(pin->send_len, pin->packet_len);
+    size_t match_len = 0, i;
+    struct cls_rule rule;
+
+    /* Estimate of required PACKET_IN length includes the
+     * head portion of the packet in message, space for the match (2 times
+     * sizeof the metadata seems like enough), 2 bytes for padding, and the
+     * packet length. */
+    *packet = ofpbuf_new(hdr_len + sizeof(struct flow_metadata) * 2 +
+                        2 + send_len);
+
+    cls_rule_init_catchall(&rule, 0);
+    cls_rule_set_tun_id_masked(&rule, pin->fmd.tun_id,
+                               pin->fmd.tun_id_mask);
+
+    for (i = 0; i < FLOW_N_REGS; i++) {
+        cls_rule_set_reg_masked(&rule, i, pin->fmd.regs[i],
+                                pin->fmd.reg_masks[i]);
+    }
+
+    cls_rule_set_in_port(&rule, pin->fmd.in_port);
+
+    ofpbuf_put_zeros(*packet, hdr_len);
+    match_len = oputil_put_match(*packet, oxm, &rule, 0, 0);
+    ofpbuf_put_zeros(*packet, 2);
+    ofpbuf_put(*packet, pin->packet, send_len);
+
+    return match_len;
+}
+
 /* Converts abstract ofputil_packet_in 'pin' into a PACKET_IN message
  * in the format specified by 'packet_in_format'.  */
 struct ofpbuf *
@@ -2488,31 +2533,10 @@ ofputil_encode_packet_in(const struct ofputil_packet_in *pin,
         ofpbuf_put(packet, pin->packet, send_len);
     } else if (packet_in_format == NXPIF_NXM) {
         struct nx_packet_in *npi;
-        struct cls_rule rule;
         size_t match_len;
-        size_t i;
 
-        /* Estimate of required PACKET_IN length includes the NPI header, space
-         * for the match (2 times sizeof the metadata seems like enough), 2
-         * bytes for padding, and the packet length. */
-        packet = ofpbuf_new(sizeof *npi + sizeof(struct flow_metadata) * 2
-                            + 2 + send_len);
-
-        cls_rule_init_catchall(&rule, 0);
-        cls_rule_set_tun_id_masked(&rule, pin->fmd.tun_id,
-                                   pin->fmd.tun_id_mask);
-
-        for (i = 0; i < FLOW_N_REGS; i++) {
-            cls_rule_set_reg_masked(&rule, i, pin->fmd.regs[i],
-                                    pin->fmd.reg_masks[i]);
-        }
-
-        cls_rule_set_in_port(&rule, pin->fmd.in_port);
-
-        ofpbuf_put_zeros(packet, sizeof *npi);
-        match_len = nx_put_match(packet, false, &rule, 0, 0);
-        ofpbuf_put_zeros(packet, 2);
-        ofpbuf_put(packet, pin->packet, send_len);
+        match_len = ofputil_encode_packet_in_tail(pin, &packet,
+                                                  sizeof *npi, false);
 
         npi = packet->data;
         npi->nxh.header.version = OFP10_VERSION;
@@ -2526,6 +2550,18 @@ ofputil_encode_packet_in(const struct ofputil_packet_in *pin,
         npi->table_id = pin->table_id;
         npi->cookie = pin->cookie;
         npi->match_len = htons(match_len);
+    } else if (packet_in_format == NXPIF_OPENFLOW12) {
+        struct ofp11_packet_in *o11pi;
+
+        ofputil_encode_packet_in_tail(pin, &packet, sizeof *o11pi, true);
+
+        o11pi = packet->data;
+        o11pi->header.version = OFP12_VERSION;
+        o11pi->header.type = OFPT_PACKET_IN;
+        o11pi->buffer_id = htonl(pin->buffer_id);
+        o11pi->total_len = htons(pin->total_len);
+        o11pi->reason = pin->reason;
+        o11pi->table_id = pin->table_id;
     } else {
         NOT_REACHED();
     }
-- 
1.7.10.2.484.gcd07cc5




More information about the dev mailing list