Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F98778785
D46938.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D46938.diff
View Options
diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h
--- a/lib/libpfctl/libpfctl.h
+++ b/lib/libpfctl/libpfctl.h
@@ -505,5 +505,6 @@
int pfctl_get_addr(struct pfctl_handle *h, uint32_t ticket, uint32_t r_num,
uint8_t r_action, const char *anchor, uint32_t nr, struct pfioc_pooladdr *pa);
int pfctl_get_rulesets(struct pfctl_handle *h, const char *path, uint32_t *nr);
+int pfctl_get_ruleset(struct pfctl_handle *h, const char *path, uint32_t nr, struct pfioc_ruleset *rs);
#endif
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -2920,6 +2920,7 @@
#define _OUT(_field) offsetof(struct pfioc_ruleset, _field)
static const struct snl_attr_parser ap_ruleset[] = {
{ .type = PF_RS_NR, .off = _OUT(nr), .cb = snl_attr_get_uint32 },
+ { .type = PF_RS_NAME, .off = _OUT(name), .arg = (void *)PF_ANCHOR_NAME_SIZE, .cb = snl_attr_copy_string },
};
static struct snl_field_parser fp_ruleset[] = {};
SNL_DECLARE_PARSER(ruleset_parser, struct genlmsghdr, fp_ruleset, ap_ruleset);
@@ -2962,3 +2963,38 @@
return (e.error);
}
+int
+pfctl_get_ruleset(struct pfctl_handle *h, const char *path, uint32_t nr, struct pfioc_ruleset *rs)
+{
+ struct snl_writer nw;
+ struct snl_errmsg_data e = {};
+ struct nlmsghdr *hdr;
+ uint32_t seq_id;
+ int family_id;
+
+ family_id = snl_get_genl_family(&h->ss, PFNL_FAMILY_NAME);
+ if (family_id == 0)
+ return (ENOTSUP);
+
+ snl_init_writer(&h->ss, &nw);
+ hdr = snl_create_genl_msg_request(&nw, family_id, PFNL_CMD_GET_RULESET);
+
+ snl_add_msg_attr_string(&nw, PF_RS_PATH, path);
+ snl_add_msg_attr_u32(&nw, PF_RS_NR, nr);
+
+ 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, &ruleset_parser, rs))
+ continue;
+ }
+
+ return (e.error);
+}
+
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1252,7 +1252,6 @@
u_int32_t mnr, nr;
memset(&prs, 0, sizeof(prs));
- memcpy(prs.path, npath, sizeof(prs.path));
if ((ret = pfctl_get_rulesets(pfh, npath, &mnr)) != 0) {
if (ret == EINVAL)
fprintf(stderr, "Anchor '%s' "
@@ -1263,9 +1262,8 @@
pfctl_print_rule_counters(&rule, opts);
for (nr = 0; nr < mnr; ++nr) {
- prs.nr = nr;
- if (ioctl(dev, DIOCGETRULESET, &prs))
- err(1, "DIOCGETRULESET");
+ if ((ret = pfctl_get_ruleset(pfh, npath, nr, &prs)) != 0)
+ errc(1, ret, "DIOCGETRULESET");
INDENT(depth, !(opts & PF_OPT_VERBOSE));
printf("anchor \"%s\" all {\n", prs.name);
pfctl_show_rules(dev, npath, opts,
@@ -1455,7 +1453,6 @@
struct pfioc_ruleset prs;
u_int32_t mnr, nr;
memset(&prs, 0, sizeof(prs));
- memcpy(prs.path, npath, sizeof(prs.path));
if ((ret = pfctl_get_rulesets(pfh, npath, &mnr)) != 0) {
if (ret == EINVAL)
fprintf(stderr, "NAT anchor '%s' "
@@ -1466,9 +1463,8 @@
pfctl_print_rule_counters(&rule, opts);
for (nr = 0; nr < mnr; ++nr) {
- prs.nr = nr;
- if (ioctl(dev, DIOCGETRULESET, &prs))
- err(1, "DIOCGETRULESET");
+ if ((ret = pfctl_get_ruleset(pfh, npath, nr, &prs)) != 0)
+ errc(1, ret, "DIOCGETRULESET");
INDENT(depth, !(opts & PF_OPT_VERBOSE));
printf("nat-anchor \"%s\" all {\n", prs.name);
pfctl_show_nat(dev, npath, opts,
@@ -2816,7 +2812,6 @@
int ret;
memset(&pr, 0, sizeof(pr));
- memcpy(pr.path, anchorname, sizeof(pr.path));
if ((ret = pfctl_get_rulesets(pfh, anchorname, &mnr)) != 0) {
if (ret == EINVAL)
fprintf(stderr, "Anchor '%s' not found.\n",
@@ -2828,9 +2823,8 @@
for (nr = 0; nr < mnr; ++nr) {
char sub[MAXPATHLEN];
- pr.nr = nr;
- if (ioctl(dev, DIOCGETRULESET, &pr))
- err(1, "DIOCGETRULESET");
+ if ((ret = pfctl_get_ruleset(pfh, anchorname, nr, &pr)) != 0)
+ errc(1, ret, "DIOCGETRULESET");
if (!strcmp(pr.name, PF_RESERVED_ANCHOR))
continue;
sub[0] = 0;
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -2581,6 +2581,7 @@
int pf_ioctl_get_addrs(struct pfioc_pooladdr *);
int pf_ioctl_get_addr(struct pfioc_pooladdr *);
int pf_ioctl_get_rulesets(struct pfioc_ruleset *);
+int pf_ioctl_get_ruleset(struct pfioc_ruleset *);
void pf_krule_free(struct pf_krule *);
void pf_krule_clear_counters(struct pf_krule *);
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
@@ -2696,6 +2696,47 @@
return (0);
}
+int
+pf_ioctl_get_ruleset(struct pfioc_ruleset *pr)
+{
+ struct pf_kruleset *ruleset;
+ struct pf_kanchor *anchor;
+ u_int32_t nr = 0;
+ int error = 0;
+
+ PF_RULES_RLOCK_TRACKER;
+
+ PF_RULES_RLOCK();
+ if ((ruleset = pf_find_kruleset(pr->path)) == NULL) {
+ PF_RULES_RUNLOCK();
+ return (ENOENT);
+ }
+
+ pr->name[0] = 0;
+ if (ruleset->anchor == NULL) {
+ /* XXX kludge for pf_main_ruleset */
+ RB_FOREACH(anchor, pf_kanchor_global, &V_pf_anchors)
+ if (anchor->parent == NULL && nr++ == pr->nr) {
+ strlcpy(pr->name, anchor->name,
+ sizeof(pr->name));
+ break;
+ }
+ } else {
+ RB_FOREACH(anchor, pf_kanchor_node,
+ &ruleset->anchor->children)
+ if (nr++ == pr->nr) {
+ strlcpy(pr->name, anchor->name,
+ sizeof(pr->name));
+ break;
+ }
+ }
+ if (!pr->name[0])
+ error = EBUSY;
+ PF_RULES_RUNLOCK();
+
+ return (error);
+}
+
static int
pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
{
@@ -4514,39 +4555,10 @@
case DIOCGETRULESET: {
struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr;
- struct pf_kruleset *ruleset;
- struct pf_kanchor *anchor;
- u_int32_t nr = 0;
pr->path[sizeof(pr->path) - 1] = 0;
- PF_RULES_RLOCK();
- if ((ruleset = pf_find_kruleset(pr->path)) == NULL) {
- PF_RULES_RUNLOCK();
- error = ENOENT;
- break;
- }
- pr->name[0] = 0;
- if (ruleset->anchor == NULL) {
- /* XXX kludge for pf_main_ruleset */
- RB_FOREACH(anchor, pf_kanchor_global, &V_pf_anchors)
- if (anchor->parent == NULL && nr++ == pr->nr) {
- strlcpy(pr->name, anchor->name,
- sizeof(pr->name));
- break;
- }
- } else {
- RB_FOREACH(anchor, pf_kanchor_node,
- &ruleset->anchor->children)
- if (nr++ == pr->nr) {
- strlcpy(pr->name, anchor->name,
- sizeof(pr->name));
- break;
- }
- }
- if (!pr->name[0])
- error = EBUSY;
- PF_RULES_RUNLOCK();
+ error = pf_ioctl_get_ruleset(pr);
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
@@ -59,6 +59,7 @@
PFNL_CMD_GET_ADDRS = 21,
PFNL_CMD_GET_ADDR = 22,
PFNL_CMD_GET_RULESETS = 23,
+ PFNL_CMD_GET_RULESET = 24,
__PFNL_CMD_MAX,
};
#define PFNL_CMD_MAX (__PFNL_CMD_MAX -1)
@@ -385,6 +386,7 @@
PF_RS_UNSPEC,
PF_RS_PATH = 1, /* string */
PF_RS_NR = 2, /* u32 */
+ PF_RS_NAME = 3, /* string */
};
#ifdef _KERNEL
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
@@ -1638,6 +1638,7 @@
#define _OUT(_field) offsetof(struct pfioc_ruleset, _field)
static const struct nlattr_parser nla_p_ruleset[] = {
{ .type = PF_RS_PATH, .off = _OUT(path), .arg = (void *)MAXPATHLEN, .cb = nlattr_get_chara },
+ { .type = PF_RS_NR, .off = _OUT(nr), .cb = nlattr_get_uint32 },
};
static const struct nlfield_parser nlf_p_ruleset[] = {
};
@@ -1678,6 +1679,40 @@
return (0);
}
+static int
+pf_handle_get_ruleset(struct nlmsghdr *hdr, struct nl_pstate *npt)
+{
+ struct pfioc_ruleset attrs = { 0 };
+ struct nl_writer *nw = npt->nw;
+ struct genlmsghdr *ghdr_new;
+ int error;
+
+ error = nl_parse_nlmsg(hdr, &ruleset_parser, npt, &attrs);
+ if (error)
+ return (error);
+
+ error = pf_ioctl_get_ruleset(&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_GET_RULESET;
+ ghdr_new->version = 0;
+ ghdr_new->reserved = 0;
+
+ nlattr_add_string(nw, PF_RS_NAME, attrs.name);
+
+ if (!nlmsg_end(nw)) {
+ nlmsg_abort(nw);
+ return (ENOMEM);
+ }
+
+ return (0);
+}
+
static const struct nlhdr_parser *all_parsers[] = {
&state_parser,
&addrule_parser,
@@ -1857,6 +1892,13 @@
.cmd_flags = GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
.cmd_priv = PRIV_NETINET_PF,
},
+ {
+ .cmd_num = PFNL_CMD_GET_RULESET,
+ .cmd_name = "GET_RULESET",
+ .cmd_cb = pf_handle_get_ruleset,
+ .cmd_flags = GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
+ .cmd_priv = PRIV_NETINET_PF,
+ },
};
void
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Oct 5, 5:18 PM (21 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
13661432
Default Alt Text
D46938.diff (8 KB)
Attached To
Mode
D46938: pf: convert DIOCGETRULESET to netlink
Attached
Detach File
Event Timeline
Log In to Comment