Skip to content

Commit c570445

Browse files
committed
Add DuplicateAddressDetection settings for systemd-networkd
* implement configuration key duplicate-address-detection * documentation of the parameter * adding a few tests
1 parent 83a8d8c commit c570445

File tree

13 files changed

+83
-3
lines changed

13 files changed

+83
-3
lines changed

doc/netplan-yaml.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,12 @@ Match devices by MAC when setting options like: `wakeonlan` or `*-offload`.
422422
> In addition to the addresses themselves one can specify configuration
423423
> parameters as mappings. Current supported options are:
424424

425+
- **`duplicate-address-detection`** (scalar)
426+
427+
> Configure the duplicate address detection (DAD). Valid options
428+
> are `ipv4`, `ipv6`, `both` or `none`. Currently supported on the
429+
> networkd back end only.
430+
425431
- **`lifetime`** (scalar) – since 0.100
426432

427433
> Default: `forever`. This can be `forever` or `0` and corresponds
@@ -445,6 +451,8 @@ Match devices by MAC when setting options like: `wakeonlan` or `*-offload`.
445451
- "10.0.0.15/24":
446452
lifetime: 0
447453
label: "maas"
454+
- "169.254.10.1/24":
455+
duplicate-address-detection: "none"
448456
- "2001:1::1/64"
449457
```
450458

python-cffi/netplan/_build_cffi.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
char* address;
4141
char* lifetime;
4242
char* label;
43+
char* duplicate_address_detection;
4344
} NetplanAddressOptions;
4445
struct address_iter { ...; };
4546
struct nameserver_iter { ...; };

python-cffi/netplan/netdef.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,10 +211,11 @@ def __next__(self):
211211

212212

213213
class NetplanAddress:
214-
def __init__(self, address: str, lifetime: str, label: str):
214+
def __init__(self, address: str, lifetime: str, label: str, duplicate_address_detection: str):
215215
self.address = address
216216
self.lifetime = lifetime
217217
self.label = label
218+
self.duplicate_address_detection = duplicate_address_detection
218219

219220
def __str__(self) -> str:
220221
return self.address
@@ -241,7 +242,9 @@ def __next__(self):
241242
address = ffi.string(content.address).decode('utf-8') if content.address else None
242243
lifetime = ffi.string(content.lifetime).decode('utf-8') if content.lifetime else None
243244
label = ffi.string(content.label).decode('utf-8') if content.label else None
244-
return NetplanAddress(address, lifetime, label)
245+
duplicate_address_detection = ffi.string(content.duplicate_address_detection).decode('utf-8') \
246+
if content.duplicate_address_detection else None
247+
return NetplanAddress(address, lifetime, label, duplicate_address_detection)
245248

246249

247250
class _NetdefNameserverIterator:

src/netplan.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,7 @@ write_addresses(yaml_event_t* event, yaml_emitter_t* emitter, const NetplanNetDe
420420
YAML_MAPPING_OPEN(event, emitter);
421421
YAML_NONNULL_STRING(event, emitter, "label", opts->label);
422422
YAML_NONNULL_STRING(event, emitter, "lifetime", opts->lifetime);
423+
YAML_NONNULL_STRING(event, emitter, "duplicate-address-detection", opts->duplicate_address_detection);
423424
YAML_MAPPING_CLOSE(event, emitter);
424425
YAML_MAPPING_CLOSE(event, emitter);
425426
}

src/networkd.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,8 @@ write_addr_option(NetplanAddressOptions* o, GString* s)
767767
g_assert(o->address != NULL);
768768
g_string_append_printf(s, "Address=%s\n", o->address);
769769

770+
if (o->duplicate_address_detection)
771+
g_string_append_printf(s, "DuplicateAddressDetection=%s\n", o->duplicate_address_detection);
770772
if (o->lifetime)
771773
g_string_append_printf(s, "PreferredLifetime=%s\n", o->lifetime);
772774
if (o->label)

src/parse.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1393,9 +1393,22 @@ handle_address_option_label(NetplanParser* npp, yaml_node_t* node, const void* d
13931393
return handle_generic_str(npp, node, npp->current.addr_options, data, error);
13941394
}
13951395

1396+
STATIC gboolean
1397+
handle_address_option_duplicate_address_detection(NetplanParser* npp, yaml_node_t* node, const void* data, GError** error)
1398+
{
1399+
if (g_ascii_strcasecmp(scalar(node), "ipv4") != 0 &&
1400+
g_ascii_strcasecmp(scalar(node), "ipv6") != 0 &&
1401+
g_ascii_strcasecmp(scalar(node), "both") != 0 &&
1402+
g_ascii_strcasecmp(scalar(node), "none") != 0) {
1403+
return yaml_error(npp, node, error, "invalid duplicate-address-detection value '%s'", scalar(node));
1404+
}
1405+
return handle_generic_str(npp, node, npp->current.addr_options, data, error);
1406+
}
1407+
13961408
const mapping_entry_handler address_option_handlers[] = {
13971409
{"lifetime", YAML_SCALAR_NODE, {.generic=handle_address_option_lifetime}, addr_option_offset(lifetime)},
13981410
{"label", YAML_SCALAR_NODE, {.generic=handle_address_option_label}, addr_option_offset(label)},
1411+
{"duplicate-address-detection", YAML_SCALAR_NODE, {.generic=handle_address_option_duplicate_address_detection}, addr_option_offset(duplicate_address_detection)},
13991412
{NULL}
14001413
};
14011414

src/types-internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ typedef struct {
9797
char* address;
9898
char* lifetime;
9999
char* label;
100+
char* duplicate_address_detection;
100101
} NetplanAddressOptions;
101102

102103
struct address_iter {

src/types.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ free_address_options(void* ptr)
6666
g_free(opts->address);
6767
g_free(opts->label);
6868
g_free(opts->lifetime);
69+
g_free(opts->duplicate_address_detection);
6970
g_free(opts);
7071
}
7172

src/util.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,7 @@ _netplan_address_iter_next(struct address_iter* it)
802802
options->address = g_strdup(netdef_options->address);
803803
options->lifetime = g_strdup(netdef_options->lifetime);
804804
options->label = g_strdup(netdef_options->label);
805+
options->duplicate_address_detection = g_strdup(netdef_options->duplicate_address_detection);
805806
it->last_address = options;
806807
return options;
807808
}

tests/config_fuzzer/schemas/common.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,11 @@ export const common_properties = {
147147
label: {
148148
type: "string",
149149
maxLength: 15,
150+
},
151+
"duplicate-address-detection": {
152+
{
153+
type: "string",
154+
enum: ["ipv4", "ipv6", "both", "none"],
150155
}
151156
}
152157
}

0 commit comments

Comments
 (0)