From patchwork Thu May 30 03:17:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 1107531 X-Patchwork-Delegate: dsahern@gmail.com Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.b="Wl4KHB1f"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45Dv9b0Jlyz9sTc for ; Thu, 30 May 2019 14:04:51 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732786AbfE3EEt (ORCPT ); Thu, 30 May 2019 00:04:49 -0400 Received: from mail.kernel.org ([198.145.29.99]:48754 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731267AbfE3DRt (ORCPT ); Wed, 29 May 2019 23:17:49 -0400 Received: from kenny.it.cumulusnetworks.com. (fw.cumulusnetworks.com [216.129.126.126]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 2A89724479; Thu, 30 May 2019 03:17:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1559186269; bh=xM5DNrsmEG9g5p6X7sFE3f4jmCS9m0E85wnQOdos27o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Wl4KHB1fvi1rfeemWen6YkVZ0HQ3DaEjbLJ3bJOZ31c1ciqQhQ3lsDHhWDikOgw3Z qejwP/z6l382QJ/9qw/E+7rwrt38grrqzjq0mM0McjkQitRBD/o6z1wDYucQ4/j48V DZTzCP1csVQtuWkKtQlV3xmOGDTw7I23OndjmYwE= From: David Ahern To: stephen@networkplumber.org Cc: netdev@vger.kernel.org, David Ahern Subject: [PATCH iproute2-next 1/9] libnetlink: Set NLA_F_NESTED in rta_nest Date: Wed, 29 May 2019 20:17:38 -0700 Message-Id: <20190530031746.2040-2-dsahern@kernel.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190530031746.2040-1-dsahern@kernel.org> References: <20190530031746.2040-1-dsahern@kernel.org> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: David Ahern Kernel now requires NLA_F_NESTED to be set on new nested attributes. Set NLA_F_NESTED in rta_nest. Signed-off-by: David Ahern --- lib/libnetlink.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/libnetlink.c b/lib/libnetlink.c index 0d48a3d43cf0..6ae51a9dba14 100644 --- a/lib/libnetlink.c +++ b/lib/libnetlink.c @@ -1336,6 +1336,7 @@ struct rtattr *rta_nest(struct rtattr *rta, int maxlen, int type) struct rtattr *nest = RTA_TAIL(rta); rta_addattr_l(rta, maxlen, type, NULL, 0); + nest->rta_type |= NLA_F_NESTED; return nest; } From patchwork Thu May 30 03:17:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 1107532 X-Patchwork-Delegate: dsahern@gmail.com Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.b="uDl2Je04"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45Dv9k518yz9sTc for ; Thu, 30 May 2019 14:04:58 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731272AbfE3EE4 (ORCPT ); Thu, 30 May 2019 00:04:56 -0400 Received: from mail.kernel.org ([198.145.29.99]:48276 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731270AbfE3DRt (ORCPT ); Wed, 29 May 2019 23:17:49 -0400 Received: from kenny.it.cumulusnetworks.com. (fw.cumulusnetworks.com [216.129.126.126]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 5DA7C24729; Thu, 30 May 2019 03:17:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1559186269; bh=wh63PGozm3piZl4WOI2F2hGTXJdzE6fSQuzQ+CdKI5E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uDl2Je04I3olNJsp3yWH/Cuv6qNOqfO8doPzi24kiKhYbZlx0ax1ndMRn9YRoW+Y4 xIMSdFYKvqtKtZDlQ5helwNLGM0CB8txizPJ0Y+5hKtd/EUHcZGG062VRH/1XLfTM/ sXFImxOvjHwCQAeP1rxQYyec2rMSNzpS09WfxBNA= From: David Ahern To: stephen@networkplumber.org Cc: netdev@vger.kernel.org, David Ahern Subject: [PATCH iproute2-next 2/9] lwtunnel: Pass encap and encap_type attributes to lwt_parse_encap Date: Wed, 29 May 2019 20:17:39 -0700 Message-Id: <20190530031746.2040-3-dsahern@kernel.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190530031746.2040-1-dsahern@kernel.org> References: <20190530031746.2040-1-dsahern@kernel.org> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: David Ahern lwt_parse_encap currently assumes the encap attribute is RTA_ENCAP and the type is RTA_ENCAP_TYPE. Change lwt_parse_encap to take these as input arguments for reuse by nexthop code which has the attributes as NHA_ENCAP and NHA_ENCAP_TYPE. Signed-off-by: David Ahern --- ip/ip_common.h | 3 ++- ip/iproute.c | 6 ++++-- ip/iproute_lwtunnel.c | 7 ++++--- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/ip/ip_common.h b/ip/ip_common.h index b4aa34a70c92..df279e4f7b9a 100644 --- a/ip/ip_common.h +++ b/ip/ip_common.h @@ -134,7 +134,8 @@ int bond_parse_xstats(struct link_util *lu, int argc, char **argv); int bond_print_xstats(struct nlmsghdr *n, void *arg); /* iproute_lwtunnel.c */ -int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp); +int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp, + int encap_attr, int encap_type_attr); void lwt_print_encap(FILE *fp, struct rtattr *encap_type, struct rtattr *encap); /* iplink_xdp.c */ diff --git a/ip/iproute.c b/ip/iproute.c index 2b3dcc5dbd53..440b1fc8b413 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -997,7 +997,8 @@ static int parse_one_nh(struct nlmsghdr *n, struct rtmsg *r, } else if (strcmp(*argv, "encap") == 0) { int old_len = rta->rta_len; - if (lwt_parse_encap(rta, len, &argc, &argv)) + if (lwt_parse_encap(rta, len, &argc, &argv, + RTA_ENCAP, RTA_ENCAP_TYPE)) return -1; rtnh->rtnh_len += rta->rta_len - old_len; } else if (strcmp(*argv, "as") == 0) { @@ -1416,7 +1417,8 @@ static int iproute_modify(int cmd, unsigned int flags, int argc, char **argv) rta->rta_type = RTA_ENCAP; rta->rta_len = RTA_LENGTH(0); - lwt_parse_encap(rta, sizeof(buf), &argc, &argv); + lwt_parse_encap(rta, sizeof(buf), &argc, &argv, + RTA_ENCAP, RTA_ENCAP_TYPE); if (rta->rta_len > RTA_LENGTH(0)) addraw_l(&req.n, 1024 diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c index 03217b8f08f8..60f34a32a6e5 100644 --- a/ip/iproute_lwtunnel.c +++ b/ip/iproute_lwtunnel.c @@ -1111,7 +1111,8 @@ static int parse_encap_bpf(struct rtattr *rta, size_t len, int *argcp, return 0; } -int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp) +int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp, + int encap_attr, int encap_type_attr) { struct rtattr *nest; int argc = *argcp; @@ -1131,7 +1132,7 @@ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp) exit(-1); } - nest = rta_nest(rta, len, RTA_ENCAP); + nest = rta_nest(rta, len, encap_attr); switch (type) { case LWTUNNEL_ENCAP_MPLS: ret = parse_encap_mpls(rta, len, &argc, &argv); @@ -1164,7 +1165,7 @@ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp) rta_nest_end(rta, nest); - ret = rta_addattr16(rta, len, RTA_ENCAP_TYPE, type); + ret = rta_addattr16(rta, len, encap_type_attr, type); *argcp = argc; *argvp = argv; From patchwork Thu May 30 03:17:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 1107496 X-Patchwork-Delegate: dsahern@gmail.com Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.b="2ajVrI/x"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45Dt7N3Yvjz9sPJ for ; Thu, 30 May 2019 13:17:52 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731295AbfE3DRv (ORCPT ); Wed, 29 May 2019 23:17:51 -0400 Received: from mail.kernel.org ([198.145.29.99]:48304 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731273AbfE3DRu (ORCPT ); Wed, 29 May 2019 23:17:50 -0400 Received: from kenny.it.cumulusnetworks.com. (fw.cumulusnetworks.com [216.129.126.126]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 90B5E24726; Thu, 30 May 2019 03:17:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1559186269; bh=n8IBK3dCAN27MQYAkoLRDxbNXvETLAbr5HekssFqeRQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=2ajVrI/xMrOv+ogUPFSLE7NjA0mBQmlJpz/X3dITvn3AfESilBISXXEalrrFBMRl+ KmieEP2ZUWGOnL8FJWloX9m7bjoH/D8sXadYkdINk0aUiPAMzheiJ2EqzfrDhy6HQD 2wd7qi1itKhByoyxGPM1UWZUtZiTRE/ducoXwVlY= From: David Ahern To: stephen@networkplumber.org Cc: netdev@vger.kernel.org, David Ahern Subject: [PATCH iproute2-next 3/9] libnetlink: Add helper to add a group via setsockopt Date: Wed, 29 May 2019 20:17:40 -0700 Message-Id: <20190530031746.2040-4-dsahern@kernel.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190530031746.2040-1-dsahern@kernel.org> References: <20190530031746.2040-1-dsahern@kernel.org> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: David Ahern groups > 31 have to be joined using the setsockopt. Since the nexthop group is 32, add a helper to allow 'ip monitor' to listen for nexthop messages. Signed-off-by: David Ahern --- include/libnetlink.h | 3 ++- lib/libnetlink.c | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/libnetlink.h b/include/libnetlink.h index 503b3ec11bb6..599b2c592f68 100644 --- a/include/libnetlink.h +++ b/include/libnetlink.h @@ -45,7 +45,8 @@ int rtnl_open(struct rtnl_handle *rth, unsigned int subscriptions) int rtnl_open_byproto(struct rtnl_handle *rth, unsigned int subscriptions, int protocol) __attribute__((warn_unused_result)); - +int rtnl_add_nl_group(struct rtnl_handle *rth, unsigned int group) + __attribute__((warn_unused_result)); void rtnl_close(struct rtnl_handle *rth); void rtnl_set_strict_dump(struct rtnl_handle *rth); diff --git a/lib/libnetlink.c b/lib/libnetlink.c index 6ae51a9dba14..eb85bbdf01ee 100644 --- a/lib/libnetlink.c +++ b/lib/libnetlink.c @@ -173,6 +173,12 @@ void rtnl_set_strict_dump(struct rtnl_handle *rth) rth->flags |= RTNL_HANDLE_F_STRICT_CHK; } +int rtnl_add_nl_group(struct rtnl_handle *rth, unsigned int group) +{ + return setsockopt(rth->fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, + &group, sizeof(group)); +} + void rtnl_close(struct rtnl_handle *rth) { if (rth->fd >= 0) { From patchwork Thu May 30 03:17:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 1107525 X-Patchwork-Delegate: dsahern@gmail.com Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.b="0T27J6xt"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45Dv8w0DqQz9sVx for ; Thu, 30 May 2019 14:04:16 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731316AbfE3DRw (ORCPT ); Wed, 29 May 2019 23:17:52 -0400 Received: from mail.kernel.org ([198.145.29.99]:48828 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731274AbfE3DRu (ORCPT ); Wed, 29 May 2019 23:17:50 -0400 Received: from kenny.it.cumulusnetworks.com. (fw.cumulusnetworks.com [216.129.126.126]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id C3C582472C; Thu, 30 May 2019 03:17:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1559186269; bh=UIstGdJB++uCNT+ZZwRcDYZ7xxWQ4yA79qmUZ+sEvoM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=0T27J6xtKTVmBeVBPCS46+Mn8vjGHSyLLpGX7KpuVSNZ/eMGjY1jgcC/f9yFNtqgp OIQELIG4Md0WBTQWeL/An3ZZn68NNX6dgBWns8mSMVXKM2WxESIW1T8Z39XguN2NOM Sr99OwL3f+tsxIHvLS4nKDDFAhrOCaFsfKEqTsOI= From: David Ahern To: stephen@networkplumber.org Cc: netdev@vger.kernel.org, David Ahern Subject: [PATCH iproute2-next 4/9] uapi: Import nexthop object API Date: Wed, 29 May 2019 20:17:41 -0700 Message-Id: <20190530031746.2040-5-dsahern@kernel.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190530031746.2040-1-dsahern@kernel.org> References: <20190530031746.2040-1-dsahern@kernel.org> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: David Ahern Add nexthop.h from kernel with the uapi for nexthop objects. Signed-off-by: David Ahern --- include/uapi/linux/nexthop.h | 56 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 include/uapi/linux/nexthop.h diff --git a/include/uapi/linux/nexthop.h b/include/uapi/linux/nexthop.h new file mode 100644 index 000000000000..b56c5b895476 --- /dev/null +++ b/include/uapi/linux/nexthop.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _LINUX_NEXTHOP_H +#define _LINUX_NEXTHOP_H + +#include + +struct nhmsg { + unsigned char nh_family; + unsigned char nh_scope; /* return only */ + unsigned char nh_protocol; /* Routing protocol that installed nh */ + unsigned char resvd; + unsigned int nh_flags; /* RTNH_F flags */ +}; + +/* entry in a nexthop group */ +struct nexthop_grp { + __u32 id; /* nexthop id - must exist */ + __u8 weight; /* weight of this nexthop */ + __u8 resvd1; + __u16 resvd2; +}; + +enum { + NEXTHOP_GRP_TYPE_MPATH, /* default type if not specified */ + __NEXTHOP_GRP_TYPE_MAX, +}; + +#define NEXTHOP_GRP_TYPE_MAX (__NEXTHOP_GRP_TYPE_MAX - 1) + +enum { + NHA_UNSPEC, + NHA_ID, /* u32; id for nexthop. id == 0 means auto-assign */ + + NHA_GROUP, /* array of nexthop_grp */ + NHA_GROUP_TYPE, /* u16 one of NEXTHOP_GRP_TYPE */ + /* if NHA_GROUP attribute is added, no other attributes can be set */ + + NHA_BLACKHOLE, /* flag; nexthop used to blackhole packets */ + /* if NHA_BLACKHOLE is added, OIF, GATEWAY, ENCAP can not be set */ + + NHA_OIF, /* u32; nexthop device */ + NHA_GATEWAY, /* be32 (IPv4) or in6_addr (IPv6) gw address */ + NHA_ENCAP_TYPE, /* u16; lwt encap type */ + NHA_ENCAP, /* lwt encap data */ + + /* NHA_OIF can be appended to dump request to return only + * nexthops using given device + */ + NHA_GROUPS, /* flag; only return nexthop groups in dump */ + NHA_MASTER, /* u32; only return nexthops with given master dev */ + + __NHA_MAX, +}; + +#define NHA_MAX (__NHA_MAX - 1) +#endif From patchwork Thu May 30 03:17:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 1107526 X-Patchwork-Delegate: dsahern@gmail.com Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.b="ZP/l34fw"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45Dv8z4c7zz9sSv for ; Thu, 30 May 2019 14:04:19 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730359AbfE3DRv (ORCPT ); Wed, 29 May 2019 23:17:51 -0400 Received: from mail.kernel.org ([198.145.29.99]:48276 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731277AbfE3DRu (ORCPT ); Wed, 29 May 2019 23:17:50 -0400 Received: from kenny.it.cumulusnetworks.com. (fw.cumulusnetworks.com [216.129.126.126]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 02ACC24718; Thu, 30 May 2019 03:17:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1559186270; bh=v7bpd8jgnSr2idUWxcnwBTFRhZC+Jp1p0sNQKJ2hAoY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZP/l34fwsSahwNYSEKP6Aee6yqShiwpb6saxBZUoiArE0UOTqDtTzGb94abSVSTcA Uh7eVTAT41pRdPfuyBOtie+yhUfP1UmwfOKgOTpNgP9/SW6RaIbwtMFIOrbKYNLF8o sdRtUwxa2dteGNFHKBp3WDNoM7rXFUoIpctx/1PE= From: David Ahern To: stephen@networkplumber.org Cc: netdev@vger.kernel.org, David Ahern Subject: [PATCH iproute2-next 5/9] libnetlink: Add helper to create nexthop dump request Date: Wed, 29 May 2019 20:17:42 -0700 Message-Id: <20190530031746.2040-6-dsahern@kernel.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190530031746.2040-1-dsahern@kernel.org> References: <20190530031746.2040-1-dsahern@kernel.org> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: David Ahern Add rtnl_nexthopdump_req to initiate a dump request of nexthop objects. Signed-off-by: David Ahern --- include/libnetlink.h | 4 ++++ lib/libnetlink.c | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/include/libnetlink.h b/include/libnetlink.h index 599b2c592f68..1ddba8dcd220 100644 --- a/include/libnetlink.h +++ b/include/libnetlink.h @@ -93,6 +93,10 @@ int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int rtnl_dump_request_n(struct rtnl_handle *rth, struct nlmsghdr *n) __attribute__((warn_unused_result)); +int rtnl_nexthopdump_req(struct rtnl_handle *rth, int family, + req_filter_fn_t filter_fn) + __attribute__((warn_unused_result)); + struct rtnl_ctrl_data { int nsid; }; diff --git a/lib/libnetlink.c b/lib/libnetlink.c index eb85bbdf01ee..c1cdda3b8d4e 100644 --- a/lib/libnetlink.c +++ b/lib/libnetlink.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "libnetlink.h" @@ -252,6 +253,32 @@ int rtnl_open(struct rtnl_handle *rth, unsigned int subscriptions) return rtnl_open_byproto(rth, subscriptions, NETLINK_ROUTE); } +int rtnl_nexthopdump_req(struct rtnl_handle *rth, int family, + req_filter_fn_t filter_fn) +{ + struct { + struct nlmsghdr nlh; + struct nhmsg nhm; + char buf[128]; + } req = { + .nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)), + .nlh.nlmsg_type = RTM_GETNEXTHOP, + .nlh.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST, + .nlh.nlmsg_seq = rth->dump = ++rth->seq, + .nhm.nh_family = family, + }; + + if (filter_fn) { + int err; + + err = filter_fn(&req.nlh, sizeof(req)); + if (err) + return err; + } + + return send(rth->fd, &req, sizeof(req), 0); +} + int rtnl_addrdump_req(struct rtnl_handle *rth, int family, req_filter_fn_t filter_fn) { From patchwork Thu May 30 03:17:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 1107530 X-Patchwork-Delegate: dsahern@gmail.com Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.b="Cu3Ho/WH"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45Dv9T2RGYz9sPk for ; Thu, 30 May 2019 14:04:45 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731723AbfE3EEk (ORCPT ); Thu, 30 May 2019 00:04:40 -0400 Received: from mail.kernel.org ([198.145.29.99]:48242 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731278AbfE3DRu (ORCPT ); Wed, 29 May 2019 23:17:50 -0400 Received: from kenny.it.cumulusnetworks.com. (fw.cumulusnetworks.com [216.129.126.126]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 36F1324730; Thu, 30 May 2019 03:17:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1559186270; bh=slmTQXCo492YJ3HiWSXk9l4HgBA82vvXctiuhGrpyGE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Cu3Ho/WHOYre62LRCNMxeTqF5yzLUbv3eQGH2eyfT4/wDwoMtAb/r2919PfNTgBHK VKKPH7uitwMQ5f+S5G3mbKlQABBqiXiPQvrzbW14SbTuSyQre64gbM9Z6AUA3tVZ2O F9fBZTGKywWzC1O+l9wXR74X1qr7sX7MKlpSq/wI= From: David Ahern To: stephen@networkplumber.org Cc: netdev@vger.kernel.org, David Ahern Subject: [PATCH iproute2-next 6/9] ip route: Export print_rt_flags and print_rta_if Date: Wed, 29 May 2019 20:17:43 -0700 Message-Id: <20190530031746.2040-7-dsahern@kernel.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190530031746.2040-1-dsahern@kernel.org> References: <20190530031746.2040-1-dsahern@kernel.org> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: David Ahern Export print_rt_flags and print_rta_if for use by the nexthop command. Signed-off-by: David Ahern --- ip/ip_common.h | 3 ++- ip/iproute.c | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ip/ip_common.h b/ip/ip_common.h index df279e4f7b9a..1c90770be548 100644 --- a/ip/ip_common.h +++ b/ip/ip_common.h @@ -156,5 +156,6 @@ int name_is_vrf(const char *name); #endif void print_num(FILE *fp, unsigned int width, uint64_t count); - +void print_rt_flags(FILE *fp, unsigned int flags); +void print_rta_if(FILE *fp, const struct rtattr *rta, const char *prefix); #endif /* _IP_COMMON_H_ */ diff --git a/ip/iproute.c b/ip/iproute.c index 440b1fc8b413..c5a473704d95 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -349,7 +349,7 @@ static void print_rtax_features(FILE *fp, unsigned int features) "features", "%#llx ", of); } -static void print_rt_flags(FILE *fp, unsigned int flags) +void print_rt_flags(FILE *fp, unsigned int flags) { open_json_array(PRINT_JSON, is_json_context() ? "flags" : ""); @@ -394,8 +394,7 @@ static void print_rt_pref(FILE *fp, unsigned int pref) } } -static void print_rta_if(FILE *fp, const struct rtattr *rta, - const char *prefix) +void print_rta_if(FILE *fp, const struct rtattr *rta, const char *prefix) { const char *ifname = ll_index_to_name(rta_getattr_u32(rta)); From patchwork Thu May 30 03:17:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 1107529 X-Patchwork-Delegate: dsahern@gmail.com Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.b="0HjltWk1"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45Dv9K6Z8Dz9sSy for ; Thu, 30 May 2019 14:04:37 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731689AbfE3EE3 (ORCPT ); Thu, 30 May 2019 00:04:29 -0400 Received: from mail.kernel.org ([198.145.29.99]:48304 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731284AbfE3DRv (ORCPT ); Wed, 29 May 2019 23:17:51 -0400 Received: from kenny.it.cumulusnetworks.com. (fw.cumulusnetworks.com [216.129.126.126]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 6A1BC24726; Thu, 30 May 2019 03:17:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1559186270; bh=TnAzSjysJjoHjdM1cJsd6M/JgE89A33czrFw+dA8t2Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=0HjltWk1BpbsSydq7B479zqWnalKkuPHxUYL25vrcVxq/L2a2/eE0uhuUwh+Ved0q T3fCp9mNvDUXp/dXq+3Cbh5CBcQqW12em+zbPZrtaqeiz/fVpBktWObIHRUgosKjAV koILXVB7W+MDDyf09EemNQ9EP8oKOx6G8ITaWhCg= From: David Ahern To: stephen@networkplumber.org Cc: netdev@vger.kernel.org, David Ahern Subject: [PATCH iproute2-next 7/9] Add support for nexthop objects Date: Wed, 29 May 2019 20:17:44 -0700 Message-Id: <20190530031746.2040-8-dsahern@kernel.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190530031746.2040-1-dsahern@kernel.org> References: <20190530031746.2040-1-dsahern@kernel.org> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: David Ahern Add nexthop subcommand to ip. Implement basic commands for creating, deleting and dumping nexthop objects. Syntax follows 'nexthop' syntax from existing 'ip route' command. Signed-off-by: David Ahern --- ip/Makefile | 3 +- ip/ip.c | 3 +- ip/ip_common.h | 2 + ip/ipnexthop.c | 571 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 577 insertions(+), 2 deletions(-) create mode 100644 ip/ipnexthop.c diff --git a/ip/Makefile b/ip/Makefile index 7ce6e91a528c..5ab78d7d3b84 100644 --- a/ip/Makefile +++ b/ip/Makefile @@ -10,7 +10,8 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o ipnetns.o \ link_iptnl.o link_gre6.o iplink_bond.o iplink_bond_slave.o iplink_hsr.o \ iplink_bridge.o iplink_bridge_slave.o ipfou.o iplink_ipvlan.o \ iplink_geneve.o iplink_vrf.o iproute_lwtunnel.o ipmacsec.o ipila.o \ - ipvrf.o iplink_xstats.o ipseg6.o iplink_netdevsim.o iplink_rmnet.o + ipvrf.o iplink_xstats.o ipseg6.o iplink_netdevsim.o iplink_rmnet.o \ + ipnexthop.o RTMONOBJ=rtmon.o diff --git a/ip/ip.c b/ip/ip.c index b71ae816e24d..b46fd8dd056c 100644 --- a/ip/ip.c +++ b/ip/ip.c @@ -50,7 +50,7 @@ static void usage(void) "where OBJECT := { link | address | addrlabel | route | rule | neigh | ntable |\n" " tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm |\n" " netns | l2tp | fou | macsec | tcp_metrics | token | netconf | ila |\n" - " vrf | sr }\n" + " vrf | sr | nexthop }\n" " OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n" " -h[uman-readable] | -iec | -j[son] | -p[retty] |\n" " -f[amily] { inet | inet6 | mpls | bridge | link } |\n" @@ -100,6 +100,7 @@ static const struct cmd { { "netconf", do_ipnetconf }, { "vrf", do_ipvrf}, { "sr", do_seg6 }, + { "nexthop", do_ipnh }, { "help", do_help }, { 0 } }; diff --git a/ip/ip_common.h b/ip/ip_common.h index 1c90770be548..5f73247ac488 100644 --- a/ip/ip_common.h +++ b/ip/ip_common.h @@ -47,6 +47,7 @@ int print_prefix(struct nlmsghdr *n, void *arg); int print_rule(struct nlmsghdr *n, void *arg); int print_netconf(struct rtnl_ctrl_data *ctrl, struct nlmsghdr *n, void *arg); +int print_nexthop(struct nlmsghdr *n, void *arg); void netns_map_init(void); void netns_nsid_socket_init(void); int print_nsid(struct nlmsghdr *n, void *arg); @@ -80,6 +81,7 @@ int do_ipvrf(int argc, char **argv); void vrf_reset(void); int netns_identify_pid(const char *pidstr, char *name, int len); int do_seg6(int argc, char **argv); +int do_ipnh(int argc, char **argv); int iplink_get(char *name, __u32 filt_mask); int iplink_ifla_xstats(int argc, char **argv); diff --git a/ip/ipnexthop.c b/ip/ipnexthop.c new file mode 100644 index 000000000000..84c2f01d7309 --- /dev/null +++ b/ip/ipnexthop.c @@ -0,0 +1,571 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ip nexthop + * + * Copyright (c) 2017-19 Cumulus Networks + * Copyright (c) 2017-19 David Ahern + */ + +#include +#include +#include +#include +#include + +#include "utils.h" +#include "ip_common.h" + +static struct +{ + unsigned int flushed; + unsigned int groups; + unsigned int ifindex; + unsigned int master; + char *flushb; + int flushp; + int flushe; +} filter; + +enum { + IPNH_LIST, + IPNH_FLUSH, +}; + +#define RTM_NHA(h) ((struct rtattr *)(((char *)(h)) + \ + NLMSG_ALIGN(sizeof(struct nhmsg)))) + +static void usage(void) __attribute__((noreturn)); + +static void usage(void) +{ + fprintf(stderr, + "Usage: ip nexthop { list | flush } SELECTOR\n" + " ip nexthop get id ID\n" + " ip nexthop { add | replace } NH\n" + " ip nexthop del id ID\n" + "SELECTOR := [ id ID ] [ dev DEV ] [ vrf NAME ] [ master DEV ] [ groups ]\n" + "NH := [ id ID ] [ via [ FAMILY ] ADDRESS ] [ dev DEV ]\n" + " [ group [//...] ] [ NHFLAGS ]\n" + " [ encap ENCAPTYPE ENCAPHDR ]\n" + "NHFLAGS := [ onlink ]\n"); + exit(-1); +} + +static int nh_dump_filter(struct nlmsghdr *nlh, int reqlen) +{ + int err; + + if (filter.ifindex) { + err = addattr32(nlh, reqlen, NHA_OIF, filter.ifindex); + if (err) + return err; + } + + if (filter.groups) { + addattr_l(nlh, reqlen, NHA_GROUPS, NULL, 0); + if (err) + return err; + } + + if (filter.master) { + addattr32(nlh, reqlen, NHA_MASTER, filter.master); + if (err) + return err; + } + + return 0; +} + +struct rtnl_handle rth_del = { .fd = -1 }; + +static int delete_nexthop(__u32 id) +{ + struct { + struct nlmsghdr n; + struct nhmsg nhm; + char buf[64]; + } req = { + .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct nhmsg)), + .n.nlmsg_flags = NLM_F_REQUEST, + .n.nlmsg_type = RTM_DELNEXTHOP, + .nhm.nh_family = AF_UNSPEC, + }; + + req.n.nlmsg_seq = ++rth_del.seq; + + addattr32(&req.n, sizeof(req), NHA_ID, id); + + if (rtnl_talk(&rth_del, &req.n, NULL) < 0) + return -1; + return 0; +} + +static int flush_nexthop(struct nlmsghdr *nlh, void *arg) +{ + struct nhmsg *nhm = NLMSG_DATA(nlh); + struct rtattr *tb[NHA_MAX+1]; + __u32 id = 0; + int len; + + len = nlh->nlmsg_len - NLMSG_SPACE(sizeof(*nhm)); + if (len < 0) { + fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); + return -1; + } + + parse_rtattr(tb, NHA_MAX, RTM_NHA(nhm), len); + if (tb[NHA_ID]) + id = rta_getattr_u32(tb[NHA_ID]); + + if (id && !delete_nexthop(id)) + filter.flushed++; + + return 0; +} + +static int ipnh_flush(unsigned int all) +{ + int rc = -2; + + if (all) { + filter.groups = 1; + filter.ifindex = 0; + filter.master = 0; + } + + if (rtnl_open(&rth_del, 0) < 0) { + fprintf(stderr, "Cannot open rtnetlink\n"); + return EXIT_FAILURE; + } +again: + if (rtnl_nexthopdump_req(&rth, preferred_family, nh_dump_filter) < 0) { + perror("Cannot send dump request"); + goto out; + } + + if (rtnl_dump_filter(&rth, flush_nexthop, stdout) < 0) { + fprintf(stderr, "Dump terminated\n"); + goto out; + } + + /* if deleting all, then remove groups first */ + if (all && filter.groups) { + filter.groups = 0; + goto again; + } + + rc = 0; +out: + rtnl_close(&rth_del); + if (!filter.flushed) + printf("Nothing to flush\n"); + else + printf("Flushed %d nexthops\n", filter.flushed); + + return rc; +} + +static void print_nh_group(FILE *fp, const struct rtattr *grps_attr) +{ + struct nexthop_grp *nhg = RTA_DATA(grps_attr); + int num = RTA_PAYLOAD(grps_attr) / sizeof(*nhg); + int i; + + if (!num || num * sizeof(*nhg) != RTA_PAYLOAD(grps_attr)) { + fprintf(fp, ""); + return; + } + + open_json_array(PRINT_JSON, "group"); + print_string(PRINT_FP, NULL, "%s", "group "); + for (i = 0; i < num; ++i) { + open_json_object(NULL); + + if (i) + print_string(PRINT_FP, NULL, "%s", "/"); + + print_uint(PRINT_ANY, "id", "%u", nhg[i].id); + if (nhg[i].weight) + print_uint(PRINT_ANY, "weight", ",%u", nhg[i].weight); + + close_json_object(); + } + close_json_array(PRINT_JSON, NULL); +} + +static void print_nh_gateway(FILE *fp, const struct nhmsg *nhm, + const struct rtattr *rta) +{ + const char *gateway = format_host_rta(nhm->nh_family, rta); + + if (is_json_context()) + print_string(PRINT_JSON, "gateway", NULL, gateway); + else { + fprintf(fp, "via "); + print_color_string(PRINT_FP, ifa_family_color(nhm->nh_family), + NULL, "%s ", gateway); + } +} + +int print_nexthop(struct nlmsghdr *n, void *arg) +{ + struct nhmsg *nhm = NLMSG_DATA(n); + struct rtattr *tb[NHA_MAX+1]; + FILE *fp = (FILE *)arg; + int len; + + SPRINT_BUF(b1); + + if (n->nlmsg_type != RTM_DELNEXTHOP && + n->nlmsg_type != RTM_NEWNEXTHOP) { + fprintf(stderr, "Not a nexthop: %08x %08x %08x\n", + n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); + return -1; + } + + len = n->nlmsg_len - NLMSG_SPACE(sizeof(*nhm)); + if (len < 0) { + close_json_object(); + fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); + return -1; + } + + parse_rtattr(tb, NHA_MAX, RTM_NHA(nhm), len); + + open_json_object(NULL); + + if (n->nlmsg_type == RTM_DELROUTE) + print_bool(PRINT_ANY, "deleted", "Deleted ", true); + + if (tb[NHA_ID]) + print_uint(PRINT_ANY, "id", "id %u ", + rta_getattr_u32(tb[NHA_ID])); + + if (tb[NHA_GROUP]) + print_nh_group(fp, tb[NHA_GROUP]); + + if (tb[NHA_ENCAP]) + lwt_print_encap(fp, tb[NHA_ENCAP_TYPE], tb[NHA_ENCAP]); + + if (tb[NHA_GATEWAY]) + print_nh_gateway(fp, nhm, tb[NHA_GATEWAY]); + + if (tb[NHA_OIF]) + print_rta_if(fp, tb[NHA_OIF], "dev"); + + if (nhm->nh_scope != RT_SCOPE_UNIVERSE || show_details > 0) { + print_string(PRINT_ANY, "scope", "scope %s ", + rtnl_rtscope_n2a(nhm->nh_scope, b1, sizeof(b1))); + } + + if (tb[NHA_BLACKHOLE]) + print_null(PRINT_ANY, "blackhole", "blackhole", NULL); + + if (nhm->nh_protocol != RTPROT_UNSPEC || show_details > 0) { + print_string(PRINT_ANY, "protocol", "proto %s ", + rtnl_rtprot_n2a(nhm->nh_protocol, b1, sizeof(b1))); + } + + if (tb[NHA_OIF]) + print_rt_flags(fp, nhm->nh_flags); + + print_string(PRINT_FP, NULL, "%s", "\n"); + close_json_object(); + fflush(fp); + + return 0; +} + +static int add_nh_group_attr(struct nlmsghdr *n, int maxlen, char *argv) +{ + struct nexthop_grp *grps; + int count = 0, i; + char *sep, *wsep; + + if (*argv != '\0') + count = 1; + + /* separator is '/' */ + sep = strchr(argv, '/'); + while (sep) { + count++; + sep = strchr(sep + 1, '/'); + } + + if (count == 0) + return -1; + + grps = calloc(count, sizeof(*grps)); + if (!grps) + return -1; + + for (i = 0; i < count; ++i) { + sep = strchr(argv, '/'); + if (sep) + *sep = '\0'; + + wsep = strchr(argv, ','); + if (wsep) + *wsep = '\0'; + + if (get_unsigned(&grps[i].id, argv, 0)) + return -1; + if (wsep) { + unsigned int tmp; + + wsep++; + if (get_unsigned(&tmp, wsep, 0)) + return -1; + if (tmp > 254) + return -1; + grps[i].weight = tmp; + } + + if (!sep) + break; + + argv = sep + 1; + } + + return addattr_l(n, maxlen, NHA_GROUP, grps, count * sizeof(*grps)); +} + +static int ipnh_modify(int cmd, unsigned int flags, int argc, char **argv) +{ + struct { + struct nlmsghdr n; + struct nhmsg nhm; + char buf[1024]; + } req = { + .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct nhmsg)), + .n.nlmsg_flags = NLM_F_REQUEST | flags, + .n.nlmsg_type = cmd, + .nhm.nh_family = preferred_family, + }; + __u32 nh_flags = 0; + + while (argc > 0) { + if (!strcmp(*argv, "id")) { + __u32 id; + + NEXT_ARG(); + if (get_unsigned(&id, *argv, 0)) + invarg("invalid id value", *argv); + addattr32(&req.n, sizeof(req), NHA_ID, id); + } else if (!strcmp(*argv, "dev")) { + int ifindex; + + NEXT_ARG(); + ifindex = ll_name_to_index(*argv); + if (!ifindex) + invarg("Device does not exist\n", *argv); + addattr32(&req.n, sizeof(req), NHA_OIF, ifindex); + if (req.nhm.nh_family == AF_UNSPEC) + req.nhm.nh_family = AF_INET; + } else if (strcmp(*argv, "via") == 0) { + inet_prefix addr; + int family; + + NEXT_ARG(); + family = read_family(*argv); + if (family == AF_UNSPEC) + family = req.nhm.nh_family; + else + NEXT_ARG(); + get_addr(&addr, *argv, family); + if (req.nhm.nh_family == AF_UNSPEC) + req.nhm.nh_family = addr.family; + else if (req.nhm.nh_family != addr.family) + invarg("address family mismatch\n", *argv); + addattr_l(&req.n, sizeof(req), NHA_GATEWAY, + &addr.data, addr.bytelen); + } else if (strcmp(*argv, "encap") == 0) { + char buf[1024]; + struct rtattr *rta = (void *)buf; + + rta->rta_type = NHA_ENCAP; + rta->rta_len = RTA_LENGTH(0); + + lwt_parse_encap(rta, sizeof(buf), &argc, &argv, + NHA_ENCAP, NHA_ENCAP_TYPE); + + if (rta->rta_len > RTA_LENGTH(0)) { + addraw_l(&req.n, 1024, RTA_DATA(rta), + RTA_PAYLOAD(rta)); + } + } else if (!strcmp(*argv, "blackhole")) { + addattr_l(&req.n, sizeof(req), NHA_BLACKHOLE, NULL, 0); + if (req.nhm.nh_family == AF_UNSPEC) + req.nhm.nh_family = AF_INET; + } else if (!strcmp(*argv, "onlink")) { + nh_flags |= RTNH_F_ONLINK; + } else if (!strcmp(*argv, "group")) { + NEXT_ARG(); + + if (add_nh_group_attr(&req.n, sizeof(req), *argv)) + invarg("\"group\" value is invalid\n", *argv); + } else if (strcmp(*argv, "help") == 0) { + usage(); + } else { + invarg("", *argv); + } + argc--; argv++; + } + + req.nhm.nh_flags = nh_flags; + + if (rtnl_talk(&rth, &req.n, NULL) < 0) + return -2; + + return 0; +} + +static int ipnh_get_id(__u32 id) +{ + struct { + struct nlmsghdr n; + struct nhmsg nhm; + char buf[1024]; + } req = { + .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct nhmsg)), + .n.nlmsg_flags = NLM_F_REQUEST, + .n.nlmsg_type = RTM_GETNEXTHOP, + .nhm.nh_family = preferred_family, + }; + struct nlmsghdr *answer; + + addattr32(&req.n, sizeof(req), NHA_ID, id); + + if (rtnl_talk(&rth, &req.n, &answer) < 0) + return -2; + + new_json_obj(json); + + if (print_nexthop(answer, (void *)stdout) < 0) { + free(answer); + return -1; + } + + delete_json_obj(); + fflush(stdout); + + free(answer); + + return 0; +} + +static int ipnh_list_flush(int argc, char **argv, int action) +{ + unsigned int all = (argc == 0); + + while (argc > 0) { + if (!matches(*argv, "dev")) { + NEXT_ARG(); + filter.ifindex = ll_name_to_index(*argv); + if (!filter.ifindex) + invarg("Device does not exist\n", *argv); + } else if (!matches(*argv, "groups")) { + filter.groups = 1; + } else if (!matches(*argv, "master")) { + NEXT_ARG(); + filter.master = ll_name_to_index(*argv); + if (!filter.master) + invarg("Device does not exist\n", *argv); + } else if (matches(*argv, "vrf") == 0) { + NEXT_ARG(); + if (!name_is_vrf(*argv)) + invarg("Invalid VRF\n", *argv); + filter.master = ll_name_to_index(*argv); + if (!filter.master) + invarg("VRF does not exist\n", *argv); + } else if (!strcmp(*argv, "id")) { + __u32 id; + + NEXT_ARG(); + if (get_unsigned(&id, *argv, 0)) + invarg("invalid id value", *argv); + return ipnh_get_id(id); + } else if (matches(*argv, "help") == 0) { + usage(); + } else { + invarg("", *argv); + } + argc--; argv++; + } + + if (action == IPNH_FLUSH) + return ipnh_flush(all); + + if (rtnl_nexthopdump_req(&rth, preferred_family, nh_dump_filter) < 0) { + perror("Cannot send dump request"); + return -2; + } + + new_json_obj(json); + + if (rtnl_dump_filter(&rth, print_nexthop, stdout) < 0) { + fprintf(stderr, "Dump terminated\n"); + return -2; + } + + delete_json_obj(); + fflush(stdout); + + return 0; +} + +static int ipnh_get(int argc, char **argv) +{ + __u32 id = 0; + + while (argc > 0) { + if (!strcmp(*argv, "id")) { + NEXT_ARG(); + if (get_unsigned(&id, *argv, 0)) + invarg("invalid id value", *argv); + } else { + usage(); + } + argc--; argv++; + } + + if (!id) { + usage(); + return -1; + } + + return ipnh_get_id(id); +} + +int do_ipnh(int argc, char **argv) +{ + if (argc < 1) + return ipnh_list_flush(0, NULL, IPNH_LIST); + + if (!matches(*argv, "add")) + return ipnh_modify(RTM_NEWNEXTHOP, NLM_F_CREATE|NLM_F_EXCL, + argc-1, argv+1); + if (!matches(*argv, "replace")) + return ipnh_modify(RTM_NEWNEXTHOP, NLM_F_CREATE|NLM_F_REPLACE, + argc-1, argv+1); + if (!matches(*argv, "delete")) + return ipnh_modify(RTM_DELNEXTHOP, 0, argc-1, argv+1); + + if (!matches(*argv, "list") || + !matches(*argv, "show") || + !matches(*argv, "lst")) + return ipnh_list_flush(argc-1, argv+1, IPNH_LIST); + + if (!matches(*argv, "get")) + return ipnh_get(argc-1, argv+1); + + if (!matches(*argv, "flush")) + return ipnh_list_flush(argc-1, argv+1, IPNH_FLUSH); + + if (!matches(*argv, "help")) + usage(); + + fprintf(stderr, + "Command \"%s\" is unknown, try \"ip nexthop help\".\n", *argv); + exit(-1); +} From patchwork Thu May 30 03:17:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 1107528 X-Patchwork-Delegate: dsahern@gmail.com Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.b="VynfEerp"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45Dv9H1bFqz9sSy for ; Thu, 30 May 2019 14:04:35 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388026AbfE3EEa (ORCPT ); Thu, 30 May 2019 00:04:30 -0400 Received: from mail.kernel.org ([198.145.29.99]:48276 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731289AbfE3DRv (ORCPT ); Wed, 29 May 2019 23:17:51 -0400 Received: from kenny.it.cumulusnetworks.com. (fw.cumulusnetworks.com [216.129.126.126]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id A7D6724718; Thu, 30 May 2019 03:17:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1559186270; bh=QwG3ZJppL2g5avXanItwvvXBW0RsH5H0/GmNgisSARE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VynfEerpG9jX03Z/CklKvjCTw7IWw2d+cnFFahuXYj1MNJuECY9V8ZfeofnI7G2sm fBK8wDvAdP8IPjc8NdNGWjwDRYPBLQTcRi45kbUEx11M2y91+jypng0J0gcmRg81yI T9CxzRY+zy8Ml5lrocZHVh1VBVG2tznSesheFxP4= From: David Ahern To: stephen@networkplumber.org Cc: netdev@vger.kernel.org, David Ahern Subject: [PATCH iproute2-next 8/9] ip route: Add option to use nexthop objects Date: Wed, 29 May 2019 20:17:45 -0700 Message-Id: <20190530031746.2040-9-dsahern@kernel.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190530031746.2040-1-dsahern@kernel.org> References: <20190530031746.2040-1-dsahern@kernel.org> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: David Ahern Add nhid option for routes to use nexthop objects by id. Signed-off-by: David Ahern --- ip/iproute.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/ip/iproute.c b/ip/iproute.c index c5a473704d95..68f7f75f2336 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -80,7 +80,7 @@ static void usage(void) " [ table TABLE_ID ] [ proto RTPROTO ]\n" " [ scope SCOPE ] [ metric METRIC ]\n" " [ ttl-propagate { enabled | disabled } ]\n" - "INFO_SPEC := NH OPTIONS FLAGS [ nexthop NH ]...\n" + "INFO_SPEC := { NH | nhid ID } OPTIONS FLAGS [ nexthop NH ]...\n" "NH := [ encap ENCAPTYPE ENCAPHDR ] [ via [ FAMILY ] ADDRESS ]\n" " [ dev STRING ] [ weight NUMBER ] NHFLAGS\n" "FAMILY := [ inet | inet6 | mpls | bridge | link ]\n" @@ -809,6 +809,10 @@ int print_route(struct nlmsghdr *n, void *arg) print_string(PRINT_ANY, "src", "from %s ", b1); } + if (tb[RTA_NH_ID]) + print_uint(PRINT_ANY, "nhid", "nhid %u ", + rta_getattr_u32(tb[RTA_NH_ID])); + if (tb[RTA_NEWDST]) print_rta_newdst(fp, r, tb[RTA_NEWDST]); @@ -1080,6 +1084,7 @@ static int iproute_modify(int cmd, unsigned int flags, int argc, char **argv) int table_ok = 0; int raw = 0; int type_ok = 0; + __u32 nhid = 0; if (cmd != RTM_DELROUTE) { req.r.rtm_protocol = RTPROT_BOOT; @@ -1358,6 +1363,11 @@ static int iproute_modify(int cmd, unsigned int flags, int argc, char **argv) } else if (strcmp(*argv, "nexthop") == 0) { nhs_ok = 1; break; + } else if (!strcmp(*argv, "nhid")) { + NEXT_ARG(); + if (get_u32(&nhid, *argv, 0)) + invarg("\"id\" value is invalid\n", *argv); + addattr32(&req.n, sizeof(req), RTA_NH_ID, nhid); } else if (matches(*argv, "protocol") == 0) { __u32 prot; @@ -1520,7 +1530,7 @@ static int iproute_modify(int cmd, unsigned int flags, int argc, char **argv) req.r.rtm_type == RTN_UNSPEC) { if (cmd == RTM_DELROUTE) req.r.rtm_scope = RT_SCOPE_NOWHERE; - else if (!gw_ok && !nhs_ok) + else if (!gw_ok && !nhs_ok && !nhid) req.r.rtm_scope = RT_SCOPE_LINK; } } From patchwork Thu May 30 03:17:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 1107527 X-Patchwork-Delegate: dsahern@gmail.com Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.b="UGI3fwQj"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45Dv981L74z9sW1 for ; Thu, 30 May 2019 14:04:28 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731408AbfE3EE1 (ORCPT ); Thu, 30 May 2019 00:04:27 -0400 Received: from mail.kernel.org ([198.145.29.99]:48242 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731296AbfE3DRv (ORCPT ); Wed, 29 May 2019 23:17:51 -0400 Received: from kenny.it.cumulusnetworks.com. (fw.cumulusnetworks.com [216.129.126.126]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id DA9702472C; Thu, 30 May 2019 03:17:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1559186271; bh=q4XWgk94DHiQSOHFmy9YG86ewVtVksqDQpele2P0ixQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UGI3fwQjezdHRGFwPyzqHc+ibHdxfWSktv/ucZRfWvdzy47lsxwxcpMF7khUEs49Z 23Kt2h0QwIeXE0xazoLl468lCkE1WvM3EuAMQycakC80MNC8HCfq6JjGVDqX3p1h1+ GSnvcTILpUAGeAPrKjErUVb9ykQfrVzyQeubCd3M= From: David Ahern To: stephen@networkplumber.org Cc: netdev@vger.kernel.org, David Ahern Subject: [PATCH iproute2-next 9/9] ipmonitor: Add nexthop option to monitor Date: Wed, 29 May 2019 20:17:46 -0700 Message-Id: <20190530031746.2040-10-dsahern@kernel.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190530031746.2040-1-dsahern@kernel.org> References: <20190530031746.2040-1-dsahern@kernel.org> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: David Ahern Add capability to ip-monitor to listen and dump nexthop messages Signed-off-by: David Ahern --- ip/ipmonitor.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/ip/ipmonitor.c b/ip/ipmonitor.c index 9ecc7fd2011a..5da1256450b3 100644 --- a/ip/ipmonitor.c +++ b/ip/ipmonitor.c @@ -84,6 +84,12 @@ static int accept_msg(struct rtnl_ctrl_data *ctrl, } } + case RTM_NEWNEXTHOP: + case RTM_DELNEXTHOP: + print_headers(fp, "[NEXTHOP]", ctrl); + print_nexthop(n, arg); + return 0; + case RTM_NEWLINK: case RTM_DELLINK: ll_remember_index(n, NULL); @@ -173,6 +179,7 @@ int do_ipmonitor(int argc, char **argv) int lrule = 0; int lnsid = 0; int ifindex = 0; + int lnexthop = 1; groups |= nl_mgrp(RTNLGRP_LINK); groups |= nl_mgrp(RTNLGRP_IPV4_IFADDR); @@ -202,30 +209,42 @@ int do_ipmonitor(int argc, char **argv) } else if (matches(*argv, "link") == 0) { llink = 1; groups = 0; + lnexthop = 0; } else if (matches(*argv, "address") == 0) { laddr = 1; groups = 0; + lnexthop = 0; } else if (matches(*argv, "route") == 0) { lroute = 1; groups = 0; + lnexthop = 0; } else if (matches(*argv, "mroute") == 0) { lmroute = 1; groups = 0; + lnexthop = 0; } else if (matches(*argv, "prefix") == 0) { lprefix = 1; groups = 0; + lnexthop = 0; } else if (matches(*argv, "neigh") == 0) { lneigh = 1; groups = 0; + lnexthop = 0; } else if (matches(*argv, "netconf") == 0) { lnetconf = 1; groups = 0; + lnexthop = 0; } else if (matches(*argv, "rule") == 0) { lrule = 1; groups = 0; + lnexthop = 0; } else if (matches(*argv, "nsid") == 0) { lnsid = 1; groups = 0; + lnexthop = 0; + } else if (matches(*argv, "nexthop") == 0) { + groups = 0; + lnexthop = 1; } else if (strcmp(*argv, "all") == 0) { prefix_banner = 1; } else if (matches(*argv, "all-nsid") == 0) { @@ -313,6 +332,11 @@ int do_ipmonitor(int argc, char **argv) if (rtnl_open(&rth, groups) < 0) exit(1); + if (lnexthop && rtnl_add_nl_group(&rth, RTNLGRP_NEXTHOP) < 0) { + fprintf(stderr, "Failed to add nexthop group to list\n"); + exit(1); + } + if (listen_all_nsid && rtnl_listen_all_nsid(&rth) < 0) exit(1);