Skip to content

Commit

Permalink
Arista: implement peer-filters (#5940)
Browse files Browse the repository at this point in the history
  • Loading branch information
progwriter committed Jun 26, 2020
1 parent 5c00ee3 commit 5b61952
Show file tree
Hide file tree
Showing 15 changed files with 436 additions and 9 deletions.
Expand Up @@ -62,6 +62,11 @@ ACAP
'acap'
;

ACCEPT
:
'accept'
;

ACCEPT_DIALIN
:
'accept-dialin'
Expand Down Expand Up @@ -721,6 +726,11 @@ AS_PATH
'as-path' -> pushMode ( M_AsPath )
;

AS_RANGE
:
'as-range'
;

ASPATH_CMP_INCLUDE_NEXTHOP
:
'aspath-cmp-include-nexthop'
Expand Down Expand Up @@ -7350,7 +7360,7 @@ PEER_CONFIG_CHECK_BYPASS

PEER_FILTER
:
'peer-filter'
'peer-filter' -> pushMode (M_Word)
;

PEER_GROUP
Expand Down Expand Up @@ -8303,6 +8313,11 @@ REGULATORY_DOMAIN_PROFILE
'regulatory-domain-profile'
;

REJECT
:
'reject'
;

RELAY
:
'relay'
Expand Down Expand Up @@ -8463,6 +8478,11 @@ RESTRICTED
'restricted'
;

RESULT
:
'result'
;

RESULT_TYPE
:
'result-type'
Expand Down
Expand Up @@ -2732,6 +2732,21 @@ s_passwd
NO? PASSWD pass = variable ENCRYPTED? NEWLINE
;

s_peer_filter
:
PEER_FILTER name = WORD NEWLINE
(
peer_filter_line
)*
;

peer_filter_line
:
(seq = DEC)? MATCH
AS_RANGE asn_range = eos_as_range RESULT action = (ACCEPT | REJECT)
NEWLINE
;

s_phone_proxy
:
NO? PHONE_PROXY null_rest_of_line
Expand Down Expand Up @@ -3523,6 +3538,7 @@ stanza
| s_nv
| s_openflow
| s_passwd
| s_peer_filter
| s_phone_proxy
| s_policy_map
| s_policy_map_ios
Expand Down
Expand Up @@ -1480,7 +1480,7 @@ eos_rbibl_range
)
(PEER_GROUP | PEER GROUP) pg = variable
(
PEER_FILTER peer_filter = variable
PEER_FILTER peer_filter = WORD
| REMOTE_AS asn = bgp_asn
)
NEWLINE
Expand Down
Expand Up @@ -38,6 +38,7 @@
import static org.batfish.representation.arista.AristaStructureType.MAC_ACCESS_LIST;
import static org.batfish.representation.arista.AristaStructureType.NAMED_RSA_PUB_KEY;
import static org.batfish.representation.arista.AristaStructureType.NAT_POOL;
import static org.batfish.representation.arista.AristaStructureType.PEER_FILTER;
import static org.batfish.representation.arista.AristaStructureType.POLICY_MAP;
import static org.batfish.representation.arista.AristaStructureType.PREFIX6_LIST;
import static org.batfish.representation.arista.AristaStructureType.PREFIX_LIST;
Expand All @@ -51,6 +52,7 @@
import static org.batfish.representation.arista.AristaStructureUsage.BGP_DEFAULT_ORIGINATE_ROUTE_MAP;
import static org.batfish.representation.arista.AristaStructureUsage.BGP_INBOUND_PREFIX_LIST;
import static org.batfish.representation.arista.AristaStructureUsage.BGP_INBOUND_ROUTE_MAP;
import static org.batfish.representation.arista.AristaStructureUsage.BGP_LISTEN_RANGE_PEER_FILTER;
import static org.batfish.representation.arista.AristaStructureUsage.BGP_NEIGHBOR_PEER_GROUP;
import static org.batfish.representation.arista.AristaStructureUsage.BGP_NETWORK_ORIGINATION_ROUTE_MAP;
import static org.batfish.representation.arista.AristaStructureUsage.BGP_OUTBOUND_PREFIX_LIST;
Expand Down Expand Up @@ -739,6 +741,7 @@
import org.batfish.grammar.arista.AristaParser.Passive_iis_stanzaContext;
import org.batfish.grammar.arista.AristaParser.Passive_interface_default_is_stanzaContext;
import org.batfish.grammar.arista.AristaParser.Passive_interface_is_stanzaContext;
import org.batfish.grammar.arista.AristaParser.Peer_filter_lineContext;
import org.batfish.grammar.arista.AristaParser.Peer_sa_filterContext;
import org.batfish.grammar.arista.AristaParser.Pi_iosicd_dropContext;
import org.batfish.grammar.arista.AristaParser.Pi_iosicd_passContext;
Expand Down Expand Up @@ -832,6 +835,7 @@
import org.batfish.grammar.arista.AristaParser.S_no_access_list_extendedContext;
import org.batfish.grammar.arista.AristaParser.S_no_access_list_standardContext;
import org.batfish.grammar.arista.AristaParser.S_ntpContext;
import org.batfish.grammar.arista.AristaParser.S_peer_filterContext;
import org.batfish.grammar.arista.AristaParser.S_policy_mapContext;
import org.batfish.grammar.arista.AristaParser.S_router_ospfContext;
import org.batfish.grammar.arista.AristaParser.S_router_ripContext;
Expand Down Expand Up @@ -1014,6 +1018,8 @@
import org.batfish.representation.arista.eos.AristaBgpNeighborAddressFamily;
import org.batfish.representation.arista.eos.AristaBgpNeighborDefaultOriginate;
import org.batfish.representation.arista.eos.AristaBgpNetworkConfiguration;
import org.batfish.representation.arista.eos.AristaBgpPeerFilter;
import org.batfish.representation.arista.eos.AristaBgpPeerFilterLine;
import org.batfish.representation.arista.eos.AristaBgpPeerGroupNeighbor;
import org.batfish.representation.arista.eos.AristaBgpProcess;
import org.batfish.representation.arista.eos.AristaBgpV4DynamicNeighbor;
Expand Down Expand Up @@ -1240,6 +1246,8 @@ private static String unquote(String text) {

private OspfProcess _currentOspfProcess;

@Nullable private AristaBgpPeerFilter _currentPeerFilter;

private Prefix6List _currentPrefix6List;

private PrefixList _currentPrefixList;
Expand Down Expand Up @@ -2695,7 +2703,10 @@ public void exitEos_rbibl_range(Eos_rbibl_rangeContext ctx) {
neighbor.setRemoteAs(toAsNum(ctx.asn));
}
if (ctx.peer_filter != null) {
warn(ctx, "Peer filters are currently not supported");
String peerFilterName = ctx.peer_filter.getText();
neighbor.setPeerFilter(peerFilterName);
_configuration.referenceStructure(
PEER_FILTER, peerFilterName, BGP_LISTEN_RANGE_PEER_FILTER, ctx.getStart().getLine());
}
}

Expand Down Expand Up @@ -4035,6 +4046,38 @@ public void enterS_policy_map(S_policy_mapContext ctx) {
}
}

@Override
public void enterS_peer_filter(S_peer_filterContext ctx) {
String name = ctx.name.getText();
_currentPeerFilter =
_configuration.getPeerFilters().computeIfAbsent(name, AristaBgpPeerFilter::new);
_configuration.defineStructure(PEER_FILTER, name, ctx);
}

@Override
public void exitS_peer_filter(S_peer_filterContext ctx) {
_currentPeerFilter = null;
}

@Override
public void exitPeer_filter_line(Peer_filter_lineContext ctx) {
assert _currentPeerFilter != null;
AristaBgpPeerFilterLine.Action action;
if (ctx.ACCEPT() != null) {
action = AristaBgpPeerFilterLine.Action.ACCEPT;
} else if (ctx.REJECT() != null) {
action = AristaBgpPeerFilterLine.Action.REJECT;
} else {
throw new IllegalStateException("peer-filter line without known action");
}
LongSpace asSpace = toAsSpace(ctx.asn_range);
if (ctx.seq == null) {
_currentPeerFilter.addLine(asSpace, action);
} else {
_currentPeerFilter.addLine(toInteger(ctx.seq), asSpace, action);
}
}

@Override
public void enterS_router_ospf(S_router_ospfContext ctx) {
String procName = ctx.name.getText();
Expand Down
Expand Up @@ -164,6 +164,7 @@
import org.batfish.representation.arista.Tunnel.TunnelMode;
import org.batfish.representation.arista.eos.AristaBgpAggregateNetwork;
import org.batfish.representation.arista.eos.AristaBgpBestpathTieBreaker;
import org.batfish.representation.arista.eos.AristaBgpPeerFilter;
import org.batfish.representation.arista.eos.AristaBgpProcess;
import org.batfish.representation.arista.eos.AristaBgpRedistributionPolicy;
import org.batfish.representation.arista.eos.AristaBgpVrf;
Expand Down Expand Up @@ -371,6 +372,8 @@ static String toJavaRegex(String ciscoRegex) {

private String _ntpSourceInterface;

private final Map<String, AristaBgpPeerFilter> _peerFilters;

private final Map<String, Prefix6List> _prefix6Lists;

private final Map<String, PrefixList> _prefixLists;
Expand Down Expand Up @@ -424,6 +427,7 @@ public AristaConfiguration() {
_macAccessLists = new TreeMap<>();
_natPools = new TreeMap<>();
_namedVlans = new HashMap<>();
_peerFilters = new HashMap<>();
_prefixLists = new TreeMap<>();
_prefix6Lists = new TreeMap<>();
_routeMaps = new TreeMap<>();
Expand Down Expand Up @@ -623,6 +627,10 @@ public String getNtpSourceInterface() {
return _ntpSourceInterface;
}

public Map<String, AristaBgpPeerFilter> getPeerFilters() {
return _peerFilters;
}

public Map<String, Prefix6List> getPrefix6Lists() {
return _prefix6Lists;
}
Expand Down Expand Up @@ -1043,7 +1051,7 @@ OSPF_INTERNAL, new MatchProtocol(RoutingProtocol.OSPF, RoutingProtocol.OSPF_IA),
// Process passive neighbors next
Map<Prefix, BgpPassivePeerConfig> passiveNeighbors =
AristaConversions.getPassiveNeighbors(
c, v, newBgpProcess, bgpGlobal, bgpVrf, _eosVxlan, _w);
c, v, newBgpProcess, bgpGlobal, bgpVrf, _eosVxlan, _peerFilters, _w);
newBgpProcess.setPassiveNeighbors(ImmutableSortedMap.copyOf(passiveNeighbors));

return newBgpProcess;
Expand Down
Expand Up @@ -8,6 +8,7 @@
import static org.batfish.datamodel.routing_policy.statement.Statements.RemovePrivateAs;
import static org.batfish.representation.arista.AristaConfiguration.MAX_ADMINISTRATIVE_COST;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.ImmutableMap;
Expand Down Expand Up @@ -65,6 +66,7 @@
import org.batfish.representation.arista.eos.AristaBgpNeighbor;
import org.batfish.representation.arista.eos.AristaBgpNeighbor.RemovePrivateAsMode;
import org.batfish.representation.arista.eos.AristaBgpNeighborAddressFamily;
import org.batfish.representation.arista.eos.AristaBgpPeerFilter;
import org.batfish.representation.arista.eos.AristaBgpProcess;
import org.batfish.representation.arista.eos.AristaBgpV4DynamicNeighbor;
import org.batfish.representation.arista.eos.AristaBgpV4Neighbor;
Expand Down Expand Up @@ -186,7 +188,7 @@ private static boolean isActive(
}

// No remote AS set.
if (neighbor.getRemoteAs() == null) {
if (neighbor.getRemoteAs() == null && neighbor.getPeerFilter() == null) {
w.redFlag("No remote-as configured for " + name);
return false;
}
Expand Down Expand Up @@ -222,6 +224,7 @@ static Map<Prefix, BgpActivePeerConfig> getNeighbors(
e.getValue(),
false,
vxlan,
ImmutableMap.of(), // peer filters not needed for non-dynamic peers
warnings)));
}

Expand All @@ -233,6 +236,7 @@ static Map<Prefix, BgpPassivePeerConfig> getPassiveNeighbors(
AristaBgpProcess bgpConfig,
AristaBgpVrf bgpVrf,
@Nullable AristaEosVxlan vxlan,
Map<String, AristaBgpPeerFilter> peerFilters,
Warnings warnings) {
return bgpVrf.getV4DynamicNeighbors().entrySet().stream()
.peek(e -> e.getValue().inherit(bgpConfig, bgpVrf, warnings))
Expand All @@ -252,6 +256,7 @@ static Map<Prefix, BgpPassivePeerConfig> getPassiveNeighbors(
e.getValue(),
true,
vxlan,
peerFilters,
warnings)));
}

Expand Down Expand Up @@ -304,6 +309,26 @@ private static Ip computeUpdateSource(
return null;
}

/** Compute the remote AS space for a dynamic BGP neighbor */
@Nonnull
@VisibleForTesting
static LongSpace getAsnSpace(
AristaBgpV4DynamicNeighbor neighbor, Map<String, AristaBgpPeerFilter> peerFilters) {
if (neighbor.getRemoteAs() != null) {
return LongSpace.of(neighbor.getRemoteAs());
} else if (neighbor.getPeerFilter() != null) {
AristaBgpPeerFilter peerFilter = peerFilters.get(neighbor.getPeerFilter());
if (peerFilter == null) {
// If the filter does not exist, accept any ASN:
// http://www.arista.com/en/um-eos/eos-section-33-2-configuring-bgp#ww1319501
return BgpPeerConfig.ALL_AS_NUMBERS;
}
return peerFilter.toLongSpace();
} else {
return LongSpace.EMPTY;
}
}

@Nonnull
private static BgpPeerConfig toBgpNeighbor(
Configuration c,
Expand All @@ -315,18 +340,17 @@ private static BgpPeerConfig toBgpNeighbor(
AristaBgpNeighbor neighbor,
boolean dynamic,
@Nullable AristaEosVxlan vxlan,
Map<String, AristaBgpPeerFilter> peerFilters,
Warnings warnings) {
// We should be converting only concrete (active or dynamic) neighbors
assert neighbor instanceof AristaBgpHasPeerGroup;

BgpPeerConfig.Builder<?, ?> newNeighborBuilder;
if (dynamic) {
assert neighbor instanceof AristaBgpV4DynamicNeighbor;
newNeighborBuilder =
BgpPassivePeerConfig.builder()
.setRemoteAsns(
Optional.ofNullable(neighbor.getRemoteAs())
.map(LongSpace::of)
.orElse(LongSpace.EMPTY))
.setRemoteAsns(getAsnSpace((AristaBgpV4DynamicNeighbor) neighbor, peerFilters))
.setPeerPrefix(prefix);
} else {
newNeighborBuilder =
Expand Down
Expand Up @@ -37,6 +37,7 @@ public enum AristaStructureType implements StructureType {
MAC_ACCESS_LIST("mac acl"),
NAMED_RSA_PUB_KEY("crypto named rsa pubkey"),
NAT_POOL("nat pool"),
PEER_FILTER("peer-filter"),
POLICY_MAP("policy-map"),
PREFIX_LIST("ipv4 prefix-list"),
PREFIX6_LIST("ipv6 prefix-list"),
Expand Down
Expand Up @@ -12,6 +12,7 @@ public enum AristaStructureUsage implements StructureUsage {
BGP_INBOUND_PREFIX6_LIST("bgp inbound ipv6 prefix-list"),
BGP_INBOUND_ROUTE_MAP("bgp inbound route-map"),
BGP_INBOUND_ROUTE6_MAP("bgp inbound ipv6 route-map"),
BGP_LISTEN_RANGE_PEER_FILTER("bgp listen range peer-filter"),
BGP_NEIGHBOR_DISTRIBUTE_LIST_ACCESS_LIST_IN("bgp neighbor distribute-list access-list in"),
BGP_NEIGHBOR_DISTRIBUTE_LIST_ACCESS_LIST_OUT("bgp neighbor distribute-list access-list out"),
BGP_NEIGHBOR_DISTRIBUTE_LIST_ACCESS6_LIST_IN("bgp neighbor distribute-list ipv6 access-list in"),
Expand Down

0 comments on commit 5b61952

Please sign in to comment.