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; } } } }
int os_sem_take(os_sem_t sem) { VALIDATE(sem); for(;;) { if(USES_EFD(sem)) { return os_sem_take_timeout(sem, 0); } else { if(sem_wait(&sem->sem) == 0) { return 0; } } switch(errno) { case EINTR: break; case EINVAL: AIM_DIE("Invalid or corrupted semaphore in os_sem_take()."); break; default: AIM_DIE("Unhandled error condition in os_sem_take(): errno=%s", strerror(errno)); break; } } }
static int insert__(bighash_table_t *table, int count, biglist_t** entries) { int c; for(c = 0; c < count; c++) { test_entry_t *te = aim_zmalloc(sizeof(*te)); te->id = c; bighash_insert(table, &te->hash_entry, hash_id(te->id)); if(entries) { *entries = biglist_prepend(*entries, te); } /** Make sure we can find it */ test_entry_t *fe = find_by_id(table, te->id); if(fe == NULL) { AIM_DIE("inserted entry was not found, count=%d/%d", c, count); } if(fe != te) { AIM_DIE("Retreived pointer not equal."); } if(bighash_entry_count(table) != (c+1)) { AIM_DIE("Entry count mismatch: should be %d, reported as %d", (c+1), bighash_entry_count(table)); } } return 0; }
void ivs_cli_init(const char *path) { ucli_init(); unlink(path); listen_socket = socket(AF_UNIX, SOCK_STREAM, 0); if (listen_socket < 0) { perror("socket (CLI)"); abort(); } struct sockaddr_un saddr; memset(&saddr, 0, sizeof(saddr)); saddr.sun_family = AF_UNIX; strcpy(saddr.sun_path, path); if (bind(listen_socket, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { perror("bind (CLI)"); abort(); } if (listen(listen_socket, LISTEN_BACKLOG) < 0) { perror("listen (CLI)"); abort(); } indigo_error_t rv = ind_soc_socket_register(listen_socket, listen_callback, NULL); if (rv < 0) { AIM_DIE("Failed to register CLI socket: %s", indigo_strerror(rv)); } }
void test_bucket(void) { struct { uint32_t k; uint32_t bucket; uint32_t reverse; } tests[] = { { 0, 0, 0 }, { 1, 1, 1 }, { 2, 2, 2 }, { 14, 14, 14 }, { 15, 15, 15 }, { 16, 16, 16 }, { 17, 17, 17 }, { 30, 30, 30 }, { 31, 31, 31 }, { 32, 32, 32 }, { 33, 32, 32 }, { 34, 33, 34 }, { 62, 47, 62 }, { 63, 47, 62 }, { 64, 48, 64 }, { 65, 48, 64 }, { 66, 48, 64 }, { 67, 48, 64 }, { 68, 49, 68 }, { UINT32_MAX, 463, 4160749568 }, }; int i; for (i = 0; i < AIM_ARRAYSIZE(tests); i++) { uint32_t actual = histogram_bucket(tests[i].k); if (tests[i].bucket != actual) { AIM_DIE("histogram_bucket test failed: k=%u expect=%u actual=%u", tests[i].k, tests[i].bucket, actual); } AIM_ASSERT(tests[i].bucket == histogram_bucket(tests[i].reverse)); actual = histogram_key(tests[i].bucket); if (tests[i].reverse != actual) { AIM_DIE("histogram_key test failed: bucket=%u expect=%u actual=%u", tests[i].bucket, tests[i].reverse, actual); } } }
void * aim_zmalloc(size_t size) { void *ptr = AIM_CALLOC(1, size); if (ptr == NULL) { AIM_DIE("memory allocation failed"); } return ptr; }
void * aim_realloc(void *ptr, size_t size) { ptr = AIM_REALLOC(ptr, size); if (ptr == NULL) { AIM_DIE("memory allocation failed"); } return ptr; }
static void check(struct histogram *hist, uint32_t k, uint32_t v) { uint32_t i = histogram_bucket(k); AIM_ASSERT(i < HISTOGRAM_BUCKETS); uint32_t v2 = hist->counts[i]; if (v != v2) { AIM_DIE("Expected %u at key %u (index %u), found %u", v, k, i, v2); } }
static void ind_soc_cfg_commit(void) { aim_log_t *lobj; if ((lobj = aim_log_find("socketmanager")) == NULL) { AIM_DIE("Could not find log module"); } else { lobj->common_flags = staged_config.log_flags; } }
static void* sem_test_thread__(void* p) { int rv; sem_test_t* t = (sem_test_t*)p; uint64_t t0 = aim_time_monotonic(); rv = aim_sem_take_timeout(t->take, t->timeout); uint64_t t1 = aim_time_monotonic(); uint64_t duration = t1 - t0; int64_t delta = t->timeout - duration; printf("%s: rv=% d timeout: %.8" PRId64 " duration: %.8" PRId64 " delta: % .8" PRId64 "\n", t->name, rv, t->timeout, duration, delta); if(rv == -1) { if(delta > 0) { AIM_DIE("%s: premature timeout.", t->name); } /* Arbitrary, within 30ms */ if(delta < -30000 && t->timeout) { AIM_DIE("%s: timeout blown.", t->name); } } else if(rv == 0) { if(delta < 0 && t->timeout) { AIM_DIE("%s: waited longer than timeout.", t->name); } if(t->timeout_required) { AIM_DIE("%s: timeout was required.", t->name); } (*t->acquired)++; } if(t->give) { aim_sem_give(t->give); } return NULL; }
indigo_error_t indigo_port_stats_get_one(of_port_no_t port_no, of_port_stats_entry_t *port_stats) { of_object_t props; of_object_t prop; of_port_stats_entry_properties_bind(port_stats, &props); of_port_stats_prop_ethernet_init(&prop, props.version, -1, 1); if (of_list_port_stats_prop_append_bind(&props, &prop) < 0) { AIM_DIE("unexpected error appending to port stats properties"); } port_counters[port_no].stats++; return INDIGO_ERROR_NONE; }
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); }
os_sem_t os_sem_create_flags(int count, uint32_t flags) { os_sem_t s = aim_zmalloc(sizeof(*s)); if(flags & OS_SEM_CREATE_F_TRUE_RELATIVE_TIMEOUTS) { s->efd = eventfd(count, EFD_SEMAPHORE | EFD_NONBLOCK); if(s->efd == -1) { AIM_DIE("eventfd() failed - %s", strerror(errno)); } } else { s->efd = EFD_INVALID; sem_init(&s->sem, 0, count); } return s; }
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); }
void ind_cxn_bundle_ctrl_handle(connection_t *cxn, of_object_t *obj) { uint32_t bundle_id; uint16_t ctrl_type; uint16_t flags; uint16_t err_code = OFPBFC_UNKNOWN; of_bundle_ctrl_msg_bundle_id_get(obj, &bundle_id); of_bundle_ctrl_msg_bundle_ctrl_type_get(obj, &ctrl_type); of_bundle_ctrl_msg_flags_get(obj, &flags); bundle_t *bundle = find_bundle(cxn, bundle_id); if (ctrl_type == OFPBCT_OPEN_REQUEST) { if (bundle != NULL) { err_code = OFPBFC_BUNDLE_EXIST; goto error; } bundle = find_bundle(cxn, BUNDLE_ID_INVALID); if (bundle == NULL) { err_code = OFPBFC_OUT_OF_BUNDLES; goto error; } bundle->id = bundle_id; bundle->flags = flags; AIM_ASSERT(bundle->count == 0); AIM_ASSERT(bundle->allocated == 0); AIM_ASSERT(bundle->bytes == 0); AIM_ASSERT(bundle->msgs == NULL); } else if (ctrl_type == OFPBCT_CLOSE_REQUEST) { /* Ignored */ } else if (ctrl_type == OFPBCT_COMMIT_REQUEST) { if (bundle == NULL) { err_code = OFPBFC_BAD_ID; goto error; } if (comparator && !(bundle->flags & OFPBF_ORDERED)) { qsort(bundle->msgs, bundle->count, sizeof(bundle->msgs[0]), compare_message); } struct bundle_task_state *state = aim_zmalloc(sizeof(*state)); state->cxn_id = cxn->cxn_id; state->reply = of_object_dup(obj); of_bundle_ctrl_msg_bundle_ctrl_type_set(state->reply, OFPBCT_COMMIT_REPLY); state->id = bundle->id; state->count = bundle->count; state->offset = 0; state->msgs = bundle->msgs; if (ind_soc_task_register(bundle_task, state, IND_SOC_NORMAL_PRIORITY) < 0) { AIM_DIE("Failed to create long running task for bundle"); } ind_cxn_pause(cxn); /* Transfer ownership of msgs to task */ bundle->msgs = NULL; bundle->count = 0; free_bundle(bundle); /* Do not send reply yet */ return; } else if (ctrl_type == OFPBCT_DISCARD_REQUEST) { if (bundle == NULL) { err_code = OFPBFC_BAD_ID; goto error; } free_bundle(bundle); } else { err_code = OFPBFC_BAD_TYPE; goto error; } /* Send reply */ of_object_t *reply = of_object_dup(obj); /* Derive the reply subtype from the request */ of_bundle_ctrl_msg_bundle_ctrl_type_set(reply, ctrl_type+1); indigo_cxn_send_controller_message(cxn->cxn_id, reply); return; error: indigo_cxn_send_error_reply( cxn->cxn_id, obj, OF_ERROR_TYPE_BUNDLE_FAILED, err_code); }
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)); } } }
/* Parse a controller string like "tcp:127.0.0.1:6633". */ static indigo_error_t parse_controller(struct controller *controller, cJSON *root) { indigo_cxn_protocol_t proto; indigo_cxn_params_tcp_over_ipv4_t *params4; indigo_cxn_params_tcp_over_ipv6_t *params6; indigo_cxn_params_unix_t *params_unix; char *proto_str = NULL, *ip = NULL, *unix_path = NULL; int port; int listen; int local; int prio; indigo_error_t err; err = ind_cfg_lookup_string(root, "protocol", &proto_str); if (err == INDIGO_ERROR_NOT_FOUND) { /* Allow default protocol value */ proto_str = "tcp"; } else if (err < 0) { if (err == INDIGO_ERROR_PARAM) { AIM_LOG_ERROR("Config: 'protocol' must be a string"); } return err; } if (strcmp(proto_str, "tcp") == 0) { proto = INDIGO_CXN_PROTO_TCP_OVER_IPV4; } else if (strcmp(proto_str, "tcp6") == 0) { proto = INDIGO_CXN_PROTO_TCP_OVER_IPV6; } else if (strcmp(proto_str, "tls") == 0) { proto = INDIGO_CXN_PROTO_TLS_OVER_IPV4; } else if (strcmp(proto_str, "tls6") == 0) { proto = INDIGO_CXN_PROTO_TLS_OVER_IPV6; } else if (strcmp(proto_str, "unix") == 0) { proto = INDIGO_CXN_PROTO_UNIX; } else { AIM_LOG_ERROR("Config: Invalid controller protocol: %s", proto_str); return INDIGO_ERROR_PARAM; } switch(proto) { case INDIGO_CXN_PROTO_TCP_OVER_IPV4: /* fall-through */ case INDIGO_CXN_PROTO_TCP_OVER_IPV6: /* fall-through */ case INDIGO_CXN_PROTO_TLS_OVER_IPV4: /* fall-through */ case INDIGO_CXN_PROTO_TLS_OVER_IPV6: err = ind_cfg_lookup_string(root, "ip_addr", &ip); if (err < 0) { if (err == INDIGO_ERROR_PARAM) { AIM_LOG_ERROR("Config: 'ip_addr' must be a string"); } else if (err == INDIGO_ERROR_NOT_FOUND) { AIM_LOG_ERROR("Config: Missing 'ip_addr' in controller spec"); } return err; } /* * WARNING: no validity checks for IP address. * Instead, they are performed by the cli front-end. */ err = ind_cfg_lookup_int(root, "port", &port); if (err == INDIGO_ERROR_NOT_FOUND) { /* Allow default protocol value */ port = 6633; } else if (err < 0) { if (err == INDIGO_ERROR_PARAM) { AIM_LOG_ERROR("Config: 'port' must be an integer"); } return err; } if (port < 0 || port >= 0xffff) { AIM_LOG_ERROR("Config: Invalid controller port: %d", port); return INDIGO_ERROR_PARAM; } break; case INDIGO_CXN_PROTO_UNIX: err = ind_cfg_lookup_string(root, "unix_path", &unix_path); if (err < 0) { if (err == INDIGO_ERROR_PARAM) { AIM_LOG_ERROR("Config: 'unix_path' must be a string"); } else if (err == INDIGO_ERROR_NOT_FOUND) { AIM_LOG_ERROR("Config: Missing 'unix_path' in controller spec"); } return err; } break; default: AIM_DIE("Config: No handling for protocol %d", proto); } err = ind_cfg_lookup_bool(root, "listen", &listen); if (err == INDIGO_ERROR_NOT_FOUND) { listen = 0; } else if (err < 0) { if (err == INDIGO_ERROR_PARAM) { AIM_LOG_ERROR("Config: 'listen' must be a boolean"); } return err; } err = ind_cfg_lookup_bool(root, "local", &local); if (err == INDIGO_ERROR_NOT_FOUND) { local = 0; } else if (err < 0) { if (err == INDIGO_ERROR_PARAM) { AIM_LOG_ERROR("Config: 'local' must be a boolean"); } return err; } err = ind_cfg_lookup_int(root, "priority", &prio); if (err == INDIGO_ERROR_NOT_FOUND) { prio = 0; } else if (err < 0) { if (err == INDIGO_ERROR_PARAM) { AIM_LOG_ERROR("Config: 'priority' must be an integer"); } return err; } /* populate 'controller' struct */ switch (proto) { case INDIGO_CXN_PROTO_TCP_OVER_IPV4: /* fall-through */ case INDIGO_CXN_PROTO_TLS_OVER_IPV4: params4 = &controller->proto.tcp_over_ipv4; params4->protocol = proto; strncpy(params4->controller_ip, ip, sizeof(params4->controller_ip)); params4->controller_port = port; break; case INDIGO_CXN_PROTO_TCP_OVER_IPV6: /* fall-through */ case INDIGO_CXN_PROTO_TLS_OVER_IPV6: params6 = &controller->proto.tcp_over_ipv6; params6->protocol = proto; strncpy(params6->controller_ip, ip, sizeof(params6->controller_ip)); params6->controller_port = port; break; case INDIGO_CXN_PROTO_UNIX: params_unix = &controller->proto.unx; params_unix->protocol = proto; strncpy(params_unix->unix_path, unix_path, INDIGO_CXN_UNIX_PATH_LEN); break; default: AIM_DIE("Config: No handling for protocol %d", proto); } controller->config.listen = listen; controller->config.cxn_priority = prio; controller->config.local = local; controller->config.version = OFCONNECTIONMANAGER_CONFIG_OF_VERSION; if (!local) { controller->config.periodic_echo_ms = staged_config.keepalive_period_ms; controller->config.reset_echo_count = 3; } else { controller->config.periodic_echo_ms = 0; controller->config.reset_echo_count = 0; } return INDIGO_ERROR_NONE; }
/* * 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; }
int aim_main(int argc, char* argv[]) { AIM_LOG_STRUCT_REGISTER(); /* * We queue many (up to 20) 64KB messages before sending them on the socket * with a single writev(). After we free all the messages the malloc * implementation would see we have more than 128KB (the default trim value) * free and return it to the OS with a call to brk(). Every time we * allocate a new message we have to get the memory with brk() all over * again. * * Increasing the trim threshold above the size of our working set * eliminates this churn. */ mallopt(M_TRIM_THRESHOLD, 2*1024*1024); loci_logger = ivs_loci_logger; core_cfg.expire_flows = 1; core_cfg.stats_check_ms = 900; core_cfg.disconnected_mode = INDIGO_CORE_DISCONNECTED_MODE_STICKY; parse_options(argc, argv); /* Setup logging from command line options */ if (loglevel >= LOGLEVEL_DEFAULT) { aim_log_fid_set_all(AIM_LOG_FLAG_FATAL, 1); aim_log_fid_set_all(AIM_LOG_FLAG_ERROR, 1); aim_log_fid_set_all(AIM_LOG_FLAG_WARN, 1); } if (loglevel >= LOGLEVEL_VERBOSE) { aim_log_fid_set_all(AIM_LOG_FLAG_VERBOSE, 1); } if (loglevel >= LOGLEVEL_TRACE) { aim_log_fid_set_all(AIM_LOG_FLAG_TRACE, 1); } if (use_syslog) { aim_log_pvs_set_all(aim_pvs_syslog_open("ivs", LOG_NDELAY, LOG_DAEMON)); } AIM_LOG_MSG("Starting %s (%s) pid %d", program_version, AIM_STRINGIFY(BUILD_ID), getpid()); /* Initialize all modules */ if (ind_soc_init(&soc_cfg) < 0) { AIM_LOG_FATAL("Failed to initialize Indigo socket manager"); return 1; } if (ind_cxn_init(&cxn_cfg) < 0) { AIM_LOG_FATAL("Failed to initialize Indigo connection manager"); return 1; } if (ind_core_init(&core_cfg) < 0) { AIM_LOG_FATAL("Failed to initialize Indigo core module"); return 1; } if (ind_ovs_init(datapath_name, max_flows) < 0) { AIM_LOG_FATAL("Failed to initialize OVSDriver module"); return 1; } if (lacpa_init() < 0) { AIM_LOG_FATAL("Failed to initialize LACP Agent module"); return 1; } if (lldpa_system_init() < 0) { AIM_LOG_FATAL("Failed to initialize LLDP Agent module"); return 1; } if (arpa_init() < 0) { AIM_LOG_FATAL("Failed to initialize ARP Agent module"); return 1; } if (router_ip_table_init() < 0) { AIM_LOG_FATAL("Failed to initialize Router IP table module"); return 1; } if (icmpa_init() < 0) { AIM_LOG_FATAL("Failed to initialize ICMP Agent module"); return 1; } if (dhcpra_system_init() < 0) { AIM_LOG_FATAL("Failed to initialize DHCP relay table and agent module"); return 1; } if (enable_tunnel) { if (ind_ovs_tunnel_init() < 0) { AIM_LOG_FATAL("Failed to initialize tunneling"); return 1; } } if (pipeline == NULL) { if (openflow_version == NULL || !strcmp(openflow_version, "1.0")) { pipeline = "standard-1.0"; } else if (!strcmp(openflow_version, "1.3")) { pipeline = "standard-1.3"; } else { AIM_DIE("unexpected OpenFlow version"); } } AIM_LOG_INFO("Initializing forwarding pipeline '%s'", pipeline); indigo_error_t rv = pipeline_set(pipeline); if (rv < 0) { AIM_LOG_FATAL("Failed to set pipeline: %s", indigo_strerror(rv)); return 1; } #if 0 /* TODO Configuration module installs its own SIGHUP handler. */ if (ind_cfg_init() < 0) { AIM_LOG_FATAL("Failed to initialize Indigo configuration module"); return 1; } #endif if (config_filename) { ind_cfg_filename_set(config_filename); if (ind_cfg_load() < 0) { AIM_LOG_FATAL("Failed to load configuration file"); return 1; } } if (dpid) { indigo_core_dpid_set(dpid); } /* Enable all modules */ if (ind_soc_enable_set(1) < 0) { AIM_LOG_FATAL("Failed to enable Indigo socket manager"); return 1; } if (ind_cxn_enable_set(1) < 0) { AIM_LOG_FATAL("Failed to enable Indigo connection manager"); return 1; } if (ind_core_enable_set(1) < 0) { AIM_LOG_FATAL("Failed to enable Indigo core module"); return 1; } /* Add interfaces from command line */ { biglist_t *element; char *str; int index = 1; BIGLIST_FOREACH_DATA(element, interfaces, char *, str) { AIM_LOG_MSG("Adding interface %s (port %d)", str, index); if (indigo_port_interface_add(str, index, NULL)) { AIM_LOG_FATAL("Failed to add interface %s", str); return 1; } index++; } }
int test_table_data__(bighash_table_t *table, biglist_t** entry_list) { /* Make sure we can find all entries in the entry list */ { biglist_t *ble; test_entry_t *te; BIGLIST_FOREACH_DATA(ble, *entry_list, test_entry_t*, te) { test_entry_t *fe = find_by_id(table, te->id); if(fe == NULL) { AIM_DIE("inserted entry (id=%d) was not found after filling table", te->id); } else if(fe != te) { AIM_DIE("Retreived pointer does not match. (te=%p (%d), fe=%p (%d)", te, te->id, fe, fe->id); } } } /* Make sure all elements in the list are enumerated */ { bighash_iter_t iter; bighash_entry_t *e; int count = 0; for(e = bighash_iter_start(table, &iter); e; e = bighash_iter_next(&iter)) { test_entry_t *te = container_of(e, hash_entry, test_entry_t); if(te->found) { AIM_DIE("Entry %p:%d was already enumerated.", te, te->id); } te->found++; if(biglist_find(*entry_list, te) == NULL) { AIM_DIE("Entry %p:%d is not in the entry list.", te, te->id); } count++; } if(count != biglist_length(*entry_list)) { AIM_DIE("Enumeration error: count=%d, length=%d", count, biglist_length(*entry_list)); } } /* Remove from table */ { biglist_t *ble; test_entry_t *te; int count = 1; BIGLIST_FOREACH_DATA(ble, *entry_list, test_entry_t*, te) { bighash_remove(table, &te->hash_entry); if(find_by_id(table, te->id) != NULL) { AIM_DIE("Removed entry was not removed."); } if(bighash_entry_count(table) != biglist_length(*entry_list)-count) { AIM_DIE("Entry count mismatch: hashcount=%d, listcount=%d", bighash_entry_count(table), biglist_length(*entry_list)-count); } count++; } } /* Free entry list */ biglist_free_all(*entry_list, aim_free); *entry_list = NULL; return 0; }
int main(int argc, char *argv[]) { biglist_t *entries = NULL; /** Basic Hashing -- statically allocated table */ bighash_table_init_static(&static_table); insert__(&static_table, 10000, &entries); test_table_data__(&static_table, &entries); bighash_table_destroy(&static_table, NULL); /** Basic hashing -- dynamically allocated table */ { bighash_table_t *dtable; dtable = bighash_table_create(64); insert__(dtable, 10000, &entries); test_table_data__(dtable, &entries); bighash_table_destroy(dtable, NULL); } /** Count and removal while iterating */ { bighash_table_t *table; bighash_iter_t iter; bighash_entry_t *e; test_entry_t *te; int ecount=100; int count = 0; table = bighash_table_create(64); insert__(table, ecount, NULL); if(bighash_entry_count(table) != ecount) { AIM_DIE("Entry count mismatch: expected %d, got %d", ecount, bighash_entry_count(table)); } /* Iterate once, just counting */ for(te = (test_entry_t*)bighash_iter_start(table, &iter); te; te = (test_entry_t*)bighash_iter_next(&iter)) { count++; } if(count != ecount) { AIM_DIE("Iteration count incorrect (%d)", count); } /* Iterate again, removing elements. Tests both iteration restart * and remove-while-iterating. */ for(e = bighash_iter_start(table, &iter); e; e = bighash_iter_next(&iter)) { test_entry_t *te = container_of(e, hash_entry, test_entry_t); bighash_remove(table, &te->hash_entry); /* Clear the list links on this element to make sure the * removal was done properly. */ memset(te, 0, sizeof(*te)); aim_free(te); } if(bighash_entry_count(table) != 0) { AIM_DIE("Count is not zero after iterated removal (count=%d)", bighash_entry_count(table)); } bighash_table_destroy(table, NULL); } /** Migrating between tables */ { bighash_table_t *src; bighash_table_t *dst; src = bighash_table_create(64); dst = bighash_table_create(128); insert__(src, 1000, &entries); bighash_entries_move(dst, src); if(bighash_entry_count(src) != 0) { AIM_DIE("Source table is not empty."); } bighash_table_destroy(src, NULL); test_table_data__(dst, &entries); bighash_table_destroy(dst, NULL); } /** Check utilization and automatic element destruction */ bighash_table_init_static(&static_table); insert__(&static_table, 100000, 0); bighash_table_utilization_show(&static_table, &aim_pvs_stdout); bighash_table_destroy(&static_table, free_test_entry); test_template(); return 0; }
static void reset_lua(void) { if (lua) { pipeline_lua_table_reset(); pipeline_lua_stats_reset(); lua_close(lua); } lua = luaL_newstate(); if (lua == NULL) { AIM_DIE("failed to allocate Lua state"); } luaL_openlibs(lua); /* Give Lua a pointer to the static context struct */ context.valid = false; lua_pushlightuserdata(lua, &context); lua_setglobal(lua, "_context"); /* Give Lua the names of all fields */ lua_newtable(lua); int i = 0; while (pipeline_lua_field_names[i]) { lua_pushstring(lua, pipeline_lua_field_names[i]); lua_rawseti(lua, -2, i+1); i++; } lua_setglobal(lua, "field_names"); lua_pushcfunction(lua, pipeline_lua_table_register); lua_setglobal(lua, "register_table"); const struct builtin_lua *builtin_lua; for (builtin_lua = &pipeline_lua_builtin_lua[0]; builtin_lua->name; builtin_lua++) { AIM_LOG_VERBOSE("Loading builtin Lua code %s", builtin_lua->name); char name[64]; snprintf(name, sizeof(name), "=%s", builtin_lua->name); /* Parse */ if (luaL_loadbuffer(lua, builtin_lua->start, builtin_lua->end-builtin_lua->start, name) != 0) { AIM_DIE("Failed to load built-in Lua code %s: %s", builtin_lua->name, lua_tostring(lua, -1)); } /* Execute */ if (lua_pcall(lua, 0, 0, 0) != 0) { AIM_DIE("Failed to execute built-in Lua code %s: %s", builtin_lua->name, lua_tostring(lua, -1)); } } /* Store a reference to process() so we can efficiently retrieve it */ lua_getglobal(lua, "process"); AIM_ASSERT(lua_isfunction(lua, -1)); process_ref = luaL_ref(lua, LUA_REGISTRYINDEX); /* Store a reference to command() so we can efficiently retrieve it */ lua_getglobal(lua, "command"); AIM_ASSERT(lua_isfunction(lua, -1)); command_ref = luaL_ref(lua, LUA_REGISTRYINDEX); /* Store a reference to pktin() so we can efficiently retrieve it */ lua_getglobal(lua, "pktin"); AIM_ASSERT(lua_isfunction(lua, -1)); pktin_ref = luaL_ref(lua, LUA_REGISTRYINDEX); lua_pushinteger(lua, ind_ovs_pktin_socket_netlink_port(&pktin_soc)); lua_setglobal(lua, "netlink_port"); }
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); }
int vpi_mmap_interface_create(vpi_interface_t** vi, char* args[], int flags, const char* vpi_name_ptr) { struct sockaddr_ll sockaddr; struct packet_mreq sockparams; struct tpacket_req treq; struct ifreq ifreq; vpi_interface_mmap_t* nvi = aim_zmalloc(sizeof(*nvi)); char** arg = args; int version; int i; frame_control_t* fc; AIM_REFERENCE(flags); if(nvi == NULL) { VPI_MERROR("interface allocation failed for %s.", vpi_name_ptr); return -1; } /* * Point our log_string to our name so we can use it immediately * in log messages. */ nvi->log_string = vpi_name_ptr; /* * The first argument is the type -- skip for now */ arg++; aim_strlcpy(nvi->interface_name, *arg, sizeof(nvi->interface_name)); /* Create RAW socket */ if((nvi->fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) { VPI_ERROR(nvi, "socket() failed: %s\n", strerror(errno)); aim_free(nvi); return -1; } /* Set version */ version = TPACKET_V2; if(setsockopt(nvi->fd, SOL_PACKET, PACKET_VERSION, &version, sizeof(version)) < 0) { VPI_ERROR(nvi, "setsockopt() version failed: %s\n", strerror(errno)); aim_free(nvi); return -1; } /* * Get the interface index for the requested interface, as specified * in the current argument. */ VPI_MEMSET(&ifreq, 0, sizeof(ifreq)); aim_strlcpy(ifreq.ifr_name, nvi->interface_name, IFNAMSIZ); if(ioctl(nvi->fd, SIOCGIFINDEX, &ifreq) < 0) { VPI_ERROR(nvi, "ioctl() failed: %s", strerror(errno)); close(nvi->fd); aim_free(nvi); return -1; } nvi->ifindex = ifreq.ifr_ifindex; VPI_INFO(nvi, "ifndex is %d", nvi->ifindex); /* Set promisc */ VPI_MEMSET(&sockparams, 0, sizeof(sockparams)); sockparams.mr_type = PACKET_MR_PROMISC; sockparams.mr_ifindex = nvi->ifindex; if(setsockopt(nvi->fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, (void *)&sockparams, sizeof(sockparams)) < 0) { VPI_ERROR(nvi, "setsockopt() promisc failed. %s\n", strerror(errno)); close(nvi->fd); aim_free(nvi); return -1; } /* Set up rx_ring buffer */ VPI_MEMSET(&treq, 0, sizeof(treq)); treq.tp_block_size = BLOCK_SIZE; treq.tp_frame_size = FRAME_SIZE; treq.tp_block_nr = NUM_BLOCKS; treq.tp_frame_nr = NUM_FRAMES;; if(setsockopt(nvi->fd, SOL_PACKET, PACKET_RX_RING, (void*)&treq , sizeof(treq)) < 0) { VPI_ERROR(nvi, "setsockopt() rx_ring failed. %s\n", strerror(errno)); close(nvi->fd); aim_free(nvi); return -1; } /* If num blocks change, bail! */ if(treq.tp_block_nr != NUM_BLOCKS) { AIM_DIE("Unhandled: RX_RING block number changed!\n"); } /* Set up rx_ring */ nvi->rx_ring.buf = mmap(NULL, BLOCK_SIZE*NUM_BLOCKS, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_LOCKED, nvi->fd, 0); if(nvi->rx_ring.buf == MAP_FAILED) { VPI_ERROR(nvi, "mmap() failed.\n"); close(nvi->fd); aim_free(nvi); return -1; } /* Set up rx_ring and frame controls */ nvi->rx_ring.current_frame = 0; for(i = 0; i < NUM_FRAMES; i++) { fc = &nvi->rx_ring.frames[i]; fc->base = nvi->rx_ring.buf + (i*FRAME_SIZE); } /* Bind */ VPI_MEMSET(&sockaddr, 0, sizeof(sockaddr)); sockaddr.sll_family = AF_PACKET; sockaddr.sll_protocol = htons(ETH_P_ALL); sockaddr.sll_ifindex = nvi->ifindex; if(bind(nvi->fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) < 0) { VPI_ERROR(nvi, "bind() failed.\n"); close(nvi->fd); aim_free(nvi); return -1; } nvi->interface.send = vpi_mmap_interface_send; nvi->interface.recv = vpi_mmap_interface_recv; nvi->interface.recv_ready = vpi_mmap_interface_recv_ready; nvi->interface.destroy = vpi_mmap_interface_destroy; nvi->interface.descriptor = vpi_mmap_interface_descriptor; *vi = (vpi_interface_t*)nvi; return 0; }
int aim_main(int argc, char *argv[]) { set_crash_handler(crash_handler); AIM_LOG_STRUCT_REGISTER(); loci_logger = ofagent_loci_logger; core_cfg.stats_check_ms = 900; parse_options(argc, argv); /* Setup logging from command line options */ if (loglevel >= LOGLEVEL_DEFAULT) { aim_log_fid_set_all(AIM_LOG_FLAG_MSG, 1); aim_log_fid_set_all(AIM_LOG_FLAG_FATAL, 1); aim_log_fid_set_all(AIM_LOG_FLAG_ERROR, 1); aim_log_fid_set_all(AIM_LOG_FLAG_WARN, 1); } if (loglevel >= LOGLEVEL_VERBOSE) { aim_log_fid_set_all(AIM_LOG_FLAG_VERBOSE, 1); } if (loglevel >= LOGLEVEL_TRACE) { aim_log_fid_set_all(AIM_LOG_FLAG_TRACE, 1); } if (use_syslog) { aim_log_pvs_set_all(aim_pvs_syslog_open("ofagent", LOG_NDELAY, LOG_DAEMON)); } create_pidfile(); AIM_LOG_MSG("Starting ofagent %s (%s %s) pid %d", ofagent_version, ofagent_build_id, ofagent_build_os, getpid()); /* Increase maximum number of file descriptors */ struct rlimit rlim = { .rlim_cur = SOCKETMANAGER_CONFIG_MAX_SOCKETS, .rlim_max = SOCKETMANAGER_CONFIG_MAX_SOCKETS }; if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) { AIM_LOG_WARN("Failed to increase RLIMIT_NOFILE"); } /* Initialize all modules */ if (ind_soc_init(&soc_cfg) < 0) { AIM_LOG_FATAL("Failed to initialize Indigo socket manager"); return 1; } if (ind_cxn_init(&cxn_cfg) < 0) { AIM_LOG_FATAL("Failed to initialize Indigo connection manager"); return 1; } if (ind_core_init(&core_cfg) < 0) { AIM_LOG_FATAL("Failed to initialize Indigo core module"); return 1; } if (bcm_driver_init() < 0) { AIM_LOG_FATAL("Failed to initialize BCM driver"); return 1; } if (pipeline == NULL) { if (openflow_version == NULL || !strcmp(openflow_version, "1.0")) { pipeline = "standard-1.0"; } else if (!strcmp(openflow_version, "1.3")) { pipeline = "standard-1.3"; } else { AIM_DIE("unexpected OpenFlow version"); } } AIM_LOG_VERBOSE("Initializing forwarding pipeline '%s'", pipeline); indigo_error_t rv = pipeline_set(pipeline); if (rv < 0) { AIM_LOG_FATAL("Failed to set pipeline: %s", indigo_strerror(rv)); return 1; } if (config_filename) { ind_cfg_filename_set(config_filename); if (ind_cfg_load() < 0) { AIM_LOG_FATAL("Failed to load configuration file"); return 1; } } if (dpid) { indigo_core_dpid_set(dpid); } /* Enable all modules */ if (ind_soc_enable_set(1) < 0) { AIM_LOG_FATAL("Failed to enable Indigo socket manager"); return 1; } if (ind_cxn_enable_set(1) < 0) { AIM_LOG_FATAL("Failed to enable Indigo connection manager"); return 1; } if (ind_core_enable_set(1) < 0) { AIM_LOG_FATAL("Failed to enable Indigo core module"); return 1; } if (bcm_driver_enable_set(1) < 0) { AIM_LOG_FATAL("Failed to enable BCM driver"); return 1; } /* Add controller from command line */ { biglist_t *element; char *str; BIGLIST_FOREACH_DATA(element, controllers, char *, str) { AIM_LOG_VERBOSE("Adding controller %s", str); indigo_cxn_protocol_params_t proto; if (parse_controller(str, &proto, OF_TCP_PORT) < 0) { AIM_LOG_FATAL("Failed to parse controller string '%s'", str); return 1; } indigo_cxn_config_params_t config = { .version = OF_VERSION_1_0, .cxn_priority = 0, .local = 0, .listen = 0, .periodic_echo_ms = 2000, .reset_echo_count = 3, }; indigo_controller_id_t id; if (indigo_controller_add(&proto, &config, &id) < 0) { AIM_LOG_FATAL("Failed to add controller %s", str); return 1; } } } ind_core_mfr_desc_set(mfr_desc); snprintf(sw_desc, sizeof(sw_desc), "ofagent %s %s %s", ofagent_version, ofagent_build_id, ofagent_build_os); ind_core_sw_desc_set(sw_desc); // TODO //read_hardware_version(hw_desc); ind_core_hw_desc_set(hw_desc); char hostname[256]; char domainname[256]; if (gethostname(hostname, sizeof(hostname))) { sprintf(hostname, "(unknown)"); } if (getdomainname(domainname, sizeof(domainname))) { sprintf(domainname, "(unknown)"); } snprintf(dp_desc, sizeof(dp_desc), "%s.%s pid %d", hostname, domainname, getpid()); ind_core_dp_desc_set(dp_desc); AIM_LOG_INFO("Datapath description: %s", dp_desc); ind_core_serial_num_set(serial_num); /* The SIGHUP handler triggers sighup_callback to run in the main loop. */ if ((sighup_eventfd = eventfd(0, 0)) < 0) { AIM_LOG_FATAL("Failed to allocate eventfd"); abort(); } signal(SIGHUP, sighup); if (ind_soc_socket_register(sighup_eventfd, sighup_callback, NULL) < 0) { abort(); } /* The SIGTERM handler triggers sigterm_callback to run in the main loop. */ if ((sigterm_eventfd = eventfd(0, 0)) < 0) { AIM_LOG_FATAL("Failed to allocate eventfd"); abort(); } signal(SIGTERM, sigterm); if (ind_soc_socket_register(sigterm_eventfd, sigterm_callback, NULL) < 0) { abort(); } /* TODO Start handling upcalls */ //ind_ovs_enable(); //packet_trace_init(datapath_name); ind_soc_select_and_run(-1); AIM_LOG_MSG("Stopping ofagent %s", ofagent_version); ind_core_finish(); bcm_driver_finish(); ind_cxn_finish(); ind_soc_finish(); return 0; }