use of org.batfish.datamodel.routing_policy.statement.SetOrigin in project batfish by batfish.
the class VpnConnection method applyToVpnGateway.
public void applyToVpnGateway(AwsConfiguration awsConfiguration, Region region, Warnings warnings) {
if (!awsConfiguration.getConfigurationNodes().containsKey(_vpnGatewayId)) {
warnings.redFlag(String.format("VPN Gateway \"%s\" referred by VPN connection \"%s\" not found", _vpnGatewayId, _vpnConnectionId));
return;
}
Configuration vpnGatewayCfgNode = awsConfiguration.getConfigurationNodes().get(_vpnGatewayId);
for (int i = 0; i < _ipsecTunnels.size(); i++) {
int idNum = i + 1;
String vpnId = _vpnConnectionId + "-" + idNum;
IpsecTunnel ipsecTunnel = _ipsecTunnels.get(i);
if (ipsecTunnel.getCgwBgpAsn() != -1 && (_staticRoutesOnly || _routes.size() != 0)) {
throw new BatfishException("Unexpected combination of BGP and static routes for VPN connection: \"" + _vpnConnectionId + "\"");
}
// create representation structures and add to configuration node
IpsecVpn ipsecVpn = new IpsecVpn(vpnId, vpnGatewayCfgNode);
vpnGatewayCfgNode.getIpsecVpns().put(vpnId, ipsecVpn);
IpsecPolicy ipsecPolicy = new IpsecPolicy(vpnId);
vpnGatewayCfgNode.getIpsecPolicies().put(vpnId, ipsecPolicy);
ipsecVpn.setIpsecPolicy(ipsecPolicy);
IpsecProposal ipsecProposal = new IpsecProposal(vpnId, -1);
vpnGatewayCfgNode.getIpsecProposals().put(vpnId, ipsecProposal);
ipsecPolicy.getProposals().put(vpnId, ipsecProposal);
IkeGateway ikeGateway = new IkeGateway(vpnId);
vpnGatewayCfgNode.getIkeGateways().put(vpnId, ikeGateway);
ipsecVpn.setIkeGateway(ikeGateway);
IkePolicy ikePolicy = new IkePolicy(vpnId);
vpnGatewayCfgNode.getIkePolicies().put(vpnId, ikePolicy);
ikeGateway.setIkePolicy(ikePolicy);
IkeProposal ikeProposal = new IkeProposal(vpnId, -1);
vpnGatewayCfgNode.getIkeProposals().put(vpnId, ikeProposal);
ikePolicy.getProposals().put(vpnId, ikeProposal);
String externalInterfaceName = "external" + idNum;
InterfaceAddress externalInterfaceAddress = new InterfaceAddress(ipsecTunnel.getVgwOutsideAddress(), Prefix.MAX_PREFIX_LENGTH);
Interface externalInterface = Utils.newInterface(externalInterfaceName, vpnGatewayCfgNode, externalInterfaceAddress);
String vpnInterfaceName = "vpn" + idNum;
InterfaceAddress vpnInterfaceAddress = new InterfaceAddress(ipsecTunnel.getVgwInsideAddress(), ipsecTunnel.getVgwInsidePrefixLength());
Interface vpnInterface = Utils.newInterface(vpnInterfaceName, vpnGatewayCfgNode, vpnInterfaceAddress);
// Set fields within representation structures
// ipsec
ipsecVpn.setBindInterface(vpnInterface);
ipsecPolicy.setPfsKeyGroup(toDiffieHellmanGroup(ipsecTunnel.getIpsecPerfectForwardSecrecy()));
ipsecProposal.setAuthenticationAlgorithm(toIpsecAuthenticationAlgorithm(ipsecTunnel.getIpsecAuthProtocol()));
ipsecProposal.setEncryptionAlgorithm(toEncryptionAlgorithm(ipsecTunnel.getIpsecEncryptionProtocol()));
ipsecProposal.setProtocol(toIpsecProtocol(ipsecTunnel.getIpsecProtocol()));
ipsecProposal.setLifetimeSeconds(ipsecTunnel.getIpsecLifetime());
// ike
ikeGateway.setExternalInterface(externalInterface);
ikeGateway.setAddress(ipsecTunnel.getCgwOutsideAddress());
ikeGateway.setLocalIp(externalInterface.getAddress().getIp());
if (ipsecTunnel.getIkePreSharedKeyHash() != null) {
ikePolicy.setPreSharedKeyHash(ipsecTunnel.getIkePreSharedKeyHash());
ikeProposal.setAuthenticationMethod(IkeAuthenticationMethod.PRE_SHARED_KEYS);
}
ikeProposal.setAuthenticationAlgorithm(toIkeAuthenticationAlgorithm(ipsecTunnel.getIkeAuthProtocol()));
ikeProposal.setDiffieHellmanGroup(toDiffieHellmanGroup(ipsecTunnel.getIkePerfectForwardSecrecy()));
ikeProposal.setEncryptionAlgorithm(toEncryptionAlgorithm(ipsecTunnel.getIkeEncryptionProtocol()));
ikeProposal.setLifetimeSeconds(ipsecTunnel.getIkeLifetime());
// bgp (if configured)
if (ipsecTunnel.getVgwBgpAsn() != -1) {
BgpProcess proc = vpnGatewayCfgNode.getDefaultVrf().getBgpProcess();
if (proc == null) {
proc = new BgpProcess();
proc.setRouterId(ipsecTunnel.getVgwInsideAddress());
proc.setMultipathEquivalentAsPathMatchMode(MultipathEquivalentAsPathMatchMode.EXACT_PATH);
vpnGatewayCfgNode.getDefaultVrf().setBgpProcess(proc);
}
BgpNeighbor cgBgpNeighbor = new BgpNeighbor(ipsecTunnel.getCgwInsideAddress(), vpnGatewayCfgNode);
cgBgpNeighbor.setVrf(Configuration.DEFAULT_VRF_NAME);
proc.getNeighbors().put(cgBgpNeighbor.getPrefix(), cgBgpNeighbor);
cgBgpNeighbor.setRemoteAs(ipsecTunnel.getCgwBgpAsn());
cgBgpNeighbor.setLocalAs(ipsecTunnel.getVgwBgpAsn());
cgBgpNeighbor.setLocalIp(ipsecTunnel.getVgwInsideAddress());
cgBgpNeighbor.setDefaultMetric(BGP_NEIGHBOR_DEFAULT_METRIC);
cgBgpNeighbor.setSendCommunity(false);
VpnGateway vpnGateway = region.getVpnGateways().get(_vpnGatewayId);
List<String> attachmentVpcIds = vpnGateway.getAttachmentVpcIds();
if (attachmentVpcIds.size() != 1) {
throw new BatfishException("Not sure what routes to advertise since VPN Gateway: \"" + _vpnGatewayId + "\" for VPN connection: \"" + _vpnConnectionId + "\" is linked to multiple VPCs");
}
String vpcId = attachmentVpcIds.get(0);
// iBGP connection to VPC
Configuration vpcNode = awsConfiguration.getConfigurationNodes().get(vpcId);
Ip vpcIfaceAddress = vpcNode.getInterfaces().get(_vpnGatewayId).getAddress().getIp();
Ip vgwToVpcIfaceAddress = vpnGatewayCfgNode.getInterfaces().get(vpcId).getAddress().getIp();
BgpNeighbor vgwToVpcBgpNeighbor = new BgpNeighbor(vpcIfaceAddress, vpnGatewayCfgNode);
proc.getNeighbors().put(vgwToVpcBgpNeighbor.getPrefix(), vgwToVpcBgpNeighbor);
vgwToVpcBgpNeighbor.setVrf(Configuration.DEFAULT_VRF_NAME);
vgwToVpcBgpNeighbor.setLocalAs(ipsecTunnel.getVgwBgpAsn());
vgwToVpcBgpNeighbor.setLocalIp(vgwToVpcIfaceAddress);
vgwToVpcBgpNeighbor.setRemoteAs(ipsecTunnel.getVgwBgpAsn());
vgwToVpcBgpNeighbor.setDefaultMetric(BGP_NEIGHBOR_DEFAULT_METRIC);
vgwToVpcBgpNeighbor.setSendCommunity(true);
// iBGP connection from VPC
BgpNeighbor vpcToVgwBgpNeighbor = new BgpNeighbor(vgwToVpcIfaceAddress, vpcNode);
BgpProcess vpcProc = new BgpProcess();
vpcNode.getDefaultVrf().setBgpProcess(vpcProc);
vpcProc.setMultipathEquivalentAsPathMatchMode(MultipathEquivalentAsPathMatchMode.EXACT_PATH);
vpcProc.setRouterId(vpcIfaceAddress);
vpcProc.getNeighbors().put(vpcToVgwBgpNeighbor.getPrefix(), vpcToVgwBgpNeighbor);
vpcToVgwBgpNeighbor.setVrf(Configuration.DEFAULT_VRF_NAME);
vpcToVgwBgpNeighbor.setLocalAs(ipsecTunnel.getVgwBgpAsn());
vpcToVgwBgpNeighbor.setLocalIp(vpcIfaceAddress);
vpcToVgwBgpNeighbor.setRemoteAs(ipsecTunnel.getVgwBgpAsn());
vpcToVgwBgpNeighbor.setDefaultMetric(BGP_NEIGHBOR_DEFAULT_METRIC);
vpcToVgwBgpNeighbor.setSendCommunity(true);
String rpRejectAllName = "~REJECT_ALL~";
String rpAcceptAllEbgpAndSetNextHopSelfName = "~ACCEPT_ALL_EBGP_AND_SET_NEXT_HOP_SELF~";
If acceptIffEbgp = new If();
acceptIffEbgp.setGuard(new MatchProtocol(RoutingProtocol.BGP));
acceptIffEbgp.setTrueStatements(ImmutableList.of(Statements.ExitAccept.toStaticStatement()));
acceptIffEbgp.setFalseStatements(ImmutableList.of(Statements.ExitReject.toStaticStatement()));
RoutingPolicy vgwRpAcceptAllBgp = new RoutingPolicy(rpAcceptAllEbgpAndSetNextHopSelfName, vpnGatewayCfgNode);
vpnGatewayCfgNode.getRoutingPolicies().put(vgwRpAcceptAllBgp.getName(), vgwRpAcceptAllBgp);
vgwRpAcceptAllBgp.setStatements(ImmutableList.of(new SetNextHop(new SelfNextHop(), false), acceptIffEbgp));
vgwToVpcBgpNeighbor.setExportPolicy(rpAcceptAllEbgpAndSetNextHopSelfName);
RoutingPolicy vgwRpRejectAll = new RoutingPolicy(rpRejectAllName, vpnGatewayCfgNode);
vpnGatewayCfgNode.getRoutingPolicies().put(rpRejectAllName, vgwRpRejectAll);
vgwToVpcBgpNeighbor.setImportPolicy(rpRejectAllName);
String rpAcceptAllName = "~ACCEPT_ALL~";
RoutingPolicy vpcRpAcceptAll = new RoutingPolicy(rpAcceptAllName, vpcNode);
vpcNode.getRoutingPolicies().put(rpAcceptAllName, vpcRpAcceptAll);
vpcRpAcceptAll.setStatements(ImmutableList.of(Statements.ExitAccept.toStaticStatement()));
vpcToVgwBgpNeighbor.setImportPolicy(rpAcceptAllName);
RoutingPolicy vpcRpRejectAll = new RoutingPolicy(rpRejectAllName, vpcNode);
vpcNode.getRoutingPolicies().put(rpRejectAllName, vpcRpRejectAll);
vpcToVgwBgpNeighbor.setExportPolicy(rpRejectAllName);
Vpc vpc = region.getVpcs().get(vpcId);
String originationPolicyName = vpnId + "_origination";
RoutingPolicy originationRoutingPolicy = new RoutingPolicy(originationPolicyName, vpnGatewayCfgNode);
vpnGatewayCfgNode.getRoutingPolicies().put(originationPolicyName, originationRoutingPolicy);
cgBgpNeighbor.setExportPolicy(originationPolicyName);
If originationIf = new If();
List<Statement> statements = originationRoutingPolicy.getStatements();
statements.add(originationIf);
statements.add(Statements.ExitReject.toStaticStatement());
originationIf.getTrueStatements().add(new SetOrigin(new LiteralOrigin(OriginType.IGP, null)));
originationIf.getTrueStatements().add(Statements.ExitAccept.toStaticStatement());
RouteFilterList originationRouteFilter = new RouteFilterList(originationPolicyName);
vpnGatewayCfgNode.getRouteFilterLists().put(originationPolicyName, originationRouteFilter);
vpc.getCidrBlockAssociations().forEach(prefix -> {
RouteFilterLine matchOutgoingPrefix = new RouteFilterLine(LineAction.ACCEPT, prefix, new SubRange(prefix.getPrefixLength(), prefix.getPrefixLength()));
originationRouteFilter.addLine(matchOutgoingPrefix);
});
Conjunction conj = new Conjunction();
originationIf.setGuard(conj);
conj.getConjuncts().add(new MatchProtocol(RoutingProtocol.STATIC));
conj.getConjuncts().add(new MatchPrefixSet(new DestinationNetwork(), new NamedPrefixSet(originationPolicyName)));
}
// static routes (if configured)
for (Prefix staticRoutePrefix : _routes) {
StaticRoute staticRoute = StaticRoute.builder().setNetwork(staticRoutePrefix).setNextHopIp(ipsecTunnel.getCgwInsideAddress()).setAdministrativeCost(Route.DEFAULT_STATIC_ROUTE_ADMIN).setMetric(Route.DEFAULT_STATIC_ROUTE_COST).build();
vpnGatewayCfgNode.getDefaultVrf().getStaticRoutes().add(staticRoute);
}
}
}
use of org.batfish.datamodel.routing_policy.statement.SetOrigin 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.routing_policy.statement.SetOrigin in project batfish by batfish.
the class TransferBDD method compute.
/*
* Convert a list of statements into a Z3 boolean expression for the transfer function.
*/
private TransferResult<TransferReturn, BDD> compute(List<Statement> statements, TransferParam<BDDRoute> p) {
boolean doesReturn = false;
TransferResult<TransferReturn, BDD> result = new TransferResult<>();
result = result.setReturnValue(new TransferReturn(p.getData(), factory.zero())).setFallthroughValue(factory.zero()).setReturnAssignedValue(factory.zero());
for (Statement stmt : statements) {
if (stmt instanceof StaticStatement) {
StaticStatement ss = (StaticStatement) stmt;
switch(ss.getType()) {
case ExitAccept:
doesReturn = true;
p.debug("ExitAccept");
result = returnValue(result, true);
break;
case ReturnTrue:
doesReturn = true;
p.debug("ReturnTrue");
result = returnValue(result, true);
break;
case ExitReject:
doesReturn = true;
p.debug("ExitReject");
result = returnValue(result, false);
break;
case ReturnFalse:
doesReturn = true;
p.debug("ReturnFalse");
result = returnValue(result, false);
break;
case SetDefaultActionAccept:
p.debug("SetDefaulActionAccept");
p = p.setDefaultAccept(true);
break;
case SetDefaultActionReject:
p.debug("SetDefaultActionReject");
p = p.setDefaultAccept(false);
break;
case SetLocalDefaultActionAccept:
p.debug("SetLocalDefaultActionAccept");
p = p.setDefaultAcceptLocal(true);
break;
case SetLocalDefaultActionReject:
p.debug("SetLocalDefaultActionReject");
p = p.setDefaultAcceptLocal(false);
break;
case ReturnLocalDefaultAction:
p.debug("ReturnLocalDefaultAction");
// TODO: need to set local default action in an environment
if (p.getDefaultAcceptLocal()) {
result = returnValue(result, true);
} else {
result = returnValue(result, false);
}
break;
case FallThrough:
p.debug("Fallthrough");
result = fallthrough(result);
break;
case Return:
// TODO: assumming this happens at the end of the function, so it is ignored for now.
p.debug("Return");
break;
case RemovePrivateAs:
p.debug("RemovePrivateAs");
// System.out.println("Warning: use of unimplemented feature RemovePrivateAs");
break;
default:
throw new BatfishException("TODO: computeTransferFunction: " + ss.getType());
}
} else if (stmt instanceof If) {
p.debug("If");
If i = (If) stmt;
TransferResult<TransferReturn, BDD> r = compute(i.getGuard(), p.indent());
BDD guard = r.getReturnValue().getSecond();
p.debug("guard: ");
BDDRoute current = result.getReturnValue().getFirst();
TransferParam<BDDRoute> pTrue = p.indent().setData(current.deepCopy());
TransferParam<BDDRoute> pFalse = p.indent().setData(current.deepCopy());
p.debug("True Branch");
TransferResult<TransferReturn, BDD> trueBranch = compute(i.getTrueStatements(), pTrue);
p.debug("True Branch: " + trueBranch.getReturnValue().getFirst().hashCode());
p.debug("False Branch");
TransferResult<TransferReturn, BDD> falseBranch = compute(i.getFalseStatements(), pFalse);
p.debug("False Branch: " + trueBranch.getReturnValue().getFirst().hashCode());
BDDRoute r1 = trueBranch.getReturnValue().getFirst();
BDDRoute r2 = falseBranch.getReturnValue().getFirst();
BDDRoute recordVal = ite(guard, r1, r2);
// update return values
BDD returnVal = ite(guard, trueBranch.getReturnValue().getSecond(), falseBranch.getReturnValue().getSecond());
// p.debug("New Return Value (neg): " + returnVal.not());
BDD returnAss = ite(guard, trueBranch.getReturnAssignedValue(), falseBranch.getReturnAssignedValue());
// p.debug("New Return Assigned: " + returnAss);
BDD fallThrough = ite(guard, trueBranch.getFallthroughValue(), falseBranch.getFallthroughValue());
// p.debug("New fallthrough: " + fallThrough);
result = result.setReturnValue(new TransferReturn(recordVal, returnVal)).setReturnAssignedValue(returnAss).setFallthroughValue(fallThrough);
p.debug("If return: " + result.getReturnValue().getFirst().hashCode());
} else if (stmt instanceof SetDefaultPolicy) {
p.debug("SetDefaultPolicy");
p = p.setDefaultPolicy((SetDefaultPolicy) stmt);
} else if (stmt instanceof SetMetric) {
p.debug("SetMetric");
SetMetric sm = (SetMetric) stmt;
LongExpr ie = sm.getMetric();
BDD isBGP = p.getData().getProtocolHistory().value(Protocol.BGP);
BDD updateMed = isBGP.and(result.getReturnAssignedValue());
BDD updateMet = isBGP.not().and(result.getReturnAssignedValue());
BDDInteger newValue = applyLongExprModification(p.indent(), p.getData().getMetric(), ie);
BDDInteger med = ite(updateMed, p.getData().getMed(), newValue);
BDDInteger met = ite(updateMet, p.getData().getMetric(), newValue);
p.getData().setMetric(met);
p.getData().setMetric(med);
} else if (stmt instanceof SetOspfMetricType) {
p.debug("SetOspfMetricType");
SetOspfMetricType somt = (SetOspfMetricType) stmt;
OspfMetricType mt = somt.getMetricType();
BDDDomain<OspfType> current = result.getReturnValue().getFirst().getOspfMetric();
BDDDomain<OspfType> newValue = new BDDDomain<>(current);
if (mt == OspfMetricType.E1) {
p.indent().debug("Value: E1");
newValue.setValue(OspfType.E1);
} else {
p.indent().debug("Value: E2");
newValue.setValue(OspfType.E1);
}
newValue = ite(result.getReturnAssignedValue(), p.getData().getOspfMetric(), newValue);
p.getData().setOspfMetric(newValue);
} else if (stmt instanceof SetLocalPreference) {
p.debug("SetLocalPreference");
SetLocalPreference slp = (SetLocalPreference) stmt;
IntExpr ie = slp.getLocalPreference();
BDDInteger newValue = applyIntExprModification(p.indent(), p.getData().getLocalPref(), ie);
newValue = ite(result.getReturnAssignedValue(), p.getData().getLocalPref(), newValue);
p.getData().setLocalPref(newValue);
} else if (stmt instanceof AddCommunity) {
p.debug("AddCommunity");
AddCommunity ac = (AddCommunity) stmt;
Set<CommunityVar> comms = _graph.findAllCommunities(_conf, ac.getExpr());
for (CommunityVar cvar : comms) {
if (!_policyQuotient.getCommsAssignedButNotMatched().contains(cvar)) {
p.indent().debug("Value: " + cvar);
BDD comm = p.getData().getCommunities().get(cvar);
BDD newValue = ite(result.getReturnAssignedValue(), comm, factory.one());
p.indent().debug("New Value: " + newValue);
p.getData().getCommunities().put(cvar, newValue);
}
}
} else if (stmt instanceof SetCommunity) {
p.debug("SetCommunity");
SetCommunity sc = (SetCommunity) stmt;
Set<CommunityVar> comms = _graph.findAllCommunities(_conf, sc.getExpr());
for (CommunityVar cvar : comms) {
if (!_policyQuotient.getCommsAssignedButNotMatched().contains(cvar)) {
p.indent().debug("Value: " + cvar);
BDD comm = p.getData().getCommunities().get(cvar);
BDD newValue = ite(result.getReturnAssignedValue(), comm, factory.one());
p.indent().debug("New Value: " + newValue);
p.getData().getCommunities().put(cvar, newValue);
}
}
} else if (stmt instanceof DeleteCommunity) {
p.debug("DeleteCommunity");
DeleteCommunity ac = (DeleteCommunity) stmt;
Set<CommunityVar> comms = _graph.findAllCommunities(_conf, ac.getExpr());
Set<CommunityVar> toDelete = new HashSet<>();
// Find comms to delete
for (CommunityVar cvar : comms) {
if (cvar.getType() == Type.REGEX) {
toDelete.addAll(_commDeps.get(cvar));
} else {
toDelete.add(cvar);
}
}
// Delete the comms
for (CommunityVar cvar : toDelete) {
if (!_policyQuotient.getCommsAssignedButNotMatched().contains(cvar)) {
p.indent().debug("Value: " + cvar.getValue() + ", " + cvar.getType());
BDD comm = p.getData().getCommunities().get(cvar);
BDD newValue = ite(result.getReturnAssignedValue(), comm, factory.zero());
p.indent().debug("New Value: " + newValue);
p.getData().getCommunities().put(cvar, newValue);
}
}
} else if (stmt instanceof RetainCommunity) {
p.debug("RetainCommunity");
// no op
} else if (stmt instanceof PrependAsPath) {
p.debug("PrependAsPath");
PrependAsPath pap = (PrependAsPath) stmt;
Integer prependCost = prependLength(pap.getExpr());
p.indent().debug("Cost: " + prependCost);
BDDInteger met = p.getData().getMetric();
BDDInteger newValue = met.add(BDDInteger.makeFromValue(met.getFactory(), 32, prependCost));
newValue = ite(result.getReturnAssignedValue(), p.getData().getMetric(), newValue);
p.getData().setMetric(newValue);
} else if (stmt instanceof SetOrigin) {
p.debug("SetOrigin");
// System.out.println("Warning: use of unimplemented feature SetOrigin");
// TODO: implement me
} else if (stmt instanceof SetNextHop) {
p.debug("SetNextHop");
// System.out.println("Warning: use of unimplemented feature SetNextHop");
// TODO: implement me
} else {
throw new BatfishException("TODO: statement transfer function: " + stmt);
}
}
// If this is the outermost call, then we relate the variables
if (p.getInitialCall()) {
p.debug("InitialCall finalizing");
// Apply the default action
if (!doesReturn) {
p.debug("Applying default action: " + p.getDefaultAccept());
if (p.getDefaultAccept()) {
result = returnValue(result, true);
} else {
result = returnValue(result, false);
}
}
// Set all the values to 0 if the return is not true;
TransferReturn ret = result.getReturnValue();
BDDRoute retVal = ite(ret.getSecond(), ret.getFirst(), zeroedRecord());
result = result.setReturnValue(new TransferReturn(retVal, ret.getSecond()));
}
return result;
}
use of org.batfish.datamodel.routing_policy.statement.SetOrigin in project batfish by batfish.
the class CiscoConfiguration method bgpRedistributeWithEnvironmentExpr.
private WithEnvironmentExpr bgpRedistributeWithEnvironmentExpr(BooleanExpr expr, OriginType originType) {
WithEnvironmentExpr we = new WithEnvironmentExpr();
we.setExpr(expr);
we.getPreStatements().add(Statements.SetWriteIntermediateBgpAttributes.toStaticStatement());
we.getPostStatements().add(Statements.UnsetWriteIntermediateBgpAttributes.toStaticStatement());
we.getPostTrueStatements().add(Statements.SetReadIntermediateBgpAttributes.toStaticStatement());
we.getPostTrueStatements().add(new SetOrigin(new LiteralOrigin(originType, null)));
return we;
}
use of org.batfish.datamodel.routing_policy.statement.SetOrigin in project batfish by batfish.
the class TransferSSA method compute.
/*
* Convert a list of statements into a Z3 boolean expression for the transfer function.
*/
private TransferResult<BoolExpr, BoolExpr> compute(List<Statement> statements, TransferParam<SymbolicRoute> p, TransferResult<BoolExpr, BoolExpr> result) {
boolean doesReturn = false;
for (Statement stmt : statements) {
if (stmt instanceof StaticStatement) {
StaticStatement ss = (StaticStatement) stmt;
switch(ss.getType()) {
case ExitAccept:
doesReturn = true;
p.debug("ExitAccept");
result = returnValue(p, result, true);
break;
case ReturnTrue:
doesReturn = true;
p.debug("ReturnTrue");
result = returnValue(p, result, true);
break;
case ExitReject:
doesReturn = true;
p.debug("ExitReject");
result = returnValue(p, result, false);
break;
case ReturnFalse:
doesReturn = true;
p.debug("ReturnFalse");
result = returnValue(p, result, false);
break;
case SetDefaultActionAccept:
p.debug("SetDefaulActionAccept");
p = p.setDefaultAccept(true);
break;
case SetDefaultActionReject:
p.debug("SetDefaultActionReject");
p = p.setDefaultAccept(false);
break;
case SetLocalDefaultActionAccept:
p.debug("SetLocalDefaultActionAccept");
p = p.setDefaultAcceptLocal(true);
break;
case SetLocalDefaultActionReject:
p.debug("SetLocalDefaultActionReject");
p = p.setDefaultAcceptLocal(false);
break;
case ReturnLocalDefaultAction:
p.debug("ReturnLocalDefaultAction");
// TODO: need to set local default action in an environment
if (p.getDefaultAcceptLocal()) {
result = returnValue(p, result, true);
} else {
result = returnValue(p, result, false);
}
break;
case FallThrough:
p.debug("Fallthrough");
result = fallthrough(p, result);
break;
case Return:
// TODO: assumming this happens at the end of the function, so it is ignored for now.
p.debug("Return");
break;
case RemovePrivateAs:
p.debug("RemovePrivateAs");
System.out.println("Warning: use of unimplemented feature RemovePrivateAs");
break;
default:
throw new BatfishException("TODO: computeTransferFunction: " + ss.getType());
}
} else if (stmt instanceof If) {
p.debug("If");
If i = (If) stmt;
TransferResult<BoolExpr, BoolExpr> r = compute(i.getGuard(), p);
result = result.addChangedVariables(r);
BoolExpr guard = (BoolExpr) r.getReturnValue().simplify();
String str = guard.toString();
// If there are updates in the guard, add them to the parameter p before entering branches
for (Pair<String, Expr> changed : r.getChangedVariables()) {
p.debug("CHANGED: " + changed.getFirst());
updateSingleValue(p, changed.getFirst(), changed.getSecond());
}
p.debug("guard: " + str);
// If we know the branch ahead of time, then specialize
switch(str) {
case "true":
p.debug("True Branch");
result = compute(i.getTrueStatements(), p.indent(), result);
break;
case "false":
p.debug("False Branch");
compute(i.getFalseStatements(), p.indent(), result);
break;
default:
p.debug("True Branch");
// clear changed variables before proceeding
TransferParam<SymbolicRoute> p1 = p.indent().setData(p.getData().copy());
TransferParam<SymbolicRoute> p2 = p.indent().setData(p.getData().copy());
TransferResult<BoolExpr, BoolExpr> trueBranch = compute(i.getTrueStatements(), p1, initialResult());
p.debug("False Branch");
TransferResult<BoolExpr, BoolExpr> falseBranch = compute(i.getFalseStatements(), p2, initialResult());
p.debug("JOIN");
PList<Pair<String, Pair<Expr, Expr>>> pairs = trueBranch.mergeChangedVariables(falseBranch);
// Extract and deal with the return value first so that other
// variables have this reflected in their value
int idx = pairs.find(pair -> pair.getFirst().equals("RETURN"));
if (idx >= 0) {
Pair<String, Pair<Expr, Expr>> ret = pairs.get(idx);
pairs = pairs.minus(idx);
pairs = pairs.plus(pairs.size(), ret);
}
for (Pair<String, Pair<Expr, Expr>> pair : pairs) {
String s = pair.getFirst();
p.debug("CHANGED: " + s);
Pair<Expr, Expr> x = joinPoint(p, result, guard, pair);
result = result.addChangedVariable(s, x.getFirst());
if (s.equals("RETURN")) {
result = result.setReturnValue((BoolExpr) x.getFirst()).setReturnAssignedValue((BoolExpr) x.getSecond());
}
if (s.equals("FALLTHROUGH")) {
result = result.setFallthroughValue((BoolExpr) x.getFirst()).setReturnAssignedValue((BoolExpr) x.getSecond());
}
}
break;
}
} else if (stmt instanceof SetDefaultPolicy) {
p.debug("SetDefaultPolicy");
p = p.setDefaultPolicy((SetDefaultPolicy) stmt);
} else if (stmt instanceof SetMetric) {
p.debug("SetMetric");
// TODO: what is the semantics for BGP? Is this MED?
if (!_current.getProto().isBgp()) {
SetMetric sm = (SetMetric) stmt;
LongExpr ie = sm.getMetric();
ArithExpr newValue = applyLongExprModification(p.getData().getMetric(), ie);
newValue = _enc.mkIf(result.getReturnAssignedValue(), p.getData().getMetric(), newValue);
ArithExpr x = createArithVariableWith(p, "METRIC", newValue);
p.getData().setMetric(x);
result = result.addChangedVariable("METRIC", x);
}
} else if (stmt instanceof SetOspfMetricType) {
p.debug("SetOspfMetricType");
SetOspfMetricType somt = (SetOspfMetricType) stmt;
OspfMetricType mt = somt.getMetricType();
SymbolicOspfType t;
if (mt == OspfMetricType.E1) {
t = new SymbolicOspfType(_enc, OspfType.E1);
} else {
t = new SymbolicOspfType(_enc, OspfType.E2);
}
BitVecExpr newValue = t.getBitVec();
newValue = _enc.mkIf(result.getReturnAssignedValue(), p.getData().getOspfType().getBitVec(), newValue);
BitVecExpr x = createBitVecVariableWith(p, "OSPF-TYPE", 2, newValue);
p.getData().getOspfType().setBitVec(x);
result = result.addChangedVariable("OSPF-TYPE", x);
} else if (stmt instanceof SetLocalPreference) {
p.debug("SetLocalPreference");
SetLocalPreference slp = (SetLocalPreference) stmt;
IntExpr ie = slp.getLocalPreference();
ArithExpr newValue = applyIntExprModification(p.getData().getLocalPref(), ie);
newValue = _enc.mkIf(result.getReturnAssignedValue(), p.getData().getLocalPref(), newValue);
ArithExpr x = createArithVariableWith(p, "LOCAL-PREF", newValue);
p.getData().setLocalPref(x);
result = result.addChangedVariable("LOCAL-PREF", x);
} else if (stmt instanceof AddCommunity) {
p.debug("AddCommunity");
AddCommunity ac = (AddCommunity) stmt;
Set<CommunityVar> comms = _enc.getGraph().findAllCommunities(_conf, ac.getExpr());
for (CommunityVar cvar : comms) {
BoolExpr newValue = _enc.mkIf(result.getReturnAssignedValue(), p.getData().getCommunities().get(cvar), _enc.mkTrue());
BoolExpr x = createBoolVariableWith(p, cvar.getValue(), newValue);
p.getData().getCommunities().put(cvar, x);
result = result.addChangedVariable(cvar.getValue(), x);
}
} else if (stmt instanceof SetCommunity) {
p.debug("SetCommunity");
SetCommunity sc = (SetCommunity) stmt;
Set<CommunityVar> comms = _enc.getGraph().findAllCommunities(_conf, sc.getExpr());
for (CommunityVar cvar : comms) {
BoolExpr newValue = _enc.mkIf(result.getReturnAssignedValue(), p.getData().getCommunities().get(cvar), _enc.mkTrue());
BoolExpr x = createBoolVariableWith(p, cvar.getValue(), newValue);
p.getData().getCommunities().put(cvar, x);
result = result.addChangedVariable(cvar.getValue(), x);
}
} else if (stmt instanceof DeleteCommunity) {
p.debug("DeleteCommunity");
DeleteCommunity ac = (DeleteCommunity) stmt;
Set<CommunityVar> comms = _enc.getGraph().findAllCommunities(_conf, ac.getExpr());
Set<CommunityVar> toDelete = new HashSet<>();
// Find comms to delete
for (CommunityVar cvar : comms) {
if (cvar.getType() == Type.REGEX) {
toDelete.addAll(_enc.getCommunityDependencies().get(cvar));
} else {
toDelete.add(cvar);
}
}
// Delete each community
for (CommunityVar cvar : toDelete) {
BoolExpr newValue = _enc.mkIf(result.getReturnAssignedValue(), p.getData().getCommunities().get(cvar), _enc.mkFalse());
BoolExpr x = createBoolVariableWith(p, cvar.getValue(), newValue);
p.getData().getCommunities().put(cvar, x);
result = result.addChangedVariable(cvar.getValue(), x);
}
} else if (stmt instanceof RetainCommunity) {
p.debug("RetainCommunity");
// no op
} else if (stmt instanceof PrependAsPath) {
p.debug("PrependAsPath");
PrependAsPath pap = (PrependAsPath) stmt;
Integer prependCost = prependLength(pap.getExpr());
ArithExpr newValue = _enc.mkSum(p.getData().getMetric(), _enc.mkInt(prependCost));
newValue = _enc.mkIf(result.getReturnAssignedValue(), p.getData().getMetric(), newValue);
ArithExpr x = createArithVariableWith(p, "METRIC", newValue);
p.getData().setMetric(x);
result = result.addChangedVariable("METRIC", x);
} else if (stmt instanceof SetOrigin) {
p.debug("SetOrigin");
System.out.println("Warning: use of unimplemented feature SetOrigin");
} else if (stmt instanceof SetNextHop) {
p.debug("SetNextHop");
System.out.println("Warning: use of unimplemented feature SetNextHop");
} else {
String s = (_isExport ? "export" : "import");
String msg = String.format("Unimplemented feature %s for %s transfer function on interface %s", stmt.toString(), s, _graphEdge.toString());
throw new BatfishException(msg);
}
}
// If this is the outermost call, then we relate the variables
if (p.getInitialCall()) {
p.debug("InitialCall finalizing");
// Apply the default action
if (!doesReturn) {
p.debug("Applying default action: " + p.getDefaultAccept());
if (p.getDefaultAccept()) {
result = returnValue(p, result, true);
} else {
result = returnValue(p, result, false);
}
}
BoolExpr related = relateVariables(p, result);
BoolExpr retValue = _enc.mkIf(result.getReturnValue(), related, _enc.mkNot(_current.getPermitted()));
result = result.setReturnValue(retValue);
}
return result;
}
Aggregations