sync with OpenBSD -current

This commit is contained in:
purplerain 2024-06-06 00:05:03 +00:00
parent 2d7157972b
commit 6040ea8924
Signed by: purplerain
GPG key ID: F42C07F07E2E35B7
17 changed files with 989 additions and 255 deletions

View file

@ -1,4 +1,4 @@
/* $OpenBSD: chacha-merged.c,v 1.12 2024/06/01 17:56:44 tb Exp $ */
/* $OpenBSD: chacha-merged.c,v 1.13 2024/06/05 19:43:06 tb Exp $ */
/*
chacha-merged.c version 20080118
D. J. Bernstein
@ -7,10 +7,6 @@ Public domain.
#include <stdint.h>
#if !defined(HAVE_ATTRIBUTE__BOUNDED__) && !defined(__OpenBSD__)
#define __bounded__(x, y, z)
#endif
#define CHACHA_MINKEYLEN 16
#define CHACHA_NONCELEN 8
#define CHACHA_CTRLEN 8

View file

@ -1,4 +1,4 @@
/* $OpenBSD: tls_prf.c,v 1.9 2024/02/03 15:58:34 beck Exp $ */
/* $OpenBSD: tls_prf.c,v 1.10 2024/06/05 04:50:36 tb Exp $ */
/*
* Copyright (c) 2017 Joel Sing <jsing@openbsd.org>
*
@ -33,7 +33,7 @@ struct tls_prf_test {
const unsigned char out[TLS_PRF_OUT_LEN];
};
static struct tls_prf_test tls_prf_tests[] = {
static const struct tls_prf_test tls_prf_tests[] = {
{
.desc = "MD5+SHA1",
.ssl_method = TLSv1_method,
@ -127,7 +127,7 @@ hexdump(const unsigned char *buf, size_t len)
}
static int
do_tls_prf_test(int test_no, struct tls_prf_test *tpt)
do_tls_prf_test(int test_no, const struct tls_prf_test *tpt)
{
unsigned char *out = NULL;
const SSL_CIPHER *cipher;

View file

@ -1,8 +1,8 @@
# $OpenBSD: Makefile,v 1.1 2024/06/02 12:28:05 florian Exp $
# $OpenBSD: Makefile,v 1.2 2024/06/05 16:15:47 florian Exp $
PROG= dhcp6leased
SRCS= control.c dhcp6leased.c engine.c frontend.c log.c
SRCS+= parse.y printconf.c
SRCS+= parse.y printconf.c parse_lease.y
MAN= dhcp6leased.8 dhcp6leased.conf.5
@ -17,6 +17,9 @@ YFLAGS=
LDADD+= -levent -lutil
DPADD+= ${LIBEVENT} ${LIBUTIL}
parse_lease.c: parse_lease.y
${YACC.y} -ppl -o ${.TARGET} ${.IMPSRC}
.include <bsd.prog.mk>
# Don't compile dhcp6leased as static binary by default

View file

@ -1,4 +1,4 @@
/* $OpenBSD: control.c,v 1.2 2024/06/02 13:35:52 florian Exp $ */
/* $OpenBSD: control.c,v 1.3 2024/06/05 16:15:47 florian Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -28,6 +28,7 @@
#include <errno.h>
#include <event.h>
#include <imsg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

View file

@ -1,4 +1,4 @@
/* $OpenBSD: dhcp6leased.c,v 1.9 2024/06/03 15:53:26 deraadt Exp $ */
/* $OpenBSD: dhcp6leased.c,v 1.11 2024/06/05 16:15:47 florian Exp $ */
/*
* Copyright (c) 2017, 2021, 2024 Florian Obser <florian@openbsd.org>
@ -78,6 +78,7 @@ void configure_address(struct imsg_configure_address *);
void deconfigure_address(struct imsg_configure_address *);
void read_lease_file(struct imsg_ifinfo *);
uint8_t *get_uuid(void);
void write_lease_file(struct imsg_lease_info *);
int main_imsg_send_ipc_sockets(struct imsgbuf *, struct imsgbuf *);
int main_imsg_compose_frontend(int, int, void *, uint16_t);
@ -309,7 +310,8 @@ main(int argc, char *argv[])
if (unveil(NULL, NULL) == -1)
fatal("unveil");
if (pledge("stdio inet rpath wpath sendfd wroute", NULL) == -1)
if (pledge("stdio inet rpath wpath cpath fattr sendfd wroute", NULL)
== -1)
fatal("pledge");
main_imsg_compose_frontend(IMSG_ROUTESOCK, frontend_routesock, NULL, 0);
@ -543,6 +545,17 @@ main_dispatch_engine(int fd, short event, void *bula)
deconfigure_address(&imsg_configure_address);
break;
}
case IMSG_WRITE_LEASE: {
struct imsg_lease_info imsg_lease_info;
if (IMSG_DATA_SIZE(imsg) !=
sizeof(imsg_lease_info))
fatalx("%s: IMSG_WRITE_LEASE wrong length: %lu",
__func__, IMSG_DATA_SIZE(imsg));
memcpy(&imsg_lease_info, imsg.data,
sizeof(imsg_lease_info));
write_lease_file(&imsg_lease_info);
break;
}
default:
log_debug("%s: error handling imsg %d", __func__,
imsg.hdr.type);
@ -726,9 +739,28 @@ configure_address(struct imsg_configure_address *address)
}
void
deconfigure_address(struct imsg_configure_address *imsg)
deconfigure_address(struct imsg_configure_address *address)
{
fatalx("%s: not implemented", __func__); /* XXX */
struct in6_ifreq in6_ridreq;
char *if_name;
memset(&in6_ridreq, 0, sizeof(in6_ridreq));
if_name = if_indextoname(address->if_index, in6_ridreq.ifr_name);
if (if_name == NULL) {
log_warnx("%s: cannot find interface %d", __func__,
address->if_index);
return;
}
memcpy(&in6_ridreq.ifr_addr, &address->addr,
sizeof(in6_ridreq.ifr_addr));
log_debug("%s: %s", __func__, if_name);
if (ioctl(ioctl_sock, SIOCDIFADDR_IN6, &in6_ridreq) == -1 &&
errno != EADDRNOTAVAIL)
log_warn("%s: cannot remove address", __func__);
}
const char*
@ -839,17 +871,99 @@ open_udpsock(uint32_t if_index)
freeifaddrs(ifap);
}
void
write_lease_file(struct imsg_lease_info *imsg_lease_info)
{
struct iface_conf *iface_conf;
uint32_t i;
int len, fd, rem;
char if_name[IF_NAMESIZE];
char lease_buf[LEASE_SIZE];
char lease_file_buf[sizeof(_PATH_LEASE) +
IF_NAMESIZE];
char tmpl[] = _PATH_LEASE"XXXXXXXXXX";
char ntopbuf[INET6_ADDRSTRLEN];
char *p;
if (no_lease_files)
return;
if (if_indextoname(imsg_lease_info->if_index, if_name) == NULL) {
log_warnx("%s: cannot find interface %d", __func__,
imsg_lease_info->if_index);
return;
}
if ((iface_conf = find_iface_conf(&main_conf->iface_list, if_name))
== NULL) {
log_debug("%s: no interface configuration for %s", __func__,
if_name);
return;
}
len = snprintf(lease_file_buf, sizeof(lease_file_buf), "%s%s",
_PATH_LEASE, if_name);
if (len == -1 || (size_t) len >= sizeof(lease_file_buf)) {
log_warnx("%s: failed to encode lease path for %s", __func__,
if_name);
return;
}
p = lease_buf;
rem = sizeof(lease_buf);
for (i = 0; i < iface_conf->ia_count; i++) {
len = snprintf(p, rem, "%s%d %s %d\n", LEASE_IA_PD_PREFIX,
i, inet_ntop(AF_INET6, &imsg_lease_info->pds[i].prefix,
ntopbuf, INET6_ADDRSTRLEN),
imsg_lease_info->pds[i].prefix_len);
if (len == -1 || len >= rem) {
log_warnx("%s: failed to encode lease for %s", __func__,
if_name);
return;
}
p += len;
rem -= len;
}
len = sizeof(lease_buf) - rem;
if ((fd = mkstemp(tmpl)) == -1) {
log_warn("%s: mkstemp", __func__);
return;
}
if (write(fd, lease_buf, len) < len)
goto err;
if (fchmod(fd, 0644) == -1)
goto err;
if (close(fd) == -1)
goto err;
fd = -1;
if (rename(tmpl, lease_file_buf) == -1)
goto err;
return;
err:
log_warn("%s", __func__);
if (fd != -1)
close(fd);
unlink(tmpl);
}
void
read_lease_file(struct imsg_ifinfo *imsg_ifinfo)
{
int len, fd;
int len;
char if_name[IF_NAMESIZE];
char lease_file_buf[sizeof(_PATH_LEASE) + IF_NAMESIZE];
if (no_lease_files)
return;
memset(imsg_ifinfo->lease, 0, sizeof(imsg_ifinfo->lease));
memset(imsg_ifinfo->pds, 0, sizeof(imsg_ifinfo->pds));
if (if_indextoname(imsg_ifinfo->if_index, if_name) == NULL) {
log_warnx("%s: cannot find interface %d", __func__,
@ -864,13 +978,22 @@ read_lease_file(struct imsg_ifinfo *imsg_ifinfo)
if_name);
return;
}
parse_lease(lease_file_buf, imsg_ifinfo);
if ((fd = open(lease_file_buf, O_RDONLY)) == -1)
return;
if (log_getverbose() > 1) {
int i;
char ntopbuf[INET6_ADDRSTRLEN];
/* no need for error handling, we'll just do a DHCP discover */
read(fd, imsg_ifinfo->lease, sizeof(imsg_ifinfo->lease) - 1);
close(fd);
for (i = 0; i < MAX_IA; i++) {
if (imsg_ifinfo->pds[i].prefix_len == 0)
continue;
log_debug("%s: %s: %d %s/%d", __func__, if_name, i,
inet_ntop(AF_INET6, &imsg_ifinfo->pds[i].prefix,
ntopbuf, INET6_ADDRSTRLEN),
imsg_ifinfo->pds[i].prefix_len);
}
}
}
void

View file

@ -1,4 +1,4 @@
/* $OpenBSD: dhcp6leased.h,v 1.5 2024/06/03 18:10:04 florian Exp $ */
/* $OpenBSD: dhcp6leased.h,v 1.7 2024/06/05 16:15:47 florian Exp $ */
/*
* Copyright (c) 2017, 2021 Florian Obser <florian@openbsd.org>
@ -18,6 +18,10 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef nitems
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
#endif
#define _PATH_LOCKFILE "/dev/dhcp6leased.lock"
#define _PATH_CONF_FILE "/etc/dhcp6leased.conf"
#define _PATH_CTRL_SOCKET "/dev/dhcp6leased.sock"
@ -33,13 +37,8 @@
#define XID_SIZE 3
#define SERVERID_SIZE 130 /* 2 octet type, max 128 octets data */
#define MAX_IA 32
#define LEASE_VERSION "version: 2"
#define LEASE_IP_PREFIX "ip: "
#define LEASE_NEXTSERVER_PREFIX "next-server: "
#define LEASE_BOOTFILE_PREFIX "filename: "
#define LEASE_HOSTNAME_PREFIX "host-name: "
#define LEASE_DOMAIN_PREFIX "domain-name: "
#define LEASE_SIZE 4096
#define LEASE_IA_PD_PREFIX "ia_pd "
/* MAXDNAME from arpa/namesr.h */
#define DHCP6LEASED_MAX_DNSSL 1025
#define MAX_RDNS_COUNT 8 /* max nameserver in a RTM_PROPOSAL */
@ -173,6 +172,7 @@ enum imsg_type {
IMSG_CONFIGURE_ADDRESS,
IMSG_DECONFIGURE_ADDRESS,
IMSG_REQUEST_REBOOT,
IMSG_WRITE_LEASE,
};
struct ctl_engine_info {
@ -213,12 +213,19 @@ struct dhcp6leased_conf {
int rapid_commit;
};
struct prefix {
struct in6_addr prefix;
int prefix_len;
uint32_t vltime;
uint32_t pltime;
};
struct imsg_ifinfo {
uint32_t if_index;
int rdomain;
int running;
int link_state;
char lease[LEASE_SIZE];
struct prefix pds[MAX_IA];
};
struct imsg_dhcp {
@ -227,13 +234,6 @@ struct imsg_dhcp {
uint8_t packet[1500];
};
struct prefix {
struct in6_addr prefix;
int prefix_len;
uint32_t vltime;
uint32_t pltime;
};
struct imsg_req_dhcp {
uint32_t if_index;
int elapsed_time;
@ -243,6 +243,11 @@ struct imsg_req_dhcp {
struct prefix pds[MAX_IA];
};
struct imsg_lease_info {
uint32_t if_index;
struct prefix pds[MAX_IA];
};
/* dhcp6leased.c */
void imsg_event_add(struct imsgev *);
int imsg_compose_event(struct imsgev *, uint16_t, uint32_t,
@ -264,6 +269,25 @@ int *changed_ifaces(struct dhcp6leased_conf *, struct
void print_config(struct dhcp6leased_conf *, int);
/* parse.y */
struct dhcp6leased_conf *parse_config(const char *);
int cmdline_symset(char *);
struct file {
TAILQ_ENTRY(file) entry;
FILE *stream;
char *name;
size_t ungetpos;
size_t ungetsize;
u_char *ungetbuf;
int eof_reached;
int lineno;
int errors;
};
struct dhcp6leased_conf *parse_config(const char *);
struct file *pushfile(const char *, int);
int popfile(void);
int kw_cmp(const void *, const void *);
int lgetc(int);
void lungetc(int);
int findeol(void);
/* parse_lease.y */
void parse_lease(const char*, struct imsg_ifinfo *);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: engine.c,v 1.8 2024/06/04 15:48:47 florian Exp $ */
/* $OpenBSD: engine.c,v 1.12 2024/06/05 16:15:47 florian Exp $ */
/*
* Copyright (c) 2017, 2021, 2024 Florian Obser <florian@openbsd.org>
@ -83,6 +83,16 @@ const char* if_state_name[] = {
"IPv6 only",
};
enum reconfigure_action {
CONFIGURE,
DECONFIGURE,
};
const char* reconfigure_action_name[] = {
"configure",
"deconfigure",
};
struct dhcp6leased_iface {
LIST_ENTRY(dhcp6leased_iface) entries;
enum if_state state;
@ -122,12 +132,11 @@ void state_transition(struct dhcp6leased_iface *, enum
void iface_timeout(int, short, void *);
void request_dhcp_discover(struct dhcp6leased_iface *);
void request_dhcp_request(struct dhcp6leased_iface *);
void log_lease(struct dhcp6leased_iface *, int);
void configure_interfaces(struct dhcp6leased_iface *);
void send_configure_interface(struct iface_pd_conf *,
struct prefix *);
void send_deconfigure_interface(struct dhcp6leased_iface *);
void parse_lease(struct dhcp6leased_iface *,
void deconfigure_interfaces(struct dhcp6leased_iface *);
void send_reconfigure_interface(struct iface_pd_conf *,
struct prefix *, enum reconfigure_action);
void parse_lease_xxx(struct dhcp6leased_iface *,
struct imsg_ifinfo *);
int engine_imsg_compose_main(int, pid_t, void *, uint16_t);
const char *dhcp_message_type2str(uint8_t);
@ -436,8 +445,6 @@ engine_dispatch_main(int fd, short event, void *bula)
fatalx("%s: IMSG_UPDATE_IF wrong length: %lu",
__func__, IMSG_DATA_SIZE(imsg));
memcpy(&imsg_ifinfo, imsg.data, sizeof(imsg_ifinfo));
if (imsg_ifinfo.lease[LEASE_SIZE - 1] != '\0')
fatalx("Invalid lease");
engine_update_iface(&imsg_ifinfo);
break;
case IMSG_RECONF_CONF:
@ -592,7 +599,9 @@ void
engine_update_iface(struct imsg_ifinfo *imsg_ifinfo)
{
struct dhcp6leased_iface *iface;
struct iface_conf *iface_conf;
int need_refresh = 0;
char ifnamebuf[IF_NAMESIZE], *if_name;
iface = get_dhcp6leased_iface_by_id(imsg_ifinfo->if_index);
@ -628,17 +637,37 @@ engine_update_iface(struct imsg_ifinfo *imsg_ifinfo)
if (!need_refresh)
return;
if (iface->running && LINK_STATE_IS_UP(iface->link_state)) {
#if 0
XXXX
if (iface->requested_ip.s_addr == INADDR_ANY)
parse_lease(iface, imsg_ifinfo);
if ((if_name = if_indextoname(iface->if_index, ifnamebuf)) == NULL) {
log_debug("%s: unknown interface %d", __func__,
iface->if_index);
return;
}
if (iface->requested_ip.s_addr == INADDR_ANY)
state_transition(iface, IF_INIT);
else
if ((iface_conf = find_iface_conf(&engine_conf->iface_list, if_name))
== NULL) {
log_debug("%s: no interface configuration for %d", __func__,
iface->if_index);
return;
}
if (iface->running && LINK_STATE_IS_UP(iface->link_state)) {
uint32_t i;
int got_lease;
if (iface->pds[0].prefix_len == 0)
memcpy(iface->pds, imsg_ifinfo->pds,
sizeof(iface->pds));
got_lease = 0;
for (i = 0; i < iface_conf->ia_count; i++) {
if (iface->pds[i].prefix_len > 0) {
got_lease = 1;
break;
}
}
if (got_lease)
state_transition(iface, IF_REBOOTING);
#endif
else
state_transition(iface, IF_INIT);
} else
state_transition(iface, IF_DOWN);
@ -665,7 +694,7 @@ remove_dhcp6leased_iface(uint32_t if_index)
if (iface == NULL)
return;
send_deconfigure_interface(iface);
deconfigure_interfaces(iface);
LIST_REMOVE(iface, entries);
evtimer_del(&iface->timer);
free(iface);
@ -875,6 +904,7 @@ parse_dhcp(struct dhcp6leased_iface *iface, struct imsg_dhcp *dhcp)
case IF_REQUESTING:
case IF_RENEWING:
case IF_REBINDING:
case IF_REBOOTING:
break;
case IF_INIT:
if (rapid_commit && engine_conf->rapid_commit)
@ -1012,7 +1042,7 @@ XXXX
}
if (old_state == IF_DOWN) {
/* nameservers already withdrawn when if went down */
send_deconfigure_interface(iface);
deconfigure_interfaces(iface);
/* nothing more to do until iface comes back */
iface->timo.tv_sec = -1;
} else {
@ -1037,7 +1067,7 @@ XXXX
case IF_REBINDING:
case IF_REBOOTING:
/* lease expired, got DHCPNAK or timeout: delete IP */
send_deconfigure_interface(iface);
deconfigure_interfaces(iface);
/* fall through */
case IF_DOWN:
iface->timo.tv_sec = START_EXP_BACKOFF;
@ -1223,8 +1253,6 @@ request_dhcp_request(struct dhcp6leased_iface *iface)
fatalx("invalid state IF_BOUND in %s", __func__);
break;
case IF_REBOOTING:
fatalx("XXX state IF_REBOOTING in %s not IMPL", __func__);
break;
case IF_REQUESTING:
case IF_RENEWING:
case IF_REBINDING:
@ -1242,6 +1270,7 @@ request_dhcp_request(struct dhcp6leased_iface *iface)
engine_imsg_compose_frontend(IMSG_SEND_RENEW, 0, &imsg,
sizeof(imsg));
break;
case IF_REBOOTING:
case IF_REBINDING:
engine_imsg_compose_frontend(IMSG_SEND_REBIND, 0, &imsg,
sizeof(imsg));
@ -1251,15 +1280,46 @@ request_dhcp_request(struct dhcp6leased_iface *iface)
}
}
void
log_lease(struct dhcp6leased_iface *iface, int deconfigure)
{
fatalx("%s: not implemented", __func__); /* XXX */
}
/* XXX we need to install a reject route for the delegated prefix */
void
configure_interfaces(struct dhcp6leased_iface *iface)
{
struct iface_conf *iface_conf;
struct iface_ia_conf *ia_conf;
struct iface_pd_conf *pd_conf;
struct imsg_lease_info imsg_lease_info;
char ifnamebuf[IF_NAMESIZE], *if_name;
if ((if_name = if_indextoname(iface->if_index, ifnamebuf)) == NULL) {
log_debug("%s: unknown interface %d", __func__,
iface->if_index);
return;
}
if ((iface_conf = find_iface_conf(&engine_conf->iface_list, if_name))
== NULL) {
log_debug("%s: no interface configuration for %d", __func__,
iface->if_index);
return;
}
memset(&imsg_lease_info, 0, sizeof(imsg_lease_info));
imsg_lease_info.if_index = iface->if_index;
memcpy(imsg_lease_info.pds, iface->pds, sizeof(iface->pds));
engine_imsg_compose_main(IMSG_WRITE_LEASE, 0, &imsg_lease_info,
sizeof(imsg_lease_info));
SIMPLEQ_FOREACH(ia_conf, &iface_conf->iface_ia_list, entry) {
struct prefix *pd = &iface->pds[ia_conf->id];
SIMPLEQ_FOREACH(pd_conf, &ia_conf->iface_pd_list, entry) {
send_reconfigure_interface(pd_conf, pd, CONFIGURE);
}
}
}
void
deconfigure_interfaces(struct dhcp6leased_iface *iface)
{
struct iface_conf *iface_conf;
struct iface_ia_conf *ia_conf;
@ -1283,19 +1343,23 @@ configure_interfaces(struct dhcp6leased_iface *iface)
struct prefix *pd = &iface->pds[ia_conf->id];
SIMPLEQ_FOREACH(pd_conf, &ia_conf->iface_pd_list, entry) {
send_configure_interface(pd_conf, pd);
send_reconfigure_interface(pd_conf, pd, DECONFIGURE);
}
}
}
void
send_configure_interface(struct iface_pd_conf *pd_conf, struct prefix *pd)
send_reconfigure_interface(struct iface_pd_conf *pd_conf, struct prefix *pd,
enum reconfigure_action action)
{
struct imsg_configure_address address;
uint32_t if_index;
int i;
char ntopbuf[INET6_ADDRSTRLEN];
if (pd->prefix_len == 0)
return;
if (strcmp(pd_conf->name, "reserve") == 0)
return;
@ -1318,27 +1382,20 @@ send_configure_interface(struct iface_pd_conf *pd_conf, struct prefix *pd)
in6_prefixlen2mask(&address.mask, pd_conf->prefix_len);
log_debug("%s: %s: %s/%d", __func__, pd_conf->name,
inet_ntop(AF_INET6, &address.addr.sin6_addr, ntopbuf,
INET6_ADDRSTRLEN), pd_conf->prefix_len);
log_debug("%s: %s %s: %s/%d", __func__, pd_conf->name,
reconfigure_action_name[action], inet_ntop(AF_INET6,
&address.addr.sin6_addr, ntopbuf, INET6_ADDRSTRLEN),
pd_conf->prefix_len);
address.vltime = pd->vltime;
address.pltime = pd->pltime;
if (action == CONFIGURE)
engine_imsg_compose_main(IMSG_CONFIGURE_ADDRESS, 0, &address,
sizeof(address));
}
void
send_deconfigure_interface(struct dhcp6leased_iface *iface)
{
fatalx("%s: not implemented", __func__); /* XXX */
}
void
parse_lease(struct dhcp6leased_iface *iface, struct imsg_ifinfo *imsg_ifinfo)
{
fatalx("%s: not implemented", __func__); /* XXX */
else
engine_imsg_compose_main(IMSG_DECONFIGURE_ADDRESS, 0, &address,
sizeof(address));
}
const char *

View file

@ -1,4 +1,4 @@
/* $OpenBSD: frontend.c,v 1.9 2024/06/04 15:48:47 florian Exp $ */
/* $OpenBSD: frontend.c,v 1.11 2024/06/05 16:14:12 florian Exp $ */
/*
* Copyright (c) 2017, 2021, 2024 Florian Obser <florian@openbsd.org>
@ -795,8 +795,11 @@ build_packet(uint8_t message_type, struct iface *iface, char *if_name)
struct dhcp_iapd iapd;
struct dhcp_iaprefix iaprefix;
struct dhcp_vendor_class vendor_class;
size_t i;
ssize_t len;
uint16_t request_option_code, elapsed_time;
const uint16_t options[] = {DHO_SOL_MAX_RT,
DHO_INF_MAX_RT};
uint8_t *p;
switch (message_type) {
@ -874,9 +877,12 @@ build_packet(uint8_t message_type, struct iface *iface, char *if_name)
case DHCPRENEW:
case DHCPREBIND:
pd = &iface->pds[ia_conf->id];
if (pd->prefix_len > 0) {
iaprefix.prefix_len = pd->prefix_len;
memcpy(&iaprefix.prefix, &pd->prefix,
sizeof(struct in6_addr));
} else
iaprefix.prefix_len = ia_conf->prefix_len;
break;
default:
fatalx("%s: %s not implemented", __func__,
@ -887,15 +893,14 @@ build_packet(uint8_t message_type, struct iface *iface, char *if_name)
}
opt_hdr.code = htons(DHO_ORO);
opt_hdr.len = htons(2 * 2);
opt_hdr.len = htons(sizeof(request_option_code) * nitems(options));
memcpy(p, &opt_hdr, sizeof(struct dhcp_option_hdr));
p += sizeof(struct dhcp_option_hdr);
request_option_code = htons(DHO_SOL_MAX_RT);
memcpy(p, &request_option_code, sizeof(uint16_t));
p += sizeof(uint16_t);
request_option_code = htons(DHO_INF_MAX_RT);
for (i = 0; i < nitems(options); i++) {
request_option_code = htons(options[i]);
memcpy(p, &request_option_code, sizeof(uint16_t));
p += sizeof(uint16_t);
}
opt_hdr.code = htons(DHO_ELAPSED_TIME);
opt_hdr.len = htons(2);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: parse.y,v 1.7 2024/06/04 15:48:47 florian Exp $ */
/* $OpenBSD: parse.y,v 1.8 2024/06/05 16:15:47 florian Exp $ */
/*
* Copyright (c) 2018, 2024 Florian Obser <florian@openbsd.org>
@ -52,31 +52,15 @@
#include "frontend.h"
TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
static struct file {
TAILQ_ENTRY(file) entry;
FILE *stream;
char *name;
size_t ungetpos;
size_t ungetsize;
u_char *ungetbuf;
int eof_reached;
int lineno;
int errors;
} *file, *topfile;
struct file *pushfile(const char *, int);
int popfile(void);
struct file *file, *topfile;
int check_file_secrecy(int, const char *);
int yyparse(void);
int yylex(void);
int yyerror(const char *, ...)
__attribute__((__format__ (printf, 1, 2)))
__attribute__((__nonnull__ (1)));
int kw_cmp(const void *, const void *);
int lookup(char *);
int igetc(void);
int lgetc(int);
void lungetc(int);
int findeol(void);
TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
struct sym {
@ -699,23 +683,6 @@ symset(const char *nam, const char *val, int persist)
return (0);
}
int
cmdline_symset(char *s)
{
char *sym, *val;
int ret;
if ((val = strrchr(s, '=')) == NULL)
return (-1);
sym = strndup(s, val - s);
if (sym == NULL)
errx(1, "%s: strndup", __func__);
ret = symset(sym, val + 1, 1);
free(sym);
return (ret);
}
char *
symget(const char *nam)
{

View file

@ -0,0 +1,289 @@
/* $OpenBSD: parse_lease.y,v 1.1 2024/06/05 16:15:47 florian Exp $ */
/*
* Copyright (c) 2018, 2024 Florian Obser <florian@openbsd.org>
* Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
* Copyright (c) 2004 Ryan McBride <mcbride@openbsd.org>
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
* Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2001 Daniel Hartmeier. All rights reserved.
* Copyright (c) 2001 Theo de Raadt. All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
%{
#include <sys/types.h>
#include <sys/queue.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <event.h>
#include <imsg.h>
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include <vis.h>
#include "log.h"
#include "dhcp6leased.h"
#include "frontend.h"
extern TAILQ_HEAD(files, file) files;
extern struct file *file, *topfile;
int yyparse(void);
int yylex(void);
int yyerror(const char *, ...)
__attribute__((__format__ (printf, 1, 2)))
__attribute__((__nonnull__ (1)));
int pllookup(char *);
struct imsg_ifinfo *ifinfo;
static int errors;
typedef struct {
union {
int64_t number;
char *string;
} v;
int lineno;
} YYSTYPE;
%}
%token ERROR IAPD
%token <v.string> STRING
%token <v.number> NUMBER
%%
grammar : /* empty */
| grammar '\n'
| grammar ia_pd '\n'
| grammar error '\n' { file->errors++; }
;
ia_pd : IAPD NUMBER STRING NUMBER {
if ($2 < 0 || $2 > MAX_IA) {
yyerror("invalid IA_ID %lld", $2);
free($3);
YYERROR;
}
if ($4 < 1 || $4 > 128) {
yyerror("invalid prefix length %lld", $4);
free($3);
ifinfo->pds[$2].prefix_len = 0;
YYERROR;
} else
ifinfo->pds[$2].prefix_len = $4;
if (inet_pton(AF_INET6, $3, &ifinfo->pds[$2].prefix)
!= 1) {
yyerror("invalid prefix %s", $3);
free($3);
ifinfo->pds[$2].prefix_len = 0;
YYERROR;
}
free($3);
}
;
%%
struct keywords {
const char *k_name;
int k_val;
};
int
yyerror(const char *fmt, ...)
{
va_list ap;
char *msg;
file->errors++;
va_start(ap, fmt);
if (vasprintf(&msg, fmt, ap) == -1)
fatalx("yyerror vasprintf");
va_end(ap);
logit(LOG_CRIT, "%s:%d: %s", file->name, yylval.lineno, msg);
free(msg);
return (0);
}
int
pllookup(char *s)
{
/* This has to be sorted always. */
static const struct keywords keywords[] = {
{"ia_pd", IAPD},
};
const struct keywords *p;
p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
sizeof(keywords[0]), kw_cmp);
if (p)
return (p->k_val);
else
return (STRING);
}
int
yylex(void)
{
char buf[8096];
char *p;
int quotec, next, c;
int token;
p = buf;
while ((c = lgetc(0)) == ' ' || c == '\t')
; /* nothing */
yylval.lineno = file->lineno;
if (c == '#')
while ((c = lgetc(0)) != '\n' && c != EOF)
; /* nothing */
switch (c) {
case '\'':
case '"':
quotec = c;
while (1) {
if ((c = lgetc(quotec)) == EOF)
return (0);
if (c == '\n') {
file->lineno++;
continue;
} else if (c == '\\') {
if ((next = lgetc(quotec)) == EOF)
return (0);
if (next == quotec || next == ' ' ||
next == '\t')
c = next;
else if (next == '\n') {
file->lineno++;
continue;
} else
lungetc(next);
} else if (c == quotec) {
*p = '\0';
break;
} else if (c == '\0') {
yyerror("syntax error");
return (findeol());
}
if (p + 1 >= buf + sizeof(buf) - 1) {
yyerror("string too long");
return (findeol());
}
*p++ = c;
}
yylval.v.string = strdup(buf);
if (yylval.v.string == NULL)
err(1, "yylex: strdup");
return (STRING);
}
#define allowed_to_end_number(x) \
(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
if (c == '-' || isdigit(c)) {
do {
*p++ = c;
if ((size_t)(p-buf) >= sizeof(buf)) {
yyerror("string too long");
return (findeol());
}
} while ((c = lgetc(0)) != EOF && isdigit(c));
lungetc(c);
if (p == buf + 1 && buf[0] == '-')
goto nodigits;
if (c == EOF || allowed_to_end_number(c)) {
const char *errstr = NULL;
*p = '\0';
yylval.v.number = strtonum(buf, LLONG_MIN,
LLONG_MAX, &errstr);
if (errstr) {
yyerror("\"%s\" invalid number: %s",
buf, errstr);
return (findeol());
}
return (NUMBER);
} else {
nodigits:
while (p > buf + 1)
lungetc((unsigned char)*--p);
c = (unsigned char)*--p;
if (c == '-')
return (c);
}
}
#define allowed_in_string(x) \
(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
x != '{' && x != '}' && \
x != '!' && x != '=' && x != '#' && \
x != ','))
if (isalnum(c) || c == ':' || c == '_') {
do {
*p++ = c;
if ((size_t)(p-buf) >= sizeof(buf)) {
yyerror("string too long");
return (findeol());
}
} while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
lungetc(c);
*p = '\0';
if ((token = pllookup(buf)) == STRING)
if ((yylval.v.string = strdup(buf)) == NULL)
err(1, "yylex: strdup");
return (token);
}
if (c == '\n') {
yylval.lineno = file->lineno;
file->lineno++;
}
if (c == EOF)
return (0);
return (c);
}
void
parse_lease(const char *filename, struct imsg_ifinfo *imsg)
{
ifinfo = imsg;
file = pushfile(filename, 0);
if (file == NULL)
return;
topfile = file;
yyparse();
errors = file->errors;
popfile();
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: hibernate_machdep.c,v 1.50 2023/04/24 09:04:03 dv Exp $ */
/* $OpenBSD: hibernate_machdep.c,v 1.51 2024/06/05 04:58:05 mglocker Exp $ */
/*
* Copyright (c) 2012 Mike Larkin <mlarkin@openbsd.org>
@ -51,6 +51,7 @@
#include "sd.h"
#include "nvme.h"
#include "sdmmc.h"
#include "ufshci.h"
/* Hibernate support */
void hibernate_enter_resume_4k_pte(vaddr_t, paddr_t);
@ -97,6 +98,8 @@ get_hibernate_io_function(dev_t dev)
vaddr_t addr, size_t size, int op, void *page);
extern int sdmmc_scsi_hibernate_io(dev_t dev, daddr_t blkno,
vaddr_t addr, size_t size, int op, void *page);
extern int ufshci_hibernate_io(dev_t dev, daddr_t blkno,
vaddr_t addr, size_t size, int op, void *page);
struct device *dv = disk_lookup(&sd_cd, DISKUNIT(dev));
struct {
const char *driver;
@ -113,6 +116,9 @@ get_hibernate_io_function(dev_t dev)
#endif
#if NSDMMC > 0
{ "sdmmc", sdmmc_scsi_hibernate_io },
#endif
#if NUFSHCI > 0
{ "ufshci", ufshci_hibernate_io },
#endif
};

View file

@ -1,4 +1,4 @@
# $OpenBSD: Makefile.amd64,v 1.135 2024/06/04 15:14:45 deraadt Exp $
# $OpenBSD: Makefile.amd64,v 1.136 2024/06/05 20:19:26 deraadt Exp $
# For instructions on building kernels consult the config(8) and options(4)
# manual pages.
@ -73,7 +73,7 @@ CMACHFLAGS+= -mno-retpoline -fcf-protection=none
.endif
.else
CMACHFLAGS+= -mretpoline-external-thunk -fcf-protection=branch
CMACHFLAGS+= -fret-clean
#CMACHFLAGS+= -fret-clean
.endif
.if ${COMPILER_VERSION:Mclang}
NO_INTEGR_AS= -no-integrated-as

View file

@ -1,4 +1,4 @@
/* $OpenBSD: dwqe.c,v 1.21 2024/05/06 09:54:38 stsp Exp $ */
/* $OpenBSD: dwqe.c,v 1.22 2024/06/05 10:19:55 stsp Exp $ */
/*
* Copyright (c) 2008, 2019 Mark Kettenis <kettenis@openbsd.org>
* Copyright (c) 2017, 2022 Patrick Wildt <patrick@blueri.se>
@ -21,6 +21,7 @@
*/
#include "bpfilter.h"
#include "vlan.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -99,6 +100,53 @@ dwqe_have_tx_csum_offload(struct dwqe_softc *sc)
return (sc->sc_hw_feature[0] & GMAC_MAC_HW_FEATURE0_TXCOESEL);
}
int
dwqe_have_tx_vlan_offload(struct dwqe_softc *sc)
{
#if NVLAN > 0
return (sc->sc_hw_feature[0] & GMAC_MAC_HW_FEATURE0_SAVLANINS);
#else
return 0;
#endif
}
void
dwqe_set_vlan_rx_mode(struct dwqe_softc *sc)
{
#if NVLAN > 0
uint32_t reg;
/* Enable outer VLAN tag stripping on Rx. */
reg = dwqe_read(sc, GMAC_VLAN_TAG_CTRL);
reg |= GMAC_VLAN_TAG_CTRL_EVLRXS | GMAC_VLAN_TAG_CTRL_STRIP_ALWAYS;
dwqe_write(sc, GMAC_VLAN_TAG_CTRL, reg);
#endif
}
void
dwqe_set_vlan_tx_mode(struct dwqe_softc *sc)
{
#if NVLAN > 0
uint32_t reg;
reg = dwqe_read(sc, GMAC_VLAN_TAG_INCL);
/* Enable insertion of outer VLAN tag. */
reg |= GMAC_VLAN_TAG_INCL_INSERT;
/*
* Generate C-VLAN tags (type 0x8100, 802.1Q). Setting this
* bit would result in S-VLAN tags (type 0x88A8, 802.1ad).
*/
reg &= ~GMAC_VLAN_TAG_INCL_CSVL;
/* Use VLAN tags provided in Tx context descriptors. */
reg |= GMAC_VLAN_TAG_INCL_VLTI;
dwqe_write(sc, GMAC_VLAN_TAG_INCL, reg);
#endif
}
int
dwqe_attach(struct dwqe_softc *sc)
{
@ -127,6 +175,8 @@ dwqe_attach(struct dwqe_softc *sc)
bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
ifp->if_capabilities = IFCAP_VLAN_MTU;
if (dwqe_have_tx_vlan_offload(sc))
ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
if (dwqe_have_tx_csum_offload(sc)) {
ifp->if_capabilities |= (IFCAP_CSUM_IPv4 |
IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4 |
@ -218,6 +268,14 @@ dwqe_attach(struct dwqe_softc *sc)
if (!sc->sc_fixed_link)
dwqe_mii_attach(sc);
/*
* All devices support VLAN tag stripping on Rx but inserting
* VLAN tags during Tx is an optional feature.
*/
dwqe_set_vlan_rx_mode(sc);
if (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING)
dwqe_set_vlan_tx_mode(sc);
if_attach(ifp);
ether_ifattach(ifp);
@ -329,7 +387,8 @@ dwqe_start(struct ifqueue *ifq)
used = 0;
for (;;) {
if (used + DWQE_NTXSEGS + 1 > left) {
/* VLAN tags require an extra Tx context descriptor. */
if (used + DWQE_NTXSEGS + 2 > left) {
ifq_set_oactive(ifq);
break;
}
@ -714,6 +773,21 @@ dwqe_rx_csum(struct dwqe_softc *sc, struct mbuf *m, struct dwqe_desc *rxd)
m->m_pkthdr.csum_flags |= csum_flags;
}
void
dwqe_vlan_strip(struct dwqe_softc *sc, struct mbuf *m, struct dwqe_desc *rxd)
{
#if NVLAN > 0
uint16_t tag;
if ((rxd->sd_tdes3 & RDES3_RDES0_VALID) &&
(rxd->sd_tdes3 & RDES3_LD)) {
tag = rxd->sd_tdes0 & RDES0_OVT;
m->m_pkthdr.ether_vtag = le16toh(tag);
m->m_flags |= M_VLANTAG;
}
#endif
}
void
dwqe_rx_proc(struct dwqe_softc *sc)
{
@ -763,6 +837,7 @@ dwqe_rx_proc(struct dwqe_softc *sc)
m->m_pkthdr.len = m->m_len = len;
dwqe_rx_csum(sc, m, rxd);
dwqe_vlan_strip(sc, m, rxd);
ml_enqueue(&ml, m);
}
@ -1107,12 +1182,34 @@ dwqe_tx_csum(struct dwqe_softc *sc, struct mbuf *m, struct dwqe_desc *txd)
txd->sd_tdes3 |= TDES3_CSUM_IPHDR_PAYLOAD_PSEUDOHDR;
}
uint16_t
dwqe_set_tx_context_desc(struct dwqe_softc *sc, struct mbuf *m, int idx)
{
uint16_t tag = 0;
#if NVLAN > 0
struct dwqe_desc *ctxt_txd;
if ((m->m_flags & M_VLANTAG) == 0)
return 0;
tag = m->m_pkthdr.ether_vtag;
if (tag) {
ctxt_txd = &sc->sc_txdesc[idx];
ctxt_txd->sd_tdes3 |= (htole16(tag) & TDES3_VLAN_TAG);
ctxt_txd->sd_tdes3 |= TDES3_VLAN_TAG_VALID;
ctxt_txd->sd_tdes3 |= (TDES3_CTXT | TDES3_OWN);
}
#endif
return tag;
}
int
dwqe_encap(struct dwqe_softc *sc, struct mbuf *m, int *idx, int *used)
{
struct dwqe_desc *txd, *txd_start;
bus_dmamap_t map;
int cur, frag, i;
uint16_t vlan_tag = 0;
cur = frag = *idx;
map = sc->sc_txbuf[cur].tb_map;
@ -1128,6 +1225,17 @@ dwqe_encap(struct dwqe_softc *sc, struct mbuf *m, int *idx, int *used)
bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
BUS_DMASYNC_PREWRITE);
if (dwqe_have_tx_vlan_offload(sc)) {
vlan_tag = dwqe_set_tx_context_desc(sc, m, frag);
if (vlan_tag) {
(*used)++;
if (frag == (DWQE_NTXDESC - 1))
frag = 0;
else
frag++;
}
}
txd = txd_start = &sc->sc_txdesc[frag];
for (i = 0; i < map->dm_nsegs; i++) {
/* TODO: check for 32-bit vs 64-bit support */
@ -1140,6 +1248,8 @@ dwqe_encap(struct dwqe_softc *sc, struct mbuf *m, int *idx, int *used)
if (i == 0) {
txd->sd_tdes3 |= TDES3_FS;
dwqe_tx_csum(sc, m, txd);
if (vlan_tag)
txd->sd_tdes2 |= TDES2_VLAN_TAG_INSERT;
}
if (i == (map->dm_nsegs - 1)) {
txd->sd_tdes2 |= TDES2_IC;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: dwqereg.h,v 1.9 2024/05/06 09:54:38 stsp Exp $ */
/* $OpenBSD: dwqereg.h,v 1.10 2024/06/05 10:19:55 stsp Exp $ */
/*
* Copyright (c) 2008, 2019 Mark Kettenis <kettenis@openbsd.org>
* Copyright (c) 2017, 2022 Patrick Wildt <patrick@blueri.se>
@ -44,6 +44,19 @@
#define GMAC_INT_MASK_LPIIM (1 << 10)
#define GMAC_INT_MASK_PIM (1 << 3)
#define GMAC_INT_MASK_RIM (1 << 0)
#define GMAC_VLAN_TAG_CTRL 0x0050
#define GMAC_VLAN_TAG_CTRL_EVLRXS (1 << 24)
#define GMAC_VLAN_TAG_CTRL_STRIP_ALWAYS ((1 << 21) | (1 << 22))
#define GMAC_VLAN_TAG_DATA 0x0054
#define GMAC_VLAN_TAG_INCL 0x0060
#define GMAC_VLAN_TAG_INCL_VLTI (1 << 20)
#define GMAC_VLAN_TAG_INCL_CSVL (1 << 19)
#define GMAC_VLAN_TAG_INCL_DELETE 0x10000
#define GMAC_VLAN_TAG_INCL_INSERT 0x20000
#define GMAC_VLAN_TAG_INCL_REPLACE 0x30000
#define GMAC_VLAN_TAG_INCL_VLT 0x0ffff
#define GMAC_VLAN_TAG_INCL_RDWR (1U << 30)
#define GMAC_VLAN_TAG_INCL_BUSY (1U << 31)
#define GMAC_QX_TX_FLOW_CTRL(x) (0x0070 + (x) * 4)
#define GMAC_QX_TX_FLOW_CTRL_PT_SHIFT 16
#define GMAC_QX_TX_FLOW_CTRL_TFE (1 << 0)
@ -64,6 +77,7 @@
#define GMAC_MAC_HW_FEATURE(x) (0x011c + (x) * 0x4)
#define GMAC_MAC_HW_FEATURE0_TXCOESEL (1 << 14)
#define GMAC_MAC_HW_FEATURE0_RXCOESEL (1 << 16)
#define GMAC_MAC_HW_FEATURE0_SAVLANINS (1 << 27)
#define GMAC_MAC_HW_FEATURE1_TXFIFOSIZE(x) (((x) >> 6) & 0x1f)
#define GMAC_MAC_HW_FEATURE1_RXFIFOSIZE(x) (((x) >> 0) & 0x1f)
#define GMAC_MAC_MDIO_ADDR 0x0200
@ -230,6 +244,12 @@ struct dwqe_desc {
uint32_t sd_tdes3;
};
/* Tx context descriptor bits (host to device); precedes regular descriptor */
#define TDES3_CTXT (1 << 30)
#define TDES3_VLAN_TAG_VALID (1 << 16)
#define TDES3_VLAN_TAG 0xffff
/* Bit 31 is the OWN bit, as in regular Tx descriptor. */
/* Tx bits (read format; host to device) */
#define TDES2_HDR_LEN 0x000003ff /* if TSO is enabled */
#define TDES2_BUF1_LEN 0x00003fff /* if TSO is disabled */
@ -250,6 +270,11 @@ struct dwqe_desc {
#define TDES3_CSUM_IPHDR_PAYLOAD (0x2 << 16)
#define TDES3_CSUM_IPHDR_PAYLOAD_PSEUDOHDR (0x3 << 16)
#define TDES3_TSO_EN (1 << 18)
#define TDES3_CPC ((1 << 26) | (1 << 27)) /* if TSO is disabled */
#define TDES3_CPC_CRC_AND_PAD (0x0 << 26)
#define TDES3_CPC_CRC_NO_PAD (0x1 << 26)
#define TDES3_CPC_DISABLE (0x2 << 26)
#define TDES3_CPC_CRC_REPLACE (0x3 << 26)
#define TDES3_LS (1 << 28)
#define TDES3_FS (1 << 29)
#define TDES3_OWN (1U << 31)
@ -268,6 +293,8 @@ struct dwqe_desc {
#define RDES3_OWN (1U << 31)
/* Rx bits (writeback format; device to host) */
#define RDES0_IVT 0xffff0000
#define RDES0_OVT 0x0000ffff
#define RDES1_IP_PAYLOAD_TYPE 0x7
#define RDES1_IP_PAYLOAD_UNKNOWN 0x0
#define RDES1_IP_PAYLOAD_UDP 0x1

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ufshci.c,v 1.33 2024/05/27 10:27:58 mglocker Exp $ */
/* $OpenBSD: ufshci.c,v 1.34 2024/06/05 04:58:05 mglocker Exp $ */
/*
* Copyright (c) 2022 Marcus Glocker <mglocker@openbsd.org>
@ -42,6 +42,13 @@
#include <dev/ic/ufshcivar.h>
#include <dev/ic/ufshcireg.h>
#ifdef HIBERNATE
#include <uvm/uvm_extern.h>
#include <sys/hibernate.h>
#include <sys/disklabel.h>
#include <sys/disk.h>
#endif
#ifdef UFSHCI_DEBUG
int ufshci_dbglvl = 1;
#define DPRINTF(l, x...) do { if ((l) <= ufshci_dbglvl) printf(x); } \
@ -59,7 +66,9 @@ int ufshci_is_poll(struct ufshci_softc *, uint32_t);
struct ufshci_dmamem *ufshci_dmamem_alloc(struct ufshci_softc *, size_t);
void ufshci_dmamem_free(struct ufshci_softc *,
struct ufshci_dmamem *);
int ufshci_alloc(struct ufshci_softc *);
int ufshci_init(struct ufshci_softc *);
int ufshci_disable(struct ufshci_softc *);
int ufshci_doorbell_read(struct ufshci_softc *);
void ufshci_doorbell_write(struct ufshci_softc *, int);
int ufshci_doorbell_poll(struct ufshci_softc *, int,
@ -104,6 +113,11 @@ void ufshci_scsi_io_done(struct ufshci_softc *,
void ufshci_scsi_done(struct ufshci_softc *,
struct ufshci_ccb *);
#if HIBERNATE
int ufshci_hibernate_io(dev_t, daddr_t, vaddr_t, size_t,
int, void *);
#endif
const struct scsi_adapter ufshci_switch = {
ufshci_scsi_cmd, NULL, NULL, NULL, NULL
};
@ -227,6 +241,8 @@ ufshci_attach(struct ufshci_softc *sc)
#if 0
sc->sc_flags |= UFSHCI_FLAGS_AGGR_INTR; /* Enable intr. aggregation */
#endif
/* Allocate the DMA buffers and initialize the controller. */
ufshci_alloc(sc);
ufshci_init(sc);
if (ufshci_ccb_alloc(sc, sc->sc_nutrs) != 0) {
@ -371,6 +387,39 @@ ufshci_dmamem_free(struct ufshci_softc *sc, struct ufshci_dmamem *udm)
free(udm, M_DEVBUF, sizeof(*udm));
}
int
ufshci_alloc(struct ufshci_softc *sc)
{
/* 7.1.1 Host Controller Initialization: 13) */
sc->sc_dmamem_utmrd = ufshci_dmamem_alloc(sc,
sizeof(struct ufshci_utmrd) * sc->sc_nutmrs);
if (sc->sc_dmamem_utmrd == NULL) {
printf("%s: Can't allocate DMA memory for UTMRD\n",
sc->sc_dev.dv_xname);
return -1;
}
/* 7.1.1 Host Controller Initialization: 15) */
sc->sc_dmamem_utrd = ufshci_dmamem_alloc(sc,
sizeof(struct ufshci_utrd) * sc->sc_nutrs);
if (sc->sc_dmamem_utrd == NULL) {
printf("%s: Can't allocate DMA memory for UTRD\n",
sc->sc_dev.dv_xname);
return -1;
}
/* Allocate UCDs. */
sc->sc_dmamem_ucd = ufshci_dmamem_alloc(sc,
sizeof(struct ufshci_ucd) * sc->sc_nutrs);
if (sc->sc_dmamem_ucd == NULL) {
printf("%s: Can't allocate DMA memory for UCD\n",
sc->sc_dev.dv_xname);
return -1;
}
return 0;
}
int
ufshci_init(struct ufshci_softc *sc)
{
@ -430,44 +479,18 @@ ufshci_init(struct ufshci_softc *sc)
* TODO: More UIC commands to issue?
*/
/* 7.1.1 Host Controller Initialization: 13) */
sc->sc_dmamem_utmrd = ufshci_dmamem_alloc(sc,
sizeof(struct ufshci_utmrd) * sc->sc_nutmrs);
if (sc->sc_dmamem_utmrd == NULL) {
printf("%s: Can't allocate DMA memory for UTMRD\n",
sc->sc_dev.dv_xname);
return -1;
}
/* 7.1.1 Host Controller Initialization: 14) */
dva = UFSHCI_DMA_DVA(sc->sc_dmamem_utmrd);
DPRINTF(2, "%s: utmrd dva=%llu\n", __func__, dva);
UFSHCI_WRITE_4(sc, UFSHCI_REG_UTMRLBA, (uint32_t)dva);
UFSHCI_WRITE_4(sc, UFSHCI_REG_UTMRLBAU, (uint32_t)(dva >> 32));
/* 7.1.1 Host Controller Initialization: 15) */
sc->sc_dmamem_utrd = ufshci_dmamem_alloc(sc,
sizeof(struct ufshci_utrd) * sc->sc_nutrs);
if (sc->sc_dmamem_utrd == NULL) {
printf("%s: Can't allocate DMA memory for UTRD\n",
sc->sc_dev.dv_xname);
return -1;
}
/* 7.1.1 Host Controller Initialization: 16) */
dva = UFSHCI_DMA_DVA(sc->sc_dmamem_utrd);
DPRINTF(2, "%s: utrd dva=%llu\n", __func__, dva);
UFSHCI_WRITE_4(sc, UFSHCI_REG_UTRLBA, (uint32_t)dva);
UFSHCI_WRITE_4(sc, UFSHCI_REG_UTRLBAU, (uint32_t)(dva >> 32));
/* Allocate UCDs. */
sc->sc_dmamem_ucd = ufshci_dmamem_alloc(sc,
sizeof(struct ufshci_ucd) * sc->sc_nutrs);
if (sc->sc_dmamem_ucd == NULL) {
printf("%s: Can't allocate DMA memory for UCD\n",
sc->sc_dev.dv_xname);
return -1;
}
/* 7.1.1 Host Controller Initialization: 17) */
UFSHCI_WRITE_4(sc, UFSHCI_REG_UTMRLRSR, UFSHCI_REG_UTMRLRSR_START);
@ -482,6 +505,19 @@ ufshci_init(struct ufshci_softc *sc)
return 0;
}
int
ufshci_disable(struct ufshci_softc *sc)
{
/* Stop run queues. */
UFSHCI_WRITE_4(sc, UFSHCI_REG_UTMRLRSR, UFSHCI_REG_UTMRLRSR_STOP);
UFSHCI_WRITE_4(sc, UFSHCI_REG_UTRLRSR, UFSHCI_REG_UTRLRSR_STOP);
/* Disable interrupts. */
UFSHCI_WRITE_4(sc, UFSHCI_REG_IE, 0);
return 0;
}
int
ufshci_doorbell_read(struct ufshci_softc *sc)
{
@ -1353,11 +1389,11 @@ ufshci_activate(struct ufshci_softc *sc, int act)
case DVACT_POWERDOWN:
DPRINTF(1, "%s: POWERDOWN\n", __func__);
rv = config_activate_children(&sc->sc_dev, act);
ufshci_powerdown(sc);
ufshci_disable(sc);
break;
case DVACT_RESUME:
DPRINTF(1, "%s: RESUME\n", __func__);
ufshci_resume(sc);
rv = ufshci_init(sc);
if (rv == 0)
rv = config_activate_children(&sc->sc_dev, act);
break;
@ -1369,56 +1405,6 @@ ufshci_activate(struct ufshci_softc *sc, int act)
return rv;
}
int
ufshci_powerdown(struct ufshci_softc *sc)
{
uint32_t reg;
/* Send "hibernate enter" command. */
UFSHCI_WRITE_4(sc, UFSHCI_REG_UICCMD,
UFSHCI_REG_UICCMD_CMDOP_DME_HIBERNATE_ENTER);
if (ufshci_is_poll(sc, UFSHCI_REG_IS_UHES) != 0) {
printf("%s: hibernate enter cmd failed\n", __func__);
return 1;
}
/* Check if "hibernate enter" command was executed successfully. */
reg = UFSHCI_READ_4(sc, UFSHCI_REG_HCS);
DPRINTF(1, "%s: UPMCRS=0x%x\n", __func__, UFSHCI_REG_HCS_UPMCRS(reg));
if (UFSHCI_REG_HCS_UPMCRS(reg) > UFSHCI_REG_HCS_UPMCRS_PWR_REMTOTE) {
printf("%s: hibernate enter cmd returned UPMCRS error=0x%x\n",
__func__, UFSHCI_REG_HCS_UPMCRS(reg));
return 1;
}
return 0;
}
int
ufshci_resume(struct ufshci_softc *sc)
{
uint32_t reg;
/* Send "hibernate exit" command. */
UFSHCI_WRITE_4(sc, UFSHCI_REG_UICCMD,
UFSHCI_REG_UICCMD_CMDOP_DME_HIBERNATE_EXIT);
if (ufshci_is_poll(sc, UFSHCI_REG_IS_UHXS) != 0) {
printf("%s: hibernate exit command failed\n", __func__);
return 1;
}
/* Check if "hibernate exit" command was executed successfully. */
reg = UFSHCI_READ_4(sc, UFSHCI_REG_HCS);
DPRINTF(1, "%s: UPMCRS=0x%x\n", __func__, UFSHCI_REG_HCS_UPMCRS(reg));
if (UFSHCI_REG_HCS_UPMCRS(reg) > UFSHCI_REG_HCS_UPMCRS_PWR_REMTOTE) {
printf("%s: hibernate exit cmd returned UPMCRS error=0x%x\n",
__func__, UFSHCI_REG_HCS_UPMCRS(reg));
return 1;
}
return 0;
}
/* SCSI */
int
@ -1928,3 +1914,155 @@ ufshci_scsi_done(struct ufshci_softc *sc, struct ufshci_ccb *ccb)
xs->resid = 0;
scsi_done(xs);
}
#if HIBERNATE
int
ufshci_hibernate_io(dev_t dev, daddr_t blkno, vaddr_t addr, size_t size,
int op, void *page)
{
struct ufshci_hibernate_page {
struct ufshci_utrd utrd;
struct ufshci_ucd ucd;
struct ufshci_softc *sc; /* Copy of softc */
daddr_t poffset; /* Start of SWAP partition */
size_t psize; /* Size of SWAP partition */
uint32_t secsize; /* Our sector size */
} *my = page;
paddr_t data_phys, page_phys;
uint64_t data_bus_phys, page_bus_phys;
uint64_t timeout_us;
int off, len, slot;
uint32_t blocks, reg;
uint64_t lba;
if (op == HIB_INIT) {
struct device *disk;
struct device *scsibus;
extern struct cfdriver sd_cd;
/* Find ufshci softc. */
disk = disk_lookup(&sd_cd, DISKUNIT(dev));
if (disk == NULL)
return ENOTTY;
scsibus = disk->dv_parent;
my->sc = (struct ufshci_softc *)disk->dv_parent->dv_parent;
/* Stop run queues and disable interrupts. */
ufshci_disable(my->sc);
/* Tell the controler the new hibernate UTRD address. */
pmap_extract(pmap_kernel(), (vaddr_t)page, &page_phys);
page_bus_phys = page_phys + ((void *)&my->utrd - page);
UFSHCI_WRITE_4(my->sc, UFSHCI_REG_UTRLBA,
(uint32_t)page_bus_phys);
UFSHCI_WRITE_4(my->sc, UFSHCI_REG_UTRLBAU,
(uint32_t)(page_bus_phys >> 32));
/* Start run queues. */
UFSHCI_WRITE_4(my->sc, UFSHCI_REG_UTMRLRSR,
UFSHCI_REG_UTMRLRSR_START);
UFSHCI_WRITE_4(my->sc, UFSHCI_REG_UTRLRSR,
UFSHCI_REG_UTRLRSR_START);
my->poffset = blkno;
my->psize = size;
my->secsize = UFSHCI_LBS;
return 0;
}
if (op != HIB_W)
return 0;
if (blkno + (size / DEV_BSIZE) > my->psize)
return E2BIG;
blocks = size / my->secsize;
lba = (blkno + my->poffset) / (my->secsize / DEV_BSIZE);
/*
* The following code is a ripped down version of ufshci_utr_cmd_io()
* adapted for hibernate.
*/
slot = 0; /* We only use the first slot for hibernate */
memset(&my->utrd, 0, sizeof(struct ufshci_utrd));
my->utrd.dw0 = UFSHCI_UTRD_DW0_CT_UFS;
my->utrd.dw0 |= UFSHCI_UTRD_DW0_DD_I2T;
my->utrd.dw0 |= UFSHCI_UTRD_DW0_I_REG;
my->utrd.dw2 = UFSHCI_UTRD_DW2_OCS_IOV;
memset(&my->ucd, 0, sizeof(struct ufshci_ucd));
my->ucd.cmd.hdr.tc = UPIU_TC_I2T_COMMAND;
my->ucd.cmd.hdr.flags = (1 << 5); /* Bit-5 = Write */
my->ucd.cmd.hdr.lun = 0;
my->ucd.cmd.hdr.task_tag = slot;
my->ucd.cmd.hdr.cmd_set_type = 0; /* SCSI command */
my->ucd.cmd.hdr.query = 0;
my->ucd.cmd.hdr.response = 0;
my->ucd.cmd.hdr.status = 0;
my->ucd.cmd.hdr.ehs_len = 0;
my->ucd.cmd.hdr.device_info = 0;
my->ucd.cmd.hdr.ds_len = 0;
my->ucd.cmd.expected_xfer_len = htobe32(UFSHCI_LBS * blocks);
my->ucd.cmd.cdb[0] = WRITE_10; /* 0x2a */
my->ucd.cmd.cdb[1] = (1 << 3); /* FUA: Force Unit Access */
my->ucd.cmd.cdb[2] = (lba >> 24) & 0xff;
my->ucd.cmd.cdb[3] = (lba >> 16) & 0xff;
my->ucd.cmd.cdb[4] = (lba >> 8) & 0xff;
my->ucd.cmd.cdb[5] = (lba >> 0) & 0xff;
my->ucd.cmd.cdb[7] = (blocks >> 8) & 0xff;
my->ucd.cmd.cdb[8] = (blocks >> 0) & 0xff;
pmap_extract(pmap_kernel(), (vaddr_t)page, &page_phys);
page_bus_phys = page_phys + ((void *)&my->ucd - page);
my->utrd.dw4 = (uint32_t)page_bus_phys;
my->utrd.dw5 = (uint32_t)(page_bus_phys >> 32);
off = sizeof(struct upiu_command) / 4; /* DWORD offset */
my->utrd.dw6 = UFSHCI_UTRD_DW6_RUO(off);
len = sizeof(struct upiu_response) / 4; /* DWORD length */
my->utrd.dw6 |= UFSHCI_UTRD_DW6_RUL(len);
off = (sizeof(struct upiu_command) + sizeof(struct upiu_response)) / 4;
my->utrd.dw7 = UFSHCI_UTRD_DW7_PRDTO(off);
my->utrd.dw7 |= UFSHCI_UTRD_DW7_PRDTL(1); /* dm_nsegs */
pmap_extract(pmap_kernel(), (vaddr_t)addr, &data_phys);
data_bus_phys = data_phys;
my->ucd.prdt[0].dw0 = (uint32_t)data_bus_phys;
my->ucd.prdt[0].dw1 = (uint32_t)(data_bus_phys >> 32);
my->ucd.prdt[0].dw2 = 0;
my->ucd.prdt[0].dw3 = size - 1; /* ds_len */
if (UFSHCI_READ_4(my->sc, UFSHCI_REG_UTRLRSR) != 1)
return EIO;
ufshci_doorbell_write(my->sc, slot);
/* ufshci_doorbell_poll() adaption for hibernate. */
for (timeout_us = 1000000 * 1000; timeout_us != 0;
timeout_us -= 1000) {
reg = UFSHCI_READ_4(my->sc, UFSHCI_REG_UTRLDBR);
if ((reg & (1U << slot)) == 0)
break;
delay(1000);
}
if (timeout_us == 0)
return EIO;
UFSHCI_WRITE_4(my->sc, UFSHCI_REG_UTRLCNR, (1U << slot));
/* Check if the command was succesfully executed. */
if (my->utrd.dw2 != UFSHCI_UTRD_DW2_OCS_SUCCESS)
return EIO;
return 0;
}
#endif /* HIBERNATE */

View file

@ -1,4 +1,4 @@
/* $OpenBSD: subr_hibernate.c,v 1.140 2024/06/04 20:31:35 krw Exp $ */
/* $OpenBSD: subr_hibernate.c,v 1.141 2024/06/05 11:04:17 krw Exp $ */
/*
* Copyright (c) 2011 Ariane van der Steldt <ariane@stack.nl>
@ -72,6 +72,7 @@ vaddr_t hibernate_rle_page;
/* Hibernate info as read from disk during resume */
union hibernate_info disk_hib;
struct bdevsw *bdsw;
/*
* Global copy of the pig start address. This needs to be a global as we
@ -1004,18 +1005,9 @@ hibernate_block_io(union hibernate_info *hib, daddr_t blkctr,
size_t xfer_size, vaddr_t dest, int iswrite)
{
struct buf *bp;
struct bdevsw *bdsw;
int error;
bp = geteblk(xfer_size);
bdsw = &bdevsw[major(hib->dev)];
error = (*bdsw->d_open)(hib->dev, FREAD, S_IFCHR, curproc);
if (error) {
printf("hibernate_block_io open failed\n");
return (1);
}
if (iswrite)
bcopy((caddr_t)dest, bp->b_data, xfer_size);
@ -1030,26 +1022,13 @@ hibernate_block_io(union hibernate_info *hib, daddr_t blkctr,
if (error) {
printf("hib block_io biowait error %d blk %lld size %zu\n",
error, (long long)blkctr, xfer_size);
error = (*bdsw->d_close)(hib->dev, 0, S_IFCHR,
curproc);
if (error)
printf("hibernate_block_io error close failed\n");
return (1);
}
error = (*bdsw->d_close)(hib->dev, FREAD, S_IFCHR, curproc);
if (error) {
printf("hibernate_block_io close failed\n");
return (1);
}
if (!iswrite)
} else if (!iswrite)
bcopy(bp->b_data, (caddr_t)dest, xfer_size);
bp->b_flags |= B_INVAL;
brelse(bp);
return (0);
return (error != 0);
}
/*
@ -1140,6 +1119,13 @@ hibernate_resume(void)
/* Read hibernate info from disk */
s = splbio();
bdsw = &bdevsw[major(hib->dev)];
if ((*bdsw->d_open)(hib->dev, FREAD, S_IFCHR, curproc)) {
printf("hibernate_resume device open failed\n");
splx(s);
return;
}
DPRINTF("reading hibernate signature block location: %lld\n",
hib->sig_offset);
@ -1147,16 +1133,14 @@ hibernate_resume(void)
hib->sig_offset,
hib->sec_size, (vaddr_t)&disk_hib, 0)) {
DPRINTF("error in hibernate read\n");
splx(s);
return;
goto fail;
}
/* Check magic number */
if (disk_hib.magic != HIBERNATE_MAGIC) {
DPRINTF("wrong magic number in hibernate signature: %x\n",
disk_hib.magic);
splx(s);
return;
goto fail;
}
/*
@ -1165,8 +1149,7 @@ hibernate_resume(void)
*/
if (hibernate_clear_signature(hib)) {
DPRINTF("error clearing hibernate signature block\n");
splx(s);
return;
goto fail;
}
/*
@ -1175,8 +1158,7 @@ hibernate_resume(void)
*/
if (hibernate_compare_signature(hib, &disk_hib)) {
DPRINTF("mismatched hibernate signature block\n");
splx(s);
return;
goto fail;
}
disk_hib.dev = hib->dev;
@ -1189,6 +1171,9 @@ hibernate_resume(void)
/* Read the image from disk into the image (pig) area */
if (hibernate_read_image(&disk_hib))
goto fail;
if ((*bdsw->d_close)(hib->dev, 0, S_IFCHR, curproc))
printf("hibernate_resume device close failed\n");
bdsw = NULL;
DPRINTF("hibernate: quiescing devices\n");
if (config_suspend_all(DVACT_QUIESCE) != 0)
@ -1235,8 +1220,11 @@ hibernate_resume(void)
hibernate_unpack_image(&disk_hib);
fail:
splx(s);
if (!bdsw)
printf("\nUnable to resume hibernated image\n");
else if ((*bdsw->d_close)(hib->dev, 0, S_IFCHR, curproc))
printf("hibernate_resume device close failed\n");
splx(s);
}
/*

View file

@ -1,4 +1,4 @@
/* $OpenBSD: crl.c,v 1.36 2024/05/31 02:45:15 tb Exp $ */
/* $OpenBSD: crl.c,v 1.37 2024/06/05 13:36:28 tb Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@ -132,7 +132,7 @@ crl_check_revoked(const char *fn, X509_CRL *x509_crl)
* to a bug in rpki-rs/Krill. So silently accept this for now.
* https://github.com/NLnetLabs/krill/issues/1197
*/
if (verbose > 0)
if (verbose > 1)
warnx("%s: RFC 5280, section 5.1.2.6: revoked "
"certificate list without entries disallowed", fn);
return 1;