Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion README.org
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ module: labn-munet-config
| +--rw new-window? boolean
| +--rw top-level? boolean
+--rw kinds* [name]
| +--rw ip* string
| +--rw ipv6* string
| +--rw merge* string
| +--rw cap-add* string
| +--rw cap-remove* string
Expand Down Expand Up @@ -134,6 +136,8 @@ module: labn-munet-config
| +--rw nodes* [name]
| +--rw id? uint32
| +--rw kind? -> ../../../kinds/name
| +--rw ip* string
| +--rw ipv6* string
| +--rw cap-add* string
| +--rw cap-remove* string
| +--rw cmd? string
Expand Down Expand Up @@ -540,6 +544,14 @@ munet>

grouping common-node {
description "Common node properties";
leaf-list ip {
type string;
description "IPv4 prefixes to set as loopback addresses.";
}
leaf-list ipv6 {
type string;
description "IPv6 prefixes to set as loopback addresses.";
}
leaf-list cap-add {
type string;
description "Capabilities to add to a container.";
Expand Down Expand Up @@ -1153,4 +1165,3 @@ munet>
[ -d /yang ] || DOCKER="sudo podman run --net=host -v $(pwd):/work docker.io/labn/org-rfc"
if ! $DOCKER pyang -P build --lax-quote-checks -Werror --lint $module 2>&1; then echo FAIL; fi
#+end_src

4 changes: 3 additions & 1 deletion doc/source/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ Topology
--------

The topology section defines the networks and nodes that make up the topology
along withe a few global topology options.
along with a few global topology options.

.. pyang labn-munet-config.yang -f tree --tree-path=/topology

Expand Down Expand Up @@ -117,6 +117,8 @@ Tree diagram for node config::
| +--rw nodes* [name]
| +--rw id? uint32
| +--rw kind? -> ../../../kinds/name
| +--rw ip* string
| +--rw ipv6* string
| +--rw cap-add* string
| +--rw cap-remove* string
| +--rw cmd? string
Expand Down
24 changes: 24 additions & 0 deletions munet/munet-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,18 @@
"type": "string"
}
},
"ip": {
"type": "array",
"items": {
"type": "string"
}
},
"ipv6": {
"type": "array",
"items": {
"type": "string"
}
},
"cap-add": {
"type": "array",
"items": {
Expand Down Expand Up @@ -425,6 +437,18 @@
"kind": {
"type": "string"
},
"ip": {
"type": "array",
"items": {
"type": "string"
}
},
"ipv6": {
"type": "array",
"items": {
"type": "string"
}
},
"cap-add": {
"type": "array",
"items": {
Expand Down
28 changes: 22 additions & 6 deletions munet/native.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,24 @@ class L3ContainerNotRunningError(MunetError):


def get_loopback_ips(c, nid):
ips = []
if ip := c.get("ip"):
if ip == "auto":
return [ipaddress.ip_interface("10.255.0.0/32") + nid]
if isinstance(ip, str):
return [ipaddress.ip_interface(ip)]
return [ipaddress.ip_interface(x) for x in ip]
return []
assert nid < 0xFFFF # Limited to 10.255.0.0/16 block
ips.append(ipaddress.ip_interface("10.255.0.0/32") + nid)
elif isinstance(ip, str):
ips.append(ipaddress.ip_interface(ip))
else:
ips.extend([ipaddress.ip_interface(x) for x in ip])
if ipv6 := c.get("ipv6"):
if ipv6 == "auto":
assert nid < 0xFFFF # Same limit as ipv4 for simplicity
ips.append(ipaddress.ip_interface(f"fcfe:ffff:{nid:02x}::1/128"))
elif isinstance(ip, str):
ips.append(ipaddress.ip_interface(ipv6))
else:
ips.extend([ipaddress.ip_interface(x) for x in ipv6])
return ips


def make_ip_network(net, inc):
Expand Down Expand Up @@ -94,6 +105,7 @@ def get_ip_network(c, brid, ipv6=False):
return ifip
except ValueError:
return ipaddress.ip_network(ip)
assert brid < 0xFDFF # Limited to 10.0.0.0/16 through 10.253.0.0/16 blocks
if ipv6:
return make_ip_interface("fc00::fe/64", brid)
return make_ip_interface("10.0.0.254/24", brid)
Expand Down Expand Up @@ -779,12 +791,16 @@ def __init__(self, *args, unet=None, **kwargs):
self.cmd_raises("sysctl -w net.ipv6.conf.all.disable_ipv6=0")
self.cmd_raises("sysctl -w net.ipv6.conf.all.forwarding=1")

assert self.id < 0xFF * (0xFF - 0x7F) # Beyond this, ipv4 address is invalid
assert self.id < 0x7FFF # Limited to 10.254.0.0/16 block
self.next_p2p_network = ipaddress.ip_network(
f"10.254.{self.id & 0xFF}.{(self.id & 0x7F00) >> 7}/31"
)
self.next_p2p_network6 = ipaddress.ip_network(f"fcff:ffff:{self.id:02x}::/127")

if "ip" not in self.config and self.unet.autonumber:
self.config["ip"] = "auto"
if "ipv6" not in self.config and self.unet.autonumber and self.unet.ipv6_enable:
self.config["ipv6"] = "auto"
self.loopback_ip = None
self.loopback_ips = get_loopback_ips(self.config, self.id)
self.loopback_ip = self.loopback_ips[0] if self.loopback_ips else None
Expand Down
2 changes: 2 additions & 0 deletions tests/basic/munet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ topology:
which ping
tail -f /dev/null
- name: r3
ip: ["172.16.0.3/32", "172.16.0.33/32"]
ipv6: ["fe8f:ffff:3::1/128", "fe8f:ffff:33::1/128"]
connections:
- to: "net1"
- to: "r2"
Expand Down
26 changes: 26 additions & 0 deletions tests/basic/test_basic_topology.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ async def test_autonumber_ping(unet_perfunc):
o = await r2.async_cmd_raises("ping -w1 -c1 10.254.2.1")
logging.debug("r2 ping r3 p2p (10.254.2.1) output: %s", o)

o = await r2.async_cmd_raises("ping -w1 -c1 10.255.0.2")
logging.debug("r2 ping lo (10.255.0.2) output: %s", o)

if unet.ipv6_enable:
addr = "fc00:0:0:1::2"
o = await r1.async_cmd_nostatus("ip -6 neigh show dev xyz0")
Expand All @@ -74,10 +77,33 @@ async def test_autonumber_ping(unet_perfunc):
o = await r2.async_cmd_raises("ping -w1 -c1 fcff:ffff:2::1")
logging.debug("r2 ping r3 p2p (fcff:ffff:2::1) output: %s", o)

o = await r2.async_cmd_raises("ping -w1 -c1 fcfe:ffff:2::1")
logging.debug("r2 ping lo (fcfe:ffff:2::1) output: %s", o)

o = await r1.async_cmd_nostatus("ip -6 neigh show")
logging.info("ip -6 neigh show: %s", o)


@pytest.mark.parametrize(
"unet_perfunc", ["munet"], indirect=["unet_perfunc"]
)
async def test_basic_config(unet_perfunc):
unet = unet_perfunc
r3 = unet.hosts["r3"]

o = await r3.async_cmd_raises("ping -w1 -c1 172.16.0.3")
logging.debug("r3 ping lo (172.16.0.3) output: %s", o)

o = await r3.async_cmd_raises("ping -w1 -c1 172.16.0.33")
logging.debug("r3 ping lo (172.16.0.33) output: %s", o)

o = await r3.async_cmd_raises("ping -w1 -c1 fe8f:ffff:3::1")
logging.debug("r3 ping lo (fe8f:ffff:3::1) output: %s", o)

o = await r3.async_cmd_raises("ping -w1 -c1 fe8f:ffff:33::1")
logging.debug("r3 ping lo (fe8f:ffff:33::1) output: %s", o)


@pytest.mark.parametrize("ipv6", [False, True])
@pytest.mark.parametrize("unet_perfunc", [False, True], indirect=["unet_perfunc"])
async def test_mtu_ping(unet_perfunc, astepf, ipv6):
Expand Down
Loading