From: Ben Pfaff Date: Thu, 4 Sep 2008 20:18:28 +0000 (-0700) Subject: Don't use designated array initializers in code compiled outside of Linux. X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=95204b0bf0c329fde1ff1ba821f9166abfa18377;hp=eb0341e7118a5a63e7a2696e3e59940668355cba;p=sliver-openvswitch.git Don't use designated array initializers in code compiled outside of Linux. Needed for partner builds. --- diff --git a/include/vlog.h b/include/vlog.h index 7582681a8..c6980a2f9 100644 --- a/include/vlog.h +++ b/include/vlog.h @@ -41,11 +41,15 @@ #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 }; diff --git a/lib/dhcp.c b/lib/dhcp.c index 4a2732832..270e49113 100644 --- a/lib/dhcp.c +++ b/lib/dhcp.c @@ -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; diff --git a/lib/learning-switch.c b/lib/learning-switch.c index 4a46a0f69..e11840514 100644 --- a/lib/learning-switch.c +++ b/lib/learning-switch.c @@ -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; } diff --git a/lib/ofp-print.c b/lib/ofp-print.c index 2729c14b8..6f0957a5b 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -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) diff --git a/lib/vlog.c b/lib/vlog.c index bfe74fde3..a136e5634 100644 --- a/lib/vlog.c +++ b/lib/vlog.c @@ -51,16 +51,16 @@ /* 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); } } diff --git a/switch/datapath.c b/switch/datapath.c index 96193002f..1e71411df 100644 --- a/switch/datapath.c +++ b/switch/datapath.c @@ -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); } /* Packet buffering. */