Received: by 2002:a05:6a10:16a7:0:0:0:0 with SMTP id gp39csp1111419pxb; Fri, 13 Nov 2020 04:40:42 -0800 (PST) X-Google-Smtp-Source: ABdhPJzSvj7XwBV3i/OxH4OxTHrKu7a9tl4vKvyzAD5uOSr4Dlpzg1K8qZk5m1u1hxKdFQDct0hG X-Received: by 2002:a17:906:d8b0:: with SMTP id qc16mr1675995ejb.268.1605271242595; Fri, 13 Nov 2020 04:40:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1605271242; cv=none; d=google.com; s=arc-20160816; b=RpDnv2V04W5os0PLSj9BTcSUxPJc0ANglZet9irmmqf4pemtkBiz3qrSZcvv0ijvNE DVXxLknChQPD/9Y33TIbVGn3sgC3LZKAJhYFA73HLdpXbKDd7WVo04UuLdVsMttpyfDr DeZMIhrRVzpD7X3SDbMxA595BBg6bQjv9sCo+S7+inkidLcWRQhZ/9B5MFhyRGzBYb26 3kF8XoPNL4IO79qJ9IWjVqX+up1uAQ6zi7qIUfyM27f/0E2FilWUku9H/3Jn8LoBfOWm aH76l1vpjTqGsV3HdCeoR9Z64b2E381K+UdOlHSr7jYzwaEdVG9LyxH9vSOHxHJajCS/ 711w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:cc:to:subject :message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=JZ87/R2nr7BDJywDkG4VTTNvSyQnQEx9n5aSWV3oeOQ=; b=Ysf9GVPwCYC5399xw9PEpuAl4JVT+meh4OPZtMhy3eK6urkHw+WOgcy2o9k7+bzZTl rYJlMPiuTwdXLZfWrCfk4kfriGDP66iVRJaBi+7vKdVvzqYPuC08Kb2tBbENWZjMiSFY zQvbUsRn7ZW0Dg934cLY7tJtIgovCLCD9IysFonYnZo0xdRPy8J/cIsb9mnkODpS7yuS SSrFYBkzRs3hrvci+OFW/+y8NzJqdep3c1jKWwlb8UklU5qybZJIweIfFGddUVhi7dwN Dg6ygXxqIjA2lU3y0LX5bdtnqJepPFbJIL/HLdzzzbXmuJEb6CclCeiv5lVQsAtH8thi btpQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@miraclelinux-com.20150623.gappssmtp.com header.s=20150623 header.b=DjjBMxKe; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id r7si5695531ejr.8.2020.11.13.04.40.18; Fri, 13 Nov 2020 04:40:42 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@miraclelinux-com.20150623.gappssmtp.com header.s=20150623 header.b=DjjBMxKe; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726469AbgKMMin (ORCPT + 99 others); Fri, 13 Nov 2020 07:38:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41260 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726160AbgKMMim (ORCPT ); Fri, 13 Nov 2020 07:38:42 -0500 Received: from mail-il1-x141.google.com (mail-il1-x141.google.com [IPv6:2607:f8b0:4864:20::141]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8ED91C0613D1 for ; Fri, 13 Nov 2020 04:38:42 -0800 (PST) Received: by mail-il1-x141.google.com with SMTP id e17so8336912ili.5 for ; Fri, 13 Nov 2020 04:38:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=miraclelinux-com.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=JZ87/R2nr7BDJywDkG4VTTNvSyQnQEx9n5aSWV3oeOQ=; b=DjjBMxKekjCqU3EXk5TpmsK9ZBs+J3FGVclsSRxYdCcdY4MuGtwrA4oLfzEYSrw9mI R2duZ7E0h5bhfH+FdFjfPCiGLk0fmDgK0veTbB4hqCdjO7hS+VwiCyy6eAtVN5GeIb1v pmv6FPlWvRj3RHI2Q/9hRv7l4qeCg21iR0h3P95AE8ViU9hh9t8d8CXSO0UTJSisaSfM D7EaHH9UoDOfP/cna/xZTwFIlL6rxIg2SzPJgT0evmNilMtiDDqnxz8UIjpQ4bG0dnOU F3+cTyJhXop7sF3lSV5yZEHj6acFM9rdDA48v356asioQ/hCjsxtxj9xAhPq1U4W7ZBa EXYA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=JZ87/R2nr7BDJywDkG4VTTNvSyQnQEx9n5aSWV3oeOQ=; b=SOivdXLJkHEcdl3z1dzBXuJsAi4Y056SdS4om6i2cJ7fpdcFn3Q479JGKSzRQRMCfo aW/V8mGXtmxwY6aZmRqngBZ1S38G/k4nwlOLI6LIudPLpTT5bVoubs840roD1285NxzT PZyxqnZgHOar+SDRbnvSMglG5kNmxRAnVm51RhleRl0XBdGH7X7F1ne0ThZJcZL1RCre I4rCmqfZohZP77ROnnPjJC52PkC5G3bGWjdPhTa0U77gnKzYQ3sg8fnEToj/kfhFQrzC MFIw53j+qlewqx/lZxnF4Fs6zzkyouFvcXWuG8SenuLYeO0Jvxupb/vuAfaQXYN0ZAEc 2S8g== X-Gm-Message-State: AOAM531IxsHuyyig8PeU2mxfjcSW/JR3bxz0DhSKT2GKdlFfRf5yGT3L jfhY+euOV0KNEd7wgLbqnhmDMS7a2aPShEmCdFouFA== X-Received: by 2002:a05:6e02:ce:: with SMTP id r14mr1778186ilq.240.1605271121632; Fri, 13 Nov 2020 04:38:41 -0800 (PST) MIME-Version: 1.0 References: <175b3433a4c.aea7c06513321.4158329434310691736@shytyi.net> <202011110944.7zNVZmvB-lkp@intel.com> <175bd218cf4.103c639bc117278.4209371191555514829@shytyi.net> <175bf515624.c67e02e8130655.7824060160954233592@shytyi.net> In-Reply-To: <175bf515624.c67e02e8130655.7824060160954233592@shytyi.net> From: Hideaki Yoshifuji Date: Fri, 13 Nov 2020 21:38:02 +0900 Message-ID: Subject: Re: [PATCH net-next V4] net: Variable SLAAC: SLAAC with prefixes of arbitrary length in PIO To: Dmytro Shytyi Cc: kuba , kuznet , yoshfuji , liuhangbin , davem , netdev , linux-kernel , Hideaki Yoshifuji Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi, 2020=E5=B9=B411=E6=9C=8813=E6=97=A5(=E9=87=91) 10:57 Dmytro Shytyi : > > Variable SLAAC: SLAAC with prefixes of arbitrary length in PIO (randomly > generated hostID or stable privacy + privacy extensions). > The main problem is that SLAAC RA or PD allocates a /64 by the Wireless > carrier 4G, 5G to a mobile hotspot, however segmentation of the /64 via > SLAAC is required so that downstream interfaces can be further subnetted. > Example: uCPE device (4G + WI-FI enabled) receives /64 via Wireless, and > assigns /72 to VNF-Firewall, /72 to WIFI, /72 to VNF-Router, /72 to > Load-Balancer and /72 to wired connected devices. > IETF document that defines problem statement: > draft-mishra-v6ops-variable-slaac-problem-stmt > IETF document that specifies variable slaac: > draft-mishra-6man-variable-slaac > > Signed-off-by: Dmytro Shytyi > --- > diff -rupN net-next-5.10.0-rc2/net/ipv6/addrconf.c net-next-patch-5.10.0-= rc2/net/ipv6/addrconf.c > --- net-next-5.10.0-rc2/net/ipv6/addrconf.c 2020-11-10 08:46:01.07519= 3379 +0100 > +++ net-next-patch-5.10.0-rc2/net/ipv6/addrconf.c 2020-11-13 02:30:= 25.552724864 +0100 > @@ -1315,10 +1322,14 @@ static int ipv6_create_tempaddr(struct i > struct ifa6_config cfg; > long max_desync_factor; > struct in6_addr addr; > - int ret =3D 0; > + int ret; > + struct in6_addr net_mask; > + struct in6_addr temp; > + struct in6_addr ipv6addr; > + int i; > > write_lock_bh(&idev->lock); > - > + ret =3D 0; > retry: > in6_dev_hold(idev); > if (idev->cnf.use_tempaddr <=3D 0) { > @@ -1340,9 +1351,26 @@ retry: > goto out; > } > in6_ifa_hold(ifp); > - memcpy(addr.s6_addr, ifp->addr.s6_addr, 8); > - ipv6_gen_rnd_iid(&addr); > > + if (ifp->prefix_len =3D=3D 64) { > + memcpy(addr.s6_addr, ifp->addr.s6_addr, 8); > + ipv6_gen_rnd_iid(&addr); > + } else if (ifp->prefix_len > 0 && ifp->prefix_len <=3D 128) { > + memcpy(addr.s6_addr32, ifp->addr.s6_addr, 16); > + get_random_bytes(temp.s6_addr32, 16); > + > + /* tranfrom prefix len into mask */ > + ipv6_plen_to_mask(ifp->prefix_len, &net_mask); > + > + for (i =3D 0; i < 4; i++) { > + /* network prefix */ > + ipv6addr.s6_addr32[i] =3D addr.s6_addr32[i] & net= _mask.s6_addr32[i]; > + /* host id */ > + ipv6addr.s6_addr32[i] |=3D temp.s6_addr32[i] & ~n= et_mask.s6_addr32[i]; > + } > + > + memcpy(addr.s6_addr, ipv6addr.s6_addr32, 16); > ipv6_addr_copy() and then ipv6_addr_prefix_copy() + } > age =3D (now - ifp->tstamp) / HZ; > > regen_advance =3D idev->cnf.regen_max_retry * > @@ -2576,9 +2604,57 @@ int addrconf_prefix_rcv_add_addr(struct > u32 addr_flags, bool sllao, bool tokeniz= ed, > __u32 valid_lft, u32 prefered_lft) > { > - struct inet6_ifaddr *ifp =3D ipv6_get_ifaddr(net, addr, dev, 1); > + struct inet6_ifaddr *ifp =3D NULL; > int create =3D 0; > > + if ((in6_dev->if_flags & IF_RA_VAR_PLEN) =3D=3D IF_RA_VAR_PLEN && > + in6_dev->cnf.addr_gen_mode !=3D IN6_ADDR_GEN_MODE_STABLE_PRIV= ACY) { > + struct inet6_ifaddr *result =3D NULL; > + struct inet6_ifaddr *result_base =3D NULL; > + struct in6_addr net_mask; > + struct in6_addr net_prfx; > + struct in6_addr curr_net_prfx; > + bool prfxs_equal; > + int i; > + > + result_base =3D result; > + rcu_read_lock(); > + list_for_each_entry_rcu(ifp, &in6_dev->addr_list, if_list= ) { > + if (!net_eq(dev_net(ifp->idev->dev), net)) > + continue; > + > + /* tranfrom prefix len into mask */ > + ipv6_plen_to_mask(pinfo->prefix_len, &net_mask); > + /* Prepare network prefixes */ > + for (i =3D 0; i < 4; i++) { > + /* Received/new network prefix */ > + net_prfx.s6_addr32[i] =3D > + pinfo->prefix.s6_addr32[i] & net_= mask.s6_addr32[i]; > + /* Configured/old IPv6 prefix */ > + curr_net_prfx.s6_addr32[i] =3D > + ifp->addr.s6_addr32[i] & net_mask= .s6_addr32[i]; > + } > + /* Compare network prefixes */ > + prfxs_equal =3D 1; > + for (i =3D 0; i < 4; i++) { > + if ((net_prfx.s6_addr32[i] ^ curr_net_prf= x.s6_addr32[i]) !=3D 0) > + prfxs_equal =3D 0; > + } ipv6_prefix_equal() > + if (prfxs_equal && pinfo->prefix_len =3D=3D ifp->= prefix_len) { > + result =3D ifp; > + in6_ifa_hold(ifp); > + break; > + } > + } > + rcu_read_unlock(); > + if (result_base !=3D result) > + ifp =3D result; > + else > + ifp =3D NULL; > + } else { > + ifp =3D ipv6_get_ifaddr(net, addr, dev, 1); > + } > + > if (!ifp && valid_lft) { > int max_addresses =3D in6_dev->cnf.max_addresses; > struct ifa6_config cfg =3D { > @@ -2781,9 +2857,35 @@ void addrconf_prefix_rcv(struct net_devi > dev_addr_generated =3D true; > } > goto ok; > + goto put; > + } else if (((in6_dev->if_flags & IF_RA_VAR_PLEN) =3D=3D I= F_RA_VAR_PLEN) && > + pinfo->prefix_len > 0 && pinfo->prefix_len <=3D= 128) { > + /* SLAAC with prefixes of arbitrary length (Varia= ble SLAAC). > + * draft-mishra-6man-variable-slaac > + * draft-mishra-v6ops-variable-slaac-problem-stmt > + * Contact: Dmytro Shytyi. > + */ > + memcpy(&addr, &pinfo->prefix, 16); > + if (in6_dev->cnf.addr_gen_mode =3D=3D IN6_ADDR_GE= N_MODE_STABLE_PRIVACY) { > + if (!ipv6_generate_address_variable_plen(= &addr, > + = 0, > + = in6_dev, > + = pinfo->prefix_len, > + = true)) { > + addr_flags |=3D IFA_F_STABLE_PRIV= ACY; > + goto ok; > + } > + } else if (!ipv6_generate_address_variable_plen(&= addr, > + 0= , > + i= n6_dev, > + p= info->prefix_len, > + f= alse)) { > + goto ok; > + } > + } else { > + net_dbg_ratelimited("IPv6: Prefix with unexpected= length %d\n", > + pinfo->prefix_len); > } > - net_dbg_ratelimited("IPv6 addrconf: prefix with wrong len= gth %d\n", > - pinfo->prefix_len); > goto put; > > ok: > @@ -3264,6 +3366,118 @@ retry: > return 0; > } > > +static void ipv6_plen_to_mask(int plen, struct in6_addr *net_mask) > +{ > + int i, plen_bytes; > + char bit_array[7] =3D {0b10000000, > + 0b11000000, > + 0b11100000, > + 0b11110000, > + 0b11111000, > + 0b11111100, > + 0b11111110}; > + > + if (plen <=3D 0 || plen > 128) > + pr_err("Unexpected plen: %d", plen); > + > + memset(net_mask, 0x00, sizeof(*net_mask)); > + > + /* We set all bits =3D=3D 1 of s6_addr[i] */ > + plen_bytes =3D plen / 8; > + for (i =3D 0; i < plen_bytes; i++) > + net_mask->s6_addr[i] =3D 0xff; > + > + /* We add bits from the bit_array to > + * netmask starting from plen_bytes position > + */ > + if (plen % 8) > + net_mask->s6_addr[plen_bytes] =3D bit_array[(plen % 8) - = 1]; > + memcpy(net_mask->s6_addr32, net_mask->s6_addr, 16); > +} I don't think we need this function. If needed, we could introduce ipv6_addr_host() (like ipv6_addr_prefix()) in include/net/ipv6.h.