Skip to content

Commit 06cd001

Browse files
jukkarnashif
authored andcommitted
net: context: Allow binding AF_PACKET multiple times
If the system has more than one network interface, then it should be possible to bind a AF_PACKET socket to each interface if the network interface index is set when bind() is called. This was not possible earlier as the code was always using default network interface with AF_PACKET socket bind(). Fixes #23153 Signed-off-by: Jukka Rissanen <[email protected]>
1 parent 2bc8b7f commit 06cd001

File tree

2 files changed

+38
-5
lines changed

2 files changed

+38
-5
lines changed

subsys/net/ip/connection.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -625,12 +625,28 @@ int net_conn_register(u16_t proto, u8_t family,
625625
}
626626
} else
627627
#endif
628+
629+
#if defined(CONFIG_NET_SOCKETS_PACKET)
630+
if (local_addr->sa_family == AF_PACKET) {
631+
const struct sockaddr_ll unspec_addr = { 0 };
632+
633+
memcpy(&conns[i].local_addr, local_addr,
634+
sizeof(struct sockaddr_ll));
635+
636+
if (!memcmp(unspec_addr.sll_addr,
637+
((struct sockaddr_ll *)local_addr)->
638+
sll_addr,
639+
sizeof(unspec_addr.sll_addr))) {
640+
rank |= NET_RANK_LOCAL_UNSPEC_ADDR;
641+
} else {
642+
rank |= NET_RANK_LOCAL_SPEC_ADDR;
643+
}
644+
} else
645+
#endif
628646
{
629647
NET_ERR("Local address family not set");
630648
return -EINVAL;
631649
}
632-
633-
conns[i].flags |= NET_CONN_LOCAL_ADDR_SET;
634650
}
635651

636652
if (remote_addr && local_addr) {

subsys/net/ip/net_context.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,10 @@ static int bind_default(struct net_context *context)
447447
if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) && family == AF_PACKET) {
448448
struct sockaddr_ll ll_addr;
449449

450+
if (net_sll_ptr(&context->local)->sll_addr) {
451+
return 0;
452+
}
453+
450454
ll_addr.sll_family = AF_PACKET;
451455
ll_addr.sll_protocol = ETH_P_ALL;
452456
ll_addr.sll_ifindex = net_if_get_by_iface(net_if_get_default());
@@ -1690,6 +1694,7 @@ static enum net_verdict net_context_raw_packet_received(
16901694
static int recv_raw(struct net_context *context,
16911695
net_context_recv_cb_t cb,
16921696
s32_t timeout,
1697+
struct sockaddr *addr,
16931698
void *user_data)
16941699
{
16951700
int ret;
@@ -1710,7 +1715,7 @@ static int recv_raw(struct net_context *context,
17101715

17111716
ret = net_conn_register(net_context_get_ip_proto(context),
17121717
net_context_get_family(context),
1713-
NULL, NULL, 0, 0,
1718+
NULL, addr, 0, 0,
17141719
net_context_raw_packet_received,
17151720
user_data,
17161721
&context->conn_handler);
@@ -1755,13 +1760,25 @@ int net_context_recv(struct net_context *context,
17551760
default:
17561761
if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
17571762
net_context_get_family(context) == AF_PACKET) {
1758-
ret = recv_raw(context, cb, timeout, user_data);
1763+
struct sockaddr_ll addr;
1764+
1765+
addr.sll_family = AF_PACKET;
1766+
addr.sll_ifindex =
1767+
net_sll_ptr(&context->local)->sll_ifindex;
1768+
addr.sll_protocol =
1769+
net_sll_ptr(&context->local)->sll_protocol;
1770+
memcpy(addr.sll_addr,
1771+
net_sll_ptr(&context->local)->sll_addr,
1772+
sizeof(addr.sll_addr));
1773+
1774+
ret = recv_raw(context, cb, timeout,
1775+
(struct sockaddr *)&addr, user_data);
17591776
break;
17601777
}
17611778

17621779
if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) &&
17631780
net_context_get_family(context) == AF_CAN) {
1764-
ret = recv_raw(context, cb, timeout, user_data);
1781+
ret = recv_raw(context, cb, timeout, NULL, user_data);
17651782
break;
17661783
}
17671784

0 commit comments

Comments
 (0)