Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153521368
D30052.id88865.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D30052.id88865.diff
View Options
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1074,6 +1074,19 @@
u_int psnk_killed;
};
+#ifdef _KERNEL
+struct pf_kstate_kill {
+ struct pf_state_cmp psk_pfcmp;
+ sa_family_t psk_af;
+ int psk_proto;
+ struct pf_rule_addr psk_src;
+ struct pf_rule_addr psk_dst;
+ char psk_ifname[IFNAMSIZ];
+ char psk_label[PF_RULE_LABEL_SIZE];
+ u_int psk_killed;
+};
+#endif
+
struct pfioc_state_kill {
struct pf_state_cmp psk_pfcmp;
sa_family_t psk_af;
@@ -1240,6 +1253,7 @@
#define DIOCGETRULENV _IOWR('D', 7, struct pfioc_nv)
/* XXX cut 8 - 17 */
#define DIOCCLRSTATES _IOWR('D', 18, struct pfioc_state_kill)
+#define DIOCCLRSTATESNV _IOWR('D', 18, struct pfioc_nv)
#define DIOCGETSTATE _IOWR('D', 19, struct pfioc_state)
#define DIOCSETSTATUSIF _IOWR('D', 20, struct pfioc_if)
#define DIOCGETSTATUS _IOWR('D', 21, struct pf_status)
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
@@ -200,7 +200,9 @@
/*
* XXX - These are new and need to be checked when moveing to a new version
*/
-static void pf_clear_states(void);
+static void pf_clear_all_states(void);
+static unsigned int pf_clear_states(const struct pf_kstate_kill *);
+static int pf_clearstates_nv(struct pfioc_nv *);
static int pf_clear_tables(void);
static void pf_clear_srcnodes(struct pf_ksrc_node *);
static void pf_kill_srcnodes(struct pfioc_src_node_kill *);
@@ -2395,6 +2397,72 @@
return (0);
}
+static int
+pf_state_kill_to_kstate_kill(const struct pfioc_state_kill *psk,
+ struct pf_kstate_kill *kill)
+{
+ bzero(kill, sizeof(*kill));
+
+ bcopy(&psk->psk_pfcmp, &kill->psk_pfcmp, sizeof(kill->psk_pfcmp));
+ kill->psk_af = psk->psk_af;
+ kill->psk_proto = psk->psk_proto;
+ bcopy(&psk->psk_src, &kill->psk_src, sizeof(kill->psk_src));
+ bcopy(&psk->psk_dst, &kill->psk_dst, sizeof(kill->psk_dst));
+ strlcpy(kill->psk_ifname, psk->psk_ifname, sizeof(kill->psk_ifname));
+ strlcpy(kill->psk_label, psk->psk_label, sizeof(kill->psk_label));
+
+ return (0);
+}
+
+static int
+pf_nvstate_cmp_to_state_cmp(const nvlist_t *nvl, struct pf_state_cmp *cmp)
+{
+ int error = 0;
+
+ bzero(cmp, sizeof(*cmp));
+
+ PFNV_CHK(pf_nvuint64(nvl, "id", &cmp->id));
+ PFNV_CHK(pf_nvuint32(nvl, "creatorid", &cmp->creatorid));
+ PFNV_CHK(pf_nvuint8(nvl, "direction", &cmp->direction));
+
+errout:
+ return (error);
+}
+
+static int
+pf_nvstate_kill_to_kstate_kill(const nvlist_t *nvl,
+ struct pf_kstate_kill *kill)
+{
+ int error = 0;
+
+ bzero(kill, sizeof(*kill));
+
+ if (! nvlist_exists_nvlist(nvl, "cmp"))
+ return (EINVAL);
+
+ PFNV_CHK(pf_nvstate_cmp_to_state_cmp(nvlist_get_nvlist(nvl, "cmp"),
+ &kill->psk_pfcmp));
+ PFNV_CHK(pf_nvuint8(nvl, "af", &kill->psk_af));
+ PFNV_CHK(pf_nvint(nvl, "proto", &kill->psk_proto));
+
+ if (! nvlist_exists_nvlist(nvl, "src"))
+ return (EINVAL);
+ PFNV_CHK(pf_nvrule_addr_to_rule_addr(nvlist_get_nvlist(nvl, "src"),
+ &kill->psk_src));
+ if (! nvlist_exists_nvlist(nvl, "dst"))
+ return (EINVAL);
+ PFNV_CHK(pf_nvrule_addr_to_rule_addr(nvlist_get_nvlist(nvl, "dst"),
+ &kill->psk_dst));
+
+ PFNV_CHK(pf_nvstring(nvl, "ifname", kill->psk_ifname,
+ sizeof(kill->psk_ifname)));
+ PFNV_CHK(pf_nvstring(nvl, "label", kill->psk_label,
+ sizeof(kill->psk_label)));
+
+errout:
+ return (error);
+}
+
static int
pf_ioctl_addrule(struct pf_krule *rule, uint32_t ticket,
uint32_t pool_ticket, const char *anchor, const char *anchor_call,
@@ -3305,33 +3373,19 @@
}
case DIOCCLRSTATES: {
- struct pf_state *s;
struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr;
- u_int i, killed = 0;
+ struct pf_kstate_kill kill;
- for (i = 0; i <= pf_hashmask; i++) {
- struct pf_idhash *ih = &V_pf_idhash[i];
+ error = pf_state_kill_to_kstate_kill(psk, &kill);
+ if (error)
+ break;
-relock_DIOCCLRSTATES:
- PF_HASHROW_LOCK(ih);
- LIST_FOREACH(s, &ih->states, entry)
- if (!psk->psk_ifname[0] ||
- !strcmp(psk->psk_ifname,
- s->kif->pfik_name)) {
- /*
- * Don't send out individual
- * delete messages.
- */
- s->state_flags |= PFSTATE_NOSYNC;
- pf_unlink_state(s, PF_ENTER_LOCKED);
- killed++;
- goto relock_DIOCCLRSTATES;
- }
- PF_HASHROW_UNLOCK(ih);
- }
- psk->psk_killed = killed;
- if (V_pfsync_clear_states_ptr != NULL)
- V_pfsync_clear_states_ptr(V_pf_status.hostid, psk->psk_ifname);
+ psk->psk_killed = pf_clear_states(&kill);
+ break;
+ }
+
+ case DIOCCLRSTATESNV: {
+ error = pf_clearstates_nv((struct pfioc_nv *)addr);
break;
}
@@ -5224,7 +5278,7 @@
* XXX - Check for version missmatch!!!
*/
static void
-pf_clear_states(void)
+pf_clear_all_states(void)
{
struct pf_state *s;
u_int i;
@@ -5375,6 +5429,97 @@
return (error);
}
+static unsigned int
+pf_clear_states(const struct pf_kstate_kill *kill)
+{
+ struct pf_state *s;
+ unsigned int killed = 0;
+
+ for (unsigned int i = 0; i <= pf_hashmask; i++) {
+ struct pf_idhash *ih = &V_pf_idhash[i];
+
+relock_DIOCCLRSTATES:
+ PF_HASHROW_LOCK(ih);
+ LIST_FOREACH(s, &ih->states, entry)
+ if (!kill->psk_ifname[0] ||
+ !strcmp(kill->psk_ifname,
+ s->kif->pfik_name)) {
+ /*
+ * Don't send out individual
+ * delete messages.
+ */
+ s->state_flags |= PFSTATE_NOSYNC;
+ pf_unlink_state(s, PF_ENTER_LOCKED);
+ killed++;
+ goto relock_DIOCCLRSTATES;
+ }
+ PF_HASHROW_UNLOCK(ih);
+ }
+
+ if (V_pfsync_clear_states_ptr != NULL)
+ V_pfsync_clear_states_ptr(V_pf_status.hostid, kill->psk_ifname);
+
+ return (killed);
+}
+
+static int
+pf_clearstates_nv(struct pfioc_nv *nv)
+{
+ struct pf_kstate_kill kill;
+ nvlist_t *nvl = NULL;
+ void *nvlpacked = NULL;
+ int error = 0;
+ unsigned int killed;
+
+#define ERROUT(x) ERROUT_FUNCTION(on_error, x)
+
+ if (nv->len > pf_ioctl_maxcount)
+ ERROUT(ENOMEM);
+
+ nvlpacked = malloc(nv->len, M_TEMP, M_WAITOK);
+ if (nvlpacked == NULL)
+ ERROUT(ENOMEM);
+
+ error = copyin(nv->data, nvlpacked, nv->len);
+ if (error)
+ ERROUT(error);
+
+ nvl = nvlist_unpack(nvlpacked, nv->len, 0);
+ if (nvl == NULL)
+ ERROUT(EBADMSG);
+
+ error = pf_nvstate_kill_to_kstate_kill(nvl, &kill);
+ if (error)
+ ERROUT(error);
+
+ killed = pf_clear_states(&kill);
+
+ free(nvlpacked, M_TEMP);
+ nvlpacked = NULL;
+ nvlist_destroy(nvl);
+ nvl = nvlist_create(0);
+ if (nvl == NULL)
+ ERROUT(ENOMEM);
+
+ nvlist_add_number(nvl, "killed", killed);
+
+ nvlpacked = nvlist_pack(nvl, &nv->len);
+ if (nvlpacked == NULL)
+ ERROUT(ENOMEM);
+
+ if (nv->size == 0)
+ ERROUT(0);
+ else if (nv->size < nv->len)
+ ERROUT(ENOSPC);
+
+ error = copyout(nvlpacked, nv->data, nv->len);
+
+on_error:
+ nvlist_destroy(nvl);
+ free(nvlpacked, M_TEMP);
+ return (error);
+}
+
/*
* XXX - Check for version missmatch!!!
*/
@@ -5434,7 +5579,7 @@
pf_commit_altq(t[0]);
#endif
- pf_clear_states();
+ pf_clear_all_states();
pf_clear_srcnodes(NULL);
diff --git a/sys/netpfil/pf/pf_nv.h b/sys/netpfil/pf/pf_nv.h
--- a/sys/netpfil/pf/pf_nv.h
+++ b/sys/netpfil/pf/pf_nv.h
@@ -48,6 +48,11 @@
size_t, size_t *);
void pf_uint32_array_nv(nvlist_t *, const char *, const uint32_t *,
size_t);
+int pf_nvuint64(const nvlist_t *, const char *, uint64_t *);
+int pf_nvuint64_array(const nvlist_t *, const char *, uint64_t *,
+ size_t, size_t *);
+void pf_uint64_array_nv(nvlist_t *, const char *, const uint64_t *,
+ size_t);
int pf_nvstring(const nvlist_t *, const char *, char *, size_t);
diff --git a/sys/netpfil/pf/pf_nv.c b/sys/netpfil/pf/pf_nv.c
--- a/sys/netpfil/pf/pf_nv.c
+++ b/sys/netpfil/pf/pf_nv.c
@@ -104,6 +104,7 @@
PF_NV_IMPL_UINT(uint8, uint8_t, UINT8_MAX);
PF_NV_IMPL_UINT(uint16, uint16_t, UINT16_MAX);
PF_NV_IMPL_UINT(uint32, uint32_t, UINT32_MAX);
+PF_NV_IMPL_UINT(uint64, uint64_t, UINT64_MAX);
int
pf_nvint(const nvlist_t *nvl, const char *name, int *val)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Apr 22, 2:56 PM (39 m, 58 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31975894
Default Alt Text
D30052.id88865.diff (7 KB)
Attached To
Mode
D30052: pf: Introduce DIOCCLRSTATESNV
Attached
Detach File
Event Timeline
Log In to Comment