<artifactId>netconf-testtool</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>netconf-test-perf</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>netconf-util</artifactId>
<type>xml</type>
<classifier>features</classifier>
</dependency>
+
+ <!-- Testing features -->
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>features-netconf-testing</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-test-tools</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
</dependencies>
</dependencyManagement>
</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2021 PANTHEON.tech, s.r.o. 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
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.opendaylight.odlparent</groupId>
+ <artifactId>feature-repo-parent</artifactId>
+ <version>8.1.0</version>
+ <relativePath/>
+ </parent>
+
+ <groupId>org.opendaylight.netconf</groupId>
+ <artifactId>features-netconf-testing</artifactId>
+ <version>1.10.0-SNAPSHOT</version>
+ <packaging>feature</packaging>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>netconf-artifacts</artifactId>
+ <version>${project.version}</version>
+ <scope>import</scope>
+ <type>pom</type>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-aaa-netconf-plugin</artifactId>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-aaa-netconf-plugin-no-cluster</artifactId>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-all</artifactId>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-api</artifactId>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-client</artifactId>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-impl</artifactId>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-mapping-api</artifactId>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-mdsal</artifactId>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-netty-util</artifactId>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-notifications-api</artifactId>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-notifications-impl</artifactId>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-ssh</artifactId>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-tcp</artifactId>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-util</artifactId>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ </dependencies>
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2021 PANTHEON.tech, s.r.o. 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
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.opendaylight.odlparent</groupId>
+ <artifactId>single-feature-parent</artifactId>
+ <version>8.1.0</version>
+ <relativePath/>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.opendaylight.netconf</groupId>
+ <artifactId>odl-netconf-test-tools</artifactId>
+ <version>1.10.0-SNAPSHOT</version>
+ <packaging>feature</packaging>
+
+ <name>OpenDaylight :: NETCONF Test Tools :: Tools used for performance testing</name>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>netconf-artifacts</artifactId>
+ <version>1.10.0-SNAPSHOT</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-mdsal</artifactId>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>netconf-test-perf</artifactId>
+ </dependency>
+ </dependencies>
+</project>
<module>odl-netconf-ssh</module>
<module>odl-netconf-tcp</module>
<module>odl-netconf-util</module>
+
+ <!-- CSIT features -->
+ <module>features-netconf-testing</module>
+ <module>odl-netconf-test-tools</module>
</modules>
<scm>
<type>xml</type>
<scope>runtime</scope>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.netconf</groupId>
+ <artifactId>features-netconf-testing</artifactId>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <scope>runtime</scope>
+ </dependency>
</dependencies>
</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.opendaylight.netconf</groupId>
+ <artifactId>netconf-parent</artifactId>
+ <version>1.10.0-SNAPSHOT</version>
+ <relativePath>../../../parent/pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>netconf-test-perf</artifactId>
+ <description>NETCONF performance test tools</description>
+ <packaging>bundle</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>mdsal-dom-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>mdsal-dom-spi</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>mdsal-binding-dom-codec-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>ietf-topology</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.netconf</groupId>
+ <artifactId>ietf-netconf-notifications</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.netconf</groupId>
+ <artifactId>mdsal-netconf-notification</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.netconf</groupId>
+ <artifactId>netconf-notifications-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.guicedee.services</groupId>
+ <artifactId>javax.inject</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>javax.annotation</groupId>
+ <artifactId>javax.annotation-api</artifactId>
+ <scope>provided</scope>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.service.component.annotations</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Name>NETCONF performance test tools</Bundle-Name>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+/*
+ * Copyright (c) 2021 Pantheon Technologies, s.r.o. 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.netconf.test.perf;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
+import java.util.Iterator;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.mdsal.dom.api.DOMMountPoint;
+import org.opendaylight.mdsal.dom.api.DOMMountPointListener;
+import org.opendaylight.mdsal.dom.api.DOMMountPointService;
+import org.opendaylight.mdsal.dom.api.DOMNotificationService;
+import org.opendaylight.mdsal.dom.api.DOMRpcResult;
+import org.opendaylight.mdsal.dom.api.DOMRpcService;
+import org.opendaylight.netconf.test.perf.notifications.NotificationsCounter;
+import org.opendaylight.netconf.test.perf.utils.TestUtils;
+import org.opendaylight.yang.gen.v1.org.opendaylight.coretutorials.ncmount.example.notifications.rev150611.VrfRouteNotification;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionInput;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+@Component(immediate = true)
+public class MountedDeviceListener implements DOMMountPointListener {
+ private static final Logger LOG = LoggerFactory.getLogger(MountedDeviceListener.class);
+ private static final String TEST_NODE_PREFIX = "perf-";
+ private static final String STREAM_DEFAULT_NAME = "STREAM-PERF-DEFAULT";
+ private static final QName CREATE_SUBSCRIPTION_QNAME = QName.create(CreateSubscriptionInput.QNAME,
+ "create-subscription");
+
+ private final ConcurrentMap<YangInstanceIdentifier, ListenerRegistration<?>> listeners = new ConcurrentHashMap<>();
+ private final DOMMountPointService mountPointService;
+ private final BindingNormalizedNodeSerializer serializer;
+ private final ListenerRegistration<?> reg;
+
+ @Inject
+ @Activate
+ public MountedDeviceListener(final @Reference DOMMountPointService mountPointService,
+ final @Reference BindingNormalizedNodeSerializer serializer) {
+ this.mountPointService = requireNonNull(mountPointService);
+ this.serializer = requireNonNull(serializer);
+ reg = mountPointService.registerProvisionListener(this);
+ }
+
+ @PreDestroy
+ @Deactivate
+ public void stop() {
+ reg.close();
+ final Iterator<ListenerRegistration<?>> it = listeners.values().iterator();
+ while (it.hasNext()) {
+ it.next().close();
+ it.remove();
+ }
+ }
+
+ @Override
+ public void onMountPointCreated(final YangInstanceIdentifier path) {
+ final Optional<String> optNodeId = TestUtils.getNodeId(path);
+ if (optNodeId.isPresent() && optNodeId.get().startsWith(TEST_NODE_PREFIX)) {
+ LOG.info("Test node mounted: {}", optNodeId.get());
+ trackNotificationsPerformance(path);
+ }
+ }
+
+ @Override
+ public void onMountPointRemoved(final YangInstanceIdentifier path) {
+ final ListenerRegistration<?> listener = listeners.remove(path);
+ if (listener != null) {
+ listener.close();
+ }
+ }
+
+ private void trackNotificationsPerformance(final YangInstanceIdentifier path) {
+ // 1. get nodeId from the path
+ final String nodeId = TestUtils.getNodeId(path).get();
+
+ // 2. extract needed services from the mount point
+ final DOMMountPoint mountPoint = mountPointService.getMountPoint(path)
+ .orElseThrow(() -> new RuntimeException("Unable to get mountpoint"));
+ final DOMRpcService rpcService = mountPoint.getService(DOMRpcService.class)
+ .orElseThrow(() -> new RuntimeException("Unable to get RPC Service from the mountpoint"));
+ final DOMNotificationService notificationService = mountPoint.getService(DOMNotificationService.class)
+ .orElseThrow(() -> new RuntimeException("Unable to get NotificationService from the mountpoint"));
+
+ // 3. create a listener for the notifications
+ listeners.put(path, notificationService.registerNotificationListener(
+ new NotificationsCounter(nodeId, serializer), Absolute.of(VrfRouteNotification.QNAME)));
+
+ // 4. send 'create-subscription' request to the device
+ final StreamNameType streamNameType = new StreamNameType(STREAM_DEFAULT_NAME);
+ final CreateSubscriptionInputBuilder subscriptionInputBuilder = new CreateSubscriptionInputBuilder();
+ subscriptionInputBuilder.setStream(streamNameType);
+ final CreateSubscriptionInput input = subscriptionInputBuilder.build();
+ final ContainerNode inputNode = serializer.toNormalizedNodeRpcData(input);
+ final ListenableFuture<? extends DOMRpcResult> resultFuture = rpcService.invokeRpc(CREATE_SUBSCRIPTION_QNAME,
+ inputNode);
+ Futures.addCallback(resultFuture, new FutureCallback<DOMRpcResult>() {
+ @Override
+ public void onSuccess(@Nullable final DOMRpcResult rpcResult) {
+ LOG.info("Notification stream subscription succesfully completed");
+ }
+
+ @Override
+ public void onFailure(final Throwable throwable) {
+ LOG.error("Notification stream subscription failed");
+ }
+ }, MoreExecutors.directExecutor());
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Pantheon Technologies, s.r.o. 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.netconf.test.perf.notifications;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Stopwatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.mdsal.dom.api.DOMNotification;
+import org.opendaylight.mdsal.dom.api.DOMNotificationListener;
+import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.ip._static.cfg.rev130722.VRFPREFIXTABLE;
+import org.opendaylight.yangtools.yang.binding.Notification;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NotificationsCounter implements DOMNotificationListener {
+
+ private static final Logger LOG = LoggerFactory.getLogger(NotificationsCounter.class);
+
+ /**
+ * Custom pattern to identify nodes where performance should be measured.
+ */
+ private static final Pattern NOTIFICATION_NUMBER_PATTERN = Pattern.compile(".*-notif-([0-9]+)");
+
+ private final String nodeId;
+ private final BindingNormalizedNodeSerializer serializer;
+ private final AtomicLong notifCounter;
+ private final long expectedNotificationCount;
+ private Stopwatch stopWatch;
+ private long totalPrefixesReceived = 0;
+
+ public NotificationsCounter(final String nodeId, final BindingNormalizedNodeSerializer serializer) {
+ this.nodeId = nodeId;
+ this.serializer = serializer;
+ final Matcher matcher = NOTIFICATION_NUMBER_PATTERN.matcher(nodeId);
+ Preconditions.checkArgument(matcher.matches());
+ expectedNotificationCount = Long.parseLong(matcher.group(1));
+ Preconditions.checkArgument(expectedNotificationCount > 0);
+ this.notifCounter = new AtomicLong(this.expectedNotificationCount);
+ }
+
+
+ @Override
+ public void onNotification(@NonNull DOMNotification domNotification) {
+ final long andDecrement = notifCounter.getAndDecrement();
+
+ if (andDecrement == expectedNotificationCount) {
+ this.stopWatch = Stopwatch.createStarted();
+ LOG.info("First notification received at {}", stopWatch);
+ }
+
+ LOG.debug("Notification received, {} to go.", andDecrement);
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Notification received: {}", domNotification);
+ }
+
+ final Notification notification = serializer.fromNormalizedNodeNotification(domNotification.getType(),
+ domNotification.getBody());
+ if (notification instanceof VRFPREFIXTABLE) {
+ totalPrefixesReceived += ((VRFPREFIXTABLE)notification).getVrfPrefixes().getVrfPrefix().size();
+ }
+
+ if (andDecrement == 1) {
+ this.stopWatch.stop();
+ LOG.info("Last notification received at {}", stopWatch);
+ LOG.info("Elapsed ms for {} notifications: {}", expectedNotificationCount,
+ stopWatch.elapsed(TimeUnit.MILLISECONDS));
+ LOG.info("Performance (notifications/second): {}",
+ (expectedNotificationCount * 1.0 / stopWatch.elapsed(TimeUnit.MILLISECONDS)) * 1000);
+ LOG.info("Performance (prefixes/second): {}",
+ (totalPrefixesReceived * 1.0 / stopWatch.elapsed(TimeUnit.MILLISECONDS)) * 1000);
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Pantheon Technologies, s.r.o. 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.netconf.test.perf.utils;
+
+import java.util.Optional;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+
+public final class TestUtils {
+
+ private static final QName NODE_QNAME = QName.create(Node.QNAME, "node-id").intern();
+
+ private TestUtils() {
+ }
+
+ public static Optional<String> getNodeId(final YangInstanceIdentifier path) {
+ if (path.getLastPathArgument() instanceof NodeIdentifierWithPredicates) {
+ final NodeIdentifierWithPredicates nodeIId = ((NodeIdentifierWithPredicates) path.getLastPathArgument());
+ return Optional.ofNullable(nodeIId.getValue(NODE_QNAME, String.class));
+ } else {
+ return Optional.empty();
+ }
+ }
+}
--- /dev/null
+module Cisco-IOS-XR-ip-static-cfg {
+
+ /*** NAMESPACE / PREFIX DEFINITION ***/
+
+ namespace "http://cisco.com/ns/yang/Cisco-IOS-XR-ip-static-cfg";
+
+
+ prefix "ip-static-cfg";
+
+ /*** LINKAGE (IMPORTS / INCLUDES) ***/
+
+ import ietf-inet-types { prefix "inet"; }
+
+ import Cisco-IOS-XR-types { prefix "xr"; }
+
+ /*** META INFORMATION ***/
+
+ organization "Cisco Systems, Inc.";
+
+ contact
+ "Cisco Systems, Inc.
+ Customer Service
+
+ Postal: 170 West Tasman Drive
+ San Jose, CA 95134
+
+ Tel: +1 800 553-NETS
+
+ E-mail: cs-yang@cisco.com";
+
+ description
+ "This module contains a collection of YANG definitions
+ for Cisco IOS-XR ip-static package configuration.
+
+ This module contains definitions
+ for the following management objects:
+ router-static: This class represents router static
+ configuration
+
+ Copyright (c) 2013 by Cisco Systems, Inc.
+ All rights reserved.";
+
+ revision "2013-07-22" {
+ description
+ "Initial revision.";
+ }
+
+
+ grouping VRF-ROUTE {
+ description "Common node of vrf-prefix, vrf-prefix-topology";
+
+ container vrf-route {
+ xr:xr-xml-map "ip_static_cfg:VRFRoute";
+ description "A connected or recursive static route";
+
+ container vrf-next-hops {
+ xr:xr-xml-map "ip_static_cfg:VRFNextHopTable";
+ description
+ "A forwarding interface and/or the address of a
+ nexthop router for this route (one of these
+ must be specified)";
+
+ grouping VRF-NEXT-HOP-CONTENT {
+ description "Content grouping.";
+ leaf bfd-fast-detect {
+ xr:xr-xml-map "ip_static_cfg:BFDFastDetect";
+ type boolean;
+ default "false";
+ description "If set, bfd is enabled";
+ }
+ leaf minimum-interval {
+ xr:xr-xml-map "ip_static_cfg:MinimumInterval";
+ type uint32 {
+ range "3..30000";
+ }
+ units "millisecond";
+ default "100";
+ description "BFD Hello interval in milliseconds";
+ }
+ leaf detect-multiplier {
+ xr:xr-xml-map "ip_static_cfg:DetectMultiplier";
+ type uint32 {
+ range "1..10";
+ }
+ default "3";
+ description "BFD Detect Multiplier";
+ }
+ leaf metric {
+ xr:xr-xml-map "ip_static_cfg:Metric";
+ type uint32 {
+ range "1..254";
+ }
+ default "1";
+ description "Distance metric for this path";
+ }
+ leaf tag {
+ xr:xr-xml-map "ip_static_cfg:Tag";
+ type uint32 {
+ range "1..4294967295";
+ }
+ description "Tag for this path";
+ }
+ leaf permanent {
+ xr:xr-xml-map "ip_static_cfg:Permanent";
+ type boolean;
+ default "false";
+ description "If set, path is permanent";
+ }
+ leaf vrf-lable {
+ xr:xr-xml-map "ip_static_cfg:VRFLable";
+ type uint32 {
+ range "0..4294967295";
+ }
+ default "0";
+ description "VRF LABEL";
+ }
+ leaf tunnel-id {
+ xr:xr-xml-map "ip_static_cfg:TunnelID";
+ type uint32 {
+ range "0..65535";
+ }
+ default "0";
+ description "Tunnel ID for this path";
+ }
+ leaf object-name {
+ xr:xr-xml-map "ip_static_cfg:ObjectName";
+ type xr:Cisco-ios-xr-string {
+ length "0..32";
+ }
+ description "Name of the object to track";
+ }
+ leaf description {
+ xr:xr-xml-map "ip_static_cfg:Description";
+ type string;
+ description "Short Description of Static Route";
+ }
+ }
+
+ list interface-name-and-next-hop-address {
+ xr:xr-xml-map "ip_static_cfg:VRFNextHop";
+ key "interface-name next-hop-address";
+ description "keys: interface-name, next-hop-address";
+ leaf interface-name {
+ xr:xr-xml-map "ip_static_cfg:InterfaceName";
+ type xr:Interface-name;
+ description "Forwarding interface";
+ }
+ leaf next-hop-address {
+ xr:xr-xml-map "ip_static_cfg:NextHopAddress";
+ type inet:ip-address;
+ description "Next hop address";
+ }
+ uses VRF-NEXT-HOP-CONTENT;
+ }
+
+ list interface-name {
+ xr:xr-xml-map "ip_static_cfg:VRFNextHop";
+ key "interface-name";
+ description "keys: interface-name";
+ leaf interface-name {
+ xr:xr-xml-map "ip_static_cfg:InterfaceName";
+ type xr:Interface-name;
+ description "Forwarding interface";
+ }
+ uses VRF-NEXT-HOP-CONTENT;
+ }
+
+ list next-hop-address {
+ xr:xr-xml-map "ip_static_cfg:VRFNextHop";
+ key "next-hop-address";
+ description "keys: next-hop-address";
+ leaf next-hop-address {
+ xr:xr-xml-map "ip_static_cfg:NextHopAddress";
+ type inet:ip-address;
+ description "Next hop address";
+ }
+ uses VRF-NEXT-HOP-CONTENT;
+ }
+ }
+ }
+ }
+
+ grouping TOPOLOGY-TABLE {
+ description "Common node of vrf-unicast, vrf-multicast";
+
+ container topologies {
+ xr:xr-xml-map "ip_static_cfg:TopologyTable";
+ description "Topology static configuration container";
+
+ list topology {
+ xr:xr-xml-map "ip_static_cfg:Topology";
+ key "topology-name";
+ description "Topology static configuration";
+ leaf topology-name {
+ xr:xr-xml-map "ip_static_cfg:TopologyName";
+ type xr:Cisco-ios-xr-string;
+ description "Topology name";
+ }
+ uses VRF-PREFIX-TOPOLOGY-TABLE;
+ }
+ }
+ }
+
+ grouping VRF-PREFIX-TABLE {
+ description "Common node of vrf-unicast, vrf-multicast";
+
+ container vrf-prefixes {
+ xr:xr-xml-map "ip_static_cfg:VRFPrefixTable";
+ description "The set of all Static Topologies for this AFI.";
+
+ list vrf-prefix {
+ xr:xr-xml-map "ip_static_cfg:VRFPrefix";
+ key "prefix prefix-length";
+ description "A static route";
+ leaf prefix {
+ xr:xr-xml-map "ip_static_cfg:Prefix";
+ type inet:ip-address;
+ description "Destination prefix";
+ }
+ leaf prefix-length {
+ xr:xr-xml-map "ip_static_cfg:PrefixLength";
+ type uint32 {
+ range "0..128";
+ }
+ description "Destination prefix length";
+ }
+ uses VRF-ROUTE;
+ }
+ }
+ }
+
+ grouping ADDRESS-FAMILY {
+ description "Common node of default-vrf, vrf";
+
+ container address-family {
+ xr:xr-xml-map "ip_static_cfg:AddressFamily";
+ description "Address family configuration";
+
+ container vrfipv4 {
+ xr:xr-xml-map "ip_static_cfg:VRFIPV4";
+ description "IPv4 static configuration";
+ uses VRF-UNICAST;
+ uses VRF-MULTICAST;
+ }
+
+ container vrfipv6 {
+ xr:xr-xml-map "ip_static_cfg:VRFIPV6";
+ description "IPv6 static configuration";
+ uses VRF-UNICAST;
+ uses VRF-MULTICAST;
+ }
+ }
+ }
+
+ grouping VRF-PREFIX-TOPOLOGY-TABLE {
+ description "Common node of default-topology, topology";
+
+ container vrf-prefix-topologies {
+ xr:xr-xml-map "ip_static_cfg:VRFPrefixTopologyTable";
+ description "The set of all Static Topologies for this AFI.";
+
+ list vrf-prefix-topology {
+ xr:xr-xml-map "ip_static_cfg:VRFPrefixTopology";
+ key "prefix prefix-length";
+ description "A static route";
+ leaf prefix {
+ xr:xr-xml-map "ip_static_cfg:Prefix";
+ type inet:ip-address;
+ description "Destination prefix";
+ }
+ leaf prefix-length {
+ xr:xr-xml-map "ip_static_cfg:PrefixLength";
+ type uint32 {
+ range "0..128";
+ }
+ description "Destination prefix length";
+ }
+ uses VRF-ROUTE;
+ }
+ }
+ }
+
+ grouping DEFAULT-TOPOLOGY {
+ description "Common node of vrf-unicast, vrf-multicast";
+
+ container default-topology {
+ xr:xr-xml-map "ip_static_cfg:DefaultTopology";
+ description "Default topology configuration";
+ uses VRF-PREFIX-TOPOLOGY-TABLE;
+ }
+ }
+
+ grouping VRF-UNICAST {
+ description "Common node of vrfipv4, vrfipv6";
+
+ container vrf-unicast {
+ xr:xr-xml-map "ip_static_cfg:VRFUnicast";
+ description "Unicast static configuration";
+ uses TOPOLOGY-TABLE;
+ uses VRF-PREFIX-TABLE;
+ uses DEFAULT-TOPOLOGY;
+ }
+ }
+
+ grouping VRF-MULTICAST {
+ description "Common node of vrfipv4, vrfipv6";
+
+ container vrf-multicast {
+ xr:xr-xml-map "ip_static_cfg:VRFMulticast";
+ description "Multicast static configuration";
+ uses TOPOLOGY-TABLE;
+ uses VRF-PREFIX-TABLE;
+ uses DEFAULT-TOPOLOGY;
+ }
+ }
+
+ container router-static {
+ xr:xr-xml-map "ip_static_cfg:RouterStatic";
+ description "This class represents router static configuration";
+
+ container vrfs {
+ xr:xr-xml-map "ip_static_cfg:VRFTable";
+ description "VRF static configuration container";
+
+ list vrf {
+ xr:xr-xml-map "ip_static_cfg:VRF";
+ key "vrf-name";
+ description "VRF static configuration";
+ leaf vrf-name {
+ xr:xr-xml-map "ip_static_cfg:VRFName";
+ type xr:Cisco-ios-xr-string;
+ description "VRF name";
+ }
+ uses ADDRESS-FAMILY;
+ }
+ }
+
+ container default-vrf {
+ xr:xr-xml-map "ip_static_cfg:DefaultVRF";
+ description "Default VRF configuration";
+ uses ADDRESS-FAMILY;
+ }
+
+ container maximum-routes {
+ xr:xr-xml-map "ip_static_cfg:MaximumRoutes";
+ description
+ "The maximum number of static routes that can be
+ configured.";
+ leaf ipv6-routes {
+ xr:xr-xml-map "ip_static_cfg:IPV6Routes";
+ type uint32 {
+ range "1..140000";
+ }
+ default "4000";
+ description
+ "The maximum number of static routes that can be
+ configured for this AFI";
+ }
+ leaf ipv4-routes {
+ xr:xr-xml-map "ip_static_cfg:IPV4Routes";
+ type uint32 {
+ range "1..140000";
+ }
+ default "4000";
+ description
+ "The maximum number of static routes that can be
+ configured for this AFI";
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+module Cisco-IOS-XR-types {
+
+ namespace "http://cisco.com/ns/yang/cisco-xr-types";
+ prefix "xr";
+
+ organization "Cisco Systems, Inc.";
+
+ contact
+ "Cisco Systems, Inc.
+ Customer Service
+
+ Postal: 170 W Tasman Drive
+ San Jose, CA 95134
+
+ Tel: +1 1800 553-NETS
+
+ E-mail: cs-yang@cisco.com";
+
+
+ description
+ "This module contains a collection of IOS-XR derived YANG data
+ types.
+
+ Copyright (c) 2013-2015 by Cisco Systems, Inc.
+ All rights reserved.";
+
+ revision "2015-01-19" {
+ description
+ "This revision adds the following new data types:
+ - Bgp-ipv4-flowspec-address
+ - Bgp-ipv6-flowspec-address";
+ }
+
+ extension xr-cli-map {
+ argument "cli-command";
+ description "The xr-cli-map statement takes as an argument
+ relevant CLI configuration command.";
+ }
+
+ extension xr-xml-map {
+ argument "xr-xml-node";
+ description "The xr-xml-map statement takes as an argument
+ relevant Cisco XML Schema node name.";
+ }
+
+ typedef Route-dist {
+ type string {
+ pattern "[a-fA-F0-9]{16}";
+ }
+ description "Route distinguisher in hexadecimal notation.";
+ }
+
+ typedef Bgp-l2vpn-evpn-addrs {
+ type string {
+ pattern "[a-fA-F0-9]{58}";
+ }
+ description "L2VPN EVPN Address in hexadecimal notation.";
+ }
+
+ typedef Bgp-ls-addr {
+ type string {
+ pattern "[a-fA-F0-9]+";
+ }
+ description "BGP link state unicast address in hexadecimal
+ notation.";
+ }
+
+ typedef Bgp-ipv6-mvpn-addr {
+ type string {
+ pattern "[a-fA-F0-9]{104}";
+ }
+ description "An IPV6 MVPN address in hexadecimal notation.";
+ }
+
+ typedef Bgp-ipv4-mvpn-addr {
+ type string {
+ pattern "[a-fA-F0-9]{56}";
+ }
+ description "An IPV4 MVPN address in hexadecimal notation.";
+ }
+
+ typedef Bgp-rt-constrt-addr {
+ type string {
+ pattern "[a-fA-F0-9]{24}";
+ }
+ description
+ "An IPV4 RTConstraint address in hexadecimal notation.";
+ }
+
+ typedef Bgp-ipv4-mdt-addr {
+ type string {
+ pattern "(([a-f0-9]{16}-)(([1-9]?[0-9]|1[0-9][0-9]|2[0-4]"+
+ "[0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9][0-9]|2[0-4][0-9]"+
+ "|25[0-5]))";
+ }
+ description "An IPV4 MDT address in dotted decimal notation.
+ An IPv4 MDT address should be of the form
+ 0000006400000065-129.29.83.45. This datatype
+ restricts the value of each field 16 digits in
+ hexadecimal for RD field and between 0 and 255
+ for IPv4 address field, i.e.
+ [0000000000000000-ffffffffffffffff]-
+ [0-255].[0-255].[0-255].[0-255].";
+ }
+
+ typedef Bgp-ipv4-tunnel-addr {
+ type string {
+ pattern "((0:|[1-9][0-9]{0,4}:)"+
+ "(([1-9]?[0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}"+
+ "([1-9]?[0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))";
+ }
+ description "An IPV4 tunnel address in dotted decimal notation.
+ An IPv4 tunnel address should be of the form
+ 65535:129.29.83.45. This datatype restricts the
+ value of each field between 0 and 65535 for prefix
+ field and 0 and 255 for IPv4 address field, i.e.
+ [0-65535]:[0-255].[0-255].[0-255].[0-255]";
+ }
+
+ typedef Cisco-ios-xr-port-number {
+ type uint16 {
+ range "1..65535";
+ }
+ description "Port number of range from 1 to 65535";
+ }
+
+ typedef Interface-name {
+ type string {
+ pattern "(([a-zA-Z0-9_]*\d+/){3}\d+)|"+
+ "(([a-zA-Z0-9_]*\d+/){4}\d+)|"+
+ "(([a-zA-Z0-9_]*\d+/){3}\d+\.\d+)|"+
+ "(([a-zA-Z0-9_]*\d+/){2}([a-zA-Z0-9_]*\d+))|"+
+ "([a-zA-Z0-9_-]*\d+)|"+
+ "([a-zA-Z0-9_-]*\d+\.\d+)|"+
+ "(mpls)|(dwdm)";
+ }
+ description "An interface name specifying an interface type and
+ instance.
+ Interface represents a string defining an interface
+ type and instance, e.g. MgmtEth0/4/CPU1/0 or
+ TenGigE0/2/0/0.2 or Bundle-Ether9 or
+ Bundle-Ether9.98";
+ }
+
+ typedef Cisco-ios-xr-string {
+ type string {
+ pattern "[\w\-\.:,_@#%$\+=\|;]+";
+ }
+ description "Special characters are not allowed.";
+ }
+
+ typedef Ipv4-prefix-length {
+ type uint8 {
+ range "0..32";
+ }
+ description "An IPv4 address prefix length.
+ Must lie between 0 and 32 inclusive.";
+ }
+
+ typedef Ipv6-prefix-length {
+ type uint8 {
+ range "0..128";
+ }
+ description "An IPv6 address prefix length.
+ Must lie between 0 and 32 inclusive.";
+ }
+
+ typedef Rack-id {
+ type string {
+ pattern "[a-zA-Z0-9_]*\d+";
+ }
+ description "Names the rack portion of a NodeID
+ Rack/Slot/Instance triple";
+ }
+
+ typedef Slot-id {
+ type string {
+ pattern "[a-zA-Z0-9_]*\d+";
+ }
+ description "Names the slot portion of a NodeID
+ Rack/Slot/Instance triple";
+ }
+
+ typedef Instance-id {
+ type string {
+ pattern "[a-zA-Z0-9_]*\d+";
+ }
+ description "Names the instance portion of a NodeID
+ Rack/Slot/Instance triple";
+ }
+
+ typedef Sub-instance-id {
+ type string {
+ pattern "[a-zA-Z0-9_]*\d+";
+ }
+ description "Names the sub-instance portion of an extended
+ NodeID Rack/Slot/Instance/SubInstance";
+ }
+
+ typedef Encryption-type {
+ type enumeration {
+ enum none {
+ value "0";
+ description "The password string is clear text.";
+ }
+ enum md5 {
+ value "1";
+ description "The password is encrypted to an MD5 digest.";
+ }
+ enum proprietary {
+ value "2";
+ description "The password is encrypted using Cisco type 7
+ password encryption.";
+ }
+ }
+ description "The type of encryption used on a password string.";
+
+ }
+
+ typedef Hex-integer {
+ type string {
+ pattern "[0-9a-fA-F]{1,8}";
+ }
+ description "An unsigned 32-bit integer represented in
+ hexadecimal format.";
+ }
+
+ typedef Osi-system-id {
+ type string {
+ pattern "[a-fA-F0-9]{4}(\.[a-fA-F0-9]{4}){2}";
+ }
+ description "An OSI system ID should be of the form
+ 0123.4567.89ab. This data type restricts each
+ character to a hex character.";
+ }
+
+ typedef Osi-area-address {
+ type string {
+ pattern "[a-fA-F0-9]{2}(\.[a-fA-F0-9]{4}){0,6}";
+ }
+ description "An OSI area address should consist of an odd number
+ of octets, and be of the form 01 or 01.2345 etc up
+ to 01.2345.6789.abcd.ef01.2345.6789. This data type
+ restricts each character to a hex character.";
+ }
+
+ typedef Isis-node-id {
+ type string {
+ pattern "[a-fA-F0-9]{4}(\.[a-fA-F0-9]{4}){2}\.[a-fA-F0-9]{2}";
+ }
+ description "An ISIS node ID should be of the form
+ 0123.4567.89ab.cd. This data type restricts each
+ character to a hex character.";
+ }
+
+ typedef Isis-snpa {
+ type string {
+ pattern "[a-fA-F0-9]{4}(\.[a-fA-F0-9]{4}){2}";
+ }
+ description "String representation of a SNPA, 802.2 MAC address
+ in canonical format, e.g. 0123.4567.89ab";
+ }
+
+ typedef Isis-lsp-id {
+ type string {
+ pattern "[a-fA-F0-9]{4}(\.[a-fA-F0-9]{4}){2}\.[a-fA-F0-9]{2}"+
+ "\-[a-fA-F0-9]{2}";
+ }
+ description "An ISIS LSP ID should be of the form
+ 0123.4567.89ab.cd-ef. This data type restricts each
+ character to a hex character.";
+ }
+
+ typedef Osi-net {
+ type string {
+ pattern
+ "[a-fA-F0-9]{2}(\.[a-fA-F0-9]{4}){3,9}\.[a-fA-F0-9]{2}";
+ }
+ description "An OSI NET should consist of an even number of
+ octets, and be of the form 01.2345.6789.abcd.ef etc
+ up to
+ 01.2345.6789.abcd.ef01.2345.6789.abcd.ef01.2345.67.
+ This data type restricts each character to a hex
+ character.";
+ }
+
+ typedef String-identifier {
+ type string {
+ pattern "[a-zA-Z][\w\-]*";
+ }
+ description "A string for specifying identifier.";
+ }
+
+ typedef Extended-node-id {
+ type string {
+ pattern "([a-zA-Z0-9_]*\d+/){3}([a-zA-Z0-9_]*\d+)";
+ }
+ description "A location used as value information and specified
+ as a Rack/Slot/Instance/SubInstance, e.g.
+ 0/1/CPU0/NPU0";
+ }
+
+ typedef Node-id {
+ type string {
+ pattern "([a-zA-Z0-9_]*\d+/){2}([a-zA-Z0-9_]*\d+)";
+ }
+ description "A location used as value information and specified
+ as a Rack/Slot/Instance triple, e.g. F0/SC1/0.";
+ }
+
+ typedef Pq-node-id {
+ type string {
+ pattern "((([a-zA-Z0-9_]*\d+)|(\*))/){2}(([a-zA-Z0-9_]*\d+)"+
+ "|(\*))";
+ }
+ description "Partially qualified location which is used for
+ wildcarding location specifications, e.g. 1/*/*";
+ }
+
+ typedef Md5-password {
+ type string {
+ pattern "(!.+)|([^!].+)";
+ }
+ description
+ "The Md5-password type is used to store password using the MD5
+ hash function.
+ When a clear text value is set to a leaf of this type, the
+ server calculates a password hash and stores the result
+ in the datastore. The password is never stored in clear text.
+
+ When a leaf of this type is read, the stored password hash is
+ returned.
+
+ A value of this type matches one of the forms:
+
+ !<clear text password>
+ <password hash>
+
+ The '!' prefix signals that the value is clear text. When
+ such a value is received by the server, a hash value is
+ calculated. This value is stored in the configuration data
+ store.
+
+ If a value starting without '!' is received, the server knows
+ that the value already represents a hashed value, and stores
+ it as is in the data store.";
+ }
+
+ typedef Proprietary-password {
+ type string {
+ pattern "(!.+)|([^!].+)";
+ }
+ description
+ "The Proprietary-password type is used to store password
+ using the Cisco proprietary hash function.
+ When a clear text value is set to a leaf of this type, the
+ server calculates a password hash and stores the result
+ in the datastore. The password is never stored in clear text.
+
+ When a leaf of this type is read, the stored password hash is
+ returned.
+
+ A value of this type matches one of the forms:
+
+ !<clear text password>
+ <password hash>
+
+ The '!' prefix signals that the value is clear text. When
+ such a value is received by the server, a hash value is
+ calculated. This value is stored in the configuration data
+ store.
+
+ If a value starting without '!' is received, the server knows
+ that the value already represents a hashed value, and stores
+ it as is in the data store.";
+ }
+
+ typedef Bgp-ipv4-flowspec-address {
+ type string {
+ pattern "[a-fA-F0-9]{4096}";
+ }
+ description "An IPV4 Flowspec address in hexadecimal notation.";
+ }
+
+ typedef Bgp-ipv6-flowspec-address {
+ type string {
+ pattern "[a-fA-F0-9]{4096}";
+ }
+ description "An IPV6 Flowspec address in hexadecimal notation.";
+ }
+}
--- /dev/null
+module Example-notifications {
+
+ namespace "org:opendaylight:coretutorials:ncmount:example:notifications";
+
+ prefix "ex-not";
+
+ import Cisco-IOS-XR-ip-static-cfg { prefix "ip-static-cfg"; }
+
+ description
+ "Sample model used for notification utilization demonstration.
+ This model is not used by XR or any other netconf server.";
+
+ revision "2015-06-11" {
+ description
+ "Initial revision.";
+ }
+
+ notification vrf-route-notification {
+ uses ip-static-cfg:VRF-PREFIX-TABLE;
+ description "Artificial notification based on Cisco-IOS-XR-ip-static-cfg model";
+ }
+
+
+}
\ No newline at end of file
</properties>
<modules>
+ <module>netconf-test-perf</module>
<module>netconf-testtool</module>
</modules>
</project>