From patchwork Tue May 9 12:44:39 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Markstrom X-Patchwork-Id: 760100 X-Patchwork-Delegate: shemminger@vyatta.com 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 3wMfHb251Hz9s75 for ; Tue, 9 May 2017 22:46:03 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="vD8oGNGK"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754076AbdEIMpd (ORCPT ); Tue, 9 May 2017 08:45:33 -0400 Received: from mail-qt0-f195.google.com ([209.85.216.195]:34105 "EHLO mail-qt0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753963AbdEIMpa (ORCPT ); Tue, 9 May 2017 08:45:30 -0400 Received: by mail-qt0-f195.google.com with SMTP id l39so13580856qtb.1; Tue, 09 May 2017 05:45:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=01UDJF87SX6NmV+5FEBo1F4K17/D5d73CuncMuTv9NQ=; b=vD8oGNGKyVmioq/1fAHtysMEGW0lUm5UOcV/ynzHse5J9iy4tEbL1Pgics/Hkh+/py Wzkh6KzWdVPB0eZ0Hix01NOqeW2EXXtb19cfne3Lrgh8A9qy7fA2pWh0iFgE4NagwANO aHKaoM2WD5yDJpm2JisbbmwfWk8gZjLIbnlngB3CL9zIZnOtO5FXzU2yQgxFmLqdF0fj rG7qM3esI/ItZ196m+W3n47Wi9jVHLjPSmwRYv3ppfuKEy96JYufuMnIIQaUxVlixWC6 Xe5CeXd9ucnvmAHsMrVXbNGa0C50TRuImLlCphhdW3sPr/mW2q1dsczQHKzHu3KBhhN1 VmVQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=01UDJF87SX6NmV+5FEBo1F4K17/D5d73CuncMuTv9NQ=; b=gwoeplbqAIztJaEcb9tF8jwowUoYkwItPZkUqr0NBx+TnibHGEaJ93MrtgKEiDRBCW LYi9HT0xE72J5+3p7V4oqXg2ixhh7K4ogQ+TEOPZHNMjCmz5gwlHqIuYq/VGzwo20ONR 6Qhy5lJTJWjt79SGGTCBNORIOS2ewpi48OdSS+CUme7aZcA6cmmnjE/RxyMUQ7fDOx+r GUZgQZuVK9bqLtQcuEWvs6RVo52pqf+pJUDZVkmBMVPifjwo2kyPXt/rI9b/IH8/27rY wgtyb4mmvWcZCkEuEYRyAvmA5TtgWsGvtFO7ViyYM/wj+n5B7rtnXW0tiI50RLe5OVZT tVUw== X-Gm-Message-State: AODbwcC4GtAltDdfHYV2k3QJ6IUpuVoke+5TF6jAVJ/Fr85KWx+qQU5k 12iOArphv3PNmA== X-Received: by 10.46.1.225 with SMTP id f94mr8964317lji.73.1494333924356; Tue, 09 May 2017 05:45:24 -0700 (PDT) Received: from arn-build3.wrs.com (62-20-3-162.customer.telia.com. [62.20.3.162]) by smtp.gmail.com with ESMTPSA id 34sm1542204lfp.1.2017.05.09.05.45.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 09 May 2017 05:45:23 -0700 (PDT) From: Fredrik Markstrom To: Eric Dumazet Cc: "David S. Miller" , Stephen Hemminger , Alexei Starovoitov , Daniel Borkmann , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, bridge@lists.linux-foundation.org, Fredrik Markstrom Subject: Support for VETH_MRU in libnl Date: Tue, 9 May 2017 14:44:39 +0200 Message-Id: <20170509124439.45674-4-fredrik.markstrom@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170509124439.45674-1-fredrik.markstrom@gmail.com> References: <20170509124439.45674-1-fredrik.markstrom@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org --- include/linux/if_link.h | 1 + include/netlink-private/types.h | 1 + include/netlink/route/link/veth.h | 4 ++ lib/route/link.c | 4 ++ lib/route/link/veth.c | 141 +++++++++++++++++++++++++++++--------- 5 files changed, 118 insertions(+), 33 deletions(-) diff --git a/include/linux/if_link.h b/include/linux/if_link.h index 8b84939..b9859bd 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h @@ -316,6 +316,7 @@ struct ifla_vxlan_port_range { enum { VETH_INFO_UNSPEC, VETH_INFO_PEER, + VETH_MRU, __VETH_INFO_MAX #define VETH_INFO_MAX (__VETH_INFO_MAX - 1) diff --git a/include/netlink-private/types.h b/include/netlink-private/types.h index 3ff4fe1..c97090b 100644 --- a/include/netlink-private/types.h +++ b/include/netlink-private/types.h @@ -165,6 +165,7 @@ struct rtnl_link uint32_t l_flags; uint32_t l_change; uint32_t l_mtu; + uint32_t l_mru; uint32_t l_link; uint32_t l_txqlen; uint32_t l_weight; diff --git a/include/netlink/route/link/veth.h b/include/netlink/route/link/veth.h index 35c2345..58eeb98 100644 --- a/include/netlink/route/link/veth.h +++ b/include/netlink/route/link/veth.h @@ -29,6 +29,10 @@ extern struct rtnl_link *rtnl_link_veth_get_peer(struct rtnl_link *); extern int rtnl_link_veth_add(struct nl_sock *sock, const char *name, const char *peer, pid_t pid); +extern int rtnl_link_veth_set_mru(struct rtnl_link *, uint32_t); + +extern uint32_t rtnl_link_veth_get_mru(struct rtnl_link *); + #ifdef __cplusplus } #endif diff --git a/lib/route/link.c b/lib/route/link.c index 3d31ffc..3cdacbb 100644 --- a/lib/route/link.c +++ b/lib/route/link.c @@ -61,6 +61,7 @@ #define LINK_ATTR_PHYS_PORT_ID (1 << 28) #define LINK_ATTR_NS_FD (1 << 29) #define LINK_ATTR_NS_PID (1 << 30) +#define LINK_ATTR_MRU (1 << 31) static struct nl_cache_ops rtnl_link_ops; static struct nl_object_ops link_obj_ops; @@ -1255,6 +1256,9 @@ int rtnl_link_fill_info(struct nl_msg *msg, struct rtnl_link *link) if (link->ce_mask & LINK_ATTR_MTU) NLA_PUT_U32(msg, IFLA_MTU, link->l_mtu); + if (link->ce_mask & LINK_ATTR_MRU) + NLA_PUT_U32(msg, IFLA_MTU, link->l_mru); + if (link->ce_mask & LINK_ATTR_TXQLEN) NLA_PUT_U32(msg, IFLA_TXQLEN, link->l_txqlen); diff --git a/lib/route/link/veth.c b/lib/route/link/veth.c index e7e4a26..5dc15af 100644 --- a/lib/route/link/veth.c +++ b/lib/route/link/veth.c @@ -33,16 +33,62 @@ #include +#define VETH_HAS_MRU (1<<0) + +struct veth_info +{ + struct rtnl_link *peer; + uint32_t vei_mru; + uint32_t vei_mask; +}; + static struct nla_policy veth_policy[VETH_INFO_MAX+1] = { [VETH_INFO_PEER] = { .minlen = sizeof(struct ifinfomsg) }, + [VETH_MRU] = { .type = NLA_U32 }, }; +static int veth_alloc(struct rtnl_link *link) +{ + struct rtnl_link *peer; + struct veth_info *vei = link->l_info; + int err; + + /* return early if we are in recursion */ + if (vei && vei->peer) + return 0; + + if (!(peer = rtnl_link_alloc())) + return -NLE_NOMEM; + + if ((vei = calloc(1, sizeof(*vei))) == NULL) + return -NLE_NOMEM; + + /* We don't need to hold a reference here, as link and + * its peer should always be freed together. + */ + vei->peer = link; + + peer->l_info = vei; + if ((err = rtnl_link_set_type(peer, "veth")) < 0) { + rtnl_link_put(peer); + return err; + } + + if ((vei = calloc(1, sizeof(*vei))) == NULL) + return -NLE_NOMEM; + + vei->peer = peer; + link->l_info = vei; + return 0; +} + static int veth_parse(struct rtnl_link *link, struct nlattr *data, struct nlattr *xstats) { struct nlattr *tb[VETH_INFO_MAX+1]; struct nlattr *peer_tb[IFLA_MAX + 1]; - struct rtnl_link *peer = link->l_info; + struct veth_info *vei = link->l_info; + struct rtnl_link *peer = vei->peer; int err; NL_DBG(3, "Parsing veth link info"); @@ -50,6 +96,14 @@ static int veth_parse(struct rtnl_link *link, struct nlattr *data, if ((err = nla_parse_nested(tb, VETH_INFO_MAX, data, veth_policy)) < 0) goto errout; + if ((err = veth_alloc(link)) < 0) + goto errout; + + if (tb[VETH_MRU]) { + vei->vei_mru = nla_get_u32(tb[VETH_MRU]); + vei->vei_mask |= VETH_HAS_MRU; + } + if (tb[VETH_INFO_PEER]) { struct nlattr *nla_peer; struct ifinfomsg *ifi; @@ -86,7 +140,8 @@ static void veth_dump_line(struct rtnl_link *link, struct nl_dump_params *p) static void veth_dump_details(struct rtnl_link *link, struct nl_dump_params *p) { - struct rtnl_link *peer = link->l_info; + struct veth_info *vei = link->l_info; + struct rtnl_link *peer = vei->peer; char *name; name = rtnl_link_get_name(peer); nl_dump(p, " peer "); @@ -98,7 +153,14 @@ static void veth_dump_details(struct rtnl_link *link, struct nl_dump_params *p) static int veth_clone(struct rtnl_link *dst, struct rtnl_link *src) { - struct rtnl_link *dst_peer = NULL, *src_peer = src->l_info; + struct veth_info *src_vei = src->l_info; + struct veth_info *dst_vei = dst->l_info; + struct rtnl_link *dst_peer = NULL, *src_peer = src_vei->peer; + + + printf("veth_clone not implemented\n"); + + // FIXME: /* we are calling nl_object_clone() recursively, this should * happen only once */ @@ -116,7 +178,8 @@ static int veth_clone(struct rtnl_link *dst, struct rtnl_link *src) static int veth_put_attrs(struct nl_msg *msg, struct rtnl_link *link) { - struct rtnl_link *peer = link->l_info; + struct veth_info *vei = link->l_info; + struct rtnl_link *peer = vei->peer; struct ifinfomsg ifi; struct nlattr *data, *info_peer; @@ -135,44 +198,31 @@ static int veth_put_attrs(struct nl_msg *msg, struct rtnl_link *link) return -NLE_MSGSIZE; rtnl_link_fill_info(msg, peer); nla_nest_end(msg, info_peer); - nla_nest_end(msg, data); - return 0; -} - -static int veth_alloc(struct rtnl_link *link) -{ - struct rtnl_link *peer; - int err; - - /* return early if we are in recursion */ - if (link->l_info) - return 0; + if (vei->vei_mask & VETH_HAS_MRU) + NLA_PUT_U32(msg, VETH_MRU, vei->vei_mru); - if (!(peer = rtnl_link_alloc())) - return -NLE_NOMEM; + nla_nest_end(msg, data); - /* We don't need to hold a reference here, as link and - * its peer should always be freed together. - */ - peer->l_info = link; - if ((err = rtnl_link_set_type(peer, "veth")) < 0) { - rtnl_link_put(peer); - return err; - } +nla_put_failure: - link->l_info = peer; return 0; } static void veth_free(struct rtnl_link *link) { - struct rtnl_link *peer = link->l_info; - if (peer) { + struct veth_info *vei = link->l_info; + if (vei) { + struct rtnl_link *peer = vei->peer; + if (peer) { + vei->peer = NULL; + rtnl_link_put(peer); + /* avoid calling this recursively */ + free(peer->l_info); + peer->l_info = NULL; + } + free(vei); link->l_info = NULL; - /* avoid calling this recursively */ - peer->l_info = NULL; - rtnl_link_put(peer); } /* the caller should finally free link */ } @@ -195,7 +245,7 @@ static struct rtnl_link_info_ops veth_info_ops = { #define IS_VETH_LINK_ASSERT(link) \ if ((link)->l_info_ops != &veth_info_ops) { \ APPBUG("Link is not a veth link. set type \"veth\" first."); \ - return NULL; \ + return -NLE_OPNOTSUPP; \ } /** @endcond */ @@ -293,6 +343,31 @@ int rtnl_link_veth_add(struct nl_sock *sock, const char *name, return err; } +int rtnl_link_veth_set_mru(struct rtnl_link *link, uint32_t mru) +{ + struct veth_info *vei = link->l_info; + + IS_VETH_LINK_ASSERT(link); + + vei->vei_mru = mru; + vei->vei_mask |= VETH_HAS_MRU; + + return 0; +} + +uint32_t rtnl_link_veth_get_mru(struct rtnl_link *link) +{ + struct veth_info *vei = link->l_info; + + IS_VETH_LINK_ASSERT(link); + + if (vei->vei_mask & VETH_HAS_MRU) + return vei->vei_mru; + else + return 0; +} + + /** @} */ static void __init veth_init(void)