use ovs_assert instead of assert
[sliver-openvswitch.git] / lib / ofp-util.c
index 075557e..c66cd40 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -807,7 +807,7 @@ ofputil_protocols_to_string(enum ofputil_protocol protocols)
 {
     struct ds s;
 
-    assert(!(protocols & ~OFPUTIL_P_ANY));
+    ovs_assert(!(protocols & ~OFPUTIL_P_ANY));
     if (protocols == 0) {
         return xstrdup("none");
     }
@@ -1367,7 +1367,7 @@ ofputil_encode_set_protocol(enum ofputil_protocol current,
         return ofputil_make_flow_mod_table_id(want_tid);
     }
 
-    assert(current == want);
+    ovs_assert(current == want);
 
     *next = current;
     return NULL;
@@ -1381,7 +1381,7 @@ ofputil_encode_nx_set_flow_format(enum nx_flow_format nxff)
     struct nx_set_flow_format *sff;
     struct ofpbuf *msg;
 
-    assert(ofputil_nx_flow_format_is_valid(nxff));
+    ovs_assert(ofputil_nx_flow_format_is_valid(nxff));
 
     msg = ofpraw_alloc(OFPRAW_NXT_SET_FLOW_FORMAT, OFP10_VERSION, 0);
     sff = ofpbuf_put_zeros(msg, sizeof *sff);
@@ -3226,7 +3226,7 @@ ofputil_decode_port_status(const struct ofp_header *oh,
     ps->reason = ops->reason;
 
     retval = ofputil_pull_phy_port(oh->version, &b, &ps->desc);
-    assert(retval != EOF);
+    ovs_assert(retval != EOF);
     return retval;
 }
 
@@ -3355,6 +3355,104 @@ ofputil_encode_port_mod(const struct ofputil_port_mod *pm,
     return b;
 }
 \f
+/* ofputil_role_request */
+
+/* Decodes the OpenFlow "role request" or "role reply" message in '*oh' into
+ * an abstract form in '*rr'.  Returns 0 if successful, otherwise an
+ * OFPERR_* value. */
+enum ofperr
+ofputil_decode_role_message(const struct ofp_header *oh,
+                            struct ofputil_role_request *rr)
+{
+    const struct ofp12_role_request *orr = ofpmsg_body(oh);
+    uint32_t role = ntohl(orr->role);
+    struct ofpbuf b;
+    enum ofpraw raw;
+
+    memset(rr, 0, sizeof *rr);
+
+    ofpbuf_use_const(&b, oh, ntohs(oh->length));
+    raw = ofpraw_pull_assert(&b);
+
+    if (raw == OFPRAW_OFPT12_ROLE_REQUEST
+        || raw == OFPRAW_OFPT12_ROLE_REPLY) {
+
+        if (raw == OFPRAW_OFPT12_ROLE_REQUEST) {
+            if (role == OFPCR12_ROLE_NOCHANGE) {
+                rr->request_current_role_only = true;
+                return 0;
+            }
+            if (role == OFPCR12_ROLE_MASTER || role == OFPCR12_ROLE_SLAVE) {
+                rr->generation_id = ntohll(orr->generation_id);
+                rr->have_generation_id = true;
+            }
+        }
+
+        /* Map to enum nx_role */
+        role -= 1; /* OFPCR12_ROLE_MASTER -> NX_ROLE_MASTER etc. */
+    } else if (raw != OFPRAW_NXT_ROLE_REQUEST
+               && raw != OFPRAW_NXT_ROLE_REPLY) {
+        return OFPERR_OFPBRC_BAD_TYPE;
+    }
+
+    if (role != NX_ROLE_OTHER && role != NX_ROLE_MASTER
+        && role != NX_ROLE_SLAVE) {
+        return OFPERR_OFPRRFC_BAD_ROLE;
+    }
+
+    rr->role = role;
+    return 0;
+}
+
+/* Returns an encoded form of a role reply suitable for the "request" in a
+ * buffer owned by the caller. */
+struct ofpbuf *
+ofputil_encode_role_reply(const struct ofp_header *request,
+                          enum nx_role role)
+{
+    struct ofp12_role_request *reply;
+    struct ofpbuf *buf;
+    size_t reply_size;
+
+    struct ofpbuf b;
+    enum ofpraw raw;
+
+    ofpbuf_use_const(&b, request, ntohs(request->length));
+    raw = ofpraw_pull_assert(&b);
+    if (raw == OFPRAW_OFPT12_ROLE_REQUEST) {
+        reply_size = sizeof (struct ofp12_role_request);
+        raw = OFPRAW_OFPT12_ROLE_REPLY;
+    }
+    else if (raw == OFPRAW_NXT_ROLE_REQUEST) {
+        reply_size = sizeof (struct nx_role_request);
+        raw = OFPRAW_NXT_ROLE_REPLY;
+    } else {
+        NOT_REACHED();
+    }
+
+    buf = ofpraw_alloc_reply(raw, request, 0);
+    reply = ofpbuf_put_zeros(buf, reply_size);
+
+    if (raw == OFPRAW_OFPT12_ROLE_REPLY) {
+        /* Map to OpenFlow enum ofp12_controller_role */
+        role += 1; /* NX_ROLE_MASTER -> OFPCR12_ROLE_MASTER etc. */
+        /*
+         * OpenFlow specification does not specify use of generation_id field
+         * on reply messages.  Intuitively, it would seem a good idea to return
+         * the current value.  However, the current value is undefined
+         * initially, and there is no way to insert an undefined value in the
+         * message.  Therefore we leave the generation_id zeroed on reply
+         * messages.
+         *
+         * A request for clarification has been filed with the Open Networking
+         * Foundation as EXT-272.
+         */
+    }
+    reply->role = htonl(role);
+
+    return buf;
+}
+\f
 /* Table stats. */
 
 static void
@@ -3384,9 +3482,9 @@ ofputil_put_ofp10_table_stats(const struct ofp12_table_stats *in,
     struct ofp10_table_stats *out;
     const struct wc_map *p;
 
-    out = ofpbuf_put_uninit(buf, sizeof *out);
+    out = ofpbuf_put_zeros(buf, sizeof *out);
     out->table_id = in->table_id;
-    strcpy(out->name, in->name);
+    ovs_strlcpy(out->name, in->name, sizeof out->name);
     out->wildcards = 0;
     for (p = wc_map; p < &wc_map[ARRAY_SIZE(wc_map)]; p++) {
         if (in->wildcards & htonll(1ULL << p->mf12)) {
@@ -3444,9 +3542,9 @@ ofputil_put_ofp11_table_stats(const struct ofp12_table_stats *in,
 {
     struct ofp11_table_stats *out;
 
-    out = ofpbuf_put_uninit(buf, sizeof *out);
+    out = ofpbuf_put_zeros(buf, sizeof *out);
     out->table_id = in->table_id;
-    strcpy(out->name, in->name);
+    ovs_strlcpy(out->name, in->name, sizeof out->name);
     out->wildcards = oxm12_to_ofp11_flow_match_fields(in->wildcards);
     out->match = oxm12_to_ofp11_flow_match_fields(in->match);
     out->instructions = in->instructions;