Page MenuHomeFreeBSD

D44090.diff
No OneTemporary

D44090.diff

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

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)

Event Timeline