From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: passt.top; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Ea7rfNMY; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by passt.top (Postfix) with ESMTP id 7B0135A0621 for ; Wed, 13 Nov 2024 02:14:24 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1731460463; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=QN//Y7u2fAM2gA7jbsLQsM5q/t6AexfiaVXuhSiC3dk=; b=Ea7rfNMYydNc/1KM1aq1Mz30Ah7JuxdRo5yd5OUkMrrDRr3EEiVKWntf0CRvvz8ToFKJIT 5pPBvu4U11+rwUlyAiaMeHtbNVWlpNzF+1f0u4MQKoSJy0vv34l1D4rS/ZvF/gBAQL+CY9 5KqlBaBDT9n8pzrwam7K+osj6Lf6tq0= Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-612-AHNCHzOAMJCf86uHg-AYdQ-1; Tue, 12 Nov 2024 20:14:22 -0500 X-MC-Unique: AHNCHzOAMJCf86uHg-AYdQ-1 X-Mimecast-MFC-AGG-ID: AHNCHzOAMJCf86uHg-AYdQ Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-43157cff1d1so48349305e9.2 for ; Tue, 12 Nov 2024 17:14:21 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731460461; x=1732065261; h=content-transfer-encoding:mime-version:organization:references :in-reply-to:message-id:subject:cc:to:from:date:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=QN//Y7u2fAM2gA7jbsLQsM5q/t6AexfiaVXuhSiC3dk=; b=wazMkAvVTBGB0MJg0oDAt4vs83QSBcdvUifZoz5+C7JTKLYtF+rEl3MKwkKf8tM2G0 uzQzsVdJDBViaD/seYdV9h7YM/sy4zgdtp9qTyXTVV1ASBU1MZ1a81yAYref5+cX5aCl 0Z2R3EjbkXoOkbVQFSRC8YCIxt54jzs1QHxUemB959E+rP8PVTvfcL3wmNDCpIP+ILts aRhbyQ3+kIyJhu0M0jlrKPNLbhsKw2rNM4l+LywsFbsDz5HK4BpMe55/rX1QYXHOCS/V EGRIHONG0e9pcipduqNwOjUzWTCmg/EyKMbVimpm/1jhpT/39O95YkJvgWhhYbOd9Nms PcAg== X-Gm-Message-State: AOJu0YxK+UTISXuaqbuNUd3mQkLbS2kIqU8PeinE7M8B3c6R3gYLnbHi 8jQrlXfYJxpa+Rqsm007ez3MHGcMoAc79HNAhczj6+wXDENqSHcteZA1+cz/+Ac1gHVnXfBUP0H ZRIT6LS+YmzbGaffGN0/AkjYdH4kawh63u/w4S26Uhd3Qcm1X8g== X-Received: by 2002:a05:6000:389:b0:37c:cbd4:ec9 with SMTP id ffacd0b85a97d-3820df6a9e5mr791759f8f.5.1731460460945; Tue, 12 Nov 2024 17:14:20 -0800 (PST) X-Google-Smtp-Source: AGHT+IHUvVsgR5kluaJVZ/HQOLFR88jbPXCPwDAKbaqpTslzx+mQG+w7YfgKZi1Mp8NLR4mgGDKVpA== X-Received: by 2002:a05:6000:389:b0:37c:cbd4:ec9 with SMTP id ffacd0b85a97d-3820df6a9e5mr791752f8f.5.1731460460539; Tue, 12 Nov 2024 17:14:20 -0800 (PST) Received: from maya.myfinge.rs (ifcgrfdd.trafficplex.cloud. [176.103.220.4]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-381eda04049sm16548941f8f.93.2024.11.12.17.14.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Nov 2024 17:14:18 -0800 (PST) Date: Wed, 13 Nov 2024 02:14:16 +0100 From: Stefano Brivio To: David Gibson Subject: Re: [PATCH 6/6] ndp: Send unsolicited Router Advertisements Message-ID: <20241113021416.418a338c@elisabeth> In-Reply-To: <20241112040618.1804081-7-david@gibson.dropbear.id.au> References: <20241112040618.1804081-1-david@gibson.dropbear.id.au> <20241112040618.1804081-7-david@gibson.dropbear.id.au> Organization: Red Hat X-Mailer: Claws Mail 4.2.0 (GTK 3.24.41; x86_64-pc-linux-gnu) MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: _UxScMcNhSFc7TUvmjTZ-OcW98LQvibhbcZI7j9BXck_1731460461 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Message-ID-Hash: FCRZFTZALSGZ7XTKZXRO3CTHVORIOXJK X-Message-ID-Hash: FCRZFTZALSGZ7XTKZXRO3CTHVORIOXJK X-MailFrom: sbrivio@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: passt-dev@passt.top X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Kind of nits only, the whole series looks good to me otherwise: On Tue, 12 Nov 2024 15:06:18 +1100 David Gibson wrote: > Currently, our NDP implementation only sends Router Advertisements (RA) > when it receives a Router Solicitation (RS) from the guest. However, > RFC 4861 requires that we periodically send unsolicited RAs. > > Linux as a guest also requires this: it will send an RS when a link first > comes up, but the route it gets from this will have a finite lifetime (we > set this to 65535s, the maximum allowed, around 18 hours). When that > expires the guest will not send a new RS, but instead expects the route to > have been renewed (if still valid) by an unsolicited RA. > > Implement sending unsolicited RAs on a partially randomised timer, as > required by RFC 4861. The RFC also specifies that solicited RAs should > also be delayed, or even not omitted, if the next unsolicited RA is soon s/not// > enough. For now we don't do that, always sending an immediate RA in > response to an RS. We can get away with this because in our use cases > we expect to just have passt itself and the guest on the link, rather than > a large broadcast domain. > > Link: https://github.com/kubevirt/kubevirt/issues/13191 > Signed-off-by: David Gibson > --- > ip.h | 9 +++++++++ > ndp.c | 41 +++++++++++++++++++++++++++++++++++++++++ > ndp.h | 3 +++ > passt.c | 3 +++ > 4 files changed, 56 insertions(+) > > diff --git a/ip.h b/ip.h > index b8d4a5b..0742612 100644 > --- a/ip.h > +++ b/ip.h > @@ -92,4 +92,13 @@ struct ipv6_opt_hdr { > > char *ipv6_l4hdr(const struct pool *p, int idx, size_t offset, uint8_t *proto, > size_t *dlen); > + > +/* IPv6 link-local all-nodes multicast adddress, ff02::1 */ > +static const struct in6_addr in6addr_ll_all_nodes = { > + .s6_addr = { > + 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, > + }, > +}; > + > #endif /* IP_H */ > diff --git a/ndp.c b/ndp.c > index c5fbccf..8c019df 100644 > --- a/ndp.c > +++ b/ndp.c > @@ -372,3 +372,44 @@ int ndp(const struct ctx *c, const struct icmp6hdr *ih, > > return 1; > } > + > +/* Default interval between unsolicited RAs (seconds) */ > +#define DEFAULT_MAX_RTR_ADV_INTERVAL 600 /* RFC 4861, 6.2.1 */ > + > +/* Minimum required interval between RAs (seconds) */ > +#define MIN_DELAY_BETWEEN_RAS 3 /* RFC 4861, 10 */ By the way, I think this is still all correct, as I quickly double checked it against RFC 8319. If you're not aware: see also sections 3 and 4 there. > + > +static time_t next_ra; > + > +/** > + * ndp_timer() - Send unsolicited NDP messages if necessary > + * @c: Execution context > + * @now: Current (monotonic) time > + */ > +void ndp_timer(const struct ctx *c, const struct timespec *now) > +{ > + time_t max_rtr_adv_interval = DEFAULT_MAX_RTR_ADV_INTERVAL; > + time_t min_rtr_adv_interval, interval; > + > + if (c->no_ra || now->tv_sec < next_ra) > + return; > + > + /* We must advertise before the route's lifetime expires */ > + max_rtr_adv_interval = MIN(max_rtr_adv_interval, RT_LIFETIME - 1); > + > + /* But we must not go smaller than the minimum delay */ > + max_rtr_adv_interval = MAX(max_rtr_adv_interval, MIN_DELAY_BETWEEN_RAS); > + > + /* RFC 4861, 6.2.1 */ > + min_rtr_adv_interval = MAX(max_rtr_adv_interval / 3, > + MIN_DELAY_BETWEEN_RAS); > + > + interval = min_rtr_adv_interval + > + random() % (max_rtr_adv_interval - min_rtr_adv_interval); So, I would have called srandom() before this, especially in the case we get, one day, two instances of passt advertising at the same time. But Coverity is more annoying than I am and reports: /home/sbrivio/passt/ndp.c:408:3: Type: Calling risky function (DC.WEAK_CRYPTO) /home/sbrivio/passt/ndp.c:408:3: dont_call: "random" should not be used for security-related applications, because linear congruential algorithms are too easy to break. /home/sbrivio/passt/ndp.c:408:3: remediation: Use a compliant random number generator, such as "/dev/random" or "/dev/urandom" on Unix-like systems, and CNG (Cryptography API: Next Generation) on Windows. Of course it's all bogus but I would have a *slight* preference to get rid of this, by either picking a fixed interval deviation at the beginning with getrandom(), or using something like tcp_init_seq() modulo something << 600. Alternatively, we could also keep /dev/random or /dev/urandom open but it looks totally overkill. At that point I'd rather keep random() here. > + > + info("NDP: sending unsolicited RA, next in %llds", (long long)interval); > + > + ndp_ra(c, &in6addr_ll_all_nodes); > + > + next_ra = now->tv_sec + interval; > +} > diff --git a/ndp.h b/ndp.h > index abe6d02..41c2000 100644 > --- a/ndp.h > +++ b/ndp.h > @@ -6,7 +6,10 @@ > #ifndef NDP_H > #define NDP_H > > +struct icmp6hdr; > + > int ndp(const struct ctx *c, const struct icmp6hdr *ih, > const struct in6_addr *saddr, const struct pool *p); > +void ndp_timer(const struct ctx *c, const struct timespec *now); > > #endif /* NDP_H */ > diff --git a/passt.c b/passt.c > index fac6101..454ac8e 100644 > --- a/passt.c > +++ b/passt.c > @@ -52,6 +52,7 @@ > #include "arch.h" > #include "log.h" > #include "tcp_splice.h" > +#include "ndp.h" > > #define EPOLL_EVENTS 8 > > @@ -110,6 +111,8 @@ static void post_handler(struct ctx *c, const struct timespec *now) > > flow_defer_handler(c, now); > #undef CALL_PROTO_HANDLER > + > + ndp_timer(c, now); > } > > /** -- Stefano