Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F148340543
D38888.id118252.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
18 KB
Referenced Files
None
Subscribers
None
D38888.id118252.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D38888: pf: add sample netlink interface
Attached
Detach File
Event Timeline
Log In to Comment