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;
}
Exemple #2
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;
}