From: Ben Pfaff Date: Thu, 9 Dec 2010 18:41:32 +0000 (-0800) Subject: Make compiler complain about unhandled OpenFlow and Nicira action types. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e41a91300789b03398007ebdb6025ca9d94fec26;p=openvswitch Make compiler complain about unhandled OpenFlow and Nicira action types. This should help avoid forgetting about them in the future, because the compiler will complain about unhandled values in switch statements. --- diff --git a/lib/ofp-print.c b/lib/ofp-print.c index 840356c5..26d11489 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -37,6 +37,7 @@ #include "openflow/nicira-ext.h" #include "packets.h" #include "pcap.h" +#include "type-props.h" #include "util.h" static void ofp_print_port_name(struct ds *string, uint16_t port); @@ -202,43 +203,74 @@ print_note(struct ds *string, const struct nx_action_note *nan) static void ofp_print_nx_action(struct ds *string, const struct nx_action_header *nah) { - switch (ntohs(nah->subtype)) { - case NXAST_RESUBMIT: { - const struct nx_action_resubmit *nar = (struct nx_action_resubmit *)nah; - ds_put_format(string, "resubmit:"); - ofp_print_port_name(string, ntohs(nar->in_port)); - break; - } + uint16_t subtype = ntohs(nah->subtype); + + if (subtype <= TYPE_MAXIMUM(enum nx_action_subtype)) { + const struct nx_action_set_tunnel *nast; + const struct nx_action_set_queue *nasq; + const struct nx_action_resubmit *nar; + + switch ((enum nx_action_subtype) subtype) { + case NXAST_RESUBMIT: + nar = (struct nx_action_resubmit *)nah; + ds_put_format(string, "resubmit:"); + ofp_print_port_name(string, ntohs(nar->in_port)); + return; - case NXAST_SET_TUNNEL: { - const struct nx_action_set_tunnel *nast = - (struct nx_action_set_tunnel *)nah; - ds_put_format(string, "set_tunnel:%#"PRIx32, ntohl(nast->tun_id)); - break; - } + case NXAST_SET_TUNNEL: + nast = (struct nx_action_set_tunnel *)nah; + ds_put_format(string, "set_tunnel:%#"PRIx32, ntohl(nast->tun_id)); + return; - case NXAST_DROP_SPOOFED_ARP: - ds_put_cstr(string, "drop_spoofed_arp"); - break; + case NXAST_DROP_SPOOFED_ARP: + ds_put_cstr(string, "drop_spoofed_arp"); + return; - case NXAST_SET_QUEUE: { - const struct nx_action_set_queue *nasq = - (struct nx_action_set_queue *)nah; - ds_put_format(string, "set_queue:%u", ntohl(nasq->queue_id)); - break; - } + case NXAST_SET_QUEUE: + nasq = (struct nx_action_set_queue *)nah; + ds_put_format(string, "set_queue:%u", ntohl(nasq->queue_id)); + return; - case NXAST_POP_QUEUE: - ds_put_cstr(string, "pop_queue"); - break; + case NXAST_POP_QUEUE: + ds_put_cstr(string, "pop_queue"); + return; - case NXAST_NOTE: - print_note(string, (const struct nx_action_note *) nah); - break; + case NXAST_NOTE: + print_note(string, (const struct nx_action_note *) nah); + return; - default: - ds_put_format(string, "***unknown Nicira action:%d***", - ntohs(nah->subtype)); + case NXAST_REG_MOVE: + case NXAST_REG_LOAD: + /* XXX */ + return; + + case NXAST_SNAT__OBSOLETE: + default: + break; + } + } + + ds_put_format(string, "***unknown Nicira action:%"PRIu16"***", subtype); +} + +static int +ofp_action_len(enum ofp_action_type type) +{ + switch (type) { + case OFPAT_OUTPUT: return sizeof(struct ofp_action_output); + case OFPAT_SET_VLAN_VID: return sizeof(struct ofp_action_vlan_vid); + case OFPAT_SET_VLAN_PCP: return sizeof(struct ofp_action_vlan_pcp); + case OFPAT_STRIP_VLAN: return sizeof(struct ofp_action_header); + case OFPAT_SET_DL_SRC: return sizeof(struct ofp_action_dl_addr); + case OFPAT_SET_DL_DST: return sizeof(struct ofp_action_dl_addr); + case OFPAT_SET_NW_SRC: return sizeof(struct ofp_action_nw_addr); + case OFPAT_SET_NW_DST: return sizeof(struct ofp_action_nw_addr); + case OFPAT_SET_NW_TOS: return sizeof(struct ofp_action_nw_tos); + case OFPAT_SET_TP_SRC: return sizeof(struct ofp_action_tp_port); + case OFPAT_SET_TP_DST: return sizeof(struct ofp_action_tp_port); + case OFPAT_ENQUEUE: return sizeof(struct ofp_action_enqueue); + case OFPAT_VENDOR: return -1; + default: return -1; } } @@ -246,66 +278,10 @@ static int ofp_print_action(struct ds *string, const struct ofp_action_header *ah, size_t actions_len) { - uint16_t type; + enum ofp_action_type type; + int required_len; size_t len; - struct openflow_action { - size_t min_size; - size_t max_size; - }; - - const struct openflow_action of_actions[] = { - [OFPAT_OUTPUT] = { - sizeof(struct ofp_action_output), - sizeof(struct ofp_action_output), - }, - [OFPAT_SET_VLAN_VID] = { - sizeof(struct ofp_action_vlan_vid), - sizeof(struct ofp_action_vlan_vid), - }, - [OFPAT_SET_VLAN_PCP] = { - sizeof(struct ofp_action_vlan_pcp), - sizeof(struct ofp_action_vlan_pcp), - }, - [OFPAT_STRIP_VLAN] = { - sizeof(struct ofp_action_header), - sizeof(struct ofp_action_header), - }, - [OFPAT_SET_DL_SRC] = { - sizeof(struct ofp_action_dl_addr), - sizeof(struct ofp_action_dl_addr), - }, - [OFPAT_SET_DL_DST] = { - sizeof(struct ofp_action_dl_addr), - sizeof(struct ofp_action_dl_addr), - }, - [OFPAT_SET_NW_SRC] = { - sizeof(struct ofp_action_nw_addr), - sizeof(struct ofp_action_nw_addr), - }, - [OFPAT_SET_NW_DST] = { - sizeof(struct ofp_action_nw_addr), - sizeof(struct ofp_action_nw_addr), - }, - [OFPAT_SET_NW_TOS] = { - sizeof(struct ofp_action_nw_tos), - sizeof(struct ofp_action_nw_tos), - }, - [OFPAT_SET_TP_SRC] = { - sizeof(struct ofp_action_tp_port), - sizeof(struct ofp_action_tp_port), - }, - [OFPAT_SET_TP_DST] = { - sizeof(struct ofp_action_tp_port), - sizeof(struct ofp_action_tp_port), - }, - [OFPAT_ENQUEUE] = { - sizeof(struct ofp_action_enqueue), - sizeof(struct ofp_action_enqueue), - } - /* OFPAT_VENDOR is not here, since it would blow up the array size. */ - }; - if (actions_len < sizeof *ah) { ds_put_format(string, "***action array too short for next action***\n"); return -1; @@ -314,7 +290,7 @@ ofp_print_action(struct ds *string, const struct ofp_action_header *ah, type = ntohs(ah->type); len = ntohs(ah->len); if (actions_len < len) { - ds_put_format(string, "***truncated action %"PRIu16"***\n", type); + ds_put_format(string, "***truncated action %d***\n", (int) type); return -1; } @@ -325,18 +301,16 @@ ofp_print_action(struct ds *string, const struct ofp_action_header *ah, if ((len % OFP_ACTION_ALIGN) != 0) { ds_put_format(string, - "***action %"PRIu16" length not a multiple of %d***\n", - type, OFP_ACTION_ALIGN); + "***action %d length not a multiple of %d***\n", + (int) type, OFP_ACTION_ALIGN); return -1; } - if (type < ARRAY_SIZE(of_actions)) { - const struct openflow_action *act = &of_actions[type]; - if ((len < act->min_size) || (len > act->max_size)) { - ds_put_format(string, - "***action %"PRIu16" wrong length: %zu***\n", type, len); - return -1; - } + required_len = ofp_action_len(type); + if (required_len >= 0 && len != required_len) { + ds_put_format(string, + "***action %d wrong length: %zu***\n", (int) type, len); + return -1; } switch (type) { @@ -448,7 +422,7 @@ ofp_print_action(struct ds *string, const struct ofp_action_header *ah, } default: - ds_put_format(string, "(decoder %"PRIu16" not implemented)", type); + ds_put_format(string, "(decoder %d not implemented)", (int) type); break; } diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 50dd1371..88851f84 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -25,6 +25,7 @@ #include "ofpbuf.h" #include "packets.h" #include "random.h" +#include "type-props.h" #include "vlog.h" VLOG_DEFINE_THIS_MODULE(ofp_util); @@ -1686,6 +1687,7 @@ check_nicira_action(const union ofp_action *a, unsigned int len, const struct flow *flow) { const struct nx_action_header *nah; + uint16_t subtype; int error; if (len < 16) { @@ -1695,7 +1697,14 @@ check_nicira_action(const union ofp_action *a, unsigned int len, } nah = (const struct nx_action_header *) a; - switch (ntohs(nah->subtype)) { + subtype = ntohs(nah->subtype); + if (subtype > TYPE_MAXIMUM(enum nx_action_subtype)) { + /* This is necessary because enum nx_action_subtype is probably an + * 8-bit type, so the cast below throws away the top 8 bits. */ + return ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_VENDOR_TYPE); + } + + switch ((enum nx_action_subtype) subtype) { case NXAST_RESUBMIT: case NXAST_SET_TUNNEL: case NXAST_DROP_SPOOFED_ARP: @@ -1722,6 +1731,7 @@ check_nicira_action(const union ofp_action *a, unsigned int len, case NXAST_NOTE: return 0; + case NXAST_SNAT__OBSOLETE: default: return ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_VENDOR_TYPE); } @@ -1731,9 +1741,10 @@ static int check_action(const union ofp_action *a, unsigned int len, const struct flow *flow, int max_ports) { + enum ofp_action_type type = ntohs(a->type); int error; - switch (ntohs(a->type)) { + switch (type) { case OFPAT_OUTPUT: error = check_action_exact_len(a, len, 8); if (error) { @@ -1782,8 +1793,7 @@ check_action(const union ofp_action *a, unsigned int len, return check_enqueue_action(a, len, max_ports); default: - VLOG_WARN_RL(&bad_ofmsg_rl, "unknown action type %"PRIu16, - ntohs(a->type)); + VLOG_WARN_RL(&bad_ofmsg_rl, "unknown action type %d", (int) type); return ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_TYPE); } } diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index d5f258ff..5799b4e2 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -2836,7 +2836,7 @@ xlate_nicira_action(struct action_xlate_ctx *ctx, const struct nx_action_set_tunnel *nast; const struct nx_action_set_queue *nasq; union odp_action *oa; - int subtype = ntohs(nah->subtype); + enum nx_action_subtype subtype = ntohs(nah->subtype); assert(nah->vendor == htonl(NX_VENDOR_ID)); switch (subtype) { @@ -2881,8 +2881,9 @@ xlate_nicira_action(struct action_xlate_ctx *ctx, /* If you add a new action here that modifies flow data, don't forget to * update the flow key in ctx->flow at the same time. */ + case NXAST_SNAT__OBSOLETE: default: - VLOG_DBG_RL(&rl, "unknown Nicira action type %"PRIu16, subtype); + VLOG_DBG_RL(&rl, "unknown Nicira action type %d", (int) subtype); break; } } @@ -2904,7 +2905,7 @@ do_xlate_actions(const union ofp_action *in, size_t n_in, } for (ia = actions_first(&iter, in, n_in); ia; ia = actions_next(&iter)) { - uint16_t type = ntohs(ia->type); + enum ofp_action_type type = ntohs(ia->type); union odp_action *oa; switch (type) { @@ -2980,7 +2981,7 @@ do_xlate_actions(const union ofp_action *in, size_t n_in, break; default: - VLOG_DBG_RL(&rl, "unknown action type %"PRIu16, type); + VLOG_DBG_RL(&rl, "unknown action type %d", (int) type); break; } }