Beispiel #1
0
static int add_port(char *iface, uint16_t port_num) {
    fprintf(stderr, "switch is adding port %s as %u\n", iface, port_num);
    if (dump_pcap != 0) {
        char pcap_filename[1024];
        snprintf(pcap_filename, 1024,
                 "/p4ns.%s-port%.2d.pcap", datapath_name, port_num);
        return bmi_port_interface_add(port_mgr, iface, port_num, pcap_filename);
    }
    else {
        return bmi_port_interface_add(port_mgr, iface, port_num, NULL);
    }
}
DevMgr::ReturnCode
DevMgr::port_add(const std::string &iface_name, port_t port_num,
		 const char *pcap)
{
  // TODO: check if port is taken...
  assert(!bmi_port_interface_add(port_mgr, iface_name.c_str(), port_num, pcap));
  return ReturnCode::SUCCESS;
}
  ReturnCode port_add_(const std::string &iface_name, port_t port_num,
                       const char *in_pcap, const char *out_pcap) override {
    if (bmi_port_interface_add(port_mgr, iface_name.c_str(), port_num, in_pcap,
                               out_pcap))
      return ReturnCode::ERROR;

    PortInfo p_info(port_num, iface_name);
    if (in_pcap) p_info.add_extra("in_pcap", std::string(in_pcap));
    if (out_pcap) p_info.add_extra("out_pcap", std::string(out_pcap));

    Lock lock(mutex);
    port_info.emplace(port_num, std::move(p_info));

    return ReturnCode::SUCCESS;
  }
Beispiel #4
0
static int load_config(char *fname, unsigned int *num_ports, int *log_level)
{
    char s[256];
    int port;
    char veth[32];
    char pcap[36];
    char tmp[32];
    char *pcap_file = NULL;
    FILE *fp = fopen(fname, "r");
    if(fp) {
        while(fgets(s, 256, fp)) {
            int r=0;
            pcap[0] = 0;
            pcap_file = NULL;
            if(s[0] == '#')
                continue;
            if(!strncmp(s, "num_ports", 9)) {
                sscanf(s, "%s = %d", tmp, num_ports);
            }
            else if(!strncmp(s, "log_level", 9)) {
                sscanf(s, "%s = %d", tmp, log_level);
            }
            else {
                if((r= sscanf(s, "%d:%s %s", &port, veth, pcap)) >= 2) {
                    pcap_file = pcap;
                }
                if(bmi_port_interface_add(port_mgr, veth, port, pcap_file) != 0) {
                    fclose(fp);
                    return -1;
                }
            }
        }
        fclose(fp);
        return 0;
    }
    return -1;
}
Beispiel #5
0
int
main(int argc, char* argv[])
{
    int rv = 0;
    char veth_name[16];
    int n_veth;

    CHECK(bmi_port_create_mgr(&port_mgr));

    srand (time(NULL));

    parse_options(argc, argv);

    /*************************************************************
     * Check for root access as uses veth interfaces
     * @fixme allow specifying vpi names as runtime config
     ************************************************************/
    if (geteuid() != 0) {
        fprintf(stderr, "This uses (v)eth interfaces; run under sudo\n");
        return 1;
    }

    if (!dpid) {
        int r1 = rand();
        int r2 = rand();
        dpid = (((uint64_t) r1) << 32) | ((uint64_t) r2);
    }

    if (!pd_server_str) {
        fprintf(stderr, "No PD RPC server address specified, "
                "using 127.0.0.1:%u\n", PD_SERVER_DEFAULT_PORT);
        parse_connection("127.0.0.1", &pd_server_addr, PD_SERVER_DEFAULT_PORT);
    } else {
        if (parse_connection(pd_server_str, &pd_server_addr,
                             PD_SERVER_DEFAULT_PORT) != 0)
            return -1;
        fprintf(stderr, "PD server address is %s:%u\n",
                pd_server_addr.ip, pd_server_addr.port);
    }

    if (!listener_str) {
        fprintf(stderr, "No listener specified, switch will run in "
                "standalone mode\n");
        if (p4nsdb_str) {
            fprintf(stderr, "P4NSDB will be ignored\n");
            free(p4nsdb_str);
            p4nsdb_str = NULL;
        }
    }

    /*************************************************************
     * Initialize Modules.
     ************************************************************/

    rmt_init();
    rmt_logger_set((p4_logging_f) printf);
    rmt_log_level_set(P4_LOG_LEVEL_TRACE);
    rmt_transmit_register(transmit_wrapper);

    /* Start up the PD RPC server */
    CHECK(start_p4_pd_rpc_server(pd_server_addr.port));

    /* Start up the API RPC server */
#ifdef SWITCHAPI_ENABLE
    CHECK(switch_api_init(0));
    CHECK(start_switch_api_rpc_server());
    CHECK(start_switch_api_packet_driver());
#endif /* SWITCHAPI_DISABLE */

#ifdef SWITCHSAI_ENABLE
    CHECK(start_p4_sai_thrift_rpc_server(SWITCH_SAI_THRIFT_RPC_SERVER_PORT));
#endif /*SWITCHSAI_ENABLE */

#ifdef SWITCHLINK_ENABLE
    CHECK(switchlink_init());
#endif /* SWITCHLINK_ENABLE */

    if (!listener_str && !no_veth) {  /* standalone mode */
        for (n_veth = 0; n_veth < NUM_VETH_INTERFACES; n_veth++) {
            sprintf(veth_name, "veth%d", n_veth*2);
            char pcap_filename[1024];
            pcap_filename[0] = 0;
            if (dump_pcap) {
                snprintf(pcap_filename, 1024,
                         "p4ns.%s-port%.2d.pcap", datapath_name, n_veth);
            }
            CHECK(bmi_port_interface_add(port_mgr, veth_name, n_veth,
                                         pcap_filename));
        }
    }

#ifdef SWITCHAPI_ENABLE
    if (!listener_str) {
        // add CPU port, port 64
        char pcap_filename[1024];
        pcap_filename[0] = 0;
        if (dump_pcap) {
            snprintf(pcap_filename, 1024,
                     "p4ns.%s-port%.2d.pcap", datapath_name, 64);
        }
        CHECK(bmi_port_interface_add(port_mgr, "veth250", 64, pcap_filename));
    }
#endif /* SWITCHAPI_ENABLE */

    if (listener_str) {
        parse_connection(listener_str, &listener_addr, 0);
        if(listener_addr.port == 0) {
            fprintf(stderr, "No port was specified for the listener");
            return -1;
        }

        if (!p4nsdb_str) {
            fprintf(stderr, "No p4nsdb address specified, using 127.0.0.1:%u\n",
                    P4NSDB_DEFAULT_PORT);
            parse_connection("127.0.0.1", &p4nsdb_addr, P4NSDB_DEFAULT_PORT);
        }
        else {
            if (parse_connection(p4nsdb_str, &p4nsdb_addr,
                                 P4NSDB_DEFAULT_PORT) != 0)
                return -1;
            fprintf(stderr, "p4nsdb address is %s:%u\n",
                    p4nsdb_addr.ip, p4nsdb_addr.port);
        }

        struct sigaction sa;
        sa.sa_handler = clean_up_on_signal;
        sigaction(SIGINT, &sa, &old_action_SIGINT);
        sigaction(SIGTERM, &sa, &old_action_SIGTERM);

        p4ns_db_cxt_t c = connect_to_p4nsdb();
        if (!c) return -1;
        if (p4ns_db_add_datapath(c, datapath_name, dpid)) {
            fprintf(stderr, "P4NSDB: could not create datapath, %s already "
                    "exists\n", datapath_name);
            return -1;
        }
        atexit(clean_up);
        p4ns_db_set_listener(c, datapath_name, &listener_addr);

        /* TODO: improve this code */
        uint16_t port_no = 0;
        /* Add interfaces from command line */
        struct entry *np;
        for (np = interfaces.tqh_first; np != NULL; np = np->entries.tqe_next) {
            printf("Adding interface %s (port %d)\n", np->str, port_no);
            if(add_port(np->str, port_no) < 0) {
                printf("Failed to add interface %s\n", np->str);
                return -1;
            }
            p4ns_db_add_port(c, datapath_name, np->str, port_no);
            port_no++;
        }

        p4ns_db_free(c);

        pthread_create(&ctl_listener_thread, NULL,
                       ctl_listen, (void *) &listener_addr);
    } else if (no_veth) {
        uint16_t port_no = 0;
        struct entry *np;
        for (np = interfaces.tqh_first; np != NULL; np = np->entries.tqe_next) {
            printf("Adding interface %s (port %d)\n", np->str, port_no);
            if(add_port(np->str, port_no) < 0) {
                printf("Failed to add interface %s\n", np->str);
                return -1;
            }
            port_no++;
        }
    }

    CHECK(bmi_set_packet_handler(port_mgr, packet_handler));

    while (1) pause();

    bmi_port_destroy_mgr(port_mgr);

    return rv;
}