Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/net bpf: support sending packets on loopback interfaces



details:   https://anonhg.NetBSD.org/src/rev/33f3c405dda5
branches:  trunk
changeset: 372451:33f3c405dda5
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Wed Nov 30 06:02:37 2022 +0000

description:
bpf: support sending packets on loopback interfaces

Previously sending packets on a loopback interface via bpf failed
because the packets are treated as AF_UNSPEC by bpf and the loopback
interface couldn't handle such packets.

This fix enables user programs to prepend a protocol family (AF_INET or
AF_INET6) to a payload.  bpf interprets it and treats a packet as so,
not just AF_UNSPEC.  The protocol family is encoded as 4 bytes, host byte
order as per DLT_NULL in the specification(*).

(*) https://www.tcpdump.org/linktypes.html

Proposed on tech-net and tech-kern

diffstat:

 sys/net/bpf.c |  28 ++++++++++++++++++++--------
 1 files changed, 20 insertions(+), 8 deletions(-)

diffs (84 lines):

diff -r bcaa2ba3d5b6 -r 33f3c405dda5 sys/net/bpf.c
--- a/sys/net/bpf.c     Wed Nov 30 04:35:53 2022 +0000
+++ b/sys/net/bpf.c     Wed Nov 30 06:02:37 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bpf.c,v 1.248 2022/11/19 08:53:06 yamt Exp $   */
+/*     $NetBSD: bpf.c,v 1.249 2022/11/30 06:02:37 ozaki-r Exp $        */
 
 /*
  * Copyright (c) 1990, 1991, 1993
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.248 2022/11/19 08:53:06 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.249 2022/11/30 06:02:37 ozaki-r Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_bpf.h"
@@ -89,6 +89,7 @@
 
 #include <net/if_arc.h>
 #include <net/if_ether.h>
+#include <net/if_types.h>
 
 #include <netinet/in.h>
 #include <netinet/if_inarp.h>
@@ -244,7 +245,7 @@
 static void    bpf_free_filter(struct bpf_filter *);
 static void    bpf_ifname(struct ifnet *, struct ifreq *);
 static void    *bpf_mcpy(void *, const void *, size_t);
-static int     bpf_movein(struct uio *, int, uint64_t,
+static int     bpf_movein(struct ifnet *, struct uio *, int, uint64_t,
                                struct mbuf **, struct sockaddr *,
                                struct bpf_filter **);
 static void    bpf_attachd(struct bpf_d *, struct bpf_if *);
@@ -323,7 +324,7 @@
 }
 
 static int
-bpf_movein(struct uio *uio, int linktype, uint64_t mtu, struct mbuf **mp,
+bpf_movein(struct ifnet *ifp, struct uio *uio, int linktype, uint64_t mtu, struct mbuf **mp,
           struct sockaddr *sockp, struct bpf_filter **wfilter)
 {
        struct mbuf *m, *m0, *n;
@@ -385,7 +386,11 @@
 
        case DLT_NULL:
                sockp->sa_family = AF_UNSPEC;
-               hlen = 0;
+               if (ifp->if_type == IFT_LOOP) {
+                       /* Set here to apply the following validations */
+                       hlen = sizeof(uint32_t);
+               } else
+                       hlen = 0;
                align = 0;
                break;
 
@@ -441,8 +446,15 @@
        }
 
        if (hlen != 0) {
-               /* move link level header in the top of mbuf to sa_data */
-               memcpy(sockp->sa_data, mtod(m0, void *), hlen);
+               if (linktype == DLT_NULL && ifp->if_type == IFT_LOOP) {
+                       uint32_t af;
+                       /* the link header indicates the address family */
+                       memcpy(&af, mtod(m0, void *), sizeof(af));
+                       sockp->sa_family = af;
+               } else {
+                       /* move link level header in the top of mbuf to sa_data */
+                       memcpy(sockp->sa_data, mtod(m0, void *), hlen);
+               }
                m0->m_data += hlen;
                m0->m_len -= hlen;
        }
@@ -853,7 +865,7 @@
                goto out;
        }
 
-       error = bpf_movein(uio, (int)bp->bif_dlt, ifp->if_mtu, &m,
+       error = bpf_movein(ifp, uio, (int)bp->bif_dlt, ifp->if_mtu, &m,
                (struct sockaddr *) &dst, &d->bd_wfilter);
        if (error)
                goto out;



Home | Main Index | Thread Index | Old Index