Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109277038
D44090.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
D44090.diff
View Options
diff --git a/contrib/pf/authpf/authpf.c b/contrib/pf/authpf/authpf.c
--- a/contrib/pf/authpf/authpf.c
+++ b/contrib/pf/authpf/authpf.c
@@ -57,6 +57,7 @@
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 @@
}
/* 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 @@
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 @@
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)");
}
diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h
--- a/lib/libpfctl/libpfctl.h
+++ b/lib/libpfctl/libpfctl.h
@@ -446,6 +446,10 @@
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);
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -1630,22 +1630,6 @@
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 @@
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);
-
- if ((ret = pfctl_do_ioctl(dev, ioctlval, 1024, &nvl)) != 0)
- goto out;
+ snl_init_writer(&h->ss, &nw);
+ hdr = snl_create_genl_msg_request(&nw, family_id, cmd);
+ hdr->nlmsg_flags |= NLM_F_DUMP;
+
+ 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
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -545,7 +545,7 @@
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 @@
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 @@
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 @@
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 @@
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)
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -2208,6 +2208,9 @@
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)
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
@@ -227,9 +227,6 @@
* 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 @@
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 @@
return (killed);
}
-static void
+void
pf_killstates(struct pf_kstate_kill *kill, unsigned int *killed)
{
struct pf_kstate *s;
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
@@ -43,6 +43,8 @@
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 @@
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);
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
@@ -782,6 +782,7 @@
};
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 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 @@
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 @@
.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
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Feb 3, 10:55 PM (21 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16443797
Default Alt Text
D44090.diff (14 KB)
Attached To
Mode
D44090: pf: convert kill/clear state to use netlink
Attached
Detach File
Event Timeline
Log In to Comment