summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/netpfil/pf
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2017-04-04 09:36:57 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-04-04 14:46:23 +0200
commitde8a76da2f374792594ce03a203b3f30e4889f6f (patch)
tree12b5e1e59358005c3c522955c08aee4795e4829c /freebsd/sys/netpfil/pf
parentEnable bridging by default (diff)
downloadrtems-libbsd-de8a76da2f374792594ce03a203b3f30e4889f6f.tar.bz2
Update to FreeBSD head 2017-04-04
Git mirror commit 642b174daddbd0efd9bb5f242c43f4ab4db6869f.
Diffstat (limited to 'freebsd/sys/netpfil/pf')
-rw-r--r--freebsd/sys/netpfil/pf/pf.c63
-rw-r--r--freebsd/sys/netpfil/pf/pf_ioctl.c14
-rw-r--r--freebsd/sys/netpfil/pf/pf_lb.c2
-rw-r--r--freebsd/sys/netpfil/pf/pf_osfp.c15
4 files changed, 61 insertions, 33 deletions
diff --git a/freebsd/sys/netpfil/pf/pf.c b/freebsd/sys/netpfil/pf/pf.c
index 5b6be3cb..0d7a353e 100644
--- a/freebsd/sys/netpfil/pf/pf.c
+++ b/freebsd/sys/netpfil/pf/pf.c
@@ -131,6 +131,8 @@ VNET_DEFINE(int, pf_tcp_secret_init);
#define V_pf_tcp_secret_init VNET(pf_tcp_secret_init)
VNET_DEFINE(int, pf_tcp_iss_off);
#define V_pf_tcp_iss_off VNET(pf_tcp_iss_off)
+VNET_DECLARE(int, pf_vnet_active);
+#define V_pf_vnet_active VNET(pf_vnet_active)
/*
* Queue for pf_intr() sends.
@@ -302,6 +304,7 @@ static void pf_route6(struct mbuf **, struct pf_rule *, int,
int in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len);
extern int pf_end_threads;
+extern struct proc *pf_purge_proc;
VNET_DEFINE(struct pf_limit, pf_limits[PF_LIMIT_MAX]);
@@ -1428,42 +1431,51 @@ pf_purge_thread(void *unused __unused)
VNET_ITERATOR_DECL(vnet_iter);
u_int idx = 0;
- for (;;) {
- PF_RULES_RLOCK();
- rw_sleep(pf_purge_thread, &pf_rules_lock, 0, "pftm", hz / 10);
- PF_RULES_RUNLOCK();
+ sx_xlock(&pf_end_lock);
+ while (pf_end_threads == 0) {
+ sx_sleep(pf_purge_thread, &pf_end_lock, 0, "pftm", hz / 10);
VNET_LIST_RLOCK();
VNET_FOREACH(vnet_iter) {
CURVNET_SET(vnet_iter);
- if (pf_end_threads) {
- pf_end_threads++;
- wakeup(pf_purge_thread);
- kproc_exit(0);
- }
- /* Process 1/interval fraction of the state table every run. */
- idx = pf_purge_expired_states(idx, pf_hashmask /
+ /* Wait until V_pf_default_rule is initialized. */
+ if (V_pf_vnet_active == 0) {
+ CURVNET_RESTORE();
+ continue;
+ }
+
+ /*
+ * Process 1/interval fraction of the state
+ * table every run.
+ */
+ idx = pf_purge_expired_states(idx, pf_hashmask /
(V_pf_default_rule.timeout[PFTM_INTERVAL] * 10));
- /* Purge other expired types every PFTM_INTERVAL seconds. */
- if (idx == 0) {
/*
- * Order is important:
- * - states and src nodes reference rules
- * - states and rules reference kifs
+ * Purge other expired types every
+ * PFTM_INTERVAL seconds.
*/
- pf_purge_expired_fragments();
- pf_purge_expired_src_nodes();
- pf_purge_unlinked_rules();
- pfi_kif_purge();
- }
- CURVNET_RESTORE();
+ if (idx == 0) {
+ /*
+ * Order is important:
+ * - states and src nodes reference rules
+ * - states and rules reference kifs
+ */
+ pf_purge_expired_fragments();
+ pf_purge_expired_src_nodes();
+ pf_purge_unlinked_rules();
+ pfi_kif_purge();
+ }
+ CURVNET_RESTORE();
}
VNET_LIST_RUNLOCK();
}
- /* not reached */
+
+ pf_end_threads++;
+ sx_xunlock(&pf_end_lock);
+ kproc_exit(0);
}
void
@@ -3559,7 +3571,7 @@ pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a,
(counter_u64_fetch(r->states_cur) >= r->max_states)) {
counter_u64_add(V_pf_status.lcounters[LCNT_STATES], 1);
REASON_SET(&reason, PFRES_MAXSTATES);
- return (PF_DROP);
+ goto csfailed;
}
/* src node for filter rule */
if ((r->rule_flag & PFRULE_SRCTRACK ||
@@ -6244,6 +6256,9 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp)
m->m_pkthdr.rcvif->if_bridge != ifp->if_bridge)))
fwdir = PF_FWD;
+ if (dir == PF_FWD)
+ dir = PF_OUT;
+
if (!V_pf_status.running)
return (PF_PASS);
diff --git a/freebsd/sys/netpfil/pf/pf_ioctl.c b/freebsd/sys/netpfil/pf/pf_ioctl.c
index 076ed5f8..3cf3eec8 100644
--- a/freebsd/sys/netpfil/pf/pf_ioctl.c
+++ b/freebsd/sys/netpfil/pf/pf_ioctl.c
@@ -200,9 +200,11 @@ VNET_DEFINE(int, pf_vnet_active);
#define V_pf_vnet_active VNET(pf_vnet_active)
int pf_end_threads;
+struct proc *pf_purge_proc;
struct rwlock pf_rules_lock;
struct sx pf_ioctl_lock;
+struct sx pf_end_lock;
/* pfsync */
pfsync_state_import_t *pfsync_state_import_ptr = NULL;
@@ -3742,6 +3744,7 @@ pf_load(void)
rw_init(&pf_rules_lock, "pf rulesets");
sx_init(&pf_ioctl_lock, "pf ioctl");
+ sx_init(&pf_end_lock, "pf end thread");
pf_mtag_initialize();
@@ -3750,7 +3753,7 @@ pf_load(void)
return (ENOMEM);
pf_end_threads = 0;
- error = kproc_create(pf_purge_thread, NULL, NULL, 0, 0, "pf purge");
+ error = kproc_create(pf_purge_thread, NULL, &pf_purge_proc, 0, 0, "pf purge");
if (error != 0)
return (error);
@@ -3778,12 +3781,12 @@ pf_unload_vnet(void)
return;
}
- pf_unload_vnet_purge();
-
PF_RULES_WLOCK();
shutdown_pf();
PF_RULES_WUNLOCK();
+ pf_unload_vnet_purge();
+
pf_normalize_cleanup();
PF_RULES_WLOCK();
pfi_cleanup_vnet();
@@ -3800,11 +3803,13 @@ pf_unload(void)
{
int error = 0;
+ sx_xlock(&pf_end_lock);
pf_end_threads = 1;
while (pf_end_threads < 2) {
wakeup_one(pf_purge_thread);
- rw_sleep(pf_purge_thread, &pf_rules_lock, 0, "pftmo", 0);
+ sx_sleep(pf_purge_proc, &pf_end_lock, 0, "pftmo", 0);
}
+ sx_xunlock(&pf_end_lock);
if (pf_dev != NULL)
destroy_dev(pf_dev);
@@ -3813,6 +3818,7 @@ pf_unload(void)
rw_destroy(&pf_rules_lock);
sx_destroy(&pf_ioctl_lock);
+ sx_destroy(&pf_end_lock);
return (error);
}
diff --git a/freebsd/sys/netpfil/pf/pf_lb.c b/freebsd/sys/netpfil/pf/pf_lb.c
index 033c3879..3fe8dfb6 100644
--- a/freebsd/sys/netpfil/pf/pf_lb.c
+++ b/freebsd/sys/netpfil/pf/pf_lb.c
@@ -555,7 +555,7 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction,
return (NULL);
*nkp = pf_state_key_clone(*skp);
if (*nkp == NULL) {
- uma_zfree(V_pf_state_key_z, skp);
+ uma_zfree(V_pf_state_key_z, *skp);
*skp = NULL;
return (NULL);
}
diff --git a/freebsd/sys/netpfil/pf/pf_osfp.c b/freebsd/sys/netpfil/pf/pf_osfp.c
index 33bef4c8..b6b51636 100644
--- a/freebsd/sys/netpfil/pf/pf_osfp.c
+++ b/freebsd/sys/netpfil/pf/pf_osfp.c
@@ -21,6 +21,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <rtems/bsd/local/opt_inet6.h>
+
#include <rtems/bsd/sys/param.h>
#include <sys/kernel.h>
#include <rtems/bsd/sys/lock.h>
@@ -36,7 +38,9 @@ __FBSDID("$FreeBSD$");
#include <net/vnet.h>
#include <net/pfvar.h>
+#ifdef INET6
#include <netinet/ip6.h>
+#endif
static MALLOC_DEFINE(M_PFOSFP, "pf_osfp", "pf(4) operating system fingerprints");
#define DPFPRINTF(format, x...) \
@@ -96,7 +100,11 @@ pf_osfp_fingerprint_hdr(const struct ip *ip, const struct ip6_hdr *ip6, const st
struct pf_os_fingerprint fp, *fpresult;
int cnt, optlen = 0;
const u_int8_t *optp;
- char srcname[128];
+#ifdef INET6
+ char srcname[INET6_ADDRSTRLEN];
+#else
+ char srcname[INET_ADDRSTRLEN];
+#endif
if ((tcp->th_flags & (TH_SYN|TH_ACK)) != TH_SYN)
return (NULL);
@@ -112,7 +120,7 @@ pf_osfp_fingerprint_hdr(const struct ip *ip, const struct ip6_hdr *ip6, const st
fp.fp_ttl = ip->ip_ttl;
if (ip->ip_off & htons(IP_DF))
fp.fp_flags |= PF_OSFP_DF;
- strlcpy(srcname, inet_ntoa(ip->ip_src), sizeof(srcname));
+ inet_ntoa_r(ip->ip_src, srcname);
}
#ifdef INET6
else if (ip6) {
@@ -121,8 +129,7 @@ pf_osfp_fingerprint_hdr(const struct ip *ip, const struct ip6_hdr *ip6, const st
fp.fp_ttl = ip6->ip6_hlim;
fp.fp_flags |= PF_OSFP_DF;
fp.fp_flags |= PF_OSFP_INET6;
- strlcpy(srcname, ip6_sprintf((struct in6_addr *)&ip6->ip6_src),
- sizeof(srcname));
+ ip6_sprintf(srcname, (const struct in6_addr *)&ip6->ip6_src);
}
#endif
else