Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F98167455
D46864.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
25 KB
Referenced Files
None
Subscribers
None
D46864.diff
View Options
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1602,7 +1602,6 @@
char any[0];
} hdr;
- struct pf_krule *nat_rule; /* nat/rdr rule applied to packet */
struct pf_addr *src; /* src address */
struct pf_addr *dst; /* dst address */
u_int16_t *sport;
@@ -2632,7 +2631,8 @@
struct pf_addr *, struct pf_addr *,
uint16_t, uint16_t, struct pf_kanchor_stackframe *,
struct pf_krule **,
- struct pf_udp_mapping **udp_mapping);
+ struct pf_udp_mapping **udp_mapping,
+ struct pf_krule_slist *match_rules);
struct pf_state_key *pf_state_key_setup(struct pf_pdesc *, struct mbuf *, int,
struct pf_addr *, struct pf_addr *, u_int16_t, u_int16_t);
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -322,14 +322,16 @@
static int pf_test_rule(struct pf_krule **, struct pf_kstate **,
struct pfi_kkif *, struct mbuf *, int,
struct pf_pdesc *, struct pf_krule **,
- struct pf_kruleset **, struct inpcb *, int);
+ struct pf_kruleset **, struct inpcb *, int,
+ struct pf_krule_slist *);
static int pf_create_state(struct pf_krule *, struct pf_krule *,
struct pf_krule *, struct pf_pdesc *,
struct pf_ksrc_node *, struct pf_state_key *,
struct pf_state_key *, struct mbuf *, int,
u_int16_t, u_int16_t, int *, struct pfi_kkif *,
struct pf_kstate **, int, u_int16_t, u_int16_t,
- int, struct pf_krule_slist *, struct pf_udp_mapping *);
+ int, struct pf_udp_mapping *,
+ struct pf_krule_slist *);
static int pf_state_key_addr_setup(struct pf_pdesc *, struct mbuf *,
int, struct pf_state_key_cmp *, int, struct pf_addr *,
int, struct pf_addr *, int);
@@ -371,10 +373,9 @@
const struct pf_state_key_cmp *, u_int);
static int pf_src_connlimit(struct pf_kstate **);
static int pf_match_rcvif(struct mbuf *, struct pf_krule *);
-static void pf_counters_inc(int,
- struct pf_pdesc *, struct pfi_kkif *,
- struct pf_kstate *, struct pf_krule *,
- struct pf_krule *);
+static void pf_counters_inc(int, struct pf_pdesc *,
+ struct pfi_kkif *, struct pf_kstate *,
+ struct pf_krule_slist *match_rules);
static void pf_overload_task(void *v, int pending);
static u_short pf_insert_src_node(struct pf_ksrc_node **,
struct pf_krule *, struct pf_addr *, sa_family_t);
@@ -4885,7 +4886,8 @@
static int
pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm, struct pfi_kkif *kif,
struct mbuf *m, int off, struct pf_pdesc *pd, struct pf_krule **am,
- struct pf_kruleset **rsm, struct inpcb *inp, int hdrlen)
+ struct pf_kruleset **rsm, struct inpcb *inp, int hdrlen,
+ struct pf_krule_slist *match_rules)
{
struct pf_krule *nr = NULL;
struct pf_addr * const saddr = pd->src;
@@ -4893,7 +4895,6 @@
sa_family_t af = pd->af;
struct pf_krule *r, *a = NULL;
struct pf_kruleset *ruleset = NULL;
- struct pf_krule_slist match_rules;
struct pf_krule_item *ri;
struct pf_ksrc_node *nsn = NULL;
struct tcphdr *th = &pd->hdr.tcp;
@@ -4912,8 +4913,6 @@
PF_RULES_RASSERT();
- SLIST_INIT(&match_rules);
-
if (inp != NULL) {
INP_LOCK_ASSERT(inp);
pd->lookup.uid = inp->inp_cred->cr_uid;
@@ -4976,7 +4975,8 @@
/* check packet for BINAT/NAT/RDR */
transerror = pf_get_translation(pd, m, off, kif, &nsn, &sk,
- &nk, saddr, daddr, sport, dport, anchor_stack, &nr, &udp_mapping);
+ &nk, saddr, daddr, sport, dport, anchor_stack, &nr, &udp_mapping,
+ match_rules);
switch (transerror) {
default:
/* A translation error occurred. */
@@ -5131,7 +5131,6 @@
}
if (nr->natpass)
r = NULL;
- pd->nat_rule = nr;
}
while (r != NULL) {
@@ -5228,21 +5227,20 @@
r->os_fingerprint)),
TAILQ_NEXT(r, entries));
/* FALLTHROUGH */
+
+ ri = malloc(sizeof(struct pf_krule_item), M_PF_RULE_ITEM, M_NOWAIT | M_ZERO);
+ if (ri == NULL) {
+ REASON_SET(&reason, PFRES_MEMORY);
+ goto cleanup;
+ }
+ ri->r = r;
+ SLIST_INSERT_HEAD(match_rules, ri, entry);
+
+
if (r->tag)
tag = r->tag;
if (r->anchor == NULL) {
if (r->action == PF_MATCH) {
- ri = malloc(sizeof(struct pf_krule_item), M_PF_RULE_ITEM, M_NOWAIT | M_ZERO);
- if (ri == NULL) {
- REASON_SET(&reason, PFRES_MEMORY);
- goto cleanup;
- }
- ri->r = r;
- SLIST_INSERT_HEAD(&match_rules, ri, entry);
- pf_counter_u64_critical_enter();
- pf_counter_u64_add_protected(&r->packets[pd->dir == PF_OUT], 1);
- pf_counter_u64_add_protected(&r->bytes[pd->dir == PF_OUT], pd->tot_len);
- pf_counter_u64_critical_exit();
pf_rule_to_actions(r, &pd->act);
if (r->log || pd->act.log & PF_LOG_MATCHES)
PFLOG_PACKET(kif, m,
@@ -5310,7 +5308,7 @@
int action;
action = pf_create_state(r, nr, a, pd, nsn, nk, sk, m, off,
sport, dport, &rewrite, kif, sm, tag, bproto_sum, bip_sum,
- hdrlen, &match_rules, udp_mapping);
+ hdrlen, udp_mapping, match_rules);
if (action != PF_PASS) {
pf_udp_mapping_release(udp_mapping);
if (action == PF_DROP &&
@@ -5321,11 +5319,6 @@
return (action);
}
} else {
- while ((ri = SLIST_FIRST(&match_rules))) {
- SLIST_REMOVE_HEAD(&match_rules, entry);
- free(ri, M_PF_RULE_ITEM);
- }
-
uma_zfree(V_pf_state_key_z, sk);
uma_zfree(V_pf_state_key_z, nk);
pf_udp_mapping_release(udp_mapping);
@@ -5349,11 +5342,6 @@
return (PF_PASS);
cleanup:
- while ((ri = SLIST_FIRST(&match_rules))) {
- SLIST_REMOVE_HEAD(&match_rules, entry);
- free(ri, M_PF_RULE_ITEM);
- }
-
uma_zfree(V_pf_state_key_z, sk);
uma_zfree(V_pf_state_key_z, nk);
pf_udp_mapping_release(udp_mapping);
@@ -5367,14 +5355,13 @@
struct pf_state_key *sk, struct mbuf *m, int off, u_int16_t sport,
u_int16_t dport, int *rewrite, struct pfi_kkif *kif, struct pf_kstate **sm,
int tag, u_int16_t bproto_sum, u_int16_t bip_sum, int hdrlen,
- struct pf_krule_slist *match_rules, struct pf_udp_mapping *udp_mapping)
+ struct pf_udp_mapping *udp_mapping, struct pf_krule_slist *match_rules)
{
struct pf_kstate *s = NULL;
struct pf_ksrc_node *sn = NULL;
struct tcphdr *th = &pd->hdr.tcp;
u_int16_t mss = V_tcp_mssdflt;
u_short reason, sn_reason;
- struct pf_krule_item *ri;
/* check maximums */
if (r->max_states &&
@@ -5589,11 +5576,6 @@
return (PF_PASS);
csfailed:
- while ((ri = SLIST_FIRST(match_rules))) {
- SLIST_REMOVE_HEAD(match_rules, entry);
- free(ri, M_PF_RULE_ITEM);
- }
-
uma_zfree(V_pf_state_key_z, sk);
uma_zfree(V_pf_state_key_z, nk);
@@ -6583,7 +6565,7 @@
*/
ret = pf_test_rule(&r, &sm, V_pfi_all,
j->m, off, &j->pd, &ra, &rs, NULL,
- sizeof(j->pd.hdr.sctp));
+ sizeof(j->pd.hdr.sctp), NULL);
PF_RULES_RUNLOCK();
SDT_PROBE4(pf, sctp, multihome, test, kif, r, j->m, ret);
if (ret != PF_DROP && sm != NULL) {
@@ -7709,6 +7691,7 @@
struct pfi_kkif *nkif = NULL;
struct ifnet *ifp = NULL;
struct pf_addr naddr;
+ struct pf_krule_item *ri;
int error = 0;
uint16_t ip_len, ip_off;
uint16_t tmp;
@@ -7900,10 +7883,17 @@
error = EMSGSIZE;
KMOD_IPSTAT_INC(ips_cantfrag);
if (r_rt != PF_DUPTO) {
- if (s && pd->nat_rule != NULL)
- PACKET_UNDO_NAT(m0, pd,
- (ip->ip_hl << 2) + (ip_off & IP_OFFMASK),
- s);
+ if (s) {
+ while ((ri = SLIST_FIRST(&(s->match_rules)))) {
+ if (ri->r->action == PF_NAT ||
+ ri->r->action == PF_RDR) {
+ PACKET_UNDO_NAT(m0, pd,
+ (ip->ip_hl << 2) +
+ (ip_off & IP_OFFMASK),
+ s);
+ }
+ }
+ }
icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0,
ifp->if_mtu);
@@ -7959,6 +7949,7 @@
struct ip6_hdr *ip6;
struct pfi_kkif *nkif = NULL;
struct ifnet *ifp = NULL;
+ struct pf_krule_item *ri;
struct pf_addr naddr;
int r_rt, r_dir;
@@ -8113,10 +8104,18 @@
else {
in6_ifstat_inc(ifp, ifs6_in_toobig);
if (r_rt != PF_DUPTO) {
- if (s && pd->nat_rule != NULL)
- PACKET_UNDO_NAT(m0, pd,
- ((caddr_t)ip6 - m0->m_data) +
- sizeof(struct ip6_hdr), s);
+ if (s) {
+ while ((ri = SLIST_FIRST(&(s->match_rules)))) {
+ if (ri->r->action == PF_NAT ||
+ ri->r->action == PF_RDR) {
+ PACKET_UNDO_NAT(m0, pd,
+ ((caddr_t)ip6 -
+ m0->m_data) +
+ sizeof(struct ip6_hdr),
+ s);
+ }
+ }
+ }
icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu);
} else
@@ -8466,17 +8465,16 @@
u_short *action, u_short *reason, struct pfi_kkif *kif, struct pf_krule **a,
struct pf_krule **r, struct pf_kstate **s, struct pf_kruleset **ruleset,
int *off, int *hdrlen, struct inpcb *inp,
- struct pf_rule_actions *default_actions)
+ struct pf_rule_actions *default_actions, struct pf_krule_slist *match_rules)
{
struct mbuf *m = *m0;
- memset(pd, 0, sizeof(*pd));
+ SLIST_INIT(match_rules);
pd->dir = dir;
TAILQ_INIT(&pd->sctp_multihome_jobs);
if (default_actions != NULL)
memcpy(&pd->act, default_actions, sizeof(pd->act));
- pd->pf_mtag = pf_find_mtag(m);
if (pd->pf_mtag && pd->pf_mtag->dnpipe) {
pd->act.dnpipe = pd->pf_mtag->dnpipe;
@@ -8539,7 +8537,7 @@
*action = PF_DROP;
else
*action = pf_test_rule(r, s, kif, m, *off,
- pd, a, ruleset, inp, *hdrlen);
+ pd, a, ruleset, inp, *hdrlen, match_rules);
if (*action != PF_PASS)
REASON_SET(reason, PFRES_FRAG);
return (-1);
@@ -8594,7 +8592,7 @@
else
*action = pf_test_rule(r, s, kif, m, *off,
pd, a, ruleset, inp,
- *hdrlen);
+ *hdrlen, match_rules);
if (*action == PF_DROP)
REASON_SET(reason, PFRES_FRAG);
return (-1);
@@ -8767,11 +8765,11 @@
}
static void
-pf_counters_inc(int action, struct pf_pdesc *pd,
- struct pfi_kkif *kif, struct pf_kstate *s,
- struct pf_krule *r, struct pf_krule *a)
+pf_counters_inc(int action, struct pf_pdesc *pd, struct pfi_kkif *kif,
+ struct pf_kstate *s, struct pf_krule_slist *match_rules)
{
- struct pf_krule *tr, *nr;
+ struct pf_krule_item *ri;
+ struct pf_addr *src, *dst;
int dir = pd->dir;
int dirndx;
@@ -8783,65 +8781,58 @@
&kif->pfik_packets[pd->af == AF_INET6][dir == PF_OUT][action != PF_PASS],
1);
- if (action == PF_PASS || r->action == PF_DROP) {
- dirndx = (dir == PF_OUT);
- pf_counter_u64_add_protected(&r->packets[dirndx], 1);
- pf_counter_u64_add_protected(&r->bytes[dirndx], pd->tot_len);
- pf_update_timestamp(r);
-
- if (a != NULL) {
- pf_counter_u64_add_protected(&a->packets[dirndx], 1);
- pf_counter_u64_add_protected(&a->bytes[dirndx], pd->tot_len);
- }
- if (s != NULL) {
- struct pf_krule_item *ri;
-
- if (s->nat_rule.ptr != NULL) {
- pf_counter_u64_add_protected(&s->nat_rule.ptr->packets[dirndx],
- 1);
- pf_counter_u64_add_protected(&s->nat_rule.ptr->bytes[dirndx],
- pd->tot_len);
- }
- if (s->src_node != NULL) {
- counter_u64_add(s->src_node->packets[dirndx],
- 1);
- counter_u64_add(s->src_node->bytes[dirndx],
- pd->tot_len);
- }
- if (s->nat_src_node != NULL) {
- counter_u64_add(s->nat_src_node->packets[dirndx],
- 1);
- counter_u64_add(s->nat_src_node->bytes[dirndx],
- pd->tot_len);
- }
- dirndx = (dir == s->direction) ? 0 : 1;
- s->packets[dirndx]++;
- s->bytes[dirndx] += pd->tot_len;
-
- SLIST_FOREACH(ri, &s->match_rules, entry) {
- pf_counter_u64_add_protected(&ri->r->packets[dirndx], 1);
- pf_counter_u64_add_protected(&ri->r->bytes[dirndx], pd->tot_len);
- }
- }
- tr = r;
- nr = (s != NULL) ? s->nat_rule.ptr : pd->nat_rule;
- if (nr != NULL && r == &V_pf_default_rule)
- tr = nr;
- if (tr->src.addr.type == PF_ADDR_TABLE)
- pfr_update_stats(tr->src.addr.p.tbl,
- (s == NULL) ? pd->src :
- &s->key[(s->direction == PF_IN)]->
- addr[(s->direction == PF_OUT)],
- pd->af, pd->tot_len, dir == PF_OUT,
- r->action == PF_PASS, tr->src.neg);
- if (tr->dst.addr.type == PF_ADDR_TABLE)
- pfr_update_stats(tr->dst.addr.p.tbl,
- (s == NULL) ? pd->dst :
- &s->key[(s->direction == PF_IN)]->
- addr[(s->direction == PF_IN)],
- pd->af, pd->tot_len, dir == PF_OUT,
- r->action == PF_PASS, tr->dst.neg);
+ if (s == NULL) {
+ src = pd->src;
+ dst = pd->dst;
+ } else {
+ src = &s->key[(s->direction == PF_IN)]->addr[(s->direction == PF_OUT)];
+ dst = &s->key[(s->direction == PF_IN)]->addr[(s->direction == PF_IN)];
}
+
+ dirndx = (dir == PF_OUT);
+
+ SLIST_FOREACH(ri, match_rules, entry) {
+ if (action == PF_PASS || ri->r->action == PF_DROP) {
+ pf_counter_u64_add_protected(&ri->r->packets[dirndx], 1);
+ pf_counter_u64_add_protected(&ri->r->bytes[dirndx], pd->tot_len);
+ pf_update_timestamp(ri->r);
+ }
+
+ if (ri->r->src.addr.type == PF_ADDR_TABLE)
+ pfr_update_stats(ri->r->src.addr.p.tbl,
+ src, pd->af, pd->tot_len, dirndx,
+ ri->r->action == PF_PASS, ri->r->src.neg);
+ if (ri->r->dst.addr.type == PF_ADDR_TABLE)
+ pfr_update_stats(ri->r->dst.addr.p.tbl,
+ dst, pd->af, pd->tot_len, dirndx,
+ ri->r->action == PF_PASS, ri->r->dst.neg);
+ }
+
+ if (s != NULL) {
+ if (s->src_node != NULL) {
+ counter_u64_add(s->src_node->packets[dirndx], 1);
+ counter_u64_add(s->src_node->bytes[dirndx], pd->tot_len);
+ }
+ if (s->nat_src_node != NULL) {
+ counter_u64_add(s->nat_src_node->packets[dirndx], 1);
+ counter_u64_add(s->nat_src_node->bytes[dirndx], pd->tot_len);
+ }
+ dirndx = (dir == s->direction) ? 0 : 1;
+ s->packets[dirndx]++;
+ s->bytes[dirndx] += pd->tot_len;
+
+ printf("Counters:");
+ printf(" 00: ");
+ pf_print_host(&s->key[0]->addr[0], 0, pd->af);
+ printf(" 01: ");
+ pf_print_host(&s->key[0]->addr[1], 0, pd->af);
+ printf(" 10: ");
+ pf_print_host(&s->key[1]->addr[0], 0, pd->af);
+ printf(" 11: ");
+ pf_print_host(&s->key[1]->addr[1], 0, pd->af);
+ printf("\n");
+ }
+
pf_counter_u64_critical_exit();
}
@@ -8850,6 +8841,8 @@
pf_test(sa_family_t af, int dir, int pflags, struct ifnet *ifp, struct mbuf **m0,
struct inpcb *inp, struct pf_rule_actions *default_actions)
{
+ struct pf_krule_slist match_rules;
+ struct pf_krule_item *ri;
struct pfi_kkif *kif;
u_short action, reason = 0;
struct mbuf *m = *m0;
@@ -8913,30 +8906,8 @@
return (PF_DROP);
}
- if (pf_setup_pdesc(af, dir, &pd, m0, &action, &reason, kif, &a, &r,
- &s, &ruleset, &off, &hdrlen, inp, default_actions) == -1) {
- if (action != PF_PASS)
- pd.act.log |= PF_LOG_FORCE;
- goto done;
- }
- m = *m0;
-
- switch (af) {
-#ifdef INET
- case AF_INET:
- h = mtod(m, struct ip *);
- ttl = h->ip_ttl;
- break;
-#endif
-#ifdef INET6
- case AF_INET6:
- h6 = mtod(m, struct ip6_hdr *);
- ttl = h6->ip6_hlim;
- break;
-#endif
- default:
- panic("Unknown af %d", af);
- }
+ memset(&pd, 0, sizeof(pd));
+ pd.pf_mtag = pf_find_mtag(*m0);
if (pd.pf_mtag != NULL && (pd.pf_mtag->flags & PF_MTAG_FLAG_ROUTE_TO)) {
pd.pf_mtag->flags &= ~PF_MTAG_FLAG_ROUTE_TO;
@@ -8969,6 +8940,15 @@
return (PF_PASS);
}
+ if (pf_setup_pdesc(af, dir, &pd, m0, &action, &reason, kif, &a, &r,
+ &s, &ruleset, &off, &hdrlen, inp, default_actions,
+ &match_rules) == -1) {
+ if (action != PF_PASS)
+ pd.act.log |= PF_LOG_FORCE;
+ goto done;
+ }
+ m = *m0;
+
if (__predict_false(ip_divert_ptr != NULL) &&
((mtag = m_tag_locate(m, MTAG_PF_DIVERT, 0, NULL)) != NULL)) {
struct pf_divert_mtag *dt = (struct pf_divert_mtag *)(mtag+1);
@@ -8992,6 +8972,23 @@
m_tag_delete(m, mtag);
}
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ h = mtod(m, struct ip *);
+ ttl = h->ip_ttl;
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ h6 = mtod(m, struct ip6_hdr *);
+ ttl = h6->ip6_hlim;
+ break;
+#endif
+ default:
+ panic("Unknown af %d", af);
+ }
+
#ifdef INET6
/*
* we do not support jumbogram. if we keep going, zero ip6_plen
@@ -9060,7 +9057,7 @@
break;
} else {
action = pf_test_rule(&r, &s, kif, m, off, &pd,
- &a, &ruleset, inp, hdrlen);
+ &a, &ruleset, inp, hdrlen, &match_rules);
}
}
break;
@@ -9075,7 +9072,7 @@
a = s->anchor.ptr;
} else if (s == NULL)
action = pf_test_rule(&r, &s, kif, m, off, &pd,
- &a, &ruleset, inp, hdrlen);
+ &a, &ruleset, inp, hdrlen, &match_rules);
break;
}
@@ -9092,7 +9089,7 @@
a = s->anchor.ptr;
} else if (s == NULL) {
action = pf_test_rule(&r, &s, kif, m, off,
- &pd, &a, &ruleset, inp, hdrlen);
+ &pd, &a, &ruleset, inp, hdrlen, &match_rules);
}
break;
}
@@ -9112,7 +9109,7 @@
a = s->anchor.ptr;
} else if (s == NULL)
action = pf_test_rule(&r, &s, kif, m, off, &pd,
- &a, &ruleset, inp, hdrlen);
+ &a, &ruleset, inp, hdrlen, &match_rules);
break;
}
@@ -9131,7 +9128,7 @@
a = s->anchor.ptr;
} else if (s == NULL)
action = pf_test_rule(&r, &s, kif, m, off, &pd,
- &a, &ruleset, inp, hdrlen);
+ &a, &ruleset, inp, hdrlen, &match_rules);
break;
}
@@ -9144,7 +9141,7 @@
a = s->anchor.ptr;
} else if (s == NULL)
action = pf_test_rule(&r, &s, kif, m, off, &pd,
- &a, &ruleset, inp, hdrlen);
+ &a, &ruleset, inp, hdrlen, &match_rules);
break;
}
@@ -9261,6 +9258,11 @@
ip_divert_ptr(*m0, dir == PF_IN);
*m0 = NULL;
+ while ((ri = SLIST_FIRST(&match_rules))) {
+ SLIST_REMOVE_HEAD(&match_rules, entry);
+ free(ri, M_PF_RULE_ITEM);
+ }
+
return (action);
} else {
/* XXX: ipfw has the same behaviour! */
@@ -9294,13 +9296,15 @@
ruleset, &pd, (s == NULL));
if (s) {
SLIST_FOREACH(ri, &s->match_rules, entry)
- if (ri->r->log & PF_LOG_ALL)
+ if (ri->r->action == PF_MATCH &&
+ ri->r->log & PF_LOG_ALL)
PFLOG_PACKET(kif, m, action,
reason, ri->r, a, ruleset, &pd, 0);
}
}
- pf_counters_inc(action, &pd, kif, s, r, a);
+ pf_counters_inc(action, &pd, kif, s,
+ (s != NULL) ? &(s->match_rules) : &match_rules);
switch (action) {
case PF_SYNPROXY_DROP:
@@ -9349,8 +9353,14 @@
s->if_index_out = ifp->if_index;
}
- if (s)
+ if (s) {
PF_STATE_UNLOCK(s);
+ } else {
+ while ((ri = SLIST_FIRST(&match_rules))) {
+ SLIST_REMOVE_HEAD(&match_rules, entry);
+ free(ri, M_PF_RULE_ITEM);
+ }
+ }
#ifdef INET6
/* If reassembled packet passed, create new fragments. */
diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c
--- a/sys/netpfil/pf/pf_lb.c
+++ b/sys/netpfil/pf/pf_lb.c
@@ -64,9 +64,10 @@
static void pf_hash(struct pf_addr *, struct pf_addr *,
struct pf_poolhashkey *, sa_family_t);
static struct pf_krule *pf_match_translation(struct pf_pdesc *, struct mbuf *,
- int, struct pfi_kkif *,
- struct pf_addr *, u_int16_t, struct pf_addr *,
- uint16_t, int, struct pf_kanchor_stackframe *);
+ int, struct pfi_kkif *, struct pf_addr *, u_int16_t,
+ struct pf_addr *, uint16_t, int,
+ struct pf_kanchor_stackframe *,
+ struct pf_krule_slist *);
static int pf_get_sport(sa_family_t, uint8_t, struct pf_krule *,
struct pf_addr *, uint16_t, struct pf_addr *, uint16_t, struct pf_addr *,
uint16_t *, uint16_t, uint16_t, struct pf_ksrc_node **,
@@ -134,10 +135,12 @@
pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
struct pfi_kkif *kif, struct pf_addr *saddr, u_int16_t sport,
struct pf_addr *daddr, uint16_t dport, int rs_num,
- struct pf_kanchor_stackframe *anchor_stack)
+ struct pf_kanchor_stackframe *anchor_stack,
+ struct pf_krule_slist *match_rules)
{
struct pf_krule *r, *rm = NULL;
struct pf_kruleset *ruleset = NULL;
+ struct pf_krule_item *ri;
int tag = -1;
int rtableid = -1;
int asd = 0;
@@ -192,6 +195,15 @@
off, &pd->hdr.tcp), r->os_fingerprint)))
r = TAILQ_NEXT(r, entries);
else {
+ ri = malloc(sizeof(struct pf_krule_item), M_PF_RULE_ITEM, M_NOWAIT | M_ZERO);
+ /*
+ * XXX KS: There's no error handling for the NAT
+ * ruleset. It needs to be added before we can add
+ * malloc failure check.
+ */
+ ri->r = r;
+ SLIST_INSERT_HEAD(match_rules, ri, entry);
+
if (r->tag)
tag = r->tag;
if (r->rtableid >= 0)
@@ -697,12 +709,11 @@
u_short
pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
- struct pfi_kkif *kif, struct pf_ksrc_node **sn,
- struct pf_state_key **skp, struct pf_state_key **nkp,
- struct pf_addr *saddr, struct pf_addr *daddr,
+ struct pfi_kkif *kif, struct pf_ksrc_node **sn, struct pf_state_key **skp,
+ struct pf_state_key **nkp, struct pf_addr *saddr, struct pf_addr *daddr,
uint16_t sport, uint16_t dport, struct pf_kanchor_stackframe *anchor_stack,
- struct pf_krule **rp,
- struct pf_udp_mapping **udp_mapping)
+ struct pf_krule **rp, struct pf_udp_mapping **udp_mapping,
+ struct pf_krule_slist *match_rules)
{
struct pf_krule *r = NULL;
struct pf_addr *naddr;
@@ -717,19 +728,19 @@
*rp = NULL;
if (pd->dir == PF_OUT) {
- r = pf_match_translation(pd, m, off, kif, saddr,
- sport, daddr, dport, PF_RULESET_BINAT, anchor_stack);
+ r = pf_match_translation(pd, m, off, kif, saddr, sport, daddr,
+ dport, PF_RULESET_BINAT, anchor_stack, match_rules);
if (r == NULL)
- r = pf_match_translation(pd, m, off, kif,
- saddr, sport, daddr, dport, PF_RULESET_NAT,
- anchor_stack);
+ r = pf_match_translation(pd, m, off, kif, saddr, sport,
+ daddr, dport, PF_RULESET_NAT, anchor_stack,
+ match_rules);
} else {
- r = pf_match_translation(pd, m, off, kif, saddr,
- sport, daddr, dport, PF_RULESET_RDR, anchor_stack);
+ r = pf_match_translation(pd, m, off, kif, saddr, sport, daddr,
+ dport, PF_RULESET_RDR, anchor_stack, match_rules);
if (r == NULL)
- r = pf_match_translation(pd, m, off, kif,
- saddr, sport, daddr, dport, PF_RULESET_BINAT,
- anchor_stack);
+ r = pf_match_translation(pd, m, off, kif, saddr, sport,
+ daddr, dport, PF_RULESET_BINAT, anchor_stack,
+ match_rules);
}
if (r == NULL)
diff --git a/tests/sys/netpfil/pf/Makefile b/tests/sys/netpfil/pf/Makefile
--- a/tests/sys/netpfil/pf/Makefile
+++ b/tests/sys/netpfil/pf/Makefile
@@ -6,6 +6,7 @@
ATF_TESTS_SH+= altq \
anchor \
+ counters \
debug \
divert-to \
dup \
diff --git a/tests/sys/netpfil/pf/counters.sh b/tests/sys/netpfil/pf/counters.sh
new file mode 100755
--- /dev/null
+++ b/tests/sys/netpfil/pf/counters.sh
@@ -0,0 +1,99 @@
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2024 Kajetan Staszkiewicz <vegeta@tuxpowered.net>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+. $(atf_get_srcdir)/utils.subr
+
+atf_test_case "source_track" "cleanup"
+
+counters_head()
+{
+ atf_set descr 'Rule and table counters'
+ atf_set require.user root
+}
+
+counters_body()
+{
+ setup_router_server_ipv6
+
+ # Clients will connect from another network behind the router.
+ # This allows for using multiple source addresses and for tester jail
+ # to not respond with RST packets for SYN+ACKs.
+ jexec router route add -6 2001:db8:44::0/64 2001:db8:42::2
+ jexec server route add -6 2001:db8:44::0/64 2001:db8:43::1
+
+ pft_set_rules router \
+ "table <nat_sources> counters { 2001:db8:44::0/64 }" \
+ "table <anchor_sources> counters { 2001:db8:44::0/64 }" \
+ "table <match_sources> counters { 2001:db8:44::0/64 }" \
+ "table <state_sources> counters { 2001:db8:44::0/64 }" \
+ "nat on ${epair_server}a inet6 from <nat_sources> to any -> ${epair_server}a" \
+ "block" \
+ "pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \
+ "anchor anchor1 in on ${epair_tester}b inet6 proto tcp from <anchor_sources> {"\
+ "match from <match_sources>" \
+ "pass from <state_sources> keep state" \
+ "}" \
+ "pass out on ${epair_server}a inet6 proto tcp keep state"
+
+ # Use the 3-way testing so that more than 1 packet is sent.
+ ping_server_check_reply exit:0 --ping-type=tcp3way --send-sport=4201 --fromaddr 2001:db8:44::1
+
+ nat_rules=$(mktemp) || exit 1
+ jexec router pfctl -qvvsn > ${nat_rules}
+ echo === NAT rules ===
+ cat $nat_rules
+
+ pass_rules=$(mktemp) || exit 1
+ jexec router pfctl -qvvsr -a '*' > ${pass_rules}
+ echo === pass_rules ===
+ cat $pass_rules
+
+ states=$(mktemp) || exit 1
+ jexec router pfctl -qvss > ${states}
+ echo === states ===
+ cat $states
+
+ nodes=$(mktemp) || exit 1
+ jexec router pfctl -qvsS > ${nodes}
+ echo === nodes ===
+ cat $nodes
+
+ tables=$(mktemp) || exit 1
+ jexec router pfctl -qvvsT > ${tables}
+ echo === tables ===
+ cat $tables
+}
+
+counters_cleanup()
+{
+ pft_cleanup
+}
+
+
+atf_init_test_cases()
+{
+ atf_add_test_case "counters"
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Oct 3, 1:45 PM (19 h, 25 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
13457156
Default Alt Text
D46864.diff (25 KB)
Attached To
Mode
D46864: WIP: pf: Fix table counters
Attached
Detach File
Event Timeline
Log In to Comment