Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F164560718
D39392.id121710.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
59 KB
Referenced Files
None
Subscribers
None
D39392.id121710.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,9 +111,11 @@
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),
@@ -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/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h
--- a/lib/libpfctl/libpfctl.h
+++ b/lib/libpfctl/libpfctl.h
@@ -353,6 +353,18 @@
uint32_t pfsync_time;
uint16_t state_flags;
uint32_t sync_flags;
+ uint16_t qid;
+ uint16_t pqid;
+ uint16_t dnpipe;
+ uint16_t dnrpipe;
+ uint8_t log;
+ int32_t rtableid;
+ uint8_t min_ttl;
+ uint8_t set_tos;
+ uint16_t max_mss;
+ uint8_t set_prio[2];
+ uint8_t rt;
+ char rt_ifname[IFNAMSIZ];
};
TAILQ_HEAD(pfctl_statelist, pfctl_state);
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -1111,6 +1111,7 @@
ps->id = s->id;
strlcpy(ps->ifname, s->ifname, sizeof(ps->ifname));
strlcpy(ps->orig_ifname, s->orig_ifname, sizeof(ps->orig_ifname));
+ strlcpy(ps->rt_ifname, s->rt_ifname, sizeof(ps->rt_ifname));
pf_state_key_export_to_state_key(&ps->key[0], &s->key[0]);
pf_state_key_export_to_state_key(&ps->key[1], &s->key[1]);
pf_state_peer_export_to_state_peer(&ps->src, &s->src);
@@ -1131,8 +1132,19 @@
ps->key[0].af = s->af;
ps->key[1].af = s->af;
ps->direction = s->direction;
- ps->state_flags = s->state_flags;
- ps->sync_flags = s->sync_flags;
+ ps->state_flags = ntohs(s->state_flags);
+ ps->sync_flags = ntohs(s->sync_flags);
+ ps->qid = ntohs(s->qid);
+ ps->pqid = ntohs(s->pqid);
+ ps->dnpipe = ntohs(s->dnpipe);
+ ps->dnrpipe = ntohs(s->dnrpipe);
+ ps->rtableid = ntohl(s->rtableid);
+ ps->min_ttl = s->min_ttl;
+ ps->set_tos = s->set_tos;
+ ps->max_mss = ntohs(s->max_mss);
+ ps->rt = s->rt;
+ ps->set_prio[0] = s->set_prio[0];
+ ps->set_prio[1] = s->set_prio[1];
}
int
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/sbin/pfctl/pf_print_state.c b/sbin/pfctl/pf_print_state.c
--- a/sbin/pfctl/pf_print_state.c
+++ b/sbin/pfctl/pf_print_state.c
@@ -350,17 +350,34 @@
if (s->state_flags & PFSTATE_NODF)
printf(", no-df");
if (s->state_flags & PFSTATE_SETTOS)
- printf(", set-tos");
+ printf(", set-tos 0x%2.2x", s->set_tos);
if (s->state_flags & PFSTATE_RANDOMID)
printf(", random-id");
if (s->state_flags & PFSTATE_SCRUB_TCP)
- printf(", scrub-tcp");
+ printf(", reassemble-tcp");
if (s->state_flags & PFSTATE_SETPRIO)
- printf(", set-prio");
+ printf(", set-prio (0x%02x 0x%02x)",
+ s->set_prio[0], s->set_prio[1]);
+ if (s->dnpipe || s->dnrpipe) {
+ if (s->state_flags & PFSTATE_DN_IS_PIPE)
+ printf(", dummynet pipe (%d %d)",
+ s->dnpipe, s->dnrpipe);
+ if (s->state_flags & PFSTATE_DN_IS_QUEUE)
+ printf(", dummynet queue (%d %d)",
+ s->dnpipe, s->dnrpipe);
+ }
if (s->sync_flags & PFSYNC_FLAG_SRCNODE)
printf(", source-track");
if (s->sync_flags & PFSYNC_FLAG_NATSRCNODE)
printf(", sticky-address");
+ if (s->log)
+ printf(", log");
+ if (s->log & PF_LOG_ALL)
+ printf(" (all)");
+ if (s->min_ttl)
+ printf(", min-ttl %d", s->min_ttl);
+ if (s->max_mss)
+ printf(", max-mss %d", s->max_mss);
printf("\n");
}
if (opts & PF_OPT_VERBOSE2) {
@@ -368,8 +385,26 @@
bcopy(&s->id, &id, sizeof(u_int64_t));
printf(" id: %016jx creatorid: %08x", id, s->creatorid);
- printf(" gateway: ");
- print_host(&s->rt_addr, 0, af, opts);
+ if (s->rt) {
+ switch (s->rt) {
+ case PF_ROUTETO:
+ printf(" route-to: ");
+ break;
+ case PF_DUPTO:
+ printf(" dup-to: ");
+ break;
+ case PF_REPLYTO:
+ printf(" reply-to: ");
+ break;
+ default:
+ printf(" gateway: ");
+ }
+ print_host(&s->rt_addr, 0, af, opts);
+ if (s->rt_ifname[0])
+ printf("@%s", s->rt_ifname);
+ }
+ if (s->rtableid != -1)
+ printf(" rtable: %d", s->rtableid);
printf("\n");
if (strcmp(s->ifname, s->orig_ifname) != 0)
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/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_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) = {
+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 }
};
-static void pfsync_q_ins(struct pf_kstate *, int, bool);
+/* 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 */
+};
+
+/* 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 */
+ 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->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);
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)
{
- 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
@@ -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,10 +2197,48 @@
pfsync_send_plus(&r, sizeof(r));
}
-static void
-pfsync_q_ins(struct pf_kstate *st, int q, bool ref)
+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 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
@@ -4636,6 +4640,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;
@@ -4704,6 +4710,7 @@
goto csfailed;
}
s->rt_kif = r->rpool.cur->kif;
+ s->rt = r->rt;
}
s->creation = time_uptime;
@@ -6439,9 +6446,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 &&
@@ -6452,7 +6470,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 ?
@@ -6482,7 +6500,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);
@@ -6581,7 +6599,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),
@@ -6617,7 +6635,7 @@
KMOD_IPSTAT_INC(ips_fragmented);
done:
- if (r->rt != PF_DUPTO)
+ if (r_rt != PF_DUPTO)
*m = NULL;
return;
@@ -6641,9 +6659,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 &&
@@ -6654,7 +6683,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 ?
@@ -6684,7 +6713,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);
@@ -6768,7 +6797,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) +
@@ -6780,7 +6809,7 @@
}
done:
- if (r->rt != PF_DUPTO)
+ if (r_rt != PF_DUPTO)
*m = NULL;
return;
@@ -7100,7 +7129,16 @@
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;
+ uint16_t qid;
+ 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));
@@ -7392,36 +7430,43 @@
}
if (s) {
- pf_scrub_ip(&m, s->state_flags, s->min_ttl, s->set_tos);
- if (s->rtableid >= 0)
- M_SETFIB(m, s->rtableid);
-#ifdef ALTQ
- if (s->qid) {
- pd.act.pqid = s->pqid;
- pd.act.qid = s->qid;
- }
-#endif
+ scrub_flags = s->state_flags;
+ min_ttl = s->min_ttl;
+ set_tos = s->set_tos;
+ rtableid = s->rtableid;
+ pqid = s->pqid;
+ qid = s->qid;
+ 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);
-#ifdef ALTQ
- if (r->qid) {
- pd.act.pqid = r->pqid;
- pd.act.qid = r->qid;
- }
-#endif
+ scrub_flags = r->scrub_flags;
+ min_ttl = r->min_ttl;
+ set_tos = r->set_tos;
+ rtableid = r->rtableid;
+ pqid = r->pqid;
+ qid = r->qid;
+ 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;
@@ -7431,6 +7476,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)) {
@@ -7602,7 +7652,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);
}
@@ -7635,7 +7685,16 @@
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;
+ uint16_t qid;
+ 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));
@@ -7923,37 +7982,44 @@
("pf: dropping packet with dangerous v6 headers\n"));
}
- if (s && s->tag > 0 && pf_tag_packet(m, &pd, s->tag)) {
+ if (s) {
+ scrub_flags = s->state_flags;
+ min_ttl = s->min_ttl;
+ set_tos = s->set_tos;
+ rtableid = s->rtableid;
+ pqid = s->pqid;
+ qid = s->qid;
+ tag = s->tag;
+ rt = s->rt;
+ set_prio[0] = s->set_prio[0];
+ set_prio[1] = s->set_prio[1];
+ } else {
+ scrub_flags = r->scrub_flags;
+ min_ttl = r->min_ttl;
+ set_tos = r->set_tos;
+ rtableid = r->rtableid;
+ pqid = r->pqid;
+ qid = r->qid;
+ tag = r->tag;
+ rt = r->rt;
+ set_prio[0] = r->set_prio[0];
+ set_prio[1] = r->set_prio[1];
+ }
+
+ if (tag > 0 && pf_tag_packet(m, &pd, 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);
-#ifdef ALTQ
- if (s->qid) {
- pd.act.pqid = s->pqid;
- pd.act.qid = s->qid;
- }
-#endif
- } else {
- pf_scrub_ip6(&m, r->scrub_flags, r->min_ttl, r->set_tos);
- if (r->rtableid >= 0)
- M_SETFIB(m, r->rtableid);
-#ifdef ALTQ
- if (r->qid) {
- pd.act.pqid = r->pqid;
- pd.act.qid = r->qid;
- }
-#endif
- }
+ pf_scrub_ip6(&m, scrub_flags, min_ttl, set_tos);
- if (r->scrub_flags & PFSTATE_SETPRIO) {
+ 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;
@@ -7963,6 +8029,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)) {
@@ -8082,7 +8153,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
@@ -5757,9 +5787,9 @@
sp->direction = st->direction;
sp->log = st->log;
sp->timeout = st->timeout;
- /* 8 bits for old peers, 16 bits for new peers */
+ /* 8 bits for the old libpfctl, 16 bits for the new libpfctl */
sp->state_flags_compat = st->state_flags;
- sp->state_flags = st->state_flags;
+ sp->state_flags = htons(st->state_flags);
if (st->src_node)
sp->sync_flags |= PFSYNC_FLAG_SRCNODE;
if (st->nat_src_node)
@@ -5787,6 +5817,22 @@
sp->packets[1] = st->packets[1];
sp->bytes[0] = st->bytes[0];
sp->bytes[1] = st->bytes[1];
+
+ sp->qid = htons(st->qid);
+ sp->pqid = htons(st->pqid);
+ sp->dnpipe = htons(st->dnpipe);
+ sp->dnrpipe = htons(st->dnrpipe);
+ sp->rtableid = htonl(st->rtableid);
+ sp->min_ttl = st->min_ttl;
+ sp->set_tos = st->set_tos;
+ sp->max_mss = htons(st->max_mss);
+ sp->rt = st->rt;
+ if (st->rt_kif)
+ strlcpy(sp->rt_ifname, st->rt_kif->pfik_name,
+ sizeof(sp->rt_ifname));
+ sp->set_prio[0] = st->set_prio[0];
+ sp->set_prio[1] = st->set_prio[1];
+
}
static void
diff --git a/sys/netpfil/pf/pfsync_nv.c b/sys/netpfil/pf/pfsync_nv.c
--- a/sys/netpfil/pf/pfsync_nv.c
+++ b/sys/netpfil/pf/pfsync_nv.c
@@ -130,6 +130,7 @@
return (EINVAL);
status->maxupdates = nvlist_get_number(nvl, "maxupdates");
+ status->version = nvlist_get_number(nvl, "version");
status->flags = nvlist_get_number(nvl, "flags");
if (nvlist_exists_string(nvl, "syncdev"))
diff --git a/usr.bin/netstat/if.c b/usr.bin/netstat/if.c
--- a/usr.bin/netstat/if.c
+++ b/usr.bin/netstat/if.c
@@ -81,9 +81,9 @@
#ifdef PF
static const char* pfsyncacts[] = {
/* PFSYNC_ACT_CLR */ "clear all request",
- /* PFSYNC_ACT_INS */ "state insert",
+ /* PFSYNC_ACT_INS_1301 */ "13.1 state insert",
/* PFSYNC_ACT_INS_ACK */ "state inserted ack",
- /* PFSYNC_ACT_UPD */ "state update",
+ /* PFSYNC_ACT_UPD_1301 */ "13.1 state update",
/* PFSYNC_ACT_UPD_C */ "compressed state update",
/* PFSYNC_ACT_UPD_REQ */ "uncompressed state request",
/* PFSYNC_ACT_DEL */ "state delete",
@@ -93,13 +93,15 @@
/* PFSYNC_ACT_BUS */ "bulk update mark",
/* PFSYNC_ACT_TDB */ "TDB replay counter update",
/* PFSYNC_ACT_EOF */ "end of frame mark",
+ /* PFSYNC_ACT_INS_1400 */ "state insert",
+ /* PFSYNC_ACT_UPD_1400 */ "state update",
};
static const char* pfsyncacts_name[] = {
/* PFSYNC_ACT_CLR */ "clear-all-request",
- /* PFSYNC_ACT_INS */ "state-insert",
+ /* PFSYNC_ACT_INS_1301 */ "state-insert-1301",
/* PFSYNC_ACT_INS_ACK */ "state-inserted-ack",
- /* PFSYNC_ACT_UPD */ "state-update",
+ /* PFSYNC_ACT_UPD_1301 */ "state-update-1301",
/* PFSYNC_ACT_UPD_C */ "compressed-state-update",
/* PFSYNC_ACT_UPD_REQ */ "uncompressed-state-request",
/* PFSYNC_ACT_DEL */ "state-delete",
@@ -109,6 +111,8 @@
/* PFSYNC_ACT_BUS */ "bulk-update-mark",
/* PFSYNC_ACT_TDB */ "TDB-replay-counter-update",
/* PFSYNC_ACT_EOF */ "end-of-frame-mark",
+ /* PFSYNC_ACT_INS_1400 */ "state-insert",
+ /* PFSYNC_ACT_UPD_1400 */ "state-update",
};
static void
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Aug 3, 2:37 AM (12 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35884374
Default Alt Text
D39392.id121710.diff (59 KB)
Attached To
Mode
D39392: Make contents of struct pfsync_state configurable
Attached
Detach File
Event Timeline
Log In to Comment