Page MenuHomeFreeBSD

D42092.diff
No OneTemporary

D42092.diff

diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h
--- a/lib/libpfctl/libpfctl.h
+++ b/lib/libpfctl/libpfctl.h
@@ -413,6 +413,7 @@
const char *anchor, const char *anchor_call, uint32_t ticket,
uint32_t pool_ticket);
int pfctl_set_keepcounters(int dev, bool keep);
+int pfctl_get_creatorids(uint32_t *creators, size_t *len);
typedef int (*pfctl_get_state_fn)(struct pfctl_state *, void *);
int pfctl_get_states_iter(pfctl_get_state_fn f, void *arg);
int pfctl_get_states(int dev, struct pfctl_states *states);
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -1106,6 +1106,71 @@
return (ret);
}
+struct pfctl_creator {
+ uint32_t id;
+};
+#define _IN(_field) offsetof(struct genlmsghdr, _field)
+#define _OUT(_field) offsetof(struct pfctl_creator, _field)
+static struct snl_attr_parser ap_creators[] = {
+ { .type = PF_ST_CREATORID, .off = _OUT(id), .cb = snl_attr_get_uint32 },
+};
+static struct snl_field_parser fp_creators[] = {
+};
+#undef _IN
+#undef _OUT
+SNL_DECLARE_PARSER(creator_parser, struct genlmsghdr, fp_creators, ap_creators);
+
+static int
+pfctl_get_creators_nl(struct snl_state *ss, uint32_t *creators, size_t *len)
+{
+
+ int family_id = snl_get_genl_family(ss, PFNL_FAMILY_NAME);
+ size_t i = 0;
+
+ struct nlmsghdr *hdr;
+ struct snl_writer nw;
+
+ snl_init_writer(ss, &nw);
+ hdr = snl_create_genl_msg_request(&nw, family_id, PFNL_CMD_GETCREATORS);
+ hdr->nlmsg_flags |= NLM_F_DUMP;
+ snl_finalize_msg(&nw);
+ uint32_t seq_id = hdr->nlmsg_seq;
+
+ snl_send_message(ss, hdr);
+
+ struct snl_errmsg_data e = {};
+ while ((hdr = snl_read_reply_multi(ss, seq_id, &e)) != NULL) {
+ struct pfctl_creator c;
+ bzero(&c, sizeof(c));
+
+ if (!snl_parse_nlmsg(ss, hdr, &creator_parser, &c))
+ continue;
+
+ creators[i] = c.id;
+ i++;
+ if (i > *len)
+ return (E2BIG);
+ }
+
+ *len = i;
+
+ return (0);
+}
+
+int
+pfctl_get_creatorids(uint32_t *creators, size_t *len)
+{
+ struct snl_state ss = {};
+ int error;
+
+ snl_init(&ss, NETLINK_GENERIC);
+ error = pfctl_get_creators_nl(&ss, creators, len);
+ snl_free(&ss);
+
+ return (error);
+
+}
+
static void
pfctl_nv_add_state_cmp(nvlist_t *nvl, const char *name,
const struct pfctl_state_cmp *cmp)
@@ -1199,7 +1264,8 @@
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
+ &state_parser, &skey_parser, &speer_parser,
+ &creator_parser,
};
static int
diff --git a/sbin/pfctl/pfctl.h b/sbin/pfctl/pfctl.h
--- a/sbin/pfctl/pfctl.h
+++ b/sbin/pfctl/pfctl.h
@@ -88,6 +88,7 @@
int pfctl_show_altq(int, const char *, int, int);
void warn_namespace_collision(const char *);
int pfctl_show_ifaces(const char *, int);
+void pfctl_show_creators(int);
FILE *pfctl_fopen(const char *, const char *);
#ifdef __FreeBSD__
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -233,7 +233,7 @@
static const char * const showopt_list[] = {
"ether", "nat", "queue", "rules", "Anchors", "Sources", "states",
"info", "Interfaces", "labels", "timeouts", "memory", "Tables",
- "osfp", "Running", "all", NULL
+ "osfp", "Running", "all", "creatorids", NULL
};
static const char * const tblcmdopt_list[] = {
@@ -1639,6 +1639,22 @@
return (0);
}
+void
+pfctl_show_creators(int opts)
+{
+ int ret;
+ uint32_t creators[16];
+ size_t count = nitems(creators);
+
+ ret = pfctl_get_creatorids(creators, &count);
+ if (ret != 0)
+ errx(ret, "Failed to retrieve creators");
+
+ printf("Creator IDs:\n");
+ for (size_t i = 0; i < count; i++)
+ printf("%08x\n", creators[i]);
+}
+
/* callbacks for rule/nat/rdr/addr */
int
pfctl_add_pool(struct pfctl *pf, struct pfctl_pool *p, sa_family_t af)
@@ -3121,6 +3137,9 @@
case 'I':
pfctl_show_ifaces(ifaceopt, opts);
break;
+ case 'c':
+ pfctl_show_creators(opts);
+ break;
}
}
diff --git a/sys/netpfil/pf/pf_nl.h b/sys/netpfil/pf/pf_nl.h
--- a/sys/netpfil/pf/pf_nl.h
+++ b/sys/netpfil/pf/pf_nl.h
@@ -37,6 +37,7 @@
enum {
PFNL_CMD_UNSPEC = 0,
PFNL_CMD_GETSTATES = 1,
+ PFNL_CMD_GETCREATORS = 2,
__PFNL_CMD_MAX,
};
#define PFNL_CMD_MAX (__PFNL_CMD_MAX -1)
diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c
--- a/sys/netpfil/pf/pf_nl.c
+++ b/sys/netpfil/pf/pf_nl.c
@@ -246,6 +246,30 @@
return (dump_state(nlp, hdr, s, npt));
}
+static int
+dump_creatorid(struct nlpcb *nlp, const struct nlmsghdr *hdr, uint32_t creator,
+ struct nl_pstate *npt)
+{
+ struct nl_writer *nw = npt->nw;
+
+ 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_GETCREATORS;
+ ghdr_new->version = 0;
+ ghdr_new->reserved = 0;
+
+ nlattr_add_u32(nw, PF_ST_CREATORID, htonl(creator));
+
+ if (nlmsg_end(nw))
+ return (0);
+
+enomem:
+ nlmsg_abort(nw);
+ return (ENOMEM);
+}
+
static int
pf_handle_getstates(struct nlmsghdr *hdr, struct nl_pstate *npt)
{
@@ -264,6 +288,56 @@
return (error);
}
+static int
+pf_handle_getcreators(struct nlmsghdr *hdr, struct nl_pstate *npt)
+{
+ uint32_t creators[16];
+ int error = 0;
+
+ bzero(creators, sizeof(creators));
+
+ 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) {
+ int j;
+ if (s->timeout == PFTM_UNLINKED)
+ continue;
+
+ for (j = 0; j < nitems(creators); j++) {
+ if (creators[j] == s->creatorid)
+ break;
+ if (creators[j] == 0) {
+ creators[j] = s->creatorid;
+ break;
+ }
+ }
+ if (j == nitems(creators))
+ printf("Warning: too many creators!\n");
+ }
+ PF_HASHROW_UNLOCK(ih);
+ }
+
+ hdr->nlmsg_flags |= NLM_F_MULTI;
+ for (int i = 0; i < nitems(creators); i++) {
+ if (creators[i] == 0)
+ break;
+ error = dump_creatorid(npt->nlp, hdr, creators[i], npt);
+ }
+
+ if (!nlmsg_end_dump(npt->nw, error, hdr)) {
+ NL_LOG(LOG_DEBUG, "Unable to finalize the dump");
+ return (ENOMEM);
+ }
+
+ return (error);
+}
+
static const struct nlhdr_parser *all_parsers[] = { &state_parser };
static int family_id;
@@ -275,6 +349,12 @@
.cmd_cb = pf_handle_getstates,
.cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
},
+ {
+ .cmd_num = PFNL_CMD_GETCREATORS,
+ .cmd_name = "GETCREATORS",
+ .cmd_cb = pf_handle_getcreators,
+ .cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
+ },
};
void
diff --git a/tests/sys/netpfil/pf/pfsync.sh b/tests/sys/netpfil/pf/pfsync.sh
--- a/tests/sys/netpfil/pf/pfsync.sh
+++ b/tests/sys/netpfil/pf/pfsync.sh
@@ -78,6 +78,8 @@
"set skip on ${epair_sync}b" \
"pass out keep state"
+ hostid_one=$(jexec one pfctl -si -v | awk '/Hostid:/ { gsub(/0x/, "", $2); printf($2); }')
+
ifconfig ${epair_one}b 198.51.100.254/24 up
ping -c 1 -S 198.51.100.254 198.51.100.1
@@ -89,6 +91,12 @@
grep 198.51.100.254 ; then
atf_fail "state not found on synced host"
fi
+
+ if ! jexec two pfctl -sc | grep ""${hostid_one}"";
+ then
+ jexec two pfctl -sc
+ atf_fail "HostID for host one not found on two"
+ fi
}
basic_cleanup()

File Metadata

Mime Type
text/plain
Expires
Fri, May 2, 10:17 AM (17 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17904429
Default Alt Text
D42092.diff (7 KB)

Event Timeline