Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F116025689
D39392.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
58 KB
Referenced Files
None
Subscribers
None
D39392.diff
View Options
diff --git a/contrib/tcpdump/print-pfsync.c b/contrib/tcpdump/print-pfsync.c
--- a/contrib/tcpdump/print-pfsync.c
+++ b/contrib/tcpdump/print-pfsync.c
@@ -55,7 +55,7 @@
static void print_src_dst(netdissect_options *,
const struct pfsync_state_peer *,
const struct pfsync_state_peer *, uint8_t);
-static void print_state(netdissect_options *, struct pfsync_state *);
+static void print_state(netdissect_options *, union pfsync_state_union *, int);
u_int
pfsync_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
@@ -100,7 +100,8 @@
};
static void pfsync_print_clr(netdissect_options *, const void *);
-static void pfsync_print_state(netdissect_options *, const void *);
+static void pfsync_print_state_1301(netdissect_options *, const void *);
+static void pfsync_print_state_1400(netdissect_options *, const void *);
static void pfsync_print_ins_ack(netdissect_options *, const void *);
static void pfsync_print_upd_c(netdissect_options *, const void *);
static void pfsync_print_upd_req(netdissect_options *, const void *);
@@ -110,14 +111,16 @@
struct pfsync_actions actions[] = {
{ "clear all", sizeof(struct pfsync_clr), pfsync_print_clr },
- { "insert", sizeof(struct pfsync_state), pfsync_print_state },
+ { "insert 13.1", sizeof(struct pfsync_state_1301),
+ pfsync_print_state_1301 },
{ "insert ack", sizeof(struct pfsync_ins_ack), pfsync_print_ins_ack },
- { "update", sizeof(struct pfsync_ins_ack), pfsync_print_state },
+ { "update 13.1", sizeof(struct pfsync_state_1301),
+ pfsync_print_state_1301 },
{ "update compressed", sizeof(struct pfsync_upd_c),
pfsync_print_upd_c },
{ "request uncompressed", sizeof(struct pfsync_upd_req),
pfsync_print_upd_req },
- { "delete", sizeof(struct pfsync_state), pfsync_print_state },
+ { "delete", sizeof(struct pfsync_state_1301), pfsync_print_state_1301 },
{ "delete compressed", sizeof(struct pfsync_del_c),
pfsync_print_del_c },
{ "frag insert", 0, NULL },
@@ -126,6 +129,8 @@
pfsync_print_bus },
{ "tdb", 0, pfsync_print_tdb },
{ "eof", 0, NULL },
+ { "insert", sizeof(struct pfsync_state_1400), pfsync_print_state_1400 },
+ { "update", sizeof(struct pfsync_state_1400), pfsync_print_state_1400 },
};
static void
@@ -212,12 +217,21 @@
}
static void
-pfsync_print_state(netdissect_options *ndo, const void *bp)
+pfsync_print_state_1301(netdissect_options *ndo, const void *bp)
{
- struct pfsync_state *st = (struct pfsync_state *)bp;
+ struct pfsync_state_1301 *st = (struct pfsync_state_1301 *)bp;
safeputchar(ndo, '\n');
- print_state(ndo, st);
+ print_state(ndo, (union pfsync_state_union *)st, PFSYNC_MSG_VERSION_1301);
+}
+
+static void
+pfsync_print_state_1400(netdissect_options *ndo, const void *bp)
+{
+ struct pfsync_state_1301 *st = (struct pfsync_state_1301 *)bp;
+
+ safeputchar(ndo, '\n');
+ print_state(ndo, (union pfsync_state_union *)st, PFSYNC_MSG_VERSION_1400);
}
static void
@@ -374,56 +388,56 @@
}
static void
-print_state(netdissect_options *ndo, struct pfsync_state *s)
+print_state(netdissect_options *ndo, union pfsync_state_union *s, int version)
{
struct pfsync_state_peer *src, *dst;
struct pfsync_state_key *sk, *nk;
int min, sec;
- if (s->direction == PF_OUT) {
- src = &s->src;
- dst = &s->dst;
- sk = &s->key[PF_SK_STACK];
- nk = &s->key[PF_SK_WIRE];
- if (s->proto == IPPROTO_ICMP || s->proto == IPPROTO_ICMPV6)
+ if (s->pfs_1301.direction == PF_OUT) {
+ src = &s->pfs_1301.src;
+ dst = &s->pfs_1301.dst;
+ sk = &s->pfs_1301.key[PF_SK_STACK];
+ nk = &s->pfs_1301.key[PF_SK_WIRE];
+ if (s->pfs_1301.proto == IPPROTO_ICMP || s->pfs_1301.proto == IPPROTO_ICMPV6)
sk->port[0] = nk->port[0];
} else {
- src = &s->dst;
- dst = &s->src;
- sk = &s->key[PF_SK_WIRE];
- nk = &s->key[PF_SK_STACK];
- if (s->proto == IPPROTO_ICMP || s->proto == IPPROTO_ICMPV6)
+ src = &s->pfs_1301.dst;
+ dst = &s->pfs_1301.src;
+ sk = &s->pfs_1301.key[PF_SK_WIRE];
+ nk = &s->pfs_1301.key[PF_SK_STACK];
+ if (s->pfs_1301.proto == IPPROTO_ICMP || s->pfs_1301.proto == IPPROTO_ICMPV6)
sk->port[1] = nk->port[1];
}
- ND_PRINT((ndo, "\t%s ", s->ifname));
- ND_PRINT((ndo, "proto %u ", s->proto));
+ ND_PRINT((ndo, "\t%s ", s->pfs_1301.ifname));
+ ND_PRINT((ndo, "proto %u ", s->pfs_1301.proto));
- print_host(ndo, &nk->addr[1], nk->port[1], s->af, NULL);
- if (PF_ANEQ(&nk->addr[1], &sk->addr[1], s->af) ||
+ print_host(ndo, &nk->addr[1], nk->port[1], s->pfs_1301.af, NULL);
+ if (PF_ANEQ(&nk->addr[1], &sk->addr[1], s->pfs_1301.af) ||
nk->port[1] != sk->port[1]) {
ND_PRINT((ndo, " ("));
- print_host(ndo, &sk->addr[1], sk->port[1], s->af, NULL);
+ print_host(ndo, &sk->addr[1], sk->port[1], s->pfs_1301.af, NULL);
ND_PRINT((ndo, ")"));
}
- if (s->direction == PF_OUT)
+ if (s->pfs_1301.direction == PF_OUT)
ND_PRINT((ndo, " -> "));
else
ND_PRINT((ndo, " <- "));
- print_host(ndo, &nk->addr[0], nk->port[0], s->af, NULL);
- if (PF_ANEQ(&nk->addr[0], &sk->addr[0], s->af) ||
+ print_host(ndo, &nk->addr[0], nk->port[0], s->pfs_1301.af, NULL);
+ if (PF_ANEQ(&nk->addr[0], &sk->addr[0], s->pfs_1301.af) ||
nk->port[0] != sk->port[0]) {
ND_PRINT((ndo, " ("));
- print_host(ndo, &sk->addr[0], sk->port[0], s->af, NULL);
+ print_host(ndo, &sk->addr[0], sk->port[0], s->pfs_1301.af, NULL);
ND_PRINT((ndo, ")"));
}
- print_src_dst(ndo, src, dst, s->proto);
+ print_src_dst(ndo, src, dst, s->pfs_1301.proto);
if (ndo->ndo_vflag > 1) {
uint64_t packets[2];
uint64_t bytes[2];
- uint32_t creation = ntohl(s->creation);
- uint32_t expire = ntohl(s->expire);
+ uint32_t creation = ntohl(s->pfs_1301.creation);
+ uint32_t expire = ntohl(s->pfs_1301.expire);
sec = creation % 60;
creation /= 60;
@@ -436,23 +450,23 @@
expire /= 60;
ND_PRINT((ndo, ", expires in %.2u:%.2u:%.2u", expire, min, sec));
- bcopy(s->packets[0], &packets[0], sizeof(uint64_t));
- bcopy(s->packets[1], &packets[1], sizeof(uint64_t));
- bcopy(s->bytes[0], &bytes[0], sizeof(uint64_t));
- bcopy(s->bytes[1], &bytes[1], sizeof(uint64_t));
+ bcopy(s->pfs_1301.packets[0], &packets[0], sizeof(uint64_t));
+ bcopy(s->pfs_1301.packets[1], &packets[1], sizeof(uint64_t));
+ bcopy(s->pfs_1301.bytes[0], &bytes[0], sizeof(uint64_t));
+ bcopy(s->pfs_1301.bytes[1], &bytes[1], sizeof(uint64_t));
ND_PRINT((ndo, ", %ju:%ju pkts, %ju:%ju bytes",
be64toh(packets[0]), be64toh(packets[1]),
be64toh(bytes[0]), be64toh(bytes[1])));
- if (s->anchor != ntohl(-1))
- ND_PRINT((ndo, ", anchor %u", ntohl(s->anchor)));
- if (s->rule != ntohl(-1))
- ND_PRINT((ndo, ", rule %u", ntohl(s->rule)));
+ if (s->pfs_1301.anchor != ntohl(-1))
+ ND_PRINT((ndo, ", anchor %u", ntohl(s->pfs_1301.anchor)));
+ if (s->pfs_1301.rule != ntohl(-1))
+ ND_PRINT((ndo, ", rule %u", ntohl(s->pfs_1301.rule)));
}
if (ndo->ndo_vflag > 1) {
uint64_t id;
- bcopy(&s->id, &id, sizeof(uint64_t));
+ bcopy(&s->pfs_1301.id, &id, sizeof(uint64_t));
ND_PRINT((ndo, "\n\tid: %016jx creatorid: %08x",
- (uintmax_t )be64toh(id), ntohl(s->creatorid)));
+ (uintmax_t )be64toh(id), ntohl(s->pfs_1301.creatorid)));
}
}
diff --git a/sbin/ifconfig/ifpfsync.c b/sbin/ifconfig/ifpfsync.c
--- a/sbin/ifconfig/ifpfsync.c
+++ b/sbin/ifconfig/ifpfsync.c
@@ -309,6 +309,27 @@
nvlist_destroy(nvl);
}
+static void
+setpfsync_version(if_ctx *ctx, const char *val, int dummy __unused)
+{
+ int version;
+ nvlist_t *nvl = nvlist_create(0);
+
+ /* Don't verify, kernel knows which versions are supported.*/
+ version = atoi(val);
+
+ if (pfsync_do_ioctl(ctx->io_s, SIOCGETPFSYNCNV, &nvl) == -1)
+ err(1, "SIOCGETPFSYNCNV");
+
+ nvlist_free_number(nvl, "version");
+ nvlist_add_number(nvl, "version", version);
+
+ if (pfsync_do_ioctl(ctx->io_s, SIOCSETPFSYNCNV, &nvl) == -1)
+ err(1, "SIOCSETPFSYNCNV");
+
+ nvlist_destroy(nvl);
+}
+
static void
pfsync_status(if_ctx *ctx)
{
@@ -318,6 +339,7 @@
struct sockaddr_storage syncpeer;
int maxupdates = 0;
int flags = 0;
+ int version;
int error;
nvl = nvlist_create(0);
@@ -333,6 +355,8 @@
IFNAMSIZ);
if (nvlist_exists_number(nvl, "maxupdates"))
maxupdates = nvlist_get_number(nvl, "maxupdates");
+ if (nvlist_exists_number(nvl, "version"))
+ version = nvlist_get_number(nvl, "version");
if (nvlist_exists_number(nvl, "flags"))
flags = nvlist_get_number(nvl, "flags");
if (nvlist_exists_nvlist(nvl, "syncpeer")) {
@@ -363,7 +387,8 @@
}
printf("maxupd: %d ", maxupdates);
- printf("defer: %s\n", (flags & PFSYNCF_DEFER) ? "on" : "off");
+ printf("defer: %s ", (flags & PFSYNCF_DEFER) ? "on" : "off");
+ printf("version: %d\n", version);
printf("\tsyncok: %d\n", (flags & PFSYNCF_OK) ? 1 : 0);
}
@@ -377,6 +402,7 @@
DEF_CMD_ARG("maxupd", setpfsync_maxupd),
DEF_CMD("defer", 1, setpfsync_defer),
DEF_CMD("-defer", 0, setpfsync_defer),
+ DEF_CMD_ARG("version", setpfsync_version),
};
static struct afswtch af_pfsync = {
.af_name = "af_pfsync",
diff --git a/sys/net/if_pfsync.h b/sys/net/if_pfsync.h
--- a/sys/net/if_pfsync.h
+++ b/sys/net/if_pfsync.h
@@ -59,10 +59,18 @@
#define PFSYNC_VERSION 5
#define PFSYNC_DFLTTL 255
+enum pfsync_msg_versions {
+ PFSYNC_MSG_VERSION_UNSPECIFIED = 0,
+ PFSYNC_MSG_VERSION_1301 = 1301,
+ PFSYNC_MSG_VERSION_1400 = 1400,
+};
+
+#define PFSYNC_MSG_VERSION_DEFAULT PFSYNC_MSG_VERSION_1400
+
#define PFSYNC_ACT_CLR 0 /* clear all states */
-#define PFSYNC_ACT_INS 1 /* insert state */
+#define PFSYNC_ACT_INS_1301 1 /* insert state */
#define PFSYNC_ACT_INS_ACK 2 /* ack of inserted state */
-#define PFSYNC_ACT_UPD 3 /* update state */
+#define PFSYNC_ACT_UPD_1301 3 /* update state */
#define PFSYNC_ACT_UPD_C 4 /* "compressed" update state */
#define PFSYNC_ACT_UPD_REQ 5 /* request "uncompressed" state */
#define PFSYNC_ACT_DEL 6 /* delete state */
@@ -72,7 +80,9 @@
#define PFSYNC_ACT_BUS 10 /* bulk update status */
#define PFSYNC_ACT_TDB 11 /* TDB replay counter update */
#define PFSYNC_ACT_EOF 12 /* end of frame */
-#define PFSYNC_ACT_MAX 13
+#define PFSYNC_ACT_INS_1400 13 /* insert state */
+#define PFSYNC_ACT_UPD_1400 14 /* update state */
+#define PFSYNC_ACT_MAX 15
/*
* A pfsync frame is built from a header followed by several sections which
@@ -251,6 +261,7 @@
char syncdev[IFNAMSIZ];
struct sockaddr_storage syncpeer;
int maxupdates;
+ int version;
int flags;
};
@@ -269,13 +280,13 @@
/*
* this shows where a pf state is with respect to the syncing.
+ * pf_kstate->sync_state
*/
#define PFSYNC_S_INS 0x00
#define PFSYNC_S_IACK 0x01
#define PFSYNC_S_UPD 0x02
#define PFSYNC_S_UPD_C 0x03
#define PFSYNC_S_DEL_C 0x04
-#define PFSYNC_S_COUNT 0x05
#define PFSYNC_S_DEFER 0xfe
#define PFSYNC_S_NONE 0xff
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -641,6 +641,7 @@
uint16_t dnpipe;
uint16_t dnrpipe; /* Reverse direction pipe */
uint32_t flags;
+ uint8_t set_prio[2];
};
union pf_keth_rule_ptr {
@@ -1057,12 +1058,14 @@
u_int8_t min_ttl;
u_int8_t set_tos;
u_int16_t max_mss;
+ u_int8_t rt;
+ u_int8_t set_prio[2];
};
/*
- * Size <= fits 12 objects per page on LP64. Try to not grow the struct beyond that.
+ * Size <= fits 11 objects per page on LP64. Try to not grow the struct beyond that.
*/
-_Static_assert(sizeof(struct pf_kstate) <= 336, "pf_kstate size crosses 336 bytes");
+_Static_assert(sizeof(struct pf_kstate) <= 368, "pf_kstate size crosses 368 bytes");
#endif
/*
@@ -1094,7 +1097,34 @@
u_int16_t port[2];
};
-struct pfsync_state {
+struct pfsync_state_1301 {
+ u_int64_t id;
+ char ifname[IFNAMSIZ];
+ struct pfsync_state_key key[2];
+ struct pfsync_state_peer src;
+ struct pfsync_state_peer dst;
+ struct pf_addr rt_addr;
+ u_int32_t rule;
+ u_int32_t anchor;
+ u_int32_t nat_rule;
+ u_int32_t creation;
+ u_int32_t expire;
+ u_int32_t packets[2][2];
+ u_int32_t bytes[2][2];
+ u_int32_t creatorid;
+ sa_family_t af;
+ u_int8_t proto;
+ u_int8_t direction;
+ u_int8_t __spare[2];
+ u_int8_t log;
+ u_int8_t state_flags;
+ u_int8_t timeout;
+ u_int8_t sync_flags;
+ u_int8_t updates;
+} __packed;
+
+struct pfsync_state_1400 {
+ /* The beginning of the struct is compatible with previous versions */
u_int64_t id;
char ifname[IFNAMSIZ];
struct pfsync_state_key key[2];
@@ -1114,15 +1144,33 @@
u_int8_t direction;
u_int16_t state_flags;
u_int8_t log;
- u_int8_t state_flags_compat;
+ u_int8_t __spare;
u_int8_t timeout;
u_int8_t sync_flags;
u_int8_t updates;
+ /* The rest is not */
+ u_int16_t qid;
+ u_int16_t pqid;
+ u_int16_t dnpipe;
+ u_int16_t dnrpipe;
+ int32_t rtableid;
+ u_int8_t min_ttl;
+ u_int8_t set_tos;
+ u_int16_t max_mss;
+ u_int8_t set_prio[2];
+ u_int8_t rt;
+ char rt_ifname[IFNAMSIZ];
+
+} __packed;
+
+union pfsync_state_union {
+ struct pfsync_state_1301 pfs_1301;
+ struct pfsync_state_1400 pfs_1400;
} __packed;
#ifdef _KERNEL
/* pfsync */
-typedef int pfsync_state_import_t(struct pfsync_state *, int);
+typedef int pfsync_state_import_t(union pfsync_state_union *, int, int);
typedef void pfsync_insert_state_t(struct pf_kstate *);
typedef void pfsync_update_state_t(struct pf_kstate *);
typedef void pfsync_delete_state_t(struct pf_kstate *);
@@ -1144,8 +1192,8 @@
#define V_pfsync_defer_ptr VNET(pfsync_defer_ptr)
extern pfsync_detach_ifnet_t *pfsync_detach_ifnet_ptr;
-void pfsync_state_export(struct pfsync_state *,
- struct pf_kstate *);
+void pfsync_state_export(union pfsync_state_union *,
+ struct pf_kstate *, int);
void pf_state_export(struct pf_state_export *,
struct pf_kstate *);
@@ -1665,7 +1713,7 @@
};
struct pfioc_state {
- struct pfsync_state state;
+ struct pfsync_state_1301 state;
};
struct pfioc_src_node_kill {
@@ -1704,8 +1752,8 @@
struct pfioc_states {
int ps_len;
union {
- void *ps_buf;
- struct pfsync_state *ps_states;
+ void *ps_buf;
+ struct pfsync_state_1301 *ps_states;
};
};
diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c
--- a/sys/netpfil/pf/if_pfsync.c
+++ b/sys/netpfil/pf/if_pfsync.c
@@ -122,23 +122,23 @@
static int pfsync_upd_tcp(struct pf_kstate *, struct pfsync_state_peer *,
struct pfsync_state_peer *);
-static int pfsync_in_clr(struct mbuf *, int, int, int);
-static int pfsync_in_ins(struct mbuf *, int, int, int);
-static int pfsync_in_iack(struct mbuf *, int, int, int);
-static int pfsync_in_upd(struct mbuf *, int, int, int);
-static int pfsync_in_upd_c(struct mbuf *, int, int, int);
-static int pfsync_in_ureq(struct mbuf *, int, int, int);
-static int pfsync_in_del_c(struct mbuf *, int, int, int);
-static int pfsync_in_bus(struct mbuf *, int, int, int);
-static int pfsync_in_tdb(struct mbuf *, int, int, int);
-static int pfsync_in_eof(struct mbuf *, int, int, int);
-static int pfsync_in_error(struct mbuf *, int, int, int);
-
-static int (*pfsync_acts[])(struct mbuf *, int, int, int) = {
+static int pfsync_in_clr(struct mbuf *, int, int, int, int);
+static int pfsync_in_ins(struct mbuf *, int, int, int, int);
+static int pfsync_in_iack(struct mbuf *, int, int, int, int);
+static int pfsync_in_upd(struct mbuf *, int, int, int, int);
+static int pfsync_in_upd_c(struct mbuf *, int, int, int, int);
+static int pfsync_in_ureq(struct mbuf *, int, int, int, int);
+static int pfsync_in_del_c(struct mbuf *, int, int, int, int);
+static int pfsync_in_bus(struct mbuf *, int, int, int, int);
+static int pfsync_in_tdb(struct mbuf *, int, int, int, int);
+static int pfsync_in_eof(struct mbuf *, int, int, int, int);
+static int pfsync_in_error(struct mbuf *, int, int, int, int);
+
+static int (*pfsync_acts[])(struct mbuf *, int, int, int, int) = {
pfsync_in_clr, /* PFSYNC_ACT_CLR */
- pfsync_in_ins, /* PFSYNC_ACT_INS */
+ pfsync_in_ins, /* PFSYNC_ACT_INS_1301 */
pfsync_in_iack, /* PFSYNC_ACT_INS_ACK */
- pfsync_in_upd, /* PFSYNC_ACT_UPD */
+ pfsync_in_upd, /* PFSYNC_ACT_UPD_1301 */
pfsync_in_upd_c, /* PFSYNC_ACT_UPD_C */
pfsync_in_ureq, /* PFSYNC_ACT_UPD_REQ */
pfsync_in_error, /* PFSYNC_ACT_DEL */
@@ -147,7 +147,9 @@
pfsync_in_error, /* PFSYNC_ACT_DEL_F */
pfsync_in_bus, /* PFSYNC_ACT_BUS */
pfsync_in_tdb, /* PFSYNC_ACT_TDB */
- pfsync_in_eof /* PFSYNC_ACT_EOF */
+ pfsync_in_eof, /* PFSYNC_ACT_EOF */
+ pfsync_in_ins, /* PFSYNC_ACT_INS_1400 */
+ pfsync_in_upd, /* PFSYNC_ACT_UPD_1400 */
};
struct pfsync_q {
@@ -156,21 +158,51 @@
u_int8_t action;
};
-/* we have one of these for every PFSYNC_S_ */
-static void pfsync_out_state(struct pf_kstate *, void *);
+/* We have the following sync queues */
+enum pfsync_q_id {
+ PFSYNC_Q_INS_1301,
+ PFSYNC_Q_INS_1400,
+ PFSYNC_Q_IACK,
+ PFSYNC_Q_UPD_1301,
+ PFSYNC_Q_UPD_1400,
+ PFSYNC_Q_UPD_C,
+ PFSYNC_Q_DEL_C,
+ PFSYNC_Q_COUNT,
+};
+
+/* Functions for building messages for given queue */
+static void pfsync_out_state_1301(struct pf_kstate *, void *);
+static void pfsync_out_state_1400(struct pf_kstate *, void *);
static void pfsync_out_iack(struct pf_kstate *, void *);
static void pfsync_out_upd_c(struct pf_kstate *, void *);
static void pfsync_out_del_c(struct pf_kstate *, void *);
+/* Attach those functions to queue */
static struct pfsync_q pfsync_qs[] = {
- { pfsync_out_state, sizeof(struct pfsync_state), PFSYNC_ACT_INS },
- { pfsync_out_iack, sizeof(struct pfsync_ins_ack), PFSYNC_ACT_INS_ACK },
- { pfsync_out_state, sizeof(struct pfsync_state), PFSYNC_ACT_UPD },
- { pfsync_out_upd_c, sizeof(struct pfsync_upd_c), PFSYNC_ACT_UPD_C },
- { pfsync_out_del_c, sizeof(struct pfsync_del_c), PFSYNC_ACT_DEL_C }
+ { pfsync_out_state_1301, sizeof(struct pfsync_state_1301), PFSYNC_ACT_INS_1301 },
+ { pfsync_out_state_1400, sizeof(struct pfsync_state_1400), PFSYNC_ACT_INS_1400 },
+ { pfsync_out_iack, sizeof(struct pfsync_ins_ack), PFSYNC_ACT_INS_ACK },
+ { pfsync_out_state_1301, sizeof(struct pfsync_state_1301), PFSYNC_ACT_UPD_1301 },
+ { pfsync_out_state_1400, sizeof(struct pfsync_state_1400), PFSYNC_ACT_UPD_1400 },
+ { pfsync_out_upd_c, sizeof(struct pfsync_upd_c), PFSYNC_ACT_UPD_C },
+ { pfsync_out_del_c, sizeof(struct pfsync_del_c), PFSYNC_ACT_DEL_C }
+};
+
+/* Map queue to pf_kstate->sync_state */
+static u_int8_t pfsync_qid_sstate[] = {
+ PFSYNC_S_INS, /* PFSYNC_Q_INS_1301 */
+ PFSYNC_S_INS, /* PFSYNC_Q_INS_1400 */
+ PFSYNC_S_IACK, /* PFSYNC_Q_IACK */
+ PFSYNC_S_UPD, /* PFSYNC_Q_UPD_1301 */
+ PFSYNC_S_UPD, /* PFSYNC_Q_UPD_1400 */
+ PFSYNC_S_UPD_C, /* PFSYNC_Q_UPD_C */
+ PFSYNC_S_DEL_C, /* PFSYNC_Q_DEL_C */
};
-static void pfsync_q_ins(struct pf_kstate *, int, bool);
+/* Map pf_kstate->sync_state to queue */
+static enum pfsync_q_id pfsync_sstate_to_qid(u_int8_t);
+
+static void pfsync_q_ins(struct pf_kstate *, int sync_state, bool);
static void pfsync_q_del(struct pf_kstate *, bool, struct pfsync_bucket *);
static void pfsync_update_state(struct pf_kstate *);
@@ -200,7 +232,7 @@
#define PFSYNCF_BUCKET_PUSH 0x00000001
size_t b_len;
- TAILQ_HEAD(, pf_kstate) b_qs[PFSYNC_S_COUNT];
+ TAILQ_HEAD(, pf_kstate) b_qs[PFSYNC_Q_COUNT];
TAILQ_HEAD(, pfsync_upd_req_item) b_upd_req_list;
TAILQ_HEAD(, pfsync_deferral) b_deferrals;
u_int b_deferred;
@@ -220,6 +252,7 @@
uint8_t sc_maxupdates;
union inet_template sc_template;
struct mtx sc_mtx;
+ uint32_t sc_version;
/* Queued data */
struct pfsync_bucket *sc_buckets;
@@ -336,7 +369,8 @@
struct pfsync_softc *sc;
struct ifnet *ifp;
struct pfsync_bucket *b;
- int c, q;
+ int c;
+ enum pfsync_q_id q;
if (unit != 0)
return (EINVAL);
@@ -347,6 +381,7 @@
sc = malloc(sizeof(struct pfsync_softc), M_PFSYNC, M_WAITOK | M_ZERO);
sc->sc_flags |= PFSYNCF_OK;
sc->sc_maxupdates = 128;
+ sc->sc_version = PFSYNC_MSG_VERSION_DEFAULT;
ifp = sc->sc_ifp = if_alloc(IFT_PFSYNC);
if (ifp == NULL) {
@@ -379,7 +414,7 @@
b->b_sc = sc;
b->b_len = PFSYNC_MINPKT;
- for (q = 0; q < PFSYNC_S_COUNT; q++)
+ for (q = 0; q < PFSYNC_Q_COUNT; q++)
TAILQ_INIT(&b->b_qs[q]);
TAILQ_INIT(&b->b_upd_req_list);
@@ -465,7 +500,7 @@
}
static int
-pfsync_state_import(struct pfsync_state *sp, int flags)
+pfsync_state_import(union pfsync_state_union *sp, int flags, int msg_version)
{
struct pfsync_softc *sc = V_pfsyncif;
#ifndef __NO_STRICT_ALIGNMENT
@@ -480,17 +515,17 @@
PF_RULES_RASSERT();
- if (sp->creatorid == 0) {
+ if (sp->pfs_1301.creatorid == 0) {
if (V_pf_status.debug >= PF_DEBUG_MISC)
printf("%s: invalid creator id: %08x\n", __func__,
- ntohl(sp->creatorid));
+ ntohl(sp->pfs_1301.creatorid));
return (EINVAL);
}
- if ((kif = pfi_kkif_find(sp->ifname)) == NULL) {
+ if ((kif = pfi_kkif_find(sp->pfs_1301.ifname)) == NULL) {
if (V_pf_status.debug >= PF_DEBUG_MISC)
printf("%s: unknown interface: %s\n", __func__,
- sp->ifname);
+ sp->pfs_1301.ifname);
if (flags & PFSYNC_SI_IOCTL)
return (EINVAL);
return (0); /* skip this state */
@@ -500,11 +535,11 @@
* If the ruleset checksums match or the state is coming from the ioctl,
* it's safe to associate the state with the rule of that number.
*/
- if (sp->rule != htonl(-1) && sp->anchor == htonl(-1) &&
- (flags & (PFSYNC_SI_IOCTL | PFSYNC_SI_CKSUM)) && ntohl(sp->rule) <
+ if (sp->pfs_1301.rule != htonl(-1) && sp->pfs_1301.anchor == htonl(-1) &&
+ (flags & (PFSYNC_SI_IOCTL | PFSYNC_SI_CKSUM)) && ntohl(sp->pfs_1301.rule) <
pf_main_ruleset.rules[PF_RULESET_FILTER].active.rcount)
r = pf_main_ruleset.rules[
- PF_RULESET_FILTER].active.ptr_array[ntohl(sp->rule)];
+ PF_RULESET_FILTER].active.ptr_array[ntohl(sp->pfs_1301.rule)];
else
r = &V_pf_default_rule;
@@ -523,16 +558,16 @@
goto cleanup;
#ifndef __NO_STRICT_ALIGNMENT
- bcopy(&sp->key, key, sizeof(struct pfsync_state_key) * 2);
+ bcopy(&sp->pfs_1301.key, key, sizeof(struct pfsync_state_key) * 2);
kw = &key[PF_SK_WIRE];
ks = &key[PF_SK_STACK];
#else
- kw = &sp->key[PF_SK_WIRE];
- ks = &sp->key[PF_SK_STACK];
+ kw = &sp->pfs_1301.key[PF_SK_WIRE];
+ ks = &sp->pfs_1301.key[PF_SK_STACK];
#endif
- if (PF_ANEQ(&kw->addr[0], &ks->addr[0], sp->af) ||
- PF_ANEQ(&kw->addr[1], &ks->addr[1], sp->af) ||
+ if (PF_ANEQ(&kw->addr[0], &ks->addr[0], sp->pfs_1301.af) ||
+ PF_ANEQ(&kw->addr[1], &ks->addr[1], sp->pfs_1301.af) ||
kw->port[0] != ks->port[0] ||
kw->port[1] != ks->port[1]) {
sks = uma_zalloc(V_pf_state_key_z, M_NOWAIT);
@@ -542,8 +577,8 @@
sks = skw;
/* allocate memory for scrub info */
- if (pfsync_alloc_scrub_memory(&sp->src, &st->src) ||
- pfsync_alloc_scrub_memory(&sp->dst, &st->dst))
+ if (pfsync_alloc_scrub_memory(&sp->pfs_1301.src, &st->src) ||
+ pfsync_alloc_scrub_memory(&sp->pfs_1301.dst, &st->dst))
goto cleanup;
/* Copy to state key(s). */
@@ -551,69 +586,110 @@
skw->addr[1] = kw->addr[1];
skw->port[0] = kw->port[0];
skw->port[1] = kw->port[1];
- skw->proto = sp->proto;
- skw->af = sp->af;
+ skw->proto = sp->pfs_1301.proto;
+ skw->af = sp->pfs_1301.af;
if (sks != skw) {
sks->addr[0] = ks->addr[0];
sks->addr[1] = ks->addr[1];
sks->port[0] = ks->port[0];
sks->port[1] = ks->port[1];
- sks->proto = sp->proto;
- sks->af = sp->af;
+ sks->proto = sp->pfs_1301.proto;
+ sks->af = sp->pfs_1301.af;
}
/* copy to state */
- bcopy(&sp->rt_addr, &st->rt_addr, sizeof(st->rt_addr));
- st->creation = time_uptime - ntohl(sp->creation);
+ bcopy(&sp->pfs_1301.rt_addr, &st->rt_addr, sizeof(st->rt_addr));
+ st->creation = time_uptime - ntohl(sp->pfs_1301.creation);
st->expire = time_uptime;
- if (sp->expire) {
+ if (sp->pfs_1301.expire) {
uint32_t timeout;
- timeout = r->timeout[sp->timeout];
+ timeout = r->timeout[sp->pfs_1301.timeout];
if (!timeout)
- timeout = V_pf_default_rule.timeout[sp->timeout];
+ timeout = V_pf_default_rule.timeout[sp->pfs_1301.timeout];
/* sp->expire may have been adaptively scaled by export. */
- st->expire -= timeout - ntohl(sp->expire);
+ st->expire -= timeout - ntohl(sp->pfs_1301.expire);
}
- st->direction = sp->direction;
- st->log = sp->log;
- st->timeout = sp->timeout;
- /* 8 from old peers, 16 bits from new peers */
- st->state_flags = sp->state_flags_compat | ntohs(sp->state_flags);
+ st->direction = sp->pfs_1301.direction;
+ st->log = sp->pfs_1301.log;
+ st->timeout = sp->pfs_1301.timeout;
- if (r == &V_pf_default_rule) {
- /* ToS and Prio are not sent over struct pfsync_state */
- st->state_flags &= ~PFSTATE_SETMASK;
- } else {
- /* Most actions are applied form state, not from rule. Until
- * pfsync can forward all those actions and their parameters we
- * must relay on restoring them from the found rule.
- * It's a copy of pf_rule_to_actions() */
- st->qid = r->qid;
- st->pqid = r->pqid;
- st->rtableid = r->rtableid;
- if (r->scrub_flags & PFSTATE_SETTOS)
- st->set_tos = r->set_tos;
- st->min_ttl = r->min_ttl;
- st->max_mss = r->max_mss;
- st->state_flags |= (r->scrub_flags & (PFSTATE_NODF|PFSTATE_RANDOMID|
- PFSTATE_SETTOS|PFSTATE_SCRUB_TCP|PFSTATE_SETPRIO));
- st->dnpipe = r->dnpipe;
- st->dnrpipe = r->dnrpipe;
- /* FIXME: dnflags are not part of state, can't update them */
- }
-
- st->id = sp->id;
- st->creatorid = sp->creatorid;
- pf_state_peer_ntoh(&sp->src, &st->src);
- pf_state_peer_ntoh(&sp->dst, &st->dst);
+ switch (msg_version) {
+ case PFSYNC_MSG_VERSION_1301:
+ st->state_flags = sp->pfs_1301.state_flags;
+ /*
+ * In FreeBSD 13 pfsync lacks many attributes. Copy them
+ * from the rule if possible. If rule can't be matched
+ * clear any set options as we can't recover their
+ * parameters.
+ */
+ if (r == &V_pf_default_rule) {
+ st->state_flags &= ~PFSTATE_SETMASK;
+ } else {
+ /*
+ * Similar to pf_rule_to_actions(). This code
+ * won't set the actions properly if they come
+ * from multiple "match" rules as only rule
+ * creating the state is send over pfsync.
+ */
+ st->qid = r->qid;
+ st->pqid = r->pqid;
+ st->rtableid = r->rtableid;
+ if (r->scrub_flags & PFSTATE_SETTOS)
+ st->set_tos = r->set_tos;
+ st->min_ttl = r->min_ttl;
+ st->max_mss = r->max_mss;
+ st->state_flags |= (r->scrub_flags &
+ (PFSTATE_NODF|PFSTATE_RANDOMID|
+ PFSTATE_SETTOS|PFSTATE_SCRUB_TCP|
+ PFSTATE_SETPRIO));
+ if (r->dnpipe || r->dnrpipe) {
+ if (r->free_flags & PFRULE_DN_IS_PIPE)
+ st->state_flags |= PFSTATE_DN_IS_PIPE;
+ else
+ st->state_flags &= ~PFSTATE_DN_IS_PIPE;
+ }
+ st->dnpipe = r->dnpipe;
+ st->dnrpipe = r->dnrpipe;
+ }
+ break;
+ case PFSYNC_MSG_VERSION_1400:
+ st->state_flags = ntohs(sp->pfs_1400.state_flags);
+ st->qid = ntohs(sp->pfs_1400.qid);
+ st->pqid = ntohs(sp->pfs_1400.pqid);
+ st->dnpipe = ntohs(sp->pfs_1400.dnpipe);
+ st->dnrpipe = ntohs(sp->pfs_1400.dnrpipe);
+ st->rtableid = ntohl(sp->pfs_1400.rtableid);
+ st->min_ttl = sp->pfs_1400.min_ttl;
+ st->set_tos = sp->pfs_1400.set_tos;
+ st->max_mss = ntohs(sp->pfs_1400.max_mss);
+ st->set_prio[0] = sp->pfs_1400.set_prio[0];
+ st->set_prio[1] = sp->pfs_1400.set_prio[1];
+ st->rt = sp->pfs_1400.rt;
+ if (st->rt && (st->rt_kif = pfi_kkif_find(sp->pfs_1400.rt_ifname)) == NULL) {
+ if (V_pf_status.debug >= PF_DEBUG_MISC)
+ printf("%s: unknown route interface: %s\n",
+ __func__, sp->pfs_1400.rt_ifname);
+ if (flags & PFSYNC_SI_IOCTL)
+ return (EINVAL);
+ return (0); /* skip this state */
+ }
+ break;
+ default:
+ panic("%s: Unsupported pfsync_msg_version %d",
+ __func__, msg_version);
+ }
+
+ st->id = sp->pfs_1301.id;
+ st->creatorid = sp->pfs_1301.creatorid;
+ pf_state_peer_ntoh(&sp->pfs_1301.src, &st->src);
+ pf_state_peer_ntoh(&sp->pfs_1301.dst, &st->dst);
st->rule.ptr = r;
st->nat_rule.ptr = NULL;
st->anchor.ptr = NULL;
- st->rt_kif = NULL;
st->pfsync_time = time_uptime;
st->sync_state = PFSYNC_S_NONE;
@@ -745,7 +821,7 @@
count = ntohs(subh.count);
V_pfsyncstats.pfsyncs_iacts[subh.action] += count;
- rv = (*pfsync_acts[subh.action])(m, offset, count, flags);
+ rv = (*pfsync_acts[subh.action])(m, offset, count, flags, subh.action);
if (rv == -1) {
PF_RULES_RUNLOCK();
return (IPPROTO_DONE);
@@ -762,7 +838,7 @@
#endif
static int
-pfsync_in_clr(struct mbuf *m, int offset, int count, int flags)
+pfsync_in_clr(struct mbuf *m, int offset, int count, int flags, int action)
{
struct pfsync_clr *clr;
struct mbuf *mp;
@@ -804,36 +880,50 @@
}
static int
-pfsync_in_ins(struct mbuf *m, int offset, int count, int flags)
+pfsync_in_ins(struct mbuf *m, int offset, int count, int flags, int action)
{
struct mbuf *mp;
- struct pfsync_state *sa, *sp;
- int len = sizeof(*sp) * count;
- int i, offp;
+ union pfsync_state_union *sa, *sp;
+ int i, offp, len, msg_version;
+
+ switch (action) {
+ case PFSYNC_ACT_INS_1301:
+ len = sizeof(struct pfsync_state_1301) * count;
+ msg_version = PFSYNC_MSG_VERSION_1301;
+ break;
+ case PFSYNC_ACT_INS_1400:
+ len = sizeof(struct pfsync_state_1400) * count;
+ msg_version = PFSYNC_MSG_VERSION_1400;
+ break;
+ default:
+ V_pfsyncstats.pfsyncs_badact++;
+ return (-1);
+ }
mp = m_pulldown(m, offset, len, &offp);
if (mp == NULL) {
V_pfsyncstats.pfsyncs_badlen++;
return (-1);
}
- sa = (struct pfsync_state *)(mp->m_data + offp);
+ sa = (union pfsync_state_union *)(mp->m_data + offp);
for (i = 0; i < count; i++) {
sp = &sa[i];
/* Check for invalid values. */
- if (sp->timeout >= PFTM_MAX ||
- sp->src.state > PF_TCPS_PROXY_DST ||
- sp->dst.state > PF_TCPS_PROXY_DST ||
- sp->direction > PF_OUT ||
- (sp->af != AF_INET && sp->af != AF_INET6)) {
+ if (sp->pfs_1301.timeout >= PFTM_MAX ||
+ sp->pfs_1301.src.state > PF_TCPS_PROXY_DST ||
+ sp->pfs_1301.dst.state > PF_TCPS_PROXY_DST ||
+ sp->pfs_1301.direction > PF_OUT ||
+ (sp->pfs_1301.af != AF_INET &&
+ sp->pfs_1301.af != AF_INET6)) {
if (V_pf_status.debug >= PF_DEBUG_MISC)
printf("%s: invalid value\n", __func__);
V_pfsyncstats.pfsyncs_badval++;
continue;
}
- if (pfsync_state_import(sp, flags) == ENOMEM)
+ if (pfsync_state_import(sp, flags, msg_version) == ENOMEM)
/* Drop out, but process the rest of the actions. */
break;
}
@@ -842,7 +932,7 @@
}
static int
-pfsync_in_iack(struct mbuf *m, int offset, int count, int flags)
+pfsync_in_iack(struct mbuf *m, int offset, int count, int flags, int action)
{
struct pfsync_ins_ack *ia, *iaa;
struct pf_kstate *st;
@@ -913,31 +1003,42 @@
}
static int
-pfsync_in_upd(struct mbuf *m, int offset, int count, int flags)
+pfsync_in_upd(struct mbuf *m, int offset, int count, int flags, int action)
{
struct pfsync_softc *sc = V_pfsyncif;
- struct pfsync_state *sa, *sp;
+ union pfsync_state_union *sa, *sp;
struct pf_kstate *st;
- int sync;
-
struct mbuf *mp;
- int len = count * sizeof(*sp);
- int offp, i;
+ int sync, offp, i, len, msg_version;
+
+ switch (action) {
+ case PFSYNC_ACT_UPD_1301:
+ len = sizeof(struct pfsync_state_1301) * count;
+ msg_version = PFSYNC_MSG_VERSION_1301;
+ break;
+ case PFSYNC_ACT_UPD_1400:
+ len = sizeof(struct pfsync_state_1400) * count;
+ msg_version = PFSYNC_MSG_VERSION_1400;
+ break;
+ default:
+ V_pfsyncstats.pfsyncs_badact++;
+ return (-1);
+ }
mp = m_pulldown(m, offset, len, &offp);
if (mp == NULL) {
V_pfsyncstats.pfsyncs_badlen++;
return (-1);
}
- sa = (struct pfsync_state *)(mp->m_data + offp);
+ sa = (union pfsync_state_union *)(mp->m_data + offp);
for (i = 0; i < count; i++) {
sp = &sa[i];
/* check for invalid values */
- if (sp->timeout >= PFTM_MAX ||
- sp->src.state > PF_TCPS_PROXY_DST ||
- sp->dst.state > PF_TCPS_PROXY_DST) {
+ if (sp->pfs_1301.timeout >= PFTM_MAX ||
+ sp->pfs_1301.src.state > PF_TCPS_PROXY_DST ||
+ sp->pfs_1301.dst.state > PF_TCPS_PROXY_DST) {
if (V_pf_status.debug >= PF_DEBUG_MISC) {
printf("pfsync_input: PFSYNC_ACT_UPD: "
"invalid value\n");
@@ -946,10 +1047,10 @@
continue;
}
- st = pf_find_state_byid(sp->id, sp->creatorid);
+ st = pf_find_state_byid(sp->pfs_1301.id, sp->pfs_1301.creatorid);
if (st == NULL) {
/* insert the update */
- if (pfsync_state_import(sp, flags))
+ if (pfsync_state_import(sp, flags, msg_version))
V_pfsyncstats.pfsyncs_badstate++;
continue;
}
@@ -959,7 +1060,7 @@
}
if (st->key[PF_SK_WIRE]->proto == IPPROTO_TCP)
- sync = pfsync_upd_tcp(st, &sp->src, &sp->dst);
+ sync = pfsync_upd_tcp(st, &sp->pfs_1301.src, &sp->pfs_1301.dst);
else {
sync = 0;
@@ -967,20 +1068,20 @@
* Non-TCP protocol state machine always go
* forwards
*/
- if (st->src.state > sp->src.state)
+ if (st->src.state > sp->pfs_1301.src.state)
sync++;
else
- pf_state_peer_ntoh(&sp->src, &st->src);
- if (st->dst.state > sp->dst.state)
+ pf_state_peer_ntoh(&sp->pfs_1301.src, &st->src);
+ if (st->dst.state > sp->pfs_1301.dst.state)
sync++;
else
- pf_state_peer_ntoh(&sp->dst, &st->dst);
+ pf_state_peer_ntoh(&sp->pfs_1301.dst, &st->dst);
}
if (sync < 2) {
- pfsync_alloc_scrub_memory(&sp->dst, &st->dst);
- pf_state_peer_ntoh(&sp->dst, &st->dst);
+ pfsync_alloc_scrub_memory(&sp->pfs_1301.dst, &st->dst);
+ pf_state_peer_ntoh(&sp->pfs_1301.dst, &st->dst);
st->expire = time_uptime;
- st->timeout = sp->timeout;
+ st->timeout = sp->pfs_1301.timeout;
}
st->pfsync_time = time_uptime;
@@ -999,7 +1100,7 @@
}
static int
-pfsync_in_upd_c(struct mbuf *m, int offset, int count, int flags)
+pfsync_in_upd_c(struct mbuf *m, int offset, int count, int flags, int action)
{
struct pfsync_softc *sc = V_pfsyncif;
struct pfsync_upd_c *ua, *up;
@@ -1086,7 +1187,7 @@
}
static int
-pfsync_in_ureq(struct mbuf *m, int offset, int count, int flags)
+pfsync_in_ureq(struct mbuf *m, int offset, int count, int flags, int action)
{
struct pfsync_upd_req *ur, *ura;
struct mbuf *mp;
@@ -1127,7 +1228,7 @@
}
static int
-pfsync_in_del_c(struct mbuf *m, int offset, int count, int flags)
+pfsync_in_del_c(struct mbuf *m, int offset, int count, int flags, int action)
{
struct mbuf *mp;
struct pfsync_del_c *sa, *sp;
@@ -1159,7 +1260,7 @@
}
static int
-pfsync_in_bus(struct mbuf *m, int offset, int count, int flags)
+pfsync_in_bus(struct mbuf *m, int offset, int count, int flags, int action)
{
struct pfsync_softc *sc = V_pfsyncif;
struct pfsync_bus *bus;
@@ -1188,7 +1289,7 @@
callout_reset(&sc->sc_bulkfail_tmo, 4 * hz +
V_pf_limits[PF_LIMIT_STATES].limit /
((sc->sc_ifp->if_mtu - PFSYNC_MINPKT) /
- sizeof(struct pfsync_state)),
+ sizeof(union pfsync_state_union)),
pfsync_bulk_fail, sc);
if (V_pf_status.debug >= PF_DEBUG_MISC)
printf("pfsync: received bulk update start\n");
@@ -1221,7 +1322,7 @@
}
static int
-pfsync_in_tdb(struct mbuf *m, int offset, int count, int flags)
+pfsync_in_tdb(struct mbuf *m, int offset, int count, int flags, int action)
{
int len = count * sizeof(struct pfsync_tdb);
@@ -1286,7 +1387,7 @@
#endif
static int
-pfsync_in_eof(struct mbuf *m, int offset, int count, int flags)
+pfsync_in_eof(struct mbuf *m, int offset, int count, int flags, int action)
{
/* check if we are at the right place in the packet */
if (offset != m->m_pkthdr.len)
@@ -1298,7 +1399,7 @@
}
static int
-pfsync_in_error(struct mbuf *m, int offset, int count, int flags)
+pfsync_in_error(struct mbuf *m, int offset, int count, int flags, int action)
{
V_pfsyncstats.pfsyncs_badact++;
@@ -1379,6 +1480,7 @@
nvlist_add_string(nvl, "syncdev", sc->sc_sync_if->if_xname);
nvlist_add_number(nvl, "maxupdates", sc->sc_maxupdates);
nvlist_add_number(nvl, "flags", sc->sc_flags);
+ nvlist_add_number(nvl, "version", sc->sc_version);
if ((nvl_syncpeer = pfsync_sockaddr_to_syncpeer_nvlist(&sc->sc_sync_peer)) != NULL)
nvlist_add_nvlist(nvl, "syncpeer", nvl_syncpeer);
@@ -1464,11 +1566,19 @@
}
static void
-pfsync_out_state(struct pf_kstate *st, void *buf)
+pfsync_out_state_1301(struct pf_kstate *st, void *buf)
+{
+ union pfsync_state_union *sp = buf;
+
+ pfsync_state_export(sp, st, PFSYNC_MSG_VERSION_1301);
+}
+
+static void
+pfsync_out_state_1400(struct pf_kstate *st, void *buf)
{
- struct pfsync_state *sp = buf;
+ union pfsync_state_union *sp = buf;
- pfsync_state_export(sp, st);
+ pfsync_state_export(sp, st, PFSYNC_MSG_VERSION_1400);
}
static void
@@ -1509,16 +1619,17 @@
struct pf_kstate *st, *next;
struct pfsync_upd_req_item *ur;
struct pfsync_bucket *b;
- int c, q;
+ int c;
+ enum pfsync_q_id q;
for (c = 0; c < pfsync_buckets; c++) {
b = &sc->sc_buckets[c];
- for (q = 0; q < PFSYNC_S_COUNT; q++) {
+ for (q = 0; q < PFSYNC_Q_COUNT; q++) {
if (TAILQ_EMPTY(&b->b_qs[q]))
continue;
TAILQ_FOREACH_SAFE(st, &b->b_qs[q], sync_list, next) {
- KASSERT(st->sync_state == q,
+ KASSERT(st->sync_state == pfsync_qid_sstate[q],
("%s: st->sync_state == q",
__func__));
st->sync_state = PFSYNC_S_NONE;
@@ -1548,8 +1659,8 @@
struct pf_kstate *st, *st_next;
struct pfsync_upd_req_item *ur;
struct pfsync_bucket *b = &sc->sc_buckets[c];
- int aflen, offset;
- int q, count = 0;
+ int aflen, offset, count = 0;
+ enum pfsync_q_id q;
KASSERT(sc != NULL, ("%s: null sc", __func__));
KASSERT(b->b_len > PFSYNC_MINPKT,
@@ -1591,7 +1702,6 @@
return;
}
-
/* build the pfsync header */
ph = (struct pfsync_header *)(m->m_data + offset);
bzero(ph, sizeof(*ph));
@@ -1602,7 +1712,7 @@
bcopy(V_pf_status.pf_chksum, ph->pfcksum, PF_MD5_DIGEST_LENGTH);
/* walk the queues */
- for (q = 0; q < PFSYNC_S_COUNT; q++) {
+ for (q = 0; q < PFSYNC_Q_COUNT; q++) {
if (TAILQ_EMPTY(&b->b_qs[q]))
continue;
@@ -1611,7 +1721,7 @@
count = 0;
TAILQ_FOREACH_SAFE(st, &b->b_qs[q], sync_list, st_next) {
- KASSERT(st->sync_state == q,
+ KASSERT(st->sync_state == pfsync_qid_sstate[q],
("%s: st->sync_state == q",
__func__));
/*
@@ -2015,7 +2125,7 @@
panic("%s: unexpected sync state %d", __func__, st->sync_state);
}
- if ((sc->sc_ifp->if_mtu - b->b_len) < sizeof(struct pfsync_state))
+ if ((sc->sc_ifp->if_mtu - b->b_len) < sizeof(union pfsync_state_union))
full = true;
PFSYNC_BUCKET_UNLOCK(b);
@@ -2087,9 +2197,47 @@
pfsync_send_plus(&r, sizeof(r));
}
+static enum pfsync_q_id
+pfsync_sstate_to_qid(u_int8_t sync_state)
+{
+ struct pfsync_softc *sc = V_pfsyncif;
+
+ switch (sync_state) {
+ case PFSYNC_S_INS:
+ switch (sc->sc_version) {
+ case PFSYNC_MSG_VERSION_1301:
+ return PFSYNC_Q_INS_1301;
+ case PFSYNC_MSG_VERSION_1400:
+ return PFSYNC_Q_INS_1400;
+ }
+ break;
+ case PFSYNC_S_IACK:
+ return PFSYNC_Q_IACK;
+ case PFSYNC_S_UPD:
+ switch (sc->sc_version) {
+ case PFSYNC_MSG_VERSION_1301:
+ return PFSYNC_Q_UPD_1301;
+ case PFSYNC_MSG_VERSION_1400:
+ return PFSYNC_Q_UPD_1400;
+ }
+ break;
+ case PFSYNC_S_UPD_C:
+ return PFSYNC_Q_UPD_C;
+ case PFSYNC_S_DEL_C:
+ return PFSYNC_Q_DEL_C;
+ default:
+ panic("%s: Unsupported st->sync_state 0x%02x",
+ __func__, sync_state);
+ }
+
+ panic("%s: Unsupported pfsync_msg_version %d",
+ __func__, sc->sc_version);
+}
+
static void
-pfsync_q_ins(struct pf_kstate *st, int q, bool ref)
+pfsync_q_ins(struct pf_kstate *st, int sync_state, bool ref)
{
+ enum pfsync_q_id q = pfsync_sstate_to_qid(sync_state);
struct pfsync_softc *sc = V_pfsyncif;
size_t nlen = pfsync_qs[q].len;
struct pfsync_bucket *b = pfsync_get_bucket(sc, st);
@@ -2112,7 +2260,7 @@
b->b_len += nlen;
TAILQ_INSERT_TAIL(&b->b_qs[q], st, sync_list);
- st->sync_state = q;
+ st->sync_state = pfsync_qid_sstate[q];
if (ref)
pf_ref_state(st);
}
@@ -2120,12 +2268,13 @@
static void
pfsync_q_del(struct pf_kstate *st, bool unref, struct pfsync_bucket *b)
{
- int q = st->sync_state;
+ enum pfsync_q_id q;
PFSYNC_BUCKET_LOCK_ASSERT(b);
KASSERT(st->sync_state != PFSYNC_S_NONE,
("%s: st->sync_state != PFSYNC_S_NONE", __func__));
+ q = pfsync_sstate_to_qid(st->sync_state);
b->b_len -= pfsync_qs[q].len;
TAILQ_REMOVE(&b->b_qs[q], st, sync_list);
st->sync_state = PFSYNC_S_NONE;
@@ -2522,6 +2671,20 @@
imf = ip_mfilter_alloc(M_WAITOK, 0, 0);
PFSYNC_LOCK(sc);
+
+ switch (status->version) {
+ case PFSYNC_MSG_VERSION_UNSPECIFIED:
+ sc->sc_version = PFSYNC_MSG_VERSION_DEFAULT;
+ break;
+ case PFSYNC_MSG_VERSION_1301:
+ case PFSYNC_MSG_VERSION_1400:
+ sc->sc_version = status->version;
+ break;
+ default:
+ PFSYNC_UNLOCK(sc);
+ return (EINVAL);
+ }
+
struct sockaddr_in *sc_sin = (struct sockaddr_in *)&sc->sc_sync_peer;
sc_sin->sin_family = AF_INET;
sc_sin->sin_len = sizeof(*sc_sin);
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -3592,6 +3592,8 @@
void
pf_rule_to_actions(struct pf_krule *r, struct pf_rule_actions *a)
{
+ a->flags |= (r->scrub_flags & (PFSTATE_NODF|PFSTATE_RANDOMID|
+ PFSTATE_SETTOS|PFSTATE_SCRUB_TCP|PFSTATE_SETPRIO));
if (r->qid)
a->qid = r->qid;
if (r->pqid)
@@ -3599,14 +3601,12 @@
if (r->rtableid >= 0)
a->rtableid = r->rtableid;
a->log |= r->log;
- if (r->scrub_flags & PFSTATE_SETTOS)
+ if (a->flags & PFSTATE_SETTOS)
a->set_tos = r->set_tos;
if (r->min_ttl)
a->min_ttl = r->min_ttl;
if (r->max_mss)
a->max_mss = r->max_mss;
- a->flags |= (r->scrub_flags & (PFSTATE_NODF|PFSTATE_RANDOMID|
- PFSTATE_SETTOS|PFSTATE_SCRUB_TCP|PFSTATE_SETPRIO));
if (r->dnpipe)
a->dnpipe = r->dnpipe;
if (r->dnrpipe)
@@ -3617,6 +3617,10 @@
else
a->flags &= ~PFSTATE_DN_IS_PIPE;
}
+ if (a->flags & PFSTATE_SETPRIO) {
+ a->set_prio[0] = r->set_prio[0];
+ a->set_prio[1] = r->set_prio[1];
+ }
}
int
@@ -4638,6 +4642,8 @@
s->pqid = pd->act.pqid;
s->dnpipe = pd->act.dnpipe;
s->dnrpipe = pd->act.dnrpipe;
+ s->set_prio[0] = pd->act.set_prio[0];
+ s->set_prio[1] = pd->act.set_prio[1];
s->state_flags |= pd->act.flags;
if (nr != NULL)
s->log |= nr->log & PF_LOG_ALL;
@@ -4706,6 +4712,7 @@
goto csfailed;
}
s->rt_kif = r->rpool.cur->kif;
+ s->rt = r->rt;
}
s->creation = time_uptime;
@@ -6441,9 +6448,20 @@
struct pf_ksrc_node *sn = NULL;
int error = 0;
uint16_t ip_len, ip_off;
+ int r_rt, r_dir;
KASSERT(m && *m && r && oifp, ("%s: invalid parameters", __func__));
- KASSERT(dir == PF_IN || dir == PF_OUT, ("%s: invalid direction",
+
+ if (s) {
+ r_rt = s->rt;
+ r_dir = s->direction;
+ } else {
+ r_rt = r->rt;
+ r_dir = r->direction;
+ }
+
+ KASSERT(dir == PF_IN || dir == PF_OUT ||
+ r_dir == PF_IN || r_dir == PF_OUT, ("%s: invalid direction",
__func__));
if ((pd->pf_mtag == NULL &&
@@ -6454,7 +6472,7 @@
goto bad_locked;
}
- if (r->rt == PF_DUPTO) {
+ if (r_rt == PF_DUPTO) {
if ((pd->pf_mtag->flags & PF_DUPLICATED)) {
if (s == NULL) {
ifp = r->rpool.cur->kif ?
@@ -6484,7 +6502,7 @@
}
}
} else {
- if ((r->rt == PF_REPLYTO) == (r->direction == dir)) {
+ if ((r_rt == PF_REPLYTO) == (r_dir == dir)) {
pf_dummynet(pd, dir, s, r, m);
if (s)
PF_STATE_UNLOCK(s);
@@ -6583,7 +6601,7 @@
if ((ip_off & IP_DF) || (m0->m_pkthdr.csum_flags & CSUM_TSO)) {
error = EMSGSIZE;
KMOD_IPSTAT_INC(ips_cantfrag);
- if (r->rt != PF_DUPTO) {
+ if (r_rt != PF_DUPTO) {
if (s && pd->nat_rule != NULL)
PACKET_UNDO_NAT(m0, pd,
(ip->ip_hl << 2) + (ip_off & IP_OFFMASK),
@@ -6619,7 +6637,7 @@
KMOD_IPSTAT_INC(ips_fragmented);
done:
- if (r->rt != PF_DUPTO)
+ if (r_rt != PF_DUPTO)
*m = NULL;
return;
@@ -6643,9 +6661,20 @@
struct ifnet *ifp = NULL;
struct pf_addr naddr;
struct pf_ksrc_node *sn = NULL;
+ int r_rt, r_dir;
KASSERT(m && *m && r && oifp, ("%s: invalid parameters", __func__));
- KASSERT(dir == PF_IN || dir == PF_OUT, ("%s: invalid direction",
+
+ if (s) {
+ r_rt = s->rt;
+ r_dir = s->direction;
+ } else {
+ r_rt = r->rt;
+ r_dir = r->direction;
+ }
+
+ KASSERT(dir == PF_IN || dir == PF_OUT ||
+ r_dir == PF_IN || r_dir == PF_OUT, ("%s: invalid direction",
__func__));
if ((pd->pf_mtag == NULL &&
@@ -6656,7 +6685,7 @@
goto bad_locked;
}
- if (r->rt == PF_DUPTO) {
+ if (r_rt == PF_DUPTO) {
if ((pd->pf_mtag->flags & PF_DUPLICATED)) {
if (s == NULL) {
ifp = r->rpool.cur->kif ?
@@ -6686,7 +6715,7 @@
}
}
} else {
- if ((r->rt == PF_REPLYTO) == (r->direction == dir)) {
+ if ((r_rt == PF_REPLYTO) == (r_dir == dir)) {
pf_dummynet(pd, dir, s, r, m);
if (s)
PF_STATE_UNLOCK(s);
@@ -6770,7 +6799,7 @@
}
else {
in6_ifstat_inc(ifp, ifs6_in_toobig);
- if (r->rt != PF_DUPTO) {
+ if (r_rt != PF_DUPTO) {
if (s && pd->nat_rule != NULL)
PACKET_UNDO_NAT(m0, pd,
((caddr_t)ip6 - m0->m_data) +
@@ -6782,7 +6811,7 @@
}
done:
- if (r->rt != PF_DUPTO)
+ if (r_rt != PF_DUPTO)
*m = NULL;
return;
@@ -7102,7 +7131,18 @@
struct pf_kstate *s = NULL;
struct pf_kruleset *ruleset = NULL;
struct pf_pdesc pd;
- int off, dirndx, pqid = 0;
+ int off, dirndx;
+ uint16_t scrub_flags;
+#ifdef ALTQ
+ uint16_t qid;
+#endif
+ uint16_t pqid;
+ uint16_t tag;
+ int32_t rtableid;
+ uint8_t min_ttl;
+ uint8_t set_tos;
+ uint8_t rt;
+ uint8_t set_prio[2];
PF_RULES_RLOCK_TRACKER;
KASSERT(dir == PF_IN || dir == PF_OUT, ("%s: bad direction %d\n", __func__, dir));
@@ -7394,36 +7434,47 @@
}
if (s) {
- pf_scrub_ip(&m, s->state_flags, s->min_ttl, s->set_tos);
- if (s->rtableid >= 0)
- M_SETFIB(m, s->rtableid);
+ scrub_flags = s->state_flags;
+ min_ttl = s->min_ttl;
+ set_tos = s->set_tos;
+ rtableid = s->rtableid;
+ pqid = s->pqid;
#ifdef ALTQ
- if (s->qid) {
- pd.act.pqid = s->pqid;
- pd.act.qid = s->qid;
- }
+ qid = s->qid;
#endif
+ tag = s->tag;
+ rt = s->rt;
+ set_prio[0] = s->set_prio[0];
+ set_prio[1] = s->set_prio[1];
} else {
- pf_scrub_ip(&m, r->scrub_flags, r->min_ttl, r->set_tos);
- if (r->rtableid >= 0)
- M_SETFIB(m, r->rtableid);
+ scrub_flags = r->scrub_flags;
+ min_ttl = r->min_ttl;
+ set_tos = r->set_tos;
+ rtableid = r->rtableid;
+ pqid = r->pqid;
#ifdef ALTQ
- if (r->qid) {
- pd.act.pqid = r->pqid;
- pd.act.qid = r->qid;
- }
+ qid = r->qid;
#endif
+ tag = r->tag;
+ rt = r->rt;
+ set_prio[0] = r->set_prio[0];
+ set_prio[1] = r->set_prio[1];
}
- if (s && s->tag > 0 && pf_tag_packet(m, &pd, s->tag)) {
+ if (tag > 0 && pf_tag_packet(m, &pd, tag)) {
action = PF_DROP;
REASON_SET(&reason, PFRES_MEMORY);
}
- if (r->scrub_flags & PFSTATE_SETPRIO) {
+ pf_scrub_ip(&m, scrub_flags, min_ttl, set_tos);
+
+ if (rtableid >= 0)
+ M_SETFIB(m, rtableid);
+
+ if (scrub_flags & PFSTATE_SETPRIO) {
if (pd.tos & IPTOS_LOWDELAY)
pqid = 1;
- if (vlan_set_pcp(m, r->set_prio[pqid])) {
+ if (vlan_set_pcp(m, set_prio[pqid])) {
action = PF_DROP;
REASON_SET(&reason, PFRES_MEMORY);
log = PF_LOG_FORCE;
@@ -7433,6 +7484,11 @@
}
#ifdef ALTQ
+ if (qid) {
+ pd.act.pqid = pqid;
+ pd.act.qid = qid;
+ }
+
if (action == PF_PASS && pd.act.qid) {
if (pd.pf_mtag == NULL &&
((pd.pf_mtag = pf_get_mtag(m)) == NULL)) {
@@ -7604,7 +7660,7 @@
break;
default:
/* pf_route() returns unlocked. */
- if (r->rt) {
+ if (rt) {
pf_route(m0, r, dir, kif->pfik_ifp, s, &pd, inp);
return (action);
}
@@ -7637,7 +7693,18 @@
struct pf_kstate *s = NULL;
struct pf_kruleset *ruleset = NULL;
struct pf_pdesc pd;
- int off, terminal = 0, dirndx, rh_cnt = 0, pqid = 0;
+ int off, terminal = 0, dirndx, rh_cnt = 0;
+ uint16_t scrub_flags;
+#ifdef ALTQ
+ uint16_t qid;
+#endif
+ uint16_t pqid;
+ uint16_t tag;
+ int32_t rtableid;
+ uint8_t min_ttl;
+ uint8_t set_tos;
+ uint8_t rt;
+ uint8_t set_prio[2];
PF_RULES_RLOCK_TRACKER;
KASSERT(dir == PF_IN || dir == PF_OUT, ("%s: bad direction %d\n", __func__, dir));
@@ -7925,37 +7992,48 @@
("pf: dropping packet with dangerous v6 headers\n"));
}
- if (s && s->tag > 0 && pf_tag_packet(m, &pd, s->tag)) {
- action = PF_DROP;
- REASON_SET(&reason, PFRES_MEMORY);
- }
-
if (s) {
- pf_scrub_ip6(&m, s->state_flags, s->min_ttl, s->set_tos);
- if (s->rtableid >= 0)
- M_SETFIB(m, s->rtableid);
+ scrub_flags = s->state_flags;
+ min_ttl = s->min_ttl;
+ set_tos = s->set_tos;
+ rtableid = s->rtableid;
+ pqid = s->pqid;
#ifdef ALTQ
- if (s->qid) {
- pd.act.pqid = s->pqid;
- pd.act.qid = s->qid;
- }
+ qid = s->qid;
#endif
+ tag = s->tag;
+ rt = s->rt;
+ set_prio[0] = s->set_prio[0];
+ set_prio[1] = s->set_prio[1];
} else {
- pf_scrub_ip6(&m, r->scrub_flags, r->min_ttl, r->set_tos);
- if (r->rtableid >= 0)
- M_SETFIB(m, r->rtableid);
+ scrub_flags = r->scrub_flags;
+ min_ttl = r->min_ttl;
+ set_tos = r->set_tos;
+ rtableid = r->rtableid;
+ pqid = r->pqid;
#ifdef ALTQ
- if (r->qid) {
- pd.act.pqid = r->pqid;
- pd.act.qid = r->qid;
- }
+ qid = r->qid;
#endif
+ tag = r->tag;
+ rt = r->rt;
+ set_prio[0] = r->set_prio[0];
+ set_prio[1] = r->set_prio[1];
}
- if (r->scrub_flags & PFSTATE_SETPRIO) {
+ if (tag > 0 && pf_tag_packet(m, &pd, tag)) {
+ action = PF_DROP;
+ REASON_SET(&reason, PFRES_MEMORY);
+ }
+
+ pf_scrub_ip6(&m, scrub_flags, min_ttl, set_tos);
+
+ if (rtableid >= 0)
+ M_SETFIB(m, rtableid);
+
+ if (scrub_flags & PFSTATE_SETPRIO) {
if (pd.tos & IPTOS_LOWDELAY)
pqid = 1;
- if (vlan_set_pcp(m, r->set_prio[pqid])) {
+ if (vlan_set_pcp(m, set_prio[pqid])) {
action = PF_DROP;
REASON_SET(&reason, PFRES_MEMORY);
log = PF_LOG_FORCE;
@@ -7965,6 +8043,11 @@
}
#ifdef ALTQ
+ if (qid) {
+ pd.act.pqid = pqid;
+ pd.act.qid = qid;
+ }
+
if (action == PF_PASS && pd.act.qid) {
if (pd.pf_mtag == NULL &&
((pd.pf_mtag = pf_get_mtag(m)) == NULL)) {
@@ -8084,7 +8167,7 @@
break;
default:
/* pf_route6() returns unlocked. */
- if (r->rt) {
+ if (rt) {
pf_route6(m0, r, dir, kif->pfik_ifp, s, &pd, inp);
return (action);
}
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
@@ -3720,8 +3720,8 @@
}
case DIOCADDSTATE: {
- struct pfioc_state *ps = (struct pfioc_state *)addr;
- struct pfsync_state *sp = &ps->state;
+ struct pfioc_state *ps = (struct pfioc_state *)addr;
+ struct pfsync_state_1301 *sp = &ps->state;
if (sp->timeout >= PFTM_MAX) {
error = EINVAL;
@@ -3729,7 +3729,9 @@
}
if (V_pfsync_state_import_ptr != NULL) {
PF_RULES_RLOCK();
- error = V_pfsync_state_import_ptr(sp, PFSYNC_SI_IOCTL);
+ error = V_pfsync_state_import_ptr(
+ (union pfsync_state_union *)sp, PFSYNC_SI_IOCTL,
+ PFSYNC_MSG_VERSION_1301);
PF_RULES_RUNLOCK();
} else
error = EOPNOTSUPP;
@@ -3746,7 +3748,8 @@
break;
}
- pfsync_state_export(&ps->state, s);
+ pfsync_state_export((union pfsync_state_union*)&ps->state,
+ s, PFSYNC_MSG_VERSION_1301);
PF_STATE_UNLOCK(s);
break;
}
@@ -3759,20 +3762,20 @@
case DIOCGETSTATES: {
struct pfioc_states *ps = (struct pfioc_states *)addr;
struct pf_kstate *s;
- struct pfsync_state *pstore, *p;
+ struct pfsync_state_1301 *pstore, *p;
int i, nr;
size_t slice_count = 16, count;
void *out;
if (ps->ps_len <= 0) {
nr = uma_zone_get_cur(V_pf_state_z);
- ps->ps_len = sizeof(struct pfsync_state) * nr;
+ ps->ps_len = sizeof(struct pfsync_state_1301) * nr;
break;
}
out = ps->ps_states;
pstore = mallocarray(slice_count,
- sizeof(struct pfsync_state), M_TEMP, M_WAITOK | M_ZERO);
+ sizeof(struct pfsync_state_1301), M_TEMP, M_WAITOK | M_ZERO);
nr = 0;
for (i = 0; i <= pf_hashmask; i++) {
@@ -3797,7 +3800,7 @@
free(pstore, M_TEMP);
slice_count = count * 2;
pstore = mallocarray(slice_count,
- sizeof(struct pfsync_state), M_TEMP,
+ sizeof(struct pfsync_state_1301), M_TEMP,
M_WAITOK | M_ZERO);
goto DIOCGETSTATES_retry;
}
@@ -3811,19 +3814,20 @@
if (s->timeout == PFTM_UNLINKED)
continue;
- pfsync_state_export(p, s);
+ pfsync_state_export((union pfsync_state_union*)p,
+ s, PFSYNC_MSG_VERSION_1301);
p++;
nr++;
}
PF_HASHROW_UNLOCK(ih);
error = copyout(pstore, out,
- sizeof(struct pfsync_state) * count);
+ sizeof(struct pfsync_state_1301) * count);
if (error)
break;
out = ps->ps_states + nr;
}
DIOCGETSTATES_full:
- ps->ps_len = sizeof(struct pfsync_state) * nr;
+ ps->ps_len = sizeof(struct pfsync_state_1301) * nr;
free(pstore, M_TEMP);
break;
@@ -5663,64 +5667,90 @@
}
void
-pfsync_state_export(struct pfsync_state *sp, struct pf_kstate *st)
+pfsync_state_export(union pfsync_state_union *sp, struct pf_kstate *st, int msg_version)
{
- bzero(sp, sizeof(struct pfsync_state));
+ bzero(sp, sizeof(union pfsync_state_union));
/* copy from state key */
- sp->key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0];
- sp->key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1];
- sp->key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0];
- sp->key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1];
- sp->key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0];
- sp->key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1];
- sp->key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0];
- sp->key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1];
- sp->proto = st->key[PF_SK_WIRE]->proto;
- sp->af = st->key[PF_SK_WIRE]->af;
+ sp->pfs_1301.key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0];
+ sp->pfs_1301.key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1];
+ sp->pfs_1301.key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0];
+ sp->pfs_1301.key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1];
+ sp->pfs_1301.key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0];
+ sp->pfs_1301.key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1];
+ sp->pfs_1301.key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0];
+ sp->pfs_1301.key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1];
+ sp->pfs_1301.proto = st->key[PF_SK_WIRE]->proto;
+ sp->pfs_1301.af = st->key[PF_SK_WIRE]->af;
/* copy from state */
- strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname));
- bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr));
- sp->creation = htonl(time_uptime - st->creation);
- sp->expire = pf_state_expires(st);
- if (sp->expire <= time_uptime)
- sp->expire = htonl(0);
+ strlcpy(sp->pfs_1301.ifname, st->kif->pfik_name, sizeof(sp->pfs_1301.ifname));
+ bcopy(&st->rt_addr, &sp->pfs_1301.rt_addr, sizeof(sp->pfs_1301.rt_addr));
+ sp->pfs_1301.creation = htonl(time_uptime - st->creation);
+ sp->pfs_1301.expire = pf_state_expires(st);
+ if (sp->pfs_1301.expire <= time_uptime)
+ sp->pfs_1301.expire = htonl(0);
else
- sp->expire = htonl(sp->expire - time_uptime);
+ sp->pfs_1301.expire = htonl(sp->pfs_1301.expire - time_uptime);
+
+ sp->pfs_1301.direction = st->direction;
+ sp->pfs_1301.log = st->log;
+ sp->pfs_1301.timeout = st->timeout;
+
+ switch (msg_version) {
+ case PFSYNC_MSG_VERSION_1301:
+ sp->pfs_1301.state_flags = st->state_flags;
+ break;
+ case PFSYNC_MSG_VERSION_1400:
+ sp->pfs_1400.state_flags = htons(st->state_flags);
+ sp->pfs_1400.qid = htons(st->qid);
+ sp->pfs_1400.pqid = htons(st->pqid);
+ sp->pfs_1400.dnpipe = htons(st->dnpipe);
+ sp->pfs_1400.dnrpipe = htons(st->dnrpipe);
+ sp->pfs_1400.rtableid = htonl(st->rtableid);
+ sp->pfs_1400.min_ttl = st->min_ttl;
+ sp->pfs_1400.set_tos = st->set_tos;
+ sp->pfs_1400.max_mss = htons(st->max_mss);
+ sp->pfs_1400.set_prio[0] = st->set_prio[0];
+ sp->pfs_1400.set_prio[1] = st->set_prio[1];
+ sp->pfs_1400.rt = st->rt;
+ if (st->rt_kif)
+ strlcpy(sp->pfs_1400.rt_ifname,
+ st->rt_kif->pfik_name,
+ sizeof(sp->pfs_1400.rt_ifname));
+ break;
+ default:
+ panic("%s: Unsupported pfsync_msg_version %d",
+ __func__, msg_version);
+ }
- sp->direction = st->direction;
- sp->log = st->log;
- sp->timeout = st->timeout;
- sp->state_flags_compat = st->state_flags;
- sp->state_flags = htons(st->state_flags);
if (st->src_node)
- sp->sync_flags |= PFSYNC_FLAG_SRCNODE;
+ sp->pfs_1301.sync_flags |= PFSYNC_FLAG_SRCNODE;
if (st->nat_src_node)
- sp->sync_flags |= PFSYNC_FLAG_NATSRCNODE;
+ sp->pfs_1301.sync_flags |= PFSYNC_FLAG_NATSRCNODE;
- sp->id = st->id;
- sp->creatorid = st->creatorid;
- pf_state_peer_hton(&st->src, &sp->src);
- pf_state_peer_hton(&st->dst, &sp->dst);
+ sp->pfs_1301.id = st->id;
+ sp->pfs_1301.creatorid = st->creatorid;
+ pf_state_peer_hton(&st->src, &sp->pfs_1301.src);
+ pf_state_peer_hton(&st->dst, &sp->pfs_1301.dst);
if (st->rule.ptr == NULL)
- sp->rule = htonl(-1);
+ sp->pfs_1301.rule = htonl(-1);
else
- sp->rule = htonl(st->rule.ptr->nr);
+ sp->pfs_1301.rule = htonl(st->rule.ptr->nr);
if (st->anchor.ptr == NULL)
- sp->anchor = htonl(-1);
+ sp->pfs_1301.anchor = htonl(-1);
else
- sp->anchor = htonl(st->anchor.ptr->nr);
+ sp->pfs_1301.anchor = htonl(st->anchor.ptr->nr);
if (st->nat_rule.ptr == NULL)
- sp->nat_rule = htonl(-1);
+ sp->pfs_1301.nat_rule = htonl(-1);
else
- sp->nat_rule = htonl(st->nat_rule.ptr->nr);
+ sp->pfs_1301.nat_rule = htonl(st->nat_rule.ptr->nr);
- pf_state_counter_hton(st->packets[0], sp->packets[0]);
- pf_state_counter_hton(st->packets[1], sp->packets[1]);
- pf_state_counter_hton(st->bytes[0], sp->bytes[0]);
- pf_state_counter_hton(st->bytes[1], sp->bytes[1]);
+ pf_state_counter_hton(st->packets[0], sp->pfs_1301.packets[0]);
+ pf_state_counter_hton(st->packets[1], sp->pfs_1301.packets[1]);
+ pf_state_counter_hton(st->bytes[0], sp->pfs_1301.bytes[0]);
+ pf_state_counter_hton(st->bytes[1], sp->pfs_1301.bytes[1]);
}
void
diff --git a/sys/netpfil/pf/pfsync_nv.c b/sys/netpfil/pf/pfsync_nv.c
--- a/sys/netpfil/pf/pfsync_nv.c
+++ b/sys/netpfil/pf/pfsync_nv.c
@@ -130,6 +130,7 @@
return (EINVAL);
status->maxupdates = nvlist_get_number(nvl, "maxupdates");
+ status->version = nvlist_get_number(nvl, "version");
status->flags = nvlist_get_number(nvl, "flags");
if (nvlist_exists_string(nvl, "syncdev"))
diff --git a/usr.bin/netstat/if.c b/usr.bin/netstat/if.c
--- a/usr.bin/netstat/if.c
+++ b/usr.bin/netstat/if.c
@@ -81,9 +81,9 @@
#ifdef PF
static const char* pfsyncacts[] = {
/* PFSYNC_ACT_CLR */ "clear all request",
- /* PFSYNC_ACT_INS */ "state insert",
+ /* PFSYNC_ACT_INS_1301 */ "13.1 state insert",
/* PFSYNC_ACT_INS_ACK */ "state inserted ack",
- /* PFSYNC_ACT_UPD */ "state update",
+ /* PFSYNC_ACT_UPD_1301 */ "13.1 state update",
/* PFSYNC_ACT_UPD_C */ "compressed state update",
/* PFSYNC_ACT_UPD_REQ */ "uncompressed state request",
/* PFSYNC_ACT_DEL */ "state delete",
@@ -93,13 +93,15 @@
/* PFSYNC_ACT_BUS */ "bulk update mark",
/* PFSYNC_ACT_TDB */ "TDB replay counter update",
/* PFSYNC_ACT_EOF */ "end of frame mark",
+ /* PFSYNC_ACT_INS_1400 */ "state insert",
+ /* PFSYNC_ACT_UPD_1400 */ "state update",
};
static const char* pfsyncacts_name[] = {
/* PFSYNC_ACT_CLR */ "clear-all-request",
- /* PFSYNC_ACT_INS */ "state-insert",
+ /* PFSYNC_ACT_INS_1301 */ "state-insert-1301",
/* PFSYNC_ACT_INS_ACK */ "state-inserted-ack",
- /* PFSYNC_ACT_UPD */ "state-update",
+ /* PFSYNC_ACT_UPD_1301 */ "state-update-1301",
/* PFSYNC_ACT_UPD_C */ "compressed-state-update",
/* PFSYNC_ACT_UPD_REQ */ "uncompressed-state-request",
/* PFSYNC_ACT_DEL */ "state-delete",
@@ -109,6 +111,8 @@
/* PFSYNC_ACT_BUS */ "bulk-update-mark",
/* PFSYNC_ACT_TDB */ "TDB-replay-counter-update",
/* PFSYNC_ACT_EOF */ "end-of-frame-mark",
+ /* PFSYNC_ACT_INS_1400 */ "state-insert",
+ /* PFSYNC_ACT_UPD_1400 */ "state-update",
};
static void
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, May 2, 6:42 PM (13 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17910212
Default Alt Text
D39392.diff (58 KB)
Attached To
Mode
D39392: Make contents of struct pfsync_state configurable
Attached
Detach File
Event Timeline
Log In to Comment