mirror of
https://github.com/systemd/systemd.git
synced 2024-11-23 18:23:32 +08:00
network: dhcp6: introduce UplinkInterface= for DHCP6 prefix delegation
This commit is contained in:
parent
2cba2146ac
commit
dc5cae6c9d
@ -2123,6 +2123,17 @@ Table=1234</programlisting></para>
|
||||
is enabled.</para>
|
||||
|
||||
<variablelist class='network-directives'>
|
||||
<varlistentry>
|
||||
<term><varname>UplinkInterface=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the name or the index of the uplink interface, or one of the special values
|
||||
<literal>:self</literal> and <literal>:auto</literal>. When <literal>:self</literal>, the
|
||||
interface itself is considered the uplink interface. When <literal>:auto</literal>, the first
|
||||
link which acquired prefixes to be delegated from the DHCPv6 server is selected. Defaults to
|
||||
<literal>:auto</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>SubnetId=</varname></term>
|
||||
<listitem>
|
||||
|
@ -1281,6 +1281,7 @@ int config_parse_uplink(
|
||||
void *userdata) {
|
||||
|
||||
Network *network = userdata;
|
||||
bool accept_none = true;
|
||||
int *index, r;
|
||||
char **name;
|
||||
|
||||
@ -1288,6 +1289,7 @@ int config_parse_uplink(
|
||||
assert(section);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(userdata);
|
||||
|
||||
if (streq(section, "DHCPServer")) {
|
||||
index = &network->dhcp_server_uplink_index;
|
||||
@ -1295,6 +1297,10 @@ int config_parse_uplink(
|
||||
} else if (streq(section, "IPv6SendRA")) {
|
||||
index = &network->router_uplink_index;
|
||||
name = &network->router_uplink_name;
|
||||
} else if (streq(section, "DHCPv6PrefixDelegation")) {
|
||||
index = &network->dhcp6_pd_uplink_index;
|
||||
name = &network->dhcp_server_uplink_name;
|
||||
accept_none = false;
|
||||
} else
|
||||
assert_not_reached();
|
||||
|
||||
@ -1304,12 +1310,18 @@ int config_parse_uplink(
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (streq(rvalue, ":none")) {
|
||||
if (accept_none && streq(rvalue, ":none")) {
|
||||
*index = UPLINK_INDEX_NONE;
|
||||
*name = mfree(*name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!accept_none && streq(rvalue, ":self")) {
|
||||
*index = UPLINK_INDEX_SELF;
|
||||
*name = mfree(*name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = parse_ifindex(rvalue);
|
||||
if (r > 0) {
|
||||
*index = r;
|
||||
|
@ -12,6 +12,7 @@
|
||||
/* Special values for *_uplink_index. */
|
||||
#define UPLINK_INDEX_AUTO 0 /* uplink will be selected automatically */
|
||||
#define UPLINK_INDEX_NONE -1 /* uplink will not be selected automatically */
|
||||
#define UPLINK_INDEX_SELF -2 /* the interface itself is uplink */
|
||||
|
||||
#define DHCP_ROUTE_METRIC 1024
|
||||
#define DHCP6PD_ROUTE_METRIC 256
|
||||
|
@ -42,6 +42,22 @@ bool link_dhcp6_pd_is_enabled(Link *link) {
|
||||
return link->network->dhcp6_pd;
|
||||
}
|
||||
|
||||
static int dhcp6_pd_resolve_uplink(Link *link, Link **ret) {
|
||||
if (link->network->dhcp6_pd_uplink_name)
|
||||
return link_get_by_name(link->manager, link->network->dhcp6_pd_uplink_name, ret);
|
||||
|
||||
if (link->network->dhcp6_pd_uplink_index > 0)
|
||||
return link_get_by_index(link->manager, link->network->dhcp6_pd_uplink_index, ret);
|
||||
|
||||
if (link->network->dhcp6_pd_uplink_index == UPLINK_INDEX_SELF) {
|
||||
*ret = link;
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(link->network->dhcp6_pd_uplink_index == UPLINK_INDEX_AUTO);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static bool dhcp6_lease_has_pd_prefix(sd_dhcp6_lease *lease) {
|
||||
uint32_t lifetime_preferred_sec, lifetime_valid_sec;
|
||||
struct in6_addr pd_prefix;
|
||||
@ -575,6 +591,7 @@ static int dhcp6_pd_distribute_prefix(
|
||||
assert(pd_prefix_len <= 64);
|
||||
|
||||
HASHMAP_FOREACH(link, dhcp6_link->manager->links_by_index) {
|
||||
Link *uplink;
|
||||
|
||||
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
|
||||
continue;
|
||||
@ -591,6 +608,15 @@ static int dhcp6_pd_distribute_prefix(
|
||||
if (assign_preferred_subnet_id != link_has_preferred_subnet_id(link))
|
||||
continue;
|
||||
|
||||
r = dhcp6_pd_resolve_uplink(link, &uplink);
|
||||
if (r != -ENOENT) {
|
||||
if (r < 0) /* The uplink interface does not exist yet. */
|
||||
continue;
|
||||
|
||||
if (uplink != dhcp6_link)
|
||||
continue;
|
||||
}
|
||||
|
||||
r = dhcp6_pd_assign_prefix(link, pd_prefix, pd_prefix_len, lifetime_preferred_usec, lifetime_valid_usec);
|
||||
if (r < 0) {
|
||||
if (link == dhcp6_link)
|
||||
@ -1402,8 +1428,17 @@ static int dhcp6_pd_find_uplink(Link *link, Link **ret) {
|
||||
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
assert(link->network);
|
||||
assert(ret);
|
||||
|
||||
if (dhcp6_pd_resolve_uplink(link, &l) >= 0) {
|
||||
if (!dhcp6_pd_uplink_is_ready(l))
|
||||
return -EBUSY;
|
||||
|
||||
*ret = l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
HASHMAP_FOREACH(l, link->manager->links_by_index) {
|
||||
if (!dhcp6_pd_uplink_is_ready(l))
|
||||
continue;
|
||||
|
@ -325,6 +325,7 @@ BridgeMDB.VLANId, config_parse_mdb_vlan_id,
|
||||
BridgeVLAN.PVID, config_parse_brvlan_pvid, 0, 0
|
||||
BridgeVLAN.VLAN, config_parse_brvlan_vlan, 0, 0
|
||||
BridgeVLAN.EgressUntagged, config_parse_brvlan_untagged, 0, 0
|
||||
DHCPv6PrefixDelegation.UplinkInterface, config_parse_uplink, 0, 0
|
||||
DHCPv6PrefixDelegation.SubnetId, config_parse_dhcp6_pd_subnet_id, 0, offsetof(Network, dhcp6_pd_subnet_id)
|
||||
DHCPv6PrefixDelegation.Announce, config_parse_bool, 0, offsetof(Network, dhcp6_pd_announce)
|
||||
DHCPv6PrefixDelegation.Assign, config_parse_bool, 0, offsetof(Network, dhcp6_pd_assign)
|
||||
|
@ -241,6 +241,8 @@ struct Network {
|
||||
int64_t dhcp6_pd_subnet_id;
|
||||
uint32_t dhcp6_pd_route_metric;
|
||||
Set *dhcp6_pd_tokens;
|
||||
int dhcp6_pd_uplink_index;
|
||||
char *dhcp6_pd_uplink_name;
|
||||
|
||||
/* Bridge Support */
|
||||
int use_bpdu;
|
||||
|
@ -151,6 +151,7 @@ DUIDType=
|
||||
DUIDRawData=
|
||||
RouteTable=
|
||||
[DHCPv6PrefixDelegation]
|
||||
UplinkInterface=
|
||||
SubnetId=
|
||||
Announce=
|
||||
Assign=
|
||||
|
Loading…
Reference in New Issue
Block a user