net: context: Allow binding to different interfaces
Allow user to bind to different network interface. This is useful if binding a multicast address to a certain network interface. Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
This commit is contained in:
parent
599bcb1e5d
commit
31ee2e678d
@ -121,7 +121,8 @@ static inline bool is_in_tcp_time_wait_state(struct net_context *context)
|
||||
#endif
|
||||
}
|
||||
|
||||
static int check_used_port(enum net_ip_protocol proto,
|
||||
static int check_used_port(struct net_if *iface,
|
||||
enum net_ip_protocol proto,
|
||||
uint16_t local_port,
|
||||
const struct sockaddr *local_addr,
|
||||
bool reuseaddr_set,
|
||||
@ -140,6 +141,12 @@ static int check_used_port(enum net_ip_protocol proto,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (net_context_is_bound_to_iface(&contexts[i])) {
|
||||
if (iface != NULL && iface != net_context_get_iface(&contexts[i])) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_NET_IPV6) &&
|
||||
local_addr->sa_family == AF_INET6) {
|
||||
if (net_sin6_ptr(&contexts[i].local)->sin6_addr == NULL ||
|
||||
@ -271,7 +278,7 @@ static uint16_t find_available_port(struct net_context *context,
|
||||
|
||||
do {
|
||||
local_port = sys_rand32_get() | 0x8000;
|
||||
} while (check_used_port(net_context_get_proto(context),
|
||||
} while (check_used_port(NULL, net_context_get_proto(context),
|
||||
htons(local_port), addr, false, false) == -EEXIST);
|
||||
|
||||
return htons(local_port);
|
||||
@ -285,7 +292,7 @@ bool net_context_port_in_use(enum net_ip_protocol proto,
|
||||
uint16_t local_port,
|
||||
const struct sockaddr *local_addr)
|
||||
{
|
||||
return check_used_port(proto, htons(local_port), local_addr, false, false) != 0;
|
||||
return check_used_port(NULL, proto, htons(local_port), local_addr, false, false) != 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NET_CONTEXT_CHECK)
|
||||
@ -742,7 +749,8 @@ int net_context_bind(struct net_context *context, const struct sockaddr *addr,
|
||||
|
||||
ret = 0;
|
||||
if (addr6->sin6_port) {
|
||||
ret = check_used_port(context->proto,
|
||||
ret = check_used_port(iface,
|
||||
context->proto,
|
||||
addr6->sin6_port,
|
||||
addr,
|
||||
net_context_is_reuseaddr_set(context),
|
||||
@ -750,6 +758,8 @@ int net_context_bind(struct net_context *context, const struct sockaddr *addr,
|
||||
if (ret != 0) {
|
||||
NET_ERR("Port %d is in use!",
|
||||
ntohs(addr6->sin6_port));
|
||||
NET_DBG("Interface %d (%p)",
|
||||
iface ? net_if_get_by_iface(iface) : 0, iface);
|
||||
ret = -EADDRINUSE;
|
||||
goto unlock_ipv6;
|
||||
} else {
|
||||
@ -839,7 +849,8 @@ int net_context_bind(struct net_context *context, const struct sockaddr *addr,
|
||||
|
||||
ret = 0;
|
||||
if (addr4->sin_port) {
|
||||
ret = check_used_port(context->proto,
|
||||
ret = check_used_port(iface,
|
||||
context->proto,
|
||||
addr4->sin_port,
|
||||
addr,
|
||||
net_context_is_reuseaddr_set(context),
|
||||
@ -848,6 +859,8 @@ int net_context_bind(struct net_context *context, const struct sockaddr *addr,
|
||||
NET_ERR("Port %d is in use!",
|
||||
ntohs(addr4->sin_port));
|
||||
ret = -EADDRINUSE;
|
||||
NET_DBG("Interface %d (%p)",
|
||||
iface ? net_if_get_by_iface(iface) : 0, iface);
|
||||
goto unlock_ipv4;
|
||||
} else {
|
||||
net_sin_ptr(&context->local)->sin_port =
|
||||
|
||||
Loading…
Reference in New Issue
Block a user