diff options
author | Jan Srnicek <jsrnicek@cisco.com> | 2017-01-04 16:39:10 +0100 |
---|---|---|
committer | Marek Gradzki <mgradzki@cisco.com> | 2017-01-04 18:04:13 +0000 |
commit | ae767d51cdba6f2296c52b63cd569a98d6f7db27 (patch) | |
tree | 2c3d9e4db9b8912782824064406d4d768af20a02 /v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces | |
parent | 7c0f620652cd014b791a3e243f9ca7b08e697d3a (diff) |
HONEYCOMB-102/HONEYCOMB-103 - Ipv6 Support
Contains
- Ipv6 read/write Support for Interfaces
- Ipv6 read/write Support for Subi-Interfaces
- Postman collection with relevant requests
Todo
- Test coverage - HC2VPP-11
- Refactoring - HC2VPP-12
- Could be related to - HONEYCOMB-328
Tested
- read/write for both interfaces and sub-interfaces - passes ok
- init with following scenarios
- vpp clean/hc has data - passes ok
- vpp has data/hc clean - passed with error for sub-interface described in HONEYCOMB-328.
The actual ipv4/ipv6 part passes ok
Change-Id: Ib18acb9b18d6374dc5847e30db4049696d512e72
Signed-off-by: Jan Srnicek <jsrnicek@cisco.com>
Diffstat (limited to 'v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces')
12 files changed, 561 insertions, 39 deletions
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4Writer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/IpWriter.java index 36e1800e1..795dc4587 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4Writer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/IpWriter.java @@ -19,23 +19,30 @@ package io.fd.hc2vpp.v3po.interfaces.ip; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import io.fd.hc2vpp.common.translate.util.AddressTranslator; import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; -import io.fd.hc2vpp.common.translate.util.Ipv4Translator; import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.MappingContext; import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.IpNeighborAddDel; import io.fd.vpp.jvpp.core.dto.SwInterfaceAddDelAddress; import io.fd.vpp.jvpp.core.dto.SwInterfaceAddDelAddressReply; import io.fd.vpp.jvpp.core.future.FutureJVppCore; import java.util.concurrent.CompletionStage; +import java.util.function.Supplier; import javax.annotation.Nonnegative; import javax.annotation.Nonnull; 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.Ipv6AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; /** - * Utility class providing Ipv4 CUD support. + * Utility class providing Ipv4/6 CUD support. */ -public interface Ipv4Writer extends ByteDataTranslator, Ipv4Translator, JvppReplyConsumer { +public interface IpWriter extends ByteDataTranslator, AddressTranslator, JvppReplyConsumer { int DOTTED_QUAD_MASK_LENGTH = 4; int IPV4_ADDRESS_PART_BITS_COUNT = 8; @@ -59,6 +66,23 @@ public interface Ipv4Writer extends ByteDataTranslator, Ipv4Translator, JvppRepl getReplyForWrite(swInterfaceAddDelAddressReplyCompletionStage.toCompletableFuture(), id); } + default void addDelAddress(@Nonnull final FutureJVppCore futureJVppCore, final boolean add, + final InstanceIdentifier<?> id, + @Nonnegative final int ifaceId, + @Nonnull final Ipv6AddressNoZone address, @Nonnegative final byte prefixLength) + throws WriteFailedException { + checkNotNull(address, "address should not be null"); + + final byte[] addressBytes = ipv6AddressNoZoneToArray(address); + + final CompletionStage<SwInterfaceAddDelAddressReply> swInterfaceAddDelAddressReplyCompletionStage = + futureJVppCore.swInterfaceAddDelAddress( + getSwInterfaceAddDelAddressRequest(ifaceId, booleanToByte(add) /* isAdd */, + (byte) 1 /* isIpv6 */, (byte) 0 /* delAll */, prefixLength, addressBytes)); + + getReplyForWrite(swInterfaceAddDelAddressReplyCompletionStage.toCompletableFuture(), id); + } + default SwInterfaceAddDelAddress getSwInterfaceAddDelAddressRequest(final int swIfc, final byte isAdd, final byte ipv6, final byte deleteAll, final byte length, final byte[] addr) { @@ -105,4 +129,38 @@ public interface Ipv4Writer extends ByteDataTranslator, Ipv4Translator, JvppRepl return (byte) leadingOnes; } + default int subInterfaceIndex(final InstanceIdentifier<?> id, final NamingContext interfaceContext, + final MappingContext mappingContext) { + return interfaceContext + .getIndex(id.firstKeyOf(Interface.class).getName() + "." + id.firstKeyOf(SubInterface.class).getIdentifier(), + mappingContext); + } + + default void addDelNeighbour(@Nonnull final InstanceIdentifier<?> id, + @Nonnull final Supplier<IpNeighborAddDel> requestSupplier, + @Nonnull final FutureJVppCore api) throws WriteFailedException { + getReplyForWrite(api.ipNeighborAddDel(requestSupplier.get()).toCompletableFuture(), id); + } + + default IpNeighborAddDel preBindIpv4Request(final boolean add) { + IpNeighborAddDel request = staticPreBindRequest(add); + request.isIpv6 = 0; + + return request; + } + + default IpNeighborAddDel preBindIpv6Request(final boolean add) { + IpNeighborAddDel request = staticPreBindRequest(add); + request.isIpv6 = 1; + + return request; + } + + static IpNeighborAddDel staticPreBindRequest(final boolean add) { + IpNeighborAddDel request = new IpNeighborAddDel(); + + request.isAdd = ByteDataTranslator.INSTANCE.booleanToByte(add); + request.isStatic = 1; + return request; + } } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/subnet/validation/SubnetValidator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/subnet/validation/Ipv4SubnetValidator.java index c5b011e07..28cd70440 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/subnet/validation/SubnetValidator.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/subnet/validation/Ipv4SubnetValidator.java @@ -21,7 +21,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.Function; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; -import io.fd.hc2vpp.v3po.interfaces.ip.Ipv4Writer; +import io.fd.hc2vpp.v3po.interfaces.ip.IpWriter; import java.util.List; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address; @@ -32,7 +32,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev14061 /** * Validator for detecting if there is an attempt to assign multiple addresses from same subnet */ -public class SubnetValidator implements Ipv4Writer { +public class Ipv4SubnetValidator implements IpWriter { /** * Checks whether data provided for writing are not in collision with already existing data diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v4/Ipv4AddressCustomizer.java index 6a6bb6c35..0860436d3 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4AddressCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v4/Ipv4AddressCustomizer.java @@ -14,17 +14,19 @@ * limitations under the License. */ -package io.fd.hc2vpp.v3po.interfaces.ip; +package io.fd.hc2vpp.v3po.interfaces.ip.v4; import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Optional; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfaces.ip.IpWriter; +import io.fd.hc2vpp.v3po.interfaces.ip.subnet.validation.Ipv4SubnetValidator; import io.fd.hc2vpp.v3po.interfaces.ip.subnet.validation.SubnetValidationException; import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; import io.fd.honeycomb.translate.util.RWUtils; -import io.fd.hc2vpp.v3po.interfaces.ip.subnet.validation.SubnetValidator; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; import io.fd.vpp.jvpp.core.future.FutureJVppCore; @@ -45,14 +47,15 @@ import org.slf4j.LoggerFactory; * Customizer for writing {@link Address} */ public class Ipv4AddressCustomizer extends FutureJVppCustomizer - implements ListWriterCustomizer<Address, AddressKey>, Ipv4Writer { + implements ListWriterCustomizer<Address, AddressKey>, IpWriter { private static final Logger LOG = LoggerFactory.getLogger(Ipv4AddressCustomizer.class); private final NamingContext interfaceContext; - private final SubnetValidator subnetValidator; + private final Ipv4SubnetValidator subnetValidator; + @VisibleForTesting Ipv4AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull final NamingContext interfaceContext, - @Nonnull final SubnetValidator subnetValidator) { + @Nonnull final Ipv4SubnetValidator subnetValidator) { super(futureJVppCore); this.interfaceContext = checkNotNull(interfaceContext, "Interface context cannot be null"); this.subnetValidator = checkNotNull(subnetValidator, "Subnet validator cannot be null"); @@ -60,7 +63,7 @@ public class Ipv4AddressCustomizer extends FutureJVppCustomizer public Ipv4AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull final NamingContext interfaceContext) { - this(futureJVppCore, interfaceContext, new SubnetValidator()); + this(futureJVppCore, interfaceContext, new Ipv4SubnetValidator()); } @Override diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v4/Ipv4Customizer.java index ff86331b1..15afda271 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4Customizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v4/Ipv4Customizer.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package io.fd.hc2vpp.v3po.interfaces.ip; +package io.fd.hc2vpp.v3po.interfaces.ip.v4; -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v4/Ipv4NeighbourCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v4/Ipv4NeighbourCustomizer.java new file mode 100644 index 000000000..b44a827a9 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v4/Ipv4NeighbourCustomizer.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2016 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.v3po.interfaces.ip.v4; + +import io.fd.hc2vpp.common.translate.util.AddressTranslator; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfaces.ip.IpWriter; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.IpNeighborAddDel; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Neighbor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.NeighborKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * Customizer for writing {@link Neighbor} for {@link Ipv4}. + */ +public class Ipv4NeighbourCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer<Neighbor, NeighborKey>, ByteDataTranslator, AddressTranslator, + IpWriter, JvppReplyConsumer { + + + private static final Logger LOG = LoggerFactory.getLogger(Ipv4NeighbourCustomizer.class); + private final NamingContext interfaceContext; + + public Ipv4NeighbourCustomizer(final FutureJVppCore futureJVppCore, final NamingContext interfaceContext) { + super(futureJVppCore); + this.interfaceContext = interfaceContext; + } + + @Override + public void writeCurrentAttributes(@Nonnull InstanceIdentifier<Neighbor> id, @Nonnull Neighbor data, + @Nonnull WriteContext writeContext) + throws WriteFailedException { + + LOG.debug("Processing request for Neighbour {} write", id); + + addDelNeighbour(id, () -> { + IpNeighborAddDel request = preBindIpv4Request(true); + + request.dstAddress = ipv4AddressNoZoneToArray(data.getIp()); + request.macAddress = parseMac(data.getLinkLayerAddress().getValue()); + request.swIfIndex = interfaceContext + .getIndex(id.firstKeyOf(Interface.class).getName(), writeContext.getMappingContext()); + + return request; + }, getFutureJVpp()); + LOG.debug("Neighbour {} successfully written", id); + } + + @Override + public void updateCurrentAttributes(@Nonnull InstanceIdentifier<Neighbor> id, @Nonnull Neighbor dataBefore, + @Nonnull Neighbor dataAfter, + @Nonnull WriteContext writeContext) throws WriteFailedException { + throw new UnsupportedOperationException("Operation not supported"); + } + + @Override + public void deleteCurrentAttributes(@Nonnull InstanceIdentifier<Neighbor> id, @Nonnull Neighbor data, + @Nonnull WriteContext writeContext) + throws WriteFailedException { + + LOG.debug("Processing request for Neighbour {} delete", id); + + addDelNeighbour(id, () -> { + IpNeighborAddDel request = preBindIpv4Request(false); + + request.dstAddress = ipv4AddressNoZoneToArray(data.getIp()); + request.macAddress = parseMac(data.getLinkLayerAddress().getValue()); + request.swIfIndex = interfaceContext + .getIndex(id.firstKeyOf(Interface.class).getName(), writeContext.getMappingContext()); + + return request; + }, getFutureJVpp()); + LOG.debug("Neighbour {} successfully deleted", id); + } +}
\ No newline at end of file diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v4/subinterface/SubInterfaceIpv4AddressCustomizer.java index 214ff36c4..f6b8ead69 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v4/subinterface/SubInterfaceIpv4AddressCustomizer.java @@ -14,14 +14,15 @@ * limitations under the License. */ -package io.fd.hc2vpp.v3po.interfaces.ip; +package io.fd.hc2vpp.v3po.interfaces.ip.v4.subinterface; import static com.google.common.base.Preconditions.checkNotNull; -import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfaces.ip.IpWriter; import io.fd.hc2vpp.v3po.util.SubInterfaceUtils; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; import io.fd.vpp.jvpp.core.future.FutureJVppCore; @@ -44,7 +45,7 @@ import org.slf4j.LoggerFactory; * Write customizer for sub-interface {@link Address} */ public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer - implements ListWriterCustomizer<Address, AddressKey>, Ipv4Writer { + implements ListWriterCustomizer<Address, AddressKey>, IpWriter { private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceIpv4AddressCustomizer.class); private final NamingContext interfaceContext; diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v4/subinterface/SubInterfaceIpv4NeighbourCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v4/subinterface/SubInterfaceIpv4NeighbourCustomizer.java new file mode 100644 index 000000000..6255d08ee --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v4/subinterface/SubInterfaceIpv4NeighbourCustomizer.java @@ -0,0 +1,99 @@ +/* + * 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.v3po.interfaces.ip.v4.subinterface; + +import io.fd.hc2vpp.common.translate.util.AddressTranslator; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfaces.ip.IpWriter; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.IpNeighborAddDel; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.Neighbor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.NeighborKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SubInterfaceIpv4NeighbourCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer<Neighbor, NeighborKey>, ByteDataTranslator, AddressTranslator, IpWriter, + JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceIpv4NeighbourCustomizer.class); + private final NamingContext interfaceContext; + + public SubInterfaceIpv4NeighbourCustomizer(final FutureJVppCore futureJVppCore, + final NamingContext interfaceContext) { + super(futureJVppCore); + this.interfaceContext = interfaceContext; + } + + @Override + public void writeCurrentAttributes(@Nonnull InstanceIdentifier<Neighbor> id, @Nonnull Neighbor data, + @Nonnull WriteContext writeContext) + throws WriteFailedException { + + LOG.debug("Processing request for Neighbour {} write", id); + + addDelNeighbour(id, () -> { + IpNeighborAddDel request = preBindIpv4Request(true); + + request.dstAddress = ipv4AddressNoZoneToArray(data.getIp()); + request.macAddress = parseMac(data.getLinkLayerAddress().getValue()); + request.swIfIndex = subInterfaceIndex(id, interfaceContext, writeContext.getMappingContext()); + + //TODO HONEYCOMB-182 if it is necessary for future use ,make adjustments to be able to set vrfid + //request.vrfId + return request; + }, getFutureJVpp()); + LOG.info("Neighbour {} successfully written", id); + } + + @Override + public void updateCurrentAttributes(@Nonnull InstanceIdentifier<Neighbor> id, @Nonnull Neighbor dataBefore, + @Nonnull Neighbor dataAfter, + @Nonnull WriteContext writeContext) throws WriteFailedException { + throw new UnsupportedOperationException("Operation not supported"); + } + + @Override + public void deleteCurrentAttributes(@Nonnull InstanceIdentifier<Neighbor> id, @Nonnull Neighbor data, + @Nonnull WriteContext writeContext) + throws WriteFailedException { + + LOG.debug("Processing request for Neighbour {} delete", id); + + addDelNeighbour(id, () -> { + IpNeighborAddDel request = preBindIpv4Request(false); + + request.dstAddress = ipv4AddressNoZoneToArray(data.getIp()); + request.macAddress = parseMac(data.getLinkLayerAddress().getValue()); + request.swIfIndex = subInterfaceIndex(id, interfaceContext, writeContext.getMappingContext()); + + //TODO HONEYCOMB-182 if it is necessary for future use ,make adjustments to be able to set vrfid + //request.vrfId + return request; + }, getFutureJVpp()); + LOG.info("Neighbour {} successfully deleted", id); + } + +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v6/Ipv6AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v6/Ipv6AddressCustomizer.java new file mode 100644 index 000000000..6984c8df6 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v6/Ipv6AddressCustomizer.java @@ -0,0 +1,92 @@ +/* + * 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.v3po.interfaces.ip.v6; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfaces.ip.IpWriter; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv6.Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv6.AddressKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class Ipv6AddressCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer<Address, AddressKey>, IpWriter { + + private static final Logger LOG = LoggerFactory.getLogger(Ipv6AddressCustomizer.class); + + private static final String LINK_LOCAL_START_MASK = "fe08"; + private final NamingContext interfaceContext; + + public Ipv6AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext interfaceContext) { + super(futureJVppCore); + this.interfaceContext = checkNotNull(interfaceContext, "Interface context cannot be null"); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Address> id, @Nonnull final Address dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final String interfaceName = id.firstKeyOf(Interface.class).getName(); + final int interfaceIndex = interfaceContext.getIndex(interfaceName, writeContext.getMappingContext()); + + // prevents scenario + // - vpp has been restarted == cleaned state + // - hc tries to restore data, which has link-local address in it + // link layer address is created by vpp(generated) after adding first address, so its present just + // after adding first address, and attempt to override it during init would cause error -1 + if (dataAfter.getIp().getValue().startsWith(LINK_LOCAL_START_MASK)) { + LOG.info("An attempt to rewrite link-local address with {} has been detected,ignoring request", + dataAfter.getIp()); + return; + } + + addDelAddress(getFutureJVpp(), true, id, interfaceIndex, dataAfter.getIp(), + dataAfter.getPrefixLength().byteValue()); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Address> id, + @Nonnull final Address dataBefore, + @Nonnull final Address dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, + new UnsupportedOperationException("Operation not supported")); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Address> id, + @Nonnull final Address dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final String interfaceName = id.firstKeyOf(Interface.class).getName(); + final int interfaceIndex = interfaceContext.getIndex(interfaceName, writeContext.getMappingContext()); + + addDelAddress(getFutureJVpp(), false, id, interfaceIndex, dataBefore.getIp(), + dataBefore.getPrefixLength().byteValue()); + } + +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv6Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v6/Ipv6Customizer.java index 85f190d83..003af53ab 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv6Customizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v6/Ipv6Customizer.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package io.fd.hc2vpp.v3po.interfaces.ip; +package io.fd.hc2vpp.v3po.interfaces.ip.v6; -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv6; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4NeighbourCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v6/Ipv6NeighbourCustomizer.java index 1a1c2d2c0..376ac9a1b 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/Ipv4NeighbourCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v6/Ipv6NeighbourCustomizer.java @@ -14,45 +14,39 @@ * limitations under the License. */ -package io.fd.hc2vpp.v3po.interfaces.ip; +package io.fd.hc2vpp.v3po.interfaces.ip.v6; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; import io.fd.hc2vpp.common.translate.util.AddressTranslator; import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; import io.fd.vpp.jvpp.core.dto.IpNeighborAddDel; import io.fd.vpp.jvpp.core.future.FutureJVppCore; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Neighbor; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.NeighborKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv6.Neighbor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv6.NeighborKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -/** - * Customizer for writing {@link Neighbor} for {@link Ipv4}. - */ -public class Ipv4NeighbourCustomizer extends FutureJVppCustomizer +public class Ipv6NeighbourCustomizer extends FutureJVppCustomizer implements ListWriterCustomizer<Neighbor, NeighborKey>, ByteDataTranslator, AddressTranslator, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(Ipv4NeighbourCustomizer.class); + private static final Logger LOG = LoggerFactory.getLogger(Ipv6NeighbourCustomizer.class); final NamingContext interfaceContext; - public Ipv4NeighbourCustomizer(final FutureJVppCore futureJVppCore, final NamingContext interfaceContext) { + public Ipv6NeighbourCustomizer(final FutureJVppCore futureJVppCore, final NamingContext interfaceContext) { super(futureJVppCore); this.interfaceContext = interfaceContext; } @@ -113,9 +107,9 @@ public class Ipv4NeighbourCustomizer extends FutureJVppCustomizer IpNeighborAddDel request = new IpNeighborAddDel(); request.isAdd = booleanToByte(add); - request.isIpv6 = 0; + request.isIpv6 = 1; request.isStatic = 1; - request.dstAddress = ipv4AddressNoZoneToArray(data.getIp()); + request.dstAddress = ipv6AddressNoZoneToArray(data.getIp()); request.macAddress = parseMac(data.getLinkLayerAddress().getValue()); request.swIfIndex = parentInterfaceIndex; @@ -123,4 +117,4 @@ public class Ipv4NeighbourCustomizer extends FutureJVppCustomizer //request.vrfId getReplyForWrite(getFutureJVpp().ipNeighborAddDel(request).toCompletableFuture(), id); } -}
\ No newline at end of file +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v6/subinterface/SubInterfaceIpv6AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v6/subinterface/SubInterfaceIpv6AddressCustomizer.java new file mode 100644 index 000000000..8348c8a25 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v6/subinterface/SubInterfaceIpv6AddressCustomizer.java @@ -0,0 +1,73 @@ +/* + * 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.v3po.interfaces.ip.v6.subinterface; + + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfaces.ip.IpWriter; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip6.attributes.ipv6.Address; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip6.attributes.ipv6.AddressKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class SubInterfaceIpv6AddressCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer<Address, AddressKey>, IpWriter { + + private final NamingContext interfaceContext; + + public SubInterfaceIpv6AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext interfaceContext) { + super(futureJVppCore); + this.interfaceContext = checkNotNull(interfaceContext, "interface context should not be null"); + } + + @Override + public void writeCurrentAttributes(InstanceIdentifier<Address> id, Address dataAfter, WriteContext writeContext) + throws WriteFailedException { + setAddress(true, id, dataAfter, writeContext); + } + + @Override + public void updateCurrentAttributes(InstanceIdentifier<Address> id, Address dataBefore, Address dataAfter, + WriteContext writeContext) throws WriteFailedException { + throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, + new UnsupportedOperationException("Operation not supported")); + } + + @Override + public void deleteCurrentAttributes(InstanceIdentifier<Address> id, Address dataBefore, WriteContext writeContext) + throws WriteFailedException { + setAddress(false, id, dataBefore, writeContext); + } + + private void setAddress(boolean add, + final InstanceIdentifier<Address> id, + final Address address, + final WriteContext writeContext) throws WriteFailedException { + + addDelAddress(getFutureJVpp(), add, id, + subInterfaceIndex(id, interfaceContext, writeContext.getMappingContext()), address.getIp(), + address.getPrefixLength().byteValue()); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v6/subinterface/SubInterfaceIpv6NeighbourCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v6/subinterface/SubInterfaceIpv6NeighbourCustomizer.java new file mode 100644 index 000000000..9d26a9a40 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v6/subinterface/SubInterfaceIpv6NeighbourCustomizer.java @@ -0,0 +1,100 @@ +/* + * 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.v3po.interfaces.ip.v6.subinterface; + +import io.fd.hc2vpp.common.translate.util.AddressTranslator; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfaces.ip.IpWriter; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.IpNeighborAddDel; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip6.attributes.ipv6.Neighbor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip6.attributes.ipv6.NeighborKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SubInterfaceIpv6NeighbourCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer<Neighbor, NeighborKey>, ByteDataTranslator, AddressTranslator, IpWriter, + JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceIpv6NeighbourCustomizer.class); + private final NamingContext interfaceContext; + + public SubInterfaceIpv6NeighbourCustomizer(final FutureJVppCore futureJVppCore, + final NamingContext interfaceContext) { + super(futureJVppCore); + this.interfaceContext = interfaceContext; + } + + @Override + public void writeCurrentAttributes(@Nonnull InstanceIdentifier<Neighbor> id, @Nonnull Neighbor data, + @Nonnull WriteContext writeContext) + throws WriteFailedException { + + LOG.debug("Processing request for Neighbour {} write", id); + + addDelNeighbour(id, () -> { + IpNeighborAddDel request = preBindIpv6Request(true); + + request.dstAddress = ipv6AddressNoZoneToArray(data.getIp()); + request.macAddress = parseMac(data.getLinkLayerAddress().getValue()); + request.swIfIndex = subInterfaceIndex(id, interfaceContext, writeContext.getMappingContext()); + + //TODO HONEYCOMB-182 if it is necessary for future use ,make adjustments to be able to set vrfid + //request.vrfId + return request; + }, getFutureJVpp()); + LOG.debug("Neighbour {} successfully written", id); + } + + @Override + public void updateCurrentAttributes(@Nonnull InstanceIdentifier<Neighbor> id, @Nonnull Neighbor dataBefore, + @Nonnull Neighbor dataAfter, + @Nonnull WriteContext writeContext) throws WriteFailedException { + throw new UnsupportedOperationException("Operation not supported"); + } + + @Override + public void deleteCurrentAttributes(@Nonnull InstanceIdentifier<Neighbor> id, @Nonnull Neighbor data, + @Nonnull WriteContext writeContext) + throws WriteFailedException { + + LOG.debug("Processing request for Neighbour {} delete", id); + + addDelNeighbour(id, () -> { + IpNeighborAddDel request = preBindIpv6Request(false); + + request.dstAddress = ipv6AddressNoZoneToArray(data.getIp()); + request.macAddress = parseMac(data.getLinkLayerAddress().getValue()); + request.swIfIndex = subInterfaceIndex(id, interfaceContext, writeContext.getMappingContext()); + + //TODO HONEYCOMB-182 if it is necessary for future use ,make adjustments to be able to set vrfid + //request.vrfId + return request; + }, getFutureJVpp()); + + LOG.debug("Neighbour {} successfully deleted", id); + } + +} |