From: Andy Zhou Date: Tue, 8 Apr 2014 18:32:57 +0000 (-0700) Subject: dpif-netdev: preserve packet metadata fields across recirculation X-Git-Tag: sliver-openvswitch-2.2.90-1~5^2~11 X-Git-Url: http://git.onelab.eu/?p=sliver-openvswitch.git;a=commitdiff_plain;h=4347b9b38e75ddb30975039ae95eade9efe5be3e dpif-netdev: preserve packet metadata fields across recirculation If the actions executed during recirculation changed metadata fields, then any actions after the recirculation returns would see those new values. Now, all metadata are saved and restored across a recirculation. Signed-off-by: Andy Zhou Acked-by: Ben Pfaff --- diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 423daba61..9fc51db02 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -2140,33 +2140,31 @@ dp_execute_cb(void *aux_, struct ofpbuf *packet, case OVS_ACTION_ATTR_RECIRC: if (*depth < MAX_RECIRC_DEPTH) { - uint32_t old_recirc_id = md->recirc_id; - uint32_t old_dp_hash = md->dp_hash; - const struct ovs_action_recirc *act; + struct pkt_metadata recirc_md = *md; struct ofpbuf *recirc_packet; + const struct ovs_action_recirc *act; recirc_packet = may_steal ? packet : ofpbuf_clone(packet); act = nl_attr_get(a); - md->recirc_id = act->recirc_id; - md->dp_hash = 0; + recirc_md.recirc_id = act->recirc_id; + recirc_md.dp_hash = 0; if (act->hash_alg == OVS_RECIRC_HASH_ALG_L4) { struct flow flow; flow_extract(recirc_packet, md, &flow); - md->dp_hash = flow_hash_symmetric_l4(&flow, act->hash_bias); - if (!md->dp_hash) { - md->dp_hash = 1; /* 0 is not valid */ + recirc_md.dp_hash = flow_hash_symmetric_l4(&flow, + act->hash_bias); + if (!recirc_md.dp_hash) { + recirc_md.dp_hash = 1; /* 0 is not valid */ } } (*depth)++; - dp_netdev_input(aux->dp, recirc_packet, md); + dp_netdev_input(aux->dp, recirc_packet, &recirc_md); (*depth)--; - md->recirc_id = old_recirc_id; - md->recirc_id = old_dp_hash; break; } else { VLOG_WARN("Packet dropped. Max recirculation depth exceeded.");