Page MenuHomeFreeBSD

D39392.diff
No OneTemporary

D39392.diff

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

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)

Event Timeline