/** Return the {@link IpSpace} of all IPs not in {@code this}. */ public final IpSpace complement() { if (this == UniverseIpSpace.INSTANCE) { return EmptyIpSpace.INSTANCE; } if (this == EmptyIpSpace.INSTANCE) { return UniverseIpSpace.INSTANCE; } return AclIpSpace.difference(UniverseIpSpace.INSTANCE, this); }
private static IpSpaceSpecifier toIpSpaceSpecifier(IpSpace include, IpSpace exclude) { return new ConstantIpSpaceSpecifier( firstNonNull(AclIpSpace.difference(include, exclude), UniverseIpSpace.INSTANCE)); }
@VisibleForTesting IpSpace computeInsufficientInfoPerInterface( String hostname, String vrfName, String interfaceName) { // If interface is full (no missing devices), it cannot be insufficient info if (!_interfacesWithMissingDevices.get(hostname).contains(interfaceName)) { return EmptyIpSpace.INSTANCE; } IpSpace ipSpaceElsewhere = AclIpSpace.difference( _internalIps, _interfaceHostSubnetIps.get(hostname).get(vrfName).get(interfaceName)); // case 1: arp for dst ip, dst ip is internal but not in any subnet of the interface IpSpace ipSpaceInternalDstIp = AclIpSpace.intersection( _arpFalseDestIp.get(hostname).get(vrfName).get(interfaceName), ipSpaceElsewhere); // case 2: arp for nhip, nhip is not owned by interfaces, dst ip is internal IpSpace dstIpsWithUnownedNextHopIpArpFalsePerInterafce = _dstIpsWithUnownedNextHopIpArpFalse.get(hostname).get(vrfName).get(interfaceName); IpSpace ipSpaceInternalDstIpUnownedNexthopIp = AclIpSpace.intersection(dstIpsWithUnownedNextHopIpArpFalsePerInterafce, _internalIps); // case 3: arp for nhip, nhip is owned by some interfaces IpSpace ipSpaceOwnedNextHopIp = _dstIpsWithOwnedNextHopIpArpFalse.get(hostname).get(vrfName).get(interfaceName); return AclIpSpace.union( ipSpaceInternalDstIp, ipSpaceInternalDstIpUnownedNexthopIp, ipSpaceOwnedNextHopIp); }
@Override public IpSpace visitInterfaceLinkLocation(InterfaceLinkLocation interfaceLinkLocation) { String node = interfaceLinkLocation.getNodeName(); String iface = interfaceLinkLocation.getInterfaceName(); @Nullable IpSpace linkIpSpace = AclIpSpace.union( interfaceAddresses(node, iface).stream() /* * Only include addresses on networks that might have hosts. */ .filter(address -> address.getNetworkBits() <= HOST_SUBNET_MAX_PREFIX_LENGTH) .map(address -> address.getPrefix().toHostIpSpace()) .collect(Collectors.toList())); return linkIpSpace == null ? EmptyIpSpace.INSTANCE : AclIpSpace.difference(linkIpSpace, _specifierContext.getSnapshotDeviceOwnedIps()); }
@VisibleForTesting Map<String, Map<String, Map<String, IpSpace>>> computeDeliveredToSubnet() { try (ActiveSpan span = GlobalTracer.get() .buildSpan("ForwardingAnalysisImpl.computeDeliveredToSubnet") .startActive()) { assert span != null; // avoid unused warning return toImmutableMap( intersection(_arpFalseDestIp, _interfaceHostSubnetIps), Entry::getKey, nodeEntry -> toImmutableMap( nodeEntry.getValue(), Entry::getKey, vrfEntry -> toImmutableMap( vrfEntry.getValue(), Entry::getKey, ifaceEntry -> AclIpSpace.difference(ifaceEntry.getValue(), _ownedIps)))); } }