sync with OpenBSD -current
This commit is contained in:
parent
2d7157972b
commit
6040ea8924
17 changed files with 989 additions and 255 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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;
|
||||
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 *
|
||||
|
|
|
@ -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];
|
||||
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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
289
sbin/dhcp6leased/parse_lease.y
Normal file
289
sbin/dhcp6leased/parse_lease.y
Normal 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();
|
||||
}
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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:
|
||||
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");
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue