use of org.batfish.datamodel.BgpNeighbor in project batfish by batfish.
the class BatfishCompressor method internalRegex.
private String internalRegex() {
StringBuilder matchInternal = new StringBuilder("(,|\\\\{|\\\\}|^|\\$| )(");
Collection<BgpNeighbor> neighbors = _graph.getEbgpNeighbors().values();
Set<Integer> allAsns = new HashSet<>();
for (BgpNeighbor n : neighbors) {
Integer asn = n.getLocalAs();
allAsns.add(asn);
}
int i = 0;
for (Integer asn : allAsns) {
i++;
matchInternal.append(asn);
if (i < allAsns.size()) {
matchInternal.append("|");
}
}
matchInternal.append(")$");
return matchInternal.toString();
}
use of org.batfish.datamodel.BgpNeighbor in project batfish by batfish.
the class JuniperConfiguration method createBgpProcess.
private BgpProcess createBgpProcess(RoutingInstance routingInstance) {
initDefaultBgpExportPolicy();
initDefaultBgpImportPolicy();
String vrfName = routingInstance.getName();
Vrf vrf = _c.getVrfs().get(vrfName);
BgpProcess proc = new BgpProcess();
Ip routerId = routingInstance.getRouterId();
if (routerId == null) {
routerId = _defaultRoutingInstance.getRouterId();
if (routerId == null) {
routerId = Ip.ZERO;
}
}
proc.setRouterId(routerId);
BgpGroup mg = routingInstance.getMasterBgpGroup();
boolean multipathEbgp = false;
boolean multipathIbgp = false;
boolean multipathMultipleAs = false;
boolean multipathEbgpSet = false;
boolean multipathIbgpSet = false;
boolean multipathMultipleAsSet = false;
if (mg.getLocalAs() == null) {
Integer routingInstanceAs = routingInstance.getAs();
if (routingInstanceAs == null) {
routingInstanceAs = _defaultRoutingInstance.getAs();
}
if (routingInstanceAs == null) {
_w.redFlag("BGP BROKEN FOR THIS ROUTER: Cannot determine local autonomous system");
} else {
mg.setLocalAs(routingInstanceAs);
}
}
// Set default authentication algorithm if missing
if (mg.getAuthenticationAlgorithm() == null) {
mg.setAuthenticationAlgorithm(DEFAULT_BGP_AUTHENTICATION_ALGORITHM);
}
for (IpBgpGroup ig : routingInstance.getIpBgpGroups().values()) {
ig.cascadeInheritance();
}
_unreferencedBgpGroups = new TreeMap<>();
int fakeIpCounter = 0;
for (Entry<String, NamedBgpGroup> e : routingInstance.getNamedBgpGroups().entrySet()) {
fakeIpCounter++;
String name = e.getKey();
NamedBgpGroup group = e.getValue();
if (!group.getIpv6() && !group.getInherited()) {
_unreferencedBgpGroups.put(name, group.getDefinitionLine());
Ip fakeIp = new Ip(-1 * fakeIpCounter);
IpBgpGroup dummy = new IpBgpGroup(fakeIp);
dummy.setParent(group);
dummy.cascadeInheritance();
routingInstance.getIpBgpGroups().put(fakeIp, dummy);
}
}
for (Entry<Ip, IpBgpGroup> e : routingInstance.getIpBgpGroups().entrySet()) {
Ip ip = e.getKey();
IpBgpGroup ig = e.getValue();
BgpNeighbor neighbor = new BgpNeighbor(ip, _c);
neighbor.setVrf(vrfName);
// route reflection
Ip declaredClusterId = ig.getClusterId();
if (declaredClusterId != null) {
neighbor.setRouteReflectorClient(true);
neighbor.setClusterId(declaredClusterId.asLong());
} else {
neighbor.setClusterId(routerId.asLong());
}
// multipath multiple-as
boolean currentGroupMultipathMultipleAs = ig.getMultipathMultipleAs();
if (multipathMultipleAsSet && currentGroupMultipathMultipleAs != multipathMultipleAs) {
_w.redFlag("Currently do not support mixed multipath-multiple-as/non-multipath-multiple-as bgp" + "groups on Juniper - FORCING NON-MULTIPATH-MULTIPLE-AS");
multipathMultipleAs = false;
} else {
multipathMultipleAs = currentGroupMultipathMultipleAs;
multipathMultipleAsSet = true;
}
String authenticationKeyChainName = ig.getAuthenticationKeyChainName();
if (ig.getAuthenticationKeyChainName() != null) {
if (!_c.getAuthenticationKeyChains().containsKey(authenticationKeyChainName)) {
authenticationKeyChainName = null;
} else if (ig.getAuthenticationKey() != null) {
_w.redFlag("Both authentication-key and authentication-key-chain specified for neighbor " + ig.getRemoteAddress());
}
}
BgpAuthenticationSettings bgpAuthenticationSettings = new BgpAuthenticationSettings();
bgpAuthenticationSettings.setAuthenticationAlgorithm(ig.getAuthenticationAlgorithm());
bgpAuthenticationSettings.setAuthenticationKey(ig.getAuthenticationKey());
bgpAuthenticationSettings.setAuthenticationKeyChainName(authenticationKeyChainName);
neighbor.setAuthenticationSettings(bgpAuthenticationSettings);
Boolean ebgpMultihop = ig.getEbgpMultihop();
if (ebgpMultihop == null) {
ebgpMultihop = false;
}
neighbor.setEbgpMultihop(ebgpMultihop);
Integer loops = ig.getLoops();
boolean allowLocalAsIn = loops != null && loops > 0;
neighbor.setAllowLocalAsIn(allowLocalAsIn);
Boolean advertisePeerAs = ig.getAdvertisePeerAs();
if (advertisePeerAs == null) {
advertisePeerAs = false;
}
neighbor.setAllowRemoteAsOut(advertisePeerAs);
Boolean advertiseExternal = ig.getAdvertiseExternal();
if (advertiseExternal == null) {
advertiseExternal = false;
}
neighbor.setAdvertiseExternal(advertiseExternal);
Boolean advertiseInactive = ig.getAdvertiseInactive();
if (advertiseInactive == null) {
advertiseInactive = false;
}
neighbor.setAdvertiseInactive(advertiseInactive);
neighbor.setGroup(ig.getGroupName());
// import policies
String peerImportPolicyName = "~PEER_IMPORT_POLICY:" + ig.getRemoteAddress() + "~";
neighbor.setImportPolicy(peerImportPolicyName);
RoutingPolicy peerImportPolicy = new RoutingPolicy(peerImportPolicyName, _c);
_c.getRoutingPolicies().put(peerImportPolicyName, peerImportPolicy);
// default import policy is to accept
peerImportPolicy.getStatements().add(new SetDefaultPolicy(DEFAULT_BGP_IMPORT_POLICY_NAME));
peerImportPolicy.getStatements().add(Statements.SetDefaultActionAccept.toStaticStatement());
List<BooleanExpr> importPolicyCalls = new ArrayList<>();
ig.getImportPolicies().forEach((importPolicyName, importPolicyLine) -> {
PolicyStatement importPolicy = _policyStatements.get(importPolicyName);
if (importPolicy == null) {
undefined(JuniperStructureType.POLICY_STATEMENT, importPolicyName, JuniperStructureUsage.BGP_IMPORT_POLICY, importPolicyLine);
} else {
setPolicyStatementReferent(importPolicyName, ig.getImportPolicies(), "BGP import policy for neighbor: " + ig.getRemoteAddress());
CallExpr callPolicy = new CallExpr(importPolicyName);
importPolicyCalls.add(callPolicy);
}
});
If peerImportPolicyConditional = new If();
DisjunctionChain importPolicyChain = new DisjunctionChain(importPolicyCalls);
peerImportPolicyConditional.setGuard(importPolicyChain);
peerImportPolicy.getStatements().add(peerImportPolicyConditional);
peerImportPolicyConditional.getTrueStatements().add(Statements.ExitAccept.toStaticStatement());
peerImportPolicyConditional.getFalseStatements().add(Statements.ExitReject.toStaticStatement());
// export policies
String peerExportPolicyName = "~PEER_EXPORT_POLICY:" + ig.getRemoteAddress() + "~";
neighbor.setExportPolicy(peerExportPolicyName);
RoutingPolicy peerExportPolicy = new RoutingPolicy(peerExportPolicyName, _c);
_c.getRoutingPolicies().put(peerExportPolicyName, peerExportPolicy);
peerExportPolicy.getStatements().add(new SetDefaultPolicy(DEFAULT_BGP_EXPORT_POLICY_NAME));
/*
* For new BGP advertisements, i.e. those that are created from non-BGP
* routes, an origin code must be set. By default, Juniper sets the origin
* code to IGP.
*/
If setOriginForNonBgp = new If();
Disjunction isBgp = new Disjunction();
isBgp.getDisjuncts().add(new MatchProtocol(RoutingProtocol.BGP));
isBgp.getDisjuncts().add(new MatchProtocol(RoutingProtocol.IBGP));
setOriginForNonBgp.setGuard(isBgp);
setOriginForNonBgp.getFalseStatements().add(new SetOrigin(new LiteralOrigin(OriginType.IGP, null)));
peerExportPolicy.getStatements().add(setOriginForNonBgp);
List<BooleanExpr> exportPolicyCalls = new ArrayList<>();
ig.getExportPolicies().forEach((exportPolicyName, exportPolicyLine) -> {
PolicyStatement exportPolicy = _policyStatements.get(exportPolicyName);
if (exportPolicy == null) {
undefined(JuniperStructureType.POLICY_STATEMENT, exportPolicyName, JuniperStructureUsage.BGP_EXPORT_POLICY, exportPolicyLine);
} else {
setPolicyStatementReferent(exportPolicyName, ig.getExportPolicies(), "BGP export policy for neighbor: " + ig.getRemoteAddress());
CallExpr callPolicy = new CallExpr(exportPolicyName);
exportPolicyCalls.add(callPolicy);
}
});
If peerExportPolicyConditional = new If();
DisjunctionChain exportPolicyChain = new DisjunctionChain(exportPolicyCalls);
peerExportPolicyConditional.setGuard(exportPolicyChain);
peerExportPolicyConditional.getTrueStatements().add(Statements.ExitAccept.toStaticStatement());
peerExportPolicyConditional.getFalseStatements().add(Statements.ExitReject.toStaticStatement());
peerExportPolicy.getStatements().add(peerExportPolicyConditional);
// inherit local-as
neighbor.setLocalAs(ig.getLocalAs());
if (neighbor.getLocalAs() == null) {
_w.redFlag("Missing local-as for neighbor: " + ig.getRemoteAddress());
continue;
}
/*
* inherit peer-as, or use local-as if internal
*
* Also set multipath
*/
if (ig.getType() == BgpGroupType.INTERNAL) {
neighbor.setRemoteAs(ig.getLocalAs());
boolean currentGroupMultipathIbgp = ig.getMultipath();
if (multipathIbgpSet && currentGroupMultipathIbgp != multipathIbgp) {
_w.redFlag("Currently do not support mixed iBGP multipath/non-multipath bgp groups on Juniper " + "- FORCING NON-MULTIPATH IBGP");
multipathIbgp = false;
} else {
multipathIbgp = currentGroupMultipathIbgp;
multipathIbgpSet = true;
}
} else {
neighbor.setRemoteAs(ig.getPeerAs());
boolean currentGroupMultipathEbgp = ig.getMultipath();
if (multipathEbgpSet && currentGroupMultipathEbgp != multipathEbgp) {
_w.redFlag("Currently do not support mixed eBGP multipath/non-multipath bgp groups on Juniper " + "- FORCING NON-MULTIPATH EBGP");
multipathEbgp = false;
} else {
multipathEbgp = currentGroupMultipathEbgp;
multipathEbgpSet = true;
}
}
// TODO: implement better behavior than setting default metric to 0
neighbor.setDefaultMetric(0);
// TODO: find out if there is a juniper equivalent of cisco
// send-community
neighbor.setSendCommunity(true);
// inherit update-source
Ip localIp = ig.getLocalAddress();
if (localIp == null) {
// peer
outerloop: for (org.batfish.datamodel.Interface iface : vrf.getInterfaces().values()) {
for (InterfaceAddress address : iface.getAllAddresses()) {
if (address.getPrefix().containsIp(ip)) {
localIp = address.getIp();
break outerloop;
}
}
}
}
if (localIp == null && _defaultAddressSelection) {
initFirstLoopbackInterface();
if (_lo0 != null) {
InterfaceAddress lo0Unit0Address = _lo0.getPrimaryAddress();
if (lo0Unit0Address != null) {
localIp = lo0Unit0Address.getIp();
}
}
}
if (localIp == null && ip.valid()) {
_w.redFlag("Could not determine local ip for bgp peering with neighbor ip: " + ip);
} else {
neighbor.setLocalIp(localIp);
}
if (neighbor.getGroup() == null || !_unreferencedBgpGroups.containsKey(neighbor.getGroup())) {
proc.getNeighbors().put(neighbor.getPrefix(), neighbor);
}
}
proc.setMultipathEbgp(multipathEbgpSet);
proc.setMultipathIbgp(multipathIbgp);
MultipathEquivalentAsPathMatchMode multipathEquivalentAsPathMatchMode = multipathMultipleAs ? MultipathEquivalentAsPathMatchMode.PATH_LENGTH : MultipathEquivalentAsPathMatchMode.FIRST_AS;
proc.setMultipathEquivalentAsPathMatchMode(multipathEquivalentAsPathMatchMode);
return proc;
}
use of org.batfish.datamodel.BgpNeighbor in project batfish by batfish.
the class Optimizations method computeCanMergeExportVars.
/*
* Determines when we can merge export variables into a single copy.
* This will be safe when there is no peer-specific export filter.
*/
private void computeCanMergeExportVars() {
Graph g = _encoderSlice.getGraph();
HeaderQuestion q = _encoderSlice.getEncoder().getQuestion();
boolean noFailures = q.getFailures() == 0;
_encoderSlice.getGraph().getConfigurations().forEach((router, conf) -> {
HashMap<Protocol, Boolean> map = new HashMap<>();
_sliceCanKeepSingleExportVar.put(router, map);
// the neighbor already being the root of the tree.
for (Protocol proto : getProtocols().get(router)) {
if (proto.isConnected() || proto.isStatic()) {
map.put(proto, noFailures && Optimizations.ENABLE_EXPORT_MERGE_OPTIMIZATION);
} else if (proto.isOspf()) {
// Ensure all interfaces are active
boolean allIfacesActive = true;
for (GraphEdge edge : g.getEdgeMap().get(router)) {
if (g.isEdgeUsed(conf, proto, edge)) {
Interface iface = edge.getStart();
allIfacesActive = allIfacesActive && g.isInterfaceActive(proto, iface);
}
}
// Ensure single area for this router
Set<Long> areas = _encoderSlice.getGraph().getAreaIds().get(router);
boolean singleArea = areas.size() <= 1;
map.put(proto, noFailures && allIfacesActive && singleArea && ENABLE_EXPORT_MERGE_OPTIMIZATION);
} else if (proto.isBgp()) {
boolean acc = true;
BgpProcess p = conf.getDefaultVrf().getBgpProcess();
for (Map.Entry<Prefix, BgpNeighbor> e : p.getNeighbors().entrySet()) {
BgpNeighbor n = e.getValue();
// If iBGP used, then don't merge
if (n.getLocalAs().equals(n.getRemoteAs())) {
acc = false;
break;
}
// If not the default export policy, then don't merge
if (!isDefaultBgpExport(conf, n)) {
acc = false;
break;
}
}
map.put(proto, noFailures && acc && ENABLE_EXPORT_MERGE_OPTIMIZATION);
} else {
throw new BatfishException("Error: unkown protocol: " + proto.name());
}
}
});
}
use of org.batfish.datamodel.BgpNeighbor in project batfish by batfish.
the class CounterExample method buildEnvRoutingTable.
SortedSet<BgpAdvertisement> buildEnvRoutingTable(Encoder enc) {
SortedSet<BgpAdvertisement> routes = new TreeSet<>();
EncoderSlice slice = enc.getMainSlice();
LogicalGraph lg = slice.getLogicalGraph();
for (Entry<LogicalEdge, SymbolicRoute> entry : lg.getEnvironmentVars().entrySet()) {
LogicalEdge lge = entry.getKey();
SymbolicRoute record = entry.getValue();
// If there is an external advertisement
if (boolVal(record.getPermitted())) {
// If we actually use it
GraphEdge ge = lge.getEdge();
String router = ge.getRouter();
SymbolicDecisions decisions = slice.getSymbolicDecisions();
BoolExpr ctrFwd = decisions.getControlForwarding().get(router, ge);
assert ctrFwd != null;
if (boolVal(ctrFwd)) {
SymbolicRoute r = decisions.getBestNeighbor().get(router);
SymbolicPacket pkt = slice.getSymbolicPacket();
Flow f = buildFlow(pkt, router);
Prefix pfx = buildPrefix(r, f);
int pathLength = intVal(r.getMetric());
// Create dummy information
BgpNeighbor n = slice.getGraph().getEbgpNeighbors().get(lge.getEdge());
String srcNode = "as" + n.getRemoteAs();
Ip zeroIp = new Ip(0);
Ip dstIp = n.getLocalIp();
// Recover AS path
List<SortedSet<Integer>> asSets = new ArrayList<>();
for (int i = 0; i < pathLength; i++) {
SortedSet<Integer> asSet = new TreeSet<>();
asSet.add(-1);
asSets.add(asSet);
}
AsPath path = new AsPath(asSets);
// Recover communities
SortedSet<Long> communities = new TreeSet<>();
for (Entry<CommunityVar, BoolExpr> entry2 : r.getCommunities().entrySet()) {
CommunityVar cvar = entry2.getKey();
BoolExpr expr = entry2.getValue();
if (cvar.getType() == Type.EXACT && boolVal(expr)) {
communities.add(cvar.asLong());
}
}
BgpAdvertisement adv = new BgpAdvertisement(BgpAdvertisementType.EBGP_RECEIVED, pfx, zeroIp, srcNode, "default", zeroIp, router, "default", dstIp, RoutingProtocol.BGP, OriginType.EGP, 100, 80, zeroIp, path, communities, new TreeSet<>(), 0);
routes.add(adv);
}
}
}
return routes;
}
use of org.batfish.datamodel.BgpNeighbor in project batfish by batfish.
the class BdpDataPlanePluginTest method testBgpNeighborReachability.
@Test
public void testBgpNeighborReachability() throws IOException {
// Only connect one neighbor (n2) to core router
SortedMap<String, Configuration> configs = generateNetworkWithDuplicates();
Batfish batfish = BatfishTestUtils.getBatfish(configs, _folder);
DataPlanePlugin dataPlanePlugin = new BdpDataPlanePlugin();
dataPlanePlugin.initialize(batfish);
dataPlanePlugin.computeDataPlane(false);
// N2 has proper neighbor relationship
Collection<BgpNeighbor> n2Neighbors = configs.get("n2").getVrfs().get(DEFAULT_VRF_NAME).getBgpProcess().getNeighbors().values();
assertThat(n2Neighbors, hasSize(1));
assertThat(n2Neighbors.iterator().next().getRemoteBgpNeighbor(), is(notNullValue()));
// N1 does not have a full session established, because it's not reachable
Collection<BgpNeighbor> n1Neighbors = configs.get("n1").getVrfs().get(DEFAULT_VRF_NAME).getBgpProcess().getNeighbors().values();
assertThat(n1Neighbors, hasSize(1));
assertThat(n1Neighbors.iterator().next().getRemoteBgpNeighbor(), is(nullValue()));
}
Aggregations