Date: Wed, 25 Apr 2012 00:26:00 +0900 (JST) From: Hiroki Sato <hrs@FreeBSD.org> To: freebsd-ipfw@FreeBSD.org Subject: CFR: ipfw0 pseudo-interface clonable Message-ID: <20120425.002600.1631867625819249738.hrs@allbsd.org>
next in thread | raw e-mail | index | archive | help
----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 <sys/syslog.h> #include <net/ethernet.h> /* for ETHERTYPE_IP */ #include <net/if.h> +#include <net/if_clone.h> #include <net/vnet.h> #include <net/if_types.h> /* for IFT_ETHER */ #include <net/bpf.h> /* 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)----
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120425.002600.1631867625819249738.hrs>