/* * Helper function to update distances of routers attached to w's interfaces */ void update_neighbor_distance(pwospf_router* w, node* pwospf_router_list) { node* cur = w->interface_list; /* iterate through each interface of this router */ while (cur) { pwospf_interface* i = (pwospf_interface*)cur->data; if ((i->router_id != 0) && i->is_active) { pwospf_router* v = get_router_by_rid(i->router_id, pwospf_router_list); /* if the distance to v is shorter through w, update it */ /* ADDED: ensure V exists in our router list as well, * it is possible that someone is reporting a router that is * a neighbor that we have not received an LSU for yet */ if ((v) && (!v->shortest_path_found) && ((w->distance+1) < v->distance)) { v->distance = w->distance + 1; v->prev_router = w; } } cur = cur->next; } }
/* --- CCDN 初始化路由表,将来可以参照 功能:从sr的rtable字段读取名字,在当前工作目录下找到相应的文件, 从文件中读取路由表entry,然后将每条entry加入到table里面*/ void init_rtable(struct sr_instance* sr) { /* get the rtable lock */ lock_rtable_wr(get_router_state(sr)); /* the sr_instance only holds 32 chars of the path to the rtable file so we have * to pass it in as a relative path to the working directory, which requires * us to get the working directory, do some string manipulation, and append * the relative path to the end of the working directory */ char path[256]; bzero(path, 256); getcwd(path, 256);//获取当前工作的绝对路径,存到path中 int len = strlen(path); path[len] = '/'; strcpy(path+len+1, sr->rtable); FILE* file = fopen(path, "r"); if (file == NULL) { perror("Failure opening file"); exit(1); } /* 前面这一大块干的是就是在工作目录下找到一个文件(例如rtable),里面存路由表之类的信息 */ char buf[1024]; bzero(buf, 1024); router_state* rs = (router_state*)sr->interface_subsystem; /* walk through the file one line at a time adding its contents to the rtable */ /* 下面这个while干的事情是从文件中读取ip表,然后把它们加入到rtable里面 */ while (fgets(buf, 1024, file) != NULL) { char* ip = NULL; char* gw = NULL; char* mask = NULL; char* iface = NULL; if (sscanf(buf, "%as %as %as %as", &ip, &gw, &mask, &iface) != 4) { printf("Failure reading from rtable file\n"); } rtable_entry* entry = (rtable_entry*)malloc(sizeof(rtable_entry)); bzero(entry, sizeof(rtable_entry)); // bzero,清空整个地址空间 if (inet_pton(AF_INET, ip, &(entry->ip)) == 0) {//点分十进制->整数之间的转换,AF_INET指地址簇,可以理解为IPv4 perror("Failure reading rtable"); // perror:标准错误流,会讲错误的原因输出到屏幕上。 } if (inet_pton(AF_INET, gw, &(entry->gw)) == 0) { perror("Failure reading rtable"); } if (inet_pton(AF_INET, mask, &(entry->mask)) == 0) { perror("Failure reading rtable"); } strncpy(entry->iface, iface, 32); entry->is_active = 1; entry->is_static = 1; /* create a node, set data pointer to the new entry */ node* n = node_create(); n->data = entry; if (rs->rtable == NULL) { rs->rtable = n; } else { node_push_back(rs->rtable, n); } char ip_array[INET_ADDRSTRLEN]; char gw_array[INET_ADDRSTRLEN]; char mask_array[INET_ADDRSTRLEN]; printf("Read: %s ", inet_ntop(AF_INET, &(entry->ip), ip_array, INET_ADDRSTRLEN)); printf("%s ", inet_ntop(AF_INET, &(entry->gw), gw_array, INET_ADDRSTRLEN)); printf("%s ", inet_ntop(AF_INET, &(entry->mask), mask_array, INET_ADDRSTRLEN)); printf("%s\n", entry->iface); } if (fclose(file) != 0) { perror("Failure closing file"); } /* check if we have a default route entry, if so we need to add it to our pwospf router */ pwospf_interface* default_route = default_route_present(rs); /* release the rtable lock */ unlock_rtable(get_router_state(sr)); if (default_route) { lock_mutex_pwospf_router_list(rs); pwospf_router* r = get_router_by_rid(rs->router_id, rs->pwospf_router_list); node* n = node_create(); n->data = default_route; if (r->interface_list) { node_push_back(r->interface_list, n); } else { r->interface_list = n; } unlock_mutex_pwospf_router_list(rs); } /* tell our dijkstra algorithm to run */ dijkstra_trigger(rs); printf("init_rtable finish \n"); }
/* * Stats thread for the NETFPGA Ports */ void* netfpga_stats(void* arg) { router_state* rs = (router_state*)arg; struct timeval now; uint32_t rx_packets, tx_packets, rx_bytes, tx_bytes; uint32_t rx_packets_diff, tx_packets_diff, rx_bytes_diff, tx_bytes_diff; long double timeDiff; int i, j; while (1) { // printf("or_netfpga.c: NetFPGA begin recording its stats...\n"); gettimeofday(&now, NULL); if (now.tv_sec == rs->stats_last_time.tv_sec) { /* must be a later usec time */ timeDiff = (((long double)(now.tv_usec - rs->stats_last_time.tv_usec)) / (long double)1000000); } else { timeDiff = (now.tv_sec - rs->stats_last_time.tv_sec - 1) + ((long double)((1000000 - rs->stats_last_time.tv_usec) + now.tv_usec) / (long double)1000000); } lock_netfpga_stats(rs); printf("port # rx_pkts tx_pkts rx_kbytes tx_kbytes pkt/s kbyte/s time\n"); printf("======================================================================================\n"); for (i = 0; i < 8; ++i) { /* read all the values */ rx_packets = get_rx_queue_num_pkts_received(&rs->netfpga, i); tx_packets = get_tx_queue_num_pkts_sent(&rs->netfpga, i); rx_bytes = get_rx_queue_num_bytes_received(&rs->netfpga, i); tx_bytes = get_tx_queue_num_bytes_sent(&rs->netfpga, i); /* compute differences */ rx_packets_diff = rx_packets - rs->stats_last[i][0]; tx_packets_diff = tx_packets - rs->stats_last[i][1]; rx_bytes_diff = rx_bytes - rs->stats_last[i][2]; tx_bytes_diff = tx_bytes - rs->stats_last[i][3]; /* bytes_diff will be in kB */ rx_bytes_diff /= 1024; tx_bytes_diff /= 1024; /* update averages */ rs->stats_avg[i][0] = ((double)rx_packets_diff) / timeDiff; rs->stats_avg[i][1] = ((double)tx_packets_diff) / timeDiff; rs->stats_avg[i][2] = ((double)rx_bytes_diff) / timeDiff; rs->stats_avg[i][3] = ((double)tx_bytes_diff) / timeDiff; /* store data back */ rs->stats_last[i][0] = rx_packets; rs->stats_last[i][1] = tx_packets; rs->stats_last[i][2] = rx_bytes; rs->stats_last[i][3] = tx_bytes; rs->stats_last_time = now; printf("%6d %10d %10d %10d %10d %8.2Lf %8.2Lf %u\n", i, rs->stats_last[i][0], rs->stats_last[i][1], rs->stats_last[i][2], rs->stats_last[i][3], rs->stats_avg[i][0] + rs->stats_avg[i][1], rs->stats_avg[i][2] + rs->stats_avg[i][3], now); } node* cur = NULL; pwospf_router* r = get_router_by_rid(rs->router_id, rs->pwospf_router_list); if (r != NULL) { cur = r->interface_list; j = 0; while (cur) { pwospf_interface* iface = (pwospf_interface*)cur->data; iface->rx_rate = (uint32_t)(rs->stats_avg[j][2]); iface->tx_rate = (uint32_t)(rs->stats_avg[j][3]); //printf("or_netfpga.c: iface->rx_rate[%d] = %d (kbytes)\n", j, iface->rx_rate); //printf("or_netfpga.c: iface->tx_rate[%d] = %d (kbytes)\n", j, iface->tx_rate); cur = cur->next; j++; } } unlock_netfpga_stats(rs); printf("======================================================================================\n"); printf("or_netfpga.c: NetFPGA end recording its stats.\n"); printf("or_netfpga.c: There are %d interfaces in this router.\n", j); usleep(500000); } return NULL; }
node* compute_rtable(uint32_t our_router_id, node* pwospf_router_list, node* if_list) { /* initialize all the entriest to their max distance, except us */ node* cur = pwospf_router_list; pwospf_router* r = NULL; pwospf_router* r_shortest = NULL; while (cur) { r = (pwospf_router*)cur->data; if (r->router_id == our_router_id) { r->distance = 0; r->shortest_path_found = 1; } else if (r->router_id != 0) { r->distance = 0xFFFFFFFF; r->shortest_path_found = 0; } cur = cur->next; } /* Set our router as the shortest */ r_shortest = get_router_by_rid(our_router_id, pwospf_router_list); while (r_shortest) { /* add this router to N' */ r_shortest->shortest_path_found = 1; /* update the distances to our neighbors */ update_neighbor_distance(r_shortest, pwospf_router_list); /* get the next router with the shortest distance */ r_shortest = get_shortest(pwospf_router_list); } /* now have the shortest path to each router, build the temporary route table */ node* route_wrapper_list = build_route_wrapper_list(our_router_id, pwospf_router_list); //print_wrapper_list(route_wrapper_list); /* we now have a list of wrapped proper entries, but they need specific interface info, * and need to lose the wrapping */ node* route_list = NULL; cur = route_wrapper_list; while (cur) { route_wrapper* wrapper = (route_wrapper*)cur->data; rtable_entry* new_entry = (rtable_entry*)calloc(1, sizeof(rtable_entry)); /* just blast the entry information across */ memcpy(new_entry, &(wrapper->entry), sizeof(rtable_entry)); /* get the new stuff */ iface_entry* iface = get_iface_by_rid(wrapper->next_rid, if_list); if (!iface) { iface = get_iface_by_subnet_mask(&(wrapper->entry.ip), &(wrapper->entry.mask), if_list); if (!iface) { /* most likely the default entry, assume its static, so just continue */ free(new_entry); cur = cur->next; continue; } } assert(iface); memcpy(new_entry->iface, iface->name, IF_LEN); if (wrapper->directly_connected) { new_entry->gw.s_addr = 0; } else { nbr_router* nbr = get_nbr_by_rid(iface, wrapper->next_rid); assert(nbr); new_entry->gw.s_addr = nbr->ip.s_addr; } new_entry->is_active = 1; new_entry->is_static = 0; /* grab a new node, add it to the list */ node* temp = node_create(); temp->data = new_entry; if (!route_list) { route_list = temp; } else { node_push_back(route_list, temp); } cur = cur->next; } /* run through and free the wrapper list */ cur = route_wrapper_list; while (cur) { node* next = cur->next; node_remove(&route_wrapper_list, cur); cur = next; } return route_list; }