Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F108625217
D42145.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D42145.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
@@ -384,6 +384,7 @@
uint8_t lowwater; /* Percent */
};
+int pfctl_startstop(int start);
struct pfctl_status* pfctl_get_status(int dev);
uint64_t pfctl_status_counter(struct pfctl_status *status, int id);
uint64_t pfctl_status_fcounter(struct pfctl_status *status, int id);
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -177,6 +177,34 @@
*nelems = elems;
}
+int
+pfctl_startstop(int start)
+{
+ struct snl_state ss = {};
+ struct snl_errmsg_data e = {};
+ struct snl_writer nw;
+ struct nlmsghdr *hdr;
+ uint32_t seq_id;
+ int family_id;
+
+ snl_init(&ss, NETLINK_GENERIC);
+ family_id = snl_get_genl_family(&ss, PFNL_FAMILY_NAME);
+
+ snl_init_writer(&ss, &nw);
+ hdr = snl_create_genl_msg_request(&nw, family_id,
+ start ? PFNL_CMD_START : PFNL_CMD_STOP);
+
+ snl_finalize_msg(&nw);
+ seq_id = hdr->nlmsg_seq;
+
+ snl_send_message(&ss, hdr);
+
+ while ((hdr = snl_read_reply_multi(&ss, seq_id, &e)) != NULL) {
+ }
+
+ return (e.error);
+}
+
static void
_pfctl_get_status_counters(const nvlist_t *nvl,
struct pfctl_status_counters *counters)
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -310,10 +310,12 @@
int
pfctl_enable(int dev, int opts)
{
- if (ioctl(dev, DIOCSTART)) {
- if (errno == EEXIST)
+ int ret;
+
+ if ((ret = pfctl_startstop(1)) != 0) {
+ if (ret == EEXIST)
errx(1, "pf already enabled");
- else if (errno == ESRCH)
+ else if (ret == ESRCH)
errx(1, "pfil registeration failed");
else
err(1, "DIOCSTART");
@@ -331,8 +333,10 @@
int
pfctl_disable(int dev, int opts)
{
- if (ioctl(dev, DIOCSTOP)) {
- if (errno == ENOENT)
+ int ret;
+
+ if ((ret = pfctl_startstop(0)) != 0) {
+ if (ret == ENOENT)
errx(1, "pf not enabled");
else
err(1, "DIOCSTOP");
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -2166,6 +2166,8 @@
#define V_pf_rulemarker VNET(pf_rulemarker)
#endif
+int pf_start(void);
+int pf_stop(void);
void pf_initialize(void);
void pf_mtag_initialize(void);
void pf_mtag_cleanup(void);
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
@@ -2337,6 +2337,49 @@
return (killed);
}
+int
+pf_start(void)
+{
+ int error = 0;
+
+ sx_xlock(&V_pf_ioctl_lock);
+ if (V_pf_status.running)
+ error = EEXIST;
+ else {
+ hook_pf();
+ if (! TAILQ_EMPTY(V_pf_keth->active.rules))
+ hook_pf_eth();
+ V_pf_status.running = 1;
+ V_pf_status.since = time_second;
+ new_unrhdr64(&V_pf_stateid, time_second);
+
+ DPFPRINTF(PF_DEBUG_MISC, ("pf: started\n"));
+ }
+ sx_xunlock(&V_pf_ioctl_lock);
+
+ return (error);
+}
+
+int
+pf_stop(void)
+{
+ int error = 0;
+
+ sx_xlock(&V_pf_ioctl_lock);
+ if (!V_pf_status.running)
+ error = ENOENT;
+ else {
+ V_pf_status.running = 0;
+ dehook_pf();
+ dehook_pf_eth();
+ V_pf_status.since = time_second;
+ DPFPRINTF(PF_DEBUG_MISC, ("pf: stopped\n"));
+ }
+ sx_xunlock(&V_pf_ioctl_lock);
+
+ return (error);
+}
+
static int
pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
{
@@ -2479,34 +2522,15 @@
CURVNET_SET(TD_TO_VNET(td));
switch (cmd) {
+#ifdef COMPAT_FREEBSD14
case DIOCSTART:
- sx_xlock(&V_pf_ioctl_lock);
- if (V_pf_status.running)
- error = EEXIST;
- else {
- hook_pf();
- if (! TAILQ_EMPTY(V_pf_keth->active.rules))
- hook_pf_eth();
- V_pf_status.running = 1;
- V_pf_status.since = time_second;
- new_unrhdr64(&V_pf_stateid, time_second);
-
- DPFPRINTF(PF_DEBUG_MISC, ("pf: started\n"));
- }
+ error = pf_start();
break;
case DIOCSTOP:
- sx_xlock(&V_pf_ioctl_lock);
- if (!V_pf_status.running)
- error = ENOENT;
- else {
- V_pf_status.running = 0;
- dehook_pf();
- dehook_pf_eth();
- V_pf_status.since = time_second;
- DPFPRINTF(PF_DEBUG_MISC, ("pf: stopped\n"));
- }
+ error = pf_stop();
break;
+#endif
case DIOCGETETHRULES: {
struct pfioc_nv *nv = (struct pfioc_nv *)addr;
@@ -5416,8 +5440,6 @@
break;
}
fail:
- if (sx_xlocked(&V_pf_ioctl_lock))
- sx_xunlock(&V_pf_ioctl_lock);
CURVNET_RESTORE();
#undef ERROUT_IOCTL
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
@@ -38,6 +38,8 @@
PFNL_CMD_UNSPEC = 0,
PFNL_CMD_GETSTATES = 1,
PFNL_CMD_GETCREATORS = 2,
+ PFNL_CMD_START = 3,
+ PFNL_CMD_STOP = 4,
__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
@@ -336,6 +336,18 @@
return (error);
}
+static int
+pf_handle_start(struct nlmsghdr *hdr __unused, struct nl_pstate *npt __unused)
+{
+ return (pf_start());
+}
+
+static int
+pf_handle_stop(struct nlmsghdr *hdr __unused, struct nl_pstate *npt __unused)
+{
+ return (pf_stop());
+}
+
static const struct nlhdr_parser *all_parsers[] = { &state_parser };
static int family_id;
@@ -353,6 +365,18 @@
.cmd_cb = pf_handle_getcreators,
.cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
},
+ {
+ .cmd_num = PFNL_CMD_START,
+ .cmd_name = "START",
+ .cmd_cb = pf_handle_start,
+ .cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_HASPOL,
+ },
+ {
+ .cmd_num = PFNL_CMD_STOP,
+ .cmd_name = "STOP",
+ .cmd_cb = pf_handle_stop,
+ .cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_HASPOL,
+ },
};
void
diff --git a/tests/sys/netpfil/pf/pass_block.sh b/tests/sys/netpfil/pf/pass_block.sh
--- a/tests/sys/netpfil/pf/pass_block.sh
+++ b/tests/sys/netpfil/pf/pass_block.sh
@@ -28,6 +28,43 @@
common_dir=$(atf_get_srcdir)/../common
+atf_test_case "enable_disable" "cleanup"
+enable_disable_head()
+{
+ atf_set descr 'Test enable/disable'
+ atf_set require.user root
+}
+
+enable_disable_body()
+{
+ pft_init
+
+ j="pass_block:enable_disable"
+
+ vnet_mkjail ${j}
+
+ # Disable when disabled fails
+ atf_check -s exit:1 -e ignore \
+ jexec ${j} pfctl -d
+
+ # Enable succeeds
+ atf_check -s exit:0 -e ignore \
+ jexec ${j} pfctl -e
+
+ # Enable when enabled fails
+ atf_check -s exit:1 -e ignore \
+ jexec ${j} pfctl -e
+
+ # Disable succeeds
+ atf_check -s exit:0 -e ignore \
+ jexec ${j} pfctl -d
+}
+
+enable_disable_cleanup()
+{
+ pft_cleanup
+}
+
atf_test_case "v4" "cleanup"
v4_head()
{
@@ -257,6 +294,7 @@
atf_init_test_cases()
{
+ atf_add_test_case "enable_disable"
atf_add_test_case "v4"
atf_add_test_case "v6"
atf_add_test_case "noalias"
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Jan 27, 11:18 PM (9 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16219911
Default Alt Text
D42145.diff (6 KB)
Attached To
Mode
D42145: pf: implement start/stop calls via netlink
Attached
Detach File
Event Timeline
Log In to Comment