xref: /linux/include/net/l3mdev.h (revision 1b69c6d0ae90b7f1a4f61d5c8209d5cb7a55f849)
1 /*
2  * include/net/l3mdev.h - L3 master device API
3  * Copyright (c) 2015 Cumulus Networks
4  * Copyright (c) 2015 David Ahern <dsa@cumulusnetworks.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  */
11 #ifndef _NET_L3MDEV_H_
12 #define _NET_L3MDEV_H_
13 
14 /**
15  * struct l3mdev_ops - l3mdev operations
16  *
17  * @l3mdev_fib_table: Get FIB table id to use for lookups
18  *
19  * @l3mdev_get_rtable: Get cached IPv4 rtable (dst_entry) for device
20  */
21 
22 struct l3mdev_ops {
23 	u32		(*l3mdev_fib_table)(const struct net_device *dev);
24 	struct rtable *	(*l3mdev_get_rtable)(const struct net_device *dev,
25 					     const struct flowi4 *fl4);
26 };
27 
28 #ifdef CONFIG_NET_L3_MASTER_DEV
29 
30 int l3mdev_master_ifindex_rcu(struct net_device *dev);
31 static inline int l3mdev_master_ifindex(struct net_device *dev)
32 {
33 	int ifindex;
34 
35 	rcu_read_lock();
36 	ifindex = l3mdev_master_ifindex_rcu(dev);
37 	rcu_read_unlock();
38 
39 	return ifindex;
40 }
41 
42 /* get index of an interface to use for FIB lookups. For devices
43  * enslaved to an L3 master device FIB lookups are based on the
44  * master index
45  */
46 static inline int l3mdev_fib_oif_rcu(struct net_device *dev)
47 {
48 	return l3mdev_master_ifindex_rcu(dev) ? : dev->ifindex;
49 }
50 
51 static inline int l3mdev_fib_oif(struct net_device *dev)
52 {
53 	int oif;
54 
55 	rcu_read_lock();
56 	oif = l3mdev_fib_oif_rcu(dev);
57 	rcu_read_unlock();
58 
59 	return oif;
60 }
61 
62 u32 l3mdev_fib_table_rcu(const struct net_device *dev);
63 u32 l3mdev_fib_table_by_index(struct net *net, int ifindex);
64 static inline u32 l3mdev_fib_table(const struct net_device *dev)
65 {
66 	u32 tb_id;
67 
68 	rcu_read_lock();
69 	tb_id = l3mdev_fib_table_rcu(dev);
70 	rcu_read_unlock();
71 
72 	return tb_id;
73 }
74 
75 static inline struct rtable *l3mdev_get_rtable(const struct net_device *dev,
76 					       const struct flowi4 *fl4)
77 {
78 	if (netif_is_l3_master(dev) && dev->l3mdev_ops->l3mdev_get_rtable)
79 		return dev->l3mdev_ops->l3mdev_get_rtable(dev, fl4);
80 
81 	return NULL;
82 }
83 
84 #else
85 
86 static inline int l3mdev_master_ifindex_rcu(struct net_device *dev)
87 {
88 	return 0;
89 }
90 static inline int l3mdev_master_ifindex(struct net_device *dev)
91 {
92 	return 0;
93 }
94 
95 static inline int l3mdev_fib_oif_rcu(struct net_device *dev)
96 {
97 	return dev ? dev->ifindex : 0;
98 }
99 static inline int l3mdev_fib_oif(struct net_device *dev)
100 {
101 	return dev ? dev->ifindex : 0;
102 }
103 
104 static inline u32 l3mdev_fib_table_rcu(const struct net_device *dev)
105 {
106 	return 0;
107 }
108 static inline u32 l3mdev_fib_table(const struct net_device *dev)
109 {
110 	return 0;
111 }
112 static inline u32 l3mdev_fib_table_by_index(struct net *net, int ifindex)
113 {
114 	return 0;
115 }
116 
117 static inline struct rtable *l3mdev_get_rtable(const struct net_device *dev,
118 					       const struct flowi4 *fl4)
119 {
120 	return NULL;
121 }
122 
123 #endif
124 
125 #endif /* _NET_L3MDEV_H_ */
126