[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