package org.batfish.datamodel; import java.util.LinkedHashSet; import java.util.Set; import org.batfish.common.util.CommonUtil; import org.batfish.common.util.ComparableStructure; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyDescription; import com.kjetland.jackson.jsonSchema.annotations.JsonSchemaDescription; /** * Represents a peering with a single router (by ip address) acting as a bgp * peer to the router whose configuration's BGP process contains this object */ @JsonSchemaDescription("A configured e/iBGP peering relationship") public final class BgpNeighbor extends ComparableStructure<Prefix> { public static final class BgpNeighborSummary extends ComparableStructure<String> { private static final String DESCRIPTION_VAR = "description"; private static final String GROUP_VAR = "group"; private static final String LOCAL_AS_VAR = "localAs"; private static final String LOCAL_IP_VAR = "localIp"; private static final String REMOTE_AS_VAR = "remoteAs"; private static final String REMOTE_IP_VAR = "remoteIp"; private static final String REMOTE_PREFIX_VAR = "dynamicRemotePrefix"; /** * */ private static final long serialVersionUID = 1L; private static final String VRF_VAR = "vrf"; private final String _description; private final String _group; private final int _localAs; private final Ip _localIp; private final int _remoteAs; private final Ip _remoteIp; private final Prefix _remotePrefix; private final String _vrf; public BgpNeighborSummary(BgpNeighbor bgpNeighbor) { super(bgpNeighbor.getOwner().getName() + ":" + (bgpNeighbor.getDynamic() ? bgpNeighbor.getPrefix().toString() : bgpNeighbor.getAddress().toString())); _description = bgpNeighbor._description; _group = bgpNeighbor._group; _localAs = bgpNeighbor._localAs; _localIp = bgpNeighbor._localIp; _remoteAs = bgpNeighbor._remoteAs; _remoteIp = bgpNeighbor.getAddress(); _remotePrefix = bgpNeighbor._key; _vrf = bgpNeighbor._vrf; } @JsonCreator public BgpNeighborSummary(@JsonProperty(NAME_VAR) String name, @JsonProperty(DESCRIPTION_VAR) String description, @JsonProperty(GROUP_VAR) String group, @JsonProperty(LOCAL_AS_VAR) int localAs, @JsonProperty(LOCAL_IP_VAR) Ip localIp, @JsonProperty(REMOTE_AS_VAR) int remoteAs, @JsonProperty(REMOTE_IP_VAR) Ip remoteIp, @JsonProperty(REMOTE_PREFIX_VAR) Prefix remotePrefix, @JsonProperty(VRF_VAR) String vrf) { super(name); _description = description; _group = group; _localAs = localAs; _localIp = localIp; _remoteAs = remoteAs; _remoteIp = remoteIp; _remotePrefix = remotePrefix; _vrf = vrf; } @JsonProperty(DESCRIPTION_VAR) public String getDescription() { return _description; } @JsonProperty(GROUP_VAR) public String getGroup() { return _group; } @JsonProperty(LOCAL_AS_VAR) public int getLocalAs() { return _localAs; } @JsonProperty(LOCAL_IP_VAR) public Ip getLocalIp() { return _localIp; } @JsonIgnore public Prefix getPrefix() { if (_remotePrefix == null) { return new Prefix(_remoteIp, 32); } else { return _remotePrefix; } } @JsonProperty(REMOTE_AS_VAR) public int getRemoteAs() { return _remoteAs; } @JsonProperty(REMOTE_IP_VAR) public Ip getRemoteIp() { return _remoteIp; } @JsonProperty(REMOTE_PREFIX_VAR) public Prefix getRemotePrefix() { return _remotePrefix; } @JsonProperty(VRF_VAR) public String getVrf() { return _vrf; } } private static final String ADDRESS_VAR = "address"; private static final String ADVERTISE_EXTERNAL_VAR = "advertiseExternal"; private static final String ADVERTISE_INACTIVE_VAR = "advertiseInactive"; private static final String ALLOW_LOCAL_AS_IN_VAR = "allowLocalAsIn"; private static final String ALLOW_REMOTE_AS_OUT_VAR = "allowRemoteAsOut"; private static final String CLUSTER_ID_VAR = "clusterId"; private static final String DEFAULT_METRIC_VAR = "defaultMetric"; private static final String DESCRIPTION_VAR = "description"; private static final String DYNAMIC_VAR = "dynamic"; private static final String EBGP_MULTIHOP_VAR = "ebgpMultihop"; private static final String GENERATED_ROUTES_VAR = "generatedRoutes"; private static final String GROUP_VAR = "group"; private static final String LOCAL_AS_VAR = "localAs"; private static final String LOCAL_IP_VAR = "localIp"; private static final String NAME_VAR = "name"; private static final String OWNER_VAR = "owner"; private static final String REMOTE_AS_VAR = "remoteAs"; private static final String REMOTE_PREFIX_VAR = "remotePrefix"; private static final String SEND_COMMUNITY_VAR = "sendCommunity"; /** * */ private static final long serialVersionUID = 1L; private boolean _advertiseExternal; private boolean _advertiseInactive; private boolean _allowLocalAsIn; private boolean _allowRemoteAsOut; private transient Set<BgpNeighbor> _candidateRemoteBgpNeighbors; /** * The cluster id associated with this peer to be used in route reflection */ private Long _clusterId; /** * The default metric associated with routes sent to this peer */ private int _defaultMetric; private String _description; private boolean _ebgpMultihop; private String _exportPolicy; /** * The set of generated and/or aggregate routes to be potentially sent to * this peer before outbound policies are taken into account */ private Set<GeneratedRoute> _generatedRoutes; /** * The group name associated with this peer in the vendor-specific * configuration from which the containing configuration is derived. This * field is OPTIONAL and should not impact the subsequent data plane * computation. */ private String _group; private String _importPolicy; /** * The autonomous system number of the containing BGP process as reported to * this peer */ private Integer _localAs; /** * The ip address of the containing router as reported to this peer */ private Ip _localIp; private Configuration _owner; /** * The autonomous system number that the containing BGP process considers * this peer to have. */ private Integer _remoteAs; private transient BgpNeighbor _remoteBgpNeighbor; private boolean _routeReflectorClient; /** * Flag governing whether to include community numbers in outgoing route * advertisements to this peer */ private boolean _sendCommunity; private String _vrf; @SuppressWarnings("unused") private BgpNeighbor() { this(null); } /** * Constructs a BgpNeighbor with the given peer ip address for * {@link #_address} * * @param address */ public BgpNeighbor(Ip address, Configuration owner) { this(new Prefix(address, 32), owner); } @JsonCreator public BgpNeighbor(@JsonProperty(NAME_VAR) Prefix prefix) { super(prefix); _generatedRoutes = new LinkedHashSet<>(); } /** * Constructs a BgpNeighbor with the given peer dynamic ip range for * {@link #_network} * * @param prefix */ public BgpNeighbor(Prefix prefix, Configuration owner) { this(prefix); _owner = owner; } @Override public boolean equals(Object o) { if (this == o) { return true; } BgpNeighbor other = (BgpNeighbor) o; if (this._advertiseExternal != other._advertiseExternal) { return false; } if (this._advertiseInactive != other._advertiseInactive) { return false; } if (this._allowLocalAsIn != other._allowLocalAsIn) { return false; } if (this._allowRemoteAsOut != other._allowRemoteAsOut) { return false; } if (_clusterId == null) { if (other._clusterId != null) { return false; } } else if (!this._clusterId.equals(other._clusterId)) { return false; } if (this._defaultMetric != other._defaultMetric) { return false; } // we will skip description if (this._ebgpMultihop != other._ebgpMultihop) { return false; } if (!this._exportPolicy.equals(other._exportPolicy)) { return false; } // we will skip generated routes. if (!CommonUtil.bothNullOrEqual(this._group, other._group)) { return false; } if (!CommonUtil.bothNullOrEqual(this._importPolicy, other._importPolicy)) { return false; } if (!this._localAs.equals(other._localAs)) { return false; } if (!CommonUtil.bothNullOrEqual(this._localIp, other._localIp)) { return false; } // we will skip owner. if (!this._remoteAs.equals(other._remoteAs)) { return false; } if (this._routeReflectorClient != other._routeReflectorClient) { return false; } if (this._sendCommunity != other._sendCommunity) { return false; } return true; } /** * @return {@link #_address} */ @JsonProperty(ADDRESS_VAR) @JsonPropertyDescription("The IPV4 address of the remote peer if not dynamic (passive)") public Ip getAddress() { if (_key != null && _key.getPrefixLength() == 32) { return _key.getAddress(); } else { return null; } } @JsonProperty(ADVERTISE_EXTERNAL_VAR) @JsonPropertyDescription("Whether to advertise the best eBGP route for each network independently of whether it is the best BGP route for that network") public boolean getAdvertiseExternal() { return _advertiseExternal; } @JsonProperty(ADVERTISE_INACTIVE_VAR) @JsonPropertyDescription("Whether to advertise the best BGP route for each network independently of whether it is the best overall route for that network") public boolean getAdvertiseInactive() { return _advertiseInactive; } @JsonProperty(ALLOW_LOCAL_AS_IN_VAR) @JsonPropertyDescription("Whether to allow reception of advertisements containing the local AS number in the AS-path") public boolean getAllowLocalAsIn() { return _allowLocalAsIn; } @JsonProperty(ALLOW_REMOTE_AS_OUT_VAR) @JsonPropertyDescription("Whether to allow sending of advertisements containing the remote AS number in the AS-path") public boolean getAllowRemoteAsOut() { return _allowRemoteAsOut; } @JsonIgnore public Set<BgpNeighbor> getCandidateRemoteBgpNeighbors() { return _candidateRemoteBgpNeighbors; } /** * @return {@link #_clusterId} */ @JsonProperty(CLUSTER_ID_VAR) @JsonPropertyDescription("Route-reflection cluster-id for this peer") public Long getClusterId() { return _clusterId; } /** * @return {@link #_defaultMetric} */ @JsonProperty(DEFAULT_METRIC_VAR) @JsonPropertyDescription("Default MED for routes sent to this neighbor") public int getDefaultMetric() { return _defaultMetric; } @JsonProperty(DESCRIPTION_VAR) @JsonPropertyDescription("Description of this peer") public String getDescription() { return _description; } @JsonProperty(DYNAMIC_VAR) @JsonPropertyDescription("Whether this represents a connection to a specific peer (false) or a passive connection to a network of peers (true)") public boolean getDynamic() { return _key != null && _key.getPrefixLength() < 32; } @JsonProperty(EBGP_MULTIHOP_VAR) @JsonPropertyDescription("Whether to allow establishment of a multihop eBGP connection with this peer") public boolean getEbgpMultihop() { return _ebgpMultihop; } @JsonPropertyDescription("The policy governing all advertisements sent to this peer") public String getExportPolicy() { return _exportPolicy; } /** * @return {@link #_generatedRoutes} */ @JsonProperty(GENERATED_ROUTES_VAR) @JsonPropertyDescription("Generated routes specific to this peer not otherwise imported into any of this node's RIBs") public Set<GeneratedRoute> getGeneratedRoutes() { return _generatedRoutes; } /** * @return {@link #_group} */ @JsonProperty(GROUP_VAR) @JsonPropertyDescription("Name of a group in the original vendor-specific configuration to which this peer is assigned") public String getGroup() { return _group; } @JsonPropertyDescription("Routing policy governing all advertisements received from this peer") public String getImportPolicy() { return _importPolicy; } /** * @return {@link #_localAs} */ @JsonProperty(LOCAL_AS_VAR) @JsonPropertyDescription("The local autonomous sysem of this peering") public Integer getLocalAs() { return _localAs; } /** * @return {@link #_localIp} */ @JsonProperty(LOCAL_IP_VAR) @JsonPropertyDescription("The local (source) IPV4 address of this peering") public Ip getLocalIp() { return _localIp; } @JsonIgnore public Configuration getOwner() { return _owner; } /** * @return {@link #_network} */ @JsonProperty(REMOTE_PREFIX_VAR) @JsonPropertyDescription("The remote (destination) IPV4 address of this peering (when prefix-length is 32), or the network of peers allowed to connect on this peering (otherwise)") public Prefix getPrefix() { return _key; } /** * @return {@link #_remoteAs} */ @JsonProperty(REMOTE_AS_VAR) @JsonPropertyDescription("The remote autonomous sysem of this peering") public Integer getRemoteAs() { return _remoteAs; } @JsonIgnore public BgpNeighbor getRemoteBgpNeighbor() { return _remoteBgpNeighbor; } @JsonPropertyDescription("Whether or not this peer is a route-reflector client") public boolean getRouteReflectorClient() { return _routeReflectorClient; } /** * @return {@link #_sendCommunity} */ @JsonProperty(SEND_COMMUNITY_VAR) @JsonPropertyDescription("Whether or not to propagate the community attribute(s) of advertisements to this peer") public boolean getSendCommunity() { return _sendCommunity; } @JsonPropertyDescription("The name of the VRF containing the BGP process containing this peering") public String getVrf() { return _vrf; } public void initCandidateRemoteBgpNeighbors() { _candidateRemoteBgpNeighbors = new LinkedHashSet<>(); } public void resolveReferences(Configuration owner) { _owner = owner; } @JsonProperty(ADDRESS_VAR) public void setAddress(Ip address) { // Intentionally empty } @JsonProperty(ADVERTISE_EXTERNAL_VAR) public void setAdvertiseExternal(boolean advertiseExternal) { _advertiseExternal = advertiseExternal; } @JsonProperty(ADVERTISE_INACTIVE_VAR) public void setAdvertiseInactive(boolean advertiseInactive) { _advertiseInactive = advertiseInactive; } @JsonProperty(ALLOW_LOCAL_AS_IN_VAR) public void setAllowLocalAsIn(boolean allowLocalAsIn) { _allowLocalAsIn = allowLocalAsIn; } @JsonProperty(ALLOW_REMOTE_AS_OUT_VAR) public void setAllowRemoteAsOut(boolean allowRemoteAsOut) { _allowRemoteAsOut = allowRemoteAsOut; } /** * Sets {@link #_clusterId} * * @param clusterId */ @JsonProperty(CLUSTER_ID_VAR) public void setClusterId(Long clusterId) { _clusterId = clusterId; } /** * Sets {@link #_defaultMetric} * * @param defaultMetric */ @JsonProperty(DEFAULT_METRIC_VAR) public void setDefaultMetric(int defaultMetric) { _defaultMetric = defaultMetric; } @JsonProperty(DESCRIPTION_VAR) public void setDescription(String description) { _description = description; } @JsonProperty(DYNAMIC_VAR) public void setDynamic(boolean dynamic) { // Intentionally empty } @JsonProperty(EBGP_MULTIHOP_VAR) public void setEbgpMultihop(boolean ebgpMultihop) { _ebgpMultihop = ebgpMultihop; } public void setExportPolicy(String originationPolicyName) { _exportPolicy = originationPolicyName; } @JsonProperty(GENERATED_ROUTES_VAR) public void setGeneratedRoutes(Set<GeneratedRoute> generatedRoutes) { _generatedRoutes = generatedRoutes; } /** * Sets {@link #_group} * * @param name */ @JsonProperty(GROUP_VAR) public void setGroup(String name) { _group = name; } public void setImportPolicy(String importPolicy) { _importPolicy = importPolicy; } /** * Sets {@link #_localAs} * * @param localAs */ @JsonProperty(LOCAL_AS_VAR) public void setLocalAs(Integer localAs) { _localAs = localAs; } /** * Sets {@link #_localIp} * * @param localIp */ @JsonProperty(LOCAL_IP_VAR) public void setLocalIp(Ip localIp) { _localIp = localIp; } @JsonProperty(OWNER_VAR) public void setOwner(Configuration owner) { _owner = owner; } /** * Sets {@link #_remoteAs} * * @param remoteAs */ @JsonProperty(REMOTE_AS_VAR) public void setRemoteAs(Integer remoteAs) { _remoteAs = remoteAs; } public void setRemoteBgpNeighbor(BgpNeighbor remoteBgpNeighbor) { _remoteBgpNeighbor = remoteBgpNeighbor; } @JsonProperty(REMOTE_PREFIX_VAR) public void setRemotePrefix(Prefix remotePrefix) { // Intentionally empty } public void setRouteReflectorClient(boolean routeReflectorClient) { _routeReflectorClient = routeReflectorClient; } /** * Sets {@link #_sendCommunity} * * @param sendCommunity */ @JsonProperty(SEND_COMMUNITY_VAR) public void setSendCommunity(boolean sendCommunity) { _sendCommunity = sendCommunity; } public void setVrf(String vrf) { _vrf = vrf; } @Override public String toString() { return "BgpNeighbor<Prefix:" + _key + ", AS:" + _remoteAs + ">"; } }