From b2eb48c23b86cb61504bb0324a94ea11df5653e8 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 2 May 2018 09:01:32 +0200 Subject: dhcpcd: Add hooks --- dhcpcd/dhcpcd.c | 14 +++++++++++ dhcpcd/namespace.h | 1 + dhcpcd/script.c | 52 +++++++++++++++++++++++++++++++++++++++++ dhcpcd/script.h | 6 +---- libbsd.py | 1 + rtemsbsd/include/rtems/dhcpcd.h | 26 +++++++++++++++++++++ testsuite/dhcpcd01/test_main.c | 24 ++++++++++++++++++- 7 files changed, 118 insertions(+), 6 deletions(-) diff --git a/dhcpcd/dhcpcd.c b/dhcpcd/dhcpcd.c index 59562d63..fd6356de 100644 --- a/dhcpcd/dhcpcd.c +++ b/dhcpcd/dhcpcd.c @@ -1599,3 +1599,17 @@ main(int argc, char **argv) eloop_start(&dhcpcd_sigset); 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__ */ diff --git a/dhcpcd/namespace.h b/dhcpcd/namespace.h index efff909a..c9f5fb1f 100644 --- a/dhcpcd/namespace.h +++ b/dhcpcd/namespace.h @@ -156,6 +156,7 @@ extern rtems_recursive_mutex dhcpcd_mutex; #define print_string dhcpcd_print_string #define read_config dhcpcd_read_config #define read_lease dhcpcd_read_lease +#define script_runreason dhcpcd_script_runreason #define select_profile dhcpcd_select_profile #define set_cloexec dhcpcd_set_cloexec #define set_nonblock dhcpcd_set_nonblock diff --git a/dhcpcd/script.c b/dhcpcd/script.c index 2de1e634..3de8715e 100644 --- a/dhcpcd/script.c +++ b/dhcpcd/script.c @@ -51,7 +51,30 @@ #include "ipv6nd.h" #include "net.h" #include "script.h" +#ifdef __rtems__ +#include +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" static const char * const if_params[] = { @@ -104,6 +127,7 @@ exec_script(char *const *argv, char *const *env) } return pid; } +#endif /* __rtems__ */ #ifdef INET static char * @@ -168,6 +192,7 @@ append_config(char ***env, ssize_t *len, } #endif +#ifndef __rtems__ static size_t arraytostr(const char *const *argv, char **s) { @@ -191,6 +216,7 @@ arraytostr(const char *const *argv, char **s) } return len; } +#endif /* __rtems__ */ static ssize_t make_env(const struct interface *ifp, const char *reason, char ***argv) @@ -435,6 +461,7 @@ eexit: return -1; } +#ifndef __rtems__ static int 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; } +#endif /* __rtems__ */ int script_runreason(const struct interface *ifp, const char *reason) { +#ifndef __rtems__ char *const argv[2] = { UNCONST(ifp->options->script), NULL }; +#endif /* __rtems__ */ char **env = NULL, **ep; +#ifndef __rtems__ char *path, *bigenv; ssize_t e, elen = 0; pid_t pid; +#else /* __rtems__ */ + ssize_t elen; + rtems_dhcpcd_hook *hook; + rtems_dhcpcd_hook *hook2; +#endif /* __rtems__ */ int status = 0; +#ifndef __rtems__ const struct fd_list *fd; struct iovec iov[2]; +#endif /* __rtems__ */ if (ifp->options->script == NULL || ifp->options->script[0] == '\0' || strcmp(ifp->options->script, "/dev/null") == 0) return 0; +#ifndef __rtems__ syslog(LOG_DEBUG, "%s: executing `%s' %s", ifp->name, argv[0], reason); +#endif /* __rtems__ */ /* Make our env */ elen = make_env(ifp, reason, &env); +#ifndef __rtems__ ep = realloc(env, sizeof(char *) * (elen + 2)); if (ep == NULL) { elen = -1; @@ -596,6 +637,17 @@ script_runreason(const struct interface *ifp, const char *reason) free(bigenv); 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 */ ep = env; while (*ep) diff --git a/dhcpcd/script.h b/dhcpcd/script.h index dfd4a172..9c5fd4d4 100644 --- a/dhcpcd/script.h +++ b/dhcpcd/script.h @@ -33,16 +33,12 @@ void if_printoptions(void); #ifndef __rtems__ int send_interface(int, const struct interface *); -int script_runreason(const struct interface *, const char *); #else /* __rtems__ */ static inline int send_interface(int fd, const struct interface *iface) { return 0; } -static inline int script_runreason(const struct interface *ifp, const char *reason) -{ - return 0; -} #endif /* __rtems__ */ +int script_runreason(const struct interface *, const char *); #endif diff --git a/libbsd.py b/libbsd.py index dac1ece1..05e9dd51 100644 --- a/libbsd.py +++ b/libbsd.py @@ -4553,6 +4553,7 @@ class dhcpcd(builder.Module): 'dhcpcd/ipv6nd.c', 'dhcpcd/net.c', 'dhcpcd/platform-bsd.c', + 'dhcpcd/script.c', 'dhcpcd/compat/pselect.c', 'dhcpcd/crypt/hmac_md5.c', ], diff --git a/rtemsbsd/include/rtems/dhcpcd.h b/rtemsbsd/include/rtems/dhcpcd.h index 324c8a90..da4972d4 100644 --- a/rtemsbsd/include/rtems/dhcpcd.h +++ b/rtemsbsd/include/rtems/dhcpcd.h @@ -40,6 +40,9 @@ #ifndef _RTEMS_DHCPCD_H_ #define _RTEMS_DHCPCD_H_ +#include +#include + #include #ifdef __cplusplus @@ -75,6 +78,29 @@ typedef struct rtems_dhcpcd_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 diff --git a/testsuite/dhcpcd01/test_main.c b/testsuite/dhcpcd01/test_main.c index 181f92ae..358b4ac8 100644 --- a/testsuite/dhcpcd01/test_main.c +++ b/testsuite/dhcpcd01/test_main.c @@ -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 * Dornierstr. 4 @@ -30,14 +30,36 @@ */ #include +#include #include +#include #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 test_main(void) { + + rtems_dhcpcd_add_hook(&dhcpcd_hook); + rtems_task_delete(RTEMS_SELF); assert(0); } -- cgit v1.2.3