net/pkt: Support binding to devices other than ETH

We're using the `sll_ifindex` inside `struct sockaddr_ll` to bind
device, so we don't need to translate it into mac address, we can just
match the index, which also let us bind to different type of devices
other than Ethernet.

Ref: Linux also uses `ifindex` to find related device and note it down without mac addresses.
https://man7.org/linux/man-pages/man7/packet.7.html
https://github.com/torvalds/linux/blob/v6.7/net/packet/af_packet.c#L3328
https://github.com/torvalds/linux/blob/v6.7/net/packet/af_packet.c#L3264-L3265

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
This commit is contained in:
Zhe Weng 2024-02-19 11:46:04 +08:00 committed by Xiang Xiao
parent aa75b7f27c
commit 9a23ebdbc0
5 changed files with 9 additions and 27 deletions

View file

@ -18,8 +18,6 @@ config NET_PKT
a packet socket will bypass the network altogether and be placed in
the transmission buffer of the network interface driver.
REVISIT: Currently only implemented for Ethernet.
if NET_PKT
config NET_PKT_PREALLOC_CONNS

View file

@ -60,9 +60,7 @@ struct pkt_conn_s
/* Pkt socket-specific content follows */
uint8_t lmac[6]; /* The local Ethernet address in network byte order */
uint8_t ifindex;
uint16_t proto;
uint8_t crefs; /* Reference counts on this instance */
/* Read-ahead buffering.
@ -97,7 +95,6 @@ EXTERN const struct sock_intf_s g_pkt_sockif;
****************************************************************************/
struct net_driver_s; /* Forward reference */
struct eth_hdr_s; /* Forward reference */
struct socket; /* Forward reference */
/****************************************************************************
@ -137,15 +134,15 @@ void pkt_free(FAR struct pkt_conn_s *conn);
* Name: pkt_active()
*
* Description:
* Find a connection structure that is the appropriate
* connection to be used with the provided Ethernet header
* Find a connection structure that is the appropriate connection to be
* used with the provided network device
*
* Assumptions:
* This function is called from network logic at with the network locked.
*
****************************************************************************/
FAR struct pkt_conn_s *pkt_active(FAR struct eth_hdr_s *buf);
FAR struct pkt_conn_s *pkt_active(FAR struct net_driver_s *dev);
/****************************************************************************
* Name: pkt_nextconn()

View file

@ -194,24 +194,21 @@ void pkt_free(FAR struct pkt_conn_s *conn)
*
* Description:
* Find a connection structure that is the appropriate connection to be
* used with the provided Ethernet header
* used with the provided network device
*
* Assumptions:
* This function is called from network logic at with the network locked.
*
****************************************************************************/
FAR struct pkt_conn_s *pkt_active(FAR struct eth_hdr_s *buf)
FAR struct pkt_conn_s *pkt_active(FAR struct net_driver_s *dev)
{
FAR struct pkt_conn_s *conn =
(FAR struct pkt_conn_s *)g_active_pkt_connections.head;
while (conn)
{
/* FIXME lmac in conn should have been set by pkt_bind() */
if (eth_addr_cmp(buf->dest, conn->lmac) ||
eth_addr_cmp(buf->src, conn->lmac))
if (dev->d_ifindex == conn->ifindex)
{
/* Matching connection found.. return a reference to it */

View file

@ -131,10 +131,9 @@ errout:
static int pkt_in(FAR struct net_driver_s *dev)
{
FAR struct pkt_conn_s *conn;
FAR struct eth_hdr_s *pbuf = ETHBUF;
int ret = OK;
conn = pkt_active(pbuf);
conn = pkt_active(dev);
if (conn)
{
uint16_t flags;

View file

@ -242,7 +242,7 @@ static int pkt_bind(FAR struct socket *psock,
ifindex = ((FAR struct sockaddr_ll *)addr)->sll_ifindex;
/* Get the MAC address of that interface */
/* Check if we have that interface */
dev = netdev_findbyindex(ifindex);
if (dev == NULL)
@ -250,18 +250,9 @@ static int pkt_bind(FAR struct socket *psock,
return -EADDRNOTAVAIL;
}
/* Only Ethernet is supported */
if (dev->d_lltype != NET_LL_ETHERNET &&
dev->d_lltype != NET_LL_IEEE80211)
{
return -EAFNOSUPPORT;
}
/* Put ifindex and mac address into connection */
/* Put ifindex into connection */
conn->ifindex = ifindex;
memcpy(conn->lmac, dev->d_mac.ether.ether_addr_octet, 6);
return OK;
}