summaryrefslogtreecommitdiffstats
path: root/sys/net
diff options
context:
space:
mode:
authorthompsa <thompsa@FreeBSD.org>2006-09-22 21:57:52 +0000
committerthompsa <thompsa@FreeBSD.org>2006-09-22 21:57:52 +0000
commit22a36e67f2dc507b9d579ccc4b1a81de4741c860 (patch)
tree6b2c542fea6e1147c45e5e744d8c6fa71494a242 /sys/net
parenta9f52fafeca473e981ed60c511519e67fa6cc765 (diff)
downloadFreeBSD-src-22a36e67f2dc507b9d579ccc4b1a81de4741c860.zip
FreeBSD-src-22a36e67f2dc507b9d579ccc4b1a81de4741c860.tar.gz
Revert r1.80 as the ethernet header was inadvertently stripped from ARP
packets. Reimplement this correctly and use a sysctl that defaults to off so the user doesnt get any suprises if ipfw blocks the ARP packet. MFC after: 3 days
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if_bridge.c50
1 files changed, 36 insertions, 14 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index ca4ddf5..e5e88e8 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -321,9 +321,12 @@ static int pfil_onlyip = 1; /* only pass IP[46] packets when pfil is enabled */
static int pfil_bridge = 1; /* run pfil hooks on the bridge interface */
static int pfil_member = 1; /* run pfil hooks on the member interface */
static int pfil_ipfw = 0; /* layer2 filter with ipfw */
+static int pfil_ipfw_arp = 0; /* layer2 filter with ipfw */
static int log_stp = 0; /* log STP state changes */
SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_onlyip, CTLFLAG_RW,
&pfil_onlyip, 0, "Only pass IP packets when pfil is enabled");
+SYSCTL_INT(_net_link_bridge, OID_AUTO, ipfw_arp, CTLFLAG_RW,
+ &pfil_ipfw_arp, 0, "Filter ARP packets through IPFW layer2");
SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_bridge, CTLFLAG_RW,
&pfil_bridge, 0, "Packet filter on the bridge interface");
SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_member, CTLFLAG_RW,
@@ -2736,6 +2739,37 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir)
}
}
+ /*
+ * If we're trying to filter bridge traffic, don't look at anything
+ * other than IP and ARP traffic. If the filter doesn't understand
+ * IPv6, don't allow IPv6 through the bridge either. This is lame
+ * since if we really wanted, say, an AppleTalk filter, we are hosed,
+ * but of course we don't have an AppleTalk filter to begin with.
+ * (Note that since pfil doesn't understand ARP it will pass *ALL*
+ * ARP traffic.)
+ */
+ switch (ether_type) {
+ case ETHERTYPE_ARP:
+ case ETHERTYPE_REVARP:
+ if (pfil_ipfw_arp == 0)
+ return (0); /* Automatically pass */
+ break;
+
+ case ETHERTYPE_IP:
+#ifdef INET6
+ case ETHERTYPE_IPV6:
+#endif /* INET6 */
+ break;
+ default:
+ /*
+ * Check to see if the user wants to pass non-ip
+ * packets, these will not be checked by pfil(9) and
+ * passed unconditionally so the default is to drop.
+ */
+ if (pfil_onlyip)
+ goto bad;
+ }
+
/* Strip off the Ethernet header and keep a copy. */
m_copydata(*mp, 0, ETHER_HDR_LEN, (caddr_t) &eh2);
m_adj(*mp, ETHER_HDR_LEN);
@@ -2808,14 +2842,9 @@ ipfwpass:
error = 0;
/*
- * Run the packet through pfil. Note that since pfil doesn't understand
- * ARP it will pass all ARP traffic.
+ * Run the packet through pfil
*/
switch (ether_type) {
- case ETHERTYPE_ARP:
- case ETHERTYPE_REVARP:
- return (0); /* Automatically pass */
-
case ETHERTYPE_IP:
/*
* before calling the firewall, swap fields the same as
@@ -2907,14 +2936,7 @@ ipfwpass:
break;
#endif
default:
- /*
- * Check to see if the user wants to pass non-ip
- * packets.
- */
- if (pfil_onlyip) {
- error = -1;
- goto bad;
- }
+ error = 0;
break;
}
OpenPOWER on IntegriCloud