OpenFastPath 学习8 (ARP协议)

在同一网段的机器A访问B的时候会发生什么事情?计算机在通讯之前必须先得到对方的MAC地址。发生上层数据时,会调用ofp_ip_output_continue函数,在调用ofp_ip_output_send发送之前,会填写本机MAC地址和目的MAC地址,由ofp_ip_output_add_eth函数实现,如下所示:

} else if (ofp_get_mac(odata->dev_out, odata->nh,     //获取目的MAC地址

             gw, is_link_local,

            eth->ether_dhost) < 0) {

             send_arp_request(odata->dev_out, gw); //发送ARP请求

            return ofp_arp_save_ipv4_pkt(pkt, odata->nh, //缓存本包

                               gw, odata->dev_out);

}

ofp_copy_mac(eth->ether_shost, odata->dev_out->mac); //填写源MAC地址

如果不能获取到目的MAC地址,将会发送一个ARP请求消息,当前数据包会进行缓存,当有对应的ARP响应过来的时候,这些包会被发出去,如下:

收包线程 ofp_eth_vlan_processing--->ofp_arp_processing--...ofp_add_mac

---->ofp_arp_ipv4_insert函数:

int ofp_arp_ipv4_insert(uint32_t ipv4_addr, unsigned char *ll_addr,

struct ofp_ifnet *dev)

{

struct pkt_entry *pktentry;

struct pkt_list send_list;

uint32_t entry_idx;

int ret_val;

ret_val = ofp_arp_ipv4_insert_entry(ipv4_addr, ll_addr, dev->vrf,

                 TRUE, &entry_idx, &send_list);

if (ret_val < 0)

             return ret_val;

/* Send queued packets */

pktentry = OFP_SLIST_FIRST(&send_list);

while (pktentry) {

         OFP_DBG("Sending saved packet %" PRIX64 " to %s",

         odp_packet_to_u64(pktentry->pkt),

         ofp_print_ip_addr(ipv4_addr));

         if (ofp_ip_output_common(pktentry->pkt, pktentry->nh, 0,

                        OFP_IPSEC_SA_INVALID) == OFP_PKT_DROP)

                odp_packet_free(pktentry->pkt);

                OFP_SLIST_REMOVE_HEAD(&send_list, next);

                pkt_entry_free(pktentry);

        pktentry = OFP_SLIST_FIRST(&send_list);

}

return 0;

}

ofp_arp_ipv4_insert_entry会返回缓存包的列表,并通过ofp_ip_output_common

把这些包发出去。

当收到的包是请求包是请求包时,会构造一个ARP相应,并回应。

你可能感兴趣的:(OpenFastPath 学习8 (ARP协议))