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 */ }
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; }
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; }