Beispiel #1
0
// Return true if we successfully sent an ARP request, false otherwise
bool IPv4Handler::resolveMac(SwitchState* state, IPAddressV4 dest) {
  // need to find out our own IP and MAC addresses so that we can send the
  // ARP request out. Since the request will be broadcast, there is no need to
  // worry about which port to send the packet out.

  // TODO: assume vrf 0 now
  auto routeTable = state->getRouteTables()->getRouteTableIf(RouterID(0));
  if (!routeTable) {
    throw FbossError("No routing tables found");
  }

  auto route = routeTable->getRibV4()->longestMatch(dest);
  if (!route || !route->isResolved()) {
    // No way to reach dest
    return false;
  }

  auto intfs = state->getInterfaces();
  auto nhs = route->getForwardInfo().getNexthops();
  for (auto nh : nhs) {
    auto intf = intfs->getInterfaceIf(nh.intf);
    if (intf) {
      auto source = intf->getAddressToReach(nh.nexthop)->first.asV4();
      auto target = route->isConnected() ? dest : nh.nexthop.asV4();
      if (source == target) {
        // This packet is for us.  Don't send ARP requess for our own IP.
        continue;
      }

      auto vlanID = intf->getVlanID();
      auto vlan = state->getVlans()->getVlanIf(vlanID);
      if (vlan) {
        auto entry = vlan->getArpTable()->getEntryIf(target);
        if (entry == nullptr) {
          // No entry in ARP table, send ARP request
          auto mac = intf->getMac();
          ArpHandler::sendArpRequest(sw_, vlanID, mac, source, target);

          // Notify the updater that we sent an arp request
          sw_->getNeighborUpdater()->sentArpRequest(vlanID, target);
        } else {
          VLOG(4) << "not sending arp for " << target.str() << ", "
                  << ((entry->isPending()) ? "pending " : "")
                  << "entry already exists";
        }
      }
    }
  }

  return true;
}
Beispiel #2
0
bool Interface::canReachAddress(const folly::IPAddress& dest) const {
  return getAddressToReach(dest) != getAddresses().end();
}