mirror of
https://github.com/kernelkit/infix.git
synced 2026-08-01 13:23:01 +02:00
Add support for GRE tunnels
Basic support GRE and GRETAP tunnels both for IPv4 and IPv6. Limited support right now, only possible to configure local ip address and remote ip address.
This commit is contained in:
committed by
Mattias Walström
parent
08990556e2
commit
c099d887af
@@ -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;
|
||||
@@ -451,6 +459,9 @@ static bool netdag_must_del(struct lyd_node *dif, struct lyd_node *cif)
|
||||
} else if (!strcmp(iftype, "infix-if-type:veth")) {
|
||||
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")) {
|
||||
if (is_phys_addr_deleted(dif))
|
||||
|
||||
@@ -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