This is an automated email from the ASF dual-hosted git repository. jiuzhudong pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 1fd47357f7edd47c6ba6864075d1d59e1f8d0223 Author: zhanghongyu <[email protected]> AuthorDate: Mon Jun 9 11:10:58 2025 +0800 net/packet: add PACKET_<ADD|DROP>_MEMBERSHIP support Some third-party network libraries use PACKET_ADD_MEMBERSHIP to add MAC addresses to devices, and this patch can add support for this. Signed-off-by: zhanghongyu <[email protected]> --- Documentation/components/net/pkt.rst | 22 ++++++++++++++- include/netpacket/packet.h | 15 ++++++++++ net/pkt/pkt_getsockopt.c | 2 +- net/pkt/pkt_setsockopt.c | 53 +++++++++++++++++++++++++++++++++++- net/socket/Kconfig | 2 +- 5 files changed, 90 insertions(+), 4 deletions(-) diff --git a/Documentation/components/net/pkt.rst b/Documentation/components/net/pkt.rst index f0ec185c1ff..52413f004a6 100644 --- a/Documentation/components/net/pkt.rst +++ b/Documentation/components/net/pkt.rst @@ -17,8 +17,10 @@ Configuration Options Dynamic memory allocations for packet connections. ``CONFIG_NET_PKT_MAX_CONNS`` Maximum number of packet connections. -``NET_PKT_WRITE_BUFFERS`` +``CONFIG_NET_PKT_WRITE_BUFFERS`` Use write buffers for packet sockets, support SOCK_NONBLOCK mode. +``CONFIG_NET_PKTPROTO_OPTIONS`` + Enable setting protocol options on packet sockets. Usage ===== @@ -58,3 +60,21 @@ Usage (struct sockaddr *)&addr, sizeof(addr)); close(sd); /* Close the socket */ + +.. code-block:: c + + int sd; + struct packet_mreq mreq; + char macaddr[ETH_ALEN] = {0x91, 0xe0, 0xf0, 0x00, 0x0e, 0x01}; + + sd = socket(AF_PACKET, SOCK_RAW, 0); + + mreq.mr_ifindex = if_nametoindex("eth0"); + mreq.mr_type = PACKET_MR_MULTICAST; + mreq.mr_alen = ETH_ALEN; + memcpy(&mreq.mr_address, macaddr, ETH_ALEN); + + setsockopt(sd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, + sizeof(struct packet_mreq)); + + close(sd); diff --git a/include/netpacket/packet.h b/include/netpacket/packet.h index a578759d781..5f8316a6d3d 100644 --- a/include/netpacket/packet.h +++ b/include/netpacket/packet.h @@ -44,6 +44,13 @@ #define PACKET_LOOPBACK 5 #define PACKET_FASTROUTE 6 +/* Packet socket options */ + +#define PACKET_ADD_MEMBERSHIP 1 /* Add a multicast address to the interface */ +#define PACKET_DROP_MEMBERSHIP 2 /* Drop a multicast address from the interface */ + +#define PACKET_MR_MULTICAST 0 /* Multicast address */ + /**************************************************************************** * Public Types ****************************************************************************/ @@ -59,4 +66,12 @@ struct sockaddr_ll unsigned char sll_addr[8]; }; +struct packet_mreq +{ + int mr_ifindex; + unsigned short mr_type; + unsigned short mr_alen; + unsigned char mr_address[8]; +}; + #endif /* __INCLUDE_NETPACKET_PACKET_H */ diff --git a/net/pkt/pkt_getsockopt.c b/net/pkt/pkt_getsockopt.c index 3ca9265adff..4f56f47a8e8 100644 --- a/net/pkt/pkt_getsockopt.c +++ b/net/pkt/pkt_getsockopt.c @@ -94,7 +94,7 @@ int pkt_getsockopt(FAR struct socket *psock, int level, int option, switch (option) { -#if CONFIG_NET_SEND_BUFSIZE > 0 +#if defined(CONFIG_NET_PKT_WRITE_BUFFERS) && CONFIG_NET_SEND_BUFSIZE > 0 case SO_SNDBUF: { FAR struct pkt_conn_s *conn; diff --git a/net/pkt/pkt_setsockopt.c b/net/pkt/pkt_setsockopt.c index b3f1015ef32..753fe7f16d4 100644 --- a/net/pkt/pkt_setsockopt.c +++ b/net/pkt/pkt_setsockopt.c @@ -32,9 +32,11 @@ #include <assert.h> #include <debug.h> +#include <netpacket/packet.h> #include <nuttx/net/net.h> #include <nuttx/net/pkt.h> +#include "netdev/netdev.h" #include "socket/socket.h" #include "utils/utils.h" #include "pkt/pkt.h" @@ -90,7 +92,7 @@ int pkt_setsockopt(FAR struct socket *psock, int level, int option, switch (option) { -#if CONFIG_NET_SEND_BUFSIZE > 0 +#if defined(CONFIG_NET_PKT_WRITE_BUFFERS) && CONFIG_NET_SEND_BUFSIZE > 0 case SO_SNDBUF: { FAR struct pkt_conn_s *conn; @@ -121,6 +123,55 @@ int pkt_setsockopt(FAR struct socket *psock, int level, int option, } #endif +#ifdef CONFIG_NET_MCASTGROUP + case PACKET_ADD_MEMBERSHIP: + case PACKET_DROP_MEMBERSHIP: + { + FAR const struct packet_mreq *mreq; + FAR struct net_driver_s *dev; + + if (value == NULL || value_len < sizeof(struct packet_mreq)) + { + return -EINVAL; + } + + mreq = (FAR const struct packet_mreq *)value; + dev = netdev_findbyindex(mreq->mr_ifindex); + if (dev == NULL) + { + return -ENODEV; + } + + if (mreq->mr_type == PACKET_MR_MULTICAST) + { + if (option == PACKET_ADD_MEMBERSHIP && dev->d_addmac != NULL) + { + /* Add the multicast MAC address to the device */ + + ret = dev->d_addmac(dev, mreq->mr_address); + } + else if (option == PACKET_DROP_MEMBERSHIP && + dev->d_rmmac != NULL) + { + /* Drop the multicast MAC address from the device */ + + ret = dev->d_rmmac(dev, mreq->mr_address); + } + else + { + nerr("ERROR: Device does not support add MAC address\n"); + ret = -ENOSYS; + } + } + else + { + nerr("ERROR: Invalid mr_type: %d\n", mreq->mr_type); + return -ENOSYS; + } + } + break; +#endif + default: nerr("ERROR: Unrecognized PKT option: %d\n", option); ret = -ENOPROTOOPT; diff --git a/net/socket/Kconfig b/net/socket/Kconfig index fb62b24eb9c..eb438e91e87 100644 --- a/net/socket/Kconfig +++ b/net/socket/Kconfig @@ -61,7 +61,7 @@ config NET_CANPROTO_OPTIONS Enable or disable support for CAN protocol level socket option config NET_PKTPROTO_OPTIONS - bool + bool "PACKET proto socket options" default n ---help--- Enable or disable support for PKT protocol level socket option
