mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-06 16:21:50 +00:00
systemd: merge branch systemd into master
This commit is contained in:
commit
fada1da80b
|
@ -1085,6 +1085,7 @@ src_libsystemd_nm_la_SOURCES = \
|
|||
src/systemd/sd-adapt/conf-parser.h \
|
||||
src/systemd/sd-adapt/def.h \
|
||||
src/systemd/sd-adapt/dirent-util.h \
|
||||
src/systemd/sd-adapt/env-util.h \
|
||||
src/systemd/sd-adapt/format-util.h \
|
||||
src/systemd/sd-adapt/gunicode.h \
|
||||
src/systemd/sd-adapt/khash.h \
|
||||
|
|
|
@ -62,6 +62,12 @@ AC_TYPE_PID_T
|
|||
AC_CHECK_SIZEOF(dev_t)
|
||||
AC_CHECK_SIZEOF(time_t)
|
||||
|
||||
AC_CHECK_DECLS([
|
||||
explicit_bzero],
|
||||
[], [], [[
|
||||
#include <string.h>
|
||||
]])
|
||||
|
||||
dnl
|
||||
dnl translation support
|
||||
dnl
|
||||
|
|
3
src/systemd/sd-adapt/env-util.h
Normal file
3
src/systemd/sd-adapt/env-util.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
/* dummy header */
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "alloc-util.h"
|
||||
#include "ctype.h"
|
||||
#include "env-util.h"
|
||||
#include "escape.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
|
@ -555,13 +556,14 @@ static int parse_env_file_internal(
|
|||
}
|
||||
}
|
||||
|
||||
if (state == PRE_VALUE ||
|
||||
state == VALUE ||
|
||||
state == VALUE_ESCAPE ||
|
||||
state == SINGLE_QUOTE_VALUE ||
|
||||
state == SINGLE_QUOTE_VALUE_ESCAPE ||
|
||||
state == DOUBLE_QUOTE_VALUE ||
|
||||
state == DOUBLE_QUOTE_VALUE_ESCAPE) {
|
||||
if (IN_SET(state,
|
||||
PRE_VALUE,
|
||||
VALUE,
|
||||
VALUE_ESCAPE,
|
||||
SINGLE_QUOTE_VALUE,
|
||||
SINGLE_QUOTE_VALUE_ESCAPE,
|
||||
DOUBLE_QUOTE_VALUE,
|
||||
DOUBLE_QUOTE_VALUE_ESCAPE)) {
|
||||
|
||||
key[n_key] = 0;
|
||||
|
||||
|
@ -588,14 +590,9 @@ fail:
|
|||
return r;
|
||||
}
|
||||
|
||||
static int parse_env_file_push(
|
||||
static int check_utf8ness_and_warn(
|
||||
const char *filename, unsigned line,
|
||||
const char *key, char *value,
|
||||
void *userdata,
|
||||
int *n_pushed) {
|
||||
|
||||
const char *k;
|
||||
va_list aq, *ap = userdata;
|
||||
const char *key, char *value) {
|
||||
|
||||
if (!utf8_is_valid(key)) {
|
||||
_cleanup_free_ char *p = NULL;
|
||||
|
@ -613,6 +610,23 @@ static int parse_env_file_push(
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_env_file_push(
|
||||
const char *filename, unsigned line,
|
||||
const char *key, char *value,
|
||||
void *userdata,
|
||||
int *n_pushed) {
|
||||
|
||||
const char *k;
|
||||
va_list aq, *ap = userdata;
|
||||
int r;
|
||||
|
||||
r = check_utf8ness_and_warn(filename, line, key, value);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
va_copy(aq, *ap);
|
||||
|
||||
while ((k = va_arg(aq, const char *))) {
|
||||
|
@ -655,6 +669,7 @@ int parse_env_file(
|
|||
return r < 0 ? r : n_pushed;
|
||||
}
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
static int load_env_file_push(
|
||||
const char *filename, unsigned line,
|
||||
const char *key, char *value,
|
||||
|
@ -664,27 +679,19 @@ static int load_env_file_push(
|
|||
char *p;
|
||||
int r;
|
||||
|
||||
if (!utf8_is_valid(key)) {
|
||||
_cleanup_free_ char *t = utf8_escape_invalid(key);
|
||||
r = check_utf8ness_and_warn(filename, line, key, value);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
log_error("%s:%u: invalid UTF-8 for key '%s', ignoring.", strna(filename), line, t);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (value && !utf8_is_valid(value)) {
|
||||
_cleanup_free_ char *t = utf8_escape_invalid(value);
|
||||
|
||||
log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.", strna(filename), line, key, t);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
p = strjoin(key, "=", strempty(value));
|
||||
p = strjoin(key, "=", value);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
r = strv_consume(m, p);
|
||||
if (r < 0)
|
||||
r = strv_env_replace(m, p);
|
||||
if (r < 0) {
|
||||
free(p);
|
||||
return r;
|
||||
}
|
||||
|
||||
if (n_pushed)
|
||||
(*n_pushed)++;
|
||||
|
@ -718,19 +725,9 @@ static int load_env_file_push_pairs(
|
|||
char ***m = userdata;
|
||||
int r;
|
||||
|
||||
if (!utf8_is_valid(key)) {
|
||||
_cleanup_free_ char *t = utf8_escape_invalid(key);
|
||||
|
||||
log_error("%s:%u: invalid UTF-8 for key '%s', ignoring.", strna(filename), line, t);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (value && !utf8_is_valid(value)) {
|
||||
_cleanup_free_ char *t = utf8_escape_invalid(value);
|
||||
|
||||
log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.", strna(filename), line, key, t);
|
||||
return -EINVAL;
|
||||
}
|
||||
r = check_utf8ness_and_warn(filename, line, key, value);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = strv_extend(m, key);
|
||||
if (r < 0)
|
||||
|
@ -769,6 +766,52 @@ int load_env_file_pairs(FILE *f, const char *fname, const char *newline, char **
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int merge_env_file_push(
|
||||
const char *filename, unsigned line,
|
||||
const char *key, char *value,
|
||||
void *userdata,
|
||||
int *n_pushed) {
|
||||
|
||||
char ***env = userdata;
|
||||
char *expanded_value;
|
||||
|
||||
assert(env);
|
||||
|
||||
if (!value) {
|
||||
log_error("%s:%u: invalid syntax (around \"%s\"), ignoring.", strna(filename), line, key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!env_name_is_valid(key)) {
|
||||
log_error("%s:%u: invalid variable name \"%s\", ignoring.", strna(filename), line, key);
|
||||
free(value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
expanded_value = replace_env(value, *env,
|
||||
REPLACE_ENV_USE_ENVIRONMENT|
|
||||
REPLACE_ENV_ALLOW_BRACELESS|
|
||||
REPLACE_ENV_ALLOW_EXTENDED);
|
||||
if (!expanded_value)
|
||||
return -ENOMEM;
|
||||
|
||||
free_and_replace(value, expanded_value);
|
||||
|
||||
return load_env_file_push(filename, line, key, value, env, n_pushed);
|
||||
}
|
||||
|
||||
int merge_env_file(
|
||||
char ***env,
|
||||
FILE *f,
|
||||
const char *fname) {
|
||||
|
||||
/* NOTE: this function supports braceful and braceless variable expansions,
|
||||
* plus "extended" substitutions, unlike other exported parsing functions.
|
||||
*/
|
||||
|
||||
return parse_env_file_internal(f, fname, NEWLINE, merge_env_file_push, env, NULL);
|
||||
}
|
||||
|
||||
static void write_env_var(FILE *f, const char *v) {
|
||||
const char *p;
|
||||
|
||||
|
@ -828,6 +871,7 @@ int write_env_file(const char *fname, char **l) {
|
|||
unlink(p);
|
||||
return r;
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
||||
int executable_is_script(const char *path, char **interpreter) {
|
||||
int r;
|
||||
|
@ -1349,6 +1393,25 @@ int open_tmpfile_linkable(const char *target, int flags, char **ret_path) {
|
|||
return fd;
|
||||
}
|
||||
|
||||
int open_serialization_fd(const char *ident) {
|
||||
int fd = -1;
|
||||
|
||||
fd = memfd_create(ident, MFD_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
const char *path;
|
||||
|
||||
path = getpid() == 1 ? "/run/systemd" : "/tmp";
|
||||
fd = open_tmpfile_unlinkable(path, O_RDWR|O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
log_debug("Serializing %s to %s.", ident, path);
|
||||
} else
|
||||
log_debug("Serializing %s to memfd.", ident);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
int link_tmpfile(int fd, const char *path, const char *target) {
|
||||
|
||||
assert(fd >= 0);
|
||||
|
|
|
@ -48,6 +48,8 @@ int parse_env_file(const char *fname, const char *separator, ...) _sentinel_;
|
|||
int load_env_file(FILE *f, const char *fname, const char *separator, char ***l);
|
||||
int load_env_file_pairs(FILE *f, const char *fname, const char *separator, char ***l);
|
||||
|
||||
int merge_env_file(char ***env, FILE *f, const char *fname);
|
||||
|
||||
int write_env_file(const char *fname, char **l);
|
||||
|
||||
int executable_is_script(const char *path, char **interpreter);
|
||||
|
@ -84,6 +86,7 @@ int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space)
|
|||
|
||||
int open_tmpfile_unlinkable(const char *directory, int flags);
|
||||
int open_tmpfile_linkable(const char *target, int flags, char **ret_path);
|
||||
int open_serialization_fd(const char *ident);
|
||||
|
||||
int link_tmpfile(int fd, const char *path, const char *target);
|
||||
|
||||
|
|
|
@ -91,3 +91,9 @@ static inline void rmdir_and_free(char *p) {
|
|||
free(p);
|
||||
}
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(char*, rmdir_and_free);
|
||||
|
||||
static inline void unlink_and_free(char *p) {
|
||||
(void) unlink(p);
|
||||
free(p);
|
||||
}
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(char*, unlink_and_free);
|
||||
|
|
|
@ -47,6 +47,7 @@ bool hostname_is_set(void) {
|
|||
return true;
|
||||
}
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
char* gethostname_malloc(void) {
|
||||
struct utsname u;
|
||||
|
||||
|
@ -57,10 +58,11 @@ char* gethostname_malloc(void) {
|
|||
assert_se(uname(&u) >= 0);
|
||||
|
||||
if (isempty(u.nodename) || streq(u.nodename, "(none)"))
|
||||
return strdup(u.sysname);
|
||||
return strdup(FALLBACK_HOSTNAME);
|
||||
|
||||
return strdup(u.nodename);
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
||||
int gethostname_strict(char **ret) {
|
||||
struct utsname u;
|
||||
|
|
|
@ -68,6 +68,18 @@ int in_addr_is_link_local(int family, const union in_addr_union *u) {
|
|||
return -EAFNOSUPPORT;
|
||||
}
|
||||
|
||||
int in_addr_is_multicast(int family, const union in_addr_union *u) {
|
||||
assert(u);
|
||||
|
||||
if (family == AF_INET)
|
||||
return IN_MULTICAST(be32toh(u->in.s_addr));
|
||||
|
||||
if (family == AF_INET6)
|
||||
return IN6_IS_ADDR_MULTICAST(&u->in6);
|
||||
|
||||
return -EAFNOSUPPORT;
|
||||
}
|
||||
|
||||
bool in4_addr_is_localhost(const struct in_addr *a) {
|
||||
assert(a);
|
||||
|
||||
|
|
|
@ -39,6 +39,8 @@ struct in_addr_data {
|
|||
bool in4_addr_is_null(const struct in_addr *a);
|
||||
int in_addr_is_null(int family, const union in_addr_union *u);
|
||||
|
||||
int in_addr_is_multicast(int family, const union in_addr_union *u);
|
||||
|
||||
bool in4_addr_is_link_local(const struct in_addr *a);
|
||||
int in_addr_is_link_local(int family, const union in_addr_union *u);
|
||||
|
||||
|
|
|
@ -216,13 +216,13 @@ bool log_on_console(void) _pure_;
|
|||
const char *log_target_to_string(LogTarget target) _const_;
|
||||
LogTarget log_target_from_string(const char *s) _pure_;
|
||||
|
||||
/* Helpers to prepare various fields for structured logging */
|
||||
/* Helper to prepare various field for structured logging */
|
||||
#define LOG_MESSAGE(fmt, ...) "MESSAGE=" fmt, ##__VA_ARGS__
|
||||
#define LOG_MESSAGE_ID(x) "MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(x)
|
||||
|
||||
void log_received_signal(int level, const struct signalfd_siginfo *si);
|
||||
|
||||
void log_set_upgrade_syslog_to_journal(bool b);
|
||||
void log_set_always_reopen_console(bool b);
|
||||
|
||||
int log_syntax_internal(
|
||||
const char *unit,
|
||||
|
|
|
@ -903,6 +903,26 @@ bool ifname_valid(const char *p) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool address_label_valid(const char *p) {
|
||||
|
||||
if (isempty(p))
|
||||
return false;
|
||||
|
||||
if (strlen(p) >= IFNAMSIZ)
|
||||
return false;
|
||||
|
||||
while (*p) {
|
||||
if ((uint8_t) *p >= 127U)
|
||||
return false;
|
||||
|
||||
if ((uint8_t) *p <= 31U)
|
||||
return false;
|
||||
p++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int getpeercred(int fd, struct ucred *ucred) {
|
||||
socklen_t n = sizeof(struct ucred);
|
||||
struct ucred u;
|
||||
|
|
|
@ -128,6 +128,7 @@ int ip_tos_to_string_alloc(int i, char **s);
|
|||
int ip_tos_from_string(const char *s);
|
||||
|
||||
bool ifname_valid(const char *p);
|
||||
bool address_label_valid(const char *p);
|
||||
|
||||
int getpeercred(int fd, struct ucred *ucred);
|
||||
int getpeersec(int fd, char **ret);
|
||||
|
|
|
@ -825,6 +825,7 @@ int free_and_strdup(char **p, const char *s) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
#if !HAVE_DECL_EXPLICIT_BZERO
|
||||
/*
|
||||
* Pointer to memset is volatile so that compiler must de-reference
|
||||
* the pointer and can't assume that it points to any function in
|
||||
|
@ -835,19 +836,19 @@ typedef void *(*memset_t)(void *,int,size_t);
|
|||
|
||||
static volatile memset_t memset_func = memset;
|
||||
|
||||
void* memory_erase(void *p, size_t l) {
|
||||
return memset_func(p, 'x', l);
|
||||
void explicit_bzero(void *p, size_t l) {
|
||||
memset_func(p, '\0', l);
|
||||
}
|
||||
#endif
|
||||
|
||||
char* string_erase(char *x) {
|
||||
|
||||
if (!x)
|
||||
return NULL;
|
||||
|
||||
/* A delicious drop of snake-oil! To be called on memory where
|
||||
* we stored passphrases or so, after we used them. */
|
||||
|
||||
return memory_erase(x, strlen(x));
|
||||
explicit_bzero(x, strlen(x));
|
||||
return x;
|
||||
}
|
||||
|
||||
char *string_free_erase(char *s) {
|
||||
|
|
|
@ -189,7 +189,10 @@ static inline void *memmem_safe(const void *haystack, size_t haystacklen, const
|
|||
return memmem(haystack, haystacklen, needle, needlelen);
|
||||
}
|
||||
|
||||
void* memory_erase(void *p, size_t l);
|
||||
#if !HAVE_DECL_EXPLICIT_BZERO
|
||||
void explicit_bzero(void *p, size_t l);
|
||||
#endif
|
||||
|
||||
char *string_erase(char *x);
|
||||
|
||||
char *string_free_erase(char *s);
|
||||
|
|
|
@ -61,9 +61,6 @@
|
|||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
/* Put this test here for a lack of better place */
|
||||
assert_cc(EAGAIN == EWOULDBLOCK);
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
int saved_argc = 0;
|
||||
char **saved_argv = NULL;
|
||||
|
@ -85,146 +82,6 @@ size_t page_size(void) {
|
|||
}
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
static int do_execute(char **directories, usec_t timeout, char *argv[]) {
|
||||
_cleanup_hashmap_free_free_ Hashmap *pids = NULL;
|
||||
_cleanup_set_free_free_ Set *seen = NULL;
|
||||
char **directory;
|
||||
|
||||
/* We fork this all off from a child process so that we can
|
||||
* somewhat cleanly make use of SIGALRM to set a time limit */
|
||||
|
||||
(void) reset_all_signal_handlers();
|
||||
(void) reset_signal_mask();
|
||||
|
||||
assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
|
||||
|
||||
pids = hashmap_new(NULL);
|
||||
if (!pids)
|
||||
return log_oom();
|
||||
|
||||
seen = set_new(&string_hash_ops);
|
||||
if (!seen)
|
||||
return log_oom();
|
||||
|
||||
STRV_FOREACH(directory, directories) {
|
||||
_cleanup_closedir_ DIR *d;
|
||||
struct dirent *de;
|
||||
|
||||
d = opendir(*directory);
|
||||
if (!d) {
|
||||
if (errno == ENOENT)
|
||||
continue;
|
||||
|
||||
return log_error_errno(errno, "Failed to open directory %s: %m", *directory);
|
||||
}
|
||||
|
||||
FOREACH_DIRENT(de, d, break) {
|
||||
_cleanup_free_ char *path = NULL;
|
||||
pid_t pid;
|
||||
int r;
|
||||
|
||||
if (!dirent_is_file(de))
|
||||
continue;
|
||||
|
||||
if (set_contains(seen, de->d_name)) {
|
||||
log_debug("%1$s/%2$s skipped (%2$s was already seen).", *directory, de->d_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
r = set_put_strdup(seen, de->d_name);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
path = strjoin(*directory, "/", de->d_name);
|
||||
if (!path)
|
||||
return log_oom();
|
||||
|
||||
if (null_or_empty_path(path)) {
|
||||
log_debug("%s is empty (a mask).", path);
|
||||
continue;
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
log_error_errno(errno, "Failed to fork: %m");
|
||||
continue;
|
||||
} else if (pid == 0) {
|
||||
char *_argv[2];
|
||||
|
||||
assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
|
||||
|
||||
if (!argv) {
|
||||
_argv[0] = path;
|
||||
_argv[1] = NULL;
|
||||
argv = _argv;
|
||||
} else
|
||||
argv[0] = path;
|
||||
|
||||
execv(path, argv);
|
||||
return log_error_errno(errno, "Failed to execute %s: %m", path);
|
||||
}
|
||||
|
||||
log_debug("Spawned %s as " PID_FMT ".", path, pid);
|
||||
|
||||
r = hashmap_put(pids, PID_TO_PTR(pid), path);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
path = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Abort execution of this process after the timout. We simply
|
||||
* rely on SIGALRM as default action terminating the process,
|
||||
* and turn on alarm(). */
|
||||
|
||||
if (timeout != USEC_INFINITY)
|
||||
alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
|
||||
|
||||
while (!hashmap_isempty(pids)) {
|
||||
_cleanup_free_ char *path = NULL;
|
||||
pid_t pid;
|
||||
|
||||
pid = PTR_TO_PID(hashmap_first_key(pids));
|
||||
assert(pid > 0);
|
||||
|
||||
path = hashmap_remove(pids, PID_TO_PTR(pid));
|
||||
assert(path);
|
||||
|
||||
wait_for_terminate_and_warn(path, pid, true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void execute_directories(const char* const* directories, usec_t timeout, char *argv[]) {
|
||||
pid_t executor_pid;
|
||||
int r;
|
||||
char *name;
|
||||
char **dirs = (char**) directories;
|
||||
|
||||
assert(!strv_isempty(dirs));
|
||||
|
||||
name = basename(dirs[0]);
|
||||
assert(!isempty(name));
|
||||
|
||||
/* Executes all binaries in the directories in parallel and waits
|
||||
* for them to finish. Optionally a timeout is applied. If a file
|
||||
* with the same name exists in more than one directory, the
|
||||
* earliest one wins. */
|
||||
|
||||
executor_pid = fork();
|
||||
if (executor_pid < 0) {
|
||||
log_error_errno(errno, "Failed to fork: %m");
|
||||
return;
|
||||
|
||||
} else if (executor_pid == 0) {
|
||||
r = do_execute(dirs, timeout, argv);
|
||||
_exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
wait_for_terminate_and_warn(name, executor_pid, true);
|
||||
}
|
||||
|
||||
bool plymouth_running(void) {
|
||||
return access("/run/plymouth/pid", F_OK) >= 0;
|
||||
}
|
||||
|
|
|
@ -65,8 +65,6 @@ static inline const char* enable_disable(bool b) {
|
|||
return b ? "enable" : "disable";
|
||||
}
|
||||
|
||||
void execute_directories(const char* const* directories, usec_t timeout, char *argv[]);
|
||||
|
||||
bool plymouth_running(void);
|
||||
|
||||
bool display_is_local(const char *display) _pure_;
|
||||
|
|
|
@ -60,7 +60,7 @@ int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_
|
|||
BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */
|
||||
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 1), /* A == 0 ? */
|
||||
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
|
||||
/* Sender Protocol Address or Target Protocol Address must be equal to the one we care about*/
|
||||
/* Sender Protocol Address or Target Protocol Address must be equal to the one we care about */
|
||||
BPF_STMT(BPF_LD + BPF_IMM, htobe32(address)), /* A <- clients IP */
|
||||
BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */
|
||||
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct ether_arp, arp_spa)), /* A <- SPA */
|
||||
|
|
|
@ -49,6 +49,13 @@ int lldp_network_bind_raw_socket(int ifindex) {
|
|||
.filter = (struct sock_filter*) filter,
|
||||
};
|
||||
|
||||
struct packet_mreq mreq = {
|
||||
.mr_ifindex = ifindex,
|
||||
.mr_type = PACKET_MR_MULTICAST,
|
||||
.mr_alen = ETH_ALEN,
|
||||
.mr_address = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x00 }
|
||||
};
|
||||
|
||||
union sockaddr_union saddrll = {
|
||||
.ll.sll_family = AF_PACKET,
|
||||
.ll.sll_ifindex = ifindex,
|
||||
|
@ -68,6 +75,20 @@ int lldp_network_bind_raw_socket(int ifindex) {
|
|||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
r = setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
mreq.mr_address[ETH_ALEN - 1] = 0x03;
|
||||
r = setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
mreq.mr_address[ETH_ALEN - 1] = 0x0E;
|
||||
r = setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
r = bind(fd, &saddrll.sa, sizeof(saddrll.ll));
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
|
|
@ -829,6 +829,15 @@ static int client_send_request(sd_dhcp_client *client) {
|
|||
return r;
|
||||
}
|
||||
|
||||
if (client->vendor_class_identifier) {
|
||||
r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
|
||||
SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER,
|
||||
strlen(client->vendor_class_identifier),
|
||||
client->vendor_class_identifier);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
|
||||
SD_DHCP_OPTION_END, 0, NULL);
|
||||
if (r < 0)
|
||||
|
|
|
@ -244,8 +244,6 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata)
|
|||
r = ipv4acd_set_next_wakeup(acd, RATE_LIMIT_INTERVAL_USEC, PROBE_WAIT_USEC);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
acd->n_conflict = 0;
|
||||
} else {
|
||||
r = ipv4acd_set_next_wakeup(acd, 0, PROBE_WAIT_USEC);
|
||||
if (r < 0)
|
||||
|
|
|
@ -732,7 +732,6 @@ static void event_unmask_signal_data(sd_event *e, struct signal_data *d, int sig
|
|||
|
||||
/* If all the mask is all-zero we can get rid of the structure */
|
||||
hashmap_remove(e->signal_data, &d->priority);
|
||||
assert(!d->current);
|
||||
safe_close(d->fd);
|
||||
free(d);
|
||||
return;
|
||||
|
|
|
@ -100,6 +100,9 @@ int sd_id128_get_invocation(sd_id128_t *ret);
|
|||
((x).bytes[15] & 15) >= 10 ? 'a' + ((x).bytes[15] & 15) - 10 : '0' + ((x).bytes[15] & 15), \
|
||||
0 })
|
||||
|
||||
#define SD_ID128_MAKE_STR(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) \
|
||||
#a #b #c #d #e #f #g #h #i #j #k #l #m #n #o #p
|
||||
|
||||
_sd_pure_ static __inline__ int sd_id128_equal(sd_id128_t a, sd_id128_t b) {
|
||||
return memcmp(&a, &b, 16) == 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue