Packet metadata fields may be modified when execute post recirculation actions. Current implementation only preserves recirc_id and dp_hash, but not other fields. With this patch, a copy of metadata is supplied instead of the original metadata for recirculation to preserve the original value. --- lib/dpif-netdev.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 423daba..9fc51db 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."); -- 1.7.9.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev