From e5b7c919ee7f0db3e4ddb59dd12ab40eaab3e953 Mon Sep 17 00:00:00 2001 From: "Anand H. Krishnan" Date: Thu, 26 Feb 2015 21:11:16 +0530 Subject: [PATCH] Allocate hold array when the action is set as 'hold' in the flow table entry HOLD is an action that is allowed to be set in a flow entry. Agent can set HOLD as action and expect the first packet to be trapped. To hold packets in an entry there needs to be hold list (an array, rather). While this hold list is allocated when a new flow is created by kernel, the hold list is freed once all the cached packets are flushed. A subsequent 'HOLD' set needs to have the hold list allocated so that packets can be cached. Closes BUG: #1425992 Change-Id: Ic32a03f402278a351c72cb6a4f72bafdaad2149c --- dp-core/vr_flow.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/dp-core/vr_flow.c b/dp-core/vr_flow.c index 0e970d9aa..9a51cf377 100644 --- a/dp-core/vr_flow.c +++ b/dp-core/vr_flow.c @@ -449,8 +449,10 @@ vr_enqueue_flow(struct vrouter *router, struct vr_flow_entry *fe, struct vr_flow_queue *vfq = fe->fe_hold_list; struct vr_packet_node *pnode; - if (!vfq) - return -EINVAL; + if (!vfq) { + drop_reason = VP_DROP_FLOW_UNUSABLE; + goto drop; + } i = __sync_fetch_and_add(&vfq->vfq_entries, 1); if (i >= VR_MAX_FLOW_QUEUE_ENTRIES) { @@ -1077,6 +1079,9 @@ vr_flush_entry(struct vrouter *router, struct vr_flow_entry *fe, { struct vr_flow_queue *vfq; + if (fe->fe_action == VR_FLOW_ACTION_HOLD) + return; + vfq = fe->fe_hold_list; if (!vfq) return; @@ -1347,6 +1352,15 @@ vr_flow_set(struct vrouter *router, vr_flow_req *req) fe = vr_add_flow_req(req, &fe_index); if (!fe) return -ENOSPC; + } else { + if ((req->fr_action == VR_FLOW_ACTION_HOLD) && + (fe->fe_action != req->fr_action)) { + if (!fe->fe_hold_list) { + fe->fe_hold_list = vr_zalloc(sizeof(struct vr_flow_queue)); + if (!fe->fe_hold_list) + return -ENOMEM; + } + } } vr_flow_set_mirror(router, req, fe);