Commit 18133ea1 authored by Thomas Haller's avatar Thomas Haller

systemd: merge branch systemd into th/systemd-lldp-bgo763384

As the lldp API changed, adjust "nm-lldp-listener.c".

Note that the commit is not yet functional due to missing
sd_event_source_set_enabled() and sd_event_source_set_time().
parents d432edba bccb4e35
......@@ -71,6 +71,8 @@ libsystemd_nm_la_SOURCES = \
systemd/src/basic/async.h \
systemd/src/basic/escape.c \
systemd/src/basic/escape.h \
systemd/src/basic/ether-addr-util.c \
systemd/src/basic/ether-addr-util.h \
systemd/src/basic/fd-util.c \
systemd/src/basic/fd-util.h \
systemd/src/basic/fileio.c \
......@@ -106,6 +108,7 @@ libsystemd_nm_la_SOURCES = \
systemd/src/basic/set.h \
systemd/src/basic/siphash24.c \
systemd/src/basic/siphash24.h \
systemd/src/basic/socket-util.c \
systemd/src/basic/socket-util.h \
systemd/src/basic/sparse-endian.h \
systemd/src/basic/stdio-util.h \
......@@ -138,14 +141,11 @@ libsystemd_nm_la_SOURCES = \
systemd/src/libsystemd-network/dhcp6-network.c \
systemd/src/libsystemd-network/dhcp6-option.c \
systemd/src/libsystemd-network/dhcp6-protocol.h \
systemd/src/libsystemd-network/lldp-internal.c \
systemd/src/libsystemd-network/lldp-internal.h \
systemd/src/libsystemd-network/lldp-neighbor.c \
systemd/src/libsystemd-network/lldp-neighbor.h \
systemd/src/libsystemd-network/lldp-network.c \
systemd/src/libsystemd-network/lldp-network.h \
systemd/src/libsystemd-network/lldp-port.c \
systemd/src/libsystemd-network/lldp-port.h \
systemd/src/libsystemd-network/lldp-tlv.c \
systemd/src/libsystemd-network/lldp-tlv.h \
systemd/src/libsystemd-network/lldp.h \
systemd/src/libsystemd-network/network-internal.c \
systemd/src/libsystemd-network/network-internal.h \
......
......@@ -1235,8 +1235,7 @@ update_dynamic_ip_setup (NMDevice *self)
nm_lldp_listener_stop (priv->lldp_listener);
addr = nm_platform_link_get_address (NM_PLATFORM_GET, priv->ifindex, &addr_length);
if (!nm_lldp_listener_start (priv->lldp_listener, nm_device_get_ifindex (self),
nm_device_get_iface (self), addr, addr_length, &error)) {
if (!nm_lldp_listener_start (priv->lldp_listener, nm_device_get_ifindex (self), &error)) {
_LOGD (LOGD_DEVICE, "LLDP listener %p could not be restarted: %s",
priv->lldp_listener, error->message);
g_clear_error (&error);
......@@ -3564,8 +3563,7 @@ activate_stage2_device_config (NMDevice *self)
addr = nm_platform_link_get_address (NM_PLATFORM_GET, priv->ifindex, &addr_length);
if (nm_lldp_listener_start (priv->lldp_listener, nm_device_get_ifindex (self),
nm_device_get_iface (self), addr, addr_length, &error))
if (nm_lldp_listener_start (priv->lldp_listener, nm_device_get_ifindex (self), &error))
_LOGD (LOGD_DEVICE, "LLDP listener %p started", priv->lldp_listener);
else {
_LOGD (LOGD_DEVICE, "LLDP listener %p could not be started: %s",
......
This diff is collapsed.
......@@ -42,8 +42,7 @@ typedef struct {
GType nm_lldp_listener_get_type (void);
NMLldpListener *nm_lldp_listener_new (void);
gboolean nm_lldp_listener_start (NMLldpListener *self, int ifindex, const char *iface,
const guint8 *mac, guint mac_len, GError **error);
gboolean nm_lldp_listener_start (NMLldpListener *self, int ifindex, GError **error);
void nm_lldp_listener_stop (NMLldpListener *self);
gboolean nm_lldp_listener_is_running (NMLldpListener *self);
......
......@@ -330,9 +330,6 @@ _test_recv_data2_ttl1_check (GMainLoop *loop, NMLldpListener *listener)
_test_recv_data0_check (loop, listener);
g_test_skip ("the test is known to fail");
return;
/* wait for signal. */
notify_id = g_signal_connect (listener, "notify::" NM_LLDP_LISTENER_NEIGHBORS,
nmtst_main_loop_quit_on_notify, loop);
......@@ -396,10 +393,12 @@ test_recv (TestRecvFixture *fixture, gconstpointer user_data)
TestRecvCallbackInfo info = { };
gsize i_frames;
gulong notify_id;
GError *error = NULL;
listener = nm_lldp_listener_new ();
g_assert (listener != NULL);
g_assert (nm_lldp_listener_start (listener, fixture->ifindex, TEST_IFNAME, fixture->mac, ETH_ALEN, NULL));
g_assert (nm_lldp_listener_start (listener, fixture->ifindex, &error));
g_assert_no_error (error);
notify_id = g_signal_connect (listener, "notify::" NM_LLDP_LISTENER_NEIGHBORS,
(GCallback) lldp_neighbors_changed, &info);
......
......@@ -61,6 +61,20 @@ sd_event_source_set_priority (sd_event_source *s, int64_t priority)
return 0;
}
int
sd_event_source_set_enabled (sd_event_source *s, int m)
{
/* TODO */
g_return_val_if_reached (-EINVAL);
}
int
sd_event_source_set_time (sd_event_source *s, uint64_t usec)
{
/* TODO */
g_return_val_if_reached (-EINVAL);
}
sd_event_source*
sd_event_source_unref (sd_event_source *s)
{
......
......@@ -102,6 +102,7 @@ G_STMT_START { \
#endif
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/ioctl.h>
#include <net/if_arp.h>
......@@ -110,6 +111,10 @@ G_STMT_START { \
#define BPF_XOR 0xa0
#endif
#ifndef ETHERTYPE_LLDP
#define ETHERTYPE_LLDP 0x88cc
#endif
/*****************************************************************************/
/* work around missing uchar.h */
......
......@@ -51,25 +51,29 @@ static inline void freep(void *p) {
#define _cleanup_free_ _cleanup_(freep)
_malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t a, size_t b) {
if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
static inline bool size_multiply_overflow(size_t size, size_t need) {
return _unlikely_(need != 0 && size > (SIZE_MAX / need));
}
_malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t size, size_t need) {
if (size_multiply_overflow(size, need))
return NULL;
return malloc(a * b);
return malloc(size * need);
}
_alloc_(2, 3) static inline void *realloc_multiply(void *p, size_t a, size_t b) {
if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
_alloc_(2, 3) static inline void *realloc_multiply(void *p, size_t size, size_t need) {
if (size_multiply_overflow(size, need))
return NULL;
return realloc(p, a * b);
return realloc(p, size * need);
}
_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t a, size_t b) {
if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t size, size_t need) {
if (size_multiply_overflow(size, need))
return NULL;
return memdup(p, a * b);
return memdup(p, size * need);
}
void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size);
......
......@@ -415,6 +415,34 @@ char *xescape(const char *s, const char *bad) {
return r;
}
char *octescape(const char *s, size_t len) {
char *r, *t;
const char *f;
/* Escapes all chars in bad, in addition to \ and " chars,
* in \nnn style escaping. */
r = new(char, len * 4 + 1);
if (!r)
return NULL;
for (f = s, t = r; f < s + len; f++) {
if (*f < ' ' || *f >= 127 || *f == '\\' || *f == '"') {
*(t++) = '\\';
*(t++) = '0' + (*f >> 6);
*(t++) = '0' + ((*f >> 3) & 8);
*(t++) = '0' + (*f & 8);
} else
*(t++) = *f;
}
*t = 0;
return r;
}
static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad) {
assert(bad);
......
......@@ -52,6 +52,7 @@ int cunescape_length_with_prefix(const char *s, size_t length, const char *prefi
int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit);
char *xescape(const char *s, const char *bad);
char *octescape(const char *s, size_t len);
char *shell_escape(const char *s, const char *bad);
char *shell_maybe_quote(const char *s);
/***
This file is part of systemd.
Copyright 2014 Tom Gundersen
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 "nm-sd-adapt.h"
#include <net/ethernet.h>
#include <stdio.h>
#include <sys/types.h>
#include "ether-addr-util.h"
#include "macro.h"
char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]) {
assert(addr);
assert(buffer);
/* Like ether_ntoa() but uses %02x instead of %x to print
* ethernet addresses, which makes them look less funny. Also,
* doesn't use a static buffer. */
sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x",
addr->ether_addr_octet[0],
addr->ether_addr_octet[1],
addr->ether_addr_octet[2],
addr->ether_addr_octet[3],
addr->ether_addr_octet[4],
addr->ether_addr_octet[5]);
return buffer;
}
bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b) {
assert(a);
assert(b);
return a->ether_addr_octet[0] == b->ether_addr_octet[0] &&
a->ether_addr_octet[1] == b->ether_addr_octet[1] &&
a->ether_addr_octet[2] == b->ether_addr_octet[2] &&
a->ether_addr_octet[3] == b->ether_addr_octet[3] &&
a->ether_addr_octet[4] == b->ether_addr_octet[4] &&
a->ether_addr_octet[5] == b->ether_addr_octet[5];
}
#pragma once
/***
This file is part of systemd.
Copyright (C) 2014 Tom Gundersen
Copyright (C) 2014 Susant Sahani
Copyright 2014 Tom Gundersen
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
......@@ -18,52 +19,19 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#pragma once
#include <net/ethernet.h>
#include <stdbool.h>
#include "sd-event.h"
#include "sd-lldp.h"
#include "util.h"
typedef struct lldp_port lldp_port;
typedef enum LLDPPortStatus {
LLDP_PORT_STATUS_NONE,
LLDP_PORT_STATUS_ENABLED,
LLDP_PORT_STATUS_DISABLED,
_LLDP_PORT_STATUS_MAX,
_LLDP_PORT_STATUS_INVALID = -1,
} LLDPPortStatus;
struct lldp_port {
LLDPPortStatus status;
int ifindex;
char *ifname;
struct ether_addr mac;
int rawfd;
sd_event *event;
sd_event_source *lldp_port_rx;
int event_priority;
#define ETHER_ADDR_FORMAT_STR "%02X%02X%02X%02X%02X%02X"
#define ETHER_ADDR_FORMAT_VAL(x) (x).ether_addr_octet[0], (x).ether_addr_octet[1], (x).ether_addr_octet[2], (x).ether_addr_octet[3], (x).ether_addr_octet[4], (x).ether_addr_octet[5]
void *userdata;
};
#define ETHER_ADDR_TO_STRING_MAX (3*6)
char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]);
int lldp_port_new(int ifindex,
const char *ifname,
const struct ether_addr *addr,
void *userdata,
lldp_port **ret);
void lldp_port_free(lldp_port *p);
bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b);
DEFINE_TRIVIAL_CLEANUP_FUNC(lldp_port*, lldp_port_free);
#define _cleanup_lldp_port_free_ _cleanup_(lldp_port_freep)
#define ETHER_ADDR_NULL ((const struct ether_addr){})
int lldp_port_start(lldp_port *p);
int lldp_port_stop(lldp_port *p);
static inline bool ether_addr_is_null(const struct ether_addr *addr) {
return ether_addr_equal(addr, &ETHER_ADDR_NULL);
}
......@@ -42,9 +42,7 @@
#include "parse-util.h"
#include "path-util.h"
#include "random-util.h"
#if 0 /* NM_IGNORED */
#include "stdio-util.h"
#endif /* NM_IGNORED */
#include "string-util.h"
#include "strv.h"
#include "time-util.h"
......@@ -356,7 +354,7 @@ static int parse_env_file_internal(
case KEY:
if (strchr(newline, c)) {
state = PRE_KEY;
line ++;
line++;
n_key = 0;
} else if (c == '=') {
state = PRE_VALUE;
......@@ -380,7 +378,7 @@ static int parse_env_file_internal(
case PRE_VALUE:
if (strchr(newline, c)) {
state = PRE_KEY;
line ++;
line++;
key[n_key] = 0;
if (value)
......@@ -420,7 +418,7 @@ static int parse_env_file_internal(
case VALUE:
if (strchr(newline, c)) {
state = PRE_KEY;
line ++;
line++;
key[n_key] = 0;
......@@ -539,7 +537,7 @@ static int parse_env_file_internal(
state = COMMENT_ESCAPE;
else if (strchr(newline, c)) {
state = PRE_KEY;
line ++;
line++;
}
break;
......@@ -912,7 +910,7 @@ int get_proc_field(const char *filename, const char *pattern, const char *termin
/* Back off one char if there's nothing but whitespace
and zeros */
if (!*t || isspace(*t))
t --;
t--;
}
len = strcspn(t, terminator);
......
......@@ -291,24 +291,6 @@ int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
return 0;
}
int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
assert(fd >= 0);
/* Under the assumption that we are running privileged we
* first change the access mode and only then hand out
* ownership to avoid a window where access is too open. */
if (mode != MODE_INVALID)
if (fchmod(fd, mode) < 0)
return -errno;
if (uid != UID_INVALID || gid != GID_INVALID)
if (fchown(fd, uid, gid) < 0)
return -errno;
return 0;
}
#endif /* NM_IGNORED */
int fchmod_umask(int fd, mode_t m) {
......
......@@ -43,7 +43,6 @@ int readlink_and_canonicalize(const char *p, char **r);
int readlink_and_make_absolute_root(const char *root, const char *path, char **ret);
int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid);
int fchmod_umask(int fd, mode_t mode);
......
......@@ -180,7 +180,7 @@ enum HashmapType {
};
struct _packed_ indirect_storage {
char *storage; /* where buckets and DIBs are stored */
void *storage; /* where buckets and DIBs are stored */
uint8_t hash_key[HASH_KEY_SIZE]; /* hash key; changes during resize */
unsigned n_entries; /* number of stored entries */
......@@ -197,7 +197,7 @@ struct direct_storage {
/* This gives us 39 bytes on 64bit, or 35 bytes on 32bit.
* That's room for 4 set_entries + 4 DIB bytes + 3 unused bytes on 64bit,
* or 7 set_entries + 7 DIB bytes + 0 unused bytes on 32bit. */
char storage[sizeof(struct indirect_storage)];
uint8_t storage[sizeof(struct indirect_storage)];
};
#define DIRECT_BUCKETS(entry_t) \
......@@ -306,7 +306,7 @@ static void n_entries_dec(HashmapBase *h) {
h->n_direct_entries--;
}
static char *storage_ptr(HashmapBase *h) {
static void *storage_ptr(HashmapBase *h) {
return h->has_indirect ? h->indirect.storage
: h->direct.storage;
}
......@@ -351,7 +351,7 @@ static void get_hash_key(uint8_t hash_key[HASH_KEY_SIZE], bool reuse_is_ok) {
static struct hashmap_base_entry *bucket_at(HashmapBase *h, unsigned idx) {
return (struct hashmap_base_entry*)
(storage_ptr(h) + idx * hashmap_type_info[h->type].entry_size);
((uint8_t*) storage_ptr(h) + idx * hashmap_type_info[h->type].entry_size);
}
static struct plain_hashmap_entry *plain_bucket_at(Hashmap *h, unsigned idx) {
......@@ -385,7 +385,7 @@ static struct hashmap_base_entry *bucket_at_virtual(HashmapBase *h, struct swap_
static dib_raw_t *dib_raw_ptr(HashmapBase *h) {
return (dib_raw_t*)
(storage_ptr(h) + hashmap_type_info[h->type].entry_size * n_buckets(h));
((uint8_t*) storage_ptr(h) + hashmap_type_info[h->type].entry_size * n_buckets(h));
}
static unsigned bucket_distance(HashmapBase *h, unsigned idx, unsigned from) {
......@@ -1032,7 +1032,7 @@ static int hashmap_base_put_boldly(HashmapBase *h, unsigned idx,
*/
static int resize_buckets(HashmapBase *h, unsigned entries_add) {
struct swap_entries swap;
char *new_storage;
void *new_storage;
dib_raw_t *old_dibs, *new_dibs;
const struct hashmap_type_info *hi;
unsigned idx, optimal_idx;
......@@ -1099,7 +1099,7 @@ static int resize_buckets(HashmapBase *h, unsigned entries_add) {
h->indirect.n_buckets = (1U << new_shift) /
(hi->entry_size + sizeof(dib_raw_t));
old_dibs = (dib_raw_t*)(new_storage + hi->entry_size * old_n_buckets);
old_dibs = (dib_raw_t*)((uint8_t*) new_storage + hi->entry_size * old_n_buckets);
new_dibs = dib_raw_ptr(h);
/*
......
......@@ -27,6 +27,7 @@
#include "alloc-util.h"
#include "hexdecoct.h"
#include "macro.h"
#include "util.h"
char octchar(int x) {
return '0' + (x & 7);
......@@ -277,8 +278,8 @@ int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_l
if (padding) {
/* strip the padding */
while (l > 0 && p[l - 1] == '=' && pad < 7) {
pad ++;
l --;
pad++;
l--;
}
}
......@@ -506,7 +507,7 @@ int unbase64char(char c) {
if (c == '+')
return offset;
offset ++;
offset++;
if (c == '/')
return offset;
......@@ -574,7 +575,7 @@ static int base64_append_width(char **prefix, int plen,
if (!t)
return -ENOMEM;
memcpy(t + plen, sep, slen);
memcpy_safe(t + plen, sep, slen);
for (line = 0, s = t + plen + slen, avail = len; line < lines; line++) {
int act = MIN(width, avail);
......@@ -622,9 +623,9 @@ int unbase64mem(const char *p, size_t l, void **mem, size_t *_len) {
/* strip the padding */
if (l > 0 && p[l - 1] == '=')
l --;
l--;
if (l > 0 && p[l - 1] == '=')
l --;
l--;
/* a group of four input bytes needs three output bytes, in case of
padding we need to add two or three extra bytes */
......
......@@ -19,7 +19,6 @@
#include "nm-sd-adapt.h"
#include <bits/local_lim.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
......@@ -51,6 +50,10 @@ bool hostname_is_set(void) {
char* gethostname_malloc(void) {
struct utsname u;
/* This call tries to return something useful, either the actual hostname
* or it makes something up. The only reason it might fail is OOM.
* It might even return "localhost" if that's set. */
assert_se(uname(&u) >= 0);
if (isempty(u.nodename) || streq(u.nodename, "(none)"))
......@@ -59,6 +62,31 @@ char* gethostname_malloc(void) {
return strdup(u.nodename);
}
int gethostname_strict(char **ret) {
struct utsname u;
char *k;
/* This call will rather fail than make up a name. It will not return "localhost" either. */
assert_se(uname(&u) >= 0);
if (isempty(u.nodename))
return -ENXIO;
if (streq(u.nodename, "(none)"))
return -ENXIO;
if (is_localhost(u.nodename))
return -ENXIO;
k = strdup(u.nodename);
if (!k)
return -ENOMEM;
*ret = k;
return 0;
}
static bool hostname_valid_char(char c) {
return
(c >= 'a' && c <= 'z') ||
......@@ -98,7 +126,7 @@ bool hostname_is_valid(const char *s, bool allow_trailing_dot) {
return false;
dot = true;
n_dots ++;
n_dots++;
} else {
if (!hostname_valid_char(*p))
return false;
......@@ -124,6 +152,8 @@ char* hostname_cleanup(char *s) {
assert(s);
strshorten(s, HOST_NAME_MAX);
for (p = s, d = s, dot = true; *p; p++) {
if (*p == '.') {
if (dot)
......@@ -143,8 +173,6 @@ char* hostname_cleanup(char *s) {
else
*d = 0;
strshorten(s, HOST_NAME_MAX);
return s;
}
......
......@@ -26,6 +26,7 @@
bool hostname_is_set(void);
char* gethostname_malloc(void);
int gethostname_strict(char **ret);
bool hostname_is_valid(const char *s, bool allow_trailing_dot) _pure_;
char* hostname_cleanup(char *s);
......
......@@ -251,7 +251,7 @@ ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
} else if (n > 0)
q += n;
else
q ++;
q++;
}
if (q > w) {
......
......@@ -46,7 +46,7 @@ ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length);
char *_s = (char *)(s); \
_i->iov_base = _s; \
_i->iov_len = strlen(_s); \
} while(false)
} while (false)
static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) {
unsigned j;
......
......@@ -32,7 +32,7 @@
#define LIST_HEAD_INIT(head) \
do { \
(head) = NULL; } \
while(false)
while (false)
/* Initialize a list item */
#define LIST_INIT(name,item) \
......@@ -40,7 +40,7 @@
typeof(*(item)) *_item = (item); \
assert(_item); \
_item->name##_prev = _item->name##_next = NULL; \
} while(false)
} while (false)
/* Prepend an item to the list */
#define LIST_PREPEND(name,head,item) \
......@@ -51,7 +51,7 @@
_item->name##_next->name##_prev = _item; \
_item->name##_prev = NULL; \
*_head = _item; \
} while(false)
} while (false)
/* Append an item to the list */
#define LIST_APPEND(name,head,item) \
......@@ -59,7 +59,7 @@
typeof(*(head)) *_tail; \
LIST_FIND_TAIL(name,head,_tail); \
LIST_INSERT_AFTER(name,head,_tail,item); \
} while(false)
} while (false)
/* Remove an item from the list */
#define LIST_REMOVE(name,head,item) \
......@@ -75,7 +75,7 @@
*_head = _item->name##_next; \
} \
_item->name##_next = _item->name##_prev = NULL; \
} while(false)
} while (false)
/* Find the head of the list */
#define LIST_FIND_HEAD(name,item,head) \
......@@ -119,7 +119,7 @@
_b->name##_prev = _a; \
_a->name##_next = _b; \
} \
} while(false)
} while (false)
/* Insert an item before another one (a = where, b = what) */
#define LIST_INSERT_BEFORE(name,head,a,b) \
......@@ -145,7 +145,7 @@
_b->name##_next = _a; \
_a->name##_prev = _b; \
} \
} while(false)
} while (false)
#define LIST_JUST_US(name,item) \