net: sockets: packet: Ensure correct interface is used
Make sure that when sendto is being used without the socket being bound before, a correct interface is used for transmission. As zpacket_sendto_ctx() calls net_context_recv() to register receive callback before sending, a default binding was used by the context layer, which would bind the socket to the default interface. This could lead to unexpected results, i.e. packet being sent on a default interface, even though a different one was specified. Make also sure that there is no ambiguity in the interface selection - the application should be explicitly clear what interface it wants to use when it comes to packet sockets. It's better to return an error if no valid interface was specified. Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commit is contained in:
parent
332843be33
commit
6c0aef4da0
2 changed files with 24 additions and 1 deletions
|
@ -764,14 +764,19 @@ static int bind_default(struct net_context *context)
|
|||
|
||||
if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) && family == AF_PACKET) {
|
||||
struct sockaddr_ll ll_addr;
|
||||
struct net_if *iface = net_context_get_iface(context);
|
||||
|
||||
if (net_sll_ptr(&context->local)->sll_addr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (iface == NULL) {
|
||||
iface = net_if_get_default();
|
||||
}
|
||||
|
||||
ll_addr.sll_family = AF_PACKET;
|
||||
ll_addr.sll_protocol = htons(ETH_P_ALL);
|
||||
ll_addr.sll_ifindex = net_if_get_by_iface(net_if_get_default());
|
||||
ll_addr.sll_ifindex = net_if_get_by_iface(iface);
|
||||
|
||||
return net_context_bind(context, (struct sockaddr *)&ll_addr,
|
||||
sizeof(ll_addr));
|
||||
|
@ -2487,6 +2492,8 @@ static int context_sendto(struct net_context *context,
|
|||
ll_addr->sll_ifindex);
|
||||
return -EDESTADDRREQ;
|
||||
}
|
||||
|
||||
net_context_set_iface(context, iface);
|
||||
}
|
||||
|
||||
if (net_context_get_type(context) == SOCK_DGRAM) {
|
||||
|
|
|
@ -234,6 +234,7 @@ ssize_t zpacket_sendto_ctx(struct net_context *ctx, const void *buf, size_t len,
|
|||
int flags, const struct sockaddr *dest_addr,
|
||||
socklen_t addrlen)
|
||||
{
|
||||
const struct sockaddr_ll *ll_addr = (const struct sockaddr_ll *)dest_addr;
|
||||
k_timeout_t timeout = K_FOREVER;
|
||||
int status;
|
||||
|
||||
|
@ -248,6 +249,21 @@ ssize_t zpacket_sendto_ctx(struct net_context *ctx, const void *buf, size_t len,
|
|||
net_context_get_option(ctx, NET_OPT_SNDTIMEO, &timeout, NULL);
|
||||
}
|
||||
|
||||
/* If no interface was set on the context yet, use the one provided in
|
||||
* the destination address for default binding, unless 0 (any interface)
|
||||
* was set, in that case let the stack choose the default.
|
||||
*/
|
||||
if (net_context_get_iface(ctx) == NULL && ll_addr->sll_ifindex != 0) {
|
||||
struct net_if *iface = net_if_get_by_index(ll_addr->sll_ifindex);
|
||||
|
||||
if (iface == NULL) {
|
||||
errno = EDESTADDRREQ;
|
||||
return -1;
|
||||
}
|
||||
|
||||
net_context_set_iface(ctx, iface);
|
||||
}
|
||||
|
||||
/* Register the callback before sending in order to receive the response
|
||||
* from the peer.
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue