From 6040ea8924b91f877c915c6ec762e42f39976631 Mon Sep 17 00:00:00 2001 From: purplerain Date: Thu, 6 Jun 2024 00:05:03 +0000 Subject: [PATCH] sync with OpenBSD -current --- lib/libcrypto/chacha/chacha-merged.c | 6 +- regress/lib/libssl/unit/tls_prf.c | 6 +- sbin/dhcp6leased/Makefile | 7 +- sbin/dhcp6leased/control.c | 3 +- sbin/dhcp6leased/dhcp6leased.c | 145 ++++++++++- sbin/dhcp6leased/dhcp6leased.h | 58 +++-- sbin/dhcp6leased/engine.c | 155 ++++++++---- sbin/dhcp6leased/frontend.c | 27 ++- sbin/dhcp6leased/parse.y | 37 +-- sbin/dhcp6leased/parse_lease.y | 289 ++++++++++++++++++++++ sys/arch/amd64/amd64/hibernate_machdep.c | 8 +- sys/arch/amd64/conf/Makefile.amd64 | 4 +- sys/dev/ic/dwqe.c | 114 ++++++++- sys/dev/ic/dwqereg.h | 29 ++- sys/dev/ic/ufshci.c | 296 +++++++++++++++++------ sys/kern/subr_hibernate.c | 56 ++--- usr.sbin/rpki-client/crl.c | 4 +- 17 files changed, 989 insertions(+), 255 deletions(-) create mode 100644 sbin/dhcp6leased/parse_lease.y diff --git a/lib/libcrypto/chacha/chacha-merged.c b/lib/libcrypto/chacha/chacha-merged.c index 3e17b9354..debb776c8 100644 --- a/lib/libcrypto/chacha/chacha-merged.c +++ b/lib/libcrypto/chacha/chacha-merged.c @@ -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 -#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 diff --git a/regress/lib/libssl/unit/tls_prf.c b/regress/lib/libssl/unit/tls_prf.c index b6836da16..ea753f46f 100644 --- a/regress/lib/libssl/unit/tls_prf.c +++ b/regress/lib/libssl/unit/tls_prf.c @@ -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 * @@ -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; diff --git a/sbin/dhcp6leased/Makefile b/sbin/dhcp6leased/Makefile index 4574a9a61..73effc96b 100644 --- a/sbin/dhcp6leased/Makefile +++ b/sbin/dhcp6leased/Makefile @@ -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 # Don't compile dhcp6leased as static binary by default diff --git a/sbin/dhcp6leased/control.c b/sbin/dhcp6leased/control.c index 5bc63c11a..364b9ada4 100644 --- a/sbin/dhcp6leased/control.c +++ b/sbin/dhcp6leased/control.c @@ -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 @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/sbin/dhcp6leased/dhcp6leased.c b/sbin/dhcp6leased/dhcp6leased.c index 09478a29f..61fbd182a 100644 --- a/sbin/dhcp6leased/dhcp6leased.c +++ b/sbin/dhcp6leased/dhcp6leased.c @@ -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 @@ -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 diff --git a/sbin/dhcp6leased/dhcp6leased.h b/sbin/dhcp6leased/dhcp6leased.h index 7a4b3ece1..040cf8cbb 100644 --- a/sbin/dhcp6leased/dhcp6leased.h +++ b/sbin/dhcp6leased/dhcp6leased.h @@ -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 @@ -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 *); diff --git a/sbin/dhcp6leased/engine.c b/sbin/dhcp6leased/engine.c index 1db154326..6f9ccf161 100644 --- a/sbin/dhcp6leased/engine.c +++ b/sbin/dhcp6leased/engine.c @@ -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 @@ -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; - int need_refresh = 0; + 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,18 +637,38 @@ 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 - state_transition(iface, IF_INIT); + 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; - 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 */ + if (action == CONFIGURE) + engine_imsg_compose_main(IMSG_CONFIGURE_ADDRESS, 0, &address, + sizeof(address)); + else + engine_imsg_compose_main(IMSG_DECONFIGURE_ADDRESS, 0, &address, + sizeof(address)); } const char * diff --git a/sbin/dhcp6leased/frontend.c b/sbin/dhcp6leased/frontend.c index 6dc1abe52..b5e349cca 100644 --- a/sbin/dhcp6leased/frontend.c +++ b/sbin/dhcp6leased/frontend.c @@ -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 @@ -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]; - iaprefix.prefix_len = pd->prefix_len; - memcpy(&iaprefix.prefix, &pd->prefix, - sizeof(struct in6_addr)); + 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); - memcpy(p, &request_option_code, sizeof(uint16_t)); - p += sizeof(uint16_t); + 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); diff --git a/sbin/dhcp6leased/parse.y b/sbin/dhcp6leased/parse.y index 940ec15d1..3b60e7726 100644 --- a/sbin/dhcp6leased/parse.y +++ b/sbin/dhcp6leased/parse.y @@ -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 @@ -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) { diff --git a/sbin/dhcp6leased/parse_lease.y b/sbin/dhcp6leased/parse_lease.y new file mode 100644 index 000000000..767e0de8f --- /dev/null +++ b/sbin/dhcp6leased/parse_lease.y @@ -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 + * Copyright (c) 2004, 2005 Esben Norby + * Copyright (c) 2004 Ryan McBride + * Copyright (c) 2002, 2003, 2004 Henning Brauer + * 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 +#include +#include +#include + +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 STRING +%token 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(); +} diff --git a/sys/arch/amd64/amd64/hibernate_machdep.c b/sys/arch/amd64/amd64/hibernate_machdep.c index 19fe8e808..db59d0866 100644 --- a/sys/arch/amd64/amd64/hibernate_machdep.c +++ b/sys/arch/amd64/amd64/hibernate_machdep.c @@ -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 @@ -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 }; diff --git a/sys/arch/amd64/conf/Makefile.amd64 b/sys/arch/amd64/conf/Makefile.amd64 index b369f9476..263e7fe8d 100644 --- a/sys/arch/amd64/conf/Makefile.amd64 +++ b/sys/arch/amd64/conf/Makefile.amd64 @@ -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 diff --git a/sys/dev/ic/dwqe.c b/sys/dev/ic/dwqe.c index eb42e09a4..69c6dd231 100644 --- a/sys/dev/ic/dwqe.c +++ b/sys/dev/ic/dwqe.c @@ -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 * Copyright (c) 2017, 2022 Patrick Wildt @@ -21,6 +21,7 @@ */ #include "bpfilter.h" +#include "vlan.h" #include #include @@ -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; diff --git a/sys/dev/ic/dwqereg.h b/sys/dev/ic/dwqereg.h index ab479d54c..01c61bfec 100644 --- a/sys/dev/ic/dwqereg.h +++ b/sys/dev/ic/dwqereg.h @@ -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 * Copyright (c) 2017, 2022 Patrick Wildt @@ -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 diff --git a/sys/dev/ic/ufshci.c b/sys/dev/ic/ufshci.c index a91aaa5cc..8f3c5d120 100644 --- a/sys/dev/ic/ufshci.c +++ b/sys/dev/ic/ufshci.c @@ -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 @@ -42,6 +42,13 @@ #include #include +#ifdef HIBERNATE +#include +#include +#include +#include +#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 */ diff --git a/sys/kern/subr_hibernate.c b/sys/kern/subr_hibernate.c index 08f641dad..5499969d3 100644 --- a/sys/kern/subr_hibernate.c +++ b/sys/kern/subr_hibernate.c @@ -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 @@ -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: + 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); - printf("\nUnable to resume hibernated image\n"); } /* diff --git a/usr.sbin/rpki-client/crl.c b/usr.sbin/rpki-client/crl.c index 6896b6f67..0e7705c74 100644 --- a/usr.sbin/rpki-client/crl.c +++ b/usr.sbin/rpki-client/crl.c @@ -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 * @@ -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;