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
This commit is contained in:
parent
43e5f4b8cd
commit
0a6f8a5050
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=162561
@ -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 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir)
|
||||
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 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir)
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user