]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - include/net/vrf.h
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
[mirror_ubuntu-artful-kernel.git] / include / net / vrf.h
1 /*
2 * include/net/net_vrf.h - adds vrf dev structure definitions
3 * Copyright (c) 2015 Cumulus Networks
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10
11 #ifndef __LINUX_NET_VRF_H
12 #define __LINUX_NET_VRF_H
13
14 struct net_vrf_dev {
15 struct rcu_head rcu;
16 int ifindex; /* ifindex of master dev */
17 u32 tb_id; /* table id for VRF */
18 };
19
20 struct slave {
21 struct list_head list;
22 struct net_device *dev;
23 };
24
25 struct slave_queue {
26 struct list_head all_slaves;
27 };
28
29 struct net_vrf {
30 struct slave_queue queue;
31 struct rtable *rth;
32 u32 tb_id;
33 };
34
35
36 #if IS_ENABLED(CONFIG_NET_VRF)
37 /* called with rcu_read_lock() */
38 static inline int vrf_master_ifindex_rcu(const struct net_device *dev)
39 {
40 struct net_vrf_dev *vrf_ptr;
41 int ifindex = 0;
42
43 if (!dev)
44 return 0;
45
46 if (netif_is_vrf(dev)) {
47 ifindex = dev->ifindex;
48 } else {
49 vrf_ptr = rcu_dereference(dev->vrf_ptr);
50 if (vrf_ptr)
51 ifindex = vrf_ptr->ifindex;
52 }
53
54 return ifindex;
55 }
56
57 static inline int vrf_master_ifindex(const struct net_device *dev)
58 {
59 int ifindex;
60
61 rcu_read_lock();
62 ifindex = vrf_master_ifindex_rcu(dev);
63 rcu_read_unlock();
64
65 return ifindex;
66 }
67
68 /* called with rcu_read_lock */
69 static inline u32 vrf_dev_table_rcu(const struct net_device *dev)
70 {
71 u32 tb_id = 0;
72
73 if (dev) {
74 struct net_vrf_dev *vrf_ptr;
75
76 vrf_ptr = rcu_dereference(dev->vrf_ptr);
77 if (vrf_ptr)
78 tb_id = vrf_ptr->tb_id;
79 }
80 return tb_id;
81 }
82
83 static inline u32 vrf_dev_table(const struct net_device *dev)
84 {
85 u32 tb_id;
86
87 rcu_read_lock();
88 tb_id = vrf_dev_table_rcu(dev);
89 rcu_read_unlock();
90
91 return tb_id;
92 }
93
94 static inline u32 vrf_dev_table_ifindex(struct net *net, int ifindex)
95 {
96 struct net_device *dev;
97 u32 tb_id = 0;
98
99 if (!ifindex)
100 return 0;
101
102 rcu_read_lock();
103
104 dev = dev_get_by_index_rcu(net, ifindex);
105 if (dev)
106 tb_id = vrf_dev_table_rcu(dev);
107
108 rcu_read_unlock();
109
110 return tb_id;
111 }
112
113 /* called with rtnl */
114 static inline u32 vrf_dev_table_rtnl(const struct net_device *dev)
115 {
116 u32 tb_id = 0;
117
118 if (dev) {
119 struct net_vrf_dev *vrf_ptr;
120
121 vrf_ptr = rtnl_dereference(dev->vrf_ptr);
122 if (vrf_ptr)
123 tb_id = vrf_ptr->tb_id;
124 }
125 return tb_id;
126 }
127
128 /* caller has already checked netif_is_vrf(dev) */
129 static inline struct rtable *vrf_dev_get_rth(const struct net_device *dev)
130 {
131 struct rtable *rth = ERR_PTR(-ENETUNREACH);
132 struct net_vrf *vrf = netdev_priv(dev);
133
134 if (vrf) {
135 rth = vrf->rth;
136 atomic_inc(&rth->dst.__refcnt);
137 }
138 return rth;
139 }
140
141 #else
142 static inline int vrf_master_ifindex_rcu(const struct net_device *dev)
143 {
144 return 0;
145 }
146
147 static inline int vrf_master_ifindex(const struct net_device *dev)
148 {
149 return 0;
150 }
151
152 static inline u32 vrf_dev_table_rcu(const struct net_device *dev)
153 {
154 return 0;
155 }
156
157 static inline u32 vrf_dev_table(const struct net_device *dev)
158 {
159 return 0;
160 }
161
162 static inline u32 vrf_dev_table_ifindex(struct net *net, int ifindex)
163 {
164 return 0;
165 }
166
167 static inline u32 vrf_dev_table_rtnl(const struct net_device *dev)
168 {
169 return 0;
170 }
171
172 static inline struct rtable *vrf_dev_get_rth(const struct net_device *dev)
173 {
174 return ERR_PTR(-ENETUNREACH);
175 }
176 #endif
177
178 #endif /* __LINUX_NET_VRF_H */