use of org.batfish.datamodel.BgpNeighbor in project batfish by batfish.
the class CommonUtil method initRemoteBgpNeighbors.
/**
* Initialize BGP neighbors for all nodes.
*
* @param configurations map of all configurations, keyed by hostname
* @param ipOwners mapping of Ips to a set of nodes (hostnames) that owns those IPs
* @param checkReachability whether bgp neighbor reachability should be checked
* @param flowProcessor dataplane plugin to use to check reachability. Must not be {@code null} if
* {@code checkReachability = true}
* @param dp dataplane to use to check reachability. Must not be {@code null} if {@code
* checkReachability = true}
*/
public static void initRemoteBgpNeighbors(Map<String, Configuration> configurations, Map<Ip, Set<String>> ipOwners, boolean checkReachability, @Nullable FlowProcessor flowProcessor, @Nullable DataPlane dp) {
// TODO: handle duplicate ips on different vrfs
Map<BgpNeighbor, Ip> remoteAddresses = new IdentityHashMap<>();
Map<Ip, Set<BgpNeighbor>> localAddresses = new HashMap<>();
/*
* Construct maps indicating which neighbor owns which Ip Address
*/
for (Configuration node : configurations.values()) {
String hostname = node.getHostname();
for (Vrf vrf : node.getVrfs().values()) {
BgpProcess proc = vrf.getBgpProcess();
if (proc == null) {
// nothing to do if no bgp process on this VRF
continue;
}
for (BgpNeighbor bgpNeighbor : proc.getNeighbors().values()) {
/*
* Begin by initializing candidate neighbors to an empty set
*/
bgpNeighbor.initCandidateRemoteBgpNeighbors();
// Skip things we don't handle
if (bgpNeighbor.getPrefix().getPrefixLength() < Prefix.MAX_PREFIX_LENGTH) {
throw new BatfishException(hostname + ": Do not support dynamic bgp sessions at this time: " + bgpNeighbor.getPrefix());
}
Ip remoteAddress = bgpNeighbor.getAddress();
if (remoteAddress == null) {
throw new BatfishException(hostname + ": Could not determine remote address of bgp neighbor: " + bgpNeighbor);
}
Ip localAddress = bgpNeighbor.getLocalIp();
if (localAddress == null || !ipOwners.containsKey(localAddress) || !ipOwners.get(localAddress).contains(hostname)) {
// Local address is not owned by anybody
continue;
}
remoteAddresses.put(bgpNeighbor, remoteAddress);
// Add this neighbor as owner of its local address
localAddresses.computeIfAbsent(localAddress, k -> Collections.newSetFromMap(new IdentityHashMap<>())).add(bgpNeighbor);
}
}
}
/*
* For each neighbor, construct the set of candidate neighbors, then filter out impossible
* sessions.
*/
for (Entry<BgpNeighbor, Ip> e : remoteAddresses.entrySet()) {
BgpNeighbor bgpNeighbor = e.getKey();
Ip remoteAddress = e.getValue();
Ip localAddress = bgpNeighbor.getLocalIp();
int localLocalAs = bgpNeighbor.getLocalAs();
int localRemoteAs = bgpNeighbor.getRemoteAs();
/*
* Let the set of candidate neighbors be set of neighbors that own the remoteAddress
*/
Set<BgpNeighbor> remoteBgpNeighborCandidates = localAddresses.get(remoteAddress);
if (remoteBgpNeighborCandidates == null) {
// No possible remote neighbors
continue;
}
/*
* Filter the set of candidate neighbors based on these checks:
* - Remote neighbor's remote address is the same as our local address
* - Remote neighbor's remote AS is the same as our local AS (and vice-versa)
*/
for (BgpNeighbor remoteBgpNeighborCandidate : remoteBgpNeighborCandidates) {
int remoteLocalAs = remoteBgpNeighborCandidate.getLocalAs();
int remoteRemoteAs = remoteBgpNeighborCandidate.getRemoteAs();
Ip reciprocalRemoteIp = remoteBgpNeighborCandidate.getAddress();
if (localAddress.equals(reciprocalRemoteIp) && localLocalAs == remoteRemoteAs && localRemoteAs == remoteLocalAs) {
/*
* Fairly confident establishing the session is possible here, but still check
* reachability if needed.
* We should check reachability only for eBgp multihop or iBgp
*/
if (checkReachability && (bgpNeighbor.getEbgpMultihop() || localLocalAs == remoteLocalAs)) {
/*
* Ensure that the session can be established by running traceroute in both directions
*/
if (flowProcessor == null || dp == null) {
throw new BatfishException("Cannot compute neighbor reachability without a dataplane");
}
Flow.Builder fb = new Flow.Builder();
fb.setIpProtocol(IpProtocol.TCP);
fb.setTag("neighbor-resolution");
fb.setIngressNode(bgpNeighbor.getOwner().getHostname());
fb.setSrcIp(localAddress);
fb.setDstIp(remoteAddress);
fb.setSrcPort(NamedPort.EPHEMERAL_LOWEST.number());
fb.setDstPort(NamedPort.BGP.number());
Flow forwardFlow = fb.build();
fb.setIngressNode(remoteBgpNeighborCandidate.getOwner().getHostname());
fb.setSrcIp(forwardFlow.getDstIp());
fb.setDstIp(forwardFlow.getSrcIp());
fb.setSrcPort(forwardFlow.getDstPort());
fb.setDstPort(forwardFlow.getSrcPort());
Flow backwardFlow = fb.build();
SortedMap<Flow, Set<FlowTrace>> traces = flowProcessor.processFlows(dp, ImmutableSet.of(forwardFlow, backwardFlow));
if (traces.values().stream().map(fts -> fts.stream().allMatch(ft -> ft.getDisposition() != FlowDisposition.ACCEPTED)).anyMatch(Predicate.isEqual(true))) {
/*
* If either flow has all traceroutes fail, do not consider the neighbor valid
*/
continue;
}
bgpNeighbor.getCandidateRemoteBgpNeighbors().add(remoteBgpNeighborCandidate);
} else {
bgpNeighbor.getCandidateRemoteBgpNeighbors().add(remoteBgpNeighborCandidate);
}
}
}
Set<BgpNeighbor> finalCandidates = bgpNeighbor.getCandidateRemoteBgpNeighbors();
if (finalCandidates.size() > 1) {
/* If we still have not narrowed it down to a single neighbor,
* pick based on sorted hostnames
*/
SortedMap<String, BgpNeighbor> hostnameToNeighbor = finalCandidates.stream().collect(ImmutableSortedMap.toImmutableSortedMap(String::compareTo, k -> k.getOwner().getHostname(), Function.identity()));
bgpNeighbor.setRemoteBgpNeighbor(hostnameToNeighbor.get(hostnameToNeighbor.firstKey()));
} else if (finalCandidates.size() == 1) {
bgpNeighbor.setRemoteBgpNeighbor(finalCandidates.iterator().next());
} else {
bgpNeighbor.setRemoteBgpNeighbor(null);
}
}
}
use of org.batfish.datamodel.BgpNeighbor in project batfish by batfish.
the class SelfNextHop method getNextHopIp.
@Override
public Ip getNextHopIp(Environment environment) {
// TODO: make work for dynamic sessions
Prefix prefix = new Prefix(environment.getPeerAddress(), Prefix.MAX_PREFIX_LENGTH);
BgpNeighbor neighbor = environment.getVrf().getBgpProcess().getNeighbors().get(prefix);
Ip localIp = neighbor.getLocalIp();
return localIp;
}
use of org.batfish.datamodel.BgpNeighbor in project batfish by batfish.
the class VirtualRouter method initBaseBgpRibs.
public void initBaseBgpRibs(Set<BgpAdvertisement> externalAdverts, Map<Ip, Set<String>> ipOwners) {
if (_vrf.getBgpProcess() != null) {
int ebgpAdmin = RoutingProtocol.BGP.getDefaultAdministrativeCost(_c.getConfigurationFormat());
int ibgpAdmin = RoutingProtocol.IBGP.getDefaultAdministrativeCost(_c.getConfigurationFormat());
for (BgpAdvertisement advert : externalAdverts) {
if (advert.getDstNode().equals(_c.getHostname())) {
Ip dstIp = advert.getDstIp();
Set<String> dstIpOwners = ipOwners.get(dstIp);
String hostname = _c.getHostname();
if (dstIpOwners == null || !dstIpOwners.contains(hostname)) {
continue;
}
Ip srcIp = advert.getSrcIp();
// TODO: support passive bgp connections
Prefix srcPrefix = new Prefix(srcIp, Prefix.MAX_PREFIX_LENGTH);
BgpNeighbor neighbor = _vrf.getBgpProcess().getNeighbors().get(srcPrefix);
if (neighbor != null) {
BgpAdvertisementType type = advert.getType();
BgpRoute.Builder outgoingRouteBuilder = new BgpRoute.Builder();
boolean ebgp;
boolean received;
switch(type) {
case EBGP_RECEIVED:
ebgp = true;
received = true;
break;
case EBGP_SENT:
ebgp = true;
received = false;
break;
case IBGP_RECEIVED:
ebgp = false;
received = true;
break;
case IBGP_SENT:
ebgp = false;
received = false;
break;
case EBGP_ORIGINATED:
case IBGP_ORIGINATED:
default:
throw new BatfishException("Missing or invalid bgp advertisement type");
}
BgpMultipathRib targetRib = ebgp ? _baseEbgpRib : _baseIbgpRib;
RoutingProtocol targetProtocol = ebgp ? RoutingProtocol.BGP : RoutingProtocol.IBGP;
if (received) {
int admin = ebgp ? ebgpAdmin : ibgpAdmin;
AsPath asPath = advert.getAsPath();
SortedSet<Long> clusterList = advert.getClusterList();
SortedSet<Long> communities = new TreeSet<>(advert.getCommunities());
int localPreference = advert.getLocalPreference();
long metric = advert.getMed();
Prefix network = advert.getNetwork();
Ip nextHopIp = advert.getNextHopIp();
Ip originatorIp = advert.getOriginatorIp();
OriginType originType = advert.getOriginType();
RoutingProtocol srcProtocol = advert.getSrcProtocol();
int weight = advert.getWeight();
BgpRoute.Builder builder = new BgpRoute.Builder();
builder.setAdmin(admin);
builder.setAsPath(asPath.getAsSets());
builder.setClusterList(clusterList);
builder.setCommunities(communities);
builder.setLocalPreference(localPreference);
builder.setMetric(metric);
builder.setNetwork(network);
builder.setNextHopIp(nextHopIp);
builder.setOriginatorIp(originatorIp);
builder.setOriginType(originType);
builder.setProtocol(targetProtocol);
// TODO: support external route reflector clients
builder.setReceivedFromIp(advert.getSrcIp());
builder.setReceivedFromRouteReflectorClient(false);
builder.setSrcProtocol(srcProtocol);
// TODO: possibly suppport setting tag
builder.setWeight(weight);
BgpRoute route = builder.build();
targetRib.mergeRoute(route);
} else {
int localPreference;
if (ebgp) {
localPreference = BgpRoute.DEFAULT_LOCAL_PREFERENCE;
} else {
localPreference = advert.getLocalPreference();
}
outgoingRouteBuilder.setAsPath(advert.getAsPath().getAsSets());
outgoingRouteBuilder.setCommunities(new TreeSet<>(advert.getCommunities()));
outgoingRouteBuilder.setLocalPreference(localPreference);
outgoingRouteBuilder.setMetric(advert.getMed());
outgoingRouteBuilder.setNetwork(advert.getNetwork());
outgoingRouteBuilder.setNextHopIp(advert.getNextHopIp());
outgoingRouteBuilder.setOriginatorIp(advert.getOriginatorIp());
outgoingRouteBuilder.setOriginType(advert.getOriginType());
outgoingRouteBuilder.setProtocol(targetProtocol);
outgoingRouteBuilder.setReceivedFromIp(advert.getSrcIp());
// TODO:
// outgoingRouteBuilder.setReceivedFromRouteReflectorClient(...);
outgoingRouteBuilder.setSrcProtocol(advert.getSrcProtocol());
BgpRoute transformedOutgoingRoute = outgoingRouteBuilder.build();
BgpRoute.Builder transformedIncomingRouteBuilder = new BgpRoute.Builder();
// Incoming originatorIp
transformedIncomingRouteBuilder.setOriginatorIp(transformedOutgoingRoute.getOriginatorIp());
// Incoming receivedFromIp
transformedIncomingRouteBuilder.setReceivedFromIp(transformedOutgoingRoute.getReceivedFromIp());
// Incoming clusterList
transformedIncomingRouteBuilder.getClusterList().addAll(transformedOutgoingRoute.getClusterList());
// Incoming receivedFromRouteReflectorClient
transformedIncomingRouteBuilder.setReceivedFromRouteReflectorClient(transformedOutgoingRoute.getReceivedFromRouteReflectorClient());
// Incoming asPath
transformedIncomingRouteBuilder.setAsPath(transformedOutgoingRoute.getAsPath().getAsSets());
// Incoming communities
transformedIncomingRouteBuilder.getCommunities().addAll(transformedOutgoingRoute.getCommunities());
// Incoming protocol
transformedIncomingRouteBuilder.setProtocol(targetProtocol);
// Incoming network
transformedIncomingRouteBuilder.setNetwork(transformedOutgoingRoute.getNetwork());
// Incoming nextHopIp
transformedIncomingRouteBuilder.setNextHopIp(transformedOutgoingRoute.getNextHopIp());
// Incoming originType
transformedIncomingRouteBuilder.setOriginType(transformedOutgoingRoute.getOriginType());
// Incoming localPreference
transformedIncomingRouteBuilder.setLocalPreference(transformedOutgoingRoute.getLocalPreference());
// Incoming admin
int admin = ebgp ? ebgpAdmin : ibgpAdmin;
transformedIncomingRouteBuilder.setAdmin(admin);
// Incoming metric
transformedIncomingRouteBuilder.setMetric(transformedOutgoingRoute.getMetric());
// Incoming srcProtocol
transformedIncomingRouteBuilder.setSrcProtocol(targetProtocol);
String importPolicyName = neighbor.getImportPolicy();
if (ebgp && transformedOutgoingRoute.getAsPath().containsAs(neighbor.getLocalAs()) && !neighbor.getAllowLocalAsIn()) {
// disable-peer-as-check (getAllowRemoteAsOut) is set
continue;
}
/*
* CREATE INCOMING ROUTE
*/
boolean acceptIncoming = true;
if (importPolicyName != null) {
RoutingPolicy importPolicy = _c.getRoutingPolicies().get(importPolicyName);
if (importPolicy != null) {
acceptIncoming = importPolicy.process(transformedOutgoingRoute, transformedIncomingRouteBuilder, advert.getSrcIp(), _key, Direction.IN);
}
}
if (acceptIncoming) {
BgpRoute transformedIncomingRoute = transformedIncomingRouteBuilder.build();
targetRib.mergeRoute(transformedIncomingRoute);
}
}
}
}
}
}
importRib(_ebgpMultipathRib, _baseEbgpRib);
importRib(_ebgpBestPathRib, _baseEbgpRib);
importRib(_bgpBestPathRib, _baseEbgpRib);
importRib(_ibgpMultipathRib, _baseIbgpRib);
importRib(_ibgpBestPathRib, _baseIbgpRib);
importRib(_bgpBestPathRib, _baseIbgpRib);
}
use of org.batfish.datamodel.BgpNeighbor in project batfish by batfish.
the class VirtualRouter method computeBgpAdvertisementsToOutside.
int computeBgpAdvertisementsToOutside(Map<Ip, Set<String>> ipOwners) {
int numAdvertisements = 0;
// If we have no BGP process, nothing to do
if (_vrf.getBgpProcess() == null) {
return numAdvertisements;
}
for (BgpNeighbor neighbor : _vrf.getBgpProcess().getNeighbors().values()) {
Ip localIp = neighbor.getLocalIp();
Set<String> localIpOwners = ipOwners.get(localIp);
String hostname = _c.getHostname();
if (localIpOwners == null || !localIpOwners.contains(hostname)) {
continue;
}
Prefix remotePrefix = neighbor.getPrefix();
if (remotePrefix.getPrefixLength() != Prefix.MAX_PREFIX_LENGTH) {
// Do not support dynamic outside neighbors
continue;
}
Ip remoteIp = remotePrefix.getStartIp();
if (ipOwners.get(remoteIp) != null) {
// Skip if neighbor is not outside the network
continue;
}
int localAs = neighbor.getLocalAs();
int remoteAs = neighbor.getRemoteAs();
String remoteHostname = remoteIp.toString();
String remoteVrfName = Configuration.DEFAULT_VRF_NAME;
RoutingPolicy exportPolicy = _c.getRoutingPolicies().get(neighbor.getExportPolicy());
boolean ebgpSession = localAs != remoteAs;
RoutingProtocol targetProtocol = ebgpSession ? RoutingProtocol.BGP : RoutingProtocol.IBGP;
Set<AbstractRoute> candidateRoutes = Collections.newSetFromMap(new IdentityHashMap<>());
// Add IGP routes
Set<AbstractRoute> activeRoutes = Collections.newSetFromMap(new IdentityHashMap<>());
activeRoutes.addAll(_mainRib.getRoutes());
for (AbstractRoute candidateRoute : activeRoutes) {
if (candidateRoute.getProtocol() != RoutingProtocol.BGP && candidateRoute.getProtocol() != RoutingProtocol.IBGP) {
candidateRoutes.add(candidateRoute);
}
}
/*
* bgp advertise-external
*
* When this is set, add best eBGP path independently of whether
* it is preempted by an iBGP or IGP route. Only applicable to
* iBGP sessions.
*/
boolean advertiseExternal = !ebgpSession && neighbor.getAdvertiseExternal();
if (advertiseExternal) {
candidateRoutes.addAll(_ebgpBestPathRib.getRoutes());
}
/*
* bgp advertise-inactive
*
* When this is set, add best BGP path independently of whether
* it is preempted by an IGP route. Only applicable to eBGP
* sessions.
*/
boolean advertiseInactive = ebgpSession && neighbor.getAdvertiseInactive();
/* Add best bgp paths if they are active, or if advertise-inactive */
for (AbstractRoute candidateRoute : _bgpBestPathRib.getRoutes()) {
if (advertiseInactive || activeRoutes.contains(candidateRoute)) {
candidateRoutes.add(candidateRoute);
}
}
/* Add all bgp paths if additional-paths active for this session */
boolean additionalPaths = !ebgpSession && neighbor.getAdditionalPathsSend() && neighbor.getAdditionalPathsSelectAll();
if (additionalPaths) {
candidateRoutes.addAll(_bgpMultipathRib.getRoutes());
}
for (AbstractRoute route : candidateRoutes) {
BgpRoute.Builder transformedOutgoingRouteBuilder = new BgpRoute.Builder();
RoutingProtocol routeProtocol = route.getProtocol();
boolean routeIsBgp = routeProtocol == RoutingProtocol.IBGP || routeProtocol == RoutingProtocol.BGP;
// originatorIP
Ip originatorIp;
if (!ebgpSession && routeProtocol.equals(RoutingProtocol.IBGP)) {
BgpRoute bgpRoute = (BgpRoute) route;
originatorIp = bgpRoute.getOriginatorIp();
} else {
originatorIp = _vrf.getBgpProcess().getRouterId();
}
transformedOutgoingRouteBuilder.setOriginatorIp(originatorIp);
transformedOutgoingRouteBuilder.setReceivedFromIp(neighbor.getLocalIp());
// for bgp remote route)
if (routeIsBgp) {
BgpRoute bgpRoute = (BgpRoute) route;
transformedOutgoingRouteBuilder.setOriginType(bgpRoute.getOriginType());
if (ebgpSession && bgpRoute.getAsPath().containsAs(neighbor.getRemoteAs()) && !neighbor.getAllowRemoteAsOut()) {
// disable-peer-as-check (getAllowRemoteAsOut) is set
continue;
}
/*
* route reflection: reflect everything received from
* clients to clients and non-clients. reflect everything
* received from non-clients to clients. Do not reflect to
* originator
*/
Ip routeOriginatorIp = bgpRoute.getOriginatorIp();
/*
* iBGP speaker should not send out routes to iBGP neighbor whose router-id is
* same as originator id of advertisement
*/
if (!ebgpSession && routeOriginatorIp != null && remoteIp.equals(routeOriginatorIp)) {
continue;
}
if (routeProtocol.equals(RoutingProtocol.IBGP) && !ebgpSession) {
boolean routeReceivedFromRouteReflectorClient = bgpRoute.getReceivedFromRouteReflectorClient();
boolean sendingToRouteReflectorClient = neighbor.getRouteReflectorClient();
transformedOutgoingRouteBuilder.getClusterList().addAll(bgpRoute.getClusterList());
if (!routeReceivedFromRouteReflectorClient && !sendingToRouteReflectorClient) {
continue;
}
if (sendingToRouteReflectorClient) {
// sender adds its local cluster id to clusterlist of
// new route
transformedOutgoingRouteBuilder.getClusterList().add(neighbor.getClusterId());
}
}
}
// Outgoing communities
if (routeIsBgp) {
BgpRoute bgpRoute = (BgpRoute) route;
transformedOutgoingRouteBuilder.setAsPath(bgpRoute.getAsPath().getAsSets());
if (neighbor.getSendCommunity()) {
transformedOutgoingRouteBuilder.getCommunities().addAll(bgpRoute.getCommunities());
}
}
if (ebgpSession) {
SortedSet<Integer> newAsPathElement = new TreeSet<>();
newAsPathElement.add(localAs);
transformedOutgoingRouteBuilder.getAsPath().add(0, newAsPathElement);
}
// Outgoing protocol
transformedOutgoingRouteBuilder.setProtocol(targetProtocol);
transformedOutgoingRouteBuilder.setNetwork(route.getNetwork());
// Outgoing metric
if (routeIsBgp) {
transformedOutgoingRouteBuilder.setMetric(route.getMetric());
}
// Outgoing nextHopIp
// Outgoing localPreference
Ip nextHopIp;
int localPreference;
if (ebgpSession || !routeIsBgp) {
nextHopIp = neighbor.getLocalIp();
localPreference = BgpRoute.DEFAULT_LOCAL_PREFERENCE;
} else {
nextHopIp = route.getNextHopIp();
BgpRoute ibgpRoute = (BgpRoute) route;
localPreference = ibgpRoute.getLocalPreference();
}
if (nextHopIp.equals(Route.UNSET_ROUTE_NEXT_HOP_IP)) {
// should only happen for ibgp
String nextHopInterface = route.getNextHopInterface();
InterfaceAddress nextHopAddress = _c.getInterfaces().get(nextHopInterface).getAddress();
if (nextHopAddress == null) {
throw new BatfishException("route's nextHopInterface has no address");
}
nextHopIp = nextHopAddress.getIp();
}
transformedOutgoingRouteBuilder.setNextHopIp(nextHopIp);
transformedOutgoingRouteBuilder.setLocalPreference(localPreference);
// Outgoing srcProtocol
transformedOutgoingRouteBuilder.setSrcProtocol(route.getProtocol());
/*
* CREATE OUTGOING ROUTE
*/
boolean acceptOutgoing = exportPolicy.process(route, transformedOutgoingRouteBuilder, remoteIp, remoteVrfName, Direction.OUT);
if (acceptOutgoing) {
BgpRoute transformedOutgoingRoute = transformedOutgoingRouteBuilder.build();
// Record sent advertisement
BgpAdvertisementType sentType = ebgpSession ? BgpAdvertisementType.EBGP_SENT : BgpAdvertisementType.IBGP_SENT;
Ip sentOriginatorIp = transformedOutgoingRoute.getOriginatorIp();
SortedSet<Long> sentClusterList = transformedOutgoingRoute.getClusterList();
AsPath sentAsPath = transformedOutgoingRoute.getAsPath();
SortedSet<Long> sentCommunities = transformedOutgoingRoute.getCommunities();
Prefix sentNetwork = route.getNetwork();
Ip sentNextHopIp;
String sentSrcNode = hostname;
String sentSrcVrf = _vrf.getName();
Ip sentSrcIp = neighbor.getLocalIp();
String sentDstNode = remoteHostname;
String sentDstVrf = remoteVrfName;
Ip sentDstIp = remoteIp;
int sentWeight = -1;
if (ebgpSession) {
sentNextHopIp = nextHopIp;
} else {
sentNextHopIp = transformedOutgoingRoute.getNextHopIp();
}
int sentLocalPreference = transformedOutgoingRoute.getLocalPreference();
long sentMed = transformedOutgoingRoute.getMetric();
OriginType sentOriginType = transformedOutgoingRoute.getOriginType();
RoutingProtocol sentSrcProtocol = targetProtocol;
BgpAdvertisement sentAdvert = new BgpAdvertisement(sentType, sentNetwork, sentNextHopIp, sentSrcNode, sentSrcVrf, sentSrcIp, sentDstNode, sentDstVrf, sentDstIp, sentSrcProtocol, sentOriginType, sentLocalPreference, sentMed, sentOriginatorIp, sentAsPath, sentCommunities, sentClusterList, sentWeight);
_sentBgpAdvertisements.add(sentAdvert);
numAdvertisements++;
}
}
}
return numAdvertisements;
}
use of org.batfish.datamodel.BgpNeighbor 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);
}
}
}
Aggregations