static int vr_do_flow_action(struct vrouter *router, struct vr_flow_entry *fe, unsigned int index, struct vr_packet *pkt, unsigned short proto, struct vr_forwarding_md *fmd) { uint32_t new_stats; new_stats = __sync_add_and_fetch(&fe->fe_stats.flow_bytes, pkt_len(pkt)); if (new_stats < pkt_len(pkt)) fe->fe_stats.flow_bytes_oflow++; new_stats = __sync_add_and_fetch(&fe->fe_stats.flow_packets, 1); if (!new_stats) fe->fe_stats.flow_packets_oflow++; if (fe->fe_action == VR_FLOW_ACTION_HOLD) { if (vr_flow_queue_is_empty(router, fe)) { vr_trap_flow(router, fe, pkt, index); return vr_enqueue_flow(fe, pkt, proto, fmd); } else { vr_pfree(pkt, VP_DROP_FLOW_UNUSABLE); return 0; } } return vr_flow_action(router, fe, index, pkt, proto, fmd); }
static flow_result_t vr_do_flow_action(struct vrouter *router, struct vr_flow_entry *fe, unsigned int index, struct vr_packet *pkt, struct vr_forwarding_md *fmd) { uint32_t new_stats; new_stats = __sync_add_and_fetch(&fe->fe_stats.flow_bytes, pkt_len(pkt)); if (new_stats < pkt_len(pkt)) fe->fe_stats.flow_bytes_oflow++; new_stats = __sync_add_and_fetch(&fe->fe_stats.flow_packets, 1); if (!new_stats) fe->fe_stats.flow_packets_oflow++; if (fe->fe_action == VR_FLOW_ACTION_HOLD) { vr_enqueue_flow(router, fe, pkt, index, fmd); return FLOW_HELD; } return vr_flow_action(router, fe, index, pkt, fmd); }