Пример #1
0
ucli_status_t
vt_ucli_module__perf__(ucli_context_t* uc)
{
    uint64_t last;
    uint64_t now;
    double seconds;
    uint64_t deltat = 2000000;
    int count = 0;
    int direction;
    uint8_t data[128] = {0};
    int misscount = 0;
    int pid = 0;

    UCLI_COMMAND_INFO(uc,
                      "perf", 2,
                      "$summary#Receive performance test."
                      "$args#[send|recv] vpi");

    UCLI_ARGPARSE_OR_RETURN(uc, "{choice}{vpi}",
                            &direction, "direction", 2, "send", "recv",
                            &vtc->vpi);

    count = 0;
    last = os_time_monotonic();
    while(1) {

        if(direction == 0) { /* send */
            *(uint32_t*)(data) = pid++;
            vpi_send(vtc->vpi, data, sizeof(data));
            count++;
        }
        else { /* recv */
            if(vpi_recv__(uc, vtc) > 0) {
                uint32_t rpid = *(uint32_t*)(vtc->data);
                if(pid != rpid) {
                    misscount += (rpid - pid);
                    pid = rpid+1;
                }
                else {
                    pid++;
                }
                count++;
            }
        }

        now = os_time_monotonic();
        if((now - last) > deltat) {
            seconds = 1.0*(now-last)/1000000;
            ucli_printf(uc, "%d packets %s in %f seconds (%f pps) missed=%d\n",
                        count, direction ? "received" : "sent", seconds, count/seconds, misscount);
            count=0;
            last = now;
            misscount=0;
        }
    }
    return UCLI_STATUS_OK;
}
/**
 * LED Handlers
 */
static void
led_update_handler__(netsnmp_request_info *req,
                     uint32_t index,
                     onlp_snmp_sensor_t *ss)
{
    uint64_t current = os_time_monotonic();

    if (SENSOR_NEEDS_UPDATE(current, ss)) {
        onlp_led_info_t *li = &ss->sensor_info.li;
        onlp_oid_t oid = (onlp_oid_t) ss->sensor_id;

        int rv = onlp_led_info_get(oid, li);
        SENSOR_SET_VALIDITY(rv, current, ss);
    }

    /* else use the last update info */
}
Пример #3
0
ucli_status_t
vt_ucli_module__spam__(ucli_context_t* uc)
{
    aim_ratelimiter_t counter_rl;
    aim_ratelimiter_t send_rl;
    int count = 0;
    int last = 0;
    int pps = -1;

    UCLI_COMMAND_INFO(uc,
                      "spam", 3,
                      "$summary#Spam packet data on the given VPI."
                      "$args#<vpi_spec> <packet_data> <pps>");

    UCLI_ARGPARSE_OR_RETURN(uc, "{vpi}{idata}i",
                            &vtc->vpi, vtc->data, &vtc->size, &pps);

    aim_ratelimiter_init(&counter_rl, 1000000, 0, NULL);
    aim_ratelimiter_init(&send_rl, 1000000/pps, 0, NULL);

    for(;;) {
        uint64_t now = os_time_monotonic();
        if(aim_ratelimiter_limit(&counter_rl, now) == 0) {
            ucli_printf(uc, "Sent %d packets - %d pps\n", count,
                        (count - last));
            last = count;

        }
        if(aim_ratelimiter_limit(&send_rl, now) == 0) {
            if(vpi_send(vtc->vpi, vtc->data, vtc->size) < 0) {
                return ucli_error(uc, "vpi_send() failed.");
            }
            count++;
        }
        else {
            os_sleep_usecs(1);
        }
    }
    return UCLI_STATUS_OK;
}
Пример #4
0
static int
os_sem_take_timeout_efd__(os_sem_t sem, uint64_t usecs)
{
    AIM_TRUE_OR_DIE(USES_EFD(sem), "timeout_efd__ called when efd is not valid.");

    /** poll() with timeout (in ms) */
    struct pollfd fds;

    fds.fd = sem->efd;
    fds.events = POLLIN;
    fds.revents = 0;

    uint64_t t_start = os_time_monotonic();
    int timeout_ms;

    if(usecs == 0) {
        /* Infinite timeout value when calling poll() */
        timeout_ms = -1;
    }
    else {
        timeout_ms = usecs / 1000;
    }

    for(;;) {

        int rv = poll(&fds, 1, timeout_ms);

        if(rv == 0) {
            /* Timed out */
            return -1;
        }
        if(rv == 1) {
            if(fds.revents & POLLIN) {
                /* Descriptor Ready */
                uint64_t v;
                if(eventfd_read(sem->efd, &v) == 0) {
                    /* Acquired. */
                    return 0;
                }
                else {
                    /**
                     * Acquired by someone else.
                     * Retry handled along with EINTR below.
                     */
                }
            }
        }
        if(rv == 1 || errno == EINTR) {
            /*
             * Calculate remaining timeout (if necessary) and retry.
             */
            if(timeout_ms != -1) {
                uint64_t now = os_time_monotonic();
                if( (now - t_start) >= usecs ) {
                    /* Total timeout has elapsed */
                    return -1;
                }
                else {
                    /* Remaining time to wait. */
                    timeout_ms = (usecs - (now - t_start) + 999)/1000;
                }
            }
            continue;
        }
        else {
            AIM_DIE("Unexpected return value from poll(): %s", strerror(errno));
        }
    }
}
/*
 * icmp_packet_in_handler
 *
 * API for handling incoming packets
 */
indigo_core_listener_result_t
icmpa_packet_in_handler (of_packet_in_t *packet_in)
{
    of_octets_t                octets;
    of_port_no_t               port_no;
    of_match_t                 match;
    ppe_packet_t               ppep;
    indigo_core_listener_result_t result = INDIGO_CORE_LISTENER_RESULT_PASS;
    uint32_t                   type, code;

    debug_counter_inc(&pkt_counters.icmp_total_in_packets);
    if (!packet_in) return INDIGO_CORE_LISTENER_RESULT_PASS;

    of_packet_in_data_get(packet_in, &octets);

    /*
     * Identify the recv port
     */
    if (packet_in->version <= OF_VERSION_1_1) {
        return INDIGO_CORE_LISTENER_RESULT_PASS;
    } else {
        if (of_packet_in_match_get(packet_in, &match) < 0) {
            AIM_LOG_ERROR("ICMPA: match get failed");
            debug_counter_inc(&pkt_counters.icmp_internal_errors);
            return INDIGO_CORE_LISTENER_RESULT_PASS;
        }
        port_no = match.fields.in_port;
    }

    if (port_no == OF_PORT_DEST_CONTROLLER) {
        debug_counter_inc(&pkt_counters.icmp_total_passed_packets);
        return INDIGO_CORE_LISTENER_RESULT_PASS;
    }

    if (port_no > MAX_PORTS) {
        AIM_LOG_ERROR("ICMPA: Port No: %d Out of Range %d", port_no, MAX_PORTS);
        debug_counter_inc(&pkt_counters.icmp_internal_errors);
        return INDIGO_CORE_LISTENER_RESULT_PASS;
    }

    /*
     * Check the packet-in reasons in metadata
     *
     * Icmp agent should not consume packets coming in due to L2 Src miss
     * and Station Move.
     */
    if ((match.fields.metadata & OFP_BSN_PKTIN_FLAG_STATION_MOVE) ||
        (match.fields.metadata & OFP_BSN_PKTIN_FLAG_NEW_HOST)) {
        debug_counter_inc(&pkt_counters.icmp_total_passed_packets);
        return INDIGO_CORE_LISTENER_RESULT_PASS;
    }

    ppe_packet_init(&ppep, octets.data, octets.bytes);
    if (ppe_parse(&ppep) < 0) {
        AIM_LOG_RL_ERROR(&icmp_pktin_log_limiter, os_time_monotonic(),
                         "ICMPA: Packet_in parsing failed.");
        debug_counter_inc(&pkt_counters.icmp_internal_errors);
        return INDIGO_CORE_LISTENER_RESULT_PASS;
    }

    /*
     * Identify if this is an Echo Request, destined to one of VRouter
     */
    if (ppe_header_get(&ppep, PPE_HEADER_ICMP)) {
        if (icmpa_reply(&ppep, port_no, &result)) {
            ++port_pkt_counters[port_no].icmp_echo_packets;
            return result;
        }
    }

    /*
     * To handle traceroute, we need to check for
     * a) UDP Packet
     * b) dest IP is Vrouter IP
     * c) UDP src and dest ports are ephemeral
     */
    if (ppe_header_get(&ppep, PPE_HEADER_UDP) &&
        ppe_header_get(&ppep, PPE_HEADER_IP4)) {
        uint32_t dest_ip, src_port, dest_port;
        ppe_field_get(&ppep, PPE_FIELD_IP4_DST_ADDR, &dest_ip);
        ppe_field_get(&ppep, PPE_FIELD_UDP_SRC_PORT, &src_port);
        ppe_field_get(&ppep, PPE_FIELD_UDP_DST_PORT, &dest_port);

        if (router_ip_check(dest_ip) && is_ephemeral(src_port) &&
            is_ephemeral(dest_port)) {
            AIM_LOG_TRACE("ICMP Port Unreachable received on port: %d",
                          port_no);
            type = ICMP_DEST_UNREACHABLE;
            code = 3;
            result = INDIGO_CORE_LISTENER_RESULT_DROP;
            if (icmpa_send(&ppep, port_no, type, code)) {
                ++port_pkt_counters[port_no].icmp_port_unreachable_packets;
                return result;
            }
        }
    }

    /*
     * Identify if the reason is valid for ICMP Agent to consume the packet
     */
    if (match.fields.metadata & OFP_BSN_PKTIN_FLAG_L3_MISS) {
        AIM_LOG_TRACE("ICMP Dest Network Unreachable received on port: %d",
                      port_no);
        type = ICMP_DEST_UNREACHABLE;
        code = 0;
        result = INDIGO_CORE_LISTENER_RESULT_DROP;
        if (icmpa_send(&ppep, port_no, type, code)) {
            ++port_pkt_counters[port_no].icmp_net_unreachable_packets;
        }
    } else if (match.fields.metadata & OFP_BSN_PKTIN_FLAG_TTL_EXPIRED) {
        AIM_LOG_TRACE("ICMP TTL Expired received on port: %d", port_no);
        type = ICMP_TIME_EXCEEDED;
        code = 0;
        result = INDIGO_CORE_LISTENER_RESULT_DROP;
        if (icmpa_send(&ppep, port_no, type, code)) {
            ++port_pkt_counters[port_no].icmp_time_exceeded_packets;
        }
    }

    return result;
}