Example #1
0
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);
}
Example #2
0
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;
}
Example #3
0
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);
}