Documentation > Userspace Clients > Atomic Configuration

Atomic Configuration

Index

  1. Introduction
  2. Syntax
  3. Semantics
  4. Examples
    1. SIIT
    2. NAT64
  5. Changes from Jool 3

Introduction

“Atomic Configuration” is a means to set up more than one of Jool’s parameters at once (using a single jool/jool_siit call). Either all or none of the new configuration will be applied, so you don’t have to worry about rolling back.

You can also think of it as “file configuration mode,” since JSON files are the means through which Atomic Configuration is retrieved.

Syntax

SIIT NAT64
jool_siit [-i <instance name>] file handle <path to json file> [--force]
jool      [-i <instance name>] file handle <path to json file> [--force]

--force silences warnings. (If you don’t silence them, sometimes they will cause operation abortion; eg. overlapping EAM entries.)

Semantics

The file describes one Jool instance. If the instance does not exist, it will be created. If it does exist, it will be updated. It will be an ordinary instance; you can subsequently apply any non-atomic operations on it, and delete it using instance remove as usual.

Most of the options are the same as their userspace client counterparts, so see Examples for a couple of full JSON files with embedded links to the relevant client documentation.

On the top level, the mandatory fields are the instance name (either through the -i client argument or the instance JSON tag) and the framework tag (which must be set to either netfilter or iptables).

Aside from vital fields from individual entries, everything else is optional, and will be initialized (or reinitialized) to default values (NOT “old” values!) on omission.

Unrecognized tags will trigger errors, but any amount of comments are allowed (and ignored) on all object contexts.

Examples

SIIT

{
	"comment": "Sample full SIIT configuration.",

	"instance": "instance name",
	"framework": "netfilter",

	"global": {
		"comment": "pool6 and the RFC6791v4 pool belong here, ever since Jool 4.",
		"pool6": "64:ff9b::/96",
		"manually-enabled": false,
		"zeroize-traffic-class": true,
		"override-tos": false,
		"tos": 254,
		"mtu-plateaus": [1, 2, 3, 4, 5, 6],
		"amend-udp-checksum-zero": true,
		"eam-hairpin-mode": "simple",
		"randomize-rfc6791-addresses": false,
		"rfc6791v6-prefix": null,
		"rfc6791v4-prefix": null
	},

	"eamt": [
		{
			"comment": {
				"text": "Here's a compound comment.",
				"more": "Its type is not checked, after all.",
				"date": "2019-01-06",
				"whatever": 1234
			},
			"ipv6 prefix": "2001:db8:1::/128",
			"ipv4 prefix": "192.0.2.0"
		}, {
			"ipv6 prefix": "2001:db8:2::",
			"ipv4 prefix": "192.0.2.1/32"
		}, {
			"ipv6 prefix": "2001:db8:3::/124",
			"ipv4 prefix": "192.0.2.16/28"
		}
	],

	"comment": "This comment is relevant to blacklist4 maybe.",
	"blacklist4": [
		"198.51.100.0",
		"198.51.100.2/32",
		"198.51.100.32/27"
	]
}

Conceptually, updating an SIIT instance through atomic configuration is the same as dropping it and creating it anew. In practice, the former prevents the small window of time in which no translator exists.

NAT64

There is one major caveat here: The current implementation of BIB/session is not suitable to guarantee the atomicity of simultaneous modifications to a running database. Therefore, the bib tag below is only handled if the JSON file is being used to create a new instance. It will be silently ignored on updates.

Sorry. This does not necessarily mean that atomic updating of static BIB entries will never be implemented, but there are no plans for now.

Also, pool6 is mandatory and immutable (as normal). It must be set during instance creation and retain the same value on subsequent updates.

{
	"comment": "Sample full NAT64 configuration.",

	"instance": "instance name",
	"framework": "netfilter",

	"global": {
		"pool6": "64:ff9b::/96",

		"manually-enabled": false,

		"zeroize-traffic-class": true,
		"override-tos": false,
		"tos": 254,
		"mtu-plateaus": [1, 2, 3, 4, 5, 6],
		"maximum-simultaneous-opens": 16,
		"source-icmpv6-errors-better": true,
		"handle-rst-during-fin-rcv": true,
		"f-args": 10,

		"logging-bib": true,
		"logging-session": true,

		"address-dependent-filtering": true,
		"drop-icmpv6-info": true,
		"drop-externally-initiated-tcp": true,

		"udp-timeout": "1:00:00",
		"tcp-est-timeout": "10:00:00",
		"tcp-trans-timeout": "5:00",
		"icmp-timeout": "5:30",

		"ss-enabled": true,
		"ss-flush-asap": false,
		"ss-flush-deadline": 1000,
		"ss-capacity": 256,
		"ss-max-payload": 600
	},

	"pool4": [
		{
			"mark": 1,
			"protocol": "UDP",
			"prefix": "192.0.2.1",
			"port range": "61001-62000"
		}, {
			"mark": 1,
			"protocol": "ICMP",
			"prefix": "192.0.2.1/32",
			"port range": "1000-2000"
		}, {
			"comment": "protocol and port range are optional.",
			"protocol": "TCP",
			"prefix": "192.0.2.2/31"
		}
	],
	
	"bib": [
		{
			"protocol": "TCP",
			"ipv6 address": "2001:db8::1#80",
			"ipv4 address": "192.0.2.2#80"
		}, {
			"protocol": "UDP",
			"ipv6 address": "2001:db8::2#10000",
			"ipv4 address": "192.0.2.1#61500"
		}, {
			"protocol": "ICMP",
			"ipv6 address": "2001:db8:AAAA::1#44",
			"ipv4 address": "192.0.2.1#1044"
		}
	]
}

Updating a NAT64 instance through atomic configuration is not the same as dropping the instance and then creating another one in its place. Aside from skipping the translatorless time window through the former, you get to keep the BIB/session database.

Changes from Jool 3

  1. pool6 and the RFC 6791 IPv4 pool were moved to the global object. (They used to be in the root.)
  2. On NAT64, pool6 is immutable now.
  3. Added the instance (the instance name) and framework (netfilter or iptables) tags.
  4. In object contexts,
    1. Comment tags are now allowed.
    2. Unknown tags are no longer allowed.
    3. Tag redeclarations are no longer allowed. (Even if they define the same value.)
  5. Configuration of static BIB entries is now supported (but only on instance creation).
  6. The configuration is not incremental anymore. (See the following paragraphs for an explatation.)

Jool 3’s atomic configuration used to try to retain old values when instances were being updated. For example, if an existing instance’s logging-bib option was set to the non-default true, then an atomic configuration run using a JSON file that lacked the logging-bib tag would result in logging-bib remaining true rather than resetting.

Despite the good intentions, this turned to be inconsistent, and therefore hard to explain and error-prone. This is because of the databases.

If the blacklist database has prefixes 192.0.2/24, 198.51.100/24, 203.0.113/24, then what should happen if the user runs atomic configuration with blacklist prefix 192.0.2.128/23? Should Jool reject it because of collision? Did they meant to replace the first prefix? And if Jool treated it that way, then what would the user have to do to delete the other prefixes? Obviously, that was a dead end, so databases were always completely replaced as long as the base tag (blacklist4 in this case) existed.

So individual global values survived reconfigurations, but individual database entries did not.

Starting from Jool 4, all tags work the same, which is to say, the JSON file is a snapshot of the ENTIRE configuration at a given time. Anything that’s absent from the file will be mercilessly defaulted during updates.

This also leads to simpler code.