pf: remove incorrect SUNION2PF() macro
It casts in_addr to pf_addr, which is smaller, so this isn't quite right. Replace it with a function that will only read the actual address. Reported by: CheriBSD Event: Kitchener-Waterloo Hackathon 202406
This commit is contained in:
+32
-24
@@ -79,10 +79,6 @@
|
|||||||
a2 = tmp; \
|
a2 = tmp; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define SUNION2PF(su, af) (((af)==AF_INET) ? \
|
|
||||||
(struct pf_addr *)&(su)->sin.sin_addr : \
|
|
||||||
(struct pf_addr *)&(su)->sin6.sin6_addr)
|
|
||||||
|
|
||||||
#define AF_BITS(af) (((af)==AF_INET)?32:128)
|
#define AF_BITS(af) (((af)==AF_INET)?32:128)
|
||||||
#define ADDR_NETWORK(ad) ((ad)->pfra_net < AF_BITS((ad)->pfra_af))
|
#define ADDR_NETWORK(ad) ((ad)->pfra_net < AF_BITS((ad)->pfra_af))
|
||||||
#define KENTRY_NETWORK(ke) ((ke)->pfrke_net < AF_BITS((ke)->pfrke_af))
|
#define KENTRY_NETWORK(ke) ((ke)->pfrke_net < AF_BITS((ke)->pfrke_af))
|
||||||
@@ -1044,6 +1040,21 @@ pfr_copyout_astats(struct pfr_astats *as, const struct pfr_kentry *ke,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pfr_sockaddr_to_pf_addr(const union sockaddr_union *sa, struct pf_addr *a)
|
||||||
|
{
|
||||||
|
switch (sa->sa.sa_family) {
|
||||||
|
case AF_INET:
|
||||||
|
memcpy(&a->v4, &sa->sin.sin_addr, sizeof(a->v4));
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
memcpy(&a->v6, &sa->sin6.sin6_addr, sizeof(a->v6));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
panic("Unknown AF");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pfr_walktree(struct radix_node *rn, void *arg)
|
pfr_walktree(struct radix_node *rn, void *arg)
|
||||||
{
|
{
|
||||||
@@ -1094,18 +1105,14 @@ pfr_walktree(struct radix_node *rn, void *arg)
|
|||||||
if (w->pfrw_dyn->pfid_acnt4++ > 0)
|
if (w->pfrw_dyn->pfid_acnt4++ > 0)
|
||||||
break;
|
break;
|
||||||
pfr_prepare_network(&pfr_mask, AF_INET, ke->pfrke_net);
|
pfr_prepare_network(&pfr_mask, AF_INET, ke->pfrke_net);
|
||||||
w->pfrw_dyn->pfid_addr4 = *SUNION2PF(&ke->pfrke_sa,
|
pfr_sockaddr_to_pf_addr(&ke->pfrke_sa, &w->pfrw_dyn->pfid_addr4);
|
||||||
AF_INET);
|
pfr_sockaddr_to_pf_addr(&pfr_mask, &w->pfrw_dyn->pfid_mask4);
|
||||||
w->pfrw_dyn->pfid_mask4 = *SUNION2PF(&pfr_mask,
|
|
||||||
AF_INET);
|
|
||||||
} else if (ke->pfrke_af == AF_INET6){
|
} else if (ke->pfrke_af == AF_INET6){
|
||||||
if (w->pfrw_dyn->pfid_acnt6++ > 0)
|
if (w->pfrw_dyn->pfid_acnt6++ > 0)
|
||||||
break;
|
break;
|
||||||
pfr_prepare_network(&pfr_mask, AF_INET6, ke->pfrke_net);
|
pfr_prepare_network(&pfr_mask, AF_INET6, ke->pfrke_net);
|
||||||
w->pfrw_dyn->pfid_addr6 = *SUNION2PF(&ke->pfrke_sa,
|
pfr_sockaddr_to_pf_addr(&ke->pfrke_sa, &w->pfrw_dyn->pfid_addr6);
|
||||||
AF_INET6);
|
pfr_sockaddr_to_pf_addr(&pfr_mask, &w->pfrw_dyn->pfid_mask6);
|
||||||
w->pfrw_dyn->pfid_mask6 = *SUNION2PF(&pfr_mask,
|
|
||||||
AF_INET6);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2235,7 +2242,7 @@ int
|
|||||||
pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter,
|
pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter,
|
||||||
sa_family_t af)
|
sa_family_t af)
|
||||||
{
|
{
|
||||||
struct pf_addr *addr, *cur, *mask;
|
struct pf_addr addr, cur, mask, umask_addr;
|
||||||
union sockaddr_union uaddr, umask;
|
union sockaddr_union uaddr, umask;
|
||||||
struct pfr_kentry *ke, *ke2 = NULL;
|
struct pfr_kentry *ke, *ke2 = NULL;
|
||||||
int idx = -1, use_counter = 0;
|
int idx = -1, use_counter = 0;
|
||||||
@@ -2253,7 +2260,7 @@ pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter,
|
|||||||
uaddr.sin6.sin6_family = AF_INET6;
|
uaddr.sin6.sin6_family = AF_INET6;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
addr = SUNION2PF(&uaddr, af);
|
pfr_sockaddr_to_pf_addr(&uaddr, &addr);
|
||||||
|
|
||||||
if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
|
if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
|
||||||
kt = kt->pfrkt_root;
|
kt = kt->pfrkt_root;
|
||||||
@@ -2273,26 +2280,26 @@ pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter,
|
|||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
pfr_prepare_network(&umask, af, ke->pfrke_net);
|
pfr_prepare_network(&umask, af, ke->pfrke_net);
|
||||||
cur = SUNION2PF(&ke->pfrke_sa, af);
|
pfr_sockaddr_to_pf_addr(&ke->pfrke_sa, &cur);
|
||||||
mask = SUNION2PF(&umask, af);
|
pfr_sockaddr_to_pf_addr(&umask, &mask);
|
||||||
|
|
||||||
if (use_counter) {
|
if (use_counter) {
|
||||||
/* is supplied address within block? */
|
/* is supplied address within block? */
|
||||||
if (!PF_MATCHA(0, cur, mask, counter, af)) {
|
if (!PF_MATCHA(0, &cur, &mask, counter, af)) {
|
||||||
/* no, go to next block in table */
|
/* no, go to next block in table */
|
||||||
idx++;
|
idx++;
|
||||||
use_counter = 0;
|
use_counter = 0;
|
||||||
goto _next_block;
|
goto _next_block;
|
||||||
}
|
}
|
||||||
PF_ACPY(addr, counter, af);
|
PF_ACPY(&addr, counter, af);
|
||||||
} else {
|
} else {
|
||||||
/* use first address of block */
|
/* use first address of block */
|
||||||
PF_ACPY(addr, cur, af);
|
PF_ACPY(&addr, &cur, af);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!KENTRY_NETWORK(ke)) {
|
if (!KENTRY_NETWORK(ke)) {
|
||||||
/* this is a single IP address - no possible nested block */
|
/* this is a single IP address - no possible nested block */
|
||||||
PF_ACPY(counter, addr, af);
|
PF_ACPY(counter, &addr, af);
|
||||||
*pidx = idx;
|
*pidx = idx;
|
||||||
pfr_kstate_counter_add(&kt->pfrkt_match, 1);
|
pfr_kstate_counter_add(&kt->pfrkt_match, 1);
|
||||||
return (0);
|
return (0);
|
||||||
@@ -2312,7 +2319,7 @@ pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter,
|
|||||||
/* no need to check KENTRY_RNF_ROOT() here */
|
/* no need to check KENTRY_RNF_ROOT() here */
|
||||||
if (ke2 == ke) {
|
if (ke2 == ke) {
|
||||||
/* lookup return the same block - perfect */
|
/* lookup return the same block - perfect */
|
||||||
PF_ACPY(counter, addr, af);
|
PF_ACPY(counter, &addr, af);
|
||||||
*pidx = idx;
|
*pidx = idx;
|
||||||
pfr_kstate_counter_add(&kt->pfrkt_match, 1);
|
pfr_kstate_counter_add(&kt->pfrkt_match, 1);
|
||||||
return (0);
|
return (0);
|
||||||
@@ -2320,9 +2327,10 @@ pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter,
|
|||||||
|
|
||||||
/* we need to increase the counter past the nested block */
|
/* we need to increase the counter past the nested block */
|
||||||
pfr_prepare_network(&umask, AF_INET, ke2->pfrke_net);
|
pfr_prepare_network(&umask, AF_INET, ke2->pfrke_net);
|
||||||
PF_POOLMASK(addr, addr, SUNION2PF(&umask, af), &pfr_ffaddr, af);
|
pfr_sockaddr_to_pf_addr(&umask, &umask_addr);
|
||||||
PF_AINC(addr, af);
|
PF_POOLMASK(&addr, &addr, &umask_addr, &pfr_ffaddr, af);
|
||||||
if (!PF_MATCHA(0, cur, mask, addr, af)) {
|
PF_AINC(&addr, af);
|
||||||
|
if (!PF_MATCHA(0, &cur, &mask, &addr, af)) {
|
||||||
/* ok, we reached the end of our main block */
|
/* ok, we reached the end of our main block */
|
||||||
/* go to next block in table */
|
/* go to next block in table */
|
||||||
idx++;
|
idx++;
|
||||||
|
|||||||
Reference in New Issue
Block a user