Skip to content

Commit 4e3c899

Browse files
David Aherndavem330
authored andcommitted
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 <[email protected]> Signed-off-by: David Ahern <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 0344338 commit 4e3c899

File tree

3 files changed

+168
-0
lines changed

3 files changed

+168
-0
lines changed

include/linux/netdevice.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,6 +1289,7 @@ enum netdev_priv_flags {
12891289
IFF_XMIT_DST_RELEASE_PERM = 1<<22,
12901290
IFF_IPVLAN_MASTER = 1<<23,
12911291
IFF_IPVLAN_SLAVE = 1<<24,
1292+
IFF_VRF_MASTER = 1<<25,
12921293
};
12931294

12941295
#define IFF_802_1Q_VLAN IFF_802_1Q_VLAN
@@ -1316,6 +1317,7 @@ enum netdev_priv_flags {
13161317
#define IFF_XMIT_DST_RELEASE_PERM IFF_XMIT_DST_RELEASE_PERM
13171318
#define IFF_IPVLAN_MASTER IFF_IPVLAN_MASTER
13181319
#define IFF_IPVLAN_SLAVE IFF_IPVLAN_SLAVE
1320+
#define IFF_VRF_MASTER IFF_VRF_MASTER
13191321

13201322
/**
13211323
* struct net_device - The DEVICE structure.
@@ -1432,6 +1434,7 @@ enum netdev_priv_flags {
14321434
* @dn_ptr: DECnet specific data
14331435
* @ip6_ptr: IPv6 specific data
14341436
* @ax25_ptr: AX.25 specific data
1437+
* @vrf_ptr: VRF specific data
14351438
* @ieee80211_ptr: IEEE 802.11 specific data, assign before registering
14361439
*
14371440
* @last_rx: Time of last Rx
@@ -1650,6 +1653,7 @@ struct net_device {
16501653
struct dn_dev __rcu *dn_ptr;
16511654
struct inet6_dev __rcu *ip6_ptr;
16521655
void *ax25_ptr;
1656+
struct net_vrf_dev __rcu *vrf_ptr;
16531657
struct wireless_dev *ieee80211_ptr;
16541658
struct wpan_dev *ieee802154_ptr;
16551659
#if IS_ENABLED(CONFIG_MPLS_ROUTING)
@@ -3808,6 +3812,22 @@ static inline bool netif_supports_nofcs(struct net_device *dev)
38083812
return dev->priv_flags & IFF_SUPP_NOFCS;
38093813
}
38103814

3815+
static inline bool netif_is_vrf(const struct net_device *dev)
3816+
{
3817+
return dev->priv_flags & IFF_VRF_MASTER;
3818+
}
3819+
3820+
static inline bool netif_index_is_vrf(struct net *net, int ifindex)
3821+
{
3822+
struct net_device *dev = dev_get_by_index_rcu(net, ifindex);
3823+
bool rc = false;
3824+
3825+
if (dev)
3826+
rc = netif_is_vrf(dev);
3827+
3828+
return rc;
3829+
}
3830+
38113831
/* This device needs to keep skb dst for qdisc enqueue or ndo_start_xmit() */
38123832
static inline void netif_keep_dst(struct net_device *dev)
38133833
{

include/net/vrf.h

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
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 */

include/uapi/linux/if_link.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,15 @@ enum macvlan_macaddr_mode {
341341

342342
#define MACVLAN_FLAG_NOPROMISC 1
343343

344+
/* VRF section */
345+
enum {
346+
IFLA_VRF_UNSPEC,
347+
IFLA_VRF_TABLE,
348+
__IFLA_VRF_MAX
349+
};
350+
351+
#define IFLA_VRF_MAX (__IFLA_VRF_MAX - 1)
352+
344353
/* IPVLAN section */
345354
enum {
346355
IFLA_IPVLAN_UNSPEC,

0 commit comments

Comments
 (0)