public void addDstIp(IpSpace dstIp) { _dstIps = AclIpSpace.union(_dstIps, dstIp); }
public static AclIpSpace of(Iterable<AclIpSpaceLine> lines) { Builder builder = builder(); lines.forEach(builder::then); return builder.build(); }
@Override protected List<AclIpSpaceLine> featureValueOf(AclIpSpace actual) { return actual.getLines(); } }
@VisibleForTesting IpSpace computeExitsNetworkPerInterface(String hostname, String vrfName, String interfaceName) { // the connected subnet is full if (!_interfacesWithMissingDevices.get(hostname).contains(interfaceName)) { return EmptyIpSpace.INSTANCE; } IpSpace dstIpsWithUnownedNextHopIpArpFalsePerInterface = _dstIpsWithUnownedNextHopIpArpFalse.get(hostname).get(vrfName).get(interfaceName); // Returns the union of the following 2 cases: // 1. Arp for dst ip and dst ip is external // 2. Arp for next hop ip, next hop ip is not owned by any interfaces, and dst ip is external return AclIpSpace.intersection( // dest ip is external _externalIps, // arp for dst Ip OR arp for external next-hop IP AclIpSpace.union( _arpFalseDestIp.get(hostname).get(vrfName).get(interfaceName), dstIpsWithUnownedNextHopIpArpFalsePerInterface)); }
@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 visitAclIpSpace(AclIpSpace aclIpSpace) { /* Just specialize the IpSpace of each acl line. */ List<AclIpSpaceLine> specializedLines = aclIpSpace.getLines().stream() .map(line -> line.toBuilder().setIpSpace(visit(line.getIpSpace())).build()) .filter(line -> line.getIpSpace() != EmptyIpSpace.INSTANCE) .collect(ImmutableList.toImmutableList()); if (specializedLines.isEmpty()) { return EmptyIpSpace.INSTANCE; } if (specializedLines.stream() .allMatch(aclIpSpaceLine -> aclIpSpaceLine.getAction() == LineAction.DENY)) { return EmptyIpSpace.INSTANCE; } return AclIpSpace.of(specializedLines); }
@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()); }
public static AclIpSpace of(AclIpSpaceLine... lines) { return of(Arrays.asList(lines)); }
/** Set-theoretic intersection of multiple IpSpaces */ public static @Nullable IpSpace intersection(Iterable<IpSpace> ipSpaces) { return intersection(ipSpaces.spliterator()); }
ImmutableMap.of( P1, AclIpSpace.rejecting( Prefix.create(P1.getEndIp(), Prefix.MAX_PREFIX_LENGTH) .toIpSpace()) ImmutableMap.of( i2.getName(), AclIpSpace.permitting(i2Ip.toIpSpace()) .thenPermitting(P1.getEndIp().toIpSpace()) .build()));
/** 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); }
@VisibleForTesting IpSpace computeInterfaceArpReplies( Interface iface, IpSpace routableIpsForThisVrf, IpSpace ipsRoutedThroughInterface) { IpSpace ipsAssignedToThisInterface = computeIpsAssignedToThisInterface(iface); if (ipsAssignedToThisInterface == EmptyIpSpace.INSTANCE) { // if no IPs are assigned to this interface, it replies to no ARP requests. return EmptyIpSpace.INSTANCE; } /* Accept IPs assigned to this interface */ AclIpSpace.Builder interfaceArpReplies = AclIpSpace.permitting(ipsAssignedToThisInterface); if (iface.getProxyArp()) { /* Reject IPs routed through this interface */ interfaceArpReplies.thenRejecting(ipsRoutedThroughInterface); /* Accept all other routable IPs */ interfaceArpReplies.thenPermitting(routableIpsForThisVrf); } return interfaceArpReplies.build(); }
computeRouteMatchConditions( routes, vrfMatchingIps); return AclIpSpace.rejecting(someoneReplies) .thenPermitting(ipsRoutedOutInterface) .build();
/** * @param aclIpSpace The {@link AclIpSpace} to dereference * @return An {@link AclIpSpace} identical to the original but with all uses of {@link * IpSpaceReference} replaced with the dereferenced {@link IpSpace} they represent * @throws CircularReferenceException if original {@link AclIpSpace} points to a cyclical * reference. * @throws UndefinedReferenceException if original {@link AclIpSpace} points to an undefined * reference. */ @Override public IpSpace visitAclIpSpace(AclIpSpace aclIpSpace) throws CircularReferenceException, UndefinedReferenceException { AclIpSpace.Builder sanitizedSpace = AclIpSpace.builder(); for (AclIpSpaceLine line : aclIpSpace.getLines()) { IpSpace ipSpace = line.getIpSpace().accept(this); sanitizedSpace.thenAction(line.getAction(), ipSpace); } // No cycles/undefined references in this AclIpSpace. Return reference-free version. return sanitizedSpace.build(); }
public static Optional<HeaderSpace> intersect(HeaderSpace h1, HeaderSpace h2) { checkArgument(isUnconstrained(h1.getSrcOrDstIps())); checkArgument(isUnconstrained(h2.getSrcOrDstIps())); checkArgument(isUnconstrained(h1.getSrcOrDstPorts())); checkArgument(isUnconstrained(h2.getSrcOrDstPorts())); checkArgument(isUnconstrained(h1.getSrcOrDstProtocols())); checkArgument(isUnconstrained(h2.getSrcOrDstProtocols())); try { return Optional.of( HeaderSpace.builder() .setDscps(intersectSimpleSets(h1.getDscps(), h2.getDscps())) .setDstIps(intersection(h1.getDstIps(), h2.getDstIps())) .setDstPorts(intersectSubRangeSets(h1.getDstPorts(), h2.getDstPorts())) .setDstProtocols(intersectSimpleSets(h1.getDstProtocols(), h2.getDstProtocols())) .setIpProtocols(intersectSimpleSets(h1.getIpProtocols(), h2.getIpProtocols())) .setIcmpCodes(intersectSubRangeSets(h1.getIcmpCodes(), h2.getIcmpCodes())) .setIcmpTypes(intersectSubRangeSets(h1.getIcmpTypes(), h2.getIcmpTypes())) .setNotDstIps(AclIpSpace.union(h1.getNotDstIps(), h2.getNotDstIps())) .setNotDstPorts(Sets.union(h1.getNotDstPorts(), h2.getNotDstPorts())) .setNotSrcIps(AclIpSpace.union(h1.getNotSrcIps(), h2.getNotSrcIps())) .setNotSrcPorts(Sets.union(h1.getNotSrcPorts(), h2.getNotSrcPorts())) .setSrcIps(AclIpSpace.intersection(h1.getSrcIps(), h2.getSrcIps())) .setSrcOrDstPorts(intersectSubRangeSets(h1.getSrcOrDstPorts(), h2.getSrcOrDstPorts())) .setSrcPorts(intersectSubRangeSets(h1.getSrcPorts(), h2.getSrcPorts())) .setTcpFlags(intersectTcpFlagMatchConditions(h1.getTcpFlags(), h2.getTcpFlags())) .build()); } catch (NoIntersection e) { return Optional.empty(); } }
@Test public void testVisitAclIpSpace() { IpSpace lineIpSpace = UniverseIpSpace.INSTANCE; String lineIpSpaceName = "lineIpSpace"; IpSpaceMetadata lineIpSpaceMetadata = new IpSpaceMetadata("line_space_name", "line_space_type"); IpSpace ipSpace = AclIpSpace.of(AclIpSpaceLine.permit(lineIpSpace)); IpSpaceDescriber describerWithMetadata = new IpSpaceDescriber( new AclTracer( _flow, null, ImmutableMap.of(), ImmutableMap.of(TEST_NAME, ipSpace), ImmutableMap.of(TEST_NAME, TEST_METADATA))); IpSpaceDescriber describerWithLineMetadata = new IpSpaceDescriber( new AclTracer( _flow, null, ImmutableMap.of(), ImmutableMap.of(lineIpSpaceName, lineIpSpace), ImmutableMap.of(lineIpSpaceName, lineIpSpaceMetadata))); assertThat(ipSpace.accept(_describerNoNamesNorMetadata), equalTo("[0: universe]")); assertThat( ipSpace.accept(describerWithLineMetadata), equalTo("[0: 'line_space_type' named 'line_space_name']")); assertThat(ipSpace.accept(describerWithMetadata), equalTo(TEST_METADATA_DESCRIPTION)); }
/** Set-theoretic intersection of multiple IpSpaces */ public static @Nullable IpSpace intersection(IpSpace... ipSpaces) { return intersection(Arrays.spliterator(ipSpaces)); }
private static IpSpaceSpecifier toIpSpaceSpecifier(IpSpace include, IpSpace exclude) { return new ConstantIpSpaceSpecifier( firstNonNull(AclIpSpace.difference(include, exclude), UniverseIpSpace.INSTANCE)); }