* [PATCH 2/4] useful: Add a cleanup handler for fd variables
2022-07-01 13:32 [PATCH 1/4] dhcp: Set lease->bound_time before emitting event Andrew Zaborowski
@ 2022-07-01 13:32 ` Andrew Zaborowski
2022-07-01 13:32 ` [PATCH 3/4] netconfig: Restore net.ipv6.conf...disable_ipv6 on stop Andrew Zaborowski
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Andrew Zaborowski @ 2022-07-01 13:32 UTC (permalink / raw)
To: ell
Allow declaring an fd variable with a simple
_auto_(close) int fd = -1;
to be able to skip the close() call. This is useful for very simple
file accesses where it's not worth using l_io with
l_io_set_close_on_destroy.
As an example, update netconfig_proc_write_ipv6_setting to use
_auto_(close) where it helps in returning the errno from the read() call
(on error) which would otherwise be clobbered by the close() call.
---
ell/netconfig.c | 5 ++---
ell/useful.h | 14 ++++++++++++++
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/ell/netconfig.c b/ell/netconfig.c
index d4487bd..19aaf56 100644
--- a/ell/netconfig.c
+++ b/ell/netconfig.c
@@ -968,7 +968,7 @@ static int netconfig_proc_write_ipv6_setting(struct l_netconfig *nc,
{
char ifname[IF_NAMESIZE];
_auto_(l_free) char *filename = NULL;
- int fd;
+ _auto_(close) int fd = -1;
int r;
if (unlikely(!if_indextoname(nc->ifindex, ifname)))
@@ -982,8 +982,7 @@ static int netconfig_proc_write_ipv6_setting(struct l_netconfig *nc,
return -errno;
r = L_TFR(write(fd, value, strlen(value)));
- L_TFR(close(fd));
- return r;
+ return r > 0 ? 0 : -errno;
}
LIB_EXPORT struct l_netconfig *l_netconfig_new(uint32_t ifindex)
diff --git a/ell/useful.h b/ell/useful.h
index 4c8b23e..791fa20 100644
--- a/ell/useful.h
+++ b/ell/useful.h
@@ -20,6 +20,11 @@
*
*/
+#include <unistd.h>
+#include <errno.h>
+
+#include <ell/util.h>
+
#define align_len(len, boundary) (((len)+(boundary)-1) & ~((boundary)-1))
#define likely(x) __builtin_expect(!!(x), 1)
@@ -65,6 +70,15 @@ static inline unsigned char bit_field(const unsigned char oct,
#define _auto_(func) \
__AUTODESTRUCT(func)
+/* Enables declaring _auto_(close) int fd = <-1 or L_TFR(open(...))>; */
+inline __attribute__((always_inline)) void close_cleanup(void *p)
+{
+ int fd = *(int *) p;
+
+ if (fd >= 0)
+ L_TFR(close(fd));
+}
+
/*
* Trick the compiler into thinking that var might be changed somehow by
* the asm
--
2.34.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/4] netconfig: Restore net.ipv6.conf...disable_ipv6 on stop
2022-07-01 13:32 [PATCH 1/4] dhcp: Set lease->bound_time before emitting event Andrew Zaborowski
2022-07-01 13:32 ` [PATCH 2/4] useful: Add a cleanup handler for fd variables Andrew Zaborowski
@ 2022-07-01 13:32 ` Andrew Zaborowski
2022-07-01 13:32 ` [PATCH 4/4] netconfig: Fix leaking domain name string Andrew Zaborowski
2022-07-01 15:11 ` [PATCH 1/4] dhcp: Set lease->bound_time before emitting event Denis Kenzior
3 siblings, 0 replies; 5+ messages in thread
From: Andrew Zaborowski @ 2022-07-01 13:32 UTC (permalink / raw)
To: ell
Since we write the net.ipv6.conf.<ifname>.disable_ipv6 option to 0 when
enabling DHCPv6, reset it to its original value when stopping netconfig.
---
ell/netconfig.c | 69 ++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 59 insertions(+), 10 deletions(-)
diff --git a/ell/netconfig.c b/ell/netconfig.c
index 19aaf56..f48018b 100644
--- a/ell/netconfig.c
+++ b/ell/netconfig.c
@@ -35,6 +35,8 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
#include "private.h"
#include "useful.h"
@@ -83,6 +85,7 @@ struct l_netconfig {
unsigned int ifaddr6_dump_cmd_id;
struct l_queue *icmp_route_data;
struct l_acd *acd;
+ unsigned int orig_disable_ipv6;
/* These objects, if not NULL, are owned by @addresses and @routes */
struct l_rtnl_address *v4_address;
@@ -962,14 +965,15 @@ static void netconfig_icmp6_event_handler(struct l_icmp6_client *client,
netconfig_emit_event(nc, AF_INET6, L_NETCONFIG_EVENT_UPDATE);
}
-static int netconfig_proc_write_ipv6_setting(struct l_netconfig *nc,
- const char *setting,
- const char *value)
+static int netconfig_proc_write_ipv6_uint_setting(struct l_netconfig *nc,
+ const char *setting,
+ unsigned int value)
{
char ifname[IF_NAMESIZE];
_auto_(l_free) char *filename = NULL;
_auto_(close) int fd = -1;
int r;
+ char valuestr[20];
if (unlikely(!if_indextoname(nc->ifindex, ifname)))
return -errno;
@@ -981,10 +985,46 @@ static int netconfig_proc_write_ipv6_setting(struct l_netconfig *nc,
if (unlikely(fd < 0))
return -errno;
- r = L_TFR(write(fd, value, strlen(value)));
+ snprintf(valuestr, sizeof(valuestr), "%u", value);
+ r = L_TFR(write(fd, valuestr, strlen(valuestr)));
return r > 0 ? 0 : -errno;
}
+static long netconfig_proc_read_ipv6_uint_setting(struct l_netconfig *nc,
+ const char *setting)
+{
+ char ifname[IF_NAMESIZE];
+ _auto_(l_free) char *filename = NULL;
+ _auto_(close) int fd = -1;
+ int r;
+ char valuestr[20];
+ long value;
+ char *endp;
+
+ if (unlikely(!if_indextoname(nc->ifindex, ifname)))
+ return -errno;
+
+ filename = l_strdup_printf("/proc/sys/net/ipv6/conf/%s/%s",
+ ifname, setting);
+
+ fd = L_TFR(open(filename, O_RDONLY));
+ if (unlikely(fd < 0))
+ return -errno;
+
+ r = L_TFR(read(fd, valuestr, sizeof(valuestr) - 1));
+ if (unlikely(r < 1))
+ return r == 0 ? -EINVAL : -errno;
+
+ valuestr[r - 1] = '\0';
+ errno = 0;
+ value = strtoul(valuestr, &endp, 10);
+
+ if (unlikely(errno || !L_IN_SET(*endp, '\n', '\0')))
+ return -EINVAL;
+
+ return value;
+}
+
LIB_EXPORT struct l_netconfig *l_netconfig_new(uint32_t ifindex)
{
struct l_netconfig *nc;
@@ -1019,7 +1059,7 @@ LIB_EXPORT struct l_netconfig *l_netconfig_new(uint32_t ifindex)
nc, NULL);
/* Disable in-kernel autoconfiguration for the interface */
- netconfig_proc_write_ipv6_setting(nc, "accept_ra", "0");
+ netconfig_proc_write_ipv6_uint_setting(nc, "accept_ra", 0);
return nc;
}
@@ -1554,13 +1594,15 @@ static void netconfig_ifaddr_ipv6_dump_done_cb(void *user_data)
nc->ifaddr6_dump_cmd_id = 0;
/* "do not generate a link-local address" */
- netconfig_proc_write_ipv6_setting(nc, "addr_gen_mode", "1");
+ netconfig_proc_write_ipv6_uint_setting(nc, "addr_gen_mode", 1);
/* "generate address based on EUI64 (default)" */
- netconfig_proc_write_ipv6_setting(nc, "addr_gen_mode", "0");
- /* "enable IPv6 operation" */
- netconfig_proc_write_ipv6_setting(nc, "disable_ipv6", "0");
+ netconfig_proc_write_ipv6_uint_setting(nc, "addr_gen_mode", 0);
- /* TODO: save original values and reset in l_netconfig_stop() */
+ /* "enable IPv6 operation" */
+ nc->orig_disable_ipv6 =
+ netconfig_proc_read_ipv6_uint_setting(nc, "disable_ipv6");
+ if (nc->orig_disable_ipv6)
+ netconfig_proc_write_ipv6_uint_setting(nc, "disable_ipv6", 0);
}
LIB_EXPORT bool l_netconfig_start(struct l_netconfig *netconfig)
@@ -1680,6 +1722,13 @@ LIB_EXPORT void l_netconfig_stop(struct l_netconfig *netconfig)
l_dhcp6_client_stop(netconfig->dhcp6_client);
l_acd_destroy(l_steal_ptr(netconfig->acd));
+
+ if (netconfig->orig_disable_ipv6) {
+ netconfig_proc_write_ipv6_uint_setting(netconfig,
+ "disable_ipv6",
+ netconfig->orig_disable_ipv6);
+ netconfig->orig_disable_ipv6 = 0;
+ }
}
LIB_EXPORT struct l_dhcp_client *l_netconfig_get_dhcp_client(
--
2.34.1
^ permalink raw reply related [flat|nested] 5+ messages in thread