diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-03-27 22:32:44 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-03-27 22:44:22 +0200 |
commit | ed898ed2ddc1e3627555488671155420a32d0167 (patch) | |
tree | eee8a0aed9fd26e7aea254004efe0e15ad83c53d | |
parent | 64d58aa8061c7c848cf0fd37de3ccbb8582d0fc5 (diff) | |
download | busybox-w32-ed898ed2ddc1e3627555488671155420a32d0167.tar.gz busybox-w32-ed898ed2ddc1e3627555488671155420a32d0167.tar.bz2 busybox-w32-ed898ed2ddc1e3627555488671155420a32d0167.zip |
udhcp6: fix releasing
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@googlemail.com>
-rw-r--r-- | networking/udhcp/d6_common.h | 3 | ||||
-rw-r--r-- | networking/udhcp/d6_dhcpc.c | 13 | ||||
-rw-r--r-- | 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 335a0927a..fcec8c15a 100644 --- a/networking/udhcp/d6_common.h +++ b/networking/udhcp/d6_common.h | |||
@@ -121,7 +121,8 @@ int FAST_FUNC d6_send_raw_packet( | |||
121 | int FAST_FUNC d6_send_kernel_packet( | 121 | int FAST_FUNC d6_send_kernel_packet( |
122 | struct d6_packet *d6_pkt, unsigned d6_pkt_size, | 122 | struct d6_packet *d6_pkt, unsigned d6_pkt_size, |
123 | struct in6_addr *src_ipv6, int source_port, | 123 | struct in6_addr *src_ipv6, int source_port, |
124 | struct in6_addr *dst_ipv6, int dest_port | 124 | struct in6_addr *dst_ipv6, int dest_port, |
125 | int ifindex | ||
125 | ); | 126 | ); |
126 | 127 | ||
127 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2 | 128 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2 |
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index a0cdded11..95de74f9b 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 | |||
623 | return d6_send_kernel_packet( | 623 | return d6_send_kernel_packet( |
624 | &packet, (opt_ptr - (uint8_t*) &packet), | 624 | &packet, (opt_ptr - (uint8_t*) &packet), |
625 | our_cur_ipv6, CLIENT_PORT6, | 625 | our_cur_ipv6, CLIENT_PORT6, |
626 | server_ipv6, SERVER_PORT6 | 626 | server_ipv6, SERVER_PORT6, |
627 | client_config.ifindex | ||
627 | ); | 628 | ); |
628 | return d6_mcast_from_client_config_ifindex(&packet, opt_ptr); | 629 | return d6_mcast_from_client_config_ifindex(&packet, opt_ptr); |
629 | } | 630 | } |
@@ -645,15 +646,14 @@ static int send_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cu | |||
645 | return d6_send_kernel_packet( | 646 | return d6_send_kernel_packet( |
646 | &packet, (opt_ptr - (uint8_t*) &packet), | 647 | &packet, (opt_ptr - (uint8_t*) &packet), |
647 | our_cur_ipv6, CLIENT_PORT6, | 648 | our_cur_ipv6, CLIENT_PORT6, |
648 | server_ipv6, SERVER_PORT6 | 649 | server_ipv6, SERVER_PORT6, |
650 | client_config.ifindex | ||
649 | ); | 651 | ); |
650 | } | 652 | } |
651 | 653 | ||
652 | /* Returns -1 on errors that are fatal for the socket, -2 for those that aren't */ | 654 | /* Returns -1 on errors that are fatal for the socket, -2 for those that aren't */ |
653 | /* NOINLINE: limit stack usage in caller */ | 655 | /* NOINLINE: limit stack usage in caller */ |
654 | static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6 | 656 | static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6, struct d6_packet *d6_pkt, int fd) |
655 | UNUSED_PARAM | ||
656 | , struct d6_packet *d6_pkt, int fd) | ||
657 | { | 657 | { |
658 | int bytes; | 658 | int bytes; |
659 | struct ip6_udp_d6_packet packet; | 659 | struct ip6_udp_d6_packet packet; |
@@ -702,6 +702,9 @@ static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6 | |||
702 | // return -2; | 702 | // return -2; |
703 | // } | 703 | // } |
704 | 704 | ||
705 | if (peer_ipv6) | ||
706 | *peer_ipv6 = packet.ip6.ip6_src; /* struct copy */ | ||
707 | |||
705 | log1("received %s", "a packet"); | 708 | log1("received %s", "a packet"); |
706 | d6_dump_packet(&packet.data); | 709 | d6_dump_packet(&packet.data); |
707 | 710 | ||
diff --git a/networking/udhcp/d6_packet.c b/networking/udhcp/d6_packet.c index e166f520d..79a0ac8a8 100644 --- a/networking/udhcp/d6_packet.c +++ b/networking/udhcp/d6_packet.c | |||
@@ -127,7 +127,8 @@ int FAST_FUNC d6_send_raw_packet( | |||
127 | int FAST_FUNC d6_send_kernel_packet( | 127 | int FAST_FUNC d6_send_kernel_packet( |
128 | struct d6_packet *d6_pkt, unsigned d6_pkt_size, | 128 | struct d6_packet *d6_pkt, unsigned d6_pkt_size, |
129 | struct in6_addr *src_ipv6, int source_port, | 129 | struct in6_addr *src_ipv6, int source_port, |
130 | struct in6_addr *dst_ipv6, int dest_port) | 130 | struct in6_addr *dst_ipv6, int dest_port, |
131 | int ifindex) | ||
131 | { | 132 | { |
132 | struct sockaddr_in6 sa; | 133 | struct sockaddr_in6 sa; |
133 | int fd; | 134 | int fd; |
@@ -154,6 +155,7 @@ int FAST_FUNC d6_send_kernel_packet( | |||
154 | sa.sin6_family = AF_INET6; | 155 | sa.sin6_family = AF_INET6; |
155 | sa.sin6_port = htons(dest_port); | 156 | sa.sin6_port = htons(dest_port); |
156 | sa.sin6_addr = *dst_ipv6; /* struct copy */ | 157 | sa.sin6_addr = *dst_ipv6; /* struct copy */ |
158 | sa.sin6_scope_id = ifindex; | ||
157 | if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) { | 159 | if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) { |
158 | msg = "connect"; | 160 | msg = "connect"; |
159 | goto ret_close; | 161 | goto ret_close; |