summaryrefslogtreecommitdiffstats
path: root/v3po/v3po2vpp/src/main/java/io/fd
diff options
context:
space:
mode:
Diffstat (limited to 'v3po/v3po2vpp/src/main/java/io/fd')
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/AddressCustomizer.java107
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java6
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizer.java42
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4Customizer.java7
4 files changed, 112 insertions, 50 deletions
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/AddressCustomizer.java
index c99fcd29f..0b62bc027 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/AddressCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/AddressCustomizer.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package io.fd.honeycomb.v3po.translate.v3po.interfaces.ip;
import static com.google.common.base.Preconditions.checkArgument;
@@ -34,6 +35,8 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev14061
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.Subnet;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.Netmask;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLength;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLengthBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.openvpp.jvpp.VppBaseCallException;
@@ -45,8 +48,6 @@ import org.slf4j.LoggerFactory;
/**
* Customizer for writing {@link Address}
- *
- * @author jsrnicek
*/
public class AddressCustomizer extends FutureJVppCustomizer implements ListWriterCustomizer<Address, AddressKey> {
@@ -60,29 +61,30 @@ public class AddressCustomizer extends FutureJVppCustomizer implements ListWrite
@Override
public void writeCurrentAttributes(InstanceIdentifier<Address> id, Address dataAfter, WriteContext writeContext)
- throws WriteFailedException {
+ 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"));
+ 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 {
+ throws WriteFailedException {
setAddress(false, id, dataBefore, writeContext);
}
@Override
public Optional<List<Address>> extract(InstanceIdentifier<Address> currentId, DataObject parentData) {
- return Optional.fromNullable((((Ipv4)parentData).getAddress()));
+ return Optional.fromNullable((((Ipv4) parentData).getAddress()));
}
- private void setAddress(boolean add,final InstanceIdentifier<Address> id, final Address address,
- final WriteContext writeContext) throws WriteFailedException {
+ private void setAddress(boolean add, final InstanceIdentifier<Address> id, final Address address,
+ final WriteContext writeContext) throws WriteFailedException {
final String interfaceName = id.firstKeyOf(Interface.class).getName();
final int swIfc = interfaceContext.getIndex(interfaceName, writeContext.getMappingContext());
@@ -90,9 +92,9 @@ public class AddressCustomizer extends FutureJVppCustomizer implements ListWrite
Subnet subnet = address.getSubnet();
if (subnet instanceof PrefixLength) {
- setPrefixLengthSubnet(add,id, interfaceName, swIfc, address, (PrefixLength) subnet);
+ setPrefixLengthSubnet(add, id, interfaceName, swIfc, address, (PrefixLength) subnet);
} else if (subnet instanceof Netmask) {
- setNetmaskSubnet();
+ setNetmaskSubnet(add, id, interfaceName, swIfc, address, (Netmask) subnet);
} else {
// FIXME how does choice extensibility work
// FIXME it is not even possible to create a dedicated
@@ -105,40 +107,95 @@ public class AddressCustomizer extends FutureJVppCustomizer implements ListWrite
}
}
- private void setNetmaskSubnet() {
- // FIXME
- throw new UnsupportedOperationException("Unimplemented");
+ private void setNetmaskSubnet(final boolean add, final InstanceIdentifier<Address> id, final String name,
+ final int swIfc,
+ final Address ipv4Addr, final Netmask subnet) throws WriteFailedException {
+ LOG.debug("Setting Subnet(subnet-mask) for interface: {}, {}. Subnet: {}, Ipv4: {}", name, swIfc, subnet,
+ ipv4Addr);
+
+ byte[] addr = TranslateUtils.ipv4AddressNoZoneToArray(ipv4Addr.getIp());
+ final DottedQuad netmask = subnet.getNetmask();
+
+ checkNotNull(addr, "Null address");
+ checkNotNull(netmask, "Null netmask");
+
+ // find netmask bit-length
+ final short subnetLength = getSubnetMaskLength(netmask.getValue());
+ PrefixLengthBuilder lengthBuilder = new PrefixLengthBuilder().setPrefixLength(subnetLength);
+
+ setPrefixLengthSubnet(add, id, name, swIfc, ipv4Addr, lengthBuilder.build());
+ }
+
+ /**
+ * Returns the prefix size in bits of the specified subnet mask. Example: For the subnet mask 255.255.255.128 it
+ * returns 25 while for 255.0.0.0 it returns 8. If the passed subnetMask array is not complete or contains not only
+ * leading ones, IllegalArgumentExpression is thrown
+ *
+ * @param mask the subnet mask in dot notation 255.255.255.255
+ * @return the prefix length as number of bits
+ */
+ private static short getSubnetMaskLength(final String mask) {
+ String[] maskParts = mask.split("\\.");
+
+ final int DOTTED_QUAD_MASK_LENGHT = 4;
+ final int IPV4_ADDRESS_PART_BITS_COUNT = 8;
+ final int NETMASK_PART_LIMIT = 256; // 2 power to 8
+
+ checkArgument(maskParts.length == DOTTED_QUAD_MASK_LENGHT,
+ "Network mask %s is not in Quad Dotted Decimal notation!", mask);
+
+ long maskAsNumber = 0;
+ for (int i = 0; i < DOTTED_QUAD_MASK_LENGHT; i++) {
+ maskAsNumber <<= IPV4_ADDRESS_PART_BITS_COUNT;
+ int value = Integer.parseInt(maskParts[i]);
+ checkArgument(value < NETMASK_PART_LIMIT, "Network mask %s contains invalid number(s) over 255!", mask);
+ checkArgument(value >= 0, "Network mask %s contains invalid negative number(s)!", mask);
+ maskAsNumber += value;
+ }
+
+ String bits = Long.toBinaryString(maskAsNumber);
+ checkArgument(bits.length() == IPV4_ADDRESS_PART_BITS_COUNT * DOTTED_QUAD_MASK_LENGHT,
+ "Incorrect network mask %s", mask);
+ final int leadingOnes = bits.indexOf('0');
+ checkArgument(leadingOnes != -1, "Broadcast address %s is not allowed!", mask);
+ checkArgument(bits.substring(leadingOnes).indexOf('1') == -1,
+ "Non-contiguous network mask %s is not allowed!", mask);
+ return (short) leadingOnes;
}
- private void setPrefixLengthSubnet(boolean add,final InstanceIdentifier<Address> id, final String name, final int swIfc,
- final Address address, final PrefixLength subnet) throws WriteFailedException {
+ private void setPrefixLengthSubnet(boolean add, final InstanceIdentifier<Address> id, final String name,
+ final int swIfc,
+ final Address address, final PrefixLength subnet) throws WriteFailedException {
try {
- Short plen = subnet.getPrefixLength();
LOG.debug("Setting Subnet(prefix-length) for interface: {}, {}. Subnet: {}, Address: {}", name, swIfc,
- subnet, address);
-
- byte[] addr = TranslateUtils.ipv4AddressNoZoneToArray(address.getIp());
+ subnet, address);
+ final Short plen = subnet.getPrefixLength();
checkArgument(plen > 0, "Invalid length");
+
+ final byte[] addr = TranslateUtils.ipv4AddressNoZoneToArray(address.getIp());
checkNotNull(addr, "Null address");
- final CompletionStage<SwInterfaceAddDelAddressReply> swInterfaceAddDelAddressReplyCompletionStage = getFutureJVpp()
- .swInterfaceAddDelAddress(getSwInterfaceAddDelAddressRequest(swIfc, TranslateUtils.booleanToByte(add) /* isAdd */,
+ final CompletionStage<SwInterfaceAddDelAddressReply> swInterfaceAddDelAddressReplyCompletionStage =
+ getFutureJVpp()
+ .swInterfaceAddDelAddress(
+ getSwInterfaceAddDelAddressRequest(swIfc, TranslateUtils.booleanToByte(add) /* isAdd */,
(byte) 0 /* isIpv6 */, (byte) 0 /* delAll */, plen.byteValue(), addr));
TranslateUtils.getReply(swInterfaceAddDelAddressReplyCompletionStage.toCompletableFuture());
LOG.debug("Subnet(prefix-length) set successfully for interface: {}, {}, Subnet: {}, Address: {}", name,
- swIfc, subnet, address);
+ swIfc, subnet, address);
} catch (VppBaseCallException e) {
LOG.warn("Failed to set Subnet(prefix-length) for interface: {}, {}, Subnet: {}, Address: {}", name, swIfc,
- subnet, address);
+ subnet, address);
throw new WriteFailedException(id, "Unable to handle subnet of type " + subnet.getClass(), e);
}
}
private SwInterfaceAddDelAddress getSwInterfaceAddDelAddressRequest(final int swIfc, final byte isAdd,
- final byte ipv6, final byte deleteAll, final byte length, final byte[] addr) {
+ final byte ipv6, final byte deleteAll,
+ final byte length, final byte[] addr) {
final SwInterfaceAddDelAddress swInterfaceAddDelAddress = new SwInterfaceAddDelAddress();
swInterfaceAddDelAddress.swIfIndex = swIfc;
swInterfaceAddDelAddress.isAdd = isAdd;
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java
index e2d3002d7..01a315a77 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java
@@ -16,10 +16,10 @@
package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
+import static com.google.common.base.Preconditions.checkArgument;
import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceCustomizer.getCachedInterfaceDump;
import static java.util.Objects.requireNonNull;
-import com.google.common.base.Preconditions;
import io.fd.honeycomb.v3po.translate.ModificationCache;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import io.fd.honeycomb.v3po.translate.util.RWUtils;
@@ -120,7 +120,7 @@ public final class InterfaceUtils {
public static String vppPhysAddrToYang(@Nonnull final byte[] vppPhysAddress, int startIndex) {
Objects.requireNonNull(vppPhysAddress, "Empty physical address bytes");
final int endIndex = startIndex + PHYSICAL_ADDRESS_LENGTH;
- Preconditions.checkArgument(endIndex <= vppPhysAddress.length,
+ checkArgument(endIndex <= vppPhysAddress.length,
"Invalid physical address size (%s) for given startIndex (%d), expected >= %d", vppPhysAddress.length,
startIndex, endIndex);
StringBuilder physAddr = new StringBuilder();
@@ -152,7 +152,7 @@ public final class InterfaceUtils {
* @return VPP's representation of the if-index
*/
public static int yangIfIndexToVpp(int yangIfIndex) {
- Preconditions.checkArgument(yangIfIndex >= 1, "YANG if-index has invalid value %s", yangIfIndex);
+ checkArgument(yangIfIndex >= 1, "YANG if-index has invalid value %s", yangIfIndex);
return yangIfIndex - 1;
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizer.java
index b52b0552a..6c8bb9447 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizer.java
@@ -17,18 +17,20 @@
package io.fd.honeycomb.v3po.translate.v3po.interfacesstate.ip;
import com.google.common.base.Optional;
+import io.fd.honeycomb.v3po.translate.MappingContext;
import io.fd.honeycomb.v3po.translate.ModificationCache;
import io.fd.honeycomb.v3po.translate.read.ReadContext;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import io.fd.honeycomb.v3po.translate.spi.read.ListReaderCustomizer;
import io.fd.honeycomb.v3po.translate.util.RWUtils;
import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
-import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4Builder;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.Address;
@@ -50,17 +52,21 @@ import org.slf4j.LoggerFactory;
* Customizer for read operations for {@link Address} of {@link Ipv4}
*/
public class Ipv4AddressCustomizer extends FutureJVppCustomizer
- implements ListReaderCustomizer<Address, AddressKey, AddressBuilder> {
+ implements ListReaderCustomizer<Address, AddressKey, AddressBuilder> {
private static final Logger LOG = LoggerFactory.getLogger(Ipv4AddressCustomizer.class);
private static final String CACHE_KEY = Ipv4AddressCustomizer.class.getName();
- public Ipv4AddressCustomizer(FutureJVpp futureJvpp) {
+ private final NamingContext interfaceContext;
+
+ public Ipv4AddressCustomizer(@Nonnull final FutureJVpp futureJvpp, @Nonnull final NamingContext interfaceContext) {
super(futureJvpp);
+ this.interfaceContext = interfaceContext;
}
@Override
+ @Nonnull
public AddressBuilder getBuilder(@Nonnull InstanceIdentifier<Address> id) {
return new AddressBuilder();
}
@@ -68,7 +74,7 @@ public class Ipv4AddressCustomizer extends FutureJVppCustomizer
@Override
public void readCurrentAttributes(@Nonnull InstanceIdentifier<Address> id, @Nonnull AddressBuilder builder,
@Nonnull ReadContext ctx)
- throws ReadFailedException {
+ throws ReadFailedException {
LOG.debug("Reading attributes...");
Optional<IpAddressDetailsReplyDump> dumpOptional = dumpAddresses(id, ctx);
@@ -77,15 +83,14 @@ public class Ipv4AddressCustomizer extends FutureJVppCustomizer
List<IpAddressDetails> details = dumpOptional.get().ipAddressDetails;
AddressKey key = id.firstKeyOf(Address.class);
- byte[] identifingIpBytes = TranslateUtils.ipv4AddressNoZoneToArray(key.getIp());
IpAddressDetails detail = details.stream()
- .filter(singleDetail -> Arrays.equals(identifingIpBytes, singleDetail.ip))
- .collect(RWUtils.singleItemCollector());
+ .filter(singleDetail -> key.getIp().equals(TranslateUtils.arrayToIpv4AddressNoZone(singleDetail.ip)))
+ .collect(RWUtils.singleItemCollector());
builder.setIp(TranslateUtils.arrayToIpv4AddressNoZone(detail.ip))
- .setSubnet(new PrefixLengthBuilder()
- .setPrefixLength(Short.valueOf(detail.prefixLength)).build());
+ .setSubnet(new PrefixLengthBuilder()
+ .setPrefixLength(Short.valueOf(detail.prefixLength)).build());
LOG.info("Address read successfull");
} else {
@@ -95,7 +100,7 @@ public class Ipv4AddressCustomizer extends FutureJVppCustomizer
@Override
public List<AddressKey> getAllIds(@Nonnull InstanceIdentifier<Address> id, @Nonnull ReadContext context)
- throws ReadFailedException {
+ throws ReadFailedException {
LOG.debug("Extracting keys..");
Optional<IpAddressDetailsReplyDump> dumpOptional = dumpAddresses(id, context);
@@ -105,8 +110,8 @@ public class Ipv4AddressCustomizer extends FutureJVppCustomizer
List<IpAddressDetails> details = dumpOptional.get().ipAddressDetails;
return details.stream()
- .map(detail -> new AddressKey(TranslateUtils.arrayToIpv4AddressNoZone(detail.ip)))
- .collect(Collectors.toList());
+ .map(detail -> new AddressKey(TranslateUtils.arrayToIpv4AddressNoZone(detail.ip)))
+ .collect(Collectors.toList());
} else {
LOG.warn("No dump present");
return Collections.emptyList();
@@ -121,7 +126,7 @@ public class Ipv4AddressCustomizer extends FutureJVppCustomizer
// TODO refactor after there is an more generic implementation of cache
// operations
private Optional<IpAddressDetailsReplyDump> dumpAddresses(InstanceIdentifier<Address> id, ReadContext ctx)
- throws ReadFailedException {
+ throws ReadFailedException {
Optional<IpAddressDetailsReplyDump> dumpFromCache = dumpAddressFromCache(ctx.getModificationCache());
if (dumpFromCache.isPresent()) {
@@ -130,7 +135,7 @@ public class Ipv4AddressCustomizer extends FutureJVppCustomizer
Optional<IpAddressDetailsReplyDump> dumpFromOperational;
try {
- dumpFromOperational = dumpAddressFromOperationalData();
+ dumpFromOperational = dumpAddressFromOperationalData(id, ctx.getMappingContext());
} catch (VppBaseCallException e) {
throw new ReadFailedException(id, e);
}
@@ -147,10 +152,15 @@ public class Ipv4AddressCustomizer extends FutureJVppCustomizer
return Optional.fromNullable((IpAddressDetailsReplyDump) cache.get(CACHE_KEY));
}
- private Optional<IpAddressDetailsReplyDump> dumpAddressFromOperationalData() throws VppBaseCallException {
+ private Optional<IpAddressDetailsReplyDump> dumpAddressFromOperationalData(final InstanceIdentifier<Address> id,
+ final MappingContext mappingContext)
+ throws VppBaseCallException {
LOG.debug("Dumping from operational data...");
+ final IpAddressDump dumpRequest = new IpAddressDump();
+ dumpRequest.isIpv6 = 0;
+ dumpRequest.swIfIndex = interfaceContext.getIndex(id.firstKeyOf(Interface.class).getName(), mappingContext);
return Optional.fromNullable(
- TranslateUtils.getReply(getFutureJVpp().ipAddressDump(new IpAddressDump()).toCompletableFuture()));
+ TranslateUtils.getReply(getFutureJVpp().ipAddressDump(dumpRequest).toCompletableFuture()));
}
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4Customizer.java
index a10ad3ba5..8e6162784 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4Customizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4Customizer.java
@@ -20,7 +20,6 @@ import io.fd.honeycomb.v3po.translate.read.ReadContext;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
import javax.annotation.Nonnull;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface2Builder;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4;
@@ -36,12 +35,8 @@ public class Ipv4Customizer extends FutureJVppCustomizer implements ChildReaderC
private static final Logger LOG = LoggerFactory.getLogger(Ipv4Customizer.class);
- //do not remove,it will be needed in future implementation
- private final NamingContext interfaceContext;
-
- public Ipv4Customizer(@Nonnull final FutureJVpp futureJvpp, final NamingContext interfaceContext) {
+ public Ipv4Customizer(@Nonnull final FutureJVpp futureJvpp) {
super(futureJvpp);
- this.interfaceContext = interfaceContext;
}
@Override