Skip to content

Commit 6c0aef4

Browse files
rluboskartben
authored andcommitted
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 <[email protected]>
1 parent 332843b commit 6c0aef4

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

subsys/net/ip/net_context.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -764,14 +764,19 @@ static int bind_default(struct net_context *context)
764764

765765
if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) && family == AF_PACKET) {
766766
struct sockaddr_ll ll_addr;
767+
struct net_if *iface = net_context_get_iface(context);
767768

768769
if (net_sll_ptr(&context->local)->sll_addr) {
769770
return 0;
770771
}
771772

773+
if (iface == NULL) {
774+
iface = net_if_get_default();
775+
}
776+
772777
ll_addr.sll_family = AF_PACKET;
773778
ll_addr.sll_protocol = htons(ETH_P_ALL);
774-
ll_addr.sll_ifindex = net_if_get_by_iface(net_if_get_default());
779+
ll_addr.sll_ifindex = net_if_get_by_iface(iface);
775780

776781
return net_context_bind(context, (struct sockaddr *)&ll_addr,
777782
sizeof(ll_addr));
@@ -2487,6 +2492,8 @@ static int context_sendto(struct net_context *context,
24872492
ll_addr->sll_ifindex);
24882493
return -EDESTADDRREQ;
24892494
}
2495+
2496+
net_context_set_iface(context, iface);
24902497
}
24912498

24922499
if (net_context_get_type(context) == SOCK_DGRAM) {

subsys/net/lib/sockets/sockets_packet.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ ssize_t zpacket_sendto_ctx(struct net_context *ctx, const void *buf, size_t len,
234234
int flags, const struct sockaddr *dest_addr,
235235
socklen_t addrlen)
236236
{
237+
const struct sockaddr_ll *ll_addr = (const struct sockaddr_ll *)dest_addr;
237238
k_timeout_t timeout = K_FOREVER;
238239
int status;
239240

@@ -248,6 +249,21 @@ ssize_t zpacket_sendto_ctx(struct net_context *ctx, const void *buf, size_t len,
248249
net_context_get_option(ctx, NET_OPT_SNDTIMEO, &timeout, NULL);
249250
}
250251

252+
/* If no interface was set on the context yet, use the one provided in
253+
* the destination address for default binding, unless 0 (any interface)
254+
* was set, in that case let the stack choose the default.
255+
*/
256+
if (net_context_get_iface(ctx) == NULL && ll_addr->sll_ifindex != 0) {
257+
struct net_if *iface = net_if_get_by_index(ll_addr->sll_ifindex);
258+
259+
if (iface == NULL) {
260+
errno = EDESTADDRREQ;
261+
return -1;
262+
}
263+
264+
net_context_set_iface(ctx, iface);
265+
}
266+
251267
/* Register the callback before sending in order to receive the response
252268
* from the peer.
253269
*/

0 commit comments

Comments
 (0)