package org.batfish.question; import java.util.Collections; import java.util.TreeSet; import org.batfish.common.Answerer; import org.batfish.common.plugin.IBatfish; import org.batfish.datamodel.IpAccessList; import org.batfish.datamodel.answers.AnswerElement; import org.batfish.datamodel.collections.NamedStructureEquivalenceSets; import org.batfish.datamodel.questions.Question; import org.batfish.question.CompareSameNameQuestionPlugin.CompareSameNameAnswerElement; import org.batfish.question.CompareSameNameQuestionPlugin.CompareSameNameAnswerer; import org.batfish.question.CompareSameNameQuestionPlugin.CompareSameNameQuestion; import com.fasterxml.jackson.annotation.JsonProperty; public class AclReachabilityQuestionPlugin extends QuestionPlugin { public static class AclReachabilityAnswerer extends Answerer { public AclReachabilityAnswerer(Question question, IBatfish batfish) { super(question, batfish); } @Override public AnswerElement answer() { AclReachabilityQuestion question = (AclReachabilityQuestion) _question; // get comparesamename results for acls CompareSameNameQuestion csnQuestion = new CompareSameNameQuestion(); csnQuestion.setNodeRegex(question.getNodeRegex()); csnQuestion.setNamedStructTypes(new TreeSet<>( Collections.singleton(IpAccessList.class.getSimpleName()))); csnQuestion.setSingletons(true); CompareSameNameAnswerer csnAnswerer = new CompareSameNameAnswerer( csnQuestion, _batfish); CompareSameNameAnswerElement csnAnswer = csnAnswerer.answer(); NamedStructureEquivalenceSets<?> aclEqSets = csnAnswer .getEquivalenceSets().get(IpAccessList.class.getSimpleName()); return _batfish.answerAclReachability(question.getAclNameRegex(), aclEqSets); } } // <question_page_comment> /** * Identifies unreachable lines in ACLs. * <p> * Report ACLs with unreachable lines, as well as reachability of each line * within the ACL. Unreachable lines can indicate erroneous configuration. * * @type AclReachability onefile * * @param aclNameRegex * Regular expression for names of the ACLs to analyze. Default * value is '.*' (i.e., all ACLs). * * @param nodeRegex * Regular expression for names of nodes to include. Default value * is '.*' (all nodes). * * @example bf_answer("AclReachability", aclNameRegex='OUTSIDE_TO_INSIDE.*') * Analyzes only ACLs whose names start with 'OUTSIDE_TO_INSIDE'. */ public static class AclReachabilityQuestion extends Question { private static final String ACL_NAME_REGEX_VAR = "aclNameRegex"; private static final String NODE_REGEX_VAR = "nodeRegex"; private String _aclNameRegex; private String _nodeRegex; public AclReachabilityQuestion() { _nodeRegex = ".*"; _aclNameRegex = ".*"; } @JsonProperty(ACL_NAME_REGEX_VAR) public String getAclNameRegex() { return _aclNameRegex; } @Override public boolean getDataPlane() { return false; } @Override public String getName() { return "aclreachability"; } @JsonProperty(NODE_REGEX_VAR) public String getNodeRegex() { return _nodeRegex; } @Override public boolean getTraffic() { return false; } @Override public String prettyPrint() { String retString = String.format("%s %s%s=\"%s\" %s=\"%s\"", getName(), prettyPrintBase(), ACL_NAME_REGEX_VAR, _aclNameRegex, NODE_REGEX_VAR, _nodeRegex); return retString; } @JsonProperty(ACL_NAME_REGEX_VAR) public void setAclNameRegex(String regex) { _aclNameRegex = regex; } @JsonProperty(NODE_REGEX_VAR) public void setNodeRegex(String regex) { _nodeRegex = regex; } } @Override protected Answerer createAnswerer(Question question, IBatfish batfish) { return new AclReachabilityAnswerer(question, batfish); } @Override protected Question createQuestion() { return new AclReachabilityQuestion(); } }