From patchwork Thu Mar 26 21:05:28 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Gospodarek X-Patchwork-Id: 455199 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id CF002140146 for ; Fri, 27 Mar 2015 08:06:41 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="verification failed; unprotected key" header.d=cumulusnetworks.com header.i=@cumulusnetworks.com header.b=SmXVZ1BR; dkim-adsp=none (unprotected policy); dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753094AbbCZVGi (ORCPT ); Thu, 26 Mar 2015 17:06:38 -0400 Received: from mail-yh0-f41.google.com ([209.85.213.41]:33371 "EHLO mail-yh0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752298AbbCZVGc (ORCPT ); Thu, 26 Mar 2015 17:06:32 -0400 Received: by yhpt93 with SMTP id t93so32230201yhp.0 for ; Thu, 26 Mar 2015 14:06:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cumulusnetworks.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=riZOG9lIdgldFQhj1ORZRUKV6jXeA/5a3c/0d0NSUrY=; b=SmXVZ1BRKg9squUmtscN6tN0USvp/QDURfc9ZzNFp3XV1BU7Uztfj31IU8mAsYDPtx FZoFao/IEpuLNV85PWIIGatgsvQ9XV0g4FeUUkE+nSODZjOtjv+Vg3VnwkoJZAow0C0o z7+MHENZoXNa6lhDeFRL/rOFxdxXdK4LfQ6VQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=riZOG9lIdgldFQhj1ORZRUKV6jXeA/5a3c/0d0NSUrY=; b=ZK8/7S43DlrEBz1eSmYspoCmEn27cJrcinUlYuZLoeE00EcRsegPrPefp5vS24Vktq fYiZr8KRA29W4g/NTH4hF3I5/OVc7lRywwnV+fyTo5X7UQnc256prjBRA0CFNQfE1ynT 0H1FBwH7vTVx0zAvtqbNKyJAz1w3CJFfDlFs+/+IopX6K+O/BkLK6z3Zi0ErA6af3+vU J9rNbnb4sNCFBv354FEG4F1iLmdtZV2zFxl14ryAb5P7tkT4iLZ7nuwOuw4d+xDabzgR ENcWqHFLoOGK+6rmwWJ9xf0uSNUklHpUfA/6+wKWWCGdWnK3GRMOHSyCf8TNno6v4qsy xgXQ== X-Gm-Message-State: ALoCoQlUEfAWK65iJgN92YkmMbDTXJLuwOIBgKpbeTeca1pA40g7Tw22mfnabYmIcArIKDQH2PqO X-Received: by 10.170.219.9 with SMTP id l9mr18353319ykf.105.1427403992020; Thu, 26 Mar 2015 14:06:32 -0700 (PDT) Received: from fedora-devel.home.greyhouse.net (cpe-024-211-243-155.nc.res.rr.com. [24.211.243.155]) by mx.google.com with ESMTPSA id v18sm1087166yha.16.2015.03.26.14.06.31 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 26 Mar 2015 14:06:31 -0700 (PDT) From: Andy Gospodarek To: netdev@vger.kernel.org, Bjornar Ness , Sowmini Varadhan , Eric Dumazet , "John W. Linville" Cc: Andy Gospodarek Subject: [RFC iproute2 2/2] iproute2: allow user to set IPv6 nexthop for IPv4 route Date: Thu, 26 Mar 2015 17:05:28 -0400 Message-Id: <1427403928-1342-3-git-send-email-gospo@cumulusnetworks.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1427403928-1342-1-git-send-email-gospo@cumulusnetworks.com> References: <1427403928-1342-1-git-send-email-gospo@cumulusnetworks.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This will allow a user to run a command like this: $ ip route add 20.0.0.0/24 via 2100::2 dev p7p1 so that an IPv6 network can be used as a carrier for IPv4 traffic. This is extremely useful in many datecenter environments especially where autoconfiguration of IPv6 helps minimize the need to configure invdividual addresses on each interface. This feature does not encompass all that is needed to support RFC-5549, but this demonstrates the netlink infrastructure needed to correctly enable the kernel infrastructure. For more informtion the full RFC is here: http://www.ietf.org/rfc/rfc5549.txt. Signed-off-by: Andy Gospodarek --- include/linux/rtnetlink.h | 4 ++++ ip/iproute.c | 18 +++++++++++++++--- lib/utils.c | 4 +++- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 3eb7810..fff7095 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -303,6 +303,10 @@ enum rtattr_type_t { RTA_TABLE, RTA_MARK, RTA_MFC_STATS, + RTA_VIA, + RTA_NEWDST, + RTA_PREF, + RTA_GATEWAY6, __RTA_MAX }; diff --git a/ip/iproute.c b/ip/iproute.c index 024d401..ed66cb8 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -384,6 +384,15 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) RTA_DATA(tb[RTA_GATEWAY]), abuf, sizeof(abuf))); } + + if (tb[RTA_GATEWAY6] && filter.rvia.bitlen != host_len) { + fprintf(fp, "via %s ", + format_host(AF_INET6, + RTA_PAYLOAD(tb[RTA_GATEWAY6]), + RTA_DATA(tb[RTA_GATEWAY6]), + abuf, sizeof(abuf))); + } + if (tb[RTA_OIF] && filter.oifmask != -1) fprintf(fp, "dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF]))); @@ -647,7 +656,7 @@ static int parse_one_nh(struct rtmsg *r, struct rtattr *rta, inet_prefix addr; NEXT_ARG(); get_addr(&addr, *argv, r->rtm_family); - if (r->rtm_family == AF_UNSPEC) + if (addr.family == AF_UNSPEC) r->rtm_family = addr.family; rta_addattr_l(rta, 4096, RTA_GATEWAY, &addr.data, addr.bytelen); rtnh->rtnh_len += sizeof(struct rtattr) + addr.bytelen; @@ -761,9 +770,12 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) gw_ok = 1; NEXT_ARG(); get_addr(&addr, *argv, req.r.rtm_family); - if (req.r.rtm_family == AF_UNSPEC) + if (addr.family == AF_UNSPEC) req.r.rtm_family = addr.family; - addattr_l(&req.n, sizeof(req), RTA_GATEWAY, &addr.data, addr.bytelen); + if (addr.family == AF_INET) + addattr_l(&req.n, sizeof(req), RTA_GATEWAY, &addr.data, addr.bytelen); + else if (addr.family == AF_INET6) + addattr_l(&req.n, sizeof(req), RTA_GATEWAY6, &addr.data, addr.bytelen); } else if (strcmp(*argv, "from") == 0) { inet_prefix addr; NEXT_ARG(); diff --git a/lib/utils.c b/lib/utils.c index 0d08a86..feadbbf 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -399,7 +399,7 @@ int get_addr_1(inet_prefix *addr, const char *name, int family) if (strchr(name, ':')) { addr->family = AF_INET6; - if (family != AF_UNSPEC && family != AF_INET6) + if (family != AF_UNSPEC && family != AF_INET6 && family != AF_INET) return -1; if (inet_pton(AF_INET6, name, addr->data) <= 0) return -1; @@ -712,6 +712,8 @@ static const char *resolve_address(const void *addr, int len, int af) const char *format_host(int af, int len, const void *addr, char *buf, int buflen) { + if (af == AF_INET && len == 16) + af = AF_INET6; #ifdef RESOLVE_HOSTNAMES if (resolve_hosts) { const char *n;