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>
This commit is contained in:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user