mirror of
https://github.com/systemd/systemd.git
synced 2025-03-14 04:58:28 +03:00
network: sd-radv - Allow to configure Mobile IPv6 Home Agent
This commit is contained in:
parent
47d8770aac
commit
6a6d27bc5b
@ -3661,6 +3661,37 @@ Token=prefixstable:2002:da8:1::</programlisting></para>
|
||||
3600 seconds (one hour).</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>HomeAgent=</varname></term>
|
||||
|
||||
<listitem><para>Takes a boolean. Specifies that IPv6 router advertisements which indicates to hosts that
|
||||
the router acts as a Home Agent and includes a Home Agent Option. Defaults to false. See
|
||||
<ulink url="https://tools.ietf.org/html/rfc6275">RFC 6275</ulink> for further details.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v255"/>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>HomeAgentLifetimeSec=</varname></term>
|
||||
|
||||
<listitem><para>Takes a timespan. Specifies the lifetime of the Home Agent. An integer the default unit of seconds,
|
||||
in the range 1…65535. Defaults to the value set to <varname>RouterLifetimeSec=</varname>.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v255"/>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>HomeAgentPreference=</varname></term>
|
||||
|
||||
<listitem><para>Configures IPv6 Home Agent preference. Takes an integer in the range 0…65535.
|
||||
Defaults to 0.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v255"/>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
@ -5,6 +5,8 @@
|
||||
Copyright © 2017 Intel Corporation. All rights reserved.
|
||||
***/
|
||||
|
||||
#include <netinet/icmp6.h>
|
||||
|
||||
#include "sd-radv.h"
|
||||
|
||||
#include "list.h"
|
||||
@ -65,6 +67,11 @@
|
||||
/* Pref64 option type (RFC8781, section 4) */
|
||||
#define RADV_OPT_PREF64 38
|
||||
|
||||
/* rfc6275 7.4 Neighbor Discovery Home Agent Lifetime.
|
||||
* The default value is the same as the Router Lifetime
|
||||
* The maximum value corresponds to 18.2 hours. value of 0 MUST NOT be used.*/
|
||||
#define RADV_MAX_HOME_AGENT_LIFETIME_USEC (65535 * USEC_PER_SEC)
|
||||
|
||||
enum RAdvState {
|
||||
RADV_STATE_IDLE = 0,
|
||||
RADV_STATE_ADVERTISING = 1,
|
||||
@ -112,6 +119,9 @@ struct sd_radv {
|
||||
size_t n_rdnss;
|
||||
struct sd_radv_opt_dns *rdnss;
|
||||
struct sd_radv_opt_dns *dnssl;
|
||||
|
||||
/* Mobile IPv6 extension: Home Agent Info. */
|
||||
struct nd_opt_home_agent_info home_agent;
|
||||
};
|
||||
|
||||
#define radv_prefix_opt__contents { \
|
||||
|
@ -231,6 +231,17 @@ static int radv_send(sd_radv *ra, const struct in6_addr *dst, usec_t lifetime_us
|
||||
if (ra->dnssl)
|
||||
iov[msg.msg_iovlen++] = IOVEC_MAKE(ra->dnssl, ra->dnssl->length * 8);
|
||||
|
||||
if (FLAGS_SET(ra->flags, ND_RA_FLAG_HOME_AGENT)) {
|
||||
ra->home_agent.nd_opt_home_agent_info_type = ND_OPT_HOME_AGENT_INFO;
|
||||
ra->home_agent.nd_opt_home_agent_info_len = 1;
|
||||
|
||||
/* 0 means to place the current Router Lifetime value */
|
||||
if (ra->home_agent.nd_opt_home_agent_info_lifetime == 0)
|
||||
ra->home_agent.nd_opt_home_agent_info_lifetime = adv.nd_ra_router_lifetime;
|
||||
|
||||
iov[msg.msg_iovlen++] = IOVEC_MAKE(&ra->home_agent, sizeof(ra->home_agent));
|
||||
}
|
||||
|
||||
if (sendmsg(ra->fd, &msg, 0) < 0)
|
||||
return -errno;
|
||||
|
||||
@ -570,6 +581,39 @@ int sd_radv_set_preference(sd_radv *ra, unsigned preference) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_radv_set_home_agent_information(sd_radv *ra, int home_agent) {
|
||||
assert_return(ra, -EINVAL);
|
||||
|
||||
if (ra->state != RADV_STATE_IDLE)
|
||||
return -EBUSY;
|
||||
|
||||
SET_FLAG(ra->flags, ND_RA_FLAG_HOME_AGENT, home_agent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_radv_set_home_agent_preference(sd_radv *ra, uint16_t preference) {
|
||||
assert_return(ra, -EINVAL);
|
||||
|
||||
if (ra->state != RADV_STATE_IDLE)
|
||||
return -EBUSY;
|
||||
|
||||
ra->home_agent.nd_opt_home_agent_info_preference = htobe16(preference);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_radv_set_home_agent_lifetime(sd_radv *ra, uint16_t lifetime) {
|
||||
assert_return(ra, -EINVAL);
|
||||
|
||||
if (ra->state != RADV_STATE_IDLE)
|
||||
return -EBUSY;
|
||||
|
||||
ra->home_agent.nd_opt_home_agent_info_lifetime = htobe16(lifetime);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p) {
|
||||
sd_radv_prefix *found = NULL;
|
||||
int r;
|
||||
|
@ -384,6 +384,9 @@ IPv6SendRA.EmitDomains, config_parse_bool,
|
||||
IPv6SendRA.Domains, config_parse_radv_search_domains, 0, 0
|
||||
IPv6SendRA.DNSLifetimeSec, config_parse_sec, 0, offsetof(Network, router_dns_lifetime_usec)
|
||||
IPv6SendRA.UplinkInterface, config_parse_uplink, 0, 0
|
||||
IPv6SendRA.HomeAgent, config_parse_bool, 0, offsetof(Network, router_home_agent_information)
|
||||
IPv6SendRA.HomeAgentLifetimeSec, config_parse_router_home_agent_lifetime, 0, offsetof(Network, home_agent_lifetime_usec)
|
||||
IPv6SendRA.HomeAgentPreference, config_parse_uint16, 0, offsetof(Network, router_home_agent_preference)
|
||||
IPv6Prefix.Prefix, config_parse_prefix, 0, 0
|
||||
IPv6Prefix.OnLink, config_parse_prefix_boolean, 0, 0
|
||||
IPv6Prefix.AddressAutoconfiguration, config_parse_prefix_boolean, 0, 0
|
||||
|
@ -242,6 +242,10 @@ struct Network {
|
||||
OrderedSet *router_search_domains;
|
||||
int router_uplink_index;
|
||||
char *router_uplink_name;
|
||||
/* Mobile IPv6 Home Agent */
|
||||
bool router_home_agent_information;
|
||||
uint16_t router_home_agent_preference;
|
||||
usec_t home_agent_lifetime_usec;
|
||||
|
||||
/* DHCP Prefix Delegation support */
|
||||
int dhcp_pd;
|
||||
|
@ -600,6 +600,18 @@ static int radv_configure(Link *link) {
|
||||
if (r < 0)
|
||||
return log_link_debug_errno(link, r, "Could not set RA Domains: %m");
|
||||
|
||||
r = sd_radv_set_home_agent_information(link->radv, link->network->router_home_agent_information);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_radv_set_home_agent_preference(link->radv, link->network->router_home_agent_preference);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_radv_set_home_agent_lifetime(link->radv, DIV_ROUND_UP(link->network->home_agent_lifetime_usec, USEC_PER_SEC));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1575,3 +1587,47 @@ int config_parse_router_preference(
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_router_home_agent_lifetime(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
usec_t usec, *home_agent_lifetime_usec = ASSERT_PTR(data);
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(section);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
*home_agent_lifetime_usec = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = parse_sec(rvalue, &usec);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (usec == USEC_INFINITY || usec == 0 ||
|
||||
DIV_ROUND_UP(usec, USEC_PER_SEC) > RADV_MAX_HOME_AGENT_LIFETIME_USEC) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Invalid %s= must be in the range 1...%lu seconds, ignoring: %s", lvalue,
|
||||
RADV_MAX_HOME_AGENT_LIFETIME_USEC / USEC_PER_SEC, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*home_agent_lifetime_usec = usec;
|
||||
return 0;
|
||||
}
|
||||
|
@ -98,3 +98,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_route_prefix);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_prefix_lifetime);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_pref64_prefix);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_pref64_prefix_lifetime);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_router_home_agent_lifetime);
|
||||
|
@ -95,6 +95,11 @@ int sd_radv_pref64_prefix_set_prefix(sd_radv_pref64_prefix *p, const struct in6_
|
||||
sd_radv_pref64_prefix *sd_radv_pref64_prefix_ref(sd_radv_pref64_prefix *ra);
|
||||
sd_radv_pref64_prefix *sd_radv_pref64_prefix_unref(sd_radv_pref64_prefix *ra);
|
||||
|
||||
/* Mobile IPv6 extension: Home Agent Info. */
|
||||
int sd_radv_set_home_agent_information(sd_radv *ra, int home_agent);
|
||||
int sd_radv_set_home_agent_preference(sd_radv *ra, uint16_t preference);
|
||||
int sd_radv_set_home_agent_lifetime(sd_radv *ra, uint16_t lifetime);
|
||||
|
||||
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_radv, sd_radv_unref);
|
||||
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_radv_prefix, sd_radv_prefix_unref);
|
||||
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_radv_route_prefix, sd_radv_route_prefix_unref);
|
||||
|
Loading…
x
Reference in New Issue
Block a user