diff options
author | Marek Gradzki <mgradzki@cisco.com> | 2017-06-23 14:00:58 +0200 |
---|---|---|
committer | Marek Gradzki <mgradzki@cisco.com> | 2017-06-28 10:51:08 +0000 |
commit | 995340b2a5204f8f643b3c5a4d18620f02b795a0 (patch) | |
tree | 44b27103896edc49e96dac399b6a5ef256ba612e /bgp/inet/src/test/java/io/fd | |
parent | 2064e56f72c75eac68773bf35de81c081cb04231 (diff) |
HC2VPP-174: add support for BGP IPv4/IPv6 unicast
Tranlates BGP IPv4/IPv6 routes to VPP FIB.
Not supported:
- multiple paths (https://tools.ietf.org/html/rfc7911)
- IPv6 SR
Change-Id: I06f0e81dd44df6a2eb7a3fe95445041e8f4f7af9
Signed-off-by: Marek Gradzki <mgradzki@cisco.com>
Diffstat (limited to 'bgp/inet/src/test/java/io/fd')
-rw-r--r-- | bgp/inet/src/test/java/io/fd/hc2vpp/bgp/inet/Ipv4WriterTest.java | 137 | ||||
-rw-r--r-- | bgp/inet/src/test/java/io/fd/hc2vpp/bgp/inet/Ipv6WriterTest.java | 142 |
2 files changed, 279 insertions, 0 deletions
diff --git a/bgp/inet/src/test/java/io/fd/hc2vpp/bgp/inet/Ipv4WriterTest.java b/bgp/inet/src/test/java/io/fd/hc2vpp/bgp/inet/Ipv4WriterTest.java new file mode 100644 index 000000000..0adfb480f --- /dev/null +++ b/bgp/inet/src/test/java/io/fd/hc2vpp/bgp/inet/Ipv4WriterTest.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.bgp.inet; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; +import static io.fd.hc2vpp.bgp.inet.RouteRequestProducer.MPLS_LABEL_INVALID; + +import io.fd.hc2vpp.common.test.util.FutureProducer; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.IpAddDelRoute; +import io.fd.vpp.jvpp.core.dto.IpAddDelRouteReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.routes.Ipv4Routes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.routes.ipv4.routes.Ipv4Route; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.routes.ipv4.routes.Ipv4RouteBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.routes.ipv4.routes.Ipv4RouteKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.PathId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.AttributesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.BgpRib; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.RibId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.Rib; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.RibKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.LocRib; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.ipv4.next.hop._case.Ipv4NextHopBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class Ipv4WriterTest implements FutureProducer, ByteDataTranslator { + private static final InstanceIdentifier<Tables> TABLE_ID = InstanceIdentifier.create(BgpRib.class) + .child(Rib.class, new RibKey(new RibId("test-rib"))).child(LocRib.class) + .child(Tables.class, new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class)); + + @Mock + private FutureJVppCore vppApi; + private Ipv4Writer writer; + + @Before + public void setUp() { + initMocks(this); + writer = new Ipv4Writer(vppApi); + when(vppApi.ipAddDelRoute(any())).thenReturn(future(new IpAddDelRouteReply())); + } + + @SuppressWarnings("unchecked") + private static InstanceIdentifier<Ipv4Route> id(final Ipv4Prefix destination, final PathId pathId) { + return TABLE_ID.child((Class) Ipv4Routes.class) + .child(Ipv4Route.class, new Ipv4RouteKey(pathId, destination)); + } + + private static Ipv4Route route(final Ipv4Prefix destination, final PathId pathId, + final Ipv4Address nextHopAddress) { + final Ipv4NextHopCase nextHop = + new Ipv4NextHopCaseBuilder().setIpv4NextHop(new Ipv4NextHopBuilder().setGlobal(nextHopAddress).build()) + .build(); + return new Ipv4RouteBuilder() + .setPrefix(destination) + .setPathId(pathId) + .setAttributes(new AttributesBuilder().setCNextHop(nextHop).build()) + .build(); + } + + @Test + public void testCreate() throws WriteFailedException.CreateFailedException { + final Ipv4Prefix destination = new Ipv4Prefix("1.2.3.4/24"); + final PathId pathId = new PathId(123L); + final Ipv4Address nextHopAddress = new Ipv4AddressNoZone("5.6.7.8"); + + writer.create( + id(destination, pathId), + route(destination, pathId, nextHopAddress) + ); + verifyRequest(true); + } + + @Test + public void testDelete() throws WriteFailedException.DeleteFailedException { + final Ipv4Prefix destination = new Ipv4Prefix("1.2.3.4/24"); + final PathId pathId = new PathId(456L); + final Ipv4Address nextHopAddress = new Ipv4AddressNoZone("5.6.7.8"); + + writer.delete( + id(destination, pathId), + route(destination, pathId, nextHopAddress) + ); + verifyRequest(false); + } + + @Test(expected = WriteFailedException.UpdateFailedException.class) + public void testUpdate() throws WriteFailedException.UpdateFailedException { + final Ipv4Prefix destination = new Ipv4Prefix("10.1.0.1/28"); + final PathId pathId = new PathId(456L); + + // update is not supported + writer.update(id(destination, pathId), mock(Ipv4Route.class), mock(Ipv4Route.class)); + } + + private void verifyRequest(boolean isAdd) { + final IpAddDelRoute request = new IpAddDelRoute(); + request.isAdd = booleanToByte(isAdd); + request.nextHopSwIfIndex = -1; + request.nextHopViaLabel = MPLS_LABEL_INVALID; + request.nextHopAddress = new byte[] {5, 6, 7, 8}; + request.dstAddress = new byte[] {1, 2, 3, 4}; + request.dstAddressLength = 24; + verify(vppApi).ipAddDelRoute(request); + } +} diff --git a/bgp/inet/src/test/java/io/fd/hc2vpp/bgp/inet/Ipv6WriterTest.java b/bgp/inet/src/test/java/io/fd/hc2vpp/bgp/inet/Ipv6WriterTest.java new file mode 100644 index 000000000..fa9554698 --- /dev/null +++ b/bgp/inet/src/test/java/io/fd/hc2vpp/bgp/inet/Ipv6WriterTest.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.bgp.inet; + +import static io.fd.hc2vpp.bgp.inet.RouteRequestProducer.MPLS_LABEL_INVALID; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +import io.fd.hc2vpp.common.test.util.FutureProducer; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.IpAddDelRoute; +import io.fd.vpp.jvpp.core.dto.IpAddDelRouteReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv6.routes.Ipv6Routes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv6.routes.ipv6.routes.Ipv6Route; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv6.routes.ipv6.routes.Ipv6RouteBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv6.routes.ipv6.routes.Ipv6RouteKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.PathId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.AttributesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.BgpRib; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.RibId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.Rib; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.RibKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.LocRib; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv6AddressFamily; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv6NextHopCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv6NextHopCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.ipv6.next.hop._case.Ipv6NextHopBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class Ipv6WriterTest implements FutureProducer, ByteDataTranslator { + private static final InstanceIdentifier<Tables> TABLE_ID = InstanceIdentifier.create(BgpRib.class) + .child(Rib.class, new RibKey(new RibId("test-rib"))).child(LocRib.class) + .child(Tables.class, new TablesKey(Ipv6AddressFamily.class, UnicastSubsequentAddressFamily.class)); + + @Mock + private FutureJVppCore vppApi; + private Ipv6Writer writer; + + @Before + public void setUp() { + initMocks(this); + writer = new Ipv6Writer(vppApi); + when(vppApi.ipAddDelRoute(any())).thenReturn(future(new IpAddDelRouteReply())); + } + + @SuppressWarnings("unchecked") + private static InstanceIdentifier<Ipv6Route> id(final Ipv6Prefix destination, final PathId pathId) { + return TABLE_ID.child((Class) Ipv6Routes.class) + .child(Ipv6Route.class, new Ipv6RouteKey(pathId, destination)); + } + + private static Ipv6Route route(final Ipv6Prefix destination, final PathId pathId, + final Ipv6Address nextHopAddress) { + final Ipv6NextHopCase nextHop = + new Ipv6NextHopCaseBuilder().setIpv6NextHop(new Ipv6NextHopBuilder().setGlobal(nextHopAddress).build()) + .build(); + return new Ipv6RouteBuilder() + .setPrefix(destination) + .setPathId(pathId) + .setAttributes(new AttributesBuilder().setCNextHop(nextHop).build()) + .build(); + } + + @Test + public void testCreate() throws WriteFailedException.CreateFailedException { + final Ipv6Prefix destination = new Ipv6Prefix("2001:db8:a0b:12f0:0:0:0:1/64"); + final PathId pathId = new PathId(123L); + final Ipv6Address nextHopAddress = new Ipv6AddressNoZone("2001:db8:a0b:12f0:0:0:0:2"); + + writer.create( + id(destination, pathId), + route(destination, pathId, nextHopAddress) + ); + verifyRequest(true); + } + + @Test + public void testDelete() throws WriteFailedException.DeleteFailedException { + final Ipv6Prefix destination = new Ipv6Prefix("2001:db8:a0b:12f0:0:0:0:1/64"); + final PathId pathId = new PathId(456L); + final Ipv6Address nextHopAddress = new Ipv6AddressNoZone("2001:db8:a0b:12f0:0:0:0:2"); + + writer.delete( + id(destination, pathId), + route(destination, pathId, nextHopAddress) + ); + verifyRequest(false); + } + + @Test(expected = WriteFailedException.UpdateFailedException.class) + public void testUpdate() throws WriteFailedException.UpdateFailedException { + final Ipv6Prefix destination = new Ipv6Prefix("2001:db8:a0b:12f0:0:0:0:1/64"); + final PathId pathId = new PathId(456L); + + // update is not supported + writer.update(id(destination, pathId), mock(Ipv6Route.class), mock(Ipv6Route.class)); + } + + private void verifyRequest(boolean isAdd) { + final IpAddDelRoute request = new IpAddDelRoute(); + request.isAdd = booleanToByte(isAdd); + request.isIpv6 = 1; + request.nextHopSwIfIndex = -1; + request.nextHopViaLabel = MPLS_LABEL_INVALID; + request.nextHopAddress = new byte[] { + 0x20, 0x01, 0x0d, (byte) 0xb8, 0x0a, 0x0b, 0x12, (byte) 0xf0, + 0, 0, 0, 0, 0, 0, 0, 2}; + request.dstAddress = new byte[] { + 0x20, 0x01, 0x0d, (byte) 0xb8, 0x0a, 0x0b, 0x12, (byte) 0xf0, + 0, 0, 0, 0, 0, 0, 0, 1}; + request.dstAddressLength = 64; + verify(vppApi).ipAddDelRoute(request); + } +} |