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

Reply via email to