Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F96124188
D39392.id119784.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
46 KB
Referenced Files
None
Subscribers
None
D39392.id119784.diff
View Options
diff --git a/contrib/tcpdump/print-pfsync.c b/contrib/tcpdump/print-pfsync.c
--- a/contrib/tcpdump/print-pfsync.c
+++ b/contrib/tcpdump/print-pfsync.c
@@ -55,7 +55,7 @@
static void print_src_dst(netdissect_options *,
const struct pfsync_state_peer *,
const struct pfsync_state_peer *, uint8_t);
-static void print_state(netdissect_options *, struct pfsync_state *);
+static void print_state(netdissect_options *, union pfsync_state_union *, int);
u_int
pfsync_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
@@ -100,7 +100,8 @@
};
static void pfsync_print_clr(netdissect_options *, const void *);
-static void pfsync_print_state(netdissect_options *, const void *);
+static void pfsync_print_state_1301(netdissect_options *, const void *);
+static void pfsync_print_state_1400(netdissect_options *, const void *);
static void pfsync_print_ins_ack(netdissect_options *, const void *);
static void pfsync_print_upd_c(netdissect_options *, const void *);
static void pfsync_print_upd_req(netdissect_options *, const void *);
@@ -110,14 +111,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
Details
Attached
Mime Type
text/plain
Expires
Tue, Sep 24, 6:52 PM (7 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
12688492
Default Alt Text
D39392.id119784.diff (46 KB)
Attached To
Mode
D39392: Make contents of struct pfsync_state configurable
Attached
Detach File
Event Timeline
Log In to Comment