From owner-freebsd-ipfw@FreeBSD.ORG Tue Apr 24 15:26:45 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 88FDE1065673 for ; Tue, 24 Apr 2012 15:26:45 +0000 (UTC) (envelope-from hrs@FreeBSD.org) Received: from mail.allbsd.org (gatekeeper-int.allbsd.org [IPv6:2001:2f0:104:e002::2]) by mx1.freebsd.org (Postfix) with ESMTP id E6C808FC1D for ; Tue, 24 Apr 2012 15:26:44 +0000 (UTC) Received: from alph.allbsd.org (p4242-ipbf1504funabasi.chiba.ocn.ne.jp [118.7.211.242]) (authenticated bits=128) by mail.allbsd.org (8.14.4/8.14.4) with ESMTP id q3OFQMHw055601 for ; Wed, 25 Apr 2012 00:26:32 +0900 (JST) (envelope-from hrs@FreeBSD.org) Received: from localhost (localhost [IPv6:::1]) (authenticated bits=0) by alph.allbsd.org (8.14.4/8.14.4) with ESMTP id q3OFQMb9078610 for ; Wed, 25 Apr 2012 00:26:22 +0900 (JST) (envelope-from hrs@FreeBSD.org) Date: Wed, 25 Apr 2012 00:26:00 +0900 (JST) Message-Id: <20120425.002600.1631867625819249738.hrs@allbsd.org> To: freebsd-ipfw@FreeBSD.org From: Hiroki Sato X-PGPkey-fingerprint: BDB3 443F A5DD B3D0 A530 FFD7 4F2C D3D8 2793 CF2D X-Mailer: Mew version 6.4.50 on Emacs 23.4 / Mule 6.0 (HANACHIRUSATO) Mime-Version: 1.0 Content-Type: Multipart/Signed; protocol="application/pgp-signature"; micalg=pgp-sha1; boundary="--Security_Multipart0(Wed_Apr_25_00_26_00_2012_958)--" Content-Transfer-Encoding: 7bit X-Virus-Scanned: clamav-milter 0.97.3 at gatekeeper.allbsd.org X-Virus-Status: Clean X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.2.3 (mail.allbsd.org [133.31.130.32]); Wed, 25 Apr 2012 00:26:38 +0900 (JST) X-Spam-Status: No, score=-103.6 required=13.0 tests=BAYES_00, CONTENT_TYPE_PRESENT,FAKEDWORD_ZERO,RCVD_IN_RP_RNBL,SPF_SOFTFAIL, USER_IN_WHITELIST autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on gatekeeper.allbsd.org Cc: Subject: CFR: ipfw0 pseudo-interface clonable X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 Apr 2012 15:26:45 -0000 ----Security_Multipart0(Wed_Apr_25_00_26_00_2012_958)-- Content-Type: Multipart/Mixed; boundary="--Next_Part(Wed_Apr_25_00_26_00_2012_602)--" Content-Transfer-Encoding: 7bit ----Next_Part(Wed_Apr_25_00_26_00_2012_602)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Hi, I created the attached patch to make the current ipfw0 pseudo-interface clonable. The functionality of ipfw0 logging interface is not changed by this patch, but the ipfw0 pseudo-interface is not created by default and can be created with the following command: # ifconfig ipfw0 create Any objection to commit this patch? The primary motivation for this change is that presence of the interface by default increases size of the interface list, which is returned by NET_RT_IFLIST sysctl even when the sysadmin does not need it. Also this pseudo-interface can confuse the sysadmin and/or network-related userland utilities like SNMP agent. With this patch, one can use ifconfig(8) to create/destroy the pseudo-interface as necessary. -- Hiroki ----Next_Part(Wed_Apr_25_00_26_00_2012_602)-- Content-Type: Text/X-Patch; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ipfw_clone_interface.20120421-1.diff" Index: sys/netinet/ipfw/ip_fw_log.c =================================================================== --- sys/netinet/ipfw/ip_fw_log.c (revision 234428) +++ sys/netinet/ipfw/ip_fw_log.c (working copy) @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include /* for ETHERTYPE_IP */ #include +#include #include #include /* for IFT_ETHER */ #include /* for BPF */ @@ -89,8 +90,11 @@ ipfw_log_bpf(int onoff) { } #else /* !WITHOUT_BPF */ +static struct mtx log_if_mtx; static struct ifnet *log_if; /* hook to attach to bpf */ +#define IPFWNAME "ipfw" + /* we use this dummy function for all ifnet callbacks */ static int log_dummy(struct ifnet *ifp, u_long cmd, caddr_t addr) @@ -116,39 +120,106 @@ ipfw_log_start(struct ifnet* ifp) static const u_char ipfwbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -void -ipfw_log_bpf(int onoff) +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; - if (onoff) { - if (log_if) - return; - ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) - return; - if_initname(ifp, "ipfw", 0); - 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; - if_attach(ifp); - ifp->if_broadcastaddr = ipfwbroadcastaddr; - ifp->if_baudrate = IF_Mbps(10); - bpfattach(ifp, DLT_EN10MB, 14); + error = ifc_name2unit(name, &unit); + if (error) + return (error); + + error = ifc_alloc_unit(ifc, &unit); + if (error) + return (error); + + ifp = if_alloc(IFT_ETHER); + 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); + + mtx_lock(&log_if_mtx); + if (log_if == NULL) { log_if = ifp; + mtx_unlock(&log_if_mtx); } else { - if (log_if) { - ether_ifdetach(log_if); - if_free(log_if); - } + mtx_unlock(&log_if_mtx); + if_free(ifp); + ifc_free_unit(ifc, unit); + return (EEXIST); + } + 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); + + mtx_lock(&log_if_mtx); + if (log_if != NULL && ifp == log_if) log_if = NULL; + else { + mtx_unlock(&log_if_mtx); + return (EINVAL); } + mtx_unlock(&log_if_mtx); + + 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 = IFC_CLONE_INITIALIZER( + IPFWNAME, NULL, IF_MAXUNIT, + NULL, ipfw_log_clone_match, ipfw_log_clone_create, ipfw_log_clone_destroy); + +void +ipfw_log_bpf(int onoff) +{ + + if (onoff) { + mtx_init(&log_if_mtx, "ipfw log_if mtx", NULL, 0); + if_clone_attach(&ipfw_log_cloner); + } else { + if_clone_detach(&ipfw_log_cloner); + mtx_destroy(&log_if_mtx); + } +} #endif /* !WITHOUT_BPF */ /* ----Next_Part(Wed_Apr_25_00_26_00_2012_602)---- ----Security_Multipart0(Wed_Apr_25_00_26_00_2012_958)-- Content-Type: application/pgp-signature Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (FreeBSD) iEYEABECAAYFAk+WxggACgkQTyzT2CeTzy2e3ACggqHzMzIW8AQHrVq2L7wPrF3V ZnMAn19hiyq9/J1gmQv/KqDhYrD6EJ4d =nevM -----END PGP SIGNATURE----- ----Security_Multipart0(Wed_Apr_25_00_26_00_2012_958)----