Page MenuHomeFreeBSD

D38888.id118252.diff
No OneTemporary

D38888.id118252.diff

diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -1116,6 +1116,210 @@
ps->sync_flags = s->sync_flags;
}
+/* ---- NETLINK START ---- */
+#include <netpfil/pf/pf_nl.h>
+#include <netlink/netlink.h>
+#include <netlink/netlink_generic.h>
+#include <netlink/netlink_snl.h>
+#include <netlink/netlink_snl_route.h>
+
+/* -- Should go to netlink_snl.h -- */
+struct getfamily_attrs {
+ uint32_t family_id;
+ char *family_name;
+};
+#define _IN(_field) offsetof(struct genlmsghdr, _field)
+#define _OUT(_field) offsetof(struct getfamily_attrs, _field)
+static struct snl_attr_parser ap_ctrl[] = {
+ { .type = CTRL_ATTR_FAMILY_ID , .off = _OUT(family_id), .cb = snl_attr_get_uint16 },
+ { .type = CTRL_ATTR_FAMILY_NAME, .off = _OUT(family_name), .cb = snl_attr_get_string },
+};
+static struct snl_field_parser fp_ctrl[] = {
+};
+#undef _IN
+#undef _OUT
+SNL_DECLARE_PARSER(genl_family_parser, struct genlmsghdr, fp_ctrl, ap_ctrl);
+
+static uint16_t
+snl_get_genl_family(struct snl_state *ss, const char *family_name)
+{
+ struct {
+ struct nlmsghdr hdr;
+ struct genlmsghdr ghdr;
+ char data[64];
+ } h = {
+ .hdr.nlmsg_type = GENL_ID_CTRL,
+ .hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK,
+ .hdr.nlmsg_seq = snl_get_seq(ss),
+ .ghdr.cmd = CTRL_CMD_GETFAMILY,
+ };
+
+ struct nlattr *nla = (struct nlattr *)&h.data[0];
+ int l = strlen(family_name);
+ strlcpy(NLA_DATA(nla), family_name, l + 1);
+ nla->nla_len = 4 + l + 1;
+ nla->nla_type = CTRL_ATTR_FAMILY_NAME;
+
+ h.hdr.nlmsg_len = sizeof(struct nlmsghdr) + sizeof(struct genlmsghdr);
+ h.hdr.nlmsg_len += NLMSG_ALIGN(nla->nla_len);
+
+ snl_send(ss, &h, NLMSG_ALIGN(h.hdr.nlmsg_len));
+
+ struct nlmsghdr *hdr = snl_read_message(ss);
+
+ struct getfamily_attrs attrs = {};
+ if (!snl_parse_nlmsg(ss, hdr, &genl_family_parser, &attrs))
+ return (0);
+ // XXX
+ snl_read_message(ss); // read NLMSG_ERROR
+ return (attrs.family_id);
+}
+
+/* -- end snl -- */
+
+static inline bool
+snl_attr_get_pfaddr(struct snl_state *ss __unused, struct nlattr *nla,
+ const void *arg __unused, void *target)
+{
+ memcpy(target, NLA_DATA(nla), NLA_DATA_LEN(nla));
+ return (true);
+}
+
+static inline bool
+snl_attr_store_ifname(struct snl_state *ss __unused, struct nlattr *nla,
+ const void *arg __unused, void *target)
+{
+ size_t maxlen = NLA_DATA_LEN(nla);
+
+ if (strnlen((char *)NLA_DATA(nla), maxlen) < maxlen) {
+ strlcpy(target, (char *)NLA_DATA(nla), maxlen);
+ return (true);
+ }
+ return (false);
+}
+
+
+#define _OUT(_field) offsetof(struct pf_state_peer_export, _field)
+static const struct snl_attr_parser nla_p_speer[] = {
+ { .type = PF_STP_PFSS_FLAGS, .off = _OUT(scrub.pfss_flags), .cb = snl_attr_get_uint16 },
+ { .type = PF_STP_PFSS_TTL, .off = _OUT(scrub.pfss_ttl), .cb = snl_attr_get_uint8 },
+ { .type = PF_STP_SCRUB_FLAG, .off = _OUT(scrub.scrub_flag), .cb = snl_attr_get_uint8 },
+ { .type = PF_STP_PFSS_TS_MOD, .off = _OUT(scrub.pfss_ts_mod), .cb = snl_attr_get_uint32 },
+ { .type = PF_STP_SEQLO, .off = _OUT(seqlo), .cb = snl_attr_get_uint32 },
+ { .type = PF_STP_SEQHI, .off = _OUT(seqhi), .cb = snl_attr_get_uint32 },
+ { .type = PF_STP_SEQDIFF, .off = _OUT(seqdiff), .cb = snl_attr_get_uint32 },
+ { .type = PF_STP_MAX_WIN, .off = _OUT(max_win), .cb = snl_attr_get_uint16 },
+ { .type = PF_STP_MSS, .off = _OUT(mss), .cb = snl_attr_get_uint16 },
+ { .type = PF_STP_STATE, .off = _OUT(state), .cb = snl_attr_get_uint8 },
+ { .type = PF_STP_WSCALE, .off = _OUT(wscale), .cb = snl_attr_get_uint8 },
+};
+SNL_DECLARE_ATTR_PARSER(speer_parser, nla_p_speer);
+#undef _OUT
+
+#define _OUT(_field) offsetof(struct pf_state_key_export, _field)
+static const struct snl_attr_parser nla_p_skey[] = {
+ { .type = PF_STK_ADDR0, .off = _OUT(addr[0]), .cb = snl_attr_get_pfaddr },
+ { .type = PF_STK_ADDR1, .off = _OUT(addr[1]), .cb = snl_attr_get_pfaddr },
+ { .type = PF_STK_PORT0, .off = _OUT(port[0]), .cb = snl_attr_get_uint16 },
+ { .type = PF_STK_PORT1, .off = _OUT(port[1]), .cb = snl_attr_get_uint16 },
+};
+SNL_DECLARE_ATTR_PARSER(skey_parser, nla_p_skey);
+#undef _OUT
+
+#define _IN(_field) offsetof(struct genlmsghdr, _field)
+#define _OUT(_field) offsetof(struct pf_state_export, _field)
+static struct snl_attr_parser ap_state[] = {
+ { .type = PF_ST_ID, .off = _OUT(id), .cb = snl_attr_get_uint64 },
+ { .type = PF_ST_CREATORID, .off = _OUT(creatorid), .cb = snl_attr_get_uint32 },
+ { .type = PF_ST_IFNAME, .off = _OUT(ifname), .cb = snl_attr_store_ifname },
+ { .type = PF_ST_ORIG_IFNAME, .off = _OUT(orig_ifname), .cb = snl_attr_store_ifname },
+ { .type = PF_ST_KEY_WIRE, .off = _OUT(key[0]), .arg = &skey_parser, .cb = snl_attr_get_nested },
+ { .type = PF_ST_KEY_STACK, .off = _OUT(key[1]), .arg = &skey_parser, .cb = snl_attr_get_nested },
+ { .type = PF_ST_PEER_SRC, .off = _OUT(src), .arg = &speer_parser, .cb = snl_attr_get_nested },
+ { .type = PF_ST_PEER_DST, .off = _OUT(dst), .arg = &speer_parser, .cb = snl_attr_get_nested },
+ { .type = PF_ST_RT_ADDR, .off = _OUT(rt_addr), .cb = snl_attr_get_pfaddr },
+ { .type = PF_ST_RULE, .off = _OUT(rule), .cb = snl_attr_get_uint32 },
+ { .type = PF_ST_ANCHOR, .off = _OUT(anchor), .cb = snl_attr_get_uint32 },
+ { .type = PF_ST_NAT_RULE, .off = _OUT(nat_rule), .cb = snl_attr_get_uint32 },
+ { .type = PF_ST_CREATION, .off = _OUT(creation), .cb = snl_attr_get_uint32 },
+ { .type = PF_ST_EXPIRE, .off = _OUT(expire), .cb = snl_attr_get_uint32 },
+ { .type = PF_ST_PACKETS0, .off = _OUT(packets[0]), .cb = snl_attr_get_uint64 },
+ { .type = PF_ST_PACKETS1, .off = _OUT(packets[1]), .cb = snl_attr_get_uint64 },
+ { .type = PF_ST_BYTES0, .off = _OUT(bytes[0]), .cb = snl_attr_get_uint64 },
+ { .type = PF_ST_BYTES1, .off = _OUT(bytes[1]), .cb = snl_attr_get_uint64 },
+ { .type = PF_ST_AF, .off = _OUT(af), .cb = snl_attr_get_uint8 },
+ { .type = PF_ST_PROTO, .off = _OUT(proto), .cb = snl_attr_get_uint8 },
+ { .type = PF_ST_DIRECTION, .off = _OUT(direction), .cb = snl_attr_get_uint8 },
+ { .type = PF_ST_LOG, .off = _OUT(log), .cb = snl_attr_get_uint8 },
+ { .type = PF_ST_TIMEOUT, .off = _OUT(timeout), .cb = snl_attr_get_uint8 },
+ { .type = PF_ST_STATE_FLAGS, .off = _OUT(state_flags), .cb = snl_attr_get_uint8 },
+ { .type = PF_ST_SYNC_FLAGS, .off = _OUT(sync_flags), .cb = snl_attr_get_uint8 },
+ { .type = PF_ST_UPDATES, .off = _OUT(updates), .cb = snl_attr_get_uint8 },
+ { .type = PF_ST_VERSION, .off = _OUT(version), .cb = snl_attr_get_uint64 },
+};
+static struct snl_field_parser fp_state[] = {
+};
+#undef _IN
+#undef _OUT
+SNL_DECLARE_PARSER(state_parser, struct genlmsghdr, fp_state, ap_state);
+
+static const struct snl_hdr_parser *all_parsers[] = {
+ &state_parser, &skey_parser, &speer_parser
+};
+
+
+static int
+pfctl_get_states_nl(struct snl_state *ss, struct pfctl_states *states)
+{
+ struct pf_state_export p;
+
+ SNL_VERIFY_PARSERS(all_parsers);
+ int family_id = snl_get_genl_family(ss, PFNL_FAMILY_NAME);
+
+ struct {
+ struct nlmsghdr hdr;
+ struct genlmsghdr ghdr;
+ } h = {
+ .hdr.nlmsg_len = sizeof(h),
+ .hdr.nlmsg_type = family_id,
+ .hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP,
+ .hdr.nlmsg_seq = snl_get_seq(ss),
+ .ghdr.cmd = PFNL_CMD_GETSTATES,
+ };
+ snl_send(ss, &h, NLMSG_ALIGN(h.hdr.nlmsg_len));
+
+ bzero(states, sizeof(*states));
+ TAILQ_INIT(&states->states);
+
+ while (true) {
+ struct nlmsghdr *hdr = snl_read_message(ss);
+
+ if (hdr->nlmsg_type == NLMSG_DONE)
+ break;
+ if (hdr->nlmsg_type == NLMSG_ERROR) {
+ struct nlmsgerr *nlerr = (struct nlmsgerr *)(hdr + 1);
+ printf("ERROR = %d\n", nlerr->error);
+ break;
+ }
+ memset(&p, 0, sizeof(p));
+ if (!snl_parse_nlmsg(ss, hdr, &state_parser, &p))
+ continue;
+
+ struct pfctl_state *s = malloc(sizeof(*s));
+ if (s == NULL) {
+ pfctl_free_states(states);
+ return (ENOMEM);
+ }
+
+ pf_state_export_to_state(s, &p);
+ TAILQ_INSERT_TAIL(&states->states, s, entry);
+ }
+
+ return (0);
+}
+
+/* ---- /NETLINK END ---- */
+
int
pfctl_get_states(int dev, struct pfctl_states *states)
{
@@ -1125,6 +1329,12 @@
unsigned int len = 0;
int i, error;
+ struct snl_state ss = {};
+ snl_init(&ss, NETLINK_GENERIC);
+ error = pfctl_get_states_nl(&ss, states);
+ snl_free(&ss);
+ return (error);
+
bzero(&ps, sizeof(ps));
ps.ps_req_version = PF_STATE_VERSION;
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -6791,6 +6791,285 @@
counter_u64_free(V_pf_status.scounters[i]);
}
+/* ---- NETLINK START ---- */
+#include <netlink/netlink.h>
+#include <netlink/netlink_ctl.h>
+#include <netlink/netlink_generic.h>
+#include <netpfil/pf/pf_nl.h>
+
+#define DEBUG_MOD_NAME nl_pf
+#define DEBUG_MAX_LEVEL LOG_DEBUG3
+#include <netlink/netlink_debug.h>
+_DECLARE_DEBUG(LOG_DEBUG);
+
+
+struct nl_parsed_state {
+ uint8_t version;
+ uint32_t id;
+ uint32_t creatorid;
+};
+
+#define _IN(_field) offsetof(struct genlmsghdr, _field)
+#define _OUT(_field) offsetof(struct nl_parsed_state, _field)
+static const struct nlattr_parser nla_p_state[] = {
+ { .type = PF_ST_ID, .off = _OUT(id), .cb = nlattr_get_uint32 },
+ { .type = PF_ST_CREATORID, .off = _OUT(creatorid), .cb = nlattr_get_uint32 },
+};
+static const struct nlfield_parser nlf_p_generic[] = {
+ { .off_in = _IN(version), .off_out = _OUT(version), .cb = nlf_get_u8 },
+};
+#undef _IN
+#undef _OUT
+NL_DECLARE_PARSER(state_parser, struct genlmsghdr, nlf_p_generic, nla_p_state);
+
+static void
+nlattr_add_u16n(struct nl_writer *nw, int attr, uint32_t val)
+{
+ nlattr_add_u16(nw, attr, htons(val));
+}
+
+static void
+nlattr_add_u32n(struct nl_writer *nw, int attr, uint32_t val)
+{
+ nlattr_add_u32(nw, attr, htonl(val));
+}
+
+static void
+nlattr_add_u64n(struct nl_writer *nw, int attr, uint64_t val)
+{
+ uint64_t ret = htonl((val >> 32) & 0xffffffff);
+ ret |= (uint64_t)(htonl(val & 0xffffffff)) << 32;
+ nlattr_add_u64(nw, attr, ret);
+}
+
+static void
+dump_addr(struct nl_writer *nw, int attr, const struct pf_addr *addr, int af)
+{
+ switch (af) {
+ case AF_INET:
+ nlattr_add(nw, attr, 4, &addr->v4);
+ break;
+ case AF_INET6:
+ nlattr_add(nw, attr, 16, &addr->v6);
+ break;
+ };
+}
+
+static bool
+dump_state_peer(struct nl_writer *nw, int attr, const struct pf_state_peer *peer)
+{
+ int off = nlattr_add_nested(nw, attr);
+ if (off == 0)
+ return (false);
+
+ nlattr_add_u32n(nw, PF_STP_SEQLO, peer->seqlo);
+ nlattr_add_u32n(nw, PF_STP_SEQHI, peer->seqhi);
+ nlattr_add_u32n(nw, PF_STP_SEQDIFF, peer->seqdiff);
+ nlattr_add_u16n(nw, PF_STP_MAX_WIN, peer->max_win);
+ nlattr_add_u16n(nw, PF_STP_MSS, peer->mss);
+ nlattr_add_u8(nw, PF_STP_STATE, peer->state);
+ nlattr_add_u8(nw, PF_STP_WSCALE, peer->wscale);
+
+ if (peer->scrub != NULL) {
+ struct pf_state_scrub *sc = peer->scrub;
+ uint16_t pfss_flags = sc->pfss_flags & PFSS_TIMESTAMP;
+
+ nlattr_add_u16n(nw, PF_STP_PFSS_FLAGS, pfss_flags);
+ nlattr_add_u32n(nw, PF_STP_PFSS_TS_MOD, sc->pfss_ts_mod);
+ nlattr_add_u8(nw, PF_STP_PFSS_TTL, sc->pfss_ttl);
+ nlattr_add_u8(nw, PF_STP_SCRUB_FLAG, PFSYNC_SCRUB_FLAG_VALID);
+ }
+ nlattr_set_len(nw, off);
+
+ return (true);
+}
+
+static bool
+dump_state_key(struct nl_writer *nw, int attr, const struct pf_state_key *key)
+{
+ int off = nlattr_add_nested(nw, attr);
+ if (off == 0)
+ return (false);
+
+ dump_addr(nw, PF_STK_ADDR0, &key->addr[0], key->af);
+ dump_addr(nw, PF_STK_ADDR1, &key->addr[1], key->af);
+ nlattr_add_u16(nw, PF_STK_PORT0, key->port[0]);
+ nlattr_add_u16(nw, PF_STK_PORT1, key->port[1]);
+
+ nlattr_set_len(nw, off);
+
+ return (true);
+}
+
+static int
+dump_state(struct nlpcb *nlp, const struct nlmsghdr *hdr, struct pf_kstate *s,
+ struct nl_pstate *npt)
+{
+ struct nl_writer *nw = npt->nw;
+ int error = 0;
+ int af;
+ struct pf_state_key *key;
+
+ if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr)))
+ goto enomem;
+
+ struct genlmsghdr *ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr);
+ ghdr_new->cmd = PFNL_CMD_GETSTATES;
+ ghdr_new->version = 0;
+ ghdr_new->reserved = 0;
+
+ nlattr_add_u64(nw, PF_ST_VERSION, PF_STATE_VERSION);
+
+ key = s->key[PF_SK_WIRE];
+ if (!dump_state_key(nw, PF_ST_KEY_WIRE, key))
+ goto enomem;
+ key = s->key[PF_SK_STACK];
+ if (!dump_state_key(nw, PF_ST_KEY_STACK, key))
+ goto enomem;
+
+ af = s->key[PF_SK_WIRE]->af;
+ nlattr_add_u8(nw, PF_ST_PROTO, s->key[PF_SK_WIRE]->proto);
+ nlattr_add_u8(nw, PF_ST_AF, af);
+
+ nlattr_add_string(nw, PF_ST_IFNAME, s->kif->pfik_name);
+ dump_addr(nw, PF_ST_RT_ADDR, &s->rt_addr, af);
+ nlattr_add_u32(nw, PF_ST_CREATION, htonl(time_uptime - s->creation));
+ uint32_t expire = pf_state_expires(s);
+ if (expire > time_uptime)
+ expire = htonl(expire - time_uptime);
+ nlattr_add_u32(nw, PF_ST_EXPIRE, expire);
+ nlattr_add_u8(nw, PF_ST_DIRECTION, s->direction);
+ nlattr_add_u8(nw, PF_ST_LOG, s->log);
+ nlattr_add_u8(nw, PF_ST_TIMEOUT, s->timeout);
+ nlattr_add_u8(nw, PF_ST_STATE_FLAGS, s->state_flags);
+ uint8_t sync_flags = 0;
+ if (s->src_node)
+ sync_flags |= PFSYNC_FLAG_SRCNODE;
+ if (s->nat_src_node)
+ sync_flags |= PFSYNC_FLAG_NATSRCNODE;
+ nlattr_add_u8(nw, PF_ST_SYNC_FLAGS, sync_flags);
+ nlattr_add_u64(nw, PF_ST_ID, s->id);
+ nlattr_add_u32(nw, PF_ST_CREATORID, s->creatorid);
+
+ nlattr_add_u32n(nw, PF_ST_RULE, s->rule.ptr ? s->rule.ptr->nr : -1);
+ nlattr_add_u32n(nw, PF_ST_ANCHOR, s->anchor.ptr ? s->anchor.ptr->nr : -1);
+ nlattr_add_u32n(nw, PF_ST_NAT_RULE, s->nat_rule.ptr ? s->nat_rule.ptr->nr : -1);
+
+ nlattr_add_u64n(nw, PF_ST_PACKETS0, s->packets[0]);
+ nlattr_add_u64n(nw, 1, s->packets[1]);
+ nlattr_add_u64n(nw, PF_ST_BYTES0, s->bytes[0]);
+ nlattr_add_u64n(nw, PF_ST_BYTES1, s->bytes[1]);
+
+ if (!dump_state_peer(nw, PF_ST_PEER_SRC, &s->src))
+ goto enomem;
+ if (!dump_state_peer(nw, PF_ST_PEER_DST, &s->dst))
+ goto enomem;
+
+ if (nlmsg_end(nw))
+ return (0);
+
+enomem:
+ error = ENOMEM;
+ nlmsg_abort(nw);
+ return (error);
+}
+
+static int
+handle_dumpstates(struct nlpcb *nlp, struct nl_parsed_state *attrs,
+ struct nlmsghdr *hdr, struct nl_pstate *npt)
+{
+ int error = 0;
+
+ hdr->nlmsg_flags |= NLM_F_MULTI;
+
+ for (int i = 0; i <= pf_hashmask; i++) {
+ struct pf_idhash *ih = &V_pf_idhash[i];
+ struct pf_kstate *s;
+
+ if (LIST_EMPTY(&ih->states))
+ continue;
+
+ PF_HASHROW_LOCK(ih);
+ LIST_FOREACH(s, &ih->states, entry) {
+ if (s->timeout != PFTM_UNLINKED) {
+ error = dump_state(nlp, hdr, s, npt);
+ if (error != 0)
+ break;
+ }
+ }
+ PF_HASHROW_UNLOCK(ih);
+ /*
+ * TODO: after sending N=100k states,
+ * do cv_wait() till the socket buffer
+ * becomes empty
+ */
+ }
+
+ if (!nlmsg_end_dump(npt->nw, error, hdr)) {
+ NL_LOG(LOG_DEBUG, "Unable to finalize the dump");
+ return (ENOMEM);
+ }
+
+ return (error);
+}
+
+static int
+handle_getstate(struct nlpcb *nlp, struct nl_parsed_state *attrs,
+ struct nlmsghdr *hdr, struct nl_pstate *npt)
+{
+ struct pf_kstate *s = pf_find_state_byid(attrs->id, attrs->creatorid);
+ if (s == NULL)
+ return (ENOENT);
+ return (dump_state(nlp, hdr, s, npt));
+}
+
+static int
+pfctl_handle_getstates(struct nlmsghdr *hdr, struct nl_pstate *npt)
+{
+ int error;
+
+ struct nl_parsed_state attrs = {};
+ error = nl_parse_nlmsg(hdr, &state_parser, npt, &attrs);
+ if (error != 0)
+ return (error);
+
+ if (attrs.id != 0)
+ error = handle_getstate(npt->nlp, &attrs, hdr, npt);
+ else
+ error = handle_dumpstates(npt->nlp, &attrs, hdr, npt);
+
+ return (error);
+}
+
+static const struct nlhdr_parser *all_parsers[] = { &state_parser };
+
+static int family_id;
+
+static const struct genl_cmd pfctl_cmds[] = {
+ {
+ .cmd_num = PFNL_CMD_GETSTATES,
+ .cmd_name = "GETSTATES",
+ .cmd_cb = pfctl_handle_getstates,
+ .cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
+ },
+};
+
+static void
+nl_register(void)
+{
+ NL_VERIFY_PARSERS(all_parsers);
+ family_id = genl_register_family(PFNL_FAMILY_NAME, 0, 2, PFNL_CMD_MAX);
+ genl_register_cmds(PFNL_FAMILY_NAME, pfctl_cmds, NL_ARRAY_LEN(pfctl_cmds));
+}
+
+static void
+nl_unregister(void)
+{
+ genl_unregister_family(PFNL_FAMILY_NAME);
+}
+
+/* ---- /NETLINK END ---- */
+
static void
pf_unload(void)
{
@@ -6803,6 +7082,8 @@
}
sx_xunlock(&pf_end_lock);
+ nl_unregister();
+
if (pf_dev != NULL)
destroy_dev(pf_dev);
@@ -6840,6 +7121,7 @@
switch(type) {
case MOD_LOAD:
error = pf_load();
+ nl_register();
break;
case MOD_UNLOAD:
/* Handled in SYSUNINIT(pf_unload) to ensure it's done after
@@ -6860,4 +7142,5 @@
};
DECLARE_MODULE(pf, pf_mod, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND);
+MODULE_DEPEND(pf, netlink, 1, 1, 1);
MODULE_VERSION(pf, PF_MODVER);
diff --git a/sys/netpfil/pf/pf_nl.h b/sys/netpfil/pf/pf_nl.h
new file mode 100644
--- /dev/null
+++ b/sys/netpfil/pf/pf_nl.h
@@ -0,0 +1,71 @@
+#ifndef _NETPFIL_PF_PF_NL_H_
+#define _NETPFIL_PF_PF_NL_H_
+
+
+/* Genetlink family */
+#define PFNL_FAMILY_NAME "pfctl"
+
+/* available commands */
+enum {
+ PFNL_CMD_UNSPEC = 0,
+ PFNL_CMD_GETSTATES = 1,
+ __PFNL_CMD_MAX,
+};
+#define PFNL_CMD_MAX (__PFNL_CMD_MAX -1)
+
+enum pfstate_key_type_t {
+ PF_STK_UNSPEC,
+ PF_STK_ADDR0 = 1, /* ip */
+ PF_STK_ADDR1 = 2, /* ip */
+ PF_STK_PORT0 = 3, /* u16 */
+ PF_STK_PORT1 = 4, /* u16 */
+};
+
+enum pfstate_peer_type_t {
+ PF_STP_UNSPEC,
+ PF_STP_PFSS_FLAGS = 1, /* u16 */
+ PF_STP_PFSS_TTL = 2, /* u8 */
+ PF_STP_SCRUB_FLAG = 3, /* u8 */
+ PF_STP_PFSS_TS_MOD = 4, /* u32 */
+ PF_STP_SEQLO = 5, /* u32 */
+ PF_STP_SEQHI = 6, /* u32 */
+ PF_STP_SEQDIFF = 7, /* u32 */
+ PF_STP_MAX_WIN = 8, /* u16 */
+ PF_STP_MSS = 9, /* u16 */
+ PF_STP_STATE = 10, /* u8 */
+ PF_STP_WSCALE = 11, /* u8 */
+};
+
+enum pfstate_type_t {
+ PF_ST_UNSPEC,
+ PF_ST_ID = 1, /* u32, state id */
+ PF_ST_CREATORID = 2, /* u32, */
+ PF_ST_IFNAME = 3, /* string */
+ PF_ST_ORIG_IFNAME = 4, /* string */
+ PF_ST_KEY_WIRE = 5, /* nested, pfstate_key_type_t */
+ PF_ST_KEY_STACK = 6, /* nested, pfstate_key_type_t */
+ PF_ST_PEER_SRC = 7, /* nested, pfstate_peer_type_t*/
+ PF_ST_PEER_DST = 8, /* nested, pfstate_peer_type_t */
+ PF_ST_RT_ADDR = 9, /* ip */
+ PF_ST_RULE = 10, /* u32 */
+ PF_ST_ANCHOR = 11, /* u32 */
+ PF_ST_NAT_RULE = 12, /* u32 */
+ PF_ST_CREATION = 13, /* u32 */
+ PF_ST_EXPIRE = 14, /* u32 */
+ PF_ST_PACKETS0 = 15, /* u64 */
+ PF_ST_PACKETS1 = 16, /* u64 */
+ PF_ST_BYTES0 = 17, /* u64 */
+ PF_ST_BYTES1 = 18, /* u64 */
+ PF_ST_AF = 19, /* u8 */
+ PF_ST_PROTO = 21, /* u8 */
+ PF_ST_DIRECTION = 22, /* u8 */
+ PF_ST_LOG = 23, /* u8 */
+ PF_ST_TIMEOUT = 24, /* u8 */
+ PF_ST_STATE_FLAGS = 25, /* u8 */
+ PF_ST_SYNC_FLAGS = 26, /* u8 */
+ PF_ST_UPDATES = 27, /* u8 */
+ PF_ST_VERSION = 28, /* u64 */
+};
+
+
+#endif

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 18, 6:11 AM (22 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29887070
Default Alt Text
D38888.id118252.diff (18 KB)

Event Timeline