xlat 0.1.0.alpha1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.dockerignore +7 -0
- data/.rspec +3 -0
- data/Cargo.lock +348 -0
- data/Cargo.toml +7 -0
- data/Dockerfile +49 -0
- data/LICENSE.txt +21 -0
- data/README.md +100 -0
- data/Rakefile +82 -0
- data/benchmark/run.rb +38 -0
- data/benchmark/tcp.cfg +23 -0
- data/clab/.gitignore +5 -0
- data/clab/464xlat-ce-pd.clab.yml +138 -0
- data/clab/build.sh +6 -0
- data/exe/xlat-siit +91 -0
- data/ext/xlat/io_buffer_ext/Cargo.toml +11 -0
- data/ext/xlat/io_buffer_ext/extconf.rb +4 -0
- data/ext/xlat/io_buffer_ext/src/gvl.rs +49 -0
- data/ext/xlat/io_buffer_ext/src/io_buffer.rs +67 -0
- data/ext/xlat/io_buffer_ext/src/lib.rs +83 -0
- data/fuzz/corpus/010507e2c9f3b5132cbf036c7197f155cd85cca8 +0 -0
- data/fuzz/corpus/019a67cbfe27ed6606fe9d9cbee1ba16eb160667 +0 -0
- data/fuzz/corpus/021f01b7a6d4ba3e8e45a733c453d6c84f8c4c38 +0 -0
- data/fuzz/corpus/02db19829d1a4cbe18127e9ab1f3792e0d7fd5f7 +0 -0
- data/fuzz/corpus/059b719daf320e809db75d37ecf7823ba33ca7aa +0 -0
- data/fuzz/corpus/080ce49cbdb1983f8b9af09d511c5ec5a6bb14ed +0 -0
- data/fuzz/corpus/080d7d8674e7d60ce13b48995567a4ad21a3d652 +0 -0
- data/fuzz/corpus/08d488926f31661a1b25f60a723ae1931c762255 +0 -0
- data/fuzz/corpus/09ee56fb3259c88ad2cb94951313d792f36da221 +0 -0
- data/fuzz/corpus/0bffe4074467b5c4ba2bd5aa33839c5a1b8c1d63 +0 -0
- data/fuzz/corpus/0dac63180387255727c844898164ce20ff08fded +0 -0
- data/fuzz/corpus/0dc6f6c09c5b7bb4da8d496ac924e7e0d4aa37ad +0 -0
- data/fuzz/corpus/0e3e8e947fd9bfed02f927d1a2651e484d231fc0 +0 -0
- data/fuzz/corpus/0e5fa83f0ef8ecbf774ac96b8bdeda31395a284d +0 -0
- data/fuzz/corpus/12f93fa0b09c44d6c61ccde2731b5554bb180144 +0 -0
- data/fuzz/corpus/1659c552b9be677f2c30210430a97c3628f615be +0 -0
- data/fuzz/corpus/183aeabfe58d5ccfd5f2ed84e2f5ee4931f14eb7 +0 -0
- data/fuzz/corpus/1b9293272fbacbfff7aff4fd951dd7beb6aed3bf +0 -0
- data/fuzz/corpus/1c30abedb2d0943ef79b0620f7b3a7e8cdebc67f +0 -0
- data/fuzz/corpus/1c479cc892198d0cc389cc681206393c8ae4cbb6 +0 -0
- data/fuzz/corpus/1ca9480af5da2221fc320bb281d7c4ff73d5f33c +0 -0
- data/fuzz/corpus/1d6087f18146fac3b663bcc635fb470cb651884b +0 -0
- data/fuzz/corpus/258d23cbc2c8081782f0dd539270848e275a8e15 +0 -0
- data/fuzz/corpus/27512fa5c0ac5f4d8393ab442b50af3e83047c01 +0 -0
- data/fuzz/corpus/29933024f32228a8b65419d63dcbb56124db0df7 +0 -0
- data/fuzz/corpus/2b19339a2f24978c8413912a8003ae8ba8885684 +0 -0
- data/fuzz/corpus/2f8d2861a271e3ee2f658b01ef6ba854d8837aff +0 -0
- data/fuzz/corpus/2fed10d20fc4ed25da9cebd41209886304b39465 +0 -0
- data/fuzz/corpus/30fd38c3af4877eda7b1ca2dee1a60c4fe0f757c +0 -0
- data/fuzz/corpus/3137ba78351b6757255261a4f364e44693c3c85f +0 -0
- data/fuzz/corpus/34e68133b209c490f960f9682d33d41aab99e60f +0 -0
- data/fuzz/corpus/359870740db1c245d6dfdad1f119c7b17c3f25fc +0 -0
- data/fuzz/corpus/37b1bb01b0544125df396b925e2c4242a90d1c52 +0 -0
- data/fuzz/corpus/387cab0f8ac36f0f5496f6b0aed7d6c7ca3f2dbf +0 -0
- data/fuzz/corpus/3c4e48335e11c3bd066bbb43db4bf82249668869 +0 -0
- data/fuzz/corpus/3ec111be62099aaa9b960f4b69c65a3b12962970 +0 -0
- data/fuzz/corpus/3fb2f3f01b304e48d9c60477dfe5834693ef80db +0 -0
- data/fuzz/corpus/40cf2f11c2ea03c56864f5097d2f989b14762426 +0 -0
- data/fuzz/corpus/40cfc6a6a60f2451974522e5450ba6434f61a8bb +0 -0
- data/fuzz/corpus/4c3f43f4654332520eb57a9bcfe95951857272ce +0 -0
- data/fuzz/corpus/4c85fdf6934e86766274dd668f3f69f15c7bbc11 +0 -0
- data/fuzz/corpus/4f708dd44266b8b567e295c03811feef57c0a493 +0 -0
- data/fuzz/corpus/50cfff5d1cfc310686d7c1f38787cb77ec6fd892 +0 -0
- data/fuzz/corpus/53b2e1cb235c4479711d9ac74a375330d69f9e4c +0 -0
- data/fuzz/corpus/560373973be830ca5a34ab8e4d4b25a942ad5ed6 +0 -0
- data/fuzz/corpus/57768a4d41ccb6149219ba3eb7fe9e5b191dc4aa +0 -0
- data/fuzz/corpus/5a7833a1a882226aa3831298fdb0d23b580016d8 +0 -0
- data/fuzz/corpus/5b394ecc62e63d030cfeff7e0c484c233c7e9d63 +0 -0
- data/fuzz/corpus/5c10ea32f35ab603f1acd9b3c3ac3c397c1c690a +0 -0
- data/fuzz/corpus/5d4f6df161ce9c6465641cea9e0e97771f4249cf +0 -0
- data/fuzz/corpus/5f29c11e0f583226dfa98c236b8d48c772bccbf1 +0 -0
- data/fuzz/corpus/603d6df8d387f6b191f9b732d8928638e2deab10 +0 -0
- data/fuzz/corpus/60e17201e5bc64340b37ac96ff6302546c231eea +0 -0
- data/fuzz/corpus/65cc3e13ae39a4cd1b207a3395b5205d3fbcae7b +0 -0
- data/fuzz/corpus/692c3712da22c928e0d1b5f91ea7a74ba6fcdf5f +0 -0
- data/fuzz/corpus/69ee357cc3bda8a068bc875dda0879bb462b4984 +0 -0
- data/fuzz/corpus/6a2310279f4fa43ee4ed3809bc039f8ec7bfdeb4 +0 -0
- data/fuzz/corpus/6bfdbaafbe1d257b49f58b7a2fa3fef51894d76a +0 -0
- data/fuzz/corpus/6d3c4288760aaf7131fb3caebb5b3aad6a1828fd +0 -0
- data/fuzz/corpus/6e2f243fb0020e9bfb797c0100da18a67c8f1cb7 +0 -0
- data/fuzz/corpus/6ee7bf4cd8249100046bd4ba28b6646dfd436bd4 +0 -0
- data/fuzz/corpus/70e0947673dd1cc2680f907ecfde339688c3fadb +0 -0
- data/fuzz/corpus/76b1ab6e0edbfeefd4a23fc8a18f7d5937fe3787 +0 -0
- data/fuzz/corpus/77d6e8a03cec0da5803042fd51030e97fb11f5fd +0 -0
- data/fuzz/corpus/79b7efd2703e6343b8daf769aea6a76b199d7aa2 +0 -0
- data/fuzz/corpus/7ab28e22d79e7f2774ab2b8baaddeedf58f37475 +0 -0
- data/fuzz/corpus/7cb99d73cc9c03dc463a7892b27ae78a857c2450 +0 -0
- data/fuzz/corpus/81f5010a3c5a44639c0fbb6325c163cd5f8b7ee9 +0 -0
- data/fuzz/corpus/8317c66a4178b54bfd405332490dfd82a3949244 +0 -0
- data/fuzz/corpus/871b1e5a6ad58fbd654725c0c280f1aa278cd7b5 +0 -0
- data/fuzz/corpus/879bd3b24e7c968141bf3c69fdfb11da99af8e8e +0 -0
- data/fuzz/corpus/8a6bc02a79659eb0c71d5bc784da0f1b351b4336 +0 -0
- data/fuzz/corpus/8d6d41bc7e792d6737c35d7c989c9772ad3ae1d6 +0 -0
- data/fuzz/corpus/8ee4e2e6827b38feaa739c7a61535087ae1ca91c +0 -0
- data/fuzz/corpus/911a7cad153c517c75ea7d410c4f093865da5b50 +0 -0
- data/fuzz/corpus/932c12b633a087eff4f195da9fed03e202190515 +0 -0
- data/fuzz/corpus/93c883857d41e5cdaaa4c2b04dd316da73c9c519 +0 -0
- data/fuzz/corpus/944e31de1264ab5347f37d1454b6bcdd06b85b51 +0 -0
- data/fuzz/corpus/9882bea35622d45012774dbf8f9658c597f07d51 +0 -0
- data/fuzz/corpus/989f9271f90207d498fb69eeba16b8393f8cc70b +0 -0
- data/fuzz/corpus/9927a043166634231659695111b473cbd19fbeec +0 -0
- data/fuzz/corpus/9a33c2ce796569be8450658c6231936816ee55bb +0 -0
- data/fuzz/corpus/9a51def27a9547cf9aa059809a2d5482f75ae8af +0 -0
- data/fuzz/corpus/9b915fd1452d10a00ae2ecb0d53784a127341e79 +0 -0
- data/fuzz/corpus/9de518e7fb61598ac152a91feaf2d7bbe3e8b943 +0 -0
- data/fuzz/corpus/9eaee706fb7d021dc5f0ecc79b524de9c74f439e +0 -0
- data/fuzz/corpus/9ecb6bbe9d4c7414406e4c002b449279bf898ee4 +0 -0
- data/fuzz/corpus/a389244e26c3e525393db7c6b89495981c5160e5 +0 -0
- data/fuzz/corpus/a52173807baf225d705386e47e57a115a8cb537c +0 -0
- data/fuzz/corpus/a6fdb8761221dfd348c29c9eb224eb5cf5e4849a +0 -0
- data/fuzz/corpus/a76ca8a3f3ffb4ff898f896b65a5bae2d0ed002a +0 -0
- data/fuzz/corpus/a91ff9c074e9503baa27194d220dca03926a4f3d +0 -0
- data/fuzz/corpus/aa66cf1089cea0a8aa7e54394e75d4f2949bba74 +0 -0
- data/fuzz/corpus/aafdf57c09c20115384292e1b39cf7dae6674fff +0 -0
- data/fuzz/corpus/af0d6601066ec5c6bac2f0a57b5753ef2826463d +0 -0
- data/fuzz/corpus/b26766574788c20a8ec6927c19327f3919c7a69f +0 -0
- data/fuzz/corpus/b2b582043818797e2a53a72e3f24e545fbda3b57 +0 -0
- data/fuzz/corpus/b31e0aa5172beb560c264d8b5c84932870271e9e +0 -0
- data/fuzz/corpus/b396625aa6e69a5eef782446bbc09606050abb8a +0 -0
- data/fuzz/corpus/b5693370c14ce015236f7746ee63d0af38ec89e4 +0 -0
- data/fuzz/corpus/b8fd1ed5f8c575a8ac6a7c468bf93f1f96f8edb4 +0 -0
- data/fuzz/corpus/b928cbb72b744adec35cba73db6b09b4c0c8af42 +0 -0
- data/fuzz/corpus/b9e36aaac143135fadf4bbcac8d892a7b515cbaf +0 -0
- data/fuzz/corpus/bae2b0281a4ce082295254dd4f49183ca6b5f2d3 +0 -0
- data/fuzz/corpus/bfdc9d194a5a4ed98adfa14a47cec84ca91aa4ad +0 -0
- data/fuzz/corpus/c2f64ce75de11ecb09496d5d95955da7730872e1 +0 -0
- data/fuzz/corpus/c45f32e7bfa9ea837d6cdd1844d7c8d354981242 +0 -0
- data/fuzz/corpus/c64d7ac2a14b5227524521fab16ff0ca4e5170d6 +0 -0
- data/fuzz/corpus/c6f8466a86b7371cbf715317cbd313f609ee739b +0 -0
- data/fuzz/corpus/c9d6e62a62fffb21687fae534b8113a07f92aee6 +0 -0
- data/fuzz/corpus/d0171338648afb30043ea71f3561c60fd8372a1d +0 -0
- data/fuzz/corpus/d0faa1afa3e94f6a51a1a4c0d3dafb2600592593 +0 -0
- data/fuzz/corpus/d467fc34aec5d7f2b24a3df67dbf99080dc00681 +0 -0
- data/fuzz/corpus/d696b7b20d1cd2a3c2bf47c302afbba1696632c9 +0 -0
- data/fuzz/corpus/d6d7695a3c86643a3ad779b75ea4d00fb535a3d9 +0 -0
- data/fuzz/corpus/d7b303e5aec6bac4311102a324cbea23663b2b20 +0 -0
- data/fuzz/corpus/d8afc09fe51ea23526db161a2a1cdacba0b1fefe +0 -0
- data/fuzz/corpus/d9bb42d0a55b8a200e3dfea84ca2e6e265ef2366 +0 -0
- data/fuzz/corpus/da6d7c1f2a7d5b0dabe71f048c9c1624c8ebdbd9 +0 -0
- data/fuzz/corpus/da70dbded78bc388cd692dc36b9da4697d5b6ad2 +0 -0
- data/fuzz/corpus/da71cde284c9f10c6c6952e2e800558720914c30 +0 -0
- data/fuzz/corpus/dcdfeaf43771474c3b236ffe79e14dc78b3b09ec +0 -0
- data/fuzz/corpus/dcef32e091776dc98ac4a4cf951528857d0b7ce1 +0 -0
- data/fuzz/corpus/ddedc95cd0c2db9ad8895fb33227e3e759f57ed9 +0 -0
- data/fuzz/corpus/de361721e7f714ac3a55ef5839801e0bf3566b37 +0 -0
- data/fuzz/corpus/e1c05af770b1443f8cfeff261affb50b3c551aa0 +0 -0
- data/fuzz/corpus/e62f88307794127ffccadf614b7062c3e78ce5c0 +0 -0
- data/fuzz/corpus/e85854d63d682e0a16f9aefa477a4337dbc63f5d +0 -0
- data/fuzz/corpus/e86666a117e96697f7823d6d61b448a76c7c8c64 +0 -0
- data/fuzz/corpus/e91897c8cefdd583e1d60e6a833fab40d775cff1 +0 -0
- data/fuzz/corpus/eb8ed69481cf71efdac8df0759d28624f2bc40cc +0 -0
- data/fuzz/corpus/ee9308e841589fbabf3013d9366ac6556d82bdf9 +0 -0
- data/fuzz/corpus/ef2a0b39689c489d499abc4188b45fafdba66ab8 +0 -0
- data/fuzz/corpus/f013d9c3de8fe4958ad84c56c651031314a92e26 +0 -0
- data/fuzz/corpus/f19cf033be3041feeee3eefe45ba5adbf2f5d421 +0 -0
- data/fuzz/corpus/f1c9fa3baf1730afaa330216edcb5ba34d2590b0 +0 -0
- data/fuzz/corpus/f1ed8642840969d76fff003dc68e48a717050e72 +0 -0
- data/fuzz/corpus/f2fbe027944e00facddfcb425be9c0269fe3b8b9 +0 -0
- data/fuzz/corpus/f7f6ff7ec8323de5100118914bacde5b4cc81a9e +0 -0
- data/fuzz/corpus/fade0bf074f861cdb9013fbdd3b084a60d9ac858 +0 -0
- data/fuzz/corpus/fd85b215e07f3ce968a5e0b810c6d04930b533e8 +0 -0
- data/fuzz/corpus/fd883fb9a67accfc7c61ddda6a781677cc8efc33 +0 -0
- data/fuzz/corpus/fd8953a87e3026bdb15d52faa387a6d49586cd66 +0 -0
- data/fuzz/corpus/fe46814360987e6b9cdaebf31a8a4ec7d26125b4 +0 -0
- data/fuzz/corpus/ffd623a08d5c93aae2ffed33346316d76d9abf1c +0 -0
- data/fuzz/instrumentation.rb +13 -0
- data/fuzz/run +11 -0
- data/fuzz/test_harness.rb +38 -0
- data/fuzz/test_tracer.rb +16 -0
- data/lib/xlat/adapters/linux_tun.rb +55 -0
- data/lib/xlat/address_translation.rb +32 -0
- data/lib/xlat/address_translators/rfc6052.rb +46 -0
- data/lib/xlat/common.rb +13 -0
- data/lib/xlat/pcap.rb +48 -0
- data/lib/xlat/protocols/icmp/base.rb +76 -0
- data/lib/xlat/protocols/icmp/echo.rb +71 -0
- data/lib/xlat/protocols/icmp/error.rb +70 -0
- data/lib/xlat/protocols/icmp.rb +14 -0
- data/lib/xlat/protocols/ip/ipv4.rb +106 -0
- data/lib/xlat/protocols/ip/ipv6.rb +133 -0
- data/lib/xlat/protocols/ip.rb +208 -0
- data/lib/xlat/protocols/tcp.rb +71 -0
- data/lib/xlat/protocols/tcpudp.rb +52 -0
- data/lib/xlat/protocols/udp.rb +66 -0
- data/lib/xlat/protocols.rb +0 -0
- data/lib/xlat/rfc7915.rb +580 -0
- data/lib/xlat/runner.rb +51 -0
- data/lib/xlat/version.rb +5 -0
- data/lib/xlat.rb +8 -0
- data/sig/xlat.rbs +4 -0
- metadata +246 -0
data/clab/.gitignore
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
name: 464xlat-ue-pd
|
2
|
+
|
3
|
+
# Scenario:
|
4
|
+
# The user equipment (ue) has IPv6-only connectivity with a /64 delegated prefix.
|
5
|
+
# UE performs on-host CLAT using a /96 prefix chosen within its delegated prefix.
|
6
|
+
# The server (sv) has IPv4-only connectivity.
|
7
|
+
# The provider-side translator (plat) provides NAT64 service between UE and the server.
|
8
|
+
#
|
9
|
+
# CLAT is SIIT (xlat), and PLAT is NAT66 (nftables) + SIIT (xlat).
|
10
|
+
#
|
11
|
+
# [ue] <--> [rt1] <--> [plat] <--> [rt2] <--> [sv]
|
12
|
+
#
|
13
|
+
# Addresses:
|
14
|
+
# 64:ff9b::/96 plat: PLAT-side IPv6 prefix (Pref64::/n)
|
15
|
+
# 2001:db8:2::/48 rt1: UE pool
|
16
|
+
# 2001:db8:2:cafe::/64 ue: delegated prefix
|
17
|
+
# 2001:db8:2:cafe::1 ue: primary address
|
18
|
+
# 2001:db8:2:cafe:46:700::/96 ue: CLAT-side IPv6 prefix
|
19
|
+
# 2001:db8:66:d1e0::/96 plat: NAT66 outer prefix (local use)
|
20
|
+
# fe80::1 rt1: link-local
|
21
|
+
# fe80::2 rt2: link-local
|
22
|
+
# fe80::64 plat: link-local
|
23
|
+
# fe80::cafe ue: link-local
|
24
|
+
# 192.0.0.1 ue: loopback address for IPv4 service continuity
|
25
|
+
# 192.0.2.0/24 rt2: server segment
|
26
|
+
# 192.0.2.1 rt2: gateway address for the segment
|
27
|
+
# 192.0.2.80 server: primary address
|
28
|
+
# 203.0.113.0/29 plat: NAT64 outer pool
|
29
|
+
|
30
|
+
mgmt:
|
31
|
+
external-access: false
|
32
|
+
|
33
|
+
topology:
|
34
|
+
nodes:
|
35
|
+
ue:
|
36
|
+
kind: linux
|
37
|
+
image: &image localhost/xlat/xlat
|
38
|
+
cmd: --multiqueue=4 tun-xlat 64:ff9b::/96 2001:db8:2:cafe:46:700::/96
|
39
|
+
exec:
|
40
|
+
- &remove_default_rt sh -c 'ip -4 route del default && ip -6 route del default'
|
41
|
+
- &enable_forwarding sysctl -w net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1
|
42
|
+
- &wait_xlat sh -c 'for i in $(seq 10); do if ip link show tun-xlat; then break; else sleep 1; fi; done'
|
43
|
+
|
44
|
+
# Direct IPv4 traffic to Xlat
|
45
|
+
- ip link set dev tun-xlat up
|
46
|
+
- ip route add 0.0.0.0/0 dev tun-xlat
|
47
|
+
- ip route add 2001:db8:2:cafe:46:700::/96 dev tun-xlat
|
48
|
+
|
49
|
+
# Assign a dummy IPv4 address from IPv4 Service Continuity Prefix [RFC7335]
|
50
|
+
- ip addr add 192.0.0.1/32 dev lo
|
51
|
+
|
52
|
+
# rt1: IPv6 uplink
|
53
|
+
- ip addr add 2001:db8:2:cafe::1/64 dev eth1
|
54
|
+
- ip addr add fe80::cafe/64 dev eth1
|
55
|
+
- ip route add ::/0 via fe80::1 dev eth1
|
56
|
+
|
57
|
+
rt1:
|
58
|
+
kind: linux
|
59
|
+
image: *image
|
60
|
+
entrypoint: /bin/sleep
|
61
|
+
cmd: infinity
|
62
|
+
exec:
|
63
|
+
- *remove_default_rt
|
64
|
+
- *enable_forwarding
|
65
|
+
|
66
|
+
# ue
|
67
|
+
- ip addr add fe80::1/64 dev eth1
|
68
|
+
- ip route add 2001:db8:2:cafe::/64 via fe80::cafe dev eth1
|
69
|
+
|
70
|
+
# plat
|
71
|
+
- ip addr add fe80::1/64 dev eth2
|
72
|
+
- ip route add 64:ff9b::/96 via fe80::64 dev eth2
|
73
|
+
|
74
|
+
plat:
|
75
|
+
kind: linux
|
76
|
+
image: *image
|
77
|
+
cmd: --multiqueue=4 tun-xlat 2001:db8:66:d1e0::/96 64:ff9b::/96
|
78
|
+
env:
|
79
|
+
XLAT_PROFILE: 'on'
|
80
|
+
# XLAT_NOJIT: 'on'
|
81
|
+
exec:
|
82
|
+
- *remove_default_rt
|
83
|
+
- *enable_forwarding
|
84
|
+
- *wait_xlat
|
85
|
+
|
86
|
+
# rt1
|
87
|
+
- ip addr add fe80::64/64 dev eth1
|
88
|
+
- ip route add ::/0 via fe80::1 dev eth1
|
89
|
+
|
90
|
+
# rt2
|
91
|
+
- ip addr add fe80::64/64 dev eth2
|
92
|
+
- ip route add 0.0.0.0/0 via inet6 fe80::2 dev eth2
|
93
|
+
|
94
|
+
# Configure NAT66: Pref64::/96 -> internal prefix + IPv4 outer
|
95
|
+
- nft "add table ip6 nat"
|
96
|
+
- nft "add chain ip6 nat postrouting { type nat hook postrouting priority srcnat; }"
|
97
|
+
- nft "add rule ip6 nat postrouting ip6 daddr 64:ff9b::/96 counter snat to 2001:db8:66:d1e0::cb00:7100/125" # 203.0.113.0/29
|
98
|
+
|
99
|
+
# Direct NAT64 traffic to Xlat
|
100
|
+
- ip link set dev tun-xlat up
|
101
|
+
- ip route add 64:ff9b::/96 dev tun-xlat
|
102
|
+
- ip route add 203.0.113.0/29 dev tun-xlat
|
103
|
+
|
104
|
+
rt2:
|
105
|
+
kind: linux
|
106
|
+
image: *image
|
107
|
+
entrypoint: /bin/sleep
|
108
|
+
cmd: infinity
|
109
|
+
exec:
|
110
|
+
- *remove_default_rt
|
111
|
+
- *enable_forwarding
|
112
|
+
|
113
|
+
# plat
|
114
|
+
- ip addr add fe80::2/64 dev eth1
|
115
|
+
- ip route add 203.0.113.0/29 via inet6 fe80::64 dev eth1
|
116
|
+
|
117
|
+
# sv
|
118
|
+
- ip addr add 192.0.2.1/24 dev eth2
|
119
|
+
|
120
|
+
sv:
|
121
|
+
kind: linux
|
122
|
+
image: busybox
|
123
|
+
cmd: httpd -f -h /tmp
|
124
|
+
exec:
|
125
|
+
- *remove_default_rt
|
126
|
+
- *enable_forwarding
|
127
|
+
|
128
|
+
- sh -c 'echo Hello > /tmp/index.html'
|
129
|
+
|
130
|
+
# rt2: IPv4 uplink
|
131
|
+
- ip addr add 192.0.2.80/24 dev eth1
|
132
|
+
- ip route add 0.0.0.0/0 via 192.0.2.1 dev eth1
|
133
|
+
|
134
|
+
links:
|
135
|
+
- endpoints: ["ue:eth1", "rt1:eth1"]
|
136
|
+
- endpoints: ["plat:eth1", "rt1:eth2"]
|
137
|
+
- endpoints: ["plat:eth2", "rt2:eth1"]
|
138
|
+
- endpoints: ["sv:eth1", "rt2:eth2"]
|
data/clab/build.sh
ADDED
data/exe/xlat-siit
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
require 'optparse'
|
5
|
+
require 'xlat/adapters/linux_tun'
|
6
|
+
require 'xlat/address_translators/rfc6052'
|
7
|
+
require 'xlat/rfc7915'
|
8
|
+
require 'xlat/runner'
|
9
|
+
|
10
|
+
opt = OptionParser.new do |opt|
|
11
|
+
opt.banner = "Usage: #{File.basename($0)} [options] IFNAME SRC::/N DST::/N"
|
12
|
+
opt.on('--multiqueue COUNT', Integer) {|n| @multiqueue = n }
|
13
|
+
end
|
14
|
+
opt.parse!(ARGV)
|
15
|
+
|
16
|
+
if ARGV.size != 3
|
17
|
+
$stderr.puts opt.help
|
18
|
+
exit 1
|
19
|
+
end
|
20
|
+
|
21
|
+
ifname, src_prefix, dst_prefix = *ARGV
|
22
|
+
src_translator = Xlat::AddressTranslators::Rfc6052.new(src_prefix)
|
23
|
+
dst_translator = Xlat::AddressTranslators::Rfc6052.new(dst_prefix)
|
24
|
+
|
25
|
+
def do_work(stderr, ifname, src_translator, dst_translator, multiqueue)
|
26
|
+
logger = Logger.new(stderr)
|
27
|
+
|
28
|
+
Xlat::Adapters::LinuxTun.open(ifname, multiqueue:) do |tun|
|
29
|
+
tun.mtu = 1500
|
30
|
+
|
31
|
+
loop do
|
32
|
+
Xlat::Runner.new(
|
33
|
+
adapter: tun,
|
34
|
+
translator: Xlat::Rfc7915.new(
|
35
|
+
source_address_translator: src_translator,
|
36
|
+
destination_address_translator: dst_translator,
|
37
|
+
),
|
38
|
+
logger:,
|
39
|
+
).run
|
40
|
+
rescue
|
41
|
+
logger.error { $!.full_message }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
begin
|
47
|
+
require 'pf2'
|
48
|
+
rescue LoadError
|
49
|
+
def profile = yield
|
50
|
+
else
|
51
|
+
def profile
|
52
|
+
return yield unless ENV.key?('XLAT_PROFILE')
|
53
|
+
|
54
|
+
Pf2.start(threads: [Thread.current])
|
55
|
+
$profiling = true
|
56
|
+
begin
|
57
|
+
yield
|
58
|
+
ensure
|
59
|
+
$profiling = false
|
60
|
+
Pf2.stop
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
Signal.trap(:USR1) do
|
66
|
+
if $profiling
|
67
|
+
profile = Pf2.stop
|
68
|
+
begin
|
69
|
+
File.write("/tmp/xlat-#$$.pf2profile", profile)
|
70
|
+
ensure
|
71
|
+
Pf2.start
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
RubyVM::YJIT.enable if defined?(RubyVM::YJIT.enable) && !ENV.key?('XLAT_NOJIT')
|
77
|
+
|
78
|
+
if @multiqueue
|
79
|
+
workers = []
|
80
|
+
while true
|
81
|
+
while workers.size < @multiqueue
|
82
|
+
workers << Ractor.new($stderr.dup, ifname, src_translator, dst_translator, true, &method(:do_work))
|
83
|
+
end
|
84
|
+
r, = Ractor.select(*workers)
|
85
|
+
workers.delete(r)
|
86
|
+
end
|
87
|
+
else
|
88
|
+
profile do
|
89
|
+
do_work($stderr, ifname, src_translator, dst_translator, false)
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
use std::{cell::Cell, ffi::c_void, mem, ptr};
|
2
|
+
|
3
|
+
struct Data<'a, F, R>
|
4
|
+
where
|
5
|
+
F: FnOnce() -> R,
|
6
|
+
{
|
7
|
+
fun: F,
|
8
|
+
ret: &'a Cell<Option<R>>,
|
9
|
+
}
|
10
|
+
|
11
|
+
/// Safety: `pdata` must point to a valid `Data<F, R>` object, which will be bitwise-copied.
|
12
|
+
unsafe extern "C" fn trampoline<F, R>(pdata: *mut c_void) -> *mut c_void
|
13
|
+
where
|
14
|
+
F: FnOnce() -> R,
|
15
|
+
{
|
16
|
+
let Data { fun, ret } = unsafe { ptr::read(pdata as *const Data<F, R>) };
|
17
|
+
ret.set(Some(fun()));
|
18
|
+
|
19
|
+
ptr::null_mut()
|
20
|
+
}
|
21
|
+
|
22
|
+
pub fn call_without_gvl2<F, R>(fun: F) -> R
|
23
|
+
where
|
24
|
+
F: FnOnce() -> R,
|
25
|
+
{
|
26
|
+
let cell = Cell::new(None);
|
27
|
+
|
28
|
+
let data = mem::ManuallyDrop::new(Data { fun, ret: &cell });
|
29
|
+
|
30
|
+
loop {
|
31
|
+
unsafe {
|
32
|
+
rb_sys::rb_thread_call_without_gvl2(
|
33
|
+
Some(trampoline::<F, R>),
|
34
|
+
ptr::addr_of!(data) as *mut c_void, // ManuallyDrop is transparent
|
35
|
+
None,
|
36
|
+
ptr::null_mut(),
|
37
|
+
);
|
38
|
+
}
|
39
|
+
|
40
|
+
// If rb_thread_call_without_gvl2 returns before invoking the callback
|
41
|
+
// due to interrupts, the cell remains to be None, and
|
42
|
+
// it's safe to retry because data is not consumed yet.
|
43
|
+
if let Some(r) = cell.take() {
|
44
|
+
return r;
|
45
|
+
}
|
46
|
+
|
47
|
+
unsafe { rb_sys::rb_thread_check_ints() }
|
48
|
+
}
|
49
|
+
}
|
@@ -0,0 +1,67 @@
|
|
1
|
+
use std::{mem::MaybeUninit, ptr};
|
2
|
+
|
3
|
+
use magnus::{
|
4
|
+
rb_sys::{AsRawValue as _, FromRawValue as _},
|
5
|
+
value::{Lazy, ReprValue as _},
|
6
|
+
Error, RClass, Ruby, TryConvert, Value,
|
7
|
+
};
|
8
|
+
|
9
|
+
#[derive(Clone, Copy)]
|
10
|
+
pub struct IOBuffer(Value);
|
11
|
+
|
12
|
+
static RB_C_IO_BUFFER: Lazy<RClass> = Lazy::new(|_ruby| {
|
13
|
+
let val = unsafe { Value::from_raw(rb_sys::rb_cIOBuffer) };
|
14
|
+
RClass::from_value(val).unwrap()
|
15
|
+
});
|
16
|
+
|
17
|
+
impl IOBuffer {
|
18
|
+
pub fn from_value(val: Value) -> Option<Self> {
|
19
|
+
if val.is_kind_of(Ruby::get_with(val).get_inner(&RB_C_IO_BUFFER)) {
|
20
|
+
Some(IOBuffer(val))
|
21
|
+
} else {
|
22
|
+
None
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
pub fn get_bytes_for_reading(&self) -> *const [u8] {
|
27
|
+
let mut ptr = MaybeUninit::uninit();
|
28
|
+
let mut len = MaybeUninit::uninit();
|
29
|
+
unsafe {
|
30
|
+
rb_sys::rb_io_buffer_get_bytes_for_reading(
|
31
|
+
self.0.as_raw(),
|
32
|
+
ptr.as_mut_ptr(),
|
33
|
+
len.as_mut_ptr(),
|
34
|
+
);
|
35
|
+
ptr::slice_from_raw_parts(ptr.assume_init().cast::<u8>(), len.assume_init() as usize)
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
pub fn get_bytes_for_writing(&self) -> *mut [u8] {
|
40
|
+
let mut ptr = MaybeUninit::uninit();
|
41
|
+
let mut len = MaybeUninit::uninit();
|
42
|
+
unsafe {
|
43
|
+
rb_sys::rb_io_buffer_get_bytes_for_writing(
|
44
|
+
self.0.as_raw(),
|
45
|
+
ptr.as_mut_ptr(),
|
46
|
+
len.as_mut_ptr(),
|
47
|
+
);
|
48
|
+
ptr::slice_from_raw_parts_mut(
|
49
|
+
ptr.assume_init().cast::<u8>(),
|
50
|
+
len.assume_init() as usize,
|
51
|
+
)
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
impl TryConvert for IOBuffer {
|
57
|
+
fn try_convert(val: Value) -> Result<Self, Error> {
|
58
|
+
Self::from_value(val).ok_or_else(|| {
|
59
|
+
Error::new(
|
60
|
+
Ruby::get_with(val).exception_type_error(),
|
61
|
+
format!("no implicit conversion of {} into IO::Buffer", unsafe {
|
62
|
+
val.classname()
|
63
|
+
},),
|
64
|
+
)
|
65
|
+
})
|
66
|
+
}
|
67
|
+
}
|
@@ -0,0 +1,83 @@
|
|
1
|
+
use std::{
|
2
|
+
fs::File,
|
3
|
+
io::{ErrorKind, IoSlice, IoSliceMut, Read, Write},
|
4
|
+
mem::ManuallyDrop,
|
5
|
+
os::fd::{AsRawFd as _, FromRawFd as _, RawFd},
|
6
|
+
};
|
7
|
+
|
8
|
+
use magnus::{function, prelude::*, Error, Object, RArray, RFile, Ruby};
|
9
|
+
|
10
|
+
mod gvl;
|
11
|
+
mod io_buffer;
|
12
|
+
|
13
|
+
fn file_from_rfile(io: RFile) -> Result<ManuallyDrop<File>, Error> {
|
14
|
+
let raw_fd = io.as_raw_fd();
|
15
|
+
if raw_fd == -1 as RawFd {
|
16
|
+
Err(Error::new(
|
17
|
+
Ruby::get_with(io).exception_io_error(),
|
18
|
+
"closed stream",
|
19
|
+
))
|
20
|
+
} else {
|
21
|
+
// Don't take FD ownership from Ruby
|
22
|
+
Ok(ManuallyDrop::new(unsafe { File::from_raw_fd(raw_fd) }))
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
/// writev(IO, Array[IO::Buffer]) -> Integer
|
27
|
+
fn writev(ruby: &Ruby, io: RFile, bufs: RArray) -> Result<usize, Error> {
|
28
|
+
let mut w = file_from_rfile(io)?;
|
29
|
+
|
30
|
+
let vec = bufs
|
31
|
+
.into_iter()
|
32
|
+
.map(|v| {
|
33
|
+
io_buffer::IOBuffer::try_convert(v)
|
34
|
+
.map(|buf| IoSlice::new(unsafe { &*buf.get_bytes_for_reading() }))
|
35
|
+
})
|
36
|
+
.collect::<Result<Vec<_>, _>>()?;
|
37
|
+
|
38
|
+
loop {
|
39
|
+
match gvl::call_without_gvl2(|| w.write_vectored(&vec)) {
|
40
|
+
Ok(n) => return Ok(n),
|
41
|
+
Err(err) => {
|
42
|
+
if err.kind() != ErrorKind::Interrupted {
|
43
|
+
return Err(Error::new(ruby.exception_io_error(), err.to_string()));
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
/// readv(IO, Array[IO::Buffer]) -> Integer
|
51
|
+
fn readv(ruby: &Ruby, io: RFile, bufs: RArray) -> Result<usize, Error> {
|
52
|
+
let mut r = file_from_rfile(io)?;
|
53
|
+
|
54
|
+
let mut vec = bufs
|
55
|
+
.into_iter()
|
56
|
+
.map(|v| {
|
57
|
+
io_buffer::IOBuffer::try_convert(v)
|
58
|
+
.map(|buf| IoSliceMut::new(unsafe { &mut *buf.get_bytes_for_writing() }))
|
59
|
+
})
|
60
|
+
.collect::<Result<Vec<_>, _>>()?;
|
61
|
+
|
62
|
+
loop {
|
63
|
+
match gvl::call_without_gvl2(|| r.read_vectored(&mut vec)) {
|
64
|
+
Ok(n) => return Ok(n),
|
65
|
+
Err(err) => {
|
66
|
+
if err.kind() != ErrorKind::Interrupted {
|
67
|
+
return Err(Error::new(ruby.exception_io_error(), err.to_string()));
|
68
|
+
}
|
69
|
+
}
|
70
|
+
}
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
#[magnus::init]
|
75
|
+
fn init(ruby: &Ruby) -> Result<(), Error> {
|
76
|
+
// We don't share objects across Ractors
|
77
|
+
unsafe { rb_sys::rb_ext_ractor_safe(true) };
|
78
|
+
|
79
|
+
let module = ruby.define_module("Xlat")?.define_module("IOBufferExt")?;
|
80
|
+
module.define_singleton_method("readv", function!(readv, 2))?;
|
81
|
+
module.define_singleton_method("writev", function!(writev, 2))?;
|
82
|
+
Ok(())
|
83
|
+
}
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|