dhcpcd: Add hooks

This commit is contained in:
Sebastian Huber 2018-05-02 09:01:32 +02:00
parent 8bd38d645c
commit b2eb48c23b
7 changed files with 118 additions and 6 deletions

View File

@ -1599,3 +1599,17 @@ main(int argc, char **argv)
eloop_start(&dhcpcd_sigset); eloop_start(&dhcpcd_sigset);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
#ifdef __rtems__
int
dhcpcd_script_runreason_do_nothing(const struct interface *ifp,
const char *reason)
{
return 0;
}
/*
* Do not pull in the script support if it is not used, e.g. no call to
* rtems_dhcpcd_add_hook() is present.
*/
__weak_reference(dhcpcd_script_runreason_do_nothing, dhcpcd_script_runreason);
#endif /* __rtems__ */

View File

@ -156,6 +156,7 @@ extern rtems_recursive_mutex dhcpcd_mutex;
#define print_string dhcpcd_print_string #define print_string dhcpcd_print_string
#define read_config dhcpcd_read_config #define read_config dhcpcd_read_config
#define read_lease dhcpcd_read_lease #define read_lease dhcpcd_read_lease
#define script_runreason dhcpcd_script_runreason
#define select_profile dhcpcd_select_profile #define select_profile dhcpcd_select_profile
#define set_cloexec dhcpcd_set_cloexec #define set_cloexec dhcpcd_set_cloexec
#define set_nonblock dhcpcd_set_nonblock #define set_nonblock dhcpcd_set_nonblock

View File

@ -51,7 +51,30 @@
#include "ipv6nd.h" #include "ipv6nd.h"
#include "net.h" #include "net.h"
#include "script.h" #include "script.h"
#ifdef __rtems__
#include <rtems/dhcpcd.h>
static SLIST_HEAD(, rtems_dhcpcd_hook) dhcpcd_hooks =
SLIST_HEAD_INITIALIZER(dhcpcd_hooks);
void
rtems_dhcpcd_add_hook(rtems_dhcpcd_hook *hook)
{
rtems_recursive_mutex_lock(&dhcpcd_mutex);
SLIST_INSERT_HEAD(&dhcpcd_hooks, hook, node);
rtems_recursive_mutex_unlock(&dhcpcd_mutex);
}
void
rtems_dhcpcd_remove_hook(rtems_dhcpcd_hook *hook)
{
rtems_recursive_mutex_lock(&dhcpcd_mutex);
SLIST_REMOVE(&dhcpcd_hooks, hook, rtems_dhcpcd_hook, node);
rtems_recursive_mutex_unlock(&dhcpcd_mutex);
}
#endif /* __rtems__ */
#ifndef __rtems__
#define DEFAULT_PATH "PATH=/usr/bin:/usr/sbin:/bin:/sbin" #define DEFAULT_PATH "PATH=/usr/bin:/usr/sbin:/bin:/sbin"
static const char * const if_params[] = { static const char * const if_params[] = {
@ -104,6 +127,7 @@ exec_script(char *const *argv, char *const *env)
} }
return pid; return pid;
} }
#endif /* __rtems__ */
#ifdef INET #ifdef INET
static char * static char *
@ -168,6 +192,7 @@ append_config(char ***env, ssize_t *len,
} }
#endif #endif
#ifndef __rtems__
static size_t static size_t
arraytostr(const char *const *argv, char **s) arraytostr(const char *const *argv, char **s)
{ {
@ -191,6 +216,7 @@ arraytostr(const char *const *argv, char **s)
} }
return len; return len;
} }
#endif /* __rtems__ */
static ssize_t static ssize_t
make_env(const struct interface *ifp, const char *reason, char ***argv) make_env(const struct interface *ifp, const char *reason, char ***argv)
@ -435,6 +461,7 @@ eexit:
return -1; return -1;
} }
#ifndef __rtems__
static int static int
send_interface1(int fd, const struct interface *iface, const char *reason) send_interface1(int fd, const struct interface *iface, const char *reason)
{ {
@ -507,29 +534,43 @@ send_interface(int fd, const struct interface *iface)
} }
return retval; return retval;
} }
#endif /* __rtems__ */
int int
script_runreason(const struct interface *ifp, const char *reason) script_runreason(const struct interface *ifp, const char *reason)
{ {
#ifndef __rtems__
char *const argv[2] = { UNCONST(ifp->options->script), NULL }; char *const argv[2] = { UNCONST(ifp->options->script), NULL };
#endif /* __rtems__ */
char **env = NULL, **ep; char **env = NULL, **ep;
#ifndef __rtems__
char *path, *bigenv; char *path, *bigenv;
ssize_t e, elen = 0; ssize_t e, elen = 0;
pid_t pid; pid_t pid;
#else /* __rtems__ */
ssize_t elen;
rtems_dhcpcd_hook *hook;
rtems_dhcpcd_hook *hook2;
#endif /* __rtems__ */
int status = 0; int status = 0;
#ifndef __rtems__
const struct fd_list *fd; const struct fd_list *fd;
struct iovec iov[2]; struct iovec iov[2];
#endif /* __rtems__ */
if (ifp->options->script == NULL || if (ifp->options->script == NULL ||
ifp->options->script[0] == '\0' || ifp->options->script[0] == '\0' ||
strcmp(ifp->options->script, "/dev/null") == 0) strcmp(ifp->options->script, "/dev/null") == 0)
return 0; return 0;
#ifndef __rtems__
syslog(LOG_DEBUG, "%s: executing `%s' %s", syslog(LOG_DEBUG, "%s: executing `%s' %s",
ifp->name, argv[0], reason); ifp->name, argv[0], reason);
#endif /* __rtems__ */
/* Make our env */ /* Make our env */
elen = make_env(ifp, reason, &env); elen = make_env(ifp, reason, &env);
#ifndef __rtems__
ep = realloc(env, sizeof(char *) * (elen + 2)); ep = realloc(env, sizeof(char *) * (elen + 2));
if (ep == NULL) { if (ep == NULL) {
elen = -1; elen = -1;
@ -596,6 +637,17 @@ script_runreason(const struct interface *ifp, const char *reason)
free(bigenv); free(bigenv);
out: out:
#else /* __rtems__ */
rtems_recursive_mutex_lock(&dhcpcd_mutex);
SLIST_FOREACH_SAFE(hook, &dhcpcd_hooks, node, hook2) {
syslog(LOG_DEBUG, "%s: executing `%s' %s", ifp->name,
hook->name, reason);
(*hook->handler)(hook, env);
}
rtems_recursive_mutex_unlock(&dhcpcd_mutex);
#endif /* __rtems__ */
/* Cleanup */ /* Cleanup */
ep = env; ep = env;
while (*ep) while (*ep)

View File

@ -33,16 +33,12 @@
void if_printoptions(void); void if_printoptions(void);
#ifndef __rtems__ #ifndef __rtems__
int send_interface(int, const struct interface *); int send_interface(int, const struct interface *);
int script_runreason(const struct interface *, const char *);
#else /* __rtems__ */ #else /* __rtems__ */
static inline int send_interface(int fd, const struct interface *iface) static inline int send_interface(int fd, const struct interface *iface)
{ {
return 0; return 0;
} }
static inline int script_runreason(const struct interface *ifp, const char *reason)
{
return 0;
}
#endif /* __rtems__ */ #endif /* __rtems__ */
int script_runreason(const struct interface *, const char *);
#endif #endif

View File

@ -4553,6 +4553,7 @@ class dhcpcd(builder.Module):
'dhcpcd/ipv6nd.c', 'dhcpcd/ipv6nd.c',
'dhcpcd/net.c', 'dhcpcd/net.c',
'dhcpcd/platform-bsd.c', 'dhcpcd/platform-bsd.c',
'dhcpcd/script.c',
'dhcpcd/compat/pselect.c', 'dhcpcd/compat/pselect.c',
'dhcpcd/crypt/hmac_md5.c', 'dhcpcd/crypt/hmac_md5.c',
], ],

View File

@ -40,6 +40,9 @@
#ifndef _RTEMS_DHCPCD_H_ #ifndef _RTEMS_DHCPCD_H_
#define _RTEMS_DHCPCD_H_ #define _RTEMS_DHCPCD_H_
#include <sys/cdefs.h>
#include <sys/queue.h>
#include <rtems.h> #include <rtems.h>
#ifdef __cplusplus #ifdef __cplusplus
@ -75,6 +78,29 @@ typedef struct rtems_dhcpcd_config {
*/ */
rtems_status_code rtems_dhcpcd_start(const rtems_dhcpcd_config *config); rtems_status_code rtems_dhcpcd_start(const rtems_dhcpcd_config *config);
typedef struct rtems_dhcpcd_hook {
SLIST_ENTRY(rtems_dhcpcd_hook) node;
const char *name;
void (*handler)(struct rtems_dhcpcd_hook *hook, char *const *env);
} rtems_dhcpcd_hook;
/**
* @brief Adds a DHCP client hook.
*
* The hook handler is invoked with an environment list (NULL terminated) of
* strings ('\0' terminated). Each string of the environment list has usually
* the format "key=value", e.g. "interface=eth0", "reason=BOUND".
*
* The hook handler are called by the DHCP client task. It is safe to
* add/remove hooks in the hook handler.
*/
void rtems_dhcpcd_add_hook(rtems_dhcpcd_hook *hook);
/**
* @brief Removes a DHCP client hook.
*/
void rtems_dhcpcd_remove_hook(rtems_dhcpcd_hook *hook);
/** @} */ /** @} */
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved. * Copyright (c) 2013, 2018 embedded brains GmbH. All rights reserved.
* *
* embedded brains GmbH * embedded brains GmbH
* Dornierstr. 4 * Dornierstr. 4
@ -30,14 +30,36 @@
*/ */
#include <assert.h> #include <assert.h>
#include <stdio.h>
#include <rtems.h> #include <rtems.h>
#include <rtems/dhcpcd.h>
#define TEST_NAME "LIBBSD DHCPCD 1" #define TEST_NAME "LIBBSD DHCPCD 1"
static void
dhcpcd_hook_handler(rtems_dhcpcd_hook *hook, char *const *env)
{
(void)hook;
while (*env != NULL) {
printf("%s\n", *env);
++env;
}
}
static rtems_dhcpcd_hook dhcpcd_hook = {
.name = "test",
.handler = dhcpcd_hook_handler
};
static void static void
test_main(void) test_main(void)
{ {
rtems_dhcpcd_add_hook(&dhcpcd_hook);
rtems_task_delete(RTEMS_SELF); rtems_task_delete(RTEMS_SELF);
assert(0); assert(0);
} }