summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_dummynet.c62
-rw-r--r--sys/netinet/ip_dummynet.h5
-rw-r--r--sys/netinet/ip_fw.c171
-rw-r--r--sys/netinet/ip_fw.h1
-rw-r--r--sys/netinet/ip_input.c9
-rw-r--r--sys/netinet/ip_output.c6
-rw-r--r--sys/netinet/raw_ip.c29
7 files changed, 157 insertions, 126 deletions
diff --git a/sys/netinet/ip_dummynet.c b/sys/netinet/ip_dummynet.c
index a1a61ca..bb3c409 100644
--- a/sys/netinet/ip_dummynet.c
+++ b/sys/netinet/ip_dummynet.c
@@ -79,9 +79,6 @@
#include <netinet/ip_dummynet.h>
#include <netinet/ip_var.h>
-#if !defined(KLD_MODULE)
-#include "opt_bdg.h"
-#endif
#include <netinet/if_ether.h> /* for struct arpcom */
#include <net/bridge.h>
@@ -165,9 +162,9 @@ 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,
- struct route *ro, struct sockaddr_in * dst,
- struct ip_fw *rule, int flags);
-void dn_rule_delete(void *);
+ struct route *ro, struct sockaddr_in * dst,
+ struct ip_fw *rule, int flags);
+static void dn_rule_delete(void *);
int if_tx_rdy(struct ifnet *ifp);
@@ -249,7 +246,7 @@ heap_init(struct dn_heap *h, int new_size)
*/
#define RESET_OFFSET(heap, node) \
if (heap->offset > 0) \
- *((int *)((char *)(heap->p[node].object) + heap->offset)) = -1 ;
+ *((int *)((char *)(heap->p[node].object) + heap->offset)) = -1 ;
static int
heap_insert(struct dn_heap *h, dn_key key1, void *p)
{
@@ -444,8 +441,12 @@ transmit_event(struct dn_pipe *pipe)
break ;
case DN_TO_BDG_FWD :
- if (bdg_forward_ptr != NULL) {
- struct mbuf *m = (struct mbuf *)pkt;
+ if (!BDG_LOADED) {
+ /* somebody unloaded the bridge module. Drop pkt */
+ printf("-- dropping bridged packet trapped in pipe--\n");
+ m_freem(pkt->dn_m);
+ } else {
+ struct mbuf *m = (struct mbuf *)pkt ;
struct ether_header *eh;
if (pkt->dn_m->m_len < ETHER_HDR_LEN &&
@@ -459,8 +460,8 @@ transmit_event(struct dn_pipe *pipe)
eh = mtod(pkt->dn_m, struct ether_header *);
m_adj(pkt->dn_m, ETHER_HDR_LEN);
/*
- * bdg_forward_ptr() wants a pointer to the pseudo-mbuf-header,
- * but on return it will supply the pointer to the actual packet
+ * bdg_forward() wants a pointer to the pseudo-mbuf-header, but
+ * on return it will supply the pointer to the actual packet
* (originally pkt->dn_m, but could be something else now) if
* it has not consumed it.
*/
@@ -474,7 +475,7 @@ transmit_event(struct dn_pipe *pipe)
m_freem(pkt->dn_m);
break ;
}
- FREE(pkt, M_DUMMYNET);
+ free(pkt, M_DUMMYNET);
}
/* if there are leftover packets, put into the heap for next event */
if ( (pkt = pipe->head) )
@@ -831,7 +832,7 @@ create_queue(struct dn_flow_set *fs, int i)
if ( fs->rq[i] != NULL )
return fs->rq[i] ;
}
- q = malloc(sizeof(*q), M_DUMMYNET, M_DONTWAIT | M_ZERO); /* M_ZERO needed */
+ q = malloc(sizeof(*q), M_DUMMYNET, M_DONTWAIT | M_ZERO);
if (q == NULL) {
printf("sorry, cannot allocate queue for new flow\n");
return NULL ;
@@ -1092,7 +1093,7 @@ dummynet_io(int pipe_nr, int dir, /* pipe_nr can also be a fs_nr */
goto dropit ;
/* XXX expensive to zero, see if we can remove it*/
- pkt = (struct dn_pkt *)malloc(sizeof (*pkt), M_DUMMYNET, M_NOWAIT | M_ZERO);
+ pkt = (struct dn_pkt *)malloc(sizeof (*pkt), M_DUMMYNET, M_NOWAIT|M_ZERO);
if ( pkt == NULL )
goto dropit ; /* cannot allocate packet header */
/* ok, i can handle the pkt now... */
@@ -1383,8 +1384,10 @@ config_red(struct dn_flow_set *p, struct dn_flow_set * x)
}
/* if the lookup table already exist, free and create it again */
- if (x->w_q_lookup)
+ if (x->w_q_lookup) {
free(x->w_q_lookup, M_DUMMYNET);
+ x->w_q_lookup = NULL ;
+ }
if (red_lookup_depth == 0) {
printf("\nnet.inet.ip.dummynet.red_lookup_depth must be > 0");
free(x, M_DUMMYNET);
@@ -1470,13 +1473,13 @@ config_pipe(struct dn_pipe *p)
int s ;
struct dn_flow_set *pfs = &(p->fs);
- /*
- * The config program passes parameters as follows:
+ /*
+ * The config program passes parameters as follows:
* bw = bits/second (0 means no limits),
* delay = ms, must be translated into ticks.
* qsize = slots/bytes
- */
- p->delay = ( p->delay * hz ) / 1000 ;
+ */
+ p->delay = ( p->delay * hz ) / 1000 ;
/* We need either a pipe number or a flow_set number */
if (p->pipe_nr == 0 && pfs->fs_nr == 0)
return EINVAL ;
@@ -1535,7 +1538,7 @@ config_pipe(struct dn_pipe *p)
if (b == NULL || b->fs_nr != pfs->fs_nr) { /* new */
if (pfs->parent_nr == 0) /* need link to a pipe */
return EINVAL ;
- x = malloc(sizeof(struct dn_flow_set), M_DUMMYNET, M_DONTWAIT | M_ZERO);
+ x = malloc(sizeof(struct dn_flow_set),M_DUMMYNET,M_DONTWAIT|M_ZERO);
if (x == NULL) {
printf("ip_dummynet.c: no memory for new flow_set\n");
return ENOSPC;
@@ -1812,7 +1815,7 @@ dummynet_get(struct sockopt *sopt)
}
splx(s);
error = sooptcopyout(sopt, buf, size);
- FREE(buf, M_TEMP);
+ free(buf, M_TEMP);
return error ;
}
@@ -1868,7 +1871,7 @@ ip_dn_ctl(struct sockopt *sopt)
static void
ip_dn_init(void)
{
- printf("DUMMYNET initialized (011004)\n");
+ printf("DUMMYNET initialized (011031)\n");
all_pipes = NULL ;
all_flow_sets = NULL ;
ready_heap.size = ready_heap.elements = 0 ;
@@ -1880,8 +1883,8 @@ ip_dn_init(void)
extract_heap.size = extract_heap.elements = 0 ;
extract_heap.offset = 0 ;
ip_dn_ctl_ptr = ip_dn_ctl;
- ip_dn_ruledel_ptr = dn_rule_delete;
ip_dn_io_ptr = dummynet_io;
+ ip_dn_ruledel_ptr = dn_rule_delete;
bzero(&dn_timeout, sizeof(struct callout_handle));
dn_timeout = timeout(dummynet, NULL, 1);
}
@@ -1893,17 +1896,28 @@ dummynet_modevent(module_t mod, int type, void *data)
switch (type) {
case MOD_LOAD:
s = splimp();
+ if (DUMMYNET_LOADED) {
+ splx(s);
+ printf("DUMMYNET already loaded\n");
+ return EEXIST ;
+ }
ip_dn_init();
splx(s);
break;
+
case MOD_UNLOAD:
+#if !defined(KLD_MODULE)
+ printf("dummynet statically compiled, cannot unload\n");
+ return EINVAL ;
+#else
+ s = splimp();
untimeout(dummynet, NULL, dn_timeout);
dummynet_flush();
- s = splimp();
ip_dn_ctl_ptr = NULL;
ip_dn_io_ptr = NULL;
ip_dn_ruledel_ptr = NULL;
splx(s);
+#endif
break ;
default:
break ;
diff --git a/sys/netinet/ip_dummynet.h b/sys/netinet/ip_dummynet.h
index 16cff51..85c5b5e 100644
--- a/sys/netinet/ip_dummynet.h
+++ b/sys/netinet/ip_dummynet.h
@@ -343,11 +343,12 @@ struct dn_pipe { /* a pipe */
typedef int ip_dn_ctl_t(struct sockopt *); /* raw_ip.c */
typedef void ip_dn_ruledel_t(void *); /* ip_fw.c */
typedef int ip_dn_io_t(int pipe, int dir, struct mbuf *m,
- struct ifnet *ifp, struct route *ro, struct sockaddr_in * dst,
- struct ip_fw *rule, int flags); /* ip_{in,out}put.c, bridge.c */
+ struct ifnet *ifp, struct route *ro, struct sockaddr_in * dst,
+ struct ip_fw *rule, int flags); /* ip_{in,out}put.c, bridge.c */
extern ip_dn_ctl_t *ip_dn_ctl_ptr;
extern ip_dn_ruledel_t *ip_dn_ruledel_ptr;
extern ip_dn_io_t *ip_dn_io_ptr;
+#define DUMMYNET_LOADED (ip_dn_io_ptr != NULL)
#endif
#endif /* _IP_DUMMYNET_H */
diff --git a/sys/netinet/ip_fw.c b/sys/netinet/ip_fw.c
index 320672c..5a26121 100644
--- a/sys/netinet/ip_fw.c
+++ b/sys/netinet/ip_fw.c
@@ -155,7 +155,8 @@ SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, permanent_rules, CTLFLAG_RW,
static struct ipfw_dyn_rule **ipfw_dyn_v = NULL ;
static u_int32_t dyn_buckets = 256 ; /* must be power of 2 */
static u_int32_t curr_dyn_buckets = 256 ; /* must be power of 2 */
-/**
+
+/*
* timeouts for various events in handing dynamic rules.
*/
static u_int32_t dyn_ack_lifetime = 300 ;
@@ -200,8 +201,7 @@ SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_short_lifetime, CTLFLAG_RW,
SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_grace_time, CTLFLAG_RD,
&dyn_grace_time, 0, "Grace time for dyn. rules");
-
-#endif
+#endif /* SYSCTL_NODE */
#define dprintf(a) do { \
if (fw_debug) \
@@ -674,22 +674,21 @@ hash_packet(struct ipfw_flow_id *id)
* head is a pointer to the head of the queue.
* Modifies q and potentially also head.
*/
-#define UNLINK_DYN_RULE(prev, head, q) { \
- struct ipfw_dyn_rule *old_q = q; \
- \
- /* remove a refcount to the parent */ \
- if (q->dyn_type == DYN_LIMIT) \
- q->parent->count--; \
- DEB(printf("-- unlink entry 0x%08x %d -> 0x%08x %d, %d left\n", \
- (q->id.src_ip), (q->id.src_port), \
- (q->id.dst_ip), (q->id.dst_port), dyn_count-1 ); ) \
- if (prev != NULL) \
- prev->next = q = q->next ; \
- else \
- ipfw_dyn_v[i] = q = q->next ; \
- dyn_count-- ; \
- free(old_q, M_IPFW); }
-
+#define UNLINK_DYN_RULE(prev, head, q) { \
+ struct ipfw_dyn_rule *old_q = q; \
+ \
+ /* remove a refcount to the parent */ \
+ if (q->dyn_type == DYN_LIMIT) \
+ q->parent->count--; \
+ DEB(printf("-- unlink entry 0x%08x %d -> 0x%08x %d, %d left\n", \
+ (q->id.src_ip), (q->id.src_port), \
+ (q->id.dst_ip), (q->id.dst_port), dyn_count-1 ); ) \
+ if (prev != NULL) \
+ prev->next = q = q->next ; \
+ else \
+ ipfw_dyn_v[i] = q = q->next ; \
+ dyn_count-- ; \
+ free(old_q, M_IPFW); }
#define TIME_LEQ(a,b) ((int)((a)-(b)) <= 0)
/**
@@ -733,8 +732,9 @@ remove_dyn_rule(struct ip_fw *rule, int force)
max_pass = 1; /* we need a second pass */
if (zap == 1 && (pass == 0 || q->count != 0) ) {
zap = 0 ;
- if (q->count != 0)
- printf("cannot remove parent, count %d\n", q->count);
+ if (pass == 1) /* should not happen */
+ printf("OUCH! cannot remove rule, count %d\n",
+ q->count);
}
}
if (zap) {
@@ -775,7 +775,7 @@ lookup_dyn_rule(struct ipfw_flow_id *pkt, int *match_direction)
goto next;
if (TIME_LEQ( q->expire , time_second ) ) { /* expire entry */
UNLINK_DYN_RULE(prev, ipfw_dyn_v[i], q);
- continue ;
+ continue;
}
if ( pkt->proto == q->id.proto) {
if (pkt->src_ip == q->id.src_ip &&
@@ -789,8 +789,8 @@ lookup_dyn_rule(struct ipfw_flow_id *pkt, int *match_direction)
pkt->dst_ip == q->id.src_ip &&
pkt->src_port == q->id.dst_port &&
pkt->dst_port == q->id.src_port ) {
- dir = 0 ; /* reverse match */
- goto found ;
+ dir = 0 ; /* reverse match */
+ goto found ;
}
}
next:
@@ -876,9 +876,9 @@ add_dyn_rule(struct ipfw_flow_id *id, u_int8_t dyn_type, struct ip_fw *rule)
dyn_buckets = curr_dyn_buckets ; /* reset */
else {
curr_dyn_buckets = dyn_buckets ;
- if (ipfw_dyn_v != NULL)
+ if (ipfw_dyn_v != NULL)
free(ipfw_dyn_v, M_IPFW);
- ipfw_dyn_v = malloc(curr_dyn_buckets * sizeof r,
+ ipfw_dyn_v = malloc(curr_dyn_buckets * sizeof r,
M_IPFW, M_DONTWAIT | M_ZERO);
if (ipfw_dyn_v == NULL)
return NULL; /* failed ! */
@@ -888,8 +888,8 @@ add_dyn_rule(struct ipfw_flow_id *id, u_int8_t dyn_type, struct ip_fw *rule)
r = malloc(sizeof *r, M_IPFW, M_DONTWAIT | M_ZERO);
if (r == NULL) {
- printf ("sorry cannot allocate state\n");
- return NULL ;
+ printf ("sorry cannot allocate state\n");
+ return NULL ;
}
/* increase refcount on parent, and set pointer */
@@ -921,7 +921,7 @@ add_dyn_rule(struct ipfw_flow_id *id, u_int8_t dyn_type, struct ip_fw *rule)
}
/**
- * lookup dynamic parent rule using pkt and chain as search keys.
+ * lookup dynamic parent rule using pkt and rule as search keys.
* If the lookup fails, then install one.
*/
static struct ipfw_dyn_rule *
@@ -986,10 +986,11 @@ install_state(struct ip_fw *rule)
}
return 1; /* cannot install, notify caller */
}
+
switch (type) {
case DYN_KEEP_STATE: /* bidir rule */
- add_dyn_rule(&last_pkt, DYN_KEEP_STATE, rule);
- break ;
+ add_dyn_rule(&last_pkt, DYN_KEEP_STATE, rule);
+ break ;
case DYN_LIMIT: /* limit number of sessions */
{
u_int16_t limit_mask = rule->limit_mask ;
@@ -1014,7 +1015,7 @@ install_state(struct ip_fw *rule)
parent = lookup_dyn_parent(&id, rule);
if (parent == NULL) {
printf("add parent failed\n");
- return 1;
+ return 1;
}
if (parent->count >= conn_limit) {
EXPIRE_DYN_CHAIN(rule); /* try to expire some */
@@ -1037,7 +1038,7 @@ install_state(struct ip_fw *rule)
/*
* given an ip_fw *, lookup_next_rule will return a pointer
* of the same type to the next one. This can be either the jump
- * target (for skipto instructions) or the next one in the chain (in
+ * target (for skipto instructions) or the next one in the list (in
* all other cases including a missing jump target).
* Backward jumps are not allowed, so start looking from the next
* rule...
@@ -1053,7 +1054,7 @@ lookup_next_rule(struct ip_fw *me)
if ( (me->fw_flg & IP_FW_F_COMMAND) == IP_FW_F_SKIPTO )
for (rule = LIST_NEXT(me,next); rule ; rule = LIST_NEXT(rule,next))
if (rule->fw_number >= rulenum)
- return rule ;
+ return rule ;
return LIST_NEXT(me,next) ; /* failure or not a skipto */
}
@@ -1198,7 +1199,7 @@ ip_fw_chk(struct ip **pip, int hlen,
goto dropit;
} else {
/*
- * Go down the chain, looking for enlightment.
+ * Go down the list, looking for enlightment.
* If we've been asked to start at a given rule, do so.
*/
f = LIST_FIRST(&ip_fw_chain_head);
@@ -1212,7 +1213,6 @@ ip_fw_chk(struct ip **pip, int hlen,
}
}
-
for (; f; f = LIST_NEXT(f, next)) {
again:
if (f->fw_number == IPFW_DEFAULT_RULE)
@@ -1516,7 +1516,7 @@ got_match:
goto again ;
case IP_FW_F_PIPE:
case IP_FW_F_QUEUE:
- *flow_id = f;
+ *flow_id = f; /* XXX set flow id */
return(f->fw_pipe_nr | IP_FW_PORT_DYNT_FLAG);
#ifdef IPFIREWALL_FORWARD
case IP_FW_F_FWD:
@@ -1608,7 +1608,7 @@ dropit:
* when a rule is added/deleted, zero the direct pointers within
* all firewall rules. These will be reconstructed on the fly
* as packets are matched.
- * Must be called at splnet().
+ * Must be called at splimp().
*/
static void
flush_rule_ptrs()
@@ -1630,7 +1630,6 @@ add_entry(struct ip_fw_head *head, struct ip_fw *rule)
ftmp = malloc(sizeof *ftmp, M_IPFW, M_DONTWAIT | M_ZERO);
if (!ftmp)
return (ENOSPC);
-
bcopy(rule, ftmp, sizeof(*ftmp));
ftmp->fw_in_if.fu_via_if.name[FW_IFNLEN - 1] = '\0';
@@ -1639,7 +1638,7 @@ add_entry(struct ip_fw_head *head, struct ip_fw *rule)
ftmp->next_rule_ptr = NULL ;
ftmp->pipe_ptr = NULL ;
- s = splnet();
+ s = splimp();
if (LIST_FIRST(head) == 0) {
LIST_INSERT_HEAD(head, ftmp, next);
@@ -1683,11 +1682,11 @@ done:
}
/**
- * free storage associated with a static chain entry (including
+ * free storage associated with a static rule entry (including
* dependent dynamic rules), and zeroes rule pointers to avoid
* dangling pointer dereferences.
* @return a pointer to the next entry.
- * Must be called at splnet() and with a non-null argument.
+ * Must be called at splimp() and with a non-null argument.
*/
static struct ip_fw *
free_chain(struct ip_fw *fcp)
@@ -1698,7 +1697,7 @@ free_chain(struct ip_fw *fcp)
DELETE_DYN_CHAIN(fcp);
LIST_REMOVE(fcp, next);
static_count--;
- if (ip_dn_ruledel_ptr != NULL)
+ if (DUMMYNET_LOADED)
ip_dn_ruledel_ptr(fcp) ;
flush_rule_ptrs(); /* more efficient to do outside the loop */
free(fcp, M_IPFW);
@@ -1718,7 +1717,7 @@ del_entry(struct ip_fw_head *chainptr, u_short number)
if (rule->fw_number == number) {
int s ;
- s = splnet(); /* prevent access to rules while removing */
+ s = splimp(); /* prevent access to rules while removing */
while (rule && rule->fw_number == number)
rule = free_chain(rule);
/* XXX could move flush_rule_ptrs() here */
@@ -1746,7 +1745,7 @@ zero_entry(struct ip_fw *frwl, int log_only)
char *msg ;
if (frwl == 0) {
- s = splnet();
+ s = splimp();
LIST_FOREACH(rule, &ip_fw_chain_head, next) {
if (log_only == 0) {
rule->fw_bcnt = rule->fw_pcnt = 0;
@@ -1756,19 +1755,18 @@ zero_entry(struct ip_fw *frwl, int log_only)
}
splx(s);
msg = log_only ? "ipfw: All logging counts cleared.\n" :
- "ipfw: Accounting cleared.\n";
+ "ipfw: Accounting cleared.\n";
} else {
int cleared = 0;
number = frwl->fw_number ;
-
/*
- * It's possible to insert multiple chain entries with the
+ * It is possible to insert multiple chain entries with the
* same number, so we don't stop after finding the first
* match if zeroing a specific entry.
*/
LIST_FOREACH(rule, &ip_fw_chain_head, next)
if (number == rule->fw_number) {
- s = splnet();
+ s = splimp();
while (rule && number == rule->fw_number) {
if (log_only == 0) {
rule->fw_bcnt = rule->fw_pcnt = 0;
@@ -1781,10 +1779,10 @@ zero_entry(struct ip_fw *frwl, int log_only)
cleared = 1;
break;
}
- if (!cleared) /* we didn't find any matching rules */
+ if (!cleared) /* we did not find any matching rules */
return (EINVAL);
msg = log_only ? "Entry %d logging count reset.\n" :
- "ipfw: Entry %d cleared.\n";
+ "ipfw: Entry %d cleared.\n";
}
if (fw_verbose)
log(LOG_SECURITY | LOG_NOTICE, msg, number);
@@ -1946,7 +1944,13 @@ ip_fw_ctl(struct sockopt *sopt)
switch (sopt->sopt_name) {
case IP_FW_GET:
- s = splnet();
+ /*
+ * pass up a copy of the current rules. Static rules
+ * come first (the last of which has number 65535),
+ * followed by a possibly empty list of dynamic rule.
+ * The last dynamic rule has NULL in the "next" field.
+ */
+ s = splimp();
/* size of static rules */
size = static_count * sizeof(struct ip_fw) ;
if (ipfw_dyn_v) /* add size of dyn.rules */
@@ -1960,9 +1964,9 @@ ip_fw_ctl(struct sockopt *sopt)
*/
buf = malloc(size, M_TEMP, M_WAITOK);
if (buf == 0) {
- splx(s);
- error = ENOBUFS;
- break;
+ splx(s);
+ error = ENOBUFS;
+ break;
}
bp = buf ;
@@ -1979,7 +1983,12 @@ ip_fw_ctl(struct sockopt *sopt)
for ( p = ipfw_dyn_v[i] ; p != NULL ; p = p->next, dst++ ) {
bcopy(p, dst, sizeof *p);
(int)dst->rule = p->rule->fw_number ;
- dst->next = dst ; /* fake non-null pointer... */
+ /*
+ * store a non-null value in "next". The userland
+ * code will interpret a NULL here as a marker
+ * for the last dynamic rule.
+ */
+ dst->next = dst ;
last = dst ;
if (TIME_LEQ(dst->expire, time_second) )
dst->expire = 0 ;
@@ -1987,12 +1996,12 @@ ip_fw_ctl(struct sockopt *sopt)
dst->expire -= time_second ;
}
if (last != NULL)
- last->next = NULL ;
+ last->next = NULL ; /* mark last dynamic rule */
}
splx(s);
error = sooptcopyout(sopt, buf, size);
- FREE(buf, M_TEMP);
+ free(buf, M_TEMP);
break;
case IP_FW_FLUSH:
@@ -2009,7 +2018,7 @@ ip_fw_ctl(struct sockopt *sopt)
* the old list without the need for a lock.
*/
- s = splnet();
+ s = splimp();
while ( (fcp = LIST_FIRST(&ip_fw_chain_head)) &&
fcp->fw_number != IPFW_DEFAULT_RULE )
free_chain(fcp);
@@ -2055,7 +2064,7 @@ ip_fw_ctl(struct sockopt *sopt)
if (sopt->sopt_val != 0) {
error = sooptcopyin(sopt, &frwl, sizeof frwl, sizeof frwl);
if (error)
- break ;
+ break;
arg = &frwl ;
}
error = zero_entry(arg, cmd);
@@ -2130,38 +2139,48 @@ ip_fw_init(void)
#endif
}
-static ip_fw_chk_t *old_chk_ptr;
-static ip_fw_ctl_t *old_ctl_ptr;
-
static int
ipfw_modevent(module_t mod, int type, void *unused)
{
int s;
+ int err = 0 ;
struct ip_fw *fcp;
switch (type) {
case MOD_LOAD:
- s = splnet();
-
- old_chk_ptr = ip_fw_chk_ptr;
- old_ctl_ptr = ip_fw_ctl_ptr;
-
- ip_fw_init();
- splx(s);
- return 0;
+ printf("IPFW: MOD_LOAD\n");
+ s = splimp();
+ if (IPFW_LOADED) {
+ splx(s);
+ printf("IP firewall already loaded\n");
+ err = EEXIST ;
+ } else {
+ ip_fw_init();
+ splx(s);
+ }
+ break ;
case MOD_UNLOAD:
- s = splnet();
- ip_fw_chk_ptr = old_chk_ptr;
- ip_fw_ctl_ptr = old_ctl_ptr;
+ printf("IPFW: MOD_UNLOAD\n");
+#if !defined(KLD_MODULE)
+ printf("ipfw statically compiled, cannot unload\n");
+ err = EBUSY;
+#else
+ s = splimp();
+ ip_fw_chk_ptr = NULL ;
+ ip_fw_ctl_ptr = NULL ;
+ {
+ struct ip_fw *fcp;
while ( (fcp = LIST_FIRST(&ip_fw_chain_head)) != NULL)
free_chain(fcp);
+ }
splx(s);
printf("IP firewall unloaded\n");
- return 0;
+#endif
+ break;
default:
break;
}
- return 0;
+ return err;
}
static moduledata_t ipfwmod = {
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h
index 12fc4fc..07d659f 100644
--- a/sys/netinet/ip_fw.h
+++ b/sys/netinet/ip_fw.h
@@ -327,6 +327,7 @@ extern ip_fw_ctl_t *ip_fw_ctl_ptr;
extern int fw_one_pass;
extern int fw_enable;
extern struct ipfw_flow_id last_pkt;
+#define IPFW_LOADED (ip_fw_chk_ptr != NULL)
#endif /* _KERNEL */
#endif /* _IP_FW_H */
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index f529a7e..17e3103 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -81,7 +81,6 @@
#include <netinet/ip_fw.h>
#include <netinet/ip_dummynet.h>
-
#ifdef IPSEC
#include <netinet6/ipsec.h>
#include <netkey/key.h>
@@ -439,7 +438,7 @@ iphack:
}
#endif /* PFIL_HOOKS */
- if (fw_enable && ip_fw_chk_ptr) {
+ if (fw_enable && IPFW_LOADED) {
#ifdef IPFIREWALL_FORWARD
/*
* If we've been forwarded from the output side, then
@@ -452,7 +451,7 @@ iphack:
* See the comment in ip_output for the return values
* produced by the firewall.
*/
- i = (*ip_fw_chk_ptr)(&ip,
+ i = ip_fw_chk_ptr(&ip,
hlen, NULL, &divert_cookie, &m, &rule, &ip_fw_fwd_addr);
if (i & IP_FW_PORT_DENY_FLAG) { /* XXX new interface-denied */
if (m)
@@ -469,7 +468,7 @@ iphack:
}
if (i == 0 && ip_fw_fwd_addr == NULL) /* common case */
goto pass;
- if (ip_dn_io_ptr != NULL && (i & IP_FW_PORT_DYNT_FLAG) != 0) {
+ if (DUMMYNET_LOADED && (i & IP_FW_PORT_DYNT_FLAG) != 0) {
/* Send packet to the appropriate pipe */
ip_dn_io_ptr(i&0xffff,DN_TO_IP_IN,m,NULL,NULL,0, rule,
0);
@@ -541,7 +540,7 @@ pass:
* is not locally generated and the packet is not subject to
* 'ipfw fwd'.
*
- * XXX - Checking also should be disabled if the destination
+ * XXX - Checking also should be disabled if the destination
* address is ipnat'ed to a different interface.
*
* XXX - Checking is incompatible with IP aliases added
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 060c4c0..304aa4d 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -586,10 +586,10 @@ skip_ipsec:
/*
* Check with the firewall...
*/
- if (fw_enable && ip_fw_chk_ptr) {
+ if (fw_enable && IPFW_LOADED) {
struct sockaddr_in *old = dst;
- off = (*ip_fw_chk_ptr)(&ip,
+ off = ip_fw_chk_ptr(&ip,
hlen, ifp, &divert_cookie, &m, &rule, &dst);
/*
* On return we must do the following:
@@ -623,7 +623,7 @@ skip_ipsec:
}
if (off == 0 && dst == old) /* common case */
goto pass ;
- if (ip_dn_io_ptr != NULL && (off & IP_FW_PORT_DYNT_FLAG) != 0) {
+ if (DUMMYNET_LOADED && (off & IP_FW_PORT_DYNT_FLAG) != 0) {
/*
* pass the pkt to dummynet. Need to include
* pipe number, m, ifp, ro, dst because these are
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 1bad6dd..b31be39 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -70,8 +70,6 @@
#include <netinet6/ipsec.h>
#endif /*IPSEC*/
-#include "opt_ipdn.h"
-
struct inpcbhead ripcb;
struct inpcbinfo ripcbinfo;
@@ -288,19 +286,19 @@ rip_ctloutput(so, sopt)
error = sooptcopyout(sopt, &optval, sizeof optval);
break;
- case IP_FW_ADD:
+ case IP_FW_ADD: /* ADD actually returns the body... */
case IP_FW_GET:
- if (ip_fw_ctl_ptr == NULL)
- error = ENOPROTOOPT;
- else
+ if (IPFW_LOADED)
error = ip_fw_ctl_ptr(sopt);
+ else
+ error = ENOPROTOOPT;
break;
case IP_DUMMYNET_GET:
- if (ip_dn_ctl_ptr == NULL)
- error = ENOPROTOOPT;
- else
+ if (DUMMYNET_LOADED)
error = ip_dn_ctl_ptr(sopt);
+ else
+ error = ENOPROTOOPT;
break ;
case MRT_INIT:
@@ -333,24 +331,23 @@ rip_ctloutput(so, sopt)
inp->inp_flags &= ~INP_HDRINCL;
break;
- case IP_FW_ADD:
case IP_FW_DEL:
case IP_FW_FLUSH:
case IP_FW_ZERO:
case IP_FW_RESETLOG:
- if (ip_fw_ctl_ptr == 0)
- error = ENOPROTOOPT;
- else
+ if (IPFW_LOADED)
error = ip_fw_ctl_ptr(sopt);
+ else
+ error = ENOPROTOOPT;
break;
case IP_DUMMYNET_CONFIGURE:
case IP_DUMMYNET_DEL:
case IP_DUMMYNET_FLUSH:
- if (ip_dn_ctl_ptr == NULL)
- error = ENOPROTOOPT ;
- else
+ if (DUMMYNET_LOADED)
error = ip_dn_ctl_ptr(sopt);
+ else
+ error = ENOPROTOOPT ;
break ;
case IP_RSVP_ON:
OpenPOWER on IntegriCloud