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 <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2020-02-28 10:25:18 +02:00
commit 505e306b72
2 changed files with 21 additions and 1 deletions

View file

@ -313,6 +313,10 @@ int net_conn_register(u16_t proto, u8_t family,
local_addr->sa_family == AF_CAN) {
memcpy(&conn->local_addr, local_addr,
sizeof(struct sockaddr_can));
} else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
local_addr->sa_family == AF_PACKET) {
memcpy(&conn->local_addr, local_addr,
sizeof(struct sockaddr_ll));
} else {
NET_ERR("Local address family not set");
goto error;

View file

@ -441,6 +441,10 @@ static int bind_default(struct net_context *context)
if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) && family == AF_PACKET) {
struct sockaddr_ll ll_addr;
if (net_sll_ptr(&context->local)->sll_addr) {
return 0;
}
ll_addr.sll_family = AF_PACKET;
ll_addr.sll_protocol = ETH_P_ALL;
ll_addr.sll_ifindex = net_if_get_by_iface(net_if_get_default());
@ -1916,7 +1920,19 @@ int net_context_recv(struct net_context *context,
} else {
if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
net_context_get_family(context) == AF_PACKET) {
ret = recv_raw(context, cb, timeout, NULL, user_data);
struct sockaddr_ll addr;
addr.sll_family = AF_PACKET;
addr.sll_ifindex =
net_sll_ptr(&context->local)->sll_ifindex;
addr.sll_protocol =
net_sll_ptr(&context->local)->sll_protocol;
memcpy(addr.sll_addr,
net_sll_ptr(&context->local)->sll_addr,
sizeof(addr.sll_addr));
ret = recv_raw(context, cb, timeout,
(struct sockaddr *)&addr, user_data);
} else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) &&
net_context_get_family(context) == AF_CAN) {
struct sockaddr_can local_addr = {