summaryrefslogtreecommitdiff
path: root/include/net/vrf.h
diff options
context:
space:
mode:
authorDavid Ahern <dsa@cumulusnetworks.com>2015-08-13 23:59:00 +0300
committerDavid S. Miller <davem@davemloft.net>2015-08-14 08:43:20 +0300
commit4e3c89920cd3a6cfce22c6f537690747c26128dd (patch)
tree80bdaa774217b466eb1014b601c24141ac5e2827 /include/net/vrf.h
parent0344338bd883e5e4a2f80409ed8260cd65d69e3b (diff)
downloadlinux-4e3c89920cd3a6cfce22c6f537690747c26128dd.tar.xz
net: Introduce VRF related flags and helpers
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 <shm@cumulusnetworks.com> Signed-off-by: David Ahern <dsa@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/vrf.h')
-rw-r--r--include/net/vrf.h139
1 files changed, 139 insertions, 0 deletions
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 */