Ejemplo n.º 1
0
void generate_pending_ARP_thread() {
    router_t *router = get_router();
    pending_arp_entry_t expiring_arp_entry[router->num_pending_arp];
    unsigned i;
    while (TRUE) {
        
        unsigned num_expiring = 0;
        
        pthread_mutex_lock(&router->pending_arp_lock);
        for (i = 0; i < router->num_pending_arp; i++) {
            pending_arp_entry_t *pending_arp_entry = &router->pending_arp[i];
            if (pending_arp_entry->num_sent >= 5) {
                debug_println("Not responding to ARP request!");
                expiring_arp_entry[num_expiring].payload = pending_arp_entry->payload;
                expiring_arp_entry[num_expiring].len = pending_arp_entry->len;
                num_expiring++;
                unsigned j;
                for (j = i; j < router->num_pending_arp-1; j++) {
                    router->pending_arp[j] = router->pending_arp[j+1];
                }
                router->num_pending_arp--;
                if (i != router->num_pending_arp)
                    i--; //Don't increase i on next go.
                continue;
            }
            send_ARP_request(pending_arp_entry->ip, ++pending_arp_entry->num_sent); //Shouldn't need lock.
        }
        debug_println("num_pending_arp=%d", router->num_pending_arp);
        pthread_mutex_unlock(&router->pending_arp_lock);
        
        for (i = 0; i < num_expiring; i++) {
            struct ip_hdr *iphdr = (void *)expiring_arp_entry[i].payload;
            if (router_lookup_interface_via_ip(router, IPH_SRC(iphdr)) == NULL) { //Don't send a response to itself.
                handle_not_repsponding_to_arp(expiring_arp_entry[i].payload, expiring_arp_entry[i].len);
            } else {
                debug_println("NOT sending response, because it originated from own interface.");
            }
            free(expiring_arp_entry[i].payload);
            expiring_arp_entry[i].payload = NULL;
        }
        
        sleep(1);
        debug_println("Pending ARP thread sleeping for 1s.");
    }
}
Ejemplo n.º 2
0
int main() {
    const int port = 8000;
    http_server svc;

    //bring up tls machine, this need to be done before server setup
    int ng = tls_engine_inhale("server-cert.pem", "server-key.pem", 0);
    assert(ng == 0);

    setup_server(&svc, "0.0.0.0", port);

    //the length of path passed explicitly to stop strlen calling
    router *rtr = get_router(&svc);
    addroute(rtr, "/redfish", 8, write_res);

    printf("Listening on %d\n", port);

    //run forever
    run(&svc);

    tls_engine_stop();
    return 0;
}
Ejemplo n.º 3
0
int handle_rtm_newroute(const struct nlmsghdr *nl){
	const struct rtmsg *rt = NLMSG_DATA(nl);
	struct rtattr *ra;
	void *as,*ad,*ag;
	int rlen,oif;
	route *r,**prev;
	size_t flen;

	oif = -1;
	if((r = create_route()) == NULL){
		return -1;
	}
	switch( (r->family = rt->rtm_family) ){
	case AF_INET:{
		flen = sizeof(uint32_t);
		as = &((struct sockaddr_in *)&r->sss)->sin_addr;
		ad = &((struct sockaddr_in *)&r->ssd)->sin_addr;
		ag = &((struct sockaddr_in *)&r->ssg)->sin_addr;
	break;}case AF_INET6:{
		flen = sizeof(uint32_t) * 4;
		as = &((struct sockaddr_in6 *)&r->sss)->sin6_addr;
		ad = &((struct sockaddr_in6 *)&r->ssd)->sin6_addr;
		ag = &((struct sockaddr_in6 *)&r->ssg)->sin6_addr;
	break;}case AF_BRIDGE:{
		// FIXME wtf is a bridge route
		diagnostic("got a bridge route hrmmm FIXME");
		return -1; // FIXME
	break;}default:{
		flen = 0;
	break;} }
	r->maskbits = rt->rtm_dst_len;
	if(flen == 0 || flen > sizeof(r->sss.__ss_padding)){
		diagnostic("Unknown route family %u",rt->rtm_family);
		return -1;
	}
	rlen = nl->nlmsg_len - NLMSG_LENGTH(sizeof(*rt));
	ra = (struct rtattr *)((char *)(NLMSG_DATA(nl)) + sizeof(*rt));
	memset(&r->ssg,0,sizeof(r->ssg));
	memset(&r->ssd,0,sizeof(r->ssd));
	memset(&r->sss,0,sizeof(r->sss));
	while(RTA_OK(ra,rlen)){
		switch(ra->rta_type){
		case RTA_DST:{
			if(RTA_PAYLOAD(ra) != flen){
				diagnostic("Expected %zu dst bytes, got %zu",
						flen,RTA_PAYLOAD(ra));
				break;
			}
			if(r->ssd.ss_family){
				diagnostic("Got two destinations for route");
				break;
			}
			memcpy(ad,RTA_DATA(ra),flen);
			r->ssd.ss_family = r->family;
		break;}case RTA_PREFSRC: case RTA_SRC:{
			// FIXME do we not want to prefer PREFSRC?
			if(RTA_PAYLOAD(ra) != flen){
				diagnostic("Expected %zu src bytes, got %zu",
						flen,RTA_PAYLOAD(ra));
				break;
			}
			if(r->sss.ss_family){
				diagnostic("Got two sources for route");
				break;
			}
			memcpy(as,RTA_DATA(ra),flen);
			r->sss.ss_family = r->family;
		break;}case RTA_IIF:{
			if(RTA_PAYLOAD(ra) != sizeof(int)){
				diagnostic("Expected %zu iiface bytes, got %zu",
						sizeof(int),RTA_PAYLOAD(ra));
				break;
			}
			// we don't use RTA_OIF: iif = *(int *)RTA_DATA(ra);
		break;}case RTA_OIF:{
			if(RTA_PAYLOAD(ra) != sizeof(int)){
				diagnostic("Expected %zu oiface bytes, got %zu",
						sizeof(int),RTA_PAYLOAD(ra));
				break;
			}
			oif = *(int *)RTA_DATA(ra);
		break;}case RTA_GATEWAY:{
			if(RTA_PAYLOAD(ra) != flen){
				diagnostic("Expected %zu gw bytes, got %zu",
						flen,RTA_PAYLOAD(ra));
				break;
			}
			if(r->ssg.ss_family){
				diagnostic("Got two gateways for route");
				break;
			}
			// We get 0.0.0.0 as the gateway when there's no 'via'
			if(memcmp(ag,RTA_DATA(ra),flen)){
				memcpy(ag,RTA_DATA(ra),flen);
				r->ssg.ss_family = r->family;
			}
		break;}case RTA_PRIORITY:{
		break;}case RTA_METRICS:{
		break;}case RTA_MULTIPATH:{
		// break;}case RTA_PROTOINFO:{ // unused
		break;}case RTA_FLOW:{
		break;}case RTA_CACHEINFO:{
		// break;}case RTA_SESSION:{ // unused
		// break;}case RTA_MP_ALGO:{ // unused
		break;}case RTA_TABLE:{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
		break;}case RTA_MARK:{
#endif
		break;}case RTA_MFC_STATS:{
		break;}case RTA_VIA:{
		break;}case RTA_NEWDST:{
		break;}case RTA_PREF:{
		break;}case RTA_ENCAP_TYPE:{
		break;}case RTA_ENCAP:{
		break;}case RTA_EXPIRES:{
		break;}case RTA_PAD:{
		break;}default:{
			diagnostic("Unknown rtatype %u",ra->rta_type);
		break;}}
		ra = RTA_NEXT(ra,rlen);
	}
	if(rlen){
		diagnostic("%d excess bytes on newlink message",rlen);
	}
	if((r->iface = iface_by_idx(oif)) == NULL){
		diagnostic("Unknown output interface %d on %s",oif,r->iface->name);
		goto err;
	}
	{
		char str[INET6_ADDRSTRLEN],via[INET6_ADDRSTRLEN];
		inet_ntop(rt->rtm_family,ad,str,sizeof(str));
		inet_ntop(rt->rtm_family,ag,via,sizeof(via));
		diagnostic("[%s] new route to %s/%u %ls%ls%s",
			r->iface->name,str,r->maskbits,
			rt->rtm_type == RTN_LOCAL ? L"(local)" :
			rt->rtm_type == RTN_BROADCAST ? L"(broadcast)" :
			rt->rtm_type == RTN_UNREACHABLE ? L"(unreachable)" :
			rt->rtm_type == RTN_ANYCAST ? L"(anycast)" :
			rt->rtm_type == RTN_UNICAST ? L"(unicast)" :
			rt->rtm_type == RTN_MULTICAST ? L"(multicast)" :
			rt->rtm_type == RTN_BLACKHOLE ? L"(blackhole)" :
			rt->rtm_type == RTN_MULTICAST ? L"(multicast)" : L"",
			r->ssg.ss_family ? L" via " : L"",
			r->ssg.ss_family ? via : "");
	}
	// We're not interest in blackholes, unreachables, prohibits, NATs yet
	if(rt->rtm_type != RTN_UNICAST && rt->rtm_type != RTN_LOCAL
			&& rt->rtm_type != RTN_BROADCAST
			&& rt->rtm_type != RTN_ANYCAST
			&& rt->rtm_type != RTN_MULTICAST){
		free_route(r);
		return 0;
	}
	assert(r->iface);
	if(!r->sss.ss_family){
		struct routepath rp;

		if(get_router(r->sss.ss_family,ad,&rp) == 0){
			if(r->sss.ss_family == AF_INET){
				memcpy(as,rp.src,4);
			}else if(r->sss.ss_family == AF_INET6){
				memcpy(as,rp.src,16);
			}else{
				assert(0);
			}
		}else{ // FIXME vicious hackery!
			if(r->family == AF_INET6){
				memcpy(as,r->iface->ip6defsrc,flen);
				r->sss.ss_family = AF_INET6;
			}
		}
	}
	if(r->family == AF_INET){
		lock_interface(r->iface);
		if(add_route4(r->iface,ad,r->ssg.ss_family ? ag : NULL,
					r->sss.ss_family ? as : NULL,
					r->maskbits)){
			unlock_interface(r->iface);
			diagnostic("Couldn't add route to %s",r->iface->name);
			goto err;
		}
		if(r->ssg.ss_family){
			send_arp_req(r->iface,r->iface->bcast,ag,as);
		}
		unlock_interface(r->iface);
		pthread_mutex_lock(&route_lock);
			prev = &ip_table4;
			// Order most-specific (largest maskbits) to least-specific (0 maskbits)
			while(*prev){
				if(r->maskbits > (*prev)->maskbits){
					break;
				}
				prev = &(*prev)->next;
			}
			r->next = *prev;
			*prev = r;
			if(r->sss.ss_family){
				while( *(prev = &(*prev)->next) ){
					assert((*prev)->maskbits < r->maskbits);
					if(!((*prev)->sss.ss_family)){
						memcpy(&(*prev)->sss,&r->sss,sizeof(r->sss));
					}
				}
			}
		pthread_mutex_unlock(&route_lock);
	}else if(r->family == AF_INET6){
		lock_interface(r->iface);
		if(add_route6(r->iface,ad,r->ssg.ss_family ? ag : NULL,r->sss.ss_family ? as : NULL,r->maskbits)){
			unlock_interface(r->iface);
			diagnostic("Couldn't add route to %s",r->iface->name);
			goto err;
		}
		unlock_interface(r->iface);
		pthread_mutex_lock(&route_lock);
			prev = &ip_table6;
			// Order most-specific (largest maskbits) to least-specific (0 maskbits)
			while(*prev){
				if(r->maskbits > (*prev)->maskbits){
					break;
				}
				prev = &(*prev)->next;
			}
			r->next = *prev;
			*prev = r;
			// FIXME set less-specific sources
		pthread_mutex_unlock(&route_lock);
	}
	return 0;

err:
	free_route(r);
	return -1;
}
Ejemplo n.º 4
0
// build the network with the parameters given in param
Network::Network(void)
{
    success = true;
    n_of_rows = param.n_of_rows;
    n_of_cols = param.n_of_cols;
    n_of_ports = param.n_of_ports;
    n_of_extra_links = param.n_of_extra_links;
    topology = param.topology;
    n_of_switch_ports = param.n_of_switch_ports;
    n_of_vcs = param.n_of_vcs;

    Traffic_source::reset_id_base();
    Traffic_sink::reset_id_base();

    if (param.verbose)
        cout << "[I] Building network..." << endl;

    if (topology != mesh)
    {
        cerr << ERRO_ARCH_NOT_SUPPORTED;
        success = false;
        return;
    }

    if (param.verbose)
        cout << "[I] Creating routers..." << endl;

    Position pos;
    // Build all the routers and PEs in the network
    for (pos.x = 0; pos.x < param.n_of_cols; pos.x++)
    {
        for (pos.y = 0; pos.y < param.n_of_rows; pos.y++)
        {
            pRouter a_router = new Router(this, pos);
            routers.push_back(a_router);
        }
    }

    if (param.verbose)
        cout << "[I] Creating traffic sources/sinks..." << endl;

    // Build all the traffic sources/sinks in the network
    for (pos.x = 0; pos.x < param.n_of_cols; pos.x++)
    {
        for (pos.y = 0; pos.y < param.n_of_rows; pos.y++)
        {
            pTraffic_source a_source = new Traffic_source(pos,
                    param.source_buffer_size);
            pTraffic_sink a_sink =
                    new Traffic_sink(pos, param.sink_buffer_size);

            //CPU
            m_newnode(yyengine, "superH", 0, 0, 0, NULL, 0);
            //network interface 1 tx/rx queue,
            network_netnodenewifc(yyengine, yyengine->cp, 0, 0, 0, 0, 0, 0, 0,
                    0, (param.source_buffer_size * 8/sizeof(FlitPayload) - 1) * 8, 2, 2); //FIXME: how to set those parameters

            //set memory size
            m_sizemem(yyengine, yyengine->cp,0x9000000);
            //load the program
            load_srec(yyengine, yyengine->cp, "default.sr");
            m_run(yyengine, yyengine->cp, ""); //FIXME: add arguments to nodes


            a_source->state = yyengine->cp;
            a_sink->state = yyengine->cp;

            sources.push_back(a_source);
            sinks.push_back(a_sink);
        }
    }

    if (param.verbose)
        cout << "[I] Attaching traffic sources/sinks with routers..." << endl;
    // connect sources and sinks with the router
    for (pos.x = 0; pos.x < param.n_of_cols; pos.x++)
    {
        for (pos.y = 0; pos.y < param.n_of_rows; pos.y++)
        {
            pTraffic_source a_source = get_traffic_source(pos);
            pTraffic_sink a_sink = get_traffic_sink(pos);
            pRouter a_router = get_router(pos);
            pIn_port a_in_port = a_router->get_in_port(local);
            pOut_port a_out_port = a_router->get_out_port(local);
            connect(a_source, a_in_port);
            connect(a_out_port, a_sink);
        }
    }

    if (param.verbose)
        cout << "[I] Connecting routers with links..." << endl;
    // connect the port of each router to the corresponding output port
    // of its neighboring router
    for (pos.x = 0; pos.x < param.n_of_cols; pos.x++)
    {
        for (pos.y = 0; pos.y < param.n_of_rows; pos.y++)
        {
            pRouter src_router = get_router(pos);
            for (unsigned int i = 0; i < n_of_ports - n_of_extra_links; i++)
            {
                Direction dir = (Direction) i;
                if (dir == local) // no go for local router
                    continue;
                pRouter dst_router = src_router->get_router(dir);
                if (dst_router == 0)
                    continue;
                pOut_port a_out_port = src_router->get_out_port(dir);
                pIn_port a_in_port = dst_router->get_in_port(reverse(dir));
                connect(a_out_port, a_in_port);
            }
        }
    }

    if (param.verbose)
        cout << "[I] Network successfully built..." << endl;

    param.network = this;
}
Ejemplo n.º 5
0
void Network::calc_channel_load(void)
{
    pInput_channel ch = 0;

    // first, clear the load parameters of every input channel
    for (vector<pRouter>::iterator r = routers.begin(); r < routers.end(); r++)
    {
        for (Direction dir = local; dir < invalid_dir; dir
                = (Direction) (((int) dir) + 1))
        {
            ch = (*r)->get_in_channel(dir);
            ch->reset_load();
        }
    }
    // clear the load parameters of every sinks
    for (vector<pTraffic_sink>::iterator iter = sinks.begin(); iter
            < sinks.end(); iter++)
        (*iter)->reset_load();

    // now enumerate all the traffic transactions between any source/destination pairs
    for (unsigned int src = 0; src < sources.size(); src++)
    {
        pTraffic_source pts = sources[src];
        for (unsigned int dst = 0; dst < sinks.size(); dst++)
        {
            if (src == dst)
                continue;
            double load = pts->get_packet_to_destination_rate(dst);
            if (load == 0)
                continue;
            // now let's update all the input channel load used by this traffic 
            Position src_pos = pts->get_position();
            Position dst_pos = sinks[dst]->get_position();

            // first, fill in the local input channel in the local router
            pRouter r = get_router(src_pos);
            ch = r->get_in_channel(local);
            pRouting_engine re = ch->get_routing_engine();
            Direction out_dir = re->decide_direction(src_pos, dst_pos);
            ch->add_load(load, out_dir);

            // now start following the routing path
            Position cur_pos = src_pos;
            pRouter cur_r = r;
            pInput_channel cur_ch = ch;
            while (cur_pos != dst_pos)
            {
                re = cur_ch->get_routing_engine();
                out_dir = re->decide_direction(src_pos, dst_pos);
                pRouter next_r = cur_r->get_router(out_dir);
                pInput_channel next_ch = next_r->get_in_channel(
                        reverse(out_dir));
                re = next_ch->get_routing_engine();
                out_dir = re->decide_direction(src_pos, dst_pos);
                next_ch->add_load(load, out_dir);

                cur_r = next_r;
                cur_ch = next_ch;
                cur_pos = cur_r->get_position();
            }

            assert(cur_pos == dst_pos);
            assert(out_dir == local);
            // finally, we need to update the traffic sinks load
            sinks[dst]->add_load(load);

        }
    }

}
Ejemplo n.º 6
0
void handle_ARP_packet(packet_info_t *pi) {
    /*unsigned i;
     for (i = 0; i < pi->len; i++)
     printf("(%d %02X) ", i, (int)*(pi->packet+i));
     printf("\n");*/
    
    byte *ARP_packet = pi->packet+14;
    struct arp_hdr *arhdr = (void *)ARP_packet;
    
    addr_ip_t target_ip = ARH_TARGET_IP(arhdr);
    char target_ip_str[16];
    ip_to_string(target_ip_str, target_ip);
    uint16_t op = ARH_OP(arhdr);
    
    router_t *router = get_router();
    
    interface_t *target_intf = router_lookup_interface_via_ip(router, target_ip);
    addr_mac_t sender_mac = ARH_SENDER_MAC(arhdr);
    addr_ip_t sender_ip = ARH_SENDER_IP(arhdr);
    
    if (target_intf && op == 1) {
        char sender_ip_str[12];
        ip_to_string(sender_ip_str, sender_ip);
        debug_println("Packet is an ARP request from %s for %s.", sender_ip_str, target_ip_str);
        
        if (router_find_arp_entry(router, sender_ip)) {
            router_delete_arp_entry(router, sender_ip);
        }
        router_add_arp_entry(router, sender_mac, sender_ip, TRUE); //Save mac address.
        ARH_OP_SET(arhdr, 2);
        
        swap_bytes(&ARH_SENDER_MAC(arhdr),&ARH_TARGET_MAC(arhdr), ARH_HARD_LEN(arhdr)+ARH_PROTO_LEN(arhdr)); //Swap ARP source and dest mac and ip
        ARH_SENDER_MAC_SET(arhdr, target_intf->mac);
        
        send_packet(pi->packet+14, target_intf->ip, sender_ip, pi->len-14, TRUE, FALSE);
    } else if (target_intf && op == 2) {
        char sender_ip_str[12];
        ip_to_string(sender_ip_str, sender_ip);
        debug_println("Packet is an ARP reply from %s for %s.\n", sender_ip_str, target_ip_str);
        
        if (router_find_arp_entry(router, sender_ip)) {
            router_delete_arp_entry(router, sender_ip);
        }
        router_add_arp_entry(router, sender_mac, sender_ip, TRUE); //Save mac address.
        
        debug_println("about to get lock!");
        pthread_mutex_lock(&router->pending_arp_lock);
        
        debug_println("num_pending_arp=%d", router->num_pending_arp);
        unsigned i;
        for (i = 0; i < router->num_pending_arp; i++) {
            debug_println("i=%d", i);
            pending_arp_entry_t *pending_arp_entry = &router->pending_arp[i];
            if (pending_arp_entry->ip == sender_ip) {
                debug_println("Resending packet in entry %d", i);
                send_packet(pending_arp_entry->payload, pending_arp_entry->src, pending_arp_entry->ip, pending_arp_entry->len, FALSE, FALSE);
                unsigned j;
                for (j = i; j < router->num_pending_arp-1; j++) {
                    router->pending_arp[j] = router->pending_arp[j+1];
                }
                router->num_pending_arp--;
                if (i != router->num_pending_arp)
                    i--; //Don't increase i on next go.
            }
        }
        
        
        pthread_mutex_unlock(&router->pending_arp_lock);
        
        
    }
}