Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FRR: route-map match source-protocol #6618

Merged
merged 2 commits into from
Feb 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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;
}
}