Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetoot...
[firefly-linux-kernel-4.4.55.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         int                     num_slaves;
28 };
29
30 struct net_vrf {
31         struct slave_queue      queue;
32         struct rtable           *rth;
33         u32                     tb_id;
34 };
35
36
37 #if IS_ENABLED(CONFIG_NET_VRF)
38 /* called with rcu_read_lock() */
39 static inline int vrf_master_ifindex_rcu(const struct net_device *dev)
40 {
41         struct net_vrf_dev *vrf_ptr;
42         int ifindex = 0;
43
44         if (!dev)
45                 return 0;
46
47         if (netif_is_vrf(dev))
48                 ifindex = dev->ifindex;
49         else {
50                 vrf_ptr = rcu_dereference(dev->vrf_ptr);
51                 if (vrf_ptr)
52                         ifindex = vrf_ptr->ifindex;
53         }
54
55         return ifindex;
56 }
57
58 /* called with rcu_read_lock */
59 static inline int vrf_dev_table_rcu(const struct net_device *dev)
60 {
61         int tb_id = 0;
62
63         if (dev) {
64                 struct net_vrf_dev *vrf_ptr;
65
66                 vrf_ptr = rcu_dereference(dev->vrf_ptr);
67                 if (vrf_ptr)
68                         tb_id = vrf_ptr->tb_id;
69         }
70         return tb_id;
71 }
72
73 static inline int vrf_dev_table(const struct net_device *dev)
74 {
75         int tb_id;
76
77         rcu_read_lock();
78         tb_id = vrf_dev_table_rcu(dev);
79         rcu_read_unlock();
80
81         return tb_id;
82 }
83
84 /* called with rtnl */
85 static inline int vrf_dev_table_rtnl(const struct net_device *dev)
86 {
87         int tb_id = 0;
88
89         if (dev) {
90                 struct net_vrf_dev *vrf_ptr;
91
92                 vrf_ptr = rtnl_dereference(dev->vrf_ptr);
93                 if (vrf_ptr)
94                         tb_id = vrf_ptr->tb_id;
95         }
96         return tb_id;
97 }
98
99 /* caller has already checked netif_is_vrf(dev) */
100 static inline struct rtable *vrf_dev_get_rth(const struct net_device *dev)
101 {
102         struct rtable *rth = ERR_PTR(-ENETUNREACH);
103         struct net_vrf *vrf = netdev_priv(dev);
104
105         if (vrf) {
106                 rth = vrf->rth;
107                 atomic_inc(&rth->dst.__refcnt);
108         }
109         return rth;
110 }
111
112 #else
113 static inline int vrf_master_ifindex_rcu(const struct net_device *dev)
114 {
115         return 0;
116 }
117
118 static inline int vrf_dev_table_rcu(const struct net_device *dev)
119 {
120         return 0;
121 }
122
123 static inline int vrf_dev_table(const struct net_device *dev)
124 {
125         return 0;
126 }
127
128 static inline int vrf_dev_table_rtnl(const struct net_device *dev)
129 {
130         return 0;
131 }
132
133 static inline struct rtable *vrf_dev_get_rth(const struct net_device *dev)
134 {
135         return ERR_PTR(-ENETUNREACH);
136 }
137 #endif
138
139 #endif /* __LINUX_NET_VRF_H */