Skip to content

Commit

Permalink
Fix pfr_kentry_byaddr() to be used for a rule in an anchor. It
Browse files Browse the repository at this point in the history
couldn't find an entry if its table is attached a table on the root.
This fixes the problem "route-to <TABLE> least-states" doesn't work.
The problem is found by IIJ.

OK sashan
  • Loading branch information
yasuoka committed Jun 4, 2020
1 parent 3df5759 commit a7d8bad
Showing 1 changed file with 23 additions and 41 deletions.
64 changes: 23 additions & 41 deletions sys/net/pf_table.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: pf_table.c,v 1.131 2019/07/08 17:49:57 mpi Exp $ */
/* $OpenBSD: pf_table.c,v 1.132 2020/06/04 04:27:51 yasuoka Exp $ */

/*
* Copyright (c) 2002 Cedric Berger
Expand Down Expand Up @@ -2083,13 +2083,30 @@ pfr_lookup_table(struct pfr_table *tbl)

int
pfr_match_addr(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af)
{
struct pfr_kentry *ke = NULL;
int match;

ke = pfr_kentry_byaddr(kt, a, af, 0);

match = (ke && !(ke->pfrke_flags & PFRKE_FLAG_NOT));
if (match)
kt->pfrkt_match++;
else
kt->pfrkt_nomatch++;

return (match);
}

struct pfr_kentry *
pfr_kentry_byaddr(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af,
int exact)
{
struct pfr_kentry *ke = NULL;
struct sockaddr_in tmp4;
#ifdef INET6
struct sockaddr_in6 tmp6;
#endif /* INET6 */
int match;

if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
kt = kt->pfrkt_root;
Expand All @@ -2116,12 +2133,10 @@ pfr_match_addr(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af)
default:
unhandled_af(af);
}
match = (ke && !(ke->pfrke_flags & PFRKE_FLAG_NOT));
if (match)
kt->pfrkt_match++;
else
kt->pfrkt_nomatch++;
return (match);
if (exact && ke && KENTRY_NETWORK(ke))
ke = NULL;

return (ke);
}

void
Expand Down Expand Up @@ -2499,39 +2514,6 @@ pfr_states_decrease(struct pfr_ktable *kt, struct pf_addr *addr, int af)
return ke->pfrke_counters->states;
}

/*
* Added for load balancing to find a kentry outside of the table.
* We need to create a custom pfr_addr struct.
*/
struct pfr_kentry *
pfr_kentry_byaddr(struct pfr_ktable *kt, struct pf_addr *addr, sa_family_t af,
int exact)
{
struct pfr_kentry *ke;
struct pfr_addr p;

bzero(&p, sizeof(p));
p.pfra_af = af;
switch (af) {
case AF_INET:
p.pfra_net = 32;
p.pfra_ip4addr = addr->v4;
break;
#ifdef INET6
case AF_INET6:
p.pfra_net = 128;
p.pfra_ip6addr = addr->v6;
break;
#endif /* INET6 */
default:
unhandled_af(af);
}

ke = pfr_lookup_addr(kt, &p, exact);

return ke;
}

void
pfr_dynaddr_update(struct pfr_ktable *kt, struct pfi_dynaddr *dyn)
{
Expand Down

0 comments on commit a7d8bad

Please sign in to comment.