Giter Site home page Giter Site logo

clatd's Introduction

NAME

clatd - a CLAT / SIIT-DC Edge Relay implementation for Linux

DESCRIPTION

clatd implements the CLAT component of the 464XLAT network architecture specified in RFC 6877. It allows an IPv6-only host to have IPv4 connectivity that is translated to IPv6 before being routed to an upstream PLAT (which is typically a Stateful NAT64 operated by the ISP) and there translated back to IPv4 before being routed to the IPv4 internet. This is especially useful when local applications on the host requires actual IPv4 connectivity or cannot make use of DNS64 (for example because they use legacy AF_INET socket calls, or if they are simply not using DNS64).

clatd may also be used to implement an SIIT-DC Edge Relay as described in RFC 7756. In this scenario, the PLAT is in reality a SIIT-DC Border Relay (see RFC 7755) instead of a Stateful NAT64 (see RFC6146). When used as a SIIT-DC Edge Relay, you will probably want to manually configure the settings clat-v4-addr, clat-v6-addr, and plat-prefix to mirror the SIIT-DC Border Relay's configuration.

It relies either on the software package TAYGA by Nathan Lutchansky or on the kernel module nat46 by Andrew Yourtchenko for the actual translation of packets between IPv4 and IPv6 (RFC 6145) TAYGA may be downloaded from its home page at http://www.litech.org/tayga/, nat46 from its repository at https://github.com/ayourtch/nat46.

SYNOPSIS

clatd [options]

OPTIONS

-q

Quiet mode; suppress normal output. This is the same as setting quiet=1. Warnings and errors are still outputted, to silence those too, repeat -q.

-d

Enable debugging output. This is the same as setting debug=1. Repeat for even more debugging output, which is the equivalent of setting debug=2.

-c conf-file

Read configuration settings from conf-file. See section CONFIGURATION below for more info.

-h, --help

Print a brief usage help and exit.

key=value

Set configuration key to value, overriding any setting found in the configuration file. Refer to the section CONFIGURATION below for more info.

INVOCATION

clatd is meant to be run under a daemonising control process such as systemd, upstart, or similar. It is further meant to be (re)started whenever a network interface goes up/down as this might mean a change in the PLAT availability or which prefixes/addresses needs to be used for the CLAT to work. It may also be run directly from the command line. It will run until killed with SIGINT (^C) or SIGTERM, at which point it will clean up after itself and exit gracefully.

See the scripts/ directory in the source distribution for some examples on how to invoke it it.

INSTALLATION

The following commands will quickly download and install the latest version of clatd and its dependencies:

git clone https://github.com/toreanderson/clatd
sudo make -C clatd install installdeps

This will install clatd to /usr/sbin, plus install systemd, upstart, and/or NetworkManager scripts if your distribution appears to be using them, and install all the dependencies. Note that TAYGA isn't available in all RPM-based distros (in particular RHEL and its clones). It is however available in EPEL (see https://fedoraproject.org/wiki/EPEL).

CONFIGURATION

clatd is designed to be able to run without any user-supplied configuration in most cases. However, user-specified configuration settings may be added to the configuration file, the path to which may be given on the command line using the -c option, or if it is not, the default location /etc/clatd.conf is used. Configuration settings may also be given directly on the command line when starting clatd, which takes precedence over settings in the configuration file.

Settings are of the form key=value. A list of recognised keys and their possible values follow below:

quiet=integer (default: 0)

Set this to 1 to suppress normal output from clatd. This is the same as providing the command line option -q. Set it to 2 to additionally suppress warnings and errors. Note that this does not suppress debugging output.

debug=integer (default: 0)

Set this to 1 to get debugging output from clatd, or 2 to get even more of the stuff. These are the equivalent of providing the command line option -d the specified number of times.

script-up=string (no default)

Specify a custom script to be run when clatd is starting up. The invocation of this script is the last thing that happens before TAYGA starts up, so all the preparations have been completed at that point (i.e., the clat-dev exists and has routing/addressing configured, forwarding has been enabled, and so on).

The script is run by the system shell, so you can do everything you could in an interactive shell: run multiple commands by separating them by semi-colon or double ampersands, use standard if/else statements, use variable substitutions, redirect output to files, set up command pipelines, and so on. However it must all be on one line, so if you want to do complex things or use some other programming language it's probably better to put the script itself in a separate executable file and just make script-up invoke that file instead.

If the script returns a nonzero exit status, this is considered a fatal error, and clatd will abort. This can be prevented by appending || true at the end of the script.

All of clatd's configuration settings are available as standard variables in the script's environment (hyphens are replaced with underscores).

Logging or debug messages from the script may simply be sent to stdout, where it will be picked up by the init system along with clatd's own output. The script may of course consult the $quiet and $debug environment variables in order to determine how much output is appropriate.

The script should not be enclosed in quotes in the configuration file (even though it contains whitespace). For example:

script-up=echo `date -Ins`: clatd started on $clat_dev | tee -a ~/clatd.log

If on the other hand you want to supply a script-up containing whitespace directly clatd's command line, quoting is required in order to prevent the shell from splitting it up and into multiple command line arguments. For example:

clatd 'script-up=ip route add 192.0.2.0/24 dev $clat_dev || true'

script-down=string (no default)

This works exactly the same as script-up, only that this script is run right after TAYGA has exited, before the clean-up process of restoring any settings that were changed.

An unsuccessful exit code from script-down will cause clatd to exit unsuccessfully too. Beyond that an unsuccessful exit won't change anything, because script-down is invoked at a point in time where the only thing left for clatd to do is to clean up after itself and exit anyway.

clat-dev=string (default: clat)

The name of the network device used by the CLAT. There should be no reason to change the default, unless you plan on running multiple instances of clatd simultaneously.

clat-v4-addr=ipv4-address (default: 192.0.0.1)

The IPv4 address that will be assigned to the CLAT device. Local applications will bind to this address when communicating with external IPv4 destinations. In a standard 464XLAT environment with a stateful NAT64 serving as the PLAT, there should be no need to change the default.

When using clatd as an SIIT-DC Edge Relay (RFC 7756), you will want to set this to the IPv4 Service Address configured in the SIIT-DC Border Relay. This way, local applications can correctly identify which public address they'll be using on the IPv4 internet, and will be able to provide fully functional references to it in application-level payload, and so on.

The default address is one from RFC 7335.

clat-v6-addr=ipv6-address (default: auto-generated)

The IPv6 address of the CLAT. Traffic to/from the clat-v4-addr will be translated into this address. When using clatd as an SIIT-DC Edge Relay, you will want to set this to the same IPv6 address in the Explicit Address Mapping configured in the SIIT-DC Border Relay.

By default, clatd will attempt to figure out which network device will be used for traffic towards the PLAT, see if there is any SLAAC-based globally scoped addresses on it (i.e., a /64 with '0xfffe' in the middle of the Interface ID), and will if so substitute that '0xfffe' value with '0xc1a7' ("clat") to generate a CLAT IPv6 address.

If only a non-SLAAC global address is found on the PLAT-facing device, clatd will substitute its Interface ID with a random integer and use the result as the CLAT IPv6 address. It will only do so if the prefix length is /120 or smaller, as otherwise the risk of IID collisions is considered to be too high. Note that on most Perl platforms, the rand() function is limited to 48 bits, which means that for longer IIDs, the least significant bits will be all 0.

If multiple addresses are found in either category, the one that shares the longest common prefix with the PLAT prefix will be preferred when deriving the CLAT IPv6 address according to the algorithm described above.

dns64-servers=srv1,[srv2,..] (default: use system resolver)

Comma-separated list of DNS64 servers to use when discovering the PLAT prefix using the method described in RFC 7050. By default, the system resolver is used, but it might be useful to override this in case your ISP doesn't provide you with a DNS64-enabled name server, and you want to test clatd using any of the public DNS64/NAT64 instances on the internet. The first PLAT prefix encountered will be used.

cmd-ip=path (default: assume in $PATH)

Path to the ip binary from the iproute2 package available at https://www.kernel.org/pub/linux/utils/net/iproute2. Required.

cmd-ip6tables=path (default: assume in $PATH)

Path to the ip6tables binary from the netfilter package available at http://netfilter.org. Only required for adding ip6tables rules (see the ip6tables-enable configuration setting).

cmd-tayga=path (default: assume in $PATH)

Path to the tayga binary from the TAYGA package available at http://www.litech.org/tayga. Required.

forwarding-enable=bool (default: yes)

Controls whether or not clatd should enable IPv6 forwarding if necessary. IPv6 forwarding is necessary for clatd to work correctly. It will also ensure that the accept_ra sysctl is to '2' for all devices have it set to '1', in order to prevent any connectivity loss as a result of enabling forwarding.

All sysctls that are modified will be restored to their original values when clatd is shutting down.

ip6tables-enable=bool (default: see below)

Controls whether or not clatd should insert ip6tables rules that permit the forwarding of IPv6 traffic between the CLAT and PLAT devices. Such forwarding must be permitted for clatd to work correctly. Any rules added will be removed when clatd is shutting down.

The default is yes if the ip6tables_filter kernel module is loaded, no if it is not.

plat-dev (default: auto-detect)

Which network device is facing the PLAT (NAT64). By default, this is auto-detected by performing a route table lookup towards the PLAT prefix. This setting is used when setting up generating the CLAT IPv6 address, and when setting up ip6tables rules and Proxy-ND entries.

plat-prefix (default: auto-detect)

The IPv6 translation prefix into which the PLAT maps the IPv4 internet. See RFC 6052 for a closer description. By default, this is auto-detected from DNS64 answers using the method in RFC 7050.

plat-fallback-prefix (no default)

The IPv6 translation prefix fallback. This is used if no plat-prefix is set or auto detected.

proxynd-enable (default: yes)

Controls whether or not clatd should add a Proxy-ND entry for the CLAT IPv6 address on the network device facing the PLAT. This is probably necessary on Ethernet networks (otherwise the upstream IPv6 router won't know where to send packets to the CLAT's IPv6 address), but likely not necessary on point-to-point links like PPP or 3GPP mobile broadband, as in those cases IPv6 ND isn't used. However it doesn't hurt to add Proxy-ND entries in that case, either.

Any entries added wil be removed when clatd is shutting down.

tayga-conffile (default: use a temporary file)

Where to write the TAYGA configuration file. By default, a temporary file will be created (and also deleted when clatd is shutting down), but you may also specify an explicit configuration file here, which will not be deleted on shutdown.

tayga-v4-addr (default: 192.0.0.2)

The IPv4 address assigned to the TAYGA process. This is used for emitting ICMPv4 errors back to the host (i.e., it will show up as the first hop when tracerouting to IPv4 destinations), and you may also ping it to verify that the TAYGA process is still alive and well.

The default address is one from RFC 7335.

v4-conncheck-enable=bool (default: yes)

Whether or not to check if the system has IPv4 connectivity before starting the CLAT. If it does, then clatd will simply exit without doing anything. This is meant so that you can always enable clatd to the system startup scripts or network-up event scripts (such as NetworkManager's dispatcher scripts), but not have clatd interfering with native IPv4 connectivity when this is present.

If you want to always start the CLAT whenever possible, even though the system has IPv4 connectivity, disable this setting. You may instead use the v4-defaultroute-enable and v4-defaultroute-metric settings to prevent clatd from interfering with native IPv4 connectivity.

Note that enabling v4-defaultroute-replace will override v4-conncheck-enable and unconditionally disable IPv4 connectivity checking.

v4-conncheck-delay=seconds (default: 10)

When performing an IPv4 connectivity check, wait this number of seconds before actually doing anything. This is to avoid a race condition where for example IPv6 SLAAC finshes and triggers a network-up event script to start clatd, while IPv4 DHCPv4 is still running in the background. This is at least a likely scenario when using NetworkManager, as it will start the dispatcher scripts as soon as either IPv4 or IPv6 has completed, and IPv6 SLAAC is typically faster than IPv4 DHCPv4.

Set it to 0 to perform the check immediately.

v4-defaultroute-enable=bool (default: yes)

Whether or not to add an IPv4 default route pointing to the CLAT. In a typical 464XLAT environment, you want this. However when using clatd in an environment where native IPv4 connectivity is also present, you might want to disable this and instead control manually which IPv4 destinations is reached through the CLAT and which are not.

v4-defaultroute-replace=bool (default: no)

Instructs clatd to remove any pre-existing IPv4 default routes, replacing it with one pointing to the CLAT (assuming v4-defaultroute-enable is yes). The replacement is temporary, any pre-existing routes that were removed will be restored when clatd is shutting down.

Note that nothing prevents software like a connection manager or a DHCPv4 client daemon from re-adding any replaced routes while clatd is running.

If you enable v4-defaultroute-replace while at the same time disabling v4-defaultroute-enable, clatd will remove any pre-existing IPv4 default routes but not add any of its own.

Setting v4-defaultroute-replace to yes will disable the IPv4 connectivity check.

v4-defaultroute-metric=integer (default: 2048)

The metric of the IPv4 default route pointing to the CLAT. The default is chosen because it is higher than that of a native IPv4 default route added by NetworkManager, which makes it so that the native IPv4 connectivity is preferred if present.

v4-defaultroute-mtu=integer (default: 1260)

The MTU of the default route pointing to the CLAT. The default is the default IPv6 MTU used by TAYGA (1280, which in turn comes from RFC 6145) minus 20 to compensate for the difference in header size between IPv4 and IPv6. This prevents outbound packets from having to be fragmented by TAYGA, and also makes local applications advertise a TCP MSS to their remote peers that prevent them from sending packets beck to us that would require fragmentation.

If you know that the IPv6 Path MTU between the host and the PLAT is larger than 1280, you may increase this, but then you should also recompile TAYGA with a larger ipv6_offlink_mtu setting in conffile.c.

v4-defaultroute-advmss=integer (default: v4-defaultroute-mtu - 40)

The "advmss" value assigned to the the default route potining to the CLAT. This controls the advertised TCP MSS value for TCP connections made through the CLAT.

You should normally not need to set this. By default the value is calculated by taking the value of v4-defaultroute-mtu and substracting 40 (20 bytes for the IPv4 header + 20 bytes for the TCP header). If v4-defaultroute-mtu is unset or 0, there is no default.

LIMITATIONS

clatd will not be able to acquire an IPv6 address for the CLAT if SLAAC isn't used. RFC 6877 suggests DHCPv6 IA_PD should be attempted in this case, but this isn't currently implemented.

clatd will not attempt to perform Duplicate Address Detection for the IPv6 address it generates. This is a violation of RFC 6877.

clatd will not attempt to perform a connectivity check to a discovered PLAT prefix before setting up the CLAT, as RFC 7050 suggest it should.

BUGS

If you are experiencing any bugs or have any feature requests, head over to https://github.com/toreanderson/clatd/issues and submit a new issue (if someone else hasn't already done so). Please make sure to include logs with full debugging output (using -d -d on the command line or debug=2 in the configuration file) when reporting a bug.

LICENCE

Copyright (c) 2014-2023 Tore Anderson <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

SEE ALSO

ip(8), ip6tables(8), tayga(8), tayga.conf(5)

RFC 6052, RFC 6145, RFC 6146, RFC 6877, RFC 7050, RFC 7335 RFC 7755, RFC 7756, RFC 7757

clatd's People

Contributors

gregbo avatar michal-josef-spacek avatar oskar456 avatar thomasschaeferm avatar toreanderson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

clatd's Issues

This system already has IPv4 connectivity; no need for a CLAT

Hi,
i tried to setup it but it seems not working
clatd says system already has ipv4 but its not
i didn't set any manual configuration.(there is no /etc/clatd.conf)
its an ipv6-only openvz vps with debian 11

root@debia1:~# clatd -d
Configuration successfully read, dumping it:
  clat-dev=clat
  clat-v4-addr=192.0.0.1
  clat-v6-addr=<undefined>
  cmd-ip=ip
  cmd-ip6tables=ip6tables
  cmd-tayga=tayga
  debug=1
  dns64-servers=<undefined>
  forwarding-enable=1
  ip6tables-enable=<undefined>
  plat-dev=<undefined>
  plat-prefix=<undefined>
  proxynd-enable=1
  quiet=0
  script-down=<undefined>
  script-up=<undefined>
  tayga-conffile=<undefined>
  tayga-v4-addr=192.0.0.2
  v4-conncheck-delay=10
  v4-conncheck-enable=1
  v4-defaultroute-advmss=0
  v4-defaultroute-enable=1
  v4-defaultroute-metric=2048
  v4-defaultroute-mtu=1260
  v4-defaultroute-replace=0
Starting clatd v1.5 by Tore Anderson <[email protected]>
Performing DNS64-based PLAT prefix discovery (cf. RFC 7050)
Looking up 'ipv4only.arpa' using system resolver
check_wka(): Testing to see if 2001:67c:2960:6464:0:0:c000:ab was DNS64-synthesised
Inferred PLAT prefix 2001:67c:2960:6464::/96 from AAAA record 2001:67c:2960:6464:0:0:c000:ab
check_wka(): Testing to see if 2001:67c:2960:6464:0:0:c000:aa was DNS64-synthesised
Inferred PLAT prefix 2001:67c:2960:6464::/96 from AAAA record 2001:67c:2960:6464:0:0:c000:aa
Using PLAT (NAT64) prefix: 2001:67c:2960:6464::/96
get_plat_dev(): finding which network dev faces the PLAT
get_plat_dev(): Found PLAT-facing device: venet0
Device facing the PLAT: venet0
Attempting to derive a CLAT IPv6 address from an IPv6 address on 'venet0'
Using CLAT IPv4 address: 192.0.0.1
Using CLAT IPv6 address: 2001:41d0:c:e70:1234:1234:5517:1dd4
Checking if this system already has IPv4 connectivity in 10 sec(s)
This system already has IPv4 connectivity; no need for a CLAT.
root@debia1:~# ifconfig 
clat: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
        inet 192.0.0.1  netmask 255.255.255.255  destination 192.0.0.1
        inet6 fe80::12fa:638c:2c1d:91ae  prefixlen 64  scopeid 0x20<link>
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 500  (UNSPEC)
        RX packets 5  bytes 400 (400.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 12  bytes 748 (748.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 130  bytes 7090 (6.9 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 130  bytes 7090 (6.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

venet0: flags=211<UP,BROADCAST,POINTOPOINT,RUNNING,NOARP>  mtu 1500
        inet 127.0.0.1  netmask 255.255.255.255  broadcast 0.0.0.0  destination 127.0.0.1
        inet6 2001:41d0:c:e70:1234:1234:5517:1  prefixlen 112  scopeid 0x0<global>
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 0  (UNSPEC)
        RX packets 7597153  bytes 11249572457 (10.4 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 7578495  bytes 1157799430 (1.0 GiB)
        TX errors 0  dropped 7 overruns 0  carrier 0  collisions 0

venet0:0: flags=211<UP,BROADCAST,POINTOPOINT,RUNNING,NOARP>  mtu 1500
        inet 192.168.0.152  netmask 255.255.252.0  broadcast 192.168.3.255  destination 192.168.0.152
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 0  (UNSPEC)
root@debia1:~# ip address show dev venet0  
2: venet0: <BROADCAST,POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default 
    link/void 
    inet 127.0.0.1/32 scope host venet0
       valid_lft forever preferred_lft forever
    inet 192.168.0.152/22 brd 192.168.3.255 scope global venet0:0
       valid_lft forever preferred_lft forever
    inet6 2001:41d0:c:e70:1234:1234:5517:1/112 scope global 
       valid_lft forever preferred_lft forever

root@debia1:~# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: venet0: <BROADCAST,POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default 
    link/void 
    inet 127.0.0.1/32 scope host venet0
       valid_lft forever preferred_lft forever
    inet 192.168.0.152/22 brd 192.168.3.255 scope global venet0:0
       valid_lft forever preferred_lft forever
    inet6 2001:41d0:c:e70:1234:1234:5517:1/112 scope global 
       valid_lft forever preferred_lft forever


root@debia1:~# ip route
192.168.0.0/22 dev venet0 proto kernel scope link src 192.168.0.152 

root@debia1:~# ip -6 route
2001:41d0:c:e70:1234:1234:5517:0/112 dev venet0 proto kernel metric 256 pref medium
default dev venet0 metric 1024 pref medium

also dns64/nat64 is ok

root@debia1:~# curl myip.ipip.net
?? IP:45.63.43.39  ???:?? ???? ?????  choopa.com

root@debia1:~# ping6 github.com
PING github.com(lb-140-82-121-3-fra.github.com (2001:67c:2960:6464::8c52:7903)) 56 data bytes
64 bytes from lb-140-82-121-3-fra.github.com (2001:67c:2960:6464::8c52:7903): icmp_seq=1 ttl=37 time=13.3 ms
^C
--- github.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 13.337/13.337/13.337/0.000 ms
root@debia1:~# 

Thanks

Question

Hi,

I'm Starting the clatd and output of the command appears as below.

[root@localhost clatd]# clatd
Configuration successfully read, dumping it:
clat-dev=eth2
clat-v4-addr=192.170.1.182
clat-v6-addr=3ffe::101/64
cmd-ip=ip
cmd-ip6tables=ip6tables
cmd-tayga=tayga
debug=2
dns64-servers=2ffe::10.102.218.110
forwarding-enable=1
ip6tables-enable=
plat-dev=
plat-prefix=2ffe::/96
proxynd-enable=1
quiet=1
script-down=
script-up=
tayga-conffile=
tayga-v4-addr=192.0.0.2
v4-conncheck-delay=10
v4-conncheck-enable=1
v4-defaultroute-advmss=0
v4-defaultroute-enable=1
v4-defaultroute-metric=2048
v4-defaultroute-mtu=1260
v4-defaultroute-replace=0
get_plat_dev(): finding which network dev faces the PLAT
cfg(plat-prefix)
cfg(cmd-ip)
get_plat_dev(): Found PLAT-facing device: eth2
cfgint(v4-defaultroute-mtu)
cfgbool(v4-conncheck-enable)
cfgbool(v4-defaultroute-replace)
cfgint(v4-conncheck-delay)
cfg(cmd-ip)
[root@localhost clatd]#

Whether this is correct. How to check whether the process is running

[root@localhost clatd]# ifconfig -a
eth2 Link encap:Ethernet HWaddr B6:09:1B:87:62:99
inet addr:192.170.1.182 Bcast:192.170.1.255 Mask:255.255.255.0
inet6 addr: 3ffe::101/64 Scope:Global
inet6 addr: fe80::b409:1bff:fe87:6299/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8475038 errors:0 dropped:0 overruns:0 frame:0
TX packets:8592595 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:553588243 (527.9 MiB) TX bytes:632604776 (603.2 MiB)
Interrupt:17 Base address:0xa000

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:81435 errors:0 dropped:0 overruns:0 frame:0
TX packets:81435 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:43692915 (41.6 MiB) TX bytes:43692915 (41.6 MiB)

This is my IP config details.

Thanks,
Jaseer

not possible to use with busybox ash/hush shells.

To me this is documentation rather than an actual program. And for most embedded uses it won't work at all. Writing the code as a POSIX sh would help this?

Some say that Staff Westerberg destroyed their childhood, Larry Wall for sure destroyed my youth.

On clat interface: IPv6 UDP Checksum getting set to invalid 0x0000

  • IPv6 UDP checksum is getting set to illegal value 0x0000 while converting an IPv4 packet with UDP checksum 4051 (I have only seen it with 1 checksum value but multiple times). Below are the relevant packets captured on clat interface. I am guessing this v4 to v6 conversion is done by tayga and this bug may not belong here. But hoping to see some feedback if someone has seen this issue. Has anyone seen this issue ?

clat_v4_addr=10.10.0.99
clatd version = 1.2

Details for Packet number 12045 and 12046
No. Time Source srcport Destination dst port Protocol Length Info
12045 0.618743 10.10.0.99 49394 10.20.0.2 57110 TFTP 560 Data Packet, Block: 3011

Frame 12045: 560 bytes on wire (4480 bits), 560 bytes captured (4480 bits)
Linux cooked capture
Internet Protocol Version 4, Src: 10.10.0.99 (10.10.0.99), Dst: 10.20.0.2 (10.20.0.2)
User Datagram Protocol, Src Port: 49394 (49394), Dst Port: 57110 (57110)
    Source Port: 49394 (49394)
    Destination Port: 57110 (57110)
    Length: 524
    Checksum: 0x4051 [validation disabled] <----------
        [Good Checksum: False]
        [Bad Checksum: False]
    [Stream index: 3]
Trivial File Transfer Protocol
    [DESTINATION File: cs2_testfile_0]
    Opcode: Data Packet (3)
    Block: 3011
Data (512 bytes)

0000  32 c4 6b 8c 63 b1 c5 85 cc 3c ee e5 12 af bf 39   2.k.c....<.....9
0010  a9 7a 12 69 18 e4 69 0d 0a f7 e9 e4 c8 ae 6c 69   .z.i..i.......li
0020  f6 73 db d0 2e ad 0d 0a 2c 49 0e c0 af 80 3b 60   .s......,I....;`
0030  74 22 32 72 0d 0a d1 96 8a 12 41 e7 fb 15 95 cb   t"2r......A.....
0040  09 b3 04 4f b8 ba c9 98 46 d0 e9 b3 c0 ec b5 71   ...O....F......q
0050  e7 dd 57 9e 83 07 2a 65 e2 25 c0 fb c1 ca df 06   ..W...*e.%......
0060  b2 a2 e2 47 8c 8a 9d 3b 6c 6a d5 e8 11 fe 94 cc   ...G...;lj......
0070  75 70 5e 65 02 ce 91 6c 92 90 46 61 b4 c9 cb c4   up^e...l..Fa....
0080  c8 05 8a ba 6b 93 7c bd 29 cc 44 c0 42 e0 2f fb   ....k.|.).D.B./.
0090  2e ef e1 db ae cd e5 36 d9 2c d9 54 b1 56 82 90   .......6.,.T.V..
00a0  1e 0c 8c 41 f9 54 90 d8 b4 0e d7 4e 54 c4 9d 9c   ...A.T.....NT...
00b0  ed cb f8 71 ab 35 89 35 34 95 db 8e d8 1b 46 13   ...q.5.54.....F.
00c0  b5 d9 cb 24 29 43 0d 0a 0d 0a 9d b9 91 75 14 e5   ...$)C.......u..
00d0  84 42 b2 89 b3 ca 5c a8 0d 00 84 fa 49 94 ad 5f   .B....\.....I.._
00e0  89 99 98 d4 cc c0 5f b2 ac 9e be 99 c1 39 ff 33   ......_......9.3
00f0  bc fb 70 1f f1 f5 bf 98 62 0c 9a 7f 75 42 e0 e1   ..p.....b...uB..
0100  f7 cf 26 86 b3 ea 4c c0 d4 83 3f db cc 0b 72 08   ..&...L...?...r.
0110  48 15 bf 63 f7 b8 d0 71 0b 43 0d 0a b1 6a 00 ec   H..c...q.C...j..
0120  46 82 bb f6 fb dc 41 da 2b cd 82 ac 06 87 37 19   F.....A.+.....7.
0130  ae 55 60 0b a0 1e c0 56 7a d2 b1 cf c0 79 12 42   .U`....Vz....y.B
0140  e7 e3 72 f6 02 94 e4 ac 5d a2 eb 9e a8 7c 67 f7   ..r.....]....|g.
0150  7d d3 4c ca d3 87 5a 74 e6 97 a3 c8 25 af fb cf   }.L...Zt....%...
0160  46 c0 e7 05 22 f2 ef 5a 39 6a 13 cc 16 ff ab e6   F..."..Z9j......
0170  72 52 71 cb 1c 98 f0 f4 e3 fc 69 3a e6 df 1c b3   rRq.......i:....
0180  d5 a8 5d 5e 78 fc 87 50 0d 0a 91 ef d4 e8 94 56   ..]^x..P.......V
0190  43 ad ca cb 2a f7 a8 03 31 af 1b 04 28 8c 62 2e   C...*...1...(.b.
01a0  e9 58 a0 d3 4c 1c 7e 46 f2 eb c3 55 ea b3 ce b7   .X..L.~F...U....
01b0  cf 68 9f 82 d5 af 83 00 42 b2 eb 0d 0a 90 26 03   .h......B.....&.
01c0  47 9d dc 26 81 e1 d7 f3 57 2f 76 ae 55 80 77 d7   G..&....W/v.U.w.
01d0  b8 62 cd c5 01 fa 43 01 db 57 18 36 71 70 f2 bf   .b....C..W.6qp..
01e0  b5 36 ac 9e 22 48 36 24 84 8d 9c a5 43 a9 33 8b   .6.."H6$....C.3.
01f0  a7 84 7a 5b 52 e6 06 9e 7b 9e 18 38 ae 41 8c 6e   ..z[R...{..8.A.n

No. Time Source srcport Destination dst port Protocol Length Info
12046 0.618751 2001::10:10:a0a:63 49394 2000::10:20:a14:2 57110 TFTP 580 Data Packet, Block: 3011

Frame 12046: 580 bytes on wire (4640 bits), 580 bytes captured (4640 bits)
Linux cooked capture
Internet Protocol Version 6, Src: 2001::10:10:a0a:63 (2001::10:10:a0a:63), Dst: 2000::10:20:a14:2 (2000::10:20:a14:2)
User Datagram Protocol, Src Port: 49394 (49394), Dst Port: 57110 (57110)
    Source Port: 49394 (49394)
    Destination Port: 57110 (57110)
    Length: 524
    Checksum: 0x0000 (Illegal)  <----------
        [Expert Info (Error/Checksum): Illegal Checksum value (0)]
        [Good Checksum: False]
        [Bad Checksum: True]
    [Stream index: 2]
Trivial File Transfer Protocol
    [DESTINATION File: cs2_testfile_0]
    Opcode: Data Packet (3)
    Block: 3011
Data (512 bytes)

0000  32 c4 6b 8c 63 b1 c5 85 cc 3c ee e5 12 af bf 39   2.k.c....<.....9
0010  a9 7a 12 69 18 e4 69 0d 0a f7 e9 e4 c8 ae 6c 69   .z.i..i.......li
0020  f6 73 db d0 2e ad 0d 0a 2c 49 0e c0 af 80 3b 60   .s......,I....;`
0030  74 22 32 72 0d 0a d1 96 8a 12 41 e7 fb 15 95 cb   t"2r......A.....
0040  09 b3 04 4f b8 ba c9 98 46 d0 e9 b3 c0 ec b5 71   ...O....F......q
0050  e7 dd 57 9e 83 07 2a 65 e2 25 c0 fb c1 ca df 06   ..W...*e.%......
0060  b2 a2 e2 47 8c 8a 9d 3b 6c 6a d5 e8 11 fe 94 cc   ...G...;lj......
0070  75 70 5e 65 02 ce 91 6c 92 90 46 61 b4 c9 cb c4   up^e...l..Fa....
0080  c8 05 8a ba 6b 93 7c bd 29 cc 44 c0 42 e0 2f fb   ....k.|.).D.B./.
0090  2e ef e1 db ae cd e5 36 d9 2c d9 54 b1 56 82 90   .......6.,.T.V..
00a0  1e 0c 8c 41 f9 54 90 d8 b4 0e d7 4e 54 c4 9d 9c   ...A.T.....NT...
00b0  ed cb f8 71 ab 35 89 35 34 95 db 8e d8 1b 46 13   ...q.5.54.....F.
00c0  b5 d9 cb 24 29 43 0d 0a 0d 0a 9d b9 91 75 14 e5   ...$)C.......u..
00d0  84 42 b2 89 b3 ca 5c a8 0d 00 84 fa 49 94 ad 5f   .B....\.....I.._
00e0  89 99 98 d4 cc c0 5f b2 ac 9e be 99 c1 39 ff 33   ......_......9.3
00f0  bc fb 70 1f f1 f5 bf 98 62 0c 9a 7f 75 42 e0 e1   ..p.....b...uB..
0100  f7 cf 26 86 b3 ea 4c c0 d4 83 3f db cc 0b 72 08   ..&...L...?...r.
0110  48 15 bf 63 f7 b8 d0 71 0b 43 0d 0a b1 6a 00 ec   H..c...q.C...j..
0120  46 82 bb f6 fb dc 41 da 2b cd 82 ac 06 87 37 19   F.....A.+.....7.
0130  ae 55 60 0b a0 1e c0 56 7a d2 b1 cf c0 79 12 42   .U`....Vz....y.B
0140  e7 e3 72 f6 02 94 e4 ac 5d a2 eb 9e a8 7c 67 f7   ..r.....]....|g.
0150  7d d3 4c ca d3 87 5a 74 e6 97 a3 c8 25 af fb cf   }.L...Zt....%...
0160  46 c0 e7 05 22 f2 ef 5a 39 6a 13 cc 16 ff ab e6   F..."..Z9j......
0170  72 52 71 cb 1c 98 f0 f4 e3 fc 69 3a e6 df 1c b3   rRq.......i:....
0180  d5 a8 5d 5e 78 fc 87 50 0d 0a 91 ef d4 e8 94 56   ..]^x..P.......V
0190  43 ad ca cb 2a f7 a8 03 31 af 1b 04 28 8c 62 2e   C...*...1...(.b.
01a0  e9 58 a0 d3 4c 1c 7e 46 f2 eb c3 55 ea b3 ce b7   .X..L.~F...U....
01b0  cf 68 9f 82 d5 af 83 00 42 b2 eb 0d 0a 90 26 03   .h......B.....&.
01c0  47 9d dc 26 81 e1 d7 f3 57 2f 76 ae 55 80 77 d7   G..&....W/v.U.w.
01d0  b8 62 cd c5 01 fa 43 01 db 57 18 36 71 70 f2 bf   .b....C..W.6qp..
01e0  b5 36 ac 9e 22 48 36 24 84 8d 9c a5 43 a9 33 8b   .6.."H6$....C.3.
01f0  a7 84 7a 5b 52 e6 06 9e 7b 9e 18 38 ae 41 8c 6e   ..z[R...{..8.A.n

tayga ipv6-addr cannot but must be set

Log:

Apr 19 12:12:46 srv12946 clatd[1855]: Checking if this system already has IPv4 connectivity in 10 sec(s)
Apr 19 12:12:46 srv12946 clatd[1855]: Enabling IPv6 forwarding
Apr 19 12:12:46 srv12946 clatd[1855]: Adding ip6tables rules allowing traffic between the CLAT and PLAT devices
Apr 19 12:12:46 srv12946 clatd[1855]: Enabling Proxy-ND for 2a02:180:6:1::203e on eth0
Apr 19 12:12:46 srv12946 clatd[1855]: Creating and configuring up CLAT device 'clat'
Apr 19 12:12:46 srv12946 clatd[1867]: Error: ipv6-addr directive must be specified if prefix is 64:ff9b::/96 and ipv4-addr is a non-global (RFC 1918) address # Edit: this line was not fully copied...
Apr 19 12:12:46 srv12946 clatd[1855]: <error> cmd(tayga --config /etc/tayga.conf --mktun ) returned 0
Apr 19 12:12:46 srv12946 systemd[1]: clatd.service: Main process exited, code=exited, status=1/FAILURE
Apr 19 12:12:46 srv12946 systemd[1]: clatd.service: Failed with result 'exit-code'.

Clatd Config

clat-v6-addr=2a02:180:6:1::203e

tayga-conffile=/etc/tayga.conf
tayga-v4-addr=192.168.255.1
tayga-v6-addr=2a02:180:6:1::203f #tried to use that but it doesnt do anything

ipv4-check maybe improved - wrong result

I have an Vodafone W5101 and an IPv6-native, NAT64-connection.
This device uses ipv4 for management via web and for DNS-Resolvers. Unfortunately the device itself has no CLAT included, so I gave your tool a try:

./clatd
Starting clatd v1.1 by Tore Anderson [email protected]
Performing DNS64-based PLAT prefix discovery (cf. RFC 7050)
Using PLAT (NAT64) prefix: 2a01:198:24c:dfff:1::/96
Device facing the PLAT: wwan0
Attempting to derive a CLAT IPv6 address from a EUI-64 address on 'wwan0'
Using CLAT IPv4 address: 192.0.0.1
Using CLAT IPv6 address: 2a01:198:24c:c152:e5b:8fc1:a727:9a64
Checking if this system already has IPv4 connectivity in 10 sec(s)
This system already has IPv4 connectivity; no need for a CLAT.
hpmini:/home/thomas/clat/clatd # ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
ping: recvmsg: Network is unreachable
WARNING: kernel is not very fresh, upgrade is recommended.
From 192.168.0.1: icmp_seq=2 Destination Net Unreachable
ping: recvmsg: Network is unreachable
From 192.168.0.1: icmp_seq=3 Destination Net Unreachable
ping: recvmsg: Network is unreachable
From 192.168.0.1: icmp_seq=4 Destination Net Unreachable
ping: recvmsg: Network is unreachable
^C
--- 8.8.8.8 ping statistics ---
5 packets transmitted, 0 received, +3 errors, 100% packet loss, time 4002ms

wwan0 Link encap:Ethernet HWaddr 0C:5B:8F:27:9A:64
inet addr:192.168.0.100 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: 2a01:198:24c:c152:cd56:67cb:eaad:9da6/64 Scope:Global
inet6 addr: 2a01:198:24c:c152:e5b:8fff:fe27:9a64/64 Scope:Global
inet6 addr: fe80::e5b:8fff:fe27:9a64/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:14109 errors:0 dropped:0 overruns:0 frame:0
TX packets:13299 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:9125673 (8.7 Mb) TX bytes:69712226 (66.4 Mb)

8: wwan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
link/ether 0c:5b:8f:27:9a:64 brd ff:ff:ff:ff:ff:ff
inet 192.168.0.100/24 brd 192.168.0.255 scope global wwan0
valid_lft forever preferred_lft forever
inet6 2a01:198:24c:c152:cd56:67cb:eaad:9da6/64 scope global temporary dynamic
valid_lft 7054sec preferred_lft 3454sec
inet6 2a01:198:24c:c152:e5b:8fff:fe27:9a64/64 scope global dynamic
valid_lft 7054sec preferred_lft 3454sec
inet6 fe80::e5b:8fff:fe27:9a64/64 scope link
valid_lft forever preferred_lft forever

cat /etc/resolv.conf
Generated by dhcpcd for interface wwan0
search VodafoneMobile.wifivodafonemobile.api
nameserver 192.168.0.1
nameserver 192.168.0.1

ip route
default via 192.168.0.1 dev wwan0
169.254.0.0/16 dev wwan0 scope link
192.168.0.0/24 dev wwan0 proto kernel scope link src 192.168.0.100

ip -6 route
2a01:198:24c:c152::/64 dev wwan0 proto kernel metric 256 expires 7000sec
fe80::/64 dev wwan0 proto kernel metric 256
default via fe80::d27a:b5ff:fe7b:e152 dev wwan0 proto ra metric 1024 expires 1600sec

Looks like working properly but still has no IPv4 connectivity

Hi
I has starting clatd and and below is it outputs, looks like it working properly, but I still could not accessing IPv4 network, netstat displays that there are no sockets created by clatd connect to any NAT64 destnation.

root@srv17086:~# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 2a02:180:6:1::2f58  prefixlen 128  scopeid 0x0<global>
        inet6 fe80::284:edff:fed6:daaa  prefixlen 64  scopeid 0x20<link>
        ether 00:84:ed:d6:da:aa  txqueuelen 1000  (Ethernet)
        RX packets 4012488  bytes 4512357414 (4.2 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 4184256  bytes 4173644024 (3.8 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 3770264  bytes 4218840186 (3.9 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3770264  bytes 4218840186 (3.9 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

root@srv17086:~# clatd -d
readconf('/etc/clatd.conf')
Configuration successfully read, dumping it:
  clat-dev=clat
  clat-v4-addr=192.0.0.1
  clat-v6-addr=2a02:180:6:1::2f58
  cmd-ip=ip
  cmd-ip6tables=ip6tables
  cmd-tayga=tayga
  debug=1
  dns64-servers=2a01:4f8:c2c:123f::1
  forwarding-enable=1
  ip6tables-enable=<undefined>
  plat-dev=<undefined>
  plat-prefix=<undefined>
  proxynd-enable=1
  quiet=0
  script-down=<undefined>
  script-up=<undefined>
  tayga-conffile=<undefined>
  tayga-v4-addr=192.0.0.2
  v4-conncheck-delay=10
  v4-conncheck-enable=1
  v4-defaultroute-advmss=0
  v4-defaultroute-enable=1
  v4-defaultroute-metric=2048
  v4-defaultroute-mtu=1260
  v4-defaultroute-replace=0
Starting clatd v1.5 by Tore Anderson <[email protected]>
Performing DNS64-based PLAT prefix discovery (cf. RFC 7050)
Looking up 'ipv4only.arpa' using DNS64 server 2a01:4f8:c2c:123f::1
check_wka(): Testing to see if 2a01:4f8:c2c:123f:64:3:c000:aa was DNS64-synthesised
Inferred PLAT prefix 2a01:4f8:c2c:123f:64:3::/96 from AAAA record 2a01:4f8:c2c:123f:64:3:c000:aa
check_wka(): Testing to see if 2a01:4f8:c2c:123f:64:3:c000:ab was DNS64-synthesised
Inferred PLAT prefix 2a01:4f8:c2c:123f:64:3::/96 from AAAA record 2a01:4f8:c2c:123f:64:3:c000:ab
check_wka(): Testing to see if 2a00:1098:2b:0:0:0:c000:ab was DNS64-synthesised
Inferred PLAT prefix 2a00:1098:2b::/96 from AAAA record 2a00:1098:2b:0:0:0:c000:ab
check_wka(): Testing to see if 2a00:1098:2b:0:0:0:c000:aa was DNS64-synthesised
Inferred PLAT prefix 2a00:1098:2b::/96 from AAAA record 2a00:1098:2b:0:0:0:c000:aa
check_wka(): Testing to see if 2a00:1098:2c:0:0:1:c000:ab was DNS64-synthesised
Inferred PLAT prefix 2a00:1098:2c::1:0:0/96 from AAAA record 2a00:1098:2c:0:0:1:c000:ab
check_wka(): Testing to see if 2a00:1098:2c:0:0:1:c000:aa was DNS64-synthesised
Inferred PLAT prefix 2a00:1098:2c::1:0:0/96 from AAAA record 2a00:1098:2c:0:0:1:c000:aa
<warn> Multiple PLAT prefixes discovered (2a01:4f8:c2c:123f:64:3::/96 2a00:1098:2b::/96 2a00:1098:2c::1:0:0/96), using the first seen
Using PLAT (NAT64) prefix: 2a01:4f8:c2c:123f:64:3::/96
get_plat_dev(): finding which network dev faces the PLAT
get_plat_dev(): Found PLAT-facing device: eth0
Device facing the PLAT: eth0
Using CLAT IPv4 address: 192.0.0.1
Using CLAT IPv6 address: 2a02:180:6:1::2f58
Checking if this system already has IPv4 connectivity in 10 sec(s)
Reading sysctl /proc/sys/net/ipv6/conf/all/forwarding
/proc/sys/net/ipv6/conf/all/forwarding is set to '0'
Enabling IPv6 forwarding
Reading sysctl /proc/sys/net/ipv6/conf/default/accept_ra
/proc/sys/net/ipv6/conf/default/accept_ra is set to '1'
Changing /proc/sys/net/ipv6/conf/default/accept_ra from 1 to 2 to prevent connectivity loss after enabling IPv6 forwarding
Setting sysctl /proc/sys/net/ipv6/conf/default/accept_ra=2
Reading sysctl /proc/sys/net/ipv6/conf/eth0/accept_ra
/proc/sys/net/ipv6/conf/eth0/accept_ra is set to '1'
Changing /proc/sys/net/ipv6/conf/eth0/accept_ra from 1 to 2 to prevent connectivity loss after enabling IPv6 forwarding
Setting sysctl /proc/sys/net/ipv6/conf/eth0/accept_ra=2
Reading sysctl /proc/sys/net/ipv6/conf/lo/accept_ra
/proc/sys/net/ipv6/conf/lo/accept_ra is set to '1'
Changing /proc/sys/net/ipv6/conf/lo/accept_ra from 1 to 2 to prevent connectivity loss after enabling IPv6 forwarding
Setting sysctl /proc/sys/net/ipv6/conf/lo/accept_ra=2
Setting sysctl /proc/sys/net/ipv6/conf/all/forwarding=1
Adding ip6tables rules allowing traffic between the CLAT and PLAT devices
cmd(ip6tables -I FORWARD -i clat -o eth0 -j ACCEPT)
cmd(ip6tables -I FORWARD -i eth0 -o clat -j ACCEPT)
 on eth0 Proxy-ND for 2a02:180:6:1::2f58
Reading sysctl /proc/sys/net/ipv6/conf/eth0/proxy_ndp
/proc/sys/net/ipv6/conf/eth0/proxy_ndp is set to '0'
Setting sysctl /proc/sys/net/ipv6/conf/eth0/proxy_ndp=1
Enabled Proxy-ND sysctl for eth0
 dev eth0)neighbour add proxy 2a02:180:6:1::2f58
".ror: inet6 address is expected rather than "2a02:180:6:1::2f58
 dev eth0) returned 0hbour add proxy 2a02:180:6:1::2f58
Creating and configuring up CLAT device 'clat'
cmd(tayga --config /tmp/PNqrArs8O7 --mktun -d)
Created persistent tun device clat
cmd(ip link set up dev clat)
cmd(ip -4 address add 192.0.0.1 dev clat)
 dev clat)route add 2a02:180:6:1::2f58
".ror: inet6 prefix is expected rather than "2a02:180:6:1::2f58
 dev clat) returned 0te add 2a02:180:6:1::2f58
Cleanup: Removing CLAT device
cmd(tayga --config /tmp/PNqrArs8O7 --rmtun)
Removed persistent tun device clat
Cleanup: Deleting TAYGA config file '/tmp/PNqrArs8O7'
Cleanup: Resetting forwarding sysctl to 0
Setting sysctl /proc/sys/net/ipv6/conf/all/forwarding=0
Cleanup: Resetting /proc/sys/net/ipv6/conf/default/accept_ra to 1
Setting sysctl /proc/sys/net/ipv6/conf/default/accept_ra=1
Cleanup: Resetting /proc/sys/net/ipv6/conf/eth0/accept_ra to 1
Setting sysctl /proc/sys/net/ipv6/conf/eth0/accept_ra=1
Cleanup: Resetting /proc/sys/net/ipv6/conf/lo/accept_ra to 1
Setting sysctl /proc/sys/net/ipv6/conf/lo/accept_ra=1
Cleanup: Resetting proxy_ndp sysctl to 0
Setting sysctl /proc/sys/net/ipv6/conf/eth0/proxy_ndp=0
on eth0: Removing Proxy-ND entry for 2a02:180:6:1::2f58
 dev eth0)neighbour delete proxy 2a02:180:6:1::2f58
".ror: inet6 address is expected rather than "2a02:180:6:1::2f58
 dev eth0) returned 0hbour delete proxy 2a02:180:6:1::2f58
Cleanup: Removing ip6tables rules allowing traffic between the CLAT and PLAT devices
cmd(ip6tables -D FORWARD -i clat -o eth0 -j ACCEPT)
cmd(ip6tables -D FORWARD -i eth0 -o clat -j ACCEPT)

install script at raspbian detects tayga but still tries to install a rpm or source code alternative

root@raspberrypi4:~# make -C clatd install installdeps 
make: Entering directory '/root/clatd'
# Install the main script
install -m0755 clatd /usr/sbin/clatd
# Install manual page if pod2man is installed
pod2man --name clatd --center "clatd - a CLAT implementation for Linux" --section 8 README.pod /usr/share/man/man8/clatd.8 && gzip -f9 /usr/share/man/man8/clatd.8 || echo "pod2man is required to generate manual page"
# Install systemd service file if applicable for this system
if test -x "/bin/systemctl" && test -d "/etc/systemd/system"; then install -m0644 scripts/clatd.systemd /etc/systemd/system/clatd.service && /bin/systemctl daemon-reload; fi
if test -e "/etc/systemd/system/clatd.service" && test ! -e "/etc/systemd/system/multi-user.target.wants/clatd.service"; then /bin/systemctl enable clatd.service; fi
# Install upstart service file if applicable for this system
if test -x "" && test -d "/etc/init"; then install -m0644 scripts/clatd.upstart /etc/init/clatd.conf; fi
# Install NetworkManager dispatcher script if applicable
if test -d /etc/NetworkManager/dispatcher.d; then install -m0755 scripts/clatd.networkmanager /etc/NetworkManager/dispatcher.d/50-clatd; fi
# .deb/apt-get based distros
if test -x "/usr/bin/apt-get"; then /usr/bin/apt-get -y install perl-base perl-modules libnet-ip-perl libnet-dns-perl libio-socket-inet6-perl iproute2 iptables tayga; fi
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Note, selecting 'perl-modules-5.28' instead of 'perl-modules'
iproute2 is already the newest version (4.20.0-2).
iptables is already the newest version (1.8.2-4).
libio-socket-inet6-perl is already the newest version (2.72-2).
libnet-dns-perl is already the newest version (1.19-1).
libnet-ip-perl is already the newest version (1.26-2).
perl-base is already the newest version (5.28.1-6).
perl-modules-5.28 is already the newest version (5.28.1-6).
tayga is already the newest version (0.9.2-8).
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
# .rpm/DNF/YUM-based distros
if test -x ""; then  -y install perl perl-Net-IP perl-Net-DNS perl-IO-Socket-INET6 perl-File-Temp iproute2 iptables; fi
# If necessary, try to install the TAYGA .rpm using dnf/yum. It is unfortunately not available in all .rpm based distros (in particular CentOS/RHEL).
if test -x "" && test ! -x "/usr/sbin/tayga"; then  -y install tayga || echo "ERROR: Failed to install TAYGA using dnf/yum, the package is probably not included in your distro. Try enabling the EPEL repo <URL: https://fedoraproject.org/wiki/EPEL> and try again, or install TAYGA <URL: http://www.litech.org/tayga> directly from source."; exit 1; fi
make: Leaving directory '/root/clatd'
root@raspberrypi4:~#

clatd command exit code bug

In order to capture the exit code from a system() call, right shift $? by eight bits. Unified diff follows:

--- clatd	2023-11-02 20:49:06
+++ clatd+	2023-11-02 21:10:23
@@ -84,7 +84,7 @@
 #
 # Runs a command. First argument is what subroutine to call to a message if
 # the command doesn't exit successfully, second is the command itself, and
-# any more is the command line arguments.
+# any more are the command line arguments.
 #
 sub cmd {
   my $msgsub = shift;
@@ -98,7 +98,7 @@
     } elsif($? & 127) {
       &{$msgsub}("cmd(@cmd) died with signal ", ($? & 127));
     } else {
-      &{$msgsub}("cmd(@cmd) returned ", ($? >> 127));
+      &{$msgsub}("cmd(@cmd) returned ", ($? >> 8));
     }
   }
   return $?;

question

I am sitting here in Zurich at the ipv6conference. There is a ipv6-only-wifi.

Unfortunately with dhcpv6 only. Is this the reason that clatd doesn't work?
(clatd needs a second address!?)

hpmini:/home/thomas/clat/clatd # ./clatd
Starting clatd v1.1 by Tore Anderson [email protected]
Performing DNS64-based PLAT prefix discovery (cf. RFC 7050)
Using PLAT (NAT64) prefix: 64:ff9b::/96
Device facing the PLAT: wlan0
Attempting to derive a CLAT IPv6 address from a EUI-64 address on 'wlan0'
Using CLAT IPv4 address: 192.0.0.1
Using CLAT IPv6 address: ::c1:a700:0
Checking if this system already has IPv4 connectivity in 10 sec(s)
Enabling IPv6 forwarding
Adding ip6tables rules allowing traffic between the CLAT and PLAT devices
Enabling Proxy-ND for ::c1:a700:0 on wlan0
Creating and configuring up CLAT device 'clat'
Cannot use reserved address ::c1:a700:0 in map directive, aborting...
cmd(tayga --config /tmp/DIJauO7082 --mktun ) returned 0
hpmini:/home/thomas/clat/clatd # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
link/ether 3c:d9:2b:1a:c9:9a brd ff:ff:ff:ff:ff:ff
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether d0:df:9a:93:67:90 brd ff:ff:ff:ff:ff:ff
inet6 2001:8a8:3800:2::35/128 scope global dynamic
valid_lft 10617sec preferred_lft 10617sec
inet6 fe80::d2df:9aff:fe93:6790/64 scope link
valid_lft forever preferred_lft forever
hpmini:/home/thomas/clat/clatd #

I try to use enforce to avoid dhcpv6. May be the the error message can be improved?

Theoretical Deployment: IPv6-Only VPS

I'm experimenting with your clatd project, as I'm developing some hobby projects in some cloud VPSs that are IPv6 only (they're a little cheaper). I was originally just using the public NAT64 service at nat64.net, but found that things we're a bit slow when making lots of requests (though it did "work").

So I thought maybe I could install something directly on my server, which is what led me to clatd (it seems to have the simplest config). Really I just want to access IPv4-only APIs and sites (i.e. GitHub) from my IPv6-only VPS,

Installing and configuring clatd, things seem to work well when pointing my resolv.conf towards the services at nat64.net. But this leads me to two questions:

  1. How is having clatd in the mix any different than what I originally configured (resolv.conf pointing towards nat64.net servers).
  2. Can clatd enable me to use Google or Cloudflare's DNS64 servers? I'd like to rely on them due to proximity / reliability. If clatd uses TAYGA under the hood (which I understand does NAT64), shouldn't this work?

Thanks in advance.

perl install script for necessary modules

Unfortunately I had to install the perl moduels manually after clatd installation.
I've created a script to resolve that issue:
#!/bin/bash
export PERL_MM_USE_DEFAULT=1
perl -MCPAN -e 'install Net::IP'
perl -MCPAN -e 'install IO::Socket::INET6'
perl -MCPAN -e 'install Net::DNS'
perl -MCPAN -e 'reload cpan'

Like I've documented previously in the past:
https://henschel.network/nat464xlat-with-clatd-on-ubuntu-18-04-lts/

I've seen this on Debian and Ubuntu.

How can I make each device in the clat subnet have its own virtual v6 address

The packet source IP from clat 192.0.0.1 will be translated as clat-v6 addr. The destination IP will be translated as plat prefix+dst IP.
TCPDump has checked and is correct.
But if the subnet has many devices, such as 192.168.0.3, 192.168.0.6192.168.0.10,how to make them access external websites correctly and independently

Could not find a global IPv6 address on enp2s0 from which to derive a CLAT IPv6 address

Hi, I have been unable to get this work, when I start clatd I get this error:

Starting clatd v1.5 by Tore Anderson <[email protected]>
Performing DNS64-based PLAT prefix discovery (cf. RFC 7050)
Using PLAT (NAT64) prefix: 64:ff9b::/96
Device facing the PLAT: enp2s0
Attempting to derive a CLAT IPv6 address from an IPv6 address on 'enp2s0'
<error> Could not find a global IPv6 address on enp2s0 from which to derive a CLAT IPv6 address (try setting 'clat-v6-addr')

enp2s0 interface info

2: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 74:86:e2:24:82:7a brd ff:ff:ff:ff:ff:ff
    inet6 [removed]::a5/128 scope global dynamic noprefixroute 
       valid_lft 5254sec preferred_lft 2554sec
    inet6 fe80::5a93:449d:1c08:bd8d/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

How would I get this working? do I need to set clat-v6-addr to something? if so what?

RPM Packaging for Fedora/Redhat/CentOS

This software needs to be built into an RPM package.

I have such a package SPEC file and will submit this soon.

I believe I currently have one for CentOS 6 and I can also build one for CentOS 7.

Need to set advmss on IPv4 default route

Seems the kernel's TCP/IP stack doesn't adjust the TCP MSS of outgoing packets to match the route MTU. This triggers PMTUD and if that doesn't work, blackholes. Fix should be to allow setting the advmss value on the default route clatd adds. Default value should be mtu - 20.

ip -6 route get with netmask failed

Log:

Starting clatd v1.4 by Tore Anderson <[email protected]>
Performing DNS64-based PLAT prefix discovery (cf. RFC 7050)
Using PLAT (NAT64) prefix: 64:ff9b::/96
Error: ipv6: Invalid values in header for get route request.
<error> get_plat_dev(): 'ip -6 route get 64:ff9b::/96' failed

Some example ip -6 route get commands

genoHost ~ $ ip -6 route get 64:ff9b::/96
Error: ipv6: Invalid values in header for get route request.
genoHost ~ $  ip -6 route get 64:ff9b::
64:ff9b:: from :: via fe80::1441:95ff:fe40:f7dc dev wlp4s0 ens3 ra src my::ipv6:addr metric 600 pref medium
genoHost ~ $  ip -6 route get 64:ff9b::8.8.8.8
64:ff9b::808:808 from :: via fe80::1441:95ff:fe40:f7dc dev ens3 proto ra src my::ipv6:addr metric 600 pref medium
genoHost ~ $  ip -6 route get 64:ff9b::1.1.1.1
64:ff9b::101:101 from :: via fe80::1441:95ff:fe40:f7dc dev ens3 proto ra src my::ipv6:addr metric 600 pref medium

Deadlock between clatd.service and network-online.target

I have installed clatd on my Arch Linux box. After that, I noticed that NetworkManager-wait-online.service started to time out. Without the NetworkManager dispatcher script provided by clatd, NetworkManager-wait-online.service does not time out.

I believe (but don't have a good proof yet) this situation is caused by the unit dependencies not being well thought out.

Namely, the NetworkManager dispatcher script calls systemctl restart clatd. At the time it is called, NetworkManager may not yet think that the network is online. But without the script finishing, it will not become online.

Proposal: understand that there are two use cases for clatd, and implement two systemd units for both.

First, the current use case: attempt to configure that clat interface when the system thinks it is online. For that, we need exactly the current systemd unit, and we don't need the dispatcher script.

Second, the dynamic use case: for that, we do need the dispatcher script, but we don't need the network-online.target dependency there. So, it should be a different systemd unit, e.g. nm-clatd.service.

clatd hangs when ufw firewall turned on

Starting clatd v1.6 by Tore Anderson [email protected]
Performing DNS64-based PLAT prefix discovery (cf. RFC 7050)
Looking up 'ipv4only.arpa' using system resolver
No AAAA records was returned for 'ipv4only.arpa'
No PLAT prefix could be discovered. Your ISP probably doesn't provide NAT64/DNS64 PLAT service. Exiting.

plat-fallback-prefix not working

Problem

plat-fallback-prefix appears to be ignored effectively. If plat-prefix is unset and it can't discover one through DNS, it exits with

clatd[40214]: Performing DNS64-based PLAT prefix discovery (cf. RFC 7050)
clatd[40214]: No PLAT prefix could be discovered. Your ISP probably doesn't provide NAT64/D>
systemd[1]: clatd.service: Deactivated successfully.

Example config:

plat-fallback-prefix=2001:db8:64::/96
v4-conncheck-enable=no
v4-defaultroute-metric=50

Possible cause

I suspect the cause is that get_plat_prefix exits before the fallback logic applies:

clatd/clatd

Lines 377 to 381 in 04062b2

} else {
p("No PLAT prefix could be discovered. Your ISP probably doesn't provide",
" NAT64/DNS64 PLAT service. Exiting.");
cleanup_and_exit(0);
}

clatd/clatd

Lines 737 to 738 in 04062b2

$CFG{"plat-prefix"} ||= get_plat_prefix();
$CFG{"plat-prefix"} ||= $CFG{"plat-fallback-prefix"};

So either the fallback has to be moved into get_plat_prefix, or get_plat_prefix shouldn't exit the program but just return null.

SLAAC problem, if more than on prefix at the eth-interface

SLAAC problem, if more than one prefix at the eth-interface (ULA)

Thanks for that great tool!!!

hpmini:/home/thomas/clat/clatd # ./clatd
Starting clatd v1.0 by Tore Anderson [email protected]
Performing DNS64-based PLAT prefix discovery (cf. RFC 7050)
Using PLAT (NAT64) prefix: 2001:67c:2b0:db32:0:1::/96
Device facing the PLAT: eth0
Attempting to derive a CLAT IPv6 address from a EUI-64 address on 'eth0'
Using CLAT IPv4 address: 192.0.0.1
Using CLAT IPv6 address: fd00::3ed9:2bc1:a71a:c99a
Checking if this system already has IPv4 connectivity in 10 sec(s)
Enabling IPv6 forwarding
Adding ip6tables rules allowing traffic between the CLAT and PLAT devices
Enabling Proxy-ND for fd00::3ed9:2bc1:a71a:c99a on eth0
Creating and configuring up CLAT device 'clat'
Created persistent tun device clat
Adding IPv4 default route via the CLAT
Starting up TAYGA, using config file '/tmp/Y_iUnAKxZ9'

hpmini:~ # ip -6 route
2001:6f8:120c::/64 dev eth0 proto kernel metric 256 expires 6796sec
fd00::3ed9:2bc1:a71a:c99a dev clat metric 1024
fd00::/64 dev eth0 proto kernel metric 256 expires 6796sec
fe80::/64 dev eth0 proto kernel metric 256
default via fe80::2665:11ff:fe8f:181f dev eth0 proto ra metric 1024 expires 1396sec

It uses/prefers the Unique Local Addresses. Maybe a check of the correct source for outgoing traffic is useful.

A side effect of this confusion was also, I have seen wrong addresses ( 2001:67c:2b0:db32:3ed9:2bff:fe1a:c99a/64) in my local net, the host with clat as well a further host learned this address. I don't know how you did this without running radvd.

Afterwards I disabled the ULA at my router, and it works in full auto-mode.

hpmini:/home/thomas/clat/clatd # ./clatd
Starting clatd v1.0 by Tore Anderson [email protected]
Performing DNS64-based PLAT prefix discovery (cf. RFC 7050)
Using PLAT (NAT64) prefix: 2001:67c:2b0:db32:0:1::/96
Device facing the PLAT: eth0
Attempting to derive a CLAT IPv6 address from a EUI-64 address on 'eth0'
Using CLAT IPv4 address: 192.0.0.1
Using CLAT IPv6 address: 2001:6f8:120c:0:3ed9:2bc1:a71a:c99a
Checking if this system already has IPv4 connectivity in 10 sec(s)
Enabling IPv6 forwarding
Adding ip6tables rules allowing traffic between the CLAT and PLAT devices
Enabling Proxy-ND for 2001:6f8:120c:0:3ed9:2bc1:a71a:c99a on eth0
Creating and configuring up CLAT device 'clat'
Created persistent tun device clat
Adding IPv4 default route via the CLAT
Starting up TAYGA, using config file '/tmp/gvkgN44R2g'

2001:6f8:120c:0:3ed9:2bc1:a71a:c99a dev clat metric 1024
2001:6f8:120c::/64 dev eth0 proto kernel metric 256 expires 6926sec
fe80::/64 dev eth0 proto kernel metric 256
default via fe80::2665:11ff:fe8f:181f dev eth0 proto ra metric 1024 expires 1526sec

ip -4 route
default dev clat scope link metric 2048 mtu 1260

Thomas Schäfer

clatd in router mode.

Hi, currently clatd runs in Host mode, can it work in routed mode on a box with dual NICs ?

I have a 2nd gateway in my LAN for testing purposes and it has 2 NICs. 1st NIC is dual-stack connected to the LAN, 2nd NIC is IPv6-only connected to a Windows laptop and is IPv6-only too.

Also, PLAT is serving the LAN on the 1st NIC.

This system already has IPv4 connectivity; no need for a CLAT!

Internet not connect 1.1.1.1 or 8.8.8.8 without clat but when install CLAT get error.
OpenWrt 464XLAT work fine. get Error when try clatd
This system already has IPv4 connectivity; no need for a CLAT.
Why?

root@pi:~# service clatd status
● clatd.service - 464XLAT CLAT daemon
     Loaded: loaded (/etc/systemd/system/clatd.service; enabled; vendor preset: enabled)
     Active: inactive (dead) since Sat 2024-01-06 17:03:27 IST; 1s ago
       Docs: man:clatd(8)
    Process: 5914 ExecStart=/usr/sbin/clatd (code=exited, status=0/SUCCESS)
   Main PID: 5914 (code=exited, status=0/SUCCESS)
        CPU: 532ms

Jan 06 17:03:13 pi clatd[5914]: Starting clatd v1.6nat46 by Tore Anderson <[email protected]>
Jan 06 17:03:13 pi clatd[5914]: Performing DNS64-based PLAT prefix discovery (cf. RFC 7050)
Jan 06 17:03:17 pi clatd[5914]: Using PLAT (NAT64) prefix: 64:ff9b::/96
Jan 06 17:03:17 pi clatd[5914]: Device facing the PLAT: eth0
Jan 06 17:03:17 pi clatd[5914]: Attempting to derive a CLAT IPv6 address from an IPv6 address on 'eth0'
Jan 06 17:03:27 pi clatd[5914]: Using CLAT IPv4 address: 192.0.0.1
Jan 06 17:03:27 pi clatd[5914]: Using CLAT IPv6 address: 2409:40c1:40xxxxx57e5:7dc1:6378:0
Jan 06 17:03:27 pi clatd[5914]: Checking if this system already has IPv4 connectivity in 10 sec(s)
Jan 06 17:03:27 pi clatd[5914]: This system already has IPv4 connectivity; no need for a CLAT.
Jan 06 17:03:27 pi systemd[1]: clatd.service: Succeeded.

Needs to work on Mac OS X

This works great on Linux!

Does anyone have any ideas on getting this to work on Mac OS X?

I started to take a look at it and it makes it up to the "ip" command and since Mac OS X doesn't have that, it fails at that point.

I suspect with some way to determine platform and a bit of re-working which commands are called and how they are parsed, the MAC OS X platform could be supported.

Thoughts?

Improve Makefile for packagers

The make install target does stuff like systemctl enable clatd.service and simiar which is not wanted when building distribution packages. It also installs everything with fully qualified paths, whereas package build scripts prefers to install to a designated build area.

So to improve this the make install logic should be split out into separate targets, e.g.:

  • install-clatd: Install clatd + manual page to $(PREFIX) if set, or /
  • install-systemd: Install clatd.service to $(PREFIX) if set, or / (but do not attempt to enable it)
  • install-upstart, install-networkmanager: Idem

install can depend on the targets appropriate for the system and remain suitable for manual user installations, while packagers can directly call the appropriate targets from their .spec or debian/rules files.

systemctl isn't always in /usr/bin

Hi,
The network manager dispatcher makes an assumption that on a systemd-based setup, systemctl will be in /usr/bin/

# systemd-based distros
if test -x /usr/bin/systemctl; then
  /usr/bin/systemctl restart clatd.service
fi

On my system (Ubuntu 16.04LTS), it is in /bin

$ cat /etc/issue.net
Ubuntu 16.04.2 LTS
$ which systemctl
/bin/systemctl

It is trivial to fix manually, but the script could do a better job :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.