From nobody Fri Feb 02 14:39:34 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4TRJMB6SfSz58sN4; Fri, 2 Feb 2024 14:39:34 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4TRJMB4cLzz4G7m; Fri, 2 Feb 2024 14:39:34 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1706884774; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=PznFGdRL0R7gsddoYBo/urGA6pqesDKdL6kpH30IaHg=; b=IyXo9od6nO+gom8Ml0HndTHzuIgkRkg6LYAhF+u9nrY/80wS0fzcVWIGklHp2WKD7dNHdz Osx6xK76E/LJoBH9EFTgI3jhINqA5VGxwoZwwDOz275s1ChwMoC4tIE8r12ccOESlSroD4 JEuXPwP9cNVCjQHAVOejhEwrzsmM9XJYVSHwfFCVVBJTJc9kyRvwnojNxkpXdQ7t4NhIH1 JvksxACojBQHyP1oR+gnVY+jJoJkKPS35mRZyfYYstRAKWJWmQg5W9BI8wK4095hcqaoWD 5U5a/YgM39TLHhgd3sGnBpxa2JOgblb6AoIdOH6Yk+ZiyUnH1ETBOZCl7zEkOQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1706884774; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=PznFGdRL0R7gsddoYBo/urGA6pqesDKdL6kpH30IaHg=; b=GbCj93HP/L2z77DAGgUwinfIx4DN17mW15uVtFq2PhceCh8lTEWtLd9syUUptjrJdncwIM nVNkjJxLBozDmMNyAKb5vCSiXZjgt/kEfjQCe3XoCMo7OWHf6Clys8uoReZo4Lwg0AIkMX 4PA/bfc4C2BixulfwITTVAQh97HQsNZt3w4QJoEwrZaqC0NuB2g2RyO1aTDyvjwQ8FC2xX 6Nnib8fqAQFQlFaf9QNfF6UILhJitVfpVUyobx6luwXZvykwLMNwjXI2Bj1m/3vS/chg+C cW+oAeca+AQErYl/N8N3Mb0yacwBFhKZMoZCS4un4RbDSS97Ze21YwhSzwtjiA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1706884774; a=rsa-sha256; cv=none; b=LBTv8b6eB5uRqB+jRuScF7tecFAx3Wz6wp2oUtnWqWQ1uoMf5I5zzVv23Mxq00H6t8pxL7 eEWe6IV6XLNg19T24kQv3wg6tHi2CwDDek1C490uBVx6VnbM8EkKvMi+VJzCBj8UNknUZU vYNvzBRvmHyClShS8S6hjPrrydD+T20FRBsr7LpWYhWj/aftwVO/wW271NekbVmROFYnqx TJ3Qu5e+su2FkniOdAgOZ64G/D3Df9GeqYweKUfLQUBoZpgXQ/dNK+Vf7GtNsM0dahzOV1 xN07SSoZulYuFKCBP3hO7TbOnJ72anJYnCUc1PNeGt+WKbe1lLAVS5LculqZXQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4TRJMB3js0zZZQ; Fri, 2 Feb 2024 14:39:34 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 412EdY07000475; Fri, 2 Feb 2024 14:39:34 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 412EdYoH000472; Fri, 2 Feb 2024 14:39:34 GMT (envelope-from git) Date: Fri, 2 Feb 2024 14:39:34 GMT Message-Id: <202402021439.412EdYoH000472@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Mark Johnston Subject: git: 73ef676c9ffd - stable/14 - traceroute6: Implement ECN bleaching detection List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: 73ef676c9ffd625027fa7fd0ccb9948adae00d93 Auto-Submitted: auto-generated The branch stable/14 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=73ef676c9ffd625027fa7fd0ccb9948adae00d93 commit 73ef676c9ffd625027fa7fd0ccb9948adae00d93 Author: Jose Luis Duran AuthorDate: 2023-10-27 23:59:28 +0000 Commit: Mark Johnston CommitDate: 2024-02-02 14:32:30 +0000 traceroute6: Implement ECN bleaching detection Explicit Congestion Notification (ECN) is a mechanism that allows end-to-end notification of network congestion without dropping packets by explicitly setting the ECN code point (2 bits). Per RFC 8087, section 3.5, network devices should not be configured to change the ECN code point in the packets that they forward, except to set the CE (Congestion Experienced) code point ('11') to signal incipient congestion. The current commit adds an -E flag to traceroute6 that crafts a packet with an ECT(1) code point ('01'). If the packet is received back with a zero ECN code point ('00'), it outputs that the hop in question erases or "bleaches" the ECN code point values. Bleaching may occur for various reasons (including normalizing packets to hide which equipment supports ECN). This policy prevents the use of ECN by applications. If the packet is received back with an all-ones ECN code point ('11'), it outputs that the hop in question is experiencing "congestion". If the packet is received back with a different ECN code point ('10'), it outputs that the hop in question changes or "mangles" the ECN code point values. If the packet is received with the same ECN code point that was sent ('01'), it outputs that the hop has "passed" the ECN bits appropriately. Inspired by: Darwin Reviewed by: imp, markj MFC after: 1 month Pull Request: https://github.com/freebsd/freebsd-src/pull/879 (cherry picked from commit 0c2218d1d5fda2c579d3d33f1fd3af9ad447e160) --- usr.sbin/traceroute6/traceroute6.8 | 20 +++++++++++++++-- usr.sbin/traceroute6/traceroute6.c | 44 ++++++++++++++++++++++++++++++++------ 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/usr.sbin/traceroute6/traceroute6.8 b/usr.sbin/traceroute6/traceroute6.8 index f02b08872ea5..13917eb47c7f 100644 --- a/usr.sbin/traceroute6/traceroute6.8 +++ b/usr.sbin/traceroute6/traceroute6.8 @@ -27,7 +27,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd November 25, 2020 +.Dd October 25, 2023 .Dt TRACEROUTE6 8 .Os .\" @@ -38,7 +38,7 @@ .Sh SYNOPSIS .Nm .Bk -words -.Op Fl adIlnNrSTUv +.Op Fl adEIlnNrSTUv .Ek .Bk -words .Op Fl f Ar firsthop @@ -94,6 +94,22 @@ Turn on AS# lookups for each hop encountered. Turn on AS# lookups and use the given server instead of the default. .It Fl d Debug mode. +.It Fl E +Detect ECN bleaching. +Set the +.Em IPTOS_ECN_ECT1 +Explicit Congestion Notification (ECN) bits +.Pq Dv 01 , +and report if the hop has bleached +.Pq Dv 00 +or mangled +.Pq Dv 10 +them, or if it is experiencing congestion +.Pq Dv 11 . +Otherwise, report that it passed the bits appropriately. +If +.Fl t +is also specified, the corresponding ECN bits will be replaced. .It Fl f Ar firsthop Specify how many hops to skip in trace. .It Fl g Ar gateway diff --git a/usr.sbin/traceroute6/traceroute6.c b/usr.sbin/traceroute6/traceroute6.c index 7907952e9328..1f5fc0a6b3a3 100644 --- a/usr.sbin/traceroute6/traceroute6.c +++ b/usr.sbin/traceroute6/traceroute6.c @@ -274,6 +274,7 @@ static char sccsid[] = "@(#)traceroute.c 8.1 (Berkeley) 6/6/93"; #include #include +#include #include #include #include @@ -306,7 +307,7 @@ void capdns_open(void); int get_hoplim(struct msghdr *); double deltaT(struct timeval *, struct timeval *); const char *pr_type(int); -int packet_ok(struct msghdr *, int, int, u_char *, u_char *); +int packet_ok(struct msghdr *, int, int, u_char *, u_char *, u_char *); void print(struct msghdr *, int); const char *inetname(struct sockaddr *); u_int32_t sctp_crc32c(void *, u_int32_t); @@ -352,6 +353,7 @@ static int nflag; /* print addresses numerically */ static int useproto = IPPROTO_UDP; /* protocol to use to send packet */ static int lflag; /* print both numerical address & hostname */ static int as_path; /* print as numbers for each hop */ +static int ecnflag; /* ECN bleaching detection flag */ static char *as_server = NULL; static void *asn; @@ -367,7 +369,7 @@ main(int argc, char *argv[]) struct hostent *hp; size_t size, minlen; uid_t uid; - u_char type, code; + u_char type, code, ecn; #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) char ipsec_inpolicy[] = "in bypass"; char ipsec_outpolicy[] = "out bypass"; @@ -413,7 +415,7 @@ main(int argc, char *argv[]) seq = 0; ident = htons(getpid() & 0xffff); /* same as ping6 */ - while ((ch = getopt(argc, argv, "aA:df:g:Ilm:nNp:q:rs:St:TUvw:")) != -1) + while ((ch = getopt(argc, argv, "aA:dEf:g:Ilm:nNp:q:rs:St:TUvw:")) != -1) switch (ch) { case 'a': as_path = 1; @@ -425,6 +427,9 @@ main(int argc, char *argv[]) case 'd': options |= SO_DEBUG; break; + case 'E': + ecnflag = 1; + break; case 'f': ep = NULL; errno = 0; @@ -596,6 +601,15 @@ main(int argc, char *argv[]) exit(1); } + if (ecnflag) { + if (tclass != -1) { + tclass &= ~IPTOS_ECN_MASK; + } else { + tclass = 0; + } + tclass |= IPTOS_ECN_ECT1; + } + /* revoke privs */ uid = getuid(); if (setresuid(uid, uid, uid) == -1) { @@ -960,7 +974,7 @@ main(int argc, char *argv[]) send_probe(++seq, hops); while ((cc = wait_for_reply(rcvsock, &rcvmhdr))) { (void) gettimeofday(&t2, NULL); - if (packet_ok(&rcvmhdr, cc, seq, &type, &code)) { + if (packet_ok(&rcvmhdr, cc, seq, &type, &code, &ecn)) { if (!IN6_ARE_ADDR_EQUAL(&Rcv.sin6_addr, &lastaddr)) { if (probe > 0) @@ -969,6 +983,22 @@ main(int argc, char *argv[]) lastaddr = Rcv.sin6_addr; } printf(" %.3f ms", deltaT(&t1, &t2)); + if (ecnflag) { + switch (ecn) { + case IPTOS_ECN_ECT1: + printf(" (ecn=passed)"); + break; + case IPTOS_ECN_NOTECT: + printf(" (ecn=bleached)"); + break; + case IPTOS_ECN_CE: + printf(" (ecn=congested)"); + break; + default: + printf(" (ecn=mangled)"); + break; + } + } if (type == ICMP6_DST_UNREACH) { switch (code) { case ICMP6_DST_UNREACH_NOROUTE: @@ -1302,7 +1332,8 @@ pr_type(int t0) } int -packet_ok(struct msghdr *mhdr, int cc, int seq, u_char *type, u_char *code) +packet_ok(struct msghdr *mhdr, int cc, int seq, u_char *type, u_char *code, + u_char *ecn) { struct icmp6_hdr *icp; struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name; @@ -1385,6 +1416,7 @@ packet_ok(struct msghdr *mhdr, int cc, int seq, u_char *type, u_char *code) void *up; hip = (struct ip6_hdr *)(icp + 1); + *ecn = ntohl(hip->ip6_flow & IPV6_ECN_MASK) >> 20; if ((up = get_uphdr(hip, (u_char *)(buf + cc))) == NULL) { if (verbose) warnx("failed to get upper layer header"); @@ -1804,7 +1836,7 @@ usage(void) { fprintf(stderr, -"usage: traceroute6 [-adIlnNrSTUv] [-A as_server] [-f firsthop] [-g gateway]\n" +"usage: traceroute6 [-adEIlnNrSTUv] [-A as_server] [-f firsthop] [-g gateway]\n" " [-m hoplimit] [-p port] [-q probes] [-s src] [-w waittime] target\n" " [datalen]\n"); exit(1);