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