Esempio n. 1
0
void
ind_cxn_bundle_add_handle(connection_t *cxn, of_object_t *obj)
{
    uint32_t bundle_id;
    uint16_t flags;
    of_octets_t data;

    of_bundle_add_msg_bundle_id_get(obj, &bundle_id);
    of_bundle_add_msg_flags_get(obj, &flags);
    of_bundle_add_msg_data_get(obj, &data);

    bundle_t *bundle = find_bundle(cxn, bundle_id);
    if (bundle == NULL) {
        indigo_cxn_send_error_reply(
            cxn->cxn_id, obj,
            OF_ERROR_TYPE_BUNDLE_FAILED,
            OFPBFC_BAD_ID);
        return;
    }

    /* Validate length */
    if (data.bytes < OF_MESSAGE_HEADER_LENGTH || data.bytes != of_message_length_get(data.data)) {
        indigo_cxn_send_error_reply(
            cxn->cxn_id, obj,
            OF_ERROR_TYPE_BUNDLE_FAILED,
            OFPBFC_MSG_BAD_LEN);
        AIM_LOG_WARN("Inconsistent bundled message length", bundle->id);
        return;
    }

    /* Limit number of messages in the bundle */
    if (bundle->count >= OFCONNECTIONMANAGER_CONFIG_MAX_BUNDLE_MSGS) {
        indigo_cxn_send_error_reply(
            cxn->cxn_id, obj,
            OF_ERROR_TYPE_BUNDLE_FAILED,
            OFPBFC_MSG_TOO_MANY);
        AIM_LOG_WARN("Exceeded maximum number (%u) of messages in bundle %u", OFCONNECTIONMANAGER_CONFIG_MAX_BUNDLE_MSGS, bundle->id);
        return;
    }

    /* Limit amount of memory used by the bundle */
    if ((bundle->bytes + data.bytes) > OFCONNECTIONMANAGER_CONFIG_MAX_BUNDLE_BYTES) {
        indigo_cxn_send_error_reply(
            cxn->cxn_id, obj,
            OF_ERROR_TYPE_BUNDLE_FAILED,
            OFPBFC_MSG_TOO_MANY);
        AIM_LOG_WARN("Exceeded maximum size (%u bytes) of messages in bundle %u", OFCONNECTIONMANAGER_CONFIG_MAX_BUNDLE_BYTES, bundle->id);
        return;
    }

    if (bundle->count == bundle->allocated) {
        /* Resize array */
        uint32_t new_allocated = (bundle->allocated == 0 ? 1 : bundle->allocated * 2);
        bundle->msgs = aim_realloc(bundle->msgs, sizeof(*bundle->msgs) * new_allocated);
        bundle->allocated = new_allocated;
    }

    bundle->msgs[bundle->count++] = aim_memdup(data.data, data.bytes);
    bundle->bytes += data.bytes;
}
Esempio n. 2
0
int
onlp_fani_info_get(onlp_oid_t id, onlp_fan_info_t* rv)
{
    *rv = fans__[ONLP_OID_ID_GET(id)];
    rv->caps |= ONLP_FAN_CAPS_GET_RPM;

    int len;
    char direction[16] = {0};

    int fid = ONLP_OID_ID_GET(id);

    /* Read the current airflow direction */
    onlp_file_read((uint8_t*)direction, sizeof(direction), &len,
                   SYS_HWMON_PREFIX "/fan_dir");

#define FAN_DIR_F2B "front-to-back"
#define FAN_DIR_B2F "back-to-front"

    if(!strncmp(direction, FAN_DIR_F2B, strlen(FAN_DIR_F2B))) {
        rv->status |= ONLP_FAN_STATUS_F2B;
        rv->caps |= ONLP_FAN_CAPS_F2B;
    }
    else if(!strncmp(direction, FAN_DIR_B2F, strlen(FAN_DIR_B2F))) {
        rv->status |= ONLP_FAN_STATUS_B2F;
        rv->caps |= ONLP_FAN_CAPS_B2F;
    }
    else {
        AIM_LOG_WARN("Invalid fan direction: '%s'", direction);
    }


    switch(fid)
        {
        case FAN_ID_FAN1:
        case FAN_ID_FAN2:
        case FAN_ID_FAN3:
        case FAN_ID_FAN4:
            {
                if(rv->status & ONLP_FAN_STATUS_F2B) {
                    return sys_fan_info_get__(rv, fid);
                }
                if(rv->status & ONLP_FAN_STATUS_B2F) {
                    return sys_fan_info_get__(rv, fid+4);
                }
                return ONLP_STATUS_E_INTERNAL;
            }

        case FAN_ID_FAN5:
        case FAN_ID_FAN6:
            {
                return psu_fan_info_get__(rv, fid);
            }
        }

    return ONLP_STATUS_E_INVALID;
}
static void
ind_cxn_cfg_commit(void)
{
    aim_log_t *lobj;
    int i;

    if ((lobj = aim_log_find("ofconnectionmanager")) == NULL) {
        AIM_LOG_WARN("Could not find log module");
    } else {
        lobj->common_flags = staged_config.log_flags;
    }

    for (i = 0; i < staged_config.num_controllers; i++) {
        struct controller *c = &staged_config.controllers[i];
        const struct controller *old_controller;
        int rv;
        indigo_cxn_params_tcp_over_ipv4_t *proto = &c->proto.tcp_over_ipv4;
        AIM_LOG_INFO("controller %d: %s:%hu", i,
                     proto->controller_ip, proto->controller_port);

        /* Keep existing connections to the same controller. */
        if ((old_controller = find_controller(&current_config, &c->proto))) {
            c->cxn_id = old_controller->cxn_id;
            /* TODO apply keepalive_period to existing connection. */
            continue;
        }

        rv = indigo_cxn_connection_add(&c->proto, &c->config, &c->cxn_id);
        if (rv != 0) {
            AIM_LOG_ERROR("failed to add controller connection %d: %s:%u",
                          i, proto->controller_ip, proto->controller_port);
        }
    }

    /* Remove connections that don't exist in the new configuration. */
    for (i = 0; i < current_config.num_controllers; i++) {
        const struct controller *c = &current_config.controllers[i];
        if (!find_controller(&staged_config, &c->proto)) {
            (void) indigo_cxn_connection_remove(c->cxn_id);
        }
    }

    /* Save config so we can diff the controllers next time */
    current_config = staged_config;
}
Esempio n. 4
0
static void
ind_core_cfg_commit(void)
{
    aim_log_t *lobj;

    if ((lobj = aim_log_find("ofstatemanager")) == NULL) {
        AIM_LOG_WARN("Could not find log module");
    } else {
        lobj->common_flags = staged_config.log_flags;
    }

    /* Set whether or not changed */
    (void)ind_core_hw_desc_set(staged_config.hw_desc);
    (void)ind_core_sw_desc_set(staged_config.sw_desc);
    (void)ind_core_dp_desc_set(staged_config.dp_desc);
    (void)ind_core_mfr_desc_set(staged_config.mfr_desc);
    (void)ind_core_serial_num_set(staged_config.serial_num);
    (void)indigo_core_dpid_set(staged_config.dpid);
    (void)indigo_core_disconnected_mode_set(staged_config.disconnected_mode);
}
void
ind_core_bsn_table_set_buckets_size_handler(of_object_t *_obj,
                                            indigo_cxn_id_t cxn_id)
{
    of_bsn_table_set_buckets_size_t *obj = _obj;
    uint16_t table_id;
    uint32_t buckets_size;
    indigo_error_t rv;

    of_bsn_table_set_buckets_size_table_id_get(obj, &table_id);
    of_bsn_table_set_buckets_size_buckets_size_get(obj, &buckets_size);

    rv = ft_set_checksum_buckets_size(ind_core_ft, table_id, buckets_size);
    if (rv < 0) {
        AIM_LOG_WARN("Failed to set table %d checksum buckets size to %d: %s",
                     table_id, buckets_size, indigo_strerror(rv));
        indigo_cxn_send_error_reply(cxn_id, obj,
                                    OF_ERROR_TYPE_BAD_REQUEST,
                                    OF_REQUEST_FAILED_EPERM);
    }
}
static void
ind_cxn_cfg_commit(void)
{
    aim_log_t *lobj;
    int i, enable;

    if (staged_config.valid != true)
        return;

    /* Commit config only if connection manager is enabled. */
    (void) ind_cxn_enable_get(&enable);
    if (!enable)
        return;

    if ((lobj = aim_log_find("ofconnectionmanager")) == NULL) {
        AIM_LOG_WARN("Could not find log module");
    } else {
        lobj->common_flags = staged_config.log_flags;
    }

    /* configure TLS before parsing controller configs */
    (void) indigo_cxn_config_tls(staged_config.cipher_list,
                                 staged_config.ca_cert,
                                 staged_config.switch_cert,
                                 staged_config.switch_priv_key,
                                 staged_config.exp_controller_suffix);

    for (i = 0; i < staged_config.num_controllers; i++) {
        struct controller *c = &staged_config.controllers[i];
        const struct controller *old_controller;
        int rv;
        char desc[256];

        ind_cxn_proto_ip_string(&c->proto, desc, sizeof(desc));
        AIM_LOG_INFO("controller %d: %s", i, desc);

        /* Keep existing connections to the same controller. */
        if ((old_controller = find_controller(&current_config, &c->proto))) {
            c->controller_id = old_controller->controller_id;
            /* TODO apply keepalive_period to existing connection. */
            continue;
        }

        rv = indigo_controller_add(&c->proto, &c->config, &c->controller_id);
        if (rv != 0) {
            AIM_LOG_ERROR("failed to add controller connection %d: %s",
                          i, desc);
        }
    }

    /* Remove controller's that don't exist in the new configuration. */
    for (i = 0; i < current_config.num_controllers; i++) {
        const struct controller *c = &current_config.controllers[i];
        if (!find_controller(&staged_config, &c->proto)) {
            (void) indigo_controller_remove(c->controller_id);
        }
    }

    /* Save config so we can diff the controllers next time */
    current_config = staged_config;
    staged_config.valid = false;
}
Esempio n. 7
0
File: cli.c Progetto: Juankc125/ivs
static void
client_callback(
    int socket_id,
    void *cookie,
    int read_ready,
    int write_ready,
    int error_seen)
{
    struct client *client = cookie;
    AIM_ASSERT(socket_id == client->fd);

    if (error_seen) {
        int socket_error = 0;
        socklen_t len = sizeof(socket_error);
        getsockopt(socket_id, SOL_SOCKET, SO_ERROR, &socket_error, &len);
        AIM_LOG_INFO("Error seen on CLI socket: %s", strerror(socket_error));
        destroy_client(client);
        return;
    }

    if (read_ready) {
        int c;
        if ((c = read(client->fd, client->read_buffer+client->read_buffer_offset,
                      READ_BUFFER_SIZE - client->read_buffer_offset)) < 0) {
            AIM_LOG_ERROR("read failed: %s", strerror(errno));
            return;
        }

        client->read_buffer_offset += c;

        if (c == 0) {
            /* Peer has shutdown their write side */
            if (client->write_buffer_len == 0 &&
                    aim_pvs_buffer_size(client->write_pvs) == 0) {
                destroy_client(client);
            } else {
                /* We'll destroy the client once we've finished writing to it */
                ind_soc_data_in_pause(client->fd);
                client->read_finished = true;
            }
            return;
        }

        /* Process each complete line */
        char *newline;
        char *start = client->read_buffer;
        int remaining = client->read_buffer_offset;
        while ((newline = memchr(start, '\n', remaining))) {
            *newline = '\0';
            ucli_dispatch_string(client->ucli, client->write_pvs, start);
            remaining -= newline - start + 1;
            start = newline + 1;
        }

        /* Move incomplete line (which may be empty) to the beginning of the read buffer */
        if (client->read_buffer != start) {
            memmove(client->read_buffer, start, remaining);
            client->read_buffer_offset = remaining;
        } else if (client->read_buffer_offset == READ_BUFFER_SIZE) {
            AIM_LOG_WARN("Disconnecting CLI client due to too-long line");
            destroy_client(client);
            return;
        }

        if (aim_pvs_buffer_size(client->write_pvs) > 0) {
            ind_soc_data_out_ready(socket_id);
        }
    }

    if (write_ready) {
        /* Copy PVS data into our write buffer and reset PVS */
        if (client->write_buffer == NULL) {
            client->write_buffer = aim_pvs_buffer_get(client->write_pvs);
            client->write_buffer_len = aim_pvs_buffer_size(client->write_pvs);
            client->write_buffer_offset = 0;
            /* aim_pvs_buffer_reset has a bug, workaround it */
            aim_pvs_destroy(client->write_pvs);
            client->write_pvs = aim_pvs_buffer_create();
        }

        int c = send(client->fd,
                     client->write_buffer+client->write_buffer_offset,
                     client->write_buffer_len-client->write_buffer_offset,
                     MSG_NOSIGNAL);
        if (c <= 0) {
            AIM_LOG_ERROR("write failed: %s", strerror(errno));
            destroy_client(client);
            return;
        }

        client->write_buffer_offset += c;

        /* Free our write buffer if we're finished with it */
        if (client->write_buffer_len == client->write_buffer_offset) {
            aim_free(client->write_buffer);
            client->write_buffer_len = client->write_buffer_offset = 0;
            client->write_buffer = NULL;
            if (aim_pvs_buffer_size(client->write_pvs) == 0) {
                ind_soc_data_out_clear(client->fd);
                if (client->read_finished) {
                    destroy_client(client);
                }
            }
        }
    }
}
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);
}
Esempio n. 9
0
int
onlp_sfpi_post_insert(int port, sff_info_t* info)
{
    /*
     * IF any platform-programming must be performed based
     * on the actual SFP that was inserted (for example, custom equalizer settings)
     * then it should be performed by this function.
     *
     * If not custom programming must be performed, then do nothing.
     * This function is optional.
     */
    int front_port=0;
    sfp_tranceiver_cable_type_t cable_type = SFP_TRANCEIVER_CABLE_TYPE_FIBER;

    switch(info->media_type)
        {
        case SFF_MEDIA_TYPE_FIBER:
            cable_type = SFP_TRANCEIVER_CABLE_TYPE_FIBER;
            break;

        case SFF_MEDIA_TYPE_COPPER:
            switch(info->length)
                {
                case 1:
                case 2:
                    AIM_LOG_MSG("Port %d EQ 1M", port);
                    cable_type = SFP_TRANCEIVER_CABLE_TYPE_COPPER_1M;
                    break;
                case 3:
                case 4:
                    AIM_LOG_MSG("Port %d EQ 3M", port);
                    cable_type = SFP_TRANCEIVER_CABLE_TYPE_COPPER_3M; break;
                case 5:
                case 6:
                    AIM_LOG_MSG("Port %d EQ 5M", port);
                    cable_type = SFP_TRANCEIVER_CABLE_TYPE_COPPER_5M; break;
                case 7:
                    AIM_LOG_MSG("Port %d EQ 7M", port);
                    cable_type = SFP_TRANCEIVER_CABLE_TYPE_COPPER_7M; break;
                default:
                    AIM_LOG_MSG("Port %d EQ 7M (MAX)", port);
                    /* Nothing beyond 7M is supported. Best we can do is use the 7M settings. */
                    cable_type = SFP_TRANCEIVER_CABLE_TYPE_COPPER_7M; break;
    }
            break;

        default:
            AIM_LOG_WARN("port(%d) media_type(%d) length(%d) is not supported\r\n",
                         port, info->media_type, info->length);
            return ONLP_STATUS_E_INTERNAL;
        }


    front_port=SFP_MAP_API_2_FRONT_PORT(port);
    if (set_active_port(front_port) < 0) {
        AIM_LOG_ERROR("Unable to set active port(%d)\r\n", port);
        return ONLP_STATUS_E_INTERNAL;
    }

    if (set_equalizer_type(cable_type) < 0) {
        AIM_LOG_ERROR("Unable to set port(%d) media_type(%d) length(%d)\r\n",
                    port, info->media_type, info->length);
        return ONLP_STATUS_E_INTERNAL;
    }

    return ONLP_STATUS_OK;
}
Esempio n. 10
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;
}