Skip to content

Commit

Permalink
Junos: Add missing vxlan grammar (#8112)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffkala committed Mar 10, 2022
1 parent 41904d8 commit ef61a3a
Show file tree
Hide file tree
Showing 14 changed files with 230 additions and 12 deletions.
Expand Up @@ -570,6 +570,8 @@ DTCP_ONLY: 'dtcp-only';

DUMP_ON_PANIC: 'dump-on-panic';

DUPLICATE_MAC_DETECTION: 'duplicate-mac-detection';

DVMRP: 'dvmrp';

DYNAMIC: 'dynamic';
Expand Down Expand Up @@ -649,7 +651,7 @@ EXPORT_RIB: 'export-rib' -> pushMode(M_Name);

EXPRESSION: 'expression';

EXTENDED_VNI_LIST: 'extended-vni-list';
EXTENDED_VNI_LIST: 'extended-vni-list' -> pushMode(M_ExtendedVniList);

EXTENSIBLE_SUBSCRIBER: 'extensible-subscriber';

Expand Down Expand Up @@ -1978,6 +1980,8 @@ OUTPUT_VLAN_MAP: 'output-vlan-map';

OUTER: 'outer';

OVERLAY_ECMP: 'overlay-ecmp';

OVERLOAD: 'overload';

OVERRIDE_METRIC: 'override-metric';
Expand Down Expand Up @@ -2862,6 +2866,8 @@ VTEP_SOURCE_INTERFACE

VXLAN: 'vxlan';

VXLAN_ROUTING: 'vxlan-routing';

WEB_MANAGEMENT: 'web-management';

WEBAPI: 'webapi';
Expand Down Expand Up @@ -4752,3 +4758,21 @@ M_Port_DASH: '-' -> type(DASH);
// Not a range. We can continue in default mode since words need not be broken up.
M_Port_NON_RANGE: [A-Za-z]+ {less();} -> popMode;
mode M_ExtendedVniList;
M_ExtendedVniList_WS: F_WhitespaceChar+ -> skip;
M_ExtendedVniList_NEWLINE: F_Newline -> type(NEWLINE), popMode;
M_ExtendedVniList_ALL: 'all' -> type(ALL), popMode;
M_ExtendedVniList_OPEN_BRACKET: '[' -> type(OPEN_BRACKET);
M_ExtendedVniList_CLOSE_BRACKET: ']' -> type(CLOSE_BRACKET), popMode;
M_ExtendedVniList_UINT32: F_Uint32 -> type(UINT32), mode(M_ExtendedVniListNumber);
mode M_ExtendedVniListNumber;
M_ExtendedVniListNumber_WS: F_WhitespaceChar+ -> skip, mode(M_ExtendedVniList);
M_ExtendedVniListNumber_NEWLINE: F_Newline -> type(NEWLINE), popMode;
M_ExtendedVniListNumber_CLOSE_BRACKET: ']' -> type(CLOSE_BRACKET), popMode;
M_ExtendedVniListNumber_DASH: '-' -> type(DASH), mode(M_ExtendedVniListDash);
mode M_ExtendedVniListDash;
M_ExtendedVniListDash_NEWLINE: F_Newline -> type(NEWLINE), popMode;
M_ExtendedVniListDash_UINT32: F_Uint32 -> type(UINT32), mode(M_ExtendedVniList);
Expand Up @@ -177,6 +177,7 @@ s_vlans_named
| vlt_interface
| vlt_l3_interface
| vlt_vlan_id
| vlt_vni_id
)
;

Expand Down Expand Up @@ -220,3 +221,8 @@ vlt_vlan_id
:
VLAN_ID id = dec
;

vlt_vni_id
:
VXLAN VNI vni_number
;
Expand Up @@ -671,3 +671,19 @@ wildcard
WILDCARD
| WILDCARD_ARTIFACT
;

vni_number
:
// 0 through 16,777,215
// https://www.juniper.net/documentation/us/en/software/junos/evpn-vxlan/topics/ref/statement/vni-vxlan.html#id-vni__d49551e60
uint32
;


vni_range
:
// Example extended-vni-list [ 10-50 60 70]

start = vni_number
| start = vni_number (DASH end = vni_number)?
;
Expand Up @@ -18,7 +18,16 @@ e_encapsulation

e_extended_vni_list
:
EXTENDED_VNI_LIST range
EXTENDED_VNI_LIST (
OPEN_BRACKET vni_range+ CLOSE_BRACKET
| ALL
| vni_range
)
;

e_duplicate_mac_detection_null
:
DUPLICATE_MAC_DETECTION null_filler
;

e_multicast_mode
Expand Down Expand Up @@ -80,6 +89,7 @@ p_evpn
| e_extended_vni_list
| e_multicast_mode
| e_vni_options
| e_duplicate_mac_detection_null
)
;

Expand Down
Expand Up @@ -41,6 +41,14 @@ fo_null
) null_filler
;

fo_vxlan_routing
:
VXLAN_ROUTING
(
fov_overlay_ecmp
)
;

fod_active_server_group
:
ACTIVE_SERVER_GROUP name = junos_name
Expand Down Expand Up @@ -148,6 +156,11 @@ fohb_server_null
)?
;

fov_overlay_ecmp
:
OVERLAY_ECMP
;

s_forwarding_options
:
FORWARDING_OPTIONS
Expand All @@ -156,5 +169,6 @@ s_forwarding_options
| fo_dhcp_relay
| fo_helpers
| fo_null
| fo_vxlan_routing
)
;
Expand Up @@ -292,6 +292,7 @@
import org.batfish.grammar.flatjuniper.FlatJuniperParser.Filter_nameContext;
import org.batfish.grammar.flatjuniper.FlatJuniperParser.Flat_juniper_configurationContext;
import org.batfish.grammar.flatjuniper.FlatJuniperParser.Fo_dhcp_relayContext;
import org.batfish.grammar.flatjuniper.FlatJuniperParser.Fo_vxlan_routingContext;
import org.batfish.grammar.flatjuniper.FlatJuniperParser.Fod_active_server_groupContext;
import org.batfish.grammar.flatjuniper.FlatJuniperParser.Fod_groupContext;
import org.batfish.grammar.flatjuniper.FlatJuniperParser.Fod_server_groupContext;
Expand Down Expand Up @@ -674,6 +675,8 @@
import org.batfish.grammar.flatjuniper.FlatJuniperParser.Vlt_interfaceContext;
import org.batfish.grammar.flatjuniper.FlatJuniperParser.Vlt_l3_interfaceContext;
import org.batfish.grammar.flatjuniper.FlatJuniperParser.Vlt_vlan_idContext;
import org.batfish.grammar.flatjuniper.FlatJuniperParser.Vlt_vni_idContext;
import org.batfish.grammar.flatjuniper.FlatJuniperParser.Vni_numberContext;
import org.batfish.grammar.flatjuniper.FlatJuniperParser.ZoneContext;
import org.batfish.grammar.silent_syntax.SilentSyntaxCollection;
import org.batfish.representation.juniper.AddressAddressBookEntry;
Expand Down Expand Up @@ -894,6 +897,8 @@ public class ConfigurationBuilder extends FlatJuniperParserBaseListener

private static final StaticRoute DUMMY_STATIC_ROUTE = new StaticRoute(Prefix.ZERO);

private static final IntegerSpace VNI_NUMBER_RANGE = IntegerSpace.of(new SubRange(0, 16777215));

private String convErrorMessage(Class<?> type, ParserRuleContext ctx) {
return String.format("Could not convert to %s: %s", type.getSimpleName(), getFullText(ctx));
}
Expand Down Expand Up @@ -1818,6 +1823,11 @@ private static int toInt(Named_portContext ctx) {
return getNamedPort(ctx).number();
}

private @Nonnull Optional<Integer> toInteger(
ParserRuleContext messageCtx, Vni_numberContext ctx) {
return toIntegerInSpace(messageCtx, ctx, VNI_NUMBER_RANGE, "vni");
}

private static @Nonnull IpOptions toIpOptions(Ip_optionContext ctx) {
if (ctx.LOOSE_SOURCE_ROUTE() != null) {
return IpOptions.LOOSE_SOURCE_ROUTE;
Expand Down Expand Up @@ -2390,6 +2400,11 @@ public void enterFf_term(Ff_termContext ctx) {
FIREWALL_FILTER_TERM, defName, FIREWALL_FILTER_TERM_DEFINITION, getLine(ctx.name.start));
}

@Override
public void exitFo_vxlan_routing(Fo_vxlan_routingContext ctx) {
todo(ctx);
}

@Override
public void enterFo_dhcp_relay(Fo_dhcp_relayContext ctx) {
_currentDhcpRelayGroup =
Expand Down Expand Up @@ -6533,6 +6548,17 @@ public void exitVlt_vlan_id(Vlt_vlan_idContext ctx) {
_currentNamedVlan.setVlanId(vlan);
}

@Override
public void exitVlt_vni_id(Vlt_vni_idContext ctx) {
Optional<Integer> maybeVniNumber = toInteger(ctx, ctx.vni_number());
if (!maybeVniNumber.isPresent()) {
// already warned
return;
}
int vni = maybeVniNumber.get();
_currentNamedVlan.setVniId(vni);
}

@Override
public void exitVlt_interface(Vlt_interfaceContext ctx) {
String name = getInterfaceFullName(ctx.interface_id());
Expand Down
Expand Up @@ -15,6 +15,7 @@ public class Vlan implements Serializable {
private @Nonnull Set<String> _interfaces;
private @Nullable String _l3Interface;
private @Nullable Integer _vlanId;
private @Nullable Integer _vniId;

public Vlan(String name) {
_name = name;
Expand All @@ -41,10 +42,18 @@ public void addInterface(String ifname) {
return _vlanId;
}

public @Nullable Integer getVniId() {
return _vniId;
}

public void setVlanId(int vlanId) {
_vlanId = vlanId;
}

public void setVniId(int vniId) {
_vniId = vniId;
}

public void setL3Interface(String l3Interface) {
_l3Interface = l3Interface;
}
Expand Down
Expand Up @@ -193,6 +193,7 @@
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
Expand Down Expand Up @@ -1540,6 +1541,24 @@ public void testEthernetSwitchingFilterReference() throws IOException {
assertThat(ccae, hasNumReferrers(filename, FIREWALL_FILTER, "esfilter2", 0));
}

@Test
public void testEvpnVniListAllExtraction() {
parseJuniperConfig("juniper-evpn-vni-list-all");
// TODO
}

@Test
public void testEvpnVniListNoRangeExtraction() {
parseJuniperConfig("juniper-evpn-vni-list-no-range");
// TODO
}

@Test
public void testEvpnVniListWithRangeExtraction() {
parseJuniperConfig("juniper-evpn-vni-list-with-range");
// TODO
}

@Test
public void testFirewallFilterReferences() throws IOException {
String hostname = "firewall-filters";
Expand Down Expand Up @@ -2905,6 +2924,14 @@ public void testInterfacePrimary() throws IOException {
+ " primary.")));
}

@Test
public void testInterfaceVniExtraction() {
JuniperConfiguration c = parseJuniperConfig("interface-vni");
Integer vni = c.getMasterLogicalSystem().getNamedVlans().get("VLAN_TEST").getVniId();
Integer vni0 = 10101;
assertEquals(vni, vni0);
}

@Test
public void testJuniperOspfIntervals() {
JuniperConfiguration config = parseJuniperConfig("ospf-intervals");
Expand Down Expand Up @@ -5016,6 +5043,24 @@ public void testOspfSummaries() {
LineAction.PERMIT, Prefix.ZERO, new SubRange(0, Prefix.MAX_PREFIX_LENGTH)))));
}

@Test
public void testOverlayEcmp() throws IOException {
String hostname = "juniper-overlay-ecmp";
Batfish batfish = getBatfishForConfigurationNames(hostname);
List<ParseWarning> parseWarnings =
batfish
.loadParseVendorConfigurationAnswerElement(batfish.getSnapshot())
.getWarnings()
.get("configs/" + hostname)
.getParseWarnings();
assertThat(
parseWarnings,
hasItem(
allOf(
hasComment("This feature is not currently supported"),
hasText("vxlan-routing overlay-ecmp"))));
}

@Test
public void testParsingRecovery() {
String recoveryText = readResource("org/batfish/grammar/juniper/testconfigs/recovery", UTF_8);
Expand Down
@@ -0,0 +1,10 @@
#
set system host-name interface-vni
#
set interfaces ge-0/0/0 unit 0 family ethernet-switching vlan members VLAN_TEST
set interfaces ge-0/0/0 unit 0 family ethernet-switching interface-mode trunk

set vlans VLAN_TEST vlan-id 101

set vlans VLAN_TEST vlan-id 101
set vlans VLAN_TEST vxlan vni 10101
@@ -0,0 +1,18 @@
#
set system host-name juniper-evpn-vni-list-all
#
set interfaces ge-0/0/0 unit 0 family ethernet-switching vlan members VLAN_TEST
set interfaces ge-0/0/0 unit 0 family ethernet-switching interface-mode trunk

set vlans VLAN_TEST vlan-id 101

set vlans VLAN_TEST vlan-id 101
set vlans VLAN_TEST vxlan vni 10101


set protocols evpn vni-options vni 10101 vrf-target target:65310:11003
set protocols evpn encapsulation vxlan
set protocols evpn multicast-mode ingress-replication
set protocols evpn default-gateway no-gateway-community
set protocols evpn extended-vni-list all
set protocols evpn duplicate-mac-detection auto-recovery-time 15
@@ -0,0 +1,18 @@
#
set system host-name juniper-evpn-vni-list-no-range
#
set interfaces ge-0/0/0 unit 0 family ethernet-switching vlan members VLAN_TEST
set interfaces ge-0/0/0 unit 0 family ethernet-switching interface-mode trunk

set vlans VLAN_TEST vlan-id 101

set vlans VLAN_TEST vlan-id 101
set vlans VLAN_TEST vxlan vni 10101


set protocols evpn vni-options vni 10101 vrf-target target:65310:11003
set protocols evpn encapsulation vxlan
set protocols evpn multicast-mode ingress-replication
set protocols evpn default-gateway no-gateway-community
set protocols evpn extended-vni-list [ 10101 10103 10105 ]
set protocols evpn duplicate-mac-detection auto-recovery-time 15
@@ -0,0 +1,18 @@
#
set system host-name juniper-evpn-vni-list-with-range
#
set interfaces ge-0/0/0 unit 0 family ethernet-switching vlan members VLAN_TEST
set interfaces ge-0/0/0 unit 0 family ethernet-switching interface-mode trunk

set vlans VLAN_TEST vlan-id 101

set vlans VLAN_TEST vlan-id 101
set vlans VLAN_TEST vxlan vni 10101


set protocols evpn vni-options vni 10101 vrf-target target:65310:11003
set protocols evpn encapsulation vxlan
set protocols evpn multicast-mode ingress-replication
set protocols evpn default-gateway no-gateway-community
set protocols evpn extended-vni-list [ 10101-10103 10105 ]
set protocols evpn duplicate-mac-detection auto-recovery-time 15
@@ -0,0 +1,4 @@
#
set system host-name juniper-overlay-ecmp
#
set forwarding-options vxlan-routing overlay-ecmp

0 comments on commit ef61a3a

Please sign in to comment.