Add utility functions for generating random numbers, and use where appropriate.
authorBen Pfaff <blp@nicira.com>
Fri, 27 Jun 2008 17:52:11 +0000 (10:52 -0700)
committerBen Pfaff <blp@nicira.com>
Tue, 1 Jul 2008 17:51:47 +0000 (10:51 -0700)
include/Makefile.am
include/packets.h
include/random.h [new file with mode: 0644]
lib/Makefile.am
lib/random.c [new file with mode: 0644]
switch/datapath.c
utilities/dpctl.c

index 6a839f2b2e56ff608ed8ff610c83a3786d6afe70..ec938310434ad5a0013d9f062e5bcc0b0ec39fab 100644 (file)
@@ -21,6 +21,7 @@ noinst_HEADERS = \
        packets.h \
        poll-loop.h \
        queue.h \
+       random.h \
        rconn.h \
        socket-util.h \
        util.h \
index b4a5f05a47e7e9d23b2a1680da0be7554ff427bf..9ba55314b7e50c75da08ecb38c9565a0f64eb89b 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <stdint.h>
 #include <string.h>
+#include "random.h"
 #include "util.h"
 
 #define ETH_ADDR_LEN           6
@@ -56,6 +57,29 @@ static inline bool eth_addr_equals(const uint8_t a[ETH_ADDR_LEN],
 {
     return !memcmp(a, b, ETH_ADDR_LEN);
 }
+static inline uint64_t eth_addr_to_uint64(const uint8_t ea[ETH_ADDR_LEN])
+{
+    return (((uint64_t) ea[0] << 40)
+            | ((uint64_t) ea[1] << 32)
+            | ((uint64_t) ea[2] << 24)
+            | ((uint64_t) ea[3] << 16)
+            | ((uint64_t) ea[4] << 8)
+            | ea[5]);
+}
+static inline void eth_addr_from_uint64(uint64_t x, uint8_t ea[ETH_ADDR_LEN])
+{
+    ea[0] = x >> 40;
+    ea[1] = x >> 32;
+    ea[2] = x >> 24;
+    ea[3] = x >> 16;
+    ea[4] = x >> 8;
+    ea[5] = x;
+}
+static inline void eth_addr_random(uint8_t ea[ETH_ADDR_LEN])
+{
+    random_bytes(ea, ETH_ADDR_LEN);
+}
+
 #define ETH_ADDR_FMT                                                    \
     "%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8
 #define ETH_ADDR_ARGS(ea)                                   \
diff --git a/include/random.h b/include/random.h
new file mode 100644 (file)
index 0000000..92e2cb3
--- /dev/null
@@ -0,0 +1,43 @@
+/* Copyright (c) 2008 The Board of Trustees of The Leland Stanford
+ * Junior University
+ *
+ * We are making the OpenFlow specification and associated documentation
+ * (Software) available for public use and benefit with the expectation
+ * that others will use, modify and enhance the Software and contribute
+ * those enhancements back to the community. However, since we would
+ * like to make the Software available for broadest use, with as few
+ * restrictions as possible permission is hereby granted, free of
+ * charge, to any person obtaining a copy of this Software to deal in
+ * the Software under the copyrights without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The name and trademarks of copyright holder(s) may NOT be used in
+ * advertising or publicity pertaining to the Software or any
+ * derivatives without specific, written prior permission.
+ */
+
+#ifndef RANDOM_H
+#define RANDOM_H 1
+
+#include <stddef.h>
+#include <stdint.h>
+
+void random_bytes(void *, size_t);
+uint32_t random_uint32(void);
+
+#endif /* random.h */
index bd86fa1a3a9caa08dd34d54a157a4699d133fad2..719f827bd4ff734a30931e529c10cfeb2869f392 100644 (file)
@@ -18,6 +18,7 @@ libopenflow_la_SOURCES = \
        ofp-print.c \
        poll-loop.c \
        queue.c \
+       random.c \
        rconn.c \
        socket-util.c \
        util.c \
diff --git a/lib/random.c b/lib/random.c
new file mode 100644 (file)
index 0000000..55507e0
--- /dev/null
@@ -0,0 +1,72 @@
+/* Copyright (c) 2008 The Board of Trustees of The Leland Stanford
+ * Junior University
+ *
+ * We are making the OpenFlow specification and associated documentation
+ * (Software) available for public use and benefit with the expectation
+ * that others will use, modify and enhance the Software and contribute
+ * those enhancements back to the community. However, since we would
+ * like to make the Software available for broadest use, with as few
+ * restrictions as possible permission is hereby granted, free of
+ * charge, to any person obtaining a copy of this Software to deal in
+ * the Software under the copyrights without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The name and trademarks of copyright holder(s) may NOT be used in
+ * advertising or publicity pertaining to the Software or any
+ * derivatives without specific, written prior permission.
+ */
+
+#include "random.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/time.h>
+
+#include "util.h"
+
+void
+random_init(void)
+{
+    static bool inited = false;
+    if (!inited) {
+        struct timeval tv;
+        inited = true;
+        if (gettimeofday(&tv, NULL) < 0) {
+            fatal(errno, "gettimeofday");
+        }
+        srand(tv.tv_sec ^ tv.tv_usec);
+    }
+}
+
+void
+random_bytes(void *p_, size_t n)
+{
+    uint8_t *p = p_;
+    random_init();
+    while (n--) {
+        *p++ = rand();
+    }
+}
+
+uint32_t
+random_uint32(void)
+{
+    uint32_t x;
+    random_bytes(&x, sizeof x);
+    return x;
+}
index 4c4aa8606ba14c83b7a1772f57ce558dcc3b772d..e1ba2b92a18cea55653213fbc0b5fa0b7156933c 100644 (file)
@@ -167,24 +167,13 @@ static int port_no(struct datapath *dp, struct sw_port *p)
     return p - dp->ports;
 }
 
-/* Generates a unique datapath id.  It incorporates the datapath index
- * and a hardware address, if available.  If not, it generates a random
- * one.
- */
+/* Generates and returns a random datapath id. */
 static uint64_t
 gen_datapath_id(void)
 {
-    /* Choose a random datapath id. */
-    uint64_t id = 0;
-    int i;
-
-    srand(time(0));
-
-    for (i = 0; i < ETH_ADDR_LEN; i++) {
-        id |= (uint64_t)(rand() & 0xff) << (8*(ETH_ADDR_LEN-1 - i));
-    }
-
-    return id;
+    uint8_t ea[ETH_ADDR_LEN];
+    eth_addr_random(ea);
+    return eth_addr_to_uint64(ea);
 }
 
 int
index 334fb81687fc3aaab78a8419726c04c2941e8a47..29f67cdd32fb38bb5bd38feaa800041be30f8bd7 100644 (file)
@@ -53,6 +53,7 @@
 #include "socket-util.h"
 #include "openflow.h"
 #include "ofp-print.h"
+#include "random.h"
 #include "vconn.h"
 #include "vconn-ssl.h"
 
@@ -319,21 +320,6 @@ static void do_benchmark_nl(int argc UNUSED, char *argv[])
 \f
 /* Generic commands. */
 
-static uint32_t
-random_xid(void)
-{
-    static bool inited = false;
-    if (!inited) {
-        struct timeval tv;
-        inited = true;
-        if (gettimeofday(&tv, NULL) < 0) {
-            fatal(errno, "gettimeofday");
-        }
-        srand(tv.tv_sec ^ tv.tv_usec);
-    }
-    return rand();
-}
-
 static void *
 alloc_openflow_buffer(size_t openflow_len, uint8_t type,
                       struct buffer **bufferp)
@@ -347,7 +333,7 @@ alloc_openflow_buffer(size_t openflow_len, uint8_t type,
        oh->version = OFP_VERSION;
        oh->type = type;
        oh->length = 0;
-       oh->xid = random_xid();
+       oh->xid = random_uint32();
        return oh;
 }