0001
0002
0003
0004
0005
0006
0007 #ifndef _NET_L3MDEV_H_
0008 #define _NET_L3MDEV_H_
0009
0010 #include <net/dst.h>
0011 #include <net/fib_rules.h>
0012
0013 enum l3mdev_type {
0014 L3MDEV_TYPE_UNSPEC,
0015 L3MDEV_TYPE_VRF,
0016 __L3MDEV_TYPE_MAX
0017 };
0018
0019 #define L3MDEV_TYPE_MAX (__L3MDEV_TYPE_MAX - 1)
0020
0021 typedef int (*lookup_by_table_id_t)(struct net *net, u32 table_d);
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 struct l3mdev_ops {
0036 u32 (*l3mdev_fib_table)(const struct net_device *dev);
0037 struct sk_buff * (*l3mdev_l3_rcv)(struct net_device *dev,
0038 struct sk_buff *skb, u16 proto);
0039 struct sk_buff * (*l3mdev_l3_out)(struct net_device *dev,
0040 struct sock *sk, struct sk_buff *skb,
0041 u16 proto);
0042
0043
0044 struct dst_entry * (*l3mdev_link_scope_lookup)(const struct net_device *dev,
0045 struct flowi6 *fl6);
0046 };
0047
0048 #ifdef CONFIG_NET_L3_MASTER_DEV
0049
0050 int l3mdev_table_lookup_register(enum l3mdev_type l3type,
0051 lookup_by_table_id_t fn);
0052
0053 void l3mdev_table_lookup_unregister(enum l3mdev_type l3type,
0054 lookup_by_table_id_t fn);
0055
0056 int l3mdev_ifindex_lookup_by_table_id(enum l3mdev_type l3type, struct net *net,
0057 u32 table_id);
0058
0059 int l3mdev_fib_rule_match(struct net *net, struct flowi *fl,
0060 struct fib_lookup_arg *arg);
0061
0062 void l3mdev_update_flow(struct net *net, struct flowi *fl);
0063
0064 int l3mdev_master_ifindex_rcu(const struct net_device *dev);
0065 static inline int l3mdev_master_ifindex(struct net_device *dev)
0066 {
0067 int ifindex;
0068
0069 rcu_read_lock();
0070 ifindex = l3mdev_master_ifindex_rcu(dev);
0071 rcu_read_unlock();
0072
0073 return ifindex;
0074 }
0075
0076 static inline int l3mdev_master_ifindex_by_index(struct net *net, int ifindex)
0077 {
0078 struct net_device *dev;
0079 int rc = 0;
0080
0081 if (likely(ifindex)) {
0082 rcu_read_lock();
0083
0084 dev = dev_get_by_index_rcu(net, ifindex);
0085 if (dev)
0086 rc = l3mdev_master_ifindex_rcu(dev);
0087
0088 rcu_read_unlock();
0089 }
0090
0091 return rc;
0092 }
0093
0094 static inline
0095 struct net_device *l3mdev_master_dev_rcu(const struct net_device *_dev)
0096 {
0097
0098
0099
0100
0101
0102
0103 struct net_device *dev = (struct net_device *)_dev;
0104 struct net_device *master;
0105
0106 if (!dev)
0107 return NULL;
0108
0109 if (netif_is_l3_master(dev))
0110 master = dev;
0111 else if (netif_is_l3_slave(dev))
0112 master = netdev_master_upper_dev_get_rcu(dev);
0113 else
0114 master = NULL;
0115
0116 return master;
0117 }
0118
0119 int l3mdev_master_upper_ifindex_by_index_rcu(struct net *net, int ifindex);
0120 static inline
0121 int l3mdev_master_upper_ifindex_by_index(struct net *net, int ifindex)
0122 {
0123 rcu_read_lock();
0124 ifindex = l3mdev_master_upper_ifindex_by_index_rcu(net, ifindex);
0125 rcu_read_unlock();
0126
0127 return ifindex;
0128 }
0129
0130 u32 l3mdev_fib_table_rcu(const struct net_device *dev);
0131 u32 l3mdev_fib_table_by_index(struct net *net, int ifindex);
0132 static inline u32 l3mdev_fib_table(const struct net_device *dev)
0133 {
0134 u32 tb_id;
0135
0136 rcu_read_lock();
0137 tb_id = l3mdev_fib_table_rcu(dev);
0138 rcu_read_unlock();
0139
0140 return tb_id;
0141 }
0142
0143 static inline bool netif_index_is_l3_master(struct net *net, int ifindex)
0144 {
0145 struct net_device *dev;
0146 bool rc = false;
0147
0148 if (ifindex == 0)
0149 return false;
0150
0151 rcu_read_lock();
0152
0153 dev = dev_get_by_index_rcu(net, ifindex);
0154 if (dev)
0155 rc = netif_is_l3_master(dev);
0156
0157 rcu_read_unlock();
0158
0159 return rc;
0160 }
0161
0162 struct dst_entry *l3mdev_link_scope_lookup(struct net *net, struct flowi6 *fl6);
0163
0164 static inline
0165 struct sk_buff *l3mdev_l3_rcv(struct sk_buff *skb, u16 proto)
0166 {
0167 struct net_device *master = NULL;
0168
0169 if (netif_is_l3_slave(skb->dev))
0170 master = netdev_master_upper_dev_get_rcu(skb->dev);
0171 else if (netif_is_l3_master(skb->dev) ||
0172 netif_has_l3_rx_handler(skb->dev))
0173 master = skb->dev;
0174
0175 if (master && master->l3mdev_ops->l3mdev_l3_rcv)
0176 skb = master->l3mdev_ops->l3mdev_l3_rcv(master, skb, proto);
0177
0178 return skb;
0179 }
0180
0181 static inline
0182 struct sk_buff *l3mdev_ip_rcv(struct sk_buff *skb)
0183 {
0184 return l3mdev_l3_rcv(skb, AF_INET);
0185 }
0186
0187 static inline
0188 struct sk_buff *l3mdev_ip6_rcv(struct sk_buff *skb)
0189 {
0190 return l3mdev_l3_rcv(skb, AF_INET6);
0191 }
0192
0193 static inline
0194 struct sk_buff *l3mdev_l3_out(struct sock *sk, struct sk_buff *skb, u16 proto)
0195 {
0196 struct net_device *dev = skb_dst(skb)->dev;
0197
0198 if (netif_is_l3_slave(dev)) {
0199 struct net_device *master;
0200
0201 master = netdev_master_upper_dev_get_rcu(dev);
0202 if (master && master->l3mdev_ops->l3mdev_l3_out)
0203 skb = master->l3mdev_ops->l3mdev_l3_out(master, sk,
0204 skb, proto);
0205 }
0206
0207 return skb;
0208 }
0209
0210 static inline
0211 struct sk_buff *l3mdev_ip_out(struct sock *sk, struct sk_buff *skb)
0212 {
0213 return l3mdev_l3_out(sk, skb, AF_INET);
0214 }
0215
0216 static inline
0217 struct sk_buff *l3mdev_ip6_out(struct sock *sk, struct sk_buff *skb)
0218 {
0219 return l3mdev_l3_out(sk, skb, AF_INET6);
0220 }
0221 #else
0222
0223 static inline int l3mdev_master_ifindex_rcu(const struct net_device *dev)
0224 {
0225 return 0;
0226 }
0227 static inline int l3mdev_master_ifindex(struct net_device *dev)
0228 {
0229 return 0;
0230 }
0231
0232 static inline int l3mdev_master_ifindex_by_index(struct net *net, int ifindex)
0233 {
0234 return 0;
0235 }
0236
0237 static inline
0238 int l3mdev_master_upper_ifindex_by_index_rcu(struct net *net, int ifindex)
0239 {
0240 return 0;
0241 }
0242 static inline
0243 int l3mdev_master_upper_ifindex_by_index(struct net *net, int ifindex)
0244 {
0245 return 0;
0246 }
0247
0248 static inline
0249 struct net_device *l3mdev_master_dev_rcu(const struct net_device *dev)
0250 {
0251 return NULL;
0252 }
0253
0254 static inline u32 l3mdev_fib_table_rcu(const struct net_device *dev)
0255 {
0256 return 0;
0257 }
0258 static inline u32 l3mdev_fib_table(const struct net_device *dev)
0259 {
0260 return 0;
0261 }
0262 static inline u32 l3mdev_fib_table_by_index(struct net *net, int ifindex)
0263 {
0264 return 0;
0265 }
0266
0267 static inline bool netif_index_is_l3_master(struct net *net, int ifindex)
0268 {
0269 return false;
0270 }
0271
0272 static inline
0273 struct dst_entry *l3mdev_link_scope_lookup(struct net *net, struct flowi6 *fl6)
0274 {
0275 return NULL;
0276 }
0277
0278 static inline
0279 struct sk_buff *l3mdev_ip_rcv(struct sk_buff *skb)
0280 {
0281 return skb;
0282 }
0283
0284 static inline
0285 struct sk_buff *l3mdev_ip6_rcv(struct sk_buff *skb)
0286 {
0287 return skb;
0288 }
0289
0290 static inline
0291 struct sk_buff *l3mdev_ip_out(struct sock *sk, struct sk_buff *skb)
0292 {
0293 return skb;
0294 }
0295
0296 static inline
0297 struct sk_buff *l3mdev_ip6_out(struct sock *sk, struct sk_buff *skb)
0298 {
0299 return skb;
0300 }
0301
0302 static inline
0303 int l3mdev_table_lookup_register(enum l3mdev_type l3type,
0304 lookup_by_table_id_t fn)
0305 {
0306 return -EOPNOTSUPP;
0307 }
0308
0309 static inline
0310 void l3mdev_table_lookup_unregister(enum l3mdev_type l3type,
0311 lookup_by_table_id_t fn)
0312 {
0313 }
0314
0315 static inline
0316 int l3mdev_ifindex_lookup_by_table_id(enum l3mdev_type l3type, struct net *net,
0317 u32 table_id)
0318 {
0319 return -ENODEV;
0320 }
0321
0322 static inline
0323 int l3mdev_fib_rule_match(struct net *net, struct flowi *fl,
0324 struct fib_lookup_arg *arg)
0325 {
0326 return 1;
0327 }
0328 static inline
0329 void l3mdev_update_flow(struct net *net, struct flowi *fl)
0330 {
0331 }
0332 #endif
0333
0334 #endif