2015-10-16 21:09:15 +02:00
|
|
|
/***
|
|
|
|
This file is part of systemd.
|
|
|
|
|
|
|
|
Copyright (C) 2014 Intel Corporation. All rights reserved.
|
|
|
|
|
|
|
|
systemd is free software; you can redistribute it and/or modify it
|
|
|
|
under the terms of the GNU Lesser General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2.1 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
systemd is distributed in the hope that it will be useful, but
|
|
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Lesser General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
|
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
***/
|
|
|
|
|
2015-10-19 22:15:50 +02:00
|
|
|
#include <netinet/icmp6.h>
|
2016-11-13 04:59:06 +01:00
|
|
|
#include <arpa/inet.h>
|
2015-10-16 21:09:15 +02:00
|
|
|
|
|
|
|
#include "sd-ndisc.h"
|
|
|
|
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
#include "networkd-ndisc.h"
|
2016-11-13 04:59:06 +01:00
|
|
|
#include "networkd-route.h"
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
|
|
|
|
#define NDISC_DNSSL_MAX 64U
|
|
|
|
#define NDISC_RDNSS_MAX 64U
|
2015-11-18 21:32:43 +01:00
|
|
|
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
static int ndisc_netlink_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
|
|
|
|
_cleanup_link_unref_ Link *link = userdata;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
assert(link);
|
|
|
|
assert(link->ndisc_messages > 0);
|
|
|
|
|
2016-02-23 05:32:04 +01:00
|
|
|
link->ndisc_messages--;
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
|
|
|
|
r = sd_netlink_message_get_errno(m);
|
|
|
|
if (r < 0 && r != -EEXIST) {
|
|
|
|
log_link_error_errno(link, r, "Could not set NDisc route or address: %m");
|
|
|
|
link_enter_failed(link);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (link->ndisc_messages == 0) {
|
|
|
|
link->ndisc_configured = true;
|
|
|
|
link_check_ready(link);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
static void ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
|
|
|
|
_cleanup_route_free_ Route *route = NULL;
|
|
|
|
struct in6_addr gateway;
|
|
|
|
uint16_t lifetime;
|
|
|
|
unsigned preference;
|
2016-11-23 22:32:19 +01:00
|
|
|
uint32_t mtu;
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
usec_t time_now;
|
|
|
|
int r;
|
2016-10-24 13:44:01 +02:00
|
|
|
Address *address;
|
|
|
|
Iterator i;
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
|
|
|
|
assert(link);
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
assert(rt);
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
r = sd_ndisc_router_get_lifetime(rt, &lifetime);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_warning_errno(link, r, "Failed to get gateway address from RA: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (lifetime == 0) /* not a default router */
|
|
|
|
return;
|
|
|
|
|
|
|
|
r = sd_ndisc_router_get_address(rt, &gateway);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_warning_errno(link, r, "Failed to get gateway address from RA: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-10-24 13:44:01 +02:00
|
|
|
SET_FOREACH(address, link->addresses, i) {
|
|
|
|
if (!memcmp(&gateway, &address->in_addr.in6,
|
|
|
|
sizeof(address->in_addr.in6))) {
|
|
|
|
char buffer[INET6_ADDRSTRLEN];
|
|
|
|
|
|
|
|
log_link_debug(link, "No NDisc route added, gateway %s matches local address",
|
|
|
|
inet_ntop(AF_INET6,
|
|
|
|
&address->in_addr.in6,
|
|
|
|
buffer, sizeof(buffer)));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SET_FOREACH(address, link->addresses_foreign, i) {
|
|
|
|
if (!memcmp(&gateway, &address->in_addr.in6,
|
|
|
|
sizeof(address->in_addr.in6))) {
|
|
|
|
char buffer[INET6_ADDRSTRLEN];
|
|
|
|
|
|
|
|
log_link_debug(link, "No NDisc route added, gateway %s matches local address",
|
|
|
|
inet_ntop(AF_INET6,
|
|
|
|
&address->in_addr.in6,
|
|
|
|
buffer, sizeof(buffer)));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
r = sd_ndisc_router_get_preference(rt, &preference);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_warning_errno(link, r, "Failed to get default router preference from RA: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_warning_errno(link, r, "Failed to get RA timestamp: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-11-23 22:32:19 +01:00
|
|
|
r = sd_ndisc_router_get_mtu(rt, &mtu);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_warning_errno(link, r, "Failed to get default router MTU from RA: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
r = route_new(&route);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_error_errno(link, r, "Could not allocate route: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
route->family = AF_INET6;
|
2016-09-19 04:59:11 +02:00
|
|
|
route->table = link->network->ipv6_accept_ra_route_table;
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
route->protocol = RTPROT_RA;
|
|
|
|
route->pref = preference;
|
|
|
|
route->gw.in6 = gateway;
|
|
|
|
route->lifetime = time_now + lifetime * USEC_PER_SEC;
|
2016-11-23 22:32:19 +01:00
|
|
|
route->mtu = mtu;
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
|
|
|
|
r = route_configure(route, link, ndisc_netlink_handler);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_warning_errno(link, r, "Could not set default route: %m");
|
|
|
|
link_enter_failed(link);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
link->ndisc_messages++;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *rt) {
|
|
|
|
_cleanup_address_free_ Address *address = NULL;
|
|
|
|
uint32_t lifetime_valid, lifetime_preferred;
|
|
|
|
unsigned prefixlen;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
assert(link);
|
|
|
|
assert(rt);
|
|
|
|
|
|
|
|
r = sd_ndisc_router_prefix_get_prefixlen(rt, &prefixlen);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_error_errno(link, r, "Failed to get prefix length: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
r = sd_ndisc_router_prefix_get_valid_lifetime(rt, &lifetime_valid);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_error_errno(link, r, "Failed to get prefix valid lifetime: %m");
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
return;
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
r = sd_ndisc_router_prefix_get_preferred_lifetime(rt, &lifetime_preferred);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_error_errno(link, r, "Failed to get prefix preferred lifetime: %m");
|
|
|
|
return;
|
|
|
|
}
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
|
|
|
|
r = address_new(&address);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_error_errno(link, r, "Could not allocate address: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
address->family = AF_INET6;
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
r = sd_ndisc_router_prefix_get_address(rt, &address->in_addr.in6);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_error_errno(link, r, "Failed to get prefix address: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
if (in_addr_is_null(AF_INET6, (const union in_addr_union *) &link->network->ipv6_token) == 0)
|
2015-11-17 13:14:36 +01:00
|
|
|
memcpy(((char *)&address->in_addr.in6) + 8, ((char *)&link->network->ipv6_token) + 8, 8);
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
else {
|
2015-11-18 21:32:43 +01:00
|
|
|
/* see RFC4291 section 2.5.1 */
|
2016-02-19 00:35:22 +01:00
|
|
|
address->in_addr.in6.s6_addr[8] = link->mac.ether_addr_octet[0];
|
|
|
|
address->in_addr.in6.s6_addr[8] ^= 1 << 1;
|
|
|
|
address->in_addr.in6.s6_addr[9] = link->mac.ether_addr_octet[1];
|
|
|
|
address->in_addr.in6.s6_addr[10] = link->mac.ether_addr_octet[2];
|
|
|
|
address->in_addr.in6.s6_addr[11] = 0xff;
|
|
|
|
address->in_addr.in6.s6_addr[12] = 0xfe;
|
|
|
|
address->in_addr.in6.s6_addr[13] = link->mac.ether_addr_octet[3];
|
|
|
|
address->in_addr.in6.s6_addr[14] = link->mac.ether_addr_octet[4];
|
|
|
|
address->in_addr.in6.s6_addr[15] = link->mac.ether_addr_octet[5];
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
}
|
|
|
|
address->prefixlen = prefixlen;
|
2016-01-15 23:39:54 +01:00
|
|
|
address->flags = IFA_F_NOPREFIXROUTE|IFA_F_MANAGETEMPADDR;
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
address->cinfo.ifa_prefered = lifetime_preferred;
|
|
|
|
address->cinfo.ifa_valid = lifetime_valid;
|
|
|
|
|
|
|
|
r = address_configure(address, link, ndisc_netlink_handler, true);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_warning_errno(link, r, "Could not set SLAAC address: %m");
|
|
|
|
link_enter_failed(link);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-02-23 05:32:04 +01:00
|
|
|
link->ndisc_messages++;
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
}
|
|
|
|
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
static void ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) {
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
_cleanup_route_free_ Route *route = NULL;
|
|
|
|
usec_t time_now;
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
uint32_t lifetime;
|
|
|
|
unsigned prefixlen;
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
int r;
|
|
|
|
|
|
|
|
assert(link);
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
assert(rt);
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_warning_errno(link, r, "Failed to get RA timestamp: %m");
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
return;
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
r = sd_ndisc_router_prefix_get_prefixlen(rt, &prefixlen);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_error_errno(link, r, "Failed to get prefix length: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
r = sd_ndisc_router_prefix_get_valid_lifetime(rt, &lifetime);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_error_errno(link, r, "Failed to get prefix lifetime: %m");
|
|
|
|
return;
|
|
|
|
}
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
|
|
|
|
r = route_new(&route);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_error_errno(link, r, "Could not allocate route: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
route->family = AF_INET6;
|
2016-09-19 04:59:11 +02:00
|
|
|
route->table = link->network->ipv6_accept_ra_route_table;
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
route->protocol = RTPROT_RA;
|
|
|
|
route->flags = RTM_F_PREFIX;
|
|
|
|
route->dst_prefixlen = prefixlen;
|
|
|
|
route->lifetime = time_now + lifetime * USEC_PER_SEC;
|
|
|
|
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
r = sd_ndisc_router_prefix_get_address(rt, &route->dst.in6);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_error_errno(link, r, "Failed to get prefix address: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
r = route_configure(route, link, ndisc_netlink_handler);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_warning_errno(link, r, "Could not set prefix route: %m");
|
|
|
|
link_enter_failed(link);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-02-23 05:32:04 +01:00
|
|
|
link->ndisc_messages++;
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
}
|
|
|
|
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
static void ndisc_router_process_route(Link *link, sd_ndisc_router *rt) {
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
_cleanup_route_free_ Route *route = NULL;
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
struct in6_addr gateway;
|
|
|
|
uint32_t lifetime;
|
|
|
|
unsigned preference, prefixlen;
|
2015-11-18 21:32:43 +01:00
|
|
|
usec_t time_now;
|
2015-11-10 15:43:52 +01:00
|
|
|
int r;
|
2015-10-16 21:09:15 +02:00
|
|
|
|
|
|
|
assert(link);
|
|
|
|
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
r = sd_ndisc_router_route_get_lifetime(rt, &lifetime);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_warning_errno(link, r, "Failed to get gateway address from RA: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (lifetime == 0)
|
2015-10-16 21:09:15 +02:00
|
|
|
return;
|
|
|
|
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
r = sd_ndisc_router_get_address(rt, &gateway);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_warning_errno(link, r, "Failed to get gateway address from RA: %m");
|
|
|
|
return;
|
2015-11-10 15:43:52 +01:00
|
|
|
}
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
r = sd_ndisc_router_route_get_prefixlen(rt, &prefixlen);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_warning_errno(link, r, "Failed to get route prefix length: %m");
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
return;
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
r = sd_ndisc_router_route_get_preference(rt, &preference);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_warning_errno(link, r, "Failed to get default router preference from RA: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_warning_errno(link, r, "Failed to get RA timestamp: %m");
|
|
|
|
return;
|
|
|
|
}
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
|
|
|
|
r = route_new(&route);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_error_errno(link, r, "Could not allocate route: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
route->family = AF_INET6;
|
2016-09-19 04:59:11 +02:00
|
|
|
route->table = link->network->ipv6_accept_ra_route_table;
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
route->protocol = RTPROT_RA;
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
route->pref = preference;
|
|
|
|
route->gw.in6 = gateway;
|
|
|
|
route->dst_prefixlen = prefixlen;
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
route->lifetime = time_now + lifetime * USEC_PER_SEC;
|
|
|
|
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
r = sd_ndisc_router_route_get_address(rt, &route->dst.in6);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_error_errno(link, r, "Failed to get route address: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
r = route_configure(route, link, ndisc_netlink_handler);
|
|
|
|
if (r < 0) {
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
log_link_warning_errno(link, r, "Could not set additional route: %m");
|
networkd: ndisc - handle router advertisement in userspace
Router Discovery is a core part of IPv6, which by default is handled by the kernel.
However, the kernel implementation is meant as a fall-back, and to fully support
the protocol a userspace implementation is desired.
The protocol essentially listens for Router Advertisement packets from routers
on the local link and use these to configure the client automatically. The four
main pieces of information are: what kind (if any) of DHCPv6 configuration should
be performed; a default gateway; the prefixes that should be considered to be on
the local link; and the prefixes with which we can preform SLAAC in order to pick
a global IPv6 address.
A lot of additional information is also available, which we do not yet fully
support, but which will eventually allow us to avoid the need for DHCPv6 in the
common case.
Short-term, the reason for wanting this is in userspace was the desire to fully
track all the addresses on links we manage, and that is not possible for addresses
managed by the kernel (as the kernel does not expose to us the fact that it
manages these addresses). Moreover, we would like to support stable privacy
addresses, which will soon be mandated and the legacy MAC-based global addresses
deprecated, to do this well we need to handle the generation in userspace. Lastly,
more long-term we wish to support more RA options than what the kernel exposes.
2015-11-03 13:02:16 +01:00
|
|
|
link_enter_failed(link);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-02-23 05:32:04 +01:00
|
|
|
link->ndisc_messages++;
|
2015-10-19 22:15:50 +02:00
|
|
|
}
|
2015-10-16 21:09:15 +02:00
|
|
|
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
static void ndisc_rdnss_hash_func(const void *p, struct siphash *state) {
|
|
|
|
const NDiscRDNSS *x = p;
|
|
|
|
|
|
|
|
siphash24_compress(&x->address, sizeof(x->address), state);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ndisc_rdnss_compare_func(const void *_a, const void *_b) {
|
|
|
|
const NDiscRDNSS *a = _a, *b = _b;
|
|
|
|
|
|
|
|
return memcmp(&a->address, &b->address, sizeof(a->address));
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct hash_ops ndisc_rdnss_hash_ops = {
|
|
|
|
.hash = ndisc_rdnss_hash_func,
|
|
|
|
.compare = ndisc_rdnss_compare_func
|
|
|
|
};
|
|
|
|
|
|
|
|
static void ndisc_router_process_rdnss(Link *link, sd_ndisc_router *rt) {
|
|
|
|
uint32_t lifetime;
|
|
|
|
const struct in6_addr *a;
|
|
|
|
usec_t time_now;
|
|
|
|
int i, n, r;
|
|
|
|
|
|
|
|
assert(link);
|
|
|
|
assert(rt);
|
|
|
|
|
|
|
|
r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_warning_errno(link, r, "Failed to get RA timestamp: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
r = sd_ndisc_router_rdnss_get_lifetime(rt, &lifetime);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_warning_errno(link, r, "Failed to get RDNSS lifetime: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
n = sd_ndisc_router_rdnss_get_addresses(rt, &a);
|
|
|
|
if (n < 0) {
|
|
|
|
log_link_warning_errno(link, n, "Failed to get RDNSS addresses: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
NDiscRDNSS d = {
|
|
|
|
.address = a[i]
|
|
|
|
}, *x;
|
|
|
|
|
|
|
|
if (lifetime == 0) {
|
|
|
|
(void) set_remove(link->ndisc_rdnss, &d);
|
|
|
|
link_dirty(link);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
x = set_get(link->ndisc_rdnss, &d);
|
|
|
|
if (x) {
|
|
|
|
x->valid_until = time_now + lifetime * USEC_PER_SEC;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
ndisc_vacuum(link);
|
|
|
|
|
|
|
|
if (set_size(link->ndisc_rdnss) >= NDISC_RDNSS_MAX) {
|
|
|
|
log_link_warning(link, "Too many RDNSS records per link, ignoring.");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
r = set_ensure_allocated(&link->ndisc_rdnss, &ndisc_rdnss_hash_ops);
|
|
|
|
if (r < 0) {
|
|
|
|
log_oom();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
x = new0(NDiscRDNSS, 1);
|
|
|
|
if (!x) {
|
|
|
|
log_oom();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
x->address = a[i];
|
|
|
|
x->valid_until = time_now + lifetime * USEC_PER_SEC;
|
|
|
|
|
|
|
|
r = set_put(link->ndisc_rdnss, x);
|
|
|
|
if (r < 0) {
|
|
|
|
free(x);
|
|
|
|
log_oom();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(r > 0);
|
|
|
|
link_dirty(link);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ndisc_dnssl_hash_func(const void *p, struct siphash *state) {
|
|
|
|
const NDiscDNSSL *x = p;
|
|
|
|
|
|
|
|
siphash24_compress(NDISC_DNSSL_DOMAIN(x), strlen(NDISC_DNSSL_DOMAIN(x)), state);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ndisc_dnssl_compare_func(const void *_a, const void *_b) {
|
|
|
|
const NDiscDNSSL *a = _a, *b = _b;
|
|
|
|
|
|
|
|
return strcmp(NDISC_DNSSL_DOMAIN(a), NDISC_DNSSL_DOMAIN(b));
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct hash_ops ndisc_dnssl_hash_ops = {
|
|
|
|
.hash = ndisc_dnssl_hash_func,
|
|
|
|
.compare = ndisc_dnssl_compare_func
|
|
|
|
};
|
|
|
|
|
|
|
|
static void ndisc_router_process_dnssl(Link *link, sd_ndisc_router *rt) {
|
|
|
|
_cleanup_strv_free_ char **l = NULL;
|
|
|
|
uint32_t lifetime;
|
|
|
|
usec_t time_now;
|
|
|
|
char **i;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
assert(link);
|
|
|
|
assert(rt);
|
|
|
|
|
|
|
|
r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_warning_errno(link, r, "Failed to get RA timestamp: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
r = sd_ndisc_router_dnssl_get_lifetime(rt, &lifetime);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_warning_errno(link, r, "Failed to get RDNSS lifetime: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
r = sd_ndisc_router_dnssl_get_domains(rt, &l);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_warning_errno(link, r, "Failed to get RDNSS addresses: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
STRV_FOREACH(i, l) {
|
2016-07-15 04:56:11 +02:00
|
|
|
_cleanup_free_ NDiscDNSSL *s;
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
NDiscDNSSL *x;
|
|
|
|
|
2016-07-15 04:56:11 +02:00
|
|
|
s = malloc0(ALIGN(sizeof(NDiscDNSSL)) + strlen(*i) + 1);
|
|
|
|
if (!s) {
|
|
|
|
log_oom();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
strcpy(NDISC_DNSSL_DOMAIN(s), *i);
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
|
|
|
|
if (lifetime == 0) {
|
2016-07-15 04:56:11 +02:00
|
|
|
(void) set_remove(link->ndisc_dnssl, s);
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
link_dirty(link);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-07-15 04:56:11 +02:00
|
|
|
x = set_get(link->ndisc_dnssl, s);
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
if (x) {
|
|
|
|
x->valid_until = time_now + lifetime * USEC_PER_SEC;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
ndisc_vacuum(link);
|
|
|
|
|
|
|
|
if (set_size(link->ndisc_dnssl) >= NDISC_DNSSL_MAX) {
|
|
|
|
log_link_warning(link, "Too many DNSSL records per link, ignoring.");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
r = set_ensure_allocated(&link->ndisc_dnssl, &ndisc_dnssl_hash_ops);
|
|
|
|
if (r < 0) {
|
|
|
|
log_oom();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-07-15 04:56:11 +02:00
|
|
|
s->valid_until = time_now + lifetime * USEC_PER_SEC;
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
|
2016-07-15 04:56:11 +02:00
|
|
|
r = set_put(link->ndisc_dnssl, s);
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
if (r < 0) {
|
|
|
|
log_oom();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-07-15 04:56:11 +02:00
|
|
|
s = NULL;
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
assert(r > 0);
|
|
|
|
link_dirty(link);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ndisc_router_process_options(Link *link, sd_ndisc_router *rt) {
|
|
|
|
int r;
|
|
|
|
|
|
|
|
assert(link);
|
|
|
|
assert(rt);
|
|
|
|
|
|
|
|
r = sd_ndisc_router_option_rewind(rt);
|
|
|
|
for (;;) {
|
|
|
|
uint8_t type;
|
|
|
|
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_warning_errno(link, r, "Failed to iterate through options: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (r == 0) /* EOF */
|
|
|
|
break;
|
|
|
|
|
|
|
|
r = sd_ndisc_router_option_get_type(rt, &type);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_warning_errno(link, r, "Failed to get RA option type: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
|
|
|
case SD_NDISC_OPTION_PREFIX_INFORMATION: {
|
|
|
|
uint8_t flags;
|
|
|
|
|
|
|
|
r = sd_ndisc_router_prefix_get_flags(rt, &flags);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_warning_errno(link, r, "Failed to get RA prefix flags: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flags & ND_OPT_PI_FLAG_ONLINK)
|
|
|
|
ndisc_router_process_onlink_prefix(link, rt);
|
|
|
|
if (flags & ND_OPT_PI_FLAG_AUTO)
|
|
|
|
ndisc_router_process_autonomous_prefix(link, rt);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case SD_NDISC_OPTION_ROUTE_INFORMATION:
|
|
|
|
ndisc_router_process_route(link, rt);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SD_NDISC_OPTION_RDNSS:
|
|
|
|
ndisc_router_process_rdnss(link, rt);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SD_NDISC_OPTION_DNSSL:
|
|
|
|
ndisc_router_process_dnssl(link, rt);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
r = sd_ndisc_router_option_next(rt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
|
|
|
|
uint64_t flags;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
assert(link);
|
|
|
|
assert(link->network);
|
|
|
|
assert(link->manager);
|
|
|
|
assert(rt);
|
|
|
|
|
|
|
|
r = sd_ndisc_router_get_flags(rt, &flags);
|
|
|
|
if (r < 0) {
|
|
|
|
log_link_warning_errno(link, r, "Failed to get RA flags: %m");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER)) {
|
|
|
|
/* (re)start DHCPv6 client in stateful or stateless mode according to RA flags */
|
|
|
|
r = dhcp6_request_address(link, !(flags & ND_RA_FLAG_MANAGED));
|
|
|
|
if (r < 0 && r != -EBUSY)
|
|
|
|
log_link_warning_errno(link, r, "Could not acquire DHCPv6 lease on NDisc request: %m");
|
|
|
|
else
|
|
|
|
log_link_debug(link, "Acquiring DHCPv6 lease on NDisc request");
|
|
|
|
}
|
|
|
|
|
|
|
|
ndisc_router_process_default(link, rt);
|
|
|
|
ndisc_router_process_options(link, rt);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ndisc_handler(sd_ndisc *nd, sd_ndisc_event event, sd_ndisc_router *rt, void *userdata) {
|
2015-10-19 22:15:50 +02:00
|
|
|
Link *link = userdata;
|
2015-10-16 21:09:15 +02:00
|
|
|
|
2015-10-19 22:15:50 +02:00
|
|
|
assert(link);
|
2015-10-16 21:09:15 +02:00
|
|
|
|
2015-10-19 22:15:50 +02:00
|
|
|
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
|
|
|
return;
|
2015-10-16 21:09:15 +02:00
|
|
|
|
2015-10-19 22:15:50 +02:00
|
|
|
switch (event) {
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
|
|
|
|
case SD_NDISC_EVENT_ROUTER:
|
|
|
|
ndisc_router_handler(link, rt);
|
|
|
|
break;
|
|
|
|
|
2015-10-19 22:15:50 +02:00
|
|
|
case SD_NDISC_EVENT_TIMEOUT:
|
2015-11-17 15:32:39 +01:00
|
|
|
link->ndisc_configured = true;
|
|
|
|
link_check_ready(link);
|
|
|
|
|
2015-10-19 22:15:50 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
log_link_warning(link, "IPv6 Neighbor Discovery unknown event: %d", event);
|
2015-10-16 21:09:15 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int ndisc_configure(Link *link) {
|
|
|
|
int r;
|
|
|
|
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
assert(link);
|
|
|
|
|
|
|
|
r = sd_ndisc_new(&link->ndisc);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2015-10-16 21:09:15 +02:00
|
|
|
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
r = sd_ndisc_attach_event(link->ndisc, NULL, 0);
|
2015-10-16 21:09:15 +02:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
r = sd_ndisc_set_mac(link->ndisc, &link->mac);
|
2015-10-16 21:09:15 +02:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
r = sd_ndisc_set_ifindex(link->ndisc, link->ifindex);
|
2015-10-16 21:09:15 +02:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
r = sd_ndisc_set_callback(link->ndisc, ndisc_handler, link);
|
2015-10-16 21:09:15 +02:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ndisc_vacuum(Link *link) {
|
|
|
|
NDiscRDNSS *r;
|
|
|
|
NDiscDNSSL *d;
|
|
|
|
Iterator i;
|
|
|
|
usec_t time_now;
|
|
|
|
|
|
|
|
assert(link);
|
|
|
|
|
|
|
|
/* Removes all RDNSS and DNSSL entries whose validity time has passed */
|
|
|
|
|
|
|
|
time_now = now(clock_boottime_or_monotonic());
|
|
|
|
|
|
|
|
SET_FOREACH(r, link->ndisc_rdnss, i)
|
|
|
|
if (r->valid_until < time_now) {
|
2016-10-25 12:08:24 +02:00
|
|
|
free(set_remove(link->ndisc_rdnss, r));
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
link_dirty(link);
|
|
|
|
}
|
2015-10-16 21:09:15 +02:00
|
|
|
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
SET_FOREACH(d, link->ndisc_dnssl, i)
|
|
|
|
if (d->valid_until < time_now) {
|
2016-10-25 12:08:24 +02:00
|
|
|
free(set_remove(link->ndisc_dnssl, d));
|
network: beef up ipv6 RA support considerably
This reworks sd-ndisc and networkd substantially to support IPv6 RA much more
comprehensively. Since the API is extended quite a bit networkd has been ported
over too, and the patch is not as straight-forward as one could wish. The
rework includes:
- Support for DNSSL, RDNSS and RA routing options in sd-ndisc and networkd. Two
new configuration options have been added to networkd to make this
configurable.
- sd-ndisc now exposes an sd_ndisc_router object that encapsulates a full RA
message, and has direct, friendly acessor functions for the singleton RA
properties, as well as an iterative interface to iterate through known and
unsupported options. The router object may either be retrieved from the wire,
or generated from raw data. In many ways the sd-ndisc API now matches the
sd-lldp API, except that no implicit database of seen data is kept. (Note
that sd-ndisc actually had a half-written, but unused implementaiton of such
a store, which is removed now.)
- sd-ndisc will now collect the reception timestamps of RA, which is useful to
make sd_ndisc_router fully descriptive of what it covers.
Fixes: #1079
2016-06-02 20:38:12 +02:00
|
|
|
link_dirty(link);
|
|
|
|
}
|
2015-10-16 21:09:15 +02:00
|
|
|
}
|
2016-10-25 12:08:43 +02:00
|
|
|
|
|
|
|
void ndisc_flush(Link *link) {
|
|
|
|
assert(link);
|
|
|
|
|
|
|
|
/* Removes all RDNSS and DNSSL entries, without exception */
|
|
|
|
|
|
|
|
link->ndisc_rdnss = set_free_free(link->ndisc_rdnss);
|
|
|
|
link->ndisc_dnssl = set_free_free(link->ndisc_dnssl);
|
|
|
|
}
|