From owner-svn-src-all@freebsd.org Mon Apr 3 07:40:39 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C7CA8D2BA8C; Mon, 3 Apr 2017 07:40:39 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A4DA41FF; Mon, 3 Apr 2017 07:40:39 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v337ecmS050475; Mon, 3 Apr 2017 07:40:38 GMT (envelope-from ae@FreeBSD.org) Received: (from ae@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v337ecKs050473; Mon, 3 Apr 2017 07:40:38 GMT (envelope-from ae@FreeBSD.org) Message-Id: <201704030740.v337ecKs050473@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ae set sender to ae@FreeBSD.org using -f From: "Andrey V. Elsukov" Date: Mon, 3 Apr 2017 07:40:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r316445 - stable/11/sbin/ipfw X-SVN-Group: stable-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 03 Apr 2017 07:40:39 -0000 Author: ae Date: Mon Apr 3 07:40:38 2017 New Revision: 316445 URL: https://svnweb.freebsd.org/changeset/base/316445 Log: MFC r307570: Add support for non-contiguous IPv6 masks in ipfw(8) rules. For example fe::640:0:0/ffff::ffff:ffff:0:0 will match addresses fe:*:*:*:0:640:*:* Submitted by: Eugene Mamchits Obtained from: Yandex LLC Sponsored by: Yandex LLC Modified: stable/11/sbin/ipfw/ipfw.8 stable/11/sbin/ipfw/ipv6.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sbin/ipfw/ipfw.8 ============================================================================== --- stable/11/sbin/ipfw/ipfw.8 Mon Apr 3 07:30:47 2017 (r316444) +++ stable/11/sbin/ipfw/ipfw.8 Mon Apr 3 07:40:38 2017 (r316445) @@ -1316,6 +1316,24 @@ or a hostname) and mask width of .Cm masklen bits. +.It Ar addr Ns / Ns Ar mask +Matches all IPv6 addresses with base +.Ar addr +(specified as allowed by +.Xr inet_pton +or a hostname) +and the mask of +.Ar mask , +specified as allowed by +.Xr inet_pton. +As an example, fe::640:0:0/ffff::ffff:ffff:0:0 will match +fe:*:*:*:0:640:*:*. +This form is advised only for non-contiguous +masks. +It is better to resort to the +.Ar addr Ns / Ns Ar masklen +format for contiguous masks, which is more compact and less +error-prone. .El .Pp No support for sets of IPv6 addresses is provided because IPv6 addresses Modified: stable/11/sbin/ipfw/ipv6.c ============================================================================== --- stable/11/sbin/ipfw/ipv6.c Mon Apr 3 07:30:47 2017 (r316444) +++ stable/11/sbin/ipfw/ipv6.c Mon Apr 3 07:40:38 2017 (r316445) @@ -124,8 +124,8 @@ print_ip6(struct buf_pr *bp, ipfw_insn_i if (inet_ntop(AF_INET6, a, trad, sizeof( trad ) ) == NULL) bprintf(bp, "Error ntop in print_ip6\n"); bprintf(bp, "%s", trad ); - if (mb < 0) /* XXX not really legal... */ - bprintf(bp, ":%s", + if (mb < 0) /* mask not contiguous */ + bprintf(bp, "/%s", inet_ntop(AF_INET6, &a[1], trad, sizeof(trad))); else if (mb < 128) bprintf(bp, "/%d", mb); @@ -325,9 +325,10 @@ lookup_host6 (char *host, struct in6_add * any matches any IP6. Actually returns an empty instruction. * me returns O_IP6_*_ME * - * 03f1::234:123:0342 single IP6 address - * 03f1::234:123:0342/24 address/mask - * 03f1::234:123:0342/24,03f1::234:123:0343/ List of address + * 03f1::234:123:0342 single IP6 address + * 03f1::234:123:0342/24 address/masklen + * 03f1::234:123:0342/ffff::ffff:ffff address/mask + * 03f1::234:123:0342/24,03f1::234:123:0343/ List of address * * Set of address (as in ipv6) not supported because ipv6 address * are typically random past the initial prefix. @@ -371,13 +372,18 @@ fill_ip6(ipfw_insn_ip6 *cmd, char *av, i * or ',' indicating another address follows. */ - char *p; + char *p, *q; int masklen; char md = '\0'; CHECK_LENGTH(cblen, 1 + len + 2 * F_INSN_SIZE(struct in6_addr)); - if ((p = strpbrk(av, "/,")) ) { + if ((q = strchr(av, ',')) ) { + *q = '\0'; + q++; + } + + if ((p = strchr(av, '/')) ) { md = *p; /* save the separator */ *p = '\0'; /* terminate address string */ p++; /* and skip past it */ @@ -390,22 +396,22 @@ fill_ip6(ipfw_insn_ip6 *cmd, char *av, i errx(EX_DATAERR, "bad address \"%s\"", av); } /* next, look at the mask, if any */ - masklen = (md == '/') ? atoi(p) : 128; - if (masklen > 128 || masklen < 0) - errx(EX_DATAERR, "bad width \"%s\''", p); - else - n2mask(&d[1], masklen); + if (md == '/' && strchr(p, ':')) { + if (!inet_pton(AF_INET6, p, &d[1])) + errx(EX_DATAERR, "bad mask \"%s\"", p); + + masklen = contigmask((uint8_t *)&(d[1]), 128); + } else { + masklen = (md == '/') ? atoi(p) : 128; + if (masklen > 128 || masklen < 0) + errx(EX_DATAERR, "bad width \"%s\''", p); + else + n2mask(&d[1], masklen); + } APPLY_MASK(d, &d[1]) /* mask base address with mask */ - /* find next separator */ - - if (md == '/') { /* find separator past the mask */ - p = strpbrk(p, ","); - if (p != NULL) - p++; - } - av = p; + av = q; /* Check this entry */ if (masklen == 0) {