<config.configfile.directory>etc/opendaylight/karaf</config.configfile.directory>
<sxp.version>1.3.0-SNAPSHOT</sxp.version>
<netconf.version>1.1.0-SNAPSHOT</netconf.version>
+ <vbd.version>1.0.0-SNAPSHOT</vbd.version>
</properties>
<dependencyManagement>
<scope>import</scope>
<type>pom</type>
</dependency>
+
+ <!-- honeycomb/VBD -->
+ <dependency>
+ <groupId>org.opendaylight.honeycomb.vbd</groupId>
+ <artifactId>vbd-artifacts</artifactId>
+ <version>${vbd.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
</dependencies>
</dependencyManagement>
<classifier>features</classifier>
</dependency>
+ <!-- honeycomb/VBD -->
+ <dependency>
+ <groupId>org.opendaylight.honeycomb.vbd</groupId>
+ <artifactId>vbd-features</artifactId>
+ <classifier>features</classifier>
+ <type>xml</type>
+ </dependency>
+
<!-- GBP -->
<dependency>
<groupId>commons-net</groupId>
<classifier>config</classifier>
</dependency>
</dependencies>
-</project>
\ No newline at end of file
+</project>
<repository>mvn:org.opendaylight.sxp/features/${sxp.version}/xml/features</repository>
<!-- Repos needed by iosxe renderer -->
<repository>mvn:org.opendaylight.netconf/features-netconf-connector/${netconf.version}/xml/features</repository>
+ <!-- Repos needed by vpp renderer -->
+ <repository>mvn:org.opendaylight.honeycomb.vbd/vbd-features/${vbd.version}/xml/features</repository>
<!-- The common GBP components -->
<feature name='odl-groupbasedpolicy-base' version='${project.version}' description='OpenDaylight :: groupbasedpolicy :: Base Copmonents'>
<feature name='odl-groupbasedpolicy-vpp' version='${project.version}' description='OpenDaylight :: groupbasedpolicy :: VPP renderer '>
<feature version="${project.version}">odl-groupbasedpolicy-base</feature>
<feature version="${netconf.version}">odl-netconf-topology</feature>
+ <feature version="${vbd.version}">odl-vbd-api</feature>
<bundle>mvn:org.opendaylight.groupbasedpolicy/l2-l3-domain-extension/{{VERSION}}</bundle>
<bundle>mvn:org.opendaylight.groupbasedpolicy/vpp-renderer/{{VERSION}}</bundle>
<configfile finalname="${config.configfile.directory}/15-l2-l3-domain-extension.xml">mvn:org.opendaylight.groupbasedpolicy/l2-l3-domain-extension/{{VERSION}}/xml/config</configfile>
<groupId>${project.groupId}</groupId>
<artifactId>l2-l3-domain-extension</artifactId>
</dependency>
- <dependency>
- <groupId>org.opendaylight.mdsal.model</groupId>
- <artifactId>ietf-yang-types-20130715</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.mdsal.model</groupId>
- <artifactId>ietf-inet-types-2013-07-15</artifactId>
- </dependency>
<dependency>
<groupId>org.opendaylight.mdsal.model</groupId>
<artifactId>yang-ext</artifactId>
</dependency>
- <dependency>
- <groupId>org.opendaylight.mdsal.model</groupId>
- <artifactId>iana-if-type-2014-05-08</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.mdsal.model</groupId>
- <artifactId>ietf-interfaces</artifactId>
- </dependency>
<dependency>
<groupId>org.opendaylight.netconf</groupId>
<artifactId>sal-netconf-connector</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.honeycomb.vbd</groupId>
+ <artifactId>vbd-api</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </dependency>
<!-- testing dependencies -->
<dependency>
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.groupbasedpolicy.renderer.vpp.api;
+
+import javax.annotation.Nonnull;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanVni;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+/**
+ * Bridge domain manager interface.
+ */
+public interface BridgeDomainManager {
+
+ /**
+ * Creates a bridge domain on VPP node and it also adds tunnels of the bridge domain to VXLAN
+ * full mesh topology
+ *
+ * @param bridgeDomainName name of bridge domain
+ * @param vni VXLAN VNI used in full mesh topology for the given bridge domain
+ * @param vppNode VPP node where the bridge domain should be created
+ * @return {@link ListenableFuture}
+ */
+ ListenableFuture<Void> createVxlanBridgeDomainOnVppNode(@Nonnull String bridgeDomainName, @Nonnull VxlanVni vni,
+ NodeId vppNode);
+
+ /**
+ * Removes a bridge domain from VPP node and it also removes tunnels of the bridge domain from
+ * VXLAN full mesh topology
+ *
+ * @param bridgeDomainName name of bridge domain
+ * @param vppNode VPP node where the bridge domain should be removed from
+ * @return {@link ListenableFuture}
+ */
+ ListenableFuture<Void> removeBridgeDomainFromVppNode(@Nonnull String bridgeDomainName, NodeId vppNode);
+}
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentationBuilder;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2Builder;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VhostUserBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.attributes.interconnection.BridgeBasedBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBasedBuilder;\r
import org.slf4j.Logger;\r
import org.slf4j.LoggerFactory;\r
\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.attributes.Interconnection;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.attributes.interconnection.BridgeBased;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.attributes.interconnection.BridgeBasedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.Interconnection;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBased;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBasedBuilder;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
String nodePath = VppPathMapper.bridgeDomainToRestPath(bridgeDomainName);
if (!nodePath.equals(epLoc.getExternalNode())) {
vppEndpointLocationProvider.updateExternalNodeLocationForEndpoint(nodePath,
- addrEpWithLoc.getKey());
+ epLoc.getExternalNodeMountPoint(), addrEpWithLoc.getKey());
}
return Futures.immediateFuture(null);
}
public Void apply(Void input) {
String nodePath = VppPathMapper.bridgeDomainToRestPath(bridgeDomainName);
vppEndpointLocationProvider.updateExternalNodeLocationForEndpoint(nodePath,
- addrEpWithLoc.getKey());
+ epLoc.getExternalNodeMountPoint(), addrEpWithLoc.getKey());
return null;
}
});
String existingBridgeDomain = resolveBridgeDomain(optIface.get());
if (Strings.isNullOrEmpty(existingBridgeDomain)) {
// bridge domain does not exist on interface so we consider job done
- vppEndpointLocationProvider.updateExternalNodeLocationForEndpoint(null, addrEpWithLoc.getKey());
+ vppEndpointLocationProvider.updateExternalNodeLocationForEndpoint(null,
+ epLoc.getExternalNodeMountPoint(), addrEpWithLoc.getKey());
return Futures.immediateFuture(null);
}
@Override
public Void apply(Void input) {
- vppEndpointLocationProvider.updateExternalNodeLocationForEndpoint(null, addrEpWithLoc.getKey());
+ vppEndpointLocationProvider.updateExternalNodeLocationForEndpoint(null,
+ epLoc.getExternalNodeMountPoint(), addrEpWithLoc.getKey());
return null;
}
});
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderAddressEndpointLocationKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocationKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
});
}
- private static ProviderAddressEndpointLocationKey createProviderAddressEndpointLocationKey(VppEndpoint vppEndpoint) {
+ private static ProviderAddressEndpointLocationKey createProviderAddressEndpointLocationKey(
+ VppEndpoint vppEndpoint) {
return new ProviderAddressEndpointLocationKey(vppEndpoint.getAddress(), vppEndpoint.getAddressType(),
vppEndpoint.getContextId(), vppEndpoint.getContextType());
}
public void updateExternalNodeLocationForEndpoint(@Nullable String nodePath,
- @Nonnull AddressEndpointWithLocationKey addrEpWithLocKey) {
+ InstanceIdentifier<?> externalNodeMountPoint, @Nonnull AddressEndpointWithLocationKey addrEpWithLocKey) {
ProviderAddressEndpointLocationKey provAddrEpLocKey =
KeyFactory.providerAddressEndpointLocationKey(addrEpWithLocKey);
- AbsoluteLocation absoluteLocation = new AbsoluteLocationBuilder()
- .setLocationType(new ExternalLocationCaseBuilder().setExternalNode(nodePath).build()).build();
+ AbsoluteLocation absoluteLocation =
+ new AbsoluteLocationBuilder().setLocationType(new ExternalLocationCaseBuilder()
+ .setExternalNodeMountPoint(externalNodeMountPoint).setExternalNode(nodePath).build()).build();
ProviderAddressEndpointLocation providerAddressEndpointLocation = new ProviderAddressEndpointLocationBuilder()
.setKey(provAddrEpLocKey).setAbsoluteLocation(absoluteLocation).build();
WriteTransaction wTx = dataProvider.newWriteOnlyTransaction();
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.groupbasedpolicy.renderer.vpp.manager;
+
+import java.util.Arrays;
+
+import javax.annotation.Nonnull;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.api.BridgeDomainManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanVni;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyTypesVbridgeAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyTypesVbridgeAugmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyVbridgeAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyVbridgeAugmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.topology.types.VbridgeTopologyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vxlan.rev160429.TunnelTypeVxlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vxlan.rev160429.network.topology.topology.tunnel.parameters.VxlanTunnelParametersBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.TopologyTypes;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.TopologyTypesBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.node.attributes.SupportingNodeBuilder;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
+public class BridgeDomainManagerImpl implements BridgeDomainManager {
+
+ private static final TopologyId SUPPORTING_TOPOLOGY_NETCONF = new TopologyId("topology-netconf");
+ private static final TopologyTypes VBRIDGE_TOPOLOGY_TYPE = new TopologyTypesBuilder().addAugmentation(
+ TopologyTypesVbridgeAugment.class,
+ new TopologyTypesVbridgeAugmentBuilder().setVbridgeTopology(new VbridgeTopologyBuilder().build()).build())
+ .build();
+ private final DataBroker dataProvder;
+
+ public BridgeDomainManagerImpl(DataBroker dataProvder) {
+ this.dataProvder = Preconditions.checkNotNull(dataProvder);
+ }
+
+ @Override
+ public ListenableFuture<Void> createVxlanBridgeDomainOnVppNode(@Nonnull String bridgeDomainName,
+ @Nonnull VxlanVni vni, NodeId vppNode) {
+ TopologyKey topologyKey = new TopologyKey(new TopologyId(bridgeDomainName));
+ ReadOnlyTransaction rTx = dataProvder.newReadOnlyTransaction();
+ CheckedFuture<Optional<Topology>, ReadFailedException> futureTopology =
+ rTx.read(LogicalDatastoreType.CONFIGURATION, VppIidFactory.getTopologyIid(topologyKey));
+ rTx.close();
+ return Futures.transform(futureTopology, new AsyncFunction<Optional<Topology>, Void>() {
+
+ @Override
+ public ListenableFuture<Void> apply(Optional<Topology> optTopology) throws Exception {
+ WriteTransaction wTx = dataProvder.newWriteOnlyTransaction();
+ if (!optTopology.isPresent()) {
+ TopologyVbridgeAugment vbridgeAugment =
+ new TopologyVbridgeAugmentBuilder().setTunnelType(TunnelTypeVxlan.class)
+ .setArpTermination(false)
+ .setFlood(true)
+ .setForward(true)
+ .setLearn(true)
+ .setUnknownUnicastFlood(true)
+ .setTunnelParameters(new VxlanTunnelParametersBuilder().setVni(vni).build())
+ .build();
+ Topology topology = new TopologyBuilder().setKey(topologyKey)
+ .setTopologyTypes(VBRIDGE_TOPOLOGY_TYPE)
+ .addAugmentation(TopologyVbridgeAugment.class, vbridgeAugment)
+ .build();
+
+ wTx.put(LogicalDatastoreType.CONFIGURATION, VppIidFactory.getTopologyIid(topology.getKey()),
+ topology, true);
+ }
+ Node node = new NodeBuilder().setNodeId(vppNode)
+ .setSupportingNode(Arrays.asList(new SupportingNodeBuilder()
+ .setTopologyRef(SUPPORTING_TOPOLOGY_NETCONF).setNodeRef(vppNode).build()))
+ .build();
+ wTx.put(LogicalDatastoreType.CONFIGURATION, VppIidFactory.getNodeIid(topologyKey, node.getKey()),
+ node);
+ return wTx.submit();
+ }
+ });
+ }
+
+ @Override
+ public ListenableFuture<Void> removeBridgeDomainFromVppNode(@Nonnull String bridgeDomainName, NodeId vppNode) {
+ WriteTransaction wTx = dataProvder.newWriteOnlyTransaction();
+ wTx.delete(LogicalDatastoreType.CONFIGURATION,
+ VppIidFactory.getNodeIid(new TopologyKey(new TopologyId(bridgeDomainName)), new NodeKey(vppNode)));
+ return wTx.submit();
+ }
+
+}
if (Strings.isNullOrEmpty(rEpLoc.getExternalNode())) {
String l2FloodDomain = resolveL2FloodDomain(rEp.getNetworkContainment());
+ if (Strings.isNullOrEmpty(l2FloodDomain)) {
+ // TODO add it to the status for renderer manager
+ LOG.info("Rednerer endpoint does not have l2FloodDomain as network containment {}", rEp);
+ return;
+ }
ListenableFuture<Void> futureAddBridgeDomainToInterface =
ifaceManager.addBridgeDomainToInterface(l2FloodDomain, rEp);
Futures.addCallback(futureAddBridgeDomainToInterface, new FutureCallback<Void>() {
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNodeKey;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
.build();
}
- public static InstanceIdentifier<Node> getNodeIid(NodeKey key) {
- TopologyKey topologyKey = new TopologyKey(new TopologyId("topology-netconf"));
+ public static InstanceIdentifier<Node> getNodeIid(TopologyKey topologyKey, NodeKey nodeKey) {
return InstanceIdentifier.builder(NetworkTopology.class)
- .child(Topology.class,topologyKey)
- .child(Node.class, key).build();
+ .child(Topology.class, topologyKey)
+ .child(Node.class, nodeKey)
+ .build();
+ }
+
+ public static InstanceIdentifier<Topology> getTopologyIid(TopologyKey bridgeDomainKey) {
+ return InstanceIdentifier.builder(NetworkTopology.class)
+ .child(Topology.class, bridgeDomainKey).build();
}
}
+++ /dev/null
-module ietf-ip {
-
- yang-version 1;
-
- namespace
- "urn:ietf:params:xml:ns:yang:ietf-ip";
-
- prefix ip;
-
- import ietf-interfaces {
- prefix if;
- }
- import ietf-inet-types {
- prefix inet;
- }
- import ietf-yang-types {
- prefix yang;
- }
-
- organization
- "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
-
- contact
- "WG Web: <http://tools.ietf.org/wg/netmod/>
- WG List: <mailto:netmod@ietf.org>
-
- WG Chair: Thomas Nadeau
- <mailto:tnadeau@lucidvision.com>
-
- WG Chair: Juergen Schoenwaelder
- <mailto:j.schoenwaelder@jacobs-university.de>
-
- Editor: Martin Bjorklund
- <mailto:mbj@tail-f.com>";
-
- description
- "This module contains a collection of YANG definitions for
- configuring IP implementations.
-
- Copyright (c) 2014 IETF Trust and the persons identified as
- authors of the code. All rights reserved.
-
- Redistribution and use in source and binary forms, with or
- without modification, is permitted pursuant to, and subject
- to the license terms contained in, the Simplified BSD License
- set forth in Section 4.c of the IETF Trust's Legal Provisions
- Relating to IETF Documents
- (http://trustee.ietf.org/license-info).
-
- This version of this YANG module is part of RFC 7277; see
- the RFC itself for full legal notices.";
-
- revision "2014-06-16" {
- description "Initial revision.";
- reference
- "RFC 7277: A YANG Data Model for IP Management";
-
- }
-
-
- feature ipv4-non-contiguous-netmasks {
- description
- "Indicates support for configuring non-contiguous
- subnet masks.";
- }
-
- feature ipv6-privacy-autoconf {
- description
- "Indicates support for Privacy Extensions for Stateless Address
- Autoconfiguration in IPv6.";
- reference
- "RFC 4941: Privacy Extensions for Stateless Address
- Autoconfiguration in IPv6";
-
- }
-
- typedef ip-address-origin {
- type enumeration {
- enum "other" {
- value 0;
- description
- "None of the following.";
- }
- enum "static" {
- value 1;
- description
- "Indicates that the address has been statically
- configured - for example, using NETCONF or a Command Line
- Interface.";
- }
- enum "dhcp" {
- value 2;
- description
- "Indicates an address that has been assigned to this
- system by a DHCP server.";
- }
- enum "link-layer" {
- value 3;
- description
- "Indicates an address created by IPv6 stateless
- autoconfiguration that embeds a link-layer address in its
- interface identifier.";
- }
- enum "random" {
- value 4;
- description
- "Indicates an address chosen by the system at
-
- random, e.g., an IPv4 address within 169.254/16, an
- RFC 4941 temporary address, or an RFC 7217 semantically
- opaque address.";
- reference
- "RFC 4941: Privacy Extensions for Stateless Address
- Autoconfiguration in IPv6
- RFC 7217: A Method for Generating Semantically Opaque
- Interface Identifiers with IPv6 Stateless
- Address Autoconfiguration (SLAAC)";
-
- }
- }
- description
- "The origin of an address.";
- }
-
- typedef neighbor-origin {
- type enumeration {
- enum "other" {
- value 0;
- description
- "None of the following.";
- }
- enum "static" {
- value 1;
- description
- "Indicates that the mapping has been statically
- configured - for example, using NETCONF or a Command Line
- Interface.";
- }
- enum "dynamic" {
- value 2;
- description
- "Indicates that the mapping has been dynamically resolved
- using, e.g., IPv4 ARP or the IPv6 Neighbor Discovery
- protocol.";
- }
- }
- description
- "The origin of a neighbor entry.";
- }
-
- augment /if:interfaces/if:interface {
- description
- "Parameters for configuring IP on interfaces.
-
- If an interface is not capable of running IP, the server
- must not allow the client to configure these parameters.";
- container ipv4 {
- presence
- "Enables IPv4 unless the 'enabled' leaf
- (which defaults to 'true') is set to 'false'";
- description
- "Parameters for the IPv4 address family.";
- leaf enabled {
- type boolean;
- default 'true';
- description
- "Controls whether IPv4 is enabled or disabled on this
- interface. When IPv4 is enabled, this interface is
- connected to an IPv4 stack, and the interface can send
- and receive IPv4 packets.";
- }
-
- leaf forwarding {
- type boolean;
- default 'false';
- description
- "Controls IPv4 packet forwarding of datagrams received by,
- but not addressed to, this interface. IPv4 routers
- forward datagrams. IPv4 hosts do not (except those
- source-routed via the host).";
- }
-
- leaf mtu {
- type uint16 {
- range "68..max";
- }
- units "octets";
- description
- "The size, in octets, of the largest IPv4 packet that the
- interface will send and receive.
-
- The server may restrict the allowed values for this leaf,
- depending on the interface's type.
-
- If this leaf is not configured, the operationally used MTU
- depends on the interface's type.";
- reference
- "RFC 791: Internet Protocol";
-
- }
-
- list address {
- key "ip";
- description
- "The list of configured IPv4 addresses on the interface.";
- leaf ip {
- type inet:ipv4-address-no-zone;
- description
- "The IPv4 address on the interface.";
- }
-
- choice subnet {
- mandatory true;
- description
- "The subnet can be specified as a prefix-length, or,
- if the server supports non-contiguous netmasks, as
- a netmask.";
- leaf prefix-length {
- type uint8 {
- range "0..32";
- }
- description
- "The length of the subnet prefix.";
- }
- leaf netmask {
- if-feature ipv4-non-contiguous-netmasks;
- type yang:dotted-quad;
- description
- "The subnet specified as a netmask.";
- }
- } // choice subnet
- } // list address
-
- list neighbor {
- key "ip";
- description
- "A list of mappings from IPv4 addresses to
- link-layer addresses.
-
- Entries in this list are used as static entries in the
- ARP Cache.";
- reference
- "RFC 826: An Ethernet Address Resolution Protocol";
-
- leaf ip {
- type inet:ipv4-address-no-zone;
- description
- "The IPv4 address of the neighbor node.";
- }
-
- leaf link-layer-address {
- type yang:phys-address;
- mandatory true;
- description
- "The link-layer address of the neighbor node.";
- }
- } // list neighbor
- } // container ipv4
-
- container ipv6 {
- presence
- "Enables IPv6 unless the 'enabled' leaf
- (which defaults to 'true') is set to 'false'";
- description
- "Parameters for the IPv6 address family.";
- leaf enabled {
- type boolean;
- default 'true';
- description
- "Controls whether IPv6 is enabled or disabled on this
- interface. When IPv6 is enabled, this interface is
- connected to an IPv6 stack, and the interface can send
- and receive IPv6 packets.";
- }
-
- leaf forwarding {
- type boolean;
- default 'false';
- description
- "Controls IPv6 packet forwarding of datagrams received by,
- but not addressed to, this interface. IPv6 routers
- forward datagrams. IPv6 hosts do not (except those
- source-routed via the host).";
- reference
- "RFC 4861: Neighbor Discovery for IP version 6 (IPv6)
- Section 6.2.1, IsRouter";
-
- }
-
- leaf mtu {
- type uint32 {
- range "1280..max";
- }
- units "octets";
- description
- "The size, in octets, of the largest IPv6 packet that the
- interface will send and receive.
-
- The server may restrict the allowed values for this leaf,
- depending on the interface's type.
-
- If this leaf is not configured, the operationally used MTU
- depends on the interface's type.";
- reference
- "RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
- Section 5";
-
- }
-
- list address {
- key "ip";
- description
- "The list of configured IPv6 addresses on the interface.";
- leaf ip {
- type inet:ipv6-address-no-zone;
- description
- "The IPv6 address on the interface.";
- }
-
- leaf prefix-length {
- type uint8 {
- range "0..128";
- }
- mandatory true;
- description
- "The length of the subnet prefix.";
- }
- } // list address
-
- list neighbor {
- key "ip";
- description
- "A list of mappings from IPv6 addresses to
- link-layer addresses.
-
- Entries in this list are used as static entries in the
- Neighbor Cache.";
- reference
- "RFC 4861: Neighbor Discovery for IP version 6 (IPv6)";
-
- leaf ip {
- type inet:ipv6-address-no-zone;
- description
- "The IPv6 address of the neighbor node.";
- }
-
- leaf link-layer-address {
- type yang:phys-address;
- mandatory true;
- description
- "The link-layer address of the neighbor node.";
- }
- } // list neighbor
-
- leaf dup-addr-detect-transmits {
- type uint32;
- default '1';
- description
- "The number of consecutive Neighbor Solicitation messages
- sent while performing Duplicate Address Detection on a
- tentative address. A value of zero indicates that
- Duplicate Address Detection is not performed on
- tentative addresses. A value of one indicates a single
- transmission with no follow-up retransmissions.";
- reference
- "RFC 4862: IPv6 Stateless Address Autoconfiguration";
-
- }
-
- container autoconf {
- description
- "Parameters to control the autoconfiguration of IPv6
- addresses, as described in RFC 4862.";
- reference
- "RFC 4862: IPv6 Stateless Address Autoconfiguration";
-
- leaf create-global-addresses {
- type boolean;
- default 'true';
- description
- "If enabled, the host creates global addresses as
- described in RFC 4862.";
- reference
- "RFC 4862: IPv6 Stateless Address Autoconfiguration
- Section 5.5";
-
- }
-
- leaf create-temporary-addresses {
- if-feature ipv6-privacy-autoconf;
- type boolean;
- default 'false';
- description
- "If enabled, the host creates temporary addresses as
- described in RFC 4941.";
- reference
- "RFC 4941: Privacy Extensions for Stateless Address
- Autoconfiguration in IPv6";
-
- }
-
- leaf temporary-valid-lifetime {
- if-feature ipv6-privacy-autoconf;
- type uint32;
- units "seconds";
- default '604800';
- description
- "The time period during which the temporary address
- is valid.";
- reference
- "RFC 4941: Privacy Extensions for Stateless Address
- Autoconfiguration in IPv6
- - TEMP_VALID_LIFETIME";
-
- }
-
- leaf temporary-preferred-lifetime {
- if-feature ipv6-privacy-autoconf;
- type uint32;
- units "seconds";
- default '86400';
- description
- "The time period during which the temporary address is
- preferred.";
- reference
- "RFC 4941: Privacy Extensions for Stateless Address
- Autoconfiguration in IPv6
- - TEMP_PREFERRED_LIFETIME";
-
- }
- } // container autoconf
- } // container ipv6
- }
-
- augment /if:interfaces-state/if:interface {
- description
- "Data nodes for the operational state of IP on interfaces.";
- container ipv4 {
- presence
- "Present if IPv4 is enabled on this interface";
- config false;
- description
- "Interface-specific parameters for the IPv4 address family.";
- leaf forwarding {
- type boolean;
- description
- "Indicates whether IPv4 packet forwarding is enabled or
- disabled on this interface.";
- }
-
- leaf mtu {
- type uint16 {
- range "68..max";
- }
- units "octets";
- description
- "The size, in octets, of the largest IPv4 packet that the
- interface will send and receive.";
- reference
- "RFC 791: Internet Protocol";
-
- }
-
- list address {
- key "ip";
- description
- "The list of IPv4 addresses on the interface.";
- leaf ip {
- type inet:ipv4-address-no-zone;
- description
- "The IPv4 address on the interface.";
- }
-
- choice subnet {
- description
- "The subnet can be specified as a prefix-length, or,
- if the server supports non-contiguous netmasks, as
- a netmask.";
- leaf prefix-length {
- type uint8 {
- range "0..32";
- }
- description
- "The length of the subnet prefix.";
- }
- leaf netmask {
- if-feature ipv4-non-contiguous-netmasks;
- type yang:dotted-quad;
- description
- "The subnet specified as a netmask.";
- }
- } // choice subnet
-
- leaf origin {
- type ip-address-origin;
- description
- "The origin of this address.";
- }
- } // list address
-
- list neighbor {
- key "ip";
- description
- "A list of mappings from IPv4 addresses to
- link-layer addresses.
-
- This list represents the ARP Cache.";
- reference
- "RFC 826: An Ethernet Address Resolution Protocol";
-
- leaf ip {
- type inet:ipv4-address-no-zone;
- description
- "The IPv4 address of the neighbor node.";
- }
-
- leaf link-layer-address {
- type yang:phys-address;
- description
- "The link-layer address of the neighbor node.";
- }
-
- leaf origin {
- type neighbor-origin;
- description
- "The origin of this neighbor entry.";
- }
- } // list neighbor
- } // container ipv4
-
- container ipv6 {
- presence
- "Present if IPv6 is enabled on this interface";
- config false;
- description
- "Parameters for the IPv6 address family.";
- leaf forwarding {
- type boolean;
- default 'false';
- description
- "Indicates whether IPv6 packet forwarding is enabled or
- disabled on this interface.";
- reference
- "RFC 4861: Neighbor Discovery for IP version 6 (IPv6)
- Section 6.2.1, IsRouter";
-
- }
-
- leaf mtu {
- type uint32 {
- range "1280..max";
- }
- units "octets";
- description
- "The size, in octets, of the largest IPv6 packet that the
- interface will send and receive.";
- reference
- "RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
- Section 5";
-
- }
-
- list address {
- key "ip";
- description
- "The list of IPv6 addresses on the interface.";
- leaf ip {
- type inet:ipv6-address-no-zone;
- description
- "The IPv6 address on the interface.";
- }
-
- leaf prefix-length {
- type uint8 {
- range "0..128";
- }
- mandatory true;
- description
- "The length of the subnet prefix.";
- }
-
- leaf origin {
- type ip-address-origin;
- description
- "The origin of this address.";
- }
-
- leaf status {
- type enumeration {
- enum "preferred" {
- value 0;
- description
- "This is a valid address that can appear as the
- destination or source address of a packet.";
- }
- enum "deprecated" {
- value 1;
- description
- "This is a valid but deprecated address that should
- no longer be used as a source address in new
- communications, but packets addressed to such an
- address are processed as expected.";
- }
- enum "invalid" {
- value 2;
- description
- "This isn't a valid address, and it shouldn't appear
- as the destination or source address of a packet.";
- }
- enum "inaccessible" {
- value 3;
- description
- "The address is not accessible because the interface
- to which this address is assigned is not
- operational.";
- }
- enum "unknown" {
- value 4;
- description
- "The status cannot be determined for some reason.";
- }
- enum "tentative" {
- value 5;
- description
- "The uniqueness of the address on the link is being
- verified. Addresses in this state should not be
- used for general communication and should only be
- used to determine the uniqueness of the address.";
- }
- enum "duplicate" {
- value 6;
- description
- "The address has been determined to be non-unique on
- the link and so must not be used.";
- }
- enum "optimistic" {
- value 7;
- description
- "The address is available for use, subject to
- restrictions, while its uniqueness on a link is
- being verified.";
- }
- }
- description
- "The status of an address. Most of the states correspond
- to states from the IPv6 Stateless Address
- Autoconfiguration protocol.";
- reference
- "RFC 4293: Management Information Base for the
- Internet Protocol (IP)
- - IpAddressStatusTC
- RFC 4862: IPv6 Stateless Address Autoconfiguration";
-
- }
- } // list address
-
- list neighbor {
- key "ip";
- description
- "A list of mappings from IPv6 addresses to
- link-layer addresses.
-
- This list represents the Neighbor Cache.";
- reference
- "RFC 4861: Neighbor Discovery for IP version 6 (IPv6)";
-
- leaf ip {
- type inet:ipv6-address-no-zone;
- description
- "The IPv6 address of the neighbor node.";
- }
-
- leaf link-layer-address {
- type yang:phys-address;
- description
- "The link-layer address of the neighbor node.";
- }
-
- leaf origin {
- type neighbor-origin;
- description
- "The origin of this neighbor entry.";
- }
-
- leaf is-router {
- type empty;
- description
- "Indicates that the neighbor node acts as a router.";
- }
-
- leaf state {
- type enumeration {
- enum "incomplete" {
- value 0;
- description
- "Address resolution is in progress, and the link-layer
- address of the neighbor has not yet been
- determined.";
- }
- enum "reachable" {
- value 1;
- description
- "Roughly speaking, the neighbor is known to have been
- reachable recently (within tens of seconds ago).";
- }
- enum "stale" {
- value 2;
- description
- "The neighbor is no longer known to be reachable, but
- until traffic is sent to the neighbor no attempt
- should be made to verify its reachability.";
- }
- enum "delay" {
- value 3;
- description
- "The neighbor is no longer known to be reachable, and
- traffic has recently been sent to the neighbor.
- Rather than probe the neighbor immediately, however,
- delay sending probes for a short while in order to
- give upper-layer protocols a chance to provide
- reachability confirmation.";
- }
- enum "probe" {
- value 4;
- description
- "The neighbor is no longer known to be reachable, and
- unicast Neighbor Solicitation probes are being sent
- to verify reachability.";
- }
- }
- description
- "The Neighbor Unreachability Detection state of this
- entry.";
- reference
- "RFC 4861: Neighbor Discovery for IP version 6 (IPv6)
- Section 7.3.2";
-
- }
- } // list neighbor
- } // container ipv6
- }
-} // module ietf-ip
+++ /dev/null
-module v3po {
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:v3po";
- prefix "v3po";
-
- revision "2015-01-05" {
- description "Initial revision of v3po model";
- }
-
- import iana-if-type {
- prefix "ianaift";
- }
- import ietf-interfaces {
- prefix "if";
- }
- import ietf-yang-types {
- prefix "yang";
- }
- import ietf-inet-types {
- prefix "inet";
- }
- import ietf-ip {
- prefix "ip";
- }
- import yang-ext {
- prefix "ext";
- }
-
- typedef bridge-domain-ref {
- type leafref {
- path "/vpp/bridge-domains/bridge-domain/name";
- }
- description
- "This type is used by to reference a bridge domain table";
- }
-
- typedef bridged-virtual-interface-ref {
- type leafref {
- path "/if:interfaces/if:interface/l2/bridged-virtual-interface";
- }
- description
- "This type is used by to reference a bridged virtual interface";
- }
-
- typedef vlan-type {
- type enumeration {
- enum 802dot1q;
- enum 802dot1ad;
- }
- }
-
- typedef tag-rewrite-operation {
- type enumeration {
- enum disabled;
- enum push-1;
- enum push-2;
- enum pop-1;
- enum pop-2;
- enum translate-1-to-1;
- enum translate-1-to-2;
- enum translate-2-to-1;
- enum translate-2-to-2;
- }
- }
-
- typedef vlan-tag {
- type uint16 {
- range "1..4094";
- }
- }
-
- identity vxlan-tunnel {
- base if:interface-type;
- }
-
- identity vhost-user {
- base if:interface-type;
- }
-
- identity tap {
- base if:interface-type;
- }
-
- identity sub-interface {
- base if:interface-type;
- }
-
- typedef vxlan-vni {
- // FIXME: should be in a vxlan-specific model
- description "VNI used in a VXLAN tunnel";
- type uint32 {
- range "0..16777215";
- }
- }
-
- typedef vhost-user-role {
- type enumeration {
- enum "server";
- enum "client";
- }
- }
-
- identity vxlan-gpe-tunnel {
- base if:interface-type;
- }
-
- typedef vxlan-gpe-vni {
- description "VNI used in a VXLAN-GPE tunnel";
- type uint32 {
- range "0..16777215";
- }
- }
-
- typedef vxlan-gpe-next-protocol {
- type enumeration {
- enum ipv4;
- enum ipv6;
- enum ethernet;
- enum nsh;
- }
- }
-
- grouping bridge-domain-attributes {
- leaf flood {
- type boolean;
- default true;
- description
- "Enable/disable L2 flooding.";
- }
- leaf forward {
- type boolean;
- default true;
- description
- "Enable/disable L2 forwarding.";
- }
- leaf learn {
- type boolean;
- default true;
- description
- "Enable/disable L2 learning.";
- }
- leaf unknown-unicast-flood {
- type boolean;
- default true;
- }
- leaf arp-termination {
- type boolean;
- default false;
- }
- }
-
- grouping sub-interface-base-attributes {
- leaf identifier {
- type uint32;
- }
- leaf vlan-type {
- type vlan-type;
- default '802dot1q';
- }
- leaf number-of-tags {
- type uint8 {
- range "0..2";
- }
- default 1;
- }
- leaf outer-id {
- type vlan-tag;
- }
- leaf inner-id {
- type vlan-tag;
- }
- leaf match-any-outer-id {
- type empty;
- }
- leaf match-any-inner-id {
- type empty;
- }
- leaf exact-match {
- type empty;
- }
- leaf default-subif {
- type empty;
- }
- }
-
- grouping tap-interface-base-attributes {
- leaf tap-name {
- type string;
- }
- }
-
- grouping tap-interface-config-attributes {
- leaf mac {
- type yang:phys-address;
- mandatory false;
- description "Mac address to be set for the tap interface. Random will be used if not configured";
- }
-
- leaf device-instance {
- type uint32;
- mandatory false;
- description "Custom device instance. Autogenerated will be used if not configured";
- }
- }
-
- grouping ethernet-base-attributes {
- leaf mtu {
- type uint16 {
- range "64..9216";
- }
- units "octets";
- default 9216;
- description
- "The size, in octets, of the largest packet that the
- hardware interface will send and receive.";
- }
- }
-
- grouping ethernet-state-attributes {
- leaf manufacturer-description {
- type string;
- config false;
- }
- leaf duplex {
- type enumeration {
- enum "half";
- enum "full";
- }
- config false;
- }
- }
-
- grouping vhost-user-interface-base-attributes {
- leaf socket {
- type string {
- length 1..255;
- }
- }
- leaf role {
- type vhost-user-role;
- default "server";
- }
- description "vhost-user settings";
- }
-
- grouping vhost-user-interface-state-attributes {
- leaf features {
- type uint64;
- config false;
- }
- leaf virtio-net-hdr-size {
- type uint32;
- config false;
- }
- leaf num-memory-regions {
- type uint32;
- config false;
- }
- leaf connect-error {
- type string;
- config false;
- }
- }
-
- grouping vxlan-base-attributes {
- // FIXME: this should be in an vxlan-specific extension
- leaf src {
- /*mandatory true;*/
- type inet:ip-address;
- }
- leaf dst {
- /*mandatory true;*/
- type inet:ip-address;
- }
- leaf vni {
- /*mandatory true;*/
- type vxlan-vni;
- }
- leaf encap-vrf-id {
- type uint32;
- }
- }
-
- grouping vxlan-gpe-base-attributes {
- leaf local {
- /*mandatory true;*/
- type inet:ip-address;
- }
- leaf remote {
- /*mandatory true;*/
- type inet:ip-address;
- }
- leaf vni {
- /*mandatory true;*/
- type vxlan-gpe-vni;
- }
- leaf next-protocol {
- type vxlan-gpe-next-protocol;
- }
- leaf encap-vrf-id {
- type uint32;
- }
- leaf decap-vrf-id {
- type uint32;
- }
- }
-
- grouping vlan-tag-rewrite-attributes {
- leaf rewrite-operation {
- type tag-rewrite-operation;
- default 'disabled';
- }
- leaf first-pushed {
- type vlan-type;
- default '802dot1q';
- }
- leaf tag1 {
- type vlan-tag;
- }
- leaf tag2 {
- type vlan-tag;
- }
- }
-
- grouping l2-attributes {
- description
- "Parameters for configuring Layer2 features on interfaces.";
-
- choice interconnection {
- case xconnect-based {
- leaf xconnect-outgoing-interface {
- /* Don't allow selection of this interface */
- must "../../if:name != current()";
- type if:interface-ref; // todo use interface-state-ref for operational data?
- description
- "L2 xconnect mode";
- }
- }
- case bridge-based {
- leaf bridge-domain {
- type bridge-domain-ref;
- description
- "Interfaces in a bridge-domain forward packets to other
- interfaces in the same bridge-domain based on
- destination mac address.";
- }
- leaf split-horizon-group {
- when "../bridge-domain";
- type uint8 {
- range "0..255";
- }
- default 0;
- description
- "Interface's split-horizon group. Interfaces in the same
- bridge-domain and split-horizon group can not forward
- packets between each other. ";
- }
- leaf bridged-virtual-interface {
- when "../bridge-domain";
- type boolean;
- default false;
- description
- "Interface forward packets in the bridge-domain
- associated with the BVI.";
- }
- }
- }
- container vlan-tag-rewrite { // todo valid only for sub-interfaces
- uses vlan-tag-rewrite-attributes;
- }
- }
-
- augment /if:interfaces/if:interface {
- ext:augment-identifier "vpp-interface-augmentation";
-
- // FIXME using ietf-interfaces model for vpp interfaces makes it hard to implement because:
- // 1. The link between interface type and this augmentation is unclear
- // 2. Only this augmentation with combination of ifc type is trigger to do something for vpp, what if user only configures base interface stuff ? + We need to get leaves defined by ietf-interfaces when we are processing this augment
- // 3. The ietf-interfaces model does not define groupings which makes types reuse difficult
-
- container sub-interface {
- when "../if:type = 'v3po:sub-interface'";
- leaf super-interface {
- type if:interface-ref;
- }
- uses sub-interface-base-attributes;
- }
-
- container tap {
- when "../if:type = 'v3po:tap'";
- uses tap-interface-base-attributes;
- uses tap-interface-config-attributes;
- }
-
- container ethernet {
- when "../if:type = 'ianaift:ethernetCsmacd'";
- uses ethernet-base-attributes;
- }
-
- container routing {
- leaf vrf-id { // todo no routing info for oper, is it possible to get it from the vpp?
- type uint32;
- default 0;
- }
- }
-
- container vhost-user {
- when "../if:type = 'v3po:vhost-user'";
- uses vhost-user-interface-base-attributes;
- }
-
- container vxlan {
- when "../if:type = 'v3po:vxlan-tunnel'";
- uses vxlan-base-attributes;
- }
-
- container l2 {
- must "(not (../if:ipv4[if:enabled = 'true']/if:address/if:ip) and " +
- "not (../if:ipv6[if:enabled = 'true']/if:address/if:ip))";
-
- uses l2-attributes;
- }
-
- container vxlan-gpe {
- when "../if:type = 'v3po:vxlan-gpe-tunnel'";
-
- uses vxlan-gpe-base-attributes;
- }
- }
-
- container vpp {
- description
- "VPP config data";
-
- container bridge-domains {
- list bridge-domain {
- key "name";
- // TODO: where does this come from?
- max-elements 1024;
-
- leaf name {
- type string;
- }
-
- uses bridge-domain-attributes;
-
- list l2-fib {
- key "phys-address";
-
- leaf phys-address {
- type yang:phys-address;
- }
- leaf action {
- type enumeration {
- enum "forward";
- enum "filter";
- }
- mandatory true;
- }
- leaf outgoing-interface {
- type if:interface-ref;
- }
- }
- }
- }
- }
-
- augment /if:interfaces-state/if:interface {
- ext:augment-identifier "vpp-interface-state-augmentation";
-
- leaf description {
- type string;
- }
-
- container sub-interface {
- when "../if:type = 'v3po:sub-interface'";
- leaf super-interface {
- type if:interface-state-ref;
- }
- uses sub-interface-base-attributes;
- }
-
- container tap {
- when "../if:type = 'v3po:tap'";
- uses tap-interface-base-attributes;
- }
-
- container ethernet {
- when "../if:type = 'ianaift:ethernetCsmacd'";
- uses ethernet-base-attributes;
- uses ethernet-state-attributes;
- }
-
- container vhost-user {
- when "../if:type = 'v3po:vhost-user'";
- uses vhost-user-interface-base-attributes;
- uses vhost-user-interface-state-attributes;
- }
-
- container vxlan {
- when "../if:type = 'v3po:vxlan-tunnel'";
- uses vxlan-base-attributes;
- }
- container vxlan-gpe {
- when "../if:type = 'v3po:vxlan-gpe-tunnel'";
-
- uses vxlan-gpe-base-attributes;
- }
-
- container l2 {
- must "(not (../if:ipv4[if:enabled = 'true']/if:address/if:ip) and " +
- "not (../if:ipv6[if:enabled = 'true']/if:address/if:ip))";
-
- uses l2-attributes;
- }
- }
-
- augment /if:interfaces-state/if:interface/if:statistics {
- ext:augment-identifier "vpp-interface-statistics-augmentation";
- leaf in-errors-no-buf {
- type yang:counter64;
- }
- leaf in-errors-miss {
- type yang:counter64;
- }
- leaf out-discards-fifo-full {
- type yang:counter64;
- }
- }
-
- container vpp-state {
- config false;
-
- description
- "VPP operational data";
-
- container bridge-domains {
- // FIXME: Should this live in bridge-domain.yang in a modular fashion ?
- list bridge-domain {
-
- key "name";
- leaf name {
- type string;
- }
-
- uses bridge-domain-attributes;
-
- list interface {
- key "name";
-
- leaf name {
- type if:interface-state-ref;
- }
-
- leaf split-horizon-group {
- type uint8;
- }
-
- leaf bridged-virtual-interface {
- type boolean;
- }
- }
-
- list l2-fib {
- key "phys-address";
-
- leaf phys-address {
- type yang:phys-address;
- }
- leaf static-config {
- type boolean;
- }
- leaf outgoing-interface {
- when "../v3po:action = 'forward'";
- type if:interface-state-ref;
- }
- leaf action {
- type enumeration {
- enum "forward";
- enum "filter";
- }
- mandatory true;
- }
- leaf bridged-virtual-interface {
- when "../v3po:action = 'forward'";
- type boolean;
- }
- }
- description
- "bridge-domain operational data";
- }
- }
-
- container version {
- leaf name {
- type string;
- }
- leaf build-directory {
- type string;
- }
- leaf build-date {
- type string;
- }
- leaf branch {
- type string;
- }
- description
- "vlib version info";
- }
- }
-}
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2Builder;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VhostUser;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VhostUserBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.attributes.interconnection.BridgeBased;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.attributes.interconnection.BridgeBasedBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBased;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBasedBuilder;\r
\r
import com.google.common.base.Optional;\r
\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUserRole;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.attributes.Interconnection;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.attributes.interconnection.BridgeBased;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.Interconnection;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBased;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomains;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.groupbasedpolicy.renderer.vpp.manager;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;
+import org.opendaylight.groupbasedpolicy.test.CustomDataBrokerTest;
+import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanVni;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyTypesVbridgeAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyTypesVbridgeAugmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyVbridgeAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyVbridgeAugmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.topology.types.VbridgeTopologyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vxlan.rev160429.TunnelTypeVxlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vxlan.rev160429.network.topology.topology.tunnel.parameters.VxlanTunnelParametersBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.TopologyTypesBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.node.attributes.SupportingNodeBuilder;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.ListenableFuture;
+
+public class BridgeDomainManagerImplTest extends CustomDataBrokerTest {
+
+ private static final TopologyId SUPPORTING_TOPOLOGY_NETCONF = new TopologyId("topology-netconf");
+ private final static String BRIDGE_DOMAIN_ID = "bridge-domain-test";
+ private final static TopologyId BASE_TOPOLOGY_ID = new TopologyId(BRIDGE_DOMAIN_ID);
+ private final static VxlanVni BRIDGE_DOMAIN_VNI = new VxlanVni(10L);
+ private final static boolean BRIDGE_DOMAIN_FLOOD = true;
+ private final static boolean BRIDGE_DOMAIN_FORWARD = true;
+ private final static boolean BRIDGE_DOMAIN_LEARN = true;
+ private final static boolean BRIDGE_DOMAIN_UNICAST_FLOOD = true;
+ private final static boolean BRIDGE_DOMAIN_ARP = false;
+ private final static NodeId VPP_NODE_ID = new NodeId("vppNode");
+ private final static Topology BASE_TOPOLOGY = new TopologyBuilder().setTopologyId(BASE_TOPOLOGY_ID)
+ .setNode(Arrays.asList(new NodeBuilder().setNodeId(VPP_NODE_ID)
+ .setSupportingNode(Arrays.asList(new SupportingNodeBuilder().setTopologyRef(SUPPORTING_TOPOLOGY_NETCONF)
+ .setNodeRef(VPP_NODE_ID)
+ .build()))
+ .build()))
+ .setTopologyTypes(new TopologyTypesBuilder()
+ .addAugmentation(TopologyTypesVbridgeAugment.class, new TopologyTypesVbridgeAugmentBuilder()
+ .setVbridgeTopology(new VbridgeTopologyBuilder().build()).build())
+ .build())
+ .addAugmentation(TopologyVbridgeAugment.class,
+ new TopologyVbridgeAugmentBuilder().setTunnelType(TunnelTypeVxlan.class)
+ .setTunnelParameters(new VxlanTunnelParametersBuilder().setVni(BRIDGE_DOMAIN_VNI).build())
+ .setForward(BRIDGE_DOMAIN_FORWARD)
+ .setUnknownUnicastFlood(BRIDGE_DOMAIN_UNICAST_FLOOD)
+ .setLearn(BRIDGE_DOMAIN_LEARN)
+ .setArpTermination(BRIDGE_DOMAIN_ARP)
+ .setFlood(BRIDGE_DOMAIN_FLOOD)
+ .build())
+ .build();
+
+ private DataBroker dataBroker;
+ private BridgeDomainManagerImpl bridgeDomainManager;
+
+ @Override
+ public Collection<Class<?>> getClassesFromModules() {
+ return Arrays.asList(NetworkTopology.class, Topology.class, TopologyVbridgeAugment.class,
+ TunnelTypeVxlan.class);
+ }
+
+ @Before
+ public void init() {
+ dataBroker = getDataBroker();
+ bridgeDomainManager = new BridgeDomainManagerImpl(dataBroker);
+ }
+
+ @Test
+ public void testCreateVxlanBridgeDomainOnVppNode() {
+ ListenableFuture<Void> registered =
+ bridgeDomainManager.createVxlanBridgeDomainOnVppNode(BRIDGE_DOMAIN_ID, BRIDGE_DOMAIN_VNI, VPP_NODE_ID);
+ Assert.assertTrue(registered.isDone());
+
+ Optional<Topology> topologyOptional = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
+ VppIidFactory.getTopologyIid(BASE_TOPOLOGY.getKey()), dataBroker.newReadOnlyTransaction());
+ Assert.assertTrue(topologyOptional.isPresent());
+
+ Topology topology = topologyOptional.get();
+ Assert.assertEquals(BASE_TOPOLOGY, topology);
+ }
+
+ @Test
+ public void testRemoveBridgeDomainFromVppNode() {
+ WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
+
+ writeTransaction.put(LogicalDatastoreType.CONFIGURATION, VppIidFactory.getTopologyIid(BASE_TOPOLOGY.getKey()),
+ BASE_TOPOLOGY, true);
+ boolean result = DataStoreHelper.submitToDs(writeTransaction);
+ Assert.assertTrue(result);
+
+ Optional<Node> topologyOptional = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
+ VppIidFactory.getNodeIid(new TopologyKey(BASE_TOPOLOGY_ID), new NodeKey(VPP_NODE_ID)),
+ dataBroker.newReadOnlyTransaction());
+ Assert.assertTrue(topologyOptional.isPresent());
+
+ ListenableFuture<Void> deleted =
+ bridgeDomainManager.removeBridgeDomainFromVppNode(BRIDGE_DOMAIN_ID, VPP_NODE_ID);
+ Assert.assertTrue(deleted.isDone());
+
+ topologyOptional = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
+ VppIidFactory.getNodeIid(new TopologyKey(BASE_TOPOLOGY_ID), new NodeKey(VPP_NODE_ID)),
+ dataBroker.newReadOnlyTransaction());
+ Assert.assertFalse(topologyOptional.isPresent());
+ }
+
+}
package org.opendaylight.groupbasedpolicy.renderer.vpp.manager;
-import com.google.common.base.Optional;
-import com.google.common.eventbus.EventBus;
-import com.google.common.util.concurrent.CheckedFuture;
+import java.util.ArrayList;
+import java.util.List;
+
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import org.opendaylight.controller.config.yang.config.vpp_provider.impl.VppRenderer;
-import org.opendaylight.controller.md.sal.binding.api.*;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.MountPoint;
+import org.opendaylight.controller.md.sal.binding.api.MountPointService;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilitiesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.UnavailableCapabilitiesBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import java.util.ArrayList;
-import java.util.List;
+import com.google.common.base.Optional;
+import com.google.common.eventbus.EventBus;
+import com.google.common.util.concurrent.CheckedFuture;
/**
* Test for {@link VppNodeManager} and {@link VppNodeListener}.
private static final String INTERFACES_CAPABILITY =
"(urn:ietf:params:xml:ns:yang:ietf-interfaces?revision=2014-05-08)ietf-interfaces";
private static final String NODE_NAME = "testVpp";
-
- private final InstanceIdentifier<Node> nodeIid = VppIidFactory.getNodeIid(new NodeKey(new NodeId(NODE_NAME)));
+ private static final InstanceIdentifier<Node> NODE_IID = VppIidFactory
+ .getNodeIid(new TopologyKey(new TopologyId("topology-netconf")), new NodeKey(new NodeId(NODE_NAME)));
@Mock
BindingAwareBroker.ProviderContext providerContext;
WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
Node testVppNode = createNode(NODE_NAME, NetconfNodeConnectionStatus.ConnectionStatus.Connected);
- writeTransaction.put(LogicalDatastoreType.OPERATIONAL, nodeIid, testVppNode, true);
+ writeTransaction.put(LogicalDatastoreType.OPERATIONAL, NODE_IID, testVppNode, true);
writeTransaction.submit();
Assert.assertTrue(rendererOptional.isPresent());
Assert.assertEquals(1, rendererOptional.get().getRendererNodes().getRendererNode().size());
- Assert.assertEquals(nodeIid, rendererOptional.get().getRendererNodes().getRendererNode().get(0).getNodePath());
+ Assert.assertEquals(NODE_IID, rendererOptional.get().getRendererNodes().getRendererNode().get(0).getNodePath());
}
@Test
WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
Node testVppNode = createNode(NODE_NAME, NetconfNodeConnectionStatus.ConnectionStatus.Connected);
- writeTransaction.put(LogicalDatastoreType.OPERATIONAL, nodeIid, testVppNode, true);
+ writeTransaction.put(LogicalDatastoreType.OPERATIONAL, NODE_IID, testVppNode, true);
writeTransaction.submit();
Assert.assertTrue(rendererOptional.isPresent());
Assert.assertEquals(1, rendererOptional.get().getRendererNodes().getRendererNode().size());
- Assert.assertEquals(nodeIid, rendererOptional.get().getRendererNodes().getRendererNode().get(0).getNodePath());
+ Assert.assertEquals(NODE_IID, rendererOptional.get().getRendererNodes().getRendererNode().get(0).getNodePath());
WriteTransaction writeTransaction2 = dataBroker.newWriteOnlyTransaction();
Node testVppNode2 = createNode(NODE_NAME, NetconfNodeConnectionStatus.ConnectionStatus.Connecting);
- writeTransaction2.put(LogicalDatastoreType.OPERATIONAL, nodeIid, testVppNode2, true);
+ writeTransaction2.put(LogicalDatastoreType.OPERATIONAL, NODE_IID, testVppNode2, true);
writeTransaction2.submit();
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.VhostUserCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.attributes.Interconnection;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.attributes.interconnection.BridgeBased;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.Interconnection;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBased;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomains;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;