pf: convert state limiter interface to netlink
This is a new feature with new ioctl calls, so we can safely remove them
right now.
Sponsored by: Rubicon Communications, LLC ("Netgate")
This commit is contained in:
+43
-65
@@ -1205,6 +1205,11 @@ struct pf_kstate {
|
||||
* State limiter
|
||||
*/
|
||||
|
||||
struct pf_limiter_rate {
|
||||
unsigned int limit;
|
||||
unsigned int seconds;
|
||||
};
|
||||
|
||||
struct pf_statelim {
|
||||
RB_ENTRY(pf_statelim) pfstlim_id_tree;
|
||||
RB_ENTRY(pf_statelim) pfstlim_nm_tree;
|
||||
@@ -1217,10 +1222,7 @@ struct pf_statelim {
|
||||
/* config */
|
||||
|
||||
unsigned int pfstlim_limit;
|
||||
struct {
|
||||
unsigned int limit;
|
||||
unsigned int seconds;
|
||||
} pfstlim_rate;
|
||||
struct pf_limiter_rate pfstlim_rate;
|
||||
|
||||
/* run state */
|
||||
struct mtx pfstlim_lock;
|
||||
@@ -1340,10 +1342,7 @@ struct pf_sourcelim {
|
||||
unsigned int pfsrlim_ipv4_prefix;
|
||||
unsigned int pfsrlim_ipv6_prefix;
|
||||
|
||||
struct {
|
||||
unsigned int limit;
|
||||
unsigned int seconds;
|
||||
} pfsrlim_rate;
|
||||
struct pf_limiter_rate pfsrlim_rate;
|
||||
|
||||
struct {
|
||||
char name[PF_TABLE_NAME_SIZE];
|
||||
@@ -2074,25 +2073,29 @@ enum pf_syncookies_mode {
|
||||
#define PF_SYNCOOKIES_HIWATPCT 25
|
||||
#define PF_SYNCOOKIES_LOWATPCT (PF_SYNCOOKIES_HIWATPCT / 2)
|
||||
|
||||
#define PF_STATELIM_ID_NONE 0
|
||||
#define PF_STATELIM_ID_MIN 1
|
||||
#define PF_STATELIM_ID_MAX 255 /* fits in pf_state uint8_t */
|
||||
#define PF_STATELIM_LIMIT_MIN 1
|
||||
#define PF_STATELIM_LIMIT_MAX (1 << 24) /* pf is pretty scalable */
|
||||
|
||||
#define PF_SOURCELIM_ID_NONE 0
|
||||
#define PF_SOURCELIM_ID_MIN 1
|
||||
#define PF_SOURCELIM_ID_MAX 255 /* fits in pf_state uint8_t */
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
struct pfioc_statelim {
|
||||
uint32_t ticket;
|
||||
|
||||
char name[PF_STATELIM_NAME_LEN];
|
||||
uint32_t id;
|
||||
#define PF_STATELIM_ID_NONE 0
|
||||
#define PF_STATELIM_ID_MIN 1
|
||||
#define PF_STATELIM_ID_MAX 255 /* fits in pf_state uint8_t */
|
||||
|
||||
/* limit on the total number of states */
|
||||
unsigned int limit;
|
||||
#define PF_STATELIM_LIMIT_MIN 1
|
||||
#define PF_STATELIM_LIMIT_MAX (1 << 24) /* pf is pretty scalable */
|
||||
|
||||
/* rate limit on the creation of states */
|
||||
struct {
|
||||
unsigned int limit;
|
||||
unsigned int seconds;
|
||||
} rate;
|
||||
struct pf_limiter_rate rate;
|
||||
|
||||
char description[PF_STATELIM_DESCR_LEN];
|
||||
|
||||
@@ -2108,9 +2111,6 @@ struct pfioc_sourcelim {
|
||||
|
||||
char name[PF_SOURCELIM_NAME_LEN];
|
||||
uint32_t id;
|
||||
#define PF_SOURCELIM_ID_NONE 0
|
||||
#define PF_SOURCELIM_ID_MIN 1
|
||||
#define PF_SOURCELIM_ID_MAX 255 /* fits in pf_state uint8_t */
|
||||
|
||||
/* limit on the total number of address entries */
|
||||
unsigned int entries;
|
||||
@@ -2119,10 +2119,7 @@ struct pfioc_sourcelim {
|
||||
unsigned int limit;
|
||||
|
||||
/* rate limit on the creation of states by an address entry */
|
||||
struct {
|
||||
unsigned int limit;
|
||||
unsigned int seconds;
|
||||
} rate;
|
||||
struct pf_limiter_rate rate;
|
||||
|
||||
/*
|
||||
* when the number of states on an entry exceeds hwm, add
|
||||
@@ -2154,37 +2151,6 @@ struct pfioc_sourcelim {
|
||||
uint64_t ratelimited; /* counter */
|
||||
};
|
||||
|
||||
struct pfioc_source_entry {
|
||||
sa_family_t af;
|
||||
unsigned int rdomain;
|
||||
struct pf_addr addr;
|
||||
|
||||
/* stats */
|
||||
|
||||
unsigned int inuse; /* gauge */
|
||||
uint64_t admitted; /* counter */
|
||||
uint64_t hardlimited; /* counter */
|
||||
uint64_t ratelimited; /* counter */
|
||||
};
|
||||
|
||||
struct pfioc_source {
|
||||
char name[PF_SOURCELIM_NAME_LEN];
|
||||
uint32_t id;
|
||||
|
||||
/* copied from the parent source limiter */
|
||||
|
||||
unsigned int inet_prefix;
|
||||
unsigned int inet6_prefix;
|
||||
unsigned int limit;
|
||||
|
||||
/* source entries */
|
||||
size_t entry_size; /* sizeof(struct pfioc_source_entry) */
|
||||
|
||||
struct pfioc_source_entry *key;
|
||||
struct pfioc_source_entry *entries;
|
||||
size_t entrieslen; /* bytes */
|
||||
};
|
||||
|
||||
struct pfioc_source_kill {
|
||||
char name[PF_SOURCELIM_NAME_LEN];
|
||||
uint32_t id;
|
||||
@@ -2195,7 +2161,28 @@ struct pfioc_source_kill {
|
||||
unsigned int rmstates; /* kill the states too? */
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
int pf_statelim_add(const struct pfioc_statelim *);
|
||||
struct pf_statelim *pf_statelim_rb_find(struct pf_statelim_id_tree *,
|
||||
struct pf_statelim *);
|
||||
struct pf_statelim *pf_statelim_rb_nfind(struct pf_statelim_id_tree *,
|
||||
struct pf_statelim *);
|
||||
int pf_statelim_get(struct pfioc_statelim *,
|
||||
struct pf_statelim *(*rbt_op)(struct pf_statelim_id_tree *,
|
||||
struct pf_statelim *));
|
||||
int pf_sourcelim_add(const struct pfioc_sourcelim *);
|
||||
struct pf_sourcelim *pf_sourcelim_rb_find(struct pf_sourcelim_id_tree *,
|
||||
struct pf_sourcelim *);
|
||||
struct pf_sourcelim *pf_sourcelim_rb_nfind(struct pf_sourcelim_id_tree *,
|
||||
struct pf_sourcelim *);
|
||||
int pf_sourcelim_get(struct pfioc_sourcelim *,
|
||||
struct pf_sourcelim *(*rbt_op)(struct pf_sourcelim_id_tree *,
|
||||
struct pf_sourcelim *));
|
||||
struct pf_source *pf_source_rb_find(struct pf_source_ioc_tree *,
|
||||
struct pf_source *);
|
||||
struct pf_source *pf_source_rb_nfind(struct pf_source_ioc_tree *,
|
||||
struct pf_source *);
|
||||
int pf_source_clr(struct pfioc_source_kill *);
|
||||
|
||||
struct pf_kstatus {
|
||||
counter_u64_t counters[PFRES_MAX]; /* reason for passing/dropping */
|
||||
counter_u64_t lcounters[KLCNT_MAX]; /* limit counters */
|
||||
@@ -2569,15 +2556,6 @@ struct pfioc_iface {
|
||||
#define DIOCGETETHRULESETS _IOWR('D', 100, struct pfioc_nv)
|
||||
#define DIOCGETETHRULESET _IOWR('D', 101, struct pfioc_nv)
|
||||
#define DIOCSETREASS _IOWR('D', 102, u_int32_t)
|
||||
#define DIOCADDSTATELIM _IOW('D', 103, struct pfioc_statelim)
|
||||
#define DIOCADDSOURCELIM _IOW('D', 104, struct pfioc_sourcelim)
|
||||
#define DIOCGETSTATELIM _IOWR('D', 105, struct pfioc_statelim)
|
||||
#define DIOCGETSOURCELIM _IOWR('D', 106, struct pfioc_sourcelim)
|
||||
#define DIOCGETSOURCE _IOWR('D', 107, struct pfioc_source)
|
||||
#define DIOCGETNSTATELIM _IOWR('D', 108, struct pfioc_statelim)
|
||||
#define DIOCGETNSOURCELIM _IOWR('D', 109, struct pfioc_sourcelim)
|
||||
#define DIOCGETNSOURCE _IOWR('D', 110, struct pfioc_source)
|
||||
#define DIOCCLRSOURCE _IOWR('D', 111, struct pfioc_source_kill)
|
||||
|
||||
struct pf_ifspeed_v0 {
|
||||
char ifname[IFNAMSIZ];
|
||||
|
||||
+11
-152
@@ -1613,7 +1613,7 @@ pf_addr_copyout(struct pf_addr_wrap *addr)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
pf_statelim_add(const struct pfioc_statelim *ioc)
|
||||
{
|
||||
struct pf_statelim *pfstlim;
|
||||
@@ -1976,7 +1976,7 @@ pf_statelim_rollback(void)
|
||||
RB_INIT(&V_pf_statelim_nm_tree_inactive);
|
||||
}
|
||||
|
||||
static struct pf_statelim *
|
||||
struct pf_statelim *
|
||||
pf_statelim_rb_find(struct pf_statelim_id_tree *tree, struct pf_statelim *key)
|
||||
{
|
||||
PF_RULES_ASSERT();
|
||||
@@ -1984,7 +1984,7 @@ pf_statelim_rb_find(struct pf_statelim_id_tree *tree, struct pf_statelim *key)
|
||||
return (RB_FIND(pf_statelim_id_tree, tree, key));
|
||||
}
|
||||
|
||||
static struct pf_statelim *
|
||||
struct pf_statelim *
|
||||
pf_statelim_rb_nfind(struct pf_statelim_id_tree *tree, struct pf_statelim *key)
|
||||
{
|
||||
PF_RULES_ASSERT();
|
||||
@@ -1992,7 +1992,7 @@ pf_statelim_rb_nfind(struct pf_statelim_id_tree *tree, struct pf_statelim *key)
|
||||
return (RB_NFIND(pf_statelim_id_tree, tree, key));
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
pf_statelim_get(struct pfioc_statelim *ioc,
|
||||
struct pf_statelim *(*rbt_op)(struct pf_statelim_id_tree *,
|
||||
struct pf_statelim *))
|
||||
@@ -2028,7 +2028,7 @@ pf_statelim_get(struct pfioc_statelim *ioc,
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
pf_sourcelim_add(const struct pfioc_sourcelim *ioc)
|
||||
{
|
||||
struct pf_sourcelim *pfsrlim;
|
||||
@@ -2187,7 +2187,7 @@ pf_sourcelim_rollback(void)
|
||||
RB_INIT(&V_pf_sourcelim_nm_tree_inactive);
|
||||
}
|
||||
|
||||
static struct pf_sourcelim *
|
||||
struct pf_sourcelim *
|
||||
pf_sourcelim_rb_find(struct pf_sourcelim_id_tree *tree,
|
||||
struct pf_sourcelim *key)
|
||||
{
|
||||
@@ -2195,7 +2195,7 @@ pf_sourcelim_rb_find(struct pf_sourcelim_id_tree *tree,
|
||||
return (RB_FIND(pf_sourcelim_id_tree, tree, key));
|
||||
}
|
||||
|
||||
static struct pf_sourcelim *
|
||||
struct pf_sourcelim *
|
||||
pf_sourcelim_rb_nfind(struct pf_sourcelim_id_tree *tree,
|
||||
struct pf_sourcelim *key)
|
||||
{
|
||||
@@ -2203,7 +2203,7 @@ pf_sourcelim_rb_nfind(struct pf_sourcelim_id_tree *tree,
|
||||
return (RB_NFIND(pf_sourcelim_id_tree, tree, key));
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
pf_sourcelim_get(struct pfioc_sourcelim *ioc,
|
||||
struct pf_sourcelim *(*rbt_op)(struct pf_sourcelim_id_tree *,
|
||||
struct pf_sourcelim *))
|
||||
@@ -2262,7 +2262,7 @@ pf_sourcelim_get(struct pfioc_sourcelim *ioc,
|
||||
return (error);
|
||||
}
|
||||
|
||||
static struct pf_source *
|
||||
struct pf_source *
|
||||
pf_source_rb_find(struct pf_source_ioc_tree *tree,
|
||||
struct pf_source *key)
|
||||
{
|
||||
@@ -2271,7 +2271,7 @@ pf_source_rb_find(struct pf_source_ioc_tree *tree,
|
||||
return (RB_FIND(pf_source_ioc_tree, tree, key));
|
||||
}
|
||||
|
||||
static struct pf_source *
|
||||
struct pf_source *
|
||||
pf_source_rb_nfind(struct pf_source_ioc_tree *tree,
|
||||
struct pf_source *key)
|
||||
{
|
||||
@@ -2280,100 +2280,7 @@ pf_source_rb_nfind(struct pf_source_ioc_tree *tree,
|
||||
return (RB_NFIND(pf_source_ioc_tree, tree, key));
|
||||
}
|
||||
|
||||
static int
|
||||
pf_source_get(struct pfioc_source *ioc,
|
||||
struct pf_source *(*rbt_op)(struct pf_source_ioc_tree *,
|
||||
struct pf_source *))
|
||||
{
|
||||
struct pf_sourcelim plkey = { .pfsrlim_id = ioc->id };
|
||||
struct pfioc_source_entry e, *uentry;
|
||||
struct pf_source key;
|
||||
struct pf_sourcelim *pfsrlim;
|
||||
struct pf_source *pfsr;
|
||||
size_t used = 0, len = ioc->entrieslen;
|
||||
int error = 0;
|
||||
PF_RULES_RLOCK_TRACKER;
|
||||
|
||||
if (ioc->entry_size != sizeof(e))
|
||||
return (EINVAL);
|
||||
if (len < sizeof(e))
|
||||
return (EMSGSIZE);
|
||||
|
||||
error = copyin(ioc->key, &e, sizeof(e));
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
PF_RULES_RLOCK();
|
||||
|
||||
#if 0
|
||||
if (ioc->ticket != pf_main_ruleset.rules.active.ticket) {
|
||||
error = EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
#endif
|
||||
|
||||
pfsrlim = pf_sourcelim_rb_find(&V_pf_sourcelim_id_tree_active, &plkey);
|
||||
if (pfsrlim == NULL) {
|
||||
error = ESRCH;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
key.pfsr_af = e.af;
|
||||
key.pfsr_rdomain = e.rdomain;
|
||||
key.pfsr_addr = e.addr;
|
||||
pfsr = (*rbt_op)(&pfsrlim->pfsrlim_ioc_sources, &key);
|
||||
if (pfsr == NULL) {
|
||||
error = ENOENT;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
memset(&e, 0, sizeof(e));
|
||||
|
||||
uentry = ioc->entries;
|
||||
for (;;) {
|
||||
e.af = pfsr->pfsr_af;
|
||||
e.rdomain = pfsr->pfsr_rdomain;
|
||||
e.addr = pfsr->pfsr_addr;
|
||||
|
||||
e.inuse = pfsr->pfsr_inuse;
|
||||
e.admitted = pfsr->pfsr_counters.admitted;
|
||||
e.hardlimited = pfsr->pfsr_counters.hardlimited;
|
||||
e.ratelimited = pfsr->pfsr_counters.ratelimited;
|
||||
|
||||
error = copyout(&e, uentry, sizeof(e));
|
||||
if (error != 0)
|
||||
goto unlock;
|
||||
|
||||
used += sizeof(e);
|
||||
if (used == len)
|
||||
break;
|
||||
|
||||
pfsr = RB_NEXT(pf_source_ioc_tree, srlim->pfsrlim_ioc_sources, pfsr);
|
||||
if (pfsr == NULL)
|
||||
break;
|
||||
|
||||
if ((len - used) < sizeof(e)) {
|
||||
error = EMSGSIZE;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
uentry++;
|
||||
}
|
||||
MPASS(error == 0);
|
||||
|
||||
ioc->inet_prefix = pfsrlim->pfsrlim_ipv4_prefix;
|
||||
ioc->inet6_prefix = pfsrlim->pfsrlim_ipv6_prefix;
|
||||
ioc->limit = pfsrlim->pfsrlim_limit;
|
||||
|
||||
ioc->entrieslen = used;
|
||||
|
||||
unlock:
|
||||
PF_RULES_RUNLOCK();
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
pf_source_clr(struct pfioc_source_kill *ioc)
|
||||
{
|
||||
extern struct pf_source_list pf_source_gc;
|
||||
@@ -3876,12 +3783,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
case DIOCGETTIMEOUT:
|
||||
case DIOCCLRRULECTRS:
|
||||
case DIOCGETLIMIT:
|
||||
case DIOCGETSTATELIM:
|
||||
case DIOCGETNSTATELIM:
|
||||
case DIOCGETSOURCELIM:
|
||||
case DIOCGETNSOURCELIM:
|
||||
case DIOCGETSOURCE:
|
||||
case DIOCGETNSOURCE:
|
||||
case DIOCGETALTQSV0:
|
||||
case DIOCGETALTQSV1:
|
||||
case DIOCGETALTQV0:
|
||||
@@ -3941,12 +3842,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
#endif
|
||||
case DIOCGETTIMEOUT:
|
||||
case DIOCGETLIMIT:
|
||||
case DIOCGETSTATELIM:
|
||||
case DIOCGETNSTATELIM:
|
||||
case DIOCGETSOURCELIM:
|
||||
case DIOCGETNSOURCELIM:
|
||||
case DIOCGETSOURCE:
|
||||
case DIOCGETNSOURCE:
|
||||
case DIOCGETALTQSV0:
|
||||
case DIOCGETALTQSV1:
|
||||
case DIOCGETALTQV0:
|
||||
@@ -5235,42 +5130,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
break;
|
||||
}
|
||||
|
||||
case DIOCADDSTATELIM:
|
||||
error = pf_statelim_add((struct pfioc_statelim *)addr);
|
||||
break;
|
||||
case DIOCGETSTATELIM:
|
||||
error = pf_statelim_get((struct pfioc_statelim *)addr,
|
||||
pf_statelim_rb_find);
|
||||
break;
|
||||
case DIOCGETNSTATELIM:
|
||||
error = pf_statelim_get((struct pfioc_statelim *)addr,
|
||||
pf_statelim_rb_nfind);
|
||||
break;
|
||||
|
||||
case DIOCADDSOURCELIM:
|
||||
error = pf_sourcelim_add((struct pfioc_sourcelim *)addr);
|
||||
break;
|
||||
case DIOCGETSOURCELIM:
|
||||
error = pf_sourcelim_get((struct pfioc_sourcelim *)addr,
|
||||
pf_sourcelim_rb_find);
|
||||
break;
|
||||
case DIOCGETNSOURCELIM:
|
||||
error = pf_sourcelim_get((struct pfioc_sourcelim *)addr,
|
||||
pf_sourcelim_rb_nfind);
|
||||
break;
|
||||
|
||||
case DIOCGETSOURCE:
|
||||
error = pf_source_get((struct pfioc_source *)addr,
|
||||
pf_source_rb_find);
|
||||
break;
|
||||
case DIOCGETNSOURCE:
|
||||
error = pf_source_get((struct pfioc_source *)addr,
|
||||
pf_source_rb_nfind);
|
||||
break;
|
||||
case DIOCCLRSOURCE:
|
||||
error = pf_source_clr((struct pfioc_source_kill *)addr);
|
||||
break;
|
||||
|
||||
case DIOCCLRRULECTRS: {
|
||||
/* obsoleted by DIOCGETRULE with action=PF_GET_CLR_CNTR */
|
||||
struct pf_kruleset *ruleset = &pf_main_ruleset;
|
||||
|
||||
@@ -2463,6 +2463,346 @@ pf_handle_table_clear_astats(struct nlmsghdr *hdr, struct nl_pstate *npt)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static const struct nlattr_parser nla_p_rate[] = {
|
||||
{ .type = PF_LR_LIMIT, .off = 0, .cb = nlattr_get_uint32 },
|
||||
{ .type = PF_LR_SECONDS, .off = sizeof(unsigned int), .cb = nlattr_get_uint32 },
|
||||
};
|
||||
NL_DECLARE_ATTR_PARSER(rate_parser, nla_p_rate);
|
||||
|
||||
#define _OUT(_field) offsetof(struct pfioc_statelim, _field)
|
||||
static const struct nlattr_parser nla_p_state_limiter[] = {
|
||||
{ .type = PF_SL_TICKET, .off = _OUT(ticket), .cb = nlattr_get_uint32 },
|
||||
{ .type = PF_SL_NAME, .off = _OUT(name), .arg = (void *)PF_STATELIM_NAME_LEN, .cb = nlattr_get_chara },
|
||||
{ .type = PF_SL_ID, .off = _OUT(id), .cb = nlattr_get_uint32 },
|
||||
{ .type = PF_SL_LIMIT, .off = _OUT(limit), .cb = nlattr_get_uint32 },
|
||||
{ .type = PF_SL_RATE, .off = _OUT(rate), .arg = &rate_parser, .cb = nlattr_get_nested },
|
||||
{ .type = PF_SL_DESCR, .off = _OUT(description), .arg = (void *)PF_STATELIM_DESCR_LEN, .cb = nlattr_get_chara },
|
||||
};
|
||||
NL_DECLARE_PARSER(state_limiter_parser, struct genlmsghdr, nlf_p_empty, nla_p_state_limiter);
|
||||
#undef _OUT
|
||||
|
||||
static int
|
||||
pf_handle_state_limiter_add(struct nlmsghdr *hdr, struct nl_pstate *npt)
|
||||
{
|
||||
struct pfioc_statelim attrs = { 0 };
|
||||
struct nl_writer *nw = npt->nw;
|
||||
struct genlmsghdr *ghdr_new;
|
||||
int error;
|
||||
|
||||
error = nl_parse_nlmsg(hdr, &state_limiter_parser, npt, &attrs);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
error = pf_statelim_add(&attrs);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr)))
|
||||
return (ENOMEM);
|
||||
|
||||
ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr);
|
||||
ghdr_new->cmd = PFNL_CMD_STATE_LIMITER_ADD;
|
||||
|
||||
nlattr_add_u32(nw, PF_SL_ID, attrs.id);
|
||||
|
||||
if (!nlmsg_end(nw))
|
||||
return (ENOMEM);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static bool
|
||||
nlattr_add_limiter_rate(struct nl_writer *nw, int attrtype,
|
||||
const struct pf_limiter_rate *rate)
|
||||
{
|
||||
int off = nlattr_add_nested(nw, attrtype);
|
||||
if (off == 0)
|
||||
return (false);
|
||||
|
||||
nlattr_add_u32(nw, PF_LR_LIMIT, rate->limit);
|
||||
nlattr_add_u32(nw, PF_LR_SECONDS, rate->seconds);
|
||||
|
||||
nlattr_set_len(nw, off);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
static int
|
||||
pf_handle_state_limiter_get(struct nlmsghdr *hdr, struct nl_pstate *npt)
|
||||
{
|
||||
struct pfioc_statelim attrs = { 0 };
|
||||
struct nl_writer *nw = npt->nw;
|
||||
struct genlmsghdr *ghdr = (struct genlmsghdr *)(hdr + 1);
|
||||
struct genlmsghdr *ghdr_new;
|
||||
int error;
|
||||
|
||||
error = nl_parse_nlmsg(hdr, &state_limiter_parser, npt, &attrs);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
error = pf_statelim_get(&attrs,
|
||||
ghdr->cmd == PFNL_CMD_STATE_LIMITER_GET ? pf_statelim_rb_find :
|
||||
pf_statelim_rb_nfind);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr)))
|
||||
return (ENOMEM);
|
||||
|
||||
ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr);
|
||||
ghdr_new->cmd = PFNL_CMD_STATE_LIMITER_GET;
|
||||
|
||||
nlattr_add_string(nw, PF_SL_NAME, attrs.name);
|
||||
nlattr_add_u32(nw, PF_SL_ID, attrs.id);
|
||||
nlattr_add_u32(nw, PF_SL_LIMIT, attrs.limit);
|
||||
nlattr_add_limiter_rate(nw, PF_SL_RATE, &attrs.rate);
|
||||
nlattr_add_string(nw, PF_SL_DESCR, attrs.description);
|
||||
nlattr_add_u32(nw, PF_SL_INUSE, attrs.inuse);
|
||||
nlattr_add_u64(nw, PF_SL_ADMITTED, attrs.admitted);
|
||||
nlattr_add_u64(nw, PF_SL_HARDLIMITED, attrs.hardlimited);
|
||||
nlattr_add_u64(nw, PF_SL_RATELIMITED, attrs.ratelimited);
|
||||
|
||||
if (!nlmsg_end(nw))
|
||||
return (ENOMEM);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
#define _OUT(_field) offsetof(struct pfioc_sourcelim, _field)
|
||||
static const struct nlattr_parser nla_p_source_limiter[] = {
|
||||
{ .type = PF_SCL_TICKET, .off = _OUT(ticket), .cb = nlattr_get_uint32 },
|
||||
{ .type = PF_SCL_NAME, .off = _OUT(name), .arg = (void *)PF_STATELIM_NAME_LEN, .cb = nlattr_get_chara },
|
||||
{ .type = PF_SCL_ID, .off = _OUT(id), .cb = nlattr_get_uint32 },
|
||||
{ .type = PF_SCL_ENTRIES, .off = _OUT(entries), .cb = nlattr_get_uint32 },
|
||||
{ .type = PF_SCL_LIMIT, .off = _OUT(limit), .cb = nlattr_get_uint32 },
|
||||
{ .type = PF_SCL_RATE, .off = _OUT(rate), .arg = &rate_parser, .cb = nlattr_get_nested },
|
||||
{ .type = PF_SCL_OVERLOAD_TBL_NAME, .off = _OUT(overload_tblname), .arg = (void *)PF_TABLE_NAME_SIZE, .cb = nlattr_get_chara },
|
||||
{ .type = PF_SCL_OVERLOAD_HIGH_WM, .off = _OUT(overload_hwm), .cb = nlattr_get_uint32 },
|
||||
{ .type = PF_SCL_OVERLOAD_LOW_WM, .off = _OUT(overload_lwm), .cb = nlattr_get_uint32 },
|
||||
{ .type = PF_SCL_INET_PREFIX, .off = _OUT(inet_prefix), .cb = nlattr_get_uint32 },
|
||||
{ .type = PF_SCL_INET6_PREFIX, .off = _OUT(inet6_prefix), .cb = nlattr_get_uint32 },
|
||||
{ .type = PF_SCL_DESCR, .off = _OUT(description), .arg = (void *)PF_STATELIM_DESCR_LEN, .cb = nlattr_get_chara },
|
||||
};
|
||||
#undef _OUT
|
||||
NL_DECLARE_PARSER(source_limiter_parser, struct genlmsghdr, nlf_p_empty, nla_p_source_limiter);
|
||||
|
||||
static int
|
||||
pf_handle_source_limiter_add(struct nlmsghdr *hdr, struct nl_pstate *npt)
|
||||
{
|
||||
struct pfioc_sourcelim attrs = { 0 };
|
||||
struct nl_writer *nw = npt->nw;
|
||||
struct genlmsghdr *ghdr_new;
|
||||
int error;
|
||||
|
||||
error = nl_parse_nlmsg(hdr, &source_limiter_parser, npt, &attrs);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
error = pf_sourcelim_add(&attrs);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr)))
|
||||
return (ENOMEM);
|
||||
|
||||
ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr);
|
||||
ghdr_new->cmd = PFNL_CMD_SOURCE_LIMITER_ADD;
|
||||
|
||||
nlattr_add_u32(nw, PF_SCL_ID, attrs.id);
|
||||
|
||||
if (!nlmsg_end(nw))
|
||||
return (ENOMEM);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
pf_handle_source_limiter_get(struct nlmsghdr *hdr, struct nl_pstate *npt)
|
||||
{
|
||||
struct pfioc_sourcelim attrs = { 0 };
|
||||
struct nl_writer *nw = npt->nw;
|
||||
struct genlmsghdr *ghdr = (struct genlmsghdr *)(hdr + 1);
|
||||
struct genlmsghdr *ghdr_new;
|
||||
int error;
|
||||
|
||||
error = nl_parse_nlmsg(hdr, &source_limiter_parser, npt, &attrs);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
error = pf_sourcelim_get(&attrs,
|
||||
ghdr->cmd == PFNL_CMD_SOURCE_LIMITER_GET ? pf_sourcelim_rb_find :
|
||||
pf_sourcelim_rb_nfind);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr)))
|
||||
return (ENOMEM);
|
||||
|
||||
ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr);
|
||||
ghdr_new->cmd = ghdr->cmd;
|
||||
|
||||
nlattr_add_string(nw, PF_SCL_NAME, attrs.name);
|
||||
nlattr_add_u32(nw, PF_SCL_ID, attrs.id);
|
||||
nlattr_add_u32(nw, PF_SCL_ENTRIES, attrs.entries);
|
||||
nlattr_add_u32(nw, PF_SCL_LIMIT, attrs.limit);
|
||||
nlattr_add_limiter_rate(nw, PF_SCL_RATE, &attrs.rate);
|
||||
nlattr_add_string(nw, PF_SCL_OVERLOAD_TBL_NAME, attrs.overload_tblname);
|
||||
nlattr_add_u32(nw, PF_SCL_OVERLOAD_HIGH_WM, attrs.overload_hwm);
|
||||
nlattr_add_u32(nw, PF_SCL_OVERLOAD_LOW_WM, attrs.overload_lwm);
|
||||
nlattr_add_u32(nw, PF_SCL_INET_PREFIX, attrs.inet_prefix);
|
||||
nlattr_add_u32(nw, PF_SCL_INET6_PREFIX, attrs.inet6_prefix);
|
||||
nlattr_add_string(nw, PF_SCL_DESCR, attrs.description);
|
||||
nlattr_add_u32(nw, PF_SCL_NENTRIES, attrs.nentries);
|
||||
nlattr_add_u32(nw, PF_SCL_INUSE, attrs.inuse);
|
||||
nlattr_add_u64(nw, PF_SCL_ADDR_ALLOCS, attrs.addrallocs);
|
||||
nlattr_add_u64(nw, PF_SCL_ADDR_NOMEM, attrs.addrnomem);
|
||||
nlattr_add_u64(nw, PF_SCL_ADMITTED, attrs.admitted);
|
||||
nlattr_add_u64(nw, PF_SCL_ADDRLIMITED, attrs.addrlimited);
|
||||
nlattr_add_u64(nw, PF_SCL_HARDLIMITED, attrs.hardlimited);
|
||||
nlattr_add_u64(nw, PF_SCL_RATELIMITED, attrs.ratelimited);
|
||||
|
||||
if (!nlmsg_end(nw))
|
||||
return (ENOMEM);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
struct nlattr_source {
|
||||
char name[PF_SOURCELIM_NAME_LEN];
|
||||
uint32_t id;
|
||||
sa_family_t af;
|
||||
unsigned int rdomain;
|
||||
struct pf_addr addr;
|
||||
};
|
||||
#define _OUT(_field) offsetof(struct nlattr_source, _field)
|
||||
static const struct nlattr_parser nla_p_source[] = {
|
||||
{ .type = PF_SRC_NAME, .off = _OUT(name), .arg = (void *)PF_SOURCELIM_NAME_LEN, .cb = nlattr_get_chara },
|
||||
{ .type = PF_SRC_ID, .off = _OUT(id), .cb = nlattr_get_uint32 },
|
||||
{ .type = PF_SRC_AF, .off = _OUT(af), .cb = nlattr_get_uint8 },
|
||||
{ .type = PF_SRC_RDOMAIN, .off = _OUT(rdomain), .cb = nlattr_get_uint32 },
|
||||
{ .type = PF_SRC_ADDR, .off = _OUT(addr), .cb = nlattr_get_in6_addr },
|
||||
};
|
||||
#undef _OUT
|
||||
NL_DECLARE_PARSER(source_parser, struct genlmsghdr, nlf_p_empty, nla_p_source);
|
||||
|
||||
static int
|
||||
pf_handle_source_get(struct nlmsghdr *hdr, struct nl_pstate *npt)
|
||||
{
|
||||
struct nlattr_source attrs = { 0 };
|
||||
struct pf_source key;
|
||||
struct pf_sourcelim plkey;
|
||||
struct nl_writer *nw = npt->nw;
|
||||
struct genlmsghdr *ghdr = (struct genlmsghdr *)(hdr + 1);
|
||||
struct genlmsghdr *ghdr_new;
|
||||
struct pf_sourcelim *pfsrlim;
|
||||
struct pf_source *pfsr;
|
||||
int error;
|
||||
PF_RULES_RLOCK_TRACKER;
|
||||
|
||||
error = nl_parse_nlmsg(hdr, &source_parser, npt, &attrs);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
PF_RULES_RLOCK();
|
||||
plkey.pfsrlim_id = attrs.id;
|
||||
pfsrlim = pf_sourcelim_rb_find(&V_pf_sourcelim_id_tree_active, &plkey);
|
||||
if (pfsrlim == NULL) {
|
||||
error = ESRCH;
|
||||
goto out;
|
||||
}
|
||||
|
||||
key.pfsr_af = attrs.af;
|
||||
key.pfsr_rdomain = attrs.rdomain;
|
||||
key.pfsr_addr = attrs.addr;
|
||||
|
||||
pfsr = (ghdr->cmd == PFNL_CMD_SOURCE_GET ? pf_source_rb_find :
|
||||
pf_source_rb_nfind)(&pfsrlim->pfsrlim_ioc_sources, &key);
|
||||
if (pfsr == NULL) {
|
||||
error = ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr))) {
|
||||
error = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr);
|
||||
ghdr_new->cmd = ghdr->cmd;
|
||||
|
||||
nlattr_add_u8(nw, PF_SRC_AF, pfsr->pfsr_af);
|
||||
nlattr_add_u32(nw, PF_SRC_RDOMAIN, pfsr->pfsr_rdomain);
|
||||
nlattr_add_in6_addr(nw, PF_SRC_ADDR, &pfsr->pfsr_addr.v6);
|
||||
|
||||
nlattr_add_u32(nw, PF_SRC_INUSE, pfsr->pfsr_inuse);
|
||||
nlattr_add_u64(nw, PF_SRC_ADMITTED, pfsr->pfsr_counters.admitted);
|
||||
nlattr_add_u64(nw, PF_SRC_HARDLIMITED, pfsr->pfsr_counters.hardlimited);
|
||||
nlattr_add_u64(nw, PF_SRC_RATELIMITED, pfsr->pfsr_counters.ratelimited);
|
||||
|
||||
nlattr_add_u32(nw, PF_SRC_LIMIT, pfsrlim->pfsrlim_limit);
|
||||
nlattr_add_u32(nw, PF_SRC_INET_PREFIX, pfsrlim->pfsrlim_ipv4_prefix);
|
||||
nlattr_add_u32(nw, PF_SRC_INET6_PREFIX, pfsrlim->pfsrlim_ipv6_prefix);
|
||||
|
||||
if (!nlmsg_end(nw)) {
|
||||
nlmsg_abort(nw);
|
||||
error = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pfsr = RB_NEXT(pf_source_ioc_tree, srlim->pfsrlim_ioc_sources, pfsr);
|
||||
if (pfsr == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
PF_RULES_RUNLOCK();
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
||||
#define _OUT(_field) offsetof(struct pfioc_source_kill, _field)
|
||||
static const struct nlattr_parser nla_p_source_clear[] = {
|
||||
{ .type = PF_SC_NAME, .off = _OUT(name), .arg = (void *)PF_SOURCELIM_NAME_LEN, .cb = nlattr_get_chara },
|
||||
{ .type = PF_SC_ID, .off = _OUT(id), .cb = nlattr_get_uint32 },
|
||||
{ .type = PF_SC_RDOMAIN, .off = _OUT(rdomain), .cb = nlattr_get_uint32 },
|
||||
{ .type = PF_SC_AF, .off = _OUT(af), .cb = nlattr_get_uint8 },
|
||||
{ .type = PF_SC_ADDR, .off = _OUT(addr), .cb = nlattr_get_in6_addr },
|
||||
};
|
||||
#undef _OUT
|
||||
NL_DECLARE_PARSER(source_clear_parser, struct genlmsghdr, nlf_p_empty, nla_p_source_clear);
|
||||
|
||||
static int
|
||||
pf_handle_source_clear(struct nlmsghdr *hdr, struct nl_pstate *npt)
|
||||
{
|
||||
struct pfioc_source_kill attrs = { 0 };
|
||||
struct nl_writer *nw = npt->nw;
|
||||
struct genlmsghdr *ghdr = (struct genlmsghdr *)(hdr + 1);
|
||||
struct genlmsghdr *ghdr_new;
|
||||
int error;
|
||||
|
||||
error = nl_parse_nlmsg(hdr, &source_clear_parser, npt, &attrs);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
error = pf_source_clr(&attrs);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr)))
|
||||
return (ENOMEM);
|
||||
|
||||
ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr);
|
||||
ghdr_new->cmd = ghdr->cmd;
|
||||
|
||||
nlattr_add_string(nw, PF_SCL_NAME, attrs.name);
|
||||
|
||||
if (!nlmsg_end(nw))
|
||||
return (ENOMEM);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static const struct nlhdr_parser *all_parsers[] = {
|
||||
&state_parser,
|
||||
&addrule_parser,
|
||||
@@ -2479,6 +2819,10 @@ static const struct nlhdr_parser *all_parsers[] = {
|
||||
&table_parser,
|
||||
&table_addr_parser,
|
||||
&table_astats_parser,
|
||||
&state_limiter_parser,
|
||||
&source_limiter_parser,
|
||||
&source_parser,
|
||||
&source_clear_parser,
|
||||
};
|
||||
|
||||
static uint16_t family_id;
|
||||
@@ -2743,6 +3087,69 @@ static const struct genl_cmd pf_cmds[] = {
|
||||
.cmd_flags = GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
|
||||
.cmd_priv = PRIV_NETINET_PF,
|
||||
},
|
||||
{
|
||||
.cmd_num = PFNL_CMD_STATE_LIMITER_ADD,
|
||||
.cmd_name = "STATE_LIMITER_ADD",
|
||||
.cmd_cb = pf_handle_state_limiter_add,
|
||||
.cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_HASPOL,
|
||||
.cmd_priv = PRIV_NETINET_PF,
|
||||
},
|
||||
{
|
||||
.cmd_num = PFNL_CMD_STATE_LIMITER_GET,
|
||||
.cmd_name = "STATE_LIMITER_GET",
|
||||
.cmd_cb = pf_handle_state_limiter_get,
|
||||
.cmd_flags = GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
|
||||
.cmd_priv = PRIV_NETINET_PF,
|
||||
},
|
||||
{
|
||||
.cmd_num = PFNL_CMD_STATE_LIMITER_NGET,
|
||||
.cmd_name = "STATE_LIMITER_NGET",
|
||||
.cmd_cb = pf_handle_state_limiter_get,
|
||||
.cmd_flags = GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
|
||||
.cmd_priv = PRIV_NETINET_PF,
|
||||
},
|
||||
{
|
||||
.cmd_num = PFNL_CMD_SOURCE_LIMITER_ADD,
|
||||
.cmd_name = "SOURCE_LIMITER_ADD",
|
||||
.cmd_cb = pf_handle_source_limiter_add,
|
||||
.cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_HASPOL,
|
||||
.cmd_priv = PRIV_NETINET_PF,
|
||||
},
|
||||
{
|
||||
.cmd_num = PFNL_CMD_SOURCE_LIMITER_GET,
|
||||
.cmd_name = "SOURCE_LIMITER_GET",
|
||||
.cmd_cb = pf_handle_source_limiter_get,
|
||||
.cmd_flags = GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
|
||||
.cmd_priv = PRIV_NETINET_PF,
|
||||
},
|
||||
{
|
||||
.cmd_num = PFNL_CMD_SOURCE_LIMITER_NGET,
|
||||
.cmd_name = "SOURCE_LIMITER_NGET",
|
||||
.cmd_cb = pf_handle_source_limiter_get,
|
||||
.cmd_flags = GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
|
||||
.cmd_priv = PRIV_NETINET_PF,
|
||||
},
|
||||
{
|
||||
.cmd_num = PFNL_CMD_SOURCE_GET,
|
||||
.cmd_name = "SOURCE_GET",
|
||||
.cmd_cb = pf_handle_source_get,
|
||||
.cmd_flags = GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
|
||||
.cmd_priv = PRIV_NETINET_PF,
|
||||
},
|
||||
{
|
||||
.cmd_num = PFNL_CMD_SOURCE_NGET,
|
||||
.cmd_name = "SOURCE_NGET",
|
||||
.cmd_cb = pf_handle_source_get,
|
||||
.cmd_flags = GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
|
||||
.cmd_priv = PRIV_NETINET_PF,
|
||||
},
|
||||
{
|
||||
.cmd_num = PFNL_CMD_SOURCE_CLEAR,
|
||||
.cmd_name = "SOURCE_CLEAR",
|
||||
.cmd_cb = pf_handle_source_clear,
|
||||
.cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_HASPOL,
|
||||
.cmd_priv = PRIV_NETINET_PF,
|
||||
},
|
||||
};
|
||||
|
||||
void
|
||||
|
||||
@@ -73,6 +73,15 @@ enum {
|
||||
PFNL_CMD_TABLE_GET_ADDR = 35,
|
||||
PFNL_CMD_TABLE_GET_ASTATS = 36,
|
||||
PFNL_CMD_TABLE_CLEAR_ASTATS = 37,
|
||||
PFNL_CMD_STATE_LIMITER_ADD = 38,
|
||||
PFNL_CMD_STATE_LIMITER_GET = 39,
|
||||
PFNL_CMD_STATE_LIMITER_NGET = 40,
|
||||
PFNL_CMD_SOURCE_LIMITER_ADD = 41,
|
||||
PFNL_CMD_SOURCE_LIMITER_GET = 42,
|
||||
PFNL_CMD_SOURCE_LIMITER_NGET = 43,
|
||||
PFNL_CMD_SOURCE_GET = 44,
|
||||
PFNL_CMD_SOURCE_NGET = 45,
|
||||
PFNL_CMD_SOURCE_CLEAR = 46,
|
||||
__PFNL_CMD_MAX,
|
||||
};
|
||||
#define PFNL_CMD_MAX (__PFNL_CMD_MAX -1)
|
||||
@@ -509,6 +518,76 @@ enum pf_table_astats_t {
|
||||
PF_TAS_ASTATS_COUNT = 4, /* u32 */
|
||||
PF_TAS_ASTATS_ZEROED = 5, /* u32 */
|
||||
};
|
||||
|
||||
enum pf_limit_rate_t {
|
||||
PF_LR_UNSPEC,
|
||||
PF_LR_LIMIT = 1, /* u32 */
|
||||
PF_LR_SECONDS = 2, /* u32 */
|
||||
};
|
||||
|
||||
enum pf_state_limit_t {
|
||||
PF_SL_UNSPEC,
|
||||
PF_SL_TICKET = 1, /* u32 */
|
||||
PF_SL_NAME = 2, /* string */
|
||||
PF_SL_ID = 3, /* u32 */
|
||||
PF_SL_LIMIT = 4, /* u32 */
|
||||
PF_SL_RATE = 5, /* nested, pf_limit_rate_t */
|
||||
PF_SL_DESCR = 6, /* string */
|
||||
PF_SL_INUSE = 7, /* u32 */
|
||||
PF_SL_ADMITTED = 8, /* u64 */
|
||||
PF_SL_HARDLIMITED = 9, /* u64 */
|
||||
PF_SL_RATELIMITED = 10, /* u64 */
|
||||
};
|
||||
|
||||
enum pf_source_limit_t {
|
||||
PF_SCL_UNSPEC,
|
||||
PF_SCL_TICKET = 1, /* u32 */
|
||||
PF_SCL_NAME = 2, /* string */
|
||||
PF_SCL_ID = 3, /* u32 */
|
||||
PF_SCL_ENTRIES = 4, /* u32 */
|
||||
PF_SCL_LIMIT = 5, /* u32 */
|
||||
PF_SCL_RATE = 6, /* nested, pf_limit_rate_t */
|
||||
PF_SCL_OVERLOAD_TBL_NAME = 7, /* string*/
|
||||
PF_SCL_OVERLOAD_HIGH_WM = 8, /* u32 */
|
||||
PF_SCL_OVERLOAD_LOW_WM = 9, /* u32 */
|
||||
PF_SCL_INET_PREFIX = 10, /* u32 */
|
||||
PF_SCL_INET6_PREFIX = 11, /* u32 */
|
||||
PF_SCL_DESCR = 12, /* string */
|
||||
PF_SCL_NENTRIES = 13, /* u32 */
|
||||
PF_SCL_INUSE = 14, /* u32 */
|
||||
PF_SCL_ADDR_ALLOCS = 15, /* u64 */
|
||||
PF_SCL_ADDR_NOMEM = 16, /* u64 */
|
||||
PF_SCL_ADMITTED = 17, /* u64 */
|
||||
PF_SCL_ADDRLIMITED = 18, /* u64 */
|
||||
PF_SCL_HARDLIMITED = 19, /* u64 */
|
||||
PF_SCL_RATELIMITED = 20, /* u64 */
|
||||
};
|
||||
|
||||
enum pf_source_t {
|
||||
PF_SRC_UNSPEC,
|
||||
PF_SRC_NAME = 1, /* string */
|
||||
PF_SRC_ID = 2, /* u32 */
|
||||
PF_SRC_AF = 3, /* u8 */
|
||||
PF_SRC_RDOMAIN = 4, /* u32 */
|
||||
PF_SRC_ADDR = 5, /* in6_addr */
|
||||
PF_SRC_INUSE = 6, /* u32 */
|
||||
PF_SRC_ADMITTED = 7, /* u64 */
|
||||
PF_SRC_HARDLIMITED = 8, /* u64 */
|
||||
PF_SRC_RATELIMITED = 9, /* u64 */
|
||||
PF_SRC_LIMIT = 10, /* u32 */
|
||||
PF_SRC_INET_PREFIX = 11, /* u32 */
|
||||
PF_SRC_INET6_PREFIX = 12, /* u32 */
|
||||
};
|
||||
|
||||
enum pf_source_clear_t {
|
||||
PF_SC_UNSPEC,
|
||||
PF_SC_NAME = 1, /* string */
|
||||
PF_SC_ID = 2, /* u32*/
|
||||
PF_SC_RDOMAIN = 3, /* u32 */
|
||||
PF_SC_AF = 4, /* u8 */
|
||||
PF_SC_ADDR = 5, /* in6_addr */
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
void pf_nl_register(void);
|
||||
|
||||
Reference in New Issue
Block a user