From: Daniele Di Proietto Date: Wed, 18 May 2016 01:38:20 +0000 (-0700) Subject: dpif-netdev: Initialize packet RSS hash in dpif_netdev_execute(). X-Git-Url: http://git.cascardo.eti.br/?a=commitdiff_plain;h=36d8de17ffe5406b26e3f5920374a363ea8bc82f;p=cascardo%2Fovs.git dpif-netdev: Initialize packet RSS hash in dpif_netdev_execute(). The datapath code expects the RSS hash to always be initialized. This is enforced by checking in emc_processing() that the hash is valid, and eventually by computing a new one. Unfortunately, there is another entry point to the datapath, dpif_netdev_execute(). A packet generated by OVS (BFD frame, packet-out from controller) doesn't have a valid RSS hash and so is allowed to enter the datapath with an uninitialized hash value. This commit recomputes the hash (if not valid) in dpif_netdev_execute(). The only place where we would use an invalid hash is netdev-vport, in push_udp_header(). This caused an uninitialized memory read, and a random value to be assigned to the outer tunnel header source port. Reported-by: William Tu Signed-off-by: Daniele Di Proietto Acked-by: William Tu Acked-by: Ben Pfaff --- diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 2677ceabe..dc1c6ad76 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -2364,9 +2364,20 @@ dpif_netdev_execute(struct dpif *dpif, struct dpif_execute *execute) ovs_mutex_lock(&dp->port_mutex); } + /* The action processing expects the RSS hash to be valid, because + * it's always initialized at the beginning of datapath processing. + * In this case, though, 'execute->packet' may not have gone through + * the datapath at all, it may have been generated by the upper layer + * (OpenFlow packet-out, BFD frame, ...). */ + if (!dp_packet_rss_valid(execute->packet)) { + dp_packet_set_rss_hash(execute->packet, + flow_hash_5tuple(execute->flow, 0)); + } + packet_batch_init_packet(&pp, execute->packet); dp_netdev_execute_actions(pmd, &pp, false, execute->actions, execute->actions_len); + if (pmd->core_id == NON_PMD_CORE_ID) { dp_netdev_pmd_unref(pmd); ovs_mutex_unlock(&dp->port_mutex);