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 void vr_flush_entry(struct vrouter *router, struct vr_flow_entry *fe, struct vr_flow_md *flmd, struct vr_forwarding_md *fmd) { struct vr_list_node *head; struct vr_packet_node *pnode; struct vr_packet *pkt; struct vr_interface *vif; head = fe->fe_hold_list.node_p; fe->fe_hold_list.node_p = NULL; while (head) { pnode = (struct vr_packet_node *)head; if (fmd) { fmd->fmd_outer_src_ip = pnode->pl_outer_src_ip; fmd->fmd_label = pnode->pl_label; } pkt = pnode->pl_packet; /* * this is only a security check and not a catch all check. one note * of caution. please do not access pkt->vp_if till the if block is * succesfully bypassed */ vif = __vrouter_get_interface(router, pnode->pl_vif_idx); if (!vif || (pkt->vp_if != vif)) { vr_pfree(pkt, VP_DROP_INVALID_IF); goto loop_continue; } if (!pkt->vp_nh) { if (vif_is_fabric(pkt->vp_if) && fmd && (fmd->fmd_label >= 0)) { pkt->vp_nh = __vrouter_get_label(router, fmd->fmd_label); } } vr_flow_action(router, fe, flmd->flmd_index, pkt, pnode->pl_proto, fmd); loop_continue: head = pnode->pl_node.node_n; vr_free(pnode); } return; }
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); }