mirror of
https://github.com/Dasharo/systemd.git
synced 2026-03-06 15:02:31 -08:00
ndisc-option: add HomeAgent option support
Currently, these are not used, but will be used later in sd-radv.
This commit is contained in:
committed by
Luca Boccassi
parent
5e8adf9f50
commit
9f3587ae44
@@ -131,6 +131,7 @@ static int ndisc_option_compare_func(const sd_ndisc_option *x, const sd_ndisc_op
|
||||
case SD_NDISC_OPTION_TARGET_LL_ADDRESS:
|
||||
case SD_NDISC_OPTION_REDIRECTED_HEADER:
|
||||
case SD_NDISC_OPTION_MTU:
|
||||
case SD_NDISC_OPTION_HOME_AGENT:
|
||||
case SD_NDISC_OPTION_FLAGS_EXTENSION:
|
||||
case SD_NDISC_OPTION_CAPTIVE_PORTAL:
|
||||
/* These options cannot be specified multiple times. */
|
||||
@@ -497,6 +498,63 @@ static int ndisc_option_build_mtu(const sd_ndisc_option *option, uint8_t **ret)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ndisc_option_add_home_agent(Set **options, size_t offset, uint16_t preference, usec_t lifetime) {
|
||||
assert(options);
|
||||
|
||||
if (lifetime > UINT16_MAX * USEC_PER_SEC)
|
||||
return -EINVAL;
|
||||
|
||||
sd_ndisc_option *p = ndisc_option_new(SD_NDISC_OPTION_HOME_AGENT, offset);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
p->home_agent = (sd_ndisc_home_agent) {
|
||||
.preference = preference,
|
||||
.lifetime = lifetime,
|
||||
};
|
||||
|
||||
return ndisc_option_consume(options, p);
|
||||
}
|
||||
|
||||
static int ndisc_option_parse_home_agent(Set **options, size_t offset, size_t len, const uint8_t *opt) {
|
||||
const struct nd_opt_home_agent_info *p = (const struct nd_opt_home_agent_info*) ASSERT_PTR(opt);
|
||||
|
||||
assert(options);
|
||||
|
||||
if (len != sizeof(struct nd_opt_home_agent_info))
|
||||
return -EBADMSG;
|
||||
|
||||
if (p->nd_opt_home_agent_info_type != SD_NDISC_OPTION_HOME_AGENT)
|
||||
return -EBADMSG;
|
||||
|
||||
return ndisc_option_add_home_agent(
|
||||
options, offset,
|
||||
be16toh(p->nd_opt_home_agent_info_preference),
|
||||
be16_sec_to_usec(p->nd_opt_home_agent_info_lifetime, /* max_as_infinity = */ false));
|
||||
}
|
||||
|
||||
static int ndisc_option_build_home_agent(const sd_ndisc_option *option, uint8_t **ret) {
|
||||
assert(option);
|
||||
assert(option->type == SD_NDISC_OPTION_HOME_AGENT);
|
||||
assert(ret);
|
||||
|
||||
assert_cc(sizeof(struct nd_opt_home_agent_info) % 8 == 0);
|
||||
|
||||
_cleanup_free_ struct nd_opt_home_agent_info *buf = new(struct nd_opt_home_agent_info, 1);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
*buf = (struct nd_opt_home_agent_info) {
|
||||
.nd_opt_home_agent_info_type = SD_NDISC_OPTION_HOME_AGENT,
|
||||
.nd_opt_home_agent_info_len = sizeof(struct nd_opt_home_agent_info) / 8,
|
||||
.nd_opt_home_agent_info_preference = htobe16(option->home_agent.preference),
|
||||
.nd_opt_home_agent_info_lifetime = usec_to_be16_sec(option->home_agent.lifetime),
|
||||
};
|
||||
|
||||
*ret = (uint8_t*) TAKE_PTR(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ndisc_option_add_route(
|
||||
Set **options,
|
||||
size_t offset,
|
||||
@@ -1121,6 +1179,10 @@ int ndisc_parse_options(ICMP6Packet *packet, Set **ret_options) {
|
||||
r = ndisc_option_parse_mtu(&options, offset, length, opt);
|
||||
break;
|
||||
|
||||
case SD_NDISC_OPTION_HOME_AGENT:
|
||||
r = ndisc_option_parse_home_agent(&options, offset, length, opt);
|
||||
break;
|
||||
|
||||
case SD_NDISC_OPTION_ROUTE_INFORMATION:
|
||||
r = ndisc_option_parse_route(&options, offset, length, opt);
|
||||
break;
|
||||
@@ -1228,6 +1290,10 @@ int ndisc_send(int fd, const struct sockaddr_in6 *dst, const struct icmp6_hdr *h
|
||||
r = ndisc_option_build_mtu(option, &buf);
|
||||
break;
|
||||
|
||||
case SD_NDISC_OPTION_HOME_AGENT:
|
||||
r = ndisc_option_build_home_agent(option, &buf);
|
||||
break;
|
||||
|
||||
case SD_NDISC_OPTION_ROUTE_INFORMATION:
|
||||
r = ndisc_option_build_route(option, &buf);
|
||||
break;
|
||||
|
||||
@@ -29,6 +29,11 @@ typedef struct sd_ndisc_prefix {
|
||||
usec_t preferred_lifetime;
|
||||
} sd_ndisc_prefix;
|
||||
|
||||
typedef struct sd_ndisc_home_agent {
|
||||
uint16_t preference;
|
||||
usec_t lifetime;
|
||||
} sd_ndisc_home_agent;
|
||||
|
||||
typedef struct sd_ndisc_route {
|
||||
uint8_t preference;
|
||||
uint8_t prefixlen;
|
||||
@@ -58,17 +63,18 @@ typedef struct sd_ndisc_option {
|
||||
size_t offset;
|
||||
|
||||
union {
|
||||
sd_ndisc_raw raw; /* for testing or unsupported options */
|
||||
struct ether_addr mac; /* SD_NDISC_OPTION_SOURCE_LL_ADDRESS or SD_NDISC_OPTION_TARGET_LL_ADDRESS */
|
||||
sd_ndisc_prefix prefix; /* SD_NDISC_OPTION_PREFIX_INFORMATION */
|
||||
struct ip6_hdr hdr; /* SD_NDISC_OPTION_REDIRECTED_HEADER */
|
||||
uint32_t mtu; /* SD_NDISC_OPTION_MTU */
|
||||
sd_ndisc_route route; /* SD_NDISC_OPTION_ROUTE_INFORMATION */
|
||||
sd_ndisc_rdnss rdnss; /* SD_NDISC_OPTION_RDNSS */
|
||||
uint64_t extended_flags; /* SD_NDISC_OPTION_FLAGS_EXTENSION */
|
||||
sd_ndisc_dnssl dnssl; /* SD_NDISC_OPTION_DNSSL */
|
||||
char *captive_portal; /* SD_NDISC_OPTION_CAPTIVE_PORTAL */
|
||||
sd_ndisc_prefix64 prefix64; /* SD_NDISC_OPTION_PREF64 */
|
||||
sd_ndisc_raw raw; /* for testing or unsupported options */
|
||||
struct ether_addr mac; /* SD_NDISC_OPTION_SOURCE_LL_ADDRESS or SD_NDISC_OPTION_TARGET_LL_ADDRESS */
|
||||
sd_ndisc_prefix prefix; /* SD_NDISC_OPTION_PREFIX_INFORMATION */
|
||||
struct ip6_hdr hdr; /* SD_NDISC_OPTION_REDIRECTED_HEADER */
|
||||
uint32_t mtu; /* SD_NDISC_OPTION_MTU */
|
||||
sd_ndisc_home_agent home_agent; /* SD_NDISC_OPTION_HOME_AGENT */
|
||||
sd_ndisc_route route; /* SD_NDISC_OPTION_ROUTE_INFORMATION */
|
||||
sd_ndisc_rdnss rdnss; /* SD_NDISC_OPTION_RDNSS */
|
||||
uint64_t extended_flags; /* SD_NDISC_OPTION_FLAGS_EXTENSION */
|
||||
sd_ndisc_dnssl dnssl; /* SD_NDISC_OPTION_DNSSL */
|
||||
char *captive_portal; /* SD_NDISC_OPTION_CAPTIVE_PORTAL */
|
||||
sd_ndisc_prefix64 prefix64; /* SD_NDISC_OPTION_PREF64 */
|
||||
};
|
||||
} sd_ndisc_option;
|
||||
|
||||
@@ -150,6 +156,11 @@ int ndisc_option_add_mtu(
|
||||
Set **options,
|
||||
size_t offset,
|
||||
uint32_t mtu);
|
||||
int ndisc_option_add_home_agent(
|
||||
Set **options,
|
||||
size_t offset,
|
||||
uint16_t preference,
|
||||
usec_t lifetime);
|
||||
int ndisc_option_add_route(
|
||||
Set **options,
|
||||
size_t offset,
|
||||
|
||||
Reference in New Issue
Block a user