From 8624f4347e8133911b0554e816f6bedb56dc5fb3 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Tue, 30 Aug 2022 15:09:21 -0700 Subject: [PATCH 001/106] divert: declare PF_DIVERT domain and stop abusing PF_INET The divert(4) is not a protocol of IPv4. It is a socket to intercept packets from ipfw(4) to userland and re-inject them back. It can divert and re-inject IPv4 and IPv6 packets today, but potentially it is not limited to these two protocols. The IPPROTO_DIVERT does not belong to known IP protocols, it doesn't even fit into u_char. I guess, the implementation of divert(4) was done the way it is done basically because it was easier to do it this way, back when protocols for sockets were intertwined with IP protocols and domains were statically compiled in. Moving divert(4) out of inetsw accomplished two important things: 1) IPDIVERT is getting much closer to be not dependent on INET. This will be finalized in following changes. 2) Now divert socket no longer aliases with raw IPv4 socket. Domain/proto selection code won't need a hack for SOCK_RAW and multiple entries in inetsw implementing different flavors of raw socket can merge into one without requirement of raw IPv4 being the last member of dom_protosw. Differential revision: https://reviews.freebsd.org/D36379 --- lib/libc/sys/socket.2 | 4 +++- share/examples/netgraph/ngctl | 6 +++--- share/man/man4/divert.4 | 38 +++++++++++++++++++++-------------- sys/kern/uipc_socket.c | 11 ++++++++++ sys/netgraph/ng_ksocket.c | 2 +- sys/netinet/in_mcast.c | 20 ++++++------------ sys/netinet/ip_divert.c | 23 ++++++++++++--------- sys/netinet6/in6_mcast.c | 20 ++++++------------ sys/sys/socket.h | 4 +++- usr.bin/netstat/inet.c | 7 +++---- usr.bin/netstat/main.c | 2 +- 11 files changed, 74 insertions(+), 63 deletions(-) diff --git a/lib/libc/sys/socket.2 b/lib/libc/sys/socket.2 index 8ced1f0ba930..1eceabbf6fd4 100644 --- a/lib/libc/sys/socket.2 +++ b/lib/libc/sys/socket.2 @@ -28,7 +28,7 @@ .\" From: @(#)socket.2 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd August 26, 2022 +.Dd August 30, 2022 .Dt SOCKET 2 .Os .Sh NAME @@ -60,6 +60,7 @@ PF_LOCAL Host-internal protocols (alias for PF_UNIX), PF_UNIX Host-internal protocols, PF_INET Internet version 4 protocols, PF_INET6 Internet version 6 protocols, +PF_DIVERT Firewall packet diversion/re-injection, PF_ROUTE Internal routing protocol, PF_KEY Internal key-management function, PF_NETGRAPH Netgraph sockets, @@ -283,6 +284,7 @@ The socket type is not supported by the protocol. .Xr accept 2 , .Xr bind 2 , .Xr connect 2 , +.Xr divert 4 , .Xr getpeername 2 , .Xr getsockname 2 , .Xr getsockopt 2 , diff --git a/share/examples/netgraph/ngctl b/share/examples/netgraph/ngctl index e7b7cd86b04f..8dc6b23815b7 100644 --- a/share/examples/netgraph/ngctl +++ b/share/examples/netgraph/ngctl @@ -31,10 +31,10 @@ quit Exit program + -# Now let's create a ng_ksocket(4) node, in the family PF_INET, -# of type SOCK_RAW, and protocol IPPROTO_DIVERT: +# Now let's create a ng_ksocket(4) node, in the family PF_DIVERT, +# of type SOCK_RAW: - + mkpeer ksocket foo inet/raw/divert + + mkpeer ksocket foo divert/raw/0 # Note that ``foo'' is the hook name on the socket node, which can be # anything. The ``inet/raw/divert'' is the hook name on the ksocket diff --git a/share/man/man4/divert.4 b/share/man/man4/divert.4 index d8296995ca97..cfe1a31486c9 100644 --- a/share/man/man4/divert.4 +++ b/share/man/man4/divert.4 @@ -1,6 +1,6 @@ .\" $FreeBSD$ .\" -.Dd December 17, 2004 +.Dd August 30, 2022 .Dt DIVERT 4 .Os .Sh NAME @@ -11,7 +11,7 @@ .In sys/socket.h .In netinet/in.h .Ft int -.Fn socket PF_INET SOCK_RAW IPPROTO_DIVERT +.Fn socket PF_DIVERT SOCK_RAW 0 .Pp To enable support for divert sockets, place the following lines in the kernel configuration file: @@ -30,24 +30,30 @@ ipfw_load="YES" ipdivert_load="YES" .Ed .Sh DESCRIPTION -Divert sockets are similar to raw IP sockets, except that they -can be bound to a specific +Divert sockets allow to intercept and re-inject packets flowing through +the +.Xr ipfw 4 +firewall. +A divert socket can be bound to a specific .Nm port via the .Xr bind 2 system call. -The IP address in the bind is ignored; only the port -number is significant. +The sockaddr argument shall be sockaddr_in with sin_port set to the +desired value. +Note that the +.Nm +port has nothing to do with TCP/UDP ports. +It is just a cookie number, that allows to differentiate between different +divert points in the +.Xr ipfw 4 +ruleset. A divert socket bound to a divert port will receive all packets diverted -to that port by some (here unspecified) kernel mechanism(s). -Packets may also be written to a divert port, in which case they -re-enter kernel IP packet processing. +to that port by +.Xr ipfw 4 . +Packets may also be written to a divert port, in which case they re-enter +firewall processing at the next rule. .Pp -Divert sockets are normally used in conjunction with -.Fx Ns 's -packet filtering implementation and the -.Xr ipfw 8 -program. By reading from and writing to a divert socket, matching packets can be passed through an arbitrary ``filter'' as they travel through the host machine, special routing tricks can be done, etc. @@ -154,7 +160,9 @@ Packets written as incoming and having incorrect checksums will be dropped. Otherwise, all header fields are unchanged (and therefore in network order). .Pp Binding to port numbers less than 1024 requires super-user access, as does -creating a socket of type SOCK_RAW. +creating a +.Nm +socket. .Sh ERRORS Writing to a divert socket can return these errors, along with the usual errors possible when writing raw packets: diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index bf22c0245f24..1bc172eacd89 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -509,6 +509,17 @@ socreate(int dom, struct socket **aso, int type, int proto, struct socket *so; int error; + /* + * XXX: divert(4) historically abused PF_INET. Keep this compatibility + * shim until all applications have been updated. + */ + if (__predict_false(dom == PF_INET && type == SOCK_RAW && + proto == IPPROTO_DIVERT)) { + dom = PF_DIVERT; + printf("%s uses obsolete way to create divert(4) socket\n", + td->td_proc->p_comm); + } + if (proto) prp = pffindproto(dom, proto, type); else diff --git a/sys/netgraph/ng_ksocket.c b/sys/netgraph/ng_ksocket.c index d4f41fe02205..ff5e7b4812bf 100644 --- a/sys/netgraph/ng_ksocket.c +++ b/sys/netgraph/ng_ksocket.c @@ -121,6 +121,7 @@ static const struct ng_ksocket_alias ng_ksocket_families[] = { { "inet", PF_INET }, { "inet6", PF_INET6 }, { "atm", PF_ATM }, + { "divert", PF_DIVERT }, { NULL, -1 }, }; @@ -147,7 +148,6 @@ static const struct ng_ksocket_alias ng_ksocket_protos[] = { { "ah", IPPROTO_AH, PF_INET }, { "swipe", IPPROTO_SWIPE, PF_INET }, { "encap", IPPROTO_ENCAP, PF_INET }, - { "divert", IPPROTO_DIVERT, PF_INET }, { "pim", IPPROTO_PIM, PF_INET }, { NULL, -1 }, }; diff --git a/sys/netinet/in_mcast.c b/sys/netinet/in_mcast.c index 3f25471f0858..87de83da7a6a 100644 --- a/sys/netinet/in_mcast.c +++ b/sys/netinet/in_mcast.c @@ -1751,13 +1751,9 @@ inp_getmoptions(struct inpcb *inp, struct sockopt *sopt) INP_WLOCK(inp); imo = inp->inp_moptions; - /* - * If socket is neither of type SOCK_RAW or SOCK_DGRAM, - * or is a divert socket, reject it. - */ - if (inp->inp_socket->so_proto->pr_protocol == IPPROTO_DIVERT || - (inp->inp_socket->so_proto->pr_type != SOCK_RAW && - inp->inp_socket->so_proto->pr_type != SOCK_DGRAM)) { + /* If socket is neither of type SOCK_RAW or SOCK_DGRAM reject it. */ + if (inp->inp_socket->so_proto->pr_type != SOCK_RAW && + inp->inp_socket->so_proto->pr_type != SOCK_DGRAM) { INP_WUNLOCK(inp); return (EOPNOTSUPP); } @@ -2717,13 +2713,9 @@ inp_setmoptions(struct inpcb *inp, struct sockopt *sopt) error = 0; - /* - * If socket is neither of type SOCK_RAW or SOCK_DGRAM, - * or is a divert socket, reject it. - */ - if (inp->inp_socket->so_proto->pr_protocol == IPPROTO_DIVERT || - (inp->inp_socket->so_proto->pr_type != SOCK_RAW && - inp->inp_socket->so_proto->pr_type != SOCK_DGRAM)) + /* If socket is neither of type SOCK_RAW or SOCK_DGRAM, reject it. */ + if (inp->inp_socket->so_proto->pr_type != SOCK_RAW && + inp->inp_socket->so_proto->pr_type != SOCK_DGRAM) return (EOPNOTSUPP); switch (sopt->sopt_name) { diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index d14ec5190ad0..b09d7e1dda7a 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -36,7 +36,7 @@ __FBSDID("$FreeBSD$"); #include "opt_inet6.h" #include "opt_sctp.h" #ifndef INET -#error "IPDIVERT requires INET" +#error "IPDIVERT requires INET" /* XXX! */ #endif #include @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -716,7 +717,6 @@ SYSCTL_PROC(_net_inet_divert, OID_AUTO, pcblist, static struct protosw div_protosw = { .pr_type = SOCK_RAW, - .pr_protocol = IPPROTO_DIVERT, .pr_flags = PR_ATOMIC|PR_ADDR, .pr_attach = div_attach, .pr_bind = div_bind, @@ -729,6 +729,13 @@ static struct protosw div_protosw = { .pr_sosetlabel = in_pcbsosetlabel }; +static struct domain divertdomain = { + .dom_family = PF_DIVERT, + .dom_name = "divert", + .dom_nprotosw = 1, + .dom_protosw = { &div_protosw }, +}; + static int div_modevent(module_t mod, int type, void *unused) { @@ -736,12 +743,7 @@ div_modevent(module_t mod, int type, void *unused) switch (type) { case MOD_LOAD: - /* - * Protocol will be initialized by pf_proto_register(). - */ - err = protosw_register(&inetdomain, &div_protosw); - if (err != 0) - return (err); + domain_add(&divertdomain); ip_divert_ptr = divert_packet; break; case MOD_QUIESCE: @@ -763,6 +765,9 @@ div_modevent(module_t mod, int type, void *unused) * XXXRW: Note that there is a slight race here, as a new * socket open request could be spinning on the lock and then * we destroy the lock. + * + * XXXGL: One more reason this code is incorrect is that it + * checks only the current vnet. */ INP_INFO_WLOCK(&V_divcbinfo); if (V_divcbinfo.ipi_count != 0) { @@ -771,7 +776,7 @@ div_modevent(module_t mod, int type, void *unused) break; } ip_divert_ptr = NULL; - err = protosw_unregister(&div_protosw); + domain_remove(&divertdomain); INP_INFO_WUNLOCK(&V_divcbinfo); #ifndef VIMAGE div_destroy(NULL); diff --git a/sys/netinet6/in6_mcast.c b/sys/netinet6/in6_mcast.c index d0f8186e75c7..a02e18656dc2 100644 --- a/sys/netinet6/in6_mcast.c +++ b/sys/netinet6/in6_mcast.c @@ -1772,13 +1772,9 @@ ip6_getmoptions(struct inpcb *inp, struct sockopt *sopt) INP_WLOCK(inp); im6o = inp->in6p_moptions; - /* - * If socket is neither of type SOCK_RAW or SOCK_DGRAM, - * or is a divert socket, reject it. - */ - if (inp->inp_socket->so_proto->pr_protocol == IPPROTO_DIVERT || - (inp->inp_socket->so_proto->pr_type != SOCK_RAW && - inp->inp_socket->so_proto->pr_type != SOCK_DGRAM)) { + /* If socket is neither of type SOCK_RAW or SOCK_DGRAM, reject it. */ + if (inp->inp_socket->so_proto->pr_type != SOCK_RAW && + inp->inp_socket->so_proto->pr_type != SOCK_DGRAM) { INP_WUNLOCK(inp); return (EOPNOTSUPP); } @@ -2655,13 +2651,9 @@ ip6_setmoptions(struct inpcb *inp, struct sockopt *sopt) error = 0; - /* - * If socket is neither of type SOCK_RAW or SOCK_DGRAM, - * or is a divert socket, reject it. - */ - if (inp->inp_socket->so_proto->pr_protocol == IPPROTO_DIVERT || - (inp->inp_socket->so_proto->pr_type != SOCK_RAW && - inp->inp_socket->so_proto->pr_type != SOCK_DGRAM)) + /* If socket is neither of type SOCK_RAW or SOCK_DGRAM, reject it. */ + if (inp->inp_socket->so_proto->pr_type != SOCK_RAW && + inp->inp_socket->so_proto->pr_type != SOCK_DGRAM) return (EOPNOTSUPP); switch (sopt->sopt_name) { diff --git a/sys/sys/socket.h b/sys/sys/socket.h index 3ec0d3b1d06d..f81aba8f972d 100644 --- a/sys/sys/socket.h +++ b/sys/sys/socket.h @@ -268,7 +268,8 @@ struct accept_filter_arg { #define AF_INET_SDP 40 /* OFED Socket Direct Protocol ipv4 */ #define AF_INET6_SDP 42 /* OFED Socket Direct Protocol ipv6 */ #define AF_HYPERV 43 /* HyperV sockets */ -#define AF_MAX 43 +#define AF_DIVERT 44 /* divert(4) */ +#define AF_MAX 44 /* * When allocating a new AF_ constant, please only allocate * even numbered constants for FreeBSD until 134 as odd numbered AF_ @@ -393,6 +394,7 @@ struct sockproto { #define PF_NETLINK AF_NETLINK #define PF_INET_SDP AF_INET_SDP #define PF_INET6_SDP AF_INET6_SDP +#define PF_DIVERT AF_DIVERT #define PF_MAX AF_MAX diff --git a/usr.bin/netstat/inet.c b/usr.bin/netstat/inet.c index b7dbcb3531b0..e848874d1695 100644 --- a/usr.bin/netstat/inet.c +++ b/usr.bin/netstat/inet.c @@ -109,15 +109,14 @@ pcblist_sysctl(int proto, const char *name, char **bufp) case IPPROTO_UDP: mibvar = "net.inet.udp.pcblist"; break; - case IPPROTO_DIVERT: - mibvar = "net.inet.divert.pcblist"; - break; default: mibvar = "net.inet.raw.pcblist"; break; } if (strncmp(name, "sdp", 3) == 0) mibvar = "net.inet.sdp.pcblist"; + else if (strncmp(name, "divert", 6) == 0) + mibvar = "net.inet.divert.pcblist"; len = 0; if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) { if (errno != ENOENT) @@ -272,7 +271,7 @@ protopr(u_long off, const char *name, int af1, int proto) so = &inp->xi_socket; /* Ignore sockets for protocols other than the desired one. */ - if (so->xso_protocol != proto) + if (proto != 0 && so->xso_protocol != proto) continue; /* Ignore PCBs which were freed during copyout. */ diff --git a/usr.bin/netstat/main.c b/usr.bin/netstat/main.c index 1a011b9d5488..d1b069f38f0c 100644 --- a/usr.bin/netstat/main.c +++ b/usr.bin/netstat/main.c @@ -101,7 +101,7 @@ static struct protox { NULL, NULL, "sdp", 1, IPPROTO_TCP }, #endif { N_DIVCBINFO, -1, 1, protopr, - NULL, NULL, "divert", 1, IPPROTO_DIVERT }, + NULL, NULL, "divert", 1, 0 }, { N_RIPCBINFO, N_IPSTAT, 1, protopr, ip_stats, NULL, "ip", 1, IPPROTO_RAW }, { N_RIPCBINFO, N_ICMPSTAT, 1, protopr, From 61f7427f02a307d28af674a12c45dd546e3898e4 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Tue, 30 Aug 2022 15:09:21 -0700 Subject: [PATCH 002/106] protosw: cleanup protocols that existed merely to provide pr_input Since 4.4BSD the protosw was used to implement socket types created by socket(2) syscall and at the same to demultiplex incoming IPv4 datagrams (later copied to IPv6). This story ended with 78b1fc05b20. These entries (e.g. IPPROTO_ICMP) in inetsw that were added to catch packets in ip_input(), they would also be returned by pffindproto() if user says socket(AF_INET, SOCK_RAW, IPPROTO_ICMP). Thus, for raw sockets to work correctly, all the entries were pointing at raw_usrreq differentiating only in the value of pr_protocol. With 78b1fc05b20 all these entries are no longer needed, as ip_protox is independent of protosw. Any socket syscall requesting SOCK_RAW type would end up with rip_protosw. And this protosw has its pr_protocol set to 0, allowing to mark socket with any protocol. For IPv6 raw socket the change required two small fixes: o Validate user provided protocol value o Always use protocol number stored in inp in rip6_attach, instead of protosw value, which is now always 0. Differential revision: https://reviews.freebsd.org/D36380 --- sys/kern/uipc_domain.c | 26 ----------- sys/kern/uipc_socket.c | 10 ++-- sys/netinet/in_proto.c | 26 +---------- sys/netinet/raw_ip.c | 80 +++++++------------------------- sys/netinet6/in6_proto.c | 26 +---------- sys/netinet6/raw_ip6.c | 99 +++++++++++----------------------------- sys/sys/protosw.h | 1 - 7 files changed, 49 insertions(+), 219 deletions(-) diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c index 5fb602226bae..832afca510fa 100644 --- a/sys/kern/uipc_domain.c +++ b/sys/kern/uipc_domain.c @@ -306,32 +306,6 @@ pffindtype(int family, int type) return (NULL); } -struct protosw * -pffindproto(int family, int protocol, int type) -{ - struct domain *dp; - struct protosw *pr; - struct protosw *maybe; - - dp = pffinddomain(family); - if (dp == NULL) - return (NULL); - - maybe = NULL; - for (int i = 0; i < dp->dom_nprotosw; i++) { - if ((pr = dp->dom_protosw[i]) == NULL) - continue; - if ((pr->pr_protocol == protocol) && (pr->pr_type == type)) - return (pr); - - /* XXX: raw catches all. Why? */ - if (type == SOCK_RAW && pr->pr_type == SOCK_RAW && - pr->pr_protocol == 0 && maybe == NULL) - maybe = pr; - } - return (maybe); -} - /* * The caller must make sure that the new protocol is fully set up and ready to * accept requests before it is registered. diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 1bc172eacd89..a93256cd7f63 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -520,11 +520,7 @@ socreate(int dom, struct socket **aso, int type, int proto, td->td_proc->p_comm); } - if (proto) - prp = pffindproto(dom, proto, type); - else - prp = pffindtype(dom, type); - + prp = pffindtype(dom, type); if (prp == NULL) { /* No support for domain. */ if (pffinddomain(dom) == NULL) @@ -534,6 +530,8 @@ socreate(int dom, struct socket **aso, int type, int proto, return (EPROTOTYPE); return (EPROTONOSUPPORT); } + if (prp->pr_protocol != 0 && proto != 0 && prp->pr_protocol != proto) + return (EPROTONOSUPPORT); MPASS(prp->pr_attach); @@ -543,8 +541,6 @@ socreate(int dom, struct socket **aso, int type, int proto, if (prison_check_af(cred, prp->pr_domain->dom_family) != 0) return (EPROTONOSUPPORT); - if (prp->pr_type != type) - return (EPROTOTYPE); so = soalloc(CRED_TO_VNET(cred)); if (so == NULL) return (ENOBUFS); diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c index 35b02d706e72..4eb037dbeed0 100644 --- a/sys/netinet/in_proto.c +++ b/sys/netinet/in_proto.c @@ -94,9 +94,7 @@ __FBSDID("$FreeBSD$"); #endif /* netinet/raw_ip.c */ -extern struct protosw rip_protosw, rsvp_protosw, rawipv4_protosw, - rawipv6_protosw, mobile_protosw, etherip_protosw, icmp_protosw, - igmp_protosw, gre_protosw, pim_protosw, ripwild_protosw; +extern struct protosw rip_protosw; /* netinet/udp_usrreq.c */ extern struct protosw udp_protosw, udplite_protosw; @@ -111,7 +109,7 @@ struct domain inetdomain = { #endif .dom_ifattach = in_domifattach, .dom_ifdetach = in_domifdetach, - .dom_nprotosw = 24, + .dom_nprotosw = 14, .dom_protosw = { &tcp_protosw, &udp_protosw, @@ -123,28 +121,8 @@ struct domain inetdomain = { #endif &udplite_protosw, &rip_protosw, - /* - * XXXGL: it is entirely possible that all below raw-based - * protosw definitions are not needed. They could have existed - * just to define pr_input, pr_drain, pr_*timo or PR_LASTHDR - * flag, and were never supposed to create a special socket. - */ - &icmp_protosw, - &igmp_protosw, - &rsvp_protosw, - &rawipv4_protosw, - &mobile_protosw, - ðerip_protosw, - &gre_protosw, -#ifdef INET6 - &rawipv6_protosw, -#else - NULL, -#endif - &pim_protosw, /* Spacer 8 times for loadable protocols. XXXGL: why 8? */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - &ripwild_protosw, }, }; diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c index 0e7e75b1fe99..3e7c81341c08 100644 --- a/sys/netinet/raw_ip.c +++ b/sys/netinet/raw_ip.c @@ -1068,70 +1068,22 @@ SYSCTL_PROC(_net_inet_raw, OID_AUTO/*XXX*/, pcblist, "List of active raw IP sockets"); #ifdef INET -/* - * See comment in in_proto.c containing "protosw definitions are not needed". - */ -#define RAW_PROTOSW \ - .pr_type = SOCK_RAW, \ - .pr_flags = PR_ATOMIC|PR_ADDR, \ - .pr_ctloutput = rip_ctloutput, \ - .pr_abort = rip_abort, \ - .pr_attach = rip_attach, \ - .pr_bind = rip_bind, \ - .pr_connect = rip_connect, \ - .pr_control = in_control, \ - .pr_detach = rip_detach, \ - .pr_disconnect = rip_disconnect, \ - .pr_peeraddr = in_getpeeraddr, \ - .pr_send = rip_send, \ - .pr_shutdown = rip_shutdown, \ - .pr_sockaddr = in_getsockaddr, \ - .pr_sosetlabel = in_pcbsosetlabel, \ - .pr_close = rip_close - struct protosw rip_protosw = { - .pr_protocol = IPPROTO_RAW, - RAW_PROTOSW -}; -struct protosw icmp_protosw = { - .pr_protocol = IPPROTO_ICMP, - RAW_PROTOSW -}; -struct protosw igmp_protosw = { - .pr_protocol = IPPROTO_IGMP, - RAW_PROTOSW -}; -struct protosw rsvp_protosw = { - .pr_protocol = IPPROTO_RSVP, - RAW_PROTOSW -}; -struct protosw rawipv4_protosw = { - .pr_protocol = IPPROTO_IPV4, - RAW_PROTOSW -}; -struct protosw mobile_protosw = { - .pr_protocol = IPPROTO_MOBILE, - RAW_PROTOSW -}; -struct protosw etherip_protosw = { - .pr_protocol = IPPROTO_ETHERIP, - RAW_PROTOSW -}; -struct protosw gre_protosw = { - .pr_protocol = IPPROTO_GRE, - RAW_PROTOSW -}; -#ifdef INET6 -struct protosw rawipv6_protosw = { - .pr_protocol = IPPROTO_IPV6, - RAW_PROTOSW -}; -#endif -struct protosw pim_protosw = { - .pr_protocol = IPPROTO_PIM, - RAW_PROTOSW -}; -struct protosw ripwild_protosw = { - RAW_PROTOSW + .pr_type = SOCK_RAW, + .pr_flags = PR_ATOMIC|PR_ADDR, + .pr_ctloutput = rip_ctloutput, + .pr_abort = rip_abort, + .pr_attach = rip_attach, + .pr_bind = rip_bind, + .pr_connect = rip_connect, + .pr_control = in_control, + .pr_detach = rip_detach, + .pr_disconnect = rip_disconnect, + .pr_peeraddr = in_getpeeraddr, + .pr_send = rip_send, + .pr_shutdown = rip_shutdown, + .pr_sockaddr = in_getsockaddr, + .pr_sosetlabel = in_pcbsosetlabel, + .pr_close = rip_close }; #endif /* INET */ diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c index 72b84c915641..688702e17e34 100644 --- a/sys/netinet6/in6_proto.c +++ b/sys/netinet6/in6_proto.c @@ -122,9 +122,7 @@ __FBSDID("$FreeBSD$"); #include /* netinet6/raw_ip6.c */ -extern struct protosw rip6_protosw, icmp6_protosw, dstopts6_protosw, - routing6_protosw, frag6_protosw, rawipv4in6_protosw, rawipv6in6_protosw, - etherip6_protosw, gre6_protosw, pim6_protosw, rip6wild_protosw; +extern struct protosw rip6_protosw; /* netinet6/udp6_usrreq.c */ extern struct protosw udp6_protosw, udplite6_protosw; @@ -143,7 +141,7 @@ struct domain inet6domain = { .dom_ifattach = in6_domifattach, .dom_ifdetach = in6_domifdetach, .dom_ifmtu = in6_domifmtu, - .dom_nprotosw = 24, + .dom_nprotosw = 14, .dom_protosw = { &tcp6_protosw, &udp6_protosw, @@ -155,28 +153,8 @@ struct domain inet6domain = { #endif &udplite6_protosw, &rip6_protosw, - /* - * XXXGL: it is entirely possible that all below raw-based - * protosw definitions are not needed. They could have existed - * just to define pr_input, pr_drain, pr_*timo or PR_LASTHDR - * flag, and were never supposed to create a special socket. - */ - &icmp6_protosw, - &dstopts6_protosw, - &routing6_protosw, - &frag6_protosw, -#ifdef INET - &rawipv4in6_protosw, -#else - NULL, -#endif - &rawipv6in6_protosw, - ðerip6_protosw, - &gre6_protosw, - &pim6_protosw, /* Spacer 8 times for loadable protocols. XXXGL: why 8? */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - &rip6wild_protosw, }, }; diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index 091e90b0eaed..acc6787d59a7 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -424,9 +424,8 @@ rip6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, if (control != NULL) { NET_EPOCH_ENTER(et); - error = ip6_setpktopts(control, &opt, - inp->in6p_outputopts, so->so_cred, - so->so_proto->pr_protocol); + error = ip6_setpktopts(control, &opt, inp->in6p_outputopts, + so->so_cred, inp->inp_ip_p); NET_EPOCH_EXIT(et); if (error != 0) { @@ -455,7 +454,7 @@ rip6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, * For an ICMPv6 packet, we should know its type and code to update * statistics. */ - if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) { + if (inp->inp_ip_p == IPPROTO_ICMPV6) { struct icmp6_hdr *icmp6; if (m->m_len < sizeof(struct icmp6_hdr) && (m = m_pullup(m, sizeof(struct icmp6_hdr))) == NULL) { @@ -479,8 +478,7 @@ rip6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, uint32_t hash_type, hash_val; hash_val = fib6_calc_software_hash(&inp->in6p_laddr, - &dstsock->sin6_addr, 0, 0, so->so_proto->pr_protocol, - &hash_type); + &dstsock->sin6_addr, 0, 0, inp->inp_ip_p, &hash_type); inp->inp_flowid = hash_val; inp->inp_flowtype = hash_type; } @@ -516,14 +514,13 @@ rip6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, ip6->ip6_nxt = inp->inp_ip_p; ip6->ip6_hlim = hlim; - if (so->so_proto->pr_protocol == IPPROTO_ICMPV6 || - inp->in6p_cksum != -1) { + if (inp->inp_ip_p == IPPROTO_ICMPV6 || inp->in6p_cksum != -1) { struct mbuf *n; int off; u_int16_t *p; /* Compute checksum. */ - if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) + if (inp->inp_ip_p == IPPROTO_ICMPV6) off = offsetof(struct icmp6_hdr, icmp6_cksum); else off = inp->in6p_cksum; @@ -550,7 +547,7 @@ rip6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, * them to rtadvd/rtsol. */ if ((send_sendso_input_hook != NULL) && - so->so_proto->pr_protocol == IPPROTO_ICMPV6) { + inp->inp_ip_p == IPPROTO_ICMPV6) { switch (type) { case ND_ROUTER_ADVERT: case ND_ROUTER_SOLICIT: @@ -565,7 +562,7 @@ rip6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, NET_EPOCH_ENTER(et); error = ip6_output(m, optp, NULL, 0, inp->in6p_moptions, &oifp, inp); NET_EPOCH_EXIT(et); - if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) { + if (inp->inp_ip_p == IPPROTO_ICMPV6) { if (oifp) icmp6_ifoutstat_inc(oifp, type, code); ICMP6STAT_INC(icp6s_outhist[type]); @@ -682,6 +679,8 @@ rip6_attach(struct socket *so, int proto, struct thread *td) error = priv_check(td, PRIV_NETINET_RAW); if (error) return (error); + if (proto >= IPPROTO_MAX || proto < 0) + return (EPROTONOSUPPORT); error = soreserve(so, rip_sendspace, rip_recvspace); if (error) return (error); @@ -694,7 +693,7 @@ rip6_attach(struct socket *so, int proto, struct thread *td) return (error); } inp = (struct inpcb *)so->so_pcb; - inp->inp_ip_p = (long)proto; + inp->inp_ip_p = proto; inp->in6p_cksum = -1; inp->in6p_icmp6filt = filter; ICMP6_FILTER_SETPASSALL(inp->in6p_icmp6filt); @@ -869,66 +868,20 @@ rip6_shutdown(struct socket *so) return (0); } -/* - * See comment in in6_proto.c containing "protosw definitions are not needed". - */ -#define RAW6_PROTOSW \ - .pr_type = SOCK_RAW, \ - .pr_flags = PR_ATOMIC|PR_ADDR, \ - .pr_ctloutput = rip6_ctloutput, \ - .pr_abort = rip6_abort, \ - .pr_attach = rip6_attach, \ - .pr_bind = rip6_bind, \ - .pr_connect = rip6_connect, \ - .pr_control = in6_control, \ - .pr_detach = rip6_detach, \ - .pr_disconnect = rip6_disconnect, \ - .pr_peeraddr = in6_getpeeraddr, \ - .pr_send = rip6_send, \ - .pr_shutdown = rip6_shutdown, \ - .pr_sockaddr = in6_getsockaddr, \ - .pr_close = rip6_close - struct protosw rip6_protosw = { - .pr_protocol = IPPROTO_RAW, - RAW6_PROTOSW -}; -struct protosw icmp6_protosw = { - .pr_protocol = IPPROTO_ICMPV6, - RAW6_PROTOSW -}; -struct protosw dstopts6_protosw = { - .pr_protocol = IPPROTO_DSTOPTS, - RAW6_PROTOSW -}; -struct protosw routing6_protosw = { - .pr_protocol = IPPROTO_ROUTING, - RAW6_PROTOSW -}; -struct protosw frag6_protosw = { - .pr_protocol = IPPROTO_FRAGMENT, - RAW6_PROTOSW -}; -struct protosw rawipv4in6_protosw = { - .pr_protocol = IPPROTO_IPV4, - RAW6_PROTOSW -}; -struct protosw rawipv6in6_protosw = { - .pr_protocol = IPPROTO_IPV6, - RAW6_PROTOSW -}; -struct protosw etherip6_protosw = { - .pr_protocol = IPPROTO_ETHERIP, - RAW6_PROTOSW -}; -struct protosw gre6_protosw = { - .pr_protocol = IPPROTO_GRE, - RAW6_PROTOSW -}; -struct protosw pim6_protosw = { - .pr_protocol = IPPROTO_PIM, - RAW6_PROTOSW -}; -struct protosw rip6wild_protosw = { - RAW6_PROTOSW + .pr_type = SOCK_RAW, + .pr_flags = PR_ATOMIC|PR_ADDR, + .pr_ctloutput = rip6_ctloutput, + .pr_abort = rip6_abort, + .pr_attach = rip6_attach, + .pr_bind = rip6_bind, + .pr_connect = rip6_connect, + .pr_control = in6_control, + .pr_detach = rip6_detach, + .pr_disconnect = rip6_disconnect, + .pr_peeraddr = in6_getpeeraddr, + .pr_send = rip6_send, + .pr_shutdown = rip6_shutdown, + .pr_sockaddr = in6_getsockaddr, + .pr_close = rip6_close }; diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h index f6907505178e..f05aff962420 100644 --- a/sys/sys/protosw.h +++ b/sys/sys/protosw.h @@ -236,7 +236,6 @@ char *prcorequests[] = { #ifdef _KERNEL struct domain *pffinddomain(int family); -struct protosw *pffindproto(int family, int protocol, int type); struct protosw *pffindtype(int family, int type); int protosw_register(struct domain *, struct protosw *); int protosw_unregister(struct protosw *); From 2b1c72171e3e44b26793013f04fb98f0b975cbad Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Tue, 30 Aug 2022 15:09:21 -0700 Subject: [PATCH 003/106] divert(4): provide statistics Instead of incrementing pretty random counters in the IP statistics, create divert socket statistics structure. Export via netstat(1). Differential revision: https://reviews.freebsd.org/D36381 --- sys/netinet/ip_divert.c | 42 ++++++++++++++++++++++----------------- sys/netinet/ip_divert.h | 10 ++++++++-- usr.bin/netstat/inet.c | 31 +++++++++++++++++++++++++++++ usr.bin/netstat/main.c | 2 +- usr.bin/netstat/netstat.h | 1 + 5 files changed, 65 insertions(+), 21 deletions(-) diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index b09d7e1dda7a..0cecbbd0d15d 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #ifdef INET6 #include #include @@ -110,8 +111,19 @@ __FBSDID("$FreeBSD$"); * written in the sin_port (ipfw does not allow a rule #0, so sin_port=0 * will apply the entire ruleset to the packet). */ +static SYSCTL_NODE(_net_inet, OID_AUTO, divert, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, + "divert(4)"); + +VNET_PCPUSTAT_DEFINE_STATIC(struct divstat, divstat); +VNET_PCPUSTAT_SYSINIT(divstat); +#ifdef VIMAGE +VNET_PCPUSTAT_SYSUNINIT(divstat); +#endif +SYSCTL_VNET_PCPUSTAT(_net_inet_divert, OID_AUTO, stats, struct divstat, + divstat, "divert(4) socket statistics"); +#define DIVSTAT_INC(name) \ + VNET_PCPUSTAT_ADD(struct divstat, divstat, div_ ## name, 1) -/* Internal variables. */ VNET_DEFINE_STATIC(struct inpcbinfo, divcbinfo); #define V_divcbinfo VNET(divcbinfo) @@ -273,17 +285,18 @@ divert_packet(struct mbuf *m, bool incoming) (struct sockaddr *)&divsrc, m, NULL) == 0) { soroverflow_locked(sa); sa = NULL; /* force mbuf reclaim below */ - } else + } else { sorwakeup_locked(sa); + DIVSTAT_INC(diverted); + } /* XXX why does only one socket match? */ INP_RUNLOCK(inp); break; } if (sa == NULL) { m_freem(m); - KMOD_IPSTAT_INC(ips_noproto); - KMOD_IPSTAT_DEC(ips_delivered); - } + DIVSTAT_INC(noport); + } } /* @@ -310,7 +323,6 @@ div_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, /* Packet must have a header (but that's about it) */ if (m->m_len < sizeof (struct ip) && (m = m_pullup(m, sizeof (struct ip))) == NULL) { - KMOD_IPSTAT_INC(ips_toosmall); m_freem(m); return (EINVAL); } @@ -447,9 +459,6 @@ div_output_outbound(int family, struct socket *so, struct mbuf *m) #endif } - /* Send packet to output processing */ - KMOD_IPSTAT_INC(ips_rawout); /* XXX */ - #ifdef MAC mac_inpcb_create_mbuf(inp, m); #endif @@ -498,6 +507,8 @@ div_output_outbound(int family, struct socket *so, struct mbuf *m) break; #endif } + if (error == 0) + DIVSTAT_INC(outbound); if (options != NULL) m_freem(options); @@ -549,10 +560,12 @@ div_output_inbound(int family, struct socket *so, struct mbuf *m, else if (in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) m->m_flags |= M_BCAST; netisr_queue_src(NETISR_IP, (uintptr_t)so, m); + DIVSTAT_INC(inbound); break; #ifdef INET6 case AF_INET6: netisr_queue_src(NETISR_IPV6, (uintptr_t)so, m); + DIVSTAT_INC(inbound); break; #endif default: @@ -704,16 +717,9 @@ div_pcblist(SYSCTL_HANDLER_ARGS) return (error); } - -#ifdef SYSCTL_NODE -static SYSCTL_NODE(_net_inet, IPPROTO_DIVERT, divert, - CTLFLAG_RW | CTLFLAG_MPSAFE, 0, - "IPDIVERT"); SYSCTL_PROC(_net_inet_divert, OID_AUTO, pcblist, - CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, - NULL, 0, div_pcblist, "S,xinpcb", - "List of active divert sockets"); -#endif + CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, div_pcblist, + "S,xinpcb", "List of active divert sockets"); static struct protosw div_protosw = { .pr_type = SOCK_RAW, diff --git a/sys/netinet/ip_divert.h b/sys/netinet/ip_divert.h index a426afeca217..dd0568bbfb07 100644 --- a/sys/netinet/ip_divert.h +++ b/sys/netinet/ip_divert.h @@ -36,10 +36,9 @@ #ifndef _NETINET_IP_DIVERT_H_ #define _NETINET_IP_DIVERT_H_ +#include /* - * divert has no custom kernel-userland API. - * * All communication occurs through a sockaddr_in socket where * * kernel-->userland @@ -54,4 +53,11 @@ * sin_addr = IN: address of the incoming interface; * OUT: INADDR_ANY */ + +struct divstat { + uint64_t div_diverted; /* successfully diverted to userland */ + uint64_t div_noport; /* failed due to no bound socket */ + uint64_t div_outbound; /* re-injected as outbound */ + uint64_t div_inbound; /* re-injected as inbound */ +}; #endif /* _NETINET_IP_DIVERT_H_ */ diff --git a/usr.bin/netstat/inet.c b/usr.bin/netstat/inet.c index e848874d1695..468bd9aba3e5 100644 --- a/usr.bin/netstat/inet.c +++ b/usr.bin/netstat/inet.c @@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -1432,6 +1433,36 @@ pim_stats(u_long off __unused, const char *name, int af1 __unused, xo_close_container(name); } +/* + * Dump divert(4) statistics structure. + */ +void +divert_stats(u_long off, const char *name, int af1 __unused, int proto __unused) +{ + struct divstat divstat; + + if (fetch_stats("net.inet.divert.stats", off, &divstat, + sizeof(divstat), kread_counters) != 0) + return; + + xo_open_container(name); + xo_emit("{T:/%s}:\n", name); + +#define p(f, m) if (divstat.f || sflag <= 1) \ + xo_emit(m, (uintmax_t)divstat.f, plural(divstat.f)) + + p(div_diverted, "\t{:diverted-packets/%ju} " + "{N:/packet%s successfully diverted to userland}\n"); + p(div_noport, "\t{:noport-fails/%ju} " + "{N:/packet%s failed to divert due to no socket bound at port}\n"); + p(div_outbound, "\t{:outbound-packets/%ju} " + "{N:/packet%s successfully re-injected as outbound}\n"); + p(div_inbound, "\t{:inbound-packets/%ju} " + "{N:/packet%s successfully re-injected as inbound}\n"); +#undef p + xo_close_container(name); +} + #ifdef INET /* * Pretty print an Internet address (net address + port). diff --git a/usr.bin/netstat/main.c b/usr.bin/netstat/main.c index d1b069f38f0c..078d8cca3c61 100644 --- a/usr.bin/netstat/main.c +++ b/usr.bin/netstat/main.c @@ -101,7 +101,7 @@ static struct protox { NULL, NULL, "sdp", 1, IPPROTO_TCP }, #endif { N_DIVCBINFO, -1, 1, protopr, - NULL, NULL, "divert", 1, 0 }, + divert_stats, NULL, "divert", 1, 0 }, { N_RIPCBINFO, N_IPSTAT, 1, protopr, ip_stats, NULL, "ip", 1, IPPROTO_RAW }, { N_RIPCBINFO, N_ICMPSTAT, 1, protopr, diff --git a/usr.bin/netstat/netstat.h b/usr.bin/netstat/netstat.h index eb5b77eade0e..32dbbc9d5576 100644 --- a/usr.bin/netstat/netstat.h +++ b/usr.bin/netstat/netstat.h @@ -92,6 +92,7 @@ void sctp_protopr(u_long, const char *, int, int); void sctp_stats(u_long, const char *, int, int); #endif void arp_stats(u_long, const char *, int, int); +void divert_stats(u_long, const char *, int, int); void ip_stats(u_long, const char *, int, int); void icmp_stats(u_long, const char *, int, int); void igmp_stats(u_long, const char *, int, int); From f1fb051716625d29d9dea599c6d7d20d773fe6e3 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Tue, 30 Aug 2022 15:09:21 -0700 Subject: [PATCH 004/106] divert(4): maintain own cb database and stop using inpcb KPI Here go cons of using inpcb for divert: - divert(4) uses only 16 bits (local port) out of struct inpcb, which is 424 bytes today. - The inpcb KPI isn't able to provide hashing for divert(4), thus it uses global inpcb list for lookups. - divert(4) uses INET-specific part of the KPI, making INET a requirement for IPDIVERT. Maintain our own very simple hash lookup database instead. It has mutex protection for write and epoch protection for lookups. Since now so->so_pcb no longer points to struct inpcb, don't initialize protosw methods to methods that belong to PF_INET. Also, drop support for setting options on a divert socket. My review of software in base and ports confirms that this has no use and unlikely worked before. Differential revision: https://reviews.freebsd.org/D36382 --- share/man/man4/divert.4 | 5 +- sys/netinet/ip_divert.c | 310 +++++++++++++++++----------------------- 2 files changed, 132 insertions(+), 183 deletions(-) diff --git a/share/man/man4/divert.4 b/share/man/man4/divert.4 index cfe1a31486c9..18da54ee9fc9 100644 --- a/share/man/man4/divert.4 +++ b/share/man/man4/divert.4 @@ -159,10 +159,9 @@ with the correct value. Packets written as incoming and having incorrect checksums will be dropped. Otherwise, all header fields are unchanged (and therefore in network order). .Pp -Binding to port numbers less than 1024 requires super-user access, as does -creating a +Creating a .Nm -socket. +socket requires super-user access. .Sh ERRORS Writing to a divert socket can return these errors, along with the usual errors possible when writing raw packets: diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index 0cecbbd0d15d..7e0a09bd8e3a 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -86,6 +86,14 @@ __FBSDID("$FreeBSD$"); #define DIVSNDQ (65536 + 100) #define DIVRCVQ (65536 + 100) +/* + * Usually a system has very few divert ports. Previous implementation + * used a linked list. + */ +#define DIVHASHSIZE (1 << 3) /* 8 entries, one cache line. */ +#define DIVHASH(port) (port % DIVHASHSIZE) +#define DCBHASH(dcb) ((dcb)->dcb_port % DIVHASHSIZE) + /* * Divert sockets work in conjunction with ipfw or other packet filters, * see the divert(4) manpage for features. @@ -124,9 +132,6 @@ SYSCTL_VNET_PCPUSTAT(_net_inet_divert, OID_AUTO, stats, struct divstat, #define DIVSTAT_INC(name) \ VNET_PCPUSTAT_ADD(struct divstat, divstat, div_ ## name, 1) -VNET_DEFINE_STATIC(struct inpcbinfo, divcbinfo); -#define V_divcbinfo VNET(divcbinfo) - static u_long div_sendspace = DIVSNDQ; /* XXX sysctl ? */ static u_long div_recvspace = DIVRCVQ; /* XXX sysctl ? */ @@ -134,39 +139,31 @@ static int div_output_inbound(int fmaily, struct socket *so, struct mbuf *m, struct sockaddr_in *sin); static int div_output_outbound(int family, struct socket *so, struct mbuf *m); -/* - * Initialize divert connection block queue. - */ -INPCBSTORAGE_DEFINE(divcbstor, "divinp", "divcb", "div", "divhash"); - -static void -div_init(void *arg __unused) -{ - - /* - * XXX We don't use the hash list for divert IP, but it's easier to - * allocate one-entry hash lists than it is to check all over the - * place for hashbase == NULL. - */ - in_pcbinfo_init(&V_divcbinfo, &divcbstor, 1, 1); -} -VNET_SYSINIT(div_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, div_init, NULL); - -static void -div_destroy(void *unused __unused) -{ +struct divcb { + union { + SLIST_ENTRY(divcb) dcb_next; + intptr_t dcb_bound; +#define DCB_UNBOUND ((intptr_t)-1) + }; + struct socket *dcb_socket; + uint16_t dcb_port; + uint64_t dcb_gencnt; + struct epoch_context dcb_epochctx; +}; - in_pcbinfo_destroy(&V_divcbinfo); -} -VNET_SYSUNINIT(divert, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, div_destroy, NULL); +SLIST_HEAD(divhashhead, divcb); -static bool -div_port_match(const struct inpcb *inp, void *v) -{ - uint16_t nport = *(uint16_t *)v; +VNET_DEFINE_STATIC(struct divhashhead, divhash[DIVHASHSIZE]) = {}; +#define V_divhash VNET(divhash) +VNET_DEFINE_STATIC(uint64_t, dcb_count) = 0; +#define V_dcb_count VNET(dcb_count) +VNET_DEFINE_STATIC(uint64_t, dcb_gencnt) = 0; +#define V_dcb_gencnt VNET(dcb_gencnt) - return (inp->inp_lport == nport); -} +static struct mtx divert_mtx; +MTX_SYSINIT(divert, &divert_mtx, "divert(4) socket pcb lists", MTX_DEF); +#define DIVERT_LOCK() mtx_lock(&divert_mtx) +#define DIVERT_UNLOCK() mtx_unlock(&divert_mtx) /* * Divert a packet by passing it up to the divert socket at port 'port'. @@ -177,12 +174,9 @@ divert_packet(struct mbuf *m, bool incoming) #if defined(SCTP) || defined(SCTP_SUPPORT) struct ip *ip; #endif - struct inpcb *inp; - struct socket *sa; + struct divcb *dcb; u_int16_t nport; struct sockaddr_in divsrc; - struct inpcb_iterator inpi = INP_ITERATOR(&V_divcbinfo, - INPLOOKUP_RLOCKPCB, div_port_match, &nport); struct m_tag *mtag; NET_EPOCH_ASSERT(); @@ -275,27 +269,26 @@ divert_packet(struct mbuf *m, bool incoming) } /* Put packet on socket queue, if any */ - sa = NULL; - /* nport is inp_next's context. */ - nport = htons((u_int16_t)(((struct ipfw_rule_ref *)(mtag+1))->info)); - while ((inp = inp_next(&inpi)) != NULL) { - sa = inp->inp_socket; + nport = htons((uint16_t)(((struct ipfw_rule_ref *)(mtag+1))->info)); + SLIST_FOREACH(dcb, &V_divhash[DIVHASH(nport)], dcb_next) + if (dcb->dcb_port == nport) + break; + + if (dcb != NULL) { + struct socket *sa = dcb->dcb_socket; + SOCKBUF_LOCK(&sa->so_rcv); if (sbappendaddr_locked(&sa->so_rcv, (struct sockaddr *)&divsrc, m, NULL) == 0) { soroverflow_locked(sa); - sa = NULL; /* force mbuf reclaim below */ + m_freem(m); } else { sorwakeup_locked(sa); DIVSTAT_INC(diverted); } - /* XXX why does only one socket match? */ - INP_RUNLOCK(inp); - break; - } - if (sa == NULL) { - m_freem(m); + } else { DIVSTAT_INC(noport); + m_freem(m); } } @@ -422,23 +415,12 @@ static int div_output_outbound(int family, struct socket *so, struct mbuf *m) { struct ip *const ip = mtod(m, struct ip *); - struct mbuf *options; - struct inpcb *inp; int error; - inp = sotoinpcb(so); - INP_RLOCK(inp); switch (family) { case AF_INET: - /* - * Don't allow both user specified and setsockopt - * options, and don't allow packet length sizes that - * will crash. - */ - if ((((ip->ip_hl << 2) != sizeof(struct ip)) && - inp->inp_options != NULL) || - ((u_short)ntohs(ip->ip_len) > m->m_pkthdr.len)) { - INP_RUNLOCK(inp); + /* Don't allow packet length sizes that will crash. */ + if (((u_short)ntohs(ip->ip_len) > m->m_pkthdr.len)) { m_freem(m); return (EINVAL); } @@ -450,7 +432,6 @@ div_output_outbound(int family, struct socket *so, struct mbuf *m) /* Don't allow packet length sizes that will crash */ if (((u_short)ntohs(ip6->ip6_plen) > m->m_pkthdr.len)) { - INP_RUNLOCK(inp); m_freem(m); return (EINVAL); } @@ -460,44 +441,13 @@ div_output_outbound(int family, struct socket *so, struct mbuf *m) } #ifdef MAC - mac_inpcb_create_mbuf(inp, m); + mac_socket_create_mbuf(so, m); #endif - /* - * Get ready to inject the packet into ip_output(). - * Just in case socket options were specified on the - * divert socket, we duplicate them. This is done - * to avoid having to hold the PCB locks over the call - * to ip_output(), as doing this results in a number of - * lock ordering complexities. - * - * Note that we set the multicast options argument for - * ip_output() to NULL since it should be invariant that - * they are not present. - */ - KASSERT(inp->inp_moptions == NULL, - ("multicast options set on a divert socket")); - /* - * XXXCSJP: It is unclear to me whether or not it makes - * sense for divert sockets to have options. However, - * for now we will duplicate them with the INP locks - * held so we can use them in ip_output() without - * requring a reference to the pcb. - */ - options = NULL; - if (inp->inp_options != NULL) { - options = m_dup(inp->inp_options, M_NOWAIT); - if (options == NULL) { - INP_RUNLOCK(inp); - m_freem(m); - return (ENOBUFS); - } - } - INP_RUNLOCK(inp); error = 0; switch (family) { case AF_INET: - error = ip_output(m, options, NULL, + error = ip_output(m, NULL, NULL, ((so->so_options & SO_DONTROUTE) ? IP_ROUTETOIF : 0) | IP_ALLOWBROADCAST | IP_RAWOUTPUT, NULL, NULL); break; @@ -509,8 +459,6 @@ div_output_outbound(int family, struct socket *so, struct mbuf *m) } if (error == 0) DIVSTAT_INC(outbound); - if (options != NULL) - m_freem(options); return (error); } @@ -579,11 +527,9 @@ div_output_inbound(int family, struct socket *so, struct mbuf *m, static int div_attach(struct socket *so, int proto, struct thread *td) { - struct inpcb *inp; + struct divcb *dcb; int error; - inp = sotoinpcb(so); - KASSERT(inp == NULL, ("div_attach: inp != NULL")); if (td != NULL) { error = priv_check(td, PRIV_NETINET_DIVERT); if (error) @@ -592,85 +538,90 @@ div_attach(struct socket *so, int proto, struct thread *td) error = soreserve(so, div_sendspace, div_recvspace); if (error) return error; - error = in_pcballoc(so, &V_divcbinfo); - if (error) - return error; - inp = (struct inpcb *)so->so_pcb; - inp->inp_ip_p = proto; - inp->inp_flags |= INP_HDRINCL; - INP_WUNLOCK(inp); - return 0; + dcb = malloc(sizeof(*dcb), M_PCB, M_WAITOK); + dcb->dcb_bound = DCB_UNBOUND; + dcb->dcb_socket = so; + DIVERT_LOCK(); + V_dcb_count++; + dcb->dcb_gencnt = ++V_dcb_gencnt; + DIVERT_UNLOCK(); + so->so_pcb = dcb; + + return (0); } static void -div_detach(struct socket *so) +div_free(epoch_context_t ctx) { - struct inpcb *inp; + struct divcb *dcb = __containerof(ctx, struct divcb, dcb_epochctx); + + free(dcb, M_PCB); +} - inp = sotoinpcb(so); - KASSERT(inp != NULL, ("div_detach: inp == NULL")); - INP_WLOCK(inp); - in_pcbdetach(inp); - in_pcbfree(inp); +static void +div_detach(struct socket *so) +{ + struct divcb *dcb = so->so_pcb; + + so->so_pcb = NULL; + DIVERT_LOCK(); + if (dcb->dcb_bound != DCB_UNBOUND) + SLIST_REMOVE(&V_divhash[DCBHASH(dcb)], dcb, divcb, dcb_next); + V_dcb_count--; + V_dcb_gencnt++; + DIVERT_UNLOCK(); + NET_EPOCH_CALL(div_free, &dcb->dcb_epochctx); } static int div_bind(struct socket *so, struct sockaddr *nam, struct thread *td) { - struct inpcb *inp; - int error; + struct divcb *dcb; + uint16_t port; - inp = sotoinpcb(so); - KASSERT(inp != NULL, ("div_bind: inp == NULL")); - /* in_pcbbind assumes that nam is a sockaddr_in - * and in_pcbbind requires a valid address. Since divert - * sockets don't we need to make sure the address is - * filled in properly. - * XXX -- divert should not be abusing in_pcbind - * and should probably have its own family. - */ if (nam->sa_family != AF_INET) return EAFNOSUPPORT; if (nam->sa_len != sizeof(struct sockaddr_in)) return EINVAL; - ((struct sockaddr_in *)nam)->sin_addr.s_addr = INADDR_ANY; - INP_WLOCK(inp); - INP_HASH_WLOCK(&V_divcbinfo); - error = in_pcbbind(inp, nam, td->td_ucred); - INP_HASH_WUNLOCK(&V_divcbinfo); - INP_WUNLOCK(inp); - return error; + port = ((struct sockaddr_in *)nam)->sin_port; + DIVERT_LOCK(); + SLIST_FOREACH(dcb, &V_divhash[DIVHASH(port)], dcb_next) + if (dcb->dcb_port == port) { + DIVERT_UNLOCK(); + return (EADDRINUSE); + } + dcb = so->so_pcb; + if (dcb->dcb_bound != DCB_UNBOUND) + SLIST_REMOVE(&V_divhash[DCBHASH(dcb)], dcb, divcb, dcb_next); + dcb->dcb_port = port; + SLIST_INSERT_HEAD(&V_divhash[DIVHASH(port)], dcb, dcb_next); + DIVERT_UNLOCK(); + + return (0); } static int div_shutdown(struct socket *so) { - struct inpcb *inp; - inp = sotoinpcb(so); - KASSERT(inp != NULL, ("div_shutdown: inp == NULL")); - INP_WLOCK(inp); socantsendmore(so); - INP_WUNLOCK(inp); return 0; } static int div_pcblist(SYSCTL_HANDLER_ARGS) { - struct inpcb_iterator inpi = INP_ALL_ITERATOR(&V_divcbinfo, - INPLOOKUP_RLOCKPCB); struct xinpgen xig; - struct inpcb *inp; + struct divcb *dcb; int error; if (req->newptr != 0) return EPERM; if (req->oldptr == 0) { - int n; + u_int n; - n = V_divcbinfo.ipi_count; + n = V_dcb_count; n += imax(n / 8, 10); req->oldidx = 2 * (sizeof xig) + n * sizeof(struct xinpcb); return 0; @@ -681,39 +632,45 @@ div_pcblist(SYSCTL_HANDLER_ARGS) bzero(&xig, sizeof(xig)); xig.xig_len = sizeof xig; - xig.xig_count = V_divcbinfo.ipi_count; - xig.xig_gen = V_divcbinfo.ipi_gencnt; + xig.xig_count = V_dcb_count; + xig.xig_gen = V_dcb_gencnt; xig.xig_sogen = so_gencnt; error = SYSCTL_OUT(req, &xig, sizeof xig); if (error) return error; - while ((inp = inp_next(&inpi)) != NULL) { - if (inp->inp_gencnt <= xig.xig_gen) { - struct xinpcb xi; - - in_pcbtoxinpcb(inp, &xi); - error = SYSCTL_OUT(req, &xi, sizeof xi); - if (error) { - INP_RUNLOCK(inp); - break; + DIVERT_LOCK(); + for (int i = 0; i < DIVHASHSIZE; i++) + SLIST_FOREACH(dcb, &V_divhash[i], dcb_next) { + if (dcb->dcb_gencnt <= xig.xig_gen) { + struct xinpcb xi; + + bzero(&xi, sizeof(xi)); + xi.xi_len = sizeof(struct xinpcb); + sotoxsocket(dcb->dcb_socket, &xi.xi_socket); + xi.inp_gencnt = dcb->dcb_gencnt; + xi.inp_vflag = INP_IPV4; /* XXX: netstat(1) */ + xi.inp_inc.inc_ie.ie_lport = dcb->dcb_port; + error = SYSCTL_OUT(req, &xi, sizeof xi); + if (error) + goto errout; } } - } - if (!error) { - /* - * Give the user an updated idea of our state. - * If the generation differs from what we told - * her before, she knows that something happened - * while we were processing this request, and it - * might be necessary to retry. - */ - xig.xig_gen = V_divcbinfo.ipi_gencnt; - xig.xig_sogen = so_gencnt; - xig.xig_count = V_divcbinfo.ipi_count; - error = SYSCTL_OUT(req, &xig, sizeof xig); - } + /* + * Give the user an updated idea of our state. + * If the generation differs from what we told + * her before, she knows that something happened + * while we were processing this request, and it + * might be necessary to retry. + */ + xig.xig_gen = V_dcb_gencnt; + xig.xig_sogen = so_gencnt; + xig.xig_count = V_dcb_count; + error = SYSCTL_OUT(req, &xig, sizeof xig); + +errout: + DIVERT_UNLOCK(); return (error); } @@ -726,13 +683,9 @@ static struct protosw div_protosw = { .pr_flags = PR_ATOMIC|PR_ADDR, .pr_attach = div_attach, .pr_bind = div_bind, - .pr_control = in_control, .pr_detach = div_detach, - .pr_peeraddr = in_getpeeraddr, .pr_send = div_send, .pr_shutdown = div_shutdown, - .pr_sockaddr = in_getsockaddr, - .pr_sosetlabel = in_pcbsosetlabel }; static struct domain divertdomain = { @@ -775,18 +728,15 @@ div_modevent(module_t mod, int type, void *unused) * XXXGL: One more reason this code is incorrect is that it * checks only the current vnet. */ - INP_INFO_WLOCK(&V_divcbinfo); - if (V_divcbinfo.ipi_count != 0) { + DIVERT_LOCK(); + if (V_dcb_count != 0) { + DIVERT_UNLOCK(); err = EBUSY; - INP_INFO_WUNLOCK(&V_divcbinfo); break; } + DIVERT_UNLOCK(); ip_divert_ptr = NULL; domain_remove(&divertdomain); - INP_INFO_WUNLOCK(&V_divcbinfo); -#ifndef VIMAGE - div_destroy(NULL); -#endif break; default: err = EOPNOTSUPP; From e72c522858cb3fe179b8ec5700cdbf46c45e917e Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Tue, 30 Aug 2022 15:09:21 -0700 Subject: [PATCH 005/106] divert(4): make it compilable and working without INET Differential revision: https://reviews.freebsd.org/D36383 --- sys/conf/files | 2 +- sys/netinet/ip_divert.c | 29 ++++++++++++++++++++--------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/sys/conf/files b/sys/conf/files index f9bd87f20894..1e3518fcfcb0 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -4333,7 +4333,7 @@ netinet/in_prot.c optional inet | inet6 netinet/in_proto.c optional inet | inet6 netinet/in_rmx.c optional inet netinet/in_rss.c optional inet rss -netinet/ip_divert.c optional inet ipdivert ipfirewall +netinet/ip_divert.c optional ipdivert ipfirewall netinet/ip_ecn.c optional inet | inet6 netinet/ip_encap.c optional inet | inet6 netinet/ip_fastfwd.c optional inet diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index 7e0a09bd8e3a..2a5a7677cb71 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -35,9 +35,6 @@ __FBSDID("$FreeBSD$"); #include "opt_inet.h" #include "opt_inet6.h" #include "opt_sctp.h" -#ifndef INET -#error "IPDIVERT requires INET" /* XXX! */ -#endif #include #include @@ -171,9 +168,6 @@ MTX_SYSINIT(divert, &divert_mtx, "divert(4) socket pcb lists", MTX_DEF); static void divert_packet(struct mbuf *m, bool incoming) { -#if defined(SCTP) || defined(SCTP_SUPPORT) - struct ip *ip; -#endif struct divcb *dcb; u_int16_t nport; struct sockaddr_in divsrc; @@ -190,14 +184,17 @@ divert_packet(struct mbuf *m, bool incoming) if (m->m_len < sizeof(struct ip) && (m = m_pullup(m, sizeof(struct ip))) == NULL) return; - +#ifdef INET /* Delayed checksums are currently not compatible with divert. */ if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { in_delayed_cksum(m); m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; } +#endif #if defined(SCTP) || defined(SCTP_SUPPORT) if (m->m_pkthdr.csum_flags & CSUM_SCTP) { + struct ip *ip; + ip = mtod(m, struct ip *); sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2)); m->m_pkthdr.csum_flags &= ~CSUM_SCTP; @@ -379,9 +376,11 @@ div_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, ip = mtod(m, struct ip *); switch (ip->ip_v) { +#ifdef INET case IPVERSION: family = AF_INET; break; +#endif #ifdef INET6 case IPV6_VERSION >> 4: family = AF_INET6; @@ -414,17 +413,22 @@ div_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, static int div_output_outbound(int family, struct socket *so, struct mbuf *m) { - struct ip *const ip = mtod(m, struct ip *); int error; switch (family) { +#ifdef INET case AF_INET: + { + struct ip *const ip = mtod(m, struct ip *); + /* Don't allow packet length sizes that will crash. */ if (((u_short)ntohs(ip->ip_len) > m->m_pkthdr.len)) { m_freem(m); return (EINVAL); } break; + } +#endif #ifdef INET6 case AF_INET6: { @@ -446,11 +450,13 @@ div_output_outbound(int family, struct socket *so, struct mbuf *m) error = 0; switch (family) { +#ifdef INET case AF_INET: error = ip_output(m, NULL, NULL, ((so->so_options & SO_DONTROUTE) ? IP_ROUTETOIF : 0) | IP_ALLOWBROADCAST | IP_RAWOUTPUT, NULL, NULL); break; +#endif #ifdef INET6 case AF_INET6: error = ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL); @@ -472,7 +478,6 @@ static int div_output_inbound(int family, struct socket *so, struct mbuf *m, struct sockaddr_in *sin) { - const struct ip *ip; struct ifaddr *ifa; if (m->m_pkthdr.rcvif == NULL) { @@ -497,7 +502,11 @@ div_output_inbound(int family, struct socket *so, struct mbuf *m, #endif /* Send packet to input processing via netisr */ switch (family) { +#ifdef INET case AF_INET: + { + const struct ip *ip; + ip = mtod(m, struct ip *); /* * Restore M_BCAST flag when destination address is @@ -510,6 +519,8 @@ div_output_inbound(int family, struct socket *so, struct mbuf *m, netisr_queue_src(NETISR_IP, (uintptr_t)so, m); DIVSTAT_INC(inbound); break; + } +#endif #ifdef INET6 case AF_INET6: netisr_queue_src(NETISR_IPV6, (uintptr_t)so, m); From 1545dd7d6cc54bdfca9bc9f74c42745b514b60c9 Mon Sep 17 00:00:00 2001 From: Cy Schubert Date: Tue, 30 Aug 2022 15:29:34 -0700 Subject: [PATCH 006/106] sqlite3: Vendor import of sqlite3 3.39.2 Changes at https://www.sqlite.org/releaselog/3_39_2.html. Obtained from: https://www.sqlite.org/2022/sqlite-autoconf-3390200.tar.gz --- configure | 20 ++-- configure.ac | 2 +- shell.c | 4 +- sqlite3.c | 246 +++++++++++++++++++++++++++++------------------ sqlite3.h | 8 +- sqlite3rc.h | 2 +- tea/configure | 18 ++-- tea/configure.ac | 2 +- 8 files changed, 179 insertions(+), 123 deletions(-) diff --git a/configure b/configure index 6175ab3c3895..548b38c1ceef 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for sqlite 3.39.0. +# Generated by GNU Autoconf 2.71 for sqlite 3.39.2. # # Report bugs to . # @@ -621,8 +621,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='sqlite' PACKAGE_TARNAME='sqlite' -PACKAGE_VERSION='3.39.0' -PACKAGE_STRING='sqlite 3.39.0' +PACKAGE_VERSION='3.39.2' +PACKAGE_STRING='sqlite 3.39.2' PACKAGE_BUGREPORT='http://www.sqlite.org' PACKAGE_URL='' @@ -1367,7 +1367,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures sqlite 3.39.0 to adapt to many kinds of systems. +\`configure' configures sqlite 3.39.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1438,7 +1438,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sqlite 3.39.0:";; + short | recursive ) echo "Configuration of sqlite 3.39.2:";; esac cat <<\_ACEOF @@ -1563,7 +1563,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sqlite configure 3.39.0 +sqlite configure 3.39.2 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -1833,7 +1833,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by sqlite $as_me 3.39.0, which was +It was created by sqlite $as_me 3.39.2, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -3106,7 +3106,7 @@ fi # Define the identity of the package. PACKAGE='sqlite' - VERSION='3.39.0' + VERSION='3.39.2' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -15314,7 +15314,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by sqlite $as_me 3.39.0, which was +This file was extended by sqlite $as_me 3.39.2, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -15373,7 +15373,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -sqlite config.status 3.39.0 +sqlite config.status 3.39.2 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index fa097dc0130e..0110dc4a10a0 100644 --- a/configure.ac +++ b/configure.ac @@ -10,7 +10,7 @@ # AC_PREREQ(2.61) -AC_INIT(sqlite, 3.39.0, http://www.sqlite.org) +AC_INIT(sqlite, 3.39.2, http://www.sqlite.org) AC_CONFIG_SRCDIR([sqlite3.c]) AC_CONFIG_AUX_DIR([.]) diff --git a/shell.c b/shell.c index b0da4cc4e92c..e66ae0874f52 100644 --- a/shell.c +++ b/shell.c @@ -4409,7 +4409,7 @@ static const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){ pRe->zInit[j++] = (unsigned char)(0xc0 | (x>>6)); pRe->zInit[j++] = 0x80 | (x&0x3f); }else if( x<=0xffff ){ - pRe->zInit[j++] = (unsigned char)(0xd0 | (x>>12)); + pRe->zInit[j++] = (unsigned char)(0xe0 | (x>>12)); pRe->zInit[j++] = 0x80 | ((x>>6)&0x3f); pRe->zInit[j++] = 0x80 | (x&0x3f); }else{ @@ -23078,7 +23078,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ char **argv; #endif #ifdef SQLITE_DEBUG - sqlite3_uint64 mem_main_enter = sqlite3_memory_used(); + sqlite3_int64 mem_main_enter = sqlite3_memory_used(); #endif char *zErrMsg = 0; #ifdef SQLITE_SHELL_WASM_MODE diff --git a/sqlite3.c b/sqlite3.c index 6a7b52d90dc0..b8f98c7c1e7c 100644 --- a/sqlite3.c +++ b/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.39.0. By combining all the individual C code files into this +** version 3.39.2. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -452,9 +452,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.39.0" -#define SQLITE_VERSION_NUMBER 3039000 -#define SQLITE_SOURCE_ID "2022-06-25 14:57:57 14e166f40dbfa6e055543f8301525f2ca2e96a02a57269818b9e69e162e98918" +#define SQLITE_VERSION "3.39.2" +#define SQLITE_VERSION_NUMBER 3039002 +#define SQLITE_SOURCE_ID "2022-07-21 15:24:47 698edb77537b67c41adc68f9b892db56bcf9a55e00371a61420f3ddd668e6603" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -6588,7 +6588,7 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); ** ** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name ** for the N-th database on database connection D, or a NULL pointer of N is -** out of range. An N alue of 0 means the main database file. An N of 1 is +** out of range. An N value of 0 means the main database file. An N of 1 is ** the "temp" schema. Larger values of N correspond to various ATTACH-ed ** databases. ** @@ -19779,6 +19779,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView*, const SrcList*); SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8); SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8); SQLITE_PRIVATE void sqlite3TreeViewUpsert(TreeView*, const Upsert*, u8); +#if TREETRACE_ENABLED SQLITE_PRIVATE void sqlite3TreeViewDelete(const With*, const SrcList*, const Expr*, const ExprList*,const Expr*, const Trigger*); SQLITE_PRIVATE void sqlite3TreeViewInsert(const With*, const SrcList*, @@ -19787,6 +19788,7 @@ SQLITE_PRIVATE void sqlite3TreeViewInsert(const With*, const SrcList*, SQLITE_PRIVATE void sqlite3TreeViewUpdate(const With*, const SrcList*, const ExprList*, const Expr*, int, const ExprList*, const Expr*, const Upsert*, const Trigger*); +#endif #ifndef SQLITE_OMIT_TRIGGER SQLITE_PRIVATE void sqlite3TreeViewTriggerStep(TreeView*, const TriggerStep*, u8, u8); SQLITE_PRIVATE void sqlite3TreeViewTrigger(TreeView*, const Trigger*, u8, u8); @@ -30428,8 +30430,8 @@ SQLITE_API void sqlite3_str_vappendf( case etSQLESCAPE: /* %q: Escape ' characters */ case etSQLESCAPE2: /* %Q: Escape ' and enclose in '...' */ case etSQLESCAPE3: { /* %w: Escape " characters */ - int i, j, k, n, isnull; - int needQuote; + i64 i, j, k, n; + int needQuote, isnull; char ch; char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote character */ char *escarg; @@ -31117,8 +31119,8 @@ SQLITE_PRIVATE void sqlite3TreeViewColumnList( sqlite3TreeViewLine(pView, "COLUMNS"); for(i=0; ipTab; sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1); } - assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); + assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0); } if( pItem->fg.isTabFunc ){ @@ -32016,6 +32018,7 @@ SQLITE_PRIVATE void sqlite3TreeViewUpsert( sqlite3TreeViewPop(&pView); } +#if TREETRACE_ENABLED /* ** Generate a human-readable diagram of the data structure that go ** into generating an DELETE statement. @@ -32069,7 +32072,9 @@ SQLITE_PRIVATE void sqlite3TreeViewDelete( } sqlite3TreeViewPop(&pView); } +#endif /* TREETRACE_ENABLED */ +#if TREETRACE_ENABLED /* ** Generate a human-readable diagram of the data structure that go ** into generating an INSERT statement. @@ -32137,7 +32142,9 @@ SQLITE_PRIVATE void sqlite3TreeViewInsert( } sqlite3TreeViewPop(&pView); } +#endif /* TREETRACE_ENABLED */ +#if TREETRACE_ENABLED /* ** Generate a human-readable diagram of the data structure that go ** into generating an UPDATE statement. @@ -32213,6 +32220,7 @@ SQLITE_PRIVATE void sqlite3TreeViewUpdate( } sqlite3TreeViewPop(&pView); } +#endif /* TREETRACE_ENABLED */ #ifndef SQLITE_OMIT_TRIGGER /* @@ -101532,33 +101540,23 @@ static void resolveAlias( sqlite3ExprDelete(db, pDup); pDup = 0; }else{ + Expr temp; incrAggFunctionDepth(pDup, nSubquery); if( pExpr->op==TK_COLLATE ){ assert( !ExprHasProperty(pExpr, EP_IntValue) ); pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); } - - /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This - ** prevents ExprDelete() from deleting the Expr structure itself, - ** allowing it to be repopulated by the memcpy() on the following line. - ** The pExpr->u.zToken might point into memory that will be freed by the - ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to - ** make a copy of the token before doing the sqlite3DbFree(). - */ - ExprSetProperty(pExpr, EP_Static); - sqlite3ExprDelete(db, pExpr); - memcpy(pExpr, pDup, sizeof(*pExpr)); - if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){ - assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 ); - pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken); - pExpr->flags |= EP_MemToken; - } + memcpy(&temp, pDup, sizeof(Expr)); + memcpy(pDup, pExpr, sizeof(Expr)); + memcpy(pExpr, &temp, sizeof(Expr)); if( ExprHasProperty(pExpr, EP_WinFunc) ){ if( ALWAYS(pExpr->y.pWin!=0) ){ pExpr->y.pWin->pOwner = pExpr; } } - sqlite3DbFree(db, pDup); + sqlite3ParserAddCleanup(pParse, + (void(*)(sqlite3*,void*))sqlite3ExprDelete, + pDup); } } @@ -101761,7 +101759,7 @@ static int lookupName( pTab = pItem->pTab; assert( pTab!=0 && pTab->zName!=0 ); assert( pTab->nCol>0 || pParse->nErr ); - assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); + assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); if( pItem->fg.isNestedFrom ){ /* In this case, pItem is a subquery that has been formed from a ** parenthesized subset of the FROM clause terms. Example: @@ -115451,8 +115449,6 @@ SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ); db->mDbFlags |= DBFLAG_PreferBuiltin; sqlite3RunParser(pParse, zSql); - sqlite3DbFree(db, pParse->zErrMsg); - pParse->zErrMsg = 0; db->mDbFlags = savedDbFlags; sqlite3DbFree(db, zSql); memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ); @@ -135853,7 +135849,7 @@ SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol){ */ SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){ assert( pItem!=0 ); - assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); + assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); if( pItem->fg.isNestedFrom ){ ExprList *pResults; assert( pItem->pSelect!=0 ); @@ -139651,6 +139647,9 @@ static void renumberCursors( ** (17d2) DISTINCT ** (17e) the subquery may not contain window functions, and ** (17f) the subquery must not be the RHS of a LEFT JOIN. +** (17g) either the subquery is the first element of the outer +** query or there are no RIGHT or FULL JOINs in any arm +** of the subquery. (This is a duplicate of condition (27b).) ** ** The parent and sub-query may contain WHERE clauses. Subject to ** rules (11), (13) and (14), they may also contain ORDER BY, @@ -139702,7 +139701,11 @@ static void renumberCursors( ** See also (3) for restrictions on LEFT JOIN. ** ** (27) The subquery may not contain a FULL or RIGHT JOIN unless it -** is the first element of the parent query. +** is the first element of the parent query. This must be the +** the case if: +** (27a) the subquery is not compound query, and +** (27b) the subquery is a compound query and the RIGHT JOIN occurs +** in any arm of the compound query. (See also (17g).) ** ** (28) The subquery is not a MATERIALIZED CTE. ** @@ -139832,7 +139835,7 @@ static int flattenSubquery( assert( pSubSrc->nSrc>0 ); /* True by restriction (7) */ if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ - return 0; /* Restriction (27) */ + return 0; /* Restriction (27a) */ } if( pSubitem->fg.isCte && pSubitem->u2.pCteUse->eM10d==M10d_Yes ){ return 0; /* (28) */ @@ -139852,7 +139855,7 @@ static int flattenSubquery( ** NATURAL join or a join that as an ON or USING clause. ** ** These conditions are sufficient to keep an EP_OuterON from being - ** flattened into an EP_InnerON. Restrictions (3a) and (27) prevent + ** flattened into an EP_InnerON. Restrictions (3a) and (27a) prevent ** an EP_InnerON from being flattened into an EP_OuterON. */ if( pSubSrc->nSrc>=2 @@ -139894,6 +139897,12 @@ static int flattenSubquery( ){ return 0; } + if( iFrom>0 && (pSub1->pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ + /* Without this restriction, the JT_LTORJ flag would end up being + ** omitted on left-hand tables of the right join that is being + ** flattened. */ + return 0; /* Restrictions (17g), (27b) */ + } testcase( pSub1->pSrc->nSrc>1 ); } @@ -141427,7 +141436,7 @@ static int selectExpander(Walker *pWalker, Select *p){ zTabName = pTab->zName; } if( db->mallocFailed ) break; - assert( pFrom->fg.isNestedFrom == IsNestedFrom(pFrom->pSelect) ); + assert( (int)pFrom->fg.isNestedFrom == IsNestedFrom(pFrom->pSelect) ); if( pFrom->fg.isNestedFrom ){ assert( pFrom->pSelect!=0 ); pNestedFrom = pFrom->pSelect->pEList; @@ -142356,7 +142365,9 @@ SQLITE_PRIVATE int sqlite3Select( ){ SELECTTRACE(0x100,pParse,p, ("omit superfluous ORDER BY on %r FROM-clause subquery\n",i+1)); - sqlite3ExprListDelete(db, pSub->pOrderBy); + sqlite3ParserAddCleanup(pParse, + (void(*)(sqlite3*,void*))sqlite3ExprListDelete, + pSub->pOrderBy); pSub->pOrderBy = 0; } @@ -155356,7 +155367,7 @@ static int whereKeyStats( #endif assert( pRec!=0 ); assert( pIdx->nSample>0 ); - assert( pRec->nField>0 && pRec->nField<=pIdx->nSampleCol ); + assert( pRec->nField>0 ); /* Do a binary search to find the first sample greater than or equal ** to pRec. If pRec contains a single field, the set of samples to search @@ -155402,7 +155413,7 @@ static int whereKeyStats( ** it is extended to two fields. The duplicates that this creates do not ** cause any problems. */ - nField = pRec->nField; + nField = MIN(pRec->nField, pIdx->nSample); iCol = 0; iSample = pIdx->nSample * nField; do{ @@ -158091,6 +158102,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ sqlite3 *db = pWInfo->pParse->db; int rc = SQLITE_OK; int bFirstPastRJ = 0; + int hasRightJoin = 0; WhereLoop *pNew; @@ -158111,15 +158123,16 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ ** prevents the right operand of a RIGHT JOIN from being swapped with ** other elements even further to the right. ** - ** The JT_LTORJ term prevents any FROM-clause term reordering for terms - ** to the left of a RIGHT JOIN. This is conservative. Relaxing this - ** constraint somewhat to prevent terms from crossing from the right - ** side of a LEFT JOIN over to the left side when they are on the - ** left side of a RIGHT JOIN would be sufficient for all known failure - ** cases. FIX ME: Implement this optimization. + ** The JT_LTORJ case and the hasRightJoin flag work together to + ** prevent FROM-clause terms from moving from the right side of + ** a LEFT JOIN over to the left side of that join if the LEFT JOIN + ** is itself on the left side of a RIGHT JOIN. */ + if( pItem->fg.jointype & JT_LTORJ ) hasRightJoin = 1; mPrereq |= mPrior; bFirstPastRJ = (pItem->fg.jointype & JT_RIGHT)!=0; + }else if( !hasRightJoin ){ + mPrereq = 0; } #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pItem->pTab) ){ @@ -169960,6 +169973,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){ mxSqlLen -= n; if( mxSqlLen<0 ){ pParse->rc = SQLITE_TOOBIG; + pParse->nErr++; break; } #ifndef SQLITE_OMIT_WINDOWFUNC @@ -174700,8 +174714,11 @@ SQLITE_API int sqlite3_test_control(int op, ...){ sqlite3ShowTriggerStepList(0); sqlite3ShowTrigger(0); sqlite3ShowTriggerList(0); +#ifndef SQLITE_OMIT_WINDOWFUNC sqlite3ShowWindow(0); sqlite3ShowWinFunc(0); +#endif + sqlite3ShowSelect(0); } #endif break; @@ -181035,8 +181052,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ char *aPoslist = 0; /* Position list for deferred tokens */ int nPoslist = 0; /* Number of bytes in aPoslist */ int iPrev = -1; /* Token number of previous deferred token */ - - assert( pPhrase->doclist.bFreeList==0 ); + char *aFree = (pPhrase->doclist.bFreeList ? pPhrase->doclist.pList : 0); for(iToken=0; iTokennToken; iToken++){ Fts3PhraseToken *pToken = &pPhrase->aToken[iToken]; @@ -181050,6 +181066,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ if( pList==0 ){ sqlite3_free(aPoslist); + sqlite3_free(aFree); pPhrase->doclist.pList = 0; pPhrase->doclist.nList = 0; return SQLITE_OK; @@ -181070,6 +181087,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ nPoslist = (int)(aOut - aPoslist); if( nPoslist==0 ){ sqlite3_free(aPoslist); + sqlite3_free(aFree); pPhrase->doclist.pList = 0; pPhrase->doclist.nList = 0; return SQLITE_OK; @@ -181109,6 +181127,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ } pPhrase->doclist.pList = aOut; + assert( p1 && p2 ); if( fts3PoslistPhraseMerge(&aOut, nDistance, 0, 1, &p1, &p2) ){ pPhrase->doclist.bFreeList = 1; pPhrase->doclist.nList = (int)(aOut - pPhrase->doclist.pList); @@ -181121,6 +181140,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ } } + if( pPhrase->doclist.pList!=aFree ) sqlite3_free(aFree); return SQLITE_OK; } #endif /* SQLITE_DISABLE_FTS4_DEFERRED */ @@ -182295,11 +182315,10 @@ static int fts3EvalTestExpr( default: { #ifndef SQLITE_DISABLE_FTS4_DEFERRED - if( pCsr->pDeferred - && (pExpr->iDocid==pCsr->iPrevId || pExpr->bDeferred) - ){ + if( pCsr->pDeferred && (pExpr->bDeferred || ( + pExpr->iDocid==pCsr->iPrevId && pExpr->pPhrase->doclist.pList + ))){ Fts3Phrase *pPhrase = pExpr->pPhrase; - assert( pExpr->bDeferred || pPhrase->doclist.bFreeList==0 ); if( pExpr->bDeferred ){ fts3EvalInvalidatePoslist(pPhrase); } @@ -236617,7 +236636,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2022-06-25 14:57:57 14e166f40dbfa6e055543f8301525f2ca2e96a02a57269818b9e69e162e98918", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2022-07-21 15:24:47 698edb77537b67c41adc68f9b892db56bcf9a55e00371a61420f3ddd668e6603", -1, SQLITE_TRANSIENT); } /* @@ -241288,6 +241307,16 @@ SQLITE_EXTENSION_INIT1 #ifndef SQLITE_OMIT_VIRTUALTABLE + +#define STMT_NUM_INTEGER_COLUMN 10 +typedef struct StmtRow StmtRow; +struct StmtRow { + sqlite3_int64 iRowid; /* Rowid value */ + char *zSql; /* column "sql" */ + int aCol[STMT_NUM_INTEGER_COLUMN+1]; /* all other column values */ + StmtRow *pNext; /* Next row to return */ +}; + /* stmt_vtab is a subclass of sqlite3_vtab which will ** serve as the underlying representation of a stmt virtual table */ @@ -241305,8 +241334,7 @@ typedef struct stmt_cursor stmt_cursor; struct stmt_cursor { sqlite3_vtab_cursor base; /* Base class - must be first */ sqlite3 *db; /* Database connection for this cursor */ - sqlite3_stmt *pStmt; /* Statement cursor is currently pointing at */ - sqlite3_int64 iRowid; /* The rowid */ + StmtRow *pRow; /* Current row */ }; /* @@ -241350,7 +241378,7 @@ static int stmtConnect( "CREATE TABLE x(sql,ncol,ro,busy,nscan,nsort,naidx,nstep," "reprep,run,mem)"); if( rc==SQLITE_OK ){ - pNew = sqlite3_malloc( sizeof(*pNew) ); + pNew = sqlite3_malloc64( sizeof(*pNew) ); *ppVtab = (sqlite3_vtab*)pNew; if( pNew==0 ) return SQLITE_NOMEM; memset(pNew, 0, sizeof(*pNew)); @@ -241372,7 +241400,7 @@ static int stmtDisconnect(sqlite3_vtab *pVtab){ */ static int stmtOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ stmt_cursor *pCur; - pCur = sqlite3_malloc( sizeof(*pCur) ); + pCur = sqlite3_malloc64( sizeof(*pCur) ); if( pCur==0 ) return SQLITE_NOMEM; memset(pCur, 0, sizeof(*pCur)); pCur->db = ((stmt_vtab*)p)->db; @@ -241380,10 +241408,21 @@ static int stmtOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ return SQLITE_OK; } +static void stmtCsrReset(stmt_cursor *pCur){ + StmtRow *pRow = 0; + StmtRow *pNext = 0; + for(pRow=pCur->pRow; pRow; pRow=pNext){ + pNext = pRow->pNext; + sqlite3_free(pRow); + } + pCur->pRow = 0; +} + /* ** Destructor for a stmt_cursor. */ static int stmtClose(sqlite3_vtab_cursor *cur){ + stmtCsrReset((stmt_cursor*)cur); sqlite3_free(cur); return SQLITE_OK; } @@ -241394,8 +241433,9 @@ static int stmtClose(sqlite3_vtab_cursor *cur){ */ static int stmtNext(sqlite3_vtab_cursor *cur){ stmt_cursor *pCur = (stmt_cursor*)cur; - pCur->iRowid++; - pCur->pStmt = sqlite3_next_stmt(pCur->db, pCur->pStmt); + StmtRow *pNext = pCur->pRow->pNext; + sqlite3_free(pCur->pRow); + pCur->pRow = pNext; return SQLITE_OK; } @@ -241409,39 +241449,11 @@ static int stmtColumn( int i /* Which column to return */ ){ stmt_cursor *pCur = (stmt_cursor*)cur; - switch( i ){ - case STMT_COLUMN_SQL: { - sqlite3_result_text(ctx, sqlite3_sql(pCur->pStmt), -1, SQLITE_TRANSIENT); - break; - } - case STMT_COLUMN_NCOL: { - sqlite3_result_int(ctx, sqlite3_column_count(pCur->pStmt)); - break; - } - case STMT_COLUMN_RO: { - sqlite3_result_int(ctx, sqlite3_stmt_readonly(pCur->pStmt)); - break; - } - case STMT_COLUMN_BUSY: { - sqlite3_result_int(ctx, sqlite3_stmt_busy(pCur->pStmt)); - break; - } - default: { - assert( i==STMT_COLUMN_MEM ); - i = SQLITE_STMTSTATUS_MEMUSED + - STMT_COLUMN_NSCAN - SQLITE_STMTSTATUS_FULLSCAN_STEP; - /* Fall thru */ - } - case STMT_COLUMN_NSCAN: - case STMT_COLUMN_NSORT: - case STMT_COLUMN_NAIDX: - case STMT_COLUMN_NSTEP: - case STMT_COLUMN_REPREP: - case STMT_COLUMN_RUN: { - sqlite3_result_int(ctx, sqlite3_stmt_status(pCur->pStmt, - i-STMT_COLUMN_NSCAN+SQLITE_STMTSTATUS_FULLSCAN_STEP, 0)); - break; - } + StmtRow *pRow = pCur->pRow; + if( i==STMT_COLUMN_SQL ){ + sqlite3_result_text(ctx, pRow->zSql, -1, SQLITE_TRANSIENT); + }else{ + sqlite3_result_int(ctx, pRow->aCol[i]); } return SQLITE_OK; } @@ -241452,7 +241464,7 @@ static int stmtColumn( */ static int stmtRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ stmt_cursor *pCur = (stmt_cursor*)cur; - *pRowid = pCur->iRowid; + *pRowid = pCur->pRow->iRowid; return SQLITE_OK; } @@ -241462,7 +241474,7 @@ static int stmtRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ */ static int stmtEof(sqlite3_vtab_cursor *cur){ stmt_cursor *pCur = (stmt_cursor*)cur; - return pCur->pStmt==0; + return pCur->pRow==0; } /* @@ -241477,9 +241489,53 @@ static int stmtFilter( int argc, sqlite3_value **argv ){ stmt_cursor *pCur = (stmt_cursor *)pVtabCursor; - pCur->pStmt = 0; - pCur->iRowid = 0; - return stmtNext(pVtabCursor); + sqlite3_stmt *p = 0; + sqlite3_int64 iRowid = 1; + StmtRow **ppRow = 0; + + stmtCsrReset(pCur); + ppRow = &pCur->pRow; + for(p=sqlite3_next_stmt(pCur->db, 0); p; p=sqlite3_next_stmt(pCur->db, p)){ + const char *zSql = sqlite3_sql(p); + sqlite3_int64 nSql = zSql ? strlen(zSql)+1 : 0; + StmtRow *pNew = (StmtRow*)sqlite3_malloc64(sizeof(StmtRow) + nSql); + + if( pNew==0 ) return SQLITE_NOMEM; + memset(pNew, 0, sizeof(StmtRow)); + if( zSql ){ + pNew->zSql = (char*)&pNew[1]; + memcpy(pNew->zSql, zSql, nSql); + } + pNew->aCol[STMT_COLUMN_NCOL] = sqlite3_column_count(p); + pNew->aCol[STMT_COLUMN_RO] = sqlite3_stmt_readonly(p); + pNew->aCol[STMT_COLUMN_BUSY] = sqlite3_stmt_busy(p); + pNew->aCol[STMT_COLUMN_NSCAN] = sqlite3_stmt_status( + p, SQLITE_STMTSTATUS_FULLSCAN_STEP, 0 + ); + pNew->aCol[STMT_COLUMN_NSORT] = sqlite3_stmt_status( + p, SQLITE_STMTSTATUS_SORT, 0 + ); + pNew->aCol[STMT_COLUMN_NAIDX] = sqlite3_stmt_status( + p, SQLITE_STMTSTATUS_AUTOINDEX, 0 + ); + pNew->aCol[STMT_COLUMN_NSTEP] = sqlite3_stmt_status( + p, SQLITE_STMTSTATUS_VM_STEP, 0 + ); + pNew->aCol[STMT_COLUMN_REPREP] = sqlite3_stmt_status( + p, SQLITE_STMTSTATUS_REPREPARE, 0 + ); + pNew->aCol[STMT_COLUMN_RUN] = sqlite3_stmt_status( + p, SQLITE_STMTSTATUS_RUN, 0 + ); + pNew->aCol[STMT_COLUMN_MEM] = sqlite3_stmt_status( + p, SQLITE_STMTSTATUS_MEMUSED, 0 + ); + pNew->iRowid = iRowid++; + *ppRow = pNew; + ppRow = &pNew->pNext; + } + + return SQLITE_OK; } /* diff --git a/sqlite3.h b/sqlite3.h index 26b4a31fd228..f0df724d7b8d 100644 --- a/sqlite3.h +++ b/sqlite3.h @@ -146,9 +146,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.39.0" -#define SQLITE_VERSION_NUMBER 3039000 -#define SQLITE_SOURCE_ID "2022-06-25 14:57:57 14e166f40dbfa6e055543f8301525f2ca2e96a02a57269818b9e69e162e98918" +#define SQLITE_VERSION "3.39.2" +#define SQLITE_VERSION_NUMBER 3039002 +#define SQLITE_SOURCE_ID "2022-07-21 15:24:47 698edb77537b67c41adc68f9b892db56bcf9a55e00371a61420f3ddd668e6603" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -6282,7 +6282,7 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); ** ** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name ** for the N-th database on database connection D, or a NULL pointer of N is -** out of range. An N alue of 0 means the main database file. An N of 1 is +** out of range. An N value of 0 means the main database file. An N of 1 is ** the "temp" schema. Larger values of N correspond to various ATTACH-ed ** databases. ** diff --git a/sqlite3rc.h b/sqlite3rc.h index eb934d43da5f..d2ab9a5f45a6 100644 --- a/sqlite3rc.h +++ b/sqlite3rc.h @@ -1,3 +1,3 @@ #ifndef SQLITE_RESOURCE_VERSION -#define SQLITE_RESOURCE_VERSION 3,39,0 +#define SQLITE_RESOURCE_VERSION 3,39,2 #endif diff --git a/tea/configure b/tea/configure index d73782a9caf9..4aeb32bd060f 100755 --- a/tea/configure +++ b/tea/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for sqlite 3.39.0. +# Generated by GNU Autoconf 2.71 for sqlite 3.39.2. # # # Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, @@ -608,8 +608,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='sqlite' PACKAGE_TARNAME='sqlite' -PACKAGE_VERSION='3.39.0' -PACKAGE_STRING='sqlite 3.39.0' +PACKAGE_VERSION='3.39.2' +PACKAGE_STRING='sqlite 3.39.2' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1328,7 +1328,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures sqlite 3.39.0 to adapt to many kinds of systems. +\`configure' configures sqlite 3.39.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1390,7 +1390,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sqlite 3.39.0:";; + short | recursive ) echo "Configuration of sqlite 3.39.2:";; esac cat <<\_ACEOF @@ -1493,7 +1493,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sqlite configure 3.39.0 +sqlite configure 3.39.2 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -1844,7 +1844,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by sqlite $as_me 3.39.0, which was +It was created by sqlite $as_me 3.39.2, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -10181,7 +10181,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by sqlite $as_me 3.39.0, which was +This file was extended by sqlite $as_me 3.39.2, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -10236,7 +10236,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -sqlite config.status 3.39.0 +sqlite config.status 3.39.2 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/tea/configure.ac b/tea/configure.ac index 50555afe73a8..03519f357c72 100644 --- a/tea/configure.ac +++ b/tea/configure.ac @@ -19,7 +19,7 @@ dnl to configure the system for the local environment. # so you can encode the package version directly into the source files. #----------------------------------------------------------------------- -AC_INIT([sqlite], [3.39.0]) +AC_INIT([sqlite], [3.39.2]) #-------------------------------------------------------------------- # Call TEA_INIT as the first TEA_ macro to set up initial vars. From 1df08e905a0b093bd05ac93761bacabc92171629 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Tue, 30 Aug 2022 16:21:19 -0700 Subject: [PATCH 007/106] natd: use PF_DIVERT/SOCK_RAW instead of PF_INET/SOCK_RAW/IPPROTO_DIVERT --- sbin/natd/natd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sbin/natd/natd.c b/sbin/natd/natd.c index 402c430dfdfd..599a5247ac85 100644 --- a/sbin/natd/natd.c +++ b/sbin/natd/natd.c @@ -226,7 +226,7 @@ int main (int argc, char** argv) */ if (mip->inOutPort) { - mip->divertInOut = socket (PF_INET, SOCK_RAW, IPPROTO_DIVERT); + mip->divertInOut = socket(PF_DIVERT, SOCK_RAW, 0); if (mip->divertInOut == -1) Quit ("Unable to create divert socket."); if (mip->divertInOut > fdMax) @@ -249,14 +249,14 @@ int main (int argc, char** argv) } else { - mip->divertIn = socket (PF_INET, SOCK_RAW, IPPROTO_DIVERT); + mip->divertIn = socket(PF_DIVERT, SOCK_RAW, 0); if (mip->divertIn == -1) Quit ("Unable to create incoming divert socket."); if (mip->divertIn > fdMax) fdMax = mip->divertIn; - mip->divertOut = socket (PF_INET, SOCK_RAW, IPPROTO_DIVERT); + mip->divertOut = socket(PF_DIVERT, SOCK_RAW, 0); if (mip->divertOut == -1) Quit ("Unable to create outgoing divert socket."); if (mip->divertOut > fdMax) @@ -317,7 +317,7 @@ int main (int argc, char** argv) } if (globalPort) { - divertGlobal = socket (PF_INET, SOCK_RAW, IPPROTO_DIVERT); + divertGlobal = socket(PF_DIVERT, SOCK_RAW, 0); if (divertGlobal == -1) Quit ("Unable to create divert socket."); if (divertGlobal > fdMax) From f70a2e2948540f0fdf6afa332b8bf5197eff4255 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Tue, 30 Aug 2022 16:22:50 -0700 Subject: [PATCH 008/106] ipfwpcap: use PF_DIVERT/SOCK_RAW instead of PF_INET/SOCK_RAW/IPPROTO_DIVERT --- usr.sbin/ipfwpcap/ipfwpcap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/ipfwpcap/ipfwpcap.c b/usr.sbin/ipfwpcap/ipfwpcap.c index 96ee47e836a6..22a83220855f 100644 --- a/usr.sbin/ipfwpcap/ipfwpcap.c +++ b/usr.sbin/ipfwpcap/ipfwpcap.c @@ -202,7 +202,7 @@ main(int ac, char *av[]) if (debug) fprintf(stderr, "bind to %d.\ndump to '%s'.\n", portnum, dumpf); - if ((r = socket(PF_INET, SOCK_RAW, IPPROTO_DIVERT)) == -1) { + if ((r = socket(PF_DIVERT, SOCK_RAW, 0)) == -1) { perror("socket(DIVERT)"); exit(2); } From 4627bc1e90fd17c8d4f44de6b932d456b67661fc Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Tue, 30 Aug 2022 16:23:36 -0700 Subject: [PATCH 009/106] tests: use PF_DIVERT/SOCK_RAW instead of PF_INET/SOCK_RAW/IPPROTO_DIVERT --- tests/sys/common/divert.py | 8 ++++---- tools/regression/netinet/ipdivert/ipdivert.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/sys/common/divert.py b/tests/sys/common/divert.py index 94e20a03571f..44b1f49ae13f 100755 --- a/tests/sys/common/divert.py +++ b/tests/sys/common/divert.py @@ -36,7 +36,7 @@ import argparse -IPPROTO_DIVERT = 258 +PF_DIVERT = 44 def parse_args(): @@ -52,14 +52,14 @@ def parse_args(): def ipdivert_ip_output_remote_success(args): packet = sc.IP(dst=args.dip) / sc.ICMP(type='echo-request') - with socket.socket(socket.AF_INET, socket.SOCK_RAW, IPPROTO_DIVERT) as s: + with socket.socket(PF_DIVERT, socket.SOCK_RAW, 0) as s: s.bind(('0.0.0.0', args.divert_port)) s.sendto(bytes(packet), ('0.0.0.0', 0)) def ipdivert_ip6_output_remote_success(args): packet = sc.IPv6(dst=args.dip) / sc.ICMPv6EchoRequest() - with socket.socket(socket.AF_INET, socket.SOCK_RAW, IPPROTO_DIVERT) as s: + with socket.socket(PF_DIVERT, socket.SOCK_RAW, 0) as s: s.bind(('0.0.0.0', args.divert_port)) s.sendto(bytes(packet), ('0.0.0.0', 0)) @@ -67,7 +67,7 @@ def ipdivert_ip6_output_remote_success(args): def ipdivert_ip_input_local_success(args): """Sends IPv4 packet to OS stack as inbound local packet.""" packet = sc.IP(dst=args.dip,src=args.sip) / sc.ICMP(type='echo-request') - with socket.socket(socket.AF_INET, socket.SOCK_RAW, IPPROTO_DIVERT) as s: + with socket.socket(PF_DIVERT, socket.SOCK_RAW, 0) as s: s.bind(('0.0.0.0', args.divert_port)) s.sendto(bytes(packet), (args.dip, 0)) diff --git a/tools/regression/netinet/ipdivert/ipdivert.c b/tools/regression/netinet/ipdivert/ipdivert.c index 0d5849159a9a..37babd68f5f3 100644 --- a/tools/regression/netinet/ipdivert/ipdivert.c +++ b/tools/regression/netinet/ipdivert/ipdivert.c @@ -76,7 +76,7 @@ ipdivert_create(const char *test) { int s; - s = socket(PF_INET, SOCK_RAW, IPPROTO_DIVERT); + s = socket(PF_DIVERT, SOCK_RAW, 0); if (s < 0) fail(test, "socket"); return (s); From 1f3d8c09be67f9b01f60b3e6434780c193228567 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Tue, 30 Aug 2022 16:26:21 -0700 Subject: [PATCH 010/106] procstat: fix printing divert(4) sockets --- usr.bin/procstat/procstat.1 | 12 ++++++++---- usr.bin/procstat/procstat_files.c | 5 +++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/usr.bin/procstat/procstat.1 b/usr.bin/procstat/procstat.1 index 65299c7f07e9..b24ac3957f8f 100644 --- a/usr.bin/procstat/procstat.1 +++ b/usr.bin/procstat/procstat.1 @@ -414,10 +414,6 @@ The following network protocols may be displayed (grouped by address family): .Dv IPPROTO_ICMP ; see .Xr icmp 4 . -.It IPD -.Dv IPPROTO_DIVERT ; -see -.Xr divert 4 . .It IP? unknown protocol. .It RAW @@ -453,6 +449,14 @@ see unknown protocol. .El .Pp +.Dv AF_DIVERT +.Pp +.Bl -tag -width indent -compact +.It IPD +.Dv Divert socket; see +.Xr divert 4 . +.El +.Pp .Bl -tag -width indent -compact .It ? unknown address family. diff --git a/usr.bin/procstat/procstat_files.c b/usr.bin/procstat/procstat_files.c index 1d7b419b3f4a..c7306b6a2a1d 100644 --- a/usr.bin/procstat/procstat_files.c +++ b/usr.bin/procstat/procstat_files.c @@ -68,8 +68,6 @@ protocol_to_string(int domain, int type, int protocol) return ("RAW"); case IPPROTO_SCTP: return ("SCT"); - case IPPROTO_DIVERT: - return ("IPD"); default: return ("IP?"); } @@ -83,6 +81,9 @@ protocol_to_string(int domain, int type, int protocol) default: return ("UD?"); } + case AF_DIVERT: + return ("IPD"); + break; default: return ("?"); } From 24af7808fa1293f34beb6b7de38894326feeb74f Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Tue, 30 Aug 2022 21:19:46 -0700 Subject: [PATCH 011/106] protosw: repair protocol selection logic in socket(2) Pointy hat to: glebius Fixes: 61f7427f02a307d28af674a12c45dd546e3898e4 --- sys/kern/uipc_domain.c | 6 ++++-- sys/kern/uipc_socket.c | 4 +--- sys/sys/protosw.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c index 832afca510fa..f1b2c616c662 100644 --- a/sys/kern/uipc_domain.c +++ b/sys/kern/uipc_domain.c @@ -290,7 +290,7 @@ pffinddomain(int family) } struct protosw * -pffindtype(int family, int type) +pffindproto(int family, int type, int proto) { struct domain *dp; struct protosw *pr; @@ -300,7 +300,9 @@ pffindtype(int family, int type) return (NULL); for (int i = 0; i < dp->dom_nprotosw; i++) - if ((pr = dp->dom_protosw[i]) != NULL && pr->pr_type == type) + if ((pr = dp->dom_protosw[i]) != NULL && pr->pr_type == type && + (pr->pr_protocol == 0 || proto == 0 || + pr->pr_protocol == proto)) return (pr); return (NULL); diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index a93256cd7f63..360b7b56cee5 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -520,7 +520,7 @@ socreate(int dom, struct socket **aso, int type, int proto, td->td_proc->p_comm); } - prp = pffindtype(dom, type); + prp = pffindproto(dom, type, proto); if (prp == NULL) { /* No support for domain. */ if (pffinddomain(dom) == NULL) @@ -530,8 +530,6 @@ socreate(int dom, struct socket **aso, int type, int proto, return (EPROTOTYPE); return (EPROTONOSUPPORT); } - if (prp->pr_protocol != 0 && proto != 0 && prp->pr_protocol != proto) - return (EPROTONOSUPPORT); MPASS(prp->pr_attach); diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h index f05aff962420..3b89c6f78caf 100644 --- a/sys/sys/protosw.h +++ b/sys/sys/protosw.h @@ -236,7 +236,7 @@ char *prcorequests[] = { #ifdef _KERNEL struct domain *pffinddomain(int family); -struct protosw *pffindtype(int family, int type); +struct protosw *pffindproto(int family, int type, int proto); int protosw_register(struct domain *, struct protosw *); int protosw_unregister(struct protosw *); From 0a9a4d2cd60920d9f8c2dffb06b6b4186a5a2715 Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Mon, 29 Aug 2022 11:50:52 +0200 Subject: [PATCH 012/106] arm64: Fix hwpmc module for OPT_ACPI isn't selected Fixes: 59191f3573f6 ("Add support of ARM CMN-600 controller ...") Sponsored by: Beckhoff Automation GmbH & Co. KG --- sys/dev/hwpmc/hwpmc_arm64.c | 6 ++++++ sys/modules/hwpmc/Makefile | 2 ++ 2 files changed, 8 insertions(+) diff --git a/sys/dev/hwpmc/hwpmc_arm64.c b/sys/dev/hwpmc/hwpmc_arm64.c index ca346f2ac4df..ec796bcc8ff5 100644 --- a/sys/dev/hwpmc/hwpmc_arm64.c +++ b/sys/dev/hwpmc/hwpmc_arm64.c @@ -38,6 +38,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include "opt_acpi.h" + static int arm64_npmcs; struct arm64_event_code_map { @@ -564,11 +566,13 @@ pmc_arm64_initialize(void) /* One AArch64 CPU class */ classes = 1; +#ifdef DEV_ACPI /* Query presence of optional classes and set max class. */ if (pmc_cmn600_nclasses() > 0) classes = MAX(classes, PMC_MDEP_CLASS_INDEX_CMN600); if (pmc_dmc620_nclasses() > 0) classes = MAX(classes, PMC_MDEP_CLASS_INDEX_DMC620_C); +#endif pmc_mdep = pmc_mdep_alloc(classes); @@ -619,12 +623,14 @@ pmc_arm64_initialize(void) pmc_mdep->pmd_npmc += arm64_npmcs; +#ifdef DEV_ACPI if (pmc_cmn600_nclasses() > 0) pmc_cmn600_initialize(pmc_mdep); if (pmc_dmc620_nclasses() > 0) { pmc_dmc620_initialize_cd2(pmc_mdep); pmc_dmc620_initialize_c(pmc_mdep); } +#endif return (pmc_mdep); } diff --git a/sys/modules/hwpmc/Makefile b/sys/modules/hwpmc/Makefile index 0db4c55e64f3..a72b3cf8d2fd 100644 --- a/sys/modules/hwpmc/Makefile +++ b/sys/modules/hwpmc/Makefile @@ -12,9 +12,11 @@ SRCS+= vnode_if.h .if ${MACHINE_CPUARCH} == "aarch64" SRCS+= hwpmc_arm64.c hwpmc_arm64_md.c +.if !empty(OPT_ACPI) SRCS+= cmn600.c hwpmc_cmn600.c SRCS+= hwpmc_dmc620.c pmu_dmc620.c .endif +.endif .if ${MACHINE_CPUARCH} == "amd64" SRCS+= hwpmc_amd.c hwpmc_core.c hwpmc_intel.c hwpmc_tsc.c From 998b0a4ad84252180ab7b06b281f923ce1d0747b Mon Sep 17 00:00:00 2001 From: Peter Wemm Date: Wed, 31 Aug 2022 01:54:04 -0700 Subject: [PATCH 013/106] OptionalObsoleteFiles.inc: Add missing sendmail feature macro files. MFC after: 3 days --- tools/build/mk/OptionalObsoleteFiles.inc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index 9a5726ab0f4d..2ca65d27e16c 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -7805,12 +7805,14 @@ OLD_FILES+=usr/share/sendmail/cf/feature/access_db.m4 OLD_FILES+=usr/share/sendmail/cf/feature/allmasquerade.m4 OLD_FILES+=usr/share/sendmail/cf/feature/always_add_domain.m4 OLD_FILES+=usr/share/sendmail/cf/feature/authinfo.m4 +OLD_FILES+=usr/share/sendmail/cf/feature/blocklist_recipients.m4 OLD_FILES+=usr/share/sendmail/cf/feature/badmx.m4 OLD_FILES+=usr/share/sendmail/cf/feature/bcc.m4 OLD_FILES+=usr/share/sendmail/cf/feature/bestmx_is_local.m4 OLD_FILES+=usr/share/sendmail/cf/feature/bitdomain.m4 OLD_FILES+=usr/share/sendmail/cf/feature/blacklist_recipients.m4 OLD_FILES+=usr/share/sendmail/cf/feature/block_bad_helo.m4 +OLD_FILES+=usr/share/sendmail/cf/feature/check_cert_altnames.m4 OLD_FILES+=usr/share/sendmail/cf/feature/compat_check.m4 OLD_FILES+=usr/share/sendmail/cf/feature/conncontrol.m4 OLD_FILES+=usr/share/sendmail/cf/feature/delay_checks.m4 @@ -7853,6 +7855,7 @@ OLD_FILES+=usr/share/sendmail/cf/feature/relay_mail_from.m4 OLD_FILES+=usr/share/sendmail/cf/feature/require_rdns.m4 OLD_FILES+=usr/share/sendmail/cf/feature/smrsh.m4 OLD_FILES+=usr/share/sendmail/cf/feature/stickyhost.m4 +OLD_FILES+=usr/share/sendmail/cf/feature/tls_failures.m4 OLD_FILES+=usr/share/sendmail/cf/feature/tls_session_features.m4 OLD_FILES+=usr/share/sendmail/cf/feature/use_client_ptr.m4 OLD_FILES+=usr/share/sendmail/cf/feature/use_ct_file.m4 From 544f047f894046a68c373f55ddd072e91bcfbf38 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Thu, 25 Aug 2022 08:28:28 +0000 Subject: [PATCH 014/106] Store mpidr as a 64-bit value on arm64 The mpidr register is 64 bit on arm64 and 32 bit on arm. Fix this by extending the arm64 definition to include the top 32 bits. To preserve KBI when MFCing split the value into two 32 bit values. This will be cleaned up later only on main. Reviewed by: bz Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D36346 --- sys/arm/arm/pmu_acpi.c | 2 +- sys/arm/arm/pmu_fdt.c | 2 +- sys/arm/include/pcpu.h | 2 ++ sys/arm64/arm64/machdep.c | 3 ++- sys/arm64/arm64/mp_machdep.c | 17 +++++++++++------ sys/arm64/include/pcpu.h | 9 +++++++-- 6 files changed, 24 insertions(+), 11 deletions(-) diff --git a/sys/arm/arm/pmu_acpi.c b/sys/arm/arm/pmu_acpi.c index 2e031338f144..8812ac7b3af4 100644 --- a/sys/arm/arm/pmu_acpi.c +++ b/sys/arm/arm/pmu_acpi.c @@ -72,7 +72,7 @@ madt_handler(ACPI_SUBTABLE_HEADER *entry, void *arg) for (i = 0; i < MAXCPU; i++) { pcpu = pcpu_find(i); - if (pcpu != NULL && pcpu->pc_mpidr == intr->ArmMpidr) { + if (pcpu != NULL && PCPU_GET_MPIDR(pcpu) == intr->ArmMpidr) { cpuid = i; break; } diff --git a/sys/arm/arm/pmu_fdt.c b/sys/arm/arm/pmu_fdt.c index 0b435375aa22..fef15e106a33 100644 --- a/sys/arm/arm/pmu_fdt.c +++ b/sys/arm/arm/pmu_fdt.c @@ -105,7 +105,7 @@ pmu_parse_affinity(device_t dev, struct pmu_softc *sc, struct pmu_intr *irq, for (i = 0; i < MAXCPU; i++) { pcpu = pcpu_find(i); - if (pcpu != NULL && pcpu->pc_mpidr == mpidr) { + if (pcpu != NULL && PCPU_GET_MPIDR(pcpu) == mpidr) { irq->cpuid = i; return (0); } diff --git a/sys/arm/include/pcpu.h b/sys/arm/include/pcpu.h index 2353b1d06b17..ced701516c70 100644 --- a/sys/arm/include/pcpu.h +++ b/sys/arm/include/pcpu.h @@ -139,6 +139,8 @@ set_tls(void *tls) #define PCPU_PTR(member) (&get_pcpu()->pc_ ## member) #define PCPU_SET(member,value) (get_pcpu()->pc_ ## member = (value)) +#define PCPU_GET_MPIDR(pc) ((pc)->pc_mpidr) + void pcpu0_init(void); #endif /* _KERNEL */ diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c index 5ce5d279e8e0..c47e16e6b2b6 100644 --- a/sys/arm64/arm64/machdep.c +++ b/sys/arm64/arm64/machdep.c @@ -300,7 +300,8 @@ cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size) { pcpu->pc_acpi_id = 0xffffffff; - pcpu->pc_mpidr = 0xffffffff; + pcpu->pc_mpidr_low = 0xffffffff; + pcpu->pc_mpidr_high = 0xffffffff; } void diff --git a/sys/arm64/arm64/mp_machdep.c b/sys/arm64/arm64/mp_machdep.c index a6e2be300bae..d1fbb4c079d2 100644 --- a/sys/arm64/arm64/mp_machdep.c +++ b/sys/arm64/arm64/mp_machdep.c @@ -153,7 +153,7 @@ static bool is_boot_cpu(uint64_t target_cpu) { - return (cpuid_to_pcpu[0]->pc_mpidr == (target_cpu & CPU_AFF_MASK)); + return (PCPU_GET_MPIDR(cpuid_to_pcpu[0]) == (target_cpu & CPU_AFF_MASK)); } static void @@ -207,7 +207,7 @@ init_secondary(uint64_t cpu) { struct pcpu *pcpup; pmap_t pmap0; - u_int mpidr; + uint64_t mpidr; ptrauth_mp_start(cpu); @@ -218,10 +218,10 @@ init_secondary(uint64_t cpu) */ mpidr = READ_SPECIALREG(mpidr_el1) & CPU_AFF_MASK; if (cpu >= MAXCPU || cpuid_to_pcpu[cpu] == NULL || - cpuid_to_pcpu[cpu]->pc_mpidr != mpidr) { + PCPU_GET_MPIDR(cpuid_to_pcpu[cpu]) != mpidr) { for (cpu = 0; cpu < mp_maxid; cpu++) if (cpuid_to_pcpu[cpu] != NULL && - cpuid_to_pcpu[cpu]->pc_mpidr == mpidr) + PCPU_GET_MPIDR(cpuid_to_pcpu[cpu]) == mpidr) break; if ( cpu >= MAXCPU) panic("MPIDR for this CPU is not in pcpu table"); @@ -517,7 +517,8 @@ start_cpu(u_int cpuid, uint64_t target_cpu, int domain) pcpup = (struct pcpu *)pcpu_mem; pcpu_init(pcpup, cpuid, sizeof(struct pcpu)); - pcpup->pc_mpidr = target_cpu & CPU_AFF_MASK; + pcpup->pc_mpidr_low = target_cpu & CPU_AFF_MASK; + pcpup->pc_mpidr_high = (target_cpu & CPU_AFF_MASK) >> 32; dpcpu[cpuid - 1] = (void *)(pcpup + 1); dpcpu_init(dpcpu[cpuid - 1], cpuid); @@ -688,11 +689,15 @@ cpu_init_fdt(void) void cpu_mp_start(void) { + uint64_t mpidr; + mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN); /* CPU 0 is always boot CPU. */ CPU_SET(0, &all_cpus); - cpuid_to_pcpu[0]->pc_mpidr = READ_SPECIALREG(mpidr_el1) & CPU_AFF_MASK; + mpidr = READ_SPECIALREG(mpidr_el1) & CPU_AFF_MASK; + cpuid_to_pcpu[0]->pc_mpidr_low = mpidr; + cpuid_to_pcpu[0]->pc_mpidr_high = mpidr >> 32; switch(arm64_bus_method) { #ifdef DEV_ACPI diff --git a/sys/arm64/include/pcpu.h b/sys/arm64/include/pcpu.h index b93f3b2e4816..8d60b4ef6356 100644 --- a/sys/arm64/include/pcpu.h +++ b/sys/arm64/include/pcpu.h @@ -48,8 +48,10 @@ struct debug_monitor_state; struct pmap *pc_curpmap; \ struct pmap *pc_curvmpmap; \ u_int pc_bcast_tlbi_workaround; \ - u_int pc_mpidr; /* stored MPIDR value */ \ - char __pad[201] + /* Store as two u_int values to preserve KBI */ \ + u_int pc_mpidr_low; /* lower MPIDR 32 bits */ \ + u_int pc_mpidr_high; /* upper MPIDR 32 bits */ \ + char __pad[197] #ifdef _KERNEL @@ -83,6 +85,9 @@ get_curthread(void) #define PCPU_PTR(member) (&pcpup->pc_ ## member) #define PCPU_SET(member,value) (pcpup->pc_ ## member = (value)) +#define PCPU_GET_MPIDR(pc) \ + ((((uint64_t)((pc)->pc_mpidr_high)) << 32) | ((pc)->pc_mpidr_low)) + #endif /* _KERNEL */ #endif /* !_MACHINE_PCPU_H_ */ From c21b7b55bea2cc2bf3b420c70a9018e703ed6f00 Mon Sep 17 00:00:00 2001 From: Richard Scheffenegger Date: Wed, 31 Aug 2022 14:49:25 +0200 Subject: [PATCH 015/106] tcp: finish SACK loss recovery on sudden lack of SACK blocks While a receiver should continue sending SACK blocks for the duration of a SACK loss recovery, if for some reason the TCP options no longer contain these SACK blocks, but we already started maintaining the Scoreboard, keep on handling incoming ACKs (without SACK) as belonging to the SACK recovery. Reported by: thj Reviewed by: tuexen, #transport MFC after: 2 weeks Sponsored by: NetApp, Inc. Differential Revision: https://reviews.freebsd.org/D36046 --- sys/netinet/tcp_input.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index bf963840cd23..e8f2676f2aa8 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -268,6 +268,20 @@ kmod_tcpstat_add(int statnum, int val) counter_u64_add(VNET(tcpstat)[statnum], val); } +/* + * Make sure that we only start a SACK loss recovery when + * receiving a duplicate ACK with a SACK block, and also + * complete SACK loss recovery in case the other end + * reneges. + */ +static bool inline +tcp_is_sack_recovery(struct tcpcb *tp, struct tcpopt *to) +{ + return ((tp->t_flags & TF_SACK_PERMIT) && + ((to->to_flags & TOF_SACK) || + (!TAILQ_EMPTY(&tp->snd_holes)))); +} + #ifdef TCP_HHOOK /* * Wrapper for the TCP established input helper hook. @@ -2491,9 +2505,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, TCPSTAT_INC(tcps_rcvacktoomuch); goto dropafterack; } - if ((tp->t_flags & TF_SACK_PERMIT) && - ((to.to_flags & TOF_SACK) || - !TAILQ_EMPTY(&tp->snd_holes))) { + if (tcp_is_sack_recovery(tp, &to)) { if (((sack_changed = tcp_sack_doack(tp, &to, th->th_ack)) != 0) && (tp->t_flags & TF_LRD)) { tcp_sack_lost_retransmission(tp, th); @@ -2566,8 +2578,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, * duplicating packets or a possible DoS attack. */ if (th->th_ack != tp->snd_una || - ((tp->t_flags & TF_SACK_PERMIT) && - (to.to_flags & TOF_SACK) && + (tcp_is_sack_recovery(tp, &to) && !sack_changed)) break; else if (!tcp_timer_active(tp, TT_REXMT)) @@ -2579,8 +2590,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, if (V_tcp_do_prr && IN_FASTRECOVERY(tp->t_flags)) { tcp_do_prr_ack(tp, th, &to); - } else if ((tp->t_flags & TF_SACK_PERMIT) && - (to.to_flags & TOF_SACK) && + } else if (tcp_is_sack_recovery(tp, &to) && IN_FASTRECOVERY(tp->t_flags)) { int awnd; @@ -2653,8 +2663,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, * snd_ssthresh is already updated by * cc_cong_signal. */ - if ((tp->t_flags & TF_SACK_PERMIT) && - (to.to_flags & TOF_SACK)) { + if (tcp_is_sack_recovery(tp, &to)) { tp->sackhint.prr_delivered = tp->sackhint.sacked_bytes; } else { @@ -2666,8 +2675,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, tp->sackhint.recover_fs = max(1, tp->snd_nxt - tp->snd_una); } - if ((tp->t_flags & TF_SACK_PERMIT) && - (to.to_flags & TOF_SACK)) { + if (tcp_is_sack_recovery(tp, &to)) { TCPSTAT_INC( tcps_sack_recovery_episode); tp->snd_recover = tp->snd_nxt; @@ -2759,8 +2767,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, * from the left side. Such partial ACKs should not be * counted as dupacks here. */ - if ((tp->t_flags & TF_SACK_PERMIT) && - (to.to_flags & TOF_SACK) && + if (tcp_is_sack_recovery(tp, &to) && sack_changed) { tp->t_dupacks++; /* limit overhead by setting maxseg last */ @@ -3942,8 +3949,7 @@ tcp_do_prr_ack(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to) * (del_data) and an estimate of how many bytes are in the * network. */ - if (((tp->t_flags & TF_SACK_PERMIT) && - (to->to_flags & TOF_SACK)) || + if (tcp_is_sack_recovery(tp, to) || (IN_CONGRECOVERY(tp->t_flags) && !IN_FASTRECOVERY(tp->t_flags))) { del_data = tp->sackhint.delivered_data; @@ -3987,8 +3993,7 @@ tcp_do_prr_ack(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to) * accordingly. */ if (IN_FASTRECOVERY(tp->t_flags)) { - if ((tp->t_flags & TF_SACK_PERMIT) && - (to->to_flags & TOF_SACK)) { + if (tcp_is_sack_recovery(tp, to)) { tp->snd_cwnd = tp->snd_nxt - tp->snd_recover + tp->sackhint.sack_bytes_rexmit + (snd_cnt * maxseg); From 4012ef7754cf29ce27d6fd728437830dea9915fd Mon Sep 17 00:00:00 2001 From: Richard Scheffenegger Date: Wed, 31 Aug 2022 15:01:25 +0200 Subject: [PATCH 016/106] tcp: Functional implementation of Accurate ECN The AccECN handshake and TCP header flags are supported, no support yet for the AccECN option. This minimalistic implementation is sufficient to support DCTCP while dramatically cutting the number of ACKs, and provide ECN response from the receiver to the CC modules. Reviewed By: #transport, #manpages, rrs, pauamma Sponsored by: NetApp, Inc. Differential Revision: https://reviews.freebsd.org/D21011 --- share/man/man4/tcp.4 | 7 + sys/netinet/tcp_ecn.c | 326 +++++++++++++++++++++++++++++++--- sys/netinet/tcp_ecn.h | 1 + sys/netinet/tcp_output.c | 2 +- sys/netinet/tcp_stacks/rack.c | 8 +- sys/netinet/tcp_var.h | 4 +- 6 files changed, 316 insertions(+), 32 deletions(-) diff --git a/share/man/man4/tcp.4 b/share/man/man4/tcp.4 index cdb58c7cbacc..753184418b1f 100644 --- a/share/man/man4/tcp.4 +++ b/share/man/man4/tcp.4 @@ -495,6 +495,13 @@ Outgoing connections will request ECN. Allow incoming connections to request ECN. Outgoing connections will not request ECN. (default) +.It 3 +Negotiate on incoming connection for Accurate ECN, ECN, or no ECN. +Outgoing connections will request Accurate ECN and fall back to +ECN depending on the capabilities of the server. +.It 4 +Negotiate on incoming connection for Accurate ECN, ECN, or no ECN. +Outgoing connections will not request ECN. .El .It Va ecn.maxretries Number of retries (SYN or SYN/ACK retransmits) before disabling ECN on a diff --git a/sys/netinet/tcp_ecn.c b/sys/netinet/tcp_ecn.c index 20f84a0c9d98..05591c2de2f7 100644 --- a/sys/netinet/tcp_ecn.c +++ b/sys/netinet/tcp_ecn.c @@ -109,12 +109,91 @@ __FBSDID("$FreeBSD$"); void tcp_ecn_input_syn_sent(struct tcpcb *tp, uint16_t thflags, int iptos) { - thflags &= (TH_CWR|TH_ECE); - if (((thflags & (TH_CWR | TH_ECE)) == TH_ECE) && - V_tcp_do_ecn) { - tp->t_flags2 |= TF2_ECN_PERMIT; - TCPSTAT_INC(tcps_ecn_shs); + if (V_tcp_do_ecn == 0) + return; + if ((V_tcp_do_ecn == 1) || + (V_tcp_do_ecn == 2)) { + /* RFC3168 ECN handling */ + if ((thflags & (TH_CWR | TH_ECE)) == (0 | TH_ECE)) { + tp->t_flags2 |= TF2_ECN_PERMIT; + TCPSTAT_INC(tcps_ecn_shs); + } + } else + /* decoding Accurate ECN according to table in section 3.1.1 */ + if ((V_tcp_do_ecn == 3) || + (V_tcp_do_ecn == 4)) { + /* + * on the SYN,ACK, process the AccECN + * flags indicating the state the SYN + * was delivered. + * Reactions to Path ECN mangling can + * come here. + */ + switch (thflags & (TH_AE | TH_CWR | TH_ECE)) { + /* RFC3168 SYN */ + case (0|0|TH_ECE): + tp->t_flags2 |= TF2_ECN_PERMIT; + TCPSTAT_INC(tcps_ecn_shs); + break; + /* non-ECT SYN */ + case (0|TH_CWR|0): + tp->t_flags2 |= TF2_ACE_PERMIT; + tp->t_scep = 5; + TCPSTAT_INC(tcps_ecn_shs); + TCPSTAT_INC(tcps_ace_nect); + break; + /* ECT0 SYN */ + case (TH_AE|0|0): + tp->t_flags2 |= TF2_ACE_PERMIT; + tp->t_scep = 5; + TCPSTAT_INC(tcps_ecn_shs); + TCPSTAT_INC(tcps_ace_ect0); + break; + /* ECT1 SYN */ + case (0|TH_CWR|TH_ECE): + tp->t_flags2 |= TF2_ACE_PERMIT; + tp->t_scep = 5; + TCPSTAT_INC(tcps_ecn_shs); + TCPSTAT_INC(tcps_ace_ect1); + break; + /* CE SYN */ + case (TH_AE|TH_CWR|0): + tp->t_flags2 |= TF2_ACE_PERMIT; + tp->t_scep = 6; + /* + * reduce the IW to 2 MSS (to + * account for delayed acks) if + * the SYN,ACK was CE marked + */ + tp->snd_cwnd = 2 * tcp_maxseg(tp); + TCPSTAT_INC(tcps_ecn_shs); + TCPSTAT_INC(tcps_ace_nect); + break; + default: + break; + } + /* + * Set the AccECN Codepoints on + * the outgoing to the ECN + * state of the + * according to table 3 in the + * AccECN draft + */ + switch (iptos & IPTOS_ECN_MASK) { + case (IPTOS_ECN_NOTECT): + tp->t_rcep = 0b010; + break; + case (IPTOS_ECN_ECT0): + tp->t_rcep = 0b100; + break; + case (IPTOS_ECN_ECT1): + tp->t_rcep = 0b011; + break; + case (IPTOS_ECN_CE): + tp->t_rcep = 0b110; + break; + } } } @@ -128,13 +207,53 @@ tcp_ecn_input_parallel_syn(struct tcpcb *tp, uint16_t thflags, int iptos) return; if (V_tcp_do_ecn == 0) return; - if ((V_tcp_do_ecn == 1) || (V_tcp_do_ecn == 2)) { + if ((V_tcp_do_ecn == 1) || + (V_tcp_do_ecn == 2)) { /* RFC3168 ECN handling */ if ((thflags & (TH_CWR | TH_ECE)) == (TH_CWR | TH_ECE)) { tp->t_flags2 |= TF2_ECN_PERMIT; tp->t_flags2 |= TF2_ECN_SND_ECE; TCPSTAT_INC(tcps_ecn_shs); } + } else + if ((V_tcp_do_ecn == 3) || + (V_tcp_do_ecn == 4)) { + /* AccECN handling */ + switch (thflags & (TH_AE | TH_CWR | TH_ECE)) { + default: + case (0|0|0): + break; + case (0|TH_CWR|TH_ECE): + tp->t_flags2 |= TF2_ECN_PERMIT; + tp->t_flags2 |= TF2_ECN_SND_ECE; + TCPSTAT_INC(tcps_ecn_shs); + break; + case (TH_AE|TH_CWR|TH_ECE): + tp->t_flags2 |= TF2_ACE_PERMIT; + TCPSTAT_INC(tcps_ecn_shs); + /* + * Set the AccECN Codepoints on + * the outgoing to the ECN + * state of the + * according to table 3 in the + * AccECN draft + */ + switch (iptos & IPTOS_ECN_MASK) { + case (IPTOS_ECN_NOTECT): + tp->t_rcep = 0b010; + break; + case (IPTOS_ECN_ECT0): + tp->t_rcep = 0b100; + break; + case (IPTOS_ECN_ECT1): + tp->t_rcep = 0b011; + break; + case (IPTOS_ECN_CE): + tp->t_rcep = 0b110; + break; + } + break; + } } } @@ -146,7 +265,7 @@ tcp_ecn_input_segment(struct tcpcb *tp, uint16_t thflags, int iptos) { int delta_ace = 0; - if (tp->t_flags2 & TF2_ECN_PERMIT) { + if (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT)) { switch (iptos & IPTOS_ECN_MASK) { case IPTOS_ECN_CE: TCPSTAT_INC(tcps_ecn_ce); @@ -159,15 +278,52 @@ tcp_ecn_input_segment(struct tcpcb *tp, uint16_t thflags, int iptos) break; } - /* RFC3168 ECN handling */ - if (thflags & TH_ECE) - delta_ace = 1; - if (thflags & TH_CWR) { - tp->t_flags2 &= ~TF2_ECN_SND_ECE; - tp->t_flags |= TF_ACKNOW; + if (tp->t_flags2 & TF2_ACE_PERMIT) { + if ((iptos & IPTOS_ECN_MASK) == IPTOS_ECN_CE) + tp->t_rcep += 1; + if (tp->t_flags2 & TF2_ECN_PERMIT) { + delta_ace = (tcp_ecn_get_ace(thflags) + 8 - + (tp->t_scep & 0x07)) & 0x07; + tp->t_scep += delta_ace; + } else { + /* + * process the final ACK of the 3WHS + * see table 3 in draft-ietf-tcpm-accurate-ecn + */ + switch (tcp_ecn_get_ace(thflags)) { + case 0b010: + /* nonECT SYN or SYN,ACK */ + /* Fallthrough */ + case 0b011: + /* ECT1 SYN or SYN,ACK */ + /* Fallthrough */ + case 0b100: + /* ECT0 SYN or SYN,ACK */ + tp->t_scep = 5; + break; + case 0b110: + /* CE SYN or SYN,ACK */ + tp->t_scep = 6; + tp->snd_cwnd = 2 * tcp_maxseg(tp); + break; + default: + /* mangled AccECN handshake */ + tp->t_scep = 5; + break; + } + tp->t_flags2 |= TF2_ECN_PERMIT; + } + } else { + /* RFC3168 ECN handling */ + if (thflags & TH_ECE) + delta_ace = 1; + if (thflags & TH_CWR) { + tp->t_flags2 &= ~TF2_ECN_SND_ECE; + tp->t_flags |= TF_ACKNOW; + } + if ((iptos & IPTOS_ECN_MASK) == IPTOS_ECN_CE) + tp->t_flags2 |= TF2_ECN_SND_ECE; } - if ((iptos & IPTOS_ECN_MASK) == IPTOS_ECN_CE) - tp->t_flags2 |= TF2_ECN_SND_ECE; /* Process a packet differently from RFC3168. */ cc_ecnpkt_handler_flags(tp, thflags, iptos); @@ -184,6 +340,8 @@ tcp_ecn_output_syn_sent(struct tcpcb *tp) { uint16_t thflags = 0; + if (V_tcp_do_ecn == 0) + return thflags; if (V_tcp_do_ecn == 1) { /* Send a RFC3168 ECN setup packet */ if (tp->t_rxtshift >= 1) { @@ -191,6 +349,14 @@ tcp_ecn_output_syn_sent(struct tcpcb *tp) thflags = TH_ECE|TH_CWR; } else thflags = TH_ECE|TH_CWR; + } else + if (V_tcp_do_ecn == 3) { + /* Send an Accurate ECN setup packet */ + if (tp->t_rxtshift >= 1) { + if (tp->t_rxtshift <= V_tcp_ecn_maxretries) + thflags = TH_ECE|TH_CWR|TH_AE; + } else + thflags = TH_ECE|TH_CWR|TH_AE; } return thflags; @@ -215,6 +381,7 @@ tcp_ecn_output_established(struct tcpcb *tp, uint16_t *thflags, int len, bool rx newdata = (len > 0 && SEQ_GEQ(tp->snd_nxt, tp->snd_max) && !rxmit && !((tp->t_flags & TF_FORCEDATA) && len == 1)); + /* RFC3168 ECN marking, only new data segments */ if (newdata) { ipecn = IPTOS_ECN_ECT0; TCPSTAT_INC(tcps_ecn_ect0); @@ -222,13 +389,35 @@ tcp_ecn_output_established(struct tcpcb *tp, uint16_t *thflags, int len, bool rx /* * Reply with proper ECN notifications. */ - if (newdata && - (tp->t_flags2 & TF2_ECN_SND_CWR)) { - *thflags |= TH_CWR; - tp->t_flags2 &= ~TF2_ECN_SND_CWR; + if (tp->t_flags2 & TF2_ACE_PERMIT) { + *thflags &= ~(TH_AE|TH_CWR|TH_ECE); + if (tp->t_rcep & 0x01) + *thflags |= TH_ECE; + if (tp->t_rcep & 0x02) + *thflags |= TH_CWR; + if (tp->t_rcep & 0x04) + *thflags |= TH_AE; + if (!(tp->t_flags2 & TF2_ECN_PERMIT)) { + /* + * here we process the final + * ACK of the 3WHS + */ + if (tp->t_rcep == 0b110) { + tp->t_rcep = 6; + } else { + tp->t_rcep = 5; + } + tp->t_flags2 |= TF2_ECN_PERMIT; + } + } else { + if (newdata && + (tp->t_flags2 & TF2_ECN_SND_CWR)) { + *thflags |= TH_CWR; + tp->t_flags2 &= ~TF2_ECN_SND_CWR; + } + if (tp->t_flags2 & TF2_ECN_SND_ECE) + *thflags |= TH_ECE; } - if (tp->t_flags2 & TF2_ECN_SND_ECE) - *thflags |= TH_ECE; return ipecn; } @@ -245,6 +434,20 @@ tcp_ecn_syncache_socket(struct tcpcb *tp, struct syncache *sc) case SCF_ECN: tp->t_flags2 |= TF2_ECN_PERMIT; break; + case SCF_ACE_N: + /* Fallthrough */ + case SCF_ACE_0: + /* Fallthrough */ + case SCF_ACE_1: + tp->t_flags2 |= TF2_ACE_PERMIT; + tp->t_scep = 5; + tp->t_rcep = 5; + break; + case SCF_ACE_CE: + tp->t_flags2 |= TF2_ACE_PERMIT; + tp->t_scep = 6; + tp->t_rcep = 6; + break; /* undefined SCF codepoint */ default: break; @@ -261,15 +464,54 @@ tcp_ecn_syncache_add(uint16_t thflags, int iptos) { int scflags = 0; - switch (thflags & (TH_CWR|TH_ECE)) { + switch (thflags & (TH_AE|TH_CWR|TH_ECE)) { /* no ECN */ - case (0|0): + case (0|0|0): break; /* legacy ECN */ - case (TH_CWR|TH_ECE): + case (0|TH_CWR|TH_ECE): scflags = SCF_ECN; break; + /* Accurate ECN */ + case (TH_AE|TH_CWR|TH_ECE): + if ((V_tcp_do_ecn == 3) || + (V_tcp_do_ecn == 4)) { + switch (iptos & IPTOS_ECN_MASK) { + case IPTOS_ECN_CE: + scflags = SCF_ACE_CE; + break; + case IPTOS_ECN_ECT0: + scflags = SCF_ACE_0; + break; + case IPTOS_ECN_ECT1: + scflags = SCF_ACE_1; + break; + case IPTOS_ECN_NOTECT: + scflags = SCF_ACE_N; + break; + } + } else + scflags = SCF_ECN; + break; + /* Default Case (section 3.1.2) */ default: + if ((V_tcp_do_ecn == 3) || + (V_tcp_do_ecn == 4)) { + switch (iptos & IPTOS_ECN_MASK) { + case IPTOS_ECN_CE: + scflags = SCF_ACE_CE; + break; + case IPTOS_ECN_ECT0: + scflags = SCF_ACE_0; + break; + case IPTOS_ECN_ECT1: + scflags = SCF_ACE_1; + break; + case IPTOS_ECN_NOTECT: + scflags = SCF_ACE_N; + break; + } + } break; } return scflags; @@ -286,8 +528,28 @@ tcp_ecn_syncache_respond(uint16_t thflags, struct syncache *sc) (sc->sc_flags & SCF_ECN_MASK)) { switch (sc->sc_flags & SCF_ECN_MASK) { case SCF_ECN: - thflags |= (0 | TH_ECE); + thflags |= (0 | 0 | TH_ECE); + TCPSTAT_INC(tcps_ecn_shs); + break; + case SCF_ACE_N: + thflags |= (0 | TH_CWR | 0); + TCPSTAT_INC(tcps_ecn_shs); + TCPSTAT_INC(tcps_ace_nect); + break; + case SCF_ACE_0: + thflags |= (TH_AE | 0 | 0); + TCPSTAT_INC(tcps_ecn_shs); + TCPSTAT_INC(tcps_ace_ect0); + break; + case SCF_ACE_1: + thflags |= (0 | TH_ECE | TH_CWR); TCPSTAT_INC(tcps_ecn_shs); + TCPSTAT_INC(tcps_ace_ect1); + break; + case SCF_ACE_CE: + thflags |= (TH_AE | TH_CWR | 0); + TCPSTAT_INC(tcps_ecn_shs); + TCPSTAT_INC(tcps_ace_ce); break; /* undefined SCF codepoint */ default: @@ -296,3 +558,17 @@ tcp_ecn_syncache_respond(uint16_t thflags, struct syncache *sc) } return thflags; } + +int +tcp_ecn_get_ace(uint16_t thflags) +{ + int ace = 0; + + if (thflags & TH_ECE) + ace += 1; + if (thflags & TH_CWR) + ace += 2; + if (thflags & TH_AE) + ace += 4; + return ace; +} diff --git a/sys/netinet/tcp_ecn.h b/sys/netinet/tcp_ecn.h index 38ac2f398e54..deade12b75d1 100644 --- a/sys/netinet/tcp_ecn.h +++ b/sys/netinet/tcp_ecn.h @@ -49,6 +49,7 @@ int tcp_ecn_output_established(struct tcpcb *, uint16_t *, int, bool); void tcp_ecn_syncache_socket(struct tcpcb *, struct syncache *); int tcp_ecn_syncache_add(uint16_t, int); uint16_t tcp_ecn_syncache_respond(uint16_t, struct syncache *); +int tcp_ecn_get_ace(uint16_t); #endif /* _KERNEL */ diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c index 4aa2f3664c55..0630e288c20f 100644 --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -1209,7 +1209,7 @@ tcp_default_output(struct tcpcb *tp) } /* Also handle parallel SYN for ECN */ if ((TCPS_HAVERCVDSYN(tp->t_state)) && - (tp->t_flags2 & TF2_ECN_PERMIT)) { + (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT))) { int ect = tcp_ecn_output_established(tp, &flags, len, sack_rxmit); if ((tp->t_state == TCPS_SYN_RECEIVED) && (tp->t_flags2 & TF2_ECN_SND_ECE)) diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c index ea370fe9247c..47bcd3b76d90 100644 --- a/sys/netinet/tcp_stacks/rack.c +++ b/sys/netinet/tcp_stacks/rack.c @@ -15883,7 +15883,7 @@ rack_fast_rsm_output(struct tcpcb *tp, struct tcp_rack *rack, struct rack_sendma } m->m_pkthdr.rcvif = (struct ifnet *)0; if (TCPS_HAVERCVDSYN(tp->t_state) && - (tp->t_flags2 & TF2_ECN_PERMIT)) { + (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT))) { int ect = tcp_ecn_output_established(tp, &flags, len, true); if ((tp->t_state == TCPS_SYN_RECEIVED) && (tp->t_flags2 & TF2_ECN_SND_ECE)) @@ -16362,7 +16362,7 @@ rack_fast_output(struct tcpcb *tp, struct tcp_rack *rack, uint64_t ts_val, } m->m_pkthdr.rcvif = (struct ifnet *)0; if (TCPS_HAVERCVDSYN(tp->t_state) && - (tp->t_flags2 & TF2_ECN_PERMIT)) { + (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT))) { int ect = tcp_ecn_output_established(tp, &flags, len, false); if ((tp->t_state == TCPS_SYN_RECEIVED) && (tp->t_flags2 & TF2_ECN_SND_ECE)) @@ -18487,7 +18487,7 @@ rack_output(struct tcpcb *tp) } /* Also handle parallel SYN for ECN */ if (TCPS_HAVERCVDSYN(tp->t_state) && - (tp->t_flags2 & TF2_ECN_PERMIT)) { + (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT))) { int ect = tcp_ecn_output_established(tp, &flags, len, sack_rxmit); if ((tp->t_state == TCPS_SYN_RECEIVED) && (tp->t_flags2 & TF2_ECN_SND_ECE)) @@ -20489,7 +20489,7 @@ rack_fill_info(struct tcpcb *tp, struct tcp_info *ti) ti->tcpi_snd_wscale = tp->snd_scale; ti->tcpi_rcv_wscale = tp->rcv_scale; } - if (tp->t_flags2 & TF2_ECN_PERMIT) + if (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT)) ti->tcpi_options |= TCPI_OPT_ECN; if (tp->t_flags & TF_FASTOPEN) ti->tcpi_options |= TCPI_OPT_TFO; diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index d80bbef1c51d..20bf72dcd9d0 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -249,8 +249,8 @@ struct tcpcb { int t_dupacks; /* consecutive dup acks recd */ int t_lognum; /* Number of log entries */ int t_loglimit; /* Maximum number of log entries */ - uint32_t r_cep; /* Number of received CE marked packets */ - uint32_t s_cep; /* Synced number of delivered CE packets */ + uint32_t t_rcep; /* Number of received CE marked packets */ + uint32_t t_scep; /* Synced number of delivered CE packets */ int64_t t_pacing_rate; /* bytes / sec, -1 => unlimited */ struct tcp_log_stailq t_logs; /* Log buffer */ struct tcp_log_id_node *t_lin; From 26a36948331bd08d9afaddfc0da724eacdb953dd Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Wed, 31 Aug 2022 23:01:36 +0000 Subject: [PATCH 017/106] iwlwifi: move an ieee80211_get_tid() call Introduce a local change. It seems ieee80211_get_tid() does not deal with non-dataqos packets unlike net80211's ieee80211_gettid(). Gernally all calls in Linux drivers to ieee80211_get_tid() seem to be proceeded by an ieee80211_is_data_qos() check. Moving the ieee80211_get_tid() has no difference in the result, but (a) saves us the call if we do not need it due to an earlier return, and (b) allows us to put an assert into the LinuxKPI ieee80211_get_tid() implementation to avoid accidentally returning random frame header data in case of a missing earlier ieee80211_is_data_qos() check in (future/ other) drivers. Sponsored by: The FreeBSD Foundation MFC after: 3 days --- sys/contrib/dev/iwlwifi/mvm/rxmq.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sys/contrib/dev/iwlwifi/mvm/rxmq.c b/sys/contrib/dev/iwlwifi/mvm/rxmq.c index 1e8a5611b9f2..7325e9d44273 100644 --- a/sys/contrib/dev/iwlwifi/mvm/rxmq.c +++ b/sys/contrib/dev/iwlwifi/mvm/rxmq.c @@ -963,7 +963,11 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm, bool amsdu = desc->mac_flags2 & IWL_RX_MPDU_MFLG2_AMSDU; bool last_subframe = desc->amsdu_info & IWL_RX_MPDU_AMSDU_LAST_SUBFRAME; +#if defined(__linux__) u8 tid = ieee80211_get_tid(hdr); +#elif defined(__FreeBSD__) + u8 tid; +#endif u8 sub_frame_idx = desc->amsdu_info & IWL_RX_MPDU_AMSDU_SUBFRAME_IDX_MASK; struct iwl_mvm_reorder_buf_entry *entries; @@ -1008,6 +1012,9 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm, return false; } +#if defined(__FreeBSD__) + tid = ieee80211_get_tid(hdr); +#endif if (WARN(tid != baid_data->tid || mvm_sta->sta_id != baid_data->sta_id, "baid 0x%x is mapped to sta:%d tid:%d, but was received for sta:%d tid:%d\n", baid, baid_data->sta_id, baid_data->tid, mvm_sta->sta_id, From f46bea05fea3faf0780a9e0fb4dbeb588e32a6ea Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Wed, 31 Aug 2022 16:19:22 -0700 Subject: [PATCH 018/106] mount_nfs.8: Reword sentence so .Pa macro works Commit 603677334a64 added a sentence with a file path in it. However, it did not use .Pa since it would leave a space after it, where ('s) was supposed to go. This patch rewords the sentence so that .Pa can be used. This is a content change. Suggested by: mkarels --- sbin/mount_nfs/mount_nfs.8 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sbin/mount_nfs/mount_nfs.8 b/sbin/mount_nfs/mount_nfs.8 index d2a22bebec39..393a40caccb3 100644 --- a/sbin/mount_nfs/mount_nfs.8 +++ b/sbin/mount_nfs/mount_nfs.8 @@ -28,7 +28,7 @@ .\" @(#)mount_nfs.8 8.3 (Berkeley) 3/29/95 .\" $FreeBSD$ .\" -.Dd August 29, 2022 +.Dd August 31, 2022 .Dt MOUNT_NFS 8 .Os .Sh NAME @@ -242,7 +242,9 @@ supported by the NFS Version 4 server will be used. See the .Cm minorversion option. -Make sure that all your NFS Version 4 clients have unique /etc/hostid's. +Make sure that all your NFS Version 4 clients have unique +values in +.Pa /etc/hostid . .It Cm minorversion Ns = Ns Aq Ar value Use the specified minor version for a NFS Version 4 mount, overriding the default. From 48551d3240a052f7c0e2ebf9b0e97327f4a85048 Mon Sep 17 00:00:00 2001 From: Ganbold Tsagaankhuu Date: Thu, 1 Sep 2022 07:21:56 +0000 Subject: [PATCH 019/106] Fix problem getting gpio version during attach. Both RK3328 and RK3399 don't have GPIO_VER_ID register. Set gpio version depending on compat string of the parent. --- sys/arm64/rockchip/rk_gpio.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/sys/arm64/rockchip/rk_gpio.c b/sys/arm64/rockchip/rk_gpio.c index c3b1044df2f7..0b4012707363 100644 --- a/sys/arm64/rockchip/rk_gpio.c +++ b/sys/arm64/rockchip/rk_gpio.c @@ -259,12 +259,13 @@ static int rk_gpio_attach(device_t dev) { struct rk_gpio_softc *sc; - phandle_t node; + phandle_t parent_node, node; int err, i; sc = device_get_softc(dev); sc->sc_dev = dev; sc->pinctrl = device_get_parent(dev); + parent_node = ofw_bus_get_node(sc->pinctrl); node = ofw_bus_get_node(sc->sc_dev); if (!OF_hasprop(node, "gpio-controller")) @@ -303,9 +304,15 @@ rk_gpio_attach(device_t dev) return (ENXIO); } - RK_GPIO_LOCK(sc); - sc->version = rk_gpio_read_4(sc, RK_GPIO_VERSION); - RK_GPIO_UNLOCK(sc); + /* + * RK3568 has GPIO_VER_ID register, however both + * RK3328 and RK3399 doesn't have. So choose the + * version based on parent's compat string. + */ + if (ofw_bus_node_is_compatible(parent_node, "rockchip,rk3568-pinctrl")) + sc->version = RK_GPIO_TYPE_V2; + else + sc->version = RK_GPIO_TYPE_V1; switch (sc->version) { case RK_GPIO_TYPE_V1: From 53b80f4d41b62baa7a6cfefa33704bc7aae36889 Mon Sep 17 00:00:00 2001 From: Ganbold Tsagaankhuu Date: Thu, 1 Sep 2022 07:31:08 +0000 Subject: [PATCH 020/106] Add support for TCS4525 pmic. Reviewed by: manu Differential Revision: https://reviews.freebsd.org/D36209 --- sys/dev/iicbus/pmic/fan53555.c | 49 +++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/sys/dev/iicbus/pmic/fan53555.c b/sys/dev/iicbus/pmic/fan53555.c index 3d40aae9e415..c4929eee07e5 100644 --- a/sys/dev/iicbus/pmic/fan53555.c +++ b/sys/dev/iicbus/pmic/fan53555.c @@ -61,6 +61,9 @@ __FBSDID("$FreeBSD$"); #define FAN53555_ID2_DIE_REV(x) (((x) >> 4) & 0x0F) #define FAN53555_MON 0x05 +#define TCS4525_VSEL0 0x11 +#define TCS4525_VSEL1 0x10 +#define TCS4525_CHIP_ID_12 12 #if 0 #define dprintf(sc, format, arg...) \ @@ -73,12 +76,14 @@ enum fan53555_pmic_type { FAN53555 = 1, SYR827, SYR828, + TCS4525, }; static struct ofw_compat_data compat_data[] = { {"fcs,fan53555", FAN53555}, {"silergy,syr827", SYR827}, {"silergy,syr828", SYR828}, + {"tcs,tcs4525", TCS4525}, {NULL, 0} }; @@ -110,6 +115,8 @@ static struct regulator_range fan_1_range = static struct regulator_range fan_4_range = REG_RANGE_INIT( 0, 0x3F, 603000, 12826); +static struct regulator_range tcs_12_range = + REG_RANGE_INIT( 0, 0x3F, 800000, 6250); static int fan53555_read(device_t dev, uint8_t reg, uint8_t *val) @@ -308,6 +315,15 @@ fan53555_get_range(struct fan53555_softc *sc, int type, uint8_t id, } } + if (type == TCS4525) { + switch (id) { + case TCS4525_CHIP_ID_12: + return (&tcs_12_range); + default: + return (NULL); + } + } + return (NULL); } @@ -411,6 +427,9 @@ fan53555_probe(device_t dev) case SYR828: device_set_desc(dev, "SYR828 PMIC"); break; + case TCS4525: + device_set_desc(dev, "TCS4525 PMIC"); + break; default: return (ENXIO); } @@ -434,12 +453,30 @@ fan53555_attach(device_t dev) sizeof(susp_sel)); if (rv <= 0) susp_sel = 1; - if (susp_sel == 1) { - sc->live_reg = FAN53555_VSEL0; - sc->sleep_reg = FAN53555_VSEL1; - } else { - sc->live_reg = FAN53555_VSEL1; - sc->sleep_reg = FAN53555_VSEL0; + + switch (type) { + case FAN53555: + case SYR827: + case SYR828: + if (susp_sel == 1) { + sc->live_reg = FAN53555_VSEL0; + sc->sleep_reg = FAN53555_VSEL1; + } else { + sc->live_reg = FAN53555_VSEL1; + sc->sleep_reg = FAN53555_VSEL0; + } + break; + case TCS4525: + if (susp_sel == 1) { + sc->live_reg = TCS4525_VSEL0; + sc->sleep_reg = TCS4525_VSEL1; + } else { + sc->live_reg = TCS4525_VSEL1; + sc->sleep_reg = TCS4525_VSEL0; + } + break; + default: + return (ENXIO); } if (fan53555_reg_attach(sc, node, type) == NULL) device_printf(dev, "cannot attach regulator.\n"); From 90098ee30e7cf5efec961896071a40f95d241b47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Schmidt?= Date: Thu, 1 Sep 2022 07:36:37 +0000 Subject: [PATCH 021/106] Fix reading the correct ID and REV. Reviewed by: manu --- sys/dev/iicbus/pmic/fan53555.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/iicbus/pmic/fan53555.c b/sys/dev/iicbus/pmic/fan53555.c index c4929eee07e5..a6d98353c041 100644 --- a/sys/dev/iicbus/pmic/fan53555.c +++ b/sys/dev/iicbus/pmic/fan53555.c @@ -56,9 +56,9 @@ __FBSDID("$FreeBSD$"); #define FAN53555_VSEL_MASK 0x3f #define FAN53555_CTRL 0x02 #define FAN53555_ID1 0x03 -#define FAN53555_ID1_DIE_ID(x) (((x) >> 4) & 0x0F) +#define FAN53555_ID1_DIE_ID(x) ((x) & 0x0F) #define FAN53555_ID2 0x04 -#define FAN53555_ID2_DIE_REV(x) (((x) >> 4) & 0x0F) +#define FAN53555_ID2_DIE_REV(x) ((x) & 0x0F) #define FAN53555_MON 0x05 #define TCS4525_VSEL0 0x11 From 598b6d4a7c789102caf7a7b36659465b67302045 Mon Sep 17 00:00:00 2001 From: Tijl Coosemans Date: Wed, 31 Aug 2022 20:56:49 +0200 Subject: [PATCH 022/106] i386 machine/cpu.h: include sys/systm.h for cpu_ticks() Fixes build of graphics/drm-510-kmod on i386. --- sys/i386/include/cpu.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/i386/include/cpu.h b/sys/i386/include/cpu.h index df35c9e92cc7..50ff4961b388 100644 --- a/sys/i386/include/cpu.h +++ b/sys/i386/include/cpu.h @@ -41,6 +41,9 @@ /* * Definitions unique to i386 cpu support. */ +#ifdef _KERNEL +#include /* For cpu_ticks(). */ +#endif #include #include #include From fdc1894795efb5c9d97044a724c01d149c569440 Mon Sep 17 00:00:00 2001 From: Tijl Coosemans Date: Sat, 1 May 2021 18:01:22 +0200 Subject: [PATCH 023/106] linuxkpi: on i386 only use first_msi_irq if apic is in kernel config --- sys/compat/linuxkpi/common/src/linux_current.c | 10 ++++++++-- sys/modules/linuxkpi/Makefile | 4 ++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/sys/compat/linuxkpi/common/src/linux_current.c b/sys/compat/linuxkpi/common/src/linux_current.c index 925d96770cc2..bfebbcb81d90 100644 --- a/sys/compat/linuxkpi/common/src/linux_current.c +++ b/sys/compat/linuxkpi/common/src/linux_current.c @@ -27,6 +27,12 @@ #include __FBSDID("$FreeBSD$"); +#ifdef __amd64__ +#define DEV_APIC +#elif defined(__i386__) +#include "opt_apic.h" +#endif + #include #include #include @@ -39,7 +45,7 @@ __FBSDID("$FreeBSD$"); #include #include -#if defined(__i386__) || defined(__amd64__) +#ifdef DEV_APIC extern u_int first_msi_irq, num_msi_irqs; #endif @@ -274,7 +280,7 @@ linux_current_init(void *arg __unused) TUNABLE_INT_FETCH("compat.linuxkpi.task_struct_reserve", &lkpi_task_resrv); if (lkpi_task_resrv == 0) { -#if defined(__i386__) || defined(__amd64__) +#ifdef DEV_APIC /* * Number of interrupt threads plus per-cpu callout * SWI threads. diff --git a/sys/modules/linuxkpi/Makefile b/sys/modules/linuxkpi/Makefile index 935584e39376..21663a078027 100644 --- a/sys/modules/linuxkpi/Makefile +++ b/sys/modules/linuxkpi/Makefile @@ -38,6 +38,10 @@ SRCS= linux_compat.c \ SRCS+= opt_acpi.h acpi_if.h linux_acpi.c .endif +.if ${MACHINE_CPUARCH} == "i386" +SRCS+= opt_apic.h +.endif + SRCS+= opt_ddb.h SRCS+= ${LINUXKPI_GENSRCS} From b1819983e70f5b8890404b7e07d17888d0cccfb6 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 1 Sep 2022 10:33:09 -0600 Subject: [PATCH 024/106] stand: Stop setting hints for bios loader too Catch up to 2753bbe71b5a and remove the old hints. Sponsored by: Netflix --- stand/i386/libi386/biosacpi.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/stand/i386/libi386/biosacpi.c b/stand/i386/libi386/biosacpi.c index 236c3fc45e7b..3bda472f3fc6 100644 --- a/stand/i386/libi386/biosacpi.c +++ b/stand/i386/libi386/biosacpi.c @@ -63,36 +63,24 @@ biosacpi_detect(void) /* * Report the RSDP to the kernel. While this can be found with * a BIOS boot, the RSDP may be elsewhere when booted from UEFI. - * The old code used the 'hints' method to communite this to - * the kernel. However, while convenient, the 'hints' method - * is fragile and does not work when static hints are compiled - * into the kernel. Instead, move to setting different tunables - * that start with acpi. The old 'hints' can be removed before - * we branch for FreeBSD 12. */ sprintf(buf, "0x%08x", VTOP(rsdp)); - setenv("hint.acpi.0.rsdp", buf, 1); setenv("acpi.rsdp", buf, 1); revision = rsdp->Revision; if (revision == 0) revision = 1; sprintf(buf, "%d", revision); - setenv("hint.acpi.0.revision", buf, 1); setenv("acpi.revision", buf, 1); strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId)); buf[sizeof(rsdp->OemId)] = '\0'; - setenv("hint.acpi.0.oem", buf, 1); setenv("acpi.oem", buf, 1); sprintf(buf, "0x%08x", rsdp->RsdtPhysicalAddress); - setenv("hint.acpi.0.rsdt", buf, 1); setenv("acpi.rsdt", buf, 1); if (revision >= 2) { /* XXX extended checksum? */ sprintf(buf, "0x%016llx", rsdp->XsdtPhysicalAddress); - setenv("hint.acpi.0.xsdt", buf, 1); setenv("acpi.xsdt", buf, 1); sprintf(buf, "%d", rsdp->Length); - setenv("hint.acpi.0.xsdt_length", buf, 1); setenv("acpi.xsdt_length", buf, 1); } } From 75a91c70f8d12825ded5a6d14841bf3065ba6595 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 1 Sep 2022 10:34:30 -0600 Subject: [PATCH 025/106] stand: Document EFI consoles Document how EFI consoles work, at least on x86. There's a number of weird quirks and limitations that are generally known, but not documented until now. Include information on how EFI decides what the defualt console is, how to set it and how to cope with common situations. Note limitations and mismatch between ACPI (which uses UID to identify a device) and our console code (which uses a raw address) and explain why we can't translate between them in the loader. Sponsored by: Netflix Reviewed by: manu, kevans, rpokala, pauamma Differential Revision: https://reviews.freebsd.org/D36286 --- stand/man/loader.efi.8 | 188 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 180 insertions(+), 8 deletions(-) diff --git a/stand/man/loader.efi.8 b/stand/man/loader.efi.8 index ca7480d5eba6..139988b111d4 100644 --- a/stand/man/loader.efi.8 +++ b/stand/man/loader.efi.8 @@ -1,7 +1,7 @@ .\" .\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD .\" -.\" Copyright (c) 2019 Netflix, Inc +.\" Copyright (c) 2019-2022 Netflix, Inc .\" Copyright (c) 2022 Mateusz Piotrowski <0mp@FreeBSD.org> .\" .\" Redistribution and use in source and binary forms, with or without @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 18, 2022 +.Dd August 31, 2022 .Dt LOADER.EFI 8 .Os .Sh NAME @@ -41,7 +41,167 @@ loads the kernel. .Xr boot1.efi 8 is used to load .Nm -when it is placed within the system. +when it is placed within a UFS or ZFS file system. +Alternatively, +.Nm +is used directly when configured with +.Xr efibootmgr 8 , +or when placed directly as the default boot program as described in +.Xr uefi 8 . +When a system is built using +.Xr bsdinstall 8 , +.Nm +will be used directly. +.Ss Console Considerations +The EFI BIOS provides a generic console. +In +.Nm +this is selected by specifying +.Dq efi +using the +.Dv console +variable. +.Nm +examines the +.Dv 8be4df61-93ca-11d2-aa0d-00e098032b8c-ConOut +UEFI environment variable to guess what the +.Dq efi +console points to. +.Nm +will output its prompts and menus to all the places specified by ConOut. +However, the +.Fx +kernel has a limitation when more than one console is present. +The kernel outputs to all configured consoles. +Only the primary console will get the log messages from the +.Xr rc 8 +system, and prompts for things like +.Xr geli 8 +passwords. +If +.Nm +finds a video device first, then +.Nm +tells the kernel to use the video console as primary. +Likewise, if a serial device is first in the +.Dv ConOut +list, the serial port will be the primary console. +.Pp +If there is no +.Dv ConOut +variable, both serial and video are attempted. +.Nm +uses the +.Dq efi +console for the video (which may or may not work) and +.Dq comconsole +for the serial on +.Dv COM1 +at the default baud rate. +The kernel will use a dual console, with the video console +primary if a UEFI graphics device is detected, or the serial console +as primary if not. +.Pp +On x86 platforms, if you wish to redirect the loader's output to a serial port +when the EFI BIOS doesn't support it, or to a serial port that isn't the one the +EFI BIOS redirects its output to, set +.Dv console +to +.Dq comconsole . +The default port is +.Dv COM1 +with an I/O address of 0x3f8. +.Dv comconsole_port +is used to set this to a different port address. +.Dv comconsole_speed +is used to set the of the serial port (the default is 9600). +If you have +.Dv console +set to +.Dq efi,comconsole +you will get output on both the EFI console and the serial port. +If this causes a doubling of characters, set +.Dv console +to +.Dq efi , +since your EFI BIOS is redirecting to the serial port already. +.Pp +If your EFI BIOS redirects the serial port, you may need to tell the kernel +which address to use. +EFI uses ACPI's UID to identify the serial port, but +.Nm +does not have an ACPI parser, so it cannot convert that to an I/O port. +The +.Fx +kernel initializes its consoles before it can decode ACPI resources. +The +.Fx +kernel will look at the +.Dv hw.uart.console +variable to set its serial console. +Its format should be described in +.Xr uart 4 +but is not. +Set it to +.Dq io:0x3f8,br:115200 +with the proper port address. +PCI or memory mapped ports are beyond the scope of this man page. +.Pp +The serial ports are assigned as follows on IBM PC compatible systems: +.Bl -column -offset indent ".Sy Windows Name" ".Sy I/O Port Address" ".Sy Typical FreeBSD device" +.It Sy Windows Name Ta Sy I/O Port Address Ta Sy Typical FreeBSD device +.It COM1 Ta 0x3f8 Ta Pa /dev/uart0 +.It COM2 Ta 0x2f8 Ta Pa /dev/uart1 +.It COM3 Ta 0x3e8 Ta Pa /dev/uart2 +.It COM4 Ta 0x2e8 Ta Pa /dev/uart3 +.El +Though +.Dv COM3 +and +.Dv COM4 +can vary. +.Pp +.Ss Primary Console +The primary console is set using the boot flags. +These command line arguments set corresponding flags for the kernel. +These flags can be controlled by setting loader environment variables +to +.Dq yes +or +.Dq no . +Boot flags may be set on the command line to the boot command. +Inside the kernel, the RB_ flags are used to control behavior, sometimes +in architecturally specific ways and are included to aid in discovery +of any behavior not covered in this document. +.Bl -column -offset indent ".Sy boot flag" ".Sy loader variable" ".Sy Kernel RB_ flag" +.It Sy boot flag Ta Sy loader variable Ta Sy Kernel RB_ flag +.It Fl a Ta Dv boot_askme Ta Va RB_ASKNAME +.It Fl c Ta Dv boot_cdrom Ta Va RB_CDROM +.It Fl d Ta Dv boot_ddb Ta Va RB_KDB +.It Fl r Ta Dv boot_dfltroot Ta Va RB_DFLTROOT +.It Fl D Ta Dv boot_multiple Ta Va RB_MULTIPLE +.It Fl m Ta Dv boot_mute Ta Va RB_MUTE +.It Fl g Ta Dv boot_gdb Ta Va RB_GDB +.It Fl h Ta Dv boot_serial Ta Va RB_SERIAL +.It Fl p Ta Dv boot_pause Ta Va RB_PAUSE +.It Fl P Ta Dv boot_probe Ta Va RB_PROBE +.It Fl s Ta Dv boot_single Ta Va RB_SINGLE +.It Fl v Ta Dv boot_verbose Ta Va RB_VERBOSE +.El +And the following flags determine the primary console: +.Bl -column -offset indent ".Sy Flags" ".Sy Kernel Flags" ".Sy Kernel Consoles" ".Sy Primary Console" +.It Sy Flags Ta Sy Kernel Flags Ta Sy Kernel Consoles Ta Sy Primary Console +.It none Ta 0 Ta Video Ta Video +.It Fl h Ta RB_SERIAL Ta Serial Ta Serial +.It Fl D Ta RB_MULTIPLE Ta Serial, Video Ta Video +.It Fl Dh Ta RB_SERIAL | RB_MULTIPLE Ta Serial, Video Ta Serial +.El +.Pp +.Nm +does not implement the probe +.Fl P +functionality where we use the video console if a keyboard is connected and a +serial console otherwise. .Sh FILES .Bl -tag -width "/boot/loader.efi" .It Pa /boot/loader.efi @@ -49,7 +209,7 @@ The location of the UEFI kernel loader within the system. .El .Ss EFI System Partition .Nm -is installed on ESP (EFI System Partition) in one of the following locations: +is installed on the ESP (EFI System Partition) in one of the following locations: .Bl -tag -width "efi/freebsd/loader.efi" .It Pa efi/boot/bootXXX.efi The default location for any EFI loader @@ -68,10 +228,10 @@ EFI loader. The default location for the ESP mount point is documented in .Xr hier 7 . .Sh EXAMPLES -.Ss Updating loader.efi on ESP +.Ss Updating loader.efi on the ESP The following examples shows how to install a new .Nm -on ESP. +on the ESP. .Pp First, find the partition of type .Dq efi : @@ -85,10 +245,10 @@ First, find the partition of type 1. Name: nvd0 .Ed .Pp -The name of ESP on this system is +The name of the ESP on this system is .Pa nvd0p1 . .Pp -Second, let's mount ESP, copy +Second, let's mount the ESP, copy .Nm to the special location reserved for .Fx @@ -97,6 +257,18 @@ EFI loaders, and unmount once finished: # mount_msdosfs /dev/nvd0p1 /boot/efi # cp /boot/loader.efi /boot/efi/efi/freebsd/loader.efi # umount /boot/efi +.Ed .Sh SEE ALSO .Xr loader 8 , .Xr uefi 8 +.Sh BUGS +Systems that do not have a +.Dv ConOut +variable set are not conformant with the standard, and likely have unexpected +results. +.Pp +Non-x86 serial console handling is even more confusing and less well documented. +.Pp +Sometimes when the serial port speed isn't set, 9600 is used. +Other times the result is typically 115200 since the speed remains unchanged +from the default. From 195f794318a33ec5bfd109d0e45f34ab583b1f38 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 1 Sep 2022 10:38:53 -0600 Subject: [PATCH 026/106] acpi: arm64 doesn't support ACPI 1.0 RSDP, report when we see one arm64 requires ACPI RSDP Revision 2.0 since it requires 64-bit physical addresses. It is an error worth reporting if we have a RSDP pointer, but it points to the wrong version. Sponsored by: Netflix Reviewed by: andrew Differential Revision: https://reviews.freebsd.org/D36404 --- sys/arm64/acpica/acpi_machdep.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/arm64/acpica/acpi_machdep.c b/sys/arm64/acpica/acpi_machdep.c index 478da9ec49ec..8ce4e521860b 100644 --- a/sys/arm64/acpica/acpi_machdep.c +++ b/sys/arm64/acpica/acpi_machdep.c @@ -194,6 +194,9 @@ acpi_find_table(const char *sig) break; } acpi_unmap_table(xsdt); + } else { + printf("ACPI: Unsupported RSDP version %d and XSDT %#llx\n", + rsdp->Revision, rsdp->XsdtPhysicalAddress); } pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP)); From a14b26a6bd3f34f27960e02948385993962e32d0 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 1 Sep 2022 10:39:20 -0600 Subject: [PATCH 027/106] acpi: Unmap RSDP in more error cases Add missing pmap_unmapbios() calls for when we return 0. Otherwise we can leave the table mapped when it is of no use. Sponsored by: Netflix Reviewed by: andrew Differential Revision: https://reviews.freebsd.org/D36405 --- sys/amd64/acpica/acpi_machdep.c | 6 ++++++ sys/arm64/acpica/acpi_machdep.c | 2 ++ 2 files changed, 8 insertions(+) diff --git a/sys/amd64/acpica/acpi_machdep.c b/sys/amd64/acpica/acpi_machdep.c index bbeb7cef44c5..1a9f44969d03 100644 --- a/sys/amd64/acpica/acpi_machdep.c +++ b/sys/amd64/acpica/acpi_machdep.c @@ -203,12 +203,16 @@ acpi_find_table(const char *sig) if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) { if (bootverbose) printf("ACPI: RSDP failed extended checksum\n"); + pmap_unmapbios((vm_offset_t)rsdp, + sizeof(ACPI_TABLE_RSDP)); return (0); } xsdt = map_table(rsdp->XsdtPhysicalAddress, ACPI_SIG_XSDT); if (xsdt == NULL) { if (bootverbose) printf("ACPI: Failed to map XSDT\n"); + pmap_unmapbios((vm_offset_t)rsdp, + sizeof(ACPI_TABLE_RSDP)); return (0); } count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) / @@ -224,6 +228,8 @@ acpi_find_table(const char *sig) if (rsdt == NULL) { if (bootverbose) printf("ACPI: Failed to map RSDT\n"); + pmap_unmapbios((vm_offset_t)rsdp, + sizeof(ACPI_TABLE_RSDP)); return (0); } count = (rsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) / diff --git a/sys/arm64/acpica/acpi_machdep.c b/sys/arm64/acpica/acpi_machdep.c index 8ce4e521860b..6145dfbbc78b 100644 --- a/sys/arm64/acpica/acpi_machdep.c +++ b/sys/arm64/acpica/acpi_machdep.c @@ -176,6 +176,8 @@ acpi_find_table(const char *sig) if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) { if (bootverbose) printf("ACPI: RSDP failed extended checksum\n"); + pmap_unmapbios((vm_offset_t)rsdp, + sizeof(ACPI_TABLE_RSDP)); return (0); } xsdt = map_table(rsdp->XsdtPhysicalAddress, ACPI_SIG_XSDT); From 991aef97957da8cb1fe5bf6ae4bbce4f8098a734 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 1 Sep 2022 10:39:34 -0600 Subject: [PATCH 028/106] acpi: Move some errors with RSDP and XSLT out from under bootverbose Failure to map RSDP, XSLT and checksum failures are events that can't happen unless something has gone wrong. As such, they should be reported always, and not in bootverbose. This has been this way since it was originally brought in to parse APIC tables. Sponsored by: Netflix Reviewed by: andrew Differential Revision: https://reviews.freebsd.org/D36406 --- sys/amd64/acpica/acpi_machdep.c | 12 ++++-------- sys/arm64/acpica/acpi_machdep.c | 9 +++------ 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/sys/amd64/acpica/acpi_machdep.c b/sys/amd64/acpica/acpi_machdep.c index 1a9f44969d03..41ec1554147f 100644 --- a/sys/amd64/acpica/acpi_machdep.c +++ b/sys/amd64/acpica/acpi_machdep.c @@ -184,8 +184,7 @@ acpi_find_table(const char *sig) return (0); rsdp = pmap_mapbios(rsdp_ptr, sizeof(ACPI_TABLE_RSDP)); if (rsdp == NULL) { - if (bootverbose) - printf("ACPI: Failed to map RSDP\n"); + printf("ACPI: Failed to map RSDP\n"); return (0); } @@ -201,16 +200,14 @@ acpi_find_table(const char *sig) * an additional checksum that we verify first. */ if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) { - if (bootverbose) - printf("ACPI: RSDP failed extended checksum\n"); + printf("ACPI: RSDP failed extended checksum\n"); pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP)); return (0); } xsdt = map_table(rsdp->XsdtPhysicalAddress, ACPI_SIG_XSDT); if (xsdt == NULL) { - if (bootverbose) - printf("ACPI: Failed to map XSDT\n"); + printf("ACPI: Failed to map XSDT\n"); pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP)); return (0); @@ -226,8 +223,7 @@ acpi_find_table(const char *sig) } else { rsdt = map_table(rsdp->RsdtPhysicalAddress, ACPI_SIG_RSDT); if (rsdt == NULL) { - if (bootverbose) - printf("ACPI: Failed to map RSDT\n"); + printf("ACPI: Failed to map RSDT\n"); pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP)); return (0); diff --git a/sys/arm64/acpica/acpi_machdep.c b/sys/arm64/acpica/acpi_machdep.c index 6145dfbbc78b..c9de53852549 100644 --- a/sys/arm64/acpica/acpi_machdep.c +++ b/sys/arm64/acpica/acpi_machdep.c @@ -161,8 +161,7 @@ acpi_find_table(const char *sig) return (0); rsdp = pmap_mapbios(rsdp_ptr, sizeof(ACPI_TABLE_RSDP)); if (rsdp == NULL) { - if (bootverbose) - printf("ACPI: Failed to map RSDP\n"); + printf("ACPI: Failed to map RSDP\n"); return (0); } @@ -174,16 +173,14 @@ acpi_find_table(const char *sig) * an additional checksum that we verify first. */ if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) { - if (bootverbose) - printf("ACPI: RSDP failed extended checksum\n"); + printf("ACPI: RSDP failed extended checksum\n"); pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP)); return (0); } xsdt = map_table(rsdp->XsdtPhysicalAddress, ACPI_SIG_XSDT); if (xsdt == NULL) { - if (bootverbose) - printf("ACPI: Failed to map XSDT\n"); + printf("ACPI: Failed to map XSDT\n"); pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP)); return (0); From 113dfadd5c8c2b8a566bf4d0e969e1dff62c9e2f Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 1 Sep 2022 11:05:42 -0600 Subject: [PATCH 029/106] stand: separate the command lookup from the command execution Factor out interp_lookup_cmd to search for a command from interp_builtin_cmd. This simplifies the latter and can be used to expand lua to ask if a command exists. Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D36363 --- stand/common/interp.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/stand/common/interp.c b/stand/common/interp.c index de5ea55eab41..227e7ad91e29 100644 --- a/stand/common/interp.c +++ b/stand/common/interp.c @@ -152,6 +152,19 @@ interp_emit_prompt(void) free(pr); } +static struct bootblk_command * +interp_lookup_cmd(const char *cmd) +{ + struct bootblk_command **cmdp; + + /* search the command set for the command */ + SET_FOREACH(cmdp, Xcommand_set) { + if (((*cmdp)->c_name != NULL) && !strcmp(cmd, (*cmdp)->c_name)) + return (*cmdp); + } + return (NULL); +} + /* * Perform a builtin command */ @@ -159,27 +172,21 @@ int interp_builtin_cmd(int argc, char *argv[]) { int result; - struct bootblk_command **cmdp; - bootblk_cmd_t *cmd; + struct bootblk_command *cmd; if (argc < 1) - return(CMD_OK); + return (CMD_OK); /* set return defaults; a successful command will override these */ command_errmsg = command_errbuf; strcpy(command_errbuf, "no error message"); - cmd = NULL; result = CMD_ERROR; - /* search the command set for the command */ - SET_FOREACH(cmdp, Xcommand_set) { - if (((*cmdp)->c_name != NULL) && !strcmp(argv[0], (*cmdp)->c_name)) - cmd = (*cmdp)->c_fn; - } - if (cmd != NULL) { - result = (cmd)(argc, argv); + cmd = interp_lookup_cmd(argv[0]); + if (cmd != NULL && cmd->c_fn) { + result = cmd->c_fn(argc, argv); } else { command_errmsg = "unknown command"; } - return(result); + return (result); } From a5948d40ad060140bf5b995f5409458a18ced0ce Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 1 Sep 2022 11:06:01 -0600 Subject: [PATCH 030/106] stand: Add interp_has_builtin_cmd to see if we have a command interp_has_builtin_cmd() will try to lookup the passed in command and returns true if it was found, false otherwise. Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D36364 --- stand/common/bootstrap.h | 1 + stand/common/interp.c | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/stand/common/bootstrap.h b/stand/common/bootstrap.h index 9c62a49b0da7..cb1c96dc3b69 100644 --- a/stand/common/bootstrap.h +++ b/stand/common/bootstrap.h @@ -52,6 +52,7 @@ extern char command_errbuf[COMMAND_ERRBUFSZ]; void interact(void); void interp_emit_prompt(void); int interp_builtin_cmd(int argc, char *argv[]); +bool interp_has_builtin_cmd(const char *cmd); /* Called by interp.c for interp_*.c embedded interpreters */ int interp_include(const char *); /* Execute commands from filename */ diff --git a/stand/common/interp.c b/stand/common/interp.c index 227e7ad91e29..8b779fb7a5e9 100644 --- a/stand/common/interp.c +++ b/stand/common/interp.c @@ -190,3 +190,12 @@ interp_builtin_cmd(int argc, char *argv[]) } return (result); } + +/* + * Return true if the builtin command exists + */ +bool +interp_has_builtin_cmd(const char *cmd) +{ + return (interp_lookup_cmd(cmd) != NULL); +} From 29fc4075e69fd27de0cded313ac6000165d99f8b Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 1 Sep 2022 11:06:19 -0600 Subject: [PATCH 031/106] stand: Add lua binding loader.has_command Give scripts the ability to determine if the currently running loader has provided a command. Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D36365 --- stand/liblua/lutils.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/stand/liblua/lutils.c b/stand/liblua/lutils.c index 9243edd07e8f..1649ac9fd508 100644 --- a/stand/liblua/lutils.c +++ b/stand/liblua/lutils.c @@ -63,6 +63,21 @@ lua_command(lua_State *L) return 1; } +static int +lua_has_command(lua_State *L) +{ + const char *cmd; + + if (lua_gettop(L) != 1) { + lua_pushnil(L); + return 1; + } + cmd = luaL_checkstring(L, 1); + lua_pushinteger(L, interp_has_builtin_cmd(cmd)); + + return 1; +} + static int lua_perform(lua_State *L) { @@ -539,9 +554,9 @@ static const struct luaL_Reg loaderlib[] = { REG_SIMPLE(interpret), REG_SIMPLE(parse), REG_SIMPLE(getenv), + REG_SIMPLE(has_command), REG_SIMPLE(perform), - /* Also registered as the global 'printc' */ - REG_SIMPLE(printc), + REG_SIMPLE(printc), /* Also registered as the global 'printc' */ REG_SIMPLE(setenv), REG_SIMPLE(time), REG_SIMPLE(unsetenv), From 57f90cf81338ca9d1e403fdfeac16f21def72763 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 1 Sep 2022 11:06:43 -0600 Subject: [PATCH 032/106] kboot: add minmalist init functionality It is desirable to run kboot as the first program in some LinuxBoot environments. This is the traditional "pid 1" or "init" program. When running as pid 1. rovide a minimal environment based on what sysvinit, u-root, initramfs-tools and other like projects do. We mount /dev, /sys, /proc, make symlinks from /dev/fd to /dev/proc, and create /tmp, /run, and /var. We also setup stdin/out/err to the console, set the tty characteristics of same and block the appropriate signals. This is indended as an environment that never does a fork/exec. If that's required, the process groups, session leaders and all things POSIX terminal handlers will need to be added. Unlike the general purpose linux projects in this area, no attempt is made to support very old kernels. When not pid 1, we skip all of the above. Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D36368 --- stand/kboot/Makefile | 1 + stand/kboot/init.c | 129 +++++++++++++++++++++++++++++++++++++++++++ stand/kboot/kboot.h | 12 ++++ stand/kboot/main.c | 7 ++- 4 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 stand/kboot/init.c create mode 100644 stand/kboot/kboot.h diff --git a/stand/kboot/Makefile b/stand/kboot/Makefile index 986e636a8c35..b8e71fd70dc7 100644 --- a/stand/kboot/Makefile +++ b/stand/kboot/Makefile @@ -19,6 +19,7 @@ INSTALLFLAGS= -b # Architecture-specific loader code SRCS= crt1.c conf.c vers.c main.c host_syscalls.c hostcons.c hostdisk.c kbootfdt.c gfx_fb_stub.c +SRCS+= init.c SRCS+= termios.c CFLAGS.gfx_fb_stub.c += -I${SRCTOP}/contrib/pnglite -I${SRCTOP}/sys/teken diff --git a/stand/kboot/init.c b/stand/kboot/init.c new file mode 100644 index 000000000000..e707f65096d7 --- /dev/null +++ b/stand/kboot/init.c @@ -0,0 +1,129 @@ +/*- + * Copyright (c) 2022, Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* + * Mini-init(8) so we can run as init/pid 1 in a LinuxBoot environment. + */ + +#include "stand.h" +#include "host_syscall.h" +#include "kboot.h" + +/* + * Create a 'standard' early boot environment. Cribbed from the things that + * sysvinit, u-root, and initramfs-tools do. This is a minimal environment + * for modern Linux systems, though the /tmp, /run and /var stuff can likely + * be done inside the initrd image itself (as can creating the mount points + * for /proc, /dev and /sys). + * + * Note: We ignore errors here. There's no stderr to report them to yet. These + * operations generally can't fail, but if they do, we may not have the ability + * to report them later. + */ +static void +init_fs_env(void) +{ + /* + * Create directories for mandatory filesystems and mount them. + */ + host_mkdir("/proc", 0555); + host_mount("proc", "/proc", "proc", MS_RELATIME, ""); + host_mkdir("/sys", 0555); + host_mount("sysfs", "/sys", "sysfs", MS_RELATIME, ""); + host_mkdir("/dev", 0755); + host_mount("devtmpfs", "/dev", "devtmpfs", MS_RELATIME, + "mode=0755,nr_inodes=0"); + + /* + * Create compat links: /dev/fd lives in /proc, and needs some help to + * get setup. + */ + host_symlink("/proc/self/fd", "/dev/fd"); + host_symlink("fd/0", "/dev/stdin"); + host_symlink("fd/1", "/dev/stdout"); + host_symlink("fd/2", "/dev/stderr"); + + + /* + * Unsure if we need this, but create a sane /tmp just in case that's useful. + * and point /run over to it. + */ + host_mkdir("/tmp", 01777); + host_mount("tmpfs", "/tmp", "tmpfs", MS_RELATIME, "size=10%,mode=1777"); + host_symlink("/tmp", "/run"); + + /* + * Unsure the loader needs /var and /var/log, but they are easy to + * create. + */ + host_mkdir("/var", 0555); + host_mkdir("/var/lock", 0555); + host_symlink("/tmp", "/var/tmp"); +} + +static void +init_tty(void) +{ + int fd; + + /* + * sysvinit asks the linux kernel to convert the CTRL-ALT-DEL to a SIGINT, + * but we skip that. + */ + + /* + * Setup /dev/console as stdin/out/err + */ + host_close(0); + host_close(1); + host_close(2); + fd = host_open("/dev/console", HOST_O_RDWR | HOST_O_NOCTTY, 0); + host_dup(fd); + host_dup(fd); +#if 0 + /* + * I think we may need to put it in 'raw' mode, but maybe not. Linux + * sysvinit sets it into 'sane' mode with several tweaks. Not enabled at + * the moment since host console initialization seems sufficient. + */ + struct host_termios tty; + + host_cfmakeraw(&tty); + host_tcsetattr(fd, HOST_TCANOW, &tty); + host_tcflush(fd, HOST_TCIOFLUSH) +#endif +} + +static void +init_sig(void) +{ + /* + * since we're running as init, we need to catch some signals + */ + + /* + * setup signals here + * + * sysvinit catches a lot of signals, but the boot loader needn't catch + * so many since we don't do as much as it does. If we need to, put the + * signal catching / ignoring code here. If we implement a 'shell' + * function to spawn a sub-shell, we'll likely need to do a lot more. + */ +} + +void +do_init(void) +{ + /* + * Only pid 1 is init + */ + if (host_getpid() != 1) + return; + + init_fs_env(); + init_tty(); + init_sig(); +} diff --git a/stand/kboot/kboot.h b/stand/kboot/kboot.h new file mode 100644 index 000000000000..01de346234f3 --- /dev/null +++ b/stand/kboot/kboot.h @@ -0,0 +1,12 @@ +/*- + * Copyright (c) 2022, Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#ifndef KBOOT_H +#define KBOOT_H + +void do_init(void); + +#endif /* KBOOT_H */ diff --git a/stand/kboot/main.c b/stand/kboot/main.c index 5d40e2c3b582..be08528049e6 100644 --- a/stand/kboot/main.c +++ b/stand/kboot/main.c @@ -34,7 +34,7 @@ __FBSDID("$FreeBSD$"); #include #include #include "host_syscall.h" - +#include "kboot.h" struct arch_switch archsw; extern void *_end; @@ -261,8 +261,11 @@ main(int argc, const char **argv) const size_t heapsize = 15*1024*1024; const char *bootdev; + /* Give us a sane world if we're running as init */ + do_init(); + /* - * Set the heap to one page after the end of the loader. + * Setup the heap 15MB should be plenty */ heapbase = host_getmem(heapsize); setheap(heapbase, heapbase + heapsize); From 69818bcf38e0bb1716a8d29f61ed392d447cea83 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 1 Sep 2022 11:07:34 -0600 Subject: [PATCH 033/106] kboot: List sources one per line to make merges easier Make SRC an alphabetical list of files, one per line. Sponsored by: Netflix --- stand/kboot/Makefile | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/stand/kboot/Makefile b/stand/kboot/Makefile index b8e71fd70dc7..c204af8b17e7 100644 --- a/stand/kboot/Makefile +++ b/stand/kboot/Makefile @@ -18,9 +18,18 @@ NEWVERSWHAT= "kboot loader" ${MACHINE_ARCH} INSTALLFLAGS= -b # Architecture-specific loader code -SRCS= crt1.c conf.c vers.c main.c host_syscalls.c hostcons.c hostdisk.c kbootfdt.c gfx_fb_stub.c -SRCS+= init.c -SRCS+= termios.c +SRCS= \ + conf.c \ + crt1.c \ + gfx_fb_stub.c \ + host_syscalls.c \ + hostcons.c \ + hostdisk.c \ + init.c \ + kbootfdt.c \ + main.c \ + termios.c \ + vers.c \ CFLAGS.gfx_fb_stub.c += -I${SRCTOP}/contrib/pnglite -I${SRCTOP}/sys/teken From 4e679d8aeaa86ce061b15c51fe9a5eae1eff7470 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Thu, 1 Sep 2022 13:18:04 -0400 Subject: [PATCH 034/106] hwpmc: Avoid touching MSR_DEBUGCTLMSR inside VMs. At least KVM in Proxmox seems not happy about it. Just to be safe block it for all VMs, since it should just improve profile accuracy. MFC after: 1 week --- sys/dev/hwpmc/hwpmc_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/hwpmc/hwpmc_core.c b/sys/dev/hwpmc/hwpmc_core.c index 7ec22c36019c..ff6bfbd4322f 100644 --- a/sys/dev/hwpmc/hwpmc_core.c +++ b/sys/dev/hwpmc/hwpmc_core.c @@ -151,7 +151,7 @@ core_pcpu_init(struct pmc_mdep *md, int cpu) pc->pc_hwpmcs[n + core_ri] = phw; } - if (core_version >= 2) { + if (core_version >= 2 && vm_guest == VM_GUEST_NO) { /* Enable Freezing PMCs on PMI. */ wrmsr(MSR_DEBUGCTLMSR, rdmsr(MSR_DEBUGCTLMSR) | 0x1000); } From 281a6ff273d191678b343d531cdb7e877d6663f9 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 1 Sep 2022 11:34:36 -0600 Subject: [PATCH 035/106] acpi: Fix error message Fix a formatting error from 195f794318a33 Fixes: 195f794318a33 Sponsored by: Netflix --- sys/arm64/acpica/acpi_machdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/arm64/acpica/acpi_machdep.c b/sys/arm64/acpica/acpi_machdep.c index c9de53852549..113c8c4b8848 100644 --- a/sys/arm64/acpica/acpi_machdep.c +++ b/sys/arm64/acpica/acpi_machdep.c @@ -194,7 +194,7 @@ acpi_find_table(const char *sig) } acpi_unmap_table(xsdt); } else { - printf("ACPI: Unsupported RSDP version %d and XSDT %#llx\n", + printf("ACPI: Unsupported RSDP version %d and XSDT %#lx\n", rsdp->Revision, rsdp->XsdtPhysicalAddress); } pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP)); From e1963173708504ecd2ee5c441a9428a046af54f4 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Thu, 11 Aug 2022 14:32:06 +0000 Subject: [PATCH 036/106] local_unbound: rc: allow to overwrite pid file path Certain configurations need to use a different path for pidfile. Allow rc.conf to overwrite it. Reviewed by: cy, 0mp MFC after: 3 days Differential Revision: https://reviews.freebsd.org/D36141 --- libexec/rc/rc.d/local_unbound | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libexec/rc/rc.d/local_unbound b/libexec/rc/rc.d/local_unbound index 19cb9a6c5c01..9c32b8263dc8 100755 --- a/libexec/rc/rc.d/local_unbound +++ b/libexec/rc/rc.d/local_unbound @@ -34,6 +34,8 @@ load_rc_config $name : ${local_unbound_anchor:=${local_unbound_workdir}/root.key} : ${local_unbound_forwarders:=} : ${local_unbound_tls:=} +: ${local_unbound_pidfile:=${pidfile}} +pidfile=${local_unbound_pidfile} do_as_unbound() { From 2486b446db8270a7d6dc7f3c6df0a88c4745b527 Mon Sep 17 00:00:00 2001 From: Mathew McBride Date: Sat, 23 Jul 2022 00:29:16 +0000 Subject: [PATCH 037/106] ds1307: add support for the EPSON RX-8035SA I2C RTC The EPSON RX-8035SA I2C RTC has a similar time register layout to the ds1307 family, with some minor differences in bit positions, polarity and control registers. Further generalize ds1307 to make it easier to add more compatible chips and add support for the EPSON RX-8035SA. MFC after: 6 days Sponsored by: Traverse Technologies Differential Revision: https://reviews.freebsd.org/D35837 --- sys/dev/iicbus/ds1307.c | 264 +++++++++++++++++++++++++++++-------- sys/dev/iicbus/ds1307reg.h | 6 + 2 files changed, 215 insertions(+), 55 deletions(-) diff --git a/sys/dev/iicbus/ds1307.c b/sys/dev/iicbus/ds1307.c index 2ba712400fe4..e14f10631fd5 100644 --- a/sys/dev/iicbus/ds1307.c +++ b/sys/dev/iicbus/ds1307.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2015 Luiz Otavio O Souza + * Copyright (c) 2022 Mathew McBride * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -54,23 +55,31 @@ __FBSDID("$FreeBSD$"); #include "clock_if.h" #include "iicbus_if.h" +enum { + TYPE_DS1307, + TYPE_MAXIM1307, + TYPE_MICROCHIP_MCP7491X, + TYPE_EPSON_RX8035, + TYPE_COUNT +}; + struct ds1307_softc { - device_t sc_dev; - struct intr_config_hook - enum_hook; - uint8_t sc_ctrl; - bool sc_mcp7941x; - bool sc_use_ampm; + device_t sc_dev; + struct intr_config_hook enum_hook; + uint32_t chiptype; + uint8_t sc_ctrl; + bool sc_use_ampm; }; static void ds1307_start(void *); #ifdef FDT static const struct ofw_compat_data ds1307_compat_data[] = { - {"dallas,ds1307", (uintptr_t)"Dallas DS1307 RTC"}, - {"maxim,ds1307", (uintptr_t)"Maxim DS1307 RTC"}, - {"microchip,mcp7941x", (uintptr_t)"Microchip MCP7941x RTC"}, - { NULL, 0 } + {"dallas,ds1307", TYPE_DS1307}, + {"maxim,ds1307", TYPE_MAXIM1307}, + {"microchip,mcp7941x", TYPE_MICROCHIP_MCP7491X}, + {"epson,rx8035", TYPE_EPSON_RX8035}, + { NULL, 0 } }; #endif @@ -96,7 +105,8 @@ ds1307_ctrl_read(struct ds1307_softc *sc) sc->sc_ctrl = 0; error = ds1307_read1(sc->sc_dev, DS1307_CONTROL, &sc->sc_ctrl); if (error) { - device_printf(sc->sc_dev, "cannot read from RTC.\n"); + device_printf(sc->sc_dev, "%s: cannot read from RTC: %d\n", + __func__, error); return (error); } @@ -112,7 +122,8 @@ ds1307_ctrl_write(struct ds1307_softc *sc) ctrl = sc->sc_ctrl & DS1307_CTRL_MASK; error = ds1307_write1(sc->sc_dev, DS1307_CONTROL, ctrl); if (error != 0) - device_printf(sc->sc_dev, "cannot write to RTC.\n"); + device_printf(sc->sc_dev, "%s: cannot write to RTC: %d\n", + __func__, error); return (error); } @@ -127,7 +138,7 @@ ds1307_sqwe_sysctl(SYSCTL_HANDLER_ARGS) error = ds1307_ctrl_read(sc); if (error != 0) return (error); - if (sc->sc_mcp7941x) + if (sc->chiptype == TYPE_MICROCHIP_MCP7491X) sqwe_bit = MCP7941X_CTRL_SQWE; else sqwe_bit = DS1307_CTRL_SQWE; @@ -216,11 +227,29 @@ ds1307_probe(device_t dev) return (ENXIO); compat = ofw_bus_search_compatible(dev, ds1307_compat_data); - if (compat->ocd_str != NULL) { - device_set_desc(dev, (const char *)compat->ocd_data); - return (BUS_PROBE_DEFAULT); + if (compat->ocd_str == NULL) + return (ENXIO); + + switch(compat->ocd_data) { + case TYPE_DS1307: + device_set_desc(dev, "Dallas DS1307"); + break; + case TYPE_MAXIM1307: + device_set_desc(dev, "Maxim DS1307"); + break; + case TYPE_MICROCHIP_MCP7491X: + device_set_desc(dev, "Microchip MCP7491X"); + break; + case TYPE_EPSON_RX8035: + device_set_desc(dev, "Epson RX-8035"); + break; + default: + device_set_desc(dev, "Unknown DS1307-like device"); + break; } + return (BUS_PROBE_DEFAULT); #endif + device_set_desc(dev, "Maxim DS1307 RTC"); return (BUS_PROBE_NOWILDCARD); } @@ -228,16 +257,23 @@ ds1307_probe(device_t dev) static int ds1307_attach(device_t dev) { +#ifdef FDT + const struct ofw_compat_data *compat; +#endif struct ds1307_softc *sc; sc = device_get_softc(dev); sc->sc_dev = dev; sc->enum_hook.ich_func = ds1307_start; sc->enum_hook.ich_arg = dev; - #ifdef FDT - if (ofw_bus_is_compatible(dev, "microchip,mcp7941x")) - sc->sc_mcp7941x = 1; + compat = ofw_bus_search_compatible(dev, ds1307_compat_data); + sc->chiptype = compat->ocd_data; + /* Unify the chiptypes to DS1307 where possible. */ + if (sc->chiptype == TYPE_MAXIM1307) + sc->chiptype = TYPE_DS1307; +#else + sc->chiptype = TYPE_DS1307; #endif /* @@ -258,6 +294,110 @@ ds1307_detach(device_t dev) return (0); } +static bool +is_epson_time_valid(struct ds1307_softc *sc) +{ + device_t dev; + int error; + uint8_t ctrl2; + + dev = sc->sc_dev; + + /* + * The RX-8035 single register read is non-standard + * Refer to section 8.9.5 of the RX-8035 application manual: + * "I2C bus basic transfer format", under "Standard Read Method". + * Basically, register to read goes into the top 4 bits. + */ + error = ds1307_read1(dev, (RX8035_CTRL_2 << 4), &ctrl2); + if (error) { + device_printf(dev, "%s cannot read Control 2 register: %d\n", + __func__, error); + return (false); + } + + if (ctrl2 & RX8035_CTRL_2_XSTP) { + device_printf(dev, "Oscillation stop detected (ctrl2=%#02x)\n", + ctrl2); + return (false); + } + + /* + * Power on reset (PON) generally implies oscillation stop, + * but catch it as well to be sure. + */ + if (ctrl2 & RX8035_CTRL_2_PON) { + device_printf(dev, "Power-on reset detected (ctrl2=%#02x)\n", + ctrl2); + return (false); + } + + return (true); +} + +static int +mark_epson_time_valid(struct ds1307_softc *sc) +{ + device_t dev; + int error; + uint8_t ctrl2; + uint8_t control_mask; + + dev = sc->sc_dev; + + error = ds1307_read1(dev, (RX8035_CTRL_2 << 4), &ctrl2); + if (error) { + device_printf(dev, "%s cannot read Control 2 register: %d\n", + __func__, error); + return (false); + } + + control_mask = (RX8035_CTRL_2_PON | RX8035_CTRL_2_XSTP | RX8035_CTRL_2_VDET); + ctrl2 = ctrl2 & ~(control_mask); + + error = ds1307_write1(dev, (RX8035_CTRL_2 << 4), ctrl2); + if (error) { + device_printf(dev, "%s cannot write to Control 2 register: %d\n", + __func__, error); + return (false); + } + return (true); +} + +static bool is_dev_time_valid(struct ds1307_softc *sc) +{ + device_t dev; + int error; + uint8_t osc_en; + uint8_t secs; + + /* Epson RTCs have different control/status registers. */ + if (sc->chiptype == TYPE_EPSON_RX8035) + return (is_epson_time_valid(sc)); + + dev = sc->sc_dev; + /* Check if the oscillator is disabled. */ + error = ds1307_read1(dev, DS1307_SECS, &secs); + if (error) { + device_printf(dev, "%s: cannot read from RTC: %d\n", + __func__, error); + return (false); + } + + switch (sc->chiptype) { + case TYPE_MICROCHIP_MCP7491X: + osc_en = 0x80; + break; + default: + osc_en = 0x00; + break; + } + if (((secs & DS1307_SECS_CH) ^ osc_en) != 0) + return (false); + + return (true); +} + static void ds1307_start(void *xdev) { @@ -266,33 +406,28 @@ ds1307_start(void *xdev) struct sysctl_ctx_list *ctx; struct sysctl_oid *tree_node; struct sysctl_oid_list *tree; - uint8_t secs; - uint8_t osc_en; dev = (device_t)xdev; sc = device_get_softc(dev); - ctx = device_get_sysctl_ctx(dev); - tree_node = device_get_sysctl_tree(dev); - tree = SYSCTL_CHILDREN(tree_node); config_intrhook_disestablish(&sc->enum_hook); - /* Check if the oscillator is disabled. */ - if (ds1307_read1(sc->sc_dev, DS1307_SECS, &secs) != 0) { - device_printf(sc->sc_dev, "cannot read from RTC.\n"); - return; - } - if (sc->sc_mcp7941x) - osc_en = 0x80; - else - osc_en = 0x00; - - if (((secs & DS1307_SECS_CH) ^ osc_en) != 0) { - device_printf(sc->sc_dev, + if (!is_dev_time_valid(sc)) + device_printf(dev, "WARNING: RTC clock stopped, check the battery.\n"); - } - /* Configuration parameters. */ + /* + * Configuration parameters: + * square wave output cannot be changed or inhibited on the RX-8035, + * so don't present the sysctls there. + */ + if (sc->chiptype == TYPE_EPSON_RX8035) + goto skip_sysctl; + + ctx = device_get_sysctl_ctx(dev); + tree_node = device_get_sysctl_tree(dev); + tree = SYSCTL_CHILDREN(tree_node); + SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "sqwe", CTLFLAG_RW | CTLTYPE_UINT | CTLFLAG_MPSAFE, sc, 0, ds1307_sqwe_sysctl, "IU", "DS1307 square-wave enable"); @@ -303,6 +438,7 @@ ds1307_start(void *xdev) SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "sqw_out", CTLFLAG_RW | CTLTYPE_UINT | CTLFLAG_MPSAFE, sc, 0, ds1307_sqw_out_sysctl, "IU", "DS1307 square-wave output state"); +skip_sysctl: /* * Register as a clock with 1 second resolution. Schedule the @@ -316,30 +452,36 @@ ds1307_start(void *xdev) static int ds1307_gettime(device_t dev, struct timespec *ts) { - int error; struct bcd_clocktime bct; struct ds1307_softc *sc; - uint8_t data[7], hourmask, st_mask; + int error; + uint8_t data[7], hourmask, ampm_mode; sc = device_get_softc(dev); error = iicdev_readfrom(sc->sc_dev, DS1307_SECS, data, sizeof(data), IIC_INTRWAIT); if (error != 0) { - device_printf(dev, "cannot read from RTC.\n"); + device_printf(dev, "%s: cannot read from RTC: %d\n", + __func__, error); return (error); } - /* If the clock halted, we don't have good data. */ - if (sc->sc_mcp7941x) - st_mask = 0x80; - else - st_mask = 0x00; - - if (((data[DS1307_SECS] & DS1307_SECS_CH) ^ st_mask) != 0) + if (!is_dev_time_valid(sc)) { + device_printf(dev, "Device time not valid.\n"); return (EINVAL); + } - /* If chip is in AM/PM mode remember that. */ - if (data[DS1307_HOUR] & DS1307_HOUR_USE_AMPM) { + /* + * If the chip is in AM/PM mode remember that. + * The EPSON uses a 1 to signify 24 hour mode, while the DS uses a 0, + * in slighly different positions. + */ + if (sc->chiptype == TYPE_EPSON_RX8035) + ampm_mode = !(data[DS1307_HOUR] & RX8035_HOUR_USE_24); + else + ampm_mode = data[DS1307_HOUR] & DS1307_HOUR_USE_AMPM; + + if (ampm_mode) { sc->sc_use_ampm = true; hourmask = DS1307_HOUR_MASK_12HR; } else @@ -377,12 +519,19 @@ ds1307_settime(device_t dev, struct timespec *ts) clock_ts_to_bcd(ts, &bct, sc->sc_use_ampm); clock_dbgprint_bcd(sc->sc_dev, CLOCK_DBG_WRITE, &bct); - /* If the chip is in AM/PM mode, adjust hour and set flags as needed. */ + /* + * If the chip is in AM/PM mode, adjust hour and set flags as needed. + * The AM/PM bit polarity and position is different on the EPSON. + */ if (sc->sc_use_ampm) { - pmflags = DS1307_HOUR_USE_AMPM; + pmflags = (sc->chiptype != TYPE_EPSON_RX8035) ? + DS1307_HOUR_USE_AMPM : 0; if (bct.ispm) pmflags |= DS1307_HOUR_IS_PM; - } else + + } else if (sc->chiptype == TYPE_EPSON_RX8035) + pmflags = RX8035_HOUR_USE_24; + else pmflags = 0; data[DS1307_SECS] = bct.sec; @@ -392,18 +541,23 @@ ds1307_settime(device_t dev, struct timespec *ts) data[DS1307_WEEKDAY] = bct.dow; data[DS1307_MONTH] = bct.mon; data[DS1307_YEAR] = bct.year & 0xff; - if (sc->sc_mcp7941x) { + if (sc->chiptype == TYPE_MICROCHIP_MCP7491X) { data[DS1307_SECS] |= MCP7941X_SECS_ST; data[DS1307_WEEKDAY] |= MCP7941X_WEEKDAY_VBATEN; year = bcd2bin(bct.year >> 8) * 100 + bcd2bin(bct.year & 0xff); if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) data[DS1307_MONTH] |= MCP7941X_MONTH_LPYR; } + /* Write the time back to RTC. */ error = iicdev_writeto(sc->sc_dev, DS1307_SECS, data, sizeof(data), IIC_INTRWAIT); if (error != 0) - device_printf(dev, "cannot write to RTC.\n"); + device_printf(dev, "%s: cannot write to RTC: %d\n", + __func__, error); + + if (sc->chiptype == TYPE_EPSON_RX8035) + error = mark_epson_time_valid(sc); return (error); } diff --git a/sys/dev/iicbus/ds1307reg.h b/sys/dev/iicbus/ds1307reg.h index f2763a5e0cd3..e4f7979c97da 100644 --- a/sys/dev/iicbus/ds1307reg.h +++ b/sys/dev/iicbus/ds1307reg.h @@ -44,6 +44,7 @@ #define DS1307_HOUR_MASK_24HR 0x3f #define DS1307_HOUR_IS_PM 0x20 #define DS1307_HOUR_USE_AMPM 0x40 +#define RX8035_HOUR_USE_24 0x80 #define DS1307_WEEKDAY 0x03 #define MCP7941X_WEEKDAY_VBATEN 0x08 #define DS1307_WEEKDAY_MASK 0x07 @@ -63,4 +64,9 @@ #define DS1307_CTRL_RS_MASK (DS1307_CTRL_RS1 | DS1307_CTRL_RS0) #define DS1307_CTRL_MASK 0x93 +#define RX8035_CTRL_2 0x0F +#define RX8035_CTRL_2_PON (1 << 4) +#define RX8035_CTRL_2_XSTP (1 << 5) +#define RX8035_CTRL_2_VDET (1 << 6) + #endif /* _DS1307REG_H_ */ From e23ad9c4ba2d2fd235fc3dc988ca422ef4e7ca3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kornel=20Dul=C4=99ba?= Date: Fri, 2 Sep 2022 13:07:03 +0200 Subject: [PATCH 038/106] tpm: Fix entropy harvesting logic Use a taskqueue instead of a callout. Callout functions mustn't sleep, where as the TPM driver uses a sx lock in order to serialize accesses to the device. Since the entropy harvesting feature is not enabled by default, this commit should not bring any functional changes to the GENERIC kernel. Approved by: mw(mentor) Sponsored by: Stormshield Obtained from: Semihalf MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D36412 --- sys/dev/tpm/tpm20.c | 24 +++++++++++++----------- sys/dev/tpm/tpm20.h | 4 ++-- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/sys/dev/tpm/tpm20.c b/sys/dev/tpm/tpm20.c index 68a30cfb51dd..3f444176732c 100644 --- a/sys/dev/tpm/tpm20.c +++ b/sys/dev/tpm/tpm20.c @@ -39,13 +39,13 @@ __FBSDID("$FreeBSD$"); * we don't want to execute this too often * as the chip is likely to be used by others too. */ -#define TPM_HARVEST_INTERVAL 10000000 +#define TPM_HARVEST_INTERVAL 10 MALLOC_DEFINE(M_TPM20, "tpm_buffer", "buffer for tpm 2.0 driver"); static void tpm20_discard_buffer(void *arg); #ifdef TPM_HARVEST -static void tpm20_harvest(void *arg); +static void tpm20_harvest(void *arg, int unused); #endif static int tpm20_save_state(device_t dev, bool suspend); @@ -192,11 +192,6 @@ tpm20_init(struct tpm_sc *sc) cv_init(&sc->buf_cv, "TPM buffer cv"); callout_init(&sc->discard_buffer_callout, 1); -#ifdef TPM_HARVEST - sc->harvest_ticks = TPM_HARVEST_INTERVAL / tick; - callout_init(&sc->harvest_callout, 1); - callout_reset(&sc->harvest_callout, 0, tpm20_harvest, sc); -#endif sc->pending_data_length = 0; make_dev_args_init(&args); @@ -209,6 +204,12 @@ tpm20_init(struct tpm_sc *sc) if (result != 0) tpm20_release(sc); +#ifdef TPM_HARVEST + TIMEOUT_TASK_INIT(taskqueue_thread, &sc->harvest_task, 0, + tpm20_harvest, sc); + taskqueue_enqueue_timeout(taskqueue_thread, &sc->harvest_task, 0); +#endif + return (result); } @@ -218,7 +219,8 @@ tpm20_release(struct tpm_sc *sc) { #ifdef TPM_HARVEST - callout_drain(&sc->harvest_callout); + if (device_is_attached(sc->dev)) + taskqueue_drain_timeout(taskqueue_thread, &sc->harvest_task); #endif if (sc->buf != NULL) @@ -243,13 +245,12 @@ tpm20_shutdown(device_t dev) } #ifdef TPM_HARVEST - /* * Get TPM_HARVEST_SIZE random bytes and add them * into system entropy pool. */ static void -tpm20_harvest(void *arg) +tpm20_harvest(void *arg, int unused) { struct tpm_sc *sc; unsigned char entropy[TPM_HARVEST_SIZE]; @@ -290,7 +291,8 @@ tpm20_harvest(void *arg) if (entropy_size > 0) random_harvest_queue(entropy, entropy_size, RANDOM_PURE_TPM); - callout_reset(&sc->harvest_callout, sc->harvest_ticks, tpm20_harvest, sc); + taskqueue_enqueue_timeout(taskqueue_thread, &sc->harvest_task, + hz * TPM_HARVEST_INTERVAL); } #endif /* TPM_HARVEST */ diff --git a/sys/dev/tpm/tpm20.h b/sys/dev/tpm/tpm20.h index 6911ca0cb6fe..bda4987120b0 100644 --- a/sys/dev/tpm/tpm20.h +++ b/sys/dev/tpm/tpm20.h @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -125,8 +126,7 @@ struct tpm_sc { struct callout discard_buffer_callout; #ifdef TPM_HARVEST - struct callout harvest_callout; - int harvest_ticks; + struct timeout_task harvest_task; #endif int (*transmit)(struct tpm_sc *, size_t); From 66c73af7ea59382ce5ca7cfb2eedb0491790276c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kornel=20Dul=C4=99ba?= Date: Fri, 2 Sep 2022 13:08:32 +0200 Subject: [PATCH 039/106] stand: Parse BIOS revision from SMBIOS Add a smbios.bios.revision kenv, which contains the system BIOS revision as defined in SMBIOS specification, section 3.3.1. Since the revision is stored in two separate byte fields, the smbios_setenv helper can't be used. Read and construct the kenv manually instead. Approved by: mw(mentor) Sponsored by: Stormshield Obtained from: Semihalf Differential Revision: https://reviews.freebsd.org/D36413 --- stand/libsa/smbios.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/stand/libsa/smbios.c b/stand/libsa/smbios.c index 5582a2f3ce90..61bd82f9d6f0 100644 --- a/stand/libsa/smbios.c +++ b/stand/libsa/smbios.c @@ -298,6 +298,8 @@ smbios_parse_table(const caddr_t addr) { caddr_t cp; int proc, size, osize, type; + uint8_t bios_minor, bios_major; + char buf[16]; type = SMBIOS_GET8(addr, 0); /* 3.1.2 Structure Header Format */ switch(type) { @@ -305,6 +307,13 @@ smbios_parse_table(const caddr_t addr) smbios_setenv("smbios.bios.vendor", addr, 0x04); smbios_setenv("smbios.bios.version", addr, 0x05); smbios_setenv("smbios.bios.reldate", addr, 0x08); + bios_major = SMBIOS_GET8(addr, 0x14); + bios_minor = SMBIOS_GET8(addr, 0x15); + if (bios_minor != 0xFF && bios_major != 0xFF) { + snprintf(buf, sizeof(buf), "%u.%u", + bios_major, bios_minor); + setenv("smbios.bios.revision", buf, 1); + } break; case 1: /* 3.3.2 System Information (Type 1) */ From cfdc649e455bc0d37d42c46b59360462e93b4300 Mon Sep 17 00:00:00 2001 From: Tijl Coosemans Date: Fri, 2 Sep 2022 16:16:35 +0200 Subject: [PATCH 040/106] i386 doreti: Fix calculation of stack frame size Reviewed by: kib Fixes: e8b2980e4a12 - i386 doreti: stop saving/restoring %ecx --- sys/i386/i386/exception.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s index 2373fa425210..ab6c83843bfe 100644 --- a/sys/i386/i386/exception.s +++ b/sys/i386/i386/exception.s @@ -530,7 +530,7 @@ doreti_exit: testl $PSL_VM,TF_EFLAGS(%esp) jz 2f /* PCB_VM86CALL is not set */ addl $VM86_STACK_SPACE, %ecx -2: subl $TF_SZ, %edx +2: subl %ecx, %edx movl %edx, %edi rep; movsb movl %edx, %esp From 74ed2e8ab20264595bfbf67c117462df68b856ce Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Fri, 2 Sep 2022 12:17:09 -0700 Subject: [PATCH 041/106] raw ip: fix regression with multicast and RSVP With 61f7427f02a raw sockets protosw has wildcard pr_protocol. Protocol of a specific pcb is stored in inp_ip_p. Reviewed by: karels Reported by: karels Differential revision: https://reviews.freebsd.org/D36429 Fixes: 61f7427f02a307d28af674a12c45dd546e3898e4 --- sys/netinet/ip_input.c | 4 ---- sys/netinet/ip_mroute.c | 6 +----- sys/netinet/raw_ip.c | 8 ++++++++ sys/netinet6/ip6_mroute.c | 7 +------ sys/netinet6/ip6_output.c | 5 ++--- sys/netinet6/raw_ip6.c | 7 +++++-- 6 files changed, 17 insertions(+), 20 deletions(-) diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 059f26869e0e..41ba82ea81dd 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -1313,10 +1313,6 @@ int ip_rsvp_init(struct socket *so) { - if (so->so_type != SOCK_RAW || - so->so_proto->pr_protocol != IPPROTO_RSVP) - return EOPNOTSUPP; - if (V_ip_rsvpd != NULL) return EADDRINUSE; diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c index f77898fb3aa4..383f2dfc076e 100644 --- a/sys/netinet/ip_mroute.c +++ b/sys/netinet/ip_mroute.c @@ -686,11 +686,7 @@ static int ip_mrouter_init(struct socket *so, int version) { - CTR3(KTR_IPMF, "%s: so_type %d, pr_protocol %d", __func__, - so->so_type, so->so_proto->pr_protocol); - - if (so->so_type != SOCK_RAW || so->so_proto->pr_protocol != IPPROTO_IGMP) - return EOPNOTSUPP; + CTR2(KTR_IPMF, "%s: so %p", __func__, so); if (version != 1) return ENOPROTOOPT; diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c index 3e7c81341c08..fb5628324020 100644 --- a/sys/netinet/raw_ip.c +++ b/sys/netinet/raw_ip.c @@ -693,6 +693,8 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt) error = priv_check(curthread, PRIV_NETINET_MROUTE); if (error != 0) return (error); + if (inp->inp_ip_p != IPPROTO_IGMP) + return (EOPNOTSUPP); error = ip_mrouter_get ? ip_mrouter_get(so, sopt) : EOPNOTSUPP; break; @@ -747,6 +749,8 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt) error = priv_check(curthread, PRIV_NETINET_MROUTE); if (error != 0) return (error); + if (inp->inp_ip_p != IPPROTO_RSVP) + return (EOPNOTSUPP); error = ip_rsvp_init(so); break; @@ -762,6 +766,8 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt) error = priv_check(curthread, PRIV_NETINET_MROUTE); if (error != 0) return (error); + if (inp->inp_ip_p != IPPROTO_RSVP) + return (EOPNOTSUPP); error = ip_rsvp_vif ? ip_rsvp_vif(so, sopt) : EINVAL; break; @@ -781,6 +787,8 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt) error = priv_check(curthread, PRIV_NETINET_MROUTE); if (error != 0) return (error); + if (inp->inp_ip_p != IPPROTO_IGMP) + return (EOPNOTSUPP); error = ip_mrouter_set ? ip_mrouter_set(so, sopt) : EOPNOTSUPP; break; diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c index 9e864859c279..9465c6662018 100644 --- a/sys/netinet6/ip6_mroute.c +++ b/sys/netinet6/ip6_mroute.c @@ -555,12 +555,7 @@ static int ip6_mrouter_init(struct socket *so, int v, int cmd) { - MRT6_DLOG(DEBUG_ANY, "so_type = %d, pr_protocol = %d", - so->so_type, so->so_proto->pr_protocol); - - if (so->so_type != SOCK_RAW || - so->so_proto->pr_protocol != IPPROTO_ICMPV6) - return (EOPNOTSUPP); + MRT6_DLOG(DEBUG_ANY, "%s: socket %p", __func__, so); if (v != 1) return (ENOPROTOOPT); diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index fc330290d6a3..a1504bfb8da6 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -2451,8 +2451,7 @@ ip6_raw_ctloutput(struct socket *so, struct sockopt *sopt) * values or -1 as a special value. */ error = EINVAL; - } else if (so->so_proto->pr_protocol == - IPPROTO_ICMPV6) { + } else if (inp->inp_ip_p == IPPROTO_ICMPV6) { if (optval != icmp6off) error = EINVAL; } else @@ -2460,7 +2459,7 @@ ip6_raw_ctloutput(struct socket *so, struct sockopt *sopt) break; case SOPT_GET: - if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) + if (inp->inp_ip_p == IPPROTO_ICMPV6) optval = icmp6off; else optval = inp->in6p_cksum; diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index acc6787d59a7..0a5d343f3725 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -596,7 +596,7 @@ rip6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, int rip6_ctloutput(struct socket *so, struct sockopt *sopt) { - struct inpcb *inp; + struct inpcb *inp = sotoinpcb(so); int error; if (sopt->sopt_level == IPPROTO_ICMPV6) @@ -608,7 +608,6 @@ rip6_ctloutput(struct socket *so, struct sockopt *sopt) else if (sopt->sopt_level != IPPROTO_IPV6) { if (sopt->sopt_level == SOL_SOCKET && sopt->sopt_name == SO_SETFIB) { - inp = sotoinpcb(so); INP_WLOCK(inp); inp->inp_inc.inc_fibnum = so->so_fibnum; INP_WUNLOCK(inp); @@ -629,6 +628,8 @@ rip6_ctloutput(struct socket *so, struct sockopt *sopt) case MRT6_ADD_MFC: case MRT6_DEL_MFC: case MRT6_PIM: + if (inp->inp_ip_p != IPPROTO_ICMPV6) + return (EOPNOTSUPP); error = ip6_mrouter_get ? ip6_mrouter_get(so, sopt) : EOPNOTSUPP; break; @@ -650,6 +651,8 @@ rip6_ctloutput(struct socket *so, struct sockopt *sopt) case MRT6_ADD_MFC: case MRT6_DEL_MFC: case MRT6_PIM: + if (inp->inp_ip_p != IPPROTO_ICMPV6) + return (EOPNOTSUPP); error = ip6_mrouter_set ? ip6_mrouter_set(so, sopt) : EOPNOTSUPP; break; From 9b17aa27406f3716383e71c6687d53599a8f8d8a Mon Sep 17 00:00:00 2001 From: Jessica Clarke Date: Fri, 2 Sep 2022 20:30:40 +0100 Subject: [PATCH 042/106] lualoader: Add loader_menu_multi_user_prompt config variable This allows the "Multi user" in "[B]oot Multi user" to be substituted with another string, for example with "Installer" in installer media. Note that this is lua-only at the moment, since loader.4th's menu.rc defines the alternate name as Boot [M]ulti User, unlike lualoader which leaves it as [B]oot Multi user. Ideally loader.4th would adopt the newer and simpler lualoader behaviour and then it could gain support for this option, but loader.4th is on the way out and isn't used by any official installer media so this is not a significant concern. Reviewed by: kevans, rpokala MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D36418 --- stand/lua/menu.lua | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/stand/lua/menu.lua b/stand/lua/menu.lua index f1a4f07a8d73..400dbf3d469b 100644 --- a/stand/lua/menu.lua +++ b/stand/lua/menu.lua @@ -60,6 +60,10 @@ local function bootenvSet(env) config.reload() end +local function multiUserPrompt() + return loader.getenv("loader_menu_multi_user_prompt") or "Multi user" +end + -- Module exports menu.handlers = { -- Menu handlers take the current menu and selected entry as parameters, @@ -263,11 +267,16 @@ menu.welcome = { all_entries = { multi_user = { entry_type = core.MENU_ENTRY, - name = color.highlight("B") .. "oot Multi user " .. - color.highlight("[Enter]"), + name = function() + return color.highlight("B") .. "oot " .. + multiUserPrompt() .. " " .. + color.highlight("[Enter]") + end, -- Not a standard menu entry function! - alternate_name = color.highlight("B") .. - "oot Multi user", + alternate_name = function() + return color.highlight("B") .. "oot " .. + multiUserPrompt() + end, func = function() core.setSingleUser(false) core.boot() From 2a90c47af158625b3e28390801639c21d6d0ed2a Mon Sep 17 00:00:00 2001 From: Jessica Clarke Date: Fri, 2 Sep 2022 20:30:50 +0100 Subject: [PATCH 043/106] release: Set loader_menu_multi_user_prompt to "Installer" for installer This makes it more obvious that the media being booted is an installer rather than an installed system, which is otherwise hard to distinguish. It also provides a more user-friendly, and more accurate, prompt. Reviewed by: gjb MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D36419 --- release/Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/release/Makefile b/release/Makefile index 7aeca8cc0276..16fae5d74acb 100644 --- a/release/Makefile +++ b/release/Makefile @@ -187,6 +187,7 @@ disc1: packagesystem echo debug.witness.trace=0 >> ${.TARGET}/etc/sysctl.conf echo vfs.mountroot.timeout=\"10\" >> ${.TARGET}/boot/loader.conf echo kernels_autodetect=\"NO\" >> ${.TARGET}/boot/loader.conf + echo loader_menu_multi_user_prompt=\"Installer\" >> ${.TARGET}/boot/loader.conf cp ${.CURDIR}/rc.local ${.TARGET}/etc .if defined(NO_ROOT) echo "./etc/resolv.conf type=link uname=root gname=wheel mode=0644 link=/tmp/bsdinstall_etc/resolv.conf" >> ${.TARGET}/METALOG @@ -222,6 +223,7 @@ bootonly: packagesystem echo debug.witness.trace=0 >> ${.TARGET}/etc/sysctl.conf echo vfs.mountroot.timeout=\"10\" >> ${.TARGET}/boot/loader.conf echo kernels_autodetect=\"NO\" >> ${.TARGET}/boot/loader.conf + echo loader_menu_multi_user_prompt=\"Installer\" >> ${.TARGET}/boot/loader.conf cp ${.CURDIR}/rc.local ${.TARGET}/etc .if defined(NO_ROOT) echo "./etc/resolv.conf type=link uname=root gname=wheel mode=0644 link=/tmp/bsdinstall_etc/resolv.conf" >> ${.TARGET}/METALOG @@ -256,6 +258,7 @@ dvd: packagesystem echo debug.witness.trace=0 >> ${.TARGET}/etc/sysctl.conf echo vfs.mountroot.timeout=\"10\" >> ${.TARGET}/boot/loader.conf echo kernels_autodetect=\"NO\" >> ${.TARGET}/boot/loader.conf + echo loader_menu_multi_user_prompt=\"Installer\" >> ${.TARGET}/boot/loader.conf cp ${.CURDIR}/rc.local ${.TARGET}/etc .if defined(NO_ROOT) echo "./etc/resolv.conf type=link uname=root gname=wheel mode=0644 link=/tmp/bsdinstall_etc/resolv.conf" >> ${.TARGET}/METALOG From e3b17b5042ed427d2298b3a00fac35cef65ac811 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 2 Sep 2022 14:49:40 -0700 Subject: [PATCH 044/106] qat: Drop extraneous parentheses from some macro values. This header duplicates a few #defines in "adf_cfg_strings.h". The latter header does not use the unneeded parentheses, but if a C file includes both of these headers, clang raises an error because the macro is redefined with a different value. Reviewed by: markj Sponsored by: DARPA Obtained from: CheriBSD Differential Revision: https://reviews.freebsd.org/D36329 --- sys/dev/qat/qat_api/qat_direct/include/icp_adf_cfg.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/dev/qat/qat_api/qat_direct/include/icp_adf_cfg.h b/sys/dev/qat/qat_api/qat_direct/include/icp_adf_cfg.h index db1e111f07bd..0c20333b7f67 100644 --- a/sys/dev/qat/qat_api/qat_direct/include/icp_adf_cfg.h +++ b/sys/dev/qat/qat_api/qat_direct/include/icp_adf_cfg.h @@ -52,9 +52,9 @@ #define ADF_SRAM_SIZE_IN_BYTES ("Sram_SizeInBytes") /* Device node id, tells to which die the device is * connected to */ -#define ADF_DEV_NODE_ID ("Device_NodeId") +#define ADF_DEV_NODE_ID "Device_NodeId" /* Device package id, this is accel_dev id */ -#define ADF_DEV_PKG_ID ("Device_PkgId") +#define ADF_DEV_PKG_ID "Device_PkgId" /* Device bus address, B.D.F (Bus(8bits),Device(5bits),Function(3bits)) */ #define ADF_DEV_BUS_ADDRESS ("Device_BusAddress") /* Number of Acceleration Engines */ @@ -76,9 +76,9 @@ /* Whether or not arbitration is supported */ #define ADF_DEV_ARB_SUPPORTED ("ArbitrationSupported") /* Slice Watch Dog Timer for CySym+Comp */ -#define ADF_DEV_SSM_WDT_BULK ("CySymAndDcWatchDogTimer") +#define ADF_DEV_SSM_WDT_BULK "CySymAndDcWatchDogTimer" /* Slice Watch Dog Timer for CyAsym */ -#define ADF_DEV_SSM_WDT_PKE ("CyAsymWatchDogTimer") +#define ADF_DEV_SSM_WDT_PKE "CyAsymWatchDogTimer" /* String names for the exposed sections of config file. */ #define GENERAL_SEC "GENERAL" From 50f1a377da0e758399ee30d75323e846d4a0b913 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 2 Sep 2022 14:50:09 -0700 Subject: [PATCH 045/106] qat: Add a prototype for icp_adf_is_dev_in_error. Reviewed by: MichalX.Gulbicki_intel.com, markj Sponsored by: DARPA Obtained from: CheriBSD Differential Revision: https://reviews.freebsd.org/D36330 --- .../qat_api/qat_direct/include/icp_adf_accel_mgr.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sys/dev/qat/qat_api/qat_direct/include/icp_adf_accel_mgr.h b/sys/dev/qat/qat_api/qat_direct/include/icp_adf_accel_mgr.h index 43d154433fe0..9fcc07a1ffd8 100644 --- a/sys/dev/qat/qat_api/qat_direct/include/icp_adf_accel_mgr.h +++ b/sys/dev/qat/qat_api/qat_direct/include/icp_adf_accel_mgr.h @@ -44,10 +44,20 @@ CpaStatus icp_adf_reset_dev(icp_accel_dev_t *accel_dev, * * Returns: * CPA_TRUE device is in reset state - * CPA_FALS device is not in reset state + * CPA_FALSE device is not in reset state */ CpaBoolean icp_adf_is_dev_in_reset(icp_accel_dev_t *accel_dev); +/* + * icp_adf_is_dev_in_error + * Check if device is in error state. + * + * Returns: + * CPA_TRUE device is in error state + * CPA_FALSE device is not in error state + */ +CpaBoolean icp_adf_is_dev_in_error(icp_accel_dev_t *accel_dev); + /* * icp_amgr_getNumInstances * From 1c4c92f91b41861b1c9c71297695b89033827871 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 2 Sep 2022 14:51:54 -0700 Subject: [PATCH 046/106] qat: Add #includes for missing prototypes. This fixes numerous -Wmissing-prototypes warnings when that warning is enabled. Reviewed by: MichalX.Gulbicki_intel.com, markj Sponsored by: DARPA Obtained from: CheriBSD Differential Revision: https://reviews.freebsd.org/D36331 --- sys/dev/qat/qat_api/qat_kernel/src/lac_adf_interface_freebsd.c | 2 ++ sys/dev/qat/qat_api/qat_kernel/src/qat_transport.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/sys/dev/qat/qat_api/qat_kernel/src/lac_adf_interface_freebsd.c b/sys/dev/qat/qat_api/qat_kernel/src/lac_adf_interface_freebsd.c index 7669e21eeaa1..fc75178946c4 100644 --- a/sys/dev/qat/qat_api/qat_kernel/src/lac_adf_interface_freebsd.c +++ b/sys/dev/qat/qat_api/qat_kernel/src/lac_adf_interface_freebsd.c @@ -5,6 +5,8 @@ #include "cpa.h" #include "icp_accel_devices.h" #include "adf_common_drv.h" +#include "icp_adf_accel_mgr.h" +#include "icp_adf_cfg.h" #include "icp_adf_debug.h" #include "icp_adf_init.h" #include "lac_sal_ctrl.h" diff --git a/sys/dev/qat/qat_api/qat_kernel/src/qat_transport.c b/sys/dev/qat/qat_api/qat_kernel/src/qat_transport.c index f8aa6e0ac3e3..739cd026eedf 100644 --- a/sys/dev/qat/qat_api/qat_kernel/src/qat_transport.c +++ b/sys/dev/qat/qat_api/qat_kernel/src/qat_transport.c @@ -6,7 +6,10 @@ #include "cpa.h" #include "icp_adf_init.h" +#include "icp_adf_transport.h" +#include "icp_adf_poll.h" #include "icp_adf_transport_dp.h" +#include "icp_sal_poll.h" /* * adf_modulo From e120d3b2d48cc59b013b4e2fae292b738a294e21 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 2 Sep 2022 14:52:19 -0700 Subject: [PATCH 047/106] qat: Move CWARNFLAGS down so it works. CWARNFLAGS must be added to after including kern.mk, otherwise all the warnings set in kern.mk are ignored. This is why the -Wmissing-prototypes warnings were not seen previously. While here, drop -Wno-pointer-sign as it is doesn't seem to be needed, but add -Wno-cast-qual to silence warnings for various casts of const pointers to non-const pointers. Reviewed by: MichalX.Gulbicki_intel.com, markj Sponsored by: DARPA Differential Revision: https://reviews.freebsd.org/D36332 --- sys/modules/qat/qat_api/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/modules/qat/qat_api/Makefile b/sys/modules/qat/qat_api/Makefile index 5dd4bc25285b..20f3acd4ecdd 100644 --- a/sys/modules/qat/qat_api/Makefile +++ b/sys/modules/qat/qat_api/Makefile @@ -71,5 +71,6 @@ CFLAGS+= -I${SRCTOP}/sys/dev/qat/qat_api/firmware/include CFLAGS+= -I${SRCTOP}/sys/dev/qat/include/common CFLAGS+= -I${SYSDIR}/compat/linuxkpi/common/include -CWARNFLAGS += -Wno-pointer-sign .include + +CWARNFLAGS+= -Wno-cast-qual From 120bacabfd4f383f028bb309581e2366110d0c28 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 2 Sep 2022 17:00:56 +0300 Subject: [PATCH 048/106] __swbuf(): style Reviewed by: emaste, markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D36427 --- lib/libc/stdio/wbuf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/libc/stdio/wbuf.c b/lib/libc/stdio/wbuf.c index 6cd75145a271..d389cdab0353 100644 --- a/lib/libc/stdio/wbuf.c +++ b/lib/libc/stdio/wbuf.c @@ -82,7 +82,7 @@ __swbuf(int c, FILE *fp) */ n = fp->_p - fp->_bf._base; if (n >= fp->_bf._size) { - if (__fflush(fp)) + if (__fflush(fp) != 0) return (EOF); n = 0; } @@ -90,7 +90,7 @@ __swbuf(int c, FILE *fp) *fp->_p++ = c; old_p = fp->_p; if (++n == fp->_bf._size || (fp->_flags & __SLBF && c == '\n')) { - if (__fflush(fp)) { + if (__fflush(fp) != 0) { if (fp->_p == old_p) { fp->_p--; fp->_w++; From 44cf1e5eb470380442fa8e240e213a71b8fe81d4 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 2 Sep 2022 16:39:38 +0300 Subject: [PATCH 049/106] libc/stdio: only roll FILE state back on EINTR Reported by: JunT PR: 266171 Reviewed by: emaste, markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D36427 --- lib/libc/stdio/fflush.c | 3 ++- lib/libc/stdio/fvwrite.c | 5 +++-- lib/libc/stdio/wbuf.c | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/libc/stdio/fflush.c b/lib/libc/stdio/fflush.c index decc974907f4..f59565abd369 100644 --- a/lib/libc/stdio/fflush.c +++ b/lib/libc/stdio/fflush.c @@ -136,7 +136,8 @@ __sflush(FILE *fp) fp->_p += n; if ((fp->_flags & (__SLBF | __SNBF)) == 0) fp->_w -= n; - } else if (p == fp->_p) { /* cond. to handle setvbuf */ + /* conditional to handle setvbuf */ + } else if (p == fp->_p && errno == EINTR) { fp->_p = old_p; fp->_w = old_w; } diff --git a/lib/libc/stdio/fvwrite.c b/lib/libc/stdio/fvwrite.c index 2a161859afa9..b1b363e6f80d 100644 --- a/lib/libc/stdio/fvwrite.c +++ b/lib/libc/stdio/fvwrite.c @@ -38,6 +38,7 @@ static char sccsid[] = "@(#)fvwrite.c 8.1 (Berkeley) 6/4/93"; #include __FBSDID("$FreeBSD$"); +#include #include #include #include @@ -140,7 +141,7 @@ __sfvwrite(FILE *fp, struct __suio *uio) fp->_p += w; old_p = fp->_p; if (__fflush(fp) == EOF) { - if (old_p == fp->_p) + if (old_p == fp->_p && errno == EINTR) fp->_p -= w; goto err; } @@ -184,7 +185,7 @@ __sfvwrite(FILE *fp, struct __suio *uio) fp->_p += w; old_p = fp->_p; if (__fflush(fp) == EOF) { - if (old_p == fp->_p) + if (old_p == fp->_p && errno == EINTR) fp->_p -= w; goto err; } diff --git a/lib/libc/stdio/wbuf.c b/lib/libc/stdio/wbuf.c index d389cdab0353..666bbf87aadd 100644 --- a/lib/libc/stdio/wbuf.c +++ b/lib/libc/stdio/wbuf.c @@ -91,7 +91,7 @@ __swbuf(int c, FILE *fp) old_p = fp->_p; if (++n == fp->_bf._size || (fp->_flags & __SLBF && c == '\n')) { if (__fflush(fp) != 0) { - if (fp->_p == old_p) { + if (fp->_p == old_p && errno == EINTR) { fp->_p--; fp->_w++; } From 05e1ac3cbfedf12e4b7a41729ad2ff6e748983a1 Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Sat, 3 Sep 2022 14:52:44 +0200 Subject: [PATCH 050/106] impi(4): Fix two typos in source code comments - s/overriden/overridden/ MFC after: 3 days --- sys/dev/ipmi/ipmi_isa.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/ipmi/ipmi_isa.c b/sys/dev/ipmi/ipmi_isa.c index 677a723b8b6d..e8bb0ffd5e0b 100644 --- a/sys/dev/ipmi/ipmi_isa.c +++ b/sys/dev/ipmi/ipmi_isa.c @@ -140,7 +140,7 @@ ipmi_hint_identify(device_t dev, struct ipmi_get_info *info) bus_delete_resource(dev, SYS_RES_IOPORT, i); } - /* Allow the I/O address to be overriden via hints. */ + /* Allow the I/O address to be overridden via hints. */ if (resource_int_value(name, unit, "port", &val) == 0 && val != 0) { info->address = val; info->io_mode = 1; @@ -150,7 +150,7 @@ ipmi_hint_identify(device_t dev, struct ipmi_get_info *info) info->io_mode = 0; } - /* Allow the spacing to be overriden. */ + /* Allow the spacing to be overridden. */ if (resource_int_value(name, unit, "spacing", &val) == 0) { switch (val) { case 8: From 310d144a83411abedc17bfeec07f1f7ccee2434e Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Sat, 3 Sep 2022 14:54:14 +0200 Subject: [PATCH 051/106] isp(4): Fix two typos in source code comments - s/overriden/overridden/ MFC after: 3 days --- sys/dev/isp/isp.c | 2 +- sys/dev/isp/ispvar.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c index c3470529657e..cc2f5ae23d2f 100644 --- a/sys/dev/isp/isp.c +++ b/sys/dev/isp/isp.c @@ -599,7 +599,7 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults) /* * We get some default values established. As a side - * effect, NVRAM is read here (unless overriden by + * effect, NVRAM is read here (unless overridden by * a configuration flag). */ if (do_load_defaults) { diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h index deb014bb4a63..eae81f6ac9ed 100644 --- a/sys/dev/isp/ispvar.h +++ b/sys/dev/isp/ispvar.h @@ -895,7 +895,7 @@ void isp_async(ispsoftc_t *, ispasync_t, ...); * DEFAULT_PORTWWN(ispsoftc_t *, chan) Default FC Port WWN to use * * These defines are hooks to allow the setting of node and - * port WWNs when NVRAM cannot be read or is to be overriden. + * port WWNs when NVRAM cannot be read or is to be overridden. * * ACTIVE_NODEWWN(ispsoftc_t *, chan) FC Node WWN to use * ACTIVE_PORTWWN(ispsoftc_t *, chan) FC Port WWN to use From 2f2cf766b2ae0d42c70ec7bff0fd87ac8449c3a3 Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Sat, 3 Sep 2022 14:55:54 +0200 Subject: [PATCH 052/106] ifconfig(8): Fix a typo in source code comment - s/overriden/overridden/ MFC after: 3 days --- sbin/ifconfig/ifieee80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbin/ifconfig/ifieee80211.c b/sbin/ifconfig/ifieee80211.c index ee611a14b45e..cb465a02b794 100644 --- a/sbin/ifconfig/ifieee80211.c +++ b/sbin/ifconfig/ifieee80211.c @@ -5733,7 +5733,7 @@ setdefregdomain(int s) /* Send changes to net80211. */ setregdomain_cb(s, ®domain); - /* Cleanup (so it can be overriden by subsequent parameters). */ + /* Cleanup (so it can be overridden by subsequent parameters). */ regdomain.regdomain = 0; regdomain.country = CTRY_DEFAULT; regdomain.isocc[0] = 0; From 0a81527da8e51e3dd77af2ef4950d6559684487f Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Sat, 3 Sep 2022 14:57:39 +0200 Subject: [PATCH 053/106] rc.conf: Fix a typo in a comment - s/overriden/overridden/ MFC after: 3 days --- libexec/rc/rc.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libexec/rc/rc.conf b/libexec/rc/rc.conf index c12377d035d6..6b2c33792ea7 100644 --- a/libexec/rc/rc.conf +++ b/libexec/rc/rc.conf @@ -570,7 +570,7 @@ font8x8="NO" # font 8x8 from /usr/share/{syscons,vt}/fonts/* (or NO). blanktime="300" # blank time (in seconds) or "NO" to turn it off. saver="NO" # screen saver: Uses /boot/kernel/${saver}_saver.ko moused_nondefault_enable="YES" # Treat non-default mice as enabled unless - # specifically overriden in rc.conf(5). + # specifically overridden in rc.conf(5). moused_enable="NO" # Run the mouse daemon. moused_type="auto" # See man page for rc.conf(5) for available settings. moused_port="/dev/psm0" # Set to your mouse port. From fa4eca789ec90d0724b81ecf7cf30503c6cd567d Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Sat, 3 Sep 2022 14:59:03 +0200 Subject: [PATCH 054/106] tip(1): Fix a typo in a source code comment - s/overriden/overridden/ MFC after: 3 days --- usr.bin/tip/tip/acu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.bin/tip/tip/acu.c b/usr.bin/tip/tip/acu.c index 0188be3c6406..1177e67bea28 100644 --- a/usr.bin/tip/tip/acu.c +++ b/usr.bin/tip/tip/acu.c @@ -56,7 +56,7 @@ static jmp_buf jmpbuf; * The phone numbers are in PN, and the call unit is in CU. * * If the PN is an '@', then we consult the PHONES file for - * the phone numbers. This file is /etc/phones, unless overriden + * the phone numbers. This file is /etc/phones, unless overridden * by an exported shell variable. * * The data base files must be in the format: From b82cbe465173baa727f7a4860c74b78718662c14 Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Sat, 3 Sep 2022 15:00:29 +0200 Subject: [PATCH 055/106] cron(8): Fix a typo in a source code comment - s/overriden/overridden/ MFC after: 3 days --- usr.sbin/cron/cron/do_command.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/cron/cron/do_command.c b/usr.sbin/cron/cron/do_command.c index 4dcbce2c1165..fcc5a5e3eb2a 100644 --- a/usr.sbin/cron/cron/do_command.c +++ b/usr.sbin/cron/cron/do_command.c @@ -527,7 +527,7 @@ child_process(e, u) */ if (mailto == NULL) { /* MAILTO not present, set to USER, - * unless globally overriden. + * unless globally overridden. */ if (defmailto) mailto = defmailto; From 028ecc7aa1a06abdae96ba076189dc973d075042 Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Sat, 3 Sep 2022 15:04:15 +0200 Subject: [PATCH 056/106] netisr(9): Fix a typo in a source code comment - s/overriden/overridden/ MFC after: 3 days --- sys/net/netisr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/net/netisr.c b/sys/net/netisr.c index 4d0bce3bedfc..9898e0b18caf 100644 --- a/sys/net/netisr.c +++ b/sys/net/netisr.c @@ -134,7 +134,7 @@ static SYSCTL_NODE(_net, OID_AUTO, isr, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, * Three global direct dispatch policies are supported: * * NETISR_DISPATCH_DEFERRED: All work is deferred for a netisr, regardless of - * context (may be overriden by protocols). + * context (may be overridden by protocols). * * NETISR_DISPATCH_HYBRID: If the executing context allows direct dispatch, * and we're running on the CPU the work would be performed on, then direct From fa52f9dc9aa1e3726c37e5a87d3d71d529df9e30 Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Sat, 3 Sep 2022 15:05:42 +0200 Subject: [PATCH 057/106] tcp_rack: Fix two typos in source code comments - s/overriden/overridden/ MFC after: 3 days --- sys/netinet/tcp_stacks/rack.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c index 47bcd3b76d90..a97f82a02b85 100644 --- a/sys/netinet/tcp_stacks/rack.c +++ b/sys/netinet/tcp_stacks/rack.c @@ -16100,7 +16100,7 @@ rack_fast_rsm_output(struct tcpcb *tp, struct tcp_rack *rack, struct rack_sendma /* * We have no pacing set or we * are using old-style rack or - * we are overriden to use the old 1ms pacing. + * we are overridden to use the old 1ms pacing. */ slot = rack->r_ctl.rc_min_to; } @@ -19172,7 +19172,7 @@ rack_output(struct tcpcb *tp) /* * We have no pacing set or we * are using old-style rack or - * we are overriden to use the old 1ms pacing. + * we are overridden to use the old 1ms pacing. */ slot = rack->r_ctl.rc_min_to; } From d0ddb5aacabab2cc5bbfbd18c3f07507b6acdb92 Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Sat, 3 Sep 2022 15:22:42 +0200 Subject: [PATCH 058/106] usb: Fix two typos in source code comments - s/overriden/overridden/ MFC after: 3 days --- sys/dev/usb/net/if_muge.c | 2 +- sys/dev/usb/net/if_smsc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/usb/net/if_muge.c b/sys/dev/usb/net/if_muge.c index 88897dac8f50..3087eb40b40a 100644 --- a/sys/dev/usb/net/if_muge.c +++ b/sys/dev/usb/net/if_muge.c @@ -1582,7 +1582,7 @@ muge_attach_post(struct usb_ether *ue) * @ue: the USB ethernet device * * Most of this is boilerplate code and copied from the base USB ethernet - * driver. It has been overriden so that we can indicate to the system + * driver. It has been overridden so that we can indicate to the system * that the chip supports H/W checksumming. * * RETURNS: diff --git a/sys/dev/usb/net/if_smsc.c b/sys/dev/usb/net/if_smsc.c index f6b0095af4ff..e3b4ae9a5cbd 100644 --- a/sys/dev/usb/net/if_smsc.c +++ b/sys/dev/usb/net/if_smsc.c @@ -1604,7 +1604,7 @@ smsc_attach_post(struct usb_ether *ue) * @ue: the USB ethernet device * * Most of this is boilerplate code and copied from the base USB ethernet - * driver. It has been overriden so that we can indicate to the system that + * driver. It has been overridden so that we can indicate to the system that * the chip supports H/W checksumming. * * RETURNS: From f9a9fe46dc3ed37c9b44cd2b6561b324819fa81e Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Sat, 3 Sep 2022 15:24:48 +0200 Subject: [PATCH 059/106] ath(4): Fix two typos in source code comments - s/overriden/overridden/ MFC after: 3 days --- sys/dev/ath/ath_hal/ar5416/ar5416_reset.c | 4 ++-- sys/dev/ath/if_ath_tx.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c index f3d6fcab0d68..75445e1459a1 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c @@ -204,11 +204,11 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode, AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET); } - /* Override ini values (that can be overriden in this fashion) */ + /* Override ini values (that can be overridden in this fashion) */ ar5416OverrideIni(ah, chan); /* Setup 11n MAC/Phy mode registers */ - ar5416Set11nRegs(ah, chan); + ar5416Set11nRegs(ah, chan); OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); diff --git a/sys/dev/ath/if_ath_tx.c b/sys/dev/ath/if_ath_tx.c index b9de388f3ad8..46ac7889f3d6 100644 --- a/sys/dev/ath/if_ath_tx.c +++ b/sys/dev/ath/if_ath_tx.c @@ -1352,7 +1352,7 @@ ath_tx_setds(struct ath_softc *sc, struct ath_buf *bf) ); /* - * This will be overriden when the descriptor chain is written. + * This will be overridden when the descriptor chain is written. */ bf->bf_lastds = ds; bf->bf_last = bf; From 2b7d656f173d7bf26a0c3f66226e797cbce98edb Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Sat, 3 Sep 2022 15:26:55 +0200 Subject: [PATCH 060/106] kern: Fix a typo in asource code comment - s/overriden/overridden/ MFC after: 3 days --- sys/kern/subr_param.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/subr_param.c b/sys/kern/subr_param.c index bac028bd8e25..ebb21283c5f9 100644 --- a/sys/kern/subr_param.c +++ b/sys/kern/subr_param.c @@ -262,7 +262,7 @@ init_param2(long physpages) /* * The following can be overridden after boot via sysctl. Note: - * unless overriden, these macros are ultimately based on maxusers. + * unless overridden, these macros are ultimately based on maxusers. * Limit maxproc so that kmap entries cannot be exhausted by * processes. */ From 6b497700885b21106235a1ee7bfd31194e4ca42b Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Sat, 3 Sep 2022 15:28:05 +0200 Subject: [PATCH 061/106] pci(4): Fix a typo in asource code comment - s/overriden/overridden/ MFC after: 3 days --- sys/dev/pci/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index ed48e20b153e..335c89423f24 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -3331,7 +3331,7 @@ pci_add_map(device_t bus, device_t dev, int reg, struct resource_list *rl, * not allow that. It is best to ignore such entries for the * moment. These will be allocated later if the driver specifically * requests them. However, some removable buses look better when - * all resources are allocated, so allow '0' to be overriden. + * all resources are allocated, so allow '0' to be overridden. * * Similarly treat maps whose values is the same as the test value * read back. These maps have had all f's written to them by the From ac34f366cc8186ec747248f31079838699b389a6 Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Sat, 3 Sep 2022 15:30:39 +0200 Subject: [PATCH 062/106] sound(4): Fix a typo in asource code comment - s/overriden/overridden/ MFC after: 3 days --- sys/dev/sound/pci/hda/hdaa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/sound/pci/hda/hdaa.c b/sys/dev/sound/pci/hda/hdaa.c index 07531d17d8f2..8d1d749ffad1 100644 --- a/sys/dev/sound/pci/hda/hdaa.c +++ b/sys/dev/sound/pci/hda/hdaa.c @@ -2642,7 +2642,7 @@ hdaa_audio_ctl_set_defaults(struct hdaa_pcm_devinfo *pdevinfo) if ((pdevinfo->ossmask & (1 << dev)) == 0) continue; - /* If the value was overriden, leave it as is. */ + /* If the value was overridden, leave it as is. */ if (resource_int_value(device_get_name(pdevinfo->dev), device_get_unit(pdevinfo->dev), ossnames[dev], &vol) == 0) continue; From cc280cac3478d39a5231aec06d50ebd27b2aa1bb Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Sat, 3 Sep 2022 15:31:59 +0200 Subject: [PATCH 063/106] sdhci(4): Fix a typo in asource code comment - s/overriden/overridden/ MFC after: 3 days --- sys/dev/sdhci/sdhci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/sdhci/sdhci.h b/sys/dev/sdhci/sdhci.h index 4feb272bb359..b7d81969b47e 100644 --- a/sys/dev/sdhci/sdhci.h +++ b/sys/dev/sdhci/sdhci.h @@ -57,7 +57,7 @@ #define SDHCI_QUIRK_LOWER_FREQUENCY (1 << 9) /* Data timeout is invalid, should use SD clock */ #define SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK (1 << 10) -/* Timeout value is invalid, should be overriden */ +/* Timeout value is invalid, should be overridden */ #define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL (1 << 11) /* SDHCI_CAPABILITIES is invalid */ #define SDHCI_QUIRK_MISSING_CAPS (1 << 12) From b55a0762fc6336b309a8f9986b8af7512516a48c Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Sat, 3 Sep 2022 15:34:27 +0200 Subject: [PATCH 064/106] malo(4): Fix a typo in asource code comment - s/overriden/overridden/ MFC after: 3 days --- sys/dev/malo/if_malohal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/malo/if_malohal.h b/sys/dev/malo/if_malohal.h index b608eaba2abd..8322f18ef739 100644 --- a/sys/dev/malo/if_malohal.h +++ b/sys/dev/malo/if_malohal.h @@ -48,7 +48,7 @@ /* * Calibration data builtin to the firmware. The firmware image * has a single set of calibration tables that we retrieve right - * after download. This can be overriden by the driver (e.g. for + * after download. This can be overridden by the driver (e.g. for * a different regdomain and/or tx power setup). */ struct malo_hal_caldata { From f93ef3ff068c96062fadd503979473fe1b1db139 Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Sat, 3 Sep 2022 15:36:00 +0200 Subject: [PATCH 065/106] bxe(4): Fix two typos in source code comments - s/overriden/overridden/ MFC after: 3 days --- sys/dev/bxe/bxe_elink.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/bxe/bxe_elink.c b/sys/dev/bxe/bxe_elink.c index dd77e9301ab0..52b375816cfc 100644 --- a/sys/dev/bxe/bxe_elink.c +++ b/sys/dev/bxe/bxe_elink.c @@ -4578,7 +4578,7 @@ static void elink_warpcore_enable_AN_KR(struct elink_phy *phy, {MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_TX_FIR_TAP, 0}, }; ELINK_DEBUG_P0(sc, "Enable Auto Negotiation for KR\n"); - /* Set to default registers that may be overriden by 10G force */ + /* Set to default registers that may be overridden by 10G force */ for (i = 0; i < ARRAY_SIZE(reg_set); i++) elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg, reg_set[i].val); @@ -7773,7 +7773,7 @@ elink_status_t elink_link_update(struct elink_params *params, struct elink_vars * hence its link is expected to be down * - SECOND_PHY means that first phy should not be able * to link up by itself (using configuration) - * - DEFAULT should be overriden during initialiazation + * - DEFAULT should be overridden during initialiazation */ ELINK_DEBUG_P1(sc, "Invalid link indication" "mpc=0x%x. DISABLING LINK !!!\n", From de47bf0d52a0dd2cfcb19a8b49a55253945342ca Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Sat, 3 Sep 2022 15:38:26 +0200 Subject: [PATCH 066/106] bge(4): Fix a typo in a source code comment - s/overriden/overridden/ MFC after: 3 days --- sys/dev/bge/if_bge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 7133e1b7d002..eb72af69a448 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -130,7 +130,7 @@ MODULE_DEPEND(bge, miibus, 1, 1, 1); /* * Various supported device vendors/types and their names. Note: the * spec seems to indicate that the hardware still has Alteon's vendor - * ID burned into it, though it will always be overriden by the vendor + * ID burned into it, though it will always be overridden by the vendor * ID in the EEPROM. Just to be safe, we cover all possibilities. */ static const struct bge_type { From ddf38e0204f8146709d3a278520873a68d1802a4 Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Sat, 3 Sep 2022 15:39:51 +0200 Subject: [PATCH 067/106] bce(4): Fix a typo in a source code comment - s/overriden/overridden/ MFC after: 3 days --- sys/dev/bce/if_bcereg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/bce/if_bcereg.h b/sys/dev/bce/if_bcereg.h index ed63c44c6a87..0aa3eda3a97d 100644 --- a/sys/dev/bce/if_bcereg.h +++ b/sys/dev/bce/if_bcereg.h @@ -411,7 +411,7 @@ u32 bce_debug_temp = bce_debug; \ bce_debug |= cond; -/* Restore the previously overriden debug level. */ +/* Restore the previously overridden debug level. */ #define DBPOP() \ bce_debug = bce_debug_temp; From b0e86eed27ec98204978685d4d3dd384267dd60f Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Sat, 3 Sep 2022 15:43:05 +0200 Subject: [PATCH 068/106] ltc430x(4): Fix a typo in a source code comment - s/overriden/overridden/ MFC after: 3 days --- sys/dev/iicbus/mux/ltc430x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/iicbus/mux/ltc430x.c b/sys/dev/iicbus/mux/ltc430x.c index 365a1d1e55d8..d18f60c5cc7f 100644 --- a/sys/dev/iicbus/mux/ltc430x.c +++ b/sys/dev/iicbus/mux/ltc430x.c @@ -168,7 +168,7 @@ ltc430x_attach(device_t dev) /* * Check for the idle-disconnect and ctlreg2 options, first in FDT data, - * then allow them to be overriden by hints data. + * then allow them to be overridden by hints data. */ #ifdef FDT phandle_t node; From 2c9fd7655ba54e7239f528e1af9fe09662de9b03 Mon Sep 17 00:00:00 2001 From: "Alfonso S. Siciliano" Date: Sat, 3 Sep 2022 16:36:16 +0200 Subject: [PATCH 069/106] contrib/bsddialog: Import version 0.3 New features overview: * Unicode. User interface handles multi-column characters. API can handle char* like a multibyte character string. Internally wide characters are used for keyboard input, to adapt word wrapping and dynamic text auto-sizing for multi-column characters. * Forms refactoring. Complete rewrite deleting libformw dependency. * Theme. New utility options to save and load custom theme at run-time. * TUI navigation. Added keys to navigate input components. Changed default focus behavior of input dialogs to be LGPL-dialog-like; a new option can set the previous whiptail-like behavior. See /usr/src/contrib/bsddialog/CHANGELOG '2022-08-29 Version 0.3' for more detailed information. --- .gitignore | 2 + CHANGELOG | 77 +- GNUMakefile | 2 +- Makefile | 2 +- README.md | 25 +- bsddialog.1 | 216 ++++-- bsddialog.c | 260 ++++--- examples_library/compile | 4 +- examples_library/datebox.c | 4 +- examples_library/form.c | 12 +- examples_library/formw.c | 61 -- examples_library/timebox.c | 4 +- examples_utility/form.sh | 10 +- examples_utility/mixedform.sh | 6 +- examples_utility/passwordform.sh | 10 +- lib/GNUMakefile | 6 +- lib/Makefile | 4 +- lib/barbox.c | 78 +- lib/bsddialog.3 | 172 +++-- lib/bsddialog.h | 20 +- lib/bsddialog_theme.h | 17 +- lib/formbox.c | 1145 ++++++++++++++++++++---------- lib/infobox.c | 6 +- lib/lib_util.c | 551 ++++++++++---- lib/lib_util.h | 16 +- lib/libbsddialog.c | 19 +- lib/menubox.c | 155 ++-- lib/messagebox.c | 63 +- lib/textbox.c | 117 ++- lib/theme.c | 187 +++-- lib/timebox.c | 190 ++--- util_theme.c | 356 ++++++++++ util_theme.h | 35 + 33 files changed, 2670 insertions(+), 1162 deletions(-) delete mode 100644 examples_library/formw.c create mode 100644 util_theme.c create mode 100644 util_theme.h diff --git a/.gitignore b/.gitignore index 62f7b594a708..10a6663fbb47 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ examples_library/checklist examples_library/datebox examples_library/form examples_library/formw +examples_library/margin examples_library/menu examples_library/mixedlist examples_library/radiolist @@ -19,6 +20,7 @@ examples_library/rangebox examples_library/sade examples_library/timebox examples_library/yesno +examples_library/u_msgbox *.gz lib/libbsddialog.so* BSDDIALOG.geany diff --git a/CHANGELOG b/CHANGELOG index 22eb3342cfe2..d6de6928c111 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,77 @@ -2022-03-02 version 0.2 +2022-08-29 Version 0.3 + + Utility: + * add: --textbox accepts options for the first button. + * add: --columns-per-row option for text autosizing. + * add: --load-theme option to read and set a custom theme at runtime. + * add: --save-theme option to save current theme. + * add: --bikeshed option for random settings. + * add: --switch-buttons enables focus switching: buttons / input + components. Available for: --form, --inputbox, --mixedform, + --passwordform, --passwordbox, --timebox and --datebox. + * change: rename --esc-cancelvalue to --esc-return-cancel. + * change: form field value is printed like multibyte charachter string, + previously widechar string. + * fix: --hline with empty string. + * fix: avoid to overlay the backtitle by setting a top margin. + * fix: avoid to overlay down shadow with menus and forms bottomdesc + by setting a down margin. + * fix: --form read-only flag with multiple fields. + + Library: + * add: conf.auto_topmargin and conf.auto_downmargin. + * add: bsddialog_textbox() accepts conf.button.* for the first button. + * add: bsddialog_textbox() arrows and percentage. + * add: conf.text.cols_per_row to set a ratio for text autosizing. + * add: timebox and datebox arrows and focus background for boxes. + * add: timebox and datebox UP key to switch focus. + * add: bsddialog_init_notheme() in bsddialo_theme.h. + * add: bsddialog_hascolors() in bsddialo_theme.h. + * add: theme.form.bottomdesccolor and theme.menu.bottomdesccolor. + * add: conf.button.always_active to disable buttons/input-boxes switch. + * add: dynamic buttons margin. + - add: theme.button.minmargin and theme.button.maxmargin. + - delete: theme.button.hmargin. + * add: Unicode. + - UI handles multicolumn charachters: backtitle, title, + text (word wrapping, autosizing), menus (shortcuts, name, desc), + forms (label, field), textbox, mixedgauge (minilabel), + buttons (label, shortcuts), bottomtitle. + - API handles char* arguments like multibyte charachter string, + depending on the current locale. + - Internally wide charachters are used to get input from keyboard + and to adapt word wrapping and dynamic text autosizing to + muticolumn charachters. + * refactoring: (rewrite) form.c. + - delete: libformw dep implementing its features from scratch. + - delete: maxvaluelen >= valuelen constraint. + - delete: conf.form.enable_wchar, get always unicode (wchar) input. + - add: KEY_HOME, KEY_END, KEY_PPAGE, KEY_NPAGE keys in field. + - add: KEY_UP can move focus from buttons to fields. + - add: KEY_DOWN can move focus from item to buttons, if nitem is 1. + - add: conf.form.securembch secure multibyte charachter. + - add: BSDDIALOG_FIELDNOCOLOR for formitem.flags. + - add: BSDDIALOG_FIELDCURSOREND for formitem.flags. + - add: BSDDIALOG_FIELDEXTEND for formitem.flags. + - add: BSDDIALOG_FIELDSINGLEBYTE for formitem.flags. + - add: resizing and refresh after KEY_RESIZE (SIGWINCH). + - add: items scrolling. + - add: conf.form.value_wchar, value is wchar_t* instead of MB-char*. + - add: formheight autosizing. + - add: dynamic item position. + * fix: bsddialog_gauge() with fd < 0. + * fix: internal segmentation fault with disabled shadow. + * fix: bsddialog_gauge() refresh new text. + * fix: center position without shadow. + * fix: bsddialog_infobox() with zero text length. + * fix: text wrapping with more than 1024 words. + * fix: rename theme.shadow.h to theme.shadow.y. + * fix: rename theme.shadow.w to theme.shadow.x. + * fix: menurows autosize with fixed rows improving text_size(). + * fix: messagebox.c scrolling and checksize without text. + + +2022-03-02 Version 0.2 Utility: * add: (this) CHANGELOG. @@ -31,7 +104,7 @@ * improve: "menus" colors for accessibility. -2022-01-27 version 0.1 +2022-01-27 Version 0.1 * Common-Options: --ascii-lines, --backtitle , --begin-x , --begin-y , --cancel-label