From 35af68b840d7778afbe7e0566ab45d1c0c511937 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 6 Jun 2025 15:08:10 +0200 Subject: [PATCH] net: mqtt: Allow to bind client to a specific interface Add a new "if_name" pointer to the transport configuration structure, allowing the application to bind MQTT client to a specific network interface. Signed-off-by: Robert Lubos --- include/zephyr/net/mqtt.h | 5 +++++ .../net/lib/mqtt/mqtt_transport_socket_tcp.c | 22 +++++++++++++++++-- .../net/lib/mqtt/mqtt_transport_socket_tls.c | 18 +++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/include/zephyr/net/mqtt.h b/include/zephyr/net/mqtt.h index d5dce240230..b992714afd3 100644 --- a/include/zephyr/net/mqtt.h +++ b/include/zephyr/net/mqtt.h @@ -809,6 +809,11 @@ struct mqtt_transport { */ enum mqtt_transport_type type; + /** Name of the interface that the MQTT client instance should be bound to. + * Leave as NULL if not specified. + */ + const char *if_name; + /** Use either unsecured TCP or secured TLS transport */ union { /** TCP socket transport for MQTT */ diff --git a/subsys/net/lib/mqtt/mqtt_transport_socket_tcp.c b/subsys/net/lib/mqtt/mqtt_transport_socket_tcp.c index ffb8bcdb683..58f37857bb2 100644 --- a/subsys/net/lib/mqtt/mqtt_transport_socket_tcp.c +++ b/subsys/net/lib/mqtt/mqtt_transport_socket_tcp.c @@ -29,6 +29,26 @@ int mqtt_client_tcp_connect(struct mqtt_client *client) return -errno; } + NET_DBG("Created socket %d", client->transport.tcp.sock); + + if (client->transport.if_name != NULL) { + struct ifreq ifname = { 0 }; + + strncpy(ifname.ifr_name, client->transport.if_name, + sizeof(ifname.ifr_name) - 1); + + ret = zsock_setsockopt(client->transport.tcp.sock, SOL_SOCKET, + SO_BINDTODEVICE, &ifname, + sizeof(struct ifreq)); + if (ret < 0) { + NET_ERR("Failed to bind ot interface %s error (%d)", + ifname.ifr_name, -errno); + goto error; + } + + NET_DBG("Bound to interface %s", ifname.ifr_name); + } + #if defined(CONFIG_SOCKS) if (client->transport.proxy.addrlen != 0) { ret = setsockopt(client->transport.tcp.sock, @@ -41,8 +61,6 @@ int mqtt_client_tcp_connect(struct mqtt_client *client) } #endif - NET_DBG("Created socket %d", client->transport.tcp.sock); - size_t peer_addr_size = sizeof(struct sockaddr_in6); if (broker->sa_family == AF_INET) { diff --git a/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c b/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c index a33cee5aecf..2ff337eef34 100644 --- a/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c +++ b/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c @@ -32,6 +32,24 @@ int mqtt_client_tls_connect(struct mqtt_client *client) NET_DBG("Created socket %d", client->transport.tls.sock); + if (client->transport.if_name != NULL) { + struct ifreq ifname = { 0 }; + + strncpy(ifname.ifr_name, client->transport.if_name, + sizeof(ifname.ifr_name) - 1); + + ret = zsock_setsockopt(client->transport.tls.sock, SOL_SOCKET, + SO_BINDTODEVICE, &ifname, + sizeof(struct ifreq)); + if (ret < 0) { + NET_ERR("Failed to bind ot interface %s error (%d)", + ifname.ifr_name, -errno); + goto error; + } + + NET_DBG("Bound to interface %s", ifname.ifr_name); + } + #if defined(CONFIG_SOCKS) if (client->transport.proxy.addrlen != 0) { ret = setsockopt(client->transport.tls.sock,