[git commit] udhcp6: fix releasing

Denys Vlasenko vda.linux at googlemail.com
Mon Mar 27 20:44:22 UTC 2017


commit: https://git.busybox.net/busybox/commit/?id=ed898ed2ddc1e3627555488671155420a32d0167
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

Patch is based on work by tiggerswelt.net. They say:
"
We wanted udhcpc6 to release its IPv6-Addresses on
quit (-R-commandline-option) which turned out to generate once again
kind of garbage on the network-link.
We tracked this down to two issues:

 - udhcpc6 uses a variable called "srv6_buf" to send packets to
   the dhcp6-server, but this variable is never initialized correctly
   and contained kind of a garbage-address

 - The address of the dhcp6-server is usually a link-local-address,
   that requires an interface-index when using connect() on an AF_INET6-
   socket

We added an
additional parameter for ifindex to d6_send_kernel_packet() and made
d6_recv_raw_packet() to capture the address of the dhcp6-server and
forward it to its callee.
"

Three last patches together:

function                                             old     new   delta
d6_read_interface                                      -     454    +454
d6_recv_raw_packet                                     -     283    +283
option_to_env                                        249     504    +255
.rodata                                           165226  165371    +145
send_d6_discover                                     195     237     +42
send_d6_select                                       118     159     +41
send_d6_renew                                        173     186     +13
send_d6_release                                      162     173     +11
opt_req                                                -      10     +10
d6_send_kernel_packet                                304     312      +8
opt_fqdn_req                                           -       6      +6
d6_mcast_from_client_config_ifindex                   48      51      +3
d6_find_option                                        63      61      -2
udhcpc6_main                                        2416    2411      -5
static.d6_recv_raw_packet                            266       -    -266
------------------------------------------------------------------------------
(add/remove: 5/1 grow/shrink: 8/2 up/down: 1271/-273)         Total: 998 bytes

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 networking/udhcp/d6_common.h |  3 ++-
 networking/udhcp/d6_dhcpc.c  | 13 ++++++++-----
 networking/udhcp/d6_packet.c |  4 +++-
 3 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/networking/udhcp/d6_common.h b/networking/udhcp/d6_common.h
index 335a092..fcec8c1 100644
--- a/networking/udhcp/d6_common.h
+++ b/networking/udhcp/d6_common.h
@@ -121,7 +121,8 @@ int FAST_FUNC d6_send_raw_packet(
 int FAST_FUNC d6_send_kernel_packet(
 		struct d6_packet *d6_pkt, unsigned d6_pkt_size,
 		struct in6_addr *src_ipv6, int source_port,
-		struct in6_addr *dst_ipv6, int dest_port
+		struct in6_addr *dst_ipv6, int dest_port,
+		int ifindex
 );
 
 #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c
index a0cdded..95de74f 100644
--- a/networking/udhcp/d6_dhcpc.c
+++ b/networking/udhcp/d6_dhcpc.c
@@ -623,7 +623,8 @@ static NOINLINE int send_d6_renew(uint32_t xid, struct in6_addr *server_ipv6, st
 		return d6_send_kernel_packet(
 			&packet, (opt_ptr - (uint8_t*) &packet),
 			our_cur_ipv6, CLIENT_PORT6,
-			server_ipv6, SERVER_PORT6
+			server_ipv6, SERVER_PORT6,
+			client_config.ifindex
 		);
 	return d6_mcast_from_client_config_ifindex(&packet, opt_ptr);
 }
@@ -645,15 +646,14 @@ static int send_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cu
 	return d6_send_kernel_packet(
 		&packet, (opt_ptr - (uint8_t*) &packet),
 		our_cur_ipv6, CLIENT_PORT6,
-		server_ipv6, SERVER_PORT6
+		server_ipv6, SERVER_PORT6,
+		client_config.ifindex
 	);
 }
 
 /* Returns -1 on errors that are fatal for the socket, -2 for those that aren't */
 /* NOINLINE: limit stack usage in caller */
-static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6
-	UNUSED_PARAM
-	, struct d6_packet *d6_pkt, int fd)
+static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6, struct d6_packet *d6_pkt, int fd)
 {
 	int bytes;
 	struct ip6_udp_d6_packet packet;
@@ -702,6 +702,9 @@ static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6
 //		return -2;
 //	}
 
+	if (peer_ipv6)
+		*peer_ipv6 = packet.ip6.ip6_src; /* struct copy */
+
 	log1("received %s", "a packet");
 	d6_dump_packet(&packet.data);
 
diff --git a/networking/udhcp/d6_packet.c b/networking/udhcp/d6_packet.c
index e166f52..79a0ac8 100644
--- a/networking/udhcp/d6_packet.c
+++ b/networking/udhcp/d6_packet.c
@@ -127,7 +127,8 @@ int FAST_FUNC d6_send_raw_packet(
 int FAST_FUNC d6_send_kernel_packet(
 		struct d6_packet *d6_pkt, unsigned d6_pkt_size,
 		struct in6_addr *src_ipv6, int source_port,
-		struct in6_addr *dst_ipv6, int dest_port)
+		struct in6_addr *dst_ipv6, int dest_port,
+		int ifindex)
 {
 	struct sockaddr_in6 sa;
 	int fd;
@@ -154,6 +155,7 @@ int FAST_FUNC d6_send_kernel_packet(
 	sa.sin6_family = AF_INET6;
 	sa.sin6_port = htons(dest_port);
 	sa.sin6_addr = *dst_ipv6; /* struct copy */
+	sa.sin6_scope_id = ifindex;
 	if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
 		msg = "connect";
 		goto ret_close;


More information about the busybox-cvs mailing list