HC2VPP-313: <copy-config> examples using nnclient library 17/12317/2
authorMarek Gradzki <[email protected]>
Wed, 18 Apr 2018 06:19:36 +0000 (08:19 +0200)
committerMarek Gradzki <[email protected]>
Wed, 2 May 2018 10:00:35 +0000 (10:00 +0000)
Shows how to configure VPP using nnclient library.

Requires following changes to ODL Netconf (HC2VPP-312):
- <copy-config> support:
  https://git.opendaylight.org/gerrit/#/c/69606/
- various fixes to make ODL Netconf compatible with nnclient:
  https://git.opendaylight.org/gerrit/#/c/71181/

and ncclient library with the following change:
https://github.com/marekgr/ncclient/commit/fbc31b06daf114c11dcb6bf1bcfac9127b2e0062

Change-Id: I3dceb8ead6e6f558a3c76f6c1c3b0ba5f7c52f93
Signed-off-by: Marek Gradzki <[email protected]>
(cherry picked from commit 2e96f3423a2619cd2aa9d188de513723416c15e6)

18 files changed:
examples/ncclient/Readme.txt [new file with mode: 0644]
examples/ncclient/acl/copy_config_acl.xml [new file with mode: 0644]
examples/ncclient/acl/copy_config_acl_update.xml [new file with mode: 0644]
examples/ncclient/acl/expected_config_acl.xml [new file with mode: 0644]
examples/ncclient/acl/expected_config_acl_update.xml [new file with mode: 0644]
examples/ncclient/acl/test_acl.sh [new file with mode: 0755]
examples/ncclient/acl/test_acl_update.sh [new file with mode: 0755]
examples/ncclient/copy_config.py [new file with mode: 0755]
examples/ncclient/get.py [new file with mode: 0755]
examples/ncclient/get_config.py [new file with mode: 0755]
examples/ncclient/nat/copy_config_nat.xml [new file with mode: 0644]
examples/ncclient/nat/copy_config_nat_update.xml [new file with mode: 0644]
examples/ncclient/nat/expected_config_nat.xml [new file with mode: 0644]
examples/ncclient/nat/expected_config_nat_update.xml [new file with mode: 0644]
examples/ncclient/nat/test_nat.sh [new file with mode: 0755]
examples/ncclient/nat/test_nat_update.sh [new file with mode: 0755]
examples/ncclient/test_copy_config.sh [new file with mode: 0755]
examples/ncclient/xmldiffs.py [new file with mode: 0755]

diff --git a/examples/ncclient/Readme.txt b/examples/ncclient/Readme.txt
new file mode 100644 (file)
index 0000000..7e1c540
--- /dev/null
@@ -0,0 +1,41 @@
+Building
+----------
+
+1) Custom ODL Oxygen build:
+git clone https://git.opendaylight.org/gerrit/netconf
+cd netconf
+git checkout -b honeycomb
+git reset --hard release/oxygen
+# copy-config support:
+git fetch https://git.opendaylight.org/gerrit/netconf refs/changes/06/69606/1 && git cherry-pick FETCH_HEAD
+# ncclient support:
+git fetch https://git.opendaylight.org/gerrit/netconf refs/changes/81/71181/1 && git cherry-pick FETCH_HEAD
+mvn clean install -pl netconf/netconf-util,netconf/netconf-netty-util,netconf/mdsal-netconf-connector
+
+2) Build vpp-integration module from hc2vpp project:
+cd hc2vpp
+mvn clean install -pl vpp-integration/minimal-distribution
+
+3) (optional) Build honeycomb package
+./packaging/deb/xenial/debuild.sh
+
+4) Build ncclient
+git clone -b honeycomb https://github.com/marekgr/ncclient.git
+cd ncclient
+sudo python setup.py install
+
+
+Running examples
+----------
+
+ACL:
+./acl/test_acl.sh
+./acl/test_acl_updates.sh
+
+NAT:
+./acl/test_nat.sh
+./acl/test_nat_updates.sh
+
+Suggestions:
+Remember that HC by default persists config and restores it after restart.
+You can disable this behaviour using config/honeycomb.json.
diff --git a/examples/ncclient/acl/copy_config_acl.xml b/examples/ncclient/acl/copy_config_acl.xml
new file mode 100644 (file)
index 0000000..d2177d6
--- /dev/null
@@ -0,0 +1,182 @@
+<!--
+  ~ Copyright (c) 2018 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
+  -->
+<config>
+    <nat-config xmlns="urn:ietf:params:xml:ns:yang:ietf-nat">
+        <nat-instances>
+            <nat-instance>
+                <id>0</id>
+            </nat-instance>
+        </nat-instances>
+    </nat-config>
+    <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
+        <interface>
+            <name>local0</name>
+            <type xmlns:x="urn:ietf:params:xml:ns:yang:iana-if-type">x:ethernetCsmacd</type>
+            <enabled>false</enabled>
+        </interface>
+        <interface>
+            <name>loop1</name>
+            <description>for testing purposes</description>
+            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
+            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+                <mac>00:ff:ff:ff:ff:ff</mac>
+            </loopback>
+            <acl xmlns="urn:opendaylight:params:xml:ns:yang:interface:acl">
+                <ingress>
+                    <vpp-acls>
+                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</type>
+                        <name>tcp-acl</name>
+                    </vpp-acls>
+                    <vpp-acls>
+                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</type>
+                        <name>udp-acl</name>
+                    </vpp-acls>
+                    <vpp-macip-acl>
+                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-macip-acl</type>
+                        <name>macip-acl</name>
+                    </vpp-macip-acl>
+                </ingress>
+            </acl>
+        </interface>
+    </interfaces>
+    <access-lists xmlns="urn:ietf:params:xml:ns:yang:ietf-access-control-list">
+        <acl>
+            <acl-name>macip-acl</acl-name>
+            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-macip-acl</acl-type>
+            <access-list-entries>
+                <ace>
+                    <rule-name>macip-rule</rule-name>
+                    <matches>
+                        <vpp-macip-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
+                            <source-mac-address>aa:aa:aa:aa:aa:aa</source-mac-address>
+                            <source-mac-address-mask>ff:00:00:00:00:00</source-mac-address-mask>
+                        </vpp-macip-ace-nodes>
+                    </matches>
+                    <actions>
+                        <permit/>
+                    </actions>
+                </ace>
+            </access-list-entries>
+        </acl>
+        <acl>
+            <acl-name>icmp-v6-acl</acl-name>
+            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
+            <access-list-entries>
+                <ace>
+                    <rule-name>imcp-v6-rule</rule-name>
+                    <matches>
+                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                            <destination-ipv6-network>2001:0db8:0a0b:12f0:0000:0000:0000:0001/64</destination-ipv6-network>
+                            <source-ipv6-network>2001:0db8:0a0b:12f0:0000:0000:0000:0002/48</source-ipv6-network>
+                            <icmp-v6-nodes>
+                                <icmp-type-range>
+                                    <last>8</last>
+                                    <first>5</first>
+                                </icmp-type-range>
+                                <icmp-code-range>
+                                    <last>3</last>
+                                    <first>1</first>
+                                </icmp-code-range>
+                            </icmp-v6-nodes>
+                        </vpp-ace-nodes>
+                    </matches>
+                    <actions>
+                        <permit/>
+                    </actions>
+                </ace>
+            </access-list-entries>
+        </acl>
+        <acl>
+            <acl-name>udp-acl</acl-name>
+            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
+            <access-list-entries>
+                <ace>
+                    <rule-name>udp-rule</rule-name>
+                    <matches>
+                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
+                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
+                            <udp-nodes>
+                                <source-port-range>
+                                    <upper-port>5487</upper-port>
+                                    <lower-port>1</lower-port>
+                                </source-port-range>
+                                <destination-port-range>
+                                    <upper-port>6745</upper-port>
+                                    <lower-port>87</lower-port>
+                                </destination-port-range>
+                            </udp-nodes>
+                        </vpp-ace-nodes>
+                    </matches>
+                    <actions>
+                        <permit/>
+                    </actions>
+                </ace>
+            </access-list-entries>
+        </acl>
+        <acl>
+            <acl-name>tcp-acl</acl-name>
+            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
+            <access-list-entries>
+                <ace>
+                    <rule-name>tcp-rule</rule-name>
+                    <matches>
+                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
+                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
+                            <tcp-nodes>
+                                <source-port-range>
+                                    <upper-port>5487</upper-port>
+                                    <lower-port>1</lower-port>
+                                </source-port-range>
+                                <destination-port-range>
+                                    <upper-port>6745</upper-port>
+                                    <lower-port>87</lower-port>
+                                </destination-port-range>
+                                <tcp-flags-mask>1</tcp-flags-mask>
+                                <tcp-flags-value>7</tcp-flags-value>
+                            </tcp-nodes>
+                        </vpp-ace-nodes>
+                    </matches>
+                    <actions>
+                        <permit/>
+                    </actions>
+                </ace>
+            </access-list-entries>
+        </acl>
+        <acl>
+            <acl-name>icmp-acl</acl-name>
+            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
+            <access-list-entries>
+                <ace>
+                    <rule-name>imcp-rule</rule-name>
+                    <matches>
+                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
+                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
+                            <icmp-nodes>
+                                <icmp-type-range>
+                                    <last>8</last>
+                                    <first>5</first>
+                                </icmp-type-range>
+                                <icmp-code-range>
+                                    <last>3</last>
+                                    <first>1</first>
+                                </icmp-code-range>
+                            </icmp-nodes>
+                        </vpp-ace-nodes>
+                    </matches>
+                    <actions>
+                        <permit/>
+                    </actions>
+                </ace>
+            </access-list-entries>
+        </acl>
+    </access-lists>
+</config>
diff --git a/examples/ncclient/acl/copy_config_acl_update.xml b/examples/ncclient/acl/copy_config_acl_update.xml
new file mode 100644 (file)
index 0000000..1a30ece
--- /dev/null
@@ -0,0 +1,209 @@
+<!--
+  ~ Copyright (c) 2018 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
+  -->
+<config>
+    <nat-config xmlns="urn:ietf:params:xml:ns:yang:ietf-nat">
+        <nat-instances>
+            <nat-instance>
+                <id>0</id>
+            </nat-instance>
+        </nat-instances>
+    </nat-config>
+    <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
+        <interface>
+            <name>local0</name>
+            <type xmlns:x="urn:ietf:params:xml:ns:yang:iana-if-type">x:ethernetCsmacd</type>
+            <enabled>false</enabled>
+        </interface>
+        <interface>
+            <name>loop1</name>
+            <description>for testing purposes</description>
+            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
+            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+                <mac>00:ff:ff:ff:ff:ff</mac>
+            </loopback>
+            <acl xmlns="urn:opendaylight:params:xml:ns:yang:interface:acl">
+                <ingress>
+                    <vpp-macip-acl>
+                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-macip-acl</type>
+                        <name>macip-acl</name>
+                    </vpp-macip-acl>
+                </ingress>
+            </acl>
+        </interface>
+        <interface>
+            <name>loop2</name>
+            <description>for testing purposes</description>
+            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
+            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+                <mac>aa:ff:ff:ff:ff:ff</mac>
+            </loopback>
+            <acl xmlns="urn:opendaylight:params:xml:ns:yang:interface:acl">
+                <ingress>
+                    <vpp-acls>
+                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</type>
+                        <name>tcp-acl2</name>
+                    </vpp-acls>
+                    <vpp-acls>
+                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</type>
+                        <name>udp-acl</name>
+                    </vpp-acls>
+                </ingress>
+            </acl>
+        </interface>
+    </interfaces>
+    <access-lists xmlns="urn:ietf:params:xml:ns:yang:ietf-access-control-list">
+        <acl>
+            <acl-name>macip-acl</acl-name>
+            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-macip-acl</acl-type>
+            <access-list-entries>
+                <ace>
+                    <rule-name>macip-rule</rule-name>
+                    <matches>
+                        <vpp-macip-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
+                            <source-mac-address>aa:aa:aa:aa:aa:aa</source-mac-address>
+                            <source-mac-address-mask>ff:00:00:00:00:00</source-mac-address-mask>
+                        </vpp-macip-ace-nodes>
+                    </matches>
+                    <actions>
+                        <permit/>
+                    </actions>
+                </ace>
+            </access-list-entries>
+        </acl>
+        <acl>
+            <acl-name>icmp-v6-acl</acl-name>
+            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
+            <access-list-entries>
+                <ace>
+                    <rule-name>imcp-v6-rule</rule-name>
+                    <matches>
+                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                            <destination-ipv6-network>2001:0db8:0a0b:12f0:0000:0000:0000:0001/64
+                            </destination-ipv6-network>
+                            <source-ipv6-network>2001:0db8:0a0b:12f0:0000:0000:0000:0002/48</source-ipv6-network>
+                            <icmp-v6-nodes>
+                                <icmp-type-range>
+                                    <last>8</last>
+                                    <first>5</first>
+                                </icmp-type-range>
+                                <icmp-code-range>
+                                    <last>3</last>
+                                    <first>1</first>
+                                </icmp-code-range>
+                            </icmp-v6-nodes>
+                        </vpp-ace-nodes>
+                    </matches>
+                    <actions>
+                        <permit/>
+                    </actions>
+                </ace>
+            </access-list-entries>
+        </acl>
+        <acl>
+            <acl-name>udp-acl</acl-name>
+            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
+            <access-list-entries>
+                <ace>
+                    <rule-name>udp-rule</rule-name>
+                    <matches>
+                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
+                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
+                            <udp-nodes>
+                                <source-port-range>
+                                    <upper-port>5486</upper-port>
+                                    <lower-port>11</lower-port>
+                                </source-port-range>
+                            </udp-nodes>
+                        </vpp-ace-nodes>
+                    </matches>
+                    <actions>
+                        <permit/>
+                    </actions>
+                </ace>
+            </access-list-entries>
+        </acl>
+        <acl>
+            <acl-name>tcp-acl2</acl-name>
+            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
+            <access-list-entries>
+                <ace>
+                    <rule-name>tcp-rule</rule-name>
+                    <matches>
+                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
+                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
+                            <tcp-nodes>
+                                <source-port-range>
+                                    <upper-port>5487</upper-port>
+                                    <lower-port>1</lower-port>
+                                </source-port-range>
+                                <destination-port-range>
+                                    <upper-port>6745</upper-port>
+                                    <lower-port>87</lower-port>
+                                </destination-port-range>
+                                <tcp-flags-mask>1</tcp-flags-mask>
+                                <tcp-flags-value>7</tcp-flags-value>
+                            </tcp-nodes>
+                        </vpp-ace-nodes>
+                    </matches>
+                    <actions>
+                        <permit/>
+                    </actions>
+                </ace>
+            </access-list-entries>
+        </acl>
+        <acl>
+            <acl-name>icmp-acl</acl-name>
+            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
+            <access-list-entries>
+                <ace>
+                    <rule-name>renamed-imcp-rule</rule-name>
+                    <matches>
+                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
+                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
+                            <icmp-nodes>
+                                <icmp-type-range>
+                                    <last>8</last>
+                                    <first>5</first>
+                                </icmp-type-range>
+                                <icmp-code-range>
+                                    <last>3</last>
+                                    <first>1</first>
+                                </icmp-code-range>
+                            </icmp-nodes>
+                        </vpp-ace-nodes>
+                    </matches>
+                    <actions>
+                        <permit/>
+                    </actions>
+                </ace>
+                <ace>
+                    <rule-name>new-icmp-rule</rule-name>
+                    <matches>
+                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                            <destination-ipv4-network>10.1.1.1/24</destination-ipv4-network>
+                            <source-ipv4-network>10.2.2.2/32</source-ipv4-network>
+                            <icmp-nodes>
+                                <icmp-type-range>
+                                    <first>4</first>
+                                    <last>9</last>
+                                </icmp-type-range>
+                            </icmp-nodes>
+                        </vpp-ace-nodes>
+                    </matches>
+                    <actions>
+                        <permit/>
+                    </actions>
+                </ace>
+            </access-list-entries>
+        </acl>
+    </access-lists>
+</config>
diff --git a/examples/ncclient/acl/expected_config_acl.xml b/examples/ncclient/acl/expected_config_acl.xml
new file mode 100644 (file)
index 0000000..735e0f4
--- /dev/null
@@ -0,0 +1,183 @@
+<!--
+  ~ Copyright (c) 2018 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
+  -->
+<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <nat-config xmlns="urn:ietf:params:xml:ns:yang:ietf-nat">
+        <nat-instances>
+            <nat-instance>
+                <id>0</id>
+            </nat-instance>
+        </nat-instances>
+    </nat-config>
+    <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
+        <interface>
+            <name>local0</name>
+            <type xmlns:x="urn:ietf:params:xml:ns:yang:iana-if-type">x:ethernetCsmacd</type>
+            <enabled>false</enabled>
+        </interface>
+        <interface>
+            <name>loop1</name>
+            <description>for testing purposes</description>
+            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
+            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+                <mac>00:ff:ff:ff:ff:ff</mac>
+            </loopback>
+            <acl xmlns="urn:opendaylight:params:xml:ns:yang:interface:acl">
+                <ingress>
+                    <vpp-acls>
+                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</type>
+                        <name>tcp-acl</name>
+                    </vpp-acls>
+                    <vpp-acls>
+                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</type>
+                        <name>udp-acl</name>
+                    </vpp-acls>
+                    <vpp-macip-acl>
+                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-macip-acl</type>
+                        <name>macip-acl</name>
+                    </vpp-macip-acl>
+                </ingress>
+            </acl>
+        </interface>
+    </interfaces>
+    <access-lists xmlns="urn:ietf:params:xml:ns:yang:ietf-access-control-list">
+        <acl>
+            <acl-name>macip-acl</acl-name>
+            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-macip-acl</acl-type>
+            <access-list-entries>
+                <ace>
+                    <rule-name>macip-rule</rule-name>
+                    <matches>
+                        <vpp-macip-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
+                            <source-mac-address>aa:aa:aa:aa:aa:aa</source-mac-address>
+                            <source-mac-address-mask>ff:00:00:00:00:00</source-mac-address-mask>
+                        </vpp-macip-ace-nodes>
+                    </matches>
+                    <actions>
+                        <permit/>
+                    </actions>
+                </ace>
+            </access-list-entries>
+        </acl>
+        <acl>
+            <acl-name>icmp-v6-acl</acl-name>
+            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
+            <access-list-entries>
+                <ace>
+                    <rule-name>imcp-v6-rule</rule-name>
+                    <matches>
+                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                            <destination-ipv6-network>2001:0db8:0a0b:12f0:0000:0000:0000:0001/64
+                            </destination-ipv6-network>
+                            <source-ipv6-network>2001:0db8:0a0b:12f0:0000:0000:0000:0002/48</source-ipv6-network>
+                            <icmp-v6-nodes>
+                                <icmp-type-range>
+                                    <last>8</last>
+                                    <first>5</first>
+                                </icmp-type-range>
+                                <icmp-code-range>
+                                    <last>3</last>
+                                    <first>1</first>
+                                </icmp-code-range>
+                            </icmp-v6-nodes>
+                        </vpp-ace-nodes>
+                    </matches>
+                    <actions>
+                        <permit/>
+                    </actions>
+                </ace>
+            </access-list-entries>
+        </acl>
+        <acl>
+            <acl-name>udp-acl</acl-name>
+            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
+            <access-list-entries>
+                <ace>
+                    <rule-name>udp-rule</rule-name>
+                    <matches>
+                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
+                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
+                            <udp-nodes>
+                                <source-port-range>
+                                    <upper-port>5487</upper-port>
+                                    <lower-port>1</lower-port>
+                                </source-port-range>
+                                <destination-port-range>
+                                    <upper-port>6745</upper-port>
+                                    <lower-port>87</lower-port>
+                                </destination-port-range>
+                            </udp-nodes>
+                        </vpp-ace-nodes>
+                    </matches>
+                    <actions>
+                        <permit/>
+                    </actions>
+                </ace>
+            </access-list-entries>
+        </acl>
+        <acl>
+            <acl-name>tcp-acl</acl-name>
+            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
+            <access-list-entries>
+                <ace>
+                    <rule-name>tcp-rule</rule-name>
+                    <matches>
+                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
+                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
+                            <tcp-nodes>
+                                <source-port-range>
+                                    <upper-port>5487</upper-port>
+                                    <lower-port>1</lower-port>
+                                </source-port-range>
+                                <destination-port-range>
+                                    <upper-port>6745</upper-port>
+                                    <lower-port>87</lower-port>
+                                </destination-port-range>
+                                <tcp-flags-mask>1</tcp-flags-mask>
+                                <tcp-flags-value>7</tcp-flags-value>
+                            </tcp-nodes>
+                        </vpp-ace-nodes>
+                    </matches>
+                    <actions>
+                        <permit/>
+                    </actions>
+                </ace>
+            </access-list-entries>
+        </acl>
+        <acl>
+            <acl-name>icmp-acl</acl-name>
+            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
+            <access-list-entries>
+                <ace>
+                    <rule-name>imcp-rule</rule-name>
+                    <matches>
+                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
+                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
+                            <icmp-nodes>
+                                <icmp-type-range>
+                                    <last>8</last>
+                                    <first>5</first>
+                                </icmp-type-range>
+                                <icmp-code-range>
+                                    <last>3</last>
+                                    <first>1</first>
+                                </icmp-code-range>
+                            </icmp-nodes>
+                        </vpp-ace-nodes>
+                    </matches>
+                    <actions>
+                        <permit/>
+                    </actions>
+                </ace>
+            </access-list-entries>
+        </acl>
+    </access-lists>
+</data>
diff --git a/examples/ncclient/acl/expected_config_acl_update.xml b/examples/ncclient/acl/expected_config_acl_update.xml
new file mode 100644 (file)
index 0000000..17f76ff
--- /dev/null
@@ -0,0 +1,209 @@
+<!--
+  ~ Copyright (c) 2018 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
+  -->
+<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <nat-config xmlns="urn:ietf:params:xml:ns:yang:ietf-nat">
+        <nat-instances>
+            <nat-instance>
+                <id>0</id>
+            </nat-instance>
+        </nat-instances>
+    </nat-config>
+    <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
+        <interface>
+            <name>local0</name>
+            <type xmlns:x="urn:ietf:params:xml:ns:yang:iana-if-type">x:ethernetCsmacd</type>
+            <enabled>false</enabled>
+        </interface>
+        <interface>
+            <name>loop1</name>
+            <description>for testing purposes</description>
+            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
+            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+                <mac>00:ff:ff:ff:ff:ff</mac>
+            </loopback>
+            <acl xmlns="urn:opendaylight:params:xml:ns:yang:interface:acl">
+                <ingress>
+                    <vpp-macip-acl>
+                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-macip-acl</type>
+                        <name>macip-acl</name>
+                    </vpp-macip-acl>
+                </ingress>
+            </acl>
+        </interface>
+        <interface>
+            <name>loop2</name>
+            <description>for testing purposes</description>
+            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
+            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+                <mac>aa:ff:ff:ff:ff:ff</mac>
+            </loopback>
+            <acl xmlns="urn:opendaylight:params:xml:ns:yang:interface:acl">
+                <ingress>
+                    <vpp-acls>
+                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</type>
+                        <name>tcp-acl2</name>
+                    </vpp-acls>
+                    <vpp-acls>
+                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</type>
+                        <name>udp-acl</name>
+                    </vpp-acls>
+                </ingress>
+            </acl>
+        </interface>
+    </interfaces>
+    <access-lists xmlns="urn:ietf:params:xml:ns:yang:ietf-access-control-list">
+        <acl>
+            <acl-name>macip-acl</acl-name>
+            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-macip-acl</acl-type>
+            <access-list-entries>
+                <ace>
+                    <rule-name>macip-rule</rule-name>
+                    <matches>
+                        <vpp-macip-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
+                            <source-mac-address>aa:aa:aa:aa:aa:aa</source-mac-address>
+                            <source-mac-address-mask>ff:00:00:00:00:00</source-mac-address-mask>
+                        </vpp-macip-ace-nodes>
+                    </matches>
+                    <actions>
+                        <permit/>
+                    </actions>
+                </ace>
+            </access-list-entries>
+        </acl>
+        <acl>
+            <acl-name>icmp-v6-acl</acl-name>
+            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
+            <access-list-entries>
+                <ace>
+                    <rule-name>imcp-v6-rule</rule-name>
+                    <matches>
+                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                            <destination-ipv6-network>2001:0db8:0a0b:12f0:0000:0000:0000:0001/64
+                            </destination-ipv6-network>
+                            <source-ipv6-network>2001:0db8:0a0b:12f0:0000:0000:0000:0002/48</source-ipv6-network>
+                            <icmp-v6-nodes>
+                                <icmp-type-range>
+                                    <last>8</last>
+                                    <first>5</first>
+                                </icmp-type-range>
+                                <icmp-code-range>
+                                    <last>3</last>
+                                    <first>1</first>
+                                </icmp-code-range>
+                            </icmp-v6-nodes>
+                        </vpp-ace-nodes>
+                    </matches>
+                    <actions>
+                        <permit/>
+                    </actions>
+                </ace>
+            </access-list-entries>
+        </acl>
+        <acl>
+            <acl-name>udp-acl</acl-name>
+            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
+            <access-list-entries>
+                <ace>
+                    <rule-name>udp-rule</rule-name>
+                    <matches>
+                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
+                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
+                            <udp-nodes>
+                                <source-port-range>
+                                    <upper-port>5486</upper-port>
+                                    <lower-port>11</lower-port>
+                                </source-port-range>
+                            </udp-nodes>
+                        </vpp-ace-nodes>
+                    </matches>
+                    <actions>
+                        <permit/>
+                    </actions>
+                </ace>
+            </access-list-entries>
+        </acl>
+        <acl>
+            <acl-name>tcp-acl2</acl-name>
+            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
+            <access-list-entries>
+                <ace>
+                    <rule-name>tcp-rule</rule-name>
+                    <matches>
+                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
+                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
+                            <tcp-nodes>
+                                <source-port-range>
+                                    <upper-port>5487</upper-port>
+                                    <lower-port>1</lower-port>
+                                </source-port-range>
+                                <destination-port-range>
+                                    <upper-port>6745</upper-port>
+                                    <lower-port>87</lower-port>
+                                </destination-port-range>
+                                <tcp-flags-mask>1</tcp-flags-mask>
+                                <tcp-flags-value>7</tcp-flags-value>
+                            </tcp-nodes>
+                        </vpp-ace-nodes>
+                    </matches>
+                    <actions>
+                        <permit/>
+                    </actions>
+                </ace>
+            </access-list-entries>
+        </acl>
+        <acl>
+            <acl-name>icmp-acl</acl-name>
+            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
+            <access-list-entries>
+                <ace>
+                    <rule-name>renamed-imcp-rule</rule-name>
+                    <matches>
+                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
+                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
+                            <icmp-nodes>
+                                <icmp-type-range>
+                                    <last>8</last>
+                                    <first>5</first>
+                                </icmp-type-range>
+                                <icmp-code-range>
+                                    <last>3</last>
+                                    <first>1</first>
+                                </icmp-code-range>
+                            </icmp-nodes>
+                        </vpp-ace-nodes>
+                    </matches>
+                    <actions>
+                        <permit/>
+                    </actions>
+                </ace>
+                <ace>
+                    <rule-name>new-icmp-rule</rule-name>
+                    <matches>
+                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                            <destination-ipv4-network>10.1.1.1/24</destination-ipv4-network>
+                            <source-ipv4-network>10.2.2.2/32</source-ipv4-network>
+                            <icmp-nodes>
+                                <icmp-type-range>
+                                    <first>4</first>
+                                    <last>9</last>
+                                </icmp-type-range>
+                            </icmp-nodes>
+                        </vpp-ace-nodes>
+                    </matches>
+                    <actions>
+                        <permit/>
+                    </actions>
+                </ace>
+            </access-list-entries>
+        </acl>
+    </access-lists>
+</data>
diff --git a/examples/ncclient/acl/test_acl.sh b/examples/ncclient/acl/test_acl.sh
new file mode 100755 (executable)
index 0000000..aedb842
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/bash
+#
+# Copyright (c) 2018 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+DIR_NAME=$(dirname $0)
+
+${DIR_NAME}/../test_copy_config.sh ${DIR_NAME}/copy_config_acl.xml ${DIR_NAME}/expected_config_acl.xml
diff --git a/examples/ncclient/acl/test_acl_update.sh b/examples/ncclient/acl/test_acl_update.sh
new file mode 100755 (executable)
index 0000000..6dedbfe
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/bash
+#
+# Copyright (c) 2018 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+DIR_NAME=$(dirname $0)
+
+${DIR_NAME}/../test_copy_config.sh ${DIR_NAME}/copy_config_acl.xml ${DIR_NAME}/expected_config_acl.xml
+
+${DIR_NAME}/../test_copy_config.sh ${DIR_NAME}/copy_config_acl_update.xml ${DIR_NAME}/expected_config_acl_update.xml
diff --git a/examples/ncclient/copy_config.py b/examples/ncclient/copy_config.py
new file mode 100755 (executable)
index 0000000..e2e95c6
--- /dev/null
@@ -0,0 +1,39 @@
+#!/usr/bin/env python2
+#
+# Copyright (c) 2018 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import argparse
+import logging
+from ncclient import manager
+
+_SOURCE_TEMPLATE = """<source xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">%s</source>"""
+
+
+def _copy_config(config_filename, host='localhost', port=2831, username='admin', password='admin'):
+    with manager.connect(host=host, port=port, username=username, password=password, hostkey_verify=False) as m:
+        logger.info("Connected to HC")
+        with open(config_filename, 'r') as f:
+            ret = m.copy_config(target='candidate', source=_SOURCE_TEMPLATE % f.read())
+            logger.debug("CopyConfig successful:\n%s" % ret)
+        ret = m.commit()
+        logger.debug("Commit successful:\n%s", ret)
+
+
+if __name__ == '__main__':
+    logger = logging.getLogger("hc2vpp.examples.copy_config")
+    logging.basicConfig(level=logging.WARNING)
+    argparser = argparse.ArgumentParser(description="Configures VPP using <copy-config> RPC")
+    argparser.add_argument('config_filename', help="name of XML file with <config> element")
+    args = argparser.parse_args()
+    _copy_config(args.config_filename)
diff --git a/examples/ncclient/get.py b/examples/ncclient/get.py
new file mode 100755 (executable)
index 0000000..9fe4ab8
--- /dev/null
@@ -0,0 +1,39 @@
+#!/usr/bin/env python2
+#
+# Copyright (c) 2018 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import argparse
+import logging
+from ncclient import manager
+
+
+def _get(reply_filename=None, host='localhost', port=2831, username='admin', password='admin'):
+    with manager.connect(host=host, port=port, username=username, password=password, hostkey_verify=False) as m:
+        logger.info("Connected to HC")
+        state = m.get()
+        logger.debug("Get successful:\n%s" % state)
+        if reply_filename:
+            with open(reply_filename, 'w') as f:
+                f.write(state.data_xml)
+        else:
+            print state.data_xml
+
+
+if __name__ == '__main__':
+    logger = logging.getLogger("hc2vpp.examples.get")
+    logging.basicConfig(level=logging.WARNING)
+    argparser = argparse.ArgumentParser(description="Obtains VPP state data using <get> RPC")
+    argparser.add_argument('--reply_filename', help="name of XML file to store received state data")
+    args = argparser.parse_args()
+    _get(args.reply_filename)
diff --git a/examples/ncclient/get_config.py b/examples/ncclient/get_config.py
new file mode 100755 (executable)
index 0000000..5fdb6da
--- /dev/null
@@ -0,0 +1,39 @@
+#!/usr/bin/env python2
+#
+# Copyright (c) 2018 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import argparse
+import logging
+from ncclient import manager
+
+
+def _get_config(reply_filename=None, host='localhost', port=2831, username='admin', password='admin'):
+    with manager.connect(host=host, port=port, username=username, password=password, hostkey_verify=False) as m:
+        logger.info("Connected to HC")
+        config = m.get_config(source='running')
+        logger.debug("GetConfig successful:\n%s" % config)
+        if reply_filename:
+            with open(reply_filename, 'w') as f:
+                f.write(config.data_xml)
+        else:
+            print config.data_xml
+
+
+if __name__ == '__main__':
+    logger = logging.getLogger("hc2vpp.examples.get_config")
+    logging.basicConfig(level=logging.WARNING)
+    argparser = argparse.ArgumentParser(description="Obtains VPP configuration using <get-config> RPC")
+    argparser.add_argument('--reply_filename', help="name of XML file to store received configuration")
+    args = argparser.parse_args()
+    _get_config(args.reply_filename)
diff --git a/examples/ncclient/nat/copy_config_nat.xml b/examples/ncclient/nat/copy_config_nat.xml
new file mode 100644 (file)
index 0000000..d1441b0
--- /dev/null
@@ -0,0 +1,82 @@
+<!--
+  ~ Copyright (c) 2018 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
+  -->
+<config>
+    <nat-config xmlns="urn:ietf:params:xml:ns:yang:ietf-nat">
+        <nat-instances>
+            <nat-instance>
+                <id>0</id>
+                <external-ip-address-pool>
+                    <pool-id>2</pool-id>
+                    <external-ip-pool>172.16.2.123/32</external-ip-pool>
+                </external-ip-address-pool>
+                <external-ip-address-pool>
+                    <pool-id>3</pool-id>
+                    <external-ip-pool>10.10.10.1/30</external-ip-pool>
+                    <pool-type xmlns="urn:opendaylight:params:xml:ns:yang:vpp:nat">nat64</pool-type>
+                </external-ip-address-pool>
+                <external-ip-address-pool>
+                    <pool-id>1</pool-id>
+                    <external-ip-pool>172.16.2.0/30</external-ip-pool>
+                </external-ip-address-pool>
+                <mapping-table>
+                    <mapping-entry>
+                        <index>1</index>
+                        <external-src-address>10.1.1.3</external-src-address>
+                        <type>static</type>
+                        <transport-protocol>6</transport-protocol>
+                        <external-src-port>
+                            <single-port-number>5678</single-port-number>
+                        </external-src-port>
+                        <internal-src-port>
+                            <single-port-number>1234</single-port-number>
+                        </internal-src-port>
+                        <internal-src-address>2001:db8:85a3::8a2e:370:7334</internal-src-address>
+                    </mapping-entry>
+                </mapping-table>
+                <nat64-prefixes>
+                    <nat64-prefix-id>0</nat64-prefix-id>
+                    <nat64-prefix>2001:db8:122:300::/56</nat64-prefix>
+                </nat64-prefixes>
+            </nat-instance>
+        </nat-instances>
+    </nat-config>
+    <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
+        <interface>
+            <name>local0</name>
+            <type xmlns:x="urn:ietf:params:xml:ns:yang:iana-if-type">x:ethernetCsmacd</type>
+            <enabled>false</enabled>
+        </interface>
+        <interface>
+            <name>loop1</name>
+            <description>for testing purposes</description>
+            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
+            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+                <mac>01:ff:ff:ff:ff:ff</mac>
+            </loopback>
+            <nat xmlns="urn:opendaylight:params:xml:ns:yang:interface:nat">
+                <outbound>
+                    <post-routing>true</post-routing>
+                </outbound>
+            </nat>
+        </interface>
+        <interface>
+            <name>loop0</name>
+            <description>for testing purposes</description>
+            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
+            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+                <mac>00:ff:ff:ff:ff:ff</mac>
+            </loopback>
+            <nat xmlns="urn:opendaylight:params:xml:ns:yang:interface:nat">
+                <inbound>
+                    <nat64-support>true</nat64-support>
+                    <nat44-support>false</nat44-support>
+                </inbound>
+            </nat>
+        </interface>
+    </interfaces>
+</config>
diff --git a/examples/ncclient/nat/copy_config_nat_update.xml b/examples/ncclient/nat/copy_config_nat_update.xml
new file mode 100644 (file)
index 0000000..6b346cf
--- /dev/null
@@ -0,0 +1,103 @@
+<!--
+  ~ Copyright (c) 2018 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
+  -->
+<config>
+    <nat-config xmlns="urn:ietf:params:xml:ns:yang:ietf-nat">
+        <nat-instances>
+            <nat-instance>
+                <id>0</id>
+                <external-ip-address-pool>
+                    <pool-id>2</pool-id>
+                    <external-ip-pool>172.15.2.123/32</external-ip-pool>
+                </external-ip-address-pool>
+                <external-ip-address-pool>
+                    <pool-id>3</pool-id>
+                    <external-ip-pool>10.10.10.1/30</external-ip-pool>
+                    <pool-type xmlns="urn:opendaylight:params:xml:ns:yang:vpp:nat">nat64</pool-type>
+                </external-ip-address-pool>
+                <external-ip-address-pool>
+                    <pool-id>5</pool-id>
+                    <external-ip-pool>172.16.2.0/30</external-ip-pool>
+                </external-ip-address-pool>
+                <external-ip-address-pool>
+                    <pool-id>6</pool-id>
+                    <external-ip-pool>1.2.3.4/32</external-ip-pool>
+                    <pool-type xmlns="urn:opendaylight:params:xml:ns:yang:vpp:nat">nat64</pool-type>
+                </external-ip-address-pool>
+                <mapping-table>
+                    <mapping-entry>
+                        <index>1</index>
+                        <external-src-address>10.1.1.3</external-src-address>
+                        <type>static</type>
+                        <transport-protocol>6</transport-protocol>
+                        <external-src-port>
+                            <single-port-number>5678</single-port-number>
+                        </external-src-port>
+                        <internal-src-port>
+                            <single-port-number>1234</single-port-number>
+                        </internal-src-port>
+                        <internal-src-address>2001:db8:85a3::8a2e:370:7334</internal-src-address>
+                    </mapping-entry>
+                </mapping-table>
+                <nat64-prefixes>
+                    <nat64-prefix-id>0</nat64-prefix-id>
+                    <nat64-prefix>2001:db8:122:300::/56</nat64-prefix>
+                </nat64-prefixes>
+            </nat-instance>
+        </nat-instances>
+    </nat-config>
+    <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
+        <interface>
+            <name>local0</name>
+            <type xmlns:x="urn:ietf:params:xml:ns:yang:iana-if-type">x:ethernetCsmacd</type>
+            <enabled>false</enabled>
+        </interface>
+        <interface>
+            <name>loop3</name>
+            <description>for testing purposes</description>
+            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
+            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+                <mac>03:ff:ff:ff:ff:ff</mac>
+            </loopback>
+            <nat xmlns="urn:opendaylight:params:xml:ns:yang:interface:nat">
+                <outbound>
+                    <post-routing>true</post-routing>
+                </outbound>
+            </nat>
+        </interface>
+        <interface>
+            <name>loop2</name>
+            <description>for testing purposes</description>
+            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
+            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+                <mac>02:ff:ff:ff:ff:ff</mac>
+            </loopback>
+            <nat xmlns="urn:opendaylight:params:xml:ns:yang:interface:nat">
+                <inbound>
+                    <nat64-support>true</nat64-support>
+                    <nat44-support>false</nat44-support>
+                </inbound>
+            </nat>
+        </interface>
+        <interface>
+            <name>loop1</name>
+            <description>for testing purposes</description>
+            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
+            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+                <mac>01:ff:ff:ff:ff:ff</mac>
+            </loopback>
+        </interface>
+        <interface>
+            <name>loop0</name>
+            <description>for testing purposes</description>
+            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
+            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+                <mac>00:ff:ff:ff:ff:ff</mac>
+            </loopback>
+        </interface>
+    </interfaces>
+</config>
diff --git a/examples/ncclient/nat/expected_config_nat.xml b/examples/ncclient/nat/expected_config_nat.xml
new file mode 100644 (file)
index 0000000..35a51bc
--- /dev/null
@@ -0,0 +1,82 @@
+<!--
+  ~ Copyright (c) 2018 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
+  -->
+<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <nat-config xmlns="urn:ietf:params:xml:ns:yang:ietf-nat">
+        <nat-instances>
+            <nat-instance>
+                <id>0</id>
+                <external-ip-address-pool>
+                    <pool-id>2</pool-id>
+                    <external-ip-pool>172.16.2.123/32</external-ip-pool>
+                </external-ip-address-pool>
+                <external-ip-address-pool>
+                    <pool-id>3</pool-id>
+                    <external-ip-pool>10.10.10.1/30</external-ip-pool>
+                    <pool-type xmlns="urn:opendaylight:params:xml:ns:yang:vpp:nat">nat64</pool-type>
+                </external-ip-address-pool>
+                <external-ip-address-pool>
+                    <pool-id>1</pool-id>
+                    <external-ip-pool>172.16.2.0/30</external-ip-pool>
+                </external-ip-address-pool>
+                <mapping-table>
+                    <mapping-entry>
+                        <index>1</index>
+                        <external-src-address>10.1.1.3</external-src-address>
+                        <type>static</type>
+                        <transport-protocol>6</transport-protocol>
+                        <external-src-port>
+                            <single-port-number>5678</single-port-number>
+                        </external-src-port>
+                        <internal-src-port>
+                            <single-port-number>1234</single-port-number>
+                        </internal-src-port>
+                        <internal-src-address>2001:db8:85a3::8a2e:370:7334</internal-src-address>
+                    </mapping-entry>
+                </mapping-table>
+                <nat64-prefixes>
+                    <nat64-prefix-id>0</nat64-prefix-id>
+                    <nat64-prefix>2001:db8:122:300::/56</nat64-prefix>
+                </nat64-prefixes>
+            </nat-instance>
+        </nat-instances>
+    </nat-config>
+    <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
+        <interface>
+            <name>local0</name>
+            <type xmlns:x="urn:ietf:params:xml:ns:yang:iana-if-type">x:ethernetCsmacd</type>
+            <enabled>false</enabled>
+        </interface>
+        <interface>
+            <name>loop1</name>
+            <description>for testing purposes</description>
+            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
+            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+                <mac>01:ff:ff:ff:ff:ff</mac>
+            </loopback>
+            <nat xmlns="urn:opendaylight:params:xml:ns:yang:interface:nat">
+                <outbound>
+                    <post-routing>true</post-routing>
+                </outbound>
+            </nat>
+        </interface>
+        <interface>
+            <name>loop0</name>
+            <description>for testing purposes</description>
+            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
+            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+                <mac>00:ff:ff:ff:ff:ff</mac>
+            </loopback>
+            <nat xmlns="urn:opendaylight:params:xml:ns:yang:interface:nat">
+                <inbound>
+                    <nat64-support>true</nat64-support>
+                    <nat44-support>false</nat44-support>
+                </inbound>
+            </nat>
+        </interface>
+    </interfaces>
+</data>
diff --git a/examples/ncclient/nat/expected_config_nat_update.xml b/examples/ncclient/nat/expected_config_nat_update.xml
new file mode 100644 (file)
index 0000000..41891e0
--- /dev/null
@@ -0,0 +1,103 @@
+<!--
+  ~ Copyright (c) 2018 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
+  -->
+<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <nat-config xmlns="urn:ietf:params:xml:ns:yang:ietf-nat">
+        <nat-instances>
+            <nat-instance>
+                <id>0</id>
+                <external-ip-address-pool>
+                    <pool-id>6</pool-id>
+                    <external-ip-pool>1.2.3.4/32</external-ip-pool>
+                    <pool-type xmlns="urn:opendaylight:params:xml:ns:yang:vpp:nat">nat64</pool-type>
+                </external-ip-address-pool>
+                <external-ip-address-pool>
+                    <pool-id>5</pool-id>
+                    <external-ip-pool>172.16.2.0/30</external-ip-pool>
+                </external-ip-address-pool>
+                <external-ip-address-pool>
+                    <pool-id>2</pool-id>
+                    <external-ip-pool>172.15.2.123/32</external-ip-pool>
+                </external-ip-address-pool>
+                <external-ip-address-pool>
+                    <pool-id>3</pool-id>
+                    <external-ip-pool>10.10.10.1/30</external-ip-pool>
+                    <pool-type xmlns="urn:opendaylight:params:xml:ns:yang:vpp:nat">nat64</pool-type>
+                </external-ip-address-pool>
+                <mapping-table>
+                    <mapping-entry>
+                        <index>1</index>
+                        <external-src-address>10.1.1.3</external-src-address>
+                        <type>static</type>
+                        <transport-protocol>6</transport-protocol>
+                        <external-src-port>
+                            <single-port-number>5678</single-port-number>
+                        </external-src-port>
+                        <internal-src-port>
+                            <single-port-number>1234</single-port-number>
+                        </internal-src-port>
+                        <internal-src-address>2001:db8:85a3::8a2e:370:7334</internal-src-address>
+                    </mapping-entry>
+                </mapping-table>
+                <nat64-prefixes>
+                    <nat64-prefix-id>0</nat64-prefix-id>
+                    <nat64-prefix>2001:db8:122:300::/56</nat64-prefix>
+                </nat64-prefixes>
+            </nat-instance>
+        </nat-instances>
+    </nat-config>
+    <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
+        <interface>
+            <name>local0</name>
+            <type xmlns:x="urn:ietf:params:xml:ns:yang:iana-if-type">x:ethernetCsmacd</type>
+            <enabled>false</enabled>
+        </interface>
+        <interface>
+            <name>loop1</name>
+            <description>for testing purposes</description>
+            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
+            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+                <mac>01:ff:ff:ff:ff:ff</mac>
+            </loopback>
+        </interface>
+        <interface>
+            <name>loop2</name>
+            <description>for testing purposes</description>
+            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
+            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+                <mac>02:ff:ff:ff:ff:ff</mac>
+            </loopback>
+            <nat xmlns="urn:opendaylight:params:xml:ns:yang:interface:nat">
+                <inbound>
+                    <nat64-support>true</nat64-support>
+                    <nat44-support>false</nat44-support>
+                </inbound>
+            </nat>
+        </interface>
+        <interface>
+            <name>loop3</name>
+            <description>for testing purposes</description>
+            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
+            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+                <mac>03:ff:ff:ff:ff:ff</mac>
+            </loopback>
+            <nat xmlns="urn:opendaylight:params:xml:ns:yang:interface:nat">
+                <outbound>
+                    <post-routing>true</post-routing>
+                </outbound>
+            </nat>
+        </interface>
+        <interface>
+            <name>loop0</name>
+            <description>for testing purposes</description>
+            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
+            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+                <mac>00:ff:ff:ff:ff:ff</mac>
+            </loopback>
+        </interface>
+    </interfaces>
+</data>
diff --git a/examples/ncclient/nat/test_nat.sh b/examples/ncclient/nat/test_nat.sh
new file mode 100755 (executable)
index 0000000..272a1d6
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/bash
+#
+# Copyright (c) 2018 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+DIR_NAME=$(dirname $0)
+
+${DIR_NAME}/../test_copy_config.sh ${DIR_NAME}/copy_config_nat.xml ${DIR_NAME}/expected_config_nat.xml
diff --git a/examples/ncclient/nat/test_nat_update.sh b/examples/ncclient/nat/test_nat_update.sh
new file mode 100755 (executable)
index 0000000..b37e4c6
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/bash
+#
+# Copyright (c) 2018 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+DIR_NAME=$(dirname $0)
+
+${DIR_NAME}/../test_copy_config.sh ${DIR_NAME}/copy_config_nat.xml ${DIR_NAME}/expected_config_nat.xml
+
+${DIR_NAME}/../test_copy_config.sh ${DIR_NAME}/copy_config_nat_update.xml ${DIR_NAME}/expected_config_nat_update.xml
diff --git a/examples/ncclient/test_copy_config.sh b/examples/ncclient/test_copy_config.sh
new file mode 100755 (executable)
index 0000000..2b751d5
--- /dev/null
@@ -0,0 +1,36 @@
+#!/bin/bash
+#
+# Copyright (c) 2018 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# $1 config element for <copy-config> RPC
+# $2 expected running config
+
+DIR_NAME=$(dirname $0)
+
+${DIR_NAME}/copy_config.py $1
+${DIR_NAME}/get_config.py --reply_filename _actual_config.xml
+
+# fixme: find better xml comparison tool
+# xmldiffs does not work well when difference occurs on deep level
+${DIR_NAME}/xmldiffs.py $2 _actual_config.xml
+ret_code=$?
+
+if [ $ret_code == 0 ]; then
+    echo "<copy-config> successful"
+    rm _actual_config.xml
+    exit 0
+fi
+
+echo "<copy-config> failed"
+exit 1
diff --git a/examples/ncclient/xmldiffs.py b/examples/ncclient/xmldiffs.py
new file mode 100755 (executable)
index 0000000..b78fa8f
--- /dev/null
@@ -0,0 +1,107 @@
+#!/usr/bin/env python
+"""
+Usage: {prog} [OPTION] FILE1 FILE2
+
+Compare two XML files, ignoring element and attribute order.
+
+Any extra options are passed to the `diff' command.
+
+Copyright (c) 2017, Johannes H. Jensen.
+License: BSD, see LICENSE for more details.
+"""
+from __future__ import print_function, unicode_literals
+import sys
+import os
+import io
+import xml.etree.ElementTree as ET
+from tempfile import NamedTemporaryFile
+import subprocess
+
+def attr_str(k, v):
+    return "{}=\"{}\"".format(k,v)
+
+def node_str(n):
+    attrs = sorted(n.attrib.items())
+    astr = " ".join(attr_str(k,v) for k,v in attrs)
+    s = n.tag
+    if astr:
+        s += " " + astr
+    return s
+
+def node_key(n):
+    return node_str(n)
+
+def indent(s, level):
+    return "  " * level + s
+
+def write_sorted(stream, node, level=0):
+    children = node.getchildren()
+    text = (node.text or "").strip()
+    tail = (node.tail or "").strip()
+
+    if children or text:
+        children.sort(key=node_key)
+
+        stream.write(indent("<" + node_str(node) + ">\n", level))
+
+        if text:
+            stream.write(indent(text + "\n", level))
+
+        for child in children:
+            write_sorted(stream, child, level + 1)
+
+        stream.write(indent("</" + node.tag + ">\n", level))
+    else:
+        stream.write(indent("<" + node_str(node) + "/>\n", level))
+
+    if tail:
+        stream.write(indent(tail + "\n", level))
+
+if sys.version_info < (3, 0):
+    # Python 2
+    import codecs
+    def unicode_writer(fp):
+        return codecs.getwriter('utf-8')(fp)
+else:
+    # Python 3
+    def unicode_writer(fp):
+        return fp
+
+def xmldiffs(file1, file2, diffargs=["-u"]):
+    tree = ET.parse(file1)
+    tmp1 = unicode_writer(NamedTemporaryFile('w'))
+    write_sorted(tmp1, tree.getroot())
+    tmp1.flush()
+
+    tree = ET.parse(file2)
+    tmp2 = unicode_writer(NamedTemporaryFile('w'))
+    write_sorted(tmp2, tree.getroot())
+    tmp2.flush()
+
+    args = [ "diff" ]
+    args += diffargs
+    args += [ "--label", file1, "--label", file2 ]
+    args += [ tmp1.name, tmp2.name ]
+
+    return subprocess.call(args)
+
+def print_usage(prog):
+    print(__doc__.format(prog=prog).strip())
+
+if __name__ == '__main__':
+    args = sys.argv
+    prog = os.path.basename(args.pop(0))
+
+    if '-h' in args or '--help' in args:
+        print_usage(prog)
+        exit(0)
+
+    if len(args) < 2:
+        print_usage(prog)
+        exit(1)
+
+    file2 = args.pop(-1)
+    file1 = args.pop(-1)
+    diffargs = args if args else ["-u"]
+
+    exit(xmldiffs(file1, file2, diffargs))