static int tcp_open(const char *name, char *suffix, struct vconn **vconnp) { char *save_ptr; const char *host_name; const char *port_string; struct sockaddr_in sin; int retval; int fd; /* Glibc 2.7 has a bug in strtok_r when compiling with optimization that * can cause segfaults here: * http://sources.redhat.com/bugzilla/show_bug.cgi?id=5614. * Using "::" instead of the obvious ":" works around it. */ host_name = strtok_r(suffix, "::", &save_ptr); port_string = strtok_r(NULL, "::", &save_ptr); if (!host_name) { ofp_error(0, "%s: bad peer name format", name); return EAFNOSUPPORT; } memset(&sin, 0, sizeof sin); sin.sin_family = AF_INET; if (lookup_ip(host_name, &sin.sin_addr)) { return ENOENT; } sin.sin_port = htons(port_string ? atoi(port_string) : OFP_TCP_PORT); fd = socket(AF_INET, SOCK_STREAM, 0); if (fd < 0) { VLOG_ERR("%s: socket: %s", name, strerror(errno)); return errno; } retval = set_nonblocking(fd); if (retval) { close(fd); return retval; } retval = connect(fd, (struct sockaddr *) &sin, sizeof sin); if (retval < 0) { if (errno == EINPROGRESS) { return new_tcp_vconn(name, fd, EAGAIN, &sin, vconnp); } else { int error = errno; VLOG_ERR("%s: connect: %s", name, strerror(error)); close(fd); return error; } } else { return new_tcp_vconn(name, fd, 0, &sin, vconnp); } }
int udatapath_cmd(int argc, char *argv[]) { int n_listeners; int error; int i; set_program_name(argv[0]); register_fault_handlers(); time_init(); vlog_init(); dp = dp_new(); parse_options(dp, argc, argv); signal(SIGPIPE, SIG_IGN); if (argc - optind < 1) { OFP_FATAL(0, "at least one listener argument is required; " "use --help for usage"); } if (use_multiple_connections && (argc - optind) % 2 != 0) OFP_FATAL(0, "when using multiple connections, you must specify an even number of listeners"); n_listeners = 0; for (i = optind; i < argc; i += 2) { const char *pvconn_name = argv[i]; const char *pvconn_name_aux = NULL; if (use_multiple_connections) pvconn_name_aux = argv[i + 1]; struct pvconn *pvconn, *pvconn_aux = NULL; int retval, retval_aux; retval = pvconn_open(pvconn_name, &pvconn); if (!retval || retval == EAGAIN) { // Get another listener if we are using auxiliary connections if (use_multiple_connections) { retval_aux = pvconn_open(pvconn_name_aux, &pvconn_aux); if (retval_aux && retval_aux != EAGAIN) { ofp_error(retval_aux, "opening auxiliary %s", pvconn_name_aux); pvconn_aux = NULL; } } dp_add_pvconn(dp, pvconn, pvconn_aux); n_listeners++; } else { ofp_error(retval, "opening %s", pvconn_name); } } if (n_listeners == 0) { OFP_FATAL(0, "could not listen for any connections"); } if (port_list != NULL) { add_ports(dp, port_list); } if (local_port != NULL) { error = dp_ports_add_local(dp, local_port); if (error) { OFP_FATAL(error, "failed to add local port %s", local_port); } } error = vlog_server_listen(NULL, NULL); if (error) { OFP_FATAL(error, "could not listen for vlog connections"); } die_if_already_running(); daemonize(); for (;;) { dp_run(dp); dp_wait(dp); poll_block(); } return 0; }
int udatapath_cmd(int argc, char *argv[]) { int n_listeners; int error; int i; set_program_name(argv[0]); register_fault_handlers(); time_init(); vlog_init(); parse_options(argc, argv); signal(SIGPIPE, SIG_IGN); if (argc - optind < 1) { OFP_FATAL(0, "at least one listener argument is required; " "use --help for usage"); } error = dp_new(&dp, dpid); n_listeners = 0; for (i = optind; i < argc; i++) { const char *pvconn_name = argv[i]; struct pvconn *pvconn; int retval; retval = pvconn_open(pvconn_name, &pvconn); if (!retval || retval == EAGAIN) { dp_add_pvconn(dp, pvconn); n_listeners++; } else { ofp_error(retval, "opening %s", pvconn_name); } } if (!n_listeners) { OFP_FATAL(0, "could not listen for any connections"); } if (port_list) { add_ports(dp, port_list); } if (local_port) { error = dp_add_local_port(dp, local_port, 0); if (error) { OFP_FATAL(error, "failed to add local port %s", local_port); } } error = vlog_server_listen(NULL, NULL); if (error) { OFP_FATAL(error, "could not listen for vlog connections"); } die_if_already_running(); daemonize(); for (;;) { dp_run(dp); dp_wait(dp); poll_block(); } return 0; }
int udatapath_cmd(int argc, char *argv[]) { int n_listeners; int error; int i; set_program_name(argv[0]); register_fault_handlers(); time_init(); vlog_init(); parse_options(argc, argv); signal(SIGPIPE, SIG_IGN); if (argc - optind < 1) { OFP_FATAL(0, "at least one listener argument is required; " "use --help for usage"); } error = dp_new(&dp, dpid); if (error) { OFP_FATAL(error, "Failed to create datapath. Exiting."); } #if defined(OF_HW_PLAT) if (got_mac) { memcpy(dp->dp_mgmt.mac, dp_mac, ETH_ADDR_LEN); } else { /* Use OF OUI and 3 bytes of DPID */ dp->dp_mgmt.mac[0] = 0; dp->dp_mgmt.mac[1] = 0x26; dp->dp_mgmt.mac[2] = 0xe1; dp->dp_mgmt.mac[3] = dp->id & 0xff; dp->dp_mgmt.mac[4] = (dp->id >> 8) & 0xff; dp->dp_mgmt.mac[5] = (dp->id >> 16) & 0xff; } dp_port_add_state_set(dp, port_add_state); dp->dp_mgmt.enabled = dp_mgmt; dp->dp_mgmt.port_fixed = dp_mgmt_port_fixed; dp->dp_mgmt.port = dp_mgmt_port; dp->dp_mgmt.vid_fixed = dp_mgmt_vid_fixed; dp->dp_mgmt.vid = dp_mgmt_vid; if (dp_mgmt_oob) { if (!dp->dp_mgmt.vid_fixed && !dp->dp_mgmt.port_fixed) { printf("WARNING: dp_mgmt misconfig: OOB requires fixed port\n"); printf("WARNING: Removing OOB management\n"); fprintf(stderr, "WARNING: dp_mgmt misconfig: OOB requires " "fixed port\n"); fprintf(stderr, "WARNING: Removing OOB management\n"); dp_mgmt_oob = false; } } dp->dp_mgmt.oob = dp_mgmt_oob; dp_mgmt_set(dp); /* Get hw_desc/dp_desc from hw-lib if not set by command args */ if (!hw_desc_set && dp->hw_drv != NULL && dp->hw_drv->hw_desc != NULL) { strncpy(hw_desc, dp->hw_drv->hw_desc, sizeof(hw_desc) - 1); } if (!dp_desc_set && dp->hw_drv != NULL && dp->hw_drv->dp_desc != NULL) { strncpy(dp->dp_desc, dp->hw_drv->dp_desc, sizeof(dp->dp_desc) - 1); } #endif n_listeners = 0; for (i = optind; i < argc; i++) { const char *pvconn_name = argv[i]; struct pvconn *pvconn; int retval; retval = pvconn_open(pvconn_name, &pvconn); if (!retval || retval == EAGAIN) { dp_add_pvconn(dp, pvconn); n_listeners++; } else { ofp_error(retval, "opening %s", pvconn_name); } } if (!n_listeners) { OFP_FATAL(0, "could not listen for any connections"); } if (port_list) { add_ports(dp, port_list); } if (max_port_set) { printf("Adding port range %d to %d\n", min_port, max_port); add_ports_range(dp, min_port, max_port); } if (local_port) { printf("Adding local port\n"); error = dp_add_local_port(dp, local_port, 0); if (error) { OFP_FATAL(error, "failed to add local port %s", local_port); } } error = vlog_server_listen(NULL, NULL); if (error) { OFP_FATAL(error, "could not listen for vlog connections"); } die_if_already_running(); daemonize(); WATCHDOG_START; dp->rx_enabled = 1; system("touch /tmp/ofswd-ready"); printf("Entering event loop"); for (;;) { WATCHDOG_STROKE; dp_run(dp); dp_wait(dp); poll_block(); } WATCHDOG_STOP; return 0; }