在同一网段的机器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相应,并回应。