mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-28 03:42:04 +01:00
pf: convert kill/clear state to use netlink
Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D44090
This commit is contained in:
parent
dfed87b5ce
commit
706d465dae
@ -57,6 +57,7 @@ static int change_table(int, const char *);
|
||||
static void authpf_kill_states(void);
|
||||
|
||||
int dev; /* pf device */
|
||||
struct pfctl_handle *pfh;
|
||||
char anchorname[PF_ANCHOR_NAME_SIZE] = "authpf";
|
||||
char rulesetname[MAXPATHLEN - PF_ANCHOR_NAME_SIZE - 2];
|
||||
char tablename[PF_TABLE_NAME_SIZE] = "authpf_users";
|
||||
@ -135,7 +136,8 @@ main(void)
|
||||
}
|
||||
/* open the pf device */
|
||||
dev = open(PATH_DEVFILE, O_RDWR);
|
||||
if (dev == -1) {
|
||||
pfh = pfctl_open(PATH_DEVFILE);
|
||||
if (dev == -1 || pfh == NULL) {
|
||||
syslog(LOG_ERR, "cannot open packet filter device (%m)");
|
||||
goto die;
|
||||
}
|
||||
@ -906,7 +908,7 @@ authpf_kill_states(void)
|
||||
sizeof(kill.src.addr.v.a.addr));
|
||||
memset(&kill.src.addr.v.a.mask, 0xff,
|
||||
sizeof(kill.src.addr.v.a.mask));
|
||||
if (pfctl_kill_states(dev, &kill, NULL))
|
||||
if (pfctl_kill_states_h(pfh, &kill, NULL))
|
||||
syslog(LOG_ERR, "pfctl_kill_states() failed (%m)");
|
||||
|
||||
/* Kill all states to ipsrc */
|
||||
@ -915,7 +917,7 @@ authpf_kill_states(void)
|
||||
sizeof(kill.dst.addr.v.a.addr));
|
||||
memset(&kill.dst.addr.v.a.mask, 0xff,
|
||||
sizeof(kill.dst.addr.v.a.mask));
|
||||
if (pfctl_kill_states(dev, &kill, NULL))
|
||||
if (pfctl_kill_states_h(pfh, &kill, NULL))
|
||||
syslog(LOG_ERR, "pfctl_kill_states() failed (%m)");
|
||||
}
|
||||
|
||||
|
@ -1630,22 +1630,6 @@ pfctl_get_creatorids(struct pfctl_handle *h, uint32_t *creators, size_t *len)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static void
|
||||
pfctl_nv_add_state_cmp(nvlist_t *nvl, const char *name,
|
||||
const struct pfctl_state_cmp *cmp)
|
||||
{
|
||||
nvlist_t *nv;
|
||||
|
||||
nv = nvlist_create(0);
|
||||
|
||||
nvlist_add_number(nv, "id", cmp->id);
|
||||
nvlist_add_number(nv, "creatorid", htonl(cmp->creatorid));
|
||||
nvlist_add_number(nv, "direction", cmp->direction);
|
||||
|
||||
nvlist_add_nvlist(nvl, name, nv);
|
||||
nvlist_destroy(nv);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
snl_attr_get_pfaddr(struct snl_state *ss __unused, struct nlattr *nla,
|
||||
const void *arg __unused, void *target)
|
||||
@ -1848,48 +1832,110 @@ pfctl_free_states(struct pfctl_states *states)
|
||||
bzero(states, sizeof(*states));
|
||||
}
|
||||
|
||||
struct pfctl_nl_clear_states {
|
||||
uint32_t killed;
|
||||
};
|
||||
#define _OUT(_field) offsetof(struct pfctl_nl_clear_states, _field)
|
||||
static struct snl_attr_parser ap_clear_states[] = {
|
||||
{ .type = PF_CS_KILLED, .off = _OUT(killed), .cb = snl_attr_get_uint32 },
|
||||
};
|
||||
static struct snl_field_parser fp_clear_states[] = {};
|
||||
#undef _OUT
|
||||
SNL_DECLARE_PARSER(clear_states_parser, struct genlmsghdr, fp_clear_states, ap_clear_states);
|
||||
|
||||
static int
|
||||
_pfctl_clear_states(int dev, const struct pfctl_kill *kill,
|
||||
unsigned int *killed, uint64_t ioctlval)
|
||||
_pfctl_clear_states_h(struct pfctl_handle *h, const struct pfctl_kill *kill,
|
||||
unsigned int *killed, int cmd)
|
||||
{
|
||||
nvlist_t *nvl;
|
||||
int ret;
|
||||
struct snl_writer nw;
|
||||
struct snl_errmsg_data e = {};
|
||||
struct pfctl_nl_clear_states attrs = {};
|
||||
struct nlmsghdr *hdr;
|
||||
uint32_t seq_id;
|
||||
int family_id;
|
||||
|
||||
nvl = nvlist_create(0);
|
||||
family_id = snl_get_genl_family(&h->ss, PFNL_FAMILY_NAME);
|
||||
if (family_id == 0)
|
||||
return (ENOTSUP);
|
||||
|
||||
pfctl_nv_add_state_cmp(nvl, "cmp", &kill->cmp);
|
||||
nvlist_add_number(nvl, "af", kill->af);
|
||||
nvlist_add_number(nvl, "proto", kill->proto);
|
||||
pfctl_nv_add_rule_addr(nvl, "src", &kill->src);
|
||||
pfctl_nv_add_rule_addr(nvl, "dst", &kill->dst);
|
||||
pfctl_nv_add_rule_addr(nvl, "rt_addr", &kill->rt_addr);
|
||||
nvlist_add_string(nvl, "ifname", kill->ifname);
|
||||
nvlist_add_string(nvl, "label", kill->label);
|
||||
nvlist_add_bool(nvl, "kill_match", kill->kill_match);
|
||||
nvlist_add_bool(nvl, "nat", kill->nat);
|
||||
snl_init_writer(&h->ss, &nw);
|
||||
hdr = snl_create_genl_msg_request(&nw, family_id, cmd);
|
||||
hdr->nlmsg_flags |= NLM_F_DUMP;
|
||||
|
||||
if ((ret = pfctl_do_ioctl(dev, ioctlval, 1024, &nvl)) != 0)
|
||||
goto out;
|
||||
snl_add_msg_attr_u64(&nw, PF_CS_CMP_ID, kill->cmp.id);
|
||||
snl_add_msg_attr_u32(&nw, PF_CS_CMP_CREATORID, htonl(kill->cmp.creatorid));
|
||||
snl_add_msg_attr_u8(&nw, PF_CS_CMP_DIR, kill->cmp.direction);
|
||||
snl_add_msg_attr_u8(&nw, PF_CS_AF, kill->af);
|
||||
snl_add_msg_attr_u8(&nw, PF_CS_PROTO, kill->proto);
|
||||
snl_add_msg_attr_rule_addr(&nw, PF_CS_SRC, &kill->src);
|
||||
snl_add_msg_attr_rule_addr(&nw, PF_CS_DST, &kill->dst);
|
||||
snl_add_msg_attr_rule_addr(&nw, PF_CS_RT_ADDR, &kill->rt_addr);
|
||||
snl_add_msg_attr_string(&nw, PF_CS_IFNAME, kill->ifname);
|
||||
snl_add_msg_attr_string(&nw, PF_CS_LABEL, kill->label);
|
||||
snl_add_msg_attr_bool(&nw, PF_CS_KILL_MATCH, kill->kill_match);
|
||||
snl_add_msg_attr_bool(&nw, PF_CS_NAT, kill->nat);
|
||||
|
||||
if ((hdr = snl_finalize_msg(&nw)) == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
seq_id = hdr->nlmsg_seq;
|
||||
|
||||
if (! snl_send_message(&h->ss, hdr))
|
||||
return (ENXIO);
|
||||
|
||||
while ((hdr = snl_read_reply_multi(&h->ss, seq_id, &e)) != NULL) {
|
||||
if (! snl_parse_nlmsg(&h->ss, hdr, &clear_states_parser, &attrs))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (killed)
|
||||
*killed = nvlist_get_number(nvl, "killed");
|
||||
*killed = attrs.killed;
|
||||
|
||||
return (e.error);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_clear_states_h(struct pfctl_handle *h, const struct pfctl_kill *kill,
|
||||
unsigned int *killed)
|
||||
{
|
||||
return(_pfctl_clear_states_h(h, kill, killed, PFNL_CMD_CLRSTATES));
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_kill_states_h(struct pfctl_handle *h, const struct pfctl_kill *kill,
|
||||
unsigned int *killed)
|
||||
{
|
||||
return(_pfctl_clear_states_h(h, kill, killed, PFNL_CMD_KILLSTATES));
|
||||
}
|
||||
|
||||
static int
|
||||
_pfctl_clear_states(int dev __unused, const struct pfctl_kill *kill,
|
||||
unsigned int *killed, uint64_t cmd)
|
||||
{
|
||||
struct pfctl_handle *h;
|
||||
int ret;
|
||||
|
||||
h = pfctl_open(PF_DEVICE);
|
||||
if (h == NULL)
|
||||
return (ENODEV);
|
||||
|
||||
ret = _pfctl_clear_states_h(h, kill, killed, cmd);
|
||||
pfctl_close(h);
|
||||
|
||||
out:
|
||||
nvlist_destroy(nvl);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_clear_states(int dev, const struct pfctl_kill *kill,
|
||||
pfctl_clear_states(int dev __unused, const struct pfctl_kill *kill,
|
||||
unsigned int *killed)
|
||||
{
|
||||
return (_pfctl_clear_states(dev, kill, killed, DIOCCLRSTATESNV));
|
||||
return (_pfctl_clear_states(dev, kill, killed, PFNL_CMD_CLRSTATES));
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_kill_states(int dev, const struct pfctl_kill *kill, unsigned int *killed)
|
||||
pfctl_kill_states(int dev __unused, const struct pfctl_kill *kill, unsigned int *killed)
|
||||
{
|
||||
return (_pfctl_clear_states(dev, kill, killed, DIOCKILLSTATESNV));
|
||||
return (_pfctl_clear_states(dev, kill, killed, PFNL_CMD_KILLSTATES));
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -446,6 +446,10 @@ int pfctl_clear_states(int dev, const struct pfctl_kill *kill,
|
||||
unsigned int *killed);
|
||||
int pfctl_kill_states(int dev, const struct pfctl_kill *kill,
|
||||
unsigned int *killed);
|
||||
int pfctl_clear_states_h(struct pfctl_handle *h, const struct pfctl_kill *kill,
|
||||
unsigned int *killed);
|
||||
int pfctl_kill_states_h(struct pfctl_handle *h, const struct pfctl_kill *kill,
|
||||
unsigned int *killed);
|
||||
int pfctl_clear_rules(int dev, const char *anchorname);
|
||||
int pfctl_clear_nat(int dev, const char *anchorname);
|
||||
int pfctl_clear_eth_rules(int dev, const char *anchorname);
|
||||
|
@ -545,7 +545,7 @@ pfctl_clear_iface_states(int dev, const char *iface, int opts)
|
||||
if (opts & PF_OPT_KILLMATCH)
|
||||
kill.kill_match = true;
|
||||
|
||||
if (pfctl_clear_states(dev, &kill, &killed))
|
||||
if (pfctl_clear_states_h(pfh, &kill, &killed))
|
||||
err(1, "DIOCCLRSTATES");
|
||||
if ((opts & PF_OPT_QUIET) == 0)
|
||||
fprintf(stderr, "%d states cleared\n", killed);
|
||||
@ -801,13 +801,13 @@ pfctl_net_kill_states(int dev, const char *iface, int opts)
|
||||
errx(1, "Unknown address family %d",
|
||||
kill.af);
|
||||
|
||||
if (pfctl_kill_states(dev, &kill, &newkilled))
|
||||
if (pfctl_kill_states_h(pfh, &kill, &newkilled))
|
||||
err(1, "DIOCKILLSTATES");
|
||||
killed += newkilled;
|
||||
}
|
||||
freeaddrinfo(res[1]);
|
||||
} else {
|
||||
if (pfctl_kill_states(dev, &kill, &newkilled))
|
||||
if (pfctl_kill_states_h(pfh, &kill, &newkilled))
|
||||
err(1, "DIOCKILLSTATES");
|
||||
killed += newkilled;
|
||||
}
|
||||
@ -873,7 +873,7 @@ pfctl_gateway_kill_states(int dev, const char *iface, int opts)
|
||||
else
|
||||
errx(1, "Unknown address family %d", kill.af);
|
||||
|
||||
if (pfctl_kill_states(dev, &kill, &newkilled))
|
||||
if (pfctl_kill_states_h(pfh, &kill, &newkilled))
|
||||
err(1, "DIOCKILLSTATES");
|
||||
killed += newkilled;
|
||||
}
|
||||
@ -907,7 +907,7 @@ pfctl_label_kill_states(int dev, const char *iface, int opts)
|
||||
sizeof(kill.label))
|
||||
errx(1, "label too long: %s", state_kill[1]);
|
||||
|
||||
if (pfctl_kill_states(dev, &kill, &killed))
|
||||
if (pfctl_kill_states_h(pfh, &kill, &killed))
|
||||
err(1, "DIOCKILLSTATES");
|
||||
|
||||
if ((opts & PF_OPT_QUIET) == 0)
|
||||
@ -946,7 +946,7 @@ pfctl_id_kill_states(int dev, const char *iface, int opts)
|
||||
usage();
|
||||
}
|
||||
|
||||
if (pfctl_kill_states(dev, &kill, &killed))
|
||||
if (pfctl_kill_states_h(pfh, &kill, &killed))
|
||||
err(1, "DIOCKILLSTATES");
|
||||
|
||||
if ((opts & PF_OPT_QUIET) == 0)
|
||||
|
@ -2208,6 +2208,9 @@ extern int pf_state_insert(struct pfi_kkif *,
|
||||
struct pf_kstate *);
|
||||
extern struct pf_kstate *pf_alloc_state(int);
|
||||
extern void pf_free_state(struct pf_kstate *);
|
||||
extern void pf_killstates(struct pf_kstate_kill *,
|
||||
unsigned int *);
|
||||
extern unsigned int pf_clear_states(const struct pf_kstate_kill *);
|
||||
|
||||
static __inline void
|
||||
pf_ref_state(struct pf_kstate *s)
|
||||
|
@ -227,9 +227,6 @@ struct cdev *pf_dev;
|
||||
* XXX - These are new and need to be checked when moveing to a new version
|
||||
*/
|
||||
static void pf_clear_all_states(void);
|
||||
static unsigned int pf_clear_states(const struct pf_kstate_kill *);
|
||||
static void pf_killstates(struct pf_kstate_kill *,
|
||||
unsigned int *);
|
||||
static int pf_killstates_row(struct pf_kstate_kill *,
|
||||
struct pf_idhash *);
|
||||
static int pf_killstates_nv(struct pfioc_nv *);
|
||||
@ -5944,7 +5941,7 @@ on_error:
|
||||
return (error);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
unsigned int
|
||||
pf_clear_states(const struct pf_kstate_kill *kill)
|
||||
{
|
||||
struct pf_state_key_cmp match_key;
|
||||
@ -6013,7 +6010,7 @@ relock_DIOCCLRSTATES:
|
||||
return (killed);
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
pf_killstates(struct pf_kstate_kill *kill, unsigned int *killed)
|
||||
{
|
||||
struct pf_kstate *s;
|
||||
|
@ -782,6 +782,7 @@ static const struct nlattr_parser nla_p_getrules[] = {
|
||||
};
|
||||
static const struct nlfield_parser nlf_p_getrules[] = {
|
||||
};
|
||||
#undef _IN
|
||||
#undef _OUT
|
||||
NL_DECLARE_PARSER(getrules_parser, struct genlmsghdr, nlf_p_getrules, nla_p_getrules);
|
||||
|
||||
@ -842,6 +843,8 @@ static const struct nlattr_parser nla_p_getrule[] = {
|
||||
};
|
||||
static const struct nlfield_parser nlf_p_getrule[] = {
|
||||
};
|
||||
#undef _IN
|
||||
#undef _OUT
|
||||
NL_DECLARE_PARSER(getrule_parser, struct genlmsghdr, nlf_p_getrule, nla_p_getrule);
|
||||
|
||||
static int
|
||||
@ -1000,10 +1003,87 @@ out:
|
||||
return (error);
|
||||
}
|
||||
|
||||
#define _IN(_field) offsetof(struct genlmsghdr, _field)
|
||||
#define _OUT(_field) offsetof(struct pf_kstate_kill, _field)
|
||||
static const struct nlattr_parser nla_p_clear_states[] = {
|
||||
{ .type = PF_CS_CMP_ID, .off = _OUT(psk_pfcmp.id), .cb = nlattr_get_uint64 },
|
||||
{ .type = PF_CS_CMP_CREATORID, .off = _OUT(psk_pfcmp.creatorid), .cb = nlattr_get_uint32 },
|
||||
{ .type = PF_CS_CMP_DIR, .off = _OUT(psk_pfcmp.direction), .cb = nlattr_get_uint8 },
|
||||
{ .type = PF_CS_AF, .off = _OUT(psk_af), .cb = nlattr_get_uint8 },
|
||||
{ .type = PF_CS_PROTO, .off = _OUT(psk_proto), .cb = nlattr_get_uint8 },
|
||||
{ .type = PF_CS_SRC, .off = _OUT(psk_src), .arg = &rule_addr_parser, .cb = nlattr_get_nested },
|
||||
{ .type = PF_CS_DST, .off = _OUT(psk_dst), .arg = &rule_addr_parser, .cb = nlattr_get_nested },
|
||||
{ .type = PF_CS_RT_ADDR, .off = _OUT(psk_rt_addr), .arg = &rule_addr_parser, .cb = nlattr_get_nested },
|
||||
{ .type = PF_CS_IFNAME, .off = _OUT(psk_ifname), .arg = (void *)IFNAMSIZ, .cb = nlattr_get_chara },
|
||||
{ .type = PF_CS_LABEL, .off = _OUT(psk_label), .arg = (void *)PF_RULE_LABEL_SIZE, .cb = nlattr_get_chara },
|
||||
{ .type = PF_CS_KILL_MATCH, .off = _OUT(psk_kill_match), .cb = nlattr_get_bool },
|
||||
{ .type = PF_CS_NAT, .off = _OUT(psk_nat), .cb = nlattr_get_bool },
|
||||
};
|
||||
static const struct nlfield_parser nlf_p_clear_states[] = {};
|
||||
#undef _IN
|
||||
#undef _OUT
|
||||
NL_DECLARE_PARSER(clear_states_parser, struct genlmsghdr, nlf_p_clear_states, nla_p_clear_states);
|
||||
|
||||
static int
|
||||
pf_handle_killclear_states(struct nlmsghdr *hdr, struct nl_pstate *npt, int cmd)
|
||||
{
|
||||
struct pf_kstate_kill kill = {};
|
||||
struct epoch_tracker et;
|
||||
struct nl_writer *nw = npt->nw;
|
||||
struct genlmsghdr *ghdr_new;
|
||||
int error;
|
||||
unsigned int killed = 0;
|
||||
|
||||
error = nl_parse_nlmsg(hdr, &clear_states_parser, npt, &kill);
|
||||
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 = cmd;
|
||||
ghdr_new->version = 0;
|
||||
ghdr_new->reserved = 0;
|
||||
|
||||
NET_EPOCH_ENTER(et);
|
||||
if (cmd == PFNL_CMD_KILLSTATES)
|
||||
pf_killstates(&kill, &killed);
|
||||
else
|
||||
killed = pf_clear_states(&kill);
|
||||
NET_EPOCH_EXIT(et);
|
||||
|
||||
nlattr_add_u32(nw, PF_CS_KILLED, killed);
|
||||
|
||||
if (! nlmsg_end(nw)) {
|
||||
error = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return (0);
|
||||
|
||||
out:
|
||||
nlmsg_abort(nw);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
pf_handle_clear_states(struct nlmsghdr *hdr, struct nl_pstate *npt)
|
||||
{
|
||||
return (pf_handle_killclear_states(hdr, npt, PFNL_CMD_CLRSTATES));
|
||||
}
|
||||
|
||||
static int
|
||||
pf_handle_kill_states(struct nlmsghdr *hdr, struct nl_pstate *npt)
|
||||
{
|
||||
return (pf_handle_killclear_states(hdr, npt, PFNL_CMD_KILLSTATES));
|
||||
}
|
||||
|
||||
static const struct nlhdr_parser *all_parsers[] = {
|
||||
&state_parser,
|
||||
&addrule_parser,
|
||||
&getrules_parser
|
||||
&getrules_parser,
|
||||
&clear_states_parser,
|
||||
};
|
||||
|
||||
static int family_id;
|
||||
@ -1058,6 +1138,20 @@ 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_CLRSTATES,
|
||||
.cmd_name = "CLRSTATES",
|
||||
.cmd_cb = pf_handle_clear_states,
|
||||
.cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
|
||||
.cmd_priv = PRIV_NETINET_PF,
|
||||
},
|
||||
{
|
||||
.cmd_num = PFNL_CMD_KILLSTATES,
|
||||
.cmd_name = "KILLSTATES",
|
||||
.cmd_cb = pf_handle_kill_states,
|
||||
.cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
|
||||
.cmd_priv = PRIV_NETINET_PF,
|
||||
},
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -43,6 +43,8 @@ enum {
|
||||
PFNL_CMD_ADDRULE = 5,
|
||||
PFNL_CMD_GETRULES = 6,
|
||||
PFNL_CMD_GETRULE = 7,
|
||||
PFNL_CMD_CLRSTATES = 8,
|
||||
PFNL_CMD_KILLSTATES = 9,
|
||||
__PFNL_CMD_MAX,
|
||||
};
|
||||
#define PFNL_CMD_MAX (__PFNL_CMD_MAX -1)
|
||||
@ -262,6 +264,23 @@ enum pf_getrules_type_t {
|
||||
PF_GR_CLEAR = 5, /* u8 */
|
||||
};
|
||||
|
||||
enum pf_clear_states_type_t {
|
||||
PF_CS_UNSPEC,
|
||||
PF_CS_CMP_ID = 1, /* u64 */
|
||||
PF_CS_CMP_CREATORID = 2, /* u32 */
|
||||
PF_CS_CMP_DIR = 3, /* u8 */
|
||||
PF_CS_AF = 4, /* u8 */
|
||||
PF_CS_PROTO = 5, /* u8 */
|
||||
PF_CS_SRC = 6, /* nested, pf_addr_wrap */
|
||||
PF_CS_DST = 7, /* nested, pf_addr_wrap */
|
||||
PF_CS_RT_ADDR = 8, /* nested, pf_addr_wrap */
|
||||
PF_CS_IFNAME = 9, /* string */
|
||||
PF_CS_LABEL = 10, /* string */
|
||||
PF_CS_KILL_MATCH = 11, /* bool */
|
||||
PF_CS_NAT = 12, /* bool */
|
||||
PF_CS_KILLED = 13, /* u32 */
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
void pf_nl_register(void);
|
||||
|
Loading…
Reference in New Issue
Block a user