mirror of
https://github.com/opnsense/src.git
synced 2026-06-08 16:22:46 -04:00
pf: make contents of struct pfsync_state configurable
Make struct pfsync_state contents configurable by sending out new versions of the structure in separate subheader actions. Both old and new version of struct pfsync_state can be understood, so replication of states from a system running an older kernel is possible. The version being sent out is configured using ifconfig pfsync0 … version XXXX. The version is an user-friendly string - 1301 stands for FreeBSD 13.1 (I have checked synchronization against a host running 13.1), 1400 stands for 14.0. A host running an older kernel will just ignore the messages and count them as "packets discarded for bad action". Reviewed by: kp Sponsored by: InnoGames GmbH Differential Revision: https://reviews.freebsd.org/D39392
This commit is contained in:
parent
153145efcd
commit
4bf98559d9
9 changed files with 689 additions and 309 deletions
|
|
@ -55,7 +55,7 @@ static void pfsync_print(netdissect_options *, struct pfsync_header *,
|
|||
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 @@ struct pfsync_actions {
|
|||
};
|
||||
|
||||
static void pfsync_print_clr(netdissect_options *, const void *);
|
||||
static void pfsync_print_state(netdissect_options *, const void *);
|
||||
static void pfsync_print_state_1301(netdissect_options *, const void *);
|
||||
static void pfsync_print_state_1400(netdissect_options *, const void *);
|
||||
static void pfsync_print_ins_ack(netdissect_options *, const void *);
|
||||
static void pfsync_print_upd_c(netdissect_options *, const void *);
|
||||
static void pfsync_print_upd_req(netdissect_options *, const void *);
|
||||
|
|
@ -110,14 +111,16 @@ static void pfsync_print_tdb(netdissect_options *, const void *);
|
|||
|
||||
struct pfsync_actions actions[] = {
|
||||
{ "clear all", sizeof(struct pfsync_clr), pfsync_print_clr },
|
||||
{ "insert", sizeof(struct pfsync_state), pfsync_print_state },
|
||||
{ "insert 13.1", sizeof(struct pfsync_state_1301),
|
||||
pfsync_print_state_1301 },
|
||||
{ "insert ack", sizeof(struct pfsync_ins_ack), pfsync_print_ins_ack },
|
||||
{ "update", sizeof(struct pfsync_ins_ack), pfsync_print_state },
|
||||
{ "update 13.1", sizeof(struct pfsync_state_1301),
|
||||
pfsync_print_state_1301 },
|
||||
{ "update compressed", sizeof(struct pfsync_upd_c),
|
||||
pfsync_print_upd_c },
|
||||
{ "request uncompressed", sizeof(struct pfsync_upd_req),
|
||||
pfsync_print_upd_req },
|
||||
{ "delete", sizeof(struct pfsync_state), pfsync_print_state },
|
||||
{ "delete", sizeof(struct pfsync_state_1301), pfsync_print_state_1301 },
|
||||
{ "delete compressed", sizeof(struct pfsync_del_c),
|
||||
pfsync_print_del_c },
|
||||
{ "frag insert", 0, NULL },
|
||||
|
|
@ -126,6 +129,8 @@ struct pfsync_actions actions[] = {
|
|||
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 @@ pfsync_print_clr(netdissect_options *ndo, const void *bp)
|
|||
}
|
||||
|
||||
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 @@ print_src_dst(netdissect_options *ndo, const struct pfsync_state_peer *src,
|
|||
}
|
||||
|
||||
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 @@ print_state(netdissect_options *ndo, struct pfsync_state *s)
|
|||
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)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -309,6 +309,27 @@ setpfsync_defer(if_ctx *ctx, const char *val, int d)
|
|||
nvlist_destroy(nvl);
|
||||
}
|
||||
|
||||
static void
|
||||
setpfsync_version(if_ctx *ctx, const char *val, int dummy __unused)
|
||||
{
|
||||
int version;
|
||||
nvlist_t *nvl = nvlist_create(0);
|
||||
|
||||
/* Don't verify, kernel knows which versions are supported.*/
|
||||
version = atoi(val);
|
||||
|
||||
if (pfsync_do_ioctl(ctx->io_s, SIOCGETPFSYNCNV, &nvl) == -1)
|
||||
err(1, "SIOCGETPFSYNCNV");
|
||||
|
||||
nvlist_free_number(nvl, "version");
|
||||
nvlist_add_number(nvl, "version", version);
|
||||
|
||||
if (pfsync_do_ioctl(ctx->io_s, SIOCSETPFSYNCNV, &nvl) == -1)
|
||||
err(1, "SIOCSETPFSYNCNV");
|
||||
|
||||
nvlist_destroy(nvl);
|
||||
}
|
||||
|
||||
static void
|
||||
pfsync_status(if_ctx *ctx)
|
||||
{
|
||||
|
|
@ -318,6 +339,7 @@ pfsync_status(if_ctx *ctx)
|
|||
struct sockaddr_storage syncpeer;
|
||||
int maxupdates = 0;
|
||||
int flags = 0;
|
||||
int version;
|
||||
int error;
|
||||
|
||||
nvl = nvlist_create(0);
|
||||
|
|
@ -333,6 +355,8 @@ pfsync_status(if_ctx *ctx)
|
|||
IFNAMSIZ);
|
||||
if (nvlist_exists_number(nvl, "maxupdates"))
|
||||
maxupdates = nvlist_get_number(nvl, "maxupdates");
|
||||
if (nvlist_exists_number(nvl, "version"))
|
||||
version = nvlist_get_number(nvl, "version");
|
||||
if (nvlist_exists_number(nvl, "flags"))
|
||||
flags = nvlist_get_number(nvl, "flags");
|
||||
if (nvlist_exists_nvlist(nvl, "syncpeer")) {
|
||||
|
|
@ -363,7 +387,8 @@ pfsync_status(if_ctx *ctx)
|
|||
}
|
||||
|
||||
printf("maxupd: %d ", maxupdates);
|
||||
printf("defer: %s\n", (flags & PFSYNCF_DEFER) ? "on" : "off");
|
||||
printf("defer: %s ", (flags & PFSYNCF_DEFER) ? "on" : "off");
|
||||
printf("version: %d\n", version);
|
||||
printf("\tsyncok: %d\n", (flags & PFSYNCF_OK) ? 1 : 0);
|
||||
}
|
||||
|
||||
|
|
@ -377,6 +402,7 @@ static struct cmd pfsync_cmds[] = {
|
|||
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",
|
||||
|
|
|
|||
|
|
@ -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 @@ struct pfsync_kstatus {
|
|||
char syncdev[IFNAMSIZ];
|
||||
struct sockaddr_storage syncpeer;
|
||||
int maxupdates;
|
||||
int version;
|
||||
int flags;
|
||||
};
|
||||
|
||||
|
|
@ -269,13 +280,13 @@ struct pfsyncioc_nv {
|
|||
|
||||
/*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -641,6 +641,7 @@ struct pf_rule_actions {
|
|||
uint16_t dnpipe;
|
||||
uint16_t dnrpipe; /* Reverse direction pipe */
|
||||
uint32_t flags;
|
||||
uint8_t set_prio[2];
|
||||
};
|
||||
|
||||
union pf_keth_rule_ptr {
|
||||
|
|
@ -1057,12 +1058,14 @@ struct pf_kstate {
|
|||
u_int8_t min_ttl;
|
||||
u_int8_t set_tos;
|
||||
u_int16_t max_mss;
|
||||
u_int8_t rt;
|
||||
u_int8_t set_prio[2];
|
||||
};
|
||||
|
||||
/*
|
||||
* Size <= fits 12 objects per page on LP64. Try to not grow the struct beyond that.
|
||||
* Size <= fits 11 objects per page on LP64. Try to not grow the struct beyond that.
|
||||
*/
|
||||
_Static_assert(sizeof(struct pf_kstate) <= 336, "pf_kstate size crosses 336 bytes");
|
||||
_Static_assert(sizeof(struct pf_kstate) <= 368, "pf_kstate size crosses 368 bytes");
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -1094,7 +1097,34 @@ struct pfsync_state_key {
|
|||
u_int16_t port[2];
|
||||
};
|
||||
|
||||
struct pfsync_state {
|
||||
struct pfsync_state_1301 {
|
||||
u_int64_t id;
|
||||
char ifname[IFNAMSIZ];
|
||||
struct pfsync_state_key key[2];
|
||||
struct pfsync_state_peer src;
|
||||
struct pfsync_state_peer dst;
|
||||
struct pf_addr rt_addr;
|
||||
u_int32_t rule;
|
||||
u_int32_t anchor;
|
||||
u_int32_t nat_rule;
|
||||
u_int32_t creation;
|
||||
u_int32_t expire;
|
||||
u_int32_t packets[2][2];
|
||||
u_int32_t bytes[2][2];
|
||||
u_int32_t creatorid;
|
||||
sa_family_t af;
|
||||
u_int8_t proto;
|
||||
u_int8_t direction;
|
||||
u_int8_t __spare[2];
|
||||
u_int8_t log;
|
||||
u_int8_t state_flags;
|
||||
u_int8_t timeout;
|
||||
u_int8_t sync_flags;
|
||||
u_int8_t updates;
|
||||
} __packed;
|
||||
|
||||
struct pfsync_state_1400 {
|
||||
/* The beginning of the struct is compatible with previous versions */
|
||||
u_int64_t id;
|
||||
char ifname[IFNAMSIZ];
|
||||
struct pfsync_state_key key[2];
|
||||
|
|
@ -1114,15 +1144,33 @@ struct pfsync_state {
|
|||
u_int8_t direction;
|
||||
u_int16_t state_flags;
|
||||
u_int8_t log;
|
||||
u_int8_t state_flags_compat;
|
||||
u_int8_t __spare;
|
||||
u_int8_t timeout;
|
||||
u_int8_t sync_flags;
|
||||
u_int8_t updates;
|
||||
/* The rest is not */
|
||||
u_int16_t qid;
|
||||
u_int16_t pqid;
|
||||
u_int16_t dnpipe;
|
||||
u_int16_t dnrpipe;
|
||||
int32_t rtableid;
|
||||
u_int8_t min_ttl;
|
||||
u_int8_t set_tos;
|
||||
u_int16_t max_mss;
|
||||
u_int8_t set_prio[2];
|
||||
u_int8_t rt;
|
||||
char rt_ifname[IFNAMSIZ];
|
||||
|
||||
} __packed;
|
||||
|
||||
union pfsync_state_union {
|
||||
struct pfsync_state_1301 pfs_1301;
|
||||
struct pfsync_state_1400 pfs_1400;
|
||||
} __packed;
|
||||
|
||||
#ifdef _KERNEL
|
||||
/* pfsync */
|
||||
typedef int pfsync_state_import_t(struct pfsync_state *, int);
|
||||
typedef int pfsync_state_import_t(union pfsync_state_union *, int, int);
|
||||
typedef void pfsync_insert_state_t(struct pf_kstate *);
|
||||
typedef void pfsync_update_state_t(struct pf_kstate *);
|
||||
typedef void pfsync_delete_state_t(struct pf_kstate *);
|
||||
|
|
@ -1144,8 +1192,8 @@ VNET_DECLARE(pfsync_defer_t *, pfsync_defer_ptr);
|
|||
#define V_pfsync_defer_ptr VNET(pfsync_defer_ptr)
|
||||
extern pfsync_detach_ifnet_t *pfsync_detach_ifnet_ptr;
|
||||
|
||||
void pfsync_state_export(struct pfsync_state *,
|
||||
struct pf_kstate *);
|
||||
void pfsync_state_export(union pfsync_state_union *,
|
||||
struct pf_kstate *, int);
|
||||
void pf_state_export(struct pf_state_export *,
|
||||
struct pf_kstate *);
|
||||
|
||||
|
|
@ -1665,7 +1713,7 @@ struct pfioc_natlook {
|
|||
};
|
||||
|
||||
struct pfioc_state {
|
||||
struct pfsync_state state;
|
||||
struct pfsync_state_1301 state;
|
||||
};
|
||||
|
||||
struct pfioc_src_node_kill {
|
||||
|
|
@ -1704,8 +1752,8 @@ struct pfioc_state_kill {
|
|||
struct pfioc_states {
|
||||
int ps_len;
|
||||
union {
|
||||
void *ps_buf;
|
||||
struct pfsync_state *ps_states;
|
||||
void *ps_buf;
|
||||
struct pfsync_state_1301 *ps_states;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -122,23 +122,23 @@ union inet_template {
|
|||
|
||||
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 @@ static int (*pfsync_acts[])(struct mbuf *, int, int, int) = {
|
|||
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 @@ struct pfsync_q {
|
|||
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 @@ struct pfsync_bucket
|
|||
#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 @@ struct pfsync_softc {
|
|||
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 @@ pfsync_clone_create(struct if_clone *ifc, int unit, caddr_t param)
|
|||
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 @@ pfsync_clone_create(struct if_clone *ifc, int unit, caddr_t param)
|
|||
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 @@ pfsync_clone_create(struct if_clone *ifc, int unit, caddr_t param)
|
|||
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 @@ pfsync_alloc_scrub_memory(struct pfsync_state_peer *s,
|
|||
}
|
||||
|
||||
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 @@ pfsync_state_import(struct pfsync_state *sp, int flags)
|
|||
|
||||
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 @@ pfsync_state_import(struct pfsync_state *sp, int flags)
|
|||
* 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 @@ pfsync_state_import(struct pfsync_state *sp, int flags)
|
|||
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 @@ pfsync_state_import(struct pfsync_state *sp, int flags)
|
|||
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 @@ pfsync_state_import(struct pfsync_state *sp, int flags)
|
|||
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 @@ pfsync_input(struct mbuf **mp, int *offp __unused, int proto __unused)
|
|||
|
||||
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 @@ done:
|
|||
#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 @@ relock:
|
|||
}
|
||||
|
||||
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 @@ pfsync_in_ins(struct mbuf *m, int offset, int count, int flags)
|
|||
}
|
||||
|
||||
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 @@ pfsync_upd_tcp(struct pf_kstate *st, struct pfsync_state_peer *src,
|
|||
}
|
||||
|
||||
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 @@ pfsync_in_upd(struct mbuf *m, int offset, int count, int flags)
|
|||
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 @@ pfsync_in_upd(struct mbuf *m, int offset, int count, int flags)
|
|||
}
|
||||
|
||||
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 @@ pfsync_in_upd(struct mbuf *m, int offset, int count, int flags)
|
|||
* 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 @@ pfsync_in_upd(struct mbuf *m, int offset, int count, int flags)
|
|||
}
|
||||
|
||||
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 @@ pfsync_in_upd_c(struct mbuf *m, int offset, int count, int flags)
|
|||
}
|
||||
|
||||
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 @@ pfsync_in_ureq(struct mbuf *m, int offset, int count, int flags)
|
|||
}
|
||||
|
||||
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 @@ pfsync_in_del_c(struct mbuf *m, int offset, int count, int flags)
|
|||
}
|
||||
|
||||
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 @@ pfsync_in_bus(struct mbuf *m, int offset, int count, int flags)
|
|||
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 @@ pfsync_in_bus(struct mbuf *m, int offset, int count, int flags)
|
|||
}
|
||||
|
||||
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 @@ bad:
|
|||
#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 @@ pfsync_in_eof(struct mbuf *m, int offset, int count, int flags)
|
|||
}
|
||||
|
||||
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 @@ pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
|||
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 @@ pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
|||
}
|
||||
|
||||
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 @@ pfsync_drop(struct pfsync_softc *sc)
|
|||
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 @@ pfsync_sendout(int schedswi, int c)
|
|||
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 @@ pfsync_sendout(int schedswi, int c)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
/* build the pfsync header */
|
||||
ph = (struct pfsync_header *)(m->m_data + offset);
|
||||
bzero(ph, sizeof(*ph));
|
||||
|
|
@ -1602,7 +1712,7 @@ pfsync_sendout(int schedswi, int c)
|
|||
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 @@ pfsync_sendout(int schedswi, int c)
|
|||
|
||||
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 @@ pfsync_update_state_req(struct pf_kstate *st)
|
|||
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_clear_states(u_int32_t creatorid, const char *ifname)
|
|||
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 @@ pfsync_q_ins(struct pf_kstate *st, int q, bool ref)
|
|||
|
||||
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 @@ pfsync_q_ins(struct pf_kstate *st, int q, bool ref)
|
|||
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 @@ pfsync_kstatus_to_softc(struct pfsync_kstatus *status, struct pfsync_softc *sc)
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -3592,6 +3592,8 @@ pf_addr_inc(struct pf_addr *addr, sa_family_t af)
|
|||
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 @@ pf_rule_to_actions(struct pf_krule *r, struct pf_rule_actions *a)
|
|||
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 @@ pf_rule_to_actions(struct pf_krule *r, struct pf_rule_actions *a)
|
|||
else
|
||||
a->flags &= ~PFSTATE_DN_IS_PIPE;
|
||||
}
|
||||
if (a->flags & PFSTATE_SETPRIO) {
|
||||
a->set_prio[0] = r->set_prio[0];
|
||||
a->set_prio[1] = r->set_prio[1];
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -4638,6 +4642,8 @@ pf_create_state(struct pf_krule *r, struct pf_krule *nr, struct pf_krule *a,
|
|||
s->pqid = pd->act.pqid;
|
||||
s->dnpipe = pd->act.dnpipe;
|
||||
s->dnrpipe = pd->act.dnrpipe;
|
||||
s->set_prio[0] = pd->act.set_prio[0];
|
||||
s->set_prio[1] = pd->act.set_prio[1];
|
||||
s->state_flags |= pd->act.flags;
|
||||
if (nr != NULL)
|
||||
s->log |= nr->log & PF_LOG_ALL;
|
||||
|
|
@ -4706,6 +4712,7 @@ pf_create_state(struct pf_krule *r, struct pf_krule *nr, struct pf_krule *a,
|
|||
goto csfailed;
|
||||
}
|
||||
s->rt_kif = r->rpool.cur->kif;
|
||||
s->rt = r->rt;
|
||||
}
|
||||
|
||||
s->creation = time_uptime;
|
||||
|
|
@ -6441,9 +6448,20 @@ pf_route(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp,
|
|||
struct pf_ksrc_node *sn = NULL;
|
||||
int error = 0;
|
||||
uint16_t ip_len, ip_off;
|
||||
int r_rt, r_dir;
|
||||
|
||||
KASSERT(m && *m && r && oifp, ("%s: invalid parameters", __func__));
|
||||
KASSERT(dir == PF_IN || dir == PF_OUT, ("%s: invalid direction",
|
||||
|
||||
if (s) {
|
||||
r_rt = s->rt;
|
||||
r_dir = s->direction;
|
||||
} else {
|
||||
r_rt = r->rt;
|
||||
r_dir = r->direction;
|
||||
}
|
||||
|
||||
KASSERT(dir == PF_IN || dir == PF_OUT ||
|
||||
r_dir == PF_IN || r_dir == PF_OUT, ("%s: invalid direction",
|
||||
__func__));
|
||||
|
||||
if ((pd->pf_mtag == NULL &&
|
||||
|
|
@ -6454,7 +6472,7 @@ pf_route(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp,
|
|||
goto bad_locked;
|
||||
}
|
||||
|
||||
if (r->rt == PF_DUPTO) {
|
||||
if (r_rt == PF_DUPTO) {
|
||||
if ((pd->pf_mtag->flags & PF_DUPLICATED)) {
|
||||
if (s == NULL) {
|
||||
ifp = r->rpool.cur->kif ?
|
||||
|
|
@ -6484,7 +6502,7 @@ pf_route(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp,
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if ((r->rt == PF_REPLYTO) == (r->direction == dir)) {
|
||||
if ((r_rt == PF_REPLYTO) == (r_dir == dir)) {
|
||||
pf_dummynet(pd, dir, s, r, m);
|
||||
if (s)
|
||||
PF_STATE_UNLOCK(s);
|
||||
|
|
@ -6583,7 +6601,7 @@ pf_route(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp,
|
|||
if ((ip_off & IP_DF) || (m0->m_pkthdr.csum_flags & CSUM_TSO)) {
|
||||
error = EMSGSIZE;
|
||||
KMOD_IPSTAT_INC(ips_cantfrag);
|
||||
if (r->rt != PF_DUPTO) {
|
||||
if (r_rt != PF_DUPTO) {
|
||||
if (s && pd->nat_rule != NULL)
|
||||
PACKET_UNDO_NAT(m0, pd,
|
||||
(ip->ip_hl << 2) + (ip_off & IP_OFFMASK),
|
||||
|
|
@ -6619,7 +6637,7 @@ pf_route(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp,
|
|||
KMOD_IPSTAT_INC(ips_fragmented);
|
||||
|
||||
done:
|
||||
if (r->rt != PF_DUPTO)
|
||||
if (r_rt != PF_DUPTO)
|
||||
*m = NULL;
|
||||
return;
|
||||
|
||||
|
|
@ -6643,9 +6661,20 @@ pf_route6(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp,
|
|||
struct ifnet *ifp = NULL;
|
||||
struct pf_addr naddr;
|
||||
struct pf_ksrc_node *sn = NULL;
|
||||
int r_rt, r_dir;
|
||||
|
||||
KASSERT(m && *m && r && oifp, ("%s: invalid parameters", __func__));
|
||||
KASSERT(dir == PF_IN || dir == PF_OUT, ("%s: invalid direction",
|
||||
|
||||
if (s) {
|
||||
r_rt = s->rt;
|
||||
r_dir = s->direction;
|
||||
} else {
|
||||
r_rt = r->rt;
|
||||
r_dir = r->direction;
|
||||
}
|
||||
|
||||
KASSERT(dir == PF_IN || dir == PF_OUT ||
|
||||
r_dir == PF_IN || r_dir == PF_OUT, ("%s: invalid direction",
|
||||
__func__));
|
||||
|
||||
if ((pd->pf_mtag == NULL &&
|
||||
|
|
@ -6656,7 +6685,7 @@ pf_route6(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp,
|
|||
goto bad_locked;
|
||||
}
|
||||
|
||||
if (r->rt == PF_DUPTO) {
|
||||
if (r_rt == PF_DUPTO) {
|
||||
if ((pd->pf_mtag->flags & PF_DUPLICATED)) {
|
||||
if (s == NULL) {
|
||||
ifp = r->rpool.cur->kif ?
|
||||
|
|
@ -6686,7 +6715,7 @@ pf_route6(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp,
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if ((r->rt == PF_REPLYTO) == (r->direction == dir)) {
|
||||
if ((r_rt == PF_REPLYTO) == (r_dir == dir)) {
|
||||
pf_dummynet(pd, dir, s, r, m);
|
||||
if (s)
|
||||
PF_STATE_UNLOCK(s);
|
||||
|
|
@ -6770,7 +6799,7 @@ pf_route6(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp,
|
|||
}
|
||||
else {
|
||||
in6_ifstat_inc(ifp, ifs6_in_toobig);
|
||||
if (r->rt != PF_DUPTO) {
|
||||
if (r_rt != PF_DUPTO) {
|
||||
if (s && pd->nat_rule != NULL)
|
||||
PACKET_UNDO_NAT(m0, pd,
|
||||
((caddr_t)ip6 - m0->m_data) +
|
||||
|
|
@ -6782,7 +6811,7 @@ pf_route6(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp,
|
|||
}
|
||||
|
||||
done:
|
||||
if (r->rt != PF_DUPTO)
|
||||
if (r_rt != PF_DUPTO)
|
||||
*m = NULL;
|
||||
return;
|
||||
|
||||
|
|
@ -7102,7 +7131,18 @@ pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *
|
|||
struct pf_kstate *s = NULL;
|
||||
struct pf_kruleset *ruleset = NULL;
|
||||
struct pf_pdesc pd;
|
||||
int off, dirndx, pqid = 0;
|
||||
int off, dirndx;
|
||||
uint16_t scrub_flags;
|
||||
#ifdef ALTQ
|
||||
uint16_t qid;
|
||||
#endif
|
||||
uint16_t pqid;
|
||||
uint16_t tag;
|
||||
int32_t rtableid;
|
||||
uint8_t min_ttl;
|
||||
uint8_t set_tos;
|
||||
uint8_t rt;
|
||||
uint8_t set_prio[2];
|
||||
|
||||
PF_RULES_RLOCK_TRACKER;
|
||||
KASSERT(dir == PF_IN || dir == PF_OUT, ("%s: bad direction %d\n", __func__, dir));
|
||||
|
|
@ -7394,36 +7434,47 @@ done:
|
|||
}
|
||||
|
||||
if (s) {
|
||||
pf_scrub_ip(&m, s->state_flags, s->min_ttl, s->set_tos);
|
||||
if (s->rtableid >= 0)
|
||||
M_SETFIB(m, s->rtableid);
|
||||
scrub_flags = s->state_flags;
|
||||
min_ttl = s->min_ttl;
|
||||
set_tos = s->set_tos;
|
||||
rtableid = s->rtableid;
|
||||
pqid = s->pqid;
|
||||
#ifdef ALTQ
|
||||
if (s->qid) {
|
||||
pd.act.pqid = s->pqid;
|
||||
pd.act.qid = s->qid;
|
||||
}
|
||||
qid = s->qid;
|
||||
#endif
|
||||
tag = s->tag;
|
||||
rt = s->rt;
|
||||
set_prio[0] = s->set_prio[0];
|
||||
set_prio[1] = s->set_prio[1];
|
||||
} else {
|
||||
pf_scrub_ip(&m, r->scrub_flags, r->min_ttl, r->set_tos);
|
||||
if (r->rtableid >= 0)
|
||||
M_SETFIB(m, r->rtableid);
|
||||
scrub_flags = r->scrub_flags;
|
||||
min_ttl = r->min_ttl;
|
||||
set_tos = r->set_tos;
|
||||
rtableid = r->rtableid;
|
||||
pqid = r->pqid;
|
||||
#ifdef ALTQ
|
||||
if (r->qid) {
|
||||
pd.act.pqid = r->pqid;
|
||||
pd.act.qid = r->qid;
|
||||
}
|
||||
qid = r->qid;
|
||||
#endif
|
||||
tag = r->tag;
|
||||
rt = r->rt;
|
||||
set_prio[0] = r->set_prio[0];
|
||||
set_prio[1] = r->set_prio[1];
|
||||
}
|
||||
|
||||
if (s && s->tag > 0 && pf_tag_packet(m, &pd, s->tag)) {
|
||||
if (tag > 0 && pf_tag_packet(m, &pd, tag)) {
|
||||
action = PF_DROP;
|
||||
REASON_SET(&reason, PFRES_MEMORY);
|
||||
}
|
||||
|
||||
if (r->scrub_flags & PFSTATE_SETPRIO) {
|
||||
pf_scrub_ip(&m, scrub_flags, min_ttl, set_tos);
|
||||
|
||||
if (rtableid >= 0)
|
||||
M_SETFIB(m, rtableid);
|
||||
|
||||
if (scrub_flags & PFSTATE_SETPRIO) {
|
||||
if (pd.tos & IPTOS_LOWDELAY)
|
||||
pqid = 1;
|
||||
if (vlan_set_pcp(m, r->set_prio[pqid])) {
|
||||
if (vlan_set_pcp(m, set_prio[pqid])) {
|
||||
action = PF_DROP;
|
||||
REASON_SET(&reason, PFRES_MEMORY);
|
||||
log = PF_LOG_FORCE;
|
||||
|
|
@ -7433,6 +7484,11 @@ done:
|
|||
}
|
||||
|
||||
#ifdef ALTQ
|
||||
if (qid) {
|
||||
pd.act.pqid = pqid;
|
||||
pd.act.qid = qid;
|
||||
}
|
||||
|
||||
if (action == PF_PASS && pd.act.qid) {
|
||||
if (pd.pf_mtag == NULL &&
|
||||
((pd.pf_mtag = pf_get_mtag(m)) == NULL)) {
|
||||
|
|
@ -7604,7 +7660,7 @@ done:
|
|||
break;
|
||||
default:
|
||||
/* pf_route() returns unlocked. */
|
||||
if (r->rt) {
|
||||
if (rt) {
|
||||
pf_route(m0, r, dir, kif->pfik_ifp, s, &pd, inp);
|
||||
return (action);
|
||||
}
|
||||
|
|
@ -7637,7 +7693,18 @@ pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb
|
|||
struct pf_kstate *s = NULL;
|
||||
struct pf_kruleset *ruleset = NULL;
|
||||
struct pf_pdesc pd;
|
||||
int off, terminal = 0, dirndx, rh_cnt = 0, pqid = 0;
|
||||
int off, terminal = 0, dirndx, rh_cnt = 0;
|
||||
uint16_t scrub_flags;
|
||||
#ifdef ALTQ
|
||||
uint16_t qid;
|
||||
#endif
|
||||
uint16_t pqid;
|
||||
uint16_t tag;
|
||||
int32_t rtableid;
|
||||
uint8_t min_ttl;
|
||||
uint8_t set_tos;
|
||||
uint8_t rt;
|
||||
uint8_t set_prio[2];
|
||||
|
||||
PF_RULES_RLOCK_TRACKER;
|
||||
KASSERT(dir == PF_IN || dir == PF_OUT, ("%s: bad direction %d\n", __func__, dir));
|
||||
|
|
@ -7925,37 +7992,48 @@ done:
|
|||
("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;
|
||||
#ifdef ALTQ
|
||||
qid = s->qid;
|
||||
#endif
|
||||
tag = s->tag;
|
||||
rt = s->rt;
|
||||
set_prio[0] = s->set_prio[0];
|
||||
set_prio[1] = s->set_prio[1];
|
||||
} else {
|
||||
scrub_flags = r->scrub_flags;
|
||||
min_ttl = r->min_ttl;
|
||||
set_tos = r->set_tos;
|
||||
rtableid = r->rtableid;
|
||||
pqid = r->pqid;
|
||||
#ifdef ALTQ
|
||||
qid = r->qid;
|
||||
#endif
|
||||
tag = r->tag;
|
||||
rt = r->rt;
|
||||
set_prio[0] = r->set_prio[0];
|
||||
set_prio[1] = r->set_prio[1];
|
||||
}
|
||||
|
||||
if (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;
|
||||
|
|
@ -7965,6 +8043,11 @@ done:
|
|||
}
|
||||
|
||||
#ifdef ALTQ
|
||||
if (qid) {
|
||||
pd.act.pqid = pqid;
|
||||
pd.act.qid = qid;
|
||||
}
|
||||
|
||||
if (action == PF_PASS && pd.act.qid) {
|
||||
if (pd.pf_mtag == NULL &&
|
||||
((pd.pf_mtag = pf_get_mtag(m)) == NULL)) {
|
||||
|
|
@ -8084,7 +8167,7 @@ done:
|
|||
break;
|
||||
default:
|
||||
/* pf_route6() returns unlocked. */
|
||||
if (r->rt) {
|
||||
if (rt) {
|
||||
pf_route6(m0, r, dir, kif->pfik_ifp, s, &pd, inp);
|
||||
return (action);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3720,8 +3720,8 @@ DIOCCHANGERULE_error:
|
|||
}
|
||||
|
||||
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 @@ DIOCCHANGERULE_error:
|
|||
}
|
||||
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 @@ DIOCCHANGERULE_error:
|
|||
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 @@ DIOCCHANGERULE_error:
|
|||
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 @@ DIOCGETSTATES_retry:
|
|||
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 @@ DIOCGETSTATES_retry:
|
|||
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 @@ fail:
|
|||
}
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ pfsync_nvstatus_to_kstatus(const nvlist_t *nvl, struct pfsync_kstatus *status)
|
|||
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"))
|
||||
|
|
|
|||
|
|
@ -81,9 +81,9 @@ static void sidewaysintpr(void);
|
|||
#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 @@ static const char* pfsyncacts[] = {
|
|||
/* 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 @@ static const char* pfsyncacts_name[] = {
|
|||
/* 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
|
||||
|
|
|
|||
Loading…
Reference in a new issue