mirror of
https://github.com/systemd/systemd.git
synced 2025-02-10 17:57:40 +03:00
Merge pull request #11208 from thom311/dhcp-router-option-list
dhcp: have DHCP library support multiple router entries in Router option (3)
This commit is contained in:
commit
c014a33fac
@ -68,6 +68,14 @@ bool in4_addr_is_localhost(const struct in_addr *a) {
|
||||
return (be32toh(a->s_addr) & UINT32_C(0xFF000000)) == UINT32_C(127) << 24;
|
||||
}
|
||||
|
||||
bool in4_addr_is_non_local(const struct in_addr *a) {
|
||||
/* Whether the address is not null and not localhost.
|
||||
*
|
||||
* As such, it is suitable to configure as DNS/NTP server from DHCP. */
|
||||
return !in4_addr_is_null(a) &&
|
||||
!in4_addr_is_localhost(a);
|
||||
}
|
||||
|
||||
int in_addr_is_localhost(int family, const union in_addr_union *u) {
|
||||
assert(u);
|
||||
|
||||
|
@ -30,6 +30,8 @@ int in_addr_is_link_local(int family, const union in_addr_union *u);
|
||||
bool in4_addr_is_localhost(const struct in_addr *a);
|
||||
int in_addr_is_localhost(int family, const union in_addr_union *u);
|
||||
|
||||
bool in4_addr_is_non_local(const struct in_addr *a);
|
||||
|
||||
int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b);
|
||||
int in_addr_prefix_intersect(int family, const union in_addr_union *a, unsigned aprefixlen, const union in_addr_union *b, unsigned bprefixlen);
|
||||
int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen);
|
||||
|
@ -41,7 +41,6 @@ struct sd_dhcp_lease {
|
||||
/* each 0 if unset */
|
||||
be32_t address;
|
||||
be32_t server_address;
|
||||
be32_t router;
|
||||
be32_t next_server;
|
||||
|
||||
bool have_subnet_mask;
|
||||
@ -50,6 +49,9 @@ struct sd_dhcp_lease {
|
||||
bool have_broadcast;
|
||||
be32_t broadcast;
|
||||
|
||||
struct in_addr *router;
|
||||
size_t router_size;
|
||||
|
||||
struct in_addr *dns;
|
||||
size_t dns_size;
|
||||
|
||||
|
@ -414,16 +414,33 @@ int config_parse_bridge_port_priority(
|
||||
return 0;
|
||||
}
|
||||
|
||||
void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size) {
|
||||
unsigned i;
|
||||
size_t serialize_in_addrs(FILE *f,
|
||||
const struct in_addr *addresses,
|
||||
size_t size,
|
||||
bool with_leading_space,
|
||||
bool (*predicate)(const struct in_addr *addr)) {
|
||||
size_t count;
|
||||
size_t i;
|
||||
|
||||
assert(f);
|
||||
assert(addresses);
|
||||
assert(size);
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
fprintf(f, "%s%s", inet_ntoa(addresses[i]),
|
||||
(i < (size - 1)) ? " ": "");
|
||||
count = 0;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
char sbuf[INET_ADDRSTRLEN];
|
||||
|
||||
if (predicate && !predicate(&addresses[i]))
|
||||
continue;
|
||||
if (with_leading_space)
|
||||
fputc(' ', f);
|
||||
else
|
||||
with_leading_space = true;
|
||||
fputs(inet_ntop(AF_INET, &addresses[i], sbuf, sizeof(sbuf)), f);
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int deserialize_in_addrs(struct in_addr **ret, const char *string) {
|
||||
@ -457,7 +474,7 @@ int deserialize_in_addrs(struct in_addr **ret, const char *string) {
|
||||
size++;
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(addresses);
|
||||
*ret = size > 0 ? TAKE_PTR(addresses) : NULL;
|
||||
|
||||
return size;
|
||||
}
|
||||
@ -526,6 +543,7 @@ void serialize_dhcp_routes(FILE *f, const char *key, sd_dhcp_route **routes, siz
|
||||
fprintf(f, "%s=", key);
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
char sbuf[INET_ADDRSTRLEN];
|
||||
struct in_addr dest, gw;
|
||||
uint8_t length;
|
||||
|
||||
@ -533,8 +551,8 @@ void serialize_dhcp_routes(FILE *f, const char *key, sd_dhcp_route **routes, siz
|
||||
assert_se(sd_dhcp_route_get_gateway(routes[i], &gw) >= 0);
|
||||
assert_se(sd_dhcp_route_get_destination_prefix_length(routes[i], &length) >= 0);
|
||||
|
||||
fprintf(f, "%s/%" PRIu8, inet_ntoa(dest), length);
|
||||
fprintf(f, ",%s%s", inet_ntoa(gw), (i < (size - 1)) ? " ": "");
|
||||
fprintf(f, "%s/%" PRIu8, inet_ntop(AF_INET, &dest, sbuf, sizeof(sbuf)), length);
|
||||
fprintf(f, ",%s%s", inet_ntop(AF_INET, &gw, sbuf, sizeof(sbuf)), (i < (size - 1)) ? " ": "");
|
||||
}
|
||||
|
||||
fputs("\n", f);
|
||||
|
@ -40,7 +40,11 @@ CONFIG_PARSER_PROTOTYPE(config_parse_bridge_port_priority);
|
||||
int net_get_unique_predictable_data(sd_device *device, uint64_t *result);
|
||||
const char *net_get_name(sd_device *device);
|
||||
|
||||
void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size);
|
||||
size_t serialize_in_addrs(FILE *f,
|
||||
const struct in_addr *addresses,
|
||||
size_t size,
|
||||
bool with_leading_space,
|
||||
bool (*predicate)(const struct in_addr *addr));
|
||||
int deserialize_in_addrs(struct in_addr **addresses, const char *string);
|
||||
void serialize_in6_addrs(FILE *f, const struct in6_addr *addresses,
|
||||
size_t size);
|
||||
|
@ -151,15 +151,15 @@ int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, struct in_addr *addr) {
|
||||
int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, const struct in_addr **addr) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(addr, -EINVAL);
|
||||
|
||||
if (lease->router == 0)
|
||||
if (lease->router_size <= 0)
|
||||
return -ENODATA;
|
||||
|
||||
addr->s_addr = lease->router;
|
||||
return 0;
|
||||
*addr = lease->router;
|
||||
return (int) lease->router_size;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr) {
|
||||
@ -261,6 +261,7 @@ static sd_dhcp_lease *dhcp_lease_free(sd_dhcp_lease *lease) {
|
||||
}
|
||||
|
||||
free(lease->root_path);
|
||||
free(lease->router);
|
||||
free(lease->timezone);
|
||||
free(lease->hostname);
|
||||
free(lease->domainname);
|
||||
@ -370,23 +371,6 @@ static int lease_parse_domain(const uint8_t *option, size_t len, char **ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void filter_bogus_addresses(struct in_addr *addresses, size_t *n) {
|
||||
size_t i, j;
|
||||
|
||||
/* Silently filter DNS/NTP servers supplied to us that do not make outside of the local scope. */
|
||||
|
||||
for (i = 0, j = 0; i < *n; i ++) {
|
||||
|
||||
if (in4_addr_is_null(addresses+i) ||
|
||||
in4_addr_is_localhost(addresses+i))
|
||||
continue;
|
||||
|
||||
addresses[j++] = addresses[i];
|
||||
}
|
||||
|
||||
*n = j;
|
||||
}
|
||||
|
||||
static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_addr **ret, size_t *n_ret) {
|
||||
assert(option);
|
||||
assert(ret);
|
||||
@ -408,8 +392,6 @@ static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_add
|
||||
if (!addresses)
|
||||
return -ENOMEM;
|
||||
|
||||
filter_bogus_addresses(addresses, &n_addresses);
|
||||
|
||||
free(*ret);
|
||||
*ret = addresses;
|
||||
*n_ret = n_addresses;
|
||||
@ -554,11 +536,9 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
|
||||
break;
|
||||
|
||||
case SD_DHCP_OPTION_ROUTER:
|
||||
if (len >= 4) {
|
||||
r = lease_parse_be32(option, 4, &lease->router);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to parse router address, ignoring: %m");
|
||||
}
|
||||
r = lease_parse_in_addrs(option, len, &lease->router, &lease->router_size);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to parse router addresses, ignoring: %m");
|
||||
break;
|
||||
|
||||
case SD_DHCP_OPTION_DOMAIN_NAME_SERVER:
|
||||
@ -820,7 +800,6 @@ int dhcp_lease_new(sd_dhcp_lease **ret) {
|
||||
if (!lease)
|
||||
return -ENOMEM;
|
||||
|
||||
lease->router = INADDR_ANY;
|
||||
lease->n_ref = 1;
|
||||
|
||||
*ret = lease;
|
||||
@ -835,6 +814,7 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
|
||||
const struct in_addr *addresses;
|
||||
const void *client_id, *data;
|
||||
size_t client_id_len, data_len;
|
||||
char sbuf[INET_ADDRSTRLEN];
|
||||
const char *string;
|
||||
uint16_t mtu;
|
||||
_cleanup_free_ sd_dhcp_route **routes = NULL;
|
||||
@ -857,27 +837,30 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
|
||||
|
||||
r = sd_dhcp_lease_get_address(lease, &address);
|
||||
if (r >= 0)
|
||||
fprintf(f, "ADDRESS=%s\n", inet_ntoa(address));
|
||||
fprintf(f, "ADDRESS=%s\n", inet_ntop(AF_INET, &address, sbuf, sizeof(sbuf)));
|
||||
|
||||
r = sd_dhcp_lease_get_netmask(lease, &address);
|
||||
if (r >= 0)
|
||||
fprintf(f, "NETMASK=%s\n", inet_ntoa(address));
|
||||
fprintf(f, "NETMASK=%s\n", inet_ntop(AF_INET, &address, sbuf, sizeof(sbuf)));
|
||||
|
||||
r = sd_dhcp_lease_get_router(lease, &address);
|
||||
if (r >= 0)
|
||||
fprintf(f, "ROUTER=%s\n", inet_ntoa(address));
|
||||
r = sd_dhcp_lease_get_router(lease, &addresses);
|
||||
if (r > 0) {
|
||||
fputs("ROUTER=", f);
|
||||
serialize_in_addrs(f, addresses, r, false, NULL);
|
||||
fputc('\n', f);
|
||||
}
|
||||
|
||||
r = sd_dhcp_lease_get_server_identifier(lease, &address);
|
||||
if (r >= 0)
|
||||
fprintf(f, "SERVER_ADDRESS=%s\n", inet_ntoa(address));
|
||||
fprintf(f, "SERVER_ADDRESS=%s\n", inet_ntop(AF_INET, &address, sbuf, sizeof(sbuf)));
|
||||
|
||||
r = sd_dhcp_lease_get_next_server(lease, &address);
|
||||
if (r >= 0)
|
||||
fprintf(f, "NEXT_SERVER=%s\n", inet_ntoa(address));
|
||||
fprintf(f, "NEXT_SERVER=%s\n", inet_ntop(AF_INET, &address, sbuf, sizeof(sbuf)));
|
||||
|
||||
r = sd_dhcp_lease_get_broadcast(lease, &address);
|
||||
if (r >= 0)
|
||||
fprintf(f, "BROADCAST=%s\n", inet_ntoa(address));
|
||||
fprintf(f, "BROADCAST=%s\n", inet_ntop(AF_INET, &address, sbuf, sizeof(sbuf)));
|
||||
|
||||
r = sd_dhcp_lease_get_mtu(lease, &mtu);
|
||||
if (r >= 0)
|
||||
@ -898,15 +881,15 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
|
||||
r = sd_dhcp_lease_get_dns(lease, &addresses);
|
||||
if (r > 0) {
|
||||
fputs("DNS=", f);
|
||||
serialize_in_addrs(f, addresses, r);
|
||||
fputs("\n", f);
|
||||
serialize_in_addrs(f, addresses, r, false, NULL);
|
||||
fputc('\n', f);
|
||||
}
|
||||
|
||||
r = sd_dhcp_lease_get_ntp(lease, &addresses);
|
||||
if (r > 0) {
|
||||
fputs("NTP=", f);
|
||||
serialize_in_addrs(f, addresses, r);
|
||||
fputs("\n", f);
|
||||
serialize_in_addrs(f, addresses, r, false, NULL);
|
||||
fputc('\n', f);
|
||||
}
|
||||
|
||||
r = sd_dhcp_lease_get_domainname(lease, &string);
|
||||
@ -917,7 +900,7 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
|
||||
if (r > 0) {
|
||||
fputs("DOMAIN_SEARCH_LIST=", f);
|
||||
fputstrv(f, search_domains, NULL, NULL);
|
||||
fputs("\n", f);
|
||||
fputc('\n', f);
|
||||
}
|
||||
|
||||
r = sd_dhcp_lease_get_hostname(lease, &string);
|
||||
@ -1080,9 +1063,11 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
|
||||
}
|
||||
|
||||
if (router) {
|
||||
r = inet_pton(AF_INET, router, &lease->router);
|
||||
if (r <= 0)
|
||||
log_debug("Failed to parse router %s, ignoring.", router);
|
||||
r = deserialize_in_addrs(&lease->router, router);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to deserialize router addresses %s, ignoring: %m", router);
|
||||
else
|
||||
lease->router_size = r;
|
||||
}
|
||||
|
||||
if (netmask) {
|
||||
|
@ -423,6 +423,7 @@ static void test_addr_acq_acquired(sd_dhcp_client *client, int event,
|
||||
sd_event *e = userdata;
|
||||
sd_dhcp_lease *lease;
|
||||
struct in_addr addr;
|
||||
const struct in_addr *addrs;
|
||||
|
||||
assert_se(client);
|
||||
assert_se(event == SD_DHCP_CLIENT_EVENT_IP_ACQUIRE);
|
||||
@ -438,9 +439,9 @@ static void test_addr_acq_acquired(sd_dhcp_client *client, int event,
|
||||
assert_se(memcmp(&addr.s_addr, &test_addr_acq_ack[285],
|
||||
sizeof(addr.s_addr)) == 0);
|
||||
|
||||
assert_se(sd_dhcp_lease_get_router(lease, &addr) >= 0);
|
||||
assert_se(memcmp(&addr.s_addr, &test_addr_acq_ack[308],
|
||||
sizeof(addr.s_addr)) == 0);
|
||||
assert_se(sd_dhcp_lease_get_router(lease, &addrs) == 1);
|
||||
assert_se(memcmp(&addrs[0].s_addr, &test_addr_acq_ack[308],
|
||||
sizeof(addrs[0].s_addr)) == 0);
|
||||
|
||||
if (verbose)
|
||||
printf(" DHCP address acquired\n");
|
||||
|
@ -51,7 +51,8 @@ static int route_scope_from_address(const Route *route, const struct in_addr *se
|
||||
static int link_set_dhcp_routes(Link *link) {
|
||||
_cleanup_free_ sd_dhcp_route **static_routes = NULL;
|
||||
bool classless_route = false, static_route = false;
|
||||
struct in_addr gateway, address;
|
||||
const struct in_addr *router;
|
||||
struct in_addr address;
|
||||
int r, n, i;
|
||||
uint32_t table;
|
||||
|
||||
@ -118,18 +119,18 @@ static int link_set_dhcp_routes(Link *link) {
|
||||
link->dhcp4_messages++;
|
||||
}
|
||||
|
||||
r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
|
||||
if (r == -ENODATA)
|
||||
log_link_info_errno(link, r, "DHCP: No gateway received from DHCP server: %m");
|
||||
else if (r < 0)
|
||||
r = sd_dhcp_lease_get_router(link->dhcp_lease, &router);
|
||||
if (r < 0 && r != -ENODATA)
|
||||
log_link_warning_errno(link, r, "DHCP error: could not get gateway: %m");
|
||||
else if (r <= 0 || in4_addr_is_null(&router[0]))
|
||||
log_link_info_errno(link, r, "DHCP: No gateway received from DHCP server: %m");
|
||||
|
||||
/* According to RFC 3442: If the DHCP server returns both a Classless Static Routes option and
|
||||
a Router option, the DHCP client MUST ignore the Router option. */
|
||||
if (classless_route && static_route)
|
||||
log_link_warning(link, "Classless static routes received from DHCP server: ignoring static-route option and router option");
|
||||
|
||||
if (r >= 0 && !classless_route) {
|
||||
if (r > 0 && !classless_route && !in4_addr_is_null(&router[0])) {
|
||||
_cleanup_(route_freep) Route *route = NULL, *route_gw = NULL;
|
||||
|
||||
r = route_new(&route_gw);
|
||||
@ -140,7 +141,7 @@ static int link_set_dhcp_routes(Link *link) {
|
||||
* route for the gw host so that we can route no matter the
|
||||
* netmask or existing kernel route tables. */
|
||||
route_gw->family = AF_INET;
|
||||
route_gw->dst.in = gateway;
|
||||
route_gw->dst.in = router[0];
|
||||
route_gw->dst_prefixlen = 32;
|
||||
route_gw->prefsrc.in = address;
|
||||
route_gw->scope = RT_SCOPE_LINK;
|
||||
@ -159,7 +160,7 @@ static int link_set_dhcp_routes(Link *link) {
|
||||
return log_link_error_errno(link, r, "Could not allocate route: %m");
|
||||
|
||||
route->family = AF_INET;
|
||||
route->gw.in = gateway;
|
||||
route->gw.in = router[0];
|
||||
route->prefsrc.in = address;
|
||||
route->protocol = RTPROT_DHCP;
|
||||
route->priority = link->network->dhcp_route_metric;
|
||||
@ -180,9 +181,9 @@ static int link_set_dhcp_routes(Link *link) {
|
||||
|
||||
static int dhcp_lease_lost(Link *link) {
|
||||
_cleanup_(address_freep) Address *address = NULL;
|
||||
const struct in_addr *router;
|
||||
struct in_addr addr;
|
||||
struct in_addr netmask;
|
||||
struct in_addr gateway;
|
||||
unsigned prefixlen = 0;
|
||||
int r;
|
||||
|
||||
@ -215,15 +216,15 @@ static int dhcp_lease_lost(Link *link) {
|
||||
|
||||
r = address_new(&address);
|
||||
if (r >= 0) {
|
||||
r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
|
||||
if (r >= 0) {
|
||||
r = sd_dhcp_lease_get_router(link->dhcp_lease, &router);
|
||||
if (r > 0 && !in4_addr_is_null(&router[0])) {
|
||||
_cleanup_(route_freep) Route *route_gw = NULL;
|
||||
_cleanup_(route_freep) Route *route = NULL;
|
||||
|
||||
r = route_new(&route_gw);
|
||||
if (r >= 0) {
|
||||
route_gw->family = AF_INET;
|
||||
route_gw->dst.in = gateway;
|
||||
route_gw->dst.in = router[0];
|
||||
route_gw->dst_prefixlen = 32;
|
||||
route_gw->scope = RT_SCOPE_LINK;
|
||||
|
||||
@ -233,7 +234,7 @@ static int dhcp_lease_lost(Link *link) {
|
||||
r = route_new(&route);
|
||||
if (r >= 0) {
|
||||
route->family = AF_INET;
|
||||
route->gw.in = gateway;
|
||||
route->gw.in = router[0];
|
||||
|
||||
route_remove(route, link, NULL);
|
||||
}
|
||||
@ -392,10 +393,10 @@ static int dhcp_lease_renew(sd_dhcp_client *client, Link *link) {
|
||||
}
|
||||
|
||||
static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
|
||||
const struct in_addr *router;
|
||||
sd_dhcp_lease *lease;
|
||||
struct in_addr address;
|
||||
struct in_addr netmask;
|
||||
struct in_addr gateway;
|
||||
unsigned prefixlen;
|
||||
uint32_t lifetime = CACHE_INFO_INFINITY_LIFE_TIME;
|
||||
int r;
|
||||
@ -417,20 +418,20 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
|
||||
|
||||
prefixlen = in4_addr_netmask_to_prefixlen(&netmask);
|
||||
|
||||
r = sd_dhcp_lease_get_router(lease, &gateway);
|
||||
r = sd_dhcp_lease_get_router(lease, &router);
|
||||
if (r < 0 && r != -ENODATA)
|
||||
return log_link_error_errno(link, r, "DHCP error: Could not get gateway: %m");
|
||||
|
||||
if (r >= 0)
|
||||
if (r > 0 && !in4_addr_is_null(&router[0]))
|
||||
log_struct(LOG_INFO,
|
||||
LOG_LINK_INTERFACE(link),
|
||||
LOG_LINK_MESSAGE(link, "DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
|
||||
ADDRESS_FMT_VAL(address),
|
||||
prefixlen,
|
||||
ADDRESS_FMT_VAL(gateway)),
|
||||
ADDRESS_FMT_VAL(router[0])),
|
||||
"ADDRESS=%u.%u.%u.%u", ADDRESS_FMT_VAL(address),
|
||||
"PREFIXLEN=%u", prefixlen,
|
||||
"GATEWAY=%u.%u.%u.%u", ADDRESS_FMT_VAL(gateway));
|
||||
"GATEWAY=%u.%u.%u.%u", ADDRESS_FMT_VAL(router[0]));
|
||||
else
|
||||
log_struct(LOG_INFO,
|
||||
LOG_LINK_INTERFACE(link),
|
||||
|
@ -1058,7 +1058,7 @@ static int link_push_uplink_dns_to_dhcp_server(Link *link, sd_dhcp_server *s) {
|
||||
|
||||
if (link->network->dhcp_use_dns && link->dhcp_lease) {
|
||||
const struct in_addr *da = NULL;
|
||||
int n;
|
||||
int j, n;
|
||||
|
||||
n = sd_dhcp_lease_get_dns(link->dhcp_lease, &da);
|
||||
if (n > 0) {
|
||||
@ -1066,8 +1066,9 @@ static int link_push_uplink_dns_to_dhcp_server(Link *link, sd_dhcp_server *s) {
|
||||
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
|
||||
return log_oom();
|
||||
|
||||
memcpy(addresses + n_addresses, da, n * sizeof(struct in_addr));
|
||||
n_addresses += n;
|
||||
for (j = 0; j < n; j++)
|
||||
if (in4_addr_is_non_local(&da[j]))
|
||||
addresses[n_addresses++] = da[j];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1106,7 +1107,7 @@ static int link_push_uplink_ntp_to_dhcp_server(Link *link, sd_dhcp_server *s) {
|
||||
|
||||
if (link->network->dhcp_use_ntp && link->dhcp_lease) {
|
||||
const struct in_addr *da = NULL;
|
||||
int n;
|
||||
int j, n;
|
||||
|
||||
n = sd_dhcp_lease_get_ntp(link->dhcp_lease, &da);
|
||||
if (n > 0) {
|
||||
@ -1114,8 +1115,9 @@ static int link_push_uplink_ntp_to_dhcp_server(Link *link, sd_dhcp_server *s) {
|
||||
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
|
||||
return log_oom();
|
||||
|
||||
memcpy(addresses + n_addresses, da, n * sizeof(struct in_addr));
|
||||
n_addresses += n;
|
||||
for (j = 0; j < n; j++)
|
||||
if (in4_addr_is_non_local(&da[j]))
|
||||
addresses[n_addresses++] = da[j];
|
||||
}
|
||||
}
|
||||
|
||||
@ -4004,12 +4006,9 @@ int link_save(Link *link) {
|
||||
const struct in_addr *addresses;
|
||||
|
||||
r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
|
||||
if (r > 0) {
|
||||
if (space)
|
||||
fputc(' ', f);
|
||||
serialize_in_addrs(f, addresses, r);
|
||||
space = true;
|
||||
}
|
||||
if (r > 0)
|
||||
if (serialize_in_addrs(f, addresses, r, space, in4_addr_is_non_local) > 0)
|
||||
space = true;
|
||||
}
|
||||
|
||||
if (link->network->dhcp_use_dns && dhcp6_lease) {
|
||||
@ -4050,12 +4049,9 @@ int link_save(Link *link) {
|
||||
const struct in_addr *addresses;
|
||||
|
||||
r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
|
||||
if (r > 0) {
|
||||
if (space)
|
||||
fputc(' ', f);
|
||||
serialize_in_addrs(f, addresses, r);
|
||||
space = true;
|
||||
}
|
||||
if (r > 0)
|
||||
if (serialize_in_addrs(f, addresses, r, space, in4_addr_is_non_local) > 0)
|
||||
space = true;
|
||||
}
|
||||
|
||||
if (link->network->dhcp_use_ntp && dhcp6_lease) {
|
||||
@ -4200,7 +4196,7 @@ int link_save(Link *link) {
|
||||
r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
|
||||
if (r >= 0) {
|
||||
fputs("DHCP4_ADDRESS=", f);
|
||||
serialize_in_addrs(f, &address, 1);
|
||||
serialize_in_addrs(f, &address, 1, false, NULL);
|
||||
fputc('\n', f);
|
||||
}
|
||||
|
||||
@ -4220,7 +4216,7 @@ int link_save(Link *link) {
|
||||
r = sd_ipv4ll_get_address(link->ipv4ll, &address);
|
||||
if (r >= 0) {
|
||||
fputs("IPV4LL_ADDRESS=", f);
|
||||
serialize_in_addrs(f, &address, 1);
|
||||
serialize_in_addrs(f, &address, 1, false, NULL);
|
||||
fputc('\n', f);
|
||||
}
|
||||
}
|
||||
|
@ -1044,14 +1044,19 @@ static int ordered_set_put_in4_addr(OrderedSet *s, const struct in_addr *address
|
||||
return r;
|
||||
}
|
||||
|
||||
static int ordered_set_put_in4_addrv(OrderedSet *s, const struct in_addr *addresses, unsigned n) {
|
||||
static int ordered_set_put_in4_addrv(OrderedSet *s,
|
||||
const struct in_addr *addresses,
|
||||
size_t n,
|
||||
bool (*predicate)(const struct in_addr *addr)) {
|
||||
int r, c = 0;
|
||||
unsigned i;
|
||||
size_t i;
|
||||
|
||||
assert(s);
|
||||
assert(n == 0 || addresses);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (predicate && !predicate(&addresses[i]))
|
||||
continue;
|
||||
r = ordered_set_put_in4_addr(s, addresses+i);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -1144,7 +1149,7 @@ static int manager_save(Manager *m) {
|
||||
|
||||
r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
|
||||
if (r > 0) {
|
||||
r = ordered_set_put_in4_addrv(dns, addresses, r);
|
||||
r = ordered_set_put_in4_addrv(dns, addresses, r, in4_addr_is_non_local);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if (r < 0 && r != -ENODATA)
|
||||
@ -1156,7 +1161,7 @@ static int manager_save(Manager *m) {
|
||||
|
||||
r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
|
||||
if (r > 0) {
|
||||
r = ordered_set_put_in4_addrv(ntp, addresses, r);
|
||||
r = ordered_set_put_in4_addrv(ntp, addresses, r, in4_addr_is_non_local);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if (r < 0 && r != -ENODATA)
|
||||
|
@ -39,7 +39,7 @@ int sd_dhcp_lease_get_t1(sd_dhcp_lease *lease, uint32_t *t1);
|
||||
int sd_dhcp_lease_get_t2(sd_dhcp_lease *lease, uint32_t *t2);
|
||||
int sd_dhcp_lease_get_broadcast(sd_dhcp_lease *lease, struct in_addr *addr);
|
||||
int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr);
|
||||
int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, struct in_addr *addr);
|
||||
int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||
int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr);
|
||||
int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *addr);
|
||||
int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||
|
Loading…
x
Reference in New Issue
Block a user