Skip to content

Commit

Permalink
FRR: route-map match source-protocol (#6618)
Browse files Browse the repository at this point in the history
  • Loading branch information
dhalperi committed Feb 10, 2021
1 parent 4f1b7e9 commit 65defd0
Show file tree
Hide file tree
Showing 10 changed files with 364 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.annotations.VisibleForTesting;
import java.util.Objects;
import javax.annotation.Nonnull;
import org.batfish.datamodel.isis.IsisLevel;
import org.batfish.datamodel.route.nh.NextHop;
import org.batfish.datamodel.route.nh.NextHopDiscard;

/** IS-IS route */
public class IsisRoute extends AbstractRoute {
Expand Down Expand Up @@ -85,6 +87,17 @@ public Builder setSystemId(@Nonnull String systemId) {
}
}

/** Return a route builder with pre-filled mandatory values. To be used in tests only */
@VisibleForTesting
public static IsisRoute.Builder testBuilder() {
return builder()
.setNextHop(NextHopDiscard.instance())
.setAdmin(115)
.setArea("49.0001")
.setSystemId("1921.6800.1077")
.setProtocol(RoutingProtocol.ISIS_L1);
}

/** Default Isis route metric, unless one is explicitly specified */
public static final long DEFAULT_METRIC = 10L;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.annotations.VisibleForTesting;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import org.batfish.datamodel.ospf.OspfMetricType;
import org.batfish.datamodel.route.nh.NextHop;
import org.batfish.datamodel.route.nh.NextHopDiscard;

/** OSPF external route of type 1 */
@ParametersAreNonnullByDefault
Expand Down Expand Up @@ -78,6 +80,17 @@ public static OspfExternalRoute.Builder builder() {
return OspfExternalRoute.builder().setOspfMetricType(OspfMetricType.E1);
}

/** Return a route builder with pre-filled mandatory values. To be used in tests only */
@VisibleForTesting
public static OspfExternalRoute.Builder testBuilder() {
return builder()
.setAdvertiser("adv")
.setArea(0L)
.setCostToAdvertiser(1L)
.setLsaMetric(2L)
.setNextHop(NextHopDiscard.instance());
}

@Nonnull
@Override
public OspfMetricType getOspfMetricType() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,11 @@ DOUBLE_QUOTE
'"' -> pushMode ( M_DoubleQuote )
;

EIGRP
:
'eigrp'
;

EMERGENCIES
:
'emergencies'
Expand Down Expand Up @@ -439,6 +444,16 @@ IPV6_PREFIX
F_Ipv6Prefix
;

ISIS
:
'isis'
;

KERNEL
:
'kernel'
;

L2VPN
:
'l2vpn'
Expand Down Expand Up @@ -644,6 +659,11 @@ REPLACE_AS
'replace-as'
;

RIP
:
'rip'
;

ROUTE_MAP
:
'route-map' -> pushMode(M_Word)
Expand Down Expand Up @@ -694,6 +714,11 @@ SOFT_RECONFIGURATION
'soft-reconfiguration'
;

SOURCE_PROTOCOL
:
'source-protocol'
;

STANDARD
:
'standard' -> pushMode ( M_Word )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ rm_match
// | rmm_origin
// | rmm_peer
// | rmm_probability
// | rmm_source_protocol
| rmm_source_protocol
// | rmm_source_vrf
| rmm_tag
)
Expand Down Expand Up @@ -123,6 +123,26 @@ rmm_ipv6
IPV6 null_rest_of_line
;

rmm_source_protocol
:
SOURCE_PROTOCOL
(
// BABEL
BGP
| CONNECTED
| EIGRP
| ISIS
| KERNEL
// | NHRP
| OSPF
// | OSPF6
| RIP
// | RIPNG
| STATIC
// | SYSTEM
) NEWLINE
;

rmm_tag
:
TAG tag = uint32 NEWLINE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
import org.batfish.grammar.cumulus_frr.CumulusFrrParser.Rmm_as_pathContext;
import org.batfish.grammar.cumulus_frr.CumulusFrrParser.Rmm_communityContext;
import org.batfish.grammar.cumulus_frr.CumulusFrrParser.Rmm_interfaceContext;
import org.batfish.grammar.cumulus_frr.CumulusFrrParser.Rmm_source_protocolContext;
import org.batfish.grammar.cumulus_frr.CumulusFrrParser.Rmm_tagContext;
import org.batfish.grammar.cumulus_frr.CumulusFrrParser.Rmmipa_prefix_lenContext;
import org.batfish.grammar.cumulus_frr.CumulusFrrParser.Rmmipa_prefix_listContext;
Expand Down Expand Up @@ -209,6 +210,8 @@
import org.batfish.representation.cumulus.RouteMapMatchInterface;
import org.batfish.representation.cumulus.RouteMapMatchIpAddressPrefixLen;
import org.batfish.representation.cumulus.RouteMapMatchIpAddressPrefixList;
import org.batfish.representation.cumulus.RouteMapMatchSourceProtocol;
import org.batfish.representation.cumulus.RouteMapMatchSourceProtocol.Protocol;
import org.batfish.representation.cumulus.RouteMapMatchTag;
import org.batfish.representation.cumulus.RouteMapSetAsPath;
import org.batfish.representation.cumulus.RouteMapSetCommListDelete;
Expand Down Expand Up @@ -1270,6 +1273,38 @@ public void exitRmm_as_path(Rmm_as_pathContext ctx) {
ctx.getStart().getLine());
}

@Override
public void exitRmm_community(Rmm_communityContext ctx) {
ctx.names.forEach(
name ->
_c.referenceStructure(
IP_COMMUNITY_LIST, name.getText(),
ROUTE_MAP_MATCH_COMMUNITY_LIST, name.getStart().getLine()));

_currentRouteMapEntry.setMatchCommunity(
new RouteMapMatchCommunity(
ImmutableList.<String>builder()
// add old names
.addAll(
Optional.ofNullable(_currentRouteMapEntry.getMatchCommunity())
.map(RouteMapMatchCommunity::getNames)
.orElse(ImmutableList.of()))
// add new names
.addAll(ctx.names.stream().map(RuleContext::getText).iterator())
.build()));
}

@Override
public void exitRmm_interface(Rmm_interfaceContext ctx) {
String name = ctx.name.getText();
_currentRouteMapEntry.setMatchInterface(new RouteMapMatchInterface(ImmutableSet.of(name)));
_c.referenceStructure(
ABSTRACT_INTERFACE,
name,
CumulusStructureUsage.ROUTE_MAP_MATCH_INTERFACE,
ctx.getStart().getLine());
}

@Override
public void exitRmmipa_prefix_len(Rmmipa_prefix_lenContext ctx) {
Optional<Integer> maybeLen = toInteger(ctx, ctx.len);
Expand Down Expand Up @@ -1299,35 +1334,27 @@ public void exitRmmipa_prefix_list(Rmmipa_prefix_listContext ctx) {
}

@Override
public void exitRmm_interface(Rmm_interfaceContext ctx) {
String name = ctx.name.getText();
_currentRouteMapEntry.setMatchInterface(new RouteMapMatchInterface(ImmutableSet.of(name)));
_c.referenceStructure(
ABSTRACT_INTERFACE,
name,
CumulusStructureUsage.ROUTE_MAP_MATCH_INTERFACE,
ctx.getStart().getLine());
}

@Override
public void exitRmm_community(Rmm_communityContext ctx) {
ctx.names.forEach(
name ->
_c.referenceStructure(
IP_COMMUNITY_LIST, name.getText(),
ROUTE_MAP_MATCH_COMMUNITY_LIST, name.getStart().getLine()));

_currentRouteMapEntry.setMatchCommunity(
new RouteMapMatchCommunity(
ImmutableList.<String>builder()
// add old names
.addAll(
Optional.ofNullable(_currentRouteMapEntry.getMatchCommunity())
.map(RouteMapMatchCommunity::getNames)
.orElse(ImmutableList.of()))
// add new names
.addAll(ctx.names.stream().map(RuleContext::getText).iterator())
.build()));
public void exitRmm_source_protocol(Rmm_source_protocolContext ctx) {
RouteMapMatchSourceProtocol p = null;
if (ctx.BGP() != null) {
p = new RouteMapMatchSourceProtocol(Protocol.BGP);
} else if (ctx.CONNECTED() != null) {
p = new RouteMapMatchSourceProtocol(Protocol.CONNECTED);
} else if (ctx.EIGRP() != null) {
p = new RouteMapMatchSourceProtocol(Protocol.EIGRP);
} else if (ctx.ISIS() != null) {
p = new RouteMapMatchSourceProtocol(Protocol.ISIS);
} else if (ctx.KERNEL() != null) {
p = new RouteMapMatchSourceProtocol(Protocol.KERNEL);
} else if (ctx.OSPF() != null) {
p = new RouteMapMatchSourceProtocol(Protocol.OSPF);
} else if (ctx.RIP() != null) {
p = new RouteMapMatchSourceProtocol(Protocol.RIP);
} else if (ctx.STATIC() != null) {
p = new RouteMapMatchSourceProtocol(Protocol.STATIC);
}
assert p != null; // or else we're missing something in the if statement.
_currentRouteMapEntry.setMatchSourceProtocol(p);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public final class RouteMapEntry implements Serializable {
private @Nullable RouteMapMatchInterface _matchInterface;
private @Nullable RouteMapMatchIpAddressPrefixLen _matchIpAddressPrefixLen;
private @Nullable RouteMapMatchIpAddressPrefixList _matchIpAddressPrefixList;
private @Nullable RouteMapMatchSourceProtocol _matchSourceProtocol;
private @Nullable RouteMapMatchTag _matchTag;
private final int _number;
private @Nullable String _description;
Expand Down Expand Up @@ -59,6 +60,7 @@ public void setCall(@Nullable RouteMapCall call) {
_matchCommunity,
_matchIpAddressPrefixLen,
_matchIpAddressPrefixList,
_matchSourceProtocol,
_matchTag)
.filter(Objects::nonNull);
}
Expand Down Expand Up @@ -88,6 +90,14 @@ public void setMatchIpAddressPrefixLen(
return _matchIpAddressPrefixList;
}

public @Nullable RouteMapMatchSourceProtocol getMatchSourceProtocol() {
return _matchSourceProtocol;
}

public void setMatchSourceProtocol(@Nullable RouteMapMatchSourceProtocol matchSourceProtocol) {
_matchSourceProtocol = matchSourceProtocol;
}

@Nullable
public RouteMapMatchTag getMatchTag() {
return _matchTag;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package org.batfish.representation.cumulus;

import javax.annotation.Nonnull;
import org.batfish.common.Warnings;
import org.batfish.datamodel.Configuration;
import org.batfish.datamodel.RoutingProtocol;
import org.batfish.datamodel.routing_policy.expr.BooleanExpr;
import org.batfish.datamodel.routing_policy.expr.BooleanExprs;
import org.batfish.datamodel.routing_policy.expr.MatchProtocol;

/** A {@link RouteMapMatch} that implements {@code route-map match source-protocol}. */
public final class RouteMapMatchSourceProtocol implements RouteMapMatch {

public enum Protocol {
BGP,
CONNECTED,
EIGRP,
ISIS,
KERNEL,
OSPF,
RIP,
STATIC,
}

private final @Nonnull Protocol _protocol;

public RouteMapMatchSourceProtocol(@Nonnull Protocol protocol) {
_protocol = protocol;
}

@Override
public @Nonnull BooleanExpr toBooleanExpr(
Configuration c, CumulusNodeConfiguration vc, Warnings w) {
switch (_protocol) {
case BGP:
return new MatchProtocol(RoutingProtocol.BGP, RoutingProtocol.IBGP);
case CONNECTED:
// TODO: cumulus local routes?
return new MatchProtocol(RoutingProtocol.CONNECTED);
case EIGRP:
// TODO: verify subsets
return new MatchProtocol(RoutingProtocol.EIGRP, RoutingProtocol.EIGRP_EX);
case ISIS:
// TODO: verify subsets
return new MatchProtocol(
RoutingProtocol.ISIS_EL1,
RoutingProtocol.ISIS_EL2,
RoutingProtocol.ISIS_L1,
RoutingProtocol.ISIS_L2);
case KERNEL:
return new MatchProtocol(RoutingProtocol.KERNEL);
case OSPF:
// TODO: verify subsets
return new MatchProtocol(
RoutingProtocol.OSPF,
RoutingProtocol.OSPF_E1,
RoutingProtocol.OSPF_E2,
RoutingProtocol.OSPF_IA);
case RIP:
return new MatchProtocol(RoutingProtocol.RIP);
case STATIC:
return new MatchProtocol(RoutingProtocol.STATIC);
default:
w.unimplemented(String.format("Matching protocol %s", _protocol));
return BooleanExprs.FALSE;
}
}

public @Nonnull Protocol getProtocol() {
return _protocol;
}
}

0 comments on commit 65defd0

Please sign in to comment.