void indigo_core_table_register(uint8_t table_id, const char *name, const indigo_core_table_ops_t *ops, void *priv) { AIM_TRUE_OR_DIE(strlen(name) <= OF_MAX_TABLE_NAME_LEN); list_links_t *cur, *next; ft_entry_t *entry; FT_ITER(ind_core_ft, entry, cur, next) { if (entry->table_id == table_id) { ind_core_flow_entry_delete(entry, OF_FLOW_REMOVED_REASON_DELETE, INDIGO_CXN_ID_UNSPECIFIED); } } ind_core_table_t *table = aim_zmalloc(sizeof(*table)); strncpy(table->name, name, sizeof(table->name)); table->ops = ops; table->priv = priv; table->num_flows = 0; AIM_TRUE_OR_DIE(ind_core_tables[table_id] == NULL); ind_core_tables[table_id] = table; ind_core_num_tables_registered++; AIM_LOG_VERBOSE("Registered flowtable \"%s\" with table id %d", name, table_id); }
static int test_port_stats(void) { struct ind_core_port *handle1, *handle2; indigo_core_port_register(1, &handle1); indigo_core_port_register(2, &handle2); /* Request for OFPP_ANY */ memset(port_counters, 0, sizeof(port_counters)); of_port_stats_request_t *obj = of_port_stats_request_new(OF_VERSION_1_4); of_port_stats_request_port_no_set(obj, OF_PORT_DEST_WILDCARD); handle_message(obj); do_barrier(); AIM_TRUE_OR_DIE(port_counters[1].stats == 1); AIM_TRUE_OR_DIE(port_counters[2].stats == 1); /* Request for a single port */ memset(port_counters, 0, sizeof(port_counters)); obj = of_port_stats_request_new(OF_VERSION_1_4); of_port_stats_request_port_no_set(obj, 2); handle_message(obj); do_barrier(); AIM_TRUE_OR_DIE(port_counters[1].stats == 0); AIM_TRUE_OR_DIE(port_counters[2].stats == 1); indigo_core_port_unregister(handle1); indigo_core_port_unregister(handle2); return TEST_PASS; }
void ind_core_bsn_table_checksum_stats_request_handler(of_object_t *_obj, indigo_cxn_id_t cxn_id) { of_bsn_table_checksum_stats_request_t *obj = _obj; of_bsn_table_checksum_stats_reply_t *reply; of_list_bsn_table_checksum_stats_entry_t entries; of_bsn_table_checksum_stats_entry_t *entry; uint32_t xid; uint8_t table_id; reply = of_bsn_table_checksum_stats_reply_new(obj->version); AIM_TRUE_OR_DIE(reply != NULL); of_bsn_table_checksum_stats_request_xid_get(obj, &xid); of_bsn_table_checksum_stats_reply_xid_set(reply, xid); of_bsn_table_checksum_stats_reply_entries_bind(reply, &entries); entry = of_bsn_table_checksum_stats_entry_new(entries.version); AIM_TRUE_OR_DIE(entry != NULL); for (table_id = 0; table_id < FT_MAX_TABLES; table_id++) { ft_table_t *table = &ind_core_ft->tables[table_id]; of_bsn_table_checksum_stats_entry_table_id_set(entry, table_id); of_bsn_table_checksum_stats_entry_checksum_set(entry, table->checksum); if (of_list_append(&entries, entry) < 0) { /* This entry didn't fit, send out the current message and * allocate a new one. */ of_bsn_table_checksum_stats_reply_flags_set( reply, OF_STATS_REPLY_FLAG_REPLY_MORE); indigo_cxn_send_controller_message(cxn_id, reply); reply = of_bsn_table_checksum_stats_reply_new(obj->version); AIM_TRUE_OR_DIE(reply != NULL); of_bsn_table_checksum_stats_reply_xid_set(reply, xid); of_bsn_table_checksum_stats_reply_entries_bind(reply, &entries); if (of_list_append(&entries, entry) < 0) { AIM_DIE("unexpected failure appending single bsn_table_checksum stats entry"); } } } of_object_delete(entry); indigo_cxn_send_controller_message(cxn_id, reply); }
static int test_queue_desc_stats_multipart(void) { int i, j; struct ind_core_port *port_handles[OFSTATEMANAGER_CONFIG_MAX_PORTS]; struct ind_core_queue *queue_handles[OFSTATEMANAGER_CONFIG_MAX_PORTS]; const int qid = 3; for (i = 0; i < OFSTATEMANAGER_CONFIG_MAX_PORTS; i++) { indigo_core_port_register(i, &port_handles[i]); indigo_core_queue_register(i, qid, &queue_handles[i]); } memset(port_counters, 0, sizeof(port_counters)); of_queue_desc_stats_request_t *obj = of_queue_desc_stats_request_new(OF_VERSION_1_4); of_queue_desc_stats_request_port_no_set(obj, OF_PORT_DEST_WILDCARD); of_queue_desc_stats_request_queue_id_set(obj, OF_QUEUE_ALL); handle_message(obj); do_barrier(); for (i = 0; i < OFSTATEMANAGER_CONFIG_MAX_PORTS; i++) { for (j = 0; j < QUEUES_PER_PORT; j++) { AIM_TRUE_OR_DIE(port_counters[i].queue_desc_stats[j] == (j == qid)? 1: 0); } } for (i = 0; i < OFSTATEMANAGER_CONFIG_MAX_PORTS; i++) { indigo_core_queue_unregister(queue_handles[i]); indigo_core_port_unregister(port_handles[i]); } return TEST_PASS; }
static int os_sem_take_timeout_sem__(os_sem_t sem, uint64_t usecs) { AIM_TRUE_OR_DIE(!USES_EFD(sem), "timout_sem__ called while EFD in use."); if(usecs == 0) { /** Normal wait */ return os_sem_take(sem); } else { struct timespec ts; timespec_init_timeout__(&ts, usecs); for(;;) { if(sem_timedwait(&sem->sem, &ts) == 0) { return 0; } switch(errno) { case EINTR: break; case ETIMEDOUT: return -1; case EINVAL: AIM_DIE("Invalid or corrupted semaphore or the timespec was invalid in os_sem_take_timeout()."); break; default: AIM_DIE("Unhandled error condition in os_sem_take() for errno=%{errno}", errno); break; } } } }
static of_list_bsn_tlv_t * make_value (uint32_t vr_ip, of_mac_addr_t mac, uint32_t dhcp_ser_ip, of_octets_t *cid) { of_list_bsn_tlv_t *list = of_list_bsn_tlv_new(OF_VERSION_1_3); { of_bsn_tlv_ipv4_t *tlv = of_bsn_tlv_ipv4_new(OF_VERSION_1_3); of_bsn_tlv_ipv4_value_set(tlv, vr_ip); of_list_append(list, tlv); of_object_delete(tlv); } { of_bsn_tlv_mac_t *tlv = of_bsn_tlv_mac_new(OF_VERSION_1_3); of_bsn_tlv_mac_value_set(tlv, mac); of_list_append(list, tlv); of_object_delete(tlv); } { of_bsn_tlv_ipv4_t *tlv = of_bsn_tlv_ipv4_new(OF_VERSION_1_3); of_bsn_tlv_ipv4_value_set(tlv, dhcp_ser_ip); of_list_append(list, tlv); of_object_delete(tlv); } { of_bsn_tlv_circuit_id_t *tlv = of_bsn_tlv_circuit_id_new(OF_VERSION_1_3); AIM_TRUE_OR_DIE(of_bsn_tlv_circuit_id_value_set(tlv, cid) == OF_ERROR_NONE); of_list_append(list, tlv); of_object_delete(tlv); } return list; }
void del_entry_to_dhcpr_table() { of_list_bsn_tlv_t *key; dhc_relay_t *dhc_relay; uint32_t vlan_id = 1; uint32_t vlan_ret = 0; printf("\nVlan %d Delete to dhcp table\n", vlan_id); if (! (dhc_relay = dhcpr_get_dhcpr_entry_from_vlan_table(vlan_id))) { printf("Error get_dhcp_conf Vlan %d\n", vlan_id); } key = make_key(vlan_id); ops->del(table_priv, dhc_relay, key); /* Test 3: routerip -> vlan * invalid vlan, no need to check circuit */ dhcpr_virtual_router_key_to_vlan(&vlan_ret, dummy_dhcp_opt_info.vrouter_ip, dummy_dhcp_opt_info.vrouter_mac.addr); printf("router_ip_to_vlan = %d\n", vlan_ret); AIM_TRUE_OR_DIE(vlan_ret==INVALID_VLAN); printf("\nVlan %d Delete entry\n", vlan_id); }
static int test_port_stats_multipart(void) { int i; struct ind_core_port *port_handles[OFSTATEMANAGER_CONFIG_MAX_PORTS]; for (i = 0; i < OFSTATEMANAGER_CONFIG_MAX_PORTS; i++) { indigo_core_port_register(i, &port_handles[i]); } memset(port_counters, 0, sizeof(port_counters)); of_port_stats_request_t *obj = of_port_stats_request_new(OF_VERSION_1_4); of_port_stats_request_port_no_set(obj, OF_PORT_DEST_WILDCARD); handle_message(obj); do_barrier(); for (i = 0; i < OFSTATEMANAGER_CONFIG_MAX_PORTS; i++) { AIM_TRUE_OR_DIE(port_counters[i].stats == 1); } for (i = 0; i < OFSTATEMANAGER_CONFIG_MAX_PORTS; i++) { indigo_core_port_unregister(port_handles[i]); } return TEST_PASS; }
void add_entry_to_dhcpr_table() { indigo_error_t rv; int i; of_list_bsn_tlv_t *key, *value; void *entry_priv; //Test dhc_relay_t *dc; uint32_t vlan; uint32_t vr_ip = dummy_dhcp_opt_info.vrouter_ip+1; //Only add Vlan1 for now for (i=1; i<2; i++) { key = make_key(i); value = make_value(vr_ip, dummy_dhcp_opt_info.vrouter_mac, dummy_dhcp_opt_info.dhcp_server_ip, &dummy_cir_id2); //Test Add if((rv = ops->add(table_priv, key, value, &entry_priv)) != INDIGO_ERROR_NONE) { printf("Error Add table rv=%u", rv); exit(1); } else { printf("\nVlan %d Added to dhcp table\n", i); /* Test 1: dhcp conf array */ if (! (dc = dhcpr_get_dhcpr_entry_from_vlan_table(i))) { printf("Error get_dhcp_conf Vlan %d\n", i); } /* Test 2: cir -> vlan */ vlan = 1; AIM_TRUE_OR_DIE(!dhcpr_circuit_id_vlan_check(vlan, dummy_cir_id2.data, dummy_cir_id2.bytes )); /* Test 3: routerip -> vlan */ dhcpr_virtual_router_key_to_vlan(&vlan, vr_ip, dummy_dhcp_opt_info.vrouter_mac.addr); printf("router_ip_to_vlan = %u, vr_ip = %s\n", vlan, inet_ntoa(*(struct in_addr *) &vr_ip)); AIM_TRUE_OR_DIE(vlan==1); printf("DHCP CONF TABLE ok\n"); } } }
void add_entry_to_dhcpr_table() { indigo_error_t rv; int i; of_list_bsn_tlv_t *key, *value; void *entry_priv; //Test dhc_relay_t *dc; uint32_t vlan; //Only add Vlan1 for now for (i=VLAN_TEST; i<=VLAN_TEST; i++) { key = make_key(i); value = make_value(dummy_dhcp_opt_info.vrouter_ip, dummy_dhcp_opt_info.vrouter_mac, dummy_dhcp_opt_info.dhcp_server_ip, &dummy_dhcp_opt_info.opt_id.circuit_id); if((rv = ops->add(table_priv, key, value, &entry_priv)) != INDIGO_ERROR_NONE) { printf("Error Add table rv=%u", rv); exit(1); } else { printf("\nVlan %d Added to dhcp table\n", i); /* Test 1: dhcp conf array */ if (! (dc = dhcpr_get_dhcpr_entry_from_vlan_table(i))) { printf("Error get_dhcp_conf Vlan %d\n", i); } /* Test 2: cir -> vlan */ dhcpr_circuit_id_to_vlan(&vlan, dummy_dhcp_opt_info.opt_id.circuit_id.data, dummy_dhcp_opt_info.opt_id.circuit_id.bytes ); printf("circuit_id_to_vlan = %u\n", vlan); AIM_TRUE_OR_DIE(vlan==1); /* Test 3: routerip -> vlan */ dhcpr_virtual_router_ip_to_vlan(&vlan, dummy_dhcp_opt_info.vrouter_ip); printf("router_ip_to_vlan = %u\n", vlan); AIM_TRUE_OR_DIE(vlan==1); printf("DHCP CONF TABLE ok\n"); } } }
void mod_entry_to_dhcpr_table() { of_list_bsn_tlv_t *key, *value; dhc_relay_t *dhc_relay; uint32_t vlan_id = 1; uint32_t vlan_ret = 0; printf("\nVlan %d Modify to dhcp table\n", vlan_id); if (! (dhc_relay = dhcpr_get_dhcpr_entry_from_vlan_table(vlan_id))) { printf("Error get_dhcp_conf Vlan %d\n", vlan_id); } key = make_key(vlan_id); value = make_value(dummy_dhcp_opt_info.vrouter_ip, dummy_dhcp_opt_info.vrouter_mac, dummy_dhcp_opt_info.dhcp_server_ip, &dummy_dhcp_opt_info.opt_id.circuit_id); ops->modify(table_priv, dhc_relay, key, value); /* Test 3: routerip -> vlan * Invalid_vlan, no need to check against circuit */ dhcpr_virtual_router_key_to_vlan(&vlan_ret, dummy_dhcp_opt_info.vrouter_ip+1, dummy_dhcp_opt_info.vrouter_mac.addr); printf("router_ip_to_vlan = %d\n", vlan_ret); AIM_TRUE_OR_DIE(vlan_ret==INVALID_VLAN); /* Test 4: cir -> vlan */ vlan_ret = vlan_id; AIM_TRUE_OR_DIE(!dhcpr_circuit_id_vlan_check(vlan_ret, dummy_dhcp_opt_info.opt_id.circuit_id.data, dummy_dhcp_opt_info.opt_id.circuit_id.bytes )); /* Test 5: routerip -> vlan */ dhcpr_virtual_router_key_to_vlan(&vlan_ret, dummy_dhcp_opt_info.vrouter_ip, dummy_dhcp_opt_info.vrouter_mac.addr); printf("router_ip_to_vlan = %d\n", vlan_ret); AIM_TRUE_OR_DIE(vlan_ret==vlan_id); printf("\nVlan %d Modify to dhcp table change virtual routerIP and circuit \n", vlan_id); }
static int test_port_desc_stats(void) { struct ind_core_port *handle1, *handle2; indigo_core_port_register(1, &handle1); indigo_core_port_register(2, &handle2); memset(port_counters, 0, sizeof(port_counters)); of_port_desc_stats_request_t *obj = of_port_desc_stats_request_new(OF_VERSION_1_4); handle_message(obj); do_barrier(); AIM_TRUE_OR_DIE(port_counters[1].desc_stats == 1); AIM_TRUE_OR_DIE(port_counters[2].desc_stats == 1); indigo_core_port_unregister(handle1); indigo_core_port_unregister(handle2); return TEST_PASS; }
/* * icmp_send_packet_out * * Send the ICMP message out */ indigo_error_t icmpa_send_packet_out (of_octets_t *octets) { of_packet_out_t *obj; of_list_action_t *list; of_action_output_t *action; indigo_error_t rv; if (!octets) return INDIGO_ERROR_PARAM; obj = of_packet_out_new(OF_VERSION_1_3); AIM_TRUE_OR_DIE(obj != NULL); list = of_list_action_new(OF_VERSION_1_3); AIM_TRUE_OR_DIE(list != NULL); action = of_action_output_new(OF_VERSION_1_3); AIM_TRUE_OR_DIE(action != NULL); of_packet_out_buffer_id_set(obj, -1); of_packet_out_in_port_set(obj, OF_PORT_DEST_CONTROLLER); of_action_output_port_set(action, OF_PORT_DEST_USE_TABLE); of_list_append(list, action); of_object_delete(action); rv = of_packet_out_actions_set(obj, list); AIM_ASSERT(rv == 0); of_object_delete(list); rv = of_packet_out_data_set(obj, octets); if (rv < 0) { AIM_LOG_ERROR("ICMPA: Failed to set data on packet out"); of_packet_out_delete(obj); return rv; } rv = indigo_fwd_packet_out(obj); of_packet_out_delete(obj); return rv; }
void indigo_core_table_unregister(uint8_t table_id) { ind_core_table_t *table = ind_core_tables[table_id]; AIM_TRUE_OR_DIE(table != NULL); list_links_t *cur, *next; ft_entry_t *entry; FT_ITER(ind_core_ft, entry, cur, next) { if (entry->table_id == table_id) { ind_core_flow_entry_delete(entry, OF_FLOW_REMOVED_REASON_DELETE, INDIGO_CXN_ID_UNSPECIFIED); } } aim_free(table); ind_core_tables[table_id] = NULL; ind_core_num_tables_registered--; }
static void handle_lua_command_request(indigo_cxn_id_t cxn_id, of_object_t *msg) { const int max_reply_size = UINT16_MAX - of_object_fixed_len[msg->version][OF_BSN_LUA_COMMAND_REPLY]; uint32_t xid; of_octets_t request_data; of_bsn_lua_command_request_xid_get(msg, &xid); of_bsn_lua_command_request_data_get(msg, &request_data); pipeline_lua_allocator_reset(); void *request_buf = pipeline_lua_allocator_dup(request_data.data, request_data.bytes); void *reply_buf = pipeline_lua_allocator_alloc(max_reply_size); lua_rawgeti(lua, LUA_REGISTRYINDEX, command_ref); lua_pushlightuserdata(lua, request_buf); lua_pushinteger(lua, request_data.bytes); lua_pushlightuserdata(lua, reply_buf); lua_pushinteger(lua, max_reply_size); if (lua_pcall(lua, 4, 1, 0) != 0) { AIM_LOG_ERROR("Failed to execute command xid=%#x: %s", xid, lua_tostring(lua, -1)); indigo_cxn_send_error_reply( cxn_id, msg, OF_ERROR_TYPE_BAD_REQUEST, OF_REQUEST_FAILED_EPERM); return; } int reply_size = lua_tointeger(lua, 0); AIM_TRUE_OR_DIE(reply_size >= 0 && reply_size < max_reply_size); lua_settop(lua, 0); of_object_t *reply = of_bsn_lua_command_reply_new(msg->version); of_bsn_lua_command_reply_xid_set(reply, xid); of_octets_t reply_data = { .data = reply_buf, .bytes = reply_size }; if (of_bsn_lua_command_reply_data_set(reply, &reply_data) < 0) { AIM_DIE("Unexpectedly failed to set data in of_bsn_lua_command_reply"); } indigo_cxn_send_controller_message(cxn_id, reply); }
int fill_all_vlan_dhcpr_table_test() { indigo_error_t rv; of_list_bsn_tlv_t *key, *value; void *entry_priv; dhc_relay_t *dhc_relay; int k; int vlan_no; int vr_ip_no; uint32_t virtualRouterIP = 1; of_mac_addr_t mac = { .addr = {0x55, 0x16, 0xc7, 0x01, 0x02, 0x03} }; uint32_t dhcpServerIP = 2; uint16_t cir_value[VLAN_MAX+1]; of_octets_t cir_id; int num_of_vlan = VLAN_MAX; int extra_vlan = 2; //Test error //NOTE: no need to do htonl or htons, //What ever value we send here, we get over there //No need to convert. //Initialize cir_value for (k = 0; k <= num_of_vlan; k++) { cir_value[k] = (k+1); } printf("TEST:1 fill all\n"); /* Add 1st half having circuit */ for (k = 0; k < num_of_vlan/2 ; k++) { cir_id.bytes = sizeof(cir_value[k]); cir_id.data = (uint8_t*)&cir_value[k]; key = make_key(k); value = make_value((virtualRouterIP+k), mac, (dhcpServerIP+k), &cir_id); if((rv = ops->add(table_priv, key, value, &entry_priv)) != INDIGO_ERROR_NONE) { printf("Error out of range table %u, rv=%u", k, rv); exit(1); } } /* Add 2nd half non circuit */ printf("Range k=%u - %u\n", num_of_vlan/2, num_of_vlan); for (k = num_of_vlan/2; k<= num_of_vlan+extra_vlan ; k++) { key = make_key(k); value = make_value((virtualRouterIP+k), mac, (dhcpServerIP+k), NULL); if((rv = ops->add(table_priv, key, value, &entry_priv)) != INDIGO_ERROR_NONE) { printf("Test Add table incorret Vlan range %u, rv=%u\n", k, rv); } } vlan_no = dhcpr_table_get_vlan_entry_count(); vr_ip_no = dhcpr_table_get_virtual_router_ip_entry_count(); AIM_TRUE_OR_DIE(vlan_no == num_of_vlan+1, "vlan=%u", vlan_no); AIM_TRUE_OR_DIE(vr_ip_no == num_of_vlan+1, "vr_ip_no=%u", vr_ip_no); printf("TEST:2 modify all\n"); /* Modify 1/4: * --Same virtual Router * --No circuit * */ for (k = 0; k < num_of_vlan/4 ; k++) { dhc_relay = dhcpr_get_dhcpr_entry_from_vlan_table(k); AIM_TRUE_OR_DIE(dhc_relay); key = make_key(k); value = make_value((virtualRouterIP+k), mac, (dhcpServerIP+k), NULL); if((rv = ops->modify(table_priv, dhc_relay, key, value)) != INDIGO_ERROR_NONE) { printf("Error Add table %u, rv=%u", k, rv); exit(1); } } /* Modify 1/4-2/4: * --Diff virtual Router * --No circuit * */ for (k = num_of_vlan/4; k < num_of_vlan/2; k++) { dhc_relay = dhcpr_get_dhcpr_entry_from_vlan_table(k); AIM_TRUE_OR_DIE(dhc_relay); key = make_key(k); value = make_value((virtualRouterIP+k+num_of_vlan), mac, (dhcpServerIP+k), NULL); if((rv = ops->modify(table_priv, dhc_relay, key, value)) != INDIGO_ERROR_NONE) { printf("Error Add table %u, rv=%u", k, rv); exit(1); } } /* Modify 2/4-3/4 * -- Same virtual router * -- Add circuit * */ for (k = num_of_vlan/2; k<= 3*num_of_vlan/4 ; k++) { dhc_relay = dhcpr_get_dhcpr_entry_from_vlan_table(k); AIM_TRUE_OR_DIE(dhc_relay); cir_id.bytes = sizeof(cir_value[k]); cir_id.data = (uint8_t*)&cir_value[k]; key = make_key(k); value = make_value((virtualRouterIP+k), mac, (dhcpServerIP+k), &cir_id); if((rv = ops->modify(table_priv, dhc_relay, key, value)) != INDIGO_ERROR_NONE) { printf("Error Add table %u, rv=%u", k, rv); exit(1); } } /* Modify 2/4-3/4 * -- Diff virtual router * -- Add circuit * */ for (k = 3*num_of_vlan/4; k<= num_of_vlan ; k++) { dhc_relay = dhcpr_get_dhcpr_entry_from_vlan_table(k); AIM_TRUE_OR_DIE(dhc_relay); cir_id.bytes = sizeof(cir_value[k]); cir_id.data = (uint8_t*)&cir_value[k]; key = make_key(k); value = make_value((virtualRouterIP+k+num_of_vlan), mac, (dhcpServerIP+k), &cir_id); if((rv = ops->modify(table_priv, dhc_relay, key, value)) != INDIGO_ERROR_NONE) { printf("Error Add table %u, rv=%u", k, rv); exit(1); } } vlan_no = dhcpr_table_get_vlan_entry_count(); vr_ip_no = dhcpr_table_get_virtual_router_ip_entry_count(); AIM_TRUE_OR_DIE(vlan_no == num_of_vlan+1, "vlan=%u", vlan_no); AIM_TRUE_OR_DIE(vr_ip_no == num_of_vlan+1, "vr_ip_no=%u", vr_ip_no); printf("TEST:3 delete all\n"); for (k = 0; k<= num_of_vlan; k++) { dhc_relay = dhcpr_get_dhcpr_entry_from_vlan_table(k); AIM_TRUE_OR_DIE(dhc_relay); key = make_key(k); ops->del(table_priv, dhc_relay, key); } /* Delete all */ vlan_no = dhcpr_table_get_vlan_entry_count(); vr_ip_no = dhcpr_table_get_virtual_router_ip_entry_count(); AIM_TRUE_OR_DIE(vlan_no == 0); AIM_TRUE_OR_DIE(vr_ip_no == 0); return 1; }
/* Dummy for compiler */ void indigo_core_gentable_unregister (indigo_core_gentable_t *gentable) { AIM_TRUE_OR_DIE(gentable == (void *)1); }
int test_discovery_pkt_in(int port_no, int indigo_ret_expected) { #define OUT_PKT_BUF_SIZE 1500 uint8_t buf[OUT_PKT_BUF_SIZE]; int rv = 0; of_packet_in_t *obj = 0; ppe_packet_t ppep; of_octets_t data = { .bytes = sizeof(Dhcp_discovery) //346 bytes (342 + 4byteVLAN }; /* Timeout due to re-register the timer */ printf("\n\n*******************************\n"); printf("TEST 1 DHCP Discovery: PKT_IN on port:%d\nExpect Option Added\n", port_no); printf("pkt_in bytes = %d\n", data.bytes); printf("*******************************\n"); /* Set up GOLDEN Expected pkt*/ AIM_TRUE_OR_DIE(sizeof(Dhcp_discovery_expected) <= OUT_PKT_BUF_SIZE); convert_chars_to_bytes(Dhcp_discovery_expected, Dhcp_discovery_expected_hex_stream, sizeof(Dhcp_discovery_expected)); /* Setup discovery pkt */ AIM_TRUE_OR_DIE(sizeof(Dhcp_discovery) <= OUT_PKT_BUF_SIZE); convert_chars_to_bytes(Dhcp_discovery, Dhcp_discovery_hex_stream, sizeof(Dhcp_discovery)); memcpy(buf, Dhcp_discovery, sizeof(Dhcp_discovery)); data.data = buf; obj = of_packet_in_new(OF_VERSION_1_0); AIM_TRUE_OR_DIE(obj); of_packet_in_reason_set(obj, OF_PACKET_IN_REASON_BSN_DHCP); of_packet_in_in_port_set(obj,port_no); if(of_packet_in_data_set(obj, &data) < 0) { AIM_TRUE_OR_DIE(obj); } /* Dump pkt in obj */ // of_object_dump((loci_writer_f)aim_printf, &aim_pvs_stdout, obj); ppe_packet_init(&ppep, data.data, data.bytes); if (ppe_parse(&ppep) < 0) { printf("\nERROR: Packet parsing failed. packet=%p, len=%u", data.data, data.bytes); } /* Dump up to DHCP hdr */ // ppe_packet_dump(&ppep,&aim_pvs_stdout); // parse_dhcp_options(&ppep, data.bytes, 0, 0); /* Handle packet */ rv = dhcpra_handle_pkt (obj); AIM_TRUE_OR_DIE(rv == indigo_ret_expected); of_packet_in_delete(obj); return rv; } int test_offer_pkt_in(int port_no) { #define OUT_PKT_BUF_SIZE 1500 uint8_t buf[OUT_PKT_BUF_SIZE]; int rv = 0; of_packet_in_t *obj; ppe_packet_t ppep; of_octets_t data = { .bytes = sizeof(Dhcp_offer) //354 (342 + 4byte VLAN + 8bytes CirID) }; printf("\n\n*******************************\n" "TEST 2 DHCP OFFER: PKT_IN on port:%d\nExpect Option Removed\n", port_no); printf("pkt_in bytes = %d\n", data.bytes); printf("*******************************\n\n"); /* Set up GOLDEN Expected pkt*/ //printf("Expected Offer pkt:\n"); AIM_TRUE_OR_DIE(sizeof(Dhcp_offer_expected) <= OUT_PKT_BUF_SIZE); convert_chars_to_bytes(Dhcp_offer_expected, Dhcp_offer_expected_hex_stream, sizeof(Dhcp_offer_expected)); /* Setup offer pkt */ //printf("Offer pkt:\n"); AIM_TRUE_OR_DIE(sizeof(Dhcp_offer) <= OUT_PKT_BUF_SIZE); convert_chars_to_bytes(Dhcp_offer, Dhcp_offer_hex_stream, sizeof(Dhcp_offer)); memcpy(buf, Dhcp_offer, sizeof(Dhcp_offer)); data.data = buf; obj = of_packet_in_new(OF_VERSION_1_0); AIM_TRUE_OR_DIE(obj); of_packet_in_in_port_set(obj,port_no); of_packet_in_reason_set(obj, OF_PACKET_IN_REASON_BSN_DHCP); if(of_packet_in_data_set(obj, &data) < 0) { AIM_TRUE_OR_DIE(obj); } /* Dump pkt in obj */ //of_object_dump((loci_writer_f)aim_printf, &aim_pvs_stdout, obj); ppe_packet_init(&ppep, data.data, data.bytes); if (ppe_parse(&ppep) < 0) { printf("\nERROR: Packet parsing failed. packet=%p, len=%u", data.data, data.bytes); } /* Dump up to DHCP hdr */ //ppe_packet_dump(&ppep,&aim_pvs_stdout); //parse_dhcp_options(&ppep, data.bytes, 0, 0); /* Handle packet */ rv = dhcpra_handle_pkt (obj); if (rv == INDIGO_CORE_LISTENER_RESULT_PASS) { printf("\nError: NOT DHCP packet-in\n"); } else if (rv == INDIGO_CORE_LISTENER_RESULT_DROP) printf("\nIS DHCP packet-in\n"); else printf("\nError: Unsupport packet-in\n"); of_packet_in_delete(obj); return rv; } int aim_main(int argc, char* argv[]) { printf("dhcpra Utest Is Empty\n"); dhcpra_config_show(&aim_pvs_stdout); dhcpra_system_init(); printf("\n*********\n0. PRE-TEST TABLE\n********\n"); test_pass[0] = fill_all_vlan_dhcpr_table_test(); printf("\n*********\nI. TEST PASS AFTER ADD and MOD\n********\n"); add_entry_to_dhcpr_table(); mod_entry_to_dhcpr_table(); //Port 1: Correct setup, packet process //Driver will take care of sending L2_SRC_MISSED to controller test_discovery_pkt_in(1, INDIGO_CORE_LISTENER_RESULT_DROP); test_offer_pkt_in(1); printf("\n\nSUMMARY:\nDISCOV:\t%s\n", dhcp_pkt_matched[0] ? "PASSED" : "FAILED"); printf("OFFER:\t%s\n", dhcp_pkt_matched[1] ? "PASSED" : "FAILED"); test_pass[1] = dhcp_pkt_matched[0]; test_pass[2] = dhcp_pkt_matched[1]; printf("\n*********\nII. TEST FAILED AFTER DELETE\n********\n"); dhcp_pkt_matched[0] = 0; dhcp_pkt_matched[1] = 0; del_entry_to_dhcpr_table(); //Incorrect VLAN pass packet test_discovery_pkt_in(1, INDIGO_CORE_LISTENER_RESULT_PASS); test_offer_pkt_in(1); printf("\n\nSUMMARY:\nDISCOV:\t%s\n", dhcp_pkt_matched[0] ? "PASSED" : "FAILED"); printf("OFFER:\t%s\n", dhcp_pkt_matched[1] ? "PASSED" : "FAILED"); test_pass[3] = !dhcp_pkt_matched[0]; test_pass[4] = !dhcp_pkt_matched[1]; printf("\n\n*****SUMMARY ALL 3 TESTS*****\n"); printf("TEST DHCP TABLE: %s\n", test_pass[0] ? "PASSED" : "FAILED"); printf("TEST DISCOVER with valid table: %s\n", test_pass[1] ? "PASSED" : "FAILED"); printf("TEST OFFER with valid table: %s\n", test_pass[2] ? "PASSED" : "FAILED"); printf("TEST DISCOVER with in valid table: %s\n", test_pass[3] ? "PASSED" : "FAILED"); printf("TEST OFFER with in valid table: %s\n", test_pass[4] ? "PASSED" : "FAILED"); return 0; }
static int test_queue_desc_stats(void) { struct ind_core_port *handle1, *handle2; indigo_core_port_register(1, &handle1); indigo_core_port_register(2, &handle2); struct ind_core_queue *queue1_3, *queue1_4, *queue2_3, *queue2_4; indigo_core_queue_register(1, 3, &queue1_3); indigo_core_queue_register(1, 4, &queue1_4); indigo_core_queue_register(2, 3, &queue2_3); indigo_core_queue_register(2, 4, &queue2_4); /* Request for OFPP_ANY, OF_QUEUE_ALL */ memset(port_counters, 0, sizeof(port_counters)); of_queue_desc_stats_request_t *obj = of_queue_desc_stats_request_new(OF_VERSION_1_4); of_queue_desc_stats_request_port_no_set(obj, OF_PORT_DEST_WILDCARD); of_queue_desc_stats_request_queue_id_set(obj, OF_QUEUE_ALL); handle_message(obj); do_barrier(); AIM_TRUE_OR_DIE(port_counters[1].queue_desc_stats[3] == 1); AIM_TRUE_OR_DIE(port_counters[1].queue_desc_stats[4] == 1); AIM_TRUE_OR_DIE(port_counters[2].queue_desc_stats[3] == 1); AIM_TRUE_OR_DIE(port_counters[2].queue_desc_stats[4] == 1); /* Request for a single port, OF_QUEUE_ALL */ memset(port_counters, 0, sizeof(port_counters)); obj = of_queue_desc_stats_request_new(OF_VERSION_1_4); of_queue_desc_stats_request_port_no_set(obj, 2); of_queue_desc_stats_request_queue_id_set(obj, OF_QUEUE_ALL); handle_message(obj); do_barrier(); AIM_TRUE_OR_DIE(port_counters[1].queue_desc_stats[3] == 0); AIM_TRUE_OR_DIE(port_counters[1].queue_desc_stats[4] == 0); AIM_TRUE_OR_DIE(port_counters[2].queue_desc_stats[3] == 1); AIM_TRUE_OR_DIE(port_counters[2].queue_desc_stats[4] == 1); /* Request for OFPP_ANY, a single queue */ memset(port_counters, 0, sizeof(port_counters)); obj = of_queue_desc_stats_request_new(OF_VERSION_1_4); of_queue_desc_stats_request_port_no_set(obj, OF_PORT_DEST_WILDCARD); of_queue_desc_stats_request_queue_id_set(obj, 4); handle_message(obj); do_barrier(); AIM_TRUE_OR_DIE(port_counters[1].queue_desc_stats[3] == 0); AIM_TRUE_OR_DIE(port_counters[1].queue_desc_stats[4] == 1); AIM_TRUE_OR_DIE(port_counters[2].queue_desc_stats[3] == 0); AIM_TRUE_OR_DIE(port_counters[2].queue_desc_stats[4] == 1); /* Request for a single port and queue */ memset(port_counters, 0, sizeof(port_counters)); obj = of_queue_desc_stats_request_new(OF_VERSION_1_4); of_queue_desc_stats_request_port_no_set(obj, 2); of_queue_desc_stats_request_queue_id_set(obj, 4); handle_message(obj); do_barrier(); AIM_TRUE_OR_DIE(port_counters[1].queue_desc_stats[3] == 0); AIM_TRUE_OR_DIE(port_counters[1].queue_desc_stats[4] == 0); AIM_TRUE_OR_DIE(port_counters[2].queue_desc_stats[3] == 0); AIM_TRUE_OR_DIE(port_counters[2].queue_desc_stats[4] == 1); indigo_core_queue_unregister(queue1_3); indigo_core_queue_unregister(queue1_4); indigo_core_queue_unregister(queue2_3); indigo_core_queue_unregister(queue2_4); indigo_core_port_unregister(handle1); indigo_core_port_unregister(handle2); return TEST_PASS; }
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)); } } }
/* * Register a sensor * Caller must make sure that 1 sensor registered only once * If it calls this twice, it will get 2 oid entries * for the same sensor * * We want to keep this snmp code as simple as possible */ static int onlp_snmp_sensor_reg__(int sensor_type, onlp_snmp_sensor_t *sensor) { oid otemp[] = { ONLP_SNMP_SENSOR_TEMP_OID }; oid ofan[] = { ONLP_SNMP_SENSOR_FAN_OID }; oid opsu[] = { ONLP_SNMP_SENSOR_PSU_OID }; oid oled[] = { ONLP_SNMP_SENSOR_LED_OID }; oid omisc[] = { ONLP_SNMP_SENSOR_MISC_OID }; oid *o; u_long o_len; int ret = MIB_REGISTRATION_FAILED; onlp_snmp_sensor_ctrl_t *ss_type = get_sensor_ctrl__(sensor_type); /* We start with Base 1 */ AIM_TRUE_OR_DIE(onlp_snmp_sensor_type_valid(sensor_type)); AIM_TRUE_OR_DIE(sensor); AIM_TRUE_OR_DIE(ss_type); switch(sensor_type) { case ONLP_SNMP_SENSOR_TYPE_TEMP: o = otemp; o_len = OID_LENGTH(otemp); /* Not init yet, init oid table */ if (!ss_type->handlers) { ss_type->handler_cnt = sizeof(temp_handler_fn__) / sizeof(temp_handler_fn__[0]); ss_type->handlers = temp_handler_fn__; snprintf(ss_type->name, sizeof(ss_type->name), "%s", "temp_table"); } break; case ONLP_SNMP_SENSOR_TYPE_FAN: o = ofan; o_len = OID_LENGTH(ofan); /* Not init yet, init oid table */ if (!ss_type->handlers) { ss_type->handler_cnt = sizeof(fan_handler_fn__) / sizeof(fan_handler_fn__[0]); ss_type->handlers = fan_handler_fn__; snprintf(ss_type->name, sizeof(ss_type->name), "%s", "fan_table"); } break; case ONLP_SNMP_SENSOR_TYPE_PSU: o = opsu; o_len = OID_LENGTH(opsu); /* Not init yet, init oid table */ if (!ss_type->handlers) { ss_type->handler_cnt = sizeof(psu_handler_fn__) / sizeof(psu_handler_fn__[0]); ss_type->handlers = psu_handler_fn__; snprintf(ss_type->name, sizeof(ss_type->name), "%s", "psu_table"); } break; case ONLP_SNMP_SENSOR_TYPE_LED: o = oled; o_len = OID_LENGTH(oled); /* Not init yet, init oid table */ if (!ss_type->handlers) { ss_type->handler_cnt = sizeof(led_handler_fn__) / sizeof(led_handler_fn__[0]); ss_type->handlers = led_handler_fn__; snprintf(ss_type->name, sizeof(ss_type->name), "%s", "led_table"); } break; case ONLP_SNMP_SENSOR_TYPE_MISC: o = omisc; o_len = OID_LENGTH(omisc); /* Not init yet, init oid table */ if (!ss_type->handlers) { ss_type->handler_cnt = sizeof(misc_handler_fn__) / sizeof(misc_handler_fn__[0]); ss_type->handlers = misc_handler_fn__; snprintf(ss_type->name, sizeof(ss_type->name), "%s", "misc_table"); } break; default: AIM_DIE("Invalid sensor value."); break; } /* * sensor_cnt original is 0 * When sensor_cnt == ONLP_SNMP_CONFIG_DEV_MAX_INDEX * We stop adding */ if (ss_type->sensor_cnt < ONLP_SNMP_CONFIG_DEV_MAX_INDEX) { /* Device index equal to ss_type->sensor_cnt */ ss_type->sensor_cnt++; /* This entry must be null */ AIM_TRUE_OR_DIE(!ss_type->sensor_list[ss_type->sensor_cnt]); snmp_log(LOG_INFO, "init type=%d, index=%d, id=%d", sensor_type, ss_type->sensor_cnt, sensor->sensor_id); onlp_snmp_sensor_t *ss = AIM_MALLOC(sizeof(onlp_snmp_sensor_t)); AIM_TRUE_OR_DIE(ss); AIM_MEMCPY(ss, sensor, sizeof(*sensor)); ss->sensor_type = sensor_type; ss->info_valid = 0; ss->last_update_time = 0; /* Assign sensor to the list */ ss_type->sensor_list[ss_type->sensor_cnt] = ss; } else { snmp_log(LOG_ALERT, "Failed to register sensor type=%d id=%d, resource limited", sensor_type, sensor->sensor_id); return ret; } AIM_TRUE_OR_DIE(o_len == ONLP_SNMP_SENSOR_OID_LENGTH, "invalid oid length=%d", o_len); ret = reg_snmp_sensor_helper__(sensor_type, o, o_len, ss_type->sensor_cnt); if (ret) { snmp_log(LOG_ALERT, "Failed to register sensor type=%d id=%d, MIB_ERROR=%d", sensor_type, sensor->sensor_id, ret); } return ret; }
void sem_test_multiple(uint32_t flags, int giving_threads, int taking_threads) { int i; int thread_count = giving_threads + taking_threads; sem_test_t* tests = aim_zmalloc(sizeof(*tests)*thread_count); aim_sem_t take = aim_sem_create_flags(0, flags); aim_sem_t give = aim_sem_create_flags(0, flags); int acquired = 0; sem_test_t* t = tests; /* * These threads wait on a semaphore timeout * that will always expire. Timeout in [10000,100000]. * * When the first timeout expires they give a different sem. */ for(i = 0; i < giving_threads; i++, t++) { t->take = take; t->give = give; sprintf(t->name, "(1:%.4d)", i); t->timeout = ( (random() % 10) + 1 ) * 100000; t->timeout_required = 1; t->acquired = &acquired; pthread_create(&t->thread, NULL, sem_test_thread__, t); } /* * These threads wait on the semaphore given at the end * of the waiting period for the first set of threads. * * Some will timeout, some will acquire. * * Their timeouts are all in [2000000, 3000000]. */ for(i = 0; i < taking_threads; i++, t++) { t->take = give; t->give = NULL; sprintf(t->name, "(2:%.4d)", i); t->timeout = 2000000 + (( (random() % 10) + 1 ) * 100000); t->give = 0; t->timeout_required = 0; t->acquired = &acquired; pthread_create(&t->thread, NULL, sem_test_thread__, t); } for(i = 0; i < thread_count; i++) { void* rv; pthread_join(tests[i].thread, &rv); } /* * The acquisition count should always be equal to the number * of giving threads when (giving_threads <= taking_threads). */ printf("Acquisition count: %d\n", acquired); AIM_TRUE_OR_DIE(acquired == giving_threads, "Failed"); aim_free(give); aim_free(take); aim_free(tests); }
void ind_core_bsn_flow_checksum_bucket_stats_request_handler(of_object_t *_obj, indigo_cxn_id_t cxn_id) { of_bsn_flow_checksum_bucket_stats_request_t *obj = _obj; of_bsn_flow_checksum_bucket_stats_reply_t *reply; of_list_bsn_flow_checksum_bucket_stats_entry_t entries; of_bsn_flow_checksum_bucket_stats_entry_t *entry; uint32_t xid; uint8_t table_id; ft_table_t *table; int bucket_idx; of_bsn_flow_checksum_bucket_stats_request_table_id_get(obj, &table_id); if (table_id >= FT_MAX_TABLES) { AIM_LOG_WARN("Invalid table ID %u", table_id); indigo_cxn_send_error_reply(cxn_id, obj, OF_ERROR_TYPE_BAD_REQUEST, OF_REQUEST_FAILED_EPERM); return; } table = &ind_core_ft->tables[table_id]; reply = of_bsn_flow_checksum_bucket_stats_reply_new(obj->version); AIM_TRUE_OR_DIE(reply != NULL); of_bsn_flow_checksum_bucket_stats_request_xid_get(obj, &xid); of_bsn_flow_checksum_bucket_stats_reply_xid_set(reply, xid); of_bsn_flow_checksum_bucket_stats_reply_entries_bind(reply, &entries); entry = of_bsn_flow_checksum_bucket_stats_entry_new(entries.version); AIM_TRUE_OR_DIE(entry != NULL); for (bucket_idx = 0; bucket_idx < table->checksum_buckets_size; bucket_idx++) { of_bsn_flow_checksum_bucket_stats_entry_checksum_set( entry, table->checksum_buckets[bucket_idx]); if (of_list_append(&entries, entry) < 0) { /* This entry didn't fit, send out the current message and * allocate a new one. */ of_bsn_flow_checksum_bucket_stats_reply_flags_set( reply, OF_STATS_REPLY_FLAG_REPLY_MORE); indigo_cxn_send_controller_message(cxn_id, reply); reply = of_bsn_flow_checksum_bucket_stats_reply_new(obj->version); AIM_TRUE_OR_DIE(reply != NULL); of_bsn_flow_checksum_bucket_stats_reply_xid_set(reply, xid); of_bsn_flow_checksum_bucket_stats_reply_entries_bind(reply, &entries); if (of_list_append(&entries, entry) < 0) { AIM_DIE("unexpected failure appending single bsn_flow_checksum_bucket stats entry"); } } } of_object_delete(entry); indigo_cxn_send_controller_message(cxn_id, reply); }