[ovs-dev] [ofp-print 16/18] Make compiler complain about unhandled OpenFlow and Nicira action types.
Ben Pfaff
blp at nicira.com
Thu Dec 9 00:27:08 UTC 2010
This should help avoid forgetting about them in the future, because the
compiler will complain about unhandled values in switch statements.
---
lib/ofp-print.c | 115 ++++++++++++++++++++--------------------------------
lib/ofp-util.c | 18 ++++++--
ofproto/ofproto.c | 9 ++--
3 files changed, 63 insertions(+), 79 deletions(-)
diff --git a/lib/ofp-print.c b/lib/ofp-print.c
index fc18390..7155125 100644
--- a/lib/ofp-print.c
+++ b/lib/ofp-print.c
@@ -202,7 +202,11 @@ 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)) {
+ enum nx_action_subtype subtype = ntohs(nah->subtype);
+ switch (subtype) {
+ case NXAST_SNAT__OBSOLETE:
+ break;
+
case NXAST_RESUBMIT: {
const struct nx_action_resubmit *nar = (struct nx_action_resubmit *)nah;
ds_put_format(string, "resubmit:");
@@ -236,9 +240,36 @@ ofp_print_nx_action(struct ds *string, const struct nx_action_header *nah)
print_note(string, (const struct nx_action_note *) nah);
break;
+ case NXAST_REG_MOVE:
+ case NXAST_REG_LOAD:
+ /* XXX */
+ break;
+
default:
- ds_put_format(string, "***unknown Nicira action:%d***",
+ ds_put_format(string, "***unknown Nicira action:%"PRIu16"***",
ntohs(nah->subtype));
+ break;
+ }
+}
+
+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 +277,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 +289,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 +300,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 +421,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 2bd2283..b2723ca 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);
@@ -1680,6 +1681,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) {
@@ -1689,7 +1691,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:
@@ -1716,6 +1725,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);
}
@@ -1725,9 +1735,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) {
@@ -1776,8 +1787,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 d5f258f..5799b4e 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;
}
}
--
1.7.1
More information about the dev
mailing list