From patchwork Thu Aug 13 20:59:00 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 507188 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 4F129140328 for ; Fri, 14 Aug 2015 07:01:02 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=cumulusnetworks.com header.i=@cumulusnetworks.com header.b=ErOQ2lFh; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754185AbbHMU74 (ORCPT ); Thu, 13 Aug 2015 16:59:56 -0400 Received: from mail-io0-f180.google.com ([209.85.223.180]:33200 "EHLO mail-io0-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932090AbbHMU7w (ORCPT ); Thu, 13 Aug 2015 16:59:52 -0400 Received: by iods203 with SMTP id s203so65575246iod.0 for ; Thu, 13 Aug 2015 13:59:51 -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=/rzYCXzAeyRfLi3JYuhPft1h3y/rjZInVHu8EpGXj2A=; b=ErOQ2lFhPqX11sNZldBoPhhELBNGE5V41W0Wjnp+luOSFyuS9cFV2hw6LfU3sgzwGV vNZsRNvXNSfexcNmGavOnuBgSknJZBVRh6xLGuW7Qk3JWNZTzIAXVA5rV50At1z+1PkG AQEl2FvGeTp0Aarng/Y4UKyhloESxeijO3o58= 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=/rzYCXzAeyRfLi3JYuhPft1h3y/rjZInVHu8EpGXj2A=; b=RUTLCPf9x1KR+nydPU52EpH+ataTrT6l08jXxA8yPtiMxX10CdwcvbyqDTJNmQW0V4 0GqiK4MJtg6hE8Ad8lbZb3v3cPzirNCM0AFWI69KvBWu3gNzCyck+Ivb635qy/6hRjr7 KK3wTe0Nu6Vxt0IrKPzs0hYQxa3SJzP5ePpy95zke+dP1l9CvawS/2SoGtlHag17R33P jSnPRAfM+FnpsAMi0g8ruybeczeV3Zn4gIOTOFw87Y7GUnuy7qtrxZgzPALyJyKmW0ZP 1hyGNDsWdZ88SgZ4Iz7VW3TUpkM5ApQYc0A9AcQEgAhlao1Fe4nALGriz0GTabi8rVLZ vZxg== X-Gm-Message-State: ALoCoQmwLMD7fluERoL7ln6IWalO+9ve2FLLgvJLp3/60LCkIbQbM5Fk4448ROglemwIgDGPfdbQ X-Received: by 10.107.164.82 with SMTP id n79mr43690143ioe.88.1439499591145; Thu, 13 Aug 2015 13:59:51 -0700 (PDT) Received: from localhost.localdomain (c-174-51-80-140.hsd1.co.comcast.net. [174.51.80.140]) by smtp.googlemail.com with ESMTPSA id l14sm2284155ioe.35.2015.08.13.13.59.48 (version=TLSv1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 13 Aug 2015 13:59:50 -0700 (PDT) From: David Ahern To: netdev@vger.kernel.org Cc: shm@cumulusnetworks.com, roopa@cumulusnetworks.com, gospo@cumulusnetworks.com, jtoppins@cumulusnetworks.com, nikolay@cumulusnetworks.com, ddutt@cumulusnetworks.com, hannes@stressinduktion.org, nicolas.dichtel@6wind.com, stephen@networkplumber.org, hadi@mojatatu.com, ebiederm@xmission.com, davem@davemloft.net, svaidya@brocade.com, David Ahern Subject: [PATCH net-next 01/11] net: Introduce VRF related flags and helpers Date: Thu, 13 Aug 2015 14:59:00 -0600 Message-Id: <1439499551-90231-2-git-send-email-dsa@cumulusnetworks.com> X-Mailer: git-send-email 2.3.2 (Apple Git-55) In-Reply-To: <1439499551-90231-1-git-send-email-dsa@cumulusnetworks.com> References: <1439499551-90231-1-git-send-email-dsa@cumulusnetworks.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add a VRF_MASTER flag for interfaces and helper functions for determining if a device is a VRF_MASTER. Add link attribute for passing VRF_TABLE id. Add vrf_ptr to netdevice. Add various macros for determining if a device is a VRF device, the index of the master VRF device and table associated with VRF device. Signed-off-by: Shrijeet Mukherjee Signed-off-by: David Ahern --- include/linux/netdevice.h | 20 +++++++ include/net/vrf.h | 139 +++++++++++++++++++++++++++++++++++++++++++ include/uapi/linux/if_link.h | 9 +++ 3 files changed, 168 insertions(+) create mode 100644 include/net/vrf.h diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 607b5f41f46f..f7a6ef2fae3a 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1289,6 +1289,7 @@ enum netdev_priv_flags { IFF_XMIT_DST_RELEASE_PERM = 1<<22, IFF_IPVLAN_MASTER = 1<<23, IFF_IPVLAN_SLAVE = 1<<24, + IFF_VRF_MASTER = 1<<25, }; #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN @@ -1316,6 +1317,7 @@ enum netdev_priv_flags { #define IFF_XMIT_DST_RELEASE_PERM IFF_XMIT_DST_RELEASE_PERM #define IFF_IPVLAN_MASTER IFF_IPVLAN_MASTER #define IFF_IPVLAN_SLAVE IFF_IPVLAN_SLAVE +#define IFF_VRF_MASTER IFF_VRF_MASTER /** * struct net_device - The DEVICE structure. @@ -1432,6 +1434,7 @@ enum netdev_priv_flags { * @dn_ptr: DECnet specific data * @ip6_ptr: IPv6 specific data * @ax25_ptr: AX.25 specific data + * @vrf_ptr: VRF specific data * @ieee80211_ptr: IEEE 802.11 specific data, assign before registering * * @last_rx: Time of last Rx @@ -1650,6 +1653,7 @@ struct net_device { struct dn_dev __rcu *dn_ptr; struct inet6_dev __rcu *ip6_ptr; void *ax25_ptr; + struct net_vrf_dev __rcu *vrf_ptr; struct wireless_dev *ieee80211_ptr; struct wpan_dev *ieee802154_ptr; #if IS_ENABLED(CONFIG_MPLS_ROUTING) @@ -3808,6 +3812,22 @@ static inline bool netif_supports_nofcs(struct net_device *dev) return dev->priv_flags & IFF_SUPP_NOFCS; } +static inline bool netif_is_vrf(const struct net_device *dev) +{ + return dev->priv_flags & IFF_VRF_MASTER; +} + +static inline bool netif_index_is_vrf(struct net *net, int ifindex) +{ + struct net_device *dev = dev_get_by_index_rcu(net, ifindex); + bool rc = false; + + if (dev) + rc = netif_is_vrf(dev); + + return rc; +} + /* This device needs to keep skb dst for qdisc enqueue or ndo_start_xmit() */ static inline void netif_keep_dst(struct net_device *dev) { diff --git a/include/net/vrf.h b/include/net/vrf.h new file mode 100644 index 000000000000..0484d29d4589 --- /dev/null +++ b/include/net/vrf.h @@ -0,0 +1,139 @@ +/* + * include/net/net_vrf.h - adds vrf dev structure definitions + * Copyright (c) 2015 Cumulus Networks + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __LINUX_NET_VRF_H +#define __LINUX_NET_VRF_H + +struct net_vrf_dev { + struct rcu_head rcu; + int ifindex; /* ifindex of master dev */ + u32 tb_id; /* table id for VRF */ +}; + +struct slave { + struct list_head list; + struct net_device *dev; +}; + +struct slave_queue { + struct list_head all_slaves; + int num_slaves; +}; + +struct net_vrf { + struct slave_queue queue; + struct rtable *rth; + u32 tb_id; +}; + + +#if IS_ENABLED(CONFIG_NET_VRF) +/* called with rcu_read_lock() */ +static inline int vrf_master_ifindex_rcu(const struct net_device *dev) +{ + struct net_vrf_dev *vrf_ptr; + int ifindex = 0; + + if (!dev) + return 0; + + if (netif_is_vrf(dev)) + ifindex = dev->ifindex; + else { + vrf_ptr = rcu_dereference(dev->vrf_ptr); + if (vrf_ptr) + ifindex = vrf_ptr->ifindex; + } + + return ifindex; +} + +/* called with rcu_read_lock */ +static inline int vrf_dev_table_rcu(const struct net_device *dev) +{ + int tb_id = 0; + + if (dev) { + struct net_vrf_dev *vrf_ptr; + + vrf_ptr = rcu_dereference(dev->vrf_ptr); + if (vrf_ptr) + tb_id = vrf_ptr->tb_id; + } + return tb_id; +} + +static inline int vrf_dev_table(const struct net_device *dev) +{ + int tb_id; + + rcu_read_lock(); + tb_id = vrf_dev_table_rcu(dev); + rcu_read_unlock(); + + return tb_id; +} + +/* called with rtnl */ +static inline int vrf_dev_table_rtnl(const struct net_device *dev) +{ + int tb_id = 0; + + if (dev) { + struct net_vrf_dev *vrf_ptr; + + vrf_ptr = rtnl_dereference(dev->vrf_ptr); + if (vrf_ptr) + tb_id = vrf_ptr->tb_id; + } + return tb_id; +} + +/* caller has already checked netif_is_vrf(dev) */ +static inline struct rtable *vrf_dev_get_rth(const struct net_device *dev) +{ + struct rtable *rth = ERR_PTR(-ENETUNREACH); + struct net_vrf *vrf = netdev_priv(dev); + + if (vrf) { + rth = vrf->rth; + atomic_inc(&rth->dst.__refcnt); + } + return rth; +} + +#else +static inline int vrf_master_ifindex_rcu(const struct net_device *dev) +{ + return 0; +} + +static inline int vrf_dev_table_rcu(const struct net_device *dev) +{ + return 0; +} + +static inline int vrf_dev_table(const struct net_device *dev) +{ + return 0; +} + +static inline int vrf_dev_table_rtnl(const struct net_device *dev) +{ + return 0; +} + +static inline struct rtable *vrf_dev_get_rth(const struct net_device *dev) +{ + return ERR_PTR(-ENETUNREACH); +} +#endif + +#endif /* __LINUX_NET_VRF_H */ diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index d450be36add2..313c305fd1ad 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -341,6 +341,15 @@ enum macvlan_macaddr_mode { #define MACVLAN_FLAG_NOPROMISC 1 +/* VRF section */ +enum { + IFLA_VRF_UNSPEC, + IFLA_VRF_TABLE, + __IFLA_VRF_MAX +}; + +#define IFLA_VRF_MAX (__IFLA_VRF_MAX - 1) + /* IPVLAN section */ enum { IFLA_IPVLAN_UNSPEC,