From owner-freebsd-ipfw@FreeBSD.ORG Sun Dec 2 00:48:43 2012 Return-Path: Delivered-To: freebsd-ipfw@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 4C04EE7E; Sun, 2 Dec 2012 00:48:43 +0000 (UTC) (envelope-from melifaro@FreeBSD.org) Received: from mail.ipfw.ru (unknown [IPv6:2a01:4f8:120:6141::2]) by mx1.freebsd.org (Postfix) with ESMTP id 162FA8FC0C; Sun, 2 Dec 2012 00:48:42 +0000 (UTC) Received: from secured.by.ipfw.ru ([95.143.220.47] helo=ws.su29.net) by mail.ipfw.ru with esmtpsa (TLSv1:CAMELLIA256-SHA:256) (Exim 4.76 (FreeBSD)) (envelope-from ) id 1Texmz-0008qu-Ll; Sun, 02 Dec 2012 04:52:10 +0400 Message-ID: <50BAA552.1010707@FreeBSD.org> Date: Sun, 02 Dec 2012 04:48:18 +0400 From: "Alexander V. Chernikov" User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:9.0) Gecko/20120121 Thunderbird/9.0 MIME-Version: 1.0 To: Hiroki Sato Subject: [CFT] Virtual BPF interfaces (was: CFR: ipfw0 pseudo-interface clonable) References: <4F96D11B.2060007@FreeBSD.org> <20120425.020518.406495893112283552.hrs@allbsd.org> <4F96E71B.9020405@FreeBSD.org> <20120427.084414.1142593201575277510.hrs@allbsd.org> <4FD4AD29.3040204@FreeBSD.org> In-Reply-To: <4FD4AD29.3040204@FreeBSD.org> Content-Type: multipart/mixed; boundary="------------080701070400070005040601" Cc: freebsd-ipfw@FreeBSD.org, Gleb Smirnoff , delphij@freebsd.org, "freebsd-net@freebsd.org" X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 02 Dec 2012 00:48:43 -0000 This is a multi-part message in MIME format. --------------080701070400070005040601 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit On 10.06.2012 18:20, Alexander V. Chernikov wrote: > On 27.04.2012 03:44, Hiroki Sato wrote: >> "Alexander V. Chernikov" wrote >> in<4F96E71B.9020405@FreeBSD.org>: >> >> me> On 24.04.2012 21:05, Hiroki Sato wrote: > > Proof-of-concept patch attached. Hopefully, libcap code is easily extendable. New version attached: * BPF code is now able to use 'virtual' interfaces without real ifnet * New bpfattach3() / bpfdetach3() routines were added to attach virtual ifaces * New BIOCGIFLIST ioctl is added to permit userland to retrieve available virtual interfaces * freebsd-specific 'platform_finddevs' version is added to libpcap code (new file) There are some rough edges (conditional code in pcap-bpf.c, lack of documentation, maybe some style issues), but generally it seems to work and does not interfere with contrib/ code much (from my point of view). ipfw log device was converted to use new bpf(4) api, see attached patch. Small example: 4:17 [0] zfscurr0# tcpdump -D 1.em0 2.em1 3.lo0 4:17 [0] zfscurr0# kldload ipfw 4:17 [0] zfscurr0# ifconfig -l em0 em1 lo0 4:17 [0] zfscurr0# tcpdump -D 1.em0 2.ipfw0 (ipfw log interface) 3.em1 4.lo0 4:40 [1] zfscurr0# ipfw add 100 count log logamount 0 ip from any to any 00100 count log ip from any to any 4:40 [0] zfscurr0# tcpdump -i ipfw0 -lns0 tcpdump: WARNING: SIOCGIFADDR: ipfw0: Device not configured tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on ipfw0, link-type EN10MB (Ethernet), capture size 65535 bytes 04:41:27.233653 IP 10.0.0.92.22 > 10.0.0.5.59076: Flags [P.], seq 2783103749:2783103941, ack 3836123088, win 1040, options [nop,nop,TS val 1668094903 ecr 564715671], length 192 04:41:27.233678 IP 10.0.0.5.59076 > 10.0.0.92.22: Flags [.], ack 0, win 1039, options [nop,nop,TS val 564715680 ecr 1668094903], length 0 Btw, do we still need warning about lack of IPv4 address? > > Unfortunately, there are problems with this approach, too. > > pcap_findalldevs() uses external to BPF method (possibly NET_RT_IFLIST), > so programs relying on that function for showing some kind of combo-box > (like wireshark) with all possible variant won't allow user to specify > such interface. > > Additionally, tcpdump assumes that passed interface name is real and > warns us that SIOCGIFADDR returns error. > > >> >> -- Hiroki > --------------080701070400070005040601 Content-Type: text/plain; name="bpf_virtual.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="bpf_virtual.diff" Index: lib/libpcap/Makefile =================================================================== --- lib/libpcap/Makefile (revision 243778) +++ lib/libpcap/Makefile (working copy) @@ -6,7 +6,7 @@ SHLIBDIR?= /lib .include LIB= pcap -SRCS= grammar.y tokdefs.h version.h pcap-bpf.c \ +SRCS= grammar.y tokdefs.h version.h pcap-bpf.c pcap-freebsd.c \ pcap.c pcap-common.c inet.c fad-getad.c gencode.c optimize.c nametoaddr.c \ etherent.c savefile.c bpf_filter.c bpf_image.c bpf_dump.c \ scanner.l sf-pcap.c sf-pcap-ng.c version.c Index: sys/net/bpf.c =================================================================== --- sys/net/bpf.c (revision 243778) +++ sys/net/bpf.c (working copy) @@ -151,6 +151,7 @@ static void bpf_detachd_locked(struct bpf_d *); static void bpf_freed(struct bpf_d *); static int bpf_movein(struct uio *, int, struct ifnet *, struct mbuf **, struct sockaddr *, int *, struct bpf_insn *); +static int bpf_getiflist(struct bpf_d *, struct bpf_iflist *); static int bpf_setif(struct bpf_d *, struct ifreq *); static void bpf_timed_out(void *); static __inline void @@ -654,7 +655,7 @@ bpf_attachd(struct bpf_d *d, struct bpf_if *bp) CTR3(KTR_NET, "%s: bpf_attach called by pid %d, adding to %s list", __func__, d->bd_pid, d->bd_writer ? "writer" : "active"); - if (op_w == 0) + if ((op_w == 0) && (!BPF_IS_VIRTUAL(bp))) EVENTHANDLER_INVOKE(bpf_track, bp->bif_ifp, bp->bif_dlt, 1); } @@ -696,7 +697,8 @@ bpf_upgraded(struct bpf_d *d) CTR2(KTR_NET, "%s: upgrade required by pid %d", __func__, d->bd_pid); - EVENTHANDLER_INVOKE(bpf_track, bp->bif_ifp, bp->bif_dlt, 1); + if (!BPF_IS_VIRTUAL(bp)) + EVENTHANDLER_INVOKE(bpf_track, bp->bif_ifp, bp->bif_dlt, 1); } /* @@ -743,6 +745,10 @@ bpf_detachd_locked(struct bpf_d *d) bpf_bpfd_cnt--; + /* Nothing to do for fake interfaces */ + if (BPF_IS_VIRTUAL(bp)) + return; + /* Call event handler iff d is attached */ if (error == 0) EVENTHANDLER_INVOKE(bpf_track, ifp, bp->bif_dlt, 0); @@ -1037,7 +1043,11 @@ bpfwrite(struct cdev *dev, struct uio *uio, int io return (ENXIO); } - ifp = d->bd_bif->bif_ifp; + /* XXX: Writing to fake interfaces is not supported */ + if ((ifp = d->bd_bif->bif_ifp) == NULL) { + d->bd_wdcount++; + return (ENXIO); + } if ((ifp->if_flags & IFF_UP) == 0) { d->bd_wdcount++; @@ -1266,10 +1276,17 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t add { struct ifnet *ifp; - if (d->bd_bif == NULL) + /* + * Lock d since other thread can do reatach in + * other thread causing d->bd_bif to be set to NULL + */ + BPFD_LOCK(d); + if ((d->bd_bif == NULL) || (BPF_IS_VIRTUAL(d->bd_bif))) { error = EINVAL; - else { + BPFD_UNLOCK(d); + } else { ifp = d->bd_bif->bif_ifp; + BPFD_UNLOCK(d); error = (*ifp->if_ioctl)(ifp, cmd, addr); } break; @@ -1325,6 +1342,13 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t add error = EINVAL; break; } + + if (BPF_IS_VIRTUAL(d->bd_bif)) { + /* Silently ignore fake interfaces */ + error = 0; + break; + } + if (d->bd_promisc == 0) { error = ifpromisc(d->bd_bif->bif_ifp, 1); if (error == 0) @@ -1390,6 +1414,12 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t add BPF_UNLOCK(); break; + case BIOCGIFLIST: + BPF_LOCK(); + error = bpf_getiflist(d, (struct bpf_iflist *)addr); + BPF_UNLOCK(); + break; + /* * Get interface name. */ @@ -1401,7 +1431,8 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t add struct ifnet *const ifp = d->bd_bif->bif_ifp; struct ifreq *const ifr = (struct ifreq *)addr; - strlcpy(ifr->ifr_name, ifp->if_xname, + strlcpy(ifr->ifr_name, BPF_IS_VIRTUAL(d->bd_bif) ? + d->bd_bif->ifname : ifp->if_xname, sizeof(ifr->ifr_name)); } BPF_UNLOCK(); @@ -1701,6 +1732,7 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t add break; } CURVNET_RESTORE(); + return (error); } @@ -1834,6 +1866,55 @@ bpf_setf(struct bpf_d *d, struct bpf_program *fp, } /* + * Get a list of available virtual interfaces + */ +static int +bpf_getiflist(struct bpf_d *d, struct bpf_iflist *ifl) +{ + int len, tot_len, error; + struct bpf_if *bp; + struct bpf_ifreply ifr; + char *buffer; + + BPF_LOCK_ASSERT(); + + tot_len = 0; + error = 0; + buffer = ifl->ifl_list; + LIST_FOREACH(bp, &bpf_iflist, bif_next) { + if (!BPF_IS_VIRTUAL(bp)) + continue; + + /* Count total length */ + len = offsetof(struct bpf_ifreply, ifr_descr) + + strlen(bp->ifdescr) + 1; + /* Align on 4-byte boundary */ + len = roundup2(len, 4); + + if (buffer != NULL) { + if (tot_len + len >= ifl->ifl_len) + return (ENOMEM); + + /* Fill in interface record */ + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_len = len; + strlcpy(ifr.ifr_name, bp->ifname, IFNAMSIZ + 1); + + copyout(&ifr, buffer, sizeof(ifr)); + /* Write interface description */ + error = copyout(bp->ifdescr, + buffer + offsetof(struct bpf_ifreply, ifr_descr), + strlen(bp->ifdescr) + 1); + + buffer += len; + } + tot_len += len; + } + ifl->ifl_len = tot_len; + return (error); +} + +/* * Detach a file from its current interface (if attached at all) and attach * to the interface indicated by the name stored in ifr. * Return an errno or 0. @@ -1847,10 +1928,19 @@ bpf_setif(struct bpf_d *d, struct ifreq *ifr) BPF_LOCK_ASSERT(); theywant = ifunit(ifr->ifr_name); - if (theywant == NULL || theywant->if_bpf == NULL) - return (ENXIO); + if (theywant == NULL || theywant->if_bpf == NULL) { + /* Check for fake interface existance */ + LIST_FOREACH(bp, &bpf_iflist, bif_next) { + if (!BPF_IS_VIRTUAL(bp)) + continue; + if (!strcmp(bp->ifname, ifr->ifr_name)) + break; + } - bp = theywant->if_bpf; + if (bp == NULL) + return (ENXIO); + } else + bp = theywant->if_bpf; /* Check if interface is not being detached from BPF */ BPFIF_RLOCK(bp); @@ -2075,7 +2165,8 @@ bpf_tap(struct bpf_if *bp, u_char *pkt, u_int pktl if (gottime < bpf_ts_quality(d->bd_tstamp)) gottime = bpf_gettime(&bt, d->bd_tstamp, NULL); #ifdef MAC - if (mac_bpfdesc_check_receive(d, bp->bif_ifp) == 0) + if (BPF_IS_VIRTUAL(bp) || + (mac_bpfdesc_check_receive(d, bp->bif_ifp) == 0)) #endif catchpacket(d, pkt, pktlen, slen, bpf_append_bytes, &bt); @@ -2085,6 +2176,7 @@ bpf_tap(struct bpf_if *bp, u_char *pkt, u_int pktl BPFIF_RUNLOCK(bp); } +/* Note i CAN be NULL */ #define BPF_CHECK_DIRECTION(d, r, i) \ (((d)->bd_direction == BPF_D_IN && (r) != (i)) || \ ((d)->bd_direction == BPF_D_OUT && (r) == (i))) @@ -2134,7 +2226,8 @@ bpf_mtap(struct bpf_if *bp, struct mbuf *m) if (gottime < bpf_ts_quality(d->bd_tstamp)) gottime = bpf_gettime(&bt, d->bd_tstamp, m); #ifdef MAC - if (mac_bpfdesc_check_receive(d, bp->bif_ifp) == 0) + if ((BPF_IS_VIRTUAL(bp)) || + (mac_bpfdesc_check_receive(d, bp->bif_ifp) == 0)) #endif catchpacket(d, (u_char *)m, pktlen, slen, bpf_append_mbuf, &bt); @@ -2190,7 +2283,8 @@ bpf_mtap2(struct bpf_if *bp, void *data, u_int dle if (gottime < bpf_ts_quality(d->bd_tstamp)) gottime = bpf_gettime(&bt, d->bd_tstamp, m); #ifdef MAC - if (mac_bpfdesc_check_receive(d, bp->bif_ifp) == 0) + if ((BPF_IS_VIRTUAL(bp)) || + (mac_bpfdesc_check_receive(d, bp->bif_ifp) == 0)) #endif catchpacket(d, (u_char *)&mb, pktlen, slen, bpf_append_mbuf, &bt); @@ -2484,6 +2578,45 @@ bpfattach2(struct ifnet *ifp, u_int dlt, u_int hdr } /* + * Attach fake interface to bpf. ifname is interface name to be attached, + * dlt is the link layer type, and hdrlen is the fixed size of the link header + * (variable length headers are not yet supporrted). + */ +void +bpfattach3(char *ifname, char *ifdescr, u_int dlt, u_int hdrlen, struct bpf_if **driverp) +{ + struct bpf_if *bp; + int len; + + len = strlen(ifdescr) + 1; + + /* Assume bpf_if to be properly aligned */ + bp = malloc(sizeof(*bp) + len, M_BPF, M_NOWAIT | M_ZERO); + if (bp == NULL) + panic("bpfattach"); + + LIST_INIT(&bp->bif_dlist); + LIST_INIT(&bp->bif_wlist); + strlcpy(bp->ifname, ifname, IFNAMSIZ + 1); + bp->ifdescr = (char *)(bp + 1); + strlcpy(bp->ifdescr, ifdescr, len); + bp->bif_dlt = dlt; + rw_init(&bp->bif_lock, "bpf interface lock"); + KASSERT(*driverp == NULL, ("bpfattach3: driverp already initialized")); + *driverp = bp; + + BPF_LOCK(); + LIST_INSERT_HEAD(&bpf_iflist, bp, bif_next); + BPF_UNLOCK(); + + bp->bif_hdrlen = hdrlen; + + if (bootverbose) + printf("%s: bpf attached\n", bp->ifname); +} + + +/* * Detach bpf from an interface. This involves detaching each descriptor * associated with the interface. Notify each descriptor as it's detached * so that any sleepers wake up and get ENXIO. @@ -2546,6 +2679,54 @@ bpfdetach(struct ifnet *ifp) } /* + * Detach bpf from the fake interface. This involves detaching each descriptor + * associated with the interface. Notify each descriptor as it's detached + * so that any sleepers wake up and get ENXIO. + */ +void +bpfdetach3(char *ifname) +{ + struct bpf_if *bp; + struct bpf_d *d; + + BPF_LOCK(); + /* Find all bpf_if struct's which reference ifp and detach them. */ + LIST_FOREACH(bp, &bpf_iflist, bif_next) { + if (!BPF_IS_VIRTUAL(bp)) + continue; + if (!strcmp(bp->ifname, ifname)) + break; + } + + if (bp != NULL) + LIST_REMOVE(bp, bif_next); + + BPF_UNLOCK(); + + if (bp != NULL) { + while ((d = LIST_FIRST(&bp->bif_dlist)) != NULL) { + bpf_detachd_locked(d); + BPFD_LOCK(d); + bpf_wakeup(d); + BPFD_UNLOCK(d); + } + /* Free writer-only descriptors */ + while ((d = LIST_FIRST(&bp->bif_wlist)) != NULL) { + bpf_detachd_locked(d); + BPFD_LOCK(d); + bpf_wakeup(d); + BPFD_UNLOCK(d); + } + + /* + * Since this interface is fake we can free our + * structure immediately. + */ + rw_destroy(&bp->bif_lock); + free(bp, M_BPF); + } +} +/* * Interface departure handler. * Note departure event does not guarantee interface is going down. */ @@ -2594,6 +2775,9 @@ bpf_getdltlist(struct bpf_d *d, struct bpf_dltlist LIST_FOREACH(bp, &bpf_iflist, bif_next) { if (bp->bif_ifp != ifp) continue; + /* Compare fake interfaces by name */ + if ((ifp == NULL) && (strcmp(d->bd_bif->ifname, bp->ifname))) + continue; if (bfl->bfl_list != NULL) { if (n >= bfl->bfl_len) return (ENOMEM); @@ -2623,7 +2807,13 @@ bpf_setdlt(struct bpf_d *d, u_int dlt) ifp = d->bd_bif->bif_ifp; LIST_FOREACH(bp, &bpf_iflist, bif_next) { - if (bp->bif_ifp == ifp && bp->bif_dlt == dlt) + if (bp->bif_ifp != ifp) + continue; + + if ((ifp == NULL) && strcmp(d->bd_bif->ifname, bp->ifname)) + continue; + + if (bp->bif_dlt == dlt) break; } @@ -2718,8 +2908,10 @@ bpfstats_fill_xbpf(struct xbpf_d *d, struct bpf_d d->bd_hlen = bd->bd_hlen; d->bd_bufsize = bd->bd_bufsize; d->bd_pid = bd->bd_pid; - strlcpy(d->bd_ifname, - bd->bd_bif->bif_ifp->if_xname, IFNAMSIZ); + if (!BPF_IS_VIRTUAL(bd->bd_bif)) + strlcpy(d->bd_ifname, bd->bd_bif->bif_ifp->if_xname, IFNAMSIZ); + else + strlcpy(d->bd_ifname, bd->bd_bif->ifname, IFNAMSIZ); d->bd_locked = bd->bd_locked; d->bd_wcount = bd->bd_wcount; d->bd_wdcount = bd->bd_wdcount; Index: sys/net/bpf.h =================================================================== --- sys/net/bpf.h (revision 243778) +++ sys/net/bpf.h (working copy) @@ -147,6 +147,7 @@ struct bpf_zbuf { #define BIOCSETFNR _IOW('B', 130, struct bpf_program) #define BIOCGTSTAMP _IOR('B', 131, u_int) #define BIOCSTSTAMP _IOW('B', 132, u_int) +#define BIOCGIFLIST _IOWR('B', 133, struct bpf_iflist) /* Obsolete */ #define BIOCGSEESENT BIOCGDIRECTION @@ -1224,6 +1225,25 @@ struct bpf_dltlist { u_int *bfl_list; /* array of DLTs */ }; +#define BIFNAMSIZ 16 +#if !defined(_KERNEL) || defined(BPF_INTERNAL) +/* + * Structure to retrieve virtual BPF intefaces. + */ +struct bpf_iflist { + u_int ifl_len; /* total memory size */ + u_int ifl_ver; /* version (set to 0) */ + char *ifl_list; /* array of interfaces */ +}; + +struct bpf_ifreply { + u_int ifr_len; /* Total record length */ + u_int ifr_spare[3]; /* Spare data */ + char ifr_name[BIFNAMSIZ + 1]; /* Interface name */ + char ifr_descr[0]; /* Interface description (variable) */ +}; +#endif + #ifdef _KERNEL #ifdef MALLOC_DECLARE MALLOC_DECLARE(M_BPF); @@ -1262,6 +1282,8 @@ struct bpf_if { struct rwlock bif_lock; /* interface lock */ LIST_HEAD(, bpf_d) bif_wlist; /* writer-only list */ int flags; /* Interface flags */ + char ifname[IFNAMSIZ + 1]; /* Virtual interface name */ + char *ifdescr; /* Virtual interface description */ #endif }; @@ -1272,7 +1294,9 @@ void bpf_mtap(struct bpf_if *, struct mbuf *); void bpf_mtap2(struct bpf_if *, void *, u_int, struct mbuf *); void bpfattach(struct ifnet *, u_int, u_int); void bpfattach2(struct ifnet *, u_int, u_int, struct bpf_if **); +void bpfattach3(char *, char *, u_int, u_int, struct bpf_if **); void bpfdetach(struct ifnet *); +void bpfdetach3(char *); void bpfilterattach(int); u_int bpf_filter(const struct bpf_insn *, u_char *, u_int, u_int); Index: sys/net/bpfdesc.h =================================================================== --- sys/net/bpfdesc.h (revision 243778) +++ sys/net/bpfdesc.h (working copy) @@ -102,6 +102,8 @@ struct bpf_d { u_char bd_compat32; /* 32-bit stream on LP64 system */ }; +#define BPF_IS_VIRTUAL(x) ((x)->bif_ifp == NULL) + /* Values for bd_state */ #define BPF_IDLE 0 /* no select in progress */ #define BPF_WAITING 1 /* waiting for read timeout in select */ Index: sys/netpfil/ipfw/ip_fw_log.c =================================================================== --- sys/netpfil/ipfw/ip_fw_log.c (revision 243778) +++ sys/netpfil/ipfw/ip_fw_log.c (working copy) @@ -93,142 +93,31 @@ ipfw_log_bpf(int onoff) { } #else /* !WITHOUT_BPF */ -static struct ifnet *log_if; /* hook to attach to bpf */ -static struct rwlock log_if_lock; -#define LOGIF_LOCK_INIT(x) rw_init(&log_if_lock, "ipfw log_if lock") -#define LOGIF_LOCK_DESTROY(x) rw_destroy(&log_if_lock) -#define LOGIF_RLOCK(x) rw_rlock(&log_if_lock) -#define LOGIF_RUNLOCK(x) rw_runlock(&log_if_lock) -#define LOGIF_WLOCK(x) rw_wlock(&log_if_lock) -#define LOGIF_WUNLOCK(x) rw_wunlock(&log_if_lock) +static struct bpf_if *log_bpfif = NULL; /* hook to attach to bpf */ +#define BPF_IFNAME "ipfw0" +#define IPFW_MTAP(_if_bpf,_data,_dlen,_m) do { \ + if (bpf_peers_present(_if_bpf)) { \ + M_ASSERTVALID(_m); \ + bpf_mtap2((_if_bpf),(_data),(_dlen),(_m)); \ + } \ +} while (0) -static const char ipfwname[] = "ipfw"; - -/* we use this dummy function for all ifnet callbacks */ -static int -log_dummy(struct ifnet *ifp, u_long cmd, caddr_t addr) -{ - return EINVAL; -} - -static int -ipfw_log_output(struct ifnet *ifp, struct mbuf *m, - struct sockaddr *dst, struct route *ro) -{ - if (m != NULL) - FREE_PKT(m); - return EINVAL; -} - -static void -ipfw_log_start(struct ifnet* ifp) -{ - panic("ipfw_log_start() must not be called"); -} - static const u_char ipfwbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -static int -ipfw_log_clone_match(struct if_clone *ifc, const char *name) -{ - - return (strncmp(name, ipfwname, sizeof(ipfwname) - 1) == 0); -} - -static int -ipfw_log_clone_create(struct if_clone *ifc, char *name, size_t len, - caddr_t params) -{ - int error; - int unit; - struct ifnet *ifp; - - error = ifc_name2unit(name, &unit); - if (error) - return (error); - - error = ifc_alloc_unit(ifc, &unit); - if (error) - return (error); - - ifp = if_alloc(IFT_PFLOG); - if (ifp == NULL) { - ifc_free_unit(ifc, unit); - return (ENOSPC); - } - ifp->if_dname = ipfwname; - ifp->if_dunit = unit; - snprintf(ifp->if_xname, IFNAMSIZ, "%s%d", ipfwname, unit); - strlcpy(name, ifp->if_xname, len); - ifp->if_mtu = 65536; - ifp->if_flags = IFF_UP | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = (void *)log_dummy; - ifp->if_ioctl = log_dummy; - ifp->if_start = ipfw_log_start; - ifp->if_output = ipfw_log_output; - ifp->if_addrlen = 6; - ifp->if_hdrlen = 14; - ifp->if_broadcastaddr = ipfwbroadcastaddr; - ifp->if_baudrate = IF_Mbps(10); - - LOGIF_WLOCK(); - if (log_if == NULL) - log_if = ifp; - else { - LOGIF_WUNLOCK(); - if_free(ifp); - ifc_free_unit(ifc, unit); - return (EEXIST); - } - LOGIF_WUNLOCK(); - if_attach(ifp); - bpfattach(ifp, DLT_EN10MB, 14); - - return (0); -} - -static int -ipfw_log_clone_destroy(struct if_clone *ifc, struct ifnet *ifp) -{ - int unit; - - if (ifp == NULL) - return (0); - - LOGIF_WLOCK(); - if (log_if != NULL && ifp == log_if) - log_if = NULL; - else { - LOGIF_WUNLOCK(); - return (EINVAL); - } - LOGIF_WUNLOCK(); - - unit = ifp->if_dunit; - bpfdetach(ifp); - if_detach(ifp); - if_free(ifp); - ifc_free_unit(ifc, unit); - - return (0); -} - -static struct if_clone *ipfw_log_cloner; - void ipfw_log_bpf(int onoff) { - if (onoff) { - LOGIF_LOCK_INIT(); - ipfw_log_cloner = if_clone_advanced(ipfwname, 0, - ipfw_log_clone_match, ipfw_log_clone_create, - ipfw_log_clone_destroy); - } else { - if_clone_detach(ipfw_log_cloner); - LOGIF_LOCK_DESTROY(); - } + if (onoff) { + if (log_bpfif) + return; + bpfattach3(BPF_IFNAME, "ipfw log interface", DLT_EN10MB, 14, &log_bpfif); + } else { + if (log_bpfif != NULL) + bpfdetach3(BPF_IFNAME); + log_bpfif = NULL; + } } #endif /* !WITHOUT_BPF */ @@ -247,20 +136,18 @@ ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw if (V_fw_verbose == 0) { #ifndef WITHOUT_BPF - LOGIF_RLOCK(); - if (log_if == NULL || log_if->if_bpf == NULL) { - LOGIF_RUNLOCK(); + if (log_bpfif == NULL) return; - } if (args->eh) /* layer2, use orig hdr */ - BPF_MTAP2(log_if, args->eh, ETHER_HDR_LEN, m); + IPFW_MTAP(log_bpfif, args->eh, ETHER_HDR_LEN, m); else - /* Add fake header. Later we will store + /* + * Add fake header. Later we will store * more info in the header. */ - BPF_MTAP2(log_if, "DDDDDDSSSSSS\x08\x00", ETHER_HDR_LEN, m); - LOGIF_RUNLOCK(); + IPFW_MTAP(log_bpfif, "DDDDDDSSSSSS\x08\x00", + ETHER_HDR_LEN, m); #endif /* !WITHOUT_BPF */ return; } Index: contrib/libpcap/pcap-bpf.c =================================================================== --- contrib/libpcap/pcap-bpf.c (revision 243778) +++ contrib/libpcap/pcap-bpf.c (working copy) @@ -132,6 +132,8 @@ static int bpf_load(char *errbuf); #include "pcap-snf.h" #endif /* HAVE_SNF_API */ +#include "pcap-freebsd.h" + #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif @@ -2311,6 +2313,8 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char if (snf_platform_finddevs(alldevsp, errbuf) < 0) return (-1); #endif /* HAVE_SNF_API */ + if (freebsd_platform_finddevs(alldevsp, errbuf) < 0) + return (-1); return (0); } --- /dev/null 2012-12-02 04:22:01.000000000 +0400 +++ contrib/libpcap/pcap-freebsd.h 2012-12-02 02:50:44.251624161 +0400 @@ -0,0 +1 @@ +int freebsd_platform_finddevs(pcap_if_t **devlistp, char *errbuf); --- /dev/null 2012-12-02 04:22:01.000000000 +0400 +++ contrib/libpcap/pcap-freebsd.c 2012-12-02 04:22:11.404710869 +0400 @@ -0,0 +1,138 @@ +/* + * pcap-freebsd.c: Packet capture advanced interface to the FreeBSD kernel + * + * License: BSD + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "pcap-int.h" + +int +freebsd_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) +{ + int ret; + + struct bpf_iflist ifl; + struct bpf_ifreply *ifr; + char *device = "/dev/bpf"; + int fd, i, len, res; + caddr_t databuf; + + if ((fd = open(device, O_RDWR)) == -1) { + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "(cannot open device) %s: %s", + device, pcap_strerror(errno)); + + return (-1); + } + + res = 0; + + for (i = 0; i < 10; i++) { + /* Get size */ + memset(&ifl, 0, sizeof(ifl)); + + if (ioctl(fd, BIOCGIFLIST, (caddr_t)&ifl) != 0) { + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "(cannot get interface list length): %s", + pcap_strerror(errno)); + + close(fd); + return (-1); + } + + /* Allocate requested length */ + len = ifl.ifl_len + 1024; + databuf = calloc(1, len); + + /* Try to read data */ + ifl.ifl_list = databuf; + ifl.ifl_len = len; + + if (ioctl(fd, BIOCGIFLIST, (caddr_t)&ifl) != 0) { + if (errno == ENOMEM) { + /* + * Probably new interface added. + * Let's try another time. + */ + free(databuf); + databuf = NULL; + ifl.ifl_len = 0; + continue; + } + + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "(cannot read interface list): %s", + pcap_strerror(errno)); + + close(fd); + return (-1); + } + + res = 1; + break; + } + + close(fd); + + if (res == 0) { + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "(error reading interface list): retries exceeded"); + return (-1); + } + + /* Okay, let's parse */ + for (len = 0; len < ifl.ifl_len; ) { + ifr = (struct bpf_ifreply *)&databuf[len]; + + if (pcap_add_if(alldevsp, ifr->ifr_name, 0, + ifr->ifr_descr, errbuf) < 0) + return (-1); + + len += ifr->ifr_len; + } + + return (0); +} + --------------080701070400070005040601-- From owner-freebsd-ipfw@FreeBSD.ORG Mon Dec 3 08:11:43 2012 Return-Path: Delivered-To: freebsd-ipfw@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 707C02E6; Mon, 3 Dec 2012 08:11:43 +0000 (UTC) (envelope-from glebius@FreeBSD.org) Received: from cell.glebius.int.ru (glebius.int.ru [81.19.69.10]) by mx1.freebsd.org (Postfix) with ESMTP id DC12E8FC15; Mon, 3 Dec 2012 08:11:42 +0000 (UTC) Received: from cell.glebius.int.ru (localhost [127.0.0.1]) by cell.glebius.int.ru (8.14.5/8.14.5) with ESMTP id qB38BZHS040405; Mon, 3 Dec 2012 12:11:35 +0400 (MSK) (envelope-from glebius@FreeBSD.org) Received: (from glebius@localhost) by cell.glebius.int.ru (8.14.5/8.14.5/Submit) id qB38BYgH040404; Mon, 3 Dec 2012 12:11:34 +0400 (MSK) (envelope-from glebius@FreeBSD.org) X-Authentication-Warning: cell.glebius.int.ru: glebius set sender to glebius@FreeBSD.org using -f Date: Mon, 3 Dec 2012 12:11:34 +0400 From: Gleb Smirnoff To: "Alexander V. Chernikov" Subject: Re: [CFT] Virtual BPF interfaces (was: CFR: ipfw0 pseudo-interface clonable) Message-ID: <20121203081134.GO14202@glebius.int.ru> References: <4F96D11B.2060007@FreeBSD.org> <20120425.020518.406495893112283552.hrs@allbsd.org> <4F96E71B.9020405@FreeBSD.org> <20120427.084414.1142593201575277510.hrs@allbsd.org> <4FD4AD29.3040204@FreeBSD.org> <50BAA552.1010707@FreeBSD.org> MIME-Version: 1.0 Content-Type: text/plain; charset=koi8-r Content-Disposition: inline In-Reply-To: <50BAA552.1010707@FreeBSD.org> User-Agent: Mutt/1.5.21 (2010-09-15) Cc: freebsd-ipfw@FreeBSD.org, Hiroki Sato , delphij@FreeBSD.org, "freebsd-net@freebsd.org" X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 03 Dec 2012 08:11:43 -0000 On Sun, Dec 02, 2012 at 04:48:18AM +0400, Alexander V. Chernikov wrote: A> On 10.06.2012 18:20, Alexander V. Chernikov wrote: A> > On 27.04.2012 03:44, Hiroki Sato wrote: A> >> "Alexander V. Chernikov" wrote A> >> in<4F96E71B.9020405@FreeBSD.org>: A> >> A> >> me> On 24.04.2012 21:05, Hiroki Sato wrote: A> > A> > Proof-of-concept patch attached. A> A> Hopefully, libcap code is easily extendable. A> New version attached: A> * BPF code is now able to use 'virtual' interfaces without real ifnet A> * New bpfattach3() / bpfdetach3() routines were added to attach virtual A> ifaces A> * New BIOCGIFLIST ioctl is added to permit userland to retrieve A> available virtual interfaces A> * freebsd-specific 'platform_finddevs' version is added to libpcap code A> (new file) A> A> There are some rough edges (conditional code in pcap-bpf.c, lack of A> documentation, maybe some style issues), but generally it seems to work A> and does not interfere with contrib/ code much (from my point of view). A> A> ipfw log device was converted to use new bpf(4) api, see attached patch. Nice proof of concept, Alexander! What does prevent us from unifing all bpf providers to be "virtual" in current terms? I think if we finish divorce between ifnet and bpf, the code would get simplier and you can proceed further with reducing locking overhead. -- Totus tuus, Glebius. From owner-freebsd-ipfw@FreeBSD.ORG Mon Dec 3 11:06:46 2012 Return-Path: Delivered-To: freebsd-ipfw@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 4840E96 for ; Mon, 3 Dec 2012 11:06:46 +0000 (UTC) (envelope-from owner-bugmaster@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:1900:2254:206c::16:87]) by mx1.freebsd.org (Postfix) with ESMTP id 2CEE18FC19 for ; Mon, 3 Dec 2012 11:06:46 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.5/8.14.5) with ESMTP id qB3B6kIs027583 for ; Mon, 3 Dec 2012 11:06:46 GMT (envelope-from owner-bugmaster@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.5/8.14.5/Submit) id qB3B6j9L027581 for freebsd-ipfw@FreeBSD.org; Mon, 3 Dec 2012 11:06:45 GMT (envelope-from owner-bugmaster@FreeBSD.org) Date: Mon, 3 Dec 2012 11:06:45 GMT Message-Id: <201212031106.qB3B6j9L027581@freefall.freebsd.org> X-Authentication-Warning: freefall.freebsd.org: gnats set sender to owner-bugmaster@FreeBSD.org using -f From: FreeBSD bugmaster To: freebsd-ipfw@FreeBSD.org Subject: Current problem reports assigned to freebsd-ipfw@FreeBSD.org X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 03 Dec 2012 11:06:46 -0000 Note: to view an individual PR, use: http://www.freebsd.org/cgi/query-pr.cgi?pr=(number). The following is a listing of current problems submitted by FreeBSD users. These represent problem reports covering all versions including experimental development code and obsolete releases. S Tracker Resp. Description -------------------------------------------------------------------------------- o kern/169206 ipfw [ipfw] ipfw does not flush entries in table o conf/167822 ipfw [ipfw] [patch] start script doesn't load firewall_type o kern/166406 ipfw [ipfw] ipfw does not set ALTQ identifier for ipv6 traf o kern/165939 ipfw [ipw] bug: incomplete firewall rules loaded if tables o kern/165190 ipfw [ipfw] [lo] [patch] loopback interface is not marking f kern/163873 ipfw [ipfw] ipfw fwd does not work with 'via interface' in o kern/158066 ipfw [ipfw] ipfw + netgraph + multicast = multicast packets o kern/157796 ipfw [ipfw] IPFW in-kernel NAT nat loopback / Default Route o kern/157689 ipfw [ipfw] ipfw nat config does not accept nonexistent int f kern/155927 ipfw [ipfw] ipfw stops to check packets for compliance with o bin/153252 ipfw [ipfw][patch] ipfw lockdown system in subsequent call o kern/153161 ipfw [ipfw] does not support specifying rules with ICMP cod o kern/152113 ipfw [ipfw] page fault on 8.1-RELEASE caused by certain amo o kern/148827 ipfw [ipfw] divert broken with in-kernel ipfw o kern/148689 ipfw [ipfw] antispoof wrongly triggers on link local IPv6 a o kern/148430 ipfw [ipfw] IPFW schedule delete broken. o kern/148091 ipfw [ipfw] ipfw ipv6 handling broken. o kern/143973 ipfw [ipfw] [panic] ipfw forward option causes kernel reboo o kern/143621 ipfw [ipfw] [dummynet] [patch] dummynet and vnet use result o kern/137346 ipfw [ipfw] ipfw nat redirect_proto is broken o kern/137232 ipfw [ipfw] parser troubles o kern/135476 ipfw [ipfw] IPFW table breaks after adding a large number o o kern/129036 ipfw [ipfw] 'ipfw fwd' does not change outgoing interface n p kern/128260 ipfw [ipfw] [patch] ipfw_divert damages IPv6 packets o kern/127230 ipfw [ipfw] [patch] Feature request to add UID and/or GID l f kern/122963 ipfw [ipfw] tcpdump does not show packets redirected by 'ip s kern/121807 ipfw [request] TCP and UDP port_table in ipfw o kern/121122 ipfw [ipfw] [patch] add support to ToS IP PRECEDENCE fields o kern/116009 ipfw [ipfw] [patch] Ignore errors when loading ruleset from o bin/104921 ipfw [patch] ipfw(8) sometimes treats ipv6 input as ipv4 (a o kern/104682 ipfw [ipfw] [patch] Some minor language consistency fixes a o kern/103454 ipfw [ipfw] [patch] [request] add a facility to modify DF b o kern/103328 ipfw [ipfw] [request] sugestions about ipfw table o kern/102471 ipfw [ipfw] [patch] add tos and dscp support o kern/97951 ipfw [ipfw] [patch] ipfw does not tie interface details to o kern/95084 ipfw [ipfw] [regression] [patch] IPFW2 ignores "recv/xmit/v o kern/86957 ipfw [ipfw] [patch] ipfw mac logging o bin/83046 ipfw [ipfw] ipfw2 error: "setup" is allowed for icmp, but s o kern/82724 ipfw [ipfw] [patch] [request] Add setnexthop and defaultrou o bin/78785 ipfw [patch] ipfw(8) verbosity locks machine if /etc/rc.fir o bin/65961 ipfw [ipfw] ipfw2 memory corruption inside add() o kern/60719 ipfw [ipfw] Headerless fragments generate cryptic error mes s kern/55984 ipfw [ipfw] [patch] time based firewalling support for ipfw o kern/48172 ipfw [ipfw] [patch] ipfw does not log size and flags o kern/46159 ipfw [ipfw] [patch] [request] ipfw dynamic rules lifetime f a kern/26534 ipfw [ipfw] Add an option to ipfw to log gid/uid of who cau 46 problems total. From owner-freebsd-ipfw@FreeBSD.ORG Mon Dec 3 12:21:48 2012 Return-Path: Delivered-To: freebsd-ipfw@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id ABDB230F; Mon, 3 Dec 2012 12:21:48 +0000 (UTC) (envelope-from melifaro@FreeBSD.org) Received: from mail.ipfw.ru (unknown [IPv6:2a01:4f8:120:6141::2]) by mx1.freebsd.org (Postfix) with ESMTP id 39C778FC12; Mon, 3 Dec 2012 12:21:48 +0000 (UTC) Received: from [2a02:6b8:0:401:222:4dff:fe50:cd2f] (helo=dhcp170-36-red.yandex.net) by mail.ipfw.ru with esmtpsa (TLSv1:CAMELLIA256-SHA:256) (Exim 4.76 (FreeBSD)) (envelope-from ) id 1TfV5I-00053l-89; Mon, 03 Dec 2012 16:25:16 +0400 Message-ID: <50BC989E.3080303@FreeBSD.org> Date: Mon, 03 Dec 2012 16:18:38 +0400 From: "Alexander V. Chernikov" User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:13.0) Gecko/20120627 Thunderbird/13.0.1 MIME-Version: 1.0 To: Gleb Smirnoff Subject: Re: [CFT] Virtual BPF interfaces References: <4F96D11B.2060007@FreeBSD.org> <20120425.020518.406495893112283552.hrs@allbsd.org> <4F96E71B.9020405@FreeBSD.org> <20120427.084414.1142593201575277510.hrs@allbsd.org> <4FD4AD29.3040204@FreeBSD.org> <50BAA552.1010707@FreeBSD.org> <20121203081134.GO14202@glebius.int.ru> In-Reply-To: <20121203081134.GO14202@glebius.int.ru> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-ipfw@FreeBSD.org, Hiroki Sato , delphij@FreeBSD.org, "freebsd-net@freebsd.org" X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 03 Dec 2012 12:21:48 -0000 On 03.12.2012 12:11, Gleb Smirnoff wrote: > On Sun, Dec 02, 2012 at 04:48:18AM +0400, Alexander V. Chernikov wrote: > A> On 10.06.2012 18:20, Alexander V. Chernikov wrote: > A> > On 27.04.2012 03:44, Hiroki Sato wrote: > A> >> "Alexander V. Chernikov" wrote > A> >> in<4F96E71B.9020405@FreeBSD.org>: > A> >> > A> >> me> On 24.04.2012 21:05, Hiroki Sato wrote: > A> > > A> > Proof-of-concept patch attached. > A> > A> Hopefully, libcap code is easily extendable. > A> New version attached: > A> * BPF code is now able to use 'virtual' interfaces without real ifnet > A> * New bpfattach3() / bpfdetach3() routines were added to attach virtual > A> ifaces > A> * New BIOCGIFLIST ioctl is added to permit userland to retrieve > A> available virtual interfaces > A> * freebsd-specific 'platform_finddevs' version is added to libpcap code > A> (new file) > A> > A> There are some rough edges (conditional code in pcap-bpf.c, lack of > A> documentation, maybe some style issues), but generally it seems to work > A> and does not interfere with contrib/ code much (from my point of view). > A> > A> ipfw log device was converted to use new bpf(4) api, see attached patch. > > Nice proof of concept, Alexander! > > What does prevent us from unifing all bpf providers to be "virtual" in > current terms? I think if we finish divorce between ifnet and bpf, the code > would get simplier and you can proceed further with reducing locking > overhead. We have to jump from ifnet to the list of per-ifnet BPF consumers somehow, so I'm not sure if we can do much more here. BPF itself doesn't require much from parent ifnet. What I really want to do next is the following: 1) Make BPF_PEERS_PRESENT(ifp) to be (ifp->if_bpf != NULL). This saves some processing time and permits 'bpf_if' to be be totally opaque without any hacks. 2) Set if_bpf pointer IFF there are some consumers (and set it back to NULL when all consumers are detached). This should work well for 'main' BPF DLT, but single (currently, 802.11) interface can hold more than one DLTs. Probably we can save dst pointer passed to bpfattach2() to given bpf_if structure, and set this value instead of ->if_bpf. This, however, can lead to hard-to-find problems, since bpfattach[2] is usually not called by driver directly. > -- WBR, Alexander From owner-freebsd-ipfw@FreeBSD.ORG Mon Dec 3 17:34:15 2012 Return-Path: Delivered-To: freebsd-ipfw@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id D8966F0B for ; Mon, 3 Dec 2012 17:34:15 +0000 (UTC) (envelope-from andre@freebsd.org) Received: from c00l3r.networx.ch (c00l3r.networx.ch [62.48.2.2]) by mx1.freebsd.org (Postfix) with ESMTP id 3E0548FC1A for ; Mon, 3 Dec 2012 17:34:14 +0000 (UTC) Received: (qmail 92577 invoked from network); 3 Dec 2012 19:04:45 -0000 Received: from c00l3r.networx.ch (HELO [127.0.0.1]) ([62.48.2.2]) (envelope-sender ) by c00l3r.networx.ch (qmail-ldap-1.03) with SMTP for ; 3 Dec 2012 19:04:45 -0000 Message-ID: <50BCE294.4070409@freebsd.org> Date: Mon, 03 Dec 2012 18:34:12 +0100 From: Andre Oppermann User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20121026 Thunderbird/16.0.2 MIME-Version: 1.0 To: "Alexander V. Chernikov" Subject: Re: [CFT] Virtual BPF interfaces References: <4F96D11B.2060007@FreeBSD.org> <20120425.020518.406495893112283552.hrs@allbsd.org> <4F96E71B.9020405@FreeBSD.org> <20120427.084414.1142593201575277510.hrs@allbsd.org> <4FD4AD29.3040204@FreeBSD.org> <50BAA552.1010707@FreeBSD.org> <20121203081134.GO14202@glebius.int.ru> <50BC989E.3080303@FreeBSD.org> In-Reply-To: <50BC989E.3080303@FreeBSD.org> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-ipfw@FreeBSD.org, Gleb Smirnoff , delphij@FreeBSD.org, Hiroki Sato , "freebsd-net@freebsd.org" X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 03 Dec 2012 17:34:16 -0000 On 03.12.2012 13:18, Alexander V. Chernikov wrote: > On 03.12.2012 12:11, Gleb Smirnoff wrote: >> On Sun, Dec 02, 2012 at 04:48:18AM +0400, Alexander V. Chernikov wrote: >> A> On 10.06.2012 18:20, Alexander V. Chernikov wrote: >> A> > On 27.04.2012 03:44, Hiroki Sato wrote: >> A> >> "Alexander V. Chernikov" wrote >> A> >> in<4F96E71B.9020405@FreeBSD.org>: >> A> >> >> A> >> me> On 24.04.2012 21:05, Hiroki Sato wrote: >> A> > >> A> > Proof-of-concept patch attached. >> A> >> A> Hopefully, libcap code is easily extendable. >> A> New version attached: >> A> * BPF code is now able to use 'virtual' interfaces without real ifnet >> A> * New bpfattach3() / bpfdetach3() routines were added to attach virtual >> A> ifaces >> A> * New BIOCGIFLIST ioctl is added to permit userland to retrieve >> A> available virtual interfaces >> A> * freebsd-specific 'platform_finddevs' version is added to libpcap code >> A> (new file) >> A> >> A> There are some rough edges (conditional code in pcap-bpf.c, lack of >> A> documentation, maybe some style issues), but generally it seems to work >> A> and does not interfere with contrib/ code much (from my point of view). >> A> >> A> ipfw log device was converted to use new bpf(4) api, see attached patch. >> >> Nice proof of concept, Alexander! >> >> What does prevent us from unifing all bpf providers to be "virtual" in >> current terms? I think if we finish divorce between ifnet and bpf, the code >> would get simplier and you can proceed further with reducing locking >> overhead. > > We have to jump from ifnet to the list of per-ifnet BPF consumers somehow, so I'm not sure if we can > do much more here. BPF itself doesn't require much from parent ifnet. > > What I really want to do next is the following: > > 1) Make BPF_PEERS_PRESENT(ifp) to be (ifp->if_bpf != NULL). This saves some processing time and > permits 'bpf_if' to be be totally opaque without any hacks. You have to be a bit careful with locking, or rather not locking. When the consumer is not doing any lock operations it may not (immediately) pick up that the pointer was changed on another CPU. > 2) Set if_bpf pointer IFF there are some consumers (and set it back to NULL when all consumers are > detached). This should work well for 'main' BPF DLT, but single (currently, 802.11) interface can > hold more than one DLTs. Probably we can save dst pointer passed to bpfattach2() to given bpf_if > structure, and set this value instead of ->if_bpf. > This, however, can lead to hard-to-find problems, since bpfattach[2] is usually not called by driver > directly. Separate from the above BPF on the output side may be optimized by passing the mbuf not from drv*_start() but from drv*_txeof(). There may be a few microseconds delay but a mbuf (-chain) copy is saved in the transmit path. As an additional benefit only those packets that actually were transmitted are persented to bpf. -- Andre From owner-freebsd-ipfw@FreeBSD.ORG Tue Dec 4 01:31:42 2012 Return-Path: Delivered-To: freebsd-ipfw@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id A5786D59 for ; Tue, 4 Dec 2012 01:31:42 +0000 (UTC) (envelope-from prvs=1685a61a7f=evendas@krazer.com.br) Received: from krazer.com.br (usaimport.com.br [74.208.147.131]) by mx1.freebsd.org (Postfix) with ESMTP id 1BEFE8FC23 for ; Tue, 4 Dec 2012 01:31:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple; d=krazer.com.br; s=MDaemon; t=1354583459; x=1355188259; q=dns/txt; h=DomainKey-Signature: Received:From:To:Subject:Date:MIME-Version:Content-Type: Message-ID; bh=/AGF6JRzB/J7iTsWt8UkF/2jJ0/KNRujXWNnXTa6qHA=; b=V WPE6tDE8dOT05divqrTLJhBdXVf4dv8id8gRvoTHF+5Zywy+xGr0gRvXQyWAO+rj BQXAucD70vlPhesquh1SrG6K6oN5Cof8UoAZawRph1USC63JVbhC6SKIeawR+cCX 80qZYUY71Me63But9GbdnCh2VL10dJoJ9EhUDkAlAk= DomainKey-Signature: a=rsa-sha1; s=MDaemon; d=krazer.com.br; c=simple; q=dns; h=from:message-id; b=WG1P4wHJ2FSAp65U0mPQIyiPDyTjU8hB9Pi6XzTnBrxJhCMjhgKAl1yNP2ft Ti2W/ytZCYYQlgqiY5MicV3FI2e2c2Qc5/aqZ5qhBgTNMibJkQxTTe0oM 1pfoZ7GcDpKWvysHZRozat60z6jVIVN78iUEkmLEVhUzXd3VxEmZdQ=; X-MDAV-Processed: allearth.com.br, Mon, 03 Dec 2012 23:10:59 -0200 Received: from krazer by allearth.com.br (MDaemon PRO v11.0.0) with ESMTP id md50003170652.msg for ; Mon, 03 Dec 2012 23:10:58 -0200 X-Spam-Processed: allearth.com.br, Mon, 03 Dec 2012 23:10:58 -0200 (not processed: message from trusted or authenticated source) X-Authenticated-Sender: evendas@krazer.com.br X-MDRemoteIP: 74.208.167.75 X-Return-Path: prvs=1685a61a7f=evendas@krazer.com.br X-Envelope-From: evendas@krazer.com.br X-MDaemon-Deliver-To: freebsd-ipfw@freebsd.org From: "Vendas Krazer Technologies" To: Subject: =?utf-8?B?Tm92YSBDUEUgS3JhemVyIFNreSBTdGF0aW9uIDVHSHo=?= =?utf-8?B?IE4gLSBDUEUgQW50ZW5hIEludGVncmFkYSBkZSAxOGRCaQ==?= =?utf-8?B?IGUgQ29tIFNhw61kYSBwYXJhIEFudGVuYSBFeHRlcm5h?= Date: Mon, 03 Dec 2012 22:08:16 -0200 MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=45652905_3502_4801_0078_850943129657" Message-ID: X-Mailer: Clientes Krazer X-Content-Filtered-By: Mailman/MimeDel 2.1.14 X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 04 Dec 2012 01:31:42 -0000 This is a multi-part message in MIME format. ------=45652905_3502_4801_0078_850943129657 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Lan=C3=A7amento CPE Krazer Sky Station 5GHz N Voc=C3=AA cliente pediu que a Krazer fizesse uma nova CPE num formato mais = estiloso, pequena, de menor tamanho e que tivesse novas funcionabilidade, m= ais especificamente acesso f=C3=A1cil ao bot=C3=A3o de reset, prote=C3=A7= =C3=A3o contra queima e a t=C3=A3o desejada SA=C3=8DDA PARA ANTENA EXTERNA!= !! R$ 179.90 Antena Integrada de 18dBi 60=C2=BA Duas Portas de Rede Lan e Wan PA Real de 630mW e LNA Ultra Ganho PoE Passivo com Prote=C3=A7=C3=A3o Dupla de 12 a 24V Fonte Chaveada 12V Full Range 110 a 220V Exclusiva Sa=C3=ADda para Antena Externa Homologa=C3=A7=C3=A3o Anatel 0269-11-5280 Instala=C3=A7=C3=A3o R=C3=A1pida e Simples. Software Amigavel e em Portugu=C3=AAs! Suporte a PPPoE Wisp Cliente! Controle de Banda! Excelente sinal de recep=C3=A7=C3=A3o! Longa Dist=C3=A2ncia! Fa=C3=A7a um teste em sua rede e compare com os concorrentes, muito mais si= nal que UBNT, muito mais dados, transmiss=C3=A3o de quase 90Mbps TCP/IP con= tinuamente! Lat=C3=AAncia de rede de 1 a 5 ms com carga completa! Contate-nos Val Campos // Carla Maria // Eder Roberto Email / MSN: vendas@allearth.com.br Vendas / SAC (19) 3256-5557 (19) 3245-0708 www.krazer.com.br Envio de Email n=C3=A3o autorizado =C3=A9 crime, n=C3=A3o seja o vil=C3=A3o= da hist=C3=B3ria! Email =C3=A9 protegido sobre sigilo fiscal e federal. Le= i Federal Brasil. ------=45652905_3502_4801_0078_850943129657-- From owner-freebsd-ipfw@FreeBSD.ORG Thu Dec 6 09:13:46 2012 Return-Path: Delivered-To: freebsd-ipfw@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 8F3E8145; Thu, 6 Dec 2012 09:13:46 +0000 (UTC) (envelope-from ermal.luci@gmail.com) Received: from mail-qa0-f47.google.com (mail-qa0-f47.google.com [209.85.216.47]) by mx1.freebsd.org (Postfix) with ESMTP id 2E2538FC15; Thu, 6 Dec 2012 09:13:45 +0000 (UTC) Received: by mail-qa0-f47.google.com with SMTP id a19so546446qad.13 for ; Thu, 06 Dec 2012 01:13:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:date:x-google-sender-auth:message-id:subject :from:to:content-type; bh=E8vbsDDCOqpkv5xjsDU6z4mwj49/e+EQ5bbcO7jESvg=; b=d92GhF2cCOr1PWrHTKxKXYespxbmt7O72XdJQgG4TyCKc7FDXyWCIDrAOx55glhg4D VZamewYt/ryvA/UZ+jggdbQFBDAnj5eJNV2lbr2Xsn9HP2lE85X23xZJ6BADjQTvNnss Ai8Ti3fm52SrSa1xT1qmw8bI1+c7VhD8l8B1vy5AfboA3FAf8VLuvHcq0rEzkTXx1RtC SHo+EwgHAUnqdAeg8ScWa3VqFrCAgOy74gGbKJx+Rr6EJzyYEt/+vxMQSZ6Y54Sn3RdH iT2udGTPnjXnTs7hjTCO8HA31dl2gDTaJk3223BoWPJikWkEx+jHlmujkC++w3lazf4p 2eVw== MIME-Version: 1.0 Received: by 10.229.201.160 with SMTP id fa32mr356975qcb.16.1354785225309; Thu, 06 Dec 2012 01:13:45 -0800 (PST) Sender: ermal.luci@gmail.com Received: by 10.49.121.163 with HTTP; Thu, 6 Dec 2012 01:13:45 -0800 (PST) Date: Thu, 6 Dec 2012 10:13:45 +0100 X-Google-Sender-Auth: 3kSIhFh3XTCevcjAOClVIc3Gmco Message-ID: Subject: ipfw(4) dynamic states/rules and its callout From: =?ISO-8859-1?Q?Ermal_Lu=E7i?= To: freebsd-net , freebsd-ipfw@freebsd.org Content-Type: text/plain; charset=ISO-8859-1 X-Content-Filtered-By: Mailman/MimeDel 2.1.14 X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 06 Dec 2012 09:13:46 -0000 Hello, i was looking at ipfw dynamic code for dynamic states/rules and see that it unconditionally schedules a callout even if there is not work to do. Wouldn't it be best to reschedule it when there is something to do to avoid having a useless callout/event run every time on the system? Is there any complication i am missing on it! Regards, Ermal From owner-freebsd-ipfw@FreeBSD.ORG Thu Dec 6 11:56:09 2012 Return-Path: Delivered-To: freebsd-ipfw@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id E6104FBF; Thu, 6 Dec 2012 11:56:09 +0000 (UTC) (envelope-from melifaro@FreeBSD.org) Received: from mail.ipfw.ru (unknown [IPv6:2a01:4f8:120:6141::2]) by mx1.freebsd.org (Postfix) with ESMTP id 785468FC13; Thu, 6 Dec 2012 11:56:09 +0000 (UTC) Received: from v6.mpls.in ([2a02:978:2::5] helo=ws.su29.net) by mail.ipfw.ru with esmtpsa (TLSv1:CAMELLIA256-SHA:256) (Exim 4.76 (FreeBSD)) (envelope-from ) id 1Tga77-0003RI-Th; Thu, 06 Dec 2012 15:59:37 +0400 Message-ID: <50C087D2.6020607@FreeBSD.org> Date: Thu, 06 Dec 2012 15:56:02 +0400 From: "Alexander V. Chernikov" User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:9.0) Gecko/20120121 Thunderbird/9.0 MIME-Version: 1.0 To: =?ISO-8859-1?Q?Ermal_Lu=E7i?= Subject: Re: ipfw(4) dynamic states/rules and its callout References: In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 8bit Cc: freebsd-net , freebsd-ipfw@freebsd.org X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 06 Dec 2012 11:56:10 -0000 On 06.12.2012 13:13, Ermal Luçi wrote: > Hello, > > i was looking at ipfw dynamic code for dynamic states/rules and see that it > unconditionally schedules a callout even if there is not work to do. > > Wouldn't it be best to reschedule it when there is something to do to avoid > having a useless > callout/event run every time on the system? > > Is there any complication i am missing on it! I thought about the same (and possibly not allocating dynamic hash at all if we have no dynamic rules) while rewriting dynamic code. The main "problem" is to reliably determine if we have dynamic rules in our ruleset. Rule checking probably can be done via adding additional argument to check_ipfw_struct(), however the rest can be a bit more complicated since we can delete more that one rule (or set with bunch of rules) at once. > > Regards, > Ermal > _______________________________________________ > freebsd-net@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-net > To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org" > From owner-freebsd-ipfw@FreeBSD.ORG Thu Dec 6 15:04:15 2012 Return-Path: Delivered-To: freebsd-ipfw@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id B500464E for ; Thu, 6 Dec 2012 15:04:15 +0000 (UTC) (envelope-from jmfinla@lps.umd.edu) Received: from lps-nt.lps.umd.edu (lps.umd.edu [129.2.108.2]) by mx1.freebsd.org (Postfix) with ESMTP id 691518FC0C for ; Thu, 6 Dec 2012 15:04:15 +0000 (UTC) Received: from cec-exch.cec.lps.gov (130.85.55.197) by lps-nt.lps.umd.edu (129.2.108.2) with Microsoft SMTP Server (TLS) id 8.3.279.5; Thu, 6 Dec 2012 10:03:04 -0500 Received: from cec-exch.cec.lps.gov ([10.10.10.12]) by cec-exch.cec.lps.gov ([10.10.10.12]) with mapi; Thu, 6 Dec 2012 10:03:02 -0500 From: "Finlayson, James" To: "freebsd-ipfw@freebsd.org" Date: Thu, 6 Dec 2012 10:03:00 -0500 Subject: Linux ipfw sysctl equivalents Thread-Topic: Linux ipfw sysctl equivalents Thread-Index: Ac3TwmMGyYPTsMkVQvSiPaQM1jytew== Message-ID: <3E9C7E247905FE44A1556F1E7B959E7604C4D23768@cec-exch.cec.lps.gov> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: acceptlanguage: en-US MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.14 X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 06 Dec 2012 15:04:15 -0000 Hi, I'm trying to build a dummynet box on linux (Centos 6.3). I have a bridge= created that properly forwards packets, however I cannot seem to alter the= ir behavior with ipfw pipes. I've used dummynet on FreeBSD without issue, = but I can't seem to find a Linux equivalent to the following two sysctl com= mands that will allow me to send bridged packets through ipfw. net.link.ether.ipfw: 0 Controls whether layer-2 packets are passed to ipfw. Default = is no. net.link.bridge.ipfw: 0 Controls whether bridged packets are passed to ipfw. Default = is no. Any suggestions? Regards, Jim From owner-freebsd-ipfw@FreeBSD.ORG Fri Dec 7 10:14:59 2012 Return-Path: Delivered-To: freebsd-ipfw@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id BDA17D8 for ; Fri, 7 Dec 2012 10:14:59 +0000 (UTC) (envelope-from luigi@onelab2.iet.unipi.it) Received: from onelab2.iet.unipi.it (onelab2.iet.unipi.it [131.114.59.238]) by mx1.freebsd.org (Postfix) with ESMTP id 74C9E8FC12 for ; Fri, 7 Dec 2012 10:14:57 +0000 (UTC) Received: by onelab2.iet.unipi.it (Postfix, from userid 275) id 56D127300A; Fri, 7 Dec 2012 11:06:56 +0100 (CET) Date: Fri, 7 Dec 2012 11:06:56 +0100 From: Luigi Rizzo To: "Finlayson, James" Subject: Re: Linux ipfw sysctl equivalents Message-ID: <20121207100656.GB32402@onelab2.iet.unipi.it> References: <3E9C7E247905FE44A1556F1E7B959E7604C4D23768@cec-exch.cec.lps.gov> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <3E9C7E247905FE44A1556F1E7B959E7604C4D23768@cec-exch.cec.lps.gov> User-Agent: Mutt/1.4.2.3i Cc: "freebsd-ipfw@freebsd.org" X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 07 Dec 2012 10:14:59 -0000 On Thu, Dec 06, 2012 at 10:03:00AM -0500, Finlayson, James wrote: > Hi, > I'm trying to build a dummynet box on linux (Centos 6.3). I have a bridge created that properly forwards packets, however I cannot seem to alter their behavior with ipfw pipes. I've used dummynet on FreeBSD without issue, but I can't seem to find a Linux equivalent to the following two sysctl commands that will allow me to send bridged packets through ipfw. > > net.link.ether.ipfw: 0 > Controls whether layer-2 packets are passed to ipfw. Default is > no. > > net.link.bridge.ipfw: 0 > Controls whether bridged packets are passed to ipfw. Default is > no. there is no equivalent, the dummynet version on linux only works at layer3 (attached to the pfilter hooks). Probably it can be made to work at a lower layer but i am not sure how. Other FreeBSD sysctl are remapped to /sys/module/ipfw_mod/parameters/* and accessible with regular filesystem read/write calls cheers luigi From owner-freebsd-ipfw@FreeBSD.ORG Fri Dec 7 12:27:50 2012 Return-Path: Delivered-To: freebsd-ipfw@freebsd.org Received: from mx2.freebsd.org (mx2.freebsd.org [69.147.83.53]) by hub.freebsd.org (Postfix) with ESMTP id B9FAB329; Fri, 7 Dec 2012 12:27:50 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from butcher-nb.yandex.net (hub.freebsd.org [IPv6:2001:1900:2254:206c::16:88]) by mx2.freebsd.org (Postfix) with ESMTP id 7CCE33B4C04; Fri, 7 Dec 2012 12:27:39 +0000 (UTC) Message-ID: <50C1E09A.5050301@FreeBSD.org> Date: Fri, 07 Dec 2012 16:27:06 +0400 From: "Andrey V. Elsukov" User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:17.0) Gecko/17.0 Thunderbird/17.0 MIME-Version: 1.0 To: freebsd-net@freebsd.org, freebsd-ipfw Subject: [RFC] IPv6 ifaddr hash X-Enigmail-Version: 1.4.6 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Cc: melifaro@FreeBSD.org X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 07 Dec 2012 12:27:50 -0000 Hi All, We have discovered that ipfw(4) shows very low performance results with our rules. One of the biggest problems is rules with O_IP6_XXX_ME opcode. They checks match or not match packet's addresses with locally configured IPv6 addresses. For IPv4 we have an in_ifaddr hash for the quick search an address, but not for the IPv6. So, I have implemented the first patch based on the code for the IPv4, but there are several questions I want to discuss. The patch is here: http://people.freebsd.org/~ae/in6_ifaddrhash.diff 1. The hash size. I made it the same what IPv4 has. But I think 512 buckets is too many. 2. What hash function is better to use? 3. Using the whole 128 bit of address to hash seems like overkill. -- WBR, Andrey V. Elsukov From owner-freebsd-ipfw@FreeBSD.ORG Sat Dec 8 09:49:37 2012 Return-Path: Delivered-To: freebsd-ipfw@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id AD12B96B; Sat, 8 Dec 2012 09:49:37 +0000 (UTC) (envelope-from melifaro@FreeBSD.org) Received: from mail.ipfw.ru (unknown [IPv6:2a01:4f8:120:6141::2]) by mx1.freebsd.org (Postfix) with ESMTP id 3CC928FC15; Sat, 8 Dec 2012 09:49:37 +0000 (UTC) Received: from v6.mpls.in ([2a02:978:2::5] helo=ws.su29.net) by mail.ipfw.ru with esmtpsa (TLSv1:CAMELLIA256-SHA:256) (Exim 4.76 (FreeBSD)) (envelope-from ) id 1ThH5l-0009WS-SS; Sat, 08 Dec 2012 13:53:05 +0400 Message-ID: <50C30D21.6070804@FreeBSD.org> Date: Sat, 08 Dec 2012 13:49:21 +0400 From: "Alexander V. Chernikov" User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:9.0) Gecko/20120121 Thunderbird/9.0 MIME-Version: 1.0 To: "Andrey V. Elsukov" Subject: Re: [RFC] IPv6 ifaddr hash References: <50C1E09A.5050301@FreeBSD.org> In-Reply-To: <50C1E09A.5050301@FreeBSD.org> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-net@freebsd.org, freebsd-ipfw X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 08 Dec 2012 09:49:37 -0000 On 07.12.2012 16:27, Andrey V. Elsukov wrote: > Hi All, > > We have discovered that ipfw(4) shows very low performance results with > our rules. One of the biggest problems is rules with O_IP6_XXX_ME > opcode. They checks match or not match packet's addresses with locally > configured IPv6 addresses. > > For IPv4 we have an in_ifaddr hash for the quick search an address, but > not for the IPv6. So, I have implemented the first patch based on the > code for the IPv4, but there are several questions I want to discuss. > > The patch is here: > http://people.freebsd.org/~ae/in6_ifaddrhash.diff > > 1. The hash size. I made it the same what IPv4 has. But I think 512 > buckets is too many. While the same IPv6 configuration can have up to x2 addresses as in IPv4 (link-local addresses), 512 is really too much, maybe 64, or 128 be better for common-use case? > > 2. What hash function is better to use? We've got at least 3 (known to me) hashes in our kernel: ng_netflow one, flowtable and in ipfw. Can you provide some benchmarks and hashing effectiveness for some real-world data for those? > > 3. Using the whole 128 bit of address to hash seems like overkill. There are people using IPv6 address space just as plain IPv4, e.g: XX:YY:ZZ::1, XX:YY:ZZ::2, ... ::n, or even XX:YY:ZZ::A.B.C.D, so hashing upper 64 bits can lead to collisions. Hashing lower 64 is more promising, but there can be other use cases, too. Imho we can just test test performance of hashing functions and see how much is the different and is it worth talking. There is another problem: link-local addresses. They are all the same, (or there are some small number of different groups) so one (or more) bucket will always be filled by them. This can result in * some searches for global addresses being much slower * IPv6 code accepting packet to link-local address of the other interface ( RFC 4291 sec 2.5.6 ) We can workaround first problem by adding global unicast to list head, and link-local - to list tail, but this leaves us with the second one. One of possible solutions is to add interface index as another parameter to hash function, and use it IFF address is site-local. >