diff options
author | luigi <luigi@FreeBSD.org> | 2002-05-13 10:37:19 +0000 |
---|---|---|
committer | luigi <luigi@FreeBSD.org> | 2002-05-13 10:37:19 +0000 |
commit | 2afce45ffcb33c722890e0085af2e0af09472a4e (patch) | |
tree | 3178446df8619c134cc22fc1485f4a05238cc975 /sys/netinet/ip_dummynet.c | |
parent | f3653f3da85e17701bd60340a6a015bdcacb446f (diff) | |
download | FreeBSD-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.c | 32 |
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 */ |