19 boost::asio::io_context &io)
20 :
ProtoHandler(agent, info, io), arp_(NULL), arp_tpa_(0) {
32 assert(
agent()->GetArpProto());
35 if (
agent()->GetArpProto()->ip_fabric_interface() == NULL) {
55 arp_cmd = ARPOP_REQUEST;
58 if ((ntohs(
arp_->ea_hdr.ar_hrd) != ARPHRD_ETHER) ||
59 (ntohs(
arp_->ea_hdr.ar_pro) != ETHERTYPE_IP) ||
60 (
arp_->ea_hdr.ar_hln != ETHER_ADDR_LEN) ||
63 ARP_TRACE(Error,
"Received Invalid ARP packet");
66 arp_cmd = ntohs(
arp_->ea_hdr.ar_op);
68 uint8_t data[
sizeof(in_addr_t)];
71 memcpy(bytes.data,
arp_->arp_tpa,
sizeof(in_addr_t));
72 in_addr_t tpa = ntohl(bytes.addr);
73 memcpy(bytes.data,
arp_->arp_spa,
sizeof(in_addr_t));
74 in_addr_t spa = ntohl(bytes.addr);
75 if (arp_cmd == ARPOP_REQUEST)
86 if (tpa == spa || spa == 0) {
91 ARP_TRACE(Error,
"ARP : Received Invalid packet");
99 ARP_TRACE(Error,
"Received ARP packet from invalid / inactive interface");
107 " has no / inactive VRF ");
111 if (!nh_vrf || !nh_vrf->
IsActive()) {
114 " has no / inactive VRF");
122 ARP_TRACE(Error,
"ARP : ignoring broadcast address" +
123 arp_addr.to_string());
130 GetInet4UnicastRouteTable())->FindLPM(arp_addr);
135 ARP_TRACE(Error,
"ARP : ignoring multicast address" +
136 arp_addr.to_string());
141 ARP_TRACE(Error,
"ARP : no active nexthop" +
142 arp_addr.to_string());
161 case ARPOP_REQUEST: {
184 memcpy(&ip,
arp_->arp_spa,
sizeof(ip));
223 memcpy(&ip,
arp_->arp_spa,
sizeof(ip));
241 ARP_TRACE(Error,
"Received Invalid ARP command : " +
277 bool key_valid =
false;
280 if (key_valid && !ipc->
interface_->IsDeleted()) {
282 ArpProto::ArpEntrySet::iterator sit = it->second.begin();
283 for (; sit != it->second.end(); sit++) {
288 if (sit == it->second.end()) {
291 it->second.insert(entry);
336 ARP_TRACE(Error,
"Received Invalid internal ARP message : " +
354 const MacAddress &tmac, in_addr_t tip, uint16_t op) {
355 arp_->ea_hdr.ar_hrd = htons(ARPHRD_ETHER);
356 arp_->ea_hdr.ar_pro = htons(0x800);
357 arp_->ea_hdr.ar_hln = ETHER_ADDR_LEN;
359 arp_->ea_hdr.ar_op = htons(op);
362 memcpy(
arp_->arp_spa, &sip,
sizeof(in_addr_t));
365 memcpy(
arp_->arp_tpa, &tip,
sizeof(in_addr_t));
366 return sizeof(ether_arp);
371 in_addr_t tip, uint32_t itf, uint32_t vrf) {
373 if (
pkt_info_->packet_buffer() == NULL) {
378 char *buf = (
char *)
pkt_info_->packet_buffer()->data();
379 memset(buf, 0,
pkt_info_->packet_buffer()->data_len());
380 pkt_info_->eth = (
struct ether_header *)buf;
382 itf, smac, dmac, ETHERTYPE_ARP);
386 ArpHdr(smac, sip, tmac, tip, op);
387 pkt_info_->set_len(l2_len +
sizeof(ether_arp));
399 GetMacIpLearningTable()->GetPairedMacAddress(
406 mac = vm_interface->
vm_mac();
412 data->
ip().to_v4().to_ulong(), vm_interface->
id(), data->
vrf_id());
415 if (!tpa.is_unspecified()) {
416 SendArp(ARPOP_REQUEST, smac, service_ip.to_ulong(),
418 tpa.to_ulong(), vm_interface->
id(), data->
vrf_id());
425 uint32_t num_addresses = pow(2, diff_plen);
427 if (num_addresses > max_addresses) {
428 num_addresses = max_addresses;
441 uint32_t base_addr = data->
ip().to_v4().to_ulong();
442 for (uint32_t i = 1; i < num_addresses; ++i) {
443 uint32_t addr = base_addr + i;
444 SendArp(ARPOP_REQUEST, smac, service_ip.to_ulong(),
446 addr, vm_interface->
id(), data->
vrf_id());
455 return pow(2, diff_plen);
463 if (p->
refcount_.fetch_and_decrement() == 1) {
void EntryDelete(ArpKey &key)
int intrusive_ptr_add_ref(const AsPath *cpath)
const MacAddress & vm_mac() const
void HandleArpReply(const MacAddress &)
bool ToArray(u_int8_t *p, size_t s) const
const uint32_t id() const
bool AddArpEntry(ArpEntry *entry)
MacLearningProto * mac_learning_proto() const
bool is_multicast() const
void IncrementStatsArpReply(uint32_t idx)
InterfaceTable * interface_table() const
static const uint8_t kMaxV4PrefixLen
void IncrementStatsArpReq()
const string & GetName() const
IpAddress GetServiceIp(const IpAddress &ip) const
ArpProto * GetArpProto() const
uint16_t min_aap_prefix_len() const
Base class for all Route entries in agent.
boost::shared_ptr< PktInfo > pkt_info_
void SendArpRequestByPlen(const VmInterface *vm_interface, const MacAddress &smac, const ArpPathPreferenceState *data, const Ip4Address &tpa)
uint16_t ArpHdr(const MacAddress &smac, in_addr_t sip, const MacAddress &tmac, in_addr_t tip, uint16_t op)
uint32_t MaxArpProbeAddresses() const
tbb::atomic< uint32_t > refcount_
const std::string & fabric_vrf_name() const
void IncrementStatsInvalidPackets()
int EthHdr(const MacAddress &src, const MacAddress &dest, const uint16_t proto)
VrfEntry * FindVrfFromId(size_t index)
std::map< ArpKey, ArpEntrySet >::iterator GratuitousArpIterator
static const std::string integerToString(const NumberType &num)
uint32_t GetInterfaceIndex() const
PathPreferenceModule * route_preference_module() const
void IncrementStatsIPFabricNotInst()
const NextHop * GetActiveNextHop() const
void Send(uint32_t itf, uint32_t vrf, uint16_t, PktHandler::PktModuleName)
bool DeleteArpEntry(ArpEntry *entry)
boost::asio::io_context & io_
InterfaceConstRef interface_
ArpEntry * FindArpEntry(const ArpKey &key)
MacAddress mac(void) const
static const MacAddress & BroadcastMac()
ArpHandler(Agent *agent, boost::shared_ptr< PktInfo > info, boost::asio::io_context &io)
AgentParam * params() const
const Interface * get_interface() const
const uint32_t vrf_id() const
boost::asio::ip::address_v4 Ip4Address
void IncrementStatsGratuitous()
VrfTable * vrf_table() const
void DeleteGratuitousArpEntry(ArpEntry *entry)
static const uint16_t kGratRetries
#define ARP_TRACE(obj,...)
void IncrementStatsInvalidInterface()
const IpAddress & ip() const
void IncrementStatsArpReplies()
void IncrementStatsInvalidVrf()
const Interface * FindInterface(size_t index) const
VrfEntry * forwarding_vrf() const
void intrusive_ptr_release(const AsPath *cpath)
void IncrementStatsArpRequest(uint32_t idx)
const std::string & name() const
const Interface * get_interface() const
void SendArp(uint16_t op, const MacAddress &smac, in_addr_t sip, const MacAddress &tmac, const MacAddress &dmac, in_addr_t tip, uint32_t itf, uint32_t vrf)
ArpProto::GratuitousArpIterator GratuitousArpEntryIterator(const ArpKey &key, bool *key_valid)
bool MatchAapIp(const IpAddress &ip, uint8_t plen) const
ArpEntry * GratuitousArpEntry(const ArpKey &key, const Interface *intf)
void HandlePathPreferenceArpReply(const VrfEntry *vrf, uint32_t itf, Ip4Address sip)
void IncrementStatsVmArpReq()
void IncrementStatsInvalidAddress()