summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_dummynet.c
diff options
context:
space:
mode:
authorluigi <luigi@FreeBSD.org>2002-05-13 10:37:19 +0000
committerluigi <luigi@FreeBSD.org>2002-05-13 10:37:19 +0000
commit2afce45ffcb33c722890e0085af2e0af09472a4e (patch)
tree3178446df8619c134cc22fc1485f4a05238cc975 /sys/netinet/ip_dummynet.c
parentf3653f3da85e17701bd60340a6a015bdcacb446f (diff)
downloadFreeBSD-src-2afce45ffcb33c722890e0085af2e0af09472a4e.zip
FreeBSD-src-2afce45ffcb33c722890e0085af2e0af09472a4e.tar.gz
Add ipfw hooks to ether_demux() and ether_output_frame().
Ipfw processing of frames at layer 2 can be enabled by the sysctl variable net.link.ether.ipfw=1 Consider this feature experimental, because right now, the firewall is invoked in the places indicated below, and controlled by the sysctl variables listed on the right. As a consequence, a packet can be filtered from 1 to 4 times depending on the path it follows, which might make a ruleset a bit hard to follow. I will add an ipfw option to tell if we want a given rule to apply to ether_demux() and ether_output_frame(), but we have run out of flags in the struct ip_fw so i need to think a bit on how to implement this. to upper layers | | +----------->-----------+ ^ V [ip_input] [ip_output] net.inet.ip.fw.enable=1 | | ^ V [ether_demux] [ether_output_frame] net.link.ether.ipfw=1 | | +->- [bdg_forward]-->---+ net.link.ether.bridge_ipfw=1 ^ V | | to devices
Diffstat (limited to 'sys/netinet/ip_dummynet.c')
-rw-r--r--sys/netinet/ip_dummynet.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/sys/netinet/ip_dummynet.c b/sys/netinet/ip_dummynet.c
index 5da5ea8..fa7fd91 100644
--- a/sys/netinet/ip_dummynet.c
+++ b/sys/netinet/ip_dummynet.c
@@ -161,7 +161,7 @@ static void rt_unref(struct rtentry *);
static void dummynet(void *);
static void dummynet_flush(void);
void dummynet_drain(void);
-static int dummynet_io(int pipe, int dir, struct mbuf *m, struct ifnet *ifp,
+static int dummynet_io(int pipe_nr, int dir, struct mbuf *m, struct ifnet *ifp,
struct route *ro, struct sockaddr_in * dst,
struct ip_fw *rule, int flags);
static void dn_rule_delete(void *);
@@ -445,7 +445,10 @@ transmit_event(struct dn_pipe *pipe)
/* somebody unloaded the bridge module. Drop pkt */
printf("-- dropping bridged packet trapped in pipe--\n");
m_freem(pkt->dn_m);
- } else {
+ break;
+ } /* fallthrough */
+ case DN_TO_ETH_DEMUX:
+ {
struct mbuf *m = (struct mbuf *)pkt ;
struct ether_header *eh;
@@ -465,11 +468,18 @@ transmit_event(struct dn_pipe *pipe)
* (originally pkt->dn_m, but could be something else now) if
* it has not consumed it.
*/
- m = bdg_forward_ptr(m, eh, pkt->ifp);
- if (m)
- m_freem(m);
+ if (pkt->dn_dir == DN_TO_BDG_FWD) {
+ m = bdg_forward_ptr(m, eh, pkt->ifp);
+ if (m)
+ m_freem(m);
+ } else
+ ether_demux(NULL, eh, m); /* which consumes the mbuf */
}
break ;
+ case DN_TO_ETH_OUT:
+ ether_output_frame(pkt->ifp, (struct mbuf *)pkt);
+ break;
+
default:
printf("dummynet: bad switch %d!\n", pkt->dn_dir);
m_freem(pkt->dn_m);
@@ -1036,6 +1046,18 @@ locate_flowset(int pipe_nr, struct ip_fw *rule)
/*
* dummynet hook for packets. Below 'pipe' is a pipe or a queue
* depending on whether WF2Q or fixed bw is used.
+ *
+ * pipe_nr pipe or queue the packet is destined for.
+ * dir where shall we send the packet after dummynet.
+ * m the mbuf with the packet
+ * ifp the 'ifp' parameter from the caller.
+ * NULL in ip_input, destination interface in ip_output,
+ * real_dst in bdg_forward
+ * ro route parameter (only used in ip_output, NULL otherwise)
+ * dst destination address, only used by ip_output
+ * rule matching rule, in case of multiple passes
+ * flags flags from the caller, only used in ip_output
+ *
*/
int
dummynet_io(int pipe_nr, int dir, /* pipe_nr can also be a fs_nr */
OpenPOWER on IntegriCloud