Exemplo n.º 1
0
/*
 * 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;
	}
}
Exemplo n.º 2
0
/* --- 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");
}
Exemplo n.º 3
0
/*
 * 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;
}
Exemplo n.º 4
0
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;
}