Don't use designated array initializers in code compiled outside of Linux.
authorBen Pfaff <blp@nicira.com>
Thu, 4 Sep 2008 20:18:28 +0000 (13:18 -0700)
committerBen Pfaff <blp@nicira.com>
Thu, 4 Sep 2008 20:53:27 +0000 (13:53 -0700)
Needed for partner builds.

include/vlog.h
lib/dhcp.c
lib/learning-switch.c
lib/ofp-print.c
lib/vlog.c
switch/datapath.c

index 7582681..c6980a2 100644 (file)
 #include "util.h"
 
 /* Logging importance levels. */
+#define VLOG_LEVELS                             \
+    VLOG_LEVEL(EMER)                            \
+    VLOG_LEVEL(ERR)                             \
+    VLOG_LEVEL(WARN)                            \
+    VLOG_LEVEL(DBG)
 enum vlog_level {
-    VLL_EMER,
-    VLL_ERR,
-    VLL_WARN,
-    VLL_DBG,
+#define VLOG_LEVEL(NAME) VLL_##NAME,
+    VLOG_LEVELS
+#undef VLOG_LEVEL
     VLL_N_LEVELS
 };
 
@@ -53,9 +57,13 @@ const char *vlog_get_level_name(enum vlog_level);
 enum vlog_level vlog_get_level_val(const char *name);
 
 /* Facilities that we can log to. */
+#define VLOG_FACILITIES                         \
+    VLOG_FACILITY(SYSLOG)                       \
+    VLOG_FACILITY(CONSOLE)
 enum vlog_facility {
-    VLF_SYSLOG,
-    VLF_CONSOLE,
+#define VLOG_FACILITY(NAME) VLF_##NAME,
+    VLOG_FACILITIES
+#undef VLOG_FACILITY
     VLF_N_FACILITIES,
     VLF_ANY_FACILITY = -1
 };
index 4a27328..270e491 100644 (file)
@@ -65,13 +65,35 @@ struct option_class {
     size_t max_args;            /* Maximum number of arguments. */
 };
 
-static struct option_class classes[DHCP_N_OPTIONS] = {
-    [0 ... 255] = {NULL, DHCP_ARG_UINT8, 0, SIZE_MAX},
-#define DHCP_OPT(NAME, CODE, TYPE, MIN, MAX) \
-    [CODE] = {#NAME, DHCP_ARG_##TYPE, MIN, MAX},
-    DHCP_OPTS
+static const struct option_class *
+get_option_class(int code)
+{
+    static struct option_class classes[DHCP_N_OPTIONS];
+    static bool init = false;
+    if (!init) {
+        int i;
+
+        init = true;
+#define DHCP_OPT(NAME, CODE, TYPE, MIN, MAX)    \
+        classes[CODE].name = #NAME;             \
+        classes[CODE].type = DHCP_ARG_##TYPE;   \
+        classes[CODE].min_args = MIN;           \
+        classes[CODE].max_args = MAX;
+        DHCP_OPTS
 #undef DHCP_OPT
-};
+
+        for (i = 0; i < DHCP_N_OPTIONS; i++) {
+            if (!classes[i].name) {
+                classes[i].name = xasprintf("option-%d", i);
+                classes[i].type = DHCP_ARG_UINT8;
+                classes[i].min_args = 0;
+                classes[i].max_args = SIZE_MAX;
+            }
+        }
+    }
+    assert(code >= 0 && code < DHCP_N_OPTIONS);
+    return &classes[code];
+}
 
 /* A single (bad) DHCP message can in theory dump out many, many log messages,
  * especially at high logging levels, so the burst size is set quite high
@@ -409,18 +431,14 @@ put_duration(struct ds *ds, unsigned int duration)
 const char *
 dhcp_option_to_string(const struct dhcp_option *opt, int code, struct ds *ds)
 {
-    struct option_class *class = &classes[code];
+    const struct option_class *class = get_option_class(code);
     const struct arg_type *type = &types[class->type];
     size_t offset;
+    const char *cp;
 
-    if (class->name) {
-        const char *cp;
-        for (cp = class->name; *cp; cp++) {
-            unsigned char c = *cp;
-            ds_put_char(ds, c == '_' ? '-' : tolower(c));
-        }
-    } else {
-        ds_put_format(ds, "option-%d", code);
+    for (cp = class->name; *cp; cp++) {
+        unsigned char c = *cp;
+        ds_put_char(ds, c == '_' ? '-' : tolower(c));
     }
     ds_put_char(ds, '=');
 
@@ -597,7 +615,7 @@ validate_options(struct dhcp_msg *msg)
 
     for (code = 0; code < DHCP_N_OPTIONS; code++) {
         struct dhcp_option *opt = &msg->options[code];
-        struct option_class *class = &classes[code];
+        const struct option_class *class = get_option_class(code);
         struct arg_type *type = &types[class->type];
         if (opt->data) {
             size_t n_elems = opt->n / type->size;
index 4a46a0f..e118405 100644 (file)
@@ -111,6 +111,14 @@ lswitch_destroy(struct lswitch *sw)
     }
 }
 
+static size_t
+min_size(uint8_t type)
+{
+    return (type == OFPT_FEATURES_REPLY ? sizeof(struct ofp_switch_features)
+            : type == OFPT_PACKET_IN ? offsetof (struct ofp_packet_in, data)
+            : sizeof(struct ofp_header));
+}
+
 /* Processes 'msg', which should be an OpenFlow received on 'rconn', according
  * to the learning switch state in 'sw'.  The most likely result of processing
  * is that flow-setup and packet-out OpenFlow messages will be sent out on
@@ -119,19 +127,14 @@ void
 lswitch_process_packet(struct lswitch *sw, struct rconn *rconn,
                        const struct ofpbuf *msg)
 {
-    static const size_t min_size[UINT8_MAX + 1] = {
-        [0 ... UINT8_MAX] = sizeof (struct ofp_header),
-        [OFPT_FEATURES_REPLY] = sizeof (struct ofp_switch_features),
-        [OFPT_PACKET_IN] = offsetof (struct ofp_packet_in, data),
-    };
     struct ofp_header *oh;
 
     oh = msg->data;
-    if (msg->size < min_size[oh->type]) {
+    if (msg->size < min_size(oh->type)) {
         VLOG_WARN_RL(&rl,
                      "%s: too short (%zu bytes) for type %"PRIu8" (min %zu)",
                      rconn_get_name(rconn),
-                     msg->size, oh->type, min_size[oh->type]);
+                     msg->size, oh->type, min_size(oh->type));
         return;
     }
 
index 2729c14..6f0957a 100644 (file)
@@ -847,25 +847,29 @@ print_stats(struct ds *string, int type, const void *body, size_t body_len,
     };
 
     struct stats_type {
+        int type;
         const char *name;
         struct stats_msg request;
         struct stats_msg reply;
     };
 
     static const struct stats_type stats_types[] = {
-        [OFPST_DESC] = {
+        {
+            OFPST_DESC,
             "description",
             { 0, 0, NULL },
             { 0, SIZE_MAX, ofp_desc_stats_reply },
         },
-        [OFPST_FLOW] = {
+        {
+            OFPST_FLOW,
             "flow",
             { sizeof(struct ofp_flow_stats_request),
               sizeof(struct ofp_flow_stats_request),
               ofp_flow_stats_request },
             { 0, SIZE_MAX, ofp_flow_stats_reply },
         },
-        [OFPST_AGGREGATE] = {
+        {
+            OFPST_AGGREGATE,
             "aggregate",
             { sizeof(struct ofp_aggregate_stats_request),
               sizeof(struct ofp_aggregate_stats_request),
@@ -874,21 +878,30 @@ print_stats(struct ds *string, int type, const void *body, size_t body_len,
               sizeof(struct ofp_aggregate_stats_reply),
               ofp_aggregate_stats_reply },
         },
-        [OFPST_TABLE] = {
+        {
+            OFPST_TABLE,
             "table",
             { 0, 0, NULL },
             { 0, SIZE_MAX, ofp_table_stats_reply },
         },
-        [OFPST_PORT] = {
+        {
+            OFPST_PORT,
             "port",
             { 0, 0, NULL, },
             { 0, SIZE_MAX, ofp_port_stats_reply },
         },
-        [OFPST_SWITCH] = {
+        {
+            OFPST_SWITCH,
             "switch status",
             { 0, 0, NULL, },
             { 0, SIZE_MAX, switch_status_reply },
         },
+        {
+            -1,
+            "unknown",
+            { 0, 0, NULL, },
+            { 0, 0, NULL, },
+        },
     };
 
     const struct stats_type *s;
@@ -898,7 +911,11 @@ print_stats(struct ds *string, int type, const void *body, size_t body_len,
         ds_put_format(string, " ***unknown type %d***", type);
         return;
     }
-    s = &stats_types[type];
+    for (s = stats_types; s->type >= 0; s++) {
+        if (s->type == type) {
+            break;
+        }
+    }
     ds_put_format(string, " type=%d(%s)\n", type, s->name);
 
     m = direction == REQUEST ? &s->request : &s->reply;
@@ -963,88 +980,105 @@ ofp_echo(struct ds *string, const void *oh, size_t len, int verbosity)
 }
 
 struct openflow_packet {
+    uint8_t type;
     const char *name;
     size_t min_size;
     void (*printer)(struct ds *, const void *, size_t len, int verbosity);
 };
 
 static const struct openflow_packet packets[] = {
-    [OFPT_FEATURES_REQUEST] = {
+    {
+        OFPT_FEATURES_REQUEST,
         "features_request",
         sizeof (struct ofp_header),
         NULL,
     },
-    [OFPT_FEATURES_REPLY] = {
+    {
+        OFPT_FEATURES_REPLY,
         "features_reply",
         sizeof (struct ofp_switch_features),
         ofp_print_switch_features,
     },
-    [OFPT_GET_CONFIG_REQUEST] = {
+    {
+        OFPT_GET_CONFIG_REQUEST,
         "get_config_request",
         sizeof (struct ofp_header),
         NULL,
     },
-    [OFPT_GET_CONFIG_REPLY] = {
+    {
+        OFPT_GET_CONFIG_REPLY,
         "get_config_reply",
         sizeof (struct ofp_switch_config),
         ofp_print_switch_config,
     },
-    [OFPT_SET_CONFIG] = {
+    {
+        OFPT_SET_CONFIG,
         "set_config",
         sizeof (struct ofp_switch_config),
         ofp_print_switch_config,
     },
-    [OFPT_PACKET_IN] = {
+    {
+        OFPT_PACKET_IN,
         "packet_in",
         offsetof(struct ofp_packet_in, data),
         ofp_packet_in,
     },
-    [OFPT_PACKET_OUT] = {
+    {
+        OFPT_PACKET_OUT,
         "packet_out",
         sizeof (struct ofp_packet_out),
         ofp_packet_out,
     },
-    [OFPT_FLOW_MOD] = {
+    {
+        OFPT_FLOW_MOD,
         "flow_mod",
         sizeof (struct ofp_flow_mod),
         ofp_print_flow_mod,
     },
-    [OFPT_FLOW_EXPIRED] = {
+    {
+        OFPT_FLOW_EXPIRED,
         "flow_expired",
         sizeof (struct ofp_flow_expired),
         ofp_print_flow_expired,
     },
-    [OFPT_PORT_MOD] = {
+    {
+        OFPT_PORT_MOD,
         "port_mod",
         sizeof (struct ofp_port_mod),
         NULL,
     },
-    [OFPT_PORT_STATUS] = {
+    {
+        OFPT_PORT_STATUS,
         "port_status",
         sizeof (struct ofp_port_status),
         ofp_print_port_status
     },
-    [OFPT_ERROR_MSG] = {
+    {
+        OFPT_ERROR_MSG,
         "error_msg",
         sizeof (struct ofp_error_msg),
         ofp_print_error_msg,
     },
-    [OFPT_STATS_REQUEST] = {
+    {
+        OFPT_STATS_REQUEST,
         "stats_request",
         sizeof (struct ofp_stats_request),
         ofp_stats_request,
     },
-    [OFPT_STATS_REPLY] = {
+    {
+        OFPT_STATS_REPLY,
         "stats_reply",
         sizeof (struct ofp_stats_reply),
         ofp_stats_reply,
     },
-    [OFPT_ECHO_REQUEST] = {
+    {
+        OFPT_ECHO_REQUEST,
         "echo_request",
         sizeof (struct ofp_header),
         ofp_echo,
     },
-    [OFPT_ECHO_REPLY] = {
+    {
+        OFPT_ECHO_REPLY,
         "echo_reply",
         sizeof (struct ofp_header),
         ofp_echo,
@@ -1070,14 +1104,19 @@ ofp_to_string(const void *oh_, size_t len, int verbosity)
         ds_put_format(&string, "Bad OpenFlow version %"PRIu8":\n", oh->version);
         ds_put_hex_dump(&string, oh, len, 0, true);
         return ds_cstr(&string);
-    } else if (oh->type >= ARRAY_SIZE(packets) || !packets[oh->type].name) {
-        ds_put_format(&string, "Unknown OpenFlow packet type %"PRIu8":\n",
-                oh->type);
-        ds_put_hex_dump(&string, oh, len, 0, true);
-        return ds_cstr(&string);
     }
 
-    pkt = &packets[oh->type];
+    for (pkt = packets; ; pkt++) {
+        if (pkt >= &packets[ARRAY_SIZE(packets)]) {
+            ds_put_format(&string, "Unknown OpenFlow packet type %"PRIu8":\n",
+                          oh->type);
+            ds_put_hex_dump(&string, oh, len, 0, true);
+            return ds_cstr(&string);
+        } else if (oh->type == pkt->type) {
+            break;
+        }
+    }
+
     ds_put_format(&string, "%s (xid=0x%"PRIx32"):", pkt->name, oh->xid);
 
     if (ntohs(oh->length) > len)
index bfe74fd..a136e56 100644 (file)
 
 /* Name for each logging level. */
 static const char *level_names[VLL_N_LEVELS] = {
-    [VLL_EMER] = "EMER",
-    [VLL_ERR] = "ERR",
-    [VLL_WARN] = "WARN",
-    [VLL_DBG] = "DBG",
+#define VLOG_LEVEL(NAME) #NAME,
+    VLOG_LEVELS
+#undef VLOG_LEVEL
 };
 
 /* Name for each logging facility. */
 static const char *facility_names[VLF_N_FACILITIES] = { 
-    [VLF_CONSOLE] = "console",
-    [VLF_SYSLOG] = "syslog",
+#define VLOG_FACILITY(NAME) #NAME,
+    VLOG_FACILITIES
+#undef VLOG_FACILITY
 };
 
 /* Name for each logging module */
@@ -341,18 +341,20 @@ vlog_valist(enum vlog_module module, enum vlog_level level,
         }
 
         if (log_syslog) {
-            static const int syslog_levels[VLL_N_LEVELS] = {
-                [VLL_EMER] = LOG_ALERT,
-                [VLL_ERR] = LOG_ERR,
-                [VLL_WARN] = LOG_WARNING,
-                [VLL_DBG] = LOG_DEBUG,
-            };
+            int syslog_level = LOG_ALERT;
             char *save_ptr = NULL;
             char *line;
 
+            switch (level) {
+            case VLL_EMER: syslog_level = LOG_ALERT; break;
+            case VLL_ERR: syslog_level = LOG_ERR; break;
+            case VLL_WARN: syslog_level = LOG_WARNING; break;
+            case VLL_DBG: syslog_level = LOG_DEBUG; break;
+            case VLL_N_LEVELS: NOT_REACHED();
+            }
             for (line = strtok_r(&s.string[time_len], "\n", &save_ptr); line;
                  line = strtok_r(NULL, "\n", &save_ptr)) {
-                syslog(syslog_levels[level], "%s", line);
+                syslog(syslog_level, "%s", line);
             }
         }
 
index 9619300..1e71411 100644 (file)
@@ -1449,6 +1449,9 @@ static void port_stats_done(void *state)
 }
 
 struct stats_type {
+    /* Value for 'type' member of struct ofp_stats_request. */
+    int type;
+
     /* Minimum and maximum acceptable number of bytes in body member of
      * struct ofp_stats_request. */
     size_t min_body, max_body;
@@ -1473,35 +1476,40 @@ struct stats_type {
 };
 
 static const struct stats_type stats[] = {
-    [OFPST_DESC] = {
+    {
+        OFPST_DESC,
         0,
         0,
         NULL,
         desc_stats_dump,
         NULL
     },
-    [OFPST_FLOW] = {
+    {
+        OFPST_FLOW,
         sizeof(struct ofp_flow_stats_request),
         sizeof(struct ofp_flow_stats_request),
         flow_stats_init,
         flow_stats_dump,
         flow_stats_done
     },
-    [OFPST_AGGREGATE] = {
+    {
+        OFPST_AGGREGATE,
         sizeof(struct ofp_aggregate_stats_request),
         sizeof(struct ofp_aggregate_stats_request),
         aggregate_stats_init,
         aggregate_stats_dump,
         aggregate_stats_done
     },
-    [OFPST_TABLE] = {
+    {
+        OFPST_TABLE,
         0,
         0,
         NULL,
         table_stats_dump,
         NULL
     },
-    [OFPST_PORT] = {
+    {
+        OFPST_PORT,
         0,
         0,
         port_stats_init,
@@ -1532,7 +1540,7 @@ stats_dump(struct datapath *dp, void *cb_)
 
     osr = make_openflow_reply(sizeof *osr, OFPT_STATS_REPLY, &cb->sender,
                               &buffer);
-    osr->type = htons(cb->s - stats);
+    osr->type = htons(cb->s->type);
     osr->flags = 0;
 
     err = cb->s->dump(dp, cb->state, buffer);
@@ -1572,21 +1580,27 @@ recv_stats_request(struct datapath *dp, const struct sender *sender,
 {
     const struct ofp_stats_request *rq = oh;
     size_t rq_len = ntohs(rq->header.length);
+    const struct stats_type *st;
     struct stats_dump_cb *cb;
     int type, body_len;
     int err;
 
     type = ntohs(rq->type);
-    if (type >= ARRAY_SIZE(stats) || !stats[type].dump) {
-        VLOG_WARN_RL(&rl, "received stats request of unknown type %d", type);
-        return -EINVAL;
+    for (st = stats; ; st++) {
+        if (st >= &stats[ARRAY_SIZE(stats)]) {
+            VLOG_WARN_RL(&rl, "received stats request of unknown type %d",
+                         type);
+            return -EINVAL;
+        } else if (type == st->type) {
+            break;
+        }
     }
 
     cb = xmalloc(sizeof *cb);
     cb->done = false;
     cb->rq = xmemdup(rq, rq_len);
     cb->sender = *sender;
-    cb->s = &stats[type];
+    cb->s = st;
     cb->state = NULL;
     
     body_len = rq_len - offsetof(struct ofp_stats_request, body);
@@ -1636,65 +1650,63 @@ int
 fwd_control_input(struct datapath *dp, const struct sender *sender,
                   const void *msg, size_t length)
 {
-    struct openflow_packet {
-        size_t min_size;
-        int (*handler)(struct datapath *, const struct sender *, const void *);
-    };
-
-    static const struct openflow_packet packets[] = {
-        [OFPT_FEATURES_REQUEST] = {
-            sizeof (struct ofp_header),
-            recv_features_request,
-        },
-        [OFPT_GET_CONFIG_REQUEST] = {
-            sizeof (struct ofp_header),
-            recv_get_config_request,
-        },
-        [OFPT_SET_CONFIG] = {
-            sizeof (struct ofp_switch_config),
-            recv_set_config,
-        },
-        [OFPT_PACKET_OUT] = {
-            sizeof (struct ofp_packet_out),
-            recv_packet_out,
-        },
-        [OFPT_FLOW_MOD] = {
-            sizeof (struct ofp_flow_mod),
-            recv_flow,
-        },
-        [OFPT_PORT_MOD] = {
-            sizeof (struct ofp_port_mod),
-            recv_port_mod,
-        },
-        [OFPT_STATS_REQUEST] = {
-            sizeof (struct ofp_stats_request),
-            recv_stats_request,
-        },
-        [OFPT_ECHO_REQUEST] = {
-            sizeof (struct ofp_header),
-            recv_echo_request,
-        },
-        [OFPT_ECHO_REPLY] = {
-            sizeof (struct ofp_header),
-            recv_echo_reply,
-        },
-    };
-
-    const struct openflow_packet *pkt;
+    int (*handler)(struct datapath *, const struct sender *, const void *);
     struct ofp_header *oh;
+    size_t min_size;
 
+    /* Check encapsulated length. */
     oh = (struct ofp_header *) msg;
-    assert(oh->version == OFP_VERSION);
-    if (oh->type >= ARRAY_SIZE(packets) || ntohs(oh->length) > length)
+    if (ntohs(oh->length) > length) {
         return -EINVAL;
+    }
+    assert(oh->version == OFP_VERSION);
 
-    pkt = &packets[oh->type];
-    if (!pkt->handler)
+    /* Figure out how to handle it. */
+    switch (oh->type) {
+    case OFPT_FEATURES_REQUEST:
+        min_size = sizeof(struct ofp_header);
+        handler = recv_features_request;
+        break;
+    case OFPT_GET_CONFIG_REQUEST:
+        min_size = sizeof(struct ofp_header);
+        handler = recv_get_config_request;
+        break;
+    case OFPT_SET_CONFIG:
+        min_size = sizeof(struct ofp_switch_config);
+        handler = recv_set_config;
+        break;
+    case OFPT_PACKET_OUT:
+        min_size = sizeof(struct ofp_packet_out);
+        handler = recv_packet_out;
+        break;
+    case OFPT_FLOW_MOD:
+        min_size = sizeof(struct ofp_flow_mod);
+        handler = recv_flow;
+        break;
+    case OFPT_PORT_MOD:
+        min_size = sizeof(struct ofp_port_mod);
+        handler = recv_port_mod;
+        break;
+    case OFPT_STATS_REQUEST:
+        min_size = sizeof(struct ofp_stats_request);
+        handler = recv_stats_request;
+        break;
+    case OFPT_ECHO_REQUEST:
+        min_size = sizeof(struct ofp_header);
+        handler = recv_echo_request;
+        break;
+    case OFPT_ECHO_REPLY:
+        min_size = sizeof(struct ofp_header);
+        handler = recv_echo_reply;
+        break;
+    default:
         return -ENOSYS;
-    if (length < pkt->min_size)
-        return -EFAULT;
+    }
 
-    return pkt->handler(dp, sender, msg);
+    /* Handle it. */
+    if (length < min_size)
+        return -EFAULT;
+    return handler(dp, sender, msg);
 }
 \f
 /* Packet buffering. */