/** * Tests that getting a range more specific than a /32 does not crash and is empty -- or at least * does not contain the initial /32. */ @Test public void testEmptyRange() { Prefix slash32 = Prefix.parse("1.2.3.4/32"); PrefixRange empty = PrefixRange.moreSpecificThan(slash32); assertFalse(empty.includesPrefixRange(PrefixRange.fromPrefix(slash32))); } }
@JsonCreator public static PrefixRange fromString(String prefixRangeStr) { String[] parts = prefixRangeStr.split(":"); if (parts.length == 1) { return fromPrefix(Prefix.parse(parts[0])); } else if (parts.length == 2) { return new PrefixRange(Prefix.parse(parts[0]), new SubRange(parts[1])); } else { throw new BatfishException("Invalid PrefixRange string: '" + prefixRangeStr + "'"); } }
@Test public void getPrefixRangesTest() { assertThat("No ranges yet", _ps.getPrefixRanges().isEmpty(), equalTo(true)); _ps.addPrefixRange(PrefixRange.fromString("10.10.10.0/20:18-21")); Set<PrefixRange> ranges = _ps.getPrefixRanges(); assertThat(ranges.contains(PrefixRange.fromString("10.10.0.0/18")), equalTo(true)); assertThat(ranges.contains(PrefixRange.fromString("10.10.0.0/19")), equalTo(true)); assertThat(ranges.contains(PrefixRange.fromString("10.10.10.0/20:18-21")), equalTo(true)); assertThat(ranges.size(), equalTo(3)); _ps.addPrefixRange((PrefixRange.fromString("10.10.10.0/20:20-22"))); ranges = _ps.getPrefixRanges(); assertThat(ranges.contains(PrefixRange.fromString("10.10.10.0/20:20-22")), equalTo(true)); }
public RouteFilterLine(LineAction action, PrefixRange prefixRange) { this(action, new IpWildcard(prefixRange.getPrefix()), prefixRange.getLengthRange()); }
public void addPrefixRange(PrefixRange prefixRange) { Prefix prefix = prefixRange.getPrefix(); BitSet bits = getAddressBits(prefix.getStartIp()); // The minimum length of the range may be shorter than the actual prefix length. // If so, we need to specially handle all shorter prefixes with a custom address and bitset. int minLength = prefixRange.getLengthRange().getStart(); int maxLength = Math.min(prefixRange.getLengthRange().getEnd(), prefix.getPrefixLength() - 1); for (int currentLength = minLength; currentLength <= maxLength; currentLength++) { Prefix currentPrefix = Prefix.create(prefix.getStartIp(), currentLength); PrefixRange currentPrefixRange = PrefixRange.fromPrefix(currentPrefix); BitSet currentBits = getAddressBits(currentPrefix.getStartIp()); _root.addPrefixRange(currentPrefixRange, currentBits, currentLength, 0); } // Otherwise, add the prefix range as-is. _root.addPrefixRange(prefixRange, bits, prefix.getPrefixLength(), 0); }
/** * Adds the given {@link Prefix} to this {@link PrefixSpace}. * * @param prefix Prefix to add */ public void addPrefix(Prefix prefix) { addPrefixRange(PrefixRange.fromPrefix(prefix)); }
/** Returns a {@link PrefixRange} that represents all more specific prefixes. */ public static PrefixRange moreSpecificThan(Prefix prefix) { return new PrefixRange( prefix, new SubRange(prefix.getPrefixLength() + 1, Prefix.MAX_PREFIX_LENGTH)); }
@Test public void testToString() { PrefixRange pr = PrefixRange.fromString("1.2.3.4/8:17-19"); assertThat(pr.toString(), equalTo("1.0.0.0/8:17-19")); }
@Override public void applyTo(RouteFilterList rfl) { int prefixLength = _prefix.getPrefixLength(); if (prefixLength >= 32) { throw new BatfishException("Route filter prefix length cannot be 'longer' than 32"); } org.batfish.datamodel.RouteFilterLine line = new org.batfish.datamodel.RouteFilterLine( LineAction.PERMIT, PrefixRange.moreSpecificThan(_prefix)); rfl.addLine(line); }
public boolean containsPrefixRange(PrefixRange prefixRange) { Prefix prefix = prefixRange.getPrefix(); int prefixLength = prefix.getPrefixLength(); BitSet bits = getAddressBits(prefix.getStartIp()); return _root.containsPrefixRange(prefixRange, bits, prefixLength, 0); }
public boolean containsPrefixRange( PrefixRange prefixRange, BitSet bits, int prefixLength, int depth) { for (PrefixRange nodeRange : _prefixRanges) { if (nodeRange.includesPrefixRange(prefixRange)) { return true; } } if (prefixLength == depth) { return false; } else { boolean currentBit = bits.get(depth); if (currentBit) { if (_right == null) { return false; } else { return _right.containsPrefixRange(prefixRange, bits, prefixLength, depth + 1); } } else { if (_left == null) { return false; } else { return _left.containsPrefixRange(prefixRange, bits, prefixLength, depth + 1); } } } }
public boolean includesPrefixRange(PrefixRange argPrefixRange) { Prefix prefix = getPrefix(); SubRange lengthRange = getLengthRange(); int prefixLength = prefix.getPrefixLength(); long maskedPrefixAsLong = prefix.getStartIp().getNetworkAddress(prefixLength).asLong(); Prefix argPrefix = argPrefixRange.getPrefix(); SubRange argLengthRange = argPrefixRange.getLengthRange(); long argMaskedPrefixAsLong = argPrefix.getStartIp().getNetworkAddress(prefixLength).asLong(); return maskedPrefixAsLong == argMaskedPrefixAsLong && lengthRange.getStart() <= argLengthRange.getStart() && lengthRange.getEnd() >= argLengthRange.getEnd(); }
public boolean containsPrefix(Prefix prefix) { @Nullable Boolean result = _cache.get(prefix); if (result != null) { return result; } else { boolean contained = containsPrefixRange(PrefixRange.fromPrefix(prefix)); _cache.put(prefix, contained); return contained; } }
/** Returns a {@link PrefixRange} that contains exactly the specified {@link Prefix}. */ public static PrefixRange fromPrefix(Prefix prefix) { int prefixLength = prefix.getPrefixLength(); return new PrefixRange(prefix, new SubRange(prefixLength, prefixLength)); }
p -> matchLonger.addLine( new RouteFilterLine(LineAction.PERMIT, PrefixRange.moreSpecificThan(p))));
private BDD matchPrefixSet( TransferParam<BDDRoute> p, Configuration conf, PrefixSetExpr e, BDDRoute other) { if (e instanceof ExplicitPrefixSet) { ExplicitPrefixSet x = (ExplicitPrefixSet) e; Set<PrefixRange> ranges = x.getPrefixSpace().getPrefixRanges(); if (ranges.isEmpty()) { p.debug("empty"); return factory.one(); } BDD acc = factory.zero(); for (PrefixRange range : ranges) { p.debug("Prefix Range: " + range); if (!PrefixUtils.isContainedBy(range.getPrefix(), _ignoredNetworks)) { acc = acc.or(isRelevantFor(other, range)); } } return acc; } else if (e instanceof NamedPrefixSet) { NamedPrefixSet x = (NamedPrefixSet) e; p.debug("Named: " + x.getName()); String name = x.getName(); RouteFilterList fl = conf.getRouteFilterLists().get(name); return matchFilterList(p, fl, other); } else { throw new BatfishException("TODO: match prefix set: " + e); } }
private void prune(PrefixRange prefixRange) { if (_left != null) { _left.prune(prefixRange); if (_left.isEmpty()) { _left = null; } } if (_right != null) { _right.prune(prefixRange); if (_right.isEmpty()) { _right = null; } } if (_prefixRanges.stream().anyMatch(prefixRange::includesPrefixRange)) { _prefixRanges = _prefixRanges.stream() .filter(pr -> !prefixRange.includesPrefixRange(pr)) .collect(ImmutableSet.toImmutableSet()); } } }
private BDD isRelevantFor(BDDRoute record, PrefixRange range) { Prefix p = range.getPrefix(); SubRange r = range.getLengthRange(); int len = p.getPrefixLength(); int lower = r.getStart(); int upper = r.getEnd(); BDD lowerBitsMatch = firstBitsEqual(record.getPrefix().getBitvec(), p, len); BDD acc = factory.zero(); if (lower == 0 && upper == 32) { acc = factory.one(); } else { for (int i = lower; i <= upper; i++) { BDD equalLen = record.getPrefixLength().value(i); acc = acc.or(equalLen); } } return acc.and(lowerBitsMatch); }
/** * For each static route in the given {@link RoutingInstance} that has at least one community set, * creates an {@link If} that matches that route (specifically, matches static routes with that * route's destination network), and sets communities for matching exported routes. */ @Nonnull private static List<If> getStaticRouteCommunitySetters(@Nonnull RoutingInstance ri) { MatchProtocol matchStatic = new MatchProtocol(RoutingProtocol.STATIC); return ri.getRibs().get(RoutingInformationBase.RIB_IPV4_UNICAST).getStaticRoutes().values() .stream() .filter(route -> !route.getCommunities().isEmpty()) .map( route -> { // Create matcher that matches routes that share this route's destination network PrefixExpr destNetworkMatcher = DestinationNetwork.instance(); PrefixSetExpr destNetwork = new ExplicitPrefixSet(new PrefixSpace(PrefixRange.fromPrefix(route.getPrefix()))); MatchPrefixSet networkMatcher = new MatchPrefixSet(destNetworkMatcher, destNetwork); // When a matching static route is exported, set its communities return new If( new Conjunction(ImmutableList.of(matchStatic, networkMatcher)), ImmutableList.of( new SetCommunity(new LiteralCommunitySet(route.getCommunities())))); }) .collect(ImmutableList.toImmutableList()); }
@Test public void testDeSerialization() throws IOException { PrefixRange pr = PrefixRange.fromString("1.2.3.4/8:17-19"); assertThat( BatfishObjectMapper.mapper().readValue("\"1.0.0.0/8:17-19\"", PrefixRange.class), equalTo(pr)); }