[ovs-dev] [PATCH 25/34] ofp-util: Prepare Packet Out encoder for other Open Flow versions

Simon Horman horms at verge.net.au
Tue Jun 19 07:49:03 UTC 2012


Signed-off-by: Simon Horman <horms at verge.net.au>

---

v3
* Add protocol variable to do_probe().
  Previously this was added by a separate patch.

v2
* No change
---
 lib/learning-switch.c | 10 ++++++++--
 lib/ofp-util.c        | 30 ++++++++++++++++++------------
 lib/ofp-util.h        |  3 ++-
 utilities/ovs-ofctl.c |  5 +++--
 4 files changed, 31 insertions(+), 17 deletions(-)

diff --git a/lib/learning-switch.c b/lib/learning-switch.c
index a44fdd8..cf82975 100644
--- a/lib/learning-switch.c
+++ b/lib/learning-switch.c
@@ -458,6 +458,9 @@ process_packet_in(struct lswitch *sw, struct rconn *rconn,
     struct ofpbuf pkt;
     struct flow flow;
 
+    enum ofputil_protocol protocol;
+    int ofp_version;
+
     error = ofputil_decode_packet_in(&pi, oh);
     if (error) {
         VLOG_WARN_RL(&rl, "failed to decode packet-in: %s",
@@ -506,6 +509,9 @@ process_packet_in(struct lswitch *sw, struct rconn *rconn,
     po.ofpacts = ofpacts.data;
     po.ofpacts_len = ofpacts.size;
 
+    ofp_version = rconn_get_version(rconn);
+    protocol = ofputil_protocol_from_ofp_version(ofp_version);
+
     /* Send the packet, and possibly the whole flow, to the output port. */
     if (sw->max_idle >= 0 && (!sw->ml || out_port != OFPP_FLOOD)) {
         struct ofputil_flow_mod fm;
@@ -528,13 +534,13 @@ process_packet_in(struct lswitch *sw, struct rconn *rconn,
 
         /* If the switch didn't buffer the packet, we need to send a copy. */
         if (pi.buffer_id == UINT32_MAX && out_port != OFPP_NONE) {
-            queue_tx(sw, rconn, ofputil_encode_packet_out(&po));
+            queue_tx(sw, rconn, ofputil_encode_packet_out(&po, protocol));
         }
     } else {
         /* We don't know that MAC, or we don't set up flows.  Send along the
          * packet without setting up a flow. */
         if (pi.buffer_id != UINT32_MAX || out_port != OFPP_NONE) {
-            queue_tx(sw, rconn, ofputil_encode_packet_out(&po));
+            queue_tx(sw, rconn, ofputil_encode_packet_out(&po, protocol));
         }
     }
 }
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index 7c5b861..860eb0a 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -3315,25 +3315,31 @@ ofputil_encode_port_mod(const struct ofputil_port_mod *pm,
 }
 
 struct ofpbuf *
-ofputil_encode_packet_out(const struct ofputil_packet_out *po)
+ofputil_encode_packet_out(const struct ofputil_packet_out *po,
+                          enum ofputil_protocol protocol)
 {
-    struct ofp_packet_out *opo;
+    uint8_t ofp_version = ofputil_protocol_to_ofp_version(protocol);
     struct ofpbuf *msg;
-    size_t size;
+    size_t packet_len = 0;
 
-    size = sizeof *opo + po->ofpacts_len;
     if (po->buffer_id == UINT32_MAX) {
-        size += po->packet_len;
+        packet_len = po->packet_len;
     }
 
-    msg = ofpbuf_new(size);
-    put_openflow(sizeof *opo, OFPT10_PACKET_OUT, msg);
-    ofpacts_to_openflow10(po->ofpacts, msg);
+    if (ofp_version == OFP10_VERSION) {
+        struct ofp_packet_out *opo;
+
+        msg = ofpbuf_new(packet_len + sizeof *opo);
+        put_openflow(sizeof *opo, OFPT10_PACKET_OUT, msg);
+        opo = msg->data;
+        opo->buffer_id = htonl(po->buffer_id);
+        opo->in_port = htons(po->in_port);
+        opo->actions_len = htons(msg->size - sizeof *opo);
+    } else {
+        NOT_REACHED();
+    }
 
-    opo = msg->data;
-    opo->buffer_id = htonl(po->buffer_id);
-    opo->in_port = htons(po->in_port);
-    opo->actions_len = htons(msg->size - sizeof *opo);
+    ofpacts_to_openflow10(po->ofpacts, msg);
 
     if (po->buffer_id == UINT32_MAX) {
         ofpbuf_put(msg, po->packet, po->packet_len);
diff --git a/lib/ofp-util.h b/lib/ofp-util.h
index 03dc9af..0ea3ebe 100644
--- a/lib/ofp-util.h
+++ b/lib/ofp-util.h
@@ -378,7 +378,8 @@ struct ofputil_packet_out {
 enum ofperr ofputil_decode_packet_out(struct ofputil_packet_out *,
                                       const struct ofp_header *,
                                       struct ofpbuf *ofpacts);
-struct ofpbuf *ofputil_encode_packet_out(const struct ofputil_packet_out *);
+struct ofpbuf *ofputil_encode_packet_out(const struct ofputil_packet_out *,
+                                         enum ofputil_protocol protocol);
 
 enum ofputil_port_config {
     /* OpenFlow 1.0 and 1.1 share these values for these port config bits. */
diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
index 6a65dc1..c7e1588 100644
--- a/utilities/ovs-ofctl.c
+++ b/utilities/ovs-ofctl.c
@@ -1223,6 +1223,7 @@ do_probe(int argc OVS_UNUSED, char *argv[])
 static void
 do_packet_out(int argc, char *argv[])
 {
+    enum ofputil_protocol protocol;
     struct ofputil_packet_out po;
     struct ofpbuf ofpacts;
     struct vconn *vconn;
@@ -1238,7 +1239,7 @@ do_packet_out(int argc, char *argv[])
     po.ofpacts = ofpacts.data;
     po.ofpacts_len = ofpacts.size;
 
-    open_vconn(argv[1], &vconn);
+    protocol = open_vconn(argv[1], &vconn);
     for (i = 4; i < argc; i++) {
         struct ofpbuf *packet, *opo;
         const char *error_msg;
@@ -1250,7 +1251,7 @@ do_packet_out(int argc, char *argv[])
 
         po.packet = packet->data;
         po.packet_len = packet->size;
-        opo = ofputil_encode_packet_out(&po);
+        opo = ofputil_encode_packet_out(&po, protocol);
         transact_noreply(vconn, opo);
         ofpbuf_delete(packet);
     }
-- 
1.7.10.2.484.gcd07cc5




More information about the dev mailing list