Beispiel #1
0
static int prepare4(struct rxe_pkt_info *pkt, struct sk_buff *skb)
{
	struct rxe_qp *qp = pkt->qp;
	struct dst_entry *dst;
	bool xnet = false;
	__be16 df = htons(IP_DF);
	struct rxe_av *av = rxe_get_av(pkt);
	struct in_addr *saddr = &av->sgid_addr._sockaddr_in.sin_addr;
	struct in_addr *daddr = &av->dgid_addr._sockaddr_in.sin_addr;

	dst = rxe_find_route(skb->dev, qp, av);
	if (!dst) {
		pr_err("Host not reachable\n");
		return -EHOSTUNREACH;
	}

	prepare_udp_hdr(skb, cpu_to_be16(qp->src_port),
			cpu_to_be16(ROCE_V2_UDP_DPORT));

	prepare_ipv4_hdr(dst, skb, saddr->s_addr, daddr->s_addr, IPPROTO_UDP,
			 av->grh.traffic_class, av->grh.hop_limit, df, xnet);

	dst_release(dst);
	return 0;
}
Beispiel #2
0
void sr_handle_arpreq(struct sr_instance* sr /* borrowed */,
			struct sr_arpreq* req /* borrowed */) {
	time_t now = time(NULL);
	if( 1.0 <= difftime(now,req->sent) ) {
		if( 5 <= req->times_sent ) {
			unsigned int len = sizeof(sr_ethernet_hdr_t)+sizeof(sr_ip_hdr_t)+sizeof(sr_icmp_t3_hdr_t);
			uint8_t* buf = (uint8_t*)malloc(len);
			struct sr_rt* rt_match = 0;
			sr_ip_hdr_t* ip_hdr = 0;
			sr_ethernet_hdr_t* eth_hdr = 0;
			struct sr_if* if_to_send = 0;

			assert(buf);

			while(req->packets) {
				ip_hdr = (sr_ip_hdr_t*)(req->packets->buf+sizeof(sr_ethernet_hdr_t));
				eth_hdr = (sr_ethernet_hdr_t*)(req->packets->buf);
				rt_match = sr_get_longest_rt_table_match(sr->routing_table,ip_hdr->ip_src);

				if(rt_match) {
					if_to_send = sr_get_interface(sr,rt_match->interface);
					prepare_icmp_t3_hdr( (sr_icmp_t3_hdr_t*)( buf+(len-sizeof(sr_icmp_t3_hdr_t)) ), 0x03 /* type */, 0x01/* code */, ip_hdr );
					/* Note: Not looking at rt_table for mac, just reusing mac->IP from existing queued packet */
					prepare_ipv4_hdr((sr_ip_hdr_t*)(buf+sizeof(sr_ethernet_hdr_t)),0x00 /* TOS */, len-sizeof(sr_ethernet_hdr_t), 0x0000 /* ID */, IP_DF /* offset */, ip_protocol_icmp /* protocol */, ntohl(if_to_send->ip) /* source */ ,ntohl(ip_hdr->ip_src) /* destination */);
					prepare_eth_hdr((sr_ethernet_hdr_t*)buf, eth_hdr->ether_shost /* destination */, if_to_send->addr /* sender */, ethertype_ip);
					
					sr_send_packet(sr,buf,len,rt_match->interface);
				}
				req->packets = req->packets->next;
			}
			free(buf);
			fprintf(stderr,"Sent ICMP host not reachable (type 3, code 1)\n");
			sr_arpreq_destroy(&sr->cache,req);
		}
		else {
			/* Send a ARP request */
			unsigned int len = sizeof(sr_ethernet_hdr_t)+sizeof(sr_arp_hdr_t);
            uint8_t* buf = (uint8_t*)malloc(len);
			struct sr_if* if_to_send = sr_get_interface(sr,req->packets->iface);

			assert(buf);
            sr_ethernet_hdr_t* eth_hdr = (sr_ethernet_hdr_t*)buf;
            sr_arp_hdr_t* arp_req = (sr_arp_hdr_t*)(buf+sizeof(sr_ethernet_hdr_t));

            /* Prepare Ethernet Header */
            memset(eth_hdr->ether_dhost,0xff,ETHER_ADDR_LEN);
            memcpy(eth_hdr->ether_shost,if_to_send->addr,ETHER_ADDR_LEN);
            eth_hdr->ether_type = htons(ethertype_arp);

            /* Prepare ARP request */
            arp_req->ar_hrd = htons(arp_hrd_ethernet);
            arp_req->ar_pro = htons(ethertype_ip);
            arp_req->ar_hln = ETHER_ADDR_LEN;
            arp_req->ar_pln = 0x04;
            arp_req->ar_op = htons(arp_op_request);
            memcpy(arp_req->ar_sha,if_to_send->addr,ETHER_ADDR_LEN);
            arp_req->ar_sip = if_to_send->ip;
            memset(arp_req->ar_tha,0xff,ETHER_ADDR_LEN);
            arp_req->ar_tip = req->ip;
			fprintf(stderr, "Sending ARP request\n");
			sr_send_packet(sr,buf,len,if_to_send->name);
			free(buf);

			req->sent = time(NULL);
			req->times_sent++;
		}
	}
}