mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-21 10:41:46 +01:00
Merge branch 'freebsd/current/main' into hardened/current/master
This commit is contained in:
commit
1d31df19f2
1
.gitignore
vendored
1
.gitignore
vendored
@ -31,3 +31,4 @@ tags
|
||||
.cache
|
||||
.clangd
|
||||
.ccls-cache
|
||||
sys/*/compile
|
||||
|
21
UPDATING
21
UPDATING
@ -27,6 +27,27 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 15.x IS SLOW:
|
||||
world, or to merely disable the most expensive debugging functionality
|
||||
at runtime, run "ln -s 'abort:false,junk:false' /etc/malloc.conf".)
|
||||
|
||||
20240202:
|
||||
Loader now also read configuration files listed in local_loader_conf_files.
|
||||
Files listed here are the last ones read. And /boot/loader.conf.local was
|
||||
moved from loader_conf_files to local_loader_conf_files leaving only
|
||||
loader.conf and device.hints in loader_conf_files by default.
|
||||
|
||||
The following sequencing is applied:
|
||||
|
||||
1. Bootstrap:
|
||||
/boot/defaults/loader.conf
|
||||
|
||||
2. Read loader_conf_files files:
|
||||
/boot/device.hints
|
||||
/boot/loader.conf
|
||||
|
||||
3. Read loader_conf_dirs files:
|
||||
/boot/loader.conf.d/*.conf
|
||||
|
||||
4. And finally, rread local_loader_conf_files files:
|
||||
/boot/loader.conf.local
|
||||
|
||||
20240201:
|
||||
sendmail 8.18.1 has been imported and merged. This version enforces
|
||||
stricter RFC compliance by default, especially with respect to line
|
||||
|
@ -84,9 +84,9 @@ extern int __mb_cur_max;
|
||||
extern int ___mb_cur_max(void);
|
||||
#define MB_CUR_MAX ((size_t)___mb_cur_max())
|
||||
|
||||
_Noreturn void abort(void);
|
||||
_Noreturn void abort(void) __noexcept;
|
||||
int abs(int) __pure2;
|
||||
int atexit(void (* _Nonnull)(void));
|
||||
int atexit(void (* _Nonnull)(void)) __noexcept;
|
||||
double atof(const char *);
|
||||
int atoi(const char *);
|
||||
long atol(const char *);
|
||||
@ -154,7 +154,7 @@ unsigned long long
|
||||
strtoull(const char * __restrict, char ** __restrict, int);
|
||||
#endif /* __LONG_LONG_SUPPORTED */
|
||||
|
||||
_Noreturn void _Exit(int);
|
||||
_Noreturn void _Exit(int) __noexcept;
|
||||
#endif /* __ISO_C_VISIBLE >= 1999 */
|
||||
|
||||
/*
|
||||
@ -163,9 +163,9 @@ _Noreturn void _Exit(int);
|
||||
#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L
|
||||
void * aligned_alloc(size_t, size_t) __malloc_like __alloc_align(1)
|
||||
__alloc_size(2);
|
||||
int at_quick_exit(void (*)(void));
|
||||
int at_quick_exit(void (*)(void)) __noexcept;
|
||||
_Noreturn void
|
||||
quick_exit(int);
|
||||
quick_exit(int) __noexcept;
|
||||
#endif /* __ISO_C_VISIBLE >= 2011 */
|
||||
/*
|
||||
* Extensions made by POSIX relative to C.
|
||||
|
@ -40,21 +40,21 @@
|
||||
* to jump around to use more capable unconditional branch
|
||||
* instruction.
|
||||
*/
|
||||
#define PSEUDO(name) \
|
||||
ENTRY(__sys_##name); \
|
||||
WEAK_REFERENCE(__sys_##name, _##name); \
|
||||
#define _SYSCALL_BODY(name) \
|
||||
_SYSCALL(name); \
|
||||
b.cs 1f; \
|
||||
ret; \
|
||||
1: b cerror; \
|
||||
1: b cerror
|
||||
|
||||
#define PSEUDO(name) \
|
||||
ENTRY(__sys_##name); \
|
||||
WEAK_REFERENCE(__sys_##name, _##name); \
|
||||
_SYSCALL_BODY(name); \
|
||||
END(__sys_##name)
|
||||
|
||||
#define RSYSCALL(name) \
|
||||
ENTRY(__sys_##name); \
|
||||
WEAK_REFERENCE(__sys_##name, name); \
|
||||
WEAK_REFERENCE(__sys_##name, _##name); \
|
||||
_SYSCALL(name); \
|
||||
b.cs 1f; \
|
||||
ret; \
|
||||
1: b cerror; \
|
||||
_SYSCALL_BODY(name); \
|
||||
END(__sys_##name)
|
||||
|
@ -321,7 +321,7 @@ regcomp_internal(regex_t * __restrict preg,
|
||||
computejumps(p, g);
|
||||
computematchjumps(p, g);
|
||||
if(g->matchjump == NULL && g->charjump != NULL) {
|
||||
free(g->charjump);
|
||||
free(&g->charjump[CHAR_MIN]);
|
||||
g->charjump = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -965,8 +965,8 @@ snl_add_msg_attr_rule_labels(struct snl_writer *nw, uint32_t type, const char la
|
||||
|
||||
off = snl_add_msg_attr_nested(nw, type);
|
||||
|
||||
while (labels[i][0] != 0 &&
|
||||
i < PF_RULE_MAX_LABEL_COUNT) {
|
||||
while (i < PF_RULE_MAX_LABEL_COUNT &&
|
||||
labels[i][0] != 0) {
|
||||
snl_add_msg_attr_string(nw, PF_LT_LABEL, labels[i]);
|
||||
i++;
|
||||
}
|
||||
@ -1229,7 +1229,287 @@ pfctl_get_rule(int dev, uint32_t nr, uint32_t ticket, const char *anchor,
|
||||
anchor_call, false));
|
||||
}
|
||||
|
||||
int pfctl_get_clear_rule(int dev, uint32_t nr, uint32_t ticket,
|
||||
#define _OUT(_field) offsetof(struct pf_addr_wrap, _field)
|
||||
static const struct snl_attr_parser ap_addr_wrap[] = {
|
||||
{ .type = PF_AT_ADDR, .off = _OUT(v.a.addr), .cb = snl_attr_get_in6_addr },
|
||||
{ .type = PF_AT_MASK, .off = _OUT(v.a.mask), .cb = snl_attr_get_in6_addr },
|
||||
{ .type = PF_AT_IFNAME, .off = _OUT(v.ifname), .arg = (void *)IFNAMSIZ,.cb = snl_attr_copy_string },
|
||||
{ .type = PF_AT_TABLENAME, .off = _OUT(v.tblname), .arg = (void *)PF_TABLE_NAME_SIZE, .cb = snl_attr_copy_string },
|
||||
{ .type = PF_AT_TYPE, .off = _OUT(type), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_AT_IFLAGS, .off = _OUT(iflags), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_AT_TBLCNT, .off = _OUT(p.tblcnt), .cb = snl_attr_get_uint32 },
|
||||
{ .type = PF_AT_DYNCNT, .off = _OUT(p.dyncnt), .cb = snl_attr_get_uint32 },
|
||||
};
|
||||
SNL_DECLARE_ATTR_PARSER(addr_wrap_parser, ap_addr_wrap);
|
||||
#undef _OUT
|
||||
|
||||
#define _OUT(_field) offsetof(struct pf_rule_addr, _field)
|
||||
static struct snl_attr_parser ap_rule_addr[] = {
|
||||
{ .type = PF_RAT_ADDR, .off = _OUT(addr), .arg = &addr_wrap_parser, .cb = snl_attr_get_nested },
|
||||
{ .type = PF_RAT_SRC_PORT, .off = _OUT(port[0]), .cb = snl_attr_get_uint16 },
|
||||
{ .type = PF_RAT_DST_PORT, .off = _OUT(port[1]), .cb = snl_attr_get_uint16 },
|
||||
{ .type = PF_RAT_NEG, .off = _OUT(neg), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RAT_OP, .off = _OUT(port_op), .cb = snl_attr_get_uint8 },
|
||||
};
|
||||
#undef _OUT
|
||||
SNL_DECLARE_ATTR_PARSER(rule_addr_parser, ap_rule_addr);
|
||||
|
||||
struct snl_parsed_labels
|
||||
{
|
||||
char labels[PF_RULE_MAX_LABEL_COUNT][PF_RULE_LABEL_SIZE];
|
||||
uint32_t i;
|
||||
};
|
||||
|
||||
static bool
|
||||
snl_attr_get_pf_rule_labels(struct snl_state *ss, struct nlattr *nla,
|
||||
const void *arg __unused, void *target)
|
||||
{
|
||||
struct snl_parsed_labels *l = (struct snl_parsed_labels *)target;
|
||||
bool ret;
|
||||
|
||||
if (l->i >= PF_RULE_MAX_LABEL_COUNT)
|
||||
return (E2BIG);
|
||||
|
||||
ret = snl_attr_copy_string(ss, nla, (void *)PF_RULE_LABEL_SIZE,
|
||||
l->labels[l->i]);
|
||||
if (ret)
|
||||
l->i++;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#define _OUT(_field) offsetof(struct nl_parsed_labels, _field)
|
||||
static const struct snl_attr_parser ap_labels[] = {
|
||||
{ .type = PF_LT_LABEL, .off = 0, .cb = snl_attr_get_pf_rule_labels },
|
||||
};
|
||||
SNL_DECLARE_ATTR_PARSER(rule_labels_parser, ap_labels);
|
||||
#undef _OUT
|
||||
|
||||
static bool
|
||||
snl_attr_get_nested_pf_rule_labels(struct snl_state *ss, struct nlattr *nla,
|
||||
const void *arg __unused, void *target)
|
||||
{
|
||||
struct snl_parsed_labels parsed_labels = { };
|
||||
bool error;
|
||||
|
||||
/* Assumes target points to the beginning of the structure */
|
||||
error = snl_parse_header(ss, NLA_DATA(nla), NLA_DATA_LEN(nla), &rule_labels_parser, &parsed_labels);
|
||||
if (! error)
|
||||
return (error);
|
||||
|
||||
memcpy(target, parsed_labels.labels, sizeof(parsed_labels));
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
#define _OUT(_field) offsetof(struct pf_mape_portset, _field)
|
||||
static const struct snl_attr_parser ap_mape_portset[] = {
|
||||
{ .type = PF_MET_OFFSET, .off = _OUT(offset), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_MET_PSID_LEN, .off = _OUT(psidlen), .cb = snl_attr_get_uint8 },
|
||||
{. type = PF_MET_PSID, .off = _OUT(psid), .cb = snl_attr_get_uint16 },
|
||||
};
|
||||
SNL_DECLARE_ATTR_PARSER(mape_portset_parser, ap_mape_portset);
|
||||
#undef _OUT
|
||||
|
||||
#define _OUT(_field) offsetof(struct pfctl_pool, _field)
|
||||
static const struct snl_attr_parser ap_pool[] = {
|
||||
{ .type = PF_PT_KEY, .off = _OUT(key), .arg = (void *)sizeof(struct pf_poolhashkey), .cb = snl_attr_get_bytes },
|
||||
{ .type = PF_PT_COUNTER, .off = _OUT(counter), .cb = snl_attr_get_in6_addr },
|
||||
{ .type = PF_PT_TBLIDX, .off = _OUT(tblidx), .cb = snl_attr_get_uint32 },
|
||||
{ .type = PF_PT_PROXY_SRC_PORT, .off = _OUT(proxy_port[0]), .cb = snl_attr_get_uint16 },
|
||||
{ .type = PF_PT_PROXY_DST_PORT, .off = _OUT(proxy_port[1]), .cb = snl_attr_get_uint16 },
|
||||
{ .type = PF_PT_OPTS, .off = _OUT(opts), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_PT_MAPE, .off = _OUT(mape), .arg = &mape_portset_parser, .cb = snl_attr_get_nested },
|
||||
};
|
||||
SNL_DECLARE_ATTR_PARSER(pool_parser, ap_pool);
|
||||
#undef _OUT
|
||||
|
||||
struct nl_parsed_timeouts
|
||||
{
|
||||
uint32_t timeouts[PFTM_MAX];
|
||||
uint32_t i;
|
||||
};
|
||||
|
||||
static bool
|
||||
snl_attr_get_pf_timeout(struct snl_state *ss, struct nlattr *nla,
|
||||
const void *arg __unused, void *target)
|
||||
{
|
||||
struct nl_parsed_timeouts *t = (struct nl_parsed_timeouts *)target;
|
||||
bool ret;
|
||||
|
||||
if (t->i >= PFTM_MAX)
|
||||
return (E2BIG);
|
||||
|
||||
ret = snl_attr_get_uint32(ss, nla, NULL, &t->timeouts[t->i]);
|
||||
if (ret)
|
||||
t->i++;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#define _OUT(_field) offsetof(struct nl_parsed_timeout, _field)
|
||||
static const struct snl_attr_parser ap_timeouts[] = {
|
||||
{ .type = PF_TT_TIMEOUT, .off = 0, .cb = snl_attr_get_pf_timeout },
|
||||
};
|
||||
SNL_DECLARE_ATTR_PARSER(timeout_parser, ap_timeouts);
|
||||
#undef _OUT
|
||||
|
||||
static bool
|
||||
snl_attr_get_nested_timeouts(struct snl_state *ss, struct nlattr *nla,
|
||||
const void *arg __unused, void *target)
|
||||
{
|
||||
struct nl_parsed_timeouts parsed_timeouts = { };
|
||||
bool error;
|
||||
|
||||
/* Assumes target points to the beginning of the structure */
|
||||
error = snl_parse_header(ss, NLA_DATA(nla), NLA_DATA_LEN(nla), &timeout_parser, &parsed_timeouts);
|
||||
if (! error)
|
||||
return (error);
|
||||
|
||||
memcpy(target, parsed_timeouts.timeouts, sizeof(parsed_timeouts.timeouts));
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
#define _OUT(_field) offsetof(struct pf_rule_uid, _field)
|
||||
static const struct snl_attr_parser ap_rule_uid[] = {
|
||||
{ .type = PF_RUT_UID_LOW, .off = _OUT(uid[0]), .cb = snl_attr_get_uint32 },
|
||||
{ .type = PF_RUT_UID_HIGH, .off = _OUT(uid[1]), .cb = snl_attr_get_uint32 },
|
||||
{ .type = PF_RUT_OP, .off = _OUT(op), .cb = snl_attr_get_uint8 },
|
||||
};
|
||||
SNL_DECLARE_ATTR_PARSER(rule_uid_parser, ap_rule_uid);
|
||||
#undef _OUT
|
||||
|
||||
struct pfctl_nl_get_rule {
|
||||
struct pfctl_rule r;
|
||||
char anchor_call[MAXPATHLEN];
|
||||
};
|
||||
#define _OUT(_field) offsetof(struct pfctl_nl_get_rule, _field)
|
||||
static struct snl_attr_parser ap_getrule[] = {
|
||||
{ .type = PF_RT_SRC, .off = _OUT(r.src), .arg = &rule_addr_parser,.cb = snl_attr_get_nested },
|
||||
{ .type = PF_RT_DST, .off = _OUT(r.dst), .arg = &rule_addr_parser,.cb = snl_attr_get_nested },
|
||||
{ .type = PF_RT_RIDENTIFIER, .off = _OUT(r.ridentifier), .cb = snl_attr_get_uint32 },
|
||||
{ .type = PF_RT_LABELS, .off = _OUT(r.label), .arg = &rule_labels_parser,.cb = snl_attr_get_nested_pf_rule_labels },
|
||||
{ .type = PF_RT_IFNAME, .off = _OUT(r.ifname), .arg = (void *)IFNAMSIZ, .cb = snl_attr_copy_string },
|
||||
{ .type = PF_RT_QNAME, .off = _OUT(r.qname), .arg = (void *)PF_QNAME_SIZE, .cb = snl_attr_copy_string },
|
||||
{ .type = PF_RT_PQNAME, .off = _OUT(r.pqname), .arg = (void *)PF_QNAME_SIZE, .cb = snl_attr_copy_string },
|
||||
{ .type = PF_RT_TAGNAME, .off = _OUT(r.tagname), .arg = (void *)PF_TAG_NAME_SIZE, .cb = snl_attr_copy_string },
|
||||
{ .type = PF_RT_MATCH_TAGNAME, .off = _OUT(r.match_tagname), .arg = (void *)PF_TAG_NAME_SIZE, .cb = snl_attr_copy_string },
|
||||
{ .type = PF_RT_OVERLOAD_TBLNAME, .off = _OUT(r.overload_tblname), .arg = (void *)PF_TABLE_NAME_SIZE, .cb = snl_attr_copy_string },
|
||||
{ .type = PF_RT_RPOOL, .off = _OUT(r.rpool), .arg = &pool_parser, .cb = snl_attr_get_nested },
|
||||
{ .type = PF_RT_OS_FINGERPRINT, .off = _OUT(r.os_fingerprint), .cb = snl_attr_get_uint32 },
|
||||
{ .type = PF_RT_RTABLEID, .off = _OUT(r.rtableid), .cb = snl_attr_get_uint32 },
|
||||
{ .type = PF_RT_TIMEOUT, .off = _OUT(r.timeout), .arg = &timeout_parser, .cb = snl_attr_get_nested_timeouts },
|
||||
{ .type = PF_RT_MAX_STATES, .off = _OUT(r.max_states), .cb = snl_attr_get_uint32 },
|
||||
{ .type = PF_RT_MAX_SRC_NODES, .off = _OUT(r.max_src_nodes), .cb = snl_attr_get_uint32 },
|
||||
{ .type = PF_RT_MAX_SRC_STATES, .off = _OUT(r.max_src_states), .cb = snl_attr_get_uint32 },
|
||||
{ .type = PF_RT_MAX_SRC_CONN_RATE_LIMIT, .off = _OUT(r.max_src_conn_rate.limit), .cb = snl_attr_get_uint32 },
|
||||
{ .type = PF_RT_MAX_SRC_CONN_RATE_SECS, .off = _OUT(r.max_src_conn_rate.seconds), .cb = snl_attr_get_uint32 },
|
||||
{ .type = PF_RT_DNPIPE, .off = _OUT(r.dnpipe), .cb = snl_attr_get_uint16 },
|
||||
{ .type = PF_RT_DNRPIPE, .off = _OUT(r.dnrpipe), .cb = snl_attr_get_uint16 },
|
||||
{ .type = PF_RT_DNFLAGS, .off = _OUT(r.free_flags), .cb = snl_attr_get_uint32 },
|
||||
{ .type = PF_RT_NR, .off = _OUT(r.nr), .cb = snl_attr_get_uint32 },
|
||||
{ .type = PF_RT_PROB, .off = _OUT(r.prob), .cb = snl_attr_get_uint32 },
|
||||
{ .type = PF_RT_CUID, .off = _OUT(r.cuid), .cb = snl_attr_get_uint32 },
|
||||
{. type = PF_RT_CPID, .off = _OUT(r.cpid), .cb = snl_attr_get_uint32 },
|
||||
{ .type = PF_RT_RETURN_ICMP, .off = _OUT(r.return_icmp), .cb = snl_attr_get_uint16 },
|
||||
{ .type = PF_RT_RETURN_ICMP6, .off = _OUT(r.return_icmp6), .cb = snl_attr_get_uint16 },
|
||||
{ .type = PF_RT_MAX_MSS, .off = _OUT(r.max_mss), .cb = snl_attr_get_uint16 },
|
||||
{ .type = PF_RT_SCRUB_FLAGS, .off = _OUT(r.scrub_flags), .cb = snl_attr_get_uint16 },
|
||||
{ .type = PF_RT_UID, .off = _OUT(r.uid), .arg = &rule_uid_parser, .cb = snl_attr_get_nested },
|
||||
{ .type = PF_RT_GID, .off = _OUT(r.gid), .arg = &rule_uid_parser, .cb = snl_attr_get_nested },
|
||||
{ .type = PF_RT_RULE_FLAG, .off = _OUT(r.rule_flag), .cb = snl_attr_get_uint32 },
|
||||
{ .type = PF_RT_ACTION, .off = _OUT(r.action), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_DIRECTION, .off = _OUT(r.direction), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_LOG, .off = _OUT(r.log), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_LOGIF, .off = _OUT(r.logif), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_QUICK, .off = _OUT(r.quick), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_IF_NOT, .off = _OUT(r.ifnot), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_MATCH_TAG_NOT, .off = _OUT(r.match_tag_not), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_NATPASS, .off = _OUT(r.natpass), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_KEEP_STATE, .off = _OUT(r.keep_state), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_AF, .off = _OUT(r.af), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_PROTO, .off = _OUT(r.proto), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_TYPE, .off = _OUT(r.type), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_CODE, .off = _OUT(r.code), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_FLAGS, .off = _OUT(r.flags), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_FLAGSET, .off = _OUT(r.flagset), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_MIN_TTL, .off = _OUT(r.min_ttl), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_ALLOW_OPTS, .off = _OUT(r.allow_opts), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_RT, .off = _OUT(r.rt), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_RETURN_TTL, .off = _OUT(r.return_ttl), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_TOS, .off = _OUT(r.tos), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_SET_TOS, .off = _OUT(r.set_tos), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_ANCHOR_RELATIVE, .off = _OUT(r.anchor_relative), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_ANCHOR_WILDCARD, .off = _OUT(r.anchor_wildcard), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_FLUSH, .off = _OUT(r.flush), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_PRIO, .off = _OUT(r.prio), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_SET_PRIO, .off = _OUT(r.set_prio[0]), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_SET_PRIO_REPLY, .off = _OUT(r.set_prio[1]), .cb = snl_attr_get_uint8 },
|
||||
{ .type = PF_RT_DIVERT_ADDRESS, .off = _OUT(r.divert.addr), .cb = snl_attr_get_in6_addr },
|
||||
{ .type = PF_RT_DIVERT_PORT, .off = _OUT(r.divert.port), .cb = snl_attr_get_uint16 },
|
||||
{ .type = PF_RT_PACKETS_IN, .off = _OUT(r.packets[0]), .cb = snl_attr_get_uint64 },
|
||||
{ .type = PF_RT_PACKETS_OUT, .off = _OUT(r.packets[1]), .cb = snl_attr_get_uint64 },
|
||||
{ .type = PF_RT_BYTES_IN, .off = _OUT(r.bytes[0]), .cb = snl_attr_get_uint64 },
|
||||
{ .type = PF_RT_BYTES_OUT, .off = _OUT(r.bytes[1]), .cb = snl_attr_get_uint64 },
|
||||
{ .type = PF_RT_EVALUATIONS, .off = _OUT(r.evaluations), .cb = snl_attr_get_uint64 },
|
||||
{ .type = PF_RT_TIMESTAMP, .off = _OUT(r.last_active_timestamp), .cb = snl_attr_get_uint64 },
|
||||
{ .type = PF_RT_STATES_CUR, .off = _OUT(r.states_cur), .cb = snl_attr_get_uint64 },
|
||||
{ .type = PF_RT_STATES_TOTAL, .off = _OUT(r.states_tot), .cb = snl_attr_get_uint64 },
|
||||
{ .type = PF_RT_SRC_NODES, .off = _OUT(r.src_nodes), .cb = snl_attr_get_uint64 },
|
||||
{ .type = PF_RT_ANCHOR_CALL, .off = _OUT(anchor_call), .arg = (void*)MAXPATHLEN, .cb = snl_attr_copy_string },
|
||||
};
|
||||
static struct snl_field_parser fp_getrule[] = {};
|
||||
#undef _OUT
|
||||
SNL_DECLARE_PARSER(getrule_parser, struct genlmsghdr, fp_getrule, ap_getrule);
|
||||
|
||||
int
|
||||
pfctl_get_clear_rule_h(struct pfctl_handle *h, uint32_t nr, uint32_t ticket,
|
||||
const char *anchor, uint32_t ruleset, struct pfctl_rule *rule,
|
||||
char *anchor_call, bool clear)
|
||||
{
|
||||
struct pfctl_nl_get_rule attrs = {};
|
||||
struct snl_errmsg_data e = {};
|
||||
struct nlmsghdr *hdr;
|
||||
struct snl_writer nw;
|
||||
uint32_t seq_id;
|
||||
int family_id;
|
||||
|
||||
family_id = snl_get_genl_family(&h->ss, PFNL_FAMILY_NAME);
|
||||
if (family_id == 0)
|
||||
return (ENOTSUP);
|
||||
|
||||
snl_init_writer(&h->ss, &nw);
|
||||
hdr = snl_create_genl_msg_request(&nw, family_id, PFNL_CMD_GETRULE);
|
||||
hdr->nlmsg_flags |= NLM_F_DUMP;
|
||||
|
||||
snl_add_msg_attr_string(&nw, PF_GR_ANCHOR, anchor);
|
||||
snl_add_msg_attr_u8(&nw, PF_GR_ACTION, ruleset);
|
||||
snl_add_msg_attr_u32(&nw, PF_GR_NR, nr);
|
||||
snl_add_msg_attr_u32(&nw, PF_GR_TICKET, ticket);
|
||||
snl_add_msg_attr_u8(&nw, PF_GR_CLEAR, clear);
|
||||
|
||||
hdr = snl_finalize_msg(&nw);
|
||||
if (hdr == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
seq_id = hdr->nlmsg_seq;
|
||||
if (! snl_send_message(&h->ss, hdr))
|
||||
return (ENXIO);
|
||||
|
||||
while ((hdr = snl_read_reply_multi(&h->ss, seq_id, &e)) != NULL) {
|
||||
if (! snl_parse_nlmsg(&h->ss, hdr, &getrule_parser, &attrs))
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(rule, &attrs.r, sizeof(attrs.r));
|
||||
strlcpy(anchor_call, attrs.anchor_call, MAXPATHLEN);
|
||||
|
||||
return (e.error);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_get_clear_rule(int dev, uint32_t nr, uint32_t ticket,
|
||||
const char *anchor, uint32_t ruleset, struct pfctl_rule *rule,
|
||||
char *anchor_call, bool clear)
|
||||
{
|
||||
|
@ -418,6 +418,9 @@ int pfctl_get_rule(int dev, uint32_t nr, uint32_t ticket,
|
||||
int pfctl_get_clear_rule(int dev, uint32_t nr, uint32_t ticket,
|
||||
const char *anchor, uint32_t ruleset, struct pfctl_rule *rule,
|
||||
char *anchor_call, bool clear);
|
||||
int pfctl_get_clear_rule_h(struct pfctl_handle *h, uint32_t nr, uint32_t ticket,
|
||||
const char *anchor, uint32_t ruleset, struct pfctl_rule *rule,
|
||||
char *anchor_call, bool clear);
|
||||
int pfctl_add_rule(int dev, const struct pfctl_rule *r,
|
||||
const char *anchor, const char *anchor_call, uint32_t ticket,
|
||||
uint32_t pool_ticket);
|
||||
|
@ -238,6 +238,7 @@ _thr_rtld_init(void)
|
||||
|
||||
mprotect(NULL, 0, 0);
|
||||
_rtld_get_stack_prot();
|
||||
thr_wake(-1);
|
||||
|
||||
li.rtli_version = RTLI_VERSION;
|
||||
li.lock_create = _thr_rtld_lock_create;
|
||||
|
@ -2662,8 +2662,8 @@ static void
|
||||
load_filtees(Obj_Entry *obj, int flags, RtldLockState *lockstate)
|
||||
{
|
||||
|
||||
lock_restart_for_upgrade(lockstate);
|
||||
if (!obj->filtees_loaded) {
|
||||
lock_restart_for_upgrade(lockstate);
|
||||
load_filtee1(obj, obj->needed_filtees, flags, lockstate);
|
||||
load_filtee1(obj, obj->needed_aux_filtees, flags, lockstate);
|
||||
obj->filtees_loaded = true;
|
||||
|
@ -1303,7 +1303,7 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
|
||||
}
|
||||
|
||||
for (nr = 0; nr < ri.nr; ++nr) {
|
||||
if (pfctl_get_clear_rule(dev, nr, ri.ticket, path, PF_SCRUB,
|
||||
if (pfctl_get_clear_rule_h(pfh, nr, ri.ticket, path, PF_SCRUB,
|
||||
&rule, anchor_call, opts & PF_OPT_CLRRULECTRS)) {
|
||||
warn("DIOCGETRULENV");
|
||||
goto error;
|
||||
@ -1334,7 +1334,7 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
|
||||
goto error;
|
||||
}
|
||||
for (nr = 0; nr < ri.nr; ++nr) {
|
||||
if (pfctl_get_clear_rule(dev, nr, ri.ticket, path, PF_PASS,
|
||||
if (pfctl_get_clear_rule_h(pfh, nr, ri.ticket, path, PF_PASS,
|
||||
&rule, anchor_call, opts & PF_OPT_CLRRULECTRS)) {
|
||||
warn("DIOCGETRULE");
|
||||
goto error;
|
||||
|
@ -1,528 +0,0 @@
|
||||
USAGE
|
||||
KAME Project
|
||||
$KAME: USAGE,v 1.33 2000/11/22 10:22:57 itojun Exp $
|
||||
|
||||
This is an introduction of how to use the commands provided in the KAME
|
||||
kit. For more information, please refer to each man page.
|
||||
|
||||
|
||||
<<<ifconfig>>>
|
||||
|
||||
A link-local address is automatically assigned to each interface, when
|
||||
the interface becomes up for the first time. Even if you find an interface
|
||||
without a link-local address, do not panic. The link-local address will be
|
||||
assigned when it becomes up (with "ifconfig IF up").
|
||||
|
||||
If you do not see a link-local address assigned to an interface on "ifconfig
|
||||
up", the interface does not support IPv6 for some reasons - for example,
|
||||
if the interface does not support link-layer multicast (IFF_MULTICAST is not
|
||||
set), the interface cannot be used for IPv6.
|
||||
|
||||
Some network drivers allow an interface to become up even without a
|
||||
hardware address (for example, PCMCIA network cards). In such cases, it is
|
||||
possible that an interface has no link-local address even if the
|
||||
interface is up. If you see such situation, please disable the
|
||||
interface once and then re-enable it (i.e. do `ifconfig IF down;
|
||||
ifconfig IF up').
|
||||
|
||||
Pseudo interfaces (like "gif" tunnel device) will borrow IPv6
|
||||
interface identifier (lowermost 64bit of the address) from
|
||||
EUI64/IEEE802 sources, like ethernet cards. Pseudo interfaces will be
|
||||
able to get an IPv6 link-local address, if you have other "real"
|
||||
interface configured beforehand. If you have no EUI64/IEEE802 sources
|
||||
on the node, we have last-resort code in the kernel, which generates
|
||||
interface identifier from MD5(hostname). MD5(hostname) may not be suitable
|
||||
for your usage (for example, if you configure same hostname on both sides of
|
||||
gif tunnel, you will be doomed), and if so, you may need to configure
|
||||
link-local address manually.
|
||||
See RFC2472 for more discussion on how to generate an interface ID for
|
||||
pseudo interfaces.
|
||||
|
||||
If you have a router announcing Router Advertisement,
|
||||
global addresses will be assigned automatically. So, neither
|
||||
"ifconfig" nor "prefix" is necessary for your *host* (non-router node).
|
||||
(Please refer to "sysctl" section for configuring a host to accept
|
||||
Router Advertisement.)
|
||||
|
||||
If you want to set up a router, you need to assign global addresses
|
||||
for two or more interfaces by "ifconfig" or "prefix" (prefix command
|
||||
is described at next section).
|
||||
If you want to assign a global address by "ifconfig", don't forget to
|
||||
specify the "alias" argument to keep the link-local address.
|
||||
|
||||
# ifconfig de0 inet6 3ffe:501:808:1:200:f8ff:fe01:6317 prefixlen 64 alias
|
||||
# ifconfig de0
|
||||
de0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
|
||||
inet6 fe80::200:f8ff:fe01:6317%de0 prefixlen 64 scopeid 0x1
|
||||
inet 163.221.202.12 netmask 0xffffff00 broadcast 163.221.202.255
|
||||
inet6 3ffe:501:808:1:200:f8ff:fe01:6317 prefixlen 64
|
||||
ether 00:00:f8:01:63:17
|
||||
media: 100baseTX status: active
|
||||
|
||||
See also "/etc/rc.network6" for actual examples.
|
||||
|
||||
<<prefix>>
|
||||
|
||||
In the IPv6 architecture, an IPv6 address of an interface can be
|
||||
generated from a prefix assigned to the interface, and a
|
||||
link-dependent identifier for the interface. So assigning a full IPv6
|
||||
address by ifconfig is not necessary anymore, because user can only
|
||||
take care of prefix, by letting system take care of interface
|
||||
identifier.
|
||||
|
||||
The newly added "prefix" command enables user to just assign prefixes
|
||||
for interfaces, and let your system automatically generate IPv6
|
||||
addresses. Prefixes added by the "prefix" command is maintained in
|
||||
the kernel consistently with prefixes assigned by Router
|
||||
Advertisement (in case of hosts) and with prefixes assigned by Router
|
||||
Renumbering (in case of routers). Manual assignment of prefixes or
|
||||
change of prefix properties take precedence over ones assigned by
|
||||
Router Advertisement or Router Renumbering.
|
||||
|
||||
prefix command works only on routers.
|
||||
|
||||
If you want to assign a prefix (and consequently address) manually, do
|
||||
as follows:
|
||||
|
||||
# ifconfig de0
|
||||
de0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
|
||||
inet6 fe80::200:f8ff:fe01:6317%de0 prefixlen 64 scopeid 0x1
|
||||
inet 163.221.202.12 netmask 0xffffff00 broadcast 163.221.202.255
|
||||
ether 00:00:f8:01:63:17
|
||||
media: 100baseTX status: active
|
||||
# prefix de0 3ffe:501:808:1::
|
||||
# ifconfig de0
|
||||
de0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
|
||||
inet6 fe80::200:f8ff:fe01:6317%de0 prefixlen 64 scopeid 0x1
|
||||
inet 163.221.202.12 netmask 0xffffff00 broadcast 163.221.202.255
|
||||
inet6 3ffe:501:808:1:200:f8ff:fe01:6317 prefixlen 64
|
||||
ether 00:00:f8:01:63:17
|
||||
media: 100baseTX status: active
|
||||
|
||||
To check assigned prefix, use the "ndp" command (See description of
|
||||
ndp command about its usage).
|
||||
|
||||
# ndp -p
|
||||
3ffe:501:808:1::/64 if=de0
|
||||
flags=LA, vltime=2592000, pltime=604800, expire=Never, origin=RR
|
||||
No advertising router
|
||||
|
||||
The "prefix" command also has node internal prefix renumbering
|
||||
ability.
|
||||
|
||||
If you have multiple prefixes which have 3ffe:501:808:/48 at the top,
|
||||
and would like to renumber them to 3ffe:501:4819:/48, then use the
|
||||
"prefix" command with the "matchpr" argument and the "usepr" argument.
|
||||
|
||||
Suppose that current state of before renumbering as follows:
|
||||
|
||||
# ifconfig de0
|
||||
de0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
|
||||
inet6 fe80::200:f8ff:fe01:6317%de0 prefixlen 64 scopeid 0x1
|
||||
inet 163.221.202.12 netmask 0xffffff00 broadcast 163.221.202.255
|
||||
inet6 3ffe:501:808:1:200:f8ff:fe01:6317 prefixlen 64
|
||||
ether 00:00:f8:01:63:17
|
||||
media: 100baseTX status: active
|
||||
# ifconfig de1
|
||||
de1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
|
||||
inet6 fe80::200:f8ff:fe55:7011%de1 prefixlen 64 scopeid 0x2
|
||||
inet 163.221.203.12 netmask 0xffffff00 broadcast 163.221.203.255
|
||||
inet6 3ffe:501:808:2:200:f8ff:fe55:7011 prefixlen 64
|
||||
ether 00:00:f8:55:70:11
|
||||
media: 100baseTX status: active
|
||||
# ndp -p
|
||||
3ffe:501:808:1::/64 if=de0
|
||||
flags=LA, vltime=2592000, pltime=604800, expire=Never, origin=RR
|
||||
No advertising router
|
||||
3ffe:501:808:2::/64 if=de1
|
||||
flags=LA, vltime=2592000, pltime=604800, expire=Never, origin=RR
|
||||
No advertising router
|
||||
|
||||
Then do as follows:
|
||||
|
||||
# prefix -a matchpr 3ffe:501:808:: mp_len 48 usepr 3ffe:501:4819:: up_uselen 48 change
|
||||
|
||||
If command is successful, prefixes and addresses will be renumbered as
|
||||
follows.
|
||||
|
||||
# ifconfig de0
|
||||
de0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
|
||||
inet6 fe80::200:f8ff:fe01:6317%de0 prefixlen 64 scopeid 0x1
|
||||
inet 163.221.202.12 netmask 0xffffff00 broadcast 163.221.202.255
|
||||
inet6 3ffe:501:4819:1:200:f8ff:fe01:6317 prefixlen 64
|
||||
ether 00:00:f8:01:63:17
|
||||
media: 100baseTX status: active
|
||||
# ifconfig de1
|
||||
de1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
|
||||
inet6 fe80::200:f8ff:fe55:7011%de0 prefixlen 64 scopeid 0x2
|
||||
inet 163.221.203.12 netmask 0xffffff00 broadcast 163.221.203.255
|
||||
inet6 3ffe:501:4819:2:200:f8ff:fe55:7011 prefixlen 64
|
||||
ether 00:00:f8:55:70:11
|
||||
media: 100baseTX status: active
|
||||
# ndp -p
|
||||
3ffe:501:4819:1::/64 if=de0
|
||||
flags=LA, vltime=2592000, pltime=604800, expire=Never, origin=RR
|
||||
No advertising router
|
||||
3ffe:501:4819:2::/64 if=de1
|
||||
flags=LA, vltime=2592000, pltime=604800, expire=Never, origin=RR
|
||||
No advertising router
|
||||
|
||||
See also "/etc/rc.network6" for actual examples.
|
||||
|
||||
|
||||
<<<route>>>
|
||||
|
||||
If there is a router announcing Router Advertisement on a subnet,
|
||||
you need not to add a default route for your host by hand
|
||||
(Please refer to "sysctl" section to accept Router Advertisement).
|
||||
|
||||
If you want to add a default route manually, do like:
|
||||
|
||||
# route add -inet6 default fe80::200:a2ff:fe0e:7543%ed0
|
||||
|
||||
"default" means ::/0. In other cases, if "prefixlen" is omitted, 64
|
||||
is assumed for "prefixlen" to get along with the aggregatable address.
|
||||
|
||||
Note that, in IPv6, a link-local address should be used as gateway
|
||||
("fe80::200:a2ff:fe0e:7543%ed0" in the above). If you use global addresses,
|
||||
ICMPv6 redirect will not work properly. Also note that we use a special form
|
||||
of link-local address as gateway. See Section 1.3 of IMPLEMENTATION for
|
||||
more details.
|
||||
For ease of configuration we recommend you to avoid static routes and run
|
||||
a routing daemon (route6d for example) instead.
|
||||
|
||||
|
||||
<<<ping6>>>
|
||||
|
||||
Reachability can be checked by "ping6". This "ping6" allows multicast
|
||||
for its argument.
|
||||
|
||||
% ping6 -n -I ed0 ff02::1
|
||||
|
||||
PING6(56=40+8+8 bytes) fe80::5254:ff:feda:cb7d --> ff02::1%ed0
|
||||
56 bytes from fe80::5254:ff:feda:cb7d%lo0, icmp_seq=0 hlim=64 time=0.25 ms
|
||||
56 bytes from fe80::2a0:c9ff:fe84:ed6c%ed0, icmp_seq=0 hlim=64 time=1.333 ms(DUP!)
|
||||
56 bytes from fe80::5254:ff:feda:d161%ed0, icmp_seq=0 hlim=64 time=1.459 ms(DUP!)
|
||||
56 bytes from fe80::260:97ff:fec2:80bf%ed0, icmp_seq=0 hlim=64 time=1.538 ms(DUP!)
|
||||
56 bytes from 3ffe:501:4819:2000:5054:ff:fedb:aa46, icmp_seq=0 hlim=255 time=1.615 ms(DUP!)
|
||||
|
||||
|
||||
<<<ping6 -w>>>
|
||||
|
||||
Name resolution is possible by ICMPv6 node information query message.
|
||||
This is very convenient for link-local addresses whose host name cannot be
|
||||
resolved by DNS. Specify the "-w" option to "ping6".
|
||||
|
||||
% ping6 -n -I ed0 -w ff02::1
|
||||
|
||||
64 bytes from fe80::5254:ff:feda:cb7d%lo0: fto.kame.net
|
||||
67 bytes from fe80::5254:ff:feda:d161%ed0: banana.kame.net
|
||||
69 bytes from fe80::2a0:c9ff:fe84:ebd9%ed0: paradise.kame.net
|
||||
66 bytes from fe80::260:8ff:fe8b:447f%ed0: taroh.kame.net
|
||||
66 bytes from fe80::2a0:c9ff:fe84:ed6c%ed0: ayame.kame.net
|
||||
|
||||
|
||||
<<<traceroute6>>>
|
||||
|
||||
The route for a target host can be checked by "traceroute6".
|
||||
|
||||
% traceroute6 tokyo.v6.wide.ad.jp
|
||||
|
||||
traceroute to tokyo.v6.wide.ad.jp (3ffe:501:0:401:200:e8ff:fed5:8923), 30 hops max, 12 byte packets
|
||||
1 nr60.v6.kame.net 1.239 ms 0.924 ms 0.908 ms
|
||||
2 otemachi.v6.wide.ad.jp 28.953 ms 31.451 ms 26.567 ms
|
||||
3 tokyo.v6.wide.ad.jp 26.549 ms 26.58 ms 26.186 ms
|
||||
|
||||
If the -l option is specified, both address and name are shown in each line.
|
||||
% traceroute6 -l tokyo.v6.wide.ad.jp
|
||||
|
||||
traceroute to tokyo.v6.wide.ad.jp (3ffe:501:0:401:200:e8ff:fed5:8923), 30 hops max, 12 byte packets
|
||||
1 nr60.v6.kame.net (3ffe:501:4819:2000:260:97ff:fec2:80bf) 1.23 ms 0.952 ms 0.92 ms
|
||||
2 otemachi.v6.wide.ad.jp (3ffe:501:0:1802:260:97ff:feb6:7ff0) 27.345 ms 26.706 ms 26.563 ms
|
||||
3 tokyo.v6.wide.ad.jp (3ffe:501:0:401:200:e8ff:fed5:8923) 26.329 ms 26.36 ms 28.63 ms
|
||||
|
||||
|
||||
<<<ndp>>>
|
||||
|
||||
To display the current Neighbor cache, use "ndp":
|
||||
|
||||
% ndp -a
|
||||
Neighbor Linklayer Address Netif Expire St Flgs Prbs
|
||||
nr60.v6.kame.net 0:60:97:c2:80:bf ed0 expired S R
|
||||
3ffe:501:4819:2000:2c0:cff:fe 0:c0:c:10:3a:53 ed0 permanent R
|
||||
paradise.v6.kame.net 52:54:0:dc:52:17 ed0 expired S R
|
||||
fe80::200:eff:fe49:f929%ed0 0:0:e:49:f9:29 ed0 expired S R
|
||||
fe80::200:86ff:fe05:80da%ed0 0:0:86:5:80:da ed0 expired S
|
||||
fe80::200:86ff:fe05:c2d8%ed0 0:0:86:5:c2:d8 ed0 9s R
|
||||
|
||||
To flush all of the NDP cache entries, execute the following as root.
|
||||
|
||||
# ndp -c
|
||||
|
||||
To display the prefix list:
|
||||
|
||||
% ndp -p
|
||||
3ffe:501:4819:2000::/64 if=ed0
|
||||
flags=LA, vltime=2592000, pltime=604800, expire=29d23h59m58s, origin=RA
|
||||
advertised by
|
||||
fe80::5254:ff:fedc:5217%ed0 (reachable)
|
||||
fe80::260:97ff:fec2:80bf%ed0 (reachable)
|
||||
fe80::200:eff:fe49:f929%ed0 (no neighbor state)
|
||||
|
||||
To display the default router list:
|
||||
|
||||
% ndp -r
|
||||
fe80::260:97ff:fec2:80bf if=ed0, flags=, expire=29m55s
|
||||
fe80::5254:ff:fedc:5217 if=ed0, flags=, expire=29m7s
|
||||
fe80::200:eff:fe49:f929 if=ed0, flags=, expire=28m47s
|
||||
|
||||
|
||||
<<<rtsol>>>
|
||||
|
||||
To generate a Router Solicitation message right now to get global
|
||||
addresses, use "rtsol".
|
||||
|
||||
# ifconfig ef0
|
||||
ef0: flags=8863<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST>
|
||||
link type ether 0:a0:24:ab:83:9b mtu 1500 speed 10Mbps
|
||||
media 10baseT status active
|
||||
inet6 fe80::2a0:24ff:feab:839b%ef0 prefixlen 64 scopeid 0x2
|
||||
# rtsol ef0
|
||||
# ifconfig ef0
|
||||
ef0: flags=8863<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST>
|
||||
link type ether 0:a0:24:ab:83:9b mtu 1500 speed 10Mbps
|
||||
media 10baseT status active
|
||||
inet6 fe80::2a0:24ff:feab:839b%ef0 prefixlen 64 scopeid 0x2
|
||||
inet6 3ffe:501:4819:2000:2a0:24ff:feab:839b prefixlen 64
|
||||
|
||||
|
||||
<<<rtsold>>>
|
||||
|
||||
rtsold is a daemon version of rtsol. If you run KAME IPv6 on a laptop
|
||||
computer and frequently move with it, the daemon is useful since it watches
|
||||
the interface and sends router solicitations when the status of the interface
|
||||
changes. Note, however, that the feature is disabled by default. Please
|
||||
add -m option when invocation of rtsold.
|
||||
|
||||
rtsold also supports multiple interfaces. For example, you can
|
||||
invoke the daemon as follows:
|
||||
|
||||
# rtsold -m ep0 cnw0
|
||||
|
||||
|
||||
<<<netstat>>>
|
||||
|
||||
To see routing table:
|
||||
|
||||
# netstat -nr
|
||||
# netstat -nrl
|
||||
long format with Ref and Use. Note that bsdi4 does not support the
|
||||
-l option. You should use the -O option instead.
|
||||
|
||||
|
||||
<<<sysctl>>>
|
||||
|
||||
If "net.inet6.ip6.accept_rtadv" is 1, Router Advertisement is
|
||||
accepted. This means that global addresses and default route are
|
||||
automatically set up. Otherwise, the announcement is rejected. The
|
||||
default value is 0. To set "net.inet6.ip6.accept_rtadv" to 1, execute
|
||||
as follows:
|
||||
|
||||
# sysctl net.inet6.ip6.accept_rtadv=1
|
||||
|
||||
|
||||
<<<gifconfig>>>
|
||||
|
||||
"gif" interface enables you to perform IPv{4,6} over IPv{4,6}
|
||||
protocol tunneling. To use this interface, you must specify the
|
||||
outer IPv{4,6} address by using gifconfig, like:
|
||||
|
||||
# gifconfig gif0 163.221.198.61 163.221.11.21
|
||||
|
||||
"ifconfig gif0" will configure the address pair used for inner
|
||||
IPv{4,6} header.
|
||||
|
||||
It is not required to configure inner IPv{4,6} address pair. If
|
||||
you do not configure inner IPv{4,6} address pair, tunnel link is
|
||||
considered as un-numbered link and the source address of inner
|
||||
IPv{4,6} address pair will be borrowed from other interfaces.
|
||||
|
||||
The following example configures un-numbered IPv6-over-IPv4 tunnel:
|
||||
# gifconfig gif0 10.0.0.1 10.0.0.1 netmask 255.255.255.0
|
||||
|
||||
The following example configures numbered IPv6-over-IPv4 tunnel:
|
||||
# gifconfig gif0 10.0.0.1 10.0.0.1 netmask 255.255.255.0
|
||||
# ifconfig gif0 inet6 3ffe:501:808:5::1 3ffe:501:808:5::2 prefixlen 64 alias
|
||||
|
||||
IPv6 spec allows you to use point-to-point link without global IPv6
|
||||
address assigned to the interface. Routing protocol (such as RIPng)
|
||||
uses link-local addresses only. If you are to configure IPv6-over-IPv4
|
||||
tunnel, you need not to configure an address pair for inner IPv6
|
||||
header. We suggest you to use the former example (un-numbered
|
||||
IPv6-over-IPv4 tunnel) to connect to 6bone for simplicity.
|
||||
|
||||
Note that it is so easy to make an infinite routing loop using gif
|
||||
interface, if you configure a tunnel using the same protocol family
|
||||
for inner and outer header (i.e. IPv4-over-IPv4).
|
||||
|
||||
Refer to gifconfig(8) for more details.
|
||||
|
||||
|
||||
<<<6to4>>>
|
||||
|
||||
WARNING: malicious party can abuse 6to4 relay routers/sites, read through
|
||||
internet draft draft-itojun-ipv6-transition-abuse-xx.txt before configuring it.
|
||||
|
||||
"stf" interface enables you to perform 6to4 IPv6-over-IPv4 encapsulation,
|
||||
as documented in draft-ietf-ngtrans-6to4-06.txt. See stf(4) for details.
|
||||
|
||||
|
||||
<<<inetd>>>
|
||||
|
||||
Inetd supports AF_INET and AF_INET6 sockets, with IPsec policy
|
||||
configuration support.
|
||||
|
||||
Refer to inetd(8) for more details.
|
||||
|
||||
|
||||
<<<IPsec>>>
|
||||
|
||||
IPsec requires fairly complex configuration, so here we show transport
|
||||
mode only. https://www.kame.net/newsletter/ has more comprehensive
|
||||
examples.
|
||||
|
||||
Let us setup security association to deploy a secure channel between
|
||||
HOST A (10.2.3.4) and HOST B (10.6.7.8). Here we show a little
|
||||
complicated example. From HOST A to HOST B, only old AH is used.
|
||||
From HOST B to HOST A, new AH and new ESP are combined.
|
||||
|
||||
Now we should choose algorithm to be used corresponding to "AH"/"new
|
||||
AH"/"ESP"/"new ESP". Please refer to the "setkey" man page to know
|
||||
algorithm names. Our choice is MD5 for AH, new-HMAC-SHA1 for new AH,
|
||||
and new-DES-expIV with 8 byte IV for new ESP.
|
||||
|
||||
Key length highly depends on each algorithm. For example, key
|
||||
length must be equal to 16 bytes for MD5, 20 for new-HMAC-SHA1,
|
||||
and 8 for new-DES-expIV. Now we choose "MYSECRETMYSECRET",
|
||||
"KAMEKAMEKAMEKAMEKAME", "PASSWORD", respectively.
|
||||
|
||||
OK, let us assign SPI (Security Parameter Index) for each protocol.
|
||||
Please note that we need 3 SPIs for this secure channel since three
|
||||
security headers are produced (one for from HOST A to HOST B, two for
|
||||
from HOST B to HOST A). Please also note that SPI MUST be greater
|
||||
than or equal to 256. We choose, 1000, 2000, and 3000, respectively.
|
||||
|
||||
|
||||
(1)
|
||||
HOST A ------> HOST B
|
||||
|
||||
(1)PROTO=AH
|
||||
ALG=MD5(RFC1826)
|
||||
KEY=MYSECRETMYSECRET
|
||||
SPI=1000
|
||||
|
||||
(2.1)
|
||||
HOST A <------ HOST B
|
||||
<------
|
||||
(2.2)
|
||||
|
||||
(2.1)
|
||||
PROTO=AH
|
||||
ALG=new-HMAC-SHA1(new AH)
|
||||
KEY=KAMEKAMEKAMEKAMEKAME
|
||||
SPI=2000
|
||||
|
||||
(2.2)
|
||||
PROTO=ESP
|
||||
ALG=new-DES-expIV(new ESP)
|
||||
IV length = 8
|
||||
KEY=PASSWORD
|
||||
SPI=3000
|
||||
|
||||
Now, let us setup security association. Execute "setkey" on both HOST
|
||||
A and B:
|
||||
|
||||
# setkey -c
|
||||
add 10.2.3.4 10.6.7.8 ah 1000 -m transport -A keyed-md5 "MYSECRETMYSECRET" ;
|
||||
add 10.6.7.8 10.2.3.4 ah 2000 -m transport -A hmac-sha1 "KAMEKAMEKAMEKAMEKAME" ;
|
||||
add 10.6.7.8 10.2.3.4 esp 3000 -m transport -E des-cbc "PASSWORD" ;
|
||||
^D
|
||||
|
||||
Actually, IPsec communication doesn't process until security policy
|
||||
entries will be defined. In this case, you must setup each host.
|
||||
|
||||
At A:
|
||||
# setkey -c
|
||||
spdadd 10.2.3.4 10.6.7.8 any -P out ipsec
|
||||
ah/transport/10.2.3.4-10.6.7.8/require ;
|
||||
^D
|
||||
|
||||
At B:
|
||||
spdadd 10.6.7.8 10.2.3.4 any -P out ipsec
|
||||
esp/transport//require
|
||||
ah/transport//require ;
|
||||
^D
|
||||
|
||||
To utilize the security associations installed into the kernel, you
|
||||
must set the socket security level by using setsockopt().
|
||||
This is per-application (or per-socket) security. For example,
|
||||
the "ping" command has the -P option with parameter to enable AH and/or ESP.
|
||||
|
||||
For example:
|
||||
% ping -P "out ipsec \
|
||||
ah/transport//use \
|
||||
esp/tunnel/10.0.1.1-10.0.1.2/require" 10.0.2.2
|
||||
|
||||
If there are proper SAs, this policy specification causes ICMP packet
|
||||
to be AH transport mode inner ESP tunnel mode like below.
|
||||
|
||||
HOST C -----------> GATEWAY D ----------> HOST E
|
||||
10.0.1.1 10.0.1.2 10.0.2.1 10.0.2.2
|
||||
| | | |
|
||||
| ======= ESP ======= |
|
||||
==================== AH ==================
|
||||
|
||||
|
||||
<<<EDNS0>>>
|
||||
|
||||
EDNS0 is defined in RFC2671. With EDNS0, the resolver library can tell DNS
|
||||
server of its receiving buffer size, and permit DNS server to transmit large
|
||||
reply packet. EDNS0 is necessary to take advantage of larger minimum MTU
|
||||
in IPv6. KAME libinet6 includes resolver side support for EDNS0.
|
||||
Server side support for EDNS0 is included in ISC BIND9.
|
||||
|
||||
query packet with EDNS0
|
||||
tells receive buffer size
|
||||
KAME box -----------------------------> BIND9 DNS server
|
||||
KAME box <----------------------------- BIND9 DNS server
|
||||
can transmit jumbo reply, since DNS server
|
||||
knows receive buffer size of KAME box
|
||||
|
||||
How to play with it:
|
||||
- prepare KAME box and BIND9 DNS server (can be a same node)
|
||||
- add the following into /etc/resolv.conf on KAME box:
|
||||
options edns0 <--- enables EDNS0
|
||||
nameserver <IPv4 or v6 address of BIND9 box>
|
||||
- run applications compiled with libinet6 (like /usr/local/v6/bin/telnet),
|
||||
see EDNS0 packet fly on the wire by tcpdump or some other method.
|
||||
|
||||
Caveats:
|
||||
- BIND 4/8 DNS server will choke with EDNS0 packet, so you must not
|
||||
turn the option on if you have BIND 4/8 DNS server. If you enable
|
||||
"options edns0" against BIND 4/8 DNS server, you will never be able
|
||||
to resolve names.
|
||||
- If you use IPv6 UDP as DNS transport, path MTU discovery may
|
||||
affect the traffic. KAME box tries to fragment packet to 1280
|
||||
bytes, however, BIND9 may not.
|
||||
- Some of our platforms do not use our extended resolver code in libinet6.
|
||||
See COVERAGE for detail.
|
||||
|
||||
|
||||
<<Further readings>>
|
||||
|
||||
http://www.netbsd.org/Documentation/network/ipv6/
|
||||
Even if you are on non-netbsd operating system, the URL should be
|
||||
useful.
|
||||
https://www.kame.net/
|
||||
|
||||
<end of USAGE>
|
@ -8,7 +8,6 @@ FILESDIR= ${SHAREDIR}/examples
|
||||
|
||||
LDIRS= BSD_daemon \
|
||||
FreeBSD_version \
|
||||
IPv6 \
|
||||
bootforth \
|
||||
csh \
|
||||
drivers \
|
||||
@ -58,9 +57,6 @@ SE_FREEBSD_VERSION= \
|
||||
Makefile \
|
||||
README
|
||||
|
||||
SE_DIRS+= IPv6
|
||||
SE_IPV6= USAGE
|
||||
|
||||
SE_DIRS+= bootforth
|
||||
SE_BOOTFORTH= \
|
||||
README \
|
||||
|
@ -13,8 +13,9 @@ exec="echo Loading /boot/defaults/loader.conf"
|
||||
kernel="kernel" # /boot sub-directory containing kernel and modules
|
||||
bootfile="kernel" # Kernel name (possibly absolute path)
|
||||
kernel_options="" # Flags to be passed to the kernel
|
||||
loader_conf_files="/boot/device.hints /boot/loader.conf /boot/loader.conf.local"
|
||||
loader_conf_files="/boot/device.hints /boot/loader.conf"
|
||||
loader_conf_dirs="/boot/loader.conf.d"
|
||||
local_loader_conf_files="/boot/loader.conf.local"
|
||||
nextboot_conf="/boot/nextboot.conf"
|
||||
verbose_loading="NO" # Set to YES for verbose loader output
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.Dd January 10, 2024
|
||||
.Dd February 2, 2024
|
||||
.Dt LOADER.CONF 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -131,6 +131,10 @@ Space separated list of directories to process for configuration files.
|
||||
The lua-based loader will process files with a
|
||||
.Dq .conf
|
||||
suffix that are placed in these directories.
|
||||
Files found here are processed after the ones listed in
|
||||
.Va loader_conf_files
|
||||
but before the ones found in
|
||||
.Va local_loader_conf_files .
|
||||
.It Ar loader_conf_files
|
||||
Defines additional configuration files to be processed right after the
|
||||
present file.
|
||||
@ -138,6 +142,45 @@ present file.
|
||||
should be treated as write-only.
|
||||
One cannot depend on any value remaining in the loader environment or carried
|
||||
over into the kernel environment.
|
||||
.It Ar local_loader_conf_files
|
||||
Space separated list of additional configuration files to be processed at last,
|
||||
i.e., after
|
||||
.Va loader_conf_files
|
||||
and
|
||||
.Va loader_conf_dirs
|
||||
are processed.
|
||||
.It Ar product_vars
|
||||
When set, must be a space separated list of environment variable names to walk
|
||||
through to guess product information.
|
||||
The order matters as reading a config file override the previously defined
|
||||
values.
|
||||
Undefined variables are silently ignored.
|
||||
.Pp
|
||||
When product information can be guessed, for each product information found,
|
||||
append
|
||||
.Pa /boot/loader.conf.d/PRODUCT
|
||||
to
|
||||
.Ar loader_conf_dirs .
|
||||
It can be typically used as follow:
|
||||
.Bd -literal
|
||||
smbios.system.planar.maker="PLANAR_MAKER"
|
||||
smbios.system.planar.product="PLANAR_PRODUCT"
|
||||
smbios.system.product="PRODUCT"
|
||||
uboot.m_product="M_PRODUCT"
|
||||
product_vars="smbios.system.planar.maker smbios.system.planar.product smbios.system.product uboot.m_product"
|
||||
.Ed
|
||||
.Pp
|
||||
to read files found in the following directories, in that order:
|
||||
.Bl -bullet -compact
|
||||
.It
|
||||
.Pa /boot/loader.conf.d/PLANAR_MAKER
|
||||
.It
|
||||
.Pa /boot/loader.conf.d/PLANAR_PRODUCT
|
||||
.It
|
||||
.Pa /boot/loader.conf.d/PRODUCT
|
||||
.It
|
||||
.Pa /boot/loader.conf.d/M_PRODUCT
|
||||
.El
|
||||
.It Ar kernel
|
||||
Name of the kernel to be loaded.
|
||||
If no kernel name is set, no additional
|
||||
@ -242,6 +285,14 @@ default settings can be ignored.
|
||||
The few of them which are important
|
||||
or useful are:
|
||||
.Bl -tag -width bootfile -offset indent
|
||||
.It Va local_loader_conf_files
|
||||
.Pq Dq /boot/loader.conf.local
|
||||
Ensure
|
||||
.Va loader.conf.local
|
||||
can always be used to override settings from files found in
|
||||
.Va loader_conf_files
|
||||
and
|
||||
.Va loader_conf_dirs .
|
||||
.It Va bitmap_load
|
||||
.Pq Dq NO
|
||||
If set to
|
||||
@ -423,13 +474,18 @@ It is not available in the default Forth-based loader.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /boot/defaults/loader.conf -compact
|
||||
.It Pa /boot/defaults/loader.conf
|
||||
default settings \(em do not change this file.
|
||||
Default settings \(em do not change this file.
|
||||
.It Pa /boot/loader.conf
|
||||
user defined settings.
|
||||
User defined settings.
|
||||
.It Pa /boot/loader.conf.lua
|
||||
user defined settings written in lua.
|
||||
User defined settings written in lua.
|
||||
.It Pa /boot/loader.conf.d/*.conf
|
||||
User defined settings split in separate files.
|
||||
.It Pa /boot/loader.conf.d/*.lua
|
||||
User defined settings written in lua and split in separate files.
|
||||
.It Pa /boot/loader.conf.local
|
||||
machine-specific settings for sites with a common loader.conf.
|
||||
Machine-specific settings for sites with a common loader.conf. Allow to override
|
||||
settings defined in other files.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr kenv 1 ,
|
||||
|
@ -630,8 +630,7 @@ function config.readConf(file, loaded_files)
|
||||
return
|
||||
end
|
||||
|
||||
-- We'll process loader_conf_dirs at the top-level readConf
|
||||
local load_conf_dirs = next(loaded_files) == nil
|
||||
local top_level = next(loaded_files) == nil -- Are we the top-level readConf?
|
||||
print("Loading " .. file)
|
||||
|
||||
-- The final value of loader_conf_files is not important, so just
|
||||
@ -656,14 +655,40 @@ function config.readConf(file, loaded_files)
|
||||
end
|
||||
end
|
||||
|
||||
if load_conf_dirs then
|
||||
if top_level then
|
||||
local loader_conf_dirs = getEnv("loader_conf_dirs")
|
||||
|
||||
-- If product_vars is set, it must be a list of environment variable names
|
||||
-- to walk through to guess product information. The order matters as
|
||||
-- reading a config files override the previously defined values.
|
||||
--
|
||||
-- If product information can be guessed, for each product information
|
||||
-- found, also read config files found in /boot/loader.conf.d/PRODUCT/.
|
||||
local product_vars = getEnv("product_vars")
|
||||
if product_vars then
|
||||
local product_conf_dirs = ""
|
||||
for var in product_vars:gmatch("%S+") do
|
||||
local product = getEnv(var)
|
||||
if product then
|
||||
product_conf_dirs = product_conf_dirs .. " /boot/loader.conf.d/" .. product
|
||||
end
|
||||
end
|
||||
|
||||
if loader_conf_dirs then
|
||||
loader_conf_dirs = loader_conf_dirs .. product_conf_dirs
|
||||
else
|
||||
loader_conf_dirs = product_conf_dirs
|
||||
end
|
||||
end
|
||||
|
||||
-- Process "loader_conf_dirs" extra-directories
|
||||
if loader_conf_dirs ~= nil then
|
||||
for name in loader_conf_dirs:gmatch("[%w%p]+") do
|
||||
if lfs.attributes(name, "mode") ~= "directory" then
|
||||
print(MSG_FAILDIR:format(name))
|
||||
goto nextdir
|
||||
end
|
||||
|
||||
for cfile in lfs.dir(name) do
|
||||
if cfile:match(".conf$") then
|
||||
local fpath = name .. "/" .. cfile
|
||||
@ -675,6 +700,15 @@ function config.readConf(file, loaded_files)
|
||||
::nextdir::
|
||||
end
|
||||
end
|
||||
|
||||
-- Always allow overriding with local config files, e.g.,
|
||||
-- /boot/loader.conf.local.
|
||||
local local_loader_conf_files = getEnv("local_loader_conf_files")
|
||||
if local_loader_conf_files then
|
||||
for name in local_loader_conf_files:gmatch("[%w%p]+") do
|
||||
config.readConf(name, loaded_files)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -64,9 +64,13 @@ as a configuration file
|
||||
.Po e.g., as
|
||||
.Pa loader.conf
|
||||
.Pc
|
||||
and then processing files listed in
|
||||
and then process files listed in the
|
||||
.Ev loader_conf_files
|
||||
variable
|
||||
variable. Additionnaly, the top-level call to readConf will process files listed in the
|
||||
.Ev loader_conf_dirs
|
||||
and
|
||||
.Ev local_loader_conf_files
|
||||
variables
|
||||
.Po see
|
||||
.Xr loader.conf 5
|
||||
.Pc .
|
||||
|
@ -1326,7 +1326,8 @@ sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
|
||||
{
|
||||
struct mbuf *m, *mlast;
|
||||
|
||||
kmsan_check_mbuf(m0, "sbappend");
|
||||
if (m0 != NULL)
|
||||
kmsan_check_mbuf(m0, "sbappend");
|
||||
kmsan_check_mbuf(control, "sbappend");
|
||||
|
||||
sbm_clrprotoflags(m0, flags);
|
||||
|
@ -2470,10 +2470,10 @@ void pf_init_kruleset(struct pf_kruleset *);
|
||||
void pf_init_keth(struct pf_keth_ruleset *);
|
||||
int pf_kanchor_setup(struct pf_krule *,
|
||||
const struct pf_kruleset *, const char *);
|
||||
int pf_kanchor_copyout(const struct pf_kruleset *,
|
||||
const struct pf_krule *, char *);
|
||||
int pf_kanchor_nvcopyout(const struct pf_kruleset *,
|
||||
const struct pf_krule *, nvlist_t *);
|
||||
int pf_kanchor_copyout(const struct pf_kruleset *,
|
||||
const struct pf_krule *, struct pfioc_rule *);
|
||||
void pf_kanchor_remove(struct pf_krule *);
|
||||
void pf_remove_if_empty_kruleset(struct pf_kruleset *);
|
||||
struct pf_kruleset *pf_find_kruleset(const char *);
|
||||
@ -2501,6 +2501,7 @@ int pf_ioctl_addrule(struct pf_krule *, uint32_t,
|
||||
pid_t);
|
||||
|
||||
void pf_krule_free(struct pf_krule *);
|
||||
void pf_krule_clear_counters(struct pf_krule *);
|
||||
#endif
|
||||
|
||||
/* The fingerprint functions can be linked into userland programs (tcpdump) */
|
||||
|
@ -513,6 +513,18 @@ snl_attr_get_flag(struct snl_state *ss __unused, struct nlattr *nla, const void
|
||||
return (false);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
snl_attr_get_bytes(struct snl_state *ss __unused, struct nlattr *nla, const void *arg,
|
||||
void *target)
|
||||
{
|
||||
if ((size_t)NLA_DATA_LEN(nla) != (size_t)arg)
|
||||
return (false);
|
||||
|
||||
memcpy(target, NLA_DATA_CONST(nla), (size_t)arg);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
snl_attr_get_uint8(struct snl_state *ss __unused, struct nlattr *nla,
|
||||
const void *arg __unused, void *target)
|
||||
|
@ -7361,6 +7361,12 @@ pf_route(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp,
|
||||
m0->m_pkthdr.csum_flags &= ~CSUM_SCTP;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure dummynet gets the correct direction, in case it needs to
|
||||
* re-inject later.
|
||||
*/
|
||||
pd->dir = PF_OUT;
|
||||
|
||||
/*
|
||||
* If small enough for interface, or the interface will take
|
||||
* care of the fragmentation for us, we can just send directly.
|
||||
|
@ -1867,6 +1867,17 @@ pf_krule_free(struct pf_krule *rule)
|
||||
free(rule, M_PFRULE);
|
||||
}
|
||||
|
||||
void
|
||||
pf_krule_clear_counters(struct pf_krule *rule)
|
||||
{
|
||||
pf_counter_u64_zero(&rule->evaluations);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
pf_counter_u64_zero(&rule->packets[i]);
|
||||
pf_counter_u64_zero(&rule->bytes[i]);
|
||||
}
|
||||
counter_u64_zero(rule->states_tot);
|
||||
}
|
||||
|
||||
static void
|
||||
pf_kpooladdr_to_pooladdr(const struct pf_kpooladdr *kpool,
|
||||
struct pf_pooladdr *pool)
|
||||
@ -3266,14 +3277,9 @@ DIOCADDRULENV_error:
|
||||
ERROUT(ENOSPC);
|
||||
}
|
||||
|
||||
if (clear_counter) {
|
||||
pf_counter_u64_zero(&rule->evaluations);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
pf_counter_u64_zero(&rule->packets[i]);
|
||||
pf_counter_u64_zero(&rule->bytes[i]);
|
||||
}
|
||||
counter_u64_zero(rule->states_tot);
|
||||
}
|
||||
if (clear_counter)
|
||||
pf_krule_clear_counters(rule);
|
||||
|
||||
PF_RULES_WUNLOCK();
|
||||
|
||||
error = copyout(nvlpacked, nv->data, nv->len);
|
||||
|
@ -401,6 +401,42 @@ static const struct nlattr_parser nla_p_addr_wrap[] = {
|
||||
NL_DECLARE_ATTR_PARSER(addr_wrap_parser, nla_p_addr_wrap);
|
||||
#undef _OUT
|
||||
|
||||
static bool
|
||||
nlattr_add_addr_wrap(struct nl_writer *nw, int attrtype, struct pf_addr_wrap *a)
|
||||
{
|
||||
int off = nlattr_add_nested(nw, attrtype);
|
||||
int num;
|
||||
|
||||
nlattr_add_in6_addr(nw, PF_AT_ADDR, &a->v.a.addr.v6);
|
||||
nlattr_add_in6_addr(nw, PF_AT_MASK, &a->v.a.mask.v6);
|
||||
nlattr_add_u8(nw, PF_AT_TYPE, a->type);
|
||||
nlattr_add_u8(nw, PF_AT_IFLAGS, a->iflags);
|
||||
|
||||
if (a->type == PF_ADDR_DYNIFTL) {
|
||||
nlattr_add_string(nw, PF_AT_IFNAME, a->v.ifname);
|
||||
num = 0;
|
||||
if (a->p.dyn != NULL)
|
||||
num = a->p.dyn->pfid_acnt4 + a->p.dyn->pfid_acnt6;
|
||||
nlattr_add_u32(nw, PF_AT_DYNCNT, num);
|
||||
} else if (a->type == PF_ADDR_TABLE) {
|
||||
struct pfr_ktable *kt;
|
||||
|
||||
nlattr_add_string(nw, PF_AT_TABLENAME, a->v.tblname);
|
||||
num = -1;
|
||||
kt = a->p.tbl;
|
||||
if ((kt->pfrkt_flags & PFR_TFLAG_ACTIVE) &&
|
||||
kt->pfrkt_root != NULL)
|
||||
kt = kt->pfrkt_root;
|
||||
if (kt->pfrkt_flags & PFR_TFLAG_ACTIVE)
|
||||
num = kt->pfrkt_cnt;
|
||||
nlattr_add_u32(nw, PF_AT_TBLCNT, num);
|
||||
}
|
||||
|
||||
nlattr_set_len(nw, off);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
#define _OUT(_field) offsetof(struct pf_rule_addr, _field)
|
||||
static const struct nlattr_parser nla_p_ruleaddr[] = {
|
||||
{ .type = PF_RAT_ADDR, .off = _OUT(addr), .arg = &addr_wrap_parser, .cb = nlattr_get_nested },
|
||||
@ -412,6 +448,22 @@ static const struct nlattr_parser nla_p_ruleaddr[] = {
|
||||
NL_DECLARE_ATTR_PARSER(rule_addr_parser, nla_p_ruleaddr);
|
||||
#undef _OUT
|
||||
|
||||
static bool
|
||||
nlattr_add_rule_addr(struct nl_writer *nw, int attrtype, struct pf_rule_addr *r)
|
||||
{
|
||||
int off = nlattr_add_nested(nw, attrtype);
|
||||
|
||||
nlattr_add_addr_wrap(nw, PF_RAT_ADDR, &r->addr);
|
||||
nlattr_add_u16(nw, PF_RAT_SRC_PORT, r->port[0]);
|
||||
nlattr_add_u16(nw, PF_RAT_DST_PORT, r->port[1]);
|
||||
nlattr_add_u8(nw, PF_RAT_NEG, r->neg);
|
||||
nlattr_add_u8(nw, PF_RAT_OP, r->port_op);
|
||||
|
||||
nlattr_set_len(nw, off);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
#define _OUT(_field) offsetof(struct pf_mape_portset, _field)
|
||||
static const struct nlattr_parser nla_p_mape_portset[] = {
|
||||
{ .type = PF_MET_OFFSET, .off = _OUT(offset), .cb = nlattr_get_uint8 },
|
||||
@ -421,6 +473,20 @@ static const struct nlattr_parser nla_p_mape_portset[] = {
|
||||
NL_DECLARE_ATTR_PARSER(mape_portset_parser, nla_p_mape_portset);
|
||||
#undef _OUT
|
||||
|
||||
static bool
|
||||
nlattr_add_mape_portset(struct nl_writer *nw, int attrtype, const struct pf_mape_portset *m)
|
||||
{
|
||||
int off = nlattr_add_nested(nw, attrtype);
|
||||
|
||||
nlattr_add_u8(nw, PF_MET_OFFSET, m->offset);
|
||||
nlattr_add_u8(nw, PF_MET_PSID_LEN, m->psidlen);
|
||||
nlattr_add_u16(nw, PF_MET_PSID, m->psid);
|
||||
|
||||
nlattr_set_len(nw, off);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
struct nl_parsed_labels
|
||||
{
|
||||
char labels[PF_RULE_MAX_LABEL_COUNT][PF_RULE_LABEL_SIZE];
|
||||
@ -468,6 +534,23 @@ nlattr_get_nested_pf_rule_labels(struct nlattr *nla, struct nl_pstate *npt, cons
|
||||
return (0);
|
||||
}
|
||||
|
||||
static bool
|
||||
nlattr_add_labels(struct nl_writer *nw, int attrtype, const struct pf_krule *r)
|
||||
{
|
||||
int off = nlattr_add_nested(nw, attrtype);
|
||||
int i = 0;
|
||||
|
||||
while (r->label[i][0] != 0
|
||||
&& i < PF_RULE_MAX_LABEL_COUNT) {
|
||||
nlattr_add_string(nw, PF_LT_LABEL, r->label[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
nlattr_set_len(nw, off);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
#define _OUT(_field) offsetof(struct pf_kpool, _field)
|
||||
static const struct nlattr_parser nla_p_pool[] = {
|
||||
{ .type = PF_PT_KEY, .off = _OUT(key), .arg = (void *)sizeof(struct pf_poolhashkey), .cb = nlattr_get_bytes },
|
||||
@ -481,6 +564,24 @@ static const struct nlattr_parser nla_p_pool[] = {
|
||||
NL_DECLARE_ATTR_PARSER(pool_parser, nla_p_pool);
|
||||
#undef _OUT
|
||||
|
||||
static bool
|
||||
nlattr_add_pool(struct nl_writer *nw, int attrtype, const struct pf_kpool *pool)
|
||||
{
|
||||
int off = nlattr_add_nested(nw, attrtype);
|
||||
|
||||
nlattr_add(nw, PF_PT_KEY, sizeof(struct pf_poolhashkey), &pool->key);
|
||||
nlattr_add_in6_addr(nw, PF_PT_COUNTER, (const struct in6_addr *)&pool->counter);
|
||||
nlattr_add_u32(nw, PF_PT_TBLIDX, pool->tblidx);
|
||||
nlattr_add_u16(nw, PF_PT_PROXY_SRC_PORT, pool->proxy_port[0]);
|
||||
nlattr_add_u16(nw, PF_PT_PROXY_DST_PORT, pool->proxy_port[1]);
|
||||
nlattr_add_u8(nw, PF_PT_OPTS, pool->opts);
|
||||
nlattr_add_mape_portset(nw, PF_PT_MAPE, &pool->mape);
|
||||
|
||||
nlattr_set_len(nw, off);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
#define _OUT(_field) offsetof(struct pf_rule_uid, _field)
|
||||
static const struct nlattr_parser nla_p_rule_uid[] = {
|
||||
{ .type = PF_RUT_UID_LOW, .off = _OUT(uid[0]), .cb = nlattr_get_uint32 },
|
||||
@ -490,6 +591,20 @@ static const struct nlattr_parser nla_p_rule_uid[] = {
|
||||
NL_DECLARE_ATTR_PARSER(rule_uid_parser, nla_p_rule_uid);
|
||||
#undef _OUT
|
||||
|
||||
static bool
|
||||
nlattr_add_rule_uid(struct nl_writer *nw, int attrtype, const struct pf_rule_uid *u)
|
||||
{
|
||||
int off = nlattr_add_nested(nw, attrtype);
|
||||
|
||||
nlattr_add_u32(nw, PF_RUT_UID_LOW, u->uid[0]);
|
||||
nlattr_add_u32(nw, PF_RUT_UID_HIGH, u->uid[1]);
|
||||
nlattr_add_u8(nw, PF_RUT_OP, u->op);
|
||||
|
||||
nlattr_set_len(nw, off);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
struct nl_parsed_timeouts
|
||||
{
|
||||
uint32_t timeouts[PFTM_MAX];
|
||||
@ -536,6 +651,19 @@ nlattr_get_nested_timeouts(struct nlattr *nla, struct nl_pstate *npt, const void
|
||||
return (0);
|
||||
}
|
||||
|
||||
static bool
|
||||
nlattr_add_timeout(struct nl_writer *nw, int attrtype, uint32_t *timeout)
|
||||
{
|
||||
int off = nlattr_add_nested(nw, attrtype);
|
||||
|
||||
for (int i = 0; i < PFTM_MAX; i++)
|
||||
nlattr_add_u32(nw, PF_RT_TIMEOUT, timeout[i]);
|
||||
|
||||
nlattr_set_len(nw, off);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
#define _OUT(_field) offsetof(struct pf_krule, _field)
|
||||
static const struct nlattr_parser nla_p_rule[] = {
|
||||
{ .type = PF_RT_SRC, .off = _OUT(src), .arg = &rule_addr_parser,.cb = nlattr_get_nested },
|
||||
@ -654,6 +782,7 @@ static const struct nlattr_parser nla_p_getrules[] = {
|
||||
};
|
||||
static const struct nlfield_parser nlf_p_getrules[] = {
|
||||
};
|
||||
#undef _OUT
|
||||
NL_DECLARE_PARSER(getrules_parser, struct genlmsghdr, nlf_p_getrules, nla_p_getrules);
|
||||
|
||||
static int
|
||||
@ -695,6 +824,182 @@ out:
|
||||
return (error);
|
||||
}
|
||||
|
||||
struct nl_parsed_get_rule {
|
||||
char anchor[MAXPATHLEN];
|
||||
uint8_t action;
|
||||
uint32_t nr;
|
||||
uint32_t ticket;
|
||||
uint8_t clear;
|
||||
};
|
||||
#define _IN(_field) offsetof(struct genlmsghdr, _field)
|
||||
#define _OUT(_field) offsetof(struct nl_parsed_get_rule, _field)
|
||||
static const struct nlattr_parser nla_p_getrule[] = {
|
||||
{ .type = PF_GR_ANCHOR, .off = _OUT(anchor), .arg = (void *)MAXPATHLEN, .cb = nlattr_get_chara },
|
||||
{ .type = PF_GR_ACTION, .off = _OUT(action), .cb = nlattr_get_uint8 },
|
||||
{ .type = PF_GR_NR, .off = _OUT(nr), .cb = nlattr_get_uint32 },
|
||||
{ .type = PF_GR_TICKET, .off = _OUT(ticket), .cb = nlattr_get_uint32 },
|
||||
{ .type = PF_GR_CLEAR, .off = _OUT(clear), .cb = nlattr_get_uint8 },
|
||||
};
|
||||
static const struct nlfield_parser nlf_p_getrule[] = {
|
||||
};
|
||||
NL_DECLARE_PARSER(getrule_parser, struct genlmsghdr, nlf_p_getrule, nla_p_getrule);
|
||||
|
||||
static int
|
||||
pf_handle_getrule(struct nlmsghdr *hdr, struct nl_pstate *npt)
|
||||
{
|
||||
char anchor_call[MAXPATHLEN];
|
||||
struct nl_parsed_get_rule attrs = {};
|
||||
struct nl_writer *nw = npt->nw;
|
||||
struct genlmsghdr *ghdr_new;
|
||||
struct pf_kruleset *ruleset;
|
||||
struct pf_krule *rule;
|
||||
int rs_num;
|
||||
int error;
|
||||
|
||||
error = nl_parse_nlmsg(hdr, &getrule_parser, npt, &attrs);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr)))
|
||||
return (ENOMEM);
|
||||
|
||||
ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr);
|
||||
ghdr_new->cmd = PFNL_CMD_GETRULE;
|
||||
ghdr_new->version = 0;
|
||||
ghdr_new->reserved = 0;
|
||||
|
||||
PF_RULES_WLOCK();
|
||||
ruleset = pf_find_kruleset(attrs.anchor);
|
||||
if (ruleset == NULL) {
|
||||
PF_RULES_WUNLOCK();
|
||||
error = ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rs_num = pf_get_ruleset_number(attrs.action);
|
||||
if (rs_num >= PF_RULESET_MAX) {
|
||||
PF_RULES_WUNLOCK();
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (attrs.ticket != ruleset->rules[rs_num].active.ticket) {
|
||||
PF_RULES_WUNLOCK();
|
||||
error = EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
|
||||
while ((rule != NULL) && (rule->nr != attrs.nr))
|
||||
rule = TAILQ_NEXT(rule, entries);
|
||||
if (rule == NULL) {
|
||||
PF_RULES_WUNLOCK();
|
||||
error = EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
nlattr_add_rule_addr(nw, PF_RT_SRC, &rule->src);
|
||||
nlattr_add_rule_addr(nw, PF_RT_DST, &rule->dst);
|
||||
nlattr_add_u32(nw, PF_RT_RIDENTIFIER, rule->ridentifier);
|
||||
nlattr_add_labels(nw, PF_RT_LABELS, rule);
|
||||
nlattr_add_string(nw, PF_RT_IFNAME, rule->ifname);
|
||||
nlattr_add_string(nw, PF_RT_QNAME, rule->qname);
|
||||
nlattr_add_string(nw, PF_RT_PQNAME, rule->pqname);
|
||||
nlattr_add_string(nw, PF_RT_TAGNAME, rule->tagname);
|
||||
nlattr_add_string(nw, PF_RT_MATCH_TAGNAME, rule->match_tagname);
|
||||
nlattr_add_string(nw, PF_RT_OVERLOAD_TBLNAME, rule->overload_tblname);
|
||||
nlattr_add_pool(nw, PF_RT_RPOOL, &rule->rpool);
|
||||
nlattr_add_u32(nw, PF_RT_OS_FINGERPRINT, rule->os_fingerprint);
|
||||
nlattr_add_u32(nw, PF_RT_RTABLEID, rule->rtableid);
|
||||
nlattr_add_timeout(nw, PF_RT_TIMEOUT, rule->timeout);
|
||||
nlattr_add_u32(nw, PF_RT_MAX_STATES, rule->max_states);
|
||||
nlattr_add_u32(nw, PF_RT_MAX_SRC_NODES, rule->max_src_nodes);
|
||||
nlattr_add_u32(nw, PF_RT_MAX_SRC_STATES, rule->max_src_states);
|
||||
nlattr_add_u32(nw, PF_RT_MAX_SRC_CONN_RATE_LIMIT, rule->max_src_conn_rate.limit);
|
||||
nlattr_add_u32(nw, PF_RT_MAX_SRC_CONN_RATE_SECS, rule->max_src_conn_rate.seconds);
|
||||
|
||||
nlattr_add_u16(nw, PF_RT_DNPIPE, rule->dnpipe);
|
||||
nlattr_add_u16(nw, PF_RT_DNRPIPE, rule->dnrpipe);
|
||||
nlattr_add_u32(nw, PF_RT_DNFLAGS, rule->free_flags);
|
||||
|
||||
nlattr_add_u32(nw, PF_RT_NR, rule->nr);
|
||||
nlattr_add_u32(nw, PF_RT_PROB, rule->prob);
|
||||
nlattr_add_u32(nw, PF_RT_CUID, rule->cuid);
|
||||
nlattr_add_u32(nw, PF_RT_CPID, rule->cpid);
|
||||
|
||||
nlattr_add_u16(nw, PF_RT_RETURN_ICMP, rule->return_icmp);
|
||||
nlattr_add_u16(nw, PF_RT_RETURN_ICMP6, rule->return_icmp6);
|
||||
nlattr_add_u16(nw, PF_RT_RETURN_ICMP6, rule->return_icmp6);
|
||||
nlattr_add_u16(nw, PF_RT_MAX_MSS, rule->max_mss);
|
||||
nlattr_add_u16(nw, PF_RT_SCRUB_FLAGS, rule->scrub_flags);
|
||||
|
||||
nlattr_add_rule_uid(nw, PF_RT_UID, &rule->uid);
|
||||
nlattr_add_rule_uid(nw, PF_RT_GID, (const struct pf_rule_uid *)&rule->gid);
|
||||
|
||||
nlattr_add_u32(nw, PF_RT_RULE_FLAG, rule->rule_flag);
|
||||
nlattr_add_u8(nw, PF_RT_ACTION, rule->action);
|
||||
nlattr_add_u8(nw, PF_RT_DIRECTION, rule->direction);
|
||||
nlattr_add_u8(nw, PF_RT_LOG, rule->log);
|
||||
nlattr_add_u8(nw, PF_RT_LOGIF, rule->logif);
|
||||
nlattr_add_u8(nw, PF_RT_QUICK, rule->quick);
|
||||
nlattr_add_u8(nw, PF_RT_IF_NOT, rule->ifnot);
|
||||
nlattr_add_u8(nw, PF_RT_MATCH_TAG_NOT, rule->match_tag_not);
|
||||
nlattr_add_u8(nw, PF_RT_NATPASS, rule->natpass);
|
||||
nlattr_add_u8(nw, PF_RT_KEEP_STATE, rule->keep_state);
|
||||
|
||||
nlattr_add_u8(nw, PF_RT_AF, rule->af);
|
||||
nlattr_add_u8(nw, PF_RT_PROTO, rule->proto);
|
||||
nlattr_add_u8(nw, PF_RT_TYPE, rule->type);
|
||||
nlattr_add_u8(nw, PF_RT_CODE, rule->code);
|
||||
nlattr_add_u8(nw, PF_RT_FLAGS, rule->flags);
|
||||
nlattr_add_u8(nw, PF_RT_FLAGSET, rule->flagset);
|
||||
nlattr_add_u8(nw, PF_RT_MIN_TTL, rule->min_ttl);
|
||||
nlattr_add_u8(nw, PF_RT_ALLOW_OPTS, rule->allow_opts);
|
||||
nlattr_add_u8(nw, PF_RT_RT, rule->rt);
|
||||
nlattr_add_u8(nw, PF_RT_RETURN_TTL, rule->return_ttl);
|
||||
nlattr_add_u8(nw, PF_RT_TOS, rule->tos);
|
||||
nlattr_add_u8(nw, PF_RT_SET_TOS, rule->set_tos);
|
||||
nlattr_add_u8(nw, PF_RT_ANCHOR_RELATIVE, rule->anchor_relative);
|
||||
nlattr_add_u8(nw, PF_RT_ANCHOR_WILDCARD, rule->anchor_wildcard);
|
||||
nlattr_add_u8(nw, PF_RT_FLUSH, rule->flush);
|
||||
nlattr_add_u8(nw, PF_RT_PRIO, rule->prio);
|
||||
nlattr_add_u8(nw, PF_RT_SET_PRIO, rule->set_prio[0]);
|
||||
nlattr_add_u8(nw, PF_RT_SET_PRIO_REPLY, rule->set_prio[1]);
|
||||
|
||||
nlattr_add_in6_addr(nw, PF_RT_DIVERT_ADDRESS, &rule->divert.addr.v6);
|
||||
nlattr_add_u16(nw, PF_RT_DIVERT_PORT, rule->divert.port);
|
||||
|
||||
nlattr_add_u64(nw, PF_RT_PACKETS_IN, pf_counter_u64_fetch(&rule->packets[0]));
|
||||
nlattr_add_u64(nw, PF_RT_PACKETS_OUT, pf_counter_u64_fetch(&rule->packets[1]));
|
||||
nlattr_add_u64(nw, PF_RT_BYTES_IN, pf_counter_u64_fetch(&rule->bytes[0]));
|
||||
nlattr_add_u64(nw, PF_RT_BYTES_OUT, pf_counter_u64_fetch(&rule->bytes[1]));
|
||||
nlattr_add_u64(nw, PF_RT_EVALUATIONS, pf_counter_u64_fetch(&rule->evaluations));
|
||||
nlattr_add_u64(nw, PF_RT_TIMESTAMP, pf_get_timestamp(rule));
|
||||
nlattr_add_u64(nw, PF_RT_STATES_CUR, counter_u64_fetch(rule->states_cur));
|
||||
nlattr_add_u64(nw, PF_RT_STATES_TOTAL, counter_u64_fetch(rule->states_tot));
|
||||
nlattr_add_u64(nw, PF_RT_SRC_NODES, counter_u64_fetch(rule->src_nodes));
|
||||
|
||||
error = pf_kanchor_copyout(ruleset, rule, anchor_call);
|
||||
MPASS(error == 0);
|
||||
|
||||
nlattr_add_string(nw, PF_RT_ANCHOR_CALL, anchor_call);
|
||||
|
||||
if (attrs.clear)
|
||||
pf_krule_clear_counters(rule);
|
||||
|
||||
PF_RULES_WUNLOCK();
|
||||
|
||||
if (!nlmsg_end(nw)) {
|
||||
error = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return (0);
|
||||
out:
|
||||
nlmsg_abort(nw);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static const struct nlhdr_parser *all_parsers[] = {
|
||||
&state_parser,
|
||||
&addrule_parser,
|
||||
@ -746,6 +1051,13 @@ static const struct genl_cmd pf_cmds[] = {
|
||||
.cmd_flags = GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
|
||||
.cmd_priv = PRIV_NETINET_PF,
|
||||
},
|
||||
{
|
||||
.cmd_num = PFNL_CMD_GETRULE,
|
||||
.cmd_name = "GETRULE",
|
||||
.cmd_cb = pf_handle_getrule,
|
||||
.cmd_flags = GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
|
||||
.cmd_priv = PRIV_NETINET_PF,
|
||||
},
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -42,6 +42,7 @@ enum {
|
||||
PFNL_CMD_STOP = 4,
|
||||
PFNL_CMD_ADDRULE = 5,
|
||||
PFNL_CMD_GETRULES = 6,
|
||||
PFNL_CMD_GETRULE = 7,
|
||||
__PFNL_CMD_MAX,
|
||||
};
|
||||
#define PFNL_CMD_MAX (__PFNL_CMD_MAX -1)
|
||||
@ -117,6 +118,8 @@ enum pf_addr_type_t {
|
||||
PF_AT_TABLENAME = 4, /* string */
|
||||
PF_AT_TYPE = 5, /* u8 */
|
||||
PF_AT_IFLAGS = 6, /* u8 */
|
||||
PF_AT_TBLCNT = 7, /* u32 */
|
||||
PF_AT_DYNCNT = 8, /* u32 */
|
||||
};
|
||||
|
||||
enum pfrule_addr_type_t {
|
||||
@ -229,6 +232,16 @@ enum pf_rule_type_t {
|
||||
PF_RT_SET_PRIO_REPLY = 60, /* u8 */
|
||||
PF_RT_DIVERT_ADDRESS = 61, /* in6_addr */
|
||||
PF_RT_DIVERT_PORT = 62, /* u16 */
|
||||
PF_RT_PACKETS_IN = 63, /* u64 */
|
||||
PF_RT_PACKETS_OUT = 64, /* u64 */
|
||||
PF_RT_BYTES_IN = 65, /* u64 */
|
||||
PF_RT_BYTES_OUT = 66, /* u64 */
|
||||
PF_RT_EVALUATIONS = 67, /* u64 */
|
||||
PF_RT_TIMESTAMP = 68, /* u64 */
|
||||
PF_RT_STATES_CUR = 69, /* u64 */
|
||||
PF_RT_STATES_TOTAL = 70, /* u64 */
|
||||
PF_RT_SRC_NODES = 71, /* u64 */
|
||||
PF_RT_ANCHOR_CALL = 72, /* string */
|
||||
};
|
||||
|
||||
enum pf_addrule_type_t {
|
||||
@ -246,6 +259,7 @@ enum pf_getrules_type_t {
|
||||
PF_GR_ACTION = 2, /* u8 */
|
||||
PF_GR_NR = 3, /* u32 */
|
||||
PF_GR_TICKET = 4, /* u32 */
|
||||
PF_GR_CLEAR = 5, /* u8 */
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
@ -367,10 +367,10 @@ pf_kanchor_setup(struct pf_krule *r, const struct pf_kruleset *s,
|
||||
}
|
||||
|
||||
int
|
||||
pf_kanchor_nvcopyout(const struct pf_kruleset *rs, const struct pf_krule *r,
|
||||
nvlist_t *nvl)
|
||||
pf_kanchor_copyout(const struct pf_kruleset *rs, const struct pf_krule *r,
|
||||
char *anchor_call)
|
||||
{
|
||||
char anchor_call[MAXPATHLEN] = { 0 };
|
||||
anchor_call[0] = 0;
|
||||
|
||||
if (r->anchor == NULL)
|
||||
goto done;
|
||||
@ -408,11 +408,25 @@ pf_kanchor_nvcopyout(const struct pf_kruleset *rs, const struct pf_krule *r,
|
||||
sizeof(anchor_call));
|
||||
|
||||
done:
|
||||
nvlist_add_string(nvl, "anchor_call", anchor_call);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pf_kanchor_nvcopyout(const struct pf_kruleset *rs, const struct pf_krule *r,
|
||||
nvlist_t *nvl)
|
||||
{
|
||||
char anchor_call[MAXPATHLEN] = { 0 };
|
||||
int ret;
|
||||
|
||||
ret = pf_kanchor_copyout(rs, r, anchor_call);
|
||||
MPASS(ret == 0);
|
||||
|
||||
nvlist_add_string(nvl, "anchor_call", anchor_call);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
pf_keth_anchor_nvcopyout(const struct pf_keth_ruleset *rs,
|
||||
const struct pf_keth_rule *r, nvlist_t *nvl)
|
||||
@ -460,52 +474,6 @@ done:
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pf_kanchor_copyout(const struct pf_kruleset *rs, const struct pf_krule *r,
|
||||
struct pfioc_rule *pr)
|
||||
{
|
||||
pr->anchor_call[0] = 0;
|
||||
if (r->anchor == NULL)
|
||||
return (0);
|
||||
if (!r->anchor_relative) {
|
||||
strlcpy(pr->anchor_call, "/", sizeof(pr->anchor_call));
|
||||
strlcat(pr->anchor_call, r->anchor->path,
|
||||
sizeof(pr->anchor_call));
|
||||
} else {
|
||||
char *a, *p;
|
||||
int i;
|
||||
|
||||
a = (char *)rs_malloc(MAXPATHLEN);
|
||||
if (a == NULL)
|
||||
return (1);
|
||||
if (rs->anchor == NULL)
|
||||
a[0] = 0;
|
||||
else
|
||||
strlcpy(a, rs->anchor->path, MAXPATHLEN);
|
||||
for (i = 1; i < r->anchor_relative; ++i) {
|
||||
if ((p = strrchr(a, '/')) == NULL)
|
||||
p = a;
|
||||
*p = 0;
|
||||
strlcat(pr->anchor_call, "../",
|
||||
sizeof(pr->anchor_call));
|
||||
}
|
||||
if (strncmp(a, r->anchor->path, strlen(a))) {
|
||||
printf("pf_anchor_copyout: '%s' '%s'\n", a,
|
||||
r->anchor->path);
|
||||
rs_free(a);
|
||||
return (1);
|
||||
}
|
||||
if (strlen(r->anchor->path) > strlen(a))
|
||||
strlcat(pr->anchor_call, r->anchor->path + (a[0] ?
|
||||
strlen(a) + 1 : 0), sizeof(pr->anchor_call));
|
||||
rs_free(a);
|
||||
}
|
||||
if (r->anchor_wildcard)
|
||||
strlcat(pr->anchor_call, pr->anchor_call[0] ? "/*" : "*",
|
||||
sizeof(pr->anchor_call));
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
pf_kanchor_remove(struct pf_krule *r)
|
||||
{
|
||||
|
@ -358,6 +358,17 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* noexcept keyword added in C++11.
|
||||
*/
|
||||
#if defined(__cplusplus) && __cplusplus >= 201103L
|
||||
#define __noexcept noexcept
|
||||
#define __noexcept_if(__c) noexcept(__c)
|
||||
#else
|
||||
#define __noexcept
|
||||
#define __noexcept_if(__c)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We use `__restrict' as a way to define the `restrict' type qualifier
|
||||
* without disturbing older software that is unaware of C99 keywords.
|
||||
|
@ -407,6 +407,55 @@ ifbound_cleanup()
|
||||
pft_cleanup
|
||||
}
|
||||
|
||||
atf_test_case "dummynet_frag" "cleanup"
|
||||
dummynet_frag_head()
|
||||
{
|
||||
atf_set descr 'Test fragmentation with route-to and dummynet'
|
||||
atf_set require.user root
|
||||
}
|
||||
|
||||
dummynet_frag_body()
|
||||
{
|
||||
pft_init
|
||||
dummynet_init
|
||||
|
||||
epair_one=$(vnet_mkepair)
|
||||
epair_two=$(vnet_mkepair)
|
||||
|
||||
ifconfig ${epair_one}a 192.0.2.1/24 up
|
||||
|
||||
vnet_mkjail alcatraz ${epair_one}b ${epair_two}a
|
||||
jexec alcatraz ifconfig ${epair_one}b 192.0.2.2/24 up
|
||||
jexec alcatraz ifconfig ${epair_two}a 198.51.100.1/24 up
|
||||
jexec alcatraz sysctl net.inet.ip.forwarding=1
|
||||
|
||||
vnet_mkjail singsing ${epair_two}b
|
||||
jexec singsing ifconfig ${epair_two}b 198.51.100.2/24 up
|
||||
jexec singsing route add default 198.51.100.1
|
||||
|
||||
route add 198.51.100.0/24 192.0.2.2
|
||||
|
||||
jexec alcatraz dnctl pipe 1 config bw 1000Byte/s burst 4500
|
||||
jexec alcatraz dnctl pipe 2 config
|
||||
# This second pipe ensures that the pf_test(PF_OUT) call in pf_route() doesn't
|
||||
# delay packets in dummynet (by inheriting pipe 1 from the input rule).
|
||||
|
||||
jexec alcatraz pfctl -e
|
||||
pft_set_rules alcatraz \
|
||||
"set reassemble yes" \
|
||||
"pass in route-to (${epair_two}a 198.51.100.2) inet proto icmp all icmp-type echoreq dnpipe 1" \
|
||||
"pass out dnpipe 2"
|
||||
|
||||
|
||||
atf_check -s exit:0 -o ignore ping -c 1 198.51.100.2
|
||||
atf_check -s exit:0 -o ignore ping -c 1 -s 4000 198.51.100.2
|
||||
}
|
||||
|
||||
dummynet_frag_cleanup()
|
||||
{
|
||||
pft_cleanup
|
||||
}
|
||||
|
||||
atf_init_test_cases()
|
||||
{
|
||||
atf_add_test_case "v4"
|
||||
@ -416,4 +465,5 @@ atf_init_test_cases()
|
||||
atf_add_test_case "icmp_nat"
|
||||
atf_add_test_case "dummynet"
|
||||
atf_add_test_case "ifbound"
|
||||
atf_add_test_case "dummynet_frag"
|
||||
}
|
||||
|
@ -533,9 +533,10 @@ Run "etcupdate extract" once when your sources match your running system, then r
|
||||
Do you want to do a binary upgrade of your running FreeBSD installation? Use freebsd-update(8).
|
||||
|
||||
To install updates and patches for the running branch use
|
||||
# freebsd-update fetch install
|
||||
# freebsd-update fetch
|
||||
# freebsd-update install
|
||||
|
||||
To upgrade to a newer release use
|
||||
Then, to upgrade to a newer release use
|
||||
# freebsd-update upgrade -r ${name_of_release}
|
||||
|
||||
-- Lars Engels <lme@FreeBSD.org>
|
||||
|
@ -717,12 +717,9 @@ read_kld(char *filename, char *kldname)
|
||||
static FILE *
|
||||
maketempfile(char *dest, const char *root)
|
||||
{
|
||||
char *p;
|
||||
int n, fd;
|
||||
int fd;
|
||||
|
||||
p = strrchr(root, '/');
|
||||
n = p != NULL ? p - root + 1 : 0;
|
||||
if (snprintf(dest, MAXPATHLEN, "%.*slhint.XXXXXX", n, root) >=
|
||||
if (snprintf(dest, MAXPATHLEN, "%s/lhint.XXXXXX", root) >=
|
||||
MAXPATHLEN) {
|
||||
errno = ENAMETOOLONG;
|
||||
return (NULL);
|
||||
|
@ -13,6 +13,7 @@ then
|
||||
fi
|
||||
|
||||
bak_dir=/var/backups
|
||||
rc=0
|
||||
|
||||
rotate() {
|
||||
base_name=$1
|
||||
@ -20,12 +21,13 @@ rotate() {
|
||||
file="$bak_dir/$base_name"
|
||||
|
||||
if [ -f "${file}.bak" ] ; then
|
||||
rc=0
|
||||
if cmp -s "${file}.bak" "${file}.tmp"; then
|
||||
rm "${file}.tmp"
|
||||
else
|
||||
rc=1
|
||||
[ -n "$show_diff" ] && diff ${daily_diff_flags} "${file}.bak" "${file}.tmp"
|
||||
if [ -n "$show_diff" ]; then
|
||||
rc=1
|
||||
diff ${daily_diff_flags} "${file}.bak" "${file}.tmp"
|
||||
fi
|
||||
mv "${file}.bak" "${file}.bak2" || rc=3
|
||||
mv "${file}.tmp" "${file}.bak" || rc=3
|
||||
fi
|
||||
@ -36,6 +38,7 @@ rotate() {
|
||||
fi
|
||||
}
|
||||
|
||||
show=""
|
||||
case "$daily_backup_zfs_verbose" in
|
||||
[Yy][Ee][Ss]) show="YES"
|
||||
esac
|
||||
@ -43,9 +46,9 @@ esac
|
||||
case "$daily_backup_zfs_enable" in
|
||||
[Yy][Ee][Ss])
|
||||
|
||||
zpools=$(zpool list $daily_backup_zpool_list_flags)
|
||||
zpools=$(zpool list $daily_backup_zpool_list_flags)
|
||||
|
||||
if [ -z "$zpools" ]; then
|
||||
if [ -z "$zpools" ]; then
|
||||
echo 'daily_backup_zfs_enable is set to YES but no zpools found.'
|
||||
rc=2
|
||||
else
|
||||
@ -59,18 +62,17 @@ case "$daily_backup_zfs_enable" in
|
||||
rotate "zfs_list" $show
|
||||
fi
|
||||
;;
|
||||
*) rc=0;;
|
||||
esac
|
||||
|
||||
case "$daily_backup_zfs_props_enable" in
|
||||
[Yy][Ee][Ss])
|
||||
[Yy][Ee][Ss])
|
||||
|
||||
zfs get $daily_backup_zfs_get_flags > "$bak_dir/zfs_props.tmp"
|
||||
rotate "zfs_props"
|
||||
zfs get $daily_backup_zfs_get_flags > "$bak_dir/zfs_props.tmp"
|
||||
rotate "zfs_props" $show
|
||||
|
||||
zpool get $daily_backup_zpool_get_flags > "$bak_dir/zpool_props.tmp"
|
||||
rotate "zpool_props"
|
||||
;;
|
||||
zpool get $daily_backup_zpool_get_flags > "$bak_dir/zpool_props.tmp"
|
||||
rotate "zpool_props" $show
|
||||
;;
|
||||
esac
|
||||
|
||||
exit $rc
|
||||
|
Loading…
Reference in New Issue
Block a user