From patchwork Fri Apr 13 17:26:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Pfaff X-Patchwork-Id: 898031 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40N4TT1SdYz9s0t for ; Sat, 14 Apr 2018 03:27:09 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id BD534D88; Fri, 13 Apr 2018 17:27:07 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id E4FDDD88 for ; Fri, 13 Apr 2018 17:27:05 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 46662673 for ; Fri, 13 Apr 2018 17:27:02 +0000 (UTC) X-Originating-IP: 208.91.3.26 Received: from sigabrt.benpfaff.org (unknown [208.91.3.26]) (Authenticated sender: blp@ovn.org) by relay1-d.mail.gandi.net (Postfix) with ESMTPSA id 47A10240009; Fri, 13 Apr 2018 19:26:59 +0200 (CEST) From: Ben Pfaff To: dev@openvswitch.org Date: Fri, 13 Apr 2018 10:26:45 -0700 Message-Id: <20180413172655.31638-1-blp@ovn.org> X-Mailer: git-send-email 2.16.1 X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Ben Pfaff Subject: [ovs-dev] [PATCH 01/11] socket-util: Fix error in comment on ss_format_address(). X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org The output for this function is a dynamic string and doesn't have a fixed buffer size, so the comment was wrong. Signed-off-by: Ben Pfaff Acked-by: Mark Michelson --- lib/socket-util.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/socket-util.c b/lib/socket-util.c index 7fbcdf19feac..5485e3b515dd 100644 --- a/lib/socket-util.c +++ b/lib/socket-util.c @@ -995,8 +995,7 @@ is_safe_name(const char *name) } /* Formats the IPv4 or IPv6 address in 'ss' into 's'. If 'ss' is an IPv6 - * address, puts square brackets around the address. 'bufsize' should be at - * least SS_NTOP_BUFSIZE. */ + * address, puts square brackets around the address. */ void ss_format_address(const struct sockaddr_storage *ss, struct ds *s) { From patchwork Fri Apr 13 17:26:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Pfaff X-Patchwork-Id: 898033 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40N4Vh2X22z9s0t for ; Sat, 14 Apr 2018 03:28:12 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 7D7DFDC1; Fri, 13 Apr 2018 17:27:10 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 9DA85D88 for ; Fri, 13 Apr 2018 17:27:07 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 906D0680 for ; Fri, 13 Apr 2018 17:27:03 +0000 (UTC) X-Originating-IP: 208.91.3.26 Received: from sigabrt.benpfaff.org (unknown [208.91.3.26]) (Authenticated sender: blp@ovn.org) by relay1-d.mail.gandi.net (Postfix) with ESMTPSA id 2BEB4240008; Fri, 13 Apr 2018 19:27:01 +0200 (CEST) From: Ben Pfaff To: dev@openvswitch.org Date: Fri, 13 Apr 2018 10:26:46 -0700 Message-Id: <20180413172655.31638-2-blp@ovn.org> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180413172655.31638-1-blp@ovn.org> References: <20180413172655.31638-1-blp@ovn.org> X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Ben Pfaff Subject: [ovs-dev] [PATCH 02/11] socket-util: Make address parser check for trailing garbage. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org Signed-off-by: Ben Pfaff --- lib/socket-util.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/socket-util.c b/lib/socket-util.c index 5485e3b515dd..86ac4d433a2d 100644 --- a/lib/socket-util.c +++ b/lib/socket-util.c @@ -455,6 +455,9 @@ inet_parse_active(const char *target_, uint16_t default_port, } else if (!port && !default_port) { VLOG_ERR("%s: port must be specified", target_); ok = false; + } else if (p && p[strspn(p, " \t\r\n")] != '\0') { + VLOG_ERR("%s: unexpected characters follow host and port", target_); + ok = false; } else { ok = parse_sockaddr_components(ss, host, port, default_port, target_); } @@ -579,6 +582,9 @@ inet_parse_passive(const char *target_, int default_port, if (!port && default_port < 0) { VLOG_ERR("%s: port must be specified", target_); ok = false; + } else if (p && p[strspn(p, " \t\r\n")] != '\0') { + VLOG_ERR("%s: unexpected characters follow port and host", target_); + ok = false; } else { ok = parse_sockaddr_components(ss, host, port, default_port, target_); } From patchwork Fri Apr 13 17:26:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Pfaff X-Patchwork-Id: 898032 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40N4V5319mz9s0t for ; Sat, 14 Apr 2018 03:27:41 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 4AFF7DC8; Fri, 13 Apr 2018 17:27:09 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 5E798D88 for ; Fri, 13 Apr 2018 17:27:07 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id EA7DB672 for ; Fri, 13 Apr 2018 17:27:04 +0000 (UTC) X-Originating-IP: 208.91.3.26 Received: from sigabrt.benpfaff.org (unknown [208.91.3.26]) (Authenticated sender: blp@ovn.org) by relay1-d.mail.gandi.net (Postfix) with ESMTPSA id 95D29240007; Fri, 13 Apr 2018 19:27:03 +0200 (CEST) From: Ben Pfaff To: dev@openvswitch.org Date: Fri, 13 Apr 2018 10:26:47 -0700 Message-Id: <20180413172655.31638-3-blp@ovn.org> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180413172655.31638-1-blp@ovn.org> References: <20180413172655.31638-1-blp@ovn.org> X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Ben Pfaff Subject: [ovs-dev] [PATCH 03/11] ovn-northd: Use common code for sockaddr_storage. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org This better reuses existing code. It does require adding a slight variant on ss_format_address(), but it still seems like a net win. Signed-off-by: Ben Pfaff --- lib/socket-util.c | 28 ++++++++++++++++++++++------ lib/socket-util.h | 1 + ovn/northd/ovn-northd.c | 22 ++++++---------------- 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/lib/socket-util.c b/lib/socket-util.c index 86ac4d433a2d..b36de371baa1 100644 --- a/lib/socket-util.c +++ b/lib/socket-util.c @@ -1000,10 +1000,10 @@ is_safe_name(const char *name) return true; } -/* Formats the IPv4 or IPv6 address in 'ss' into 's'. If 'ss' is an IPv6 - * address, puts square brackets around the address. */ -void -ss_format_address(const struct sockaddr_storage *ss, struct ds *s) +static void +ss_format_address__(const struct sockaddr_storage *ss, + const char *lbrack, const char *rbrack, + struct ds *s) { if (ss->ss_family == AF_INET) { const struct sockaddr_in *sin @@ -1014,7 +1014,7 @@ ss_format_address(const struct sockaddr_storage *ss, struct ds *s) const struct sockaddr_in6 *sin6 = ALIGNED_CAST(const struct sockaddr_in6 *, ss); - ds_put_char(s, '['); + ds_put_cstr(s, lbrack); ds_reserve(s, s->length + INET6_ADDRSTRLEN); char *tail = &s->string[s->length]; inet_ntop(AF_INET6, sin6->sin6_addr.s6_addr, tail, INET6_ADDRSTRLEN); @@ -1034,12 +1034,28 @@ ss_format_address(const struct sockaddr_storage *ss, struct ds *s) } #endif - ds_put_char(s, ']'); + ds_put_cstr(s, rbrack); } else { OVS_NOT_REACHED(); } } +/* Formats the IPv4 or IPv6 address in 'ss' into 's'. If 'ss' is an IPv6 + * address, puts square brackets around the address. */ +void +ss_format_address(const struct sockaddr_storage *ss, struct ds *s) +{ + ss_format_address__(ss, "[", "]", s); +} + +/* Formats the IPv4 or IPv6 address in 'ss' into 's'. Does not add square + * brackets around IPv6 addresses. */ +void +ss_format_address_nobracks(const struct sockaddr_storage *ss, struct ds *s) +{ + ss_format_address__(ss, "", "", s); +} + size_t ss_length(const struct sockaddr_storage *ss) { diff --git a/lib/socket-util.h b/lib/socket-util.h index 439f0c285107..d8c6f082c8cf 100644 --- a/lib/socket-util.h +++ b/lib/socket-util.h @@ -75,6 +75,7 @@ char *describe_fd(int fd); * IPv6 address. */ uint16_t ss_get_port(const struct sockaddr_storage *); void ss_format_address(const struct sockaddr_storage *, struct ds *); +void ss_format_address_nobracks(const struct sockaddr_storage *, struct ds *); size_t ss_length(const struct sockaddr_storage *); const char *sock_strerror(int error); diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c index 845faba86fe0..b518953f2e63 100644 --- a/ovn/northd/ovn-northd.c +++ b/ovn/northd/ovn-northd.c @@ -2942,29 +2942,19 @@ ip_address_and_port_from_lb_key(const char *key, char **ip_address, uint16_t *port, int *addr_family) { struct sockaddr_storage ss; - char ip_addr_buf[INET6_ADDRSTRLEN]; - char *error; - - error = ipv46_parse(key, PORT_OPTIONAL, &ss); - if (error) { + if (!inet_parse_active(key, 0, &ss)) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); VLOG_WARN_RL(&rl, "bad ip address or port for load balancer key %s", key); - free(error); return; } - if (ss.ss_family == AF_INET) { - struct sockaddr_in *sin = ALIGNED_CAST(struct sockaddr_in *, &ss); - *port = sin->sin_port == 0 ? 0 : ntohs(sin->sin_port); - inet_ntop(AF_INET, &sin->sin_addr, ip_addr_buf, sizeof ip_addr_buf); - } else { - struct sockaddr_in6 *sin6 = ALIGNED_CAST(struct sockaddr_in6 *, &ss); - *port = sin6->sin6_port == 0 ? 0 : ntohs(sin6->sin6_port); - inet_ntop(AF_INET6, &sin6->sin6_addr, ip_addr_buf, sizeof ip_addr_buf); - } + struct ds s = DS_EMPTY_INITIALIZER; + ss_format_address_nobracks(&ss, &s); + *ip_address = ds_steal_cstr(&s); + + *port = ss_get_port(&ss); - *ip_address = xstrdup(ip_addr_buf); *addr_family = ss.ss_family; } From patchwork Fri Apr 13 17:26:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Pfaff X-Patchwork-Id: 898034 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40N4WF5qr9z9s0t for ; Sat, 14 Apr 2018 03:28:41 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 6B590DE6; Fri, 13 Apr 2018 17:27:12 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id EC763D8D for ; Fri, 13 Apr 2018 17:27:07 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 54F28673 for ; Fri, 13 Apr 2018 17:27:06 +0000 (UTC) X-Originating-IP: 208.91.3.26 Received: from sigabrt.benpfaff.org (unknown [208.91.3.26]) (Authenticated sender: blp@ovn.org) by relay1-d.mail.gandi.net (Postfix) with ESMTPSA id E86AD240003; Fri, 13 Apr 2018 19:27:04 +0200 (CEST) From: Ben Pfaff To: dev@openvswitch.org Date: Fri, 13 Apr 2018 10:26:48 -0700 Message-Id: <20180413172655.31638-4-blp@ovn.org> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180413172655.31638-1-blp@ovn.org> References: <20180413172655.31638-1-blp@ovn.org> X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Ben Pfaff Subject: [ovs-dev] [PATCH 04/11] socket-util: New function inet_parse_address(). X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org This will acquire its first user in an upcoming commit. Signed-off-by: Ben Pfaff --- lib/socket-util.c | 26 ++++++++++++++++++++++++++ lib/socket-util.h | 2 ++ 2 files changed, 28 insertions(+) diff --git a/lib/socket-util.c b/lib/socket-util.c index b36de371baa1..2d893bc9feb6 100644 --- a/lib/socket-util.c +++ b/lib/socket-util.c @@ -698,6 +698,32 @@ error: return -error; } +/* Parses 'target', which may be an IPv4 address or an IPv6 address + * enclosed in square brackets. + * + * On success, returns true and stores the parsed remote address into '*ss'. + * On failure, logs an error, stores zeros into '*ss', and returns false. */ +bool +inet_parse_address(const char *target_, struct sockaddr_storage *ss) +{ + char *target = xstrdup(target_); + char *p = target; + char *host = inet_parse_token(&p); + bool ok = false; + if (!host) { + VLOG_ERR("%s: host must be specified", target_); + } else if (p && p[strspn(p, " \t\r\n")] != '\0') { + VLOG_ERR("%s: unexpected characters follow host", target_); + } else { + ok = parse_sockaddr_components(ss, host, NULL, 0, target_); + } + if (!ok) { + memset(ss, 0, sizeof *ss); + } + free(target); + return ok; +} + int read_fully(int fd, void *p_, size_t size, size_t *bytes_read) { diff --git a/lib/socket-util.h b/lib/socket-util.h index d8c6f082c8cf..b1eca88eb131 100644 --- a/lib/socket-util.h +++ b/lib/socket-util.h @@ -58,6 +58,8 @@ int inet_open_passive(int style, const char *target, int default_port, struct sockaddr_storage *ssp, uint8_t dscp, bool kernel_print_port); +bool inet_parse_address(const char *target, struct sockaddr_storage *); + int read_fully(int fd, void *, size_t, size_t *bytes_read); int write_fully(int fd, const void *, size_t, size_t *bytes_written); From patchwork Fri Apr 13 17:26:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Pfaff X-Patchwork-Id: 898037 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40N4Wl1Tpcz9s0t for ; Sat, 14 Apr 2018 03:29:07 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 67BDDDCB; Fri, 13 Apr 2018 17:27:13 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 38D1BDA8 for ; Fri, 13 Apr 2018 17:27:09 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 1689A672 for ; Fri, 13 Apr 2018 17:27:07 +0000 (UTC) X-Originating-IP: 208.91.3.26 Received: from sigabrt.benpfaff.org (unknown [208.91.3.26]) (Authenticated sender: blp@ovn.org) by relay1-d.mail.gandi.net (Postfix) with ESMTPSA id 4CEF524000E; Fri, 13 Apr 2018 19:27:05 +0200 (CEST) From: Ben Pfaff To: dev@openvswitch.org Date: Fri, 13 Apr 2018 10:26:49 -0700 Message-Id: <20180413172655.31638-5-blp@ovn.org> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180413172655.31638-1-blp@ovn.org> References: <20180413172655.31638-1-blp@ovn.org> X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Ben Pfaff Subject: [ovs-dev] [PATCH 05/11] socket-util: Make inet_parse_active() and inet_parse_passive() more alike. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org Until now, the default_port parameters to these functions have had different types and different behavior. There is a reason for this, since it makes sense to listen on a kernel-selected port but it does not make sense to connect to a kernel-selected port, but this overlooks the possibility that a caller might want to parse a string in the format understood by inet_parse_active() without actually using it to connect to a remote host. This commit makes the behavior consistent and updates all the callers to work with the new semantics. Signed-off-by: Ben Pfaff --- lib/socket-util.c | 14 +++++++------- lib/socket-util.h | 4 ++-- lib/stream-tcp.c | 2 +- lib/stream.c | 3 +-- lib/stream.h | 2 +- lib/vlog.c | 2 +- ofproto/collectors.c | 4 ++-- ofproto/collectors.h | 2 +- ofproto/netflow.c | 2 +- ovn/northd/ovn-northd.c | 2 +- ovsdb/raft-private.c | 2 +- 11 files changed, 19 insertions(+), 20 deletions(-) diff --git a/lib/socket-util.c b/lib/socket-util.c index 2d893bc9feb6..223e3780ba5f 100644 --- a/lib/socket-util.c +++ b/lib/socket-util.c @@ -431,13 +431,13 @@ exit: /* Parses 'target', which should be a string in the format "[:]". * , which is required, may be an IPv4 address or an IPv6 address - * enclosed in square brackets. If 'default_port' is nonzero then is - * optional and defaults to 'default_port'. + * enclosed in square brackets. If 'default_port' is nonnegative then + * is optional and defaults to 'default_port'. * * On success, returns true and stores the parsed remote address into '*ss'. * On failure, logs an error, stores zeros into '*ss', and returns false. */ bool -inet_parse_active(const char *target_, uint16_t default_port, +inet_parse_active(const char *target_, int default_port, struct sockaddr_storage *ss) { char *target = xstrdup(target_); @@ -452,7 +452,7 @@ inet_parse_active(const char *target_, uint16_t default_port, if (!host) { VLOG_ERR("%s: host must be specified", target_); ok = false; - } else if (!port && !default_port) { + } else if (!port && default_port < 0) { VLOG_ERR("%s: port must be specified", target_); ok = false; } else if (p && p[strspn(p, " \t\r\n")] != '\0') { @@ -472,8 +472,8 @@ inet_parse_active(const char *target_, uint16_t default_port, /* Opens a non-blocking IPv4 or IPv6 socket of the specified 'style' and * connects to 'target', which should be a string in the format * "[:]". , which is required, may be an IPv4 address or an - * IPv6 address enclosed in square brackets. If 'default_port' is nonzero then - * is optional and defaults to 'default_port'. + * IPv6 address enclosed in square brackets. If 'default_port' is nonnegative + * then is optional and defaults to 'default_port'. * * 'style' should be SOCK_STREAM (for TCP) or SOCK_DGRAM (for UDP). * @@ -488,7 +488,7 @@ inet_parse_active(const char *target_, uint16_t default_port, * should be in the range [0, 63] and will automatically be shifted to the * appropriately place in the IP tos field. */ int -inet_open_active(int style, const char *target, uint16_t default_port, +inet_open_active(int style, const char *target, int default_port, struct sockaddr_storage *ssp, int *fdp, uint8_t dscp) { struct sockaddr_storage ss; diff --git a/lib/socket-util.h b/lib/socket-util.h index b1eca88eb131..d927d67a0e1b 100644 --- a/lib/socket-util.h +++ b/lib/socket-util.h @@ -47,9 +47,9 @@ void drain_fd(int fd, size_t n_packets); ovs_be32 guess_netmask(ovs_be32 ip); char *inet_parse_token(char **); -bool inet_parse_active(const char *target, uint16_t default_port, +bool inet_parse_active(const char *target, int default_port, struct sockaddr_storage *ssp); -int inet_open_active(int style, const char *target, uint16_t default_port, +int inet_open_active(int style, const char *target, int default_port, struct sockaddr_storage *ssp, int *fdp, uint8_t dscp); bool inet_parse_passive(const char *target, int default_port, diff --git a/lib/stream-tcp.c b/lib/stream-tcp.c index 4fae731d9b9e..e8dc2bfaa2df 100644 --- a/lib/stream-tcp.c +++ b/lib/stream-tcp.c @@ -53,7 +53,7 @@ tcp_open(const char *name, char *suffix, struct stream **streamp, uint8_t dscp) { int fd, error; - error = inet_open_active(SOCK_STREAM, suffix, 0, NULL, &fd, dscp); + error = inet_open_active(SOCK_STREAM, suffix, -1, NULL, &fd, dscp); if (fd >= 0) { return new_tcp_stream(xstrdup(name), fd, error, streamp); } else { diff --git a/lib/stream.c b/lib/stream.c index 083e2fb93f77..63c592344080 100644 --- a/lib/stream.c +++ b/lib/stream.c @@ -747,8 +747,7 @@ pstream_open_with_default_port(const char *name_, * - On error, function returns false and *ss contains garbage. */ bool -stream_parse_target_with_default_port(const char *target, - uint16_t default_port, +stream_parse_target_with_default_port(const char *target, int default_port, struct sockaddr_storage *ss) { return ((!strncmp(target, "tcp:", 4) || !strncmp(target, "ssl:", 4)) diff --git a/lib/stream.h b/lib/stream.h index 7d35fa6461ee..88f576155108 100644 --- a/lib/stream.h +++ b/lib/stream.h @@ -78,7 +78,7 @@ int pstream_open_with_default_port(const char *name, struct pstream **, uint8_t dscp); bool stream_parse_target_with_default_port(const char *target, - uint16_t default_port, + int default_port, struct sockaddr_storage *ss); int stream_or_pstream_needs_probes(const char *name); diff --git a/lib/vlog.c b/lib/vlog.c index 0e862a773cf1..bf5fd88ba9e8 100644 --- a/lib/vlog.c +++ b/lib/vlog.c @@ -599,7 +599,7 @@ vlog_set_syslog_target(const char *target) { int new_fd; - inet_open_active(SOCK_DGRAM, target, 0, NULL, &new_fd, 0); + inet_open_active(SOCK_DGRAM, target, -1, NULL, &new_fd, 0); ovs_rwlock_wrlock(&pattern_rwlock); if (syslog_fd >= 0) { diff --git a/ofproto/collectors.c b/ofproto/collectors.c index bc92332b1b4a..bb6ae021fa64 100644 --- a/ofproto/collectors.c +++ b/ofproto/collectors.c @@ -40,7 +40,7 @@ struct collectors { * otherwise a positive errno value if opening at least one collector failed. * * Each target in 'targets' should be a string in the format "[:]". - * may be omitted if 'default_port' is nonzero, in which case it + * may be omitted if 'default_port' is nonnegative, in which case it * defaults to 'default_port'. * * '*collectorsp' is set to a null pointer if no targets were successfully @@ -49,7 +49,7 @@ struct collectors { * is nonnull, and even on a successful return, it is possible that * '*collectorsp' is null, if 'target's is an empty sset. */ int -collectors_create(const struct sset *targets, uint16_t default_port, +collectors_create(const struct sset *targets, int default_port, struct collectors **collectorsp) { struct collectors *c; diff --git a/ofproto/collectors.h b/ofproto/collectors.h index 1e4e96135ff6..83cd26b7ce25 100644 --- a/ofproto/collectors.h +++ b/ofproto/collectors.h @@ -23,7 +23,7 @@ struct collectors; struct sset; -int collectors_create(const struct sset *targets, uint16_t default_port, +int collectors_create(const struct sset *targets, int default_port, struct collectors **); void collectors_destroy(struct collectors *); diff --git a/ofproto/netflow.c b/ofproto/netflow.c index b6baeb8268ab..ed58de17de5e 100644 --- a/ofproto/netflow.c +++ b/ofproto/netflow.c @@ -362,7 +362,7 @@ netflow_set_options(struct netflow *nf, nf->add_id_to_iface = nf_options->add_id_to_iface; collectors_destroy(nf->collectors); - collectors_create(&nf_options->collectors, 0, &nf->collectors); + collectors_create(&nf_options->collectors, -1, &nf->collectors); old_timeout = nf->active_timeout; if (nf_options->active_timeout >= 0) { diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c index b518953f2e63..e06d28d6f8fc 100644 --- a/ovn/northd/ovn-northd.c +++ b/ovn/northd/ovn-northd.c @@ -2942,7 +2942,7 @@ ip_address_and_port_from_lb_key(const char *key, char **ip_address, uint16_t *port, int *addr_family) { struct sockaddr_storage ss; - if (!inet_parse_active(key, 0, &ss)) { + if (!inet_parse_active(key, -1, &ss)) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); VLOG_WARN_RL(&rl, "bad ip address or port for load balancer key %s", key); diff --git a/ovsdb/raft-private.c b/ovsdb/raft-private.c index 36725f7e12b7..07996e35bc6a 100644 --- a/ovsdb/raft-private.c +++ b/ovsdb/raft-private.c @@ -33,7 +33,7 @@ raft_address_validate(const char *address) return NULL; } else if (!strncmp(address, "ssl:", 4) || !strncmp(address, "tcp:", 4)) { struct sockaddr_storage ss; - if (!inet_parse_active(address + 4, 0, &ss)) { + if (!inet_parse_active(address + 4, -1, &ss)) { return ovsdb_error(NULL, "%s: syntax error in address", address); } return NULL; From patchwork Fri Apr 13 17:26:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Pfaff X-Patchwork-Id: 898038 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40N4XG3m3bz9s0t for ; Sat, 14 Apr 2018 03:29:34 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 83BB9DEB; Fri, 13 Apr 2018 17:27:14 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 3AECADA6 for ; Fri, 13 Apr 2018 17:27:11 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 7DDA3672 for ; Fri, 13 Apr 2018 17:27:09 +0000 (UTC) X-Originating-IP: 208.91.3.26 Received: from sigabrt.benpfaff.org (unknown [208.91.3.26]) (Authenticated sender: blp@ovn.org) by relay1-d.mail.gandi.net (Postfix) with ESMTPSA id 03006240012; Fri, 13 Apr 2018 19:27:07 +0200 (CEST) From: Ben Pfaff To: dev@openvswitch.org Date: Fri, 13 Apr 2018 10:26:50 -0700 Message-Id: <20180413172655.31638-6-blp@ovn.org> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180413172655.31638-1-blp@ovn.org> References: <20180413172655.31638-1-blp@ovn.org> X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Ben Pfaff Subject: [ovs-dev] [PATCH 06/11] Make : parsing uniform treewide. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org I didn't realize until now that the tree had two different ways of parsing strings in the form : and :. There are the long-standing inet_parse_active() and inet_parse_passive() functions, and more recently the ipv46_parse() function. This commit eliminates the latter and changes the code to use the former. The two implementations interpreted some input differently. In particular, the older functions required IPv6 addresses to be [bracketed], but the newer ones did not. I'd prefer the brackets to be required, because of ambiguous cases like "::1:2:3:4:80" (is :80 part of the IPv6 address or a port number?) but for compatibility this patch changes the merged code to use the more liberal interpretation. Signed-off-by: Ben Pfaff --- lib/packets.c | 76 ------------------------- lib/packets.h | 10 ---- lib/socket-util.c | 140 +++++++++++++++++++++++++++------------------- lib/socket-util.h | 3 +- ovn/utilities/ovn-nbctl.c | 43 +++----------- ovsdb/raft.c | 5 +- tests/ovn-nbctl.at | 56 +++++++++---------- 7 files changed, 125 insertions(+), 208 deletions(-) diff --git a/lib/packets.c b/lib/packets.c index 8ebae8cc8fe8..38bfb6015b9e 100644 --- a/lib/packets.c +++ b/lib/packets.c @@ -652,82 +652,6 @@ ip_parse_cidr(const char *s, ovs_be32 *ip, unsigned int *plen) return error; } -/* Parses the string into an IPv4 or IPv6 address. - * The port flags act as follows: - * * PORT_OPTIONAL: A port may be present but is not required - * * PORT_REQUIRED: A port must be present - * * PORT_FORBIDDEN: A port must not be present - */ -char * OVS_WARN_UNUSED_RESULT -ipv46_parse(const char *s, enum port_flags flags, struct sockaddr_storage *ss) -{ - char *error = NULL; - - char *copy; - copy = xstrdup(s); - - char *addr; - char *port; - if (*copy == '[') { - char *end; - - addr = copy + 1; - end = strchr(addr, ']'); - if (!end) { - error = xasprintf("No closing bracket on address %s", s); - goto finish; - } - *end++ = '\0'; - if (*end == ':') { - port = end + 1; - } else { - port = NULL; - } - } else { - addr = copy; - port = strchr(copy, ':'); - if (port) { - if (strchr(port + 1, ':')) { - port = NULL; - } else { - *port++ = '\0'; - } - } - } - - if (port && !*port) { - error = xasprintf("Port is an empty string"); - goto finish; - } - - if (port && flags == PORT_FORBIDDEN) { - error = xasprintf("Port forbidden in address %s", s); - goto finish; - } else if (!port && flags == PORT_REQUIRED) { - error = xasprintf("Port required in address %s", s); - goto finish; - } - - struct addrinfo hints = { - .ai_flags = AI_NUMERICHOST | AI_NUMERICSERV, - .ai_family = AF_UNSPEC, - }; - struct addrinfo *res; - int status; - status = getaddrinfo(addr, port, &hints, &res); - if (status) { - error = xasprintf("Error parsing address %s: %s", - s, gai_strerror(status)); - goto finish; - } - memcpy(ss, res->ai_addr, res->ai_addrlen); - freeaddrinfo(res); - -finish: - free(copy); - return error; -} - /* Parses string 's', which must be an IPv6 address. Stores the IPv6 address * into '*ip'. Returns true if successful, otherwise false. */ bool diff --git a/lib/packets.h b/lib/packets.h index 9a71aa3abbdb..b2bf70697e90 100644 --- a/lib/packets.h +++ b/lib/packets.h @@ -1362,16 +1362,6 @@ struct in6_addr ipv6_create_mask(int mask); int ipv6_count_cidr_bits(const struct in6_addr *netmask); bool ipv6_is_cidr(const struct in6_addr *netmask); -enum port_flags { - PORT_OPTIONAL, - PORT_REQUIRED, - PORT_FORBIDDEN, -}; - -char *ipv46_parse(const char *s, enum port_flags flags, - struct sockaddr_storage *ss) - OVS_WARN_UNUSED_RESULT; - bool ipv6_parse(const char *s, struct in6_addr *ip); char *ipv6_parse_masked(const char *s, struct in6_addr *ipv6, struct in6_addr *mask); diff --git a/lib/socket-util.c b/lib/socket-util.c index 223e3780ba5f..0964a015e3f9 100644 --- a/lib/socket-util.c +++ b/lib/socket-util.c @@ -333,39 +333,89 @@ guess_netmask(ovs_be32 ip_) : htonl(0)); /* ??? */ } -/* This is like strsep() except: - * - * - The separator string is ":". - * - * - Square brackets [] quote ":" separators and are removed from the - * tokens. */ -char * -inet_parse_token(char **pp) +static char * +unbracket(char *s) +{ + if (*s == '[') { + s++; + + char *end = strchr(s, '\0'); + if (end[-1] == ']') { + end[-1] = '\0'; + } + } + return s; +} + +/* 'host_index' is 0 if the host precedes the port within 's', 1 otherwise. */ +static void +inet_parse_tokens__(char *s, int host_index, char **hostp, char **portp) { - char *p = *pp; - - if (p == NULL) { - return NULL; - } else if (*p == '\0') { - *pp = NULL; - return p; - } else if (*p == '[') { - char *start = p + 1; - char *end = start + strcspn(start, "]"); - *pp = (*end == '\0' ? NULL - : end[1] == ':' ? end + 2 - : end + 1); - *end = '\0'; - return start; + char *colon = NULL; + bool in_brackets = false; + int n_colons = 0; + for (char *p = s; *p; p++) { + if (*p == '[') { + in_brackets = true; + } else if (*p == ']') { + in_brackets = false; + } else if (*p == ':' && !in_brackets) { + n_colons++; + colon = p; + } + } + + *hostp = *portp = NULL; + if (n_colons > 1) { + *hostp = s; } else { - char *start = p; - char *end = start + strcspn(start, ":"); - *pp = *end == '\0' ? NULL : end + 1; - *end = '\0'; - return start; + char **tokens[2]; + tokens[host_index] = hostp; + tokens[!host_index] = portp; + + if (colon) { + *colon = '\0'; + *tokens[1] = unbracket(colon + 1); + } + *tokens[0] = unbracket(s); } } +/* Parses 's', a string in the form "[:]", into its (required) host + * and (optional) port components, and stores pointers to them in '*hostp' and + * '*portp' respectively. Always sets '*hostp' nonnull, although possibly to + * an empty string empty string. Can set '*portp' to the null string. + * + * Supports both IPv4 and IPv6. IPv6 addresses may be quoted with square + * brackets. Resolves ambiguous cases that might represent an IPv6 address or + * an IPv6 address and a port as representing just a host, e.g. "::1:2:3:4:80" + * is a host but "[::1:2:3:4]:80" is a host and a port. + * + * Modifies 's' and points '*hostp' and '*portp' (if nonnull) into it. + */ +void +inet_parse_host_port_tokens(char *s, char **hostp, char **portp) +{ + inet_parse_tokens__(s, 0, hostp, portp); +} + +/* Parses 's', a string in the form "[:]", into its port and host + * components, and stores pointers to them in '*portp' and '*hostp' + * respectively. Both '*portp' and '*hostp' can end up null. + * + * Supports both IPv4 and IPv6. IPv6 addresses may be quoted with square + * brackets. Resolves ambiguous cases that might represent an IPv6 address or + * an IPv6 address and a port as representing just a host, e.g. "::1:2:3:4:80" + * is a host but "[::1:2:3:4]:80" is a host and a port. + * + * Modifies 's' and points '*hostp' and '*portp' (if nonnull) into it. + */ +void +inet_parse_port_host_tokens(char *s, char **portp, char **hostp) +{ + inet_parse_tokens__(s, 1, hostp, portp); +} + static bool parse_sockaddr_components(struct sockaddr_storage *ss, char *host_s, @@ -441,23 +491,16 @@ inet_parse_active(const char *target_, int default_port, struct sockaddr_storage *ss) { char *target = xstrdup(target_); - const char *port; - char *host; - char *p; + char *port, *host; bool ok; - p = target; - host = inet_parse_token(&p); - port = inet_parse_token(&p); + inet_parse_host_port_tokens(target, &host, &port); if (!host) { VLOG_ERR("%s: host must be specified", target_); ok = false; } else if (!port && default_port < 0) { VLOG_ERR("%s: port must be specified", target_); ok = false; - } else if (p && p[strspn(p, " \t\r\n")] != '\0') { - VLOG_ERR("%s: unexpected characters follow host and port", target_); - ok = false; } else { ok = parse_sockaddr_components(ss, host, port, default_port, target_); } @@ -571,20 +614,13 @@ inet_parse_passive(const char *target_, int default_port, struct sockaddr_storage *ss) { char *target = xstrdup(target_); - const char *port; - char *host; - char *p; + char *port, *host; bool ok; - p = target; - port = inet_parse_token(&p); - host = inet_parse_token(&p); + inet_parse_port_host_tokens(target, &port, &host); if (!port && default_port < 0) { VLOG_ERR("%s: port must be specified", target_); ok = false; - } else if (p && p[strspn(p, " \t\r\n")] != '\0') { - VLOG_ERR("%s: unexpected characters follow port and host", target_); - ok = false; } else { ok = parse_sockaddr_components(ss, host, port, default_port, target_); } @@ -707,16 +743,8 @@ bool inet_parse_address(const char *target_, struct sockaddr_storage *ss) { char *target = xstrdup(target_); - char *p = target; - char *host = inet_parse_token(&p); - bool ok = false; - if (!host) { - VLOG_ERR("%s: host must be specified", target_); - } else if (p && p[strspn(p, " \t\r\n")] != '\0') { - VLOG_ERR("%s: unexpected characters follow host", target_); - } else { - ok = parse_sockaddr_components(ss, host, NULL, 0, target_); - } + char *host = unbracket(target); + bool ok = parse_sockaddr_components(ss, host, NULL, 0, target_); if (!ok) { memset(ss, 0, sizeof *ss); } diff --git a/lib/socket-util.h b/lib/socket-util.h index d927d67a0e1b..239d3f22041c 100644 --- a/lib/socket-util.h +++ b/lib/socket-util.h @@ -46,7 +46,8 @@ int check_connection_completion(int fd); void drain_fd(int fd, size_t n_packets); ovs_be32 guess_netmask(ovs_be32 ip); -char *inet_parse_token(char **); +void inet_parse_host_port_tokens(char *s, char **hostp, char **portp); +void inet_parse_port_host_tokens(char *s, char **portp, char **hostp); bool inet_parse_active(const char *target, int default_port, struct sockaddr_storage *ssp); int inet_open_active(int style, const char *target, int default_port, diff --git a/ovn/utilities/ovn-nbctl.c b/ovn/utilities/ovn-nbctl.c index 7efc5065c962..16698de1f049 100644 --- a/ovn/utilities/ovn-nbctl.c +++ b/ovn/utilities/ovn-nbctl.c @@ -1798,10 +1798,7 @@ nbctl_lb_add(struct ctl_context *ctx) } struct sockaddr_storage ss_vip; - char *error; - error = ipv46_parse(lb_vip, PORT_OPTIONAL, &ss_vip); - if (error) { - free(error); + if (!inet_parse_active(lb_vip, 0, &ss_vip)) { ctl_fatal("%s: should be an IP address (or an IP address " "and a port number with : as a separator).", lb_vip); } @@ -1848,17 +1845,13 @@ nbctl_lb_add(struct ctl_context *ctx) token != NULL; token = strtok_r(NULL, ",", &save_ptr)) { struct sockaddr_storage ss_dst; - error = ipv46_parse(token, is_vip_with_port - ? PORT_REQUIRED - : PORT_FORBIDDEN, - &ss_dst); - - if (error) { - free(error); - if (is_vip_with_port) { + if (is_vip_with_port) { + if (!inet_parse_active(token, -1, &ss_dst)) { ctl_fatal("%s: should be an IP address and a port " - "number with : as a separator.", token); - } else { + "number with : as a separator.", token); + } + } else { + if (!inet_parse_address(token, &ss_dst)) { ctl_fatal("%s: should be an IP address.", token); } } @@ -1954,36 +1947,18 @@ lb_info_add_smap(const struct nbrec_load_balancer *lb, { struct ds key = DS_EMPTY_INITIALIZER; struct ds val = DS_EMPTY_INITIALIZER; - char *error, *protocol; const struct smap_node **nodes = smap_sort(&lb->vips); if (nodes) { for (int i = 0; i < smap_count(&lb->vips); i++) { const struct smap_node *node = nodes[i]; - protocol = lb->protocol; struct sockaddr_storage ss; - error = ipv46_parse(node->key, PORT_OPTIONAL, &ss); - if (error) { - VLOG_WARN("%s", error); - free(error); + if (!inet_parse_active(node->key, 0, &ss)) { continue; } - if (ss.ss_family == AF_INET) { - struct sockaddr_in *sin = ALIGNED_CAST(struct sockaddr_in *, - &ss); - if (!sin->sin_port) { - protocol = "tcp/udp"; - } - } else { - struct sockaddr_in6 *sin6 = ALIGNED_CAST(struct sockaddr_in6 *, - &ss); - if (!sin6->sin6_port) { - protocol = "tcp/udp"; - } - } - + char *protocol = ss_get_port(&ss) ? lb->protocol : "tcp/udp"; i == 0 ? ds_put_format(&val, UUID_FMT " %-20.16s%-11.7s%-*.*s%s", UUID_ARGS(&lb->header_.uuid), diff --git a/ovsdb/raft.c b/ovsdb/raft.c index edb22f2e7b60..c0c1e98977b9 100644 --- a/ovsdb/raft.c +++ b/ovsdb/raft.c @@ -335,9 +335,8 @@ raft_make_address_passive(const char *address_) return xasprintf("p%s", address_); } else { char *address = xstrdup(address_); - char *p = strchr(address, ':') + 1; - char *host = inet_parse_token(&p); - char *port = inet_parse_token(&p); + char *host, *port; + inet_parse_host_port_tokens(strchr(address, ':') + 1, &host, &port); struct ds paddr = DS_EMPTY_INITIALIZER; ds_put_format(&paddr, "p%.3s:%s:", address, port); diff --git a/tests/ovn-nbctl.at b/tests/ovn-nbctl.at index f07b47fd20ea..514e7e7d2d49 100644 --- a/tests/ovn-nbctl.at +++ b/tests/ovn-nbctl.at @@ -460,46 +460,46 @@ AT_SETUP([ovn-nbctl - LBs]) OVN_NBCTL_TEST_START dnl Add two LBs. -AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10:80a 192.168.10.10:80,192.168.10.20:80 tcp], [1], [], +AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 30.0.0.10:80a 192.168.10.10:80,192.168.10.20:80 tcp], [1], [], [ovn-nbctl: 30.0.0.10:80a: should be an IP address (or an IP address and a port number with : as a separator). ]) -AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10:a80 192.168.10.10:80,192.168.10.20:80 tcp], [1], [], +AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 30.0.0.10:a80 192.168.10.10:80,192.168.10.20:80 tcp], [1], [], [ovn-nbctl: 30.0.0.10:a80: should be an IP address (or an IP address and a port number with : as a separator). ]) -AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10: 192.168.10.10:80,192.168.10.20:80 tcp], [1], [], -[ovn-nbctl: 30.0.0.10:: should be an IP address (or an IP address and a port number with : as a separator). -]) - -AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10:80 192.168.10.10:80,192.168.10.20 tcp], [1], [], +AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 30.0.0.10:80 192.168.10.10:80,192.168.10.20 tcp], [1], [], [ovn-nbctl: 192.168.10.20: should be an IP address and a port number with : as a separator. ]) -AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.1a 192.168.10.10:80,192.168.10.20:80], [1], [], +AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 30.0.0.1a 192.168.10.10:80,192.168.10.20:80], [1], [], [ovn-nbctl: 30.0.0.1a: should be an IP address (or an IP address and a port number with : as a separator). ]) -AT_CHECK([ovn-nbctl lb-add lb0 30.0.0 192.168.10.10:80,192.168.10.20:80], [1], [], -[ovn-nbctl: 192.168.10.10:80: should be an IP address. +AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 30.0.0 192.168.10.10:80,192.168.10.20:80], [1], [], +[ovn-nbctl: 30.0.0: should be an IP address (or an IP address and a port number with : as a separator). ]) -AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10 192.168.10.10,192.168.10.20:80], [1], [], +AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 30.0.0.10 192.168.10.10,192.168.10.20:80], [1], [], [ovn-nbctl: 192.168.10.20:80: should be an IP address. ]) -AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10 192.168.10.10:a80], [1], [], +AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 30.0.0.10 192.168.10.10:a80], [1], [], [ovn-nbctl: 192.168.10.10:a80: should be an IP address. ]) -AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10 192.168.10.10:], [1], [], +AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 30.0.0.10 192.168.10.10:], [1], [], [ovn-nbctl: 192.168.10.10:: should be an IP address. ]) -AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10 192.168.10.1a], [1], [], +AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 30.0.0.10 192.168.10.1a], [1], [], [ovn-nbctl: 192.168.10.1a: should be an IP address. ]) +AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10: 192.168.10.10:80,192.168.10.20:80 tcp], [1], [], +[ovn-nbctl: Protocol is unnecessary when no port of vip is given. +]) + AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10 192.168.10.10 tcp], [1], [], [ovn-nbctl: Protocol is unnecessary when no port of vip is given. ]) @@ -685,56 +685,56 @@ AT_SETUP([ovn-nbctl - LBs IPv6]) OVN_NBCTL_TEST_START dnl A bunch of commands that should fail -AT_CHECK([ovn-nbctl lb-add lb0 [[ae0f::10]]:80a [[fd0f::10]]:80,[[fd0f::20]]:80 tcp], [1], [], +AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 [[ae0f::10]]:80a [[fd0f::10]]:80,[[fd0f::20]]:80 tcp], [1], [], [ovn-nbctl: [[ae0f::10]]:80a: should be an IP address (or an IP address and a port number with : as a separator). ]) -AT_CHECK([ovn-nbctl lb-add lb0 [[ae0f::10]]:a80 [[fd0f::10]]:80,[[fd0f::20]]:80 tcp], [1], [], +AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 [[ae0f::10]]:a80 [[fd0f::10]]:80,[[fd0f::20]]:80 tcp], [1], [], [ovn-nbctl: [[ae0f::10]]:a80: should be an IP address (or an IP address and a port number with : as a separator). ]) -AT_CHECK([ovn-nbctl lb-add lb0 [[ae0f::10]]: [[fd0f::10]]:80,[[fd0f::20]]:80 tcp], [1], [], -[ovn-nbctl: [[ae0f::10]]:: should be an IP address (or an IP address and a port number with : as a separator). -]) - - -AT_CHECK([ovn-nbctl lb-add lb0 [[ae0f::10]]:80 [[fd0f::10]]:80,fd0f::20 tcp], [1], [], +AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 [[ae0f::10]]:80 [[fd0f::10]]:80,fd0f::20 tcp], [1], [], [ovn-nbctl: fd0f::20: should be an IP address and a port number with : as a separator. ]) -AT_CHECK([ovn-nbctl lb-add lb0 ae0f::10fff [[fd0f::10]]:80,fd0f::20 tcp], [1], [], +AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 ae0f::10fff [[fd0f::10]]:80,fd0f::20 tcp], [1], [], [ovn-nbctl: ae0f::10fff: should be an IP address (or an IP address and a port number with : as a separator). ]) -AT_CHECK([ovn-nbctl lb-add lb0 ae0f::10 [[fd0f::10]]:80,[[fd0f::20]]:80], [1], [], +AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 ae0f::10 [[fd0f::10]]:80,[[fd0f::20]]:80], [1], [], [ovn-nbctl: [[fd0f::10]]:80: should be an IP address. ]) -AT_CHECK([ovn-nbctl lb-add lb0 ae0f::10 fd0f::10,[[fd0f::20]]:80], [1], [], +AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 ae0f::10 fd0f::10,[[fd0f::20]]:80], [1], [], [ovn-nbctl: [[fd0f::20]]:80: should be an IP address. ]) -AT_CHECK([ovn-nbctl lb-add lb0 ae0f::10 [[fd0f::10]]:a80], [1], [], +AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 ae0f::10 [[fd0f::10]]:a80], [1], [], [ovn-nbctl: [[fd0f::10]]:a80: should be an IP address. ]) -AT_CHECK([ovn-nbctl lb-add lb0 ae0f::10 [[fd0f::10]]:], [1], [], +AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 ae0f::10 [[fd0f::10]]:], [1], [], [ovn-nbctl: [[fd0f::10]]:: should be an IP address. ]) -AT_CHECK([ovn-nbctl lb-add lb0 ae0f::10 fd0f::1001a], [1], [], +AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 ae0f::10 fd0f::1001a], [1], [], [ovn-nbctl: fd0f::1001a: should be an IP address. ]) +AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 [[ae0f::10]]: [[fd0f::10]]:80,[[fd0f::20]]:80 tcp], [1], [], +[ovn-nbctl: Protocol is unnecessary when no port of vip is given. +]) + + AT_CHECK([ovn-nbctl lb-add lb0 ae0f::10 fd0f::10 tcp], [1], [], [ovn-nbctl: Protocol is unnecessary when no port of vip is given. ]) From patchwork Fri Apr 13 17:26:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Pfaff X-Patchwork-Id: 898039 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40N4Xx140Qz9s0t for ; Sat, 14 Apr 2018 03:30:09 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id D2E2EDFD; Fri, 13 Apr 2018 17:27:15 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 42141DA4 for ; Fri, 13 Apr 2018 17:27:12 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 17FF4673 for ; Fri, 13 Apr 2018 17:27:10 +0000 (UTC) X-Originating-IP: 208.91.3.26 Received: from sigabrt.benpfaff.org (unknown [208.91.3.26]) (Authenticated sender: blp@ovn.org) by relay1-d.mail.gandi.net (Postfix) with ESMTPSA id 895DD240003; Fri, 13 Apr 2018 19:27:09 +0200 (CEST) From: Ben Pfaff To: dev@openvswitch.org Date: Fri, 13 Apr 2018 10:26:51 -0700 Message-Id: <20180413172655.31638-7-blp@ovn.org> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180413172655.31638-1-blp@ovn.org> References: <20180413172655.31638-1-blp@ovn.org> X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Ben Pfaff Subject: [ovs-dev] [PATCH 07/11] socket-util: Add more functions for IPv[46] sockaddr and sockaddr_storage. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org The existing functions for working with sockaddr_storage that contain an IPv4 or IPv6 address are useful. This commit adds more functions for working with them, as well as a parallel set of functions for struct sockaddr. This also adds an initial user for some of the new sockaddr functions in netdev.c. Signed-off-by: Ben Pfaff --- lib/netdev.c | 31 ++++-------- lib/socket-util.c | 138 +++++++++++++++++++++++++++++++++++++++--------------- lib/socket-util.h | 12 +++++ 3 files changed, 120 insertions(+), 61 deletions(-) diff --git a/lib/netdev.c b/lib/netdev.c index b303a7dc558d..00192f0b00da 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -50,6 +50,7 @@ #include "seq.h" #include "openvswitch/shash.h" #include "smap.h" +#include "socket-util.h" #include "sset.h" #include "svec.h" #include "openvswitch/vlog.h" @@ -2034,29 +2035,13 @@ netdev_get_addrs(const char dev[], struct in6_addr **paddr, addr_array = xzalloc(sizeof *addr_array * cnt); mask_array = xzalloc(sizeof *mask_array * cnt); for (ifa = if_addr_list; ifa; ifa = ifa->ifa_next) { - int family; - - if (!ifa->ifa_name || !ifa->ifa_addr || !ifa->ifa_netmask - || strncmp(ifa->ifa_name, dev, IFNAMSIZ)) { - continue; - } - - family = ifa->ifa_addr->sa_family; - if (family == AF_INET) { - const struct sockaddr_in *sin; - - sin = ALIGNED_CAST(const struct sockaddr_in *, ifa->ifa_addr); - in6_addr_set_mapped_ipv4(&addr_array[i], sin->sin_addr.s_addr); - sin = ALIGNED_CAST(const struct sockaddr_in *, ifa->ifa_netmask); - in6_addr_set_mapped_ipv4(&mask_array[i], sin->sin_addr.s_addr); - i++; - } else if (family == AF_INET6) { - const struct sockaddr_in6 *sin6; - - sin6 = ALIGNED_CAST(const struct sockaddr_in6 *, ifa->ifa_addr); - memcpy(&addr_array[i], &sin6->sin6_addr, sizeof *addr_array); - sin6 = ALIGNED_CAST(const struct sockaddr_in6 *, ifa->ifa_netmask); - memcpy(&mask_array[i], &sin6->sin6_addr, sizeof *mask_array); + if (ifa->ifa_name + && ifa->ifa_addr + && ifa->ifa_netmask + && !strncmp(ifa->ifa_name, dev, IFNAMSIZ) + && sa_is_ip(ifa->ifa_addr)) { + addr_array[i] = sa_get_address(ifa->ifa_addr); + mask_array[i] = sa_get_address(ifa->ifa_netmask); i++; } } diff --git a/lib/socket-util.c b/lib/socket-util.c index 0964a015e3f9..12d16f582d52 100644 --- a/lib/socket-util.c +++ b/lib/socket-util.c @@ -53,6 +53,9 @@ VLOG_DEFINE_THIS_MODULE(socket_util); static int getsockopt_int(int fd, int level, int option, const char *optname, int *valuep); +static struct sockaddr_in *sin_cast(const struct sockaddr *); +static struct sockaddr_in6 *sin6_cast(const struct sockaddr *); +static const struct sockaddr *sa_cast(const struct sockaddr_storage *); /* Sets 'fd' to non-blocking mode. Returns 0 if successful, otherwise a * positive errno value. */ @@ -422,7 +425,7 @@ parse_sockaddr_components(struct sockaddr_storage *ss, const char *port_s, uint16_t default_port, const char *s) { - struct sockaddr_in *sin = ALIGNED_CAST(struct sockaddr_in *, ss); + struct sockaddr_in *sin = sin_cast(sa_cast(ss)); int port; if (port_s && port_s[0]) { @@ -436,9 +439,7 @@ parse_sockaddr_components(struct sockaddr_storage *ss, memset(ss, 0, sizeof *ss); if (host_s && strchr(host_s, ':')) { - struct sockaddr_in6 *sin6 - = ALIGNED_CAST(struct sockaddr_in6 *, ss); - + struct sockaddr_in6 *sin6 = sin6_cast(sa_cast(ss)); char *addr = strsep(&host_s, "%"); sin6->sin6_family = AF_INET6; @@ -1017,25 +1018,47 @@ describe_fd(int fd) #endif /* _WIN32 */ return ds_steal_cstr(&string); } - -/* sockaddr_storage helpers. */ +/* sockaddr helpers. */ + +static struct sockaddr_in * +sin_cast(const struct sockaddr *sa) +{ + return ALIGNED_CAST(struct sockaddr_in *, sa); +} + +static struct sockaddr_in6 * +sin6_cast(const struct sockaddr *sa) +{ + return ALIGNED_CAST(struct sockaddr_in6 *, sa); +} + +/* Returns true if 'sa' represents an IPv4 or IPv6 address, false otherwise. */ +bool +sa_is_ip(const struct sockaddr *sa) +{ + return sa->sa_family == AF_INET || sa->sa_family == AF_INET6; +} + +/* Returns the IPv4 or IPv6 address in 'sa'. Returns IPv4 addresses as + * v6-mapped. */ +struct in6_addr +sa_get_address(const struct sockaddr *sa) +{ + ovs_assert(sa_is_ip(sa)); + return (sa->sa_family == AF_INET + ? in6_addr_mapped_ipv4(sin_cast(sa)->sin_addr.s_addr) + : sin6_cast(sa)->sin6_addr); +} -/* Returns the IPv4 or IPv6 port in 'ss'. */ +/* Returns the IPv4 or IPv6 port in 'sa'. */ uint16_t -ss_get_port(const struct sockaddr_storage *ss) +sa_get_port(const struct sockaddr *sa) { - if (ss->ss_family == AF_INET) { - const struct sockaddr_in *sin - = ALIGNED_CAST(const struct sockaddr_in *, ss); - return ntohs(sin->sin_port); - } else if (ss->ss_family == AF_INET6) { - const struct sockaddr_in6 *sin6 - = ALIGNED_CAST(const struct sockaddr_in6 *, ss); - return ntohs(sin6->sin6_port); - } else { - OVS_NOT_REACHED(); - } + ovs_assert(sa_is_ip(sa)); + return ntohs(sa->sa_family == AF_INET + ? sin_cast(sa)->sin_port + : sin6_cast(sa)->sin6_port); } /* Returns true if 'name' is safe to include inside a network address field. @@ -1055,18 +1078,15 @@ is_safe_name(const char *name) } static void -ss_format_address__(const struct sockaddr_storage *ss, +sa_format_address__(const struct sockaddr *sa, const char *lbrack, const char *rbrack, struct ds *s) { - if (ss->ss_family == AF_INET) { - const struct sockaddr_in *sin - = ALIGNED_CAST(const struct sockaddr_in *, ss); - - ds_put_format(s, IP_FMT, IP_ARGS(sin->sin_addr.s_addr)); - } else if (ss->ss_family == AF_INET6) { - const struct sockaddr_in6 *sin6 - = ALIGNED_CAST(const struct sockaddr_in6 *, ss); + ovs_assert(sa_is_ip(sa)); + if (sa->sa_family == AF_INET) { + ds_put_format(s, IP_FMT, IP_ARGS(sin_cast(sa)->sin_addr.s_addr)); + } else { + const struct sockaddr_in6 *sin6 = sin6_cast(sa); ds_put_cstr(s, lbrack); ds_reserve(s, s->length + INET6_ADDRSTRLEN); @@ -1089,31 +1109,29 @@ ss_format_address__(const struct sockaddr_storage *ss, #endif ds_put_cstr(s, rbrack); - } else { - OVS_NOT_REACHED(); } } -/* Formats the IPv4 or IPv6 address in 'ss' into 's'. If 'ss' is an IPv6 +/* Formats the IPv4 or IPv6 address in 'sa' into 's'. If 'sa' is an IPv6 * address, puts square brackets around the address. */ void -ss_format_address(const struct sockaddr_storage *ss, struct ds *s) +sa_format_address(const struct sockaddr *sa, struct ds *s) { - ss_format_address__(ss, "[", "]", s); + sa_format_address__(sa, "[", "]", s); } -/* Formats the IPv4 or IPv6 address in 'ss' into 's'. Does not add square +/* Formats the IPv4 or IPv6 address in 'sa' into 's'. Does not add square * brackets around IPv6 addresses. */ void -ss_format_address_nobracks(const struct sockaddr_storage *ss, struct ds *s) +sa_format_address_nobracks(const struct sockaddr *sa, struct ds *s) { - ss_format_address__(ss, "", "", s); + sa_format_address__(sa, "", "", s); } size_t -ss_length(const struct sockaddr_storage *ss) +sa_length(const struct sockaddr *sa) { - switch (ss->ss_family) { + switch (sa->sa_family) { case AF_INET: return sizeof(struct sockaddr_in); @@ -1124,7 +1142,51 @@ ss_length(const struct sockaddr_storage *ss) OVS_NOT_REACHED(); } } + +/* sockaddr_storage helpers. */ +static const struct sockaddr * +sa_cast(const struct sockaddr_storage *ss) +{ + return ALIGNED_CAST(const struct sockaddr *, ss); +} + +bool +ss_is_ip(const struct sockaddr_storage *ss) +{ + return sa_is_ip(sa_cast(ss)); +} + +uint16_t +ss_get_port(const struct sockaddr_storage *ss) +{ + return sa_get_port(sa_cast(ss)); +} + +struct in6_addr +ss_get_address(const struct sockaddr_storage *ss) +{ + return sa_get_address(sa_cast(ss)); +} + +void +ss_format_address(const struct sockaddr_storage *ss, struct ds *s) +{ + sa_format_address(sa_cast(ss), s); +} + +void +ss_format_address_nobracks(const struct sockaddr_storage *ss, struct ds *s) +{ + sa_format_address_nobracks(sa_cast(ss), s); +} + +size_t +ss_length(const struct sockaddr_storage *ss) +{ + return sa_length(sa_cast(ss)); +} + /* For Windows socket calls, 'errno' is not set. One has to call * WSAGetLastError() to get the error number and then pass it to * this function to get the correct error string. diff --git a/lib/socket-util.h b/lib/socket-util.h index 239d3f22041c..6d386304dc3a 100644 --- a/lib/socket-util.h +++ b/lib/socket-util.h @@ -74,12 +74,24 @@ char *describe_fd(int fd); * in is used. */ #define DSCP_DEFAULT (IPTOS_PREC_INTERNETCONTROL >> 2) +/* Functions for working with sockaddr that might contain an IPv4 or + * IPv6 address. */ +bool sa_is_ip(const struct sockaddr *); +uint16_t sa_get_port(const struct sockaddr *); +struct in6_addr sa_get_address(const struct sockaddr *); +void sa_format_address(const struct sockaddr *, struct ds *); +void sa_format_address_nobracks(const struct sockaddr *, struct ds *); +size_t sa_length(const struct sockaddr *); + /* Functions for working with sockaddr_storage that might contain an IPv4 or * IPv6 address. */ +bool ss_is_ip(const struct sockaddr_storage *); uint16_t ss_get_port(const struct sockaddr_storage *); +struct in6_addr ss_get_address(const struct sockaddr_storage *); void ss_format_address(const struct sockaddr_storage *, struct ds *); void ss_format_address_nobracks(const struct sockaddr_storage *, struct ds *); size_t ss_length(const struct sockaddr_storage *); + const char *sock_strerror(int error); #ifndef _WIN32 From patchwork Fri Apr 13 17:26:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Pfaff X-Patchwork-Id: 898040 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40N4YS0DmJz9s0t for ; Sat, 14 Apr 2018 03:30:36 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 52EE2E04; Fri, 13 Apr 2018 17:27:17 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 74D4FDD5 for ; Fri, 13 Apr 2018 17:27:13 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 771C8672 for ; Fri, 13 Apr 2018 17:27:12 +0000 (UTC) X-Originating-IP: 208.91.3.26 Received: from sigabrt.benpfaff.org (unknown [208.91.3.26]) (Authenticated sender: blp@ovn.org) by relay1-d.mail.gandi.net (Postfix) with ESMTPSA id E45EC24000D; Fri, 13 Apr 2018 19:27:10 +0200 (CEST) From: Ben Pfaff To: dev@openvswitch.org Date: Fri, 13 Apr 2018 10:26:52 -0700 Message-Id: <20180413172655.31638-8-blp@ovn.org> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180413172655.31638-1-blp@ovn.org> References: <20180413172655.31638-1-blp@ovn.org> X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Ben Pfaff Subject: [ovs-dev] [PATCH 08/11] netdev: New function netdev_get_ip_by_name(). X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org This is like netdev_get_in4_by_name() but accepts any IP address instead of just an IPv4 address. It will acquire its first user in an upcoming commit. Signed-off-by: Ben Pfaff --- lib/netdev.c | 81 +++++++++++++++++++++++++++++++++++++++++++----------------- lib/netdev.h | 1 + 2 files changed, 59 insertions(+), 23 deletions(-) diff --git a/lib/netdev.c b/lib/netdev.c index 00192f0b00da..1c4ae2c6cdd2 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -1142,39 +1142,74 @@ netdev_set_in4(struct netdev *netdev, struct in_addr addr, struct in_addr mask) : EOPNOTSUPP); } -/* Obtains ad IPv4 address from device name and save the address in - * in4. Returns 0 if successful, otherwise a positive errno value. - */ +static int +netdev_get_addresses_by_name(const char *device_name, + struct in6_addr **addrsp, int *n_addrsp) +{ + struct netdev *netdev; + int error = netdev_open(device_name, NULL, &netdev); + if (error) { + *addrsp = NULL; + *n_addrsp = 0; + return error; + } + + struct in6_addr *masks; + error = netdev_get_addr_list(netdev, addrsp, &masks, n_addrsp); + netdev_close(netdev); + free(masks); + return error; +} + +/* Obtains an IPv4 address from 'device_name' and save the address in '*in4'. + * Returns 0 if successful, otherwise a positive errno value. */ int netdev_get_in4_by_name(const char *device_name, struct in_addr *in4) { - struct in6_addr *mask, *addr6; - int err, n_in6, i; - struct netdev *dev; + struct in6_addr *addrs; + int n; + int error = netdev_get_addresses_by_name(device_name, &addrs, &n); - err = netdev_open(device_name, NULL, &dev); - if (err) { - return err; + in4->s_addr = 0; + if (!error) { + error = ENOENT; + for (int i = 0; i < n; i++) { + if (IN6_IS_ADDR_V4MAPPED(&addrs[i])) { + in4->s_addr = in6_addr_get_mapped_ipv4(&addrs[i]); + error = 0; + break; + } + } } + free(addrs); - err = netdev_get_addr_list(dev, &addr6, &mask, &n_in6); - if (err) { - goto out; - } + return error; +} - for (i = 0; i < n_in6; i++) { - if (IN6_IS_ADDR_V4MAPPED(&addr6[i])) { - in4->s_addr = in6_addr_get_mapped_ipv4(&addr6[i]); - goto out; +/* Obtains an IPv4 or IPv6 address from 'device_name' and save the address in + * '*ss', representing IPv4 addressse as v6-mapped. Returns 0 if successful, + * otherwise a positive errno value. */ +int +netdev_get_ip_by_name(const char *device_name, struct in6_addr *in6) +{ + struct in6_addr *addrs; + int n; + int error = netdev_get_addresses_by_name(device_name, &addrs, &n); + + *in6 = in6addr_any; + if (!error) { + error = ENOENT; + for (int i = 0; i < n; i++) { + if (!in6_is_lla(&addrs[i])) { + *in6 = addrs[i]; + error = 0; + break; + } } } - err = -ENOENT; -out: - free(addr6); - free(mask); - netdev_close(dev); - return err; + free(addrs); + return error; } /* Adds 'router' as a default IP gateway for the TCP/IP stack that corresponds diff --git a/lib/netdev.h b/lib/netdev.h index ff1b604b24e2..441e53daeb69 100644 --- a/lib/netdev.h +++ b/lib/netdev.h @@ -282,6 +282,7 @@ void netdev_restore_flags(struct netdev_saved_flags *); /* TCP/IP stack interface. */ int netdev_set_in4(struct netdev *, struct in_addr addr, struct in_addr mask); int netdev_get_in4_by_name(const char *device_name, struct in_addr *in4); +int netdev_get_ip_by_name(const char *device_name, struct in6_addr *); int netdev_get_addr_list(const struct netdev *netdev, struct in6_addr **addr, struct in6_addr **mask, int *n_in6); From patchwork Fri Apr 13 17:26:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Pfaff X-Patchwork-Id: 898042 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40N4Yx3Xqzz9s0t for ; Sat, 14 Apr 2018 03:31:01 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 430AEE08; Fri, 13 Apr 2018 17:27:18 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 638F1DE5 for ; Fri, 13 Apr 2018 17:27:15 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 52DCD672 for ; Fri, 13 Apr 2018 17:27:14 +0000 (UTC) X-Originating-IP: 208.91.3.26 Received: from sigabrt.benpfaff.org (unknown [208.91.3.26]) (Authenticated sender: blp@ovn.org) by relay1-d.mail.gandi.net (Postfix) with ESMTPSA id 80FB7240009; Fri, 13 Apr 2018 19:27:12 +0200 (CEST) From: Ben Pfaff To: dev@openvswitch.org Date: Fri, 13 Apr 2018 10:26:53 -0700 Message-Id: <20180413172655.31638-9-blp@ovn.org> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180413172655.31638-1-blp@ovn.org> References: <20180413172655.31638-1-blp@ovn.org> X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Ben Pfaff Subject: [ovs-dev] [PATCH 09/11] ofproto-dpif-slow: Add IPv6 agent address support. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org Suggested-by: Neil McKee Signed-off-by: Ben Pfaff --- ofproto/ofproto-dpif-sflow.c | 55 ++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/ofproto/ofproto-dpif-sflow.c b/ofproto/ofproto-dpif-sflow.c index 5d8c0e19f8e3..fe79a9dbbad6 100644 --- a/ofproto/ofproto-dpif-sflow.c +++ b/ofproto/ofproto-dpif-sflow.c @@ -446,43 +446,45 @@ sflow_choose_agent_address(const char *agent_device, const char *control_ip, SFLAddress *agent_addr) { - const char *target; - struct in_addr in4; - - memset(agent_addr, 0, sizeof *agent_addr); - agent_addr->type = SFLADDRESSTYPE_IP_V4; + struct in6_addr ip; if (agent_device) { - if (!netdev_get_in4_by_name(agent_device, &in4) - || !lookup_ip(agent_device, &in4)) { + /* If 'agent_device' is the name of a network device, use its IP + * address. */ + if (!netdev_get_ip_by_name(agent_device, &ip)) { + goto success; + } + + /* If 'agent_device' is itself an IP address, use it. */ + struct sockaddr_storage ss; + if (inet_parse_address(agent_device, &ss)) { + ip = ss_get_address(&ss); goto success; } } + /* Otherwise, use an appropriate local IP address for one of the + * collectors' remote IP addresses. */ + const char *target; SSET_FOR_EACH (target, targets) { - union { - struct sockaddr_storage ss; - struct sockaddr_in sin; - } sa; - char name[IFNAMSIZ]; - - if (inet_parse_active(target, SFL_DEFAULT_COLLECTOR_PORT, &sa.ss) - && sa.ss.ss_family == AF_INET) { - struct in6_addr addr6, src, gw; - - in6_addr_set_mapped_ipv4(&addr6, sa.sin.sin_addr.s_addr); + struct sockaddr_storage ss; + if (inet_parse_active(target, SFL_DEFAULT_COLLECTOR_PORT, &ss)) { /* sFlow only supports target in default routing table with * packet mark zero. */ - if (ovs_router_lookup(0, &addr6, name, &src, &gw)) { + ip = ss_get_address(&ss); - in4.s_addr = in6_addr_get_mapped_ipv4(&src); + struct in6_addr src, gw; + char name[IFNAMSIZ]; + if (ovs_router_lookup(0, &ip, name, &src, &gw)) { goto success; } } } - if (control_ip && !lookup_ip(control_ip, &in4)) { + struct sockaddr_storage ss; + if (control_ip && inet_parse_address(control_ip, &ss)) { + ip = ss_get_address(&ss); goto success; } @@ -490,7 +492,16 @@ sflow_choose_agent_address(const char *agent_device, return false; success: - agent_addr->address.ip_v4.addr = (OVS_FORCE uint32_t) in4.s_addr; + memset(agent_addr, 0, sizeof *agent_addr); + if (IN6_IS_ADDR_V4MAPPED(&ip)) { + agent_addr->type = SFLADDRESSTYPE_IP_V4; + agent_addr->address.ip_v4.addr + = (OVS_FORCE uint32_t) in6_addr_get_mapped_ipv4(&ip); + } else { + agent_addr->type = SFLADDRESSTYPE_IP_V6; + memcpy(agent_addr->address.ip_v6.addr, ip.s6_addr, + sizeof agent_addr->address.ip_v6.addr); + } return true; } From patchwork Fri Apr 13 17:26:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Pfaff X-Patchwork-Id: 898043 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40N4ZM6qllz9s0t for ; Sat, 14 Apr 2018 03:31:23 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 5E76CE16; Fri, 13 Apr 2018 17:27:19 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 7DD35DE3 for ; Fri, 13 Apr 2018 17:27:16 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id EFC8C672 for ; Fri, 13 Apr 2018 17:27:15 +0000 (UTC) X-Originating-IP: 208.91.3.26 Received: from sigabrt.benpfaff.org (unknown [208.91.3.26]) (Authenticated sender: blp@ovn.org) by relay1-d.mail.gandi.net (Postfix) with ESMTPSA id 4F52A240008; Fri, 13 Apr 2018 19:27:13 +0200 (CEST) From: Ben Pfaff To: dev@openvswitch.org Date: Fri, 13 Apr 2018 10:26:54 -0700 Message-Id: <20180413172655.31638-10-blp@ovn.org> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180413172655.31638-1-blp@ovn.org> References: <20180413172655.31638-1-blp@ovn.org> X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Ben Pfaff Subject: [ovs-dev] [PATCH 10/11] ovn-nbctl: Simplify lb_info_add_smap(). X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org Signed-off-by: Ben Pfaff --- ovn/utilities/ovn-nbctl.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/ovn/utilities/ovn-nbctl.c b/ovn/utilities/ovn-nbctl.c index 16698de1f049..85d4d3534b54 100644 --- a/ovn/utilities/ovn-nbctl.c +++ b/ovn/utilities/ovn-nbctl.c @@ -1945,11 +1945,9 @@ static void lb_info_add_smap(const struct nbrec_load_balancer *lb, struct smap *lbs, int vip_width) { - struct ds key = DS_EMPTY_INITIALIZER; - struct ds val = DS_EMPTY_INITIALIZER; - const struct smap_node **nodes = smap_sort(&lb->vips); if (nodes) { + struct ds val = DS_EMPTY_INITIALIZER; for (int i = 0; i < smap_count(&lb->vips); i++) { const struct smap_node *node = nodes[i]; @@ -1971,11 +1969,8 @@ lb_info_add_smap(const struct nbrec_load_balancer *lb, node->key, node->value); } - ds_put_format(&key, "%-20.16s", lb->name); - smap_add(lbs, ds_cstr(&key), ds_cstr(&val)); - - ds_destroy(&key); - ds_destroy(&val); + smap_add_nocopy(lbs, xasprintf("%-20.16s", lb->name), + ds_steal_cstr(&val)); free(nodes); } } From patchwork Fri Apr 13 17:26:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Pfaff X-Patchwork-Id: 898044 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40N4Zn6s4jz9s0t for ; Sat, 14 Apr 2018 03:31:45 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id E9913E11; Fri, 13 Apr 2018 17:27:20 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 1C1A3DE0 for ; Fri, 13 Apr 2018 17:27:18 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 3BA1767D for ; Fri, 13 Apr 2018 17:27:17 +0000 (UTC) X-Originating-IP: 208.91.3.26 Received: from sigabrt.benpfaff.org (unknown [208.91.3.26]) (Authenticated sender: blp@ovn.org) by relay1-d.mail.gandi.net (Postfix) with ESMTPSA id DC5B3240003; Fri, 13 Apr 2018 19:27:15 +0200 (CEST) From: Ben Pfaff To: dev@openvswitch.org Date: Fri, 13 Apr 2018 10:26:55 -0700 Message-Id: <20180413172655.31638-11-blp@ovn.org> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180413172655.31638-1-blp@ovn.org> References: <20180413172655.31638-1-blp@ovn.org> X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Ben Pfaff Subject: [ovs-dev] [PATCH 11/11] ovn-nbctl: Use common code for sockaddr_storage. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org This better reuses existing code. Signed-off-by: Ben Pfaff --- ovn/utilities/ovn-nbctl.c | 43 ++++++++++++------------------------------- 1 file changed, 12 insertions(+), 31 deletions(-) diff --git a/ovn/utilities/ovn-nbctl.c b/ovn/utilities/ovn-nbctl.c index 85d4d3534b54..5c18161fe1c2 100644 --- a/ovn/utilities/ovn-nbctl.c +++ b/ovn/utilities/ovn-nbctl.c @@ -1782,7 +1782,6 @@ nbctl_lb_add(struct ctl_context *ctx) const char *lb_proto; bool is_update_proto = false; - bool is_vip_with_port = true; if (ctx->argc == 4) { /* Default protocol. */ @@ -1803,38 +1802,17 @@ nbctl_lb_add(struct ctl_context *ctx) "and a port number with : as a separator).", lb_vip); } - char lb_vip_normalized[INET6_ADDRSTRLEN + 8]; - char normalized_ip[INET6_ADDRSTRLEN]; - if (ss_vip.ss_family == AF_INET) { - struct sockaddr_in *sin = ALIGNED_CAST(struct sockaddr_in *, &ss_vip); - inet_ntop(AF_INET, &sin->sin_addr, normalized_ip, - sizeof normalized_ip); - if (sin->sin_port) { - is_vip_with_port = true; - snprintf(lb_vip_normalized, sizeof lb_vip_normalized, "%s:%d", - normalized_ip, ntohs(sin->sin_port)); - } else { - is_vip_with_port = false; - ovs_strlcpy(lb_vip_normalized, normalized_ip, - sizeof lb_vip_normalized); - } + struct ds lb_vip_normalized_ds = DS_EMPTY_INITIALIZER; + uint16_t lb_vip_port = ss_get_port(&ss_vip); + if (lb_vip_port) { + ss_format_address(&ss_vip, &lb_vip_normalized_ds); + ds_put_format(&lb_vip_normalized_ds, ":%d", lb_vip_port); } else { - struct sockaddr_in6 *sin6 = ALIGNED_CAST(struct sockaddr_in6 *, - &ss_vip); - inet_ntop(AF_INET6, &sin6->sin6_addr, normalized_ip, - sizeof normalized_ip); - if (sin6->sin6_port) { - is_vip_with_port = true; - snprintf(lb_vip_normalized, sizeof lb_vip_normalized, "[%s]:%d", - normalized_ip, ntohs(sin6->sin6_port)); - } else { - is_vip_with_port = false; - ovs_strlcpy(lb_vip_normalized, normalized_ip, - sizeof lb_vip_normalized); - } + ss_format_address_nobracks(&ss_vip, &lb_vip_normalized_ds); } + const char *lb_vip_normalized = ds_cstr(&lb_vip_normalized_ds); - if (!is_vip_with_port && is_update_proto) { + if (!lb_vip_port && is_update_proto) { ctl_fatal("Protocol is unnecessary when no port of vip " "is given."); } @@ -1845,7 +1823,7 @@ nbctl_lb_add(struct ctl_context *ctx) token != NULL; token = strtok_r(NULL, ",", &save_ptr)) { struct sockaddr_storage ss_dst; - if (is_vip_with_port) { + if (lb_vip_port) { if (!inet_parse_active(token, -1, &ss_dst)) { ctl_fatal("%s: should be an IP address and a port " "number with : as a separator.", token); @@ -1892,6 +1870,7 @@ nbctl_lb_add(struct ctl_context *ctx) nbrec_load_balancer_verify_vips(lb); nbrec_load_balancer_set_vips(lb, &lb->vips); ds_destroy(&lb_ips_new); + ds_destroy(&lb_vip_normalized_ds); return; } } @@ -1904,6 +1883,8 @@ nbctl_lb_add(struct ctl_context *ctx) lb_vip_normalized, ds_cstr(&lb_ips_new)); nbrec_load_balancer_set_vips(lb, &lb->vips); ds_destroy(&lb_ips_new); + + ds_destroy(&lb_vip_normalized_ds); } static void