Support preferred_lft for IPv6 addresses

Bug #1803203 reported by Andy Smith
20
This bug affects 3 people
Affects Status Importance Assigned to Milestone
Netplan
Fix Released
Undecided
Unassigned
netplan.io (Ubuntu)
Fix Released
Medium
Heitor Alves de Siqueira
systemd (Ubuntu)
Fix Released
Medium
Dimitri John Ledkov

Bug Description

There doesn't currently seem to be any way to set the preferred_lft of an IPv6 address.

With the "ip" command it might be, for example:

# ip address add 2001:db8::2/32 dev eth0 preferred_lft 0

In a systemd unit file it might be:

[Match]
Name=eth0

[Network]
Address=2001:db8::2/32
Gateway=2001:db8::1/32
PreferredLifetime=0

but I can't find any way to express this with netplan.

This is commonly used for per-service IP addresses that should never be used as source addresses for outgoing traffic.

Tags: sts
Daniel Axtens (daxtens)
Changed in netplan:
status: New → Confirmed
Revision history for this message
Daniel Axtens (daxtens) wrote :

Hi Andy,

I have another user reporting exactly the same issue and with exactly the same requirement to set the source address for outgoing traffic, so I have set the issue as Confirmed.

I want to discuss the best way to achieve what you want. Do you actually want to be able to set a non-zero lifetime, or do you just want to be able to set the lifetime to zero to disable using that address as a source address?

If you just want to be able to disable an address for use as a source address, that's at least conceptually simple, but I don't have a good way to describe it in the YAML at the moment that doesn't require rewriting large parts of the parser.

If you want to be able to set a non-zero preferred lifetime, I have some follow-up questions:

 - What should the behaviour be when you run netplan apply after the system has booted? Currently it will restart systemd-networkd, which will delete and re-add the address, which will have the effect of resetting the timer.

 - Do you expect something to happen when the preferred lifetime expires? There's no way to describe an action to happen afterwards, so it would be very easy to accidentally specify a configuration that cuts the interface off from IPv6 after some time.

Regards,
Daniel

Revision history for this message
Richard Laager (rlaager) wrote :

Andy, in the interest of full disclosure, I'm the other user that reported this through the paid support channel.

Daniel:

The behavior when the preferred lifetime expires is well-defined and handled automatically by the kernel. 'When an address is assigned to an interface it gets the status "preferred", which it holds during its preferred-lifetime. After that lifetime expires the status becomes "deprecated" and no new connections should be made using this address. The address becomes "invalid" after its valid-lifetime also expires'
-- https://en.wikipedia.org/wiki/IPv6_address#Address_lifetime

So on that note, if you're going to support non-zero lifetimes, you should probably also wire in valid_lft at the same time. It would be just a copy-and-paste of the same code for preferred_lft, and they go together conceptually.

To answer your other question, I think if you re-run "netplan apply", it should reset the timer. But take that with a grain of salt, as I do not personally have a use case for non-zero (and non-forever) preferred lifetimes.

Revision history for this message
Andy Smith (grifferz) wrote :

Hi Daniel,

I am in agreement with Daniel. I too am only interested in "forever" (default) or "0" as the only settings of preferred_lft.

Thanks,
Andy

Revision history for this message
Andy Smith (grifferz) wrote :

As a workaround, here is a networkd-dispatcher hook script which when called will set preferred_lft 0 for all IPv6 addresses on the system, apart from any exceptions you list.

https://gist.github.com/grifferz/0421e2876b270bb6816e94e5db37bb2e

Eric Desrochers (slashd)
Changed in netplan:
status: Confirmed → In Progress
status: In Progress → Invalid
Changed in systemd (Ubuntu):
assignee: nobody → Dimitri John Ledkov (xnox)
status: New → In Progress
Eric Desrochers (slashd)
Changed in systemd (Ubuntu):
importance: Undecided → Medium
tags: added: sts
Dan Streetman (ddstreet)
tags: removed: sts
Dan Streetman (ddstreet)
tags: added: sts
Dan Streetman (ddstreet)
Changed in systemd (Ubuntu):
status: In Progress → Fix Released
Revision history for this message
Dan Streetman (ddstreet) wrote :

systemd back to bionic already supports the PreferredLifetime config param. Only netplan needs a change to provide a param to set PreferredLifetime.

Changed in netplan:
status: Invalid → New
status: New → In Progress
status: In Progress → New
Changed in netplan.io (Ubuntu):
status: New → In Progress
Dan Streetman (ddstreet)
Changed in netplan.io (Ubuntu):
assignee: nobody → Heitor Alves de Siqueira (halves)
importance: Undecided → Medium
Revision history for this message
Heitor Alves de Siqueira (halves) wrote :

Some notes for reference:

We might actually have some trouble in expressing the Lifetime of an Address in the Netplan schema. From the Netplan Reference [0] we can see that the 'addresses:' field accepts a list of mixed IPv4 and IPv6 addresses. We can't just add a 'lifetime:' field to the schema, because then we wouldn't have a way to link that value to one of the addresses in the mixed list. I can see a few different ways to change the configuration to accommodate the lifetime change:

1) Implement a list of lifetimes, which would "follow" the list of addresses
  (i.e. lifetime[0] corresponds to addresses[0] and so on)

2) Modify the address syntax inside the list to allow an optional lifetime, e.g.:
  addresses: [127.0.0.1 (forever), "2001:1::1/64 (0)"]

3) Allow the definition of an address+lifetime mapping and use that in the
'addresses' field, e.g.:
  myaddr:
    value: 127.0.0.1
    lifetime: 0
  ...
  addresses: [ myaddr, 2001:1::1/64 ]

Option 1 has the obvious problem of matching one lifetime to a list of multiple addresses. Say we want to specify a lifetime to address number K in the list, would we need to specify a lifetime for all of them? How would we "skip" default lifetimes with this approach?

Option 2 has the benefit of being somewhat compatible with the current schema in the sense that if no lifetime is specified, we can keep the current behavior. I feel like it would introduce a lot of complexity in the schema parsing code to sort the addresses from the lifetime though, and this might not be something that we want in a sensitive code section.

Option 3 looks very flexible, but I'm not familiar enough with the schema and its parsing code to estimate the impact that would have. I think we would need quite a few significant changes, and I'm not really sure where we would place the 'myaddr' definition in the schema either.

None of the above options feel like a good way to solve the lifetime problem, but I'm not sure we have an easy way to integrate that into the current netplan schema. Perhaps someone more experienced with the Netplan schema/codebase might offer better insight on how to tackle this issue.

[0] https://netplan.io/reference

Revision history for this message
Richard Laager (rlaager) wrote :

Currently, addresses is a "sequence of scalars" (aka a list). Here is the example from the Netplan reference you quoted:

addresses: [192.168.14.2/24, "2001:1::1/64"]

This can, currently, also be written in this form (quotes optional):
addresses:
 - 192.168.14.2/24
 - "2001:1::1/64"

I actually prefer the latter form, so that's what I use today.

In YAML generally (not necessarily Netplan specifically), I think the obvious extension would be to support dictionaries in addition to scalars, for the addresses. That would allow for this type of extension:

addresses:
 - 192.168.14.2/24
 - "2001:1::1/64":
     lifetime: 0
     other: x
     future: y
     parameters: z

If you really want the flattened form, it would be:
addresses: [192.168.14.2/24, "2001:1::1/64": {lifetime: 0}]

This is a clean extension from the current syntax and supports other future parameters.

Whether Netplan's YAML parser currently supports dictionaries is another question. But this is all normal YAML. See, for example, Ansible: https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html

Revision history for this message
Heitor Alves de Siqueira (halves) wrote :

@rlaager
I've started a PR discussion on Netplan.io's Github with your proposed changes as they seemed the best way forward for now.

I don't expect this to get merged right away, as the maintainers might want to discuss the changes to the schema in further detail. In any case, this should at least start a discussion on getting this fixed in upstream netplan.

https://github.com/CanonicalLtd/netplan/pull/89

Revision history for this message
Lukas Märdian (slyon) wrote :

Thanks to Heitor's work, the pull request to support preferred_lft has been merged upstream: https://github.com/CanonicalLtd/netplan/pull/89

Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package netplan.io - 0.100-0ubuntu4

---------------
netplan.io (0.100-0ubuntu4) groovy; urgency=medium

  * debian/tests/cloud-init
    - Improve reboot test to avoid failure on arm64

 -- Lukas Märdian <email address hidden> Mon, 21 Sep 2020 12:23:02 +0200

Changed in netplan.io (Ubuntu):
status: In Progress → Fix Released
Lukas Märdian (slyon)
Changed in netplan:
status: New → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.