diff options
Diffstat (limited to 'sys/contrib/pf/net/pf_table.c')
-rw-r--r-- | sys/contrib/pf/net/pf_table.c | 250 |
1 files changed, 175 insertions, 75 deletions
diff --git a/sys/contrib/pf/net/pf_table.c b/sys/contrib/pf/net/pf_table.c index 42d4cee..621809a 100644 --- a/sys/contrib/pf/net/pf_table.c +++ b/sys/contrib/pf/net/pf_table.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_table.c,v 1.47 2004/03/09 21:44:41 mcbride Exp $ */ +/* $OpenBSD: pf_table.c,v 1.62 2004/12/07 18:02:04 mcbride Exp $ */ /* * Copyright (c) 2002 Cedric Berger @@ -125,6 +125,7 @@ struct pfr_walktree { struct pool pfr_ktable_pl; struct pool pfr_kentry_pl; +struct pool pfr_kentry_pl2; struct sockaddr_in pfr_sin; struct sockaddr_in6 pfr_sin6; union sockaddr_union pfr_mask; @@ -138,7 +139,7 @@ void pfr_enqueue_addrs(struct pfr_ktable *, void pfr_mark_addrs(struct pfr_ktable *); struct pfr_kentry *pfr_lookup_addr(struct pfr_ktable *, struct pfr_addr *, int); -struct pfr_kentry *pfr_create_kentry(struct pfr_addr *); +struct pfr_kentry *pfr_create_kentry(struct pfr_addr *, int); void pfr_destroy_kentries(struct pfr_kentryworkq *); void pfr_destroy_kentry(struct pfr_kentry *); void pfr_insert_kentries(struct pfr_ktable *, @@ -155,6 +156,7 @@ int pfr_unroute_kentry(struct pfr_ktable *, struct pfr_kentry *); int pfr_walktree(struct radix_node *, void *); int pfr_validate_table(struct pfr_table *, int, int); +int pfr_fix_anchor(char *); void pfr_commit_ktable(struct pfr_ktable *, long); void pfr_insert_ktables(struct pfr_ktableworkq *); void pfr_insert_ktable(struct pfr_ktable *); @@ -187,9 +189,11 @@ void pfr_initialize(void) { pool_init(&pfr_ktable_pl, sizeof(struct pfr_ktable), 0, 0, 0, - "pfrktable", NULL); + "pfrktable", &pool_allocator_oldnointr); pool_init(&pfr_kentry_pl, sizeof(struct pfr_kentry), 0, 0, 0, - "pfrkentry", NULL); + "pfrkentry", &pool_allocator_oldnointr); + pool_init(&pfr_kentry_pl2, sizeof(struct pfr_kentry), 0, 0, 0, + "pfrkentry2", NULL); pfr_sin.sin_len = sizeof(pfr_sin); pfr_sin.sin_family = AF_INET; @@ -240,7 +244,7 @@ pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, struct pfr_kentry *p, *q; struct pfr_addr ad; int i, rv, s, xadd = 0; - long tzero = time.tv_sec; + long tzero = time_second; ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK); if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL)) @@ -272,7 +276,7 @@ pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, ad.pfra_fback = PFR_FB_NONE; } if (p == NULL && q == NULL) { - p = pfr_create_kentry(&ad); + p = pfr_create_kentry(&ad, 0); if (p == NULL) senderr(ENOMEM); if (pfr_route_kentry(tmpkt, p)) { @@ -317,7 +321,7 @@ pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, struct pfr_kentryworkq workq; struct pfr_kentry *p; struct pfr_addr ad; - int i, rv, s, xdel = 0; + int i, rv, s, xdel = 0, log = 1; ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK); if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL)) @@ -327,7 +331,34 @@ pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, return (ESRCH); if (kt->pfrkt_flags & PFR_TFLAG_CONST) return (EPERM); - pfr_mark_addrs(kt); + /* + * there are two algorithms to choose from here. + * with: + * n: number of addresses to delete + * N: number of addresses in the table + * + * one is O(N) and is better for large 'n' + * one is O(n*LOG(N)) and is better for small 'n' + * + * following code try to decide which one is best. + */ + for (i = kt->pfrkt_cnt; i > 0; i >>= 1) + log++; + if (size > kt->pfrkt_cnt/log) { + /* full table scan */ + pfr_mark_addrs(kt); + } else { + /* iterate over addresses to delete */ + for (i = 0; i < size; i++) { + if (COPYIN(addr+i, &ad, sizeof(ad))) + return (EFAULT); + if (pfr_validate_addr(&ad)) + return (EINVAL); + p = pfr_lookup_addr(kt, &ad, 1); + if (p != NULL) + p->pfrke_mark = 0; + } + } SLIST_INIT(&workq); for (i = 0; i < size; i++) { if (COPYIN(addr+i, &ad, sizeof(ad))) @@ -380,7 +411,7 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, struct pfr_kentry *p, *q; struct pfr_addr ad; int i, rv, s, xadd = 0, xdel = 0, xchange = 0; - long tzero = time.tv_sec; + long tzero = time_second; ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK); if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL)) @@ -421,7 +452,7 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, ad.pfra_fback = PFR_FB_DUPLICATE; goto _skip; } - p = pfr_create_kentry(&ad); + p = pfr_create_kentry(&ad, 0); if (p == NULL) senderr(ENOMEM); if (pfr_route_kentry(tmpkt, p)) { @@ -568,7 +599,7 @@ pfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size, struct pfr_walktree w; struct pfr_kentryworkq workq; int rv, s; - long tzero = time.tv_sec; + long tzero = time_second; ACCEPT_FLAGS(PFR_FLAG_ATOMIC); /* XXX PFR_FLAG_CLSTATS disabled */ if (pfr_validate_table(tbl, 0, 0)) @@ -666,14 +697,18 @@ pfr_validate_addr(struct pfr_addr *ad) int i; switch (ad->pfra_af) { +#ifdef INET case AF_INET: if (ad->pfra_net > 32) return (-1); break; +#endif /* INET */ +#ifdef INET6 case AF_INET6: if (ad->pfra_net > 128) return (-1); break; +#endif /* INET6 */ default: return (-1); } @@ -736,7 +771,7 @@ pfr_lookup_addr(struct pfr_ktable *kt, struct pfr_addr *ad, int exact) if (ad->pfra_af == AF_INET) { FILLIN_SIN(sa.sin, ad->pfra_ip4addr); head = kt->pfrkt_ip4; - } else { + } else if ( ad->pfra_af == AF_INET6 ) { FILLIN_SIN6(sa.sin6, ad->pfra_ip6addr); head = kt->pfrkt_ip6; } @@ -758,22 +793,26 @@ pfr_lookup_addr(struct pfr_ktable *kt, struct pfr_addr *ad, int exact) } struct pfr_kentry * -pfr_create_kentry(struct pfr_addr *ad) +pfr_create_kentry(struct pfr_addr *ad, int intr) { struct pfr_kentry *ke; - ke = pool_get(&pfr_kentry_pl, PR_NOWAIT); + if (intr) + ke = pool_get(&pfr_kentry_pl2, PR_NOWAIT); + else + ke = pool_get(&pfr_kentry_pl, PR_NOWAIT); if (ke == NULL) return (NULL); bzero(ke, sizeof(*ke)); if (ad->pfra_af == AF_INET) FILLIN_SIN(ke->pfrke_sa.sin, ad->pfra_ip4addr); - else + else if (ad->pfra_af == AF_INET6) FILLIN_SIN6(ke->pfrke_sa.sin6, ad->pfra_ip6addr); ke->pfrke_af = ad->pfra_af; ke->pfrke_net = ad->pfra_net; ke->pfrke_not = ad->pfra_not; + ke->pfrke_intrpool = intr; return (ke); } @@ -791,7 +830,10 @@ pfr_destroy_kentries(struct pfr_kentryworkq *workq) void pfr_destroy_kentry(struct pfr_kentry *ke) { - pool_put(&pfr_kentry_pl, ke); + if (ke->pfrke_intrpool) + pool_put(&pfr_kentry_pl2, ke); + else + pool_put(&pfr_kentry_pl, ke); } void @@ -814,6 +856,29 @@ pfr_insert_kentries(struct pfr_ktable *kt, kt->pfrkt_cnt += n; } +int +pfr_insert_kentry(struct pfr_ktable *kt, struct pfr_addr *ad, long tzero) +{ + struct pfr_kentry *p; + int rv; + + p = pfr_lookup_addr(kt, ad, 1); + if (p != NULL) + return (0); + p = pfr_create_kentry(ad, 1); + if (p == NULL) + return (EINVAL); + + rv = pfr_route_kentry(kt, p); + if (rv) + return (rv); + + p->pfrke_tzero = tzero; + kt->pfrkt_cnt++; + + return (0); +} + void pfr_remove_kentries(struct pfr_ktable *kt, struct pfr_kentryworkq *workq) @@ -880,14 +945,14 @@ pfr_prepare_network(union sockaddr_union *sa, int af, int net) if (af == AF_INET) { sa->sin.sin_len = sizeof(sa->sin); sa->sin.sin_family = AF_INET; - sa->sin.sin_addr.s_addr = htonl(-1 << (32-net)); - } else { + sa->sin.sin_addr.s_addr = net ? htonl(-1 << (32-net)) : 0; + } else if (af == AF_INET6) { sa->sin6.sin6_len = sizeof(sa->sin6); sa->sin6.sin6_family = AF_INET6; for (i = 0; i < 4; i++) { if (net <= 32) { sa->sin6.sin6_addr.s6_addr32[i] = - htonl(-1 << (32-net)); + net ? htonl(-1 << (32-net)) : 0; break; } sa->sin6.sin6_addr.s6_addr32[i] = 0xFFFFFFFF; @@ -907,7 +972,7 @@ pfr_route_kentry(struct pfr_ktable *kt, struct pfr_kentry *ke) bzero(ke->pfrke_node, sizeof(ke->pfrke_node)); if (ke->pfrke_af == AF_INET) head = kt->pfrkt_ip4; - else + else if (ke->pfrke_af == AF_INET6) head = kt->pfrkt_ip6; s = splsoftnet(); @@ -931,15 +996,15 @@ pfr_unroute_kentry(struct pfr_ktable *kt, struct pfr_kentry *ke) if (ke->pfrke_af == AF_INET) head = kt->pfrkt_ip4; - else + else if (ke->pfrke_af == AF_INET6) head = kt->pfrkt_ip6; s = splsoftnet(); if (KENTRY_NETWORK(ke)) { pfr_prepare_network(&mask, ke->pfrke_af, ke->pfrke_net); - rn = rn_delete(&ke->pfrke_sa, &mask, head); + rn = rn_delete(&ke->pfrke_sa, &mask, head, NULL); } else - rn = rn_delete(&ke->pfrke_sa, NULL, head); + rn = rn_delete(&ke->pfrke_sa, NULL, head, NULL); splx(s); if (rn == NULL) { @@ -960,7 +1025,7 @@ pfr_copyout_addr(struct pfr_addr *ad, struct pfr_kentry *ke) ad->pfra_not = ke->pfrke_not; if (ad->pfra_af == AF_INET) ad->pfra_ip4addr = ke->pfrke_sa.sin.sin_addr; - else + else if (ad->pfra_af == AF_INET6) ad->pfra_ip6addr = ke->pfrke_sa.sin6.sin6_addr; } @@ -1029,7 +1094,7 @@ pfr_walktree(struct radix_node *rn, void *arg) &ke->pfrke_sa, AF_INET); w->pfrw_dyn->pfid_mask4 = *SUNION2PF( &pfr_mask, AF_INET); - } else { + } else if (ke->pfrke_af == AF_INET6){ if (w->pfrw_dyn->pfid_acnt6++ > 0) break; pfr_prepare_network(&pfr_mask, AF_INET6, ke->pfrke_net); @@ -1051,6 +1116,8 @@ pfr_clr_tables(struct pfr_table *filter, int *ndel, int flags) int s, xdel = 0; ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_ALLRSETS); + if (pfr_fix_anchor(filter->pfrt_anchor)) + return (EINVAL); if (pfr_table_count(filter, flags) < 0) return (ENOENT); @@ -1084,7 +1151,7 @@ pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags) struct pfr_ktableworkq addq, changeq; struct pfr_ktable *p, *q, *r, key; int i, rv, s, xadd = 0; - long tzero = time.tv_sec; + long tzero = time_second; ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY); SLIST_INIT(&addq); @@ -1112,7 +1179,6 @@ pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags) /* find or create root table */ bzero(key.pfrkt_anchor, sizeof(key.pfrkt_anchor)); - bzero(key.pfrkt_ruleset, sizeof(key.pfrkt_ruleset)); r = RB_FIND(pfr_ktablehead, &pfr_ktables, &key); if (r != NULL) { p->pfrkt_root = r; @@ -1207,6 +1273,8 @@ pfr_get_tables(struct pfr_table *filter, struct pfr_table *tbl, int *size, int n, nn; ACCEPT_FLAGS(PFR_FLAG_ALLRSETS); + if (pfr_fix_anchor(filter->pfrt_anchor)) + return (EINVAL); n = nn = pfr_table_count(filter, flags); if (n < 0) return (ENOENT); @@ -1237,10 +1305,12 @@ pfr_get_tstats(struct pfr_table *filter, struct pfr_tstats *tbl, int *size, struct pfr_ktable *p; struct pfr_ktableworkq workq; int s, n, nn; - long tzero = time.tv_sec; + long tzero = time_second; ACCEPT_FLAGS(PFR_FLAG_ATOMIC|PFR_FLAG_ALLRSETS); /* XXX PFR_FLAG_CLSTATS disabled */ + if (pfr_fix_anchor(filter->pfrt_anchor)) + return (EINVAL); n = nn = pfr_table_count(filter, flags); if (n < 0) return (ENOENT); @@ -1285,7 +1355,7 @@ pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags) struct pfr_ktableworkq workq; struct pfr_ktable *p, key; int i, s, xzero = 0; - long tzero = time.tv_sec; + long tzero = time_second; ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_ADDRSTOO); SLIST_INIT(&workq); @@ -1375,7 +1445,7 @@ pfr_ina_begin(struct pfr_table *trs, u_int32_t *ticket, int *ndel, int flags) int xdel = 0; ACCEPT_FLAGS(PFR_FLAG_DUMMY); - rs = pf_find_or_create_ruleset(trs->pfrt_anchor, trs->pfrt_ruleset); + rs = pf_find_or_create_ruleset(trs->pfrt_anchor); if (rs == NULL) return (ENOMEM); SLIST_INIT(&workq); @@ -1417,7 +1487,7 @@ pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size, if (pfr_validate_table(tbl, PFR_TFLAG_USRMASK, flags & PFR_FLAG_USERIOCTL)) return (EINVAL); - rs = pf_find_ruleset(tbl->pfrt_anchor, tbl->pfrt_ruleset); + rs = pf_find_ruleset(tbl->pfrt_anchor); if (rs == NULL || !rs->topen || ticket != rs->tticket) return (EBUSY); tbl->pfrt_flags |= PFR_TFLAG_INACTIVE; @@ -1463,7 +1533,7 @@ _skip: senderr(EINVAL); if (pfr_lookup_addr(shadow, &ad, 1) != NULL) continue; - p = pfr_create_kentry(&ad); + p = pfr_create_kentry(&ad, 0); if (p == NULL) senderr(ENOMEM); if (pfr_route_kentry(shadow, p)) { @@ -1508,7 +1578,7 @@ pfr_ina_rollback(struct pfr_table *trs, u_int32_t ticket, int *ndel, int flags) int xdel = 0; ACCEPT_FLAGS(PFR_FLAG_DUMMY); - rs = pf_find_ruleset(trs->pfrt_anchor, trs->pfrt_ruleset); + rs = pf_find_ruleset(trs->pfrt_anchor); if (rs == NULL || !rs->topen || ticket != rs->tticket) return (0); SLIST_INIT(&workq); @@ -1534,14 +1604,14 @@ int pfr_ina_commit(struct pfr_table *trs, u_int32_t ticket, int *nadd, int *nchange, int flags) { - struct pfr_ktable *p; + struct pfr_ktable *p, *q; struct pfr_ktableworkq workq; struct pf_ruleset *rs; int s, xadd = 0, xchange = 0; - long tzero = time.tv_sec; + long tzero = time_second; ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY); - rs = pf_find_ruleset(trs->pfrt_anchor, trs->pfrt_ruleset); + rs = pf_find_ruleset(trs->pfrt_anchor); if (rs == NULL || !rs->topen || ticket != rs->tticket) return (EBUSY); @@ -1560,8 +1630,10 @@ pfr_ina_commit(struct pfr_table *trs, u_int32_t ticket, int *nadd, if (!(flags & PFR_FLAG_DUMMY)) { if (flags & PFR_FLAG_ATOMIC) s = splsoftnet(); - SLIST_FOREACH(p, &workq, pfrkt_workq) + for (p = SLIST_FIRST(&workq); p != NULL; p = q) { + q = SLIST_NEXT(p, pfrkt_workq); pfr_commit_ktable(p, tzero); + } if (flags & PFR_FLAG_ATOMIC) splx(s); rs->topen = 0; @@ -1648,27 +1720,52 @@ pfr_validate_table(struct pfr_table *tbl, int allowedflags, int no_reserved) for (i = strlen(tbl->pfrt_name); i < PF_TABLE_NAME_SIZE; i++) if (tbl->pfrt_name[i]) return (-1); + if (pfr_fix_anchor(tbl->pfrt_anchor)) + return (-1); if (tbl->pfrt_flags & ~allowedflags) return (-1); return (0); } +/* + * Rewrite anchors referenced by tables to remove slashes + * and check for validity. + */ +int +pfr_fix_anchor(char *anchor) +{ + size_t siz = MAXPATHLEN; + int i; + + if (anchor[0] == '/') { + char *path; + int off; + + path = anchor; + off = 1; + while (*++path == '/') + off++; + bcopy(path, anchor, siz - off); + memset(anchor + siz - off, 0, off); + } + if (anchor[siz - 1]) + return (-1); + for (i = strlen(anchor); i < siz; i++) + if (anchor[i]) + return (-1); + return (0); +} + int pfr_table_count(struct pfr_table *filter, int flags) { struct pf_ruleset *rs; - struct pf_anchor *ac; if (flags & PFR_FLAG_ALLRSETS) return (pfr_ktable_cnt); - if (filter->pfrt_ruleset[0]) { - rs = pf_find_ruleset(filter->pfrt_anchor, - filter->pfrt_ruleset); - return ((rs != NULL) ? rs->tables : -1); - } if (filter->pfrt_anchor[0]) { - ac = pf_find_anchor(filter->pfrt_anchor); - return ((ac != NULL) ? ac->tables : -1); + rs = pf_find_ruleset(filter->pfrt_anchor); + return ((rs != NULL) ? rs->tables : -1); } return (pf_main_ruleset.tables); } @@ -1678,13 +1775,7 @@ pfr_skip_table(struct pfr_table *filter, struct pfr_ktable *kt, int flags) { if (flags & PFR_FLAG_ALLRSETS) return (0); - if (strncmp(filter->pfrt_anchor, kt->pfrkt_anchor, - PF_ANCHOR_NAME_SIZE)) - return (1); - if (!filter->pfrt_ruleset[0]) - return (0); - if (strncmp(filter->pfrt_ruleset, kt->pfrkt_ruleset, - PF_RULESET_NAME_SIZE)) + if (strcmp(filter->pfrt_anchor, kt->pfrkt_anchor)) return (1); return (0); } @@ -1712,10 +1803,12 @@ pfr_insert_ktable(struct pfr_ktable *kt) void pfr_setflags_ktables(struct pfr_ktableworkq *workq) { - struct pfr_ktable *p; + struct pfr_ktable *p, *q; - SLIST_FOREACH(p, workq, pfrkt_workq) + for (p = SLIST_FIRST(workq); p; p = q) { + q = SLIST_NEXT(p, pfrkt_workq); pfr_setflags_ktable(p, p->pfrkt_nflags); + } } void @@ -1790,16 +1883,13 @@ pfr_create_ktable(struct pfr_table *tbl, long tzero, int attachruleset) kt->pfrkt_t = *tbl; if (attachruleset) { - rs = pf_find_or_create_ruleset(tbl->pfrt_anchor, - tbl->pfrt_ruleset); + rs = pf_find_or_create_ruleset(tbl->pfrt_anchor); if (!rs) { pfr_destroy_ktable(kt, 0); return (NULL); } kt->pfrkt_rs = rs; rs->tables++; - if (rs->anchor != NULL) - rs->anchor->tables++; } if (!rn_inithead((void **)&kt->pfrkt_ip4, @@ -1843,8 +1933,6 @@ pfr_destroy_ktable(struct pfr_ktable *kt, int flushaddr) pfr_destroy_ktable(kt->pfrkt_shadow, flushaddr); if (kt->pfrkt_rs != NULL) { kt->pfrkt_rs->tables--; - if (kt->pfrkt_rs->anchor != NULL) - kt->pfrkt_rs->anchor->tables--; pf_remove_if_empty_ruleset(kt->pfrkt_rs); } pool_put(&pfr_ktable_pl, kt); @@ -1857,11 +1945,7 @@ pfr_ktable_compare(struct pfr_ktable *p, struct pfr_ktable *q) if ((d = strncmp(p->pfrkt_name, q->pfrkt_name, PF_TABLE_NAME_SIZE))) return (d); - if ((d = strncmp(p->pfrkt_anchor, q->pfrkt_anchor, - PF_ANCHOR_NAME_SIZE))) - return (d); - return (strncmp(p->pfrkt_ruleset, q->pfrkt_ruleset, - PF_RULESET_NAME_SIZE)); + return (strcmp(p->pfrkt_anchor, q->pfrkt_anchor)); } struct pfr_ktable * @@ -1884,18 +1968,22 @@ pfr_match_addr(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af) return (0); switch (af) { +#ifdef INET case AF_INET: pfr_sin.sin_addr.s_addr = a->addr32[0]; ke = (struct pfr_kentry *)rn_match(&pfr_sin, kt->pfrkt_ip4); if (ke && KENTRY_RNF_ROOT(ke)) ke = NULL; break; +#endif /* INET */ +#ifdef INET6 case AF_INET6: bcopy(a, &pfr_sin6.sin6_addr, sizeof(pfr_sin6.sin6_addr)); ke = (struct pfr_kentry *)rn_match(&pfr_sin6, kt->pfrkt_ip6); if (ke && KENTRY_RNF_ROOT(ke)) ke = NULL; break; +#endif /* INET6 */ } match = (ke && !ke->pfrke_not); if (match) @@ -1917,18 +2005,24 @@ pfr_update_stats(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af, return; switch (af) { +#ifdef INET case AF_INET: pfr_sin.sin_addr.s_addr = a->addr32[0]; ke = (struct pfr_kentry *)rn_match(&pfr_sin, kt->pfrkt_ip4); if (ke && KENTRY_RNF_ROOT(ke)) ke = NULL; break; +#endif /* INET */ +#ifdef INET6 case AF_INET6: bcopy(a, &pfr_sin6.sin6_addr, sizeof(pfr_sin6.sin6_addr)); ke = (struct pfr_kentry *)rn_match(&pfr_sin6, kt->pfrkt_ip6); if (ke && KENTRY_RNF_ROOT(ke)) ke = NULL; break; +#endif /* INET6 */ + default: + ; } if ((ke == NULL || ke->pfrke_not) != notrule) { if (op_pass != PFR_OP_PASS) @@ -1952,18 +2046,15 @@ pfr_attach_table(struct pf_ruleset *rs, char *name) bzero(&tbl, sizeof(tbl)); strlcpy(tbl.pfrt_name, name, sizeof(tbl.pfrt_name)); - if (ac != NULL) { + if (ac != NULL) strlcpy(tbl.pfrt_anchor, ac->name, sizeof(tbl.pfrt_anchor)); - strlcpy(tbl.pfrt_ruleset, rs->name, sizeof(tbl.pfrt_ruleset)); - } kt = pfr_lookup_table(&tbl); if (kt == NULL) { - kt = pfr_create_ktable(&tbl, time.tv_sec, 1); + kt = pfr_create_ktable(&tbl, time_second, 1); if (kt == NULL) return (NULL); if (ac != NULL) { bzero(tbl.pfrt_anchor, sizeof(tbl.pfrt_anchor)); - bzero(tbl.pfrt_ruleset, sizeof(tbl.pfrt_ruleset)); rt = pfr_lookup_table(&tbl); if (rt == NULL) { rt = pfr_create_ktable(&tbl, 0, 1); @@ -2001,8 +2092,10 @@ pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter, union sockaddr_union mask; int idx = -1, use_counter = 0; - addr = (af == AF_INET) ? (struct pf_addr *)&pfr_sin.sin_addr : - (struct pf_addr *)&pfr_sin6.sin6_addr; + if (af == AF_INET) + addr = (struct pf_addr *)&pfr_sin.sin_addr; + else if (af == AF_INET6) + addr = (struct pf_addr *)&pfr_sin6.sin6_addr; if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL) kt = kt->pfrkt_root; if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE)) @@ -2045,9 +2138,12 @@ _next_block: } for (;;) { /* we don't want to use a nested block */ - ke2 = (struct pfr_kentry *)(af == AF_INET ? - rn_match(&pfr_sin, kt->pfrkt_ip4) : - rn_match(&pfr_sin6, kt->pfrkt_ip6)); + if (af == AF_INET) + ke2 = (struct pfr_kentry *)rn_match(&pfr_sin, + kt->pfrkt_ip4); + else if (af == AF_INET6) + ke2 = (struct pfr_kentry *)rn_match(&pfr_sin6, + kt->pfrkt_ip6); /* no need to check KENTRY_RNF_ROOT() here */ if (ke2 == ke) { /* lookup return the same block - perfect */ @@ -2080,12 +2176,16 @@ pfr_kentry_byidx(struct pfr_ktable *kt, int idx, int af) w.pfrw_cnt = idx; switch (af) { +#ifdef INET case AF_INET: rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w); return (w.pfrw_kentry); +#endif /* INET */ +#ifdef INET6 case AF_INET6: rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w); return (w.pfrw_kentry); +#endif /* INET6 */ default: return (NULL); } |