summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Gradzki <mgradzki@cisco.com>2017-02-06 16:54:07 +0100
committerJan Srnicek <jsrnicek@cisco.com>2017-02-13 09:42:04 +0000
commita54c5d0db782ea2dd06cc1a60df46fdbc945d138 (patch)
treebd0492bd112d6561f4a4ec8c1963752f81a3fae7
parentb83a4a9d291991b07034c0889694eda247e9c8cd (diff)
Add support for RA configuration
Includes: * ietf-routing model augmentation that addresses VPP specific RA options (HC2VPP-64) * writers for RA cfg (HC2VPP-65) Change-Id: Iea523caaddcf03e38c8e5e7c586f1606a44d335b Signed-off-by: Marek Gradzki <mgradzki@cisco.com>
-rw-r--r--routing/routing-api/src/main/yang/vpp-routing-ra.yang103
-rw-r--r--routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/PrefixCustomizer.java129
-rw-r--r--routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/RouterAdvertisementsCustomizer.java121
-rw-r--r--routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/RoutingInterfaceCustomizer.java73
-rw-r--r--routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/RoutingWriterFactory.java32
5 files changed, 457 insertions, 1 deletions
diff --git a/routing/routing-api/src/main/yang/vpp-routing-ra.yang b/routing/routing-api/src/main/yang/vpp-routing-ra.yang
new file mode 100644
index 000000000..5bea1db9c
--- /dev/null
+++ b/routing/routing-api/src/main/yang/vpp-routing-ra.yang
@@ -0,0 +1,103 @@
+module vpp-routing-ra {
+
+ namespace "urn:ietf:params:xml:ns:yang:vpp-routing";
+ prefix "vpp-routing";
+ description "General extensions for routing advertisments message configuration provided by VPP APIs";
+
+ revision 2017-03-15 {
+ description "Initial revision.";
+ }
+
+ import yang-ext {
+ prefix "ext";
+ }
+
+ import hc2vpp-ietf-routing {
+ prefix "ietf-r";
+ }
+
+ import hc2vpp-ietf-ipv6-unicast-routing {
+ prefix "v6ur";
+ }
+
+ grouping ipv6-router-advertisements-vpp-attributes {
+ leaf suppress-link-layer {
+ type boolean;
+ default false;
+ description
+ "Dicates not to include the optional source link-layer address
+ in the ICMPv6 router-advertisement messages.";
+ }
+ leaf send-unicast {
+ type boolean;
+ default false;
+ description
+ "Use the source address of the router-solicitation message if availiable.";
+ }
+ leaf cease {
+ type boolean;
+ default false;
+ description
+ "Cease sending ICMPv6 router-advertisement messages.";
+ }
+ leaf initial-count {
+ type uint8 {
+ range "1..3";
+ }
+ default 3;
+ description
+ "Number of initial ICMPv6 router-advertisement messages sent.";
+ }
+ leaf initial-interval {
+ type uint8 {
+ range "1..16";
+ }
+ units "seconds";
+ default 16;
+ description
+ "Interval between initial ICMPv6 router-advertisement messages.";
+ }
+
+ description
+ "VPP specific configuration of RA messages. Mapped to sw_interface_ip6nd_ra_config API:
+ https://git.fd.io/vpp/tree/src/vnet/ip/ip.api#n196";
+
+ reference
+ "https://docs.fd.io/vpp/17.04/clicmd_src_vnet_ip.html#clicmd_ip6_nd";
+ }
+
+ grouping control-adv-prefixes-vpp-attributes {
+ leaf advertise-router-address {
+ type boolean;
+ default true;
+ description
+ "Send full router address in prefix advertisement.";
+ }
+ leaf vpp-default {
+ type boolean;
+ default false;
+ description
+ "Use VPP default values for prefix advertisment.";
+ }
+
+ description
+ "VPP specific configuration of prefixes in RA messages. Mapped to sw_interface_ip6nd_ra_prefix API:
+ https://git.fd.io/vpp/tree/src/vnet/ip/ip.api#n243";
+
+ reference
+ "https://docs.fd.io/vpp/17.04/clicmd_src_vnet_ip.html#clicmd_ip6_nd";
+ }
+
+ augment "/ietf-r:routing/ietf-r:routing-instance/ietf-r:interfaces/ietf-r:interface/"
+ + "v6ur:ipv6-router-advertisements" {
+ ext:augment-identifier "ipv6-router-advertisements-vpp-augmentation";
+ uses ipv6-router-advertisements-vpp-attributes;
+ }
+
+ augment "/ietf-r:routing/ietf-r:routing-instance/ietf-r:interfaces/ietf-r:interface/"
+ + "v6ur:ipv6-router-advertisements/v6ur:prefix-list/v6ur:prefix" {
+ // TODO control-adv-prefixes/advertise case should be target node (change after yangtools issues are solved)
+ ext:augment-identifier "control-adv-prefixes-vpp-augmentation";
+ uses control-adv-prefixes-vpp-attributes;
+ }
+} \ No newline at end of file
diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/PrefixCustomizer.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/PrefixCustomizer.java
new file mode 100644
index 000000000..8d7192271
--- /dev/null
+++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/PrefixCustomizer.java
@@ -0,0 +1,129 @@
+/*
+ * 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.routing.write;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import com.google.common.base.Preconditions;
+import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.Ipv6Translator;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+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.SwInterfaceIp6NdRaPrefix;
+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.ipv6.unicast.routing.rev140525.routing.routing.instance.interfaces._interface.ipv6.router.advertisements.prefix.list.Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev140525.routing.routing.instance.interfaces._interface.ipv6.router.advertisements.prefix.list.PrefixKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev140525.routing.routing.instance.interfaces._interface.ipv6.router.advertisements.prefix.list.prefix.ControlAdvPrefixes;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev140525.routing.routing.instance.interfaces._interface.ipv6.router.advertisements.prefix.list.prefix.control.adv.prefixes.Advertise;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev140525.routing.routing.instance.interfaces._interface.ipv6.router.advertisements.prefix.list.prefix.control.adv.prefixes.NoAdvertise;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev170315.ControlAdvPrefixesVppAugmentation;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class PrefixCustomizer extends FutureJVppCustomizer
+ implements ListWriterCustomizer<Prefix, PrefixKey>, JvppReplyConsumer, ByteDataTranslator, Ipv6Translator {
+ private static final Logger LOG = LoggerFactory.getLogger(PrefixCustomizer.class);
+
+ private final NamingContext interfaceContext;
+
+ PrefixCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext) {
+ super(jvpp);
+ this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null");
+ }
+
+ @Override
+ public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Prefix> id,
+ @Nonnull final Prefix dataAfter, @Nonnull final WriteContext writeContext)
+ throws WriteFailedException {
+ LOG.debug("Writing Prefix {} dataAfter={}", id, dataAfter);
+ setPrefix(id, dataAfter, writeContext, false);
+ }
+
+ @Override
+ public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Prefix> id,
+ @Nonnull final Prefix dataBefore, @Nonnull final Prefix dataAfter,
+ @Nonnull final WriteContext writeContext) throws WriteFailedException {
+ LOG.debug("Updating Prefix {} before={} after={}", id, dataBefore, dataAfter);
+ setPrefix(id, dataAfter, writeContext, false);
+ }
+
+ @Override
+ public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Prefix> id,
+ @Nonnull final Prefix dataBefore, @Nonnull final WriteContext writeContext)
+ throws WriteFailedException {
+ LOG.debug("Removing Prefix {} dataBefore={}", id, dataBefore);
+ setPrefix(id, dataBefore, writeContext, true);
+ }
+
+ private void setPrefix(final InstanceIdentifier<Prefix> id, final Prefix prefix, final WriteContext writeContext,
+ final boolean isDelete) throws WriteFailedException {
+ final String ifcName = id.firstKeyOf(Interface.class).getName();
+ final int ifcIndex = interfaceContext.getIndex(ifcName, writeContext.getMappingContext());
+ final SwInterfaceIp6NdRaPrefix request = new SwInterfaceIp6NdRaPrefix();
+ request.swIfIndex = ifcIndex;
+ request.address = ipv6AddressPrefixToArray(prefix.getPrefixSpec());
+ request.addressLength = extractPrefix(prefix.getPrefixSpec()); // prefix length (vpp api naming bug)
+
+ if (isDelete) {
+ request.isNo = 1;
+ } else {
+ parseControlAdvPrefixes(request, prefix.getControlAdvPrefixes(), prefix.getAugmentation(
+ ControlAdvPrefixesVppAugmentation.class));
+ }
+ LOG.debug("Setting Prefix for interface {}(id={}): {}", ifcName, ifcIndex, request);
+ getReplyForWrite(getFutureJVpp().swInterfaceIp6NdRaPrefix(request).toCompletableFuture(), id);
+ LOG.debug("Prefix: {} updated successfully", id);
+ }
+
+ private void parseControlAdvPrefixes(final SwInterfaceIp6NdRaPrefix request,
+ final ControlAdvPrefixes controlAdvPrefixes,
+ final ControlAdvPrefixesVppAugmentation vppAugmentation) {
+ if (controlAdvPrefixes instanceof Advertise) {
+ final Advertise advertise = (Advertise) controlAdvPrefixes;
+ request.noAutoconfig = booleanToByte(!advertise.isAutonomousFlag());
+ request.noOnlink = booleanToByte(!advertise.isOnLinkFlag());
+ // request.offLink controls L bit in the same way as noOnlink, but also controls if it is installed in FIB
+ if (advertise.getValidLifetime() != null) {
+ request.valLifetime = advertise.getValidLifetime().intValue();
+ }
+ if (advertise.getPreferredLifetime() != null) {
+ checkArgument(advertise.getValidLifetime() != null,
+ "valid-lifetime needs to be configured if preferred-lifetime is given");
+ checkArgument(advertise.getPreferredLifetime() <= advertise.getValidLifetime(),
+ "preferred-lifetime MUST NOT be greater than valid-lifetime.");
+ request.prefLifetime = advertise.getPreferredLifetime().intValue();
+ }
+ if (vppAugmentation != null) {
+ request.useDefault = booleanToByte(vppAugmentation.isVppDefault());
+ request.noAdvertise = booleanToByte(!vppAugmentation.isAdvertiseRouterAddress());
+ }
+ } else if (controlAdvPrefixes instanceof NoAdvertise) {
+ throw new IllegalArgumentException(
+ "NoAdvertise control-adv-prefix is not supported." +
+ "To remove prefix from set of advertised prefixes, use DELETE request.");
+ } else {
+ throw new IllegalArgumentException("Unsupported control-adv-prefix: " + controlAdvPrefixes);
+ }
+ }
+}
diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/RouterAdvertisementsCustomizer.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/RouterAdvertisementsCustomizer.java
new file mode 100644
index 000000000..f33272b70
--- /dev/null
+++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/RouterAdvertisementsCustomizer.java
@@ -0,0 +1,121 @@
+/*
+ * 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.routing.write;
+
+import com.google.common.base.Preconditions;
+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.spi.write.WriterCustomizer;
+import io.fd.honeycomb.translate.write.WriteContext;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceIp6NdRaConfig;
+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.ipv6.unicast.routing.rev140525.routing.routing.instance.interfaces._interface.Ipv6RouterAdvertisements;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev170315.Ipv6RouterAdvertisementsVppAugmentation;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class RouterAdvertisementsCustomizer extends FutureJVppCustomizer
+ implements WriterCustomizer<Ipv6RouterAdvertisements>, JvppReplyConsumer, ByteDataTranslator {
+ private static final Logger LOG = LoggerFactory.getLogger(RouterAdvertisementsCustomizer.class);
+
+ private final NamingContext interfaceContext;
+
+ RouterAdvertisementsCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext) {
+ super(jvpp);
+ this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null");
+ }
+
+ @Override
+ public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Ipv6RouterAdvertisements> id,
+ @Nonnull final Ipv6RouterAdvertisements dataAfter,
+ @Nonnull final WriteContext writeContext) throws WriteFailedException {
+ LOG.debug("Writing RouterAdvertisements {} dataAfter={}", id, dataAfter);
+ setRouterAdvertisements(id, dataAfter, writeContext, false);
+ }
+
+ @Override
+ public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Ipv6RouterAdvertisements> id,
+ @Nonnull final Ipv6RouterAdvertisements dataBefore,
+ @Nonnull final Ipv6RouterAdvertisements dataAfter,
+ @Nonnull final WriteContext writeContext)
+ throws WriteFailedException {
+ LOG.debug("Updating RouterAdvertisements {} dataBefore={} dataAfter={}", id, dataBefore, dataAfter);
+ setRouterAdvertisements(id, dataAfter, writeContext, false);
+ }
+
+ @Override
+ public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Ipv6RouterAdvertisements> id,
+ @Nonnull final Ipv6RouterAdvertisements dataBefore,
+ @Nonnull final WriteContext writeContext) throws WriteFailedException {
+ LOG.debug("Removing RouterAdvertisements {} dataBefore={}", id, dataBefore);
+ setRouterAdvertisements(id, dataBefore, writeContext, true);
+ }
+
+ private void setRouterAdvertisements(@Nonnull final InstanceIdentifier<Ipv6RouterAdvertisements> id,
+ @Nonnull final Ipv6RouterAdvertisements data,
+ @Nonnull final WriteContext writeContext,
+ final boolean isDelete) throws WriteFailedException {
+ final String ifcName = id.firstKeyOf(Interface.class).getName();
+ final int ifcIndex = interfaceContext.getIndex(ifcName, writeContext.getMappingContext());
+ SwInterfaceIp6NdRaConfig request;
+ if (isDelete) {
+ request = new SwInterfaceIp6NdRaConfig();
+ request.swIfIndex = ifcIndex;
+ request.suppress = 1;
+ } else {
+ request = getRequest(data, ifcIndex);
+ }
+ LOG.debug("Updating RouterAdvertisements configuration for interface {}(id={}): {}", ifcName, ifcIndex, request);
+ getReplyForWrite(getFutureJVpp().swInterfaceIp6NdRaConfig(request).toCompletableFuture(), id);
+ LOG.debug("RouterAdvertisements: {} configuration updated successfully", id);
+ }
+
+ private SwInterfaceIp6NdRaConfig getRequest(final Ipv6RouterAdvertisements dataAfter, final int ifcIndex) {
+ final SwInterfaceIp6NdRaConfig request = new SwInterfaceIp6NdRaConfig();
+ request.swIfIndex = ifcIndex;
+ request.suppress = booleanToByte(!dataAfter.isSendAdvertisements());
+ request.managed = booleanToByte(dataAfter.isManagedFlag());
+ request.other = booleanToByte(dataAfter.isOtherConfigFlag());
+ final Ipv6RouterAdvertisementsVppAugmentation vppAugmentation =
+ dataAfter.getAugmentation(Ipv6RouterAdvertisementsVppAugmentation.class);
+ if (vppAugmentation != null) {
+ request.llOption = booleanToByte(vppAugmentation.isSuppressLinkLayer());
+ request.sendUnicast = booleanToByte(vppAugmentation.isSendUnicast());
+ request.cease = booleanToByte(vppAugmentation.isCease());
+ request.initialCount = vppAugmentation.getInitialCount();
+ request.initialInterval = vppAugmentation.getInitialInterval();
+ }
+ request.isNo = 0;
+ if (dataAfter.getMinRtrAdvInterval() != null) {
+ request.minInterval = dataAfter.getMinRtrAdvInterval();
+ }
+ if (dataAfter.getMaxRtrAdvInterval() != null) {
+ request.maxInterval = dataAfter.getMaxRtrAdvInterval();
+ }
+ if (dataAfter.getDefaultLifetime() != null && dataAfter.getDefaultLifetime() != 0) {
+ request.lifetime = dataAfter.getDefaultLifetime();
+ request.defaultRouter = 1;
+ }
+ return request;
+ }
+}
diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/RoutingInterfaceCustomizer.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/RoutingInterfaceCustomizer.java
new file mode 100644
index 000000000..d8737ce07
--- /dev/null
+++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/RoutingInterfaceCustomizer.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.routing.write;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer;
+import io.fd.honeycomb.translate.write.WriteContext;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.interfaces.InterfaceKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Dummy customizer for Interfaces node responsible for validation only.
+ */
+public class RoutingInterfaceCustomizer implements ListWriterCustomizer<Interface, InterfaceKey> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(RoutingInterfaceCustomizer.class);
+
+ @Override
+ public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Interface> id,
+ @Nonnull final Interface after, @Nonnull final WriteContext writeContext)
+ throws WriteFailedException {
+ LOG.debug("Writing {} after={}", id, after);
+ checkIfcIsConfigured(after.getName(), writeContext);
+ }
+
+ @Override
+ public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Interface> id,
+ @Nonnull final Interface before, @Nonnull final Interface after,
+ @Nonnull final WriteContext writeContext) throws WriteFailedException {
+ LOG.debug("Updating {} before={} after={}", id, before, after);
+ checkIfcIsConfigured(after.getName(), writeContext);
+ }
+
+ @Override
+ public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Interface> id,
+ @Nonnull final Interface after, @Nonnull final WriteContext writeContext)
+ throws WriteFailedException {
+ LOG.debug("Removing {}", id);
+ // here we do not care if the ifc exists or not, because we are removing reference to it
+ }
+
+ private static void checkIfcIsConfigured(@Nonnull final String ifcName, @Nonnull final WriteContext writeContext) {
+ final KeyedInstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey>
+ id = InstanceIdentifier.create(Interfaces.class)
+ .child(
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface.class,
+ new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey(
+ ifcName));
+ checkArgument(writeContext.readAfter(id).isPresent(), "Interface %s is not configured");
+ }
+}
diff --git a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/RoutingWriterFactory.java b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/RoutingWriterFactory.java
index 02fa7d1b2..e5487e570 100644
--- a/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/RoutingWriterFactory.java
+++ b/routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/RoutingWriterFactory.java
@@ -34,13 +34,21 @@ import io.fd.vpp.jvpp.core.future.FutureJVppCore;
import java.util.Set;
import javax.annotation.Nonnull;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev140524.routing.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.Route;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev140525.Interface1;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev140525.routing.routing.instance.interfaces._interface.Ipv6RouterAdvertisements;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev140525.routing.routing.instance.interfaces._interface.ipv6.router.advertisements.PrefixList;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv6.unicast.routing.rev140525.routing.routing.instance.interfaces._interface.ipv6.router.advertisements.prefix.list.Prefix;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.Routing;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.RoutingInstance;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.Interfaces;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.RoutingProtocols;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.interfaces.Interface;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.routing.protocols.RoutingProtocol;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.routing.protocols.routing.protocol.StaticRoutes;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev161214.RoutingProtocolVppAttr;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev161214.routing.routing.instance.routing.protocols.routing.protocol.VppProtocolAttributes;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev170315.ControlAdvPrefixesVppAugmentation;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev170315.Ipv6RouterAdvertisementsVppAugmentation;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
/**
@@ -49,6 +57,13 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
public final class RoutingWriterFactory implements WriterFactory, Ipv4WriteRoutingNodes, Ipv6WriteRoutingNodes {
private static final InstanceIdentifier<Routing> ROOT_CONTAINER_ID = InstanceIdentifier.create(Routing.class);
+ private static final InstanceIdentifier<Interface> ROUTING_INTERFACE_ID =
+ ROOT_CONTAINER_ID.child(RoutingInstance.class).child(Interfaces.class).child(Interface.class);
+ private static final InstanceIdentifier<Ipv6RouterAdvertisements> ROUTING_ADVERTISMENT_ID =
+ ROUTING_INTERFACE_ID.augmentation(
+ Interface1.class).child(Ipv6RouterAdvertisements.class);
+ private static final InstanceIdentifier<Prefix> PREFIX_ID =
+ ROUTING_ADVERTISMENT_ID.child(PrefixList.class).child(Prefix.class);
@Inject
private FutureJVppCore vppApi;
@@ -97,6 +112,12 @@ public final class RoutingWriterFactory implements WriterFactory, Ipv4WriteRouti
registry.subtreeAdd(ipv6RoutingHandledChildren(ipv6RouteSubtree()), new GenericWriter<>(ipv6RouteIdentifier,
new Ipv6RouteCustomizer(vppApi, interfaceContext, routeContext, routingProtocolContext, routHopContext,
vppClassifierContextManager)));
+ registry.add(new GenericWriter<>(ROUTING_INTERFACE_ID, new RoutingInterfaceCustomizer()));
+ registry.subtreeAdd(raHandledChildren(),
+ new GenericWriter<>(ROUTING_ADVERTISMENT_ID, new RouterAdvertisementsCustomizer(vppApi, interfaceContext)));
+ registry.subtreeAdd(prefixHandledChildren(),
+ new GenericWriter<>(PREFIX_ID, new PrefixCustomizer(vppApi, interfaceContext)));
+
}
private static ImmutableSet<InstanceIdentifier<?>> routingProtocolHandledChildren() {
@@ -107,7 +128,6 @@ public final class RoutingWriterFactory implements WriterFactory, Ipv4WriteRouti
private static InstanceIdentifier<RoutingInstance> routingInstanceIdentifier() {
return ROOT_CONTAINER_ID.child(RoutingInstance.class);
}
-
private static InstanceIdentifier<RoutingProtocol> routingProtocolIdentifier() {
return routingInstanceIdentifier().child(RoutingProtocols.class).child(RoutingProtocol.class);
}
@@ -119,4 +139,14 @@ public final class RoutingWriterFactory implements WriterFactory, Ipv4WriteRouti
private static Set<InstanceIdentifier<?>> rootNodeHandledChildren(final InstanceIdentifier<Routing> parent) {
return ImmutableSet.of(parent.child(RoutingInstance.class).child(RoutingProtocols.class));
}
+
+ private static Set<InstanceIdentifier<?>> raHandledChildren() {
+ final InstanceIdentifier<Ipv6RouterAdvertisements> raIID = InstanceIdentifier.create(Ipv6RouterAdvertisements.class);
+ return ImmutableSet.of(raIID.augmentation(Ipv6RouterAdvertisementsVppAugmentation.class));
+ }
+
+ private static Set<InstanceIdentifier<?>> prefixHandledChildren() {
+ final InstanceIdentifier<Prefix> prefixIID = InstanceIdentifier.create(Prefix.class);
+ return ImmutableSet.of(prefixIID.augmentation(ControlAdvPrefixesVppAugmentation.class));
+ }
}