When generating a port fails a few times (because they are already in used
outside of libnl's knowledge), we would back off generating a local
port and instead let kernel decide.
There was however a bug in nl_connect() that caused an assertion:
BUG at file position socket.c:147:_nl_socket_used_ports_release_all
app: socket.c:147: _nl_socket_used_ports_release_all: Assertion `0' failed.
Fixes: 96e1e5bdc2e803700055395cc3c428fa2525d1ca
#endif
int _nl_socket_is_local_port_unspecified (struct nl_sock *sk);
-uint32_t _nl_socket_generate_local_port_no_release(struct nl_sock *sk);
+uint32_t _nl_socket_set_local_port_no_release(struct nl_sock *sk, int generate_other);
void _nl_socket_used_ports_release_all(const uint32_t *used_ports);
void _nl_socket_used_ports_set(uint32_t *used_ports, uint32_t port);
if (ntries++ > 5) {
/* try only a few times. We hit this only if many ports are already in
* use but allocated *outside* libnl/generate_local_port(). */
- nl_socket_set_local_port (sk, 0);
+ _nl_socket_set_local_port_no_release (sk, 0);
break;
}
- port = _nl_socket_generate_local_port_no_release(sk);
+ port = _nl_socket_set_local_port_no_release(sk, 1);
if (port == 0)
break;
return (sk->s_local.nl_pid == 0);
}
-uint32_t _nl_socket_generate_local_port_no_release(struct nl_sock *sk)
+uint32_t _nl_socket_set_local_port_no_release(struct nl_sock *sk, int generate_other)
{
uint32_t port;
/* reset the port to generate_local_port(), but do not release
* the previously generated port. */
- port = generate_local_port();
+ if (generate_other)
+ port = generate_local_port();
+ else
+ port = 0;
sk->s_local.nl_pid = port;
if (port == 0) {
/* failed to find an unsed port. Restore the socket to have an