/* Initiate for tcpcopy server */ void interception_init(uint16_t port) { delay_table_init(srv_settings.hash_size); router_init(srv_settings.hash_size << 1); select_server_set_callback(interception_process); msg_listen_sock = msg_server_init(srv_settings.binded_ip, port); log_info(LOG_NOTICE, "msg listen socket:%d", msg_listen_sock); select_server_add(msg_listen_sock); firewall_sock = nl_firewall_init(); log_info(LOG_NOTICE, "firewall socket:%d", firewall_sock); select_server_add(firewall_sock); }
// ------------------------------------------------------------------------ // main // ------------------------------------------------------------------------ void c_main() { io_printf (IO_STD, "starting dumped packet bouncer\n"); timer_init (TICK_PERIOD); // setup timer to maybe turn on bouncing cc_init (); // setup comms. cont. interrupt when not full router_init (); // setup router to interrupt when dumping #ifdef DEBUG timer2_init (); // setup timer2 for profiling #endif cpu_sleep (); // Send core to sleep }
/* initiate for tcpcopy server */ int interception_init(tc_event_loop_t *event_loop, char *ip, uint16_t port) { int fd; tc_event_t *ev; delay_table_init(srv_settings.hash_size); if (router_init() != TC_OK) { return TC_ERROR; } /* init the listening socket */ if ((fd = tc_socket_init()) == TC_INVALID_SOCKET) { return TC_ERROR; } else { if (tc_socket_listen(fd, ip, port) == TC_ERROR) { return TC_ERROR; } tc_log_info(LOG_NOTICE, 0, "msg listen socket:%d", fd); ev = tc_event_create(fd, tc_msg_event_accept, NULL); if (ev == NULL) { return TC_ERROR; } if (tc_event_add(event_loop, ev, TC_EVENT_READ) == TC_EVENT_ERROR) { return TC_ERROR; } } if (sniff_init(event_loop) != TC_OK) { return TC_ERROR; } return TC_OK; }
/* initiate for tcpcopy server */ int interception_init(tc_event_loop_t *event_loop, char *ip, uint16_t port) { int fd; #if (INTERCEPT_THREAD) pthread_t thread; #endif tc_event_t *ev; router_init(srv_settings.hash_size); pid = getpid(); /* init the listening socket */ if ((fd = tc_socket_init()) == TC_INVALID_SOCKET) { return TC_ERROR; } else { if (tc_socket_listen(fd, ip, port) == TC_ERROR) { return TC_ERROR; } tc_log_info(LOG_NOTICE, 0, "msg listen socket:%d", fd); ev = tc_event_create(fd, tc_msg_event_accept, NULL); if (ev == NULL) { return TC_ERROR; } if (tc_event_add(event_loop, ev, TC_EVENT_READ) == TC_EVENT_ERROR) { return TC_ERROR; } } /* init the netlink socket */ if ((fd = tc_nl_socket_init()) == TC_INVALID_SOCKET) { return TC_ERROR; } else { tc_log_info(LOG_NOTICE, 0, "firewall socket:%d", fd); ev = tc_event_create(fd, tc_nl_event_process, NULL); if (ev == NULL) { return TC_ERROR; } if (tc_event_add(event_loop, ev, TC_EVENT_READ) == TC_EVENT_ERROR) { return TC_ERROR; } } #if (INTERCEPT_THREAD) pthread_mutex_init(&mutex, NULL); pthread_cond_init(&full, NULL); pthread_cond_init(&empty, NULL); pthread_create(&thread, NULL, interception_process_msg, NULL); pthread_mutex_init(&nl_mutex, NULL); pthread_cond_init(&nl_full, NULL); pthread_cond_init(&nl_empty, NULL); pthread_create(&thread, NULL, interception_dispose_nl_verdict, NULL); #endif return TC_OK; }
int main(int argc, char *argv[]) { /* check command line args. */ if(argc < 4){ printf("usage : %s <RouterID> <LogFileName> <Initialization file> \n", argv[0]); exit(1); } char *router_id; char *log_filename; char *init_file; FILE *log_file; int nbytes; // Extract arguments router_id = argv[1]; log_filename = argv[2]; init_file = argv[3]; Router router; router = router_init(*router_id,init_file); //printf("Router init:\n"); //print_router(router); // Open log file log_file = fopen(log_filename, "wb"); if (!log_file) { printf("Failed open log file %s for router %s.\n", argv[2], argv[1]); exit(1); } router = initSock(router); //printf("Router after initSock:\n"); //print_router(router); // Initialize LSP of this router LSP_init(&router); print_LSP(&router.self_packet,log_filename); LSP lsp = router.self_packet; // Each router has an array of recently received packets // Receive buffer //LSP buffer_packet; LSP templsp; //LSP checklsp; char* buffer = malloc(sizeof(LSP)); //bzero(buffer,sizeof(buffer)); //memcpy(buffer,(char*) &lsp, sizeof(LSP)); //memcpy((char*) &checklsp, buffer, sizeof(LSP)); //print_LSP(&checklsp, log_file); //printf("router id: %c\nsequence number: %d\n sizeof: %d\n",checklsp.router.ID,checklsp.seq_num, (int) sizeof(lsp)); // initialize router routing table routing_table_init(&router); print_routing_table(&router, log_filename); fclose(log_file); // ?? int i, j; fd_set readSet; fd_set tempReadSet; FD_ZERO(&readSet); FD_ZERO(&tempReadSet); //first try to connect to neighbors for(i = 0; i< router.nbrs_count; i++) { if(TCPconnect(router.nbrs[i]) < 0) router.nbrs[i].connectedR = 0; else router.nbrs[i].connectedR = 1; } //then listen for(i = 0; i< router.nbrs_count; i++) { TCPlisten(router.nbrs[i]); FD_SET(router.nbrs[i].localSock,&readSet); } int highSock; highSock = router.nbrs[0].localSock; for(i = 0; i < router.nbrs_count-1; i++ ) { highSock = router.nbrs[i].localSock > router.nbrs[i+1].localSock? router.nbrs[i].localSock: router.nbrs[i+1].localSock; } int counter = 0; struct timeval tv; tv.tv_sec = 5; tv.tv_usec = 0; // Select: while router is listening, it waits for one or more neighbors // to connect. for(;;) { tv.tv_sec = 5; tv.tv_usec = 0; tempReadSet = readSet; printf("- %d\n", counter); if(select(highSock+1, &tempReadSet, 0, 0, &tv) < 0) { printf("select error!\n"); } //CHECK FD for(i = 0; i< router.nbrs_count; i++) { // for select: Check if there's a connection or not if(FD_ISSET(router.nbrs[i].localSock, &tempReadSet)) { // Accept connections if( router.nbrs[i].connectedS == 0) { int newSock; if ((newSock = TCPaccept(router.nbrs[i])) > -1) { router.nbrs[i].connectedS= 1; router.nbrs[i].localSock = newSock; printf("sock: %d\n",router.nbrs[i].localSock); printf("connectedS: %d\n",router.nbrs[i].connectedS); FD_SET(router.nbrs[i].localSock,&readSet); if(highSock < newSock) highSock = newSock; } } // Receive LSPs else { bzero(buffer,sizeof(LSP)); socklen_t size = sizeof(&router.nbrs[i].localAddr); if(recvfrom(router.nbrs[i].localSock, buffer, sizeof(LSP), 0, (struct sockaddr *) &router.nbrs[i].localAddr, &size) <0) { printf("error receiving from node %s\n", router.nbrs[i].ID); } else { printf("LSP received from %s \n",router.nbrs[i].ID); memcpy((char *)&templsp, buffer, sizeof(LSP)); //print_LSP(&templsp,log_file); // Check if received lsp is new int check_lsp_flag = check_LSP(&router, &templsp); if (check_lsp_flag == 1 || check_lsp_flag == 2) { // Log if LSP caused change in routing table. if(check_lsp_flag == 2) { print_LSP(&templsp, log_filename); print_routing_table(&router,log_filename); } // 2. Flood to all links, except where it came from for(j = 0; j<router.nbrs_count; j++) { if((j != i) && router.nbrs[i].connectedR == 1) { //buffer = malloc(sizeof(LSP)); //bzero(buffer, sizeof(LSP)); //memcpy(buffer, (char*) &lsp, sizeof(LSP)); //memcpy((char *)&templsp, buffer, sizeof(LSP)); nbytes = sendto(router.nbrs[j].remoteSock, buffer, LSPSIZE, MSG_NOSIGNAL, (struct sockaddr*)&router.nbrs[j].remoteAddr, sizeof(router.nbrs[j].remoteAddr)); if (nbytes == -1) { printf("Failed to send on link: %s, %d, %s, %d\n", router.nbrs[i].src_ID, router.nbrs[i].send_port, router.nbrs[i].ID, router.nbrs[i].recv_port); } else { printf("Forward LSP from %s to %s\n", templsp.routerID, router.nbrs[j].ID); //print_LSP(&templsp, log_file); } } } } } } } } sleep(5); // Try to connect again. for(i = 0; i< router.nbrs_count; i++) { if(router.nbrs[i].connectedS == 1 &&router.nbrs[i].connectedR == 0) { if(TCPconnect(router.nbrs[i]) < 0) { printf("failed to connect to %s \n", router.nbrs[i].ID); router.nbrs[i].connectedR = 0; } else router.nbrs[i].connectedR = 1; } } // initial and periodic flooding: Send LSP to connected links. lsp.seq_num++; for(i = 0; i<router.nbrs_count; i++) { if(router.nbrs[i].connectedR == 1) { buffer = malloc(sizeof(LSP)); bzero(buffer, sizeof(LSP)); memcpy(buffer, (char*) &lsp, sizeof(LSP)); memcpy((char *)&templsp, buffer, sizeof(LSP)); nbytes = sendto(router.nbrs[i].remoteSock, buffer, sizeof(LSP), 0, (struct sockaddr*)&router.nbrs[i].remoteAddr, sizeof(router.nbrs[i].remoteAddr)); if (nbytes == -1) { printf("Failed to send on link: %s, %d, %s, %d\n", router.nbrs[i].src_ID, router.nbrs[i].send_port, router.nbrs[i].ID, router.nbrs[i].recv_port); } else { printf("Send LSP to: %s\n", router.nbrs[i].ID); //print_LSP(&templsp, log_file); } } } counter ++; } fclose(log_file); return 0; // Set router timer //time_t curr_time; //time(&router.timestamp); // some connection shit /* // check time, send self lsp on all ports with established link time(&curr_time); if (difftime(curr_time, router.timestamp) >= (double)5.0) { router.timestamp = curr_time; // update lsp seq router.self_packet.seq++; for (i=0 ; i<router.nbrs_count ; i++) { if (router.nbrs[i].connected) { nbytes = send(socket?, router.self_pakcet, sizeof(LSP), 0); if (nbytes == -1) { printf("Failed to send on link: %s, %d, %s, %d\n", router.nbrs[i].src_ID, router.nbrs[i].send_port, router.nbrs[i].ID, router.nbrs[i].recv_port); } else { printf("Send LSP to: %s\n", router.nbrs[i].ID); } } } } int lsp_update_flag; // Receive LSP from all ports with "connected" neighbors for (i=0 ; i<router.nbrs_count ; i++) { if (router.nbrs[i].connected) { nbytes = recv(router.nbrs[i].connect_fd, &buffer_packet, sizeof(LSP), 0); if (nbytes > 0) { printf("LSP received from ID %s, seq %d\n", buffer_packet.router.ID, buffer_lsp.seq_num); // store recvd lsp into database and determine if need forwarding // also determine if need update topology and recompute lsp_update_flag = update_LSP_list(&router, &buffer_lsp); if (lsp_update_flag == 1) { // 1. Run Dijkstra! printf("Update routing table...\n"); if (update_routing_table(&(router), &buffer_packet)) { time(&curr_time); sprintf(tmp_char_buffer, "UTC:\t%s", asctime(gmtime(&curr_time))); printf("%s",tmp_char_buffer); fwrite(tmp_char_buffer, sizeof(char), strlen(tmp_char_buffer), log_file); print_lsp(&buffer_packet, log_file); log_routing_table(&router, log_file); } // 2. Flood LSP to all outgoing links, except where it came from buffer_pacekt.ttl--; int j; for (j=0; j<router.nbrs_count; j++) { if ((j != i) && (router.nbrs[j].connected)) { nbytes = send(router.nbrs[j].connect_fd, &buffer_packet, sizeof(LSP), 0); if (nbytes == -1) { printf("Failed to send on link: %s, %d, %s, %d\n", router.nbrs[i].src_ID, router.nbrs[i].send_port, router.nbrs[i].ID, router.nbrs[i].recv_port); } else { printf("Forward LSP from %s to %s\n", buffer_packet.routerID, router.nbrs[j].ID); } } } } if(lsp_update_flag == 2) { // run dijkstra's algorithm printf("Update routing table...\n"); if (update_routing_table(&(router), &buffer_packet)) { time(&curr_time); sprintf(tmp_char_buffer, "UTC:\t%s", asctime(gmtime(&curr_time))); printf("%s",tmp_char_buffer); fwrite(tmp_char_buffer, sizeof(char), strlen(tmp_char_buffer), log_file); print_lsp(&buffer_packet, log_file); log_routing_table(&router, log_file); } }*/ //} //} //} // end if }
/* initiate for tcpcopy server */ int interception_init(tc_event_loop_t *event_loop, char *ip, uint16_t port) { int fd; tc_event_t *ev; #if (!TCPCOPY_SINGLE) delay_table_init(srv_settings.hash_size); if (router_init() != TC_OK) { return TC_ERROR; } #endif pid = getpid(); /* init the listening socket */ if ((fd = tc_socket_init()) == TC_INVALID_SOCKET) { return TC_ERROR; } else { if (tc_socket_listen(fd, ip, port) == TC_ERROR) { return TC_ERROR; } tc_log_info(LOG_NOTICE, 0, "msg listen socket:%d", fd); ev = tc_event_create(fd, tc_msg_event_accept, NULL); if (ev == NULL) { return TC_ERROR; } if (tc_event_add(event_loop, ev, TC_EVENT_READ) == TC_EVENT_ERROR) { return TC_ERROR; } } #if (INTERCEPT_NFQUEUE) /* init the nfq socket */ if ((fd = tc_nfq_socket_init(&srv_settings.nfq_handler, &srv_settings.nfq_q_handler, tc_nfq_process_packet)) == TC_INVALID_SOCKET) { return TC_ERROR; } else { tc_log_info(LOG_NOTICE, 0, "nfq socket:%d", fd); ev = tc_event_create(fd, tc_nfq_event_process, NULL); if (ev == NULL) { return TC_ERROR; } if (tc_event_add(event_loop, ev, TC_EVENT_READ) == TC_EVENT_ERROR) { return TC_ERROR; } } #else /* init the netlink socket */ if ((fd = tc_nl_socket_init()) == TC_INVALID_SOCKET) { return TC_ERROR; } else { tc_log_info(LOG_NOTICE, 0, "firewall socket:%d", fd); ev = tc_event_create(fd, tc_nl_event_process, NULL); if (ev == NULL) { return TC_ERROR; } if (tc_event_add(event_loop, ev, TC_EVENT_READ) == TC_EVENT_ERROR) { return TC_ERROR; } } #endif return TC_OK; }
bool ether_init(void) { char str[256]; // Do nothing if no Ethernet device specified const char *name = PrefsFindString("ether"); if (name == NULL) return false; ether_multi_mode = PrefsFindInt32("ethermulticastmode"); ether_use_permanent = PrefsFindBool("etherpermanentaddress"); // Determine Ethernet device type net_if_type = -1; if (PrefsFindBool("routerenabled") || strcmp(name, "router") == 0) net_if_type = NET_IF_ROUTER; else if (strcmp(name, "slirp") == 0) net_if_type = NET_IF_SLIRP; else if (strcmp(name, "tap") == 0) net_if_type = NET_IF_TAP; else net_if_type = NET_IF_B2ETHER; // Initialize NAT-Router if (net_if_type == NET_IF_ROUTER) { if (!router_init()) net_if_type = NET_IF_FAKE; } // Initialize slirp library if (net_if_type == NET_IF_SLIRP) { if (slirp_init() < 0) { sprintf(str, GetString(STR_SLIRP_NO_DNS_FOUND_WARN)); WarningAlert(str); return false; } } // Open ethernet device const char *dev_name; switch (net_if_type) { case NET_IF_B2ETHER: dev_name = PrefsFindString("etherguid"); if (dev_name == NULL || strcmp(name, "b2ether") != 0) dev_name = name; break; case NET_IF_TAP: dev_name = PrefsFindString("etherguid"); break; } if (net_if_type == NET_IF_B2ETHER) { if (dev_name == NULL) { WarningAlert("No ethernet device GUID specified. Ethernet is not available."); goto open_error; } fd = PacketOpenAdapter( dev_name, ether_multi_mode ); if (!fd) { sprintf(str, "Could not open ethernet adapter %s.", dev_name); WarningAlert(str); goto open_error; } // Get Ethernet address if(!PacketGetMAC(fd,ether_addr,ether_use_permanent)) { sprintf(str, "Could not get hardware address of device %s. Ethernet is not available.", dev_name); WarningAlert(str); goto open_error; } D(bug("Real ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5])); const char *ether_fake_address; ether_fake_address = PrefsFindString("etherfakeaddress"); if(ether_fake_address && strlen(ether_fake_address) == 12) { char sm[10]; strcpy( sm, "0x00" ); for( int i=0; i<6; i++ ) { sm[2] = ether_fake_address[i*2]; sm[3] = ether_fake_address[i*2+1]; ether_addr[i] = (uint8)strtoul(sm,0,0); } D(bug("Fake ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5])); } } else if (net_if_type == NET_IF_TAP) { if (dev_name == NULL) { WarningAlert("No ethernet device GUID specified. Ethernet is not available."); goto open_error; } fd = tap_open_adapter(dev_name); if (!fd) { sprintf(str, "Could not open ethernet adapter %s.", dev_name); WarningAlert(str); goto open_error; } if (!tap_check_version(fd)) { sprintf(str, "Minimal TAP-Win32 version supported is %d.%d.", TAP_VERSION_MIN_MAJOR, TAP_VERSION_MIN_MINOR); WarningAlert(str); goto open_error; } if (!tap_set_status(fd, true)) { sprintf(str, "Could not set media status to connected."); WarningAlert(str); goto open_error; } if (!tap_get_mac(fd, ether_addr)) { sprintf(str, "Could not get hardware address of device %s. Ethernet is not available.", dev_name); WarningAlert(str); goto open_error; } D(bug("Real ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5])); const char *ether_fake_address; ether_fake_address = PrefsFindString("etherfakeaddress"); if (ether_fake_address && strlen(ether_fake_address) == 12) { char sm[10]; strcpy( sm, "0x00" ); for( int i=0; i<6; i++ ) { sm[2] = ether_fake_address[i*2]; sm[3] = ether_fake_address[i*2+1]; ether_addr[i] = (uint8)strtoul(sm,0,0); } } #if 1 /* If we bridge the underlying ethernet connection and the TAP device altogether, we have to use a fake address. */ else { ether_addr[0] = 0x52; ether_addr[1] = 0x54; ether_addr[2] = 0x00; } #endif D(bug("Fake ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5])); } else if (net_if_type == NET_IF_SLIRP) { ether_addr[0] = 0x52; ether_addr[1] = 0x54; ether_addr[2] = 0x00; ether_addr[3] = 0x12; ether_addr[4] = 0x34; ether_addr[5] = 0x56; D(bug("Ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5])); } else { memcpy( ether_addr, router_mac_addr, 6 ); D(bug("Fake ethernet address (same as router) %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5])); } // Start packet reception thread int_ack = CreateSemaphore( 0, 0, 1, NULL); if(!int_ack) { WarningAlert("WARNING: Cannot create int_ack semaphore"); goto open_error; } // nonsignaled int_sig = CreateSemaphore( 0, 0, 1, NULL); if(!int_sig) { WarningAlert("WARNING: Cannot create int_sig semaphore"); goto open_error; } int_sig2 = CreateSemaphore( 0, 0, 1, NULL); if(!int_sig2) { WarningAlert("WARNING: Cannot create int_sig2 semaphore"); goto open_error; } int_send_now = CreateSemaphore( 0, 0, 1, NULL); if(!int_send_now) { WarningAlert("WARNING: Cannot create int_send_now semaphore"); goto open_error; } init_queue(); if(!allocate_read_packets()) goto open_error; // No need to enter wait state if we can avoid it. // These all terminate fast. if(pfnInitializeCriticalSectionAndSpinCount) { pfnInitializeCriticalSectionAndSpinCount( &fetch_csection, 5000 ); } else { InitializeCriticalSection( &fetch_csection ); } if(pfnInitializeCriticalSectionAndSpinCount) { pfnInitializeCriticalSectionAndSpinCount( &queue_csection, 5000 ); } else { InitializeCriticalSection( &queue_csection ); } if(pfnInitializeCriticalSectionAndSpinCount) { pfnInitializeCriticalSectionAndSpinCount( &send_csection, 5000 ); } else { InitializeCriticalSection( &send_csection ); } if(pfnInitializeCriticalSectionAndSpinCount) { pfnInitializeCriticalSectionAndSpinCount( &wpool_csection, 5000 ); } else { InitializeCriticalSection( &wpool_csection ); } ether_th = (HANDLE)_beginthreadex( 0, 0, ether_thread_feed_int, 0, 0, ðer_tid ); if (!ether_th) { D(bug("Failed to create ethernet thread\n")); goto open_error; } thread_active = true; unsigned int dummy; unsigned int (WINAPI *receive_func)(void *); switch (net_if_type) { case NET_IF_SLIRP: receive_func = slirp_receive_func; break; default: receive_func = ether_thread_get_packets_nt; break; } ether_th2 = (HANDLE)_beginthreadex( 0, 0, receive_func, 0, 0, &dummy ); ether_th1 = (HANDLE)_beginthreadex( 0, 0, ether_thread_write_packets, 0, 0, &dummy ); // Everything OK return true; open_error: if (thread_active) { TerminateThread(ether_th,0); ether_th = 0; if (int_ack) CloseHandle(int_ack); int_ack = 0; if(int_sig) CloseHandle(int_sig); int_sig = 0; if(int_sig2) CloseHandle(int_sig2); int_sig2 = 0; if(int_send_now) CloseHandle(int_send_now); int_send_now = 0; thread_active = false; } if (fd) { switch (net_if_type) { case NET_IF_B2ETHER: PacketCloseAdapter(fd); break; case NET_IF_TAP: tap_close_adapter(fd); break; } fd = 0; } return false; }
/* * Initialize all I/O on the specified node. */ static void io_init_node(cnodeid_t cnodeid) { /*REFERENCED*/ devfs_handle_t hubv, switchv, widgetv; struct xwidget_hwid_s hwid; hubinfo_t hubinfo; int is_xswitch; nodepda_t *npdap; struct semaphore *peer_sema = 0; uint32_t widget_partnum; nodepda_router_info_t *npda_rip; cpu_cookie_t c = 0; extern int hubdev_docallouts(devfs_handle_t); #ifdef LATER /* Try to execute on the node that we're initializing. */ c = setnoderun(cnodeid); #endif npdap = NODEPDA(cnodeid); /* * Get the "top" vertex for this node's hardware * graph; it will carry the per-hub hub-specific * data, and act as the crosstalk provider master. * It's canonical path is probably something of the * form /hw/module/%M/slot/%d/node */ hubv = cnodeid_to_vertex(cnodeid); DBG("io_init_node: Initialize IO for cnode %d hubv(node) 0x%p npdap 0x%p\n", cnodeid, hubv, npdap); ASSERT(hubv != GRAPH_VERTEX_NONE); hubdev_docallouts(hubv); /* * Set up the dependent routers if we have any. */ npda_rip = npdap->npda_rip_first; while(npda_rip) { /* If the router info has not been initialized * then we need to do the router initialization */ if (!npda_rip->router_infop) { router_init(cnodeid,0,npda_rip); } npda_rip = npda_rip->router_next; } /* * Read mfg info on this hub */ #ifdef LATER printk("io_init_node: FIXME need to implement HUB_VERTEX_MFG_INFO\n"); HUB_VERTEX_MFG_INFO(hubv); #endif /* LATER */ /* * If nothing connected to this hub's xtalk port, we're done. */ early_probe_for_widget(hubv, &hwid); if (hwid.part_num == XWIDGET_PART_NUM_NONE) { #ifdef PROBE_TEST if ((cnodeid == 1) || (cnodeid == 2)) { int index; for (index = 0; index < 600; index++) DBG("Interfering with device probing!!!\n"); } #endif /* io_init_done takes cpu cookie as 2nd argument * to do a restorenoderun for the setnoderun done * at the start of this thread */ DBG("**** io_init_node: Node's 0x%p hub widget has XWIDGET_PART_NUM_NONE ****\n", hubv); return; /* NOTREACHED */ } /* * attach our hub_provider information to hubv, * so we can use it as a crosstalk provider "master" * vertex. */ xtalk_provider_register(hubv, &hub_provider); xtalk_provider_startup(hubv); /* * Create a vertex to represent the crosstalk bus * attached to this hub, and a vertex to be used * as the connect point for whatever is out there * on the other side of our crosstalk connection. * * Crosstalk Switch drivers "climb up" from their * connection point to try and take over the switch * point. * * Of course, the edges and verticies may already * exist, in which case our net effect is just to * associate the "xtalk_" driver with the connection * point for the device. */ (void)hwgraph_path_add(hubv, EDGE_LBL_XTALK, &switchv); DBG("io_init_node: Created 'xtalk' entry to '../node/' xtalk vertex 0x%p\n", switchv); ASSERT(switchv != GRAPH_VERTEX_NONE); (void)hwgraph_edge_add(hubv, switchv, EDGE_LBL_IO); DBG("io_init_node: Created symlink 'io' from ../node/io to ../node/xtalk \n"); /* * We need to find the widget id and update the basew_id field * accordingly. In particular, SN00 has direct connected bridge, * and hence widget id is Not 0. */ widget_partnum = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + WIDGET_ID))) & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT; if (widget_partnum == BRIDGE_WIDGET_PART_NUM || widget_partnum == XBRIDGE_WIDGET_PART_NUM){ npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID); DBG("io_init_node: Found XBRIDGE widget_partnum= 0x%x\n", widget_partnum); } else if (widget_partnum == XBOW_WIDGET_PART_NUM || widget_partnum == XXBOW_WIDGET_PART_NUM) { /* * Xbow control register does not have the widget ID field. * So, hard code the widget ID to be zero. */ DBG("io_init_node: Found XBOW widget_partnum= 0x%x\n", widget_partnum); npdap->basew_id = 0; } else if (widget_partnum == XG_WIDGET_PART_NUM) { /* * OK, WTF do we do here if we have an XG direct connected to a HUB/Bedrock??? * So, hard code the widget ID to be zero? */ npdap->basew_id = 0; npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID); } else { npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID); panic(" ****io_init_node: Unknown Widget Part Number 0x%x Widgt ID 0x%x attached to Hubv 0x%p ****\n", widget_partnum, npdap->basew_id, (void *)hubv); /*NOTREACHED*/ } { char widname[10]; sprintf(widname, "%x", npdap->basew_id); (void)hwgraph_path_add(switchv, widname, &widgetv); DBG("io_init_node: Created '%s' to '..node/xtalk/' vertex 0x%p\n", widname, widgetv); ASSERT(widgetv != GRAPH_VERTEX_NONE); } nodepda->basew_xc = widgetv; is_xswitch = xwidget_hwid_is_xswitch(&hwid); /* * Try to become the master of the widget. If this is an xswitch * with multiple hubs connected, only one will succeed. Mastership * of an xswitch is used only when touching registers on that xswitch. * The slave xwidgets connected to the xswitch can be owned by various * masters. */ if (device_master_set(widgetv, hubv) == 0) { /* Only one hub (thread) per Crosstalk device or switch makes * it to here. */ /* * Initialize whatever xwidget is hanging off our hub. * Whatever it is, it's accessible through widgetnum 0. */ hubinfo_get(hubv, &hubinfo); (void)xwidget_register(&hwid, widgetv, npdap->basew_id, hubv, hubinfo->h_widgetid, NULL); if (!is_xswitch) { /* io_init_done takes cpu cookie as 2nd argument * to do a restorenoderun for the setnoderun done * at the start of this thread */ io_init_done(cnodeid,c); /* NOTREACHED */ } /* * Special handling for Crosstalk Switches (e.g. xbow). * We need to do things in roughly the following order: * 1) Initialize xswitch hardware (done above) * 2) Determine which hubs are available to be widget masters * 3) Discover which links are active from the xswitch * 4) Assign xwidgets hanging off the xswitch to hubs * 5) Initialize all xwidgets on the xswitch */ volunteer_for_widgets(switchv, hubv); /* If there's someone else on this crossbow, recognize him */ if (npdap->xbow_peer != INVALID_NASID) { nodepda_t *peer_npdap = NODEPDA(NASID_TO_COMPACT_NODEID(npdap->xbow_peer)); peer_sema = &peer_npdap->xbow_sema; volunteer_for_widgets(switchv, peer_npdap->node_vertex); } assign_widgets_to_volunteers(switchv, hubv); /* Signal that we're done */ if (peer_sema) { mutex_unlock(peer_sema); } } else { /* Wait 'til master is done assigning widgets. */ mutex_lock(&npdap->xbow_sema); } #ifdef PROBE_TEST if ((cnodeid == 1) || (cnodeid == 2)) { int index; for (index = 0; index < 500; index++) DBG("Interfering with device probing!!!\n"); } #endif /* Now both nodes can safely inititialize widgets */ io_init_xswitch_widgets(switchv, cnodeid); io_link_xswitch_widgets(switchv, cnodeid); /* io_init_done takes cpu cookie as 2nd argument * to do a restorenoderun for the setnoderun done * at the start of this thread */ io_init_done(cnodeid,c); DBG("\nio_init_node: DONE INITIALIZED ALL I/O FOR CNODEID %d\n\n", cnodeid); }