Skip to content

Commit

Permalink
XR: basic support for bundle interfaces (#6019)
Browse files Browse the repository at this point in the history
  • Loading branch information
dhalperi committed Jul 21, 2020
1 parent 1227611 commit cd21308
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6902,6 +6902,11 @@ MAXIMUM_ACCEPTED_ROUTES
'maximum-accepted-routes'
;

MAXIMUM_ACTIVE
:
'maximum-active'
;

MAXIMUM_HOPS
:
'maximum-hops'
Expand Down Expand Up @@ -7187,6 +7192,11 @@ MINIMUM
'minimum'
;

MINIMUM_ACTIVE
:
'minimum-active'
;

MINIMUM_INTERVAL
:
'minimum-interval'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,29 @@ if_bfd_template
TEMPLATE name = variable_permissive NEWLINE
;

if_bundle
:
BUNDLE
(
if_bundle_id
| if_bundle_null
)
;

if_bundle_id
:
ID id = DEC MODE (ACTIVE | ON | PASSIVE) NEWLINE
;

if_bundle_null
:
(
MAXIMUM_ACTIVE
| MINIMUM_ACTIVE
| PORT_PRIORITY
) null_rest_of_line
;

if_channel_group
:
CHANNEL_GROUP num = DEC
Expand Down Expand Up @@ -617,7 +640,6 @@ if_null_block
| BEACON
| BGP_POLICY
| BRIDGE_GROUP
| BUNDLE
| CABLE
| CABLELENGTH
| CARRIER_DELAY
Expand Down Expand Up @@ -1621,6 +1643,7 @@ if_inner
if_autostate
| if_bandwidth
| if_bfd
| if_bundle
| if_channel_group
| if_crypto_map
| if_default_gw
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@
import org.batfish.grammar.cisco_xr.CiscoXrParser.If_autostateContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.If_bandwidthContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.If_bfd_templateContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.If_channel_groupContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.If_bundle_idContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.If_crypto_mapContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.If_delayContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.If_descriptionContext;
Expand Down Expand Up @@ -4444,10 +4444,9 @@ public void exitIf_bfd_template(If_bfd_templateContext ctx) {
}

@Override
public void exitIf_channel_group(If_channel_groupContext ctx) {
int num = toInteger(ctx.num);
String name = String.format("Bundle-Ether%d", num);
_currentInterfaces.forEach(i -> i.setChannelGroup(name));
public void exitIf_bundle_id(If_bundle_idContext ctx) {
int id = toInteger(ctx.id);
_currentInterfaces.forEach(i -> i.setBundleId(id));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ public Map<String, AsPathSet> getAsPathSets() {
return _asPathSets;
}

private Ip getBgpRouterId(final Configuration c, String vrfName, BgpProcess proc) {
private Ip getBgpRouterId(Configuration c, String vrfName, BgpProcess proc) {
Ip processRouterId = proc.getRouterId();
if (processRouterId == null) {
processRouterId = _vrfs.get(Configuration.DEFAULT_VRF_NAME).getBgpProcess().getRouterId();
Expand Down Expand Up @@ -944,7 +944,7 @@ public void setVendor(ConfigurationFormat format) {
}

private org.batfish.datamodel.BgpProcess toBgpProcess(
final Configuration c, BgpProcess proc, String vrfName) {
Configuration c, BgpProcess proc, String vrfName) {
org.batfish.datamodel.Vrf v = c.getVrfs().get(vrfName);
Ip bgpRouterId = getBgpRouterId(c, vrfName, proc);
int ebgpAdmin = RoutingProtocol.BGP.getDefaultAdministrativeCost(c.getConfigurationFormat());
Expand Down Expand Up @@ -1382,7 +1382,9 @@ private org.batfish.datamodel.Interface toInterface(
Vrf vrf = _vrfs.computeIfAbsent(vrfName, Vrf::new);
newIface.setDescription(iface.getDescription());
newIface.setActive(iface.getActive());
newIface.setChannelGroup(iface.getChannelGroup());
if (iface.getBundleId() != null) {
newIface.setChannelGroup(String.format("Bundle-Ether%d", iface.getBundleId()));
}
newIface.setCryptoMap(iface.getCryptoMap());
newIface.setHsrpGroups(
CollectionUtil.toImmutableMap(
Expand Down Expand Up @@ -2058,7 +2060,7 @@ public String toString() {

@Override
public List<Configuration> toVendorIndependentConfigurations() {
final Configuration c = new Configuration(_hostname, _vendor);
Configuration c = new Configuration(_hostname, _vendor);
c.getVendorFamily().setCiscoXr(_cf);
c.setDefaultInboundAction(LineAction.PERMIT);
c.setDefaultCrossZoneAction(LineAction.PERMIT);
Expand Down Expand Up @@ -2238,10 +2240,11 @@ public List<Configuration> toVendorIndependentConfigurations() {
*/
_interfaces.forEach(
(ifaceName, iface) -> {
// Portchannels
String chGroup = iface.getChannelGroup();
if (chGroup != null) {
org.batfish.datamodel.Interface viIface = c.getAllInterfaces().get(chGroup);
// Bundle ID
Integer bundleId = iface.getBundleId();
if (bundleId != null) {
String bundleName = String.format("Bundle-Ether%d", bundleId);
org.batfish.datamodel.Interface viIface = c.getAllInterfaces().get(bundleName);
if (viIface != null) {
viIface.addDependency(new Dependency(ifaceName, DependencyType.AGGREGATE));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public static int getDefaultMtu() {

@Nullable private Double _bandwidth;

private String _channelGroup;
private @Nullable Integer _bundleId;

private String _cryptoMap;

Expand Down Expand Up @@ -276,8 +276,8 @@ public Double getBandwidth() {
return _bandwidth;
}

public String getChannelGroup() {
return _channelGroup;
public Integer getBundleId() {
return _bundleId;
}

public String getCryptoMap() {
Expand Down Expand Up @@ -459,8 +459,8 @@ public void setBandwidth(@Nullable Double bandwidth) {
_bandwidth = bandwidth;
}

public void setChannelGroup(String channelGroup) {
_channelGroup = channelGroup;
public void setBundleId(@Nullable Integer bundleId) {
_bundleId = bundleId;
}

public void setCryptoMap(String cryptoMap) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package org.batfish.grammar.cisco_xr;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.batfish.common.util.Resources.readResource;
import static org.batfish.datamodel.matchers.ConfigurationMatchers.hasConfigurationFormat;
import static org.batfish.datamodel.matchers.MapMatchers.hasKeys;
import static org.batfish.main.BatfishTestUtils.TEST_SNAPSHOT;
import static org.batfish.main.BatfishTestUtils.configureBatfishTestSettings;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;

import java.io.IOException;
import java.util.Map;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.antlr.v4.runtime.ParserRuleContext;
import org.apache.commons.lang3.SerializationUtils;
import org.batfish.common.BatfishLogger;
import org.batfish.common.Warnings;
import org.batfish.config.Settings;
import org.batfish.datamodel.Configuration;
import org.batfish.datamodel.ConfigurationFormat;
import org.batfish.main.Batfish;
import org.batfish.main.BatfishTestUtils;
import org.batfish.representation.cisco_xr.CiscoXrConfiguration;
import org.batfish.representation.cisco_xr.Interface;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;

/** Tests for https://github.com/batfish/batfish/issues/6018. */
@ParametersAreNonnullByDefault
public final class GitHub6018Test {

private static final String TESTCONFIGS_PREFIX = "org/batfish/grammar/cisco_xr/testconfigs/";

@Rule public TemporaryFolder _folder = new TemporaryFolder();
@Rule public ExpectedException _thrown = ExpectedException.none();

private @Nonnull Configuration parseConfig(String hostname) {
try {
String[] names = new String[] {TESTCONFIGS_PREFIX + hostname};
Map<String, Configuration> configs = BatfishTestUtils.parseTextConfigs(_folder, names);
assertThat(configs, hasKey(hostname.toLowerCase()));
Configuration c = configs.get(hostname.toLowerCase());
assertThat(c, hasConfigurationFormat(ConfigurationFormat.CISCO_IOS_XR));
// Ensure that we used the CiscoXr parser.
assertThat(c.getVendorFamily().getCiscoXr(), notNullValue());
return c;
} catch (IOException e) {
throw new RuntimeException(e);
}
}

private @Nonnull CiscoXrConfiguration parseVendorConfig(String hostname) {
String src = readResource(TESTCONFIGS_PREFIX + hostname, UTF_8);
Settings settings = new Settings();
configureBatfishTestSettings(settings);
CiscoXrCombinedParser ciscoXrParser = new CiscoXrCombinedParser(src, settings);
CiscoXrControlPlaneExtractor extractor =
new CiscoXrControlPlaneExtractor(
src, ciscoXrParser, ConfigurationFormat.CISCO_IOS_XR, new Warnings());
ParserRuleContext tree =
Batfish.parse(
ciscoXrParser, new BatfishLogger(BatfishLogger.LEVELSTR_FATAL, false), settings);
extractor.processParseTree(TEST_SNAPSHOT, tree);
CiscoXrConfiguration vendorConfiguration =
(CiscoXrConfiguration) extractor.getVendorConfiguration();
vendorConfiguration.setFilename(TESTCONFIGS_PREFIX + hostname);
// crash if not serializable
return SerializationUtils.clone(vendorConfiguration);
}

@Test
public void testGitHub6018Extraction() {
CiscoXrConfiguration c = parseVendorConfig("gh6018");
assertThat(c.getInterfaces(), hasKeys("TenGigE0/0/0/24/0", "Bundle-Ether5"));
Interface tenGE = c.getInterfaces().get("TenGigE0/0/0/24/0");
assertThat(tenGE.getBundleId(), equalTo(5));
}

@Test
public void testGitHub6018Conversion() {
Configuration c = parseConfig("gh6018");
assertThat(c.getAllInterfaces(), hasKeys("TenGigE0/0/0/24/0", "Bundle-Ether5"));
org.batfish.datamodel.Interface tenGE = c.getAllInterfaces().get("TenGigE0/0/0/24/0");
assertThat(tenGE.getChannelGroup(), equalTo("Bundle-Ether5"));
assertThat(tenGE.getBandwidth(), equalTo(10e9));
org.batfish.datamodel.Interface bundle = c.getAllInterfaces().get("Bundle-Ether5");
assertThat(bundle.getChannelGroupMembers(), containsInAnyOrder("TenGigE0/0/0/24/0"));
assertThat(bundle.getBandwidth(), equalTo(10e9));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
!RANCID-CONTENT-TYPE: cisco-xr
hostname gh6018
!
interface TenGigE0/0/0/24/0
bundle id 5 mode active
load-interval 30
!
interface Bundle-Ether5
mtu 1514
lacp mode active
bundle minimum-active links 1
load-interval 30
!

0 comments on commit cd21308

Please sign in to comment.