mirror of
https://github.com/kernelkit/infix.git
synced 2026-08-06 07:33:01 +02:00
@@ -17,6 +17,7 @@ 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
|
||||
|
||||
### Fixes
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# Tunnel configuration
|
||||
|
||||
Tunnel traffic from point A to point B
|
||||
|
||||
|
||||
## Generic Routing Encapsulation (GRE)
|
||||
|
||||
The support for GRE tunnels includes IPv4 and IPv6 tunnels both in GRE
|
||||
(IP) and GRETAP (MAC) modes.
|
||||
```
|
||||
admin@example:/config/> edit interface gre1
|
||||
admin@example:/config/interface/gre1/> set type gretap
|
||||
admin@example:/config/interface/gre1/> set gre local 192.168.3.1 remote 192.168.3.2
|
||||
admin@example:/config/interface/gre1/> leave
|
||||
admin@example:/>
|
||||
```
|
||||
@@ -34,6 +34,7 @@ confd_plugin_la_SOURCES = \
|
||||
infix-if-bridge-port.c \
|
||||
infix-if-veth.c \
|
||||
infix-if-vlan.c \
|
||||
infix-if-gre.c \
|
||||
ietf-keystore.c \
|
||||
ietf-system.c \
|
||||
ietf-syslog.c \
|
||||
|
||||
@@ -87,6 +87,10 @@ static int ifchange_cand_infer_type(sr_session_ctx_t *session, const char *path)
|
||||
inferred.data.string_val = "infix-if-type:vlan";
|
||||
else if (!fnmatch("*.+([0-9])", ifname, FNM_EXTMATCH))
|
||||
inferred.data.string_val = "infix-if-type:vlan";
|
||||
else if (!fnmatch("gre+([0-9])", ifname, FNM_EXTMATCH))
|
||||
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";
|
||||
|
||||
free(ifname);
|
||||
|
||||
@@ -395,6 +399,8 @@ static int netdag_gen_afspec_add(sr_session_ctx_t *session, struct dagger *net,
|
||||
sr_session_set_error_message(net->session, "Cannot create fixed Ethernet interface %s,"
|
||||
" wrong type or name.", ifname);
|
||||
return -ENOENT;
|
||||
} else if (!strcmp(iftype, "infix-if-type:gre") || !strcmp(iftype, "infix-if-type:gretap")) {
|
||||
err = gre_gen(net, NULL, cif, ip);
|
||||
} else {
|
||||
sr_session_set_error_message(net->session, "%s: unsupported interface type \"%s\"", ifname, iftype);
|
||||
return -ENOSYS;
|
||||
@@ -420,6 +426,8 @@ static int netdag_gen_afspec_set(sr_session_ctx_t *session, struct dagger *net,
|
||||
return netdag_gen_vlan(net, dif, cif, ip);
|
||||
if (!strcmp(iftype, "infix-if-type:veth"))
|
||||
return 0;
|
||||
if (!strcmp(iftype, "infix-if-type:gretap"))
|
||||
return 0;
|
||||
|
||||
ERROR("%s: unsupported interface type \"%s\"", ifname, iftype);
|
||||
return -ENOSYS;
|
||||
@@ -449,7 +457,10 @@ static bool netdag_must_del(struct lyd_node *dif, struct lyd_node *cif)
|
||||
if (lydx_get_descendant(lyd_child(dif), "vlan", NULL))
|
||||
return true;
|
||||
} else if (!strcmp(iftype, "infix-if-type:veth")) {
|
||||
if (lydx_get_descendant(lyd_child(dif), "peer", NULL))
|
||||
if (lydx_get_descendant(lyd_child(dif), "veth", NULL))
|
||||
return true;
|
||||
} 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:lag")) {
|
||||
|
||||
@@ -73,6 +73,8 @@ int ifchange_cand_infer_vlan(sr_session_ctx_t *session, const char *path);
|
||||
int netdag_gen_vlan(struct dagger *net, struct lyd_node *dif,
|
||||
struct lyd_node *cif, FILE *ip);
|
||||
|
||||
/* infix-if-gre.c */
|
||||
int gre_gen(struct dagger *net, struct lyd_node *dif,
|
||||
struct lyd_node *cif, FILE *ip);
|
||||
|
||||
#endif /* CONFD_IETF_INTERFACES_H_ */
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
#include <srx/lyx.h>
|
||||
|
||||
#include "ietf-interfaces.h"
|
||||
|
||||
int gre_gen(struct dagger *net, struct lyd_node *dif,
|
||||
struct lyd_node *cif, FILE *ip)
|
||||
{
|
||||
const char *ifname, *iftype, *local, *remote, *mac = NULL;
|
||||
struct lyd_node *node = NULL;
|
||||
char gretype[10] = "";
|
||||
int ipv6;
|
||||
|
||||
ifname = lydx_get_cattr(cif, "name");
|
||||
iftype = lydx_get_cattr(cif, "type");
|
||||
|
||||
node = lydx_get_descendant(lyd_child(cif), "gre", NULL);
|
||||
if (!node)
|
||||
return -EINVAL;
|
||||
|
||||
local = lydx_get_cattr(node, "local");
|
||||
remote = lydx_get_cattr(node, "remote");
|
||||
ipv6 = !!strstr(local, ":");
|
||||
|
||||
if (!strcmp(iftype, "infix-if-type:gre")) {
|
||||
snprintf(gretype, sizeof(gretype), "%sgre", ipv6 ? "ip6" : "");
|
||||
|
||||
}
|
||||
else if (!strcmp(iftype, "infix-if-type:gretap")) {
|
||||
snprintf(gretype, sizeof(gretype), "%sgretap", ipv6 ? "ip6" : "");
|
||||
mac = get_phys_addr(cif, NULL);
|
||||
}
|
||||
|
||||
fprintf(ip, "link add name %s type %s local %s remote %s", ifname, gretype, local, remote);
|
||||
if (mac)
|
||||
fprintf(ip, "address %s\n", mac);
|
||||
else
|
||||
fprintf(ip, "\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -525,7 +525,8 @@ submodule infix-if-bridge {
|
||||
"derived-from-or-self(if:type,'ianaift:ethernetCsmacd') or "+
|
||||
"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')" {
|
||||
"derived-from-or-self(if:type,'ianaift:ilan') or "+
|
||||
"derived-from-or-self(if:type,'infix-ift:gretap')" {
|
||||
description "Applies when a Bridge interface exists.";
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
submodule infix-if-gre {
|
||||
yang-version 1.1;
|
||||
belongs-to infix-interfaces {
|
||||
prefix infix-if;
|
||||
}
|
||||
|
||||
import ietf-interfaces {
|
||||
prefix if;
|
||||
}
|
||||
|
||||
import infix-if-type {
|
||||
prefix infixift;
|
||||
}
|
||||
|
||||
organization "KernelKit";
|
||||
contact "kernelkit@googlegroups.com";
|
||||
description "GRE and GRETAP tunnel extension for ietf-interfaces";
|
||||
|
||||
revision 2024-12-20 {
|
||||
description "Initial revision.";
|
||||
reference "internal";
|
||||
}
|
||||
|
||||
augment "/if:interfaces/if:interface" {
|
||||
when "derived-from-or-self(if:type, 'infixift:gre') or"+
|
||||
"derived-from-or-self(if:type, 'infixift:gretap')" {
|
||||
description "Only shown for if:type infixift:gre";
|
||||
}
|
||||
|
||||
description "Augments the interface model with GRE tunnels.";
|
||||
container gre {
|
||||
uses local-remote;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
infix-if-gre.yang
|
||||
@@ -64,6 +64,12 @@ module infix-if-type {
|
||||
description "Interface with properties resembling Ethernet";
|
||||
reference "RFC 3635";
|
||||
}
|
||||
identity gre {
|
||||
base infix-interface-type;
|
||||
}
|
||||
identity gretap {
|
||||
base infix-interface-type;
|
||||
}
|
||||
identity lag {
|
||||
base infix-interface-type;
|
||||
base ianaift:ieee8023adLag;
|
||||
|
||||
@@ -12,12 +12,16 @@ module infix-interfaces {
|
||||
import ietf-yang-types {
|
||||
prefix yang;
|
||||
}
|
||||
import ietf-inet-types {
|
||||
prefix inet;
|
||||
}
|
||||
|
||||
include infix-if-base;
|
||||
include infix-if-bridge;
|
||||
include infix-if-container;
|
||||
include infix-if-veth;
|
||||
include infix-if-vlan;
|
||||
include infix-if-gre;
|
||||
|
||||
organization "KernelKit";
|
||||
contact "kernelkit@googlegroups.com";
|
||||
@@ -80,6 +84,23 @@ module infix-interfaces {
|
||||
reference "internal";
|
||||
}
|
||||
|
||||
grouping local-remote {
|
||||
description "Local address to use as source address";
|
||||
leaf local {
|
||||
type inet:ip-address;
|
||||
mandatory true;
|
||||
}
|
||||
leaf remote {
|
||||
description "Peer address";
|
||||
type inet:ip-address;
|
||||
must "(contains(../local, ':') and contains(., ':'))
|
||||
or (not(contains(../local, ':')) and not(contains(., ':')))" {
|
||||
error-message
|
||||
"Local and remote must be both IPv4 or both IPv6 addresses.";
|
||||
}
|
||||
mandatory true;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Data Nodes
|
||||
*/
|
||||
|
||||
@@ -304,6 +304,8 @@ class Iface:
|
||||
else:
|
||||
self.ipv6_addr = []
|
||||
|
||||
if self.data.get('infix-interfaces:gre'):
|
||||
self.gre = self.data['infix-interfaces:gre']
|
||||
|
||||
if self.data.get('infix-interfaces:vlan'):
|
||||
self.lower_if = self.data.get('infix-interfaces:vlan', None).get('lower-layer-if',None)
|
||||
@@ -323,6 +325,9 @@ class Iface:
|
||||
def is_veth(self):
|
||||
return self.data['type'] == "infix-if-type:veth"
|
||||
|
||||
def is_gre(self):
|
||||
return self.data['type'] == "infix-if-type:gre" or self.data['type'] == "infix-if-type:gretap"
|
||||
|
||||
def oper(self, detail=False):
|
||||
"""Remap in brief overview to fit column widths."""
|
||||
if not detail and self.oper_status == "lower-layer-down":
|
||||
|
||||
@@ -38,6 +38,9 @@ def json_get_yang_type(iface_in):
|
||||
if iface_in['link_type'] == "loopback":
|
||||
return "infix-if-type:loopback"
|
||||
|
||||
if iface_in['link_type'] in ("gre", "gre6"):
|
||||
return "infix-if-type:gre"
|
||||
|
||||
if iface_in['link_type'] != "ether":
|
||||
return "infix-if-type:other"
|
||||
|
||||
@@ -53,6 +56,9 @@ def json_get_yang_type(iface_in):
|
||||
if iface_in['linkinfo']['info_kind'] == "veth":
|
||||
return "infix-if-type:veth"
|
||||
|
||||
if iface_in['linkinfo']['info_kind'] in ("gretap", "ip6gretap"):
|
||||
return "infix-if-type:gretap"
|
||||
|
||||
if iface_in['linkinfo']['info_kind'] == "vlan":
|
||||
return "infix-if-type:vlan"
|
||||
|
||||
@@ -715,6 +721,19 @@ def add_bridge_port_lower(ifname, iface_in, iface_out):
|
||||
multicast = get_brport_multicast(ifname)
|
||||
insert(iface_out, "infix-interfaces:bridge-port", "multicast", multicast)
|
||||
|
||||
|
||||
def add_gre(iface_in, iface_out):
|
||||
if 'link_type' in iface_in:
|
||||
val = json_get_yang_type(iface_in)
|
||||
if val != "infix-if-type:gre" and val != "infix-if-type:gretap":
|
||||
return;
|
||||
gre={}
|
||||
info_data=iface_in.get("linkinfo", {}).get("info_data", {})
|
||||
gre["local"] = info_data.get("local")
|
||||
gre["remote"] = info_data.get("remote")
|
||||
insert(iface_out, "infix-interfaces:gre", gre)
|
||||
|
||||
|
||||
def add_ip_link(ifname, iface_in, iface_out):
|
||||
if 'ifname' in iface_in:
|
||||
iface_out['name'] = ifname
|
||||
@@ -725,14 +744,14 @@ def add_ip_link(ifname, iface_in, iface_out):
|
||||
if 'ifalias' in iface_in:
|
||||
iface_out['description'] = iface_in['ifalias']
|
||||
|
||||
if 'address' in iface_in:
|
||||
if 'address' in iface_in and not "POINTOPOINT" in iface_in["flags"]:
|
||||
iface_out['phys-address'] = iface_in['address']
|
||||
|
||||
add_bridge_port_common(ifname, iface_in, iface_out)
|
||||
add_bridge_port_lower(ifname, iface_in, iface_out)
|
||||
|
||||
if not iface_is_dsa(iface_in):
|
||||
if 'link' in iface_in:
|
||||
if iface_in.get('link'):
|
||||
insert(iface_out, "infix-interfaces:vlan", "lower-layer-if", iface_in['link'])
|
||||
elif 'link_index' in iface_in:
|
||||
# 'link_index' is the only reference we have if the link iface is in a namespace
|
||||
@@ -758,6 +777,7 @@ def add_ip_link(ifname, iface_in, iface_out):
|
||||
if 'link_type' in iface_in:
|
||||
val = json_get_yang_type(iface_in)
|
||||
iface_out['type'] = val
|
||||
add_gre(iface_in, iface_out)
|
||||
|
||||
val = lookup(iface_in, "stats64", "rx", "bytes")
|
||||
if val is not None:
|
||||
|
||||
@@ -47,3 +47,6 @@ include::veth_delete/Readme.adoc[]
|
||||
|
||||
include::vlan_iface_termination/Readme.adoc[]
|
||||
|
||||
include::gre_basic/Readme.adoc[]
|
||||
|
||||
include::gretap_bridged/Readme.adoc[]
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
=== Basic IP GRE test
|
||||
==== Description
|
||||
Test setting up IP GRE tunnels using IPv4 and IPv6,
|
||||
and then a connectivity test.
|
||||
|
||||
==== Topology
|
||||
ifdef::topdoc[]
|
||||
image::../../test/case/ietf_interfaces/gre_basic/topology.svg[Basic IP GRE test topology]
|
||||
endif::topdoc[]
|
||||
ifndef::topdoc[]
|
||||
ifdef::testgroup[]
|
||||
image::gre_basic/topology.svg[Basic IP GRE test topology]
|
||||
endif::testgroup[]
|
||||
ifndef::testgroup[]
|
||||
image::topology.svg[Basic IP GRE test topology]
|
||||
endif::testgroup[]
|
||||
endif::topdoc[]
|
||||
==== Test sequence
|
||||
. Set up topology and attach to target DUTs
|
||||
. Configure DUTs
|
||||
. Test connectivity host:data to gre 10.0.0.2
|
||||
. Test connectivity host:data to gre on right 2001:db8::c0a8:0a02
|
||||
|
||||
|
||||
<<<
|
||||
|
||||
Executable
+186
@@ -0,0 +1,186 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Basic IP GRE test
|
||||
|
||||
Test setting up IP GRE tunnels using IPv4 and IPv6,
|
||||
and then a connectivity test.
|
||||
"""
|
||||
|
||||
import infamy
|
||||
|
||||
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")
|
||||
|
||||
|
||||
with test.step("Configure DUTs"):
|
||||
left.put_config_dicts({ "ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": leftlink,
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": "192.168.50.1",
|
||||
"prefix-length": 24
|
||||
}],
|
||||
"forwarding": True
|
||||
},
|
||||
"ipv6": {
|
||||
"address": [{
|
||||
"ip": "2001:db8:3c4d:50::1",
|
||||
"prefix-length": 64
|
||||
}],
|
||||
"forwarding": True
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": leftdata,
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": "192.168.10.1",
|
||||
"prefix-length": 24
|
||||
}],
|
||||
"forwarding": True
|
||||
},
|
||||
"ipv6": {
|
||||
"address": [{
|
||||
"ip": "2001:db8:3c4d:10::1",
|
||||
"prefix-length": 64
|
||||
}],
|
||||
"forwarding": True
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "gre0",
|
||||
"type": "infix-if-type:gre",
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": "192.168.30.1",
|
||||
"prefix-length": 24
|
||||
}],
|
||||
"forwarding": True
|
||||
},
|
||||
"gre": {
|
||||
"local": "192.168.50.1",
|
||||
"remote": "192.168.50.2"
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
"name": "gre6",
|
||||
"type": "infix-if-type:gre",
|
||||
"ipv6": {
|
||||
"address": [{
|
||||
"ip": "2001:db8:3c4d:30::1",
|
||||
"prefix-length": 64
|
||||
}]
|
||||
},
|
||||
"gre": {
|
||||
"local": "2001:db8:3c4d:50::1",
|
||||
"remote": "2001:db8:3c4d:50::2",
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
right.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": rightlink,
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": "192.168.50.2",
|
||||
"prefix-length": 24
|
||||
}],
|
||||
"forwarding": True
|
||||
},
|
||||
"ipv6": {
|
||||
"address": [{
|
||||
"ip": "2001:db8:3c4d:50::2",
|
||||
"prefix-length": 64
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "gre1",
|
||||
"type": "infix-if-type:gre",
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": "192.168.30.2",
|
||||
"prefix-length": 24
|
||||
}],
|
||||
"forwarding": True
|
||||
},
|
||||
"gre": {
|
||||
"local": "192.168.50.2",
|
||||
"remote": "192.168.50.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "gre6",
|
||||
"type": "infix-if-type:gre",
|
||||
"ipv6": {
|
||||
"address": [{
|
||||
"ip": "2001:db8:3c4d:30::2",
|
||||
"prefix-length": 64
|
||||
}]
|
||||
},
|
||||
"gre": {
|
||||
"local": "2001:db8:3c4d:50::2",
|
||||
"remote": "2001:db8:3c4d:50::1",
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
"ietf-routing": {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [{
|
||||
"type": "infix-routing:static",
|
||||
"name": "default",
|
||||
"static-routes": {
|
||||
"ipv4": {
|
||||
"route": [{
|
||||
"destination-prefix": "192.168.10.0/24",
|
||||
"next-hop": {
|
||||
"next-hop-address": "192.168.30.1"
|
||||
}
|
||||
}]
|
||||
},
|
||||
"ipv6": {
|
||||
"route": [{
|
||||
"destination-prefix": "2001:db8:3c4d:10::/64",
|
||||
"next-hop": {
|
||||
"next-hop-address": "2001:db8:3c4d:30::1"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
_, hport = env.ltop.xlate("host", "data")
|
||||
with test.step("Test connectivity host:data to gre 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")
|
||||
ns0.must_reach("192.168.30.2")
|
||||
with test.step("Test connectivity host:data to gre on right 2001:db8::c0a8:0a02"):
|
||||
with infamy.IsolatedMacVlan(hport) as ns0:
|
||||
ns0.addip("2001:db8:3c4d:10::2", prefix_length=64, proto="ipv6")
|
||||
ns0.addroute("2001:db8:3c4d:30::/64", "2001:db8:3c4d:10::1", proto="ipv6")
|
||||
#breakpoint()
|
||||
ns0.must_reach("2001:db8:3c4d:30::2")
|
||||
|
||||
test.succeed()
|
||||
@@ -0,0 +1,35 @@
|
||||
graph "gre-basic" {
|
||||
layout="neato";
|
||||
overlap="false";
|
||||
esep="+40";
|
||||
|
||||
node [shape=record, fontname="DejaVu Sans Mono, Book"];
|
||||
edge [color="cornflowerblue", penwidth="2", fontname="DejaVu Serif, Book"];
|
||||
|
||||
host [
|
||||
label="host | { <mgmt1> mgmt1 } | { <data> data } | { <mgmt2> mgmt2 }"
|
||||
pos="3,0!",
|
||||
kind="controller",
|
||||
];
|
||||
|
||||
left [
|
||||
label="{ left } | { <mgmt> mgmt } | { <data> data } | { <link> link }",
|
||||
pos="0, -3!",
|
||||
|
||||
kind="infix",
|
||||
];
|
||||
|
||||
right [
|
||||
label="{ <link> link } | { <mgmt> mgmt } | { right }",
|
||||
pos="8,-3!",
|
||||
|
||||
kind="infix",
|
||||
];
|
||||
|
||||
host:mgmt1 -- left:mgmt [kind=mgmt, color="lightgray"]
|
||||
host:data -- left:data [headlabel=".1", label="192.168.10.0/24" taillabel=".2 ", labeldistance=1, fontcolor="black", color="black"]
|
||||
host:mgmt2 -- right:mgmt [kind=mgmt, color="lightgray"]
|
||||
|
||||
|
||||
left:link -- right:link [headlabel=".1\n\n", label="192.168.50.0/24", taillabel="\n.2", labeldistance=1, fontcolor="black", color="black"]
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
|
||||
<!-- Title: gre-basic Pages: 1 -->
|
||||
<svg width="552pt" height="183pt"
|
||||
viewBox="0.00 0.00 552.37 183.24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 179.24)">
|
||||
<title>gre-basic</title>
|
||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-179.24 548.37,-179.24 548.37,4 -4,4"/>
|
||||
<!-- host -->
|
||||
<g id="node1" class="node">
|
||||
<title>host</title>
|
||||
<polygon fill="none" stroke="black" points="129.01,-138.74 129.01,-174.74 345.01,-174.74 345.01,-138.74 129.01,-138.74"/>
|
||||
<text text-anchor="middle" x="154.01" y="-153.04" font-family="DejaVu Sans Mono, Book" font-size="14.00">host</text>
|
||||
<polyline fill="none" stroke="black" points="179.01,-138.74 179.01,-174.74 "/>
|
||||
<text text-anchor="middle" x="208.01" y="-153.04" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt1</text>
|
||||
<polyline fill="none" stroke="black" points="237.01,-138.74 237.01,-174.74 "/>
|
||||
<text text-anchor="middle" x="262.01" y="-153.04" font-family="DejaVu Sans Mono, Book" font-size="14.00">data</text>
|
||||
<polyline fill="none" stroke="black" points="287.01,-138.74 287.01,-174.74 "/>
|
||||
<text text-anchor="middle" x="316.01" y="-153.04" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt2</text>
|
||||
</g>
|
||||
<!-- left -->
|
||||
<g id="node2" class="node">
|
||||
<title>left</title>
|
||||
<polygon fill="none" stroke="black" points="0,-1.73 0,-37.73 200,-37.73 200,-1.73 0,-1.73"/>
|
||||
<text text-anchor="middle" x="25" y="-16.03" font-family="DejaVu Sans Mono, Book" font-size="14.00">left</text>
|
||||
<polyline fill="none" stroke="black" points="50,-1.73 50,-37.73 "/>
|
||||
<text text-anchor="middle" x="75" y="-16.03" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="100,-1.73 100,-37.73 "/>
|
||||
<text text-anchor="middle" x="125" y="-16.03" font-family="DejaVu Sans Mono, Book" font-size="14.00">data</text>
|
||||
<polyline fill="none" stroke="black" points="150,-1.73 150,-37.73 "/>
|
||||
<text text-anchor="middle" x="175" y="-16.03" font-family="DejaVu Sans Mono, Book" font-size="14.00">link</text>
|
||||
</g>
|
||||
<!-- host--left -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>host:mgmt1--left:mgmt</title>
|
||||
<path fill="none" stroke="lightgray" stroke-width="2" d="M208.01,-138.74C208.01,-138.74 75,-37.73 75,-37.73"/>
|
||||
</g>
|
||||
<!-- host--left -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>host:data--left:data</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M262.01,-138.74C262.01,-138.74 125,-37.73 125,-37.73"/>
|
||||
<text text-anchor="middle" x="134.51" y="-92.03" font-family="DejaVu Serif, Book" font-size="14.00">192.168.10.0/24</text>
|
||||
<text text-anchor="middle" x="134.8" y="-36" font-family="DejaVu Serif, Book" font-size="14.00">.1</text>
|
||||
<text text-anchor="middle" x="252.21" y="-133.06" font-family="DejaVu Serif, Book" font-size="14.00">.2 </text>
|
||||
</g>
|
||||
<!-- right -->
|
||||
<g id="node3" class="node">
|
||||
<title>right</title>
|
||||
<polygon fill="none" stroke="black" points="386.37,-1.73 386.37,-37.73 544.37,-37.73 544.37,-1.73 386.37,-1.73"/>
|
||||
<text text-anchor="middle" x="411.37" y="-16.03" font-family="DejaVu Sans Mono, Book" font-size="14.00">link</text>
|
||||
<polyline fill="none" stroke="black" points="436.37,-1.73 436.37,-37.73 "/>
|
||||
<text text-anchor="middle" x="461.37" y="-16.03" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="486.37,-1.73 486.37,-37.73 "/>
|
||||
<text text-anchor="middle" x="515.37" y="-16.03" font-family="DejaVu Sans Mono, Book" font-size="14.00">right</text>
|
||||
</g>
|
||||
<!-- host--right -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>host:mgmt2--right:mgmt</title>
|
||||
<path fill="none" stroke="lightgray" stroke-width="2" d="M345.01,-156.74C345.01,-156.74 461.37,-37.73 461.37,-37.73"/>
|
||||
</g>
|
||||
<!-- left--right -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>left:link--right:link</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M200,-19.73C200,-19.73 386.37,-19.73 386.37,-19.73"/>
|
||||
<text text-anchor="middle" x="293.18" y="-8.53" font-family="DejaVu Serif, Book" font-size="14.00">192.168.50.0/24</text>
|
||||
<text text-anchor="middle" x="377.31" y="-28.25" font-family="DejaVu Serif, Book" font-size="14.00">.1</text>
|
||||
<text text-anchor="middle" x="209.06" y="-3.8" font-family="DejaVu Serif, Book" font-size="14.00">.2</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.4 KiB |
@@ -0,0 +1,24 @@
|
||||
=== 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
|
||||
|
||||
|
||||
<<<
|
||||
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
GRETAP interface bridged with physical
|
||||
|
||||
Test that GRETAP works as it should and that it possible to bridge it.
|
||||
|
||||
"""
|
||||
|
||||
import infamy
|
||||
|
||||
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")
|
||||
|
||||
|
||||
with test.step("Configure DUTs"):
|
||||
left.put_config_dicts({ "ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": leftlink,
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": "192.168.50.1",
|
||||
"prefix-length": 24
|
||||
}],
|
||||
"forwarding": True
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": leftdata,
|
||||
"bridge-port": {
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "br0",
|
||||
"type": "infix-if-type:bridge"
|
||||
},
|
||||
{
|
||||
"name": "gre0",
|
||||
"type": "infix-if-type:gretap",
|
||||
"gre": {
|
||||
"local": "192.168.50.1",
|
||||
"remote": "192.168.50.2"
|
||||
},
|
||||
"bridge-port": {
|
||||
"bridge": "br0"
|
||||
}
|
||||
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
right.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": rightlink,
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": "192.168.50.2",
|
||||
"prefix-length": 24
|
||||
}],
|
||||
"forwarding": True
|
||||
},
|
||||
"ipv6": {
|
||||
"address": [{
|
||||
"ip": "2001:db8:3c4d:50::2",
|
||||
"prefix-length": 64
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "gre0",
|
||||
"type": "infix-if-type:gretap",
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": "192.168.10.2",
|
||||
"prefix-length": 24
|
||||
}],
|
||||
"forwarding": True
|
||||
},
|
||||
"gre": {
|
||||
"local": "192.168.50.2",
|
||||
"remote": "192.168.50.1"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
})
|
||||
_, hport = env.ltop.xlate("host", "data")
|
||||
with test.step("Test connectivity host:data to right:gre0 at 192.168.10.2"):
|
||||
with infamy.IsolatedMacVlan(hport) as ns0:
|
||||
ns0.addip("192.168.10.1")
|
||||
ns0.must_reach("192.168.10.2")
|
||||
|
||||
test.succeed()
|
||||
@@ -0,0 +1,35 @@
|
||||
graph "gre-basic" {
|
||||
layout="neato";
|
||||
overlap="false";
|
||||
esep="+40";
|
||||
|
||||
node [shape=record, fontname="DejaVu Sans Mono, Book"];
|
||||
edge [color="cornflowerblue", penwidth="2", fontname="DejaVu Serif, Book"];
|
||||
|
||||
host [
|
||||
label="host | { <mgmt1> mgmt1 } | { <data> data } | { <mgmt2> mgmt2 }"
|
||||
pos="3,0!",
|
||||
kind="controller",
|
||||
];
|
||||
|
||||
left [
|
||||
label="{ left } | { <mgmt> mgmt } | { <data> data } | { <link> link }",
|
||||
pos="0, -3!",
|
||||
|
||||
kind="infix",
|
||||
];
|
||||
|
||||
right [
|
||||
label="{ <link> link } | { <mgmt> mgmt } | { right }",
|
||||
pos="8,-3!",
|
||||
|
||||
kind="infix",
|
||||
];
|
||||
|
||||
host:mgmt1 -- left:mgmt [kind=mgmt, color="lightgray"]
|
||||
host:data -- left:data [taillabel="192.168.10.2/24 ", fontcolor="black", color="black"]
|
||||
host:mgmt2 -- right:mgmt [kind=mgmt, color="lightgray"]
|
||||
|
||||
|
||||
left:link -- right:link [headlabel=".1\n\n", label="192.168.50.0/24", taillabel="\n.2", labeldistance=1, fontcolor="black", color="black"]
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
|
||||
<!-- Title: gre-basic Pages: 1 -->
|
||||
<svg width="552pt" height="183pt"
|
||||
viewBox="0.00 0.00 552.37 183.24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 179.24)">
|
||||
<title>gre-basic</title>
|
||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-179.24 548.37,-179.24 548.37,4 -4,4"/>
|
||||
<!-- host -->
|
||||
<g id="node1" class="node">
|
||||
<title>host</title>
|
||||
<polygon fill="none" stroke="black" points="129.01,-138.74 129.01,-174.74 345.01,-174.74 345.01,-138.74 129.01,-138.74"/>
|
||||
<text text-anchor="middle" x="154.01" y="-153.04" font-family="DejaVu Sans Mono, Book" font-size="14.00">host</text>
|
||||
<polyline fill="none" stroke="black" points="179.01,-138.74 179.01,-174.74 "/>
|
||||
<text text-anchor="middle" x="208.01" y="-153.04" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt1</text>
|
||||
<polyline fill="none" stroke="black" points="237.01,-138.74 237.01,-174.74 "/>
|
||||
<text text-anchor="middle" x="262.01" y="-153.04" font-family="DejaVu Sans Mono, Book" font-size="14.00">data</text>
|
||||
<polyline fill="none" stroke="black" points="287.01,-138.74 287.01,-174.74 "/>
|
||||
<text text-anchor="middle" x="316.01" y="-153.04" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt2</text>
|
||||
</g>
|
||||
<!-- left -->
|
||||
<g id="node2" class="node">
|
||||
<title>left</title>
|
||||
<polygon fill="none" stroke="black" points="0,-1.73 0,-37.73 200,-37.73 200,-1.73 0,-1.73"/>
|
||||
<text text-anchor="middle" x="25" y="-16.03" font-family="DejaVu Sans Mono, Book" font-size="14.00">left</text>
|
||||
<polyline fill="none" stroke="black" points="50,-1.73 50,-37.73 "/>
|
||||
<text text-anchor="middle" x="75" y="-16.03" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="100,-1.73 100,-37.73 "/>
|
||||
<text text-anchor="middle" x="125" y="-16.03" font-family="DejaVu Sans Mono, Book" font-size="14.00">data</text>
|
||||
<polyline fill="none" stroke="black" points="150,-1.73 150,-37.73 "/>
|
||||
<text text-anchor="middle" x="175" y="-16.03" font-family="DejaVu Sans Mono, Book" font-size="14.00">link</text>
|
||||
</g>
|
||||
<!-- host--left -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>host:mgmt1--left:mgmt</title>
|
||||
<path fill="none" stroke="lightgray" stroke-width="2" d="M208.01,-138.74C208.01,-138.74 75,-37.73 75,-37.73"/>
|
||||
</g>
|
||||
<!-- host--left -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>host:data--left:data</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M262.01,-138.74C262.01,-138.74 125,-37.73 125,-37.73"/>
|
||||
<text text-anchor="middle" x="194.01" y="-127.54" font-family="DejaVu Serif, Book" font-size="14.00">192.168.10.2/24 </text>
|
||||
</g>
|
||||
<!-- right -->
|
||||
<g id="node3" class="node">
|
||||
<title>right</title>
|
||||
<polygon fill="none" stroke="black" points="386.37,-1.73 386.37,-37.73 544.37,-37.73 544.37,-1.73 386.37,-1.73"/>
|
||||
<text text-anchor="middle" x="411.37" y="-16.03" font-family="DejaVu Sans Mono, Book" font-size="14.00">link</text>
|
||||
<polyline fill="none" stroke="black" points="436.37,-1.73 436.37,-37.73 "/>
|
||||
<text text-anchor="middle" x="461.37" y="-16.03" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="486.37,-1.73 486.37,-37.73 "/>
|
||||
<text text-anchor="middle" x="515.37" y="-16.03" font-family="DejaVu Sans Mono, Book" font-size="14.00">right</text>
|
||||
</g>
|
||||
<!-- host--right -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>host:mgmt2--right:mgmt</title>
|
||||
<path fill="none" stroke="lightgray" stroke-width="2" d="M345.01,-156.74C345.01,-156.74 461.37,-37.73 461.37,-37.73"/>
|
||||
</g>
|
||||
<!-- left--right -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>left:link--right:link</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M200,-19.73C200,-19.73 386.37,-19.73 386.37,-19.73"/>
|
||||
<text text-anchor="middle" x="293.18" y="-8.53" font-family="DejaVu Serif, Book" font-size="14.00">192.168.50.0/24</text>
|
||||
<text text-anchor="middle" x="377.31" y="-28.25" font-family="DejaVu Serif, Book" font-size="14.00">.1</text>
|
||||
<text text-anchor="middle" x="209.06" y="-3.8" font-family="DejaVu Serif, Book" font-size="14.00">.2</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
@@ -64,3 +64,9 @@
|
||||
|
||||
- name: vlan_iface_termination
|
||||
case: vlan_iface_termination/test.py
|
||||
|
||||
- name: gre_basic
|
||||
case: gre_basic/test.py
|
||||
|
||||
- name: gretap_bridged
|
||||
case: gretap_bridged/test.py
|
||||
|
||||
Reference in New Issue
Block a user