? distrib/socppc ? distrib/alpha/bsd.rd ? distrib/alpha/cdfs ? distrib/amd64/cdfs ? distrib/arm64/miniroot ? distrib/i386/cdfs ? distrib/landisk/miniroot ? distrib/loongson/miniroot ? distrib/luna88k/miniroot ? distrib/octeon/boot ? distrib/octeon/miniroot ? distrib/sparc64/bsd.rd ? distrib/sparc64/cdfs ? etc/etc.socppc ? gnu/usr.bin/perl/cpan/Unicode-Collate/Collate/.new.allkeys.t ? lib/libcrypto/man/PKCS7_dataFinal.3 ? lib/libcrypto/man/PKCS7_dataInit.3 ? lib/libcrypto/man/PKCS7_final.3 ? lib/libpcap/10 ? regress/lib/libc/asr/bin/getaddrinfo/common.d ? regress/lib/libc/asr/bin/getaddrinfo/getaddrinfo.b ? regress/lib/libc/asr/bin/getaddrinfo/getaddrinfo.d ? regress/lib/libc/asr/bin/gethostnamadr/common.d ? regress/lib/libc/asr/bin/gethostnamadr/gethostnamadr.b ? regress/lib/libc/asr/bin/gethostnamadr/gethostnamadr.d ? regress/lib/libc/asr/bin/getnameinfo/common.d ? regress/lib/libc/asr/bin/getnameinfo/getnameinfo.b ? regress/lib/libc/asr/bin/getnameinfo/getnameinfo.d ? regress/lib/libc/asr/bin/getnetnamadr/common.d ? regress/lib/libc/asr/bin/getnetnamadr/getnetnamadr.b ? regress/lib/libc/asr/bin/getnetnamadr/getnetnamadr.d ? regress/lib/libc/asr/bin/getrrsetbyname/common.d ? regress/lib/libc/asr/bin/getrrsetbyname/getrrsetbyname.b ? regress/lib/libc/asr/bin/getrrsetbyname/getrrsetbyname.d ? regress/lib/libc/asr/bin/res_mkquery/common.d ? regress/lib/libc/asr/bin/res_mkquery/res_mkquery.b ? regress/lib/libc/asr/bin/res_mkquery/res_mkquery.d ? regress/lib/libc/asr/bin/res_query/common.d ? regress/lib/libc/asr/bin/res_query/res_query.b ? regress/lib/libc/asr/bin/res_query/res_query.d ? regress/lib/libc/asr/bin/threads/common.d ? regress/lib/libc/asr/bin/threads/threads.b ? regress/lib/libc/asr/bin/threads/threads.d ? regress/sys/net/toeplitz ? regress/usr.sbin/syslogd/args-socket-udp-close.pl ? regress/usr.sbin/syslogd/args-socket-udp-keep.pl ? share/man/man4/acpihid.4 ? share/man/man4/man4.socppc ? share/man/man4/umstc.4 ? share/man/man8/man8.socppc ? share/man/man9/kstat_create.9 ? sys/cscope.out ? sys/arch/socppc ? sys/arch/amd64/compile/GENERIC.MP.PROF ? sys/arch/amd64/compile/PROFILED.MP ? sys/arch/amd64/compile/WITNESS.MP ? sys/arch/amd64/conf/PROFILED.MP ? sys/arch/amd64/conf/WITNESS.MP ? sys/dev/pci/if_mcx.c.min_delay ? sys/net/if_macsec.c ? sys/net/if_macsec.h ? sys/net/if_tg.c ? usr.sbin/snmpctl Index: Makefile =================================================================== RCS file: /cvs/src/Makefile,v retrieving revision 1.136 diff -u -p -r1.136 Makefile --- Makefile 5 Apr 2020 20:14:14 -0000 1.136 +++ Makefile 22 Nov 2021 03:07:57 -0000 @@ -37,7 +37,7 @@ .include # for NOMAN, if it's there. SUBDIR+= lib include bin libexec sbin usr.bin usr.sbin share games -SUBDIR+= gnu +#SUBDIR+= gnu SUBDIR+= sys Index: etc/services =================================================================== RCS file: /cvs/src/etc/services,v retrieving revision 1.103 diff -u -p -r1.103 services --- etc/services 2 Sep 2021 10:46:22 -0000 1.103 +++ etc/services 22 Nov 2021 03:08:01 -0000 @@ -309,6 +309,21 @@ spamd-cfg 8026/tcp # spamd(8) configur dhcpd-sync 8067/udp # dhcpd(8) synchronisation hunt 26740/udp # hunt(6) # +# GRE Protocol Types +# +keepalive 0/gre # 0x0000: IP tunnel keepalive +ipv4 2048/gre # 0x0800: IPv4 +nhrp 8193/gre # 0x2001: Next Hop Resolution Protocol +erspan3 8939/gre # 0x22eb: ERSPAN III +transether 25944/gre ethernet # 0x6558: Trans Ether Bridging +ipv6 34525/gre # 0x86dd: IPv6 +wccp 34878/gre # 0x883e: Web Content Cache Protocol +mpls 34887/gre # 0x8847: MPLS +#mpls 34888/gre # 0x8848: MPLS Multicast +erspan 35006/gre erspan2 # 0x88be: ERSPAN I/II +nsh 35151/gre # 0x894f: Network Service Header +control 47082/gre # 0xb7ea: RFC 8157 +# # Appletalk # rtmp 1/ddp # Routing Table Maintenance Protocol Index: lib/libc/asr/getaddrinfo_async.c =================================================================== RCS file: /cvs/src/lib/libc/asr/getaddrinfo_async.c,v retrieving revision 1.56 diff -u -p -r1.56 getaddrinfo_async.c --- lib/libc/asr/getaddrinfo_async.c 3 Nov 2018 09:13:24 -0000 1.56 +++ lib/libc/asr/getaddrinfo_async.c 22 Nov 2021 03:09:15 -0000 @@ -34,36 +34,15 @@ #include "asr_private.h" -struct match { - int family; - int socktype; - int protocol; -}; - static int getaddrinfo_async_run(struct asr_query *, struct asr_result *); static int get_port(const char *, const char *, int); +static int get_service(const char *, int, int); static int iter_family(struct asr_query *, int); static int addrinfo_add(struct asr_query *, const struct sockaddr *, const char *); static int addrinfo_from_file(struct asr_query *, int, FILE *); static int addrinfo_from_pkt(struct asr_query *, char *, size_t); static int addrconfig_setup(struct asr_query *); -static const struct match matches[] = { - { PF_INET, SOCK_DGRAM, IPPROTO_UDP }, - { PF_INET, SOCK_STREAM, IPPROTO_TCP }, - { PF_INET, SOCK_RAW, 0 }, - { PF_INET6, SOCK_DGRAM, IPPROTO_UDP }, - { PF_INET6, SOCK_STREAM, IPPROTO_TCP }, - { PF_INET6, SOCK_RAW, 0 }, - { -1, 0, 0, }, -}; - -#define MATCH_FAMILY(a, b) ((a) == matches[(b)].family || (a) == PF_UNSPEC) -#define MATCH_PROTO(a, b) ((a) == matches[(b)].protocol || (a) == 0 || matches[(b)].protocol == 0) -/* Do not match SOCK_RAW unless explicitly specified */ -#define MATCH_SOCKTYPE(a, b) ((a) == matches[(b)].socktype || ((a) == 0 && \ - matches[(b)].socktype != SOCK_RAW)) - enum { DOM_INIT, DOM_DOMAIN, @@ -199,24 +178,27 @@ getaddrinfo_async_run(struct asr_query * } } - /* Make sure there is at least a valid combination */ - for (i = 0; matches[i].family != -1; i++) - if (MATCH_FAMILY(ai->ai_family, i) && - MATCH_SOCKTYPE(ai->ai_socktype, i) && - MATCH_PROTO(ai->ai_protocol, i)) - break; - if (matches[i].family == -1) { - ar->ar_gai_errno = EAI_BADHINTS; - async_set_state(as, ASR_STATE_HALT); - break; - } - - if (ai->ai_protocol == 0 || ai->ai_protocol == IPPROTO_UDP) + switch (ai->ai_protocol) { + case 0: as->as.ai.port_udp = get_port(as->as.ai.servname, "udp", as->as.ai.hints.ai_flags & AI_NUMERICSERV); - if (ai->ai_protocol == 0 || ai->ai_protocol == IPPROTO_TCP) as->as.ai.port_tcp = get_port(as->as.ai.servname, "tcp", as->as.ai.hints.ai_flags & AI_NUMERICSERV); + break; + case IPPROTO_TCP: + as->as.ai.port_tcp = get_port(as->as.ai.servname, "tcp", + as->as.ai.hints.ai_flags & AI_NUMERICSERV); + break; + case IPPROTO_UDP: + as->as.ai.port_udp = get_port(as->as.ai.servname, "udp", + as->as.ai.hints.ai_flags & AI_NUMERICSERV); + break; + default: + as->as.ai.port_udp = get_service(as->as.ai.servname, + ai->ai_protocol, + as->as.ai.hints.ai_flags & AI_NUMERICSERV); + break; + } if (as->as.ai.port_tcp == -2 || as->as.ai.port_udp == -2 || (as->as.ai.port_tcp == -1 && as->as.ai.port_udp == -1) || (ai->ai_protocol && (as->as.ai.port_udp == -1 || @@ -491,6 +473,24 @@ get_port(const char *servname, const cha return (port); } +static int +get_service(const char *servname, int protocol, int numonly) +{ + struct protoent pe; + struct protoent_data ped; + int rv; + + memset(&ped, 0, sizeof(ped)); + rv = getprotobynumber_r(protocol, &pe, &ped); + if (rv == -1) + return (-1); + + rv = get_port(servname, pe.p_name, numonly); + endprotoent_r(&ped); + + return (rv); +} + /* * Iterate over the address families that are to be queried. Use the * list on the async context, unless a specific family was given in hints. @@ -519,65 +519,107 @@ iter_family(struct asr_query *as, int fi * entry per protocol/socktype match. */ static int -addrinfo_add(struct asr_query *as, const struct sockaddr *sa, const char *cname) +addrinfo_add_ai(struct asr_query *as, const struct sockaddr *sa, + const char *cname, int socktype, int proto, int port) { struct addrinfo *ai; - int i, port, proto; - - for (i = 0; matches[i].family != -1; i++) { - if (matches[i].family != sa->sa_family || - !MATCH_SOCKTYPE(as->as.ai.hints.ai_socktype, i) || - !MATCH_PROTO(as->as.ai.hints.ai_protocol, i)) - continue; - - proto = as->as.ai.hints.ai_protocol; - if (!proto) - proto = matches[i].protocol; - - if (proto == IPPROTO_TCP) - port = as->as.ai.port_tcp; - else if (proto == IPPROTO_UDP) - port = as->as.ai.port_udp; - else - port = 0; + int i; - /* servname specified, but not defined for this protocol */ - if (port == -1) - continue; + if (port == -1) + return (0); - ai = calloc(1, sizeof(*ai) + sa->sa_len); - if (ai == NULL) + ai = calloc(1, sizeof(*ai) + sa->sa_len); + if (ai == NULL) + return (EAI_MEMORY); + ai->ai_family = sa->sa_family; + ai->ai_socktype = socktype; + ai->ai_protocol = proto; + ai->ai_flags = as->as.ai.hints.ai_flags; + ai->ai_addrlen = sa->sa_len; + ai->ai_addr = (void *)(ai + 1); + if (cname && + as->as.ai.hints.ai_flags & (AI_CANONNAME | AI_FQDN)) { + if ((ai->ai_canonname = strdup(cname)) == NULL) { + free(ai); return (EAI_MEMORY); - ai->ai_family = sa->sa_family; - ai->ai_socktype = matches[i].socktype; - ai->ai_protocol = proto; - ai->ai_flags = as->as.ai.hints.ai_flags; - ai->ai_addrlen = sa->sa_len; - ai->ai_addr = (void *)(ai + 1); - if (cname && - as->as.ai.hints.ai_flags & (AI_CANONNAME | AI_FQDN)) { - if ((ai->ai_canonname = strdup(cname)) == NULL) { - free(ai); - return (EAI_MEMORY); - } } - memmove(ai->ai_addr, sa, sa->sa_len); - if (sa->sa_family == PF_INET) - ((struct sockaddr_in *)ai->ai_addr)->sin_port = - htons(port); - else if (sa->sa_family == PF_INET6) - ((struct sockaddr_in6 *)ai->ai_addr)->sin6_port = - htons(port); - - if (as->as.ai.aifirst == NULL) - as->as.ai.aifirst = ai; - if (as->as.ai.ailast) - as->as.ai.ailast->ai_next = ai; - as->as.ai.ailast = ai; - as->as_count += 1; } + memmove(ai->ai_addr, sa, sa->sa_len); + if (sa->sa_family == PF_INET) + ((struct sockaddr_in *)ai->ai_addr)->sin_port = + htons(port); + else if (sa->sa_family == PF_INET6) + ((struct sockaddr_in6 *)ai->ai_addr)->sin6_port = + htons(port); + + if (as->as.ai.aifirst == NULL) + as->as.ai.aifirst = ai; + if (as->as.ai.ailast) + as->as.ai.ailast->ai_next = ai; + as->as.ai.ailast = ai; + as->as_count += 1; return (0); +} + +static int +addrinfo_add_proto(struct asr_query *as, const struct sockaddr *sa, + const char *cname, int proto, int port) +{ + int rv; + + switch (as->as.ai.hints.ai_socktype) { + case 0: + rv = addrinfo_add_ai(as, sa, cname, SOCK_STREAM, proto, port); + if (rv != 0) + break; + + rv = addrinfo_add_ai(as, sa, cname, SOCK_DGRAM, proto, port); + if (rv != 0) + break; + + break; + + default: + rv = addrinfo_add_ai(as, sa, cname, + as->as.ai.hints.ai_socktype, proto, port); + break; + } + + return (rv); +} + +static int +addrinfo_add(struct asr_query *as, const struct sockaddr *sa, const char *cname) +{ + int rv; + + switch (as->as.ai.hints.ai_protocol) { + case 0: + rv = addrinfo_add_proto(as, sa, cname, + IPPROTO_TCP, as->as.ai.port_tcp); + if (rv != 0) + break; + + rv = addrinfo_add_proto(as, sa, cname, + IPPROTO_UDP, as->as.ai.port_udp); + if (rv != 0) + break; + + break; + + case IPPROTO_TCP: + rv = addrinfo_add_proto(as, sa, cname, + IPPROTO_TCP, as->as.ai.port_tcp); + break; + + default: /* includes IPPROTO_UDP */ + rv = addrinfo_add_proto(as, sa, cname, + as->as.ai.hints.ai_protocol, as->as.ai.port_udp); + break; + } + + return (rv); } static int Index: lib/libpcap/gencode.c =================================================================== RCS file: /cvs/src/lib/libpcap/gencode.c,v retrieving revision 1.55 diff -u -p -r1.55 gencode.c --- lib/libpcap/gencode.c 3 Aug 2020 03:40:02 -0000 1.55 +++ lib/libpcap/gencode.c 22 Nov 2021 03:09:17 -0000 @@ -1255,6 +1255,9 @@ gen_host(addr, mask, proto, dir) case Q_STP: bpf_error("'stp' modifier applied to host"); + case Q_LACP: + bpf_error("'lacp' modifier applied to host"); + case Q_ATALK: bpf_error("ATALK host filtering not implemented"); @@ -1337,6 +1340,9 @@ gen_host6(addr, mask, proto, dir) case Q_STP: bpf_error("'stp' modifier applied to host"); + case Q_LACP: + bpf_error("'lacp' modifier applied to host"); + case Q_ATALK: bpf_error("ATALK host filtering not implemented"); @@ -1512,6 +1518,22 @@ gen_proto_abbrev(proto) case Q_STP: b1 = gen_linktype(LLCSAP_8021D); + break; + + case Q_LACP: + if (linktype != DLT_EN10MB) { + b1 = gen_false(); + break; + } + + /* SLOWPROTOCOLS_SUBTYPE_LACP */ + b0 = gen_cmp(off_linktype + 2, BPF_B, 1); + /* SLOWPROTOCOLS_SUBTYPE_LACP_MARKER */ + b1 = gen_cmp(off_linktype + 2, BPF_B, 2); + gen_or(b0, b1); + + b0 = gen_cmp(off_linktype, BPF_H, ETHERTYPE_SLOW); + gen_and(b0, b1); break; #ifdef INET6 Index: lib/libpcap/gencode.h =================================================================== RCS file: /cvs/src/lib/libpcap/gencode.h,v retrieving revision 1.21 diff -u -p -r1.21 gencode.h --- lib/libpcap/gencode.h 3 Aug 2020 03:40:02 -0000 1.21 +++ lib/libpcap/gencode.h 22 Nov 2021 03:09:17 -0000 @@ -58,6 +58,7 @@ #define Q_PIM 20 #define Q_STP 21 +#define Q_LACP 22 /* Directional qualifiers. */ Index: lib/libpcap/grammar.y =================================================================== RCS file: /cvs/src/lib/libpcap/grammar.y,v retrieving revision 1.22 diff -u -p -r1.22 grammar.y --- lib/libpcap/grammar.y 3 Aug 2020 03:40:02 -0000 1.22 +++ lib/libpcap/grammar.y 22 Nov 2021 03:09:17 -0000 @@ -104,7 +104,7 @@ pcap_parse() %token DST SRC HOST GATEWAY %token NET MASK PORT LESS GREATER PROTO PROTOCHAIN BYTE %token ARP RARP IP TCP UDP ICMP IGMP IGRP PIM -%token ATALK DECNET LAT SCA MOPRC MOPDL STP +%token ATALK DECNET LAT SCA MOPRC MOPDL STP LACP %token TK_BROADCAST TK_MULTICAST %token NUM INBOUND OUTBOUND %token PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION @@ -269,6 +269,7 @@ pname: LINK { $$ = Q_LINK; } | AH { $$ = Q_AH; } | ESP { $$ = Q_ESP; } | STP { $$ = Q_STP; } + | LACP { $$ = Q_LACP; } ; other: pqual TK_BROADCAST { $$ = gen_broadcast($1); } | pqual TK_MULTICAST { $$ = gen_multicast($1); } Index: lib/libpcap/pcap-bpf.c =================================================================== RCS file: /cvs/src/lib/libpcap/pcap-bpf.c,v retrieving revision 1.37 diff -u -p -r1.37 pcap-bpf.c --- lib/libpcap/pcap-bpf.c 28 Jun 2019 13:32:42 -0000 1.37 +++ lib/libpcap/pcap-bpf.c 22 Nov 2021 03:09:17 -0000 @@ -63,6 +63,8 @@ pcap_stats(pcap_t *p, struct pcap_stat * ps->ps_recv = s.bs_recv; ps->ps_drop = s.bs_drop; + ps->ps_ifdrop = s.bs_ifdrop; + return (0); } Index: lib/libpcap/scanner.l =================================================================== RCS file: /cvs/src/lib/libpcap/scanner.l,v retrieving revision 1.28 diff -u -p -r1.28 scanner.l --- lib/libpcap/scanner.l 3 Aug 2020 03:40:02 -0000 1.28 +++ lib/libpcap/scanner.l 22 Nov 2021 03:09:17 -0000 @@ -193,6 +193,7 @@ sca return SCA; moprc return MOPRC; mopdl return MOPDL; stp return STP; +lacp return LACP; host return HOST; net return NET; Index: lib/libutil/openpty.3 =================================================================== RCS file: /cvs/src/lib/libutil/openpty.3,v retrieving revision 1.19 diff -u -p -r1.19 openpty.3 --- lib/libutil/openpty.3 20 Apr 2017 19:30:42 -0000 1.19 +++ lib/libutil/openpty.3 22 Nov 2021 03:09:17 -0000 @@ -42,6 +42,7 @@ .Nm fdforkpty .Nd tty utility functions .Sh SYNOPSIS +.Lb libutil .In termios.h .In util.h .Ft int Index: regress/usr.sbin/ospfd/Client.pm =================================================================== RCS file: /cvs/src/regress/usr.sbin/ospfd/Client.pm,v retrieving revision 1.7 diff -u -p -r1.7 Client.pm --- regress/usr.sbin/ospfd/Client.pm 30 Jan 2020 13:03:46 -0000 1.7 +++ regress/usr.sbin/ospfd/Client.pm 22 Nov 2021 03:09:27 -0000 @@ -351,7 +351,7 @@ sub child { if ($ENV{KTRACE}) { my @ktrace = $ENV{KTRACE}; - push @ktrace, "-i", "-f", "client.ktrace", "-p", $$; + push @ktrace, "-a", "-i", "-f", "client.ktrace", "-p", $$; system(@ktrace) and die "Command '@ktrace' failed: $?"; } Index: regress/usr.sbin/ospfd/Ospfd.pm =================================================================== RCS file: /cvs/src/regress/usr.sbin/ospfd/Ospfd.pm,v retrieving revision 1.4 diff -u -p -r1.4 Ospfd.pm --- regress/usr.sbin/ospfd/Ospfd.pm 30 Jan 2020 13:03:46 -0000 1.4 +++ regress/usr.sbin/ospfd/Ospfd.pm 22 Nov 2021 03:09:27 -0000 @@ -68,7 +68,7 @@ sub child { my $self = shift; my @sudo = $ENV{SUDO} ? $ENV{SUDO} : (); my @ktrace = $ENV{KTRACE} || (); - push @ktrace, "-i", "-f", "ospfd.ktrace" if @ktrace; + push @ktrace, "-a", "-i", "-f", "ospfd.ktrace" if @ktrace; my $ospfd = $ENV{OSPFD} ? $ENV{OSPFD} : "ospfd"; my @cmd = (@sudo, @ktrace, $ospfd, "-dv", "-f", $self->{conffile}); print STDERR "execute: @cmd\n"; Index: sbin/ifconfig/brconfig.c =================================================================== RCS file: /cvs/src/sbin/ifconfig/brconfig.c,v retrieving revision 1.25 diff -u -p -r1.25 brconfig.c --- sbin/ifconfig/brconfig.c 22 Jan 2020 06:24:07 -0000 1.25 +++ sbin/ifconfig/brconfig.c 22 Nov 2021 03:09:27 -0000 @@ -763,21 +763,17 @@ int is_bridge() { struct ifreq ifr; - struct ifbaconf ifbac; + struct if_data ifrdat; + + bzero(&ifrdat, sizeof(ifrdat)); strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + ifr.ifr_data = (caddr_t)&ifrdat; - if (ioctl(sock, SIOCGIFFLAGS, (caddr_t)&ifr) == -1) + if (ioctl(sock, SIOCGIFDATA, (caddr_t)&ifr) == -1) return (0); - ifbac.ifbac_len = 0; - strlcpy(ifbac.ifbac_name, ifname, sizeof(ifbac.ifbac_name)); - if (ioctl(sock, SIOCBRDGRTS, (caddr_t)&ifbac) == -1) { - if (errno == ENETDOWN) - return (1); - return (0); - } - return (1); + return (ifrdata.ifi_type == IFT_BRIDGE); } void @@ -786,11 +782,7 @@ bridge_status(void) struct ifreq ifr; struct ifbrparam bp1, bp2; - if (!is_bridge() || is_switch()) - return; - - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(sock, SIOCGIFFLAGS, (caddr_t)&ifr) == -1) + if (!is_bridge()) return; bridge_cfg("\t"); Index: sbin/pfctl/parse.y =================================================================== RCS file: /cvs/src/sbin/pfctl/parse.y,v retrieving revision 1.701 diff -u -p -r1.701 parse.y --- sbin/pfctl/parse.y 28 Jan 2020 15:40:35 -0000 1.701 +++ sbin/pfctl/parse.y 22 Nov 2021 03:09:28 -0000 @@ -492,15 +492,17 @@ int parseport(char *, struct range *r, i %token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY PFLOW MAXPKTRATE %token TAGGED TAG IFBOUND FLOATING STATEPOLICY STATEDEFAULTS ROUTE %token DIVERTTO DIVERTREPLY DIVERTPACKET NATTO AFTO RDRTO RECEIVEDON NE LE GE +%token DIVERTTO DIVERTREPLY DIVERTPACKET NATTO AFTO RDRTO RECEIVEDON NE LE GE +%token PATH FORWARD REPLY %token STRING %token NUMBER %token PORTBINARY %type interface if_list if_item_not if_item -%type number icmptype icmp6type uid gid +%type number icmptype icmp6type uid gid pathid %type tos not yesno optnodf %type probability %type optweight -%type dir af optimizer syncookie_val +%type dir af optimizer syncookie_val pathdir %type sourcetrack flush unaryop statelock %type action %type flags flag blockspec prio @@ -546,6 +548,7 @@ ruleset : /* empty */ | ruleset include '\n' | ruleset '\n' | ruleset option '\n' + | ruleset pathdef '\n' | ruleset pfrule '\n' | ruleset anchorrule '\n' | ruleset loadrule '\n' @@ -707,6 +710,38 @@ option : SET REASSEMBLE yesno optnodf } ; +pathdef : pathid ON STRING { + struct pfctl_path *p; + + /* XXX check if the interface exists? */ + + TAILQ_FOREACH(p, pf->paths, p_entry) { + if (p->p_id == $1) { + yyerror("duplicate path id %lld, " + "original on %s at %s:%d", + $1, p->p_iface, + p->p_file, p->p_lineno); + free($4); + YYERROR; + } + } + + p = malloc(sizeof(*p)); + if (p == NULL) + err(1, "path malloc"); + + p->p_id = $1; + p->p_iface = $2; + + /* pretty errors */ + p->lineno = yylval.lineno; + p->file = strdup(file->name); + if (p->file == NULL) + err(1, "path filename malloc"); + + TAILQ_INSERT_TAIL(pf->paths, p, p_entry); + } + syncookie_val : STRING { if (!strcmp($1, "never")) $$ = PF_SYNCOOKIES_NEVER; @@ -2155,6 +2190,18 @@ filter_opt : USER uids { if ($3.key != NULL) filter_opts.route.key = $3.key; } + | pathdir pathid { + struct pfctl_path *p; + + /* check if the direction is already specified */ + + p = pfctl_path_get(pf, $2); + + if (p == NULL) { + yyerror("path %lld is not defined", $2); + YYERROR; + } + } | not RECEIVEDON if_item { if (filter_opts.rcv) { yyerror("cannot respecify received-on"); @@ -3101,6 +3148,21 @@ gid : STRING { } ; +pathop : FORWARD { $$ = PF_PATH_FORWARD; } + | REPLY { $$ = PF_PATH_REPLY; } + ; + +pathid : PATH NUMBER { + if ($2 < PF_PATH_ID_MIN || $2 > PF_PATH_ID_MAX) { + yyerror("path %lld id is out of range %u-%u", + $2, PF_PATH_ID_MIN, PF_PATH_ID_MAX); + YYERROR; + } + + $$ = $2; + } + ; + flag : STRING { int f; @@ -5049,6 +5111,7 @@ lookup(char *s) { "flows", FLOWS}, { "flush", FLUSH}, { "for", FOR}, + { "forward", FORWARD}, { "fragment", FRAGMENT}, { "from", FROM}, { "global", GLOBAL}, @@ -5093,6 +5156,7 @@ lookup(char *s) { "overload", OVERLOAD}, { "parent", PARENT}, { "pass", PASS}, + { "path", PATH}, { "pflow", PFLOW}, { "port", PORT}, { "prio", PRIO}, @@ -5108,6 +5172,7 @@ lookup(char *s) { "rdr-to", RDRTO}, { "reassemble", REASSEMBLE}, { "received-on", RECEIVEDON}, + { "reply", REPLY}, { "reply-to", REPLYTO}, { "return", RETURN}, { "return-icmp", RETURNICMP}, Index: sbin/pfctl/pfctl.c =================================================================== RCS file: /cvs/src/sbin/pfctl/pfctl.c,v retrieving revision 1.382 diff -u -p -r1.382 pfctl.c --- sbin/pfctl/pfctl.c 16 Jan 2020 01:02:20 -0000 1.382 +++ sbin/pfctl/pfctl.c 22 Nov 2021 03:09:28 -0000 @@ -1587,6 +1587,11 @@ pfctl_rules(int dev, char *filename, int pf.trans = t; pfctl_init_options(&pf); + pf.paths = malloc(sizeof(pf.paths)); + if (pf.paths == NULL) + err(1, "pfctl path list alloc"); + TAILQ_INIT(pf.paths); + if ((opts & PF_OPT_NOACTION) == 0) { /* * XXX For the time being we need to open transactions for Index: sbin/pfctl/pfctl_parser.c =================================================================== RCS file: /cvs/src/sbin/pfctl/pfctl_parser.c,v retrieving revision 1.343 diff -u -p -r1.343 pfctl_parser.c --- sbin/pfctl/pfctl_parser.c 15 May 2020 00:56:03 -0000 1.343 +++ sbin/pfctl/pfctl_parser.c 22 Nov 2021 03:09:28 -0000 @@ -1474,6 +1474,31 @@ ifa_exists(const char *ifa_name) return (NULL); } +int +ifa_data(const char *ifa_name, struct if_data *d) +{ + struct ifreq ifr; + int s; + int rv; + + if (strlcpy(ifr.ifr_name, ifa_name, sizeof(ifr.ifr_name)) >= + sizeof(ifr.ifr_name)) { + errno = ENXIO; + return (-1); + } + + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s == -1) + err(1, "socket"); + + ifr.ifr_data = (caddr_t)d; + rv = ioctl(s, SIOCGIFDATA, (caddr_t)&ifr); + + close(s); + + return (rv); +} + struct node_host * ifa_grouplookup(const char *ifa_name, int flags) { @@ -1951,4 +1976,17 @@ pfctl_trans(int dev, struct pfr_buffer * trans.esize = sizeof(struct pfioc_trans_e); trans.array = ((struct pfioc_trans_e *)buf->pfrb_caddr) + from; return ioctl(dev, cmd, &trans); +} + +struct pfctl_path * +pfctl_path_get(struct pfctl *pf, uint32_t id) +{ + struct pfctl_path *p; + + TAILQ_FOREACH(p, pf->paths, p_entry) { + if (p->p_id == id) + return (p); + } + + return (NULL); } Index: sbin/pfctl/pfctl_parser.h =================================================================== RCS file: /cvs/src/sbin/pfctl/pfctl_parser.h,v retrieving revision 1.116 diff -u -p -r1.116 pfctl_parser.h --- sbin/pfctl/pfctl_parser.h 15 Jan 2020 11:52:50 -0000 1.116 +++ sbin/pfctl/pfctl_parser.h 22 Nov 2021 03:09:28 -0000 @@ -69,7 +69,7 @@ } struct pfr_buffer; /* forward definition */ - +struct pfctl_path_list; struct pfctl { int dev; @@ -86,6 +86,8 @@ struct pfctl { struct pf_anchor *anchor, *alast; const char *ruleset; + struct pfctl_path_list *paths; + /* 'set foo' options */ u_int32_t timeout[PFTM_MAX]; u_int32_t limit[PF_LIMIT_MAX]; @@ -211,6 +213,19 @@ struct pfctl_watermarks { u_int32_t lo; }; +struct pfctl_path { + uint32_t p_id; + const char *p_ifname; + + const char *p_file; + int p_lineno; + + TAILQ_ENTRY(pfctl_path) + p_entry; +}; + +TAILQ_HEAD(pfctl_path_list, pfctl_path); + void copy_satopfaddr(struct pf_addr *, struct sockaddr *); int pfctl_rules(int, char *, int, int, char *, struct pfr_buffer *); @@ -297,5 +312,7 @@ struct node_host *host(const char *, int int append_addr(struct pfr_buffer *, char *, int, int); int append_addr_host(struct pfr_buffer *, struct node_host *, int, int); + +struct pfctl_path *pfctl_path_get(struct pfctl *, uint32_t); #endif /* _PFCTL_PARSER_H_ */ Index: sbin/ping/ping.c =================================================================== RCS file: /cvs/src/sbin/ping/ping.c,v retrieving revision 1.240 diff -u -p -r1.240 ping.c --- sbin/ping/ping.c 11 Feb 2020 18:41:39 -0000 1.240 +++ sbin/ping/ping.c 22 Nov 2021 03:09:28 -0000 @@ -153,6 +153,7 @@ int options; #define F_TOS 0x1000 #define F_AUD_RECV 0x2000 #define F_AUD_MISS 0x4000 +#define F_SO_TSTAMP 0x8000 /* multicast options */ int moptions; @@ -217,6 +218,8 @@ const char *pr_addr(struct sockaddr *, void pr_pack(u_char *, int, struct msghdr *); __dead void usage(void); +int get_tstamp(struct msghdr *, struct timespec *); + /* IPv4 specific functions */ void pr_ipopt(int, u_char *); int in_cksum(u_short *, int); @@ -297,8 +300,8 @@ main(int argc, char *argv[]) preload = 0; datap = &outpack[ECHOLEN + ECHOTMLEN]; while ((ch = getopt(argc, argv, v6flag ? - "c:DdEefHh:I:i:Ll:mNnp:qS:s:T:V:vw:" : - "DEI:LRS:c:defHi:l:np:qs:T:t:V:vw:")) != -1) { + "c:DdEefHh:I:i:Ll:mNnp:qS:s:T:V:vw:x" : + "DEI:LRS:c:defHi:l:np:qs:T:t:V:vw:x")) != -1) { switch(ch) { case 'c': npackets = strtonum(optarg, 0, INT64_MAX, &errstr); @@ -429,6 +432,9 @@ main(int argc, char *argv[]) errx(1, "maxwait value is %s: %s", errstr, optarg); break; + case 'x': + options |= F_SO_TSTAMP; + break; default: usage(); } @@ -567,6 +573,13 @@ main(int argc, char *argv[]) (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, &optval, sizeof(optval)); + if (options & F_SO_TSTAMP) { + optval = 1; + if (setsockopt(s, SOL_SOCKET, SO_MONOSTAMP, + &optval, sizeof(optval)) == -1) + warn("setsockopt SO_MONOSTAMP"); + } + if ((options & F_FLOOD) && (options & F_INTERVAL)) errx(1, "-f and -i options are incompatible"); @@ -1145,11 +1158,12 @@ pr_pack(u_char *buf, int cc, struct msgh struct ip *ip = NULL; struct icmp *icp = NULL; struct icmp6_hdr *icp6 = NULL; - struct timespec ts, tp; + struct timespec ts, tp, diff; struct payload payload; struct sockaddr *from; socklen_t fromlen; double triptime = 0; + int64_t xtriptime = 0; int i, dupflag; int hlen = -1, hoplim = -1, echo_reply = 0; u_int16_t seq; @@ -1253,15 +1267,25 @@ pr_pack(u_char *buf, int cc, struct msgh tp.tv_nsec = betoh64(tv64->tv64_nsec) - tv64_offset.tv64_nsec; - timespecsub(&ts, &tp, &ts); - triptime = ((double)ts.tv_sec) * 1000.0 + - ((double)ts.tv_nsec) / 1000000.0; + timespecsub(&ts, &tp, &diff); + triptime = ((double)diff.tv_sec) * 1000.0 + + ((double)diff.tv_nsec) / 1000000.0; tsum += triptime; tsumsq += triptime * triptime; if (triptime < tmin) tmin = triptime; if (triptime > tmax) tmax = triptime; + + if (options & F_SO_TSTAMP && + get_tstamp(mhdr, &ts) != -1) { + uint64_t tsnsec = ts.tv_sec * 1000000000 + + ts.tv_nsec; + uint64_t tpnsec = tp.tv_sec * 1000000000 + + tp.tv_nsec; + + xtriptime = tsnsec - tpnsec; + } } if (TST(ntohs(seq) % mx_dup_ck)) { @@ -1287,6 +1311,10 @@ pr_pack(u_char *buf, int cc, struct msgh printf(" ttl=%d", ip->ip_ttl); if (cc >= ECHOLEN + ECHOTMLEN) printf(" time=%.3f ms", triptime); + if (options & F_SO_TSTAMP) { + printf(" xtime=%.3f ms", + (double)xtriptime / 1000000.0); + } if (dupflag) printf(" (DUP!)"); /* check the data */ @@ -1889,6 +1917,27 @@ get_hoplim(struct msghdr *mhdr) cm->cmsg_type == IPV6_HOPLIMIT && cm->cmsg_len == CMSG_LEN(sizeof(int))) return(*(int *)CMSG_DATA(cm)); + } + + return(-1); +} + +int +get_tstamp(struct msghdr *mhdr, struct timespec *ts) +{ + struct cmsghdr *cm; + + for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; + cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { + if (cm->cmsg_len == 0) + return(-1); + + if (cm->cmsg_level == SOL_SOCKET && + cm->cmsg_type == SCM_MONOSTAMP && + cm->cmsg_len == CMSG_LEN(sizeof(*ts))) { + *ts = *(struct timespec *)CMSG_DATA(cm); + return (0); + } } return(-1); Index: share/man/man4/bpf.4 =================================================================== RCS file: /cvs/src/share/man/man4/bpf.4,v retrieving revision 1.41 diff -u -p -r1.41 bpf.4 --- share/man/man4/bpf.4 25 Apr 2019 18:26:16 -0000 1.41 +++ share/man/man4/bpf.4 22 Nov 2021 03:09:28 -0000 @@ -614,6 +614,8 @@ packet data at a variable offset .Pf ( Dv BPF_IND ) , the packet length .Pf ( Dv BPF_LEN ) , +a random number +.Pf ( Dv BPF_RND ) , or a word in the scratch memory store .Pf ( Dv BPF_MEM ) . For @@ -674,6 +676,12 @@ A <- P[X+k:1] .Sm on A <- len .Sm off +.It Xo Dv BPF_LD No + Dv BPF_W No + +.Dv BPF_RND +.Xc +.Sm on +A <- arc4random() +.Sm off .It Dv BPF_LD No + Dv BPF_IMM .Sm on A <- k @@ -1044,7 +1052,8 @@ request is too large to be represented b .Xr select 2 , .Xr signal 3 , .Xr MAKEDEV 8 , -.Xr tcpdump 8 +.Xr tcpdump 8 , +.Xr arc4random 9 .Rs .%A McCanne, S. .%A Jacobson, V. Index: share/man/man4/vxlan.4 =================================================================== RCS file: /cvs/src/share/man/man4/vxlan.4,v retrieving revision 1.9 diff -u -p -r1.9 vxlan.4 --- share/man/man4/vxlan.4 26 Jun 2020 12:04:17 -0000 1.9 +++ share/man/man4/vxlan.4 22 Nov 2021 03:09:28 -0000 @@ -82,6 +82,14 @@ The configuration can be done at runtime .Xr hostname.if 5 configuration file for .Xr netstart 8 . +.Pp +For correct operation, encapsulated traffic must not be routed +over the interface itself. +This can be implemented by adding a distinct or a more specific +route to the tunnel destination than the hosts or networks routed +via the tunnel interface. +Alternatively, the tunnel traffic may be configured in a separate +routing table to the encapsulated traffic. .Sh EXAMPLES Create a tunnel to a unicast tunnel endpoint, using the virtual tunnel identifier 5: Index: share/man/man9/SMR_LIST_INIT.9 =================================================================== RCS file: /cvs/src/share/man/man9/SMR_LIST_INIT.9,v retrieving revision 1.7 diff -u -p -r1.7 SMR_LIST_INIT.9 --- share/man/man9/SMR_LIST_INIT.9 3 Aug 2020 05:29:05 -0000 1.7 +++ share/man/man9/SMR_LIST_INIT.9 22 Nov 2021 03:09:28 -0000 @@ -73,6 +73,8 @@ .Sh SYNOPSIS .In sys/smr.h .Fn SMR_SLIST_ENTRY "TYPE" +.Fn SMR_SLIST_HEAD "HEADNAME" "TYPE" +.Fn SMR_SLIST_HEAD_INITIALIZER "SMR_SLIST_HEAD head" .Ft void .Fn SMR_SLIST_INIT "SMR_SLIST_HEAD *head" .Ft TYPE * @@ -99,6 +101,8 @@ .Ft void .Fn SMR_SLIST_REMOVE_LOCKED "SMR_SLIST_HEAD *head" "struct TYPE *elm" "TYPE" "FIELDNAME" .Fn SMR_LIST_ENTRY "TYPE" +.Fn SMR_LIST_HEAD "HEADNAME" "TYPE" +.Fn SMR_LIST_HEAD_INITIALIZER "SMR_LIST_HEAD head" .Ft void .Fn SMR_LIST_INIT "SMR_LIST_HEAD *head" .Ft TYPE * @@ -123,6 +127,8 @@ .Ft void .Fn SMR_LIST_REMOVE_LOCKED "struct TYPE *elm" "FIELDNAME" .Fn SMR_TAILQ_ENTRY "TYPE" +.Fn SMR_TAILQ_HEAD "HEADNAME" "TYPE" +.Fn SMR_TAILQ_HEAD_INITIALIZER "SMR_TAILQ_HEAD head" .Ft void .Fn SMR_TAILQ_INIT "SMR_TAILQ_HEAD *head" .Ft TYPE * Index: share/man/man9/mbuf.9 =================================================================== RCS file: /cvs/src/share/man/man9/mbuf.9,v retrieving revision 1.118 diff -u -p -r1.118 mbuf.9 --- share/man/man9/mbuf.9 7 Dec 2018 08:37:24 -0000 1.118 +++ share/man/man9/mbuf.9 22 Nov 2021 03:09:28 -0000 @@ -58,7 +58,7 @@ .Nm m_devget , .Nm m_apply , .Nm MCLGET , -.Nm MCLGETI , +.Nm MCLGETL , .Nm MEXTADD , .Nm m_align , .Nm M_READONLY , @@ -126,7 +126,7 @@ "int (*func)(caddr_t, caddr_t, unsigned int)" "caddr_t fstate" .Fn MCLGET "struct mbuf *m" "int how" .Ft struct mbuf * -.Fn MCLGETI "struct mbuf *m" "int how" "struct ifnet *ifp" "int len" +.Fn MCLGETL "struct mbuf *m" "int how" "int len" .Fn MEXTADD "struct mbuf *m" "caddr_t buf" "u_int size" "int flags" \ "void (*free)(caddr_t, u_int, void *)" "void *arg" .Ft void @@ -723,7 +723,7 @@ See .Fn m_get for a description of .Fa how . -.It Fn MCLGETI "struct mbuf *m" "int how" "struct ifnet *ifp" "int len" +.It Fn MCLGETL "struct mbuf *m" "int how" "int len" If .Fa m is NULL, allocate it. Index: sys/conf/GENERIC =================================================================== RCS file: /cvs/src/sys/conf/GENERIC,v retrieving revision 1.274 diff -u -p -r1.274 GENERIC --- sys/conf/GENERIC 25 Feb 2021 01:19:35 -0000 1.274 +++ sys/conf/GENERIC 22 Nov 2021 03:09:31 -0000 @@ -82,6 +82,7 @@ pseudo-device msts 1 # MSTS line discipl pseudo-device endrun 1 # EndRun line discipline pseudo-device vnd 4 # vnode disk devices pseudo-device ksyms 1 # kernel symbols device +pseudo-device kstat # kernel statistics #pseudo-device dt # Dynamic Tracer # clonable devices Index: sys/dev/bio.c =================================================================== RCS file: /cvs/src/sys/dev/bio.c,v retrieving revision 1.17 diff -u -p -r1.17 bio.c --- sys/dev/bio.c 26 Aug 2015 22:28:57 -0000 1.17 +++ sys/dev/bio.c 22 Nov 2021 03:09:31 -0000 @@ -31,18 +31,33 @@ #include #include #include -#include +#include #include #include struct bio_mapping { - LIST_ENTRY(bio_mapping) bm_link; + RBT_ENTRY(bio_mapping) bm_link; + uintptr_t bm_cookie; struct device *bm_dev; int (*bm_ioctl)(struct device *, u_long, caddr_t); }; -LIST_HEAD(, bio_mapping) bios = LIST_HEAD_INITIALIZER(bios); +RBT_HEAD(bio_mappings, bio_mapping); + +static inline int +bio_cookie_cmp(const struct bio_mapping *a, const struct bio_mapping *b) +{ + if (a->bm_cookie < b->bm_cookie) + return (1); + if (a->bm_cookie > b->bm_cookie) + return (-1); + return (0); +} + +RBT_PROTOTYPE(bio_mappings, bio_mapping, bm_link, bio_cookie_cmp); + +struct bio_mappings bios = RBT_INITIALIZER(); void bioattach(int); int bioclose(dev_t, int, int, struct proc *); @@ -51,7 +66,7 @@ int bioopen(dev_t, int, int, struct proc int bio_delegate_ioctl(struct bio_mapping *, u_long, caddr_t); struct bio_mapping *bio_lookup(char *); -int bio_validate(void *); +struct bio_mapping *bio_validate(void *); void bioattach(int nunits) @@ -73,6 +88,7 @@ bioclose(dev_t dev, int flags, int mode, int bioioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) { + struct bio_mapping *bm; struct bio_locate *locate; struct bio *bio; char name[16]; @@ -84,9 +100,10 @@ bioioctl(dev_t dev, u_long cmd, caddr_t error = copyinstr(locate->bl_name, name, sizeof name, NULL); if (error != 0) return (error); - locate->bl_bio.bio_cookie = bio_lookup(name); - if (locate->bl_bio.bio_cookie == NULL) + bm = bio_lookup(name); + if (bm == NULL) return (ENOENT); + locate->bl_bio.bio_cookie = (void *)bm->bm_cookie; break; case BIOCINQ: @@ -100,10 +117,10 @@ bioioctl(dev_t dev, u_long cmd, caddr_t case BIOCDISCIPLINE: case BIOCPATROL: bio = (struct bio *)addr; - if (!bio_validate(bio->bio_cookie)) + bm = bio_validate(bio->bio_cookie); + if (bm == NULL) return (ENOENT); - return (bio_delegate_ioctl( - (struct bio_mapping *)bio->bio_cookie, cmd, addr)); + return (bio_delegate_ioctl(bm, cmd, addr)); default: return (ENXIO); @@ -121,7 +138,10 @@ bio_register(struct device *dev, int (*i return (ENOMEM); bm->bm_dev = dev; bm->bm_ioctl = ioctl; - LIST_INSERT_HEAD(&bios, bm, bm_link); + do { + bm->bm_cookie = arc4random(); + /* lets hope we don't have 4 billion bio_registers */ + } while (RBT_INSERT(bio_mappings, &bios, bm) != NULL); return (0); } @@ -130,11 +150,9 @@ bio_unregister(struct device *dev) { struct bio_mapping *bm, *next; - for (bm = LIST_FIRST(&bios); bm != NULL; bm = next) { - next = LIST_NEXT(bm, bm_link); - + RBT_FOREACH_SAFE(bm, bio_mappings, &bios, next) { if (dev == bm->bm_dev) { - LIST_REMOVE(bm, bm_link); + RBT_REMOVE(bio_mappings, &bios, bm); free(bm, M_DEVBUF, sizeof(*bm)); } } @@ -145,21 +163,20 @@ bio_lookup(char *name) { struct bio_mapping *bm; - LIST_FOREACH(bm, &bios, bm_link) + RBT_FOREACH(bm, bio_mappings, &bios) { if (strcmp(name, bm->bm_dev->dv_xname) == 0) return (bm); + } + return (NULL); } -int +struct bio_mapping * bio_validate(void *cookie) { - struct bio_mapping *bm; + struct bio_mapping key = { .bm_cookie = (uintptr_t)cookie }; - LIST_FOREACH(bm, &bios, bm_link) - if (bm == cookie) - return (1); - return (0); + return (RBT_FIND(bio_mappings, &bios, &key)); } int @@ -227,3 +244,5 @@ bio_status(struct bio_status *bs, int pr if (print) printf("%s: %s\n", bs->bs_controller, bs->bs_msgs[idx].bm_msg); } + +RBT_GENERATE(bio_mappings, bio_mapping, bm_link, bio_cookie_cmp); Index: sys/dev/pci/if_em.c =================================================================== RCS file: /cvs/src/sys/dev/pci/if_em.c,v retrieving revision 1.358 diff -u -p -r1.358 if_em.c --- sys/dev/pci/if_em.c 24 Jan 2021 10:21:43 -0000 1.358 +++ sys/dev/pci/if_em.c 22 Nov 2021 03:09:32 -0000 @@ -296,6 +296,7 @@ u_int32_t em_fill_descriptors(u_int64_t void em_flush_tx_ring(struct em_queue *); void em_flush_rx_ring(struct em_queue *); void em_flush_desc_rings(struct em_softc *); +int em_get_sffpage(struct em_softc *, struct if_sffpage *); #ifndef SMALL_KERNEL /* MSIX/Multiqueue functions */ @@ -406,6 +407,7 @@ em_attach(struct device *parent, struct sc->sc_dmat = pa->pa_dmat; sc->osdep.em_pa = *pa; + rw_init(&sc->sfflock, "emsff"); timeout_set(&sc->timer_handle, em_local_timer, sc); timeout_set(&sc->tx_fifo_timer_handle, em_82547_move_tail, sc); @@ -764,6 +766,15 @@ em_ioctl(struct ifnet *ifp, u_long comma NULL, EM_MCLBYTES, &sc->queues->rx.sc_rx_ring); break; + case SIOCGIFSFFPAGE: + error = rw_enter(&sc->sfflock, RW_WRITE|RW_INTR); + if (error != 0) + break; + + error = em_get_sffpage(sc, (struct if_sffpage *)data); + rw_exit(&sc->sfflock); + break; + default: error = ether_ioctl(ifp, &sc->sc_ac, command, data); } @@ -4024,6 +4035,34 @@ em_allocate_desc_rings(struct em_softc * } que->rx.sc_rx_desc_ring = (struct em_rx_desc *)que->rx.sc_rx_dma.dma_vaddr; + } + + return (0); +} + +int +em_get_sffpage(struct em_softc *sc, struct if_sffpage *sff) +{ + struct em_hw *hw = &sc->hw; + size_t i; + int off; + + if (hw->mac_type != em_82575 && hw->mac_type != em_82580 && + hw->mac_type != em_82576 && + hw->mac_type != em_i210 && hw->mac_type != em_i350) + return (ENODEV); + + if (sff->sff_addr == IFSFF_ADDR_EEPROM) + off = E1000_I2CCMD_SFP_DATA_ADDR(0); + else if (sff->sff_addr == IFSFF_ADDR_DDM) + off = E1000_I2CCMD_SFP_DIAG_ADDR(0); + else + return (EIO); + + for (i = 0; i < sizeof(sff->sff_data); i++) { + if (em_read_sfp_data_byte(hw, off + i, + &sff->sff_data[i]) != E1000_SUCCESS) + return (EIO); } return (0); Index: sys/dev/pci/if_em.h =================================================================== RCS file: /cvs/src/sys/dev/pci/if_em.h,v retrieving revision 1.78 diff -u -p -r1.78 if_em.h --- sys/dev/pci/if_em.h 13 Jul 2020 10:35:55 -0000 1.78 +++ sys/dev/pci/if_em.h 22 Nov 2021 03:09:32 -0000 @@ -405,6 +405,7 @@ struct em_softc { u_int32_t tx_abs_int_delay; u_int32_t rx_int_delay; u_int32_t rx_abs_int_delay; + struct rwlock sfflock; u_int sc_tx_slots; u_int sc_rx_slots; Index: sys/dev/pci/if_em_hw.c =================================================================== RCS file: /cvs/src/sys/dev/pci/if_em_hw.c,v retrieving revision 1.110 diff -u -p -r1.110 if_em_hw.c --- sys/dev/pci/if_em_hw.c 24 Jan 2021 10:21:43 -0000 1.110 +++ sys/dev/pci/if_em_hw.c 22 Nov 2021 03:09:32 -0000 @@ -724,6 +724,72 @@ em_set_mac_type(struct em_hw *hw) return E1000_SUCCESS; } +/** + * em_set_sfp_media_type_82575 - derives SFP module media type. + * @hw: pointer to the HW structure + * + * The media type is chosen based on SFP module. + * compatibility flags retrieved from SFP ID EEPROM. + **/ +STATIC int32_t em_set_sfp_media_type_82575(struct em_hw *hw) +{ + struct sfp_e1000_flags eth_flags; + int32_t ret_val = E1000_ERR_CONFIG; + uint32_t ctrl_ext = 0; + uint8_t tranceiver_type = 0; + int32_t timeout = 3; + + /* Turn I2C interface ON and power on sfp cage */ + ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); + ctrl_ext &= ~E1000_CTRL_EXT_SDP3_DATA; + E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext | E1000_CTRL_I2C_ENA); + + E1000_WRITE_FLUSH(hw); + + /* Read SFP module data */ + while (timeout) { + ret_val = em_read_sfp_data_byte(hw, + E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_IDENTIFIER_OFFSET), + &tranceiver_type); + if (ret_val == E1000_SUCCESS) + break; + msec_delay(100); + timeout--; + } + if (ret_val != E1000_SUCCESS) + goto out; + + ret_val = em_read_sfp_data_byte(hw, + E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_ETH_FLAGS_OFFSET), + (uint8_t *)ð_flags); + if (ret_val != E1000_SUCCESS) + goto out; + + /* Check if there is some SFP module plugged and powered */ + if ((tranceiver_type == E1000_SFF_IDENTIFIER_SFP) || + (tranceiver_type == E1000_SFF_IDENTIFIER_SFF)) { + if (eth_flags.e1000_base_lx || eth_flags.e1000_base_sx) { + hw->media_type = em_media_type_internal_serdes; + } else if (eth_flags.e100_base_fx) { + hw->media_type = em_media_type_internal_serdes; + hw->sgmii_active = TRUE; + } else if (eth_flags.e1000_base_t) { + hw->media_type = em_media_type_copper; + hw->sgmii_active = TRUE; + } else { + DEBUGOUT("PHY module has not been recognized\n"); + goto out; + } + } else + goto out; + ret_val = E1000_SUCCESS; +out: + /* Restore I2C interface setting */ + E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); + return ret_val; +} + + /***************************************************************************** * Set media type and TBI compatibility. * @@ -732,7 +798,7 @@ em_set_mac_type(struct em_hw *hw) void em_set_media_type(struct em_hw *hw) { - uint32_t status, ctrl_ext; + uint32_t status, ctrl_ext, mdic; DEBUGFUNC("em_set_media_type"); if (hw->mac_type != em_82543) { @@ -744,16 +810,39 @@ em_set_media_type(struct em_hw *hw) hw->mac_type == em_82576 || hw->mac_type == em_i210 || hw->mac_type == em_i350) { hw->media_type = em_media_type_copper; - + hw->sgmii_active = FALSE; + ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); switch (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) { - case E1000_CTRL_EXT_LINK_MODE_SGMII: + case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX: + hw->media_type = em_media_type_internal_serdes; ctrl_ext |= E1000_CTRL_I2C_ENA; break; - case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX: + case E1000_CTRL_EXT_LINK_MODE_SGMII: + mdic = EM_READ_REG(hw, E1000_MDICNFG); + ctrl_ext |= E1000_CTRL_I2C_ENA; + if (mdic & E1000_MDICNFG_EXT_MDIO) { + hw->media_type = em_media_type_copper; + hw->sgmii_active = TRUE; + break; + } + /* FALLTHROUGH */ case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES: - hw->media_type = em_media_type_internal_serdes; ctrl_ext |= E1000_CTRL_I2C_ENA; + if (em_set_sfp_media_type_82575(hw) != 0) { + hw->media_type = em_media_type_internal_serdes; + if ((ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) == + E1000_CTRL_EXT_LINK_MODE_SGMII) { + hw->media_type = em_media_type_copper; + hw->sgmii_active = TRUE; + } + } + + ctrl_ext &= ~E1000_CTRL_EXT_LINK_MODE_MASK; + if (hw->sgmii_active) + ctrl_ext |= E1000_CTRL_EXT_LINK_MODE_SGMII; + else + ctrl_ext |= E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES; break; default: ctrl_ext &= ~E1000_CTRL_I2C_ENA; @@ -1976,6 +2065,10 @@ em_power_up_serdes_link_82575(struct em_ { uint32_t reg; + if (hw->media_type != em_media_type_internal_serdes && + hw->sgmii_active == FALSE) + return; + /* Enable PCS to turn on link */ reg = E1000_READ_REG(hw, PCS_CFG0); reg |= E1000_PCS_CFG_PCS_EN; @@ -2010,6 +2103,11 @@ em_setup_fiber_serdes_link(struct em_hw uint32_t signal = 0; int32_t ret_val; DEBUGFUNC("em_setup_fiber_serdes_link"); + + if (hw->media_type != em_media_type_internal_serdes && + hw->sgmii_active == FALSE) + return -E1000_ERR_CONFIG; + /* * On 82571 and 82572 Fiber connections, SerDes loopback mode * persists until explicitly turned off or a power cycle is @@ -5337,6 +5435,61 @@ em_write_kmrn_reg(struct em_hw *hw, uint return E1000_SUCCESS; } +/** + * em_read_sfp_data_byte - Reads SFP module data. + * @hw: pointer to the HW structure + * @offset: byte location offset to be read + * @data: read data buffer pointer + * + * Reads one byte from SFP module data stored + * in SFP resided EEPROM memory or SFP diagnostic area. + * Function should be called with + * E1000_I2CCMD_SFP_DATA_ADDR() for SFP module database access + * E1000_I2CCMD_SFP_DIAG_ADDR() for SFP diagnostics parameters + * access + **/ +int32_t em_read_sfp_data_byte(struct em_hw *hw, uint16_t offset, uint8_t *data) +{ + uint32_t i = 0; + uint32_t i2ccmd = 0; + uint32_t data_local = 0; + + DEBUGFUNC("em_read_sfp_data_byte"); + + if (offset > E1000_I2CCMD_SFP_DIAG_ADDR(255)) { + DEBUGOUT("I2CCMD command address exceeds upper limit\n"); + return -E1000_ERR_PHY; + } + + /* Set up Op-code, EEPROM Address,in the I2CCMD + * register. The MAC will take care of interfacing with the + * EEPROM to retrieve the desired data. + */ + i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) | + E1000_I2CCMD_OPCODE_READ); + + E1000_WRITE_REG(hw, I2CCMD, i2ccmd); + + /* Poll the ready bit to see if the I2C read completed */ + for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) { + usec_delay(50); + data_local = E1000_READ_REG(hw, I2CCMD); + if (data_local & E1000_I2CCMD_READY) + break; + } + if (!(data_local & E1000_I2CCMD_READY)) { + DEBUGOUT("I2CCMD Read did not complete\n"); + return -E1000_ERR_PHY; + } + if (data_local & E1000_I2CCMD_ERROR) { + DEBUGOUT("I2CCMD Error bit set\n"); + return -E1000_ERR_PHY; + } + *data = (uint8_t) data_local & 0xFF; + + return E1000_SUCCESS; +} + /****************************************************************************** * Returns the PHY to the power-on reset state * @@ -5719,10 +5872,12 @@ em_match_gig_phy(struct em_hw *hw) uint32_t mdic; mdic = EM_READ_REG(hw, E1000_MDICNFG); - mdic &= E1000_MDICNFG_PHY_MASK; - hw->phy_addr = mdic >> E1000_MDICNFG_PHY_SHIFT; - DEBUGOUT1("MDICNFG PHY ADDR %d", - mdic >> E1000_MDICNFG_PHY_SHIFT); + if (mdic & E1000_MDICNFG_EXT_MDIO) { + mdic &= E1000_MDICNFG_PHY_MASK; + hw->phy_addr = mdic >> E1000_MDICNFG_PHY_SHIFT; + DEBUGOUT1("MDICNFG PHY ADDR %d", + mdic >> E1000_MDICNFG_PHY_SHIFT); + } match = TRUE; } break; @@ -5858,7 +6013,8 @@ em_detect_gig_phy(struct em_hw *hw) uint32_t ctrl_ext = EM_READ_REG(hw, E1000_CTRL_EXT); EM_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_SDP3_DATA); - delay(300); + E1000_WRITE_FLUSH(hw); + msec_delay(300); } /* Read the PHY ID Registers to identify which PHY is onboard. */ Index: sys/dev/pci/if_em_hw.h =================================================================== RCS file: /cvs/src/sys/dev/pci/if_em_hw.h,v retrieving revision 1.84 diff -u -p -r1.84 if_em_hw.h --- sys/dev/pci/if_em_hw.h 24 Jan 2021 10:21:43 -0000 1.84 +++ sys/dev/pci/if_em_hw.h 22 Nov 2021 03:09:32 -0000 @@ -361,6 +361,7 @@ int32_t em_phy_reset(struct em_hw *hw); int32_t em_phy_get_info(struct em_hw *hw, struct em_phy_info *phy_info); int32_t em_validate_mdi_setting(struct em_hw *hw); void em_phy_powerdown_workaround(struct em_hw *hw); +int32_t em_read_sfp_data_byte(struct em_hw *, uint16_t, uint8_t *); /* EEPROM Functions */ int32_t em_init_eeprom_params(struct em_hw *hw); @@ -1095,6 +1096,7 @@ struct em_ffvt_entry { #define E1000_FLSWDATA 0x01034 /* FLASH data register */ #define E1000_FLSWCNT 0x01038 /* FLASH Access Counter */ #define E1000_FLOP 0x0103C /* FLASH Opcode Register */ +#define E1000_I2CCMD 0x01028 /* SFPI2C Command Register - RW */ #define E1000_ERT 0x02008 /* Early Rx Threshold - RW */ #define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */ #define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */ @@ -1492,6 +1494,7 @@ struct em_hw { uint16_t swfw; boolean_t eee_enable; int sw_flag; + boolean_t sgmii_active; }; #define E1000_EEPROM_SWDPIN0 0x0001 /* SWDPIN 0 EEPROM Value */ @@ -1528,6 +1531,16 @@ struct em_hw { #define E1000_CTRL_LANPHYPC_VALUE 0x00020000 /* SW value of LANPHYPC */ #define E1000_CTRL_EXT_FORCE_SMBUS 0x00000800 /* Force SMBus mode */ #define E1000_CTRL_EXT_PHYPDEN 0x00100000 +#define E1000_I2CCMD_REG_ADDR_SHIFT 16 +#define E1000_I2CCMD_PHY_ADDR_SHIFT 24 +#define E1000_I2CCMD_OPCODE_READ 0x08000000 +#define E1000_I2CCMD_OPCODE_WRITE 0x00000000 +#define E1000_I2CCMD_READY 0x20000000 +#define E1000_I2CCMD_ERROR 0x80000000 +#define E1000_I2CCMD_SFP_DATA_ADDR(a) (0x0000 + (a)) +#define E1000_I2CCMD_SFP_DIAG_ADDR(a) (0x0100 + (a)) +#define E1000_MAX_SGMII_PHY_REG_ADDR 255 +#define E1000_I2CCMD_PHY_TIMEOUT 200 #define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */ #define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */ @@ -3789,5 +3802,29 @@ union ich8_hws_flash_regacc { ((uint16_t)(((offset) & MAX_PHY_REG_ADDRESS) |\ (((offset) >> (PHY_UPPER_SHIFT - PHY_PAGE_SHIFT)) &\ ~MAX_PHY_REG_ADDRESS))) + +/* SFP modules ID memory locations */ +#define E1000_SFF_IDENTIFIER_OFFSET 0x00 +#define E1000_SFF_IDENTIFIER_SFF 0x02 +#define E1000_SFF_IDENTIFIER_SFP 0x03 + +#define E1000_SFF_ETH_FLAGS_OFFSET 0x06 +/* Flags for SFP modules compatible with ETH up to 1Gb */ +struct sfp_e1000_flags { + uint8_t e1000_base_sx:1; + uint8_t e1000_base_lx:1; + uint8_t e1000_base_cx:1; + uint8_t e1000_base_t:1; + uint8_t e100_base_lx:1; + uint8_t e100_base_fx:1; + uint8_t e10_base_bx10:1; + uint8_t e10_base_px:1; +}; + +/* Vendor OUIs: format of OUI is 0x[byte0][byte1][byte2][00] */ +#define E1000_SFF_VENDOR_OUI_TYCO 0x00407600 +#define E1000_SFF_VENDOR_OUI_FTL 0x00906500 +#define E1000_SFF_VENDOR_OUI_AVAGO 0x00176A00 +#define E1000_SFF_VENDOR_OUI_INTEL 0x001B2100 #endif /* _EM_HW_H_ */ Index: sys/kern/kern_pledge.c =================================================================== RCS file: /cvs/src/sys/kern/kern_pledge.c,v retrieving revision 1.271 diff -u -p -r1.271 kern_pledge.c --- sys/kern/kern_pledge.c 25 Mar 2021 21:27:45 -0000 1.271 +++ sys/kern/kern_pledge.c 22 Nov 2021 03:09:33 -0000 @@ -1361,6 +1361,7 @@ pledge_sockopt(struct proc *p, int set, case SOL_SOCKET: switch (optname) { case SO_TIMESTAMP: + case SO_MONOSTAMP: return 0; } break; Index: sys/kern/kern_tc.c =================================================================== RCS file: /cvs/src/sys/kern/kern_tc.c,v retrieving revision 1.71 diff -u -p -r1.71 kern_tc.c --- sys/kern/kern_tc.c 23 Feb 2021 04:44:31 -0000 1.71 +++ sys/kern/kern_tc.c 22 Nov 2021 03:09:33 -0000 @@ -79,7 +79,7 @@ struct timehands { struct bintime th_next_ntp_update; /* [T,W] */ int64_t th_adjustment; /* [W] */ u_int64_t th_scale; /* [W] */ - u_int th_offset_count; /* [W] */ + u_int64_t th_offset_count; /* [W] */ struct bintime th_boottime; /* [T,W] */ struct bintime th_offset; /* [W] */ struct bintime th_naptime; /* [W] */ @@ -87,6 +87,7 @@ struct timehands { struct timespec th_nanotime; /* [W] */ /* Fields not to be copied in tc_windup start with th_generation. */ volatile u_int th_generation; /* [W] */ + unsigned int th_version; /* [W] */ struct timehands *th_next; /* [I] */ }; @@ -123,21 +124,27 @@ volatile time_t time_uptime = 0; static int timestepwarnings; +volatile unsigned int __tc_version; + void ntp_update_second(struct timehands *); void tc_windup(struct bintime *, struct bintime *, int64_t *); +static inline u_int +tc_read(struct timehands *th) +{ + struct timecounter *tc = th->th_counter; + + return (tc->tc_get_timecount(tc) & tc->tc_counter_mask); +} + /* * Return the difference between the timehands' counter value now and what * was when we copied it to the timehands' offset_count. */ -static __inline u_int +static inline u_int tc_delta(struct timehands *th) { - struct timecounter *tc; - - tc = th->th_counter; - return ((tc->tc_get_timecount(tc) - th->th_offset_count) & - tc->tc_counter_mask); + return (tc_read(th) - (u_int)th->th_offset_count); } /* @@ -377,6 +384,42 @@ getmicrotime(struct timeval *tvp) } while (gen == 0 || gen != th->th_generation); } +void +timecycle(struct timecycle *tcyc) +{ + struct timehands *th; + u_int gen; + + do { + th = timehands; + gen = th->th_generation; + membar_consumer(); + tcyc->tcyc_cycles = th->th_offset_count + tc_delta(th); + tcyc->tcyc_scale = th->th_scale; + tcyc->tcyc_offset = th->th_offset; + tcyc->tcyc_version = th->th_version; + membar_consumer(); + } while (gen == 0 || gen != th->th_generation); +} + +void +gettimecycle(struct timecycle *tcyc) +{ + struct timehands *th; + u_int gen; + + do { + th = timehands; + gen = th->th_generation; + membar_consumer(); + tcyc->tcyc_cycles = th->th_offset_count; + tcyc->tcyc_scale = th->th_scale; + tcyc->tcyc_offset = th->th_offset; + tcyc->tcyc_version = th->th_version; + membar_consumer(); + } while (gen == 0 || gen != th->th_generation); +} + /* * Initialize a new timecounter and possibly use it. */ @@ -578,6 +621,7 @@ tc_windup(struct bintime *new_boottime, struct timehands *th, *tho; u_int64_t scale; u_int delta, ncount, ogen; + unsigned int nversion = 0; if (new_boottime != NULL || new_adjtimedelta != NULL) rw_assert_wrlock(&tc_lock); @@ -608,7 +652,6 @@ tc_windup(struct bintime *new_boottime, else ncount = 0; th->th_offset_count += delta; - th->th_offset_count &= th->th_counter->tc_counter_mask; bintimeaddfrac(&th->th_offset, th->th_scale * delta, &th->th_offset); /* @@ -640,8 +683,10 @@ tc_windup(struct bintime *new_boottime, * If changing the boot time or clock adjustment, do so before * NTP processing. */ - if (new_boottime != NULL) + if (new_boottime != NULL) { th->th_boottime = *new_boottime; + nversion = 1; + } if (new_adjtimedelta != NULL) { th->th_adjtimedelta = *new_adjtimedelta; /* Reset the NTP update period. */ @@ -669,6 +714,7 @@ tc_windup(struct bintime *new_boottime, if (th->th_counter != active_tc) { th->th_counter = active_tc; th->th_offset_count = ncount; + nversion = 1; } /*- @@ -706,6 +752,8 @@ tc_windup(struct bintime *new_boottime, */ if (++ogen == 0) ogen = 1; + + th->th_version = (__tc_version += nversion); membar_producer(); th->th_generation = ogen; Index: sys/kern/uipc_mbuf.c =================================================================== RCS file: /cvs/src/sys/kern/uipc_mbuf.c,v retrieving revision 1.279 diff -u -p -r1.279 uipc_mbuf.c --- sys/kern/uipc_mbuf.c 6 Mar 2021 09:20:49 -0000 1.279 +++ sys/kern/uipc_mbuf.c 22 Nov 2021 03:09:33 -0000 @@ -1471,6 +1471,15 @@ m_microtime(const struct mbuf *m, struct microtime(tv); } +void +m_nanouptime(const struct mbuf *m, struct timespec *ts) +{ + if (ISSET(m->m_pkthdr.csum_flags, M_TIMESTAMP)) + NSEC_TO_TIMESPEC(m->m_pkthdr.ph_timestamp, ts); + else + nanouptime(ts); +} + void * m_pool_alloc(struct pool *pp, int flags, int *slowdown) { Index: sys/kern/uipc_socket.c =================================================================== RCS file: /cvs/src/sys/kern/uipc_socket.c,v retrieving revision 1.256 diff -u -p -r1.256 uipc_socket.c --- sys/kern/uipc_socket.c 24 Feb 2021 13:19:48 -0000 1.256 +++ sys/kern/uipc_socket.c 22 Nov 2021 03:09:33 -0000 @@ -1727,6 +1727,7 @@ sosetopt(struct socket *so, int level, i case SO_OOBINLINE: case SO_TIMESTAMP: case SO_ZEROIZE: + case SO_MONOSTAMP: if (m == NULL || m->m_len < sizeof (int)) return (EINVAL); if (*mtod(m, int *)) @@ -1900,6 +1901,7 @@ sogetopt(struct socket *so, int level, i case SO_OOBINLINE: case SO_TIMESTAMP: case SO_ZEROIZE: + case SO_MONOSTAMP: *mtod(m, int *) = so->so_options & optname; break; Index: sys/net/if_aggr.c =================================================================== RCS file: /cvs/src/sys/net/if_aggr.c,v retrieving revision 1.38 diff -u -p -r1.38 if_aggr.c --- sys/net/if_aggr.c 28 Feb 2021 03:59:25 -0000 1.38 +++ sys/net/if_aggr.c 22 Nov 2021 03:09:34 -0000 @@ -299,7 +299,10 @@ static const char *lacp_mux_event_names[ * aggr interface */ -#define AGGR_MAX_PORTS 32 +#define AGGR_PORT_BITS 5 +#define AGGR_FLOWID_SHIFT (16 - AGGR_PORT_BITS) + +#define AGGR_MAX_PORTS (1 << AGGR_PORT_BITS) #define AGGR_MAX_SLOW_PKTS (AGGR_MAX_PORTS * 3) struct aggr_multiaddr { @@ -660,7 +663,7 @@ aggr_transmit(struct aggr_softc *sc, con #endif if (ISSET(m->m_pkthdr.csum_flags, M_FLOWID)) - flow = m->m_pkthdr.ph_flowid; + flow = m->m_pkthdr.ph_flowid >> AGGR_FLOWID_SHIFT; ifp0 = map->m_ifp0s[flow % AGGR_MAX_PORTS]; Index: sys/netinet/gre_proto.h =================================================================== RCS file: sys/netinet/gre_proto.h diff -N sys/netinet/gre_proto.h Index: sys/netinet/gre_var.h =================================================================== RCS file: sys/netinet/gre_var.h diff -N sys/netinet/gre_var.h Index: sys/netinet/ip_input.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_input.c,v retrieving revision 1.355 diff -u -p -r1.355 ip_input.c --- sys/netinet/ip_input.c 10 Mar 2021 10:21:48 -0000 1.355 +++ sys/netinet/ip_input.c 22 Nov 2021 03:09:34 -0000 @@ -1705,6 +1705,15 @@ ip_savecontrol(struct inpcb *inp, struct if (*mp) mp = &(*mp)->m_next; } + if (inp->inp_socket->so_options & SO_MONOSTAMP) { + struct timespec ts; + + m_nanouptime(m, &ts); + *mp = sbcreatecontrol((caddr_t)&ts, sizeof(ts), + SCM_MONOSTAMP, SOL_SOCKET); + if (*mp) + mp = &(*mp)->m_next; + } if (inp->inp_flags & INP_RECVDSTADDR) { *mp = sbcreatecontrol((caddr_t) &ip->ip_dst, Index: sys/netinet/raw_ip.c =================================================================== RCS file: /cvs/src/sys/netinet/raw_ip.c,v retrieving revision 1.119 diff -u -p -r1.119 raw_ip.c --- sys/netinet/raw_ip.c 4 Feb 2019 21:40:52 -0000 1.119 +++ sys/netinet/raw_ip.c 22 Nov 2021 03:09:34 -0000 @@ -175,7 +175,8 @@ rip_input(struct mbuf **mp, int *offp, i if ((n = m_copym(m, 0, M_COPYALL, M_NOWAIT)) != NULL) { if (last->inp_flags & INP_CONTROLOPTS || - last->inp_socket->so_options & SO_TIMESTAMP) + ISSET(last->inp_socket->so_options, + SO_TIMESTAMP|SO_MONOSTAMP)) ip_savecontrol(last, &opts, ip, n); if (sbappendaddr(last->inp_socket, &last->inp_socket->so_rcv, @@ -192,7 +193,8 @@ rip_input(struct mbuf **mp, int *offp, i } if (last) { if (last->inp_flags & INP_CONTROLOPTS || - last->inp_socket->so_options & SO_TIMESTAMP) + ISSET(last->inp_socket->so_options, + SO_TIMESTAMP|SO_MONOSTAMP)) ip_savecontrol(last, &opts, ip, m); if (sbappendaddr(last->inp_socket, &last->inp_socket->so_rcv, sintosa(&ripsrc), m, opts) == 0) { Index: sys/netinet/udp_usrreq.c =================================================================== RCS file: /cvs/src/sys/netinet/udp_usrreq.c,v retrieving revision 1.262 diff -u -p -r1.262 udp_usrreq.c --- sys/netinet/udp_usrreq.c 22 Aug 2020 17:54:57 -0000 1.262 +++ sys/netinet/udp_usrreq.c 22 Nov 2021 03:09:34 -0000 @@ -604,11 +604,11 @@ udp_sbappend(struct inpcb *inp, struct m #ifdef INET6 if (ip6 && (inp->inp_flags & IN6P_CONTROLOPTS || - so->so_options & SO_TIMESTAMP)) + ISSET(so->so_options, SO_TIMESTAMP|SO_MONOSTAMP))) ip6_savecontrol(inp, m, &opts); #endif /* INET6 */ if (ip && (inp->inp_flags & INP_CONTROLOPTS || - so->so_options & SO_TIMESTAMP)) + ISSET(so->so_options, SO_TIMESTAMP|SO_MONOSTAMP))) ip_savecontrol(inp, &opts, ip, m); #ifdef INET6 if (ip6 && (inp->inp_flags & IN6P_RECVDSTPORT)) { Index: sys/netinet6/ip6_input.c =================================================================== RCS file: /cvs/src/sys/netinet6/ip6_input.c,v retrieving revision 1.232 diff -u -p -r1.232 ip6_input.c --- sys/netinet6/ip6_input.c 10 Mar 2021 10:21:49 -0000 1.232 +++ sys/netinet6/ip6_input.c 22 Nov 2021 03:09:34 -0000 @@ -931,6 +931,15 @@ ip6_savecontrol(struct inpcb *in6p, stru if (*mp) mp = &(*mp)->m_next; } + if (in6p->inp_socket->so_options & SO_MONOSTAMP) { + struct timespec ts; + + m_nanouptime(m, &ts); + *mp = sbcreatecontrol((caddr_t)&ts, sizeof(ts), + SCM_MONOSTAMP, SOL_SOCKET); + if (*mp) + mp = &(*mp)->m_next; + } /* RFC 2292 sec. 5 */ if ((in6p->inp_flags & IN6P_PKTINFO) != 0) { Index: sys/sys/kstat.h =================================================================== RCS file: /cvs/src/sys/sys/kstat.h,v retrieving revision 1.1 diff -u -p -r1.1 kstat.h --- sys/sys/kstat.h 6 Jul 2020 03:56:51 -0000 1.1 +++ sys/sys/kstat.h 22 Nov 2021 03:09:34 -0000 @@ -79,6 +79,10 @@ enum kstat_kv_type { KSTAT_KV_T_STR, /* trailing string */ KSTAT_KV_T_BYTES, /* trailing bytes */ KSTAT_KV_T_TEMP, /* temperature (uK) */ + + KSTAT_KV_T_REALTIME, /* struct timespec */ + KSTAT_KV_T_MONOTIME, /* struct timespec */ + KSTAT_KV_T_INTERVAL, /* struct timespec */ }; /* units only apply to integer types */ @@ -99,6 +103,7 @@ struct kstat_kv { uint32_t v_u32; int32_t v_s32; size_t v_len; + struct timespec v_timespec; } kv_v; enum kstat_kv_type kv_type; enum kstat_kv_unit kv_unit; @@ -112,6 +117,7 @@ struct kstat_kv { #define kstat_kv_s32(_kv) (_kv)->kv_v.v_s32 #define kstat_kv_len(_kv) (_kv)->kv_v.v_len #define kstat_kv_temp(_kv) (_kv)->kv_v.v_u64 +#define kstat_kv_timespec(_kv) (_kv)->kv_v.v_timespec #ifdef _KERNEL Index: sys/sys/mbuf.h =================================================================== RCS file: /cvs/src/sys/sys/mbuf.h,v retrieving revision 1.252 diff -u -p -r1.252 mbuf.h --- sys/sys/mbuf.h 25 Feb 2021 02:43:31 -0000 1.252 +++ sys/sys/mbuf.h 22 Nov 2021 03:09:34 -0000 @@ -444,6 +444,7 @@ struct mbuf *m_dup_pkt(struct mbuf *, un int m_dup_pkthdr(struct mbuf *, struct mbuf *, int); void m_microtime(const struct mbuf *, struct timeval *); +void m_nanouptime(const struct mbuf *, struct timespec *); static inline struct mbuf * m_freemp(struct mbuf **mp) Index: sys/sys/socket.h =================================================================== RCS file: /cvs/src/sys/sys/socket.h,v retrieving revision 1.99 diff -u -p -r1.99 socket.h --- sys/sys/socket.h 29 Oct 2020 21:15:27 -0000 1.99 +++ sys/sys/socket.h 22 Nov 2021 03:09:34 -0000 @@ -97,6 +97,7 @@ typedef __sa_family_t sa_family_t; /* so #define SO_TIMESTAMP 0x0800 /* timestamp received dgram traffic */ #define SO_BINDANY 0x1000 /* allow bind to any address */ #define SO_ZEROIZE 0x2000 /* zero out all mbufs sent over socket */ +#define SO_MONOSTAMP 0x4000 /* monotime stamp rxed dgram traffic */ /* * Additional options, not kept in so_options. @@ -523,6 +524,7 @@ struct cmsghdr { /* "Socket"-level control message types: */ #define SCM_RIGHTS 0x01 /* access rights (array of int) */ #define SCM_TIMESTAMP 0x04 /* timestamp (struct timeval) */ +#define SCM_MONOSTAMP 0x08 /* timestamp (struct timespec) */ #ifndef _KERNEL Index: sys/sys/sockio.h =================================================================== RCS file: /cvs/src/sys/sys/sockio.h,v retrieving revision 1.83 diff -u -p -r1.83 sockio.h --- sys/sys/sockio.h 13 Nov 2019 11:54:01 -0000 1.83 +++ sys/sys/sockio.h 22 Nov 2021 03:09:34 -0000 @@ -42,6 +42,7 @@ #define SIOCSPGRP _IOW('s', 8, int) /* set process group */ #define SIOCGPGRP _IOR('s', 9, int) /* get process group */ +#define SIOCGIFDROPS _IOWR('i', 10, struct ifreq) /* get if hw drops */ #define SIOCSIFADDR _IOW('i', 12, struct ifreq) /* set ifnet address */ #define SIOCGIFADDR _IOWR('i', 33, struct ifreq) /* get ifnet address */ #define SIOCSIFDSTADDR _IOW('i', 14, struct ifreq) /* set p-p address */ Index: sys/sys/timetc.h =================================================================== RCS file: /cvs/src/sys/sys/timetc.h,v retrieving revision 1.12 diff -u -p -r1.12 timetc.h --- sys/sys/timetc.h 6 Jul 2020 13:33:09 -0000 1.12 +++ sys/sys/timetc.h 22 Nov 2021 03:09:34 -0000 @@ -117,6 +117,16 @@ extern struct timecounter *timecounter; extern struct uvm_object *timekeep_object; extern struct timekeep *timekeep; +struct timecycle { + uint64_t tcyc_cycles; + int64_t tcyc_scale; + struct bintime tcyc_offset; + unsigned int tcyc_version; +}; + +void timecycle(struct timecycle *); +void gettimecycle(struct timecycle *); + u_int64_t tc_getfrequency(void); u_int64_t tc_getprecision(void); void tc_init(struct timecounter *tc); Index: usr.bin/kstat/kstat.c =================================================================== RCS file: /cvs/src/usr.bin/kstat/kstat.c,v retrieving revision 1.6 diff -u -p -r1.6 kstat.c --- usr.bin/kstat/kstat.c 13 Aug 2020 12:37:16 -0000 1.6 +++ usr.bin/kstat/kstat.c 22 Nov 2021 03:09:35 -0000 @@ -351,6 +351,7 @@ kstat_kv(const void *d, ssize_t len) buf = d; do { kv = (const struct kstat_kv *)buf; + const struct timespec *ts; buf += sizeof(*kv); len -= sizeof(*kv); @@ -401,6 +402,19 @@ kstat_kv(const void *d, ssize_t len) printf("%.2f degC", (f - 273150000.0) / 1000000.0); break; + case KSTAT_KV_T_MONOTIME: + ts = &kstat_kv_timespec(kv); + printf("monotime %lld.%09ld", ts->tv_sec, ts->tv_nsec); + break; + case KSTAT_KV_T_REALTIME: + ts = &kstat_kv_timespec(kv); + printf("realtime %lld.%09ld", ts->tv_sec, ts->tv_nsec); + break; + case KSTAT_KV_T_INTERVAL: + ts = &kstat_kv_timespec(kv); + printf("interval %lld.%09ld", ts->tv_sec, ts->tv_nsec); + break; + default: printf("unknown type %u, stopping\n", kv->kv_type); return; @@ -474,17 +488,17 @@ kstat_list(struct kstat_tree *kt, int fd } else id = ksreq->ks_id; - if (!kstat_filter_entry(kfs, ksreq)) { + if (kse->serrno != 0 || !kstat_filter_entry(kfs, ksreq)) { free(ksreq->ks_data); free(kse); continue; } - if (RBT_INSERT(kstat_tree, kt, kse) != NULL) - errx(1, "duplicate kstat entry"); - - if (kse->serrno != 0) - continue; + if (RBT_INSERT(kstat_tree, kt, kse) != NULL) { + errx(1, "duplicate kstat entry %s:%u:%s:%u", + ksreq->ks_provider, ksreq->ks_instance, + ksreq->ks_name, ksreq->ks_unit); + } while (ksreq->ks_datalen > len) { len = ksreq->ks_datalen; @@ -525,6 +539,8 @@ kstat_print(struct kstat_tree *kt) break; } } + + fflush(stdout); } static void Index: usr.sbin/tcpdump/print-ether.c =================================================================== RCS file: /cvs/src/usr.sbin/tcpdump/print-ether.c,v retrieving revision 1.38 diff -u -p -r1.38 print-ether.c --- usr.sbin/tcpdump/print-ether.c 15 Apr 2020 20:19:25 -0000 1.38 +++ usr.sbin/tcpdump/print-ether.c 22 Nov 2021 03:09:38 -0000 @@ -88,7 +88,26 @@ u_short extracted_ethertype; void ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) { + const struct bpf_hdr *bh = (const struct bpf_hdr *)h; + ts_print(&h->ts); + printf("rcvif %u ", bh->bh_ifidx); + printf("pri %u ", bh->bh_flags & BPF_F_PRI_MASK); + switch (bh->bh_flags & BPF_F_DIR_MASK) { + case 0: + break; + case BPF_F_DIR_IN: + printf("in "); + break; + case BPF_F_DIR_OUT: + printf("out "); + break; + case BPF_F_DIR_IN|BPF_F_DIR_OUT: + printf("in+out "); + break; + } + if (bh->bh_flags & BPF_F_FLOWID) + printf("flow %04x ", bh->bh_flowid); /* * Some printers want to get back at the ethernet addresses, Index: usr.sbin/vmd/priv.c =================================================================== RCS file: /cvs/src/usr.sbin/vmd/priv.c,v retrieving revision 1.15 diff -u -p -r1.15 priv.c --- usr.sbin/vmd/priv.c 28 Jun 2019 13:32:51 -0000 1.15 +++ usr.sbin/vmd/priv.c 22 Nov 2021 03:09:38 -0000 @@ -144,8 +144,10 @@ priv_dispatch_parent(int fd, struct priv strlcpy(ifbr.ifbr_ifsname, vfr.vfr_value, sizeof(ifbr.ifbr_ifsname)); if (ioctl(env->vmd_fd, SIOCBRDGADD, &ifbr) == -1 && - errno != EEXIST) - log_warn("SIOCBRDGADD"); + errno != EEXIST) { + log_warn("switch %s add %s", + vfr.vfr_name, vfr.vfr_value); + } break; case IMSG_VMDOP_PRIV_IFEXISTS: /* Determine if bridge/switch exists */