Don't use designated array initializers in code compiled outside of Linux.

Needed for partner builds.
This commit is contained in:
Ben Pfaff committed 2008-09-04 13:53:27 -07:00
1 parent eb0341e711
commit 95204b0bf0
6 files changed
+215 -133

No files matched your search

+14 -6
View File
@@ -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
};
+34 -16
View 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;
+10 -7
View 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;
}
+68 -29
View 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)
+15 -13
View File
@@ -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);
}
}
+74 -62
View 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);
}
/* Packet buffering. */