From mboxrd@z Thu Jan 1 00:00:00 1970 From: Serhey Popovych Subject: [PATCH iproute2 3/6] utils: Fast inet address classification after get_addr() Date: Thu, 18 Jan 2018 20:13:44 +0200 Message-ID: <1516299227-26724-4-git-send-email-serhe.popovych@gmail.com> References: <1516299227-26724-1-git-send-email-serhe.popovych@gmail.com> To: netdev@vger.kernel.org Return-path: Received: from mail-lf0-f67.google.com ([209.85.215.67]:40909 "EHLO mail-lf0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753228AbeARSOT (ORCPT ); Thu, 18 Jan 2018 13:14:19 -0500 Received: by mail-lf0-f67.google.com with SMTP id h92so17499562lfi.7 for ; Thu, 18 Jan 2018 10:14:18 -0800 (PST) Received: from tuxracer.localdomain ([2a01:6d80::195:20:96:53]) by smtp.gmail.com with ESMTPSA id l187sm1319975lfg.12.2018.01.18.10.14.16 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 18 Jan 2018 10:14:16 -0800 (PST) In-Reply-To: <1516299227-26724-1-git-send-email-serhe.popovych@gmail.com> Sender: netdev-owner@vger.kernel.org List-ID: It looks very useful to receive additional information from get_addr_1() and get_addr() about address to simplify caller and get rid of code duplications. For now following information can be returned: 1) address is unspecified (zero) 2) address is multicast 3) address is internet: family is either AF_INET or AF_INET6. More information can be added in the future. Introduce inline helpers to make code using this new address classification interface more self explaining: bool is_addrtype_inet(inet_prefix *addr) true if @addr is inet address bool is_addrtype_inet_unspec(inet_prefix *addr) true if @addr is unspecified inet address bool is_addrtype_inet_multi(inet_prefix *addr) true if @addr is multicast inet address bool is_addrtype_inet_not_unspec(inet_prefix *addr) true if @addr is not unspecified inet address false if @addr is not inet or unspecified inet bool is_addrtype_inet_not_multi(inet_prefix *addr) true if @addr is not multicast inet address false if @addr is not inet or multicast inet Last two are useful for case when we need inet address that is not unspecified or multicast. Signed-off-by: Serhey Popovych --- include/utils.h | 35 ++++++++++++++++++++++++++++++++++- lib/utils.c | 32 +++++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/include/utils.h b/include/utils.h index d3895d5..6f072f6 100644 --- a/include/utils.h +++ b/include/utils.h @@ -54,7 +54,40 @@ typedef struct __u32 data[64]; } inet_prefix; -#define PREFIXLEN_SPECIFIED 1 +enum { + PREFIXLEN_SPECIFIED = (1 << 0), + ADDRTYPE_INET = (1 << 1), + ADDRTYPE_UNSPEC = (1 << 2), + ADDRTYPE_MULTI = (1 << 3), + + ADDRTYPE_INET_UNSPEC = ADDRTYPE_INET | ADDRTYPE_UNSPEC, + ADDRTYPE_INET_MULTI = ADDRTYPE_INET | ADDRTYPE_MULTI +}; + +static inline bool is_addrtype_inet(const inet_prefix *p) +{ + return p->flags & ADDRTYPE_INET; +} + +static inline bool is_addrtype_inet_unspec(const inet_prefix *p) +{ + return (p->flags & ADDRTYPE_INET_UNSPEC) == ADDRTYPE_INET_UNSPEC; +} + +static inline bool is_addrtype_inet_multi(const inet_prefix *p) +{ + return (p->flags & ADDRTYPE_INET_MULTI) == ADDRTYPE_INET_MULTI; +} + +static inline bool is_addrtype_inet_not_unspec(const inet_prefix *p) +{ + return (p->flags & ADDRTYPE_INET_UNSPEC) == ADDRTYPE_INET; +} + +static inline bool is_addrtype_inet_not_multi(const inet_prefix *p) +{ + return (p->flags & ADDRTYPE_INET_MULTI) == ADDRTYPE_INET; +} #define DN_MAXADDL 20 #ifndef AF_DECnet diff --git a/lib/utils.c b/lib/utils.c index 48c4bcb..e66c1ff 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -534,7 +534,7 @@ int get_addr64(__u64 *ap, const char *cp) return 1; } -int get_addr_1(inet_prefix *addr, const char *name, int family) +static int __get_addr_1(inet_prefix *addr, const char *name, int family) { memset(addr, 0, sizeof(*addr)); @@ -619,6 +619,36 @@ int get_addr_1(inet_prefix *addr, const char *name, int family) return 0; } +int get_addr_1(inet_prefix *addr, const char *name, int family) +{ + int ret; + + ret = __get_addr_1(addr, name, family); + if (ret) + return ret; + + switch (addr->family) { + case AF_INET: + if (!addr->data[0]) + addr->flags |= ADDRTYPE_INET_UNSPEC; + else if (IN_MULTICAST(ntohl(addr->data[0]))) + addr->flags |= ADDRTYPE_INET_MULTI; + else + addr->flags |= ADDRTYPE_INET; + break; + case AF_INET6: + if (IN6_IS_ADDR_UNSPECIFIED(addr->data)) + addr->flags |= ADDRTYPE_INET_UNSPEC; + else if (IN6_IS_ADDR_MULTICAST(addr->data)) + addr->flags |= ADDRTYPE_INET_MULTI; + else + addr->flags |= ADDRTYPE_INET; + break; + } + + return 0; +} + int af_bit_len(int af) { switch (af) { -- 1.7.10.4