use of org.batfish.datamodel.OspfArea in project batfish by batfish.
the class VirtualRouter method propagateOspfExternalRoutes.
public boolean propagateOspfExternalRoutes(Map<String, Node> nodes, Topology topology) {
boolean changed = false;
String node = _c.getHostname();
OspfProcess proc = _vrf.getOspfProcess();
if (proc != null) {
int admin = RoutingProtocol.OSPF.getDefaultAdministrativeCost(_c.getConfigurationFormat());
SortedSet<Edge> edges = topology.getNodeEdges().get(node);
if (edges == null) {
// there are no edges, so OSPF won't produce anything
return false;
}
for (Edge edge : edges) {
if (!edge.getNode1().equals(node)) {
continue;
}
String connectingInterfaceName = edge.getInt1();
Interface connectingInterface = _vrf.getInterfaces().get(connectingInterfaceName);
if (connectingInterface == null) {
// wrong vrf, so skip
continue;
}
String neighborName = edge.getNode2();
Node neighbor = nodes.get(neighborName);
String neighborInterfaceName = edge.getInt2();
OspfArea area = connectingInterface.getOspfArea();
Configuration nc = neighbor._c;
Interface neighborInterface = nc.getInterfaces().get(neighborInterfaceName);
String neighborVrfName = neighborInterface.getVrfName();
VirtualRouter neighborVirtualRouter = nodes.get(neighborName)._virtualRouters.get(neighborVrfName);
OspfArea neighborArea = neighborInterface.getOspfArea();
if (connectingInterface.getOspfEnabled() && !connectingInterface.getOspfPassive() && neighborInterface.getOspfEnabled() && !neighborInterface.getOspfPassive() && area != null && neighborArea != null && area.getName().equals(neighborArea.getName())) {
/*
* We have an ospf neighbor relationship on this edge. So we
* should add all ospf external type 1(2) routes from this
* neighbor into our ospf external type 1(2) staging rib. For
* type 1, the cost of the route increases each time. For type 2,
* the cost remains constant, but we must keep track of cost to
* advertiser as a tie-breaker.
*/
long connectingInterfaceCost = connectingInterface.getOspfCost();
long incrementalCost = proc.getMaxMetricTransitLinks() != null ? proc.getMaxMetricTransitLinks() : connectingInterfaceCost;
for (OspfExternalType1Route neighborRoute : neighborVirtualRouter._prevOspfExternalType1Rib.getRoutes()) {
long oldArea = neighborRoute.getArea();
long connectionArea = area.getName();
long newArea;
long baseMetric = neighborRoute.getMetric();
long baseCostToAdvertiser = neighborRoute.getCostToAdvertiser();
newArea = connectionArea;
if (oldArea != OspfRoute.NO_AREA) {
Long maxMetricSummaryNetworks = neighborVirtualRouter._vrf.getOspfProcess().getMaxMetricSummaryNetworks();
if (connectionArea != oldArea) {
if (connectionArea != 0L && oldArea != 0L) {
continue;
}
if (maxMetricSummaryNetworks != null) {
baseMetric = maxMetricSummaryNetworks + neighborRoute.getLsaMetric();
baseCostToAdvertiser = maxMetricSummaryNetworks;
}
}
}
long newMetric = baseMetric + incrementalCost;
long newCostToAdvertiser = baseCostToAdvertiser + incrementalCost;
OspfExternalType1Route newRoute = new OspfExternalType1Route(neighborRoute.getNetwork(), neighborInterface.getAddress().getIp(), admin, newMetric, neighborRoute.getLsaMetric(), newArea, newCostToAdvertiser, neighborRoute.getAdvertiser());
if (_ospfExternalType1StagingRib.mergeRoute(newRoute)) {
changed = true;
}
}
for (OspfExternalType2Route neighborRoute : neighborVirtualRouter._prevOspfExternalType2Rib.getRoutes()) {
long oldArea = neighborRoute.getArea();
long connectionArea = area.getName();
long newArea;
long baseCostToAdvertiser = neighborRoute.getCostToAdvertiser();
if (oldArea == OspfRoute.NO_AREA) {
newArea = connectionArea;
} else {
newArea = oldArea;
Long maxMetricSummaryNetworks = neighborVirtualRouter._vrf.getOspfProcess().getMaxMetricSummaryNetworks();
if (connectionArea != oldArea && maxMetricSummaryNetworks != null) {
baseCostToAdvertiser = maxMetricSummaryNetworks;
}
}
long newCostToAdvertiser = baseCostToAdvertiser + incrementalCost;
OspfExternalType2Route newRoute = new OspfExternalType2Route(neighborRoute.getNetwork(), neighborInterface.getAddress().getIp(), admin, neighborRoute.getMetric(), neighborRoute.getLsaMetric(), newArea, newCostToAdvertiser, neighborRoute.getAdvertiser());
if (_ospfExternalType2StagingRib.mergeRoute(newRoute)) {
changed = true;
}
}
}
}
}
return changed;
}
use of org.batfish.datamodel.OspfArea in project batfish by batfish.
the class VirtualRouter method propagateOspfInternalRoutesFromNeighbor.
/**
* Propagate OSPF Internal routes from a single neighbor.
*
* @param proc The receiving OSPF process
* @param neighbor the neighbor
* @param connectingInterface interface on which we are connected to the neighbor
* @param neighborInterface interface that the neighbor uses to connect to us
* @param adminCost route administrative distance
* @return true if new routes have been added to our staging RIB
*/
boolean propagateOspfInternalRoutesFromNeighbor(OspfProcess proc, Node neighbor, Interface connectingInterface, Interface neighborInterface, int adminCost) {
OspfArea area = connectingInterface.getOspfArea();
OspfArea neighborArea = neighborInterface.getOspfArea();
// Ensure that the link (i.e., both interfaces) has OSPF enabled and OSPF areas are set
if (!connectingInterface.getOspfEnabled() || connectingInterface.getOspfPassive() || !neighborInterface.getOspfEnabled() || neighborInterface.getOspfPassive() || area == null || neighborArea == null || !area.getName().equals(neighborArea.getName())) {
return false;
}
/*
* An OSPF neighbor relationship exists on this edge. So we examine all intra- and inter-area
* routes belonging to the neighbor to see what should be propagated to this router. We add the
* incremental cost associated with our settings and the connecting interface, and use the
* neighborInterface's address as the next hop ip.
*/
int connectingInterfaceCost = connectingInterface.getOspfCost();
long incrementalCost = proc.getMaxMetricTransitLinks() != null ? proc.getMaxMetricTransitLinks() : connectingInterfaceCost;
Long areaNum = area.getName();
VirtualRouter neighborVirtualRouter = neighbor._virtualRouters.get(neighborInterface.getVrfName());
boolean changed = false;
for (OspfIntraAreaRoute neighborRoute : neighborVirtualRouter._ospfIntraAreaRib.getRoutes()) {
changed |= propagateOspfIntraAreaRoute(neighborRoute, incrementalCost, neighborInterface, adminCost, areaNum);
changed |= propagateOspfInterAreaRouteFromIntraAreaRoute(neighbor, neighborRoute, incrementalCost, neighborInterface, adminCost, areaNum);
}
for (OspfInterAreaRoute neighborRoute : neighborVirtualRouter._ospfInterAreaRib.getRoutes()) {
changed |= propagateOspfInterAreaRouteFromInterAreaRoute(neighbor, neighborRoute, incrementalCost, neighborInterface, adminCost, areaNum);
}
return changed;
}
use of org.batfish.datamodel.OspfArea in project batfish by batfish.
the class ConfigurationBuilder method enterO_area.
@Override
public void enterO_area(O_areaContext ctx) {
Ip areaIp = new Ip(ctx.area.getText());
Map<Long, OspfArea> areas = _currentRoutingInstance.getOspfAreas();
_currentArea = areas.computeIfAbsent(areaIp.asLong(), OspfArea::new);
}
use of org.batfish.datamodel.OspfArea in project batfish by batfish.
the class JuniperConfiguration method placeInterfaceIntoArea.
private void placeInterfaceIntoArea(Map<Long, OspfArea> newAreas, String name, Interface iface, String vrfName) {
Vrf vrf = _c.getVrfs().get(vrfName);
org.batfish.datamodel.Interface newIface = vrf.getInterfaces().get(name);
Ip ospfArea = iface.getOspfActiveArea();
boolean setCost = false;
if (ospfArea != null) {
if (newIface.getAddress() == null) {
_w.redFlag(String.format("Cannot assign interface %s to be active in area %s because it has no IP address.", name, ospfArea));
} else {
setCost = true;
long ospfAreaLong = ospfArea.asLong();
OspfArea newArea = newAreas.get(ospfAreaLong);
newArea.getInterfaces().add(name);
newIface.setOspfArea(newArea);
newIface.setOspfEnabled(true);
}
}
for (Ip passiveArea : iface.getOspfPassiveAreas()) {
if (newIface.getAddress() == null) {
_w.redFlag(String.format("Cannot assign interface %s to be passive in area %s because it has no IP address.", name, passiveArea));
continue;
}
setCost = true;
long ospfAreaLong = passiveArea.asLong();
OspfArea newArea = newAreas.get(ospfAreaLong);
newArea.getInterfaces().add(name);
newIface.setOspfEnabled(true);
newIface.setOspfPassive(true);
}
if (setCost) {
Integer ospfCost = iface.getOspfCost();
if (ospfCost == null && newIface.isLoopback(ConfigurationFormat.FLAT_JUNIPER)) {
ospfCost = 0;
}
newIface.setOspfCost(ospfCost);
}
}
use of org.batfish.datamodel.OspfArea in project batfish by batfish.
the class OspfTest method getOspfRoutes.
/*
* Int:1/2 2/1 2/3 3/2 3/4 4/3
* R1 <=========> R2 <=========> R3 <=========> R4
* A B C D E F G
*
* Areas:
* A: R1 Loopback0
* B: R1 E1/2, R2 E2/1
* C: R2 Loopback0
* D: R2 E2/3, R3 E3/2
* E: R3 Loopback0
* F: R3 E3/4, R4 E4/3
* G: R4 Loopback0
*/
private SortedMap<String, SortedMap<String, SortedSet<AbstractRoute>>> getOspfRoutes(long areaA, long areaB, long areaC, long areaD, long areaE, long areaF, long areaG, Long maxMetricExternalNetworks, Long maxMetricStubNetworks, Long maxMetricSummaryNetworks, Long maxMetricTransitLinks) {
String l0Name = "Loopback0";
String l1Name = "Loopback1";
String c1E1To2Name = "Ethernet1/2";
String c2E2To1Name = "Ethernet2/1";
String c2E2To3Name = "Ethernet2/3";
String c3E3To2Name = "Ethernet3/2";
String c3E3To4Name = "Ethernet3/4";
String c4E4To3Name = "Ethernet4/3";
RoutingPolicy.Builder rpb = _nf.routingPolicyBuilder();
OspfArea.Builder oaba = _nf.ospfAreaBuilder().setNumber(areaA);
OspfArea.Builder oabb = _nf.ospfAreaBuilder().setNumber(areaB);
OspfArea.Builder oabc = _nf.ospfAreaBuilder().setNumber(areaC);
OspfArea.Builder oabd = _nf.ospfAreaBuilder().setNumber(areaD);
OspfArea.Builder oabe = _nf.ospfAreaBuilder().setNumber(areaE);
OspfArea.Builder oabf = _nf.ospfAreaBuilder().setNumber(areaF);
OspfArea.Builder oabg = _nf.ospfAreaBuilder().setNumber(areaG);
Configuration c1 = _cb.setHostname(C1_NAME).build();
Vrf v1 = _vb.setOwner(c1).build();
RoutingPolicy c1ExportPolicy = rpb.setOwner(c1).setStatements(getExportPolicyStatements(C1_L1_ADDRESS)).build();
OspfProcess op1 = _opb.setVrf(v1).setExportPolicy(c1ExportPolicy).build();
OspfArea oa1a = oaba.setOspfProcess(op1).build();
OspfArea oa1b = areaA == areaB ? oa1a : oabb.setOspfProcess(op1).build();
_ib.setOwner(c1).setVrf(v1).setOspfArea(oa1a);
_ib.setOspfPassive(true).setName(l0Name).setAddress(C1_L0_ADDRESS).build();
_ib.setOspfEnabled(false).setOspfPassive(false).setOspfArea(null).setName(l1Name).setAddress(C1_L1_ADDRESS).build();
_ib.setOspfEnabled(true).setOspfArea(oa1b);
_ib.setName(c1E1To2Name).setAddress(C1_E1_2_ADDRESS).build();
Configuration c2 = _cb.setHostname(C2_NAME).build();
Vrf v2 = _vb.setOwner(c2).build();
RoutingPolicy c2ExportPolicy = rpb.setOwner(c2).setStatements(getExportPolicyStatements(C2_L1_ADDRESS)).build();
OspfProcess op2 = _opb.setVrf(v2).setMaxMetricExternalNetworks(maxMetricExternalNetworks).setMaxMetricStubNetworks(maxMetricStubNetworks).setMaxMetricSummaryNetworks(maxMetricSummaryNetworks).setMaxMetricTransitLinks(maxMetricTransitLinks).setExportPolicy(c2ExportPolicy).build();
_opb.setMaxMetricExternalNetworks(null).setMaxMetricStubNetworks(null).setMaxMetricSummaryNetworks(null).setMaxMetricTransitLinks(null);
OspfArea oa2b = oabb.setOspfProcess(op2).build();
OspfArea oa2c = areaB == areaC ? oa2b : oabc.setOspfProcess(op2).build();
OspfArea oa2d = areaB == areaD ? oa2b : areaC == areaD ? oa2c : oabd.setOspfProcess(op2).build();
_ib.setOwner(c2).setVrf(v2).setOspfArea(oa2c);
_ib.setOspfPassive(true).setName(l0Name).setAddress(C2_L0_ADDRESS).build();
_ib.setOspfEnabled(false).setOspfPassive(false).setOspfArea(null).setName(l1Name).setAddress(C2_L1_ADDRESS).build();
_ib.setOspfEnabled(true).setOspfArea(oa2b);
_ib.setName(c2E2To1Name).setAddress(C2_E2_1_ADDRESS).setOspfPointToPoint(true).build();
_ib.setOspfPointToPoint(false).setOspfArea(oa2d);
_ib.setName(c2E2To3Name).setAddress(C2_E2_3_ADDRESS).build();
Configuration c3 = _cb.setHostname(C3_NAME).build();
Vrf v3 = _vb.setOwner(c3).build();
RoutingPolicy c3ExportPolicy = rpb.setOwner(c3).setStatements(getExportPolicyStatements(C3_L1_ADDRESS)).build();
OspfProcess op3 = _opb.setVrf(v3).setExportPolicy(c3ExportPolicy).build();
OspfArea oa3d = oabd.setOspfProcess(op3).build();
OspfArea oa3e = areaD == areaE ? oa3d : oabe.setOspfProcess(op3).build();
OspfArea oa3f = areaD == areaF ? oa3d : areaE == areaF ? oa3e : oabf.setOspfProcess(op3).build();
_ib.setOwner(c3).setVrf(v3).setOspfArea(oa3e);
_ib.setOspfPassive(true).setName(l0Name).setAddress(C3_L0_ADDRESS).build();
_ib.setOspfEnabled(false).setOspfPassive(false).setOspfArea(null).setName(l1Name).setAddress(C3_L1_ADDRESS).build();
_ib.setOspfEnabled(true).setOspfArea(oa3d);
_ib.setName(c3E3To2Name).setAddress(C3_E3_2_ADDRESS).build();
_ib.setName(c3E3To4Name).setAddress(C3_E3_4_ADDRESS).setOspfArea(oa3f).build();
Configuration c4 = _cb.setHostname(C4_NAME).build();
Vrf v4 = _vb.setOwner(c4).build();
RoutingPolicy c4ExportPolicy = rpb.setOwner(c4).setStatements(getExportPolicyStatements(C4_L1_ADDRESS)).build();
OspfProcess op4 = _opb.setVrf(v4).setExportPolicy(c4ExportPolicy).build();
OspfArea oa4f = oabf.setOspfProcess(op4).build();
OspfArea oa4g = areaF == areaG ? oa4f : oabg.setOspfProcess(op4).build();
_ib.setOwner(c4).setVrf(v4).setOspfArea(oa4g);
_ib.setOspfPassive(true).setName(l0Name).setAddress(C4_L0_ADDRESS).build();
_ib.setOspfEnabled(false).setOspfPassive(false).setOspfArea(null).setName(l1Name).setAddress(C4_L1_ADDRESS).build();
_ib.setOspfEnabled(true).setOspfArea(oa4f);
_ib.setName(c4E4To3Name).setAddress(C4_E4_3_ADDRESS).build();
SortedMap<String, Configuration> configurations = new ImmutableSortedMap.Builder<String, Configuration>(String::compareTo).put(c1.getName(), c1).put(c2.getName(), c2).put(c3.getName(), c3).put(c4.getName(), c4).build();
BdpEngine engine = new BdpEngine(new MockBdpSettings(), new BatfishLogger(BatfishLogger.LEVELSTR_OUTPUT, false), (s, i) -> new AtomicInteger());
Topology topology = CommonUtil.synthesizeTopology(configurations);
BdpDataPlane dp = engine.computeDataPlane(false, configurations, topology, Collections.emptySet(), new BdpAnswerElement());
return engine.getRoutes(dp);
}
Aggregations