From 4782cee201cf862077b19b569413aa42f01c41d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Walstr=C3=B6m?= Date: Tue, 14 Jan 2025 14:10:57 +0100 Subject: [PATCH] Add support for simple VXLAN tunnels This is just a first step to add VXLAN tunnels, much more remains. Implemented right now is as GRE, local, remote and a VNI. Also refactor gre_basic and gre_bridged to generic tunnel tests, the same test now tests VXLAN as well. --- doc/ChangeLog.md | 3 +- doc/tunnels.md | 12 ++++ src/confd/src/Makefile.am | 3 +- src/confd/src/ietf-interfaces.c | 11 ++- src/confd/src/ietf-interfaces.h | 6 +- src/confd/src/infix-if-gre.c | 2 +- src/confd/src/infix-if-vxlan.c | 29 ++++++++ src/confd/yang/infix-if-bridge.yang | 3 +- src/confd/yang/infix-if-type.yang | 3 + src/confd/yang/infix-if-vxlan.yang | 54 ++++++++++++++ src/confd/yang/infix-if-vxlan@2025-01-13.yang | 1 + src/confd/yang/infix-interfaces.yang | 2 + test/case/ietf_interfaces/Readme.adoc | 4 +- .../gretap_bridged/Readme.adoc | 1 - .../gretap_bridged/gretap_bridged.adoc | 24 ------- .../case/ietf_interfaces/ietf_interfaces.yaml | 8 +-- .../{gre_basic => tunnel_basic}/Readme.adoc | 2 + .../gre_basic.adoc | 7 +- .../gretap_basic.adoc | 7 +- .../{gre_basic => tunnel_basic}/test.py | 70 ++++++++++++------- .../{gre_basic => tunnel_basic}/test.yaml | 6 ++ .../{gre_basic => tunnel_basic}/topology.dot | 0 .../{gre_basic => tunnel_basic}/topology.svg | 0 .../tunnel_basic/vxlan_basic.adoc | 26 +++++++ .../tunnel_bridged/Readme.adoc | 4 ++ .../tunnel_bridged/gretap_bridged.adoc | 24 +++++++ .../test.py | 66 ++++++++++------- .../ietf_interfaces/tunnel_bridged/test.yaml | 12 ++++ .../topology.dot | 0 .../topology.svg | 0 .../tunnel_bridged/vxlan_bridged.adoc | 24 +++++++ 31 files changed, 320 insertions(+), 94 deletions(-) create mode 100644 src/confd/src/infix-if-vxlan.c create mode 100644 src/confd/yang/infix-if-vxlan.yang create mode 120000 src/confd/yang/infix-if-vxlan@2025-01-13.yang delete mode 120000 test/case/ietf_interfaces/gretap_bridged/Readme.adoc delete mode 100644 test/case/ietf_interfaces/gretap_bridged/gretap_bridged.adoc rename test/case/ietf_interfaces/{gre_basic => tunnel_basic}/Readme.adoc (66%) rename test/case/ietf_interfaces/{gre_basic => tunnel_basic}/gre_basic.adoc (62%) rename test/case/ietf_interfaces/{gre_basic => tunnel_basic}/gretap_basic.adoc (62%) rename test/case/ietf_interfaces/{gre_basic => tunnel_basic}/test.py (80%) rename test/case/ietf_interfaces/{gre_basic => tunnel_basic}/test.yaml (66%) rename test/case/ietf_interfaces/{gre_basic => tunnel_basic}/topology.dot (100%) rename test/case/ietf_interfaces/{gre_basic => tunnel_basic}/topology.svg (100%) create mode 100644 test/case/ietf_interfaces/tunnel_basic/vxlan_basic.adoc create mode 100644 test/case/ietf_interfaces/tunnel_bridged/Readme.adoc create mode 100644 test/case/ietf_interfaces/tunnel_bridged/gretap_bridged.adoc rename test/case/ietf_interfaces/{gretap_bridged => tunnel_bridged}/test.py (62%) create mode 100644 test/case/ietf_interfaces/tunnel_bridged/test.yaml rename test/case/ietf_interfaces/{gretap_bridged => tunnel_bridged}/topology.dot (100%) rename test/case/ietf_interfaces/{gretap_bridged => tunnel_bridged}/topology.svg (100%) create mode 100644 test/case/ietf_interfaces/tunnel_bridged/vxlan_bridged.adoc diff --git a/doc/ChangeLog.md b/doc/ChangeLog.md index f176a5d1..fecdabc6 100644 --- a/doc/ChangeLog.md +++ b/doc/ChangeLog.md @@ -17,8 +17,9 @@ All notable changes to the project are documented in this file. RPC and add boot order to operational datastore. - SSH Server is now configurable, issue #441 SSH Server and NETCONF Server now uses the same SSH hostkey in factory-config - - Add support for GRE/GRETAP tunnels + - Support for GRE/GRETAP tunnels - Support for STP/RSTP on bridges + - Support for VXLAN tunnels ### Fixes diff --git a/doc/tunnels.md b/doc/tunnels.md index fc1ffc4a..70064519 100644 --- a/doc/tunnels.md +++ b/doc/tunnels.md @@ -14,3 +14,15 @@ admin@example:/config/interface/gre1/> set gre local 192.168.3.1 remote 192.168. admin@example:/config/interface/gre1/> leave admin@example:/> ``` + +## Virtual eXtensible Local Area Network (VXLAN) + +The support for VXLAN tunnels includes IPv4 and IPv6. + +``` +admin@example:/config/> edit interface vxlan100 +admin@example:/config/interface/vxlan100/> set vxlan local 192.168.3.1 +admin@example:/config/interface/vxlan100/> set vxlan remote 192.168.3.2 +admin@example:/config/interface/vxlan100/> set vxlan vni 100 +admin@example:/config/interface/vxlan100/> leave +``` diff --git a/src/confd/src/Makefile.am b/src/confd/src/Makefile.am index 101183d0..601340bb 100644 --- a/src/confd/src/Makefile.am +++ b/src/confd/src/Makefile.am @@ -34,7 +34,8 @@ confd_plugin_la_SOURCES = \ infix-if-bridge-port.c \ infix-if-veth.c \ infix-if-vlan.c \ - infix-if-gre.c \ + infix-if-gre.c \ + infix-if-vxlan.c \ ietf-keystore.c \ ietf-system.c \ ietf-syslog.c \ diff --git a/src/confd/src/ietf-interfaces.c b/src/confd/src/ietf-interfaces.c index 2ced2d96..5e02d1ad 100644 --- a/src/confd/src/ietf-interfaces.c +++ b/src/confd/src/ietf-interfaces.c @@ -91,7 +91,8 @@ static int ifchange_cand_infer_type(sr_session_ctx_t *session, const char *path) inferred.data.string_val = "infix-if-type:gre"; else if (!fnmatch("gretap+([0-9])", ifname, FNM_EXTMATCH)) inferred.data.string_val = "infix-if-type:gretap"; - + else if (!fnmatch("vxlan+([0-9])", ifname, FNM_EXTMATCH)) + inferred.data.string_val = "infix-if-type:vxlan"; free(ifname); if (inferred.data.string_val) @@ -401,6 +402,8 @@ static int netdag_gen_afspec_add(sr_session_ctx_t *session, struct dagger *net, return -ENOENT; } else if (!strcmp(iftype, "infix-if-type:gre") || !strcmp(iftype, "infix-if-type:gretap")) { err = gre_gen(net, NULL, cif, ip); + } else if (!strcmp(iftype, "infix-if-type:vxlan")) { + err = vxlan_gen(net, NULL, cif, ip); } else { sr_session_set_error_message(net->session, "%s: unsupported interface type \"%s\"", ifname, iftype); return -ENOSYS; @@ -428,7 +431,8 @@ static int netdag_gen_afspec_set(sr_session_ctx_t *session, struct dagger *net, return 0; if (!strcmp(iftype, "infix-if-type:gretap")) return 0; - + if (!strcmp(iftype, "infix-if-type:vxlan")) + return 0; ERROR("%s: unsupported interface type \"%s\"", ifname, iftype); return -ENOSYS; } @@ -462,6 +466,9 @@ static bool netdag_must_del(struct lyd_node *dif, struct lyd_node *cif) } else if (!strcmp(iftype, "infix-if-type:gre") || !strcmp(iftype, "infix-if-type:gretap")) { if (lydx_get_descendant(lyd_child(dif), "gre", NULL)) return true; + } else if (!strcmp(iftype, "infix-if-type:vxlan")) { + if (lydx_get_descendant(lyd_child(dif), "vxlan", NULL)) + return true; /* } else if (!strcmp(iftype, "infix-if-type:lag")) { if (is_phys_addr_deleted(dif)) diff --git a/src/confd/src/ietf-interfaces.h b/src/confd/src/ietf-interfaces.h index 4b74a2be..fa0b06b4 100644 --- a/src/confd/src/ietf-interfaces.h +++ b/src/confd/src/ietf-interfaces.h @@ -76,6 +76,10 @@ int netdag_gen_vlan(struct dagger *net, struct lyd_node *dif, /* infix-if-gre.c */ int gre_gen(struct dagger *net, struct lyd_node *dif, - struct lyd_node *cif, FILE *ip); + struct lyd_node *cif, FILE *ip); + +/* infix-if-vxlan.c */ +int vxlan_gen(struct dagger *net, struct lyd_node *dif, + struct lyd_node *cif, FILE *ip); #endif /* CONFD_IETF_INTERFACES_H_ */ diff --git a/src/confd/src/infix-if-gre.c b/src/confd/src/infix-if-gre.c index 9b078ba7..387fc708 100644 --- a/src/confd/src/infix-if-gre.c +++ b/src/confd/src/infix-if-gre.c @@ -4,7 +4,7 @@ #include "ietf-interfaces.h" int gre_gen(struct dagger *net, struct lyd_node *dif, - struct lyd_node *cif, FILE *ip) + struct lyd_node *cif, FILE *ip) { const char *ifname, *iftype, *local, *remote, *mac = NULL; struct lyd_node *node = NULL; diff --git a/src/confd/src/infix-if-vxlan.c b/src/confd/src/infix-if-vxlan.c new file mode 100644 index 00000000..956869d3 --- /dev/null +++ b/src/confd/src/infix-if-vxlan.c @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +#include + +#include "ietf-interfaces.h" + +int vxlan_gen(struct dagger *net, struct lyd_node *dif, + struct lyd_node *cif, FILE *ip) +{ + const char *ifname, *local, *remote, *mac = NULL; + const char *vni, *remote_port; + struct lyd_node *node = NULL; + + ifname = lydx_get_cattr(cif, "name"); + node = lydx_get_descendant(lyd_child(cif), "vxlan", NULL); + if (!node) + return -EINVAL; + + local = lydx_get_cattr(node, "local"); + remote = lydx_get_cattr(node, "remote"); + vni = lydx_get_cattr(node, "vni"); + remote_port = lydx_get_cattr(node, "remote-port"); + fprintf(ip, "link add name %s type vxlan id %s local %s remote %s dstport %s", ifname, vni, local, remote, remote_port); + if (mac) + fprintf(ip, "address %s\n", mac); + else + fprintf(ip, "\n"); + + return 0; +} diff --git a/src/confd/yang/infix-if-bridge.yang b/src/confd/yang/infix-if-bridge.yang index 11adce17..7d8b853b 100644 --- a/src/confd/yang/infix-if-bridge.yang +++ b/src/confd/yang/infix-if-bridge.yang @@ -714,7 +714,8 @@ submodule infix-if-bridge { "derived-from-or-self(if:type,'ianaift:ieee8023adLag') or "+ "derived-from-or-self(if:type,'ianaift:l2vlan') or "+ "derived-from-or-self(if:type,'ianaift:ilan') or "+ - "derived-from-or-self(if:type,'infix-ift:gretap')" { + "derived-from-or-self(if:type,'infix-ift:gretap') or "+ + "derived-from-or-self(if:type,'infix-ift:vxlan')" { description "Applies when a Bridge interface exists."; } diff --git a/src/confd/yang/infix-if-type.yang b/src/confd/yang/infix-if-type.yang index d26ba58f..8afce55c 100644 --- a/src/confd/yang/infix-if-type.yang +++ b/src/confd/yang/infix-if-type.yang @@ -70,6 +70,9 @@ module infix-if-type { identity gretap { base infix-interface-type; } + identity vxlan { + base infix-interface-type; + } identity lag { base infix-interface-type; base ianaift:ieee8023adLag; diff --git a/src/confd/yang/infix-if-vxlan.yang b/src/confd/yang/infix-if-vxlan.yang new file mode 100644 index 00000000..8523433c --- /dev/null +++ b/src/confd/yang/infix-if-vxlan.yang @@ -0,0 +1,54 @@ +submodule infix-if-vxlan { + yang-version 1.1; + belongs-to infix-interfaces { + prefix infix-if; + } + + import ietf-interfaces { + prefix if; + } + + import ietf-inet-types { + prefix inet-types; + } + + import infix-if-type { + prefix infixift; + } + + organization "KernelKit"; + contact "kernelkit@googlegroups.com"; + description "VXLAN tunnel extension for ietf-interfaces"; + + revision 2025-01-13 { + description "Initial revision."; + reference "internal"; + } + + typedef vni { + type uint32 { + range "0..16777215"; + } + } + augment "/if:interfaces/if:interface" { + when "derived-from-or-self(if:type, 'infixift:vxlan')" { + description "Only shown for if:type infixift:vxlan"; + } + description "Augments the interface model with VXLAN tunnels."; + container vxlan { + uses local-remote; + leaf remote-port { + type inet-types:port-number; + default 4789; + description + "VXLAN destination UDP port. Valid range: 0..65535. Default is 4789 (IANA-assigned VXLAN UDP port)."; + } + leaf vni { + type vni; + mandatory true; + description + "VXLAN Network Identifier (VNI), valid values are 0 to 16777215."; + } + } + } +} diff --git a/src/confd/yang/infix-if-vxlan@2025-01-13.yang b/src/confd/yang/infix-if-vxlan@2025-01-13.yang new file mode 120000 index 00000000..a4b5d860 --- /dev/null +++ b/src/confd/yang/infix-if-vxlan@2025-01-13.yang @@ -0,0 +1 @@ +infix-if-vxlan.yang \ No newline at end of file diff --git a/src/confd/yang/infix-interfaces.yang b/src/confd/yang/infix-interfaces.yang index f339091a..eaf6b08c 100644 --- a/src/confd/yang/infix-interfaces.yang +++ b/src/confd/yang/infix-interfaces.yang @@ -22,6 +22,7 @@ module infix-interfaces { include infix-if-veth; include infix-if-vlan; include infix-if-gre; + include infix-if-vxlan; organization "KernelKit"; contact "kernelkit@googlegroups.com"; @@ -106,6 +107,7 @@ module infix-interfaces { mandatory true; } } + /* * Data Nodes */ diff --git a/test/case/ietf_interfaces/Readme.adoc b/test/case/ietf_interfaces/Readme.adoc index 97e48bc5..ff5f893e 100644 --- a/test/case/ietf_interfaces/Readme.adoc +++ b/test/case/ietf_interfaces/Readme.adoc @@ -49,6 +49,6 @@ include::veth_delete/Readme.adoc[] include::vlan_iface_termination/Readme.adoc[] -include::gre_basic/Readme.adoc[] +include::tunnel_basic/Readme.adoc[] -include::gretap_bridged/Readme.adoc[] +include::tunnel_bridged/Readme.adoc[] diff --git a/test/case/ietf_interfaces/gretap_bridged/Readme.adoc b/test/case/ietf_interfaces/gretap_bridged/Readme.adoc deleted file mode 120000 index 6fdba522..00000000 --- a/test/case/ietf_interfaces/gretap_bridged/Readme.adoc +++ /dev/null @@ -1 +0,0 @@ -gretap_bridged.adoc \ No newline at end of file diff --git a/test/case/ietf_interfaces/gretap_bridged/gretap_bridged.adoc b/test/case/ietf_interfaces/gretap_bridged/gretap_bridged.adoc deleted file mode 100644 index 6060218a..00000000 --- a/test/case/ietf_interfaces/gretap_bridged/gretap_bridged.adoc +++ /dev/null @@ -1,24 +0,0 @@ -=== GRETAP interface bridged with physical -==== Description -Test that GRETAP works as it should and that it possible to bridge it. - -==== Topology -ifdef::topdoc[] -image::../../test/case/ietf_interfaces/gretap_bridged/topology.svg[GRETAP interface bridged with physical topology] -endif::topdoc[] -ifndef::topdoc[] -ifdef::testgroup[] -image::gretap_bridged/topology.svg[GRETAP interface bridged with physical topology] -endif::testgroup[] -ifndef::testgroup[] -image::topology.svg[GRETAP interface bridged with physical topology] -endif::testgroup[] -endif::topdoc[] -==== Test sequence -. Set up topology and attach to target DUTs -. Configure DUTs -. Test connectivity host:data to right:gre0 at 192.168.10.2 - - -<<< - diff --git a/test/case/ietf_interfaces/ietf_interfaces.yaml b/test/case/ietf_interfaces/ietf_interfaces.yaml index 550c4b19..2f2bbe8e 100644 --- a/test/case/ietf_interfaces/ietf_interfaces.yaml +++ b/test/case/ietf_interfaces/ietf_interfaces.yaml @@ -68,8 +68,8 @@ - name: vlan_iface_termination case: vlan_iface_termination/test.py -- name: gre_basic - suite: gre_basic/test.yaml +- name: tunnel_basic + suite: tunnel_basic/test.yaml -- name: gretap_bridged - case: gretap_bridged/test.py +- name: tunnel_bridged + suite: tunnel_bridged/test.yaml diff --git a/test/case/ietf_interfaces/gre_basic/Readme.adoc b/test/case/ietf_interfaces/tunnel_basic/Readme.adoc similarity index 66% rename from test/case/ietf_interfaces/gre_basic/Readme.adoc rename to test/case/ietf_interfaces/tunnel_basic/Readme.adoc index be68d210..79d3c027 100644 --- a/test/case/ietf_interfaces/gre_basic/Readme.adoc +++ b/test/case/ietf_interfaces/tunnel_basic/Readme.adoc @@ -2,3 +2,5 @@ include::gre_basic.adoc[] include::gretap_basic.adoc[] +include::vxlan_basic.adoc[] + diff --git a/test/case/ietf_interfaces/gre_basic/gre_basic.adoc b/test/case/ietf_interfaces/tunnel_basic/gre_basic.adoc similarity index 62% rename from test/case/ietf_interfaces/gre_basic/gre_basic.adoc rename to test/case/ietf_interfaces/tunnel_basic/gre_basic.adoc index e178f3e7..41e61add 100644 --- a/test/case/ietf_interfaces/gre_basic/gre_basic.adoc +++ b/test/case/ietf_interfaces/tunnel_basic/gre_basic.adoc @@ -1,15 +1,15 @@ === GRE point-to-point ==== Description -Test setting up IP GRE tunnels using IPv4 and IPv6, +Test setting up gre tunnels using IPv4 and IPv6, and ends with a connectivity test. ==== Topology ifdef::topdoc[] -image::../../test/case/ietf_interfaces/gre_basic/topology.svg[GRE point-to-point topology] +image::../../test/case/ietf_interfaces/tunnel_basic/topology.svg[GRE point-to-point topology] endif::topdoc[] ifndef::topdoc[] ifdef::testgroup[] -image::gre_basic/topology.svg[GRE point-to-point topology] +image::tunnel_basic/topology.svg[GRE point-to-point topology] endif::testgroup[] ifndef::testgroup[] image::topology.svg[GRE point-to-point topology] @@ -18,6 +18,7 @@ endif::topdoc[] ==== Test sequence . Set up topology and attach to target DUTs . Configure DUTs +. Verify connectivity host:data to 10.0.0.2 . Verify connectivity host:data to 2001:db8::c0a8:0a02 diff --git a/test/case/ietf_interfaces/gre_basic/gretap_basic.adoc b/test/case/ietf_interfaces/tunnel_basic/gretap_basic.adoc similarity index 62% rename from test/case/ietf_interfaces/gre_basic/gretap_basic.adoc rename to test/case/ietf_interfaces/tunnel_basic/gretap_basic.adoc index a2d69d7e..48c7122a 100644 --- a/test/case/ietf_interfaces/gre_basic/gretap_basic.adoc +++ b/test/case/ietf_interfaces/tunnel_basic/gretap_basic.adoc @@ -1,15 +1,15 @@ === GRETAP point-to-point ==== Description -Test setting up IP GRE tunnels using IPv4 and IPv6, +Test setting up gretap tunnels using IPv4 and IPv6, and ends with a connectivity test. ==== Topology ifdef::topdoc[] -image::../../test/case/ietf_interfaces/gre_basic/topology.svg[GRETAP point-to-point topology] +image::../../test/case/ietf_interfaces/tunnel_basic/topology.svg[GRETAP point-to-point topology] endif::topdoc[] ifndef::topdoc[] ifdef::testgroup[] -image::gre_basic/topology.svg[GRETAP point-to-point topology] +image::tunnel_basic/topology.svg[GRETAP point-to-point topology] endif::testgroup[] ifndef::testgroup[] image::topology.svg[GRETAP point-to-point topology] @@ -18,6 +18,7 @@ endif::topdoc[] ==== Test sequence . Set up topology and attach to target DUTs . Configure DUTs +. Verify connectivity host:data to 10.0.0.2 . Verify connectivity host:data to 2001:db8::c0a8:0a02 diff --git a/test/case/ietf_interfaces/gre_basic/test.py b/test/case/ietf_interfaces/tunnel_basic/test.py similarity index 80% rename from test/case/ietf_interfaces/gre_basic/test.py rename to test/case/ietf_interfaces/tunnel_basic/test.py index 64afa853..6c33f231 100755 --- a/test/case/ietf_interfaces/gre_basic/test.py +++ b/test/case/ietf_interfaces/tunnel_basic/test.py @@ -1,8 +1,8 @@ #!/usr/bin/env python3 """ -Basic GRE connectivity test +Basic tunnel connectivity test -Test setting up IP GRE tunnels using IPv4 and IPv6, +Test setting up {type} tunnels using IPv4 and IPv6, and ends with a connectivity test. """ @@ -21,8 +21,41 @@ with infamy.Test() as test: left = env.attach("left", "mgmt") right = env.attach("right", "mgmt") - with test.step("Configure DUTs"): + container_left4 = { + "local": "192.168.50.1", + "remote": "192.168.50.2" + } + container_left6 = { + "local": "2001:db8:3c4d:50::1", + "remote": "2001:db8:3c4d:50::2", + } + container_right4 = { + "local": "192.168.50.2", + "remote": "192.168.50.1" + } + container_right6 = { + "local": "2001:db8:3c4d:50::2", + "remote": "2001:db8:3c4d:50::1", + } + if type == "gretap" or type == "gre": + container_name = "gre" + if type == "vxlan": + container_name = "vxlan" + container_left4.update({ + "vni": 4 + }) + container_left6.update({ + "vni": 6 + }) + container_right4.update({ + "vni": 4 + }) + container_right6.update({ + "vni": 6 + }) + + left.put_config_dicts({ "ietf-interfaces": { "interfaces": { "interface": [ @@ -61,7 +94,7 @@ with infamy.Test() as test: } }, { - "name": "gre0", + "name": f"{type}4", "type": f"infix-if-type:{type}", "ipv4": { "address": [{ @@ -70,14 +103,10 @@ with infamy.Test() as test: }], "forwarding": True }, - "gre": { - "local": "192.168.50.1", - "remote": "192.168.50.2" - } - + container_name: container_left4 }, { - "name": "gre6", + "name": f"{type}6", "type": f"infix-if-type:{type}", "ipv6": { "address": [{ @@ -85,10 +114,7 @@ with infamy.Test() as test: "prefix-length": 64 }] }, - "gre": { - "local": "2001:db8:3c4d:50::1", - "remote": "2001:db8:3c4d:50::2", - } + container_name: container_left6 }] } } @@ -115,7 +141,7 @@ with infamy.Test() as test: } }, { - "name": "gre1", + "name": f"{type}4", "type": f"infix-if-type:{type}", "ipv4": { "address": [{ @@ -124,13 +150,10 @@ with infamy.Test() as test: }], "forwarding": True }, - "gre": { - "local": "192.168.50.2", - "remote": "192.168.50.1" - } + container_name: container_right4 }, { - "name": "gre6", + "name": f"{type}", "type": f"infix-if-type:{type}", "ipv6": { "address": [{ @@ -138,10 +161,7 @@ with infamy.Test() as test: "prefix-length": 64 }] }, - "gre": { - "local": "2001:db8:3c4d:50::2", - "remote": "2001:db8:3c4d:50::1", - } + container_name: container_right6 }] } }, @@ -175,7 +195,7 @@ with infamy.Test() as test: } }) _, hport = env.ltop.xlate("host", "data") - with test.step(f"Verify connectivity host:data to 10.0.0.2"): + with test.step("Verify connectivity host:data to 10.0.0.2"): with infamy.IsolatedMacVlan(hport) as ns0: ns0.addip("192.168.10.2") ns0.addroute("192.168.30.0/24", "192.168.10.1") diff --git a/test/case/ietf_interfaces/gre_basic/test.yaml b/test/case/ietf_interfaces/tunnel_basic/test.yaml similarity index 66% rename from test/case/ietf_interfaces/gre_basic/test.yaml rename to test/case/ietf_interfaces/tunnel_basic/test.yaml index 150b311e..a56130f7 100644 --- a/test/case/ietf_interfaces/gre_basic/test.yaml +++ b/test/case/ietf_interfaces/tunnel_basic/test.yaml @@ -10,3 +10,9 @@ opts: ["--type", "gretap"] infamy: title: GRETAP point-to-point + +- name: vxlan_basic + case: test.py + opts: ["--type", "vxlan"] + infamy: + title: VXLAN point-to-point diff --git a/test/case/ietf_interfaces/gre_basic/topology.dot b/test/case/ietf_interfaces/tunnel_basic/topology.dot similarity index 100% rename from test/case/ietf_interfaces/gre_basic/topology.dot rename to test/case/ietf_interfaces/tunnel_basic/topology.dot diff --git a/test/case/ietf_interfaces/gre_basic/topology.svg b/test/case/ietf_interfaces/tunnel_basic/topology.svg similarity index 100% rename from test/case/ietf_interfaces/gre_basic/topology.svg rename to test/case/ietf_interfaces/tunnel_basic/topology.svg diff --git a/test/case/ietf_interfaces/tunnel_basic/vxlan_basic.adoc b/test/case/ietf_interfaces/tunnel_basic/vxlan_basic.adoc new file mode 100644 index 00000000..6351726b --- /dev/null +++ b/test/case/ietf_interfaces/tunnel_basic/vxlan_basic.adoc @@ -0,0 +1,26 @@ +=== VXLAN point-to-point +==== Description +Test setting up vxlan tunnels using IPv4 and IPv6, +and ends with a connectivity test. + +==== Topology +ifdef::topdoc[] +image::../../test/case/ietf_interfaces/tunnel_basic/topology.svg[VXLAN point-to-point topology] +endif::topdoc[] +ifndef::topdoc[] +ifdef::testgroup[] +image::tunnel_basic/topology.svg[VXLAN point-to-point topology] +endif::testgroup[] +ifndef::testgroup[] +image::topology.svg[VXLAN point-to-point topology] +endif::testgroup[] +endif::topdoc[] +==== Test sequence +. Set up topology and attach to target DUTs +. Configure DUTs +. Verify connectivity host:data to 10.0.0.2 +. Verify connectivity host:data to 2001:db8::c0a8:0a02 + + +<<< + diff --git a/test/case/ietf_interfaces/tunnel_bridged/Readme.adoc b/test/case/ietf_interfaces/tunnel_bridged/Readme.adoc new file mode 100644 index 00000000..cab52edf --- /dev/null +++ b/test/case/ietf_interfaces/tunnel_bridged/Readme.adoc @@ -0,0 +1,4 @@ +include::gretap_bridged.adoc[] + +include::vxlan_bridged.adoc[] + diff --git a/test/case/ietf_interfaces/tunnel_bridged/gretap_bridged.adoc b/test/case/ietf_interfaces/tunnel_bridged/gretap_bridged.adoc new file mode 100644 index 00000000..a855e10f --- /dev/null +++ b/test/case/ietf_interfaces/tunnel_bridged/gretap_bridged.adoc @@ -0,0 +1,24 @@ +=== GRETAP bridged with physical interface +==== Description +Undefined + +==== Topology +ifdef::topdoc[] +image::../../test/case/ietf_interfaces/tunnel_bridged/topology.svg[GRETAP bridged with physical interface topology] +endif::topdoc[] +ifndef::topdoc[] +ifdef::testgroup[] +image::tunnel_bridged/topology.svg[GRETAP bridged with physical interface topology] +endif::testgroup[] +ifndef::testgroup[] +image::topology.svg[GRETAP bridged with physical interface topology] +endif::testgroup[] +endif::topdoc[] +==== Test sequence +. Set up topology and attach to target DUTs +. Configure DUTs +. Test connectivity host:data to right:gretap0 at 192.168.10.2 + + +<<< + diff --git a/test/case/ietf_interfaces/gretap_bridged/test.py b/test/case/ietf_interfaces/tunnel_bridged/test.py similarity index 62% rename from test/case/ietf_interfaces/gretap_bridged/test.py rename to test/case/ietf_interfaces/tunnel_bridged/test.py index 2ec73c7f..685b8696 100755 --- a/test/case/ietf_interfaces/gretap_bridged/test.py +++ b/test/case/ietf_interfaces/tunnel_bridged/test.py @@ -1,29 +1,51 @@ #!/usr/bin/env python3 """ -GRETAP interface bridged with physical +Tunnel interface bridged with physical -Test that GRETAP works as it should and that it possible to bridge it. +Test that {type} works as it should and that it possible to bridge it. """ import infamy +class ArgumentParser(infamy.ArgumentParser): + def __init__(self): + super().__init__() + self.add_argument("--type") + with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): - env = infamy.Env() - left = env.attach("left", "mgmt") - right = env.attach("right", "mgmt") - _, leftlink = env.ltop.xlate("left", "link") - _, leftdata = env.ltop.xlate("left", "data") - _, rightlink = env.ltop.xlate("right", "link") - + args=ArgumentParser() + env = infamy.Env(args=args) + left = env.attach("left", "mgmt") + right = env.attach("right", "mgmt") + type = env.args.type with test.step("Configure DUTs"): + if type == "gretap": + container_name = "gre" + else: + container_name = type + + container_left = { + "local": "192.168.50.1", + "remote": "192.168.50.2" + } + container_right = { + "local": "192.168.50.2", + "remote": "192.168.50.1" + } + container_left.update({ + "vni": 4 + }) + container_right.update({ + "vni": 4 + }) left.put_config_dicts({ "ietf-interfaces": { "interfaces": { "interface": [ { - "name": leftlink, + "name": left["link"], "ipv4": { "address": [{ "ip": "192.168.50.1", @@ -33,7 +55,7 @@ with infamy.Test() as test: } }, { - "name": leftdata, + "name": left["data"], "bridge-port": { "bridge": "br0" } @@ -43,12 +65,9 @@ with infamy.Test() as test: "type": "infix-if-type:bridge" }, { - "name": "gre0", - "type": "infix-if-type:gretap", - "gre": { - "local": "192.168.50.1", - "remote": "192.168.50.2" - }, + "name": f"{type}0", + "type": f"infix-if-type:{type}", + container_name: container_left, "bridge-port": { "bridge": "br0" } @@ -64,7 +83,7 @@ with infamy.Test() as test: "interfaces": { "interface": [ { - "name": rightlink, + "name": right["link"], "ipv4": { "address": [{ "ip": "192.168.50.2", @@ -80,8 +99,8 @@ with infamy.Test() as test: } }, { - "name": "gre0", - "type": "infix-if-type:gretap", + "name": f"{type}0", + "type": f"infix-if-type:{type}", "ipv4": { "address": [{ "ip": "192.168.10.2", @@ -89,16 +108,13 @@ with infamy.Test() as test: }], "forwarding": True }, - "gre": { - "local": "192.168.50.2", - "remote": "192.168.50.1" - } + container_name: container_right, }] } } }) _, hport = env.ltop.xlate("host", "data") - with test.step("Test connectivity host:data to right:gre0 at 192.168.10.2"): + with test.step(f"Test connectivity host:data to right:{type}0 at 192.168.10.2"): with infamy.IsolatedMacVlan(hport) as ns0: ns0.addip("192.168.10.1") ns0.must_reach("192.168.10.2") diff --git a/test/case/ietf_interfaces/tunnel_bridged/test.yaml b/test/case/ietf_interfaces/tunnel_bridged/test.yaml new file mode 100644 index 00000000..58b53673 --- /dev/null +++ b/test/case/ietf_interfaces/tunnel_bridged/test.yaml @@ -0,0 +1,12 @@ +--- +- name: gretap_bridged + case: test.py + opts: ["--type", "gretap"] + infamy: + title: GRETAP bridged with physical interface + +- name: vxlan_bridged + case: test.py + opts: ["--type", "vxlan"] + infamy: + title: VXLAN bridged with physical interface diff --git a/test/case/ietf_interfaces/gretap_bridged/topology.dot b/test/case/ietf_interfaces/tunnel_bridged/topology.dot similarity index 100% rename from test/case/ietf_interfaces/gretap_bridged/topology.dot rename to test/case/ietf_interfaces/tunnel_bridged/topology.dot diff --git a/test/case/ietf_interfaces/gretap_bridged/topology.svg b/test/case/ietf_interfaces/tunnel_bridged/topology.svg similarity index 100% rename from test/case/ietf_interfaces/gretap_bridged/topology.svg rename to test/case/ietf_interfaces/tunnel_bridged/topology.svg diff --git a/test/case/ietf_interfaces/tunnel_bridged/vxlan_bridged.adoc b/test/case/ietf_interfaces/tunnel_bridged/vxlan_bridged.adoc new file mode 100644 index 00000000..8dd6a79a --- /dev/null +++ b/test/case/ietf_interfaces/tunnel_bridged/vxlan_bridged.adoc @@ -0,0 +1,24 @@ +=== VXLAN bridged with physical interface +==== Description +Undefined + +==== Topology +ifdef::topdoc[] +image::../../test/case/ietf_interfaces/tunnel_bridged/topology.svg[VXLAN bridged with physical interface topology] +endif::topdoc[] +ifndef::topdoc[] +ifdef::testgroup[] +image::tunnel_bridged/topology.svg[VXLAN bridged with physical interface topology] +endif::testgroup[] +ifndef::testgroup[] +image::topology.svg[VXLAN bridged with physical interface topology] +endif::testgroup[] +endif::topdoc[] +==== Test sequence +. Set up topology and attach to target DUTs +. Configure DUTs +. Test connectivity host:data to right:vxlan0 at 192.168.10.2 + + +<<< +