Exemple #1
0
/* ENTRY POINT: handle receive packet from Controller
 * msg will be freed by caller. Do copy as necessary.
 */
void
lldpa_agent_handle_msg(lldpa_port_t* lldpa, void* msg)
{
    int status = -1;
    of_bsn_header_t *hdr = (of_bsn_header_t *)msg;
    lldpa_pkt_type ptype = INVALID_PACKET;
    lldpa_contr_stype stype = SW_CONTR_INVALID;
    lldpa_pkt_t *lpkt = NULL;

    if (hdr->subtype == SW_CONTR_TX_REQ) {
        ptype = TX_PACKET;
        stype = SW_CONTR_TX_RES;
    } else if (hdr->subtype == SW_CONTR_RX_REQ) {
        /* Got new matched request - Reset matched */
        lldpa->rx_pkt_matched = 0;
        ptype = RX_PACKET;
        stype = SW_CONTR_RX_RES;
    } else {
        AIM_LOG_FATAL("Unsupported msg type %u", ptype);
    }

    /* Processing packet
     * if interval > 0, clear old alarm, free current pkt, set new pkt & new alarm
     *    interval == 0, clear old alarm, free current pkt
     * Ret = -1: Error can't handle request
     */
    if (ptype != INVALID_PACKET ) {
        status = 0;
        lldpa_port_alarm_register(lldpa, ptype, ALARM_UNREGISTER);
        lpkt = lldpa_port_get_lpkt(lldpa, ptype);
        lldpa_pkt_buf_free(lpkt);

        if (hdr->interval_ms) {
            /*  &hdr->payload might be null */
            if ((status = lldpa_port_set_pkt(lldpa, ptype, &hdr->payload,
                                             hdr->length-sizeof(of_bsn_header_t))) == -1) {
                AIM_LOG_FATAL("Failed to set pkt type %u", ptype);
            } else {
                status = lldpa_port_alarm_register(lldpa, ptype, hdr->interval_ms);
            }
        }
    }

    /* Always generatate a new header base on old hdr to reply */
    hdr = lldpa_gen_msg_reply(stype, status, hdr, hdr->length);
    if (lldpa->tx_ctrl_fn)
        (*lldpa->tx_ctrl_fn)(hdr, hdr->length, os_ctrl_cxn_id);
    free(hdr);
}
Exemple #2
0
/*
 * Always unregister old one
 * Only register new one if interval > 0
 * Return -1 if new one can't be registered
 */
static int
lldpa_port_alarm_register(lldpa_port_t* lldpa, lldpa_pkt_type ptype, uint32_t interval_ms)
{
    //Always SA_REPEAT Until Unregistered
    unsigned int flags = 0x1;
    int ret = 0;
    lldpa_pkt_t *pkt;

    if(!os_alarm_register_fn || !os_alarm_unregister_fn){
        AIM_LOG_FATAL("NO_EVEN_REGISTER\n");
        return -1;
    }
    pkt = lldpa_port_get_lpkt(lldpa, ptype);

    /* Always unregister old one */
    if(pkt->alarm_id) {
        os_alarm_unregister_fn(pkt->alarm_id);
        pkt->alarm_id = 0;
        pkt->interval_ms = 0;
    }

    pkt->interval_ms = interval_ms;

    if (interval_ms > 0) {
        pkt->alarm_id = os_alarm_register_fn(interval_ms, flags, pkt->alarm_cb, lldpa);
        if (!pkt->alarm_id) {
             pkt->interval_ms = 0;
            ret = -1;
        }
    }
    return ret;
}
Exemple #3
0
/* Get rx_pkt or tx_pkt */
static lldpa_pkt_t*
lldpa_port_get_lpkt(lldpa_port_t* lldpa, lldpa_pkt_type ptype)
{
    lldpa_pkt_t* ret = NULL;
    if (ptype == RX_PACKET) {
        ret = &lldpa->rx_pkt;
    } else if (ptype == TX_PACKET)  {
        ret = &lldpa->tx_pkt;
    } else {
        AIM_LOG_FATAL("get_lpkt: Unsupported pkt type %s", ptype);
    }
    return ret;
}
/*
 * icmpa_init
 *
 * API to init the ICMP Agent
 * This should only be done once at the beginning.
 */
indigo_error_t
icmpa_init (void)
{
    if (icmpa_is_initialized()) return INDIGO_ERROR_NONE;

    AIM_LOG_INFO("init");

    /*
     * Register system debug counters
     */
    debug_counter_register(&pkt_counters.icmp_total_in_packets,
                           "icmpa.icmp_total_in_packets",
                           "Packet-ins recv'd by icmpa");
    debug_counter_register(&pkt_counters.icmp_total_out_packets,
                           "icmpa.icmp_total_out_packets",
                           "Icmp packets sent by lacpa");
    debug_counter_register(&pkt_counters.icmp_total_passed_packets,
                           "icmpa.icmp_total_passed_packets",
                            "Packet-ins passed by icmpa");
    debug_counter_register(&pkt_counters.icmp_internal_errors,
                           "icmpa.icmp_internal_errors",
                           "Internal errors in icmpa");

    ICMPA_MEMSET(&port_pkt_counters[0], 0,
                 sizeof(icmpa_typecode_packet_counter_t) * (MAX_PORTS+1));
    aim_ratelimiter_init(&icmp_pktin_log_limiter, 1000*1000, 5, NULL);

    /*
     * Register listerner for packet_in
     */
    if (indigo_core_packet_in_listener_register(
        (indigo_core_packet_in_listener_f) icmpa_packet_in_handler) < 0) {
        AIM_LOG_FATAL("Failed to register for packet_in in ICMPA module");
        return INDIGO_ERROR_INIT;
    }

    icmp_initialized = true;
    return INDIGO_ERROR_NONE;
}
Exemple #5
0
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++;
        }
    }
Exemple #6
0
int
aim_main(int argc, char* argv[])
{
    AIM_LOG_STRUCT_REGISTER();

    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)", program_version, AIM_STRINGIFY(BUILD_ID));

    /* 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) < 0) {
        AIM_LOG_FATAL("Failed to initialize OVSDriver module");
        return 1;
    }

    if (enable_tunnel) {
        if (ind_ovs_tunnel_init() < 0) {
            AIM_LOG_FATAL("Failed to initialize tunneling");
            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++;
        }
    }
Exemple #7
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;
}