From: Ben Pfaff Date: Fri, 27 Jun 2008 17:52:11 +0000 (-0700) Subject: Add utility functions for generating random numbers, and use where appropriate. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7225d06a782d071a05362f356b81fdc060aa8981;p=openvswitch Add utility functions for generating random numbers, and use where appropriate. --- diff --git a/include/Makefile.am b/include/Makefile.am index 6a839f2b..ec938310 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -21,6 +21,7 @@ noinst_HEADERS = \ packets.h \ poll-loop.h \ queue.h \ + random.h \ rconn.h \ socket-util.h \ util.h \ diff --git a/include/packets.h b/include/packets.h index b4a5f05a..9ba55314 100644 --- a/include/packets.h +++ b/include/packets.h @@ -35,6 +35,7 @@ #include #include +#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 index 00000000..92e2cb3b --- /dev/null +++ b/include/random.h @@ -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 +#include + +void random_bytes(void *, size_t); +uint32_t random_uint32(void); + +#endif /* random.h */ diff --git a/lib/Makefile.am b/lib/Makefile.am index bd86fa1a..719f827b 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -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 index 00000000..55507e02 --- /dev/null +++ b/lib/random.c @@ -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 +#include +#include + +#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; +} diff --git a/switch/datapath.c b/switch/datapath.c index 4c4aa860..e1ba2b92 100644 --- a/switch/datapath.c +++ b/switch/datapath.c @@ -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 diff --git a/utilities/dpctl.c b/utilities/dpctl.c index 334fb816..29f67cdd 100644 --- a/utilities/dpctl.c +++ b/utilities/dpctl.c @@ -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[]) /* 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; }