Page MenuHomeFreeBSD

D39392.id119784.diff
No OneTemporary

D39392.id119784.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,14 @@
struct pfsync_actions actions[] = {
{ "clear all", sizeof(struct pfsync_clr), pfsync_print_clr },
- { "insert", sizeof(struct pfsync_state), pfsync_print_state },
+ { "insert", 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", 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 +127,9 @@
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 },
+ { "delete", sizeof(struct pfsync_state_1400), pfsync_print_state_1400 },
};
static void
@@ -212,12 +216,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 +387,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 +449,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
@@ -57,6 +57,7 @@
void setpfsync_syncpeer(const char *, int, int, const struct afswtch *);
void setpfsync_maxupd(const char *, int, int, const struct afswtch *);
void setpfsync_defer(const char *, int, int, const struct afswtch *);
+void setpfsync_version(const char *, int, int, const struct afswtch *);
void pfsync_status(int);
static int
@@ -323,6 +324,28 @@
nvlist_destroy(nvl);
}
+/* ARGSUSED */
+void
+setpfsync_version(const char *val, int d, int s, const struct afswtch *rafp)
+{
+ int version;
+ nvlist_t *nvl = nvlist_create(0);
+
+ /* Don't verify, kernel knows which versions are supported.*/
+ version = atoi(val);
+
+ if (pfsync_do_ioctl(s, SIOCGETPFSYNCNV, &nvl) == -1)
+ err(1, "SIOCGETPFSYNCNV");
+
+ nvlist_free_number(nvl, "version");
+ nvlist_add_number(nvl, "version", version);
+
+ if (pfsync_do_ioctl(s, SIOCSETPFSYNCNV, &nvl) == -1)
+ err(1, "SIOCSETPFSYNCNV");
+
+ nvlist_destroy(nvl);
+}
+
void
pfsync_status(int s)
{
@@ -331,6 +354,7 @@
char syncpeer_str[NI_MAXHOST];
struct sockaddr_storage syncpeer;
int maxupdates;
+ int version;
int flags;
int error;
@@ -347,6 +371,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")) {
@@ -377,7 +403,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);
}
@@ -391,6 +418,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,20 +59,31 @@
#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 */
+#define PFSYNC_ACT_DEL_1301 6 /* delete state */
#define PFSYNC_ACT_DEL_C 7 /* "compressed" delete state */
#define PFSYNC_ACT_INS_F 8 /* insert fragment */
#define PFSYNC_ACT_DEL_F 9 /* delete fragments */
#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_DEL_1400 15 /* delete state */
+#define PFSYNC_ACT_MAX 16
/*
* A pfsync frame is built from a header followed by several sections which
@@ -251,6 +262,7 @@
char syncdev[IFNAMSIZ];
struct sockaddr_storage syncpeer;
int maxupdates;
+ int version;
int flags;
};
@@ -269,13 +281,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 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
@@ -1043,7 +1043,7 @@
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];
@@ -1069,9 +1069,50 @@
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];
+ 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_int16_t state_flags;
+ u_int8_t log;
+ u_int8_t __spare;
+ u_int8_t timeout;
+ u_int8_t sync_flags;
+ u_int8_t updates;
+ /* The rest is not */
+
+ u_int8_t rt;
+ u_int16_t max_mss;
+ u_int8_t min_ttl;
+ u_int8_t set_tos;
+ u_int8_t set_prio[2];
+ int32_t rtableid;
+
+} __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 *);
@@ -1093,8 +1134,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 *);
@@ -1613,7 +1654,7 @@
};
struct pfioc_state {
- struct pfsync_state state;
+ struct pfsync_state_1301 state;
};
struct pfioc_src_node_kill {
@@ -1653,7 +1694,7 @@
int ps_len;
union {
caddr_t psu_buf;
- struct pfsync_state *psu_states;
+ struct pfsync_state_1301 *psu_states;
} ps_u;
#define ps_buf ps_u.psu_buf
#define ps_states ps_u.psu_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,33 +122,36 @@
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(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_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(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) = {
+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_del, /* PFSYNC_ACT_DEL */
+ pfsync_in_del, /* PFSYNC_ACT_DEL_1301 */
pfsync_in_del_c, /* PFSYNC_ACT_DEL_C */
pfsync_in_error, /* PFSYNC_ACT_INS_F */
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 */
+ pfsync_in_del, /* PFSYNC_ACT_DEL_1400 */
};
struct pfsync_q {
@@ -157,18 +160,45 @@
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,
+ 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(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, 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, 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, /* PFSYNC_Q_DEL */
};
static void pfsync_q_ins(struct pf_kstate *, int, bool);
@@ -201,7 +231,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;
@@ -221,6 +251,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;
@@ -348,6 +379,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) {
@@ -380,7 +412,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);
@@ -466,7 +498,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
@@ -481,17 +513,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 */
@@ -501,11 +533,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;
@@ -524,16 +556,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);
@@ -543,8 +575,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). */
@@ -552,41 +584,64 @@
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;
- st->state_flags = sp->state_flags;
+ st->direction = sp->pfs_1301.direction;
+ st->log = sp->pfs_1301.log;
+ st->timeout = sp->pfs_1301.timeout;
- st->id = sp->id;
- st->creatorid = sp->creatorid;
- pf_state_peer_ntoh(&sp->src, &st->src);
- pf_state_peer_ntoh(&sp->dst, &st->dst);
+ 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);
+
+ switch (msg_version) {
+ case PFSYNC_MSG_VERSION_1301:
+ st->state_flags = sp->pfs_1301.state_flags;
+ break;
+ case PFSYNC_MSG_VERSION_1400:
+ st->state_flags = ntohs(sp->pfs_1400.state_flags);
+ /*
+ * TODO: modify pf.c to store those values in states.
+ * This is already partially done in D38025.
+ * Add export for DIOCGETSTATESV2 too.
+ *
+ * st->rt = sp->pfs_1400.rt;
+ * st->max_mss = sp->pfs_1400.max_mss;
+ * st->min_ttl = sp->pfs_1400.min_ttl;
+ * st->set_prio[0] = sp->pfs_1400->set_prio[0];
+ * st->set_prio[1] = sp->pfs_1400->set_prio[1];
+ * st->rtableid = sp->pfs_1400->rtableid;
+ */
+ break;
+ default:
+ panic("%s: Unsupported pfsync_msg_version %d",
+ __func__, msg_version);
+ }
st->rule.ptr = r;
st->nat_rule.ptr = NULL;
@@ -611,7 +666,7 @@
if (st->state_flags & PFSTATE_ACK) {
struct pfsync_bucket *b = pfsync_get_bucket(sc, st);
PFSYNC_BUCKET_LOCK(b);
- pfsync_q_ins(st, PFSYNC_S_IACK, true);
+ pfsync_q_ins(st, PFSYNC_Q_IACK, true);
PFSYNC_BUCKET_UNLOCK(b);
pfsync_push_all(sc);
@@ -725,7 +780,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);
@@ -742,7 +797,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;
@@ -784,36 +839,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;
}
@@ -822,7 +891,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;
@@ -893,31 +962,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");
@@ -926,10 +1006,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;
}
@@ -939,7 +1019,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;
@@ -947,20 +1027,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;
@@ -979,7 +1059,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;
@@ -1066,7 +1146,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;
@@ -1107,25 +1187,36 @@
}
static int
-pfsync_in_del(struct mbuf *m, int offset, int count, int flags)
+pfsync_in_del(struct mbuf *m, int offset, int count, int flags, int action)
{
struct mbuf *mp;
- struct pfsync_state *sa, *sp;
+ union pfsync_state_union *sa, *sp;
struct pf_kstate *st;
- int len = count * sizeof(*sp);
- int offp, i;
+ int len, offp, i;
+
+ switch (action) {
+ case PFSYNC_ACT_DEL_1301:
+ len = sizeof(struct pfsync_state_1301) * count;
+ break;
+ case PFSYNC_ACT_DEL_1400:
+ len = sizeof(struct pfsync_state_1400) * count;
+ 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];
- 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) {
V_pfsyncstats.pfsyncs_badstate++;
continue;
@@ -1138,7 +1229,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;
@@ -1170,7 +1261,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;
@@ -1199,7 +1290,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");
@@ -1232,7 +1323,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);
@@ -1297,7 +1388,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)
@@ -1309,7 +1400,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++;
@@ -1390,6 +1481,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);
@@ -1475,11 +1567,19 @@
}
static void
-pfsync_out_state(struct pf_kstate *st, void *buf)
+pfsync_out_state_1301(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_1301);
+}
+
+static void
+pfsync_out_state_1400(struct pf_kstate *st, void *buf)
+{
+ union pfsync_state_union *sp = buf;
+
+ pfsync_state_export(sp, st, PFSYNC_MSG_VERSION_1400);
}
static void
@@ -1524,12 +1624,13 @@
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,
+ printf("%s: q: %02d, creator: %08x, id: %016lx ss: %d\n", __func__, q, st->creatorid, st->id, st->sync_state);
+ KASSERT(st->sync_state == pfsync_qid_sstate[q],
("%s: st->sync_state == q",
__func__));
st->sync_state = PFSYNC_S_NONE;
@@ -1602,7 +1703,6 @@
return;
}
-
/* build the pfsync header */
ph = (struct pfsync_header *)(m->m_data + offset);
bzero(ph, sizeof(*ph));
@@ -1613,7 +1713,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;
@@ -1622,7 +1722,8 @@
count = 0;
TAILQ_FOREACH_SAFE(st, &b->b_qs[q], sync_list, st_next) {
- KASSERT(st->sync_state == q,
+ printf("%s: q: %02d, creator: %08x, id: %016lx ss: %d\n", __func__, q, st->creatorid, st->id, st->sync_state);
+ KASSERT(st->sync_state == pfsync_qid_sstate[q],
("%s: st->sync_state == q",
__func__));
/*
@@ -1731,7 +1832,18 @@
if (b->b_len == PFSYNC_MINPKT)
callout_reset(&b->b_tmo, 1 * hz, pfsync_timeout, b);
- pfsync_q_ins(st, PFSYNC_S_INS, true);
+ switch (sc->sc_version) {
+ case PFSYNC_MSG_VERSION_1301:
+ pfsync_q_ins(st, PFSYNC_Q_INS_1301, true);
+ break;
+ case PFSYNC_MSG_VERSION_1400:
+ pfsync_q_ins(st, PFSYNC_Q_INS_1400, true);
+ break;
+ default:
+ panic("%s: Unsupported pfsync_msg_version %d",
+ __func__, sc->sc_version);
+ }
+
PFSYNC_BUCKET_UNLOCK(b);
st->sync_updates = 0;
@@ -1930,7 +2042,7 @@
/* FALLTHROUGH */
case PFSYNC_S_NONE:
- pfsync_q_ins(st, PFSYNC_S_UPD_C, ref);
+ pfsync_q_ins(st, PFSYNC_Q_UPD_C, ref);
st->sync_updates = 0;
break;
@@ -2012,7 +2124,17 @@
/* FALLTHROUGH */
case PFSYNC_S_NONE:
- pfsync_q_ins(st, PFSYNC_S_UPD, ref);
+ switch (sc->sc_version) {
+ case PFSYNC_MSG_VERSION_1301:
+ pfsync_q_ins(st, PFSYNC_Q_UPD_1301, ref);
+ break;
+ case PFSYNC_MSG_VERSION_1400:
+ pfsync_q_ins(st, PFSYNC_Q_UPD_1400, ref);
+ break;
+ default:
+ panic("%s: Unsupported pfsync_msg_version %d",
+ __func__, sc->sc_version);
+ }
pfsync_push(b);
break;
@@ -2026,7 +2148,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);
@@ -2068,7 +2190,7 @@
/* FALLTHROUGH */
case PFSYNC_S_NONE:
- pfsync_q_ins(st, PFSYNC_S_DEL, ref);
+ pfsync_q_ins(st, PFSYNC_Q_DEL, ref);
break;
default:
@@ -2123,7 +2245,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);
}
@@ -2131,20 +2253,25 @@
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__));
- b->b_len -= pfsync_qs[q].len;
- TAILQ_REMOVE(&b->b_qs[q], st, sync_list);
- st->sync_state = PFSYNC_S_NONE;
- if (unref)
- pf_release_state(st);
+ for (q=0; q<PFSYNC_Q_COUNT; q++) {
+ if (pfsync_qid_sstate[q] != st->sync_state)
+ continue;
- if (TAILQ_EMPTY(&b->b_qs[q]))
- b->b_len -= sizeof(struct pfsync_subheader);
+ b->b_len -= pfsync_qs[q].len;
+ TAILQ_REMOVE(&b->b_qs[q], st, sync_list);
+ st->sync_state = PFSYNC_S_NONE;
+ if (unref)
+ pf_release_state(st);
+
+ if (TAILQ_EMPTY(&b->b_qs[q]))
+ b->b_len -= sizeof(struct pfsync_subheader);
+ }
}
static void
@@ -2533,6 +2660,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
@@ -2011,6 +2011,8 @@
{
struct pf_idhash *ih = &V_pf_idhash[PF_IDHASH(s)];
+ printf("%s: creator: %08x, id: %016lx ss: %d\n", __func__, s->creatorid, s->id, s->sync_state);
+
PF_HASHROW_ASSERT(ih);
if (s->timeout == PFTM_UNLINKED) {
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
@@ -3708,8 +3708,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;
@@ -3717,7 +3717,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;
@@ -3734,7 +3736,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;
}
@@ -3747,20 +3750,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++) {
@@ -3785,7 +3788,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;
}
@@ -3799,19 +3802,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;
@@ -5640,63 +5644,75 @@
}
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);
+ 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 = 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"))

File Metadata

Mime Type
text/plain
Expires
Tue, Sep 24, 6:52 PM (7 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
12688492
Default Alt Text
D39392.id119784.diff (46 KB)

Event Timeline