Page MenuHomeFreeBSD

D31139.diff
No OneTemporary

D31139.diff

diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1572,6 +1572,7 @@
struct mtx lock;
};
+extern u_long pf_ioctl_maxcount;
extern u_long pf_hashmask;
extern u_long pf_srchashmask;
#define PF_HASHSIZ (131072)
@@ -1840,7 +1841,6 @@
u_int16_t);
void pf_syncookies_init(void);
-int pf_syncookies_setmode(u_int8_t);
int pf_get_syncookies(struct pfioc_nv *);
int pf_set_syncookies(struct pfioc_nv *);
int pf_synflood_check(struct pf_pdesc *);
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
@@ -275,6 +275,14 @@
extern u_long pf_ioctl_maxcount;
+#define ERROUT_FUNCTION(target, x) \
+ do { \
+ error = (x); \
+ SDT_PROBE3(pf, ioctl, function, error, __func__, error, \
+ __LINE__); \
+ goto target; \
+ } while (0)
+
static void
pfattach_vnet(void)
{
@@ -2136,6 +2144,7 @@
case DIOCOSFPGET:
case DIOCGETSRCNODES:
case DIOCCLRSRCNODES:
+ case DIOCGETSYNCOOKIES:
case DIOCIGETIFACES:
case DIOCGIFSPEEDV0:
case DIOCGIFSPEEDV1:
@@ -2183,6 +2192,7 @@
case DIOCRTSTADDRS:
case DIOCOSFPGET:
case DIOCGETSRCNODES:
+ case DIOCGETSYNCOOKIES:
case DIOCIGETIFACES:
case DIOCGIFSPEEDV1:
case DIOCGIFSPEEDV0:
@@ -4538,6 +4548,14 @@
error = pf_keepcounters((struct pfioc_nv *)addr);
break;
+ case DIOCGETSYNCOOKIES:
+ error = pf_get_syncookies((struct pfioc_nv *)addr);
+ break;
+
+ case DIOCSETSYNCOOKIES:
+ error = pf_set_syncookies((struct pfioc_nv *)addr);
+ break;
+
case DIOCSETHOSTID: {
u_int32_t *hostid = (u_int32_t *)addr;
diff --git a/sys/netpfil/pf/pf_syncookies.c b/sys/netpfil/pf/pf_syncookies.c
--- a/sys/netpfil/pf/pf_syncookies.c
+++ b/sys/netpfil/pf/pf_syncookies.c
@@ -110,6 +110,7 @@
VNET_DEFINE_STATIC(struct pf_syncookie_status, pf_syncookie_status);
#define V_pf_syncookie_status VNET(pf_syncookie_status)
+static int pf_syncookies_setmode(u_int8_t);
void pf_syncookie_rotate(void *);
void pf_syncookie_newkey(void);
uint32_t pf_syncookie_mac(struct pf_pdesc *, union pf_syncookie,
@@ -127,6 +128,89 @@
}
int
+pf_get_syncookies(struct pfioc_nv *nv)
+{
+ nvlist_t *nvl = NULL;
+ void *nvlpacked = NULL;
+
+ nvl = nvlist_create(0);
+ if (nvl == NULL)
+ return (ENOMEM);
+
+ nvlist_add_bool(nvl, "enabled",
+ V_pf_status.syncookies_mode != PF_SYNCOOKIES_NEVER);
+ nvlist_add_bool(nvl, "adaptive", false);
+
+ nvlpacked = nvlist_pack(nvl, &nv->len);
+ if (nvlpacked == NULL) {
+ nvlist_destroy(nvl);
+ return (ENOMEM);
+ }
+ if (nv->size == 0) {
+ nvlist_destroy(nvl);
+ free(nvlpacked, M_TEMP);
+ return (0);
+ } else if (nv->size < nv->len) {
+ nvlist_destroy(nvl);
+ free(nvlpacked, M_TEMP);
+ return (ENOSPC);
+ }
+
+ return (copyout(nvlpacked, nv->data, nv->len));
+}
+
+int
+pf_set_syncookies(struct pfioc_nv *nv)
+{
+ nvlist_t *nvl = NULL;
+ void *nvlpacked = NULL;
+ int error;
+ bool enabled, adaptive;
+
+ if (nv->len > pf_ioctl_maxcount)
+ return (ENOMEM);
+
+ nvlpacked = malloc(nv->len, M_TEMP, M_WAITOK);
+ if (nvlpacked == NULL)
+ return (ENOMEM);
+
+ error = copyin(nv->data, nvlpacked, nv->len);
+ if (error) {
+ free(nvlpacked, M_TEMP);
+ return (error);
+ }
+
+ nvl = nvlist_unpack(nvlpacked, nv->len, 0);
+ if (nvl == NULL) {
+ free(nvlpacked, M_TEMP);
+ return (EBADMSG);
+ }
+
+ if (! nvlist_exists_bool(nvl, "enabled")
+ || ! nvlist_exists_bool(nvl, "adaptive")) {
+ nvlist_destroy(nvl);
+ free(nvlpacked, M_TEMP);
+ return (EBADMSG);
+ }
+
+ enabled = nvlist_get_bool(nvl, "enabled");
+ adaptive = nvlist_get_bool(nvl, "adaptive");
+
+ if (adaptive) {
+ nvlist_destroy(nvl);
+ free(nvlpacked, M_TEMP);
+ return (ENOTSUP);
+ }
+
+ PF_RULES_WLOCK();
+ error = pf_syncookies_setmode(enabled ?
+ PF_SYNCOOKIES_ALWAYS : PF_SYNCOOKIES_NEVER);
+ PF_RULES_WUNLOCK();
+
+ return (error);
+}
+
+static int
pf_syncookies_setmode(u_int8_t mode)
{
if (mode > PF_SYNCOOKIES_MODE_MAX)

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 6, 8:30 AM (7 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14481061
Default Alt Text
D31139.diff (3 KB)

Event Timeline