diff --git a/backport-add-IPV6_DROP_MEMBERSHIP-to-clean-up-resources-when-.patch b/backport-add-IPV6_DROP_MEMBERSHIP-to-clean-up-resources-when-.patch new file mode 100644 index 0000000..8c026c2 --- /dev/null +++ b/backport-add-IPV6_DROP_MEMBERSHIP-to-clean-up-resources-when-.patch @@ -0,0 +1,136 @@ +From 1c3030c8cee48ab52d988e8be4914a7804a5fbec Mon Sep 17 00:00:00 2001 +From: gaoxingwang +Date: Tue, 7 Jun 2022 10:43:13 +0800 +Subject: [PATCH 2/2] add IPV6_DROP_MEMBERSHIP to clean up resources when + reload or restart radvd + +Reference:https://github.com/radvd-project/radvd/commit/1c3030c8cee48ab52d988e8be4914a7804a5fbec +Conflict:NA + +--- + device-bsd44.c | 1 + + device-linux.c | 16 ++++++++++++++++ + interface.c | 6 ++++++ + radvd.c | 11 +++++++++++ + radvd.h | 2 ++ + 5 files changed, 36 insertions(+) + +diff --git a/device-bsd44.c b/device-bsd44.c +index fe411ba..68c1df1 100644 +--- a/device-bsd44.c ++++ b/device-bsd44.c +@@ -127,6 +127,7 @@ ret: + } + + int setup_allrouters_membership(int sock, struct Interface *iface) { return 0; } ++int cleanup_allrouters_membership(int sock, struct Interface *iface) { return 0; } + + int set_interface_linkmtu(const char *iface, uint32_t mtu) + { +diff --git a/device-linux.c b/device-linux.c +index 5874e5c..019c126 100644 +--- a/device-linux.c ++++ b/device-linux.c +@@ -185,6 +185,22 @@ int setup_allrouters_membership(int sock, struct Interface *iface) + return 0; + } + ++int cleanup_allrouters_membership(int sock, struct Interface *iface) ++{ ++ struct ipv6_mreq mreq; ++ ++ memset(&mreq, 0, sizeof(mreq)); ++ mreq.ipv6mr_interface = iface->props.if_index; ++ ++ /* ipv6-allrouters: ff02::2 */ ++ mreq.ipv6mr_multiaddr.s6_addr32[0] = htonl(0xFF020000); ++ mreq.ipv6mr_multiaddr.s6_addr32[3] = htonl(0x2); ++ ++ setsockopt(sock, SOL_IPV6, IPV6_DROP_MEMBERSHIP, &mreq, sizeof(mreq)); ++ ++ return 0; ++} ++ + uint32_t get_interface_linkmtu(const char *iface) + { + int value; +diff --git a/interface.c b/interface.c +index f5f9a54..222d1aa 100644 +--- a/interface.c ++++ b/interface.c +@@ -109,6 +109,12 @@ int setup_iface(int sock, struct Interface *iface) + return 0; + } + ++int cleanup_iface(int sock, struct Interface *iface) ++{ ++ /* leave the allrouters multicast group */ ++ cleanup_allrouters_membership(sock, iface); ++ return 0; ++} + void prefix_init_defaults(struct AdvPrefix *prefix) + { + memset(prefix, 0, sizeof(struct AdvPrefix)); +diff --git a/radvd.c b/radvd.c +index 22255b1..3bd3a06 100644 +--- a/radvd.c ++++ b/radvd.c +@@ -93,6 +93,7 @@ static void reset_prefix_lifetimes(struct Interface *ifaces); + static void reset_prefix_lifetimes_foo(struct Interface *iface, void *data); + static void setup_iface_foo(struct Interface *iface, void *data); + static void setup_ifaces(int sock, struct Interface *ifaces); ++static void cleanup_ifaces(int sock, struct Interface *ifaces); + static void sighup_handler(int sig); + static void sigint_handler(int sig); + static void sigterm_handler(int sig); +@@ -435,6 +436,8 @@ int main(int argc, char *argv[]) + setup_ifaces(sock, ifaces); + ifaces = main_loop(sock, ifaces, conf_path); + stop_adverts(sock, ifaces); ++ cleanup_ifaces(sock, ifaces); ++ close(sock); + + flog(LOG_INFO, "removing %s", daemon_pid_file_ident); + unlink(daemon_pid_file_ident); +@@ -778,10 +781,18 @@ static void setup_iface_foo(struct Interface *iface, void *data) + kickoff_adverts(sock, iface); + } + ++static void cleanup_iface_foo(struct Interface *iface, void *data) ++{ ++ int sock = *(int *)data; ++ cleanup_iface(sock, iface); ++} ++ + static void setup_ifaces(int sock, struct Interface *ifaces) { for_each_iface(ifaces, setup_iface_foo, &sock); } ++static void cleanup_ifaces(int sock, struct Interface *ifaces) { for_each_iface(ifaces, cleanup_iface_foo, &sock); } + + static struct Interface *reload_config(int sock, struct Interface *ifaces, char const *conf_path) + { ++ cleanup_ifaces(sock, ifaces); + free_ifaces(ifaces); + + flog(LOG_INFO, "attempting to reread config file"); +diff --git a/radvd.h b/radvd.h +index 2a61c75..d16a5c6 100644 +--- a/radvd.h ++++ b/radvd.h +@@ -286,6 +286,7 @@ int set_interface_linkmtu(const char *, uint32_t); + int set_interface_reachtime(const char *, uint32_t); + int set_interface_retranstimer(const char *, uint32_t); + int setup_allrouters_membership(int sock, struct Interface *); ++int cleanup_allrouters_membership(int sock, struct Interface *iface); + int setup_iface_addrs(struct Interface *); + int update_device_index(struct Interface *iface); + int update_device_info(int sock, struct Interface *); +@@ -296,6 +297,7 @@ int get_iface_addrs(char const *name, struct in6_addr *if_addr, /* the first lin + /* interface.c */ + int check_iface(struct Interface *); + int setup_iface(int sock, struct Interface *iface); ++int cleanup_iface(int sock, struct Interface *iface); + struct Interface *find_iface_by_index(struct Interface *iface, int index); + struct Interface *find_iface_by_name(struct Interface *iface, const char *name); + struct Interface *find_iface_by_time(struct Interface *iface_list); +-- +2.27.0 + diff --git a/radvd.spec b/radvd.spec index a2e4658..9378f44 100644 --- a/radvd.spec +++ b/radvd.spec @@ -1,6 +1,6 @@ Name: radvd Version: 2.19 -Release: 1 +Release: 2 Summary: Router ADVertisement Daemon for IPv6 License: BSD with advertising URL: http://www.litech.org/radvd/ @@ -8,6 +8,8 @@ Source0: http://www.litech.org/radvd/dist/%{name}-%{version}.tar.gz Source1: radvd-tmpfs.conf Source2: radvd.service +Patch6000: backport-add-IPV6_DROP_MEMBERSHIP-to-clean-up-resources-when-.patch + BuildRequires: gcc bison flex flex-static pkgconfig check-devel systemd Requires(pre): shadow-utils %{?systemd_requires} @@ -88,6 +90,12 @@ exit 0 %{_mandir}/*/* %changelog +* Tue Jun 28 2022 Aichun Li - 2.19-2 +- Type:bugfix +- Id:NA +- SUG:NA +- DESC:add IPV6_DROP_MEMBERSHIP to fix memory leak in kernel space + * Fri Jan 29 2021 xihaochen - 2.19-1 - Type:requirements - Id:NA