Skip to content

Commit

Permalink
IOS-XR interface ipv4/6 address parsing (#6899)
Browse files Browse the repository at this point in the history
- update ipv4 address parsing for XR syntax
- parse and ignore ipv6 address
  • Loading branch information
arifogel committed Apr 12, 2021
1 parent fd37fbf commit 6668c2e
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 77 deletions.
Expand Up @@ -1780,6 +1780,8 @@ ETHERNET_SERVICES: 'ethernet-services';

ETYPE: 'etype';

EUI_64: 'eui-64';

EVALUATE: 'evaluate';

EVENT: 'event';
Expand Down Expand Up @@ -2725,6 +2727,8 @@ LINK_FAIL: 'link-fail';

LINK_FAULT_SIGNALING: 'link-fault-signaling';

LINK_LOCAL: 'link-local';

LINK_TYPE: 'link-type';

LINKSEC: 'linksec';
Expand Down Expand Up @@ -4365,6 +4369,8 @@ ROUTE_PREFERENCE: 'route-preference';

ROUTE_REFLECTOR_CLIENT: 'route-reflector-client';

ROUTE_TAG: 'route-tag';

ROUTE_TARGET: 'route-target';

ROUTE_TYPE: 'route-type';
Expand Down
Expand Up @@ -505,6 +505,12 @@ route_distinguisher
(IP_ADDRESS | bgp_asn) COLON uint_legacy
;

route_tag
:
// 1-4294967295
uint32
;

route_target
:
(IP_ADDRESS | bgp_asn) COLON uint_legacy
Expand Down Expand Up @@ -653,4 +659,4 @@ route_policy_name: WORD;

vrf_name: WORD;

access_list_name: WORD;
access_list_name: WORD;
Expand Up @@ -249,39 +249,6 @@ if_hsrp6_ip_address
IP ip = IPV6_ADDRESS NEWLINE
;

if_ip_address
:
(IP | IPV4) ADDRESS
VIRTUAL?
(
ip = IP_ADDRESS subnet = IP_ADDRESS
| prefix = IP_PREFIX
)
(STANDBY standby_address = IP_ADDRESS)?
(ROUTE_PREFERENCE pref=uint_legacy)?
(TAG tag=uint_legacy)?
NEWLINE
;

if_ip_address_dhcp
:
IP ADDRESS DHCP NEWLINE
;

if_ip_address_secondary
:
(
IP
| IPV4
) ADDRESS
(
(
ip = IP_ADDRESS subnet = IP_ADDRESS
)
| prefix = IP_PREFIX
) SECONDARY DHCP_GIADDR? NEWLINE
;

if_ip_authentication
:
IP AUTHENTICATION
Expand Down Expand Up @@ -519,6 +486,7 @@ if_ipv4: IPV4 if_ipv4_inner;
if_ipv4_inner
:
if_ipv4_access_group
| if_ipv4_address
| if_ipv4_null
;

Expand All @@ -537,6 +505,14 @@ if_ipv4_access_group
) NEWLINE
;

if_ipv4_address: ADDRESS interface_ipv4_address SECONDARY? (ROUTE_TAG tag=route_tag)? NEWLINE;

interface_ipv4_address
:
address = IP_ADDRESS mask = IP_ADDRESS
| prefix = IP_PREFIX
;

if_ipv4_null
:
// TODO: some of these should be handled or at least warn
Expand All @@ -557,6 +533,7 @@ if_ipv6
if_ipv6_inner
:
if_ipv6_access_group
| if_ipv6_address
| if_ipv6_enable
| if_ipv6_traffic_filter
;
Expand All @@ -574,6 +551,21 @@ if_ipv6_access_group
) NEWLINE
;

if_ipv6_address
:
ADDRESS
(
address = IPV6_ADDRESS (LINK_LOCAL | len = ipv6_interface_address_length)
| prefix = IPV6_PREFIX EUI_64?
) (ROUTE_TAG tag = route_tag)? NEWLINE
;

ipv6_interface_address_length
:
// 1-128
uint8
;

if_ipv6_enable
:
ENABLE NEWLINE
Expand Down Expand Up @@ -1680,9 +1672,6 @@ if_inner
| if_hsrp6
| if_ip_proxy_arp
| if_ip_verify
| if_ip_address
| if_ip_address_dhcp
| if_ip_address_secondary
| if_ip_authentication
| if_ip_dhcp
| if_ip_flow_monitor
Expand Down
Expand Up @@ -466,8 +466,6 @@
import org.batfish.grammar.cisco_xr.CiscoXrParser.If_delayContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.If_descriptionContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.If_encapsulationContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.If_ip_addressContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.If_ip_address_secondaryContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.If_ip_forwardContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.If_ip_helper_addressContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.If_ip_igmpContext;
Expand All @@ -486,6 +484,7 @@
import org.batfish.grammar.cisco_xr.CiscoXrParser.If_ip_summary_addressContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.If_ip_verifyContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.If_ipv4_access_groupContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.If_ipv4_addressContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.If_ipv6_access_groupContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.If_ipv6_traffic_filterContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.If_isis_metricContext;
Expand Down Expand Up @@ -525,6 +524,7 @@
import org.batfish.grammar.cisco_xr.CiscoXrParser.Inspect_protocolContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.Int_compContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.Int_exprContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.Interface_ipv4_addressContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.Interface_is_stanzaContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.Interface_nameContext;
import org.batfish.grammar.cisco_xr.CiscoXrParser.Ios_banner_headerContext;
Expand Down Expand Up @@ -3843,48 +3843,22 @@ public void exitIf_ipv6_access_group(If_ipv6_access_groupContext ctx) {
}

@Override
public void exitIf_ip_address(If_ip_addressContext ctx) {
ConcreteInterfaceAddress address;
if (ctx.prefix != null) {
address = ConcreteInterfaceAddress.parse(ctx.prefix.getText());
} else {
Ip ip = toIp(ctx.ip);
Ip mask = toIp(ctx.subnet);
address = ConcreteInterfaceAddress.create(ip, mask);
public void exitIf_ipv4_address(If_ipv4_addressContext ctx) {
Optional<ConcreteInterfaceAddress> maybeAddress =
toConcreteInterfaceAddress(ctx, ctx.interface_ipv4_address());
if (!maybeAddress.isPresent()) {
return;
}
ConcreteInterfaceAddress address = maybeAddress.get();
for (Interface currentInterface : _currentInterfaces) {
currentInterface.setAddress(address);
}
if (ctx.STANDBY() != null) {
Ip standbyIp = toIp(ctx.standby_address);
ConcreteInterfaceAddress standbyAddress =
ConcreteInterfaceAddress.create(standbyIp, address.getNetworkBits());
for (Interface currentInterface : _currentInterfaces) {
currentInterface.setStandbyAddress(standbyAddress);
if (ctx.SECONDARY() != null) {
currentInterface.getSecondaryAddresses().add(address);
} else {
currentInterface.setAddress(address);
}
}
if (ctx.ROUTE_PREFERENCE() != null) {
warn(ctx, "Unsupported: route-preference declared in interface IP address");
}
if (ctx.TAG() != null) {
warn(ctx, "Unsupported: tag declared in interface IP address");
}
}

@Override
public void exitIf_ip_address_secondary(If_ip_address_secondaryContext ctx) {
Ip ip;
Ip mask;
ConcreteInterfaceAddress address;
if (ctx.prefix != null) {
address = ConcreteInterfaceAddress.parse(ctx.prefix.getText());
} else {
ip = toIp(ctx.ip);
mask = toIp(ctx.subnet);
address = ConcreteInterfaceAddress.create(ip, mask.numSubnetBits());
}
for (Interface currentInterface : _currentInterfaces) {
currentInterface.getSecondaryAddresses().add(address);
if (ctx.tag != null) {
warn(ctx, "Unsupported: tag declared in interface ipv4 address");
}
}

Expand Down Expand Up @@ -8538,4 +8512,18 @@ public void visitErrorNode(ErrorNode errorNode) {
}
return Optional.of(num);
}

private @Nonnull Optional<ConcreteInterfaceAddress> toConcreteInterfaceAddress(
ParserRuleContext messageCtx, Interface_ipv4_addressContext ctx) {
try {
if (ctx.prefix != null) {
return Optional.of(ConcreteInterfaceAddress.parse(ctx.prefix.getText()));
} else if (ctx.address != null) {
return Optional.of(ConcreteInterfaceAddress.create(toIp(ctx.address), toIp(ctx.mask)));
}
} catch (IllegalArgumentException e) {
warn(messageCtx, "Invalid interface ipv4 address");
}
return Optional.empty();
}
}
Expand Up @@ -77,6 +77,7 @@
import org.batfish.datamodel.AsPath;
import org.batfish.datamodel.BgpActivePeerConfig;
import org.batfish.datamodel.Bgpv4Route;
import org.batfish.datamodel.ConcreteInterfaceAddress;
import org.batfish.datamodel.Configuration;
import org.batfish.datamodel.ConfigurationFormat;
import org.batfish.datamodel.Interface;
Expand Down Expand Up @@ -1275,4 +1276,25 @@ public void testIpv6AccessListParsing() {
// Do not crash
assertNotNull(parseVendorConfig(hostname));
}

@Test
public void testInterfaceAddressExtraction() {
String hostname = "xr-interface-address";
CiscoXrConfiguration vc = parseVendorConfig(hostname);

String i1Name = "GigabitEthernet0/0/0/0";

assertThat(vc.getInterfaces(), hasKeys(i1Name));

{
org.batfish.representation.cisco_xr.Interface iface = vc.getInterfaces().get(i1Name);
ConcreteInterfaceAddress primary = ConcreteInterfaceAddress.parse("10.0.0.1/31");
ConcreteInterfaceAddress secondary1 = ConcreteInterfaceAddress.parse("10.0.0.3/31");
ConcreteInterfaceAddress secondary2 = ConcreteInterfaceAddress.parse("10.0.0.5/31");

assertThat(iface.getAllAddresses(), containsInAnyOrder(primary, secondary1, secondary2));
assertThat(iface.getAddress(), equalTo(primary));
assertThat(iface.getSecondaryAddresses(), containsInAnyOrder(secondary1, secondary2));
}
}
}
@@ -0,0 +1,15 @@
!RANCID-CONTENT-TYPE: cisco-xr
!
hostname xr-interface-address
!

interface GigabitEthernet0/0/0/0
ipv4 address 10.0.0.1/31
ipv4 address 10.0.0.3 255.255.255.254 secondary
ipv4 address 10.0.0.5 255.255.255.254 secondary route-tag 5

ipv6 address dead:beef::1/126
ipv6 address deee:beef::1 127
ipv6 address beee:beef::1/64 route-tag 5
ipv6 address 2::3 link-local
!

0 comments on commit 6668c2e

Please sign in to comment.