learning-switch: Avoid violating C aliasing rules initializing actions.
authorBen Pfaff <blp@nicira.com>
Fri, 30 Jul 2010 21:51:35 +0000 (14:51 -0700)
committerBen Pfaff <blp@nicira.com>
Fri, 30 Jul 2010 23:04:29 +0000 (16:04 -0700)
The C standard says that an object that is declared of one particular type
must not be accessed through a pointer to another type, with a few notable
exceptions.  This code was violating those rules, and GCC 4.4 complains
about it.  This commit fixes the problem by using one of the exceptions:
it's always OK to access an object as an array of character type (which is
what memcpy() does implicitly).

Reported-by: Justin Pettit <jpettit@nicira.com>
lib/learning-switch.c

index 22fa70d..aba3525 100644 (file)
@@ -533,22 +533,29 @@ process_packet_in(struct lswitch *sw, struct rconn *rconn, void *opi_)
     out_port = lswitch_choose_destination(sw, &flow);
 
     /* Make actions. */
-    memset(actions, 0, sizeof actions);
     if (out_port == OFPP_NONE) {
         actions_len = 0;
     } else if (sw->queue == UINT32_MAX || out_port >= OFPP_MAX) {
-        struct ofp_action_output *oao = (struct ofp_action_output *) actions;
-        oao->type = htons(OFPAT_OUTPUT);
-        oao->len = htons(sizeof *oao);
-        oao->port = htons(out_port);
-        actions_len = sizeof *oao;
+        struct ofp_action_output oao;
+
+        memset(&oao, 0, sizeof oao);
+        oao.type = htons(OFPAT_OUTPUT);
+        oao.len = htons(sizeof oao);
+        oao.port = htons(out_port);
+
+        memcpy(actions, &oao, sizeof oao);
+        actions_len = sizeof oao;
     } else {
-        struct ofp_action_enqueue *oae = (struct ofp_action_enqueue *) actions;
-        oae->type = htons(OFPAT_ENQUEUE);
-        oae->len = htons(sizeof *oae);
-        oae->port = htons(out_port);
-        oae->queue_id = htonl(sw->queue);
-        actions_len = sizeof *oae;
+        struct ofp_action_enqueue oae;
+
+        memset(&oae, 0, sizeof oae);
+        oae.type = htons(OFPAT_ENQUEUE);
+        oae.len = htons(sizeof oae);
+        oae.port = htons(out_port);
+        oae.queue_id = htonl(sw->queue);
+
+        memcpy(actions, &oae, sizeof oae);
+        actions_len = sizeof oae;
     }
     assert(actions_len <= sizeof actions);