From patchwork Fri Sep 11 11:30:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Wienand X-Patchwork-Id: 249718 Delivered-To: patch@linaro.org Received: by 2002:a05:6e02:ecf:0:0:0:0 with SMTP id i15csp1556023ilk; Fri, 11 Sep 2020 04:31:20 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwG0AI0atyWDKNh4WBjNeCeFdZQbjLqkRdRZ6+FsMl6crsZdwGiItzmKwLRnBnDBUU7Qt4l X-Received: by 2002:a25:5306:: with SMTP id h6mr1829272ybb.60.1599823880601; Fri, 11 Sep 2020 04:31:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1599823880; cv=none; d=google.com; s=arc-20160816; b=gFUH3hh68jeakbBg7G83JgKYwHsnY9qbfXnwB38OxN48lRyjJs222+exwsxUZxpBla LGW4FycNKlw7xRlrYKTMbFiq0O+Yk0B5+UgpCjnz23ephHmcreJSWjEcVOwLkNwld2cA NbRAJoY/hbfUYiyLATNGllwR8MBexOByMtwi+74F4u0EZouJxgZjKZgKKikyMdj1+9PB oFU4ljfXBI/48xAEAgntNXDztUfcp+CniNese5164So7/oMgsT6sCgz2yiuqNh1OMY9r nazHXrM2aGGW6WY8Ffq/oBh4uWQ4kmbrBQeskVUzOmK3AnvmkoqJDUeRCUke4/hFGXbI Rg4Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:errors-to:sender:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:cc :mime-version:message-id:date:subject:to:from:delivered-to :dkim-signature; bh=Zaz8zAI1/FjFYuSGx4aNAfREYaQ8V2bBCRVTFZ8BKbI=; b=Alb6Ddocj7qF4LALPB3O5PDv51hi2ulZWFAq7bfRtrBZgEmxU/qST064SjjqV899qQ bqifbJVAOLzzhMeduKW29UzJC/u4FwApd7sCvTnrV8uRn4mHyeBmlR+f96bDU8lRpG8F 3TnfeeRaCIfB1bzwJldnIFWppmbCWgmyaJQ6EIk960Zq/C2dsA1Xvs10tjsUZgSKUYMT BZmUNzhEMdH08r2fw8nqb/OXXfskZWVSd97pct3KbU/LugnqSrdrfpaamAYklTPU4I2B 45UoOyx19dEVZlur4HHCMy1bGKd1VC2FSDzNlDTM7cJdPe0K795NZ539npaThb/xRxrk RcBw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=DGgahb7y; spf=pass (google.com: domain of libvir-list-bounces@redhat.com designates 205.139.110.61 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from us-smtp-delivery-1.mimecast.com (us-smtp-1.mimecast.com. [205.139.110.61]) by mx.google.com with ESMTPS id o69si2159462ybg.44.2020.09.11.04.31.20 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 11 Sep 2020 04:31:20 -0700 (PDT) Received-SPF: pass (google.com: domain of libvir-list-bounces@redhat.com designates 205.139.110.61 as permitted sender) client-ip=205.139.110.61; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=DGgahb7y; spf=pass (google.com: domain of libvir-list-bounces@redhat.com designates 205.139.110.61 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1599823880; h=from:from:sender:sender: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:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=Zaz8zAI1/FjFYuSGx4aNAfREYaQ8V2bBCRVTFZ8BKbI=; b=DGgahb7yT34PgXeI5O0DRQPtu0aAmyKismVbjLaWI4jWUDu0mo/35zXDs0ZTA7ZQ0MdLDB ptU9fXGLD8Spad2GyVcf/5At3mfYo4wly4LPNdFNo9O9YbKvZAXgm7VD1mIs71ep0LD/00 /6EeGj+cv+BaBWTKrMOYqB0mX/RELw4= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-266-UgcbnYJMNviWs7Q9SUzHow-1; Fri, 11 Sep 2020 07:31:17 -0400 X-MC-Unique: UgcbnYJMNviWs7Q9SUzHow-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D116F1074643; Fri, 11 Sep 2020 11:31:12 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A73C47E8F0; Fri, 11 Sep 2020 11:31:12 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 66370181A050; Fri, 11 Sep 2020 11:31:12 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 08BBVAtV009005 for ; Fri, 11 Sep 2020 07:31:11 -0400 Received: by smtp.corp.redhat.com (Postfix) id C947D201828C; Fri, 11 Sep 2020 11:31:10 +0000 (UTC) Delivered-To: libvir-list@redhat.com Received: from mimecast-mx02.redhat.com (mimecast03.extmail.prod.ext.rdu2.redhat.com [10.11.55.19]) by smtp.corp.redhat.com (Postfix) with ESMTPS id C544F2028DCC for ; Fri, 11 Sep 2020 11:31:07 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 84B76811E76 for ; Fri, 11 Sep 2020 11:31:07 +0000 (UTC) Received: from mail-pf1-f200.google.com (mail-pf1-f200.google.com [209.85.210.200]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-545-lVqFXyokP7Ss-yX7Hm8bAg-1; Fri, 11 Sep 2020 07:31:05 -0400 X-MC-Unique: lVqFXyokP7Ss-yX7Hm8bAg-1 Received: by mail-pf1-f200.google.com with SMTP id m13so5031203pfk.19 for ; Fri, 11 Sep 2020 04:31:05 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=Zaz8zAI1/FjFYuSGx4aNAfREYaQ8V2bBCRVTFZ8BKbI=; b=t/eQFaNXYiMFd6/H/+hoHtRhd93drdEfzwo5e6tdX5qhd7n3DjjGvtZ61j6QXjy2bV LNAsZxKmqm5pL9FA5l70f78hNc6r5Wfu41dr/drn3JzQfzV3M/MV6P0cZbzlNMNmuzUj jVn3YLgfMTVRUr2icH3xbfCp9I07vlYFxXkP0h9IrD7887Io6tvw6dBTS8Szsd4gdkxj dnPmUKsyk/vX3F0SIsmKiaUw0Uj572rT/zOsJIiz2O3IFN5KyJw1Y+tXdXvLMLUiEy1B rokAUQb174XTvnoe1GgDK4ARvDNrXFYjWcMpM8R6uFvmU7Z/Dn2bESPc26J+3vJ5Lb5j omEQ== X-Gm-Message-State: AOAM531sCShtzzHtkAWie2iXtIh/xl6aRYxmyk2QePNWLOufIUstJr6W R7ajNd9yeoG8hbhbS6absamIrxFUmOzxrxdOrRBgqbHeYG6BSfWVnd5aKZ0cXz1FfrZqt6pXzEk o8He3PgV11ut9+5qwJhM= X-Received: by 2002:a62:7e04:: with SMTP id z4mr1784185pfc.64.1599823864206; Fri, 11 Sep 2020 04:31:04 -0700 (PDT) X-Received: by 2002:a62:7e04:: with SMTP id z4mr1784158pfc.64.1599823863805; Fri, 11 Sep 2020 04:31:03 -0700 (PDT) Received: from fedora19.redhat.com (2001-44b8-4132-5a00-e6a4-71ff-fe56-570c.static.ipv6.internode.on.net. [2001:44b8:4132:5a00:e6a4:71ff:fe56:570c]) by smtp.gmail.com with ESMTPSA id 20sm2152017pfv.87.2020.09.11.04.31.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Sep 2020 04:31:03 -0700 (PDT) From: Ian Wienand To: libvir-list@redhat.com Subject: [PATCH] network: Only check kernel added routes in virNetDevIPCheckIPv6Forwarding Date: Fri, 11 Sep 2020 21:30:30 +1000 Message-Id: <20200911113030.915357-1-iwienand@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-loop: libvir-list@redhat.com Cc: Cedric Bosdonnat , Laine Stump , Ian Wienand X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0.003 X-Mimecast-Originator: redhat.com The original motivation for adding virNetDevIPCheckIPv6Forwarding (00d28a78b5d1f6eaf79f06ac59e31c568af9da37) was that networking routes would disappear when ipv6 forwarding was enabled for an interface. This is a fairly undocumented side-effect of the "accept_ra" sysctl for an interface. 1 means the interface will accept_ra's if not forwarding, 2 means always accept_RAs; but it is not explained that enabling forwarding when accept_ra==1 will also clear any kernel RA assigned routes, very likely breaking your networking. The check to warn about this currently uses netlink to go through all the routes and then look at the accept_ra status of the interfaces. However, it has been noticed that this problem does not affect systems where IPv6 RA configuration is handled in userspace, e.g. via tools such as NetworkManager. In this case, the error message from libvirt is spurious, and modifying the forwarding state will not affect the RA state or disable your networking. If you refer to the function rt6_purge_dflt_routers() in the kernel, we can see that the routes being purged are only those with the kernel's RTF_ADDRCONF flag set; that is, routes added by the kernel's RA handling. Why does it do this? I think this is a Linux implementation decision; it has always been like that and there are some comments suggesting that it is because a router should be statically configured, rather than accepting external configurations. The solution implemented here is to convert the existing check into a walk of /proc/net/ipv6_route and look for routes with this flag set. We then check the accept_ra status for the interface, and if enabling forwarding would break things raise an error. This should hopefully avoid "interactive" users, who are likely to be using NetworkManager and the like, having false warnings when enabling IPv6, but retain the error check for users relying on kernel-based IPv6 interface auto-configuration. Signed-off-by: Ian Wienand --- src/util/virnetdevip.c | 108 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 2 deletions(-) -- 2.26.2 diff --git a/src/util/virnetdevip.c b/src/util/virnetdevip.c index 7bd5a75f85..93f47f22d9 100644 --- a/src/util/virnetdevip.c +++ b/src/util/virnetdevip.c @@ -43,8 +43,11 @@ #ifdef __linux__ # include # include +# include #endif +#define PROC_NET_IPV6_ROUTE "/proc/net/ipv6_route" + #define VIR_FROM_THIS VIR_FROM_NONE VIR_LOG_INIT("util.netdevip"); @@ -688,15 +691,116 @@ virNetDevIPRouteAdd(const char *ifname, return 0; } +#endif /* defined(__linux__) && defined(HAVE_LIBNL) */ + + +#if defined(__linux__) + +/** + * virNetDevIPCheckIPv6Forwarding + * + * This function checks if IPv6 routes have the RTF_ADDRCONF flag set, + * indicating they have been created by the kernel's RA configuration + * handling. These routes are subject to being flushed when ipv6 + * forwarding is enabled unless accept_ra is explicitly set to "2". + * This will most likely result in ipv6 networking being broken. + * + * Returns: true if it is safe to enable forwarding, or false if + * breakable routes are found. + * + **/ +bool +virNetDevIPCheckIPv6Forwarding(void) +{ + int len; + char *cur; + g_autofree char *buf = NULL; + /* lines are 150 chars */ + enum {MAX_ROUTE_SIZE = 150*100000}; + + /* This is /proc/sys/net/ipv6/conf/all/accept_ra */ + int all_accept_ra = virNetDevIPGetAcceptRA(NULL); + + /* Read ipv6 routes */ + if ((len = virFileReadAll(PROC_NET_IPV6_ROUTE, + MAX_ROUTE_SIZE, &buf)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to read %s " + "for ipv6 forwarding checks"), PROC_NET_IPV6_ROUTE); + return false; + } + + /* VIR_DEBUG("%s output:\n%s", PROC_NET_IPV6_ROUTE, buf); */ + + /* Dropping the last character to stop the loop */ + if (len > 0) + buf[len-1] = '\0'; + + cur = buf; + while (cur) { + char route[33], flags[9], iface[9]; + unsigned int flags_val; + char *iface_val; + int num; + char *nl = strchr(cur, '\n'); + + if (nl) + *nl++ = '\0'; + + num = sscanf(cur, "%32s %*s %*s %*s %*s %*s %*s %*s %8s %8s", + route, flags, iface); + + cur = nl; + if (num != 3) { + VIR_DEBUG("Failed to parse route line: %s", cur); + continue; + } + + if (virStrToLong_ui(flags, NULL, 16, &flags_val)) { + VIR_DEBUG("Failed to parse flags: %s", flags); + continue; + } + + /* This is right justified, strip leading spaces */ + iface_val = &iface[0]; + while (*iface_val && g_ascii_isspace(*iface_val)) + iface_val++; + + VIR_DEBUG("%s iface %s flags %s : RTF_ADDRCONF %sset", + route, iface_val, flags, + (flags_val & RTF_ADDRCONF ? "" : "not ")); + + if (flags_val & RTF_ADDRCONF) { + int ret = virNetDevIPGetAcceptRA(iface_val); + VIR_DEBUG("%s reports accept_ra of %d", + iface_val, ret); + /* If the interface for this autoconfigured route + * has accept_ra == 1, or it is default and the "all" + * value of accept_ra == 1, it will be subject to + * flushing if forwarding is enabled. + */ + if (ret == 1 || (ret == 0 && all_accept_ra == 1)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Check the host setup: interface %s has kernel " + "autoconfigured IPv6 routes and enabling forwarding " + " without accept_ra set to 2 will cause the kernel " + "to flush them, breaking networking."), iface_val); + return false; + } + } + } + return true; +} +#else bool virNetDevIPCheckIPv6Forwarding(void) { - VIR_WARN("built without libnl: unable to check if IPv6 forwarding can be safely enabled"); + VIR_DEBUG("No checks for IPv6 forwarding issues on non-Linux systems", flags); return true; } -#endif /* defined(__linux__) && defined(WITH_LIBNL) */ +#endif /* defined(__linux__) */ /**