Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JunOS: Support As-Path-Group #8613

Merged
merged 4 commits into from
Dec 6, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import static org.batfish.representation.juniper.JuniperStructureUsage.APPLICATION_SET_MEMBER_APPLICATION;
import static org.batfish.representation.juniper.JuniperStructureUsage.APPLICATION_SET_MEMBER_APPLICATION_SET;
import static org.batfish.representation.juniper.JuniperStructureUsage.AS_PATH_GROUP_AS_PATH_SELF_REFERENCE;
import static org.batfish.representation.juniper.JuniperStructureUsage.AS_PATH_GROUP_SELF_REFERENCE;
import static org.batfish.representation.juniper.JuniperStructureUsage.AUTHENTICATION_KEY_CHAINS_POLICY;
import static org.batfish.representation.juniper.JuniperStructureUsage.BGP_ALLOW;
import static org.batfish.representation.juniper.JuniperStructureUsage.BGP_EXPORT_POLICY;
Expand Down Expand Up @@ -868,6 +869,7 @@
import org.batfish.representation.juniper.PolicyStatement;
import org.batfish.representation.juniper.PrefixList;
import org.batfish.representation.juniper.PsFromAsPath;
import org.batfish.representation.juniper.PsFromAsPathGroup;
import org.batfish.representation.juniper.PsFromColor;
import org.batfish.representation.juniper.PsFromCommunity;
import org.batfish.representation.juniper.PsFromCommunityCount;
Expand Down Expand Up @@ -3001,7 +3003,10 @@ public void enterPo_as_path_group(Po_as_path_groupContext ctx) {

@Override
public void exitPo_as_path_group(Po_as_path_groupContext ctx) {
_currentAsPathGroup = null;
String name = toString(ctx.name);
_configuration.referenceStructure(
AS_PATH_GROUP, name, AS_PATH_GROUP_SELF_REFERENCE, getLine(ctx.name.getStart()));
_currentAsPathGroup = null;
}

@Override
Expand Down Expand Up @@ -5504,10 +5509,9 @@ public void exitPopsf_as_path(Popsf_as_pathContext ctx) {
@Override
public void exitPopsf_as_path_group(Popsf_as_path_groupContext ctx) {
String name = toString(ctx.name);
_currentPsTerm.getFroms().addFromAsPathGroup(new PsFromAsPathGroup(name));
_configuration.referenceStructure(
AS_PATH_GROUP, name, POLICY_STATEMENT_FROM_AS_PATH_GROUP, getLine(ctx.getStart()));
_currentPsTerm.getFroms().setFromUnsupported(new PsFromUnsupported());
todo(ctx);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.batfish.representation.juniper;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.annotation.Nonnull;
Expand All @@ -25,4 +27,10 @@ public AsPathGroup(String name) {
public @Nonnull String getName() {
return _name;
}

public @Nonnull List<String> getAsPathRegexes() {
List<String> regexes = new ArrayList<>();
_asPaths.values().forEach(asPath -> regexes.add(asPath.getRegex()));
return regexes;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3141,6 +3141,9 @@ private BooleanExpr toGuard(PsFroms froms) {
if (!froms.getFromAsPaths().isEmpty()) {
conj.getConjuncts().add(new Disjunction(toBooleanExprs(froms.getFromAsPaths())));
}
if (!froms.getFromAsPathGroups().isEmpty()) {
conj.getConjuncts().add(new Disjunction(toBooleanExprs(froms.getFromAsPathGroups())));
}
if (froms.getFromColor() != null) {
conj.getConjuncts().add(froms.getFromColor().toBooleanExpr(this, _c, _w));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public enum JuniperStructureUsage implements StructureUsage {
AGGREGATE_ROUTE_POLICY("aggregate route policy"),
APPLICATION_SET_MEMBER_APPLICATION("application-set member application"),
APPLICATION_SET_MEMBER_APPLICATION_SET("application-set member application-set"),
AS_PATH_GROUP_SELF_REFERENCE("as-path-group"),
AS_PATH_GROUP_AS_PATH_SELF_REFERENCE("as-path-group as-path"),
AUTHENTICATION_KEY_CHAINS_POLICY("authentication-key-chains policy"),
BGP_ALLOW("bgp group allow"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package org.batfish.representation.juniper;

import com.google.common.annotations.VisibleForTesting;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import org.batfish.common.Warnings;
import org.batfish.datamodel.Configuration;
import org.batfish.datamodel.routing_policy.as_path.AsPathMatchRegex;
import org.batfish.datamodel.routing_policy.as_path.InputAsPath;
import org.batfish.datamodel.routing_policy.as_path.MatchAsPath;
import org.batfish.datamodel.routing_policy.expr.BooleanExpr;
import org.batfish.datamodel.routing_policy.expr.BooleanExprs;

public final class PsFromAsPathGroup extends PsFrom {
private final String _asPathGroupName;

public PsFromAsPathGroup(String asPathGroupName) {
_asPathGroupName = asPathGroupName;
}

@Override
public BooleanExpr toBooleanExpr(JuniperConfiguration jc, Configuration c, Warnings warnings) {
Map<String, AsPathGroup> asPathGroups = jc.getMasterLogicalSystem().getAsPathGroups();
return toBooleanExpr(asPathGroups.get(_asPathGroupName), warnings);
}

@VisibleForTesting
static BooleanExpr toBooleanExpr(@Nullable AsPathGroup asPathGroup, Warnings w) {
if (asPathGroup == null) {
// Undefined reference, return false.
return BooleanExprs.FALSE;
}
try {
List<String> javaRegex = new ArrayList<>();
asPathGroup
.getAsPathRegexes()
.forEach(
regex ->
javaRegex.add(
org.batfish.representation.juniper.parboiled.AsPathRegex.convertToJavaRegex(
regex)));
String ORedRegexes = String.join(" | ", javaRegex);

return MatchAsPath.of(InputAsPath.instance(), AsPathMatchRegex.of(ORedRegexes));
} catch (Exception e) {
w.redFlag(
String.format(
"Error converting Juniper as-path-group regex %s, will assume no paths match instead:"
+ " %s.",
asPathGroup.getName(), e.getMessage()));
/* Handle error, return false instead. */
return BooleanExprs.FALSE;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public final class PsFroms implements Serializable {
private boolean _atLeastOneFrom = false;

private final Set<PsFromAsPath> _fromAsPaths;
private final Set<PsFromAsPathGroup> _fromAsPathGroups;
private PsFromColor _fromColor;
private final Set<PsFromCommunity> _fromCommunities;
private PsFromCommunityCount _fromCommunityCount;
Expand All @@ -34,6 +35,7 @@ public final class PsFroms implements Serializable {

PsFroms() {
_fromAsPaths = new LinkedHashSet<>();
_fromAsPathGroups = new LinkedHashSet<>();
_fromCommunities = new LinkedHashSet<>();
_fromConditions = new LinkedHashSet<>();
_fromInterfaces = new LinkedHashSet<>();
Expand All @@ -52,6 +54,11 @@ public void addFromAsPath(@Nonnull PsFromAsPath fromAsPath) {
_fromAsPaths.add(fromAsPath);
}

public void addFromAsPathGroup(@Nonnull PsFromAsPathGroup fromAsPathGroup) {
_atLeastOneFrom = true;
_fromAsPathGroups.add(fromAsPathGroup);
}

public void addFromCommunity(@Nonnull PsFromCommunity fromCommunity) {
_atLeastOneFrom = true;
_fromCommunities.add(fromCommunity);
Expand Down Expand Up @@ -115,6 +122,11 @@ Set<PsFromAsPath> getFromAsPaths() {
return _fromAsPaths;
}

@Nonnull
Set<PsFromAsPathGroup> getFromAsPathGroups() {
return _fromAsPathGroups;
}

@VisibleForTesting
public @Nullable PsFromColor getFromColor() {
return _fromColor;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package org.batfish.representation.juniper;

import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

import com.google.common.collect.Iterables;
import org.batfish.common.Warnings;
import org.batfish.datamodel.routing_policy.as_path.MatchAsPath;
import org.batfish.datamodel.routing_policy.expr.BooleanExpr;
import org.batfish.datamodel.routing_policy.expr.BooleanExprs;
import org.junit.Test;

/** Tests of {@link PsFromAsPathGroup}. */
public class PsFromAsPathGroupTest {

@Test
public void testUndefined() {
Warnings w = new Warnings(true, true, true);
BooleanExpr ret = PsFromAsPathGroup.toBooleanExpr(null, w);
assertThat(ret, is(BooleanExprs.FALSE));
assertThat(w.getRedFlagWarnings(), empty()); // Prefer undefined reference elsewhere
}

@Test
public void testConversionError() {
AsPathGroup asPathGroup = new AsPathGroup("Group");
asPathGroup
.getAsPaths()
.put("not-aspath", new NamedAsPath("not-aspath", "this is not a valid as-path regex"));

Warnings w = new Warnings(true, true, true);
BooleanExpr ret = PsFromAsPathGroup.toBooleanExpr(asPathGroup, w);

assertThat(ret, is(BooleanExprs.FALSE));
assertThat(w.getRedFlagWarnings(), hasSize(1));
assertThat(
Iterables.getOnlyElement(w.getRedFlagWarnings()).getText(),
containsString("Error converting Juniper as-path-group regex Group"));
}

@Test
public void testConversion() {
AsPathGroup asPathGroup = new AsPathGroup("Group");
asPathGroup.getAsPaths().put("aspath1", new NamedAsPath("aspath1", "1 2"));
asPathGroup.getAsPaths().put("aspath2", new NamedAsPath("aspath2", "3 4"));

Warnings w = new Warnings(true, true, true);
BooleanExpr ret = PsFromAsPathGroup.toBooleanExpr(asPathGroup, w);

assertThat(ret, instanceOf(MatchAsPath.class));
assertThat(w.getRedFlagWarnings(), empty());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,5 @@ set policy-options policy-statement POLICY-NAME from protocol evpn
#
set policy-options as-path ORIGINATED_IN_65535 ".* 65535"
set policy-options as-path UNUSED_ORIGINATED_IN_65535 ".* 65535"
set policy-options as-path-group AS_PATH_GROUP as-path ASN714 ".* 714$"
set policy-options as-path-group AS_PATH_GROUP as-path ASN715 ".* 715$"
15 changes: 13 additions & 2 deletions tests/parsing-tests/unit-tests-unused.ref
Original file line number Diff line number Diff line change
Expand Up @@ -2888,6 +2888,17 @@
]
}
},
{
"Structure_Type" : "as-path-group",
"Structure_Name" : "AS_PATH_GROUP",
"Source_Lines" : {
"filename" : "configs/juniper_policy_statement",
"lines" : [
46,
47
]
}
},
{
"Structure_Type" : "policy-statement",
"Structure_Name" : "POLICY-NAME",
Expand Down Expand Up @@ -3772,10 +3783,10 @@
}
],
"summary" : {
"notes" : "Found 247 results",
"notes" : "Found 248 results",
"numFailed" : 0,
"numPassed" : 0,
"numResults" : 247
"numResults" : 248
}
}
]
11 changes: 2 additions & 9 deletions tests/parsing-tests/unit-tests-warnings.ref
Original file line number Diff line number Diff line change
Expand Up @@ -1358,13 +1358,6 @@
"Parser_Context" : "[oa_area_range o_area o_common p_ospf3 s_protocols s_common statement set_line_tail set_line flat_juniper_configuration]",
"Comment" : "This feature is not currently supported"
},
{
"Filename" : "configs/juniper_policy_statement",
"Line" : 4,
"Text" : "as-path-group AS_PATH_GROUP",
"Parser_Context" : "[popsf_as_path_group pops_from pops_common pops_term po_policy_statement s_policy_options s_common statement set_line_tail set_line flat_juniper_configuration]",
"Comment" : "This feature is not currently supported"
},
{
"Filename" : "configs/juniper_policy_statement",
"Line" : 18,
Expand Down Expand Up @@ -1444,10 +1437,10 @@
}
],
"summary" : {
"notes" : "Found 200 results",
"notes" : "Found 199 results",
"numFailed" : 0,
"numPassed" : 0,
"numResults" : 200
"numResults" : 199
}
}
]