/** * Constant-time constructor for AndMatchExpr. Simplifies if given zero or one conjunct. Doesn't * do other simplifications that require more work (like removing all {@link TrueExpr TrueExprs}). */ public static AclLineMatchExpr and(Iterable<AclLineMatchExpr> exprs) { Iterator<AclLineMatchExpr> iter = exprs.iterator(); if (!iter.hasNext()) { // Empty. Return the identity element return TrueExpr.INSTANCE; } AclLineMatchExpr first = iter.next(); if (!iter.hasNext()) { // Only 1 element return first; } return new AndMatchExpr(exprs); }
@Override public AclLineMatchExpr visitAndMatchExpr(AndMatchExpr andMatchExpr) throws CircularReferenceException, UndefinedReferenceException { return new AndMatchExpr( andMatchExpr.getConjuncts().stream().map(this::visit).collect(Collectors.toList())); }
@Override public AclLineMatchExpr visitAndMatchExpr(AndMatchExpr andMatchExpr) { return new AndMatchExpr( andMatchExpr.getConjuncts().stream() .map(this::visit) .collect(ImmutableSortedSet.toImmutableSortedSet(Ordering.natural()))); }
/** Merge the list of lines with the specified conjunct match expression. */ private static List<IpAccessListLine> mergeIpAccessListLines( List<IpAccessListLine> lines, @Nullable AclLineMatchExpr conjunctMatchExpr) { if (conjunctMatchExpr == null) { return lines; } else { return lines.stream() .map( l -> new IpAccessListLine( l.getAction(), new AndMatchExpr(ImmutableList.of(l.getMatchCondition(), conjunctMatchExpr)), l.getName())) .collect(ImmutableList.toImmutableList()); } }
@Override public AclLineMatchExpr visitOrMatchExpr(OrMatchExpr orMatchExpr) { return new AndMatchExpr(negate(orMatchExpr.getDisjuncts())); }
@Override public final AclLineMatchExpr visitAndMatchExpr(AndMatchExpr andMatchExpr) { List<AclLineMatchExpr> conjuncts = andMatchExpr.getConjuncts().stream() .map(expr -> expr.accept(this)) .filter(expr -> expr != TrueExpr.INSTANCE) .collect(ImmutableList.toImmutableList()); if (conjuncts.isEmpty()) { return TrueExpr.INSTANCE; } if (conjuncts.contains(FalseExpr.INSTANCE)) { return FalseExpr.INSTANCE; } return new AndMatchExpr(conjuncts); }
@Test public void testCompareToForEqualVals() { // Test equivalent expressions with both non-null and null descriptions assertThat(new AndMatchExpr(null, "x").compareTo(new AndMatchExpr(null, "x")), equalTo(0)); assertThat(new AndMatchExpr(null, null).compareTo(new AndMatchExpr(null, null)), equalTo(0)); } }
@Nullable @VisibleForTesting IpAccessList buildScreensPerZone(@Nonnull Zone zone, String aclName) { List<AclLineMatchExpr> matches = zone.getScreens().stream() .map( screenName -> { Screen screen = _masterLogicalSystem.getScreens().get(screenName); String screenAclName = ACL_NAME_SCREEN + screenName; IpAccessList screenAcl = _c.getIpAccessLists() .computeIfAbsent(screenAclName, x -> buildScreen(screen, screenAclName)); return screenAcl != null ? new PermittedByAcl(screenAcl.getName(), false) : null; }) .filter(Objects::nonNull) .collect(Collectors.toList()); return matches.isEmpty() ? null : IpAccessList.builder() .setName(aclName) .setLines(ImmutableList.of(IpAccessListLine.accepting(new AndMatchExpr(matches)))) .build(); }
return new AclLineMatchExprWithProvenance<>(conjuncts.first(), conjunctsProvenance); return new AclLineMatchExprWithProvenance<>(new AndMatchExpr(conjuncts), conjunctsProvenance);
@Test public void testSingleExpr() { // Test that if and only if the only ACL line is a match, the AndMatchExpr indicates a match // Setup simple expression with a single true boolean expr List<AclLineMatchExpr> setTrue = ImmutableList.of(TrueExpr.INSTANCE); AndMatchExpr exprTrue = new AndMatchExpr(setTrue); // Setup simple expression with a single false boolean expr List<AclLineMatchExpr> setFalse = ImmutableList.of(FalseExpr.INSTANCE); AndMatchExpr exprFalse = new AndMatchExpr(setFalse); // Confirm true boolean expr matches assertThat(exprTrue, matches(createFlow(), "")); // Confirm false boolean expr does not match assertThat(exprFalse, not(matches(createFlow(), ""))); }
@Test public void testMultipleExprs() { // Test that if and only if all ACL lines are a match, the AndMatchExpr returns a match List<AclLineMatchExpr> setTrueTrue = ImmutableList.of(TrueExpr.INSTANCE, TrueExpr.INSTANCE); AndMatchExpr exprTrueTrue = new AndMatchExpr(setTrueTrue); List<AclLineMatchExpr> setTrueFalse = ImmutableList.of(TrueExpr.INSTANCE, FalseExpr.INSTANCE); AndMatchExpr exprTrueFalse = new AndMatchExpr(setTrueFalse); List<AclLineMatchExpr> setFalseFalse = ImmutableList.of(FalseExpr.INSTANCE, FalseExpr.INSTANCE); AndMatchExpr exprFalseFalse = new AndMatchExpr(setFalseFalse); // Confirm boolean expr true AND true = true assertThat(exprTrueTrue, matches(createFlow(), "")); // Confirm boolean expr true AND false = false assertThat(exprTrueFalse, not(matches(createFlow(), ""))); // Confirm boolean expr false AND false = false assertThat(exprFalseFalse, not(matches(createFlow(), ""))); } }
switch (matchSemantics) { case MATCH_ALL: matchClassMap = new AndMatchExpr(matchConditions); break; case MATCH_ANY:
@Nullable IpAccessList buildIncomingFilter(Interface iface) { String screenAclName = ACL_NAME_SCREEN_INTERFACE + iface.getName(); IpAccessList screenAcl = _c.getIpAccessLists().computeIfAbsent(screenAclName, x -> buildScreensPerInterface(iface)); // merge screen options to incoming filter // but keep both originial filters in the config, so we can run search filter queris on them String inAclName = iface.getIncomingFilter(); IpAccessList inAcl = inAclName != null ? _c.getIpAccessLists().get(inAclName) : null; Set<AclLineMatchExpr> aclConjunctList; if (screenAcl == null) { return inAcl; } else if (inAcl == null) { aclConjunctList = ImmutableSet.of(new PermittedByAcl(screenAcl.getName(), false)); } else { aclConjunctList = ImmutableSet.of( new PermittedByAcl(screenAcl.getName(), false), new PermittedByAcl(inAclName, false)); } String combinedAclName = ACL_NAME_COMBINED_INCOMING + iface.getName(); IpAccessList combinedAcl = IpAccessList.builder() .setName(combinedAclName) .setLines( ImmutableList.of(IpAccessListLine.accepting(new AndMatchExpr(aclConjunctList)))) .build(); _c.getIpAccessLists().put(combinedAclName, combinedAcl); return combinedAcl; }
IpAccessListLine.accepting() .setMatchCondition( new AndMatchExpr( ImmutableList.of(matchSrcZoneInterface, permittedByPolicyMap))) .setName(
.setMatchCondition(new AndMatchExpr(conjuncts)) .build();
IpAccessListLine.accepting() .setMatchCondition( new AndMatchExpr(ImmutableList.of(new PermittedByAcl("acl0")))) .build())) .setName("acl1")
ImmutableList.of( IpAccessListLine.accepting() .setMatchCondition(new AndMatchExpr(ImmutableList.of(ipSpaceReference))) .build())) .setName("acl1") equalTo( ImmutableSet.of( new AndMatchExpr(ImmutableList.of(dereferencedIpSpace)), new OrMatchExpr(ImmutableList.of(dereferencedIpSpace)), new NotMatchExpr(dereferencedIpSpace))));
IpAccessListLine.accepting() .setMatchCondition( new AndMatchExpr( ImmutableList.of(new MatchSrcInterface(ImmutableList.of("iface1"))))) .build(),
IpAccessListLine.accepting() .setMatchCondition( new AndMatchExpr( ImmutableList.of( new PermittedByAcl(aclIndirectName1),
private static IpAccessListLine toIpAccessListLine( ExtendedAccessListLine line, Map<String, ObjectGroup> objectGroups) { IpSpace srcIpSpace = line.getSourceAddressSpecifier().toIpSpace(); IpSpace dstIpSpace = line.getDestinationAddressSpecifier().toIpSpace(); AclLineMatchExpr matchService = line.getServiceSpecifier().toAclLineMatchExpr(objectGroups); AclLineMatchExpr match; if (matchService instanceof MatchHeaderSpace) { match = new MatchHeaderSpace( ((MatchHeaderSpace) matchService) .getHeaderspace() .toBuilder() .setSrcIps(srcIpSpace) .setDstIps(dstIpSpace) .build()); } else { match = new AndMatchExpr( ImmutableList.of( matchService, new MatchHeaderSpace( HeaderSpace.builder().setSrcIps(srcIpSpace).setDstIps(dstIpSpace).build()))); } return IpAccessListLine.builder() .setAction(line.getAction()) .setMatchCondition(match) .setName(line.getName()) .build(); }