Merge pull request #1055 from poettering/dhcp-updates

Various networkd and dhcp updates
This commit is contained in:
Tom Gundersen
2015-08-27 21:38:36 +02:00
61 changed files with 2362 additions and 1416 deletions
+3 -1
View File
@@ -21,7 +21,9 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
/* A type-safe atomic refcounter */
/* A type-safe atomic refcounter.
*
* DO NOT USE THIS UNLESS YOU ACTUALLY CARE ABOUT THREAD SAFETY! */
typedef struct {
volatile unsigned _value;
+1 -2
View File
@@ -50,7 +50,6 @@ int ring_push(Ring *r, const void *u8, size_t size);
void ring_pull(Ring *r, size_t size);
/* return size of occupied buffer in bytes */
static inline size_t ring_get_size(Ring *r)
{
static inline size_t ring_get_size(Ring *r) {
return r->used;
}
+32 -1
View File
@@ -26,6 +26,7 @@
#include "util.h"
#include "time-util.h"
#include "path-util.h"
#include "strv.h"
usec_t now(clockid_t clock_id) {
@@ -971,7 +972,10 @@ bool timezone_is_valid(const char *name) {
const char *p, *t;
struct stat st;
if (!name || *name == 0 || *name == '/')
if (isempty(name))
return false;
if (name[0] == '/')
return false;
for (p = name; *p; p++) {
@@ -1021,3 +1025,30 @@ clockid_t clock_boottime_or_monotonic(void) {
return clock;
}
int get_timezone(char **timezone) {
_cleanup_free_ char *t = NULL;
const char *e;
char *z;
int r;
r = readlink_malloc("/etc/localtime", &t);
if (r < 0)
return r; /* returns EINVAL if not a symlink */
e = path_startswith(t, "/usr/share/zoneinfo/");
if (!e)
e = path_startswith(t, "../usr/share/zoneinfo/");
if (!e)
return -EINVAL;
if (!timezone_is_valid(e))
return -EINVAL;
z = strdup(e);
if (!z)
return -ENOMEM;
*timezone = z;
return 0;
}
+2
View File
@@ -110,3 +110,5 @@ bool timezone_is_valid(const char *name);
clockid_t clock_boottime_or_monotonic(void);
#define xstrftime(buf, fmt, tm) assert_se(strftime(buf, ELEMENTSOF(buf), fmt, tm) > 0)
int get_timezone(char **timezone);
+5 -10
View File
@@ -70,16 +70,14 @@ typedef struct {
BOOLEAN no_editor;
} Config;
static VOID cursor_left(UINTN *cursor, UINTN *first)
{
static VOID cursor_left(UINTN *cursor, UINTN *first) {
if ((*cursor) > 0)
(*cursor)--;
else if ((*first) > 0)
(*first)--;
}
static VOID cursor_right(UINTN *cursor, UINTN *first, UINTN x_max, UINTN len)
{
static VOID cursor_right(UINTN *cursor, UINTN *first, UINTN x_max, UINTN len) {
if ((*cursor)+1 < x_max)
(*cursor)++;
else if ((*first) + (*cursor) < len)
@@ -856,13 +854,11 @@ static VOID config_entry_free(ConfigEntry *entry) {
FreePool(entry->options);
}
static BOOLEAN is_digit(CHAR16 c)
{
static BOOLEAN is_digit(CHAR16 c) {
return (c >= '0') && (c <= '9');
}
static UINTN c_order(CHAR16 c)
{
static UINTN c_order(CHAR16 c) {
if (c == '\0')
return 0;
if (is_digit(c))
@@ -873,8 +869,7 @@ static UINTN c_order(CHAR16 c)
return c + 0x10000;
}
static INTN str_verscmp(CHAR16 *s1, CHAR16 *s2)
{
static INTN str_verscmp(CHAR16 *s1, CHAR16 *s2) {
CHAR16 *os1 = s1;
CHAR16 *os2 = s2;
+2 -2
View File
@@ -45,10 +45,10 @@ int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset, uint8_
uint8_t code, size_t optlen, const void *optval);
typedef int (*dhcp_option_cb_t)(uint8_t code, uint8_t len,
const uint8_t *option, void *user_data);
const void *option, void *userdata);
int dhcp_option_parse(DHCPMessage *message, size_t len,
dhcp_option_cb_t cb, void *user_data);
dhcp_option_cb_t cb, void *userdata);
int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid,
uint8_t type, uint16_t arp_type, size_t optlen,
+30 -23
View File
@@ -25,7 +25,6 @@
#include <stdint.h>
#include <linux/if_packet.h>
#include "refcnt.h"
#include "util.h"
#include "list.h"
@@ -48,54 +47,62 @@ struct sd_dhcp_raw_option {
};
struct sd_dhcp_lease {
RefCount n_ref;
unsigned n_ref;
int32_t time_offset;
/* each 0 if unset */
uint32_t t1;
uint32_t t2;
uint32_t lifetime;
uint32_t mtu_aging_timeout;
/* each 0 if unset */
be32_t address;
be32_t server_address;
be32_t subnet_mask;
be32_t router;
be32_t next_server;
bool have_subnet_mask;
be32_t subnet_mask;
bool have_broadcast;
be32_t broadcast;
struct in_addr *dns;
size_t dns_size;
struct in_addr *ntp;
size_t ntp_size;
struct in_addr *policy_filter;
size_t policy_filter_size;
struct sd_dhcp_route *static_route;
size_t static_route_size;
size_t static_route_allocated;
uint16_t boot_file_size;
uint16_t mdr;
uint16_t mtu;
uint8_t ttl;
bool ip_forward;
bool ip_forward_non_local;
size_t static_route_size, static_route_allocated;
uint16_t mtu; /* 0 if unset */
char *domainname;
char *hostname;
char *root_path;
uint8_t *client_id;
void *client_id;
size_t client_id_len;
uint8_t *vendor_specific;
void *vendor_specific;
size_t vendor_specific_len;
char *timezone;
LIST_HEAD(struct sd_dhcp_raw_option, private_options);
};
int dhcp_lease_new(sd_dhcp_lease **ret);
int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option,
void *user_data);
int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag,
const uint8_t *data, uint8_t len);
int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void *userdata);
int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, const void *data, uint8_t len);
int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease);
int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const uint8_t *client_id,
size_t client_id_len);
int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const void *client_id, size_t client_id_len);
int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file);
int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file);
DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_lease*, sd_dhcp_lease_unref);
#define _cleanup_dhcp_lease_unref_ _cleanup_(sd_dhcp_lease_unrefp)
+6 -6
View File
@@ -140,7 +140,7 @@ int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset,
static int parse_options(const uint8_t options[], size_t buflen, uint8_t *overload,
uint8_t *message_type, dhcp_option_cb_t cb,
void *user_data) {
void *userdata) {
uint8_t code, len;
size_t offset = 0;
@@ -199,7 +199,7 @@ static int parse_options(const uint8_t options[], size_t buflen, uint8_t *overlo
return -EINVAL;
if (cb)
cb(code, len, &options[offset], user_data);
cb(code, len, &options[offset], userdata);
offset += len;
@@ -214,7 +214,7 @@ static int parse_options(const uint8_t options[], size_t buflen, uint8_t *overlo
}
int dhcp_option_parse(DHCPMessage *message, size_t len,
dhcp_option_cb_t cb, void *user_data) {
dhcp_option_cb_t cb, void *userdata) {
uint8_t overload = 0;
uint8_t message_type = 0;
int r;
@@ -228,20 +228,20 @@ int dhcp_option_parse(DHCPMessage *message, size_t len,
len -= sizeof(DHCPMessage);
r = parse_options(message->options, len, &overload, &message_type,
cb, user_data);
cb, userdata);
if (r < 0)
return r;
if (overload & DHCP_OVERLOAD_FILE) {
r = parse_options(message->file, sizeof(message->file),
NULL, &message_type, cb, user_data);
NULL, &message_type, cb, userdata);
if (r < 0)
return r;
}
if (overload & DHCP_OVERLOAD_SNAME) {
r = parse_options(message->sname, sizeof(message->sname),
NULL, &message_type, cb, user_data);
NULL, &message_type, cb, userdata);
if (r < 0)
return r;
}
+2
View File
@@ -137,6 +137,8 @@ enum {
DHCP_OPTION_REBINDING_T2_TIME = 59,
DHCP_OPTION_VENDOR_CLASS_IDENTIFIER = 60,
DHCP_OPTION_CLIENT_IDENTIFIER = 61,
DHCP_OPTION_NEW_POSIX_TIMEZONE = 100,
DHCP_OPTION_NEW_TZDB_TIMEZONE = 101,
DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121,
DHCP_OPTION_PRIVATE_BASE = 224,
DHCP_OPTION_PRIVATE_LAST = 254,
+11 -5
View File
@@ -26,7 +26,6 @@
#include "sd-dhcp-server.h"
#include "hashmap.h"
#include "refcnt.h"
#include "util.h"
#include "log.h"
@@ -34,7 +33,7 @@
typedef struct DHCPClientId {
size_t length;
uint8_t *data;
void *data;
} DHCPClientId;
typedef struct DHCPLease {
@@ -47,7 +46,7 @@ typedef struct DHCPLease {
} DHCPLease;
struct sd_dhcp_server {
RefCount n_ref;
unsigned n_ref;
sd_event *event;
int event_priority;
@@ -55,15 +54,22 @@ struct sd_dhcp_server {
int fd;
int fd_raw;
int index;
int ifindex;
be32_t address;
be32_t netmask;
be32_t pool_start;
size_t pool_size;
size_t next_offer;
char *timezone;
struct in_addr *ntp, *dns;
unsigned n_ntp, n_dns;
Hashmap *leases_by_client_id;
DHCPLease **bound_leases;
uint32_t max_lease_time, default_lease_time;
};
typedef struct DHCPRequest {
@@ -75,7 +81,7 @@ typedef struct DHCPRequest {
size_t max_optlen;
be32_t server_id;
be32_t requested_ip;
int lifetime;
uint32_t lifetime;
} DHCPRequest;
DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_server*, sd_dhcp_server_unref);
@@ -24,13 +24,11 @@
#include <stdint.h>
#include "refcnt.h"
#include "sd-dhcp6-lease.h"
#include "dhcp6-internal.h"
struct sd_dhcp6_lease {
RefCount n_ref;
unsigned n_ref;
uint8_t *serverid;
size_t serverid_len;
+2 -4
View File
@@ -41,8 +41,7 @@
{ { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }
int dhcp_network_icmp6_bind_router_solicitation(int index)
{
int dhcp_network_icmp6_bind_router_solicitation(int index) {
struct icmp6_filter filter = { };
struct ipv6_mreq mreq = {
.ipv6mr_multiaddr = IN6ADDR_ALL_NODES_MULTICAST_INIT,
@@ -92,8 +91,7 @@ int dhcp_network_icmp6_bind_router_solicitation(int index)
return r;
}
int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr)
{
int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
struct sockaddr_in6 dst = {
.sin6_family = AF_INET6,
.sin6_addr = IN6ADDR_ALL_ROUTERS_MULTICAST_INIT,
+1 -3
View File
@@ -338,9 +338,7 @@ int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
return count;
}
int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen,
char ***str_arr)
{
int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char ***str_arr) {
size_t pos = 0, idx = 0;
_cleanup_free_ char **names = NULL;
int r;
+7 -7
View File
@@ -374,9 +374,8 @@ int lldp_mib_add_objects(Prioq *by_expiry,
}
/* Admission Control: Can this port attached to the existing chassis ? */
if (REFCNT_GET(c->n_ref) >= LLDP_MIB_MAX_PORT_PER_CHASSIS) {
log_lldp("Port limit reached. Chassis has: %d ports. Dropping ...",
REFCNT_GET(c->n_ref));
if (c->n_ref >= LLDP_MIB_MAX_PORT_PER_CHASSIS) {
log_lldp("Port limit reached. Chassis has: %d ports. Dropping ...", c->n_ref);
c = NULL;
goto drop;
@@ -394,7 +393,7 @@ int lldp_mib_add_objects(Prioq *by_expiry,
/* Attach new port to chassis */
LIST_PREPEND(port, c->ports, p);
REFCNT_INC(c->n_ref);
c->n_ref ++;
p = NULL;
c = NULL;
@@ -424,7 +423,8 @@ void lldp_neighbour_port_remove_and_free(lldp_neighbour_port *p) {
lldp_neighbour_port_free(p);
/* Drop the Chassis if no port is attached */
if (REFCNT_DEC(c->n_ref) <= 1) {
c->n_ref --;
if (c->n_ref <= 1) {
hashmap_remove(c->neighbour_mib, &c->chassis_id);
lldp_chassis_free(c);
}
@@ -486,7 +486,7 @@ void lldp_chassis_free(lldp_chassis *c) {
if (!c)
return;
if (REFCNT_GET(c->n_ref) > 1)
if (c->n_ref > 1)
return;
free(c->chassis_id.data);
@@ -513,7 +513,7 @@ int lldp_chassis_new(tlv_packet *tlv,
if (!c)
return -ENOMEM;
c->n_ref = REFCNT_INIT;
c->n_ref = 1;
c->chassis_id.type = type;
c->chassis_id.length = length;
+1 -2
View File
@@ -24,7 +24,6 @@
#include "log.h"
#include "list.h"
#include "refcnt.h"
#include "lldp-tlv.h"
#include "prioq.h"
@@ -63,7 +62,7 @@ struct lldp_chassis_id {
};
struct lldp_chassis {
RefCount n_ref;
unsigned n_ref;
lldp_chassis_id chassis_id;
+2 -2
View File
@@ -525,7 +525,7 @@ int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t
return 0;
}
int serialize_dhcp_option(FILE *f, const char *key, const uint8_t *data, size_t size) {
int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t size) {
_cleanup_free_ char *hex_buf = NULL;
assert(f);
@@ -541,7 +541,7 @@ int serialize_dhcp_option(FILE *f, const char *key, const uint8_t *data, size_t
return 0;
}
int deserialize_dhcp_option(uint8_t **data, size_t *data_len, const char *string) {
int deserialize_dhcp_option(void **data, size_t *data_len, const char *string) {
assert(data);
assert(data_len);
assert(string);
+2 -2
View File
@@ -77,5 +77,5 @@ struct sd_dhcp_route;
void serialize_dhcp_routes(FILE *f, const char *key, struct sd_dhcp_route *routes, size_t size);
int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_allocated, const char *string);
int serialize_dhcp_option(FILE *f, const char *key, const uint8_t *data, size_t size);
int deserialize_dhcp_option(uint8_t **data, size_t *data_len, const char *string);
int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t size);
int deserialize_dhcp_option(void **data, size_t *data_len, const char *string);
+43 -33
View File
@@ -27,7 +27,6 @@
#include <sys/ioctl.h>
#include "util.h"
#include "refcnt.h"
#include "random-util.h"
#include "async.h"
@@ -41,7 +40,7 @@
#define MAX_MAC_ADDR_LEN CONST_MAX(INFINIBAND_ALEN, ETH_ALEN)
struct sd_dhcp_client {
RefCount n_ref;
unsigned n_ref;
DHCPState state;
sd_event *event;
@@ -106,7 +105,6 @@ static const uint8_t default_req_opts[] = {
DHCP_OPTION_HOST_NAME,
DHCP_OPTION_DOMAIN_NAME,
DHCP_OPTION_DOMAIN_NAME_SERVER,
DHCP_OPTION_NTP_SERVER,
};
static int client_receive_message_raw(sd_event_source *s, int fd,
@@ -377,8 +375,7 @@ static int client_initialize(sd_dhcp_client *client) {
client->state = DHCP_STATE_INIT;
client->xid = 0;
if (client->lease)
client->lease = sd_dhcp_lease_unref(client->lease);
client->lease = sd_dhcp_lease_unref(client->lease);
return 0;
}
@@ -1055,18 +1052,16 @@ static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer,
}
lease->next_server = offer->siaddr;
lease->address = offer->yiaddr;
if (lease->address == INADDR_ANY ||
lease->server_address == INADDR_ANY ||
if (lease->address == 0 ||
lease->server_address == 0 ||
lease->lifetime == 0) {
log_dhcp_client(client, "received lease lacks address, server "
"address or lease lifetime, ignoring");
log_dhcp_client(client, "received lease lacks address, server address or lease lifetime, ignoring");
return -ENOMSG;
}
if (lease->subnet_mask == INADDR_ANY) {
if (!lease->have_subnet_mask) {
r = dhcp_lease_set_default_subnet_mask(lease);
if (r < 0) {
log_dhcp_client(client, "received lease lacks subnet "
@@ -1168,13 +1163,17 @@ static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack,
return r;
}
static uint64_t client_compute_timeout(sd_dhcp_client *client,
uint32_t lifetime, double factor) {
static uint64_t client_compute_timeout(sd_dhcp_client *client, uint32_t lifetime, double factor) {
assert(client);
assert(client->request_sent);
assert(lifetime);
assert(lifetime > 0);
return client->request_sent + ((lifetime - 3) * USEC_PER_SEC * factor) +
if (lifetime > 3)
lifetime -= 3;
else
lifetime = 0;
return client->request_sent + (lifetime * USEC_PER_SEC * factor) +
+ (random_u32() & 0x1fffff);
}
@@ -1206,7 +1205,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
/* convert the various timeouts from relative (secs) to absolute (usecs) */
lifetime_timeout = client_compute_timeout(client, client->lease->lifetime, 1);
if (client->lease->t1 && client->lease->t2) {
if (client->lease->t1 > 0 && client->lease->t2 > 0) {
/* both T1 and T2 are given */
if (client->lease->t1 < client->lease->t2 &&
client->lease->t2 < client->lease->lifetime) {
@@ -1220,7 +1219,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
client->lease->t1 = client->lease->lifetime / 2;
}
} else if (client->lease->t2 && client->lease->t2 < client->lease->lifetime) {
} else if (client->lease->t2 > 0 && client->lease->t2 < client->lease->lifetime) {
/* only T2 is given, and it is valid */
t2_timeout = client_compute_timeout(client, client->lease->t2, 1);
t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
@@ -1230,7 +1229,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
client->lease->t2 = (client->lease->lifetime * 7) / 8;
}
} else if (client->lease->t1 && client->lease->t1 < client->lease->lifetime) {
} else if (client->lease->t1 > 0 && client->lease->t1 < client->lease->lifetime) {
/* only T1 is given, and it is valid */
t1_timeout = client_compute_timeout(client, client->lease->t1, 1);
t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
@@ -1676,30 +1675,41 @@ sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) {
}
sd_dhcp_client *sd_dhcp_client_ref(sd_dhcp_client *client) {
if (client)
assert_se(REFCNT_INC(client->n_ref) >= 2);
if (!client)
return NULL;
assert(client->n_ref >= 1);
client->n_ref++;
return client;
}
sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) {
if (client && REFCNT_DEC(client->n_ref) == 0) {
log_dhcp_client(client, "FREE");
client_initialize(client);
if (!client)
return NULL;
client->receive_message =
sd_event_source_unref(client->receive_message);
assert(client->n_ref >= 1);
client->n_ref--;
sd_dhcp_client_detach_event(client);
if (client->n_ref > 0)
return NULL;
sd_dhcp_lease_unref(client->lease);
log_dhcp_client(client, "FREE");
free(client->req_opts);
free(client->hostname);
free(client->vendor_class_identifier);
free(client);
}
client_initialize(client);
client->receive_message = sd_event_source_unref(client->receive_message);
sd_dhcp_client_detach_event(client);
sd_dhcp_lease_unref(client->lease);
free(client->req_opts);
free(client->hostname);
free(client->vendor_class_identifier);
free(client);
return NULL;
}
@@ -1713,7 +1723,7 @@ int sd_dhcp_client_new(sd_dhcp_client **ret) {
if (!client)
return -ENOMEM;
client->n_ref = REFCNT_INIT;
client->n_ref = 1;
client->state = DHCP_STATE_INIT;
client->index = -1;
client->fd = -1;
File diff suppressed because it is too large Load Diff
+162 -41
View File
@@ -28,7 +28,8 @@
#include "dhcp-server-internal.h"
#include "dhcp-internal.h"
#define DHCP_DEFAULT_LEASE_TIME 3600 /* one hour */
#define DHCP_DEFAULT_LEASE_TIME_USEC USEC_PER_HOUR
#define DHCP_MAX_LEASE_TIME_USEC (USEC_PER_HOUR*12)
int sd_dhcp_server_set_lease_pool(sd_dhcp_server *server,
struct in_addr *address,
@@ -73,8 +74,12 @@ bool sd_dhcp_server_is_running(sd_dhcp_server *server) {
}
sd_dhcp_server *sd_dhcp_server_ref(sd_dhcp_server *server) {
if (server)
assert_se(REFCNT_INC(server->n_ref) >= 2);
if (!server)
return NULL;
assert(server->n_ref >= 1);
server->n_ref++;
return server;
}
@@ -127,7 +132,10 @@ sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server) {
if (!server)
return NULL;
if (REFCNT_DEC(server->n_ref) > 0)
assert(server->n_ref >= 1);
server->n_ref--;
if (server->n_ref > 0)
return NULL;
log_dhcp_server(server, "UNREF");
@@ -136,6 +144,10 @@ sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server) {
sd_event_unref(server->event);
free(server->timezone);
free(server->dns);
free(server->ntp);
while ((lease = hashmap_steal_first(server->leases_by_client_id)))
dhcp_lease_free(lease);
hashmap_free(server->leases_by_client_id);
@@ -156,13 +168,15 @@ int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex) {
if (!server)
return -ENOMEM;
server->n_ref = REFCNT_INIT;
server->n_ref = 1;
server->fd_raw = -1;
server->fd = -1;
server->address = htobe32(INADDR_ANY);
server->netmask = htobe32(INADDR_ANY);
server->index = ifindex;
server->ifindex = ifindex;
server->leases_by_client_id = hashmap_new(&client_id_hash_ops);
server->default_lease_time = DIV_ROUND_UP(DHCP_DEFAULT_LEASE_TIME_USEC, USEC_PER_SEC);
server->max_lease_time = DIV_ROUND_UP(DHCP_MAX_LEASE_TIME_USEC, USEC_PER_SEC);
*ret = server;
server = NULL;
@@ -223,13 +237,12 @@ static int dhcp_server_send_unicast_raw(sd_dhcp_server *server,
union sockaddr_union link = {
.ll.sll_family = AF_PACKET,
.ll.sll_protocol = htons(ETH_P_IP),
.ll.sll_ifindex = server->index,
.ll.sll_ifindex = server->ifindex,
.ll.sll_halen = ETH_ALEN,
};
int r;
assert(server);
assert(server->index > 0);
assert(server->ifindex > 0);
assert(server->address);
assert(packet);
assert(len > sizeof(DHCPPacket));
@@ -240,11 +253,7 @@ static int dhcp_server_send_unicast_raw(sd_dhcp_server *server,
packet->dhcp.yiaddr,
DHCP_PORT_CLIENT, len);
r = dhcp_network_send_raw_socket(server->fd_raw, &link, packet, len);
if (r < 0)
return r;
return 0;
return dhcp_network_send_raw_socket(server->fd_raw, &link, packet, len);
}
static int dhcp_server_send_udp(sd_dhcp_server *server, be32_t destination,
@@ -290,7 +299,7 @@ static int dhcp_server_send_udp(sd_dhcp_server *server, be32_t destination,
pktinfo = (struct in_pktinfo*) CMSG_DATA(cmsg);
assert(pktinfo);
pktinfo->ipi_ifindex = server->index;
pktinfo->ipi_ifindex = server->ifindex;
pktinfo->ipi_spec_dst.s_addr = server->address;
r = sendmsg(server->fd, &msg, 0);
@@ -474,6 +483,33 @@ static int server_send_ack(sd_dhcp_server *server, DHCPRequest *req,
if (r < 0)
return r;
if (server->n_dns > 0) {
r = dhcp_option_append(
&packet->dhcp, req->max_optlen, &offset, 0,
DHCP_OPTION_DOMAIN_NAME_SERVER,
sizeof(struct in_addr) * server->n_dns, server->dns);
if (r < 0)
return r;
}
if (server->n_ntp > 0) {
r = dhcp_option_append(
&packet->dhcp, req->max_optlen, &offset, 0,
DHCP_OPTION_NTP_SERVER,
sizeof(struct in_addr) * server->n_ntp, server->ntp);
if (r < 0)
return r;
}
if (server->timezone) {
r = dhcp_option_append(
&packet->dhcp, req->max_optlen, &offset, 0,
DHCP_OPTION_NEW_TZDB_TIMEZONE,
strlen(server->timezone), server->timezone);
if (r < 0)
return r;
}
r = dhcp_server_send_packet(server, req, packet, DHCP_ACK, offset);
if (r < 0)
return r;
@@ -490,11 +526,7 @@ static int server_send_nak(sd_dhcp_server *server, DHCPRequest *req) {
if (r < 0)
return r;
r = dhcp_server_send_packet(server, req, packet, DHCP_NAK, offset);
if (r < 0)
return r;
return 0;
return dhcp_server_send_packet(server, req, packet, DHCP_NAK, offset);
}
static int server_send_forcerenew(sd_dhcp_server *server, be32_t address,
@@ -532,9 +564,8 @@ static int server_send_forcerenew(sd_dhcp_server *server, be32_t address,
return 0;
}
static int parse_request(uint8_t code, uint8_t len, const uint8_t *option,
void *user_data) {
DHCPRequest *req = user_data;
static int parse_request(uint8_t code, uint8_t len, const void *option, void *userdata) {
DHCPRequest *req = userdata;
assert(req);
@@ -590,7 +621,7 @@ static void dhcp_request_free(DHCPRequest *req) {
DEFINE_TRIVIAL_CLEANUP_FUNC(DHCPRequest*, dhcp_request_free);
#define _cleanup_dhcp_request_free_ _cleanup_(dhcp_request_freep)
static int ensure_sane_request(DHCPRequest *req, DHCPMessage *message) {
static int ensure_sane_request(sd_dhcp_server *server, DHCPRequest *req, DHCPMessage *message) {
assert(req);
assert(message);
@@ -599,23 +630,27 @@ static int ensure_sane_request(DHCPRequest *req, DHCPMessage *message) {
/* set client id based on MAC address if client did not send an explicit
one */
if (!req->client_id.data) {
uint8_t *data;
void *data;
data = new0(uint8_t, ETH_ALEN + 1);
data = malloc0(ETH_ALEN + 1);
if (!data)
return -ENOMEM;
((uint8_t*) data)[0] = 0x01;
memcpy((uint8_t*) data + 1, &message->chaddr, ETH_ALEN);
req->client_id.length = ETH_ALEN + 1;
req->client_id.data = data;
req->client_id.data[0] = 0x01;
memcpy(&req->client_id.data[1], &message->chaddr, ETH_ALEN);
}
if (req->max_optlen < DHCP_MIN_OPTIONS_SIZE)
req->max_optlen = DHCP_MIN_OPTIONS_SIZE;
if (!req->lifetime)
req->lifetime = DHCP_DEFAULT_LEASE_TIME;
if (req->lifetime <= 0)
req->lifetime = MAX(1ULL, server->default_lease_time);
if (server->max_lease_time > 0 && req->lifetime > server->max_lease_time)
req->lifetime = server->max_lease_time;
return 0;
}
@@ -656,7 +691,7 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
if (type < 0)
return 0;
r = ensure_sane_request(req, message);
r = ensure_sane_request(server, req, message);
if (r < 0)
/* this only fails on critical errors */
return r;
@@ -665,8 +700,8 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
&req->client_id);
switch(type) {
case DHCP_DISCOVER:
{
case DHCP_DISCOVER: {
be32_t address = INADDR_ANY;
unsigned i;
@@ -716,9 +751,7 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
return 1;
break;
case DHCP_REQUEST:
{
case DHCP_REQUEST: {
be32_t address;
bool init_reboot = false;
int pool_offset;
@@ -840,6 +873,7 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
break;
}
case DHCP_RELEASE: {
int pool_offset;
@@ -883,13 +917,12 @@ static int server_receive_message(sd_event_source *s, int fd,
.msg_controllen = sizeof(cmsgbuf),
};
struct cmsghdr *cmsg;
int buflen = 0, len, r;
int buflen = 0, len;
assert(server);
r = ioctl(fd, FIONREAD, &buflen);
if (r < 0)
return r;
if (ioctl(fd, FIONREAD, &buflen) < 0)
return -errno;
if (buflen < 0)
return -EIO;
@@ -914,7 +947,7 @@ static int server_receive_message(sd_event_source *s, int fd,
/* TODO figure out if this can be done as a filter on
* the socket, like for IPv6 */
if (server->index != info->ipi_ifindex)
if (server->ifindex != info->ipi_ifindex)
return 0;
break;
@@ -993,3 +1026,91 @@ int sd_dhcp_server_forcerenew(sd_dhcp_server *server) {
return r;
}
int sd_dhcp_server_set_timezone(sd_dhcp_server *server, const char *timezone) {
int r;
assert_return(server, -EINVAL);
assert_return(timezone_is_valid(timezone), -EINVAL);
if (streq_ptr(timezone, server->timezone))
return 0;
r = free_and_strdup(&server->timezone, timezone);
if (r < 0)
return r;
return 1;
}
int sd_dhcp_server_set_max_lease_time(sd_dhcp_server *server, uint32_t t) {
assert_return(server, -EINVAL);
if (t == server->max_lease_time)
return 0;
server->max_lease_time = t;
return 1;
}
int sd_dhcp_server_set_default_lease_time(sd_dhcp_server *server, uint32_t t) {
assert_return(server, -EINVAL);
if (t == server->default_lease_time)
return 0;
server->default_lease_time = t;
return 1;
}
int sd_dhcp_server_set_dns(sd_dhcp_server *server, const struct in_addr dns[], unsigned n) {
assert_return(server, -EINVAL);
assert_return(dns || n <= 0, -EINVAL);
if (server->n_dns == n &&
memcmp(server->dns, dns, sizeof(struct in_addr) * n) == 0)
return 0;
if (n <= 0) {
server->dns = mfree(server->dns);
server->n_dns = 0;
} else {
struct in_addr *c;
c = newdup(struct in_addr, dns, n);
if (!c)
return -ENOMEM;
free(server->dns);
server->dns = c;
server->n_dns = n;
}
return 1;
}
int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr ntp[], unsigned n) {
assert_return(server, -EINVAL);
assert_return(ntp || n <= 0, -EINVAL);
if (server->n_ntp == n &&
memcmp(server->ntp, ntp, sizeof(struct in_addr) * n) == 0)
return 0;
if (n <= 0) {
server->ntp = mfree(server->ntp);
server->n_ntp = 0;
} else {
struct in_addr *c;
c = newdup(struct in_addr, ntp, n);
if (!c)
return -ENOMEM;
free(server->ntp);
server->ntp = c;
server->n_ntp = n;
}
return 1;
}
+48 -52
View File
@@ -27,7 +27,6 @@
#include "udev.h"
#include "udev-util.h"
#include "util.h"
#include "refcnt.h"
#include "random-util.h"
#include "network-internal.h"
@@ -40,7 +39,7 @@
#define MAX_MAC_ADDR_LEN INFINIBAND_ALEN
struct sd_dhcp6_client {
RefCount n_ref;
unsigned n_ref;
enum DHCP6State state;
sd_event *event;
@@ -113,9 +112,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp6_client*, sd_dhcp6_client_unref);
static int client_start(sd_dhcp6_client *client, enum DHCP6State state);
int sd_dhcp6_client_set_callback(sd_dhcp6_client *client,
sd_dhcp6_client_cb_t cb, void *userdata)
{
int sd_dhcp6_client_set_callback(sd_dhcp6_client *client, sd_dhcp6_client_cb_t cb, void *userdata) {
assert_return(client, -EINVAL);
client->cb = cb;
@@ -124,8 +121,7 @@ int sd_dhcp6_client_set_callback(sd_dhcp6_client *client,
return 0;
}
int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index)
{
int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index) {
assert_return(client, -EINVAL);
assert_return(interface_index >= -1, -EINVAL);
@@ -134,9 +130,11 @@ int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index)
return 0;
}
int sd_dhcp6_client_set_mac(sd_dhcp6_client *client, const uint8_t *addr,
size_t addr_len, uint16_t arp_type)
{
int sd_dhcp6_client_set_mac(
sd_dhcp6_client *client,
const uint8_t *addr, size_t addr_len,
uint16_t arp_type) {
assert_return(client, -EINVAL);
assert_return(addr, -EINVAL);
assert_return(addr_len > 0 && addr_len <= MAX_MAC_ADDR_LEN, -EINVAL);
@@ -160,16 +158,17 @@ int sd_dhcp6_client_set_mac(sd_dhcp6_client *client, const uint8_t *addr,
return 0;
}
static int client_ensure_duid(sd_dhcp6_client *client)
{
static int client_ensure_duid(sd_dhcp6_client *client) {
if (client->duid_len != 0)
return 0;
return dhcp_identifier_set_duid_en(&client->duid, &client->duid_len);
}
int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t type, uint8_t *duid,
size_t duid_len)
{
int sd_dhcp6_client_set_duid(
sd_dhcp6_client *client,
uint16_t type,
uint8_t *duid, size_t duid_len) {
assert_return(client, -EINVAL);
assert_return(duid, -EINVAL);
assert_return(duid_len > 0 && duid_len <= MAX_DUID_LEN, -EINVAL);
@@ -203,8 +202,7 @@ int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t type, uint8_t *du
return 0;
}
int sd_dhcp6_client_set_information_request(sd_dhcp6_client *client,
bool enabled) {
int sd_dhcp6_client_set_information_request(sd_dhcp6_client *client, bool enabled) {
assert_return(client, -EINVAL);
client->information_request = enabled;
@@ -212,8 +210,7 @@ int sd_dhcp6_client_set_information_request(sd_dhcp6_client *client,
return 0;
}
int sd_dhcp6_client_get_information_request(sd_dhcp6_client *client,
bool *enabled) {
int sd_dhcp6_client_get_information_request(sd_dhcp6_client *client, bool *enabled) {
assert_return(client, -EINVAL);
assert_return(enabled, -EINVAL);
@@ -222,8 +219,7 @@ int sd_dhcp6_client_get_information_request(sd_dhcp6_client *client,
return 0;
}
int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client,
uint16_t option) {
int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client, uint16_t option) {
size_t t;
assert_return(client, -EINVAL);
@@ -805,9 +801,7 @@ static int client_parse_message(sd_dhcp6_client *client,
return r;
}
static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply,
size_t len)
{
static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply, size_t len) {
int r;
_cleanup_dhcp6_lease_free_ sd_dhcp6_lease *lease = NULL;
bool rapid_commit;
@@ -843,8 +837,7 @@ static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply,
return DHCP6_STATE_BOUND;
}
static int client_receive_advertise(sd_dhcp6_client *client,
DHCP6Message *advertise, size_t len) {
static int client_receive_advertise(sd_dhcp6_client *client, DHCP6Message *advertise, size_t len) {
int r;
_cleanup_dhcp6_lease_free_ sd_dhcp6_lease *lease = NULL;
uint8_t pref_advertise = 0, pref_lease = 0;
@@ -879,8 +872,7 @@ static int client_receive_advertise(sd_dhcp6_client *client,
return r;
}
static int client_receive_message(sd_event_source *s, int fd, uint32_t revents,
void *userdata) {
static int client_receive_message(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
sd_dhcp6_client *client = userdata;
DHCP6_CLIENT_DONT_DESTROY(client);
_cleanup_free_ DHCP6Message *message;
@@ -991,8 +983,7 @@ static int client_receive_message(sd_event_source *s, int fd, uint32_t revents,
return 0;
}
static int client_start(sd_dhcp6_client *client, enum DHCP6State state)
{
static int client_start(sd_dhcp6_client *client, enum DHCP6State state) {
int r;
usec_t timeout, time_now;
char time_string[FORMAT_TIMESPAN_MAX];
@@ -1121,15 +1112,13 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state)
return 0;
}
int sd_dhcp6_client_stop(sd_dhcp6_client *client)
{
int sd_dhcp6_client_stop(sd_dhcp6_client *client) {
client_stop(client, DHCP6_EVENT_STOP);
return 0;
}
int sd_dhcp6_client_start(sd_dhcp6_client *client)
{
int sd_dhcp6_client_start(sd_dhcp6_client *client) {
int r = 0;
enum DHCP6State state = DHCP6_STATE_SOLICITATION;
@@ -1185,9 +1174,7 @@ error:
return r;
}
int sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event,
int priority)
{
int sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event, int priority) {
int r;
assert_return(client, -EINVAL);
@@ -1222,30 +1209,39 @@ sd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client) {
}
sd_dhcp6_client *sd_dhcp6_client_ref(sd_dhcp6_client *client) {
if (client)
assert_se(REFCNT_INC(client->n_ref) >= 2);
if (!client)
return NULL;
assert(client->n_ref >= 1);
client->n_ref++;
return client;
}
sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client) {
if (client && REFCNT_DEC(client->n_ref) == 0) {
client_reset(client);
sd_dhcp6_client_detach_event(client);
sd_dhcp6_lease_unref(client->lease);
free(client->req_opts);
free(client);
if (!client)
return NULL;
}
return client;
assert(client->n_ref >= 1);
client->n_ref--;
if (client->n_ref > 0)
return NULL;
client_reset(client);
sd_dhcp6_client_detach_event(client);
sd_dhcp6_lease_unref(client->lease);
free(client->req_opts);
free(client);
return NULL;
}
int sd_dhcp6_client_new(sd_dhcp6_client **ret)
{
int sd_dhcp6_client_new(sd_dhcp6_client **ret) {
_cleanup_dhcp6_client_unref_ sd_dhcp6_client *client = NULL;
size_t t;
@@ -1255,7 +1251,7 @@ int sd_dhcp6_client_new(sd_dhcp6_client **ret)
if (!client)
return -ENOMEM;
client->n_ref = REFCNT_INIT;
client->n_ref = 1;
client->ia_na.type = DHCP6_OPTION_IA_NA;
+25 -14
View File
@@ -247,8 +247,7 @@ int sd_dhcp6_lease_get_domains(sd_dhcp6_lease *lease, char ***domains) {
return -ENOENT;
}
int dhcp6_lease_set_ntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen)
{
int dhcp6_lease_set_ntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) {
int r;
uint16_t subopt;
size_t sublen;
@@ -361,26 +360,38 @@ int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ntp_fqdn) {
}
sd_dhcp6_lease *sd_dhcp6_lease_ref(sd_dhcp6_lease *lease) {
if (lease)
assert_se(REFCNT_INC(lease->n_ref) >= 2);
if (!lease)
return NULL;
assert(lease->n_ref >= 1);
lease->n_ref++;
return lease;
}
sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease) {
if (lease && REFCNT_DEC(lease->n_ref) == 0) {
free(lease->serverid);
dhcp6_lease_free_ia(&lease->ia);
free(lease->dns);
if (!lease)
return NULL;
lease->domains = strv_free(lease->domains);
assert(lease->n_ref >= 1);
lease->n_ref--;
free(lease->ntp);
if (lease->n_ref > 0)
return NULL;
lease->ntp_fqdn = strv_free(lease->ntp_fqdn);
free(lease);
}
free(lease->serverid);
dhcp6_lease_free_ia(&lease->ia);
free(lease->dns);
lease->domains = strv_free(lease->domains);
free(lease->ntp);
lease->ntp_fqdn = strv_free(lease->ntp_fqdn);
free(lease);
return NULL;
}
@@ -392,7 +403,7 @@ int dhcp6_lease_new(sd_dhcp6_lease **ret) {
if (!lease)
return -ENOMEM;
lease->n_ref = REFCNT_INIT;
lease->n_ref = 1;
LIST_HEAD_INIT(lease->ia.addresses);
+39 -32
View File
@@ -25,7 +25,6 @@
#include <sys/ioctl.h>
#include "socket-util.h"
#include "refcnt.h"
#include "async.h"
#include "dhcp6-internal.h"
@@ -47,7 +46,7 @@ enum icmp6_nd_state {
typedef struct ICMP6Prefix ICMP6Prefix;
struct ICMP6Prefix {
RefCount n_ref;
unsigned n_ref;
LIST_FIELDS(ICMP6Prefix, prefixes);
@@ -57,7 +56,7 @@ struct ICMP6Prefix {
};
struct sd_icmp6_nd {
RefCount n_ref;
unsigned n_ref;
enum icmp6_nd_state state;
sd_event *event;
@@ -78,13 +77,18 @@ struct sd_icmp6_nd {
#define log_icmp6_nd(p, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "ICMPv6 CLIENT: " fmt, ##__VA_ARGS__)
static ICMP6Prefix *icmp6_prefix_unref(ICMP6Prefix *prefix) {
if (prefix && REFCNT_DEC(prefix->n_ref) <= 0) {
prefix->timeout_valid =
sd_event_source_unref(prefix->timeout_valid);
free(prefix);
}
if (!prefix)
return NULL;
assert(prefix->n_ref > 0);
prefix->n_ref--;
if (prefix->n_ref > 0)
return NULL;
prefix->timeout_valid = sd_event_source_unref(prefix->timeout_valid);
free(prefix);
return NULL;
}
@@ -97,7 +101,7 @@ static int icmp6_prefix_new(ICMP6Prefix **ret) {
if (!prefix)
return -ENOMEM;
prefix->n_ref = REFCNT_INIT;
prefix->n_ref = 1;
LIST_INIT(prefixes, prefix);
*ret = prefix;
@@ -106,8 +110,7 @@ static int icmp6_prefix_new(ICMP6Prefix **ret) {
return 0;
}
static void icmp6_nd_notify(sd_icmp6_nd *nd, int event)
{
static void icmp6_nd_notify(sd_icmp6_nd *nd, int event) {
if (nd->callback)
nd->callback(nd, event, nd->userdata);
}
@@ -177,9 +180,12 @@ sd_event *sd_icmp6_nd_get_event(sd_icmp6_nd *nd) {
}
sd_icmp6_nd *sd_icmp6_nd_ref(sd_icmp6_nd *nd) {
assert (nd);
assert_se(REFCNT_INC(nd->n_ref) >= 2);
if (!nd)
return NULL;
assert(nd->n_ref > 0);
nd->n_ref++;
return nd;
}
@@ -195,21 +201,28 @@ static int icmp6_nd_init(sd_icmp6_nd *nd) {
}
sd_icmp6_nd *sd_icmp6_nd_unref(sd_icmp6_nd *nd) {
if (nd && REFCNT_DEC(nd->n_ref) == 0) {
ICMP6Prefix *prefix, *p;
ICMP6Prefix *prefix, *p;
icmp6_nd_init(nd);
sd_icmp6_nd_detach_event(nd);
if (!nd)
return NULL;
LIST_FOREACH_SAFE(prefixes, prefix, p, nd->prefixes) {
LIST_REMOVE(prefixes, nd->prefixes, prefix);
assert(nd->n_ref > 0);
nd->n_ref--;
prefix = icmp6_prefix_unref(prefix);
}
if (nd->n_ref > 0)
return NULL;
free(nd);
icmp6_nd_init(nd);
sd_icmp6_nd_detach_event(nd);
LIST_FOREACH_SAFE(prefixes, prefix, p, nd->prefixes) {
LIST_REMOVE(prefixes, nd->prefixes, prefix);
prefix = icmp6_prefix_unref(prefix);
}
free(nd);
return NULL;
}
@@ -225,7 +238,7 @@ int sd_icmp6_nd_new(sd_icmp6_nd **ret) {
if (!nd)
return -ENOMEM;
nd->n_ref = REFCNT_INIT;
nd->n_ref = 1;
nd->index = -1;
nd->fd = -1;
@@ -376,9 +389,7 @@ int sd_icmp6_ra_get_prefixlen(sd_icmp6_nd *nd, const struct in6_addr *addr,
return 0;
}
int sd_icmp6_ra_get_expired_prefix(sd_icmp6_nd *nd, struct in6_addr **addr,
uint8_t *prefixlen)
{
int sd_icmp6_ra_get_expired_prefix(sd_icmp6_nd *nd, struct in6_addr **addr, uint8_t *prefixlen) {
assert_return(nd, -EINVAL);
assert_return(addr, -EINVAL);
assert_return(prefixlen, -EINVAL);
@@ -525,9 +536,7 @@ static int icmp6_ra_parse(sd_icmp6_nd *nd, struct nd_router_advert *ra,
return 0;
}
static int icmp6_router_advertisment_recv(sd_event_source *s, int fd,
uint32_t revents, void *userdata)
{
static int icmp6_router_advertisment_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
sd_icmp6_nd *nd = userdata;
int r, buflen = 0;
ssize_t len;
@@ -586,9 +595,7 @@ static int icmp6_router_advertisment_recv(sd_event_source *s, int fd,
return 0;
}
static int icmp6_router_solicitation_timeout(sd_event_source *s, uint64_t usec,
void *userdata)
{
static int icmp6_router_solicitation_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
sd_icmp6_nd *nd = userdata;
uint64_t time_now, next_timeout;
struct ether_addr unset = { };
+27 -19
View File
@@ -26,7 +26,6 @@
#include "util.h"
#include "siphash24.h"
#include "list.h"
#include "refcnt.h"
#include "random-util.h"
#include "ipv4ll-internal.h"
@@ -68,7 +67,7 @@ typedef enum IPv4LLState {
} IPv4LLState;
struct sd_ipv4ll {
RefCount n_ref;
unsigned n_ref;
IPv4LLState state;
int index;
@@ -598,30 +597,39 @@ int sd_ipv4ll_stop(sd_ipv4ll *ll) {
}
sd_ipv4ll *sd_ipv4ll_ref(sd_ipv4ll *ll) {
if (ll)
assert_se(REFCNT_INC(ll->n_ref) >= 2);
if (!ll)
return NULL;
assert(ll->n_ref >= 1);
ll->n_ref++;
return ll;
}
sd_ipv4ll *sd_ipv4ll_unref(sd_ipv4ll *ll) {
if (ll && REFCNT_DEC(ll->n_ref) == 0) {
ll->receive_message =
sd_event_source_unref(ll->receive_message);
ll->fd = safe_close(ll->fd);
ll->timer = sd_event_source_unref(ll->timer);
sd_ipv4ll_detach_event(ll);
free(ll->random_data);
free(ll->random_data_state);
free(ll);
if (!ll)
return NULL;
}
return ll;
assert(ll->n_ref >= 1);
ll->n_ref--;
if (ll->n_ref > 0)
return ll;
ll->receive_message = sd_event_source_unref(ll->receive_message);
ll->fd = safe_close(ll->fd);
ll->timer = sd_event_source_unref(ll->timer);
sd_ipv4ll_detach_event(ll);
free(ll->random_data);
free(ll->random_data_state);
free(ll);
return NULL;
}
DEFINE_TRIVIAL_CLEANUP_FUNC(sd_ipv4ll*, sd_ipv4ll_unref);
@@ -636,7 +644,7 @@ int sd_ipv4ll_new(sd_ipv4ll **ret) {
if (!ll)
return -ENOMEM;
ll->n_ref = REFCNT_INIT;
ll->n_ref = 1;
ll->state = IPV4LL_STATE_INIT;
ll->index = -1;
ll->fd = -1;
+23 -13
View File
@@ -36,7 +36,6 @@
#include "random-util.h"
#include "socket-util.h"
#include "async.h"
#include "refcnt.h"
#include "utf8.h"
#define PPPOE_MAX_PACKET_SIZE 1484
@@ -68,7 +67,7 @@ typedef struct PPPoETags {
} PPPoETags;
struct sd_pppoe {
RefCount n_ref;
unsigned n_ref;
PPPoEState state;
uint64_t host_uniq;
@@ -202,23 +201,34 @@ int sd_pppoe_detach_event(sd_pppoe *ppp) {
}
sd_pppoe *sd_pppoe_ref(sd_pppoe *ppp) {
if (ppp)
assert_se(REFCNT_INC(ppp->n_ref) >= 2);
if (!ppp)
return NULL;
assert(ppp->n_ref > 0);
ppp->n_ref++;
return ppp;
}
sd_pppoe *sd_pppoe_unref(sd_pppoe *ppp) {
if (ppp && REFCNT_DEC(ppp->n_ref) <= 0) {
pppoe_tags_clear(&ppp->tags);
free(ppp->ifname);
free(ppp->service_name);
sd_pppoe_stop(ppp);
sd_pppoe_detach_event(ppp);
free(ppp);
}
if (!ppp)
return NULL;
assert(ppp->n_ref > 0);
ppp->n_ref--;
if (ppp->n_ref > 0)
return NULL;
pppoe_tags_clear(&ppp->tags);
free(ppp->ifname);
free(ppp->service_name);
sd_pppoe_stop(ppp);
sd_pppoe_detach_event(ppp);
free(ppp);
return NULL;
}
@@ -231,7 +241,7 @@ int sd_pppoe_new (sd_pppoe **ret) {
if (!ppp)
return -ENOMEM;
ppp->n_ref = REFCNT_INIT;
ppp->n_ref = 1;
ppp->state = _PPPOE_STATE_INVALID;
ppp->ifindex = -1;
ppp->fd = -1;
+20 -33
View File
@@ -43,16 +43,13 @@ static test_callback_recv_t callback_recv;
static be32_t xid;
static sd_event_source *test_hangcheck;
static int test_dhcp_hangcheck(sd_event_source *s, uint64_t usec,
void *userdata)
{
static int test_dhcp_hangcheck(sd_event_source *s, uint64_t usec, void *userdata) {
assert_not_reached("Test case should have completed in 2 seconds");
return 0;
}
static void test_request_basic(sd_event *e)
{
static void test_request_basic(sd_event *e) {
int r;
sd_dhcp_client *client;
@@ -87,10 +84,7 @@ static void test_request_basic(sd_event *e)
assert_se(sd_dhcp_client_set_request_option(client,
DHCP_OPTION_DOMAIN_NAME) == -EEXIST);
assert_se(sd_dhcp_client_set_request_option(client,
DHCP_OPTION_DOMAIN_NAME_SERVER)
== -EEXIST);
assert_se(sd_dhcp_client_set_request_option(client,
DHCP_OPTION_NTP_SERVER) == -EEXIST);
DHCP_OPTION_DOMAIN_NAME_SERVER) == -EEXIST);
assert_se(sd_dhcp_client_set_request_option(client,
DHCP_OPTION_PAD) == -EINVAL);
@@ -112,8 +106,7 @@ static void test_request_basic(sd_event *e)
sd_dhcp_client_unref(client);
}
static void test_checksum(void)
{
static void test_checksum(void) {
uint8_t buf[20] = {
0x45, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -126,9 +119,7 @@ static void test_checksum(void)
assert_se(dhcp_packet_checksum((uint8_t*)&buf, 20) == be16toh(0x78ae));
}
static int check_options(uint8_t code, uint8_t len, const uint8_t *option,
void *user_data)
{
static int check_options(uint8_t code, uint8_t len, const void *option, void *userdata) {
switch(code) {
case DHCP_OPTION_CLIENT_IDENTIFIER:
{
@@ -141,10 +132,10 @@ static int check_options(uint8_t code, uint8_t len, const uint8_t *option,
assert_se(len == sizeof(uint8_t) + sizeof(uint32_t) + duid_len);
assert_se(len == 19);
assert_se(option[0] == 0xff);
assert_se(((uint8_t*) option)[0] == 0xff);
assert_se(memcmp(&option[1], &iaid, sizeof(iaid)) == 0);
assert_se(memcmp(&option[5], &duid, duid_len) == 0);
assert_se(memcmp((uint8_t*) option + 1, &iaid, sizeof(iaid)) == 0);
assert_se(memcmp((uint8_t*) option + 5, &duid, duid_len) == 0);
break;
}
@@ -155,9 +146,7 @@ static int check_options(uint8_t code, uint8_t len, const uint8_t *option,
return 0;
}
int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
const void *packet, size_t len)
{
int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link, const void *packet, size_t len) {
size_t size;
_cleanup_free_ DHCPPacket *discover;
uint16_t ip_check, udp_check;
@@ -202,18 +191,20 @@ int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
return 575;
}
int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link,
uint32_t id, const uint8_t *addr,
size_t addr_len, uint16_t arp_type)
{
int dhcp_network_bind_raw_socket(
int index,
union sockaddr_union *link,
uint32_t id,
const uint8_t *addr, size_t addr_len,
uint16_t arp_type) {
if (socketpair(AF_UNIX, SOCK_STREAM, 0, test_fd) < 0)
return -errno;
return test_fd[0];
}
int dhcp_network_bind_udp_socket(be32_t address, uint16_t port)
{
int dhcp_network_bind_udp_socket(be32_t address, uint16_t port) {
int fd;
fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0);
@@ -223,14 +214,11 @@ int dhcp_network_bind_udp_socket(be32_t address, uint16_t port)
return fd;
}
int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port,
const void *packet, size_t len)
{
int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port, const void *packet, size_t len) {
return 0;
}
static int test_discover_message_verify(size_t size, struct DHCPMessage *dhcp)
{
static int test_discover_message_verify(size_t size, struct DHCPMessage *dhcp) {
int res;
res = dhcp_option_parse(dhcp, size, check_options, NULL);
@@ -242,8 +230,7 @@ static int test_discover_message_verify(size_t size, struct DHCPMessage *dhcp)
return 0;
}
static void test_discover_message(sd_event *e)
{
static void test_discover_message(sd_event *e) {
sd_dhcp_client *client;
int res, r;
+4 -4
View File
@@ -145,8 +145,8 @@ static void test_ignore_opts(uint8_t *descoption, int *descpos, int *desclen) {
}
}
static int test_options_cb(uint8_t code, uint8_t len, const uint8_t *option, void *user_data) {
struct option_desc *desc = user_data;
static int test_options_cb(uint8_t code, uint8_t len, const void *option, void *userdata) {
struct option_desc *desc = userdata;
uint8_t *descoption = NULL;
int *desclen = NULL, *descpos = NULL;
uint8_t optcode = 0;
@@ -207,10 +207,10 @@ static int test_options_cb(uint8_t code, uint8_t len, const uint8_t *option, voi
for (i = 0; i < len; i++) {
if (verbose)
printf("0x%02x(0x%02x) ", option[i],
printf("0x%02x(0x%02x) ", ((uint8_t*) option)[i],
descoption[*descpos + 2 + i]);
assert_se(option[i] == descoption[*descpos + 2 + i]);
assert_se(((uint8_t*) option)[i] == descoption[*descpos + 2 + i]);
}
if (verbose)
+1 -2
View File
@@ -501,8 +501,7 @@ static int test_client_verify_request(DHCP6Message *request, uint8_t *option,
return 0;
}
static int test_client_send_advertise(DHCP6Message *solicit)
{
static int test_client_send_advertise(DHCP6Message *solicit) {
DHCP6Message advertise;
advertise.transaction_id = solicit->transaction_id;
+3 -3
View File
@@ -39,9 +39,9 @@ static int test_fd[2];
static int basic_request_handler_bind = 0;
static int basic_request_handler_stop = 0;
static void* basic_request_handler_user_data = (void*)0xCABCAB;
static void* basic_request_handler_userdata = (void*)0xCABCAB;
static void basic_request_handler(sd_ipv4ll *ll, int event, void *userdata) {
assert_se(userdata == basic_request_handler_user_data);
assert_se(userdata == basic_request_handler_userdata);
switch(event) {
case IPV4LL_EVENT_STOP:
@@ -175,7 +175,7 @@ static void test_basic_request(sd_event *e) {
assert_se(sd_ipv4ll_start(ll) == -EINVAL);
assert_se(sd_ipv4ll_set_callback(ll, basic_request_handler,
basic_request_handler_user_data) == 0);
basic_request_handler_userdata) == 0);
assert_se(sd_ipv4ll_start(ll) == -EINVAL);
assert_se(sd_ipv4ll_set_index(ll, 1) == 0);
+3 -1
View File
@@ -1024,7 +1024,9 @@ _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
_public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
assert_return(m, NULL);
assert_return(sd_bus_error_is_set(&m->error), NULL);
if (!sd_bus_error_is_set(&m->error))
return NULL;
return &m->error;
}
+6 -7
View File
@@ -79,8 +79,7 @@ static bool linebuf_add(struct linebuf *buf, const char *s, size_t len) {
return true;
}
static bool linebuf_add_char(struct linebuf *buf, char c)
{
static bool linebuf_add_char(struct linebuf *buf, char c) {
if (buf->len + 1 >= sizeof(buf->bytes))
return false;
buf->bytes[buf->len++] = c;
@@ -269,13 +268,13 @@ static int trie_search_f(sd_hwdb *hwdb, const char *search) {
}
static const char hwdb_bin_paths[] =
"/etc/systemd/hwdb/hwdb.bin\0"
"/etc/udev/hwdb.bin\0"
"/usr/lib/systemd/hwdb/hwdb.bin\0"
"/etc/systemd/hwdb/hwdb.bin\0"
"/etc/udev/hwdb.bin\0"
"/usr/lib/systemd/hwdb/hwdb.bin\0"
#ifdef HAVE_SPLIT_USR
"/lib/systemd/hwdb/hwdb.bin\0"
"/lib/systemd/hwdb/hwdb.bin\0"
#endif
UDEVLIBEXECDIR "/hwdb.bin\0";
UDEVLIBEXECDIR "/hwdb.bin\0";
_public_ int sd_hwdb_new(sd_hwdb **ret) {
_cleanup_hwdb_unref_ sd_hwdb *hwdb = NULL;
+22
View File
@@ -214,6 +214,28 @@ _public_ int sd_network_link_get_lldp(int ifindex, char **lldp) {
return 0;
}
int sd_network_link_get_timezone(int ifindex, char **ret) {
_cleanup_free_ char *s = NULL, *p = NULL;
int r;
assert_return(ifindex > 0, -EINVAL);
assert_return(ret, -EINVAL);
if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
return -ENOMEM;
r = parse_env_file(p, NEWLINE, "TIMEZONE", &s, NULL);
if (r == -ENOENT)
return -ENODATA;
if (r < 0)
return r;
if (isempty(s))
return -ENODATA;
*ret = s;
s = NULL;
return 0;
}
static int network_get_link_strv(const char *key, int ifindex, char ***ret) {
_cleanup_free_ char *p = NULL, *s = NULL;
+7 -2
View File
@@ -497,7 +497,7 @@ static int link_status_one(
sd_hwdb *hwdb,
const char *name) {
_cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **domains = NULL;
_cleanup_free_ char *setup_state = NULL, *operational_state = NULL;
_cleanup_free_ char *setup_state = NULL, *operational_state = NULL, *timezone = NULL;
_cleanup_netlink_message_unref_ sd_netlink_message *req = NULL, *reply = NULL;
_cleanup_device_unref_ sd_device *d = NULL;
char devid[2 + DECIMAL_STR_MAX(int)];
@@ -570,7 +570,6 @@ static int link_status_one(
setup_state_to_color(setup_state, &on_color_setup, &off_color_setup);
sd_network_link_get_dns(ifindex, &dns);
sd_network_link_get_ntp(ifindex, &ntp);
sd_network_link_get_domains(ifindex, &domains);
r = sd_network_link_get_wildcard_domain(ifindex);
if (r > 0) {
@@ -652,6 +651,8 @@ static int link_status_one(
dump_list(" DNS: ", dns);
if (!strv_isempty(domains))
dump_list(" Domain: ", domains);
(void) sd_network_link_get_ntp(ifindex, &ntp);
if (!strv_isempty(ntp))
dump_list(" NTP: ", ntp);
@@ -661,6 +662,10 @@ static int link_status_one(
if (!strv_isempty(carrier_bound_by))
dump_list("Carrier Bound By: ", carrier_bound_by);
(void) sd_network_link_get_timezone(ifindex, &timezone);
if (timezone)
printf(" Time Zone: %s", timezone);
return 0;
}
+1 -2
View File
@@ -19,9 +19,8 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include "networkd.h"
#include "networkd-link.h"
#include "networkd-address-pool.h"
int address_pool_new(
Manager *m,
+43
View File
@@ -0,0 +1,43 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***
This file is part of systemd.
Copyright 2014 Lennart Poettering
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/>.
***/
typedef struct AddressPool AddressPool;
#include "networkd.h"
struct AddressPool {
Manager *manager;
int family;
unsigned prefixlen;
union in_addr_union in_addr;
LIST_FIELDS(AddressPool, address_pools);
};
int address_pool_new(Manager *m, AddressPool **ret, int family, const union in_addr_union *u, unsigned prefixlen);
int address_pool_new_from_string(Manager *m, AddressPool **ret, int family, const char *p, unsigned prefixlen);
void address_pool_free(AddressPool *p);
int address_pool_acquire(AddressPool *p, unsigned prefixlen, union in_addr_union *found);
+3 -1
View File
@@ -25,8 +25,10 @@
#include "util.h"
#include "conf-parser.h"
#include "firewall-util.h"
#include "netlink-util.h"
#include "networkd.h"
#include "networkd-link.h"
#include "networkd-address.h"
static void address_init(Address *address) {
assert(address);
+73
View File
@@ -0,0 +1,73 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***
This file is part of systemd.
Copyright 2013 Tom Gundersen <teg@jklm.no>
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/>.
***/
#include <inttypes.h>
#include <stdbool.h>
#include "in-addr-util.h"
typedef struct Address Address;
#include "networkd.h"
#include "networkd-network.h"
#include "networkd-link.h"
#define CACHE_INFO_INFINITY_LIFE_TIME 0xFFFFFFFFU
struct Address {
Network *network;
unsigned section;
int family;
unsigned char prefixlen;
unsigned char scope;
uint32_t flags;
char *label;
struct in_addr broadcast;
struct ifa_cacheinfo cinfo;
union in_addr_union in_addr;
union in_addr_union in_addr_peer;
bool ip_masquerade_done;
LIST_FIELDS(Address, addresses);
};
int address_new_static(Network *network, unsigned section, Address **ret);
int address_new_dynamic(Address **ret);
void address_free(Address *address);
int address_configure(Address *address, Link *link, sd_netlink_message_handler_t callback);
int address_update(Address *address, Link *link, sd_netlink_message_handler_t callback);
int address_drop(Address *address, Link *link, sd_netlink_message_handler_t callback);
int address_establish(Address *address, Link *link);
int address_release(Address *address, Link *link);
bool address_equal(Address *a1, Address *a2);
DEFINE_TRIVIAL_CLEANUP_FUNC(Address*, address_free);
#define _cleanup_address_free_ _cleanup_(address_freep)
int config_parse_address(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);
int config_parse_broadcast(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);
int config_parse_label(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);
+73 -109
View File
@@ -39,8 +39,7 @@ static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m,
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
log_link_error(link, "could not set DHCPv4 route: %s",
strerror(-r));
log_link_error_errno(link, r, "Could not set DHCPv4 route: %m");
link_enter_failed(link);
}
@@ -61,40 +60,25 @@ static int link_set_dhcp_routes(Link *link) {
assert(link->dhcp_lease);
r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
if (r < 0 && r != -ENOENT) {
log_link_warning(link,
"DHCP error: could not get gateway: %s",
strerror(-r));
return r;
}
if (r < 0 && r != -ENOENT)
return log_link_warning_errno(link, r, "DHCP error: could not get gateway: %m");
if (r >= 0) {
struct in_addr address;
_cleanup_route_free_ Route *route = NULL;
_cleanup_route_free_ Route *route_gw = NULL;
r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
if (r < 0) {
log_link_warning(link,
"DHCP error: could not get address: %s",
strerror(-r));
return r;
}
if (r < 0)
return log_link_warning_errno(link, r, "DHCP error: could not get address: %m");
r = route_new_dynamic(&route, RTPROT_DHCP);
if (r < 0) {
log_link_error(link,
"Could not allocate route: %s",
strerror(-r));
return r;
}
if (r < 0)
return log_link_error_errno(link, r, "Could not allocate route: %m");
r = route_new_dynamic(&route_gw, RTPROT_DHCP);
if (r < 0) {
log_link_error(link,
"Could not allocate route: %s",
strerror(-r));
return r;
}
if (r < 0)
return log_link_error_errno(link, r, "Could not allocate route: %m");
/* The dhcp netmask may mask out the gateway. Add an explicit
* route for the gw host so that we can route no matter the
@@ -107,12 +91,8 @@ static int link_set_dhcp_routes(Link *link) {
route_gw->metrics = link->network->dhcp_route_metric;
r = route_configure(route_gw, link, &dhcp4_route_handler);
if (r < 0) {
log_link_warning(link,
"could not set host route: %s",
strerror(-r));
return r;
}
if (r < 0)
return log_link_warning_errno(link, r, "Could not set host route: %m");
link->dhcp4_messages ++;
@@ -123,9 +103,7 @@ static int link_set_dhcp_routes(Link *link) {
r = route_configure(route, link, &dhcp4_route_handler);
if (r < 0) {
log_link_warning(link,
"could not set routes: %s",
strerror(-r));
log_link_warning_errno(link, r, "Could not set routes: %m");
link_enter_failed(link);
return r;
}
@@ -136,23 +114,15 @@ static int link_set_dhcp_routes(Link *link) {
n = sd_dhcp_lease_get_routes(link->dhcp_lease, &static_routes);
if (n == -ENOENT)
return 0;
if (n < 0) {
log_link_warning(link,
"DHCP error: could not get routes: %s",
strerror(-n));
return n;
}
if (n < 0)
return log_link_warning_errno(link, n, "DHCP error: could not get routes: %m");
for (i = 0; i < n; i++) {
_cleanup_route_free_ Route *route = NULL;
r = route_new_dynamic(&route, RTPROT_DHCP);
if (r < 0) {
log_link_error(link, "Could not allocate route: %s",
strerror(-r));
return r;
}
if (r < 0)
return log_link_error_errno(link, r, "Could not allocate route: %m");
route->family = AF_INET;
route->in_addr.in = static_routes[i].gw_addr;
@@ -161,12 +131,8 @@ static int link_set_dhcp_routes(Link *link) {
route->metrics = link->network->dhcp_route_metric;
r = route_configure(route, link, &dhcp4_route_handler);
if (r < 0) {
log_link_warning(link,
"could not set host route: %s",
strerror(-r));
return r;
}
if (r < 0)
return log_link_warning_errno(link, r, "Could not set host route: %m");
link->dhcp4_messages ++;
}
@@ -270,18 +236,16 @@ static int dhcp_lease_lost(Link *link) {
if (link->network->dhcp_hostname) {
const char *hostname = NULL;
if (!link->network->hostname)
r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
else
if (link->network->hostname)
hostname = link->network->hostname;
else
(void) sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
if (r >= 0 || hostname) {
r = link_set_hostname(link, hostname);
if (hostname) {
/* If a hostname was set due to the lease, then unset it now. */
r = link_set_hostname(link, NULL);
if (r < 0)
log_link_error_errno(link, r,
"Failed to set transient hostname to '%s': %m",
hostname);
log_link_warning_errno(link, r, "Failed to reset transient hostname: %m");
}
}
@@ -300,8 +264,7 @@ static int dhcp4_address_handler(sd_netlink *rtnl, sd_netlink_message *m,
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
log_link_error(link, "could not set DHCPv4 address: %s",
strerror(-r));
log_link_error_errno(link, r, "Could not set DHCPv4 address: %m");
link_enter_failed(link);
} else if (r >= 0)
link_rtnl_process_address(rtnl, m, link->manager);
@@ -357,45 +320,30 @@ static int dhcp_lease_renew(sd_dhcp_client *client, Link *link) {
assert(link->network);
r = sd_dhcp_client_get_lease(client, &lease);
if (r < 0) {
log_link_warning(link, "DHCP error: no lease %s",
strerror(-r));
return r;
}
if (r < 0)
return log_link_warning_errno(link, r, "DHCP error: no lease: %m");
sd_dhcp_lease_unref(link->dhcp_lease);
link->dhcp4_configured = false;
link->dhcp_lease = sd_dhcp_lease_ref(lease);
r = sd_dhcp_lease_get_address(lease, &address);
if (r < 0) {
log_link_warning(link, "DHCP error: no address: %s",
strerror(-r));
return r;
}
if (r < 0)
return log_link_warning_errno(link, r, "DHCP error: no address: %m");
r = sd_dhcp_lease_get_netmask(lease, &netmask);
if (r < 0) {
log_link_warning(link, "DHCP error: no netmask: %s",
strerror(-r));
return r;
}
if (r < 0)
return log_link_warning_errno(link, r, "DHCP error: no netmask: %m");
if (!link->network->dhcp_critical) {
r = sd_dhcp_lease_get_lifetime(link->dhcp_lease,
&lifetime);
if (r < 0) {
log_link_warning(link,
"DHCP error: no lifetime: %s",
strerror(-r));
return r;
}
r = sd_dhcp_lease_get_lifetime(link->dhcp_lease, &lifetime);
if (r < 0)
return log_link_warning_errno(link, r, "DHCP error: no lifetime: %m");
}
r = dhcp4_update_address(link, &address, &netmask, lifetime);
if (r < 0) {
log_link_warning(link, "could not update IP address: %s",
strerror(-r));
log_link_warning_errno(link, r, "Could not update IP address: %m");
link_enter_failed(link);
return r;
}
@@ -417,21 +365,21 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
r = sd_dhcp_client_get_lease(client, &lease);
if (r < 0)
return log_link_error_errno(link, r, "DHCP error: no lease: %m");
return log_link_error_errno(link, r, "DHCP error: No lease: %m");
r = sd_dhcp_lease_get_address(lease, &address);
if (r < 0)
return log_link_error_errno(link, r, "DHCP error: no address: %m");
return log_link_error_errno(link, r, "DHCP error: No address: %m");
r = sd_dhcp_lease_get_netmask(lease, &netmask);
if (r < 0)
return log_link_error_errno(link, r, "DHCP error: no netmask: %m");
return log_link_error_errno(link, r, "DHCP error: No netmask: %m");
prefixlen = in_addr_netmask_to_prefixlen(&netmask);
r = sd_dhcp_lease_get_router(lease, &gateway);
if (r < 0 && r != -ENOENT)
return log_link_error_errno(link, r, "DHCP error: could not get gateway: %m");
return log_link_error_errno(link, r, "DHCP error: Could not get gateway: %m");
if (r >= 0)
log_struct(LOG_INFO,
@@ -470,18 +418,30 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
if (link->network->dhcp_hostname) {
const char *hostname = NULL;
if (!link->network->hostname)
r = sd_dhcp_lease_get_hostname(lease, &hostname);
else
if (link->network->hostname)
hostname = link->network->hostname;
else
(void) sd_dhcp_lease_get_hostname(lease, &hostname);
if (r >= 0 || hostname) {
if (hostname) {
r = link_set_hostname(link, hostname);
if (r < 0)
log_link_error_errno(link, r, "Failed to set transient hostname to '%s': %m", hostname);
}
}
if (link->network->dhcp_timezone) {
const char *tz = NULL;
(void) sd_dhcp_lease_get_timezone(link->dhcp_lease, &tz);
if (tz) {
r = link_set_timezone(link, tz);
if (r < 0)
log_link_error_errno(link, r, "Failed to set timezone to '%s': %m", tz);
}
}
if (!link->network->dhcp_critical) {
r = sd_dhcp_lease_get_lifetime(link->dhcp_lease, &lifetime);
if (r < 0) {
@@ -515,8 +475,7 @@ static void dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
case DHCP_EVENT_STOP:
case DHCP_EVENT_IP_CHANGE:
if (link->network->dhcp_critical) {
log_link_error(link,
"DHCPv4 connection considered system critical, ignoring request to reconfigure it.");
log_link_error(link, "DHCPv4 connection considered system critical, ignoring request to reconfigure it.");
return;
}
@@ -553,13 +512,9 @@ static void dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
break;
default:
if (event < 0)
log_link_warning(link,
"DHCP error: client failed: %s",
strerror(-event));
log_link_warning_errno(link, event, "DHCP error: Client failed: %m");
else
log_link_warning(link,
"DHCP unknown event: %d",
event);
log_link_warning(link, "DHCP unknown event: %i", event);
break;
}
@@ -607,10 +562,10 @@ int dhcp4_configure(Link *link) {
}
if (link->network->dhcp_mtu) {
r = sd_dhcp_client_set_request_option(link->dhcp_client,
DHCP_OPTION_INTERFACE_MTU);
if (r < 0)
return r;
r = sd_dhcp_client_set_request_option(link->dhcp_client,
DHCP_OPTION_INTERFACE_MTU);
if (r < 0)
return r;
}
if (link->network->dhcp_routes) {
@@ -624,6 +579,15 @@ int dhcp4_configure(Link *link) {
return r;
}
/* Always acquire the timezone and NTP*/
r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_NTP_SERVER);
if (r < 0)
return r;
r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_NEW_TZDB_TIMEZONE);
if (r < 0)
return r;
if (link->network->dhcp_sendhost) {
_cleanup_free_ char *hostname = NULL;
const char *hn = NULL;
+4 -2
View File
@@ -22,10 +22,12 @@
#include <net/if.h>
#include <net/ethernet.h>
#include "networkd.h"
#include "networkd-link.h"
#include "conf-parser.h"
#include "util.h"
#include "netlink-util.h"
#include "networkd.h"
#include "networkd-fdb.h"
/* create a new FDB entry or get an existing one. */
int fdb_entry_new_static(Network *const network,
+47
View File
@@ -0,0 +1,47 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***
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/>.
***/
typedef struct FdbEntry FdbEntry;
#include "networkd.h"
#include "networkd-network.h"
struct FdbEntry {
Network *network;
unsigned section;
struct ether_addr *mac_addr;
uint16_t vlan_id;
LIST_FIELDS(FdbEntry, static_fdb_entries);
};
int fdb_entry_new_static(Network *const network, const unsigned section, FdbEntry **ret);
void fdb_entry_free(FdbEntry *fdb_entry);
int fdb_entry_configure(Link *const link, FdbEntry *const fdb_entry);
DEFINE_TRIVIAL_CLEANUP_FUNC(FdbEntry*, fdb_entry_free);
#define _cleanup_fdbentry_free_ _cleanup_(fdb_entry_freep)
int config_parse_fdb_hwaddr(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);
int config_parse_fdb_vlan_id(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);
+236 -8
View File
@@ -29,7 +29,10 @@
#include "socket-util.h"
#include "bus-util.h"
#include "udev-util.h"
#include "netlink-util.h"
#include "dhcp-lease-internal.h"
#include "network-internal.h"
#include "networkd-link.h"
#include "networkd-netdev.h"
@@ -613,6 +616,96 @@ static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userda
return 1;
}
static int link_push_dns_to_dhcp_server(Link *link, sd_dhcp_server *s) {
_cleanup_free_ struct in_addr *addresses = NULL;
size_t n_addresses = 0, n_allocated = 0;
char **a;
log_debug("Copying DNS server information from %s", link->ifname);
if (!link->network)
return 0;
STRV_FOREACH(a, link->network->dns) {
struct in_addr ia;
/* Only look for IPv4 addresses */
if (inet_pton(AF_INET, *a, &ia) <= 0)
continue;
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
return log_oom();
addresses[n_addresses++] = ia;
}
if (link->network->dhcp_dns &&
link->dhcp_lease) {
const struct in_addr *da = NULL;
int n;
n = sd_dhcp_lease_get_dns(link->dhcp_lease, &da);
if (n > 0) {
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;
}
}
if (n_addresses <= 0)
return 0;
return sd_dhcp_server_set_dns(s, addresses, n_addresses);
}
static int link_push_ntp_to_dhcp_server(Link *link, sd_dhcp_server *s) {
_cleanup_free_ struct in_addr *addresses = NULL;
size_t n_addresses = 0, n_allocated = 0;
char **a;
if (!link->network)
return 0;
log_debug("Copying NTP server information from %s", link->ifname);
STRV_FOREACH(a, link->network->ntp) {
struct in_addr ia;
/* Only look for IPv4 addresses */
if (inet_pton(AF_INET, *a, &ia) <= 0)
continue;
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
return log_oom();
addresses[n_addresses++] = ia;
}
if (link->network->dhcp_ntp &&
link->dhcp_lease) {
const struct in_addr *da = NULL;
int n;
n = sd_dhcp_lease_get_ntp(link->dhcp_lease, &da);
if (n > 0) {
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;
}
}
if (n_addresses <= 0)
return 0;
return sd_dhcp_server_set_ntp(s, addresses, n_addresses);
}
static int link_enter_set_addresses(Link *link) {
Address *ad;
int r;
@@ -639,6 +732,8 @@ static int link_enter_set_addresses(Link *link) {
if (link_dhcp4_server_enabled(link)) {
struct in_addr pool_start;
Address *address;
Link *uplink = NULL;
bool acquired_uplink = false;
address = link_find_dhcp_server_address(link);
if (!address) {
@@ -672,6 +767,81 @@ static int link_enter_set_addresses(Link *link) {
return r;
*/
if (link->network->dhcp_server_max_lease_time_usec > 0) {
r = sd_dhcp_server_set_max_lease_time(
link->dhcp_server,
DIV_ROUND_UP(link->network->dhcp_server_max_lease_time_usec, USEC_PER_SEC));
if (r < 0)
return r;
}
if (link->network->dhcp_server_default_lease_time_usec > 0) {
r = sd_dhcp_server_set_default_lease_time(
link->dhcp_server,
DIV_ROUND_UP(link->network->dhcp_server_default_lease_time_usec, USEC_PER_SEC));
if (r < 0)
return r;
}
if (link->network->dhcp_server_emit_dns) {
if (link->network->n_dhcp_server_dns > 0)
r = sd_dhcp_server_set_dns(link->dhcp_server, link->network->dhcp_server_dns, link->network->n_dhcp_server_dns);
else {
uplink = manager_find_uplink(link->manager, link);
acquired_uplink = true;
if (!uplink) {
log_link_debug(link, "Not emitting DNS server information on link, couldn't find suitable uplink.");
r = 0;
} else
r = link_push_dns_to_dhcp_server(uplink, link->dhcp_server);
}
if (r < 0)
log_link_warning_errno(link, r, "Failed to set DNS server for DHCP server, ignoring: %m");
}
if (link->network->dhcp_server_emit_ntp) {
if (link->network->n_dhcp_server_ntp > 0)
r = sd_dhcp_server_set_ntp(link->dhcp_server, link->network->dhcp_server_ntp, link->network->n_dhcp_server_ntp);
else {
if (!acquired_uplink)
uplink = manager_find_uplink(link->manager, link);
if (!uplink) {
log_link_debug(link, "Not emitting NTP server information on link, couldn't find suitable uplink.");
r = 0;
} else
r = link_push_ntp_to_dhcp_server(uplink, link->dhcp_server);
}
if (r < 0)
log_link_warning_errno(link, r, "Failed to set NTP server for DHCP server, ignoring: %m");
}
if (link->network->dhcp_server_emit_timezone) {
_cleanup_free_ char *buffer = NULL;
const char *tz;
if (link->network->dhcp_server_timezone)
tz = link->network->dhcp_server_timezone;
else {
r = get_timezone(&buffer);
if (r < 0)
log_warning_errno(r, "Failed to determine timezone: %m");
else
tz = buffer;
}
if (tz) {
r = sd_dhcp_server_set_timezone(link->dhcp_server, tz);
if (r < 0)
return r;
}
}
r = sd_dhcp_server_start(link->dhcp_server);
if (r < 0) {
log_link_warning_errno(link, r, "Could not start DHCPv4 server instance: %m");
@@ -743,7 +913,7 @@ static int link_set_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userd
static int set_hostname_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
_cleanup_link_unref_ Link *link = userdata;
int r;
const sd_bus_error *e;
assert(m);
assert(link);
@@ -751,21 +921,20 @@ static int set_hostname_handler(sd_bus_message *m, void *userdata, sd_bus_error
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
r = sd_bus_message_get_errno(m);
if (r > 0)
log_link_warning_errno(link, r, "Could not set hostname: %m");
e = sd_bus_message_get_error(m);
if (e)
log_link_warning_errno(link, sd_bus_error_get_errno(e), "Could not set hostname: %s", e->message);
return 1;
}
int link_set_hostname(Link *link, const char *hostname) {
int r = 0;
int r;
assert(link);
assert(link->manager);
assert(hostname);
log_link_debug(link, "Setting transient hostname: '%s'", hostname);
log_link_debug(link, "Setting transient hostname: '%s'", strna(hostname));
if (!link->manager->bus) {
/* TODO: replace by assert when we can rely on kdbus */
@@ -794,6 +963,57 @@ int link_set_hostname(Link *link, const char *hostname) {
return 0;
}
static int set_timezone_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
_cleanup_link_unref_ Link *link = userdata;
const sd_bus_error *e;
assert(m);
assert(link);
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
e = sd_bus_message_get_error(m);
if (e)
log_link_warning_errno(link, sd_bus_error_get_errno(e), "Could not set timezone: %s", e->message);
return 1;
}
int link_set_timezone(Link *link, const char *timezone) {
int r;
assert(link);
assert(link->manager);
assert(timezone);
log_link_debug(link, "Setting system timezone: '%s'", timezone);
if (!link->manager->bus) {
log_link_info(link, "Not connected to system bus, ignoring timezone.");
return 0;
}
r = sd_bus_call_method_async(
link->manager->bus,
NULL,
"org.freedesktop.timedate1",
"/org/freedesktop/timedate1",
"org.freedesktop.timedate1",
"SetTimezone",
set_timezone_handler,
link,
"sb",
timezone,
false);
if (r < 0)
return log_link_error_errno(link, r, "Could not set timezone: %m");
link_ref(link);
return 0;
}
static int set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
_cleanup_link_unref_ Link *link = userdata;
int r;
@@ -2413,10 +2633,18 @@ int link_save(Link *link) {
fputs("\n", f);
}
if (link->dhcp_lease) {
const char *tz = NULL;
r = sd_dhcp_lease_get_timezone(link->dhcp_lease, &tz);
if (r >= 0)
fprintf(f, "TIMEZONE=%s\n", tz);
}
if (link->dhcp_lease) {
assert(link->network);
r = sd_dhcp_lease_save(link->dhcp_lease, link->lease_file);
r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
if (r < 0)
goto fail;
+29 -3
View File
@@ -1,5 +1,7 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***
This file is part of systemd.
@@ -19,11 +21,16 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#pragma once
#include <endian.h>
#include "networkd.h"
#include "sd-dhcp-client.h"
#include "sd-dhcp-server.h"
#include "sd-ipv4ll.h"
#include "sd-icmp6-nd.h"
#include "sd-dhcp6-client.h"
#include "sd-lldp.h"
typedef struct Link Link;
typedef enum LinkState {
LINK_STATE_PENDING,
@@ -38,6 +45,21 @@ typedef enum LinkState {
_LINK_STATE_INVALID = -1
} LinkState;
typedef enum LinkOperationalState {
LINK_OPERSTATE_OFF,
LINK_OPERSTATE_NO_CARRIER,
LINK_OPERSTATE_DORMANT,
LINK_OPERSTATE_CARRIER,
LINK_OPERSTATE_DEGRADED,
LINK_OPERSTATE_ROUTABLE,
_LINK_OPERSTATE_MAX,
_LINK_OPERSTATE_INVALID = -1
} LinkOperationalState;
#include "networkd.h"
#include "networkd-network.h"
#include "networkd-address.h"
struct Link {
Manager *manager;
@@ -115,6 +137,7 @@ bool link_has_carrier(Link *link);
int link_set_mtu(Link *link, uint32_t mtu);
int link_set_hostname(Link *link, const char *hostname);
int link_set_timezone(Link *link, const char *timezone);
int ipv4ll_configure(Link *link);
int dhcp4_configure(Link *link);
@@ -130,6 +153,9 @@ bool link_dhcp6_enabled(Link *link);
const char* link_state_to_string(LinkState s) _const_;
LinkState link_state_from_string(const char *s) _pure_;
const char* link_operstate_to_string(LinkOperationalState s) _const_;
LinkOperationalState link_operstate_from_string(const char *s) _pure_;
extern const sd_bus_vtable link_vtable[];
int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
+50 -45
View File
@@ -22,20 +22,21 @@
#include <sys/socket.h>
#include <linux/if.h>
#include "sd-netlink.h"
#include "sd-daemon.h"
#include "conf-parser.h"
#include "path-util.h"
#include "networkd.h"
#include "networkd-netdev.h"
#include "networkd-link.h"
#include "libudev-private.h"
#include "udev-util.h"
#include "netlink-util.h"
#include "bus-util.h"
#include "def.h"
#include "virt.h"
#include "set.h"
#include "local-addresses.h"
#include "sd-netlink.h"
#include "sd-daemon.h"
#include "networkd.h"
/* use 8 MB for receive socket kernel queue. */
#define RCVBUF_SIZE (8*1024*1024)
@@ -99,7 +100,7 @@ static int manager_reset_all(Manager *m) {
HASHMAP_FOREACH(link, m->links, i) {
r = link_carrier_reset(link);
if (r < 0)
log_link_warning_errno(link, r, "could not reset carrier: %m");
log_link_warning_errno(link, r, "Could not reset carrier: %m");
}
return 0;
@@ -204,7 +205,7 @@ static int manager_udev_process_link(Manager *m, struct udev_device *device) {
ifindex = udev_device_get_ifindex(device);
if (ifindex <= 0) {
log_debug("ignoring udev ADD event for device with invalid ifindex");
log_debug("Ignoring udev ADD event for device with invalid ifindex");
return 0;
}
@@ -291,23 +292,23 @@ static int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *messa
if (sd_netlink_message_is_error(message)) {
r = sd_netlink_message_get_errno(message);
if (r < 0)
log_warning_errno(r, "rtnl: could not receive link: %m");
log_warning_errno(r, "rtnl: Could not receive link: %m");
return 0;
}
r = sd_netlink_message_get_type(message, &type);
if (r < 0) {
log_warning_errno(r, "rtnl: could not get message type: %m");
log_warning_errno(r, "rtnl: Could not get message type: %m");
return 0;
} else if (type != RTM_NEWLINK && type != RTM_DELLINK) {
log_warning("rtnl: received unexpected message type when processing link");
log_warning("rtnl: Received unexpected message type when processing link");
return 0;
}
r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
if (r < 0) {
log_warning_errno(r, "rtnl: could not get ifindex from link: %m");
log_warning_errno(r, "rtnl: Could not get ifindex from link: %m");
return 0;
} else if (ifindex <= 0) {
log_warning("rtnl: received link message with invalid ifindex: %d", ifindex);
@@ -317,7 +318,7 @@ static int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *messa
r = sd_netlink_message_read_string(message, IFLA_IFNAME, &name);
if (r < 0) {
log_warning_errno(r, "rtnl: received link message without ifname: %m");
log_warning_errno(r, "rtnl: Received link message without ifname: %m");
return 0;
} else
netdev_get(m, name, &netdev);
@@ -328,7 +329,7 @@ static int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *messa
/* link is new, so add it */
r = link_add(m, message, &link);
if (r < 0) {
log_warning_errno(r, "could not add new link: %m");
log_warning_errno(r, "Could not add new link: %m");
return 0;
}
}
@@ -337,7 +338,7 @@ static int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *messa
/* netdev exists, so make sure the ifindex matches */
r = netdev_set_ifindex(netdev, message);
if (r < 0) {
log_warning_errno(r, "could not set ifindex on netdev: %m");
log_warning_errno(r, "Could not set ifindex on netdev: %m");
return 0;
}
}
@@ -476,13 +477,13 @@ void manager_free(Manager *m) {
free(m->state_file);
sd_event_source_unref(m->udev_event_source);
udev_monitor_unref(m->udev_monitor);
udev_unref(m->udev);
sd_bus_unref(m->bus);
sd_bus_slot_unref(m->prepare_for_sleep_slot);
sd_event_source_unref(m->udev_event_source);
sd_event_source_unref(m->bus_retry_event_source);
sd_event_unref(m->event);
while ((link = hashmap_first(m->links)))
link_unref(link);
@@ -501,6 +502,7 @@ void manager_free(Manager *m) {
address_pool_free(pool);
sd_netlink_unref(m->rtnl);
sd_event_unref(m->event);
free(m);
}
@@ -846,36 +848,39 @@ int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, uni
return 0;
}
const char *address_family_boolean_to_string(AddressFamilyBoolean b) {
if (b == ADDRESS_FAMILY_YES ||
b == ADDRESS_FAMILY_NO)
return yes_no(b == ADDRESS_FAMILY_YES);
Link* manager_find_uplink(Manager *m, Link *exclude) {
_cleanup_free_ struct local_address *gateways = NULL;
int n, i;
if (b == ADDRESS_FAMILY_IPV4)
return "ipv4";
if (b == ADDRESS_FAMILY_IPV6)
return "ipv6";
assert(m);
/* Looks for a suitable "uplink", via black magic: an
* interface that is up and where the default route with the
* highest priority points to. */
n = local_gateways(m->rtnl, 0, AF_UNSPEC, &gateways);
if (n < 0) {
log_warning_errno(n, "Failed to determine list of default gateways: %m");
return NULL;
}
for (i = 0; i < n; i++) {
Link *link;
link = hashmap_get(m->links, INT_TO_PTR(gateways[i].ifindex));
if (!link) {
log_debug("Weird, found a gateway for a link we don't know. Ignoring.");
continue;
}
if (link == exclude)
continue;
if (link->operstate < LINK_OPERSTATE_ROUTABLE)
continue;
return link;
}
return NULL;
}
AddressFamilyBoolean address_family_boolean_from_string(const char *s) {
int r;
/* Make this a true superset of a boolean */
r = parse_boolean(s);
if (r > 0)
return ADDRESS_FAMILY_YES;
if (r == 0)
return ADDRESS_FAMILY_NO;
if (streq(s, "ipv4"))
return ADDRESS_FAMILY_IPV4;
if (streq(s, "ipv6"))
return ADDRESS_FAMILY_IPV6;
return _ADDRESS_FAMILY_BOOLEAN_INVALID;
}
DEFINE_CONFIG_PARSE_ENUM(config_parse_address_family_boolean, address_family_boolean, AddressFamilyBoolean, "Failed to parse option");
+3 -1
View File
@@ -1,5 +1,7 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***
This file is part of systemd.
@@ -19,7 +21,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#pragma once
#include "in-addr-util.h"
typedef struct Bond Bond;
+6 -3
View File
@@ -21,15 +21,18 @@
#include <net/if.h>
#include "networkd-netdev.h"
#include "networkd-link.h"
#include "network-internal.h"
#include "conf-files.h"
#include "conf-parser.h"
#include "list.h"
#include "siphash24.h"
#include "netlink-util.h"
#include "network-internal.h"
#include "networkd.h"
#include "networkd-netdev.h"
const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = {
[NETDEV_KIND_BRIDGE] = &bridge_vtable,
[NETDEV_KIND_BOND] = &bond_vtable,
[NETDEV_KIND_VLAN] = &vlan_vtable,
+4 -1
View File
@@ -21,11 +21,14 @@
#pragma once
#include "networkd.h"
#include "list.h"
typedef struct NetDev NetDev;
typedef struct NetDevVTable NetDevVTable;
#include "networkd.h"
#include "networkd-link.h"
typedef struct netdev_join_callback netdev_join_callback;
struct netdev_join_callback {
+9
View File
@@ -73,6 +73,15 @@ DHCP.RequestBroadcast, config_parse_bool, 0
DHCP.CriticalConnection, config_parse_bool, 0, offsetof(Network, dhcp_critical)
DHCP.VendorClassIdentifier, config_parse_string, 0, offsetof(Network, dhcp_vendor_class_identifier)
DHCP.RouteMetric, config_parse_unsigned, 0, offsetof(Network, dhcp_route_metric)
DHCP.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_timezone)
DHCPServer.MaxLeaseTimeSec, config_parse_sec, 0, offsetof(Network, dhcp_server_max_lease_time_usec)
DHCPServer.DefaultLeaseTimeSec,config_parse_sec, 0, offsetof(Network, dhcp_server_default_lease_time_usec)
DHCPServer.EmitDNS, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_dns)
DHCPServer.DNS, config_parse_dhcp_server_dns, 0, 0
DHCPServer.EmitNTP, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_ntp)
DHCPServer.NTP, config_parse_dhcp_server_ntp, 0, 0
DHCPServer.EmitTimezone, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_timezone)
DHCPServer.Timezone, config_parse_timezone, 0, offsetof(Network, dhcp_server_timezone)
Bridge.Cost, config_parse_unsigned, 0, offsetof(Network, cost)
Bridge.UseBPDU, config_parse_bool, 0, offsetof(Network, use_bpdu)
Bridge.HairPin, config_parse_bool, 0, offsetof(Network, hairpin)
+159 -107
View File
@@ -26,11 +26,11 @@
#include "conf-parser.h"
#include "util.h"
#include "hostname-util.h"
#include "networkd.h"
#include "networkd-netdev.h"
#include "networkd-link.h"
#include "network-internal.h"
#include "dns-domain.h"
#include "network-internal.h"
#include "networkd.h"
#include "networkd-network.h"
static int network_load_one(Manager *manager, const char *filename) {
_cleanup_network_free_ Network *network = NULL;
@@ -107,6 +107,10 @@ static int network_load_one(Manager *manager, const char *filename) {
network->dhcp_route_metric = DHCP_ROUTE_METRIC;
network->dhcp_client_identifier = DHCP_CLIENT_ID_DUID;
network->dhcp_server_emit_dns = true;
network->dhcp_server_emit_ntp = true;
network->dhcp_server_emit_timezone = true;
network->use_bpdu = true;
network->allow_port_to_be_root = true;
network->unicast_flood = true;
@@ -124,7 +128,8 @@ static int network_load_one(Manager *manager, const char *filename) {
"Address\0"
"Route\0"
"DHCP\0"
"DHCPv4\0"
"DHCPv4\0" /* compat */
"DHCPServer\0"
"Bridge\0"
"BridgeFDB\0",
config_item_perf_lookup, network_network_gperf_lookup,
@@ -258,6 +263,10 @@ void network_free(Network *network) {
condition_free_list(network->match_kernel);
condition_free_list(network->match_arch);
free(network->dhcp_server_timezone);
free(network->dhcp_server_dns);
free(network->dhcp_server_ntp);
free(network);
}
@@ -632,57 +641,6 @@ static const char* const dhcp_client_identifier_table[_DHCP_CLIENT_ID_MAX] = {
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier, DCHPClientIdentifier);
DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier, dhcp_client_identifier, DCHPClientIdentifier, "Failed to parse client identifier type");
static const char* const resolve_support_table[_RESOLVE_SUPPORT_MAX] = {
[RESOLVE_SUPPORT_NO] = "no",
[RESOLVE_SUPPORT_YES] = "yes",
[RESOLVE_SUPPORT_RESOLVE] = "resolve",
};
DEFINE_STRING_TABLE_LOOKUP(resolve_support, ResolveSupport);
int config_parse_resolve(
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) {
ResolveSupport *resolve = data;
int k;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(resolve);
/* Our enum shall be a superset of booleans, hence first try
* to parse as boolean, and then as enum */
k = parse_boolean(rvalue);
if (k > 0)
*resolve = RESOLVE_SUPPORT_YES;
else if (k == 0)
*resolve = RESOLVE_SUPPORT_NO;
else {
ResolveSupport s;
s = resolve_support_from_string(rvalue);
if (s < 0){
log_syntax(unit, LOG_ERR, filename, line, -s, "Failed to parse %s option, ignoring: %s", lvalue, rvalue);
return 0;
}
*resolve = s;
}
return 0;
}
int config_parse_ipv6token(
const char* unit,
const char *filename,
@@ -726,40 +684,6 @@ int config_parse_ipv6token(
return 0;
}
int config_parse_address_family_boolean_with_kernel(
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) {
AddressFamilyBoolean *fwd = data, s;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
s = address_family_boolean_from_string(rvalue);
if (s < 0) {
if (streq(rvalue, "kernel"))
s = _ADDRESS_FAMILY_BOOLEAN_INVALID;
else {
log_syntax(unit, LOG_ERR, filename, line, s, "Failed to parse IPForwarding option, ignoring: %s", rvalue);
return 0;
}
}
*fwd = s;
return 0;
}
static const char* const ipv6_privacy_extensions_table[_IPV6_PRIVACY_EXTENSIONS_MAX] = {
[IPV6_PRIVACY_EXTENSIONS_NO] = "no",
[IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC] = "prefer-public",
@@ -816,37 +740,165 @@ int config_parse_ipv6_privacy_extensions(
return 0;
}
int config_parse_hostname(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) {
char **hostname = data;
char *hn = NULL;
int config_parse_hostname(
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) {
char **hostname = data, *hn = NULL;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
r = config_parse_string(unit, filename, line, section, section_line,
lvalue, ltype, rvalue, &hn, userdata);
r = config_parse_string(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &hn, userdata);
if (r < 0)
return r;
if (!hostname_is_valid(hn, true)) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL, "hostname is not valid, ignoring assignment: %s", rvalue);
if (!hostname_is_valid(hn, false)) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Hostname is not valid, ignoring assignment: %s", rvalue);
free(hn);
return 0;
}
free(*hostname);
*hostname = hostname_cleanup(hn);
return 0;
}
int config_parse_timezone(
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) {
char **timezone = data, *tz = NULL;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
r = config_parse_string(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &tz, userdata);
if (r < 0)
return r;
if (!timezone_is_valid(tz)) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Timezone is not valid, ignoring assignment: %s", rvalue);
free(tz);
return 0;
}
free(*timezone);
*timezone = tz;
return 0;
}
int config_parse_dhcp_server_dns(
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) {
Network *n = data;
const char *p = rvalue;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
for (;;) {
_cleanup_free_ char *w = NULL;
struct in_addr a, *m;
r = extract_first_word(&p, &w, NULL, 0);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract word, ignoring: %s", rvalue);
return 0;
}
if (r == 0)
return 0;
if (inet_pton(AF_INET, w, &a) <= 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse DNS server address, ignoring: %s", w);
continue;
}
m = realloc(n->dhcp_server_dns, (n->n_dhcp_server_dns + 1) * sizeof(struct in_addr));
if (!m)
return log_oom();
m[n->n_dhcp_server_dns++] = a;
n->dhcp_server_dns = m;
}
}
int config_parse_dhcp_server_ntp(
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) {
Network *n = data;
const char *p = rvalue;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
for (;;) {
_cleanup_free_ char *w = NULL;
struct in_addr a, *m;
r = extract_first_word(&p, &w, NULL, 0);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, r, line, "Failed to extract word, ignoring: %s", rvalue);
return 0;
}
if (r == 0)
return 0;
if (inet_pton(AF_INET, w, &a) <= 0) {
log_syntax(unit, LOG_ERR, filename, r, line, "Failed to parse NTP server address, ignoring: %s", w);
continue;
}
m = realloc(n->dhcp_server_ntp, (n->n_dhcp_server_ntp + 1) * sizeof(struct in_addr));
if (!m)
return log_oom();
m[n->n_dhcp_server_ntp++] = a;
n->dhcp_server_ntp = m;
}
}
+179
View File
@@ -0,0 +1,179 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***
This file is part of systemd.
Copyright 2013 Tom Gundersen <teg@jklm.no>
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/>.
***/
#include "condition.h"
typedef struct Network Network;
#include "networkd.h"
#include "networkd-netdev.h"
#include "networkd-address.h"
#include "networkd-route.h"
#include "networkd-fdb.h"
#include "networkd-util.h"
#define DHCP_ROUTE_METRIC 1024
#define IPV4LL_ROUTE_METRIC 2048
typedef enum DCHPClientIdentifier {
DHCP_CLIENT_ID_MAC,
DHCP_CLIENT_ID_DUID,
_DHCP_CLIENT_ID_MAX,
_DHCP_CLIENT_ID_INVALID = -1,
} DCHPClientIdentifier;
typedef enum IPv6PrivacyExtensions {
/* The values map to the kernel's /proc/sys/net/ipv6/conf/xxx/use_tempaddr values */
IPV6_PRIVACY_EXTENSIONS_NO,
IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC,
IPV6_PRIVACY_EXTENSIONS_YES, /* aka prefer-temporary */
_IPV6_PRIVACY_EXTENSIONS_MAX,
_IPV6_PRIVACY_EXTENSIONS_INVALID = -1,
} IPv6PrivacyExtensions;
struct Network {
Manager *manager;
char *filename;
char *name;
struct ether_addr *match_mac;
char **match_path;
char **match_driver;
char **match_type;
char **match_name;
Condition *match_host;
Condition *match_virt;
Condition *match_kernel;
Condition *match_arch;
char *description;
NetDev *bridge;
NetDev *bond;
Hashmap *stacked_netdevs;
/* DHCP Client Support */
AddressFamilyBoolean dhcp;
DCHPClientIdentifier dhcp_client_identifier;
char *dhcp_vendor_class_identifier;
char *hostname;
bool dhcp_dns;
bool dhcp_ntp;
bool dhcp_mtu;
bool dhcp_hostname;
bool dhcp_domains;
bool dhcp_sendhost;
bool dhcp_broadcast;
bool dhcp_critical;
bool dhcp_routes;
bool dhcp_timezone;
unsigned dhcp_route_metric;
/* DHCP Server Support */
bool dhcp_server;
bool dhcp_server_emit_dns;
struct in_addr *dhcp_server_dns;
unsigned n_dhcp_server_dns;
bool dhcp_server_emit_ntp;
struct in_addr *dhcp_server_ntp;
unsigned n_dhcp_server_ntp;
bool dhcp_server_emit_timezone;
char *dhcp_server_timezone;
usec_t dhcp_server_default_lease_time_usec, dhcp_server_max_lease_time_usec;
/* IPV4LL Support */
AddressFamilyBoolean link_local;
bool ipv4ll_route;
/* Bridge Support */
bool use_bpdu;
bool hairpin;
bool fast_leave;
bool allow_port_to_be_root;
bool unicast_flood;
unsigned cost;
AddressFamilyBoolean ip_forward;
bool ip_masquerade;
union in_addr_union ipv6_token;
IPv6PrivacyExtensions ipv6_privacy_extensions;
struct ether_addr *mac;
unsigned mtu;
bool lldp;
LIST_HEAD(Address, static_addresses);
LIST_HEAD(Route, static_routes);
LIST_HEAD(FdbEntry, static_fdb_entries);
Hashmap *addresses_by_section;
Hashmap *routes_by_section;
Hashmap *fdb_entries_by_section;
bool wildcard_domain;
char **domains, **dns, **ntp, **bind_carrier;
ResolveSupport llmnr;
LIST_FIELDS(Network, networks);
};
void network_free(Network *network);
DEFINE_TRIVIAL_CLEANUP_FUNC(Network*, network_free);
#define _cleanup_network_free_ _cleanup_(network_freep)
int network_load(Manager *manager);
int network_get_by_name(Manager *manager, const char *name, Network **ret);
int network_get(Manager *manager, struct udev_device *device, const char *ifname, const struct ether_addr *mac, Network **ret);
int network_apply(Manager *manager, Network *network, Link *link);
int config_parse_netdev(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);
int config_parse_domains(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);
int config_parse_tunnel(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);
int config_parse_dhcp(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);
int config_parse_dhcp_client_identifier(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);
int config_parse_ipv6token(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);
int config_parse_ipv6_privacy_extensions(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);
int config_parse_hostname(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);
int config_parse_timezone(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);
int config_parse_dhcp_server_dns(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);
int config_parse_dhcp_server_ntp(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);
/* Legacy IPv4LL support */
int config_parse_ipv4ll(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);
const struct ConfigPerfItem* network_network_gperf_lookup(const char *key, unsigned length);
extern const sd_bus_vtable network_vtable[];
int network_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
int network_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error);
const char* ipv6_privacy_extensions_to_string(IPv6PrivacyExtensions i) _const_;
IPv6PrivacyExtensions ipv6_privacy_extensions_from_string(const char *s) _pure_;
+4 -4
View File
@@ -19,12 +19,12 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include "networkd.h"
#include "networkd-link.h"
#include "util.h"
#include "conf-parser.h"
#include "netlink-util.h"
#include "networkd.h"
#include "networkd-route.h"
int route_new_static(Network *network, unsigned section, Route **ret) {
_cleanup_route_free_ Route *route = NULL;
+60
View File
@@ -0,0 +1,60 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***
This file is part of systemd.
Copyright 2013 Tom Gundersen <teg@jklm.no>
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/>.
***/
typedef struct Route Route;
#include "networkd.h"
#include "networkd-network.h"
struct Route {
Network *network;
unsigned section;
int family;
unsigned char dst_prefixlen;
unsigned char src_prefixlen;
unsigned char scope;
uint32_t metrics;
unsigned char protocol; /* RTPROT_* */
union in_addr_union in_addr;
union in_addr_union dst_addr;
union in_addr_union src_addr;
union in_addr_union prefsrc_addr;
LIST_FIELDS(Route, routes);
};
int route_new_static(Network *network, unsigned section, Route **ret);
int route_new_dynamic(Route **ret, unsigned char rtm_protocol);
void route_free(Route *route);
int route_configure(Route *route, Link *link, sd_netlink_message_handler_t callback);
int route_drop(Route *route, Link *link, sd_netlink_message_handler_t callback);
DEFINE_TRIVIAL_CLEANUP_FUNC(Route*, route_free);
#define _cleanup_route_free_ _cleanup_(route_freep)
int config_parse_gateway(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);
int config_parse_destination(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);
int config_parse_route_priority(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);
int config_parse_route_scope(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);
+144
View File
@@ -0,0 +1,144 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2013 Tom Gundersen <teg@jklm.no>
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/>.
***/
#include "util.h"
#include "conf-parser.h"
#include "networkd-util.h"
const char *address_family_boolean_to_string(AddressFamilyBoolean b) {
if (b == ADDRESS_FAMILY_YES ||
b == ADDRESS_FAMILY_NO)
return yes_no(b == ADDRESS_FAMILY_YES);
if (b == ADDRESS_FAMILY_IPV4)
return "ipv4";
if (b == ADDRESS_FAMILY_IPV6)
return "ipv6";
return NULL;
}
AddressFamilyBoolean address_family_boolean_from_string(const char *s) {
int r;
/* Make this a true superset of a boolean */
r = parse_boolean(s);
if (r > 0)
return ADDRESS_FAMILY_YES;
if (r == 0)
return ADDRESS_FAMILY_NO;
if (streq(s, "ipv4"))
return ADDRESS_FAMILY_IPV4;
if (streq(s, "ipv6"))
return ADDRESS_FAMILY_IPV6;
return _ADDRESS_FAMILY_BOOLEAN_INVALID;
}
DEFINE_CONFIG_PARSE_ENUM(config_parse_address_family_boolean, address_family_boolean, AddressFamilyBoolean, "Failed to parse option");
int config_parse_address_family_boolean_with_kernel(
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) {
AddressFamilyBoolean *fwd = data, s;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
s = address_family_boolean_from_string(rvalue);
if (s < 0) {
if (streq(rvalue, "kernel"))
s = _ADDRESS_FAMILY_BOOLEAN_INVALID;
else {
log_syntax(unit, LOG_ERR, filename, line, s, "Failed to parse IPForwarding= option, ignoring: %s", rvalue);
return 0;
}
}
*fwd = s;
return 0;
}
static const char* const resolve_support_table[_RESOLVE_SUPPORT_MAX] = {
[RESOLVE_SUPPORT_NO] = "no",
[RESOLVE_SUPPORT_YES] = "yes",
[RESOLVE_SUPPORT_RESOLVE] = "resolve",
};
DEFINE_STRING_TABLE_LOOKUP(resolve_support, ResolveSupport);
int config_parse_resolve(
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) {
ResolveSupport *resolve = data;
int k;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(resolve);
/* Our enum shall be a superset of booleans, hence first try
* to parse as boolean, and then as enum */
k = parse_boolean(rvalue);
if (k > 0)
*resolve = RESOLVE_SUPPORT_YES;
else if (k == 0)
*resolve = RESOLVE_SUPPORT_NO;
else {
ResolveSupport s;
s = resolve_support_from_string(rvalue);
if (s < 0){
log_syntax(unit, LOG_ERR, filename, line, -s, "Failed to parse %s= option, ignoring: %s", lvalue, rvalue);
return 0;
}
*resolve = s;
}
return 0;
}
+52
View File
@@ -0,0 +1,52 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***
This file is part of systemd.
Copyright 2013 Tom Gundersen <teg@jklm.no>
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/>.
***/
#include "macro.h"
typedef enum AddressFamilyBoolean {
/* This is a bitmask, though it usually doesn't feel that way! */
ADDRESS_FAMILY_NO = 0,
ADDRESS_FAMILY_IPV4 = 1,
ADDRESS_FAMILY_IPV6 = 2,
ADDRESS_FAMILY_YES = 3,
_ADDRESS_FAMILY_BOOLEAN_MAX,
_ADDRESS_FAMILY_BOOLEAN_INVALID = -1,
} AddressFamilyBoolean;
typedef enum ResolveSupport {
RESOLVE_SUPPORT_NO,
RESOLVE_SUPPORT_YES,
RESOLVE_SUPPORT_RESOLVE,
_RESOLVE_SUPPORT_MAX,
_RESOLVE_SUPPORT_INVALID = -1,
} ResolveSupport;
int config_parse_resolve(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);
int config_parse_address_family_boolean(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);
int config_parse_address_family_boolean_with_kernel(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);
const char* resolve_support_to_string(ResolveSupport i) _const_;
ResolveSupport resolve_support_from_string(const char *s) _pure_;
const char *address_family_boolean_to_string(AddressFamilyBoolean b) _const_;
AddressFamilyBoolean address_family_boolean_from_string(const char *s) _const_;
+6 -378
View File
@@ -26,213 +26,17 @@
#include "sd-event.h"
#include "sd-netlink.h"
#include "sd-bus.h"
#include "sd-dhcp-client.h"
#include "sd-dhcp-server.h"
#include "sd-ipv4ll.h"
#include "sd-icmp6-nd.h"
#include "sd-dhcp6-client.h"
#include "udev.h"
#include "sd-lldp.h"
#include "netlink-util.h"
#include "hashmap.h"
#include "list.h"
#include "set.h"
#include "condition.h"
#include "in-addr-util.h"
#define CACHE_INFO_INFINITY_LIFE_TIME 0xFFFFFFFFU
#define DHCP_ROUTE_METRIC 1024
#define IPV4LL_ROUTE_METRIC 2048
typedef struct NetDev NetDev;
typedef struct Network Network;
typedef struct Link Link;
typedef struct Address Address;
typedef struct Route Route;
typedef struct Manager Manager;
typedef struct AddressPool AddressPool;
typedef struct FdbEntry FdbEntry;
typedef enum AddressFamilyBoolean {
/* This is a bitmask, though it usually doesn't feel that way! */
ADDRESS_FAMILY_NO = 0,
ADDRESS_FAMILY_IPV4 = 1,
ADDRESS_FAMILY_IPV6 = 2,
ADDRESS_FAMILY_YES = 3,
_ADDRESS_FAMILY_BOOLEAN_MAX,
_ADDRESS_FAMILY_BOOLEAN_INVALID = -1,
} AddressFamilyBoolean;
typedef enum ResolveSupport {
RESOLVE_SUPPORT_NO,
RESOLVE_SUPPORT_YES,
RESOLVE_SUPPORT_RESOLVE,
_RESOLVE_SUPPORT_MAX,
_RESOLVE_SUPPORT_INVALID = -1,
} ResolveSupport;
typedef enum LinkOperationalState {
LINK_OPERSTATE_OFF,
LINK_OPERSTATE_NO_CARRIER,
LINK_OPERSTATE_DORMANT,
LINK_OPERSTATE_CARRIER,
LINK_OPERSTATE_DEGRADED,
LINK_OPERSTATE_ROUTABLE,
_LINK_OPERSTATE_MAX,
_LINK_OPERSTATE_INVALID = -1
} LinkOperationalState;
typedef enum DCHPClientIdentifier {
DHCP_CLIENT_ID_MAC,
DHCP_CLIENT_ID_DUID,
_DHCP_CLIENT_ID_MAX,
_DHCP_CLIENT_ID_INVALID = -1,
} DCHPClientIdentifier;
typedef enum IPv6PrivacyExtensions {
/* The values map to the kernel's /proc/sys/net/ipv6/conf/xxx/use_tempaddr values */
IPV6_PRIVACY_EXTENSIONS_NO,
IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC,
IPV6_PRIVACY_EXTENSIONS_YES, /* aka prefer-temporary */
_IPV6_PRIVACY_EXTENSIONS_MAX,
_IPV6_PRIVACY_EXTENSIONS_INVALID = -1,
} IPv6PrivacyExtensions;
struct FdbEntry {
Network *network;
unsigned section;
struct ether_addr *mac_addr;
uint16_t vlan_id;
LIST_FIELDS(FdbEntry, static_fdb_entries);
};
struct Network {
Manager *manager;
char *filename;
char *name;
struct ether_addr *match_mac;
char **match_path;
char **match_driver;
char **match_type;
char **match_name;
Condition *match_host;
Condition *match_virt;
Condition *match_kernel;
Condition *match_arch;
char *description;
NetDev *bridge;
NetDev *bond;
Hashmap *stacked_netdevs;
AddressFamilyBoolean dhcp;
DCHPClientIdentifier dhcp_client_identifier;
char *dhcp_vendor_class_identifier;
char *hostname;
bool dhcp_dns;
bool dhcp_ntp;
bool dhcp_mtu;
bool dhcp_hostname;
bool dhcp_domains;
bool dhcp_sendhost;
bool dhcp_broadcast;
bool dhcp_critical;
bool dhcp_routes;
unsigned dhcp_route_metric;
AddressFamilyBoolean link_local;
bool ipv4ll_route;
union in_addr_union ipv6_token;
bool dhcp_server;
bool use_bpdu;
bool hairpin;
bool fast_leave;
bool allow_port_to_be_root;
bool unicast_flood;
unsigned cost;
AddressFamilyBoolean ip_forward;
bool ip_masquerade;
IPv6PrivacyExtensions ipv6_privacy_extensions;
struct ether_addr *mac;
unsigned mtu;
bool lldp;
LIST_HEAD(Address, static_addresses);
LIST_HEAD(Route, static_routes);
LIST_HEAD(FdbEntry, static_fdb_entries);
Hashmap *addresses_by_section;
Hashmap *routes_by_section;
Hashmap *fdb_entries_by_section;
bool wildcard_domain;
char **domains, **dns, **ntp, **bind_carrier;
ResolveSupport llmnr;
LIST_FIELDS(Network, networks);
};
struct Address {
Network *network;
unsigned section;
int family;
unsigned char prefixlen;
unsigned char scope;
uint32_t flags;
char *label;
struct in_addr broadcast;
struct ifa_cacheinfo cinfo;
union in_addr_union in_addr;
union in_addr_union in_addr_peer;
bool ip_masquerade_done;
LIST_FIELDS(Address, addresses);
};
struct Route {
Network *network;
unsigned section;
int family;
unsigned char dst_prefixlen;
unsigned char src_prefixlen;
unsigned char scope;
uint32_t metrics;
unsigned char protocol; /* RTPROT_* */
union in_addr_union in_addr;
union in_addr_union dst_addr;
union in_addr_union src_addr;
union in_addr_union prefsrc_addr;
LIST_FIELDS(Route, routes);
};
struct AddressPool {
Manager *manager;
int family;
unsigned prefixlen;
union in_addr_union in_addr;
LIST_FIELDS(AddressPool, address_pools);
};
#include "networkd-network.h"
#include "networkd-address-pool.h"
#include "networkd-link.h"
#include "networkd-util.h"
struct Manager {
sd_netlink *rtnl;
@@ -281,183 +85,7 @@ int manager_save(Manager *m);
int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found);
Link* manager_find_uplink(Manager *m, Link *exclude);
DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
#define _cleanup_manager_free_ _cleanup_(manager_freep)
/* Network */
int network_load(Manager *manager);
void network_free(Network *network);
DEFINE_TRIVIAL_CLEANUP_FUNC(Network*, network_free);
#define _cleanup_network_free_ _cleanup_(network_freep)
int network_get_by_name(Manager *manager, const char *name, Network **ret);
int network_get(Manager *manager, struct udev_device *device,
const char *ifname, const struct ether_addr *mac,
Network **ret);
int network_apply(Manager *manager, Network *network, Link *link);
int config_parse_netdev(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);
int config_parse_domains(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);
int config_parse_tunnel(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);
extern const sd_bus_vtable network_vtable[];
int network_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
int network_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error);
/* gperf */
const struct ConfigPerfItem* network_network_gperf_lookup(const char *key, unsigned length);
/* Route */
int route_new_static(Network *network, unsigned section, Route **ret);
int route_new_dynamic(Route **ret, unsigned char rtm_protocol);
void route_free(Route *route);
int route_configure(Route *route, Link *link, sd_netlink_message_handler_t callback);
int route_drop(Route *route, Link *link, sd_netlink_message_handler_t callback);
DEFINE_TRIVIAL_CLEANUP_FUNC(Route*, route_free);
#define _cleanup_route_free_ _cleanup_(route_freep)
int config_parse_gateway(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);
int config_parse_destination(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);
int config_parse_route_priority(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);
int config_parse_route_scope(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);
/* Address */
int address_new_static(Network *network, unsigned section, Address **ret);
int address_new_dynamic(Address **ret);
void address_free(Address *address);
int address_configure(Address *address, Link *link, sd_netlink_message_handler_t callback);
int address_update(Address *address, Link *link, sd_netlink_message_handler_t callback);
int address_drop(Address *address, Link *link, sd_netlink_message_handler_t callback);
int address_establish(Address *address, Link *link);
int address_release(Address *address, Link *link);
bool address_equal(Address *a1, Address *a2);
DEFINE_TRIVIAL_CLEANUP_FUNC(Address*, address_free);
#define _cleanup_address_free_ _cleanup_(address_freep)
int config_parse_address(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);
int config_parse_broadcast(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);
int config_parse_label(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);
/* Forwarding database table. */
int fdb_entry_configure(Link *const link, FdbEntry *const fdb_entry);
void fdb_entry_free(FdbEntry *fdb_entry);
int fdb_entry_new_static(Network *const network, const unsigned section, FdbEntry **ret);
DEFINE_TRIVIAL_CLEANUP_FUNC(FdbEntry*, fdb_entry_free);
#define _cleanup_fdbentry_free_ _cleanup_(fdb_entry_freep)
int config_parse_fdb_hwaddr(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);
int config_parse_fdb_vlan_id(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);
/* DHCP support */
int config_parse_dhcp(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);
int config_parse_dhcp_client_identifier(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);
/* IPv4LL support (legacy) */
int config_parse_ipv4ll(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);
/* IPv6 support */
int config_parse_ipv6token(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);
/* Resolve protocols support */
const char* resolve_support_to_string(ResolveSupport i) _const_;
ResolveSupport resolve_support_from_string(const char *s) _pure_;
int config_parse_resolve(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);
/* Address Pool */
int address_pool_new(Manager *m, AddressPool **ret, int family, const union in_addr_union *u, unsigned prefixlen);
int address_pool_new_from_string(Manager *m, AddressPool **ret, int family, const char *p, unsigned prefixlen);
void address_pool_free(AddressPool *p);
int address_pool_acquire(AddressPool *p, unsigned prefixlen, union in_addr_union *found);
const char *address_family_boolean_to_string(AddressFamilyBoolean b) _const_;
AddressFamilyBoolean address_family_boolean_from_string(const char *s) _const_;
int config_parse_address_family_boolean(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);
/* IPForwarding parser */
int config_parse_address_family_boolean_with_kernel(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);
/* Operational State */
const char* link_operstate_to_string(LinkOperationalState s) _const_;
LinkOperationalState link_operstate_from_string(const char *s) _pure_;
/* IPv6 privacy extensions support */
const char* ipv6_privacy_extensions_to_string(IPv6PrivacyExtensions i) _const_;
IPv6PrivacyExtensions ipv6_privacy_extensions_from_string(const char *s) _pure_;
int config_parse_ipv6_privacy_extensions(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);
/* Hostname */
int config_parse_hostname(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);
+7 -8
View File
@@ -34,6 +34,9 @@ sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease);
int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr);
int sd_dhcp_lease_get_lifetime(sd_dhcp_lease *lease, uint32_t *lifetime);
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_next_server(sd_dhcp_lease *lease, struct in_addr *addr);
@@ -44,13 +47,9 @@ int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu);
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname);
int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname);
int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path);
int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, struct sd_dhcp_route **routesgn);
int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const uint8_t **data,
size_t *data_len);
int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const uint8_t **client_id,
size_t *client_id_len);
int sd_dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file);
int sd_dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file);
int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, struct sd_dhcp_route **routes);
int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len);
int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const void **client_id, size_t *client_id_len);
int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **timezone);
#endif
+10 -2
View File
@@ -30,11 +30,11 @@
typedef struct sd_dhcp_server sd_dhcp_server;
int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex);
sd_dhcp_server *sd_dhcp_server_ref(sd_dhcp_server *server);
sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server);
int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex);
int sd_dhcp_server_attach_event(sd_dhcp_server *client, sd_event *event, int priority);
int sd_dhcp_server_detach_event(sd_dhcp_server *client);
sd_event *sd_dhcp_server_get_event(sd_dhcp_server *client);
@@ -47,5 +47,13 @@ int sd_dhcp_server_stop(sd_dhcp_server *server);
int sd_dhcp_server_set_address(sd_dhcp_server *server, struct in_addr *address, unsigned char prefixlen);
int sd_dhcp_server_set_lease_pool(sd_dhcp_server *server, struct in_addr *start, size_t size);
int sd_dhcp_server_set_timezone(sd_dhcp_server *server, const char *timezone);
int sd_dhcp_server_set_dns(sd_dhcp_server *server, const struct in_addr ntp[], unsigned n);
int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr dns[], unsigned n);
int sd_dhcp_server_set_max_lease_time(sd_dhcp_server *server, uint32_t t);
int sd_dhcp_server_set_default_lease_time(sd_dhcp_server *server, uint32_t t);
int sd_dhcp_server_forcerenew(sd_dhcp_server *server);
#endif
+3
View File
@@ -122,6 +122,9 @@ int sd_network_link_get_carrier_bound_to(int ifindex, char ***carriers);
/* Get the CARRIERS that are bound to current link. */
int sd_network_link_get_carrier_bound_by(int ifindex, char ***carriers);
/* Get the timezone that was learnt on a specific link. */
int sd_network_link_get_timezone(int ifindex, char **timezone);
/* Returns whether or not domains that don't match any link should be resolved
* on this link. 1 for yes, 0 for no and negative value for error */
int sd_network_link_get_wildcard_domain(int ifindex);
+8 -25
View File
@@ -68,32 +68,15 @@ static int context_read_data(Context *c) {
assert(c);
r = readlink_malloc("/etc/localtime", &t);
if (r < 0) {
if (r == -EINVAL)
log_warning("/etc/localtime should be a symbolic link to a time zone data file in /usr/share/zoneinfo/.");
else
log_warning_errno(r, "Failed to get target of /etc/localtime: %m");
} else {
const char *e;
r = get_timezone(&t);
if (r == -EINVAL)
log_warning_errno(r, "/etc/localtime should be a symbolic link to a time zone data file in /usr/share/zoneinfo/.");
else if (r < 0)
log_warning_errno(r, "Failed to get target of /etc/localtime: %m");
e = path_startswith(t, "/usr/share/zoneinfo/");
if (!e)
e = path_startswith(t, "../usr/share/zoneinfo/");
if (!e)
log_warning("/etc/localtime should be a symbolic link to a time zone data file in /usr/share/zoneinfo/.");
else {
c->zone = strdup(e);
if (!c->zone)
return log_oom();
}
}
if (isempty(c->zone)) {
free(c->zone);
c->zone = NULL;
}
free(c->zone);
c->zone = t;
t = NULL;
c->local_rtc = clock_is_localtime() > 0;