root/include/net/l3mdev.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. l3mdev_master_ifindex
  2. l3mdev_master_ifindex_by_index
  3. l3mdev_master_dev_rcu
  4. l3mdev_master_upper_ifindex_by_index
  5. l3mdev_fib_table
  6. netif_index_is_l3_master
  7. l3mdev_l3_rcv
  8. l3mdev_ip_rcv
  9. l3mdev_ip6_rcv
  10. l3mdev_l3_out
  11. l3mdev_ip_out
  12. l3mdev_ip6_out
  13. l3mdev_master_ifindex_rcu
  14. l3mdev_master_ifindex
  15. l3mdev_master_ifindex_by_index
  16. l3mdev_master_upper_ifindex_by_index_rcu
  17. l3mdev_master_upper_ifindex_by_index
  18. l3mdev_master_dev_rcu
  19. l3mdev_fib_table_rcu
  20. l3mdev_fib_table
  21. l3mdev_fib_table_by_index
  22. netif_index_is_l3_master
  23. l3mdev_link_scope_lookup
  24. l3mdev_ip_rcv
  25. l3mdev_ip6_rcv
  26. l3mdev_ip_out
  27. l3mdev_ip6_out
  28. l3mdev_fib_rule_match
  29. l3mdev_update_flow

   1 /* SPDX-License-Identifier: GPL-2.0-or-later */
   2 /*
   3  * include/net/l3mdev.h - L3 master device API
   4  * Copyright (c) 2015 Cumulus Networks
   5  * Copyright (c) 2015 David Ahern <dsa@cumulusnetworks.com>
   6  */
   7 #ifndef _NET_L3MDEV_H_
   8 #define _NET_L3MDEV_H_
   9 
  10 #include <net/dst.h>
  11 #include <net/fib_rules.h>
  12 
  13 /**
  14  * struct l3mdev_ops - l3mdev operations
  15  *
  16  * @l3mdev_fib_table: Get FIB table id to use for lookups
  17  *
  18  * @l3mdev_l3_rcv:    Hook in L3 receive path
  19  *
  20  * @l3mdev_l3_out:    Hook in L3 output path
  21  *
  22  * @l3mdev_link_scope_lookup: IPv6 lookup for linklocal and mcast destinations
  23  */
  24 
  25 struct l3mdev_ops {
  26         u32             (*l3mdev_fib_table)(const struct net_device *dev);
  27         struct sk_buff * (*l3mdev_l3_rcv)(struct net_device *dev,
  28                                           struct sk_buff *skb, u16 proto);
  29         struct sk_buff * (*l3mdev_l3_out)(struct net_device *dev,
  30                                           struct sock *sk, struct sk_buff *skb,
  31                                           u16 proto);
  32 
  33         /* IPv6 ops */
  34         struct dst_entry * (*l3mdev_link_scope_lookup)(const struct net_device *dev,
  35                                                  struct flowi6 *fl6);
  36 };
  37 
  38 #ifdef CONFIG_NET_L3_MASTER_DEV
  39 
  40 int l3mdev_fib_rule_match(struct net *net, struct flowi *fl,
  41                           struct fib_lookup_arg *arg);
  42 
  43 void l3mdev_update_flow(struct net *net, struct flowi *fl);
  44 
  45 int l3mdev_master_ifindex_rcu(const struct net_device *dev);
  46 static inline int l3mdev_master_ifindex(struct net_device *dev)
  47 {
  48         int ifindex;
  49 
  50         rcu_read_lock();
  51         ifindex = l3mdev_master_ifindex_rcu(dev);
  52         rcu_read_unlock();
  53 
  54         return ifindex;
  55 }
  56 
  57 static inline int l3mdev_master_ifindex_by_index(struct net *net, int ifindex)
  58 {
  59         struct net_device *dev;
  60         int rc = 0;
  61 
  62         if (likely(ifindex)) {
  63                 rcu_read_lock();
  64 
  65                 dev = dev_get_by_index_rcu(net, ifindex);
  66                 if (dev)
  67                         rc = l3mdev_master_ifindex_rcu(dev);
  68 
  69                 rcu_read_unlock();
  70         }
  71 
  72         return rc;
  73 }
  74 
  75 static inline
  76 struct net_device *l3mdev_master_dev_rcu(const struct net_device *_dev)
  77 {
  78         /* netdev_master_upper_dev_get_rcu calls
  79          * list_first_or_null_rcu to walk the upper dev list.
  80          * list_first_or_null_rcu does not handle a const arg. We aren't
  81          * making changes, just want the master device from that list so
  82          * typecast to remove the const
  83          */
  84         struct net_device *dev = (struct net_device *)_dev;
  85         struct net_device *master;
  86 
  87         if (!dev)
  88                 return NULL;
  89 
  90         if (netif_is_l3_master(dev))
  91                 master = dev;
  92         else if (netif_is_l3_slave(dev))
  93                 master = netdev_master_upper_dev_get_rcu(dev);
  94         else
  95                 master = NULL;
  96 
  97         return master;
  98 }
  99 
 100 int l3mdev_master_upper_ifindex_by_index_rcu(struct net *net, int ifindex);
 101 static inline
 102 int l3mdev_master_upper_ifindex_by_index(struct net *net, int ifindex)
 103 {
 104         rcu_read_lock();
 105         ifindex = l3mdev_master_upper_ifindex_by_index_rcu(net, ifindex);
 106         rcu_read_unlock();
 107 
 108         return ifindex;
 109 }
 110 
 111 u32 l3mdev_fib_table_rcu(const struct net_device *dev);
 112 u32 l3mdev_fib_table_by_index(struct net *net, int ifindex);
 113 static inline u32 l3mdev_fib_table(const struct net_device *dev)
 114 {
 115         u32 tb_id;
 116 
 117         rcu_read_lock();
 118         tb_id = l3mdev_fib_table_rcu(dev);
 119         rcu_read_unlock();
 120 
 121         return tb_id;
 122 }
 123 
 124 static inline bool netif_index_is_l3_master(struct net *net, int ifindex)
 125 {
 126         struct net_device *dev;
 127         bool rc = false;
 128 
 129         if (ifindex == 0)
 130                 return false;
 131 
 132         rcu_read_lock();
 133 
 134         dev = dev_get_by_index_rcu(net, ifindex);
 135         if (dev)
 136                 rc = netif_is_l3_master(dev);
 137 
 138         rcu_read_unlock();
 139 
 140         return rc;
 141 }
 142 
 143 struct dst_entry *l3mdev_link_scope_lookup(struct net *net, struct flowi6 *fl6);
 144 
 145 static inline
 146 struct sk_buff *l3mdev_l3_rcv(struct sk_buff *skb, u16 proto)
 147 {
 148         struct net_device *master = NULL;
 149 
 150         if (netif_is_l3_slave(skb->dev))
 151                 master = netdev_master_upper_dev_get_rcu(skb->dev);
 152         else if (netif_is_l3_master(skb->dev) ||
 153                  netif_has_l3_rx_handler(skb->dev))
 154                 master = skb->dev;
 155 
 156         if (master && master->l3mdev_ops->l3mdev_l3_rcv)
 157                 skb = master->l3mdev_ops->l3mdev_l3_rcv(master, skb, proto);
 158 
 159         return skb;
 160 }
 161 
 162 static inline
 163 struct sk_buff *l3mdev_ip_rcv(struct sk_buff *skb)
 164 {
 165         return l3mdev_l3_rcv(skb, AF_INET);
 166 }
 167 
 168 static inline
 169 struct sk_buff *l3mdev_ip6_rcv(struct sk_buff *skb)
 170 {
 171         return l3mdev_l3_rcv(skb, AF_INET6);
 172 }
 173 
 174 static inline
 175 struct sk_buff *l3mdev_l3_out(struct sock *sk, struct sk_buff *skb, u16 proto)
 176 {
 177         struct net_device *dev = skb_dst(skb)->dev;
 178 
 179         if (netif_is_l3_slave(dev)) {
 180                 struct net_device *master;
 181 
 182                 master = netdev_master_upper_dev_get_rcu(dev);
 183                 if (master && master->l3mdev_ops->l3mdev_l3_out)
 184                         skb = master->l3mdev_ops->l3mdev_l3_out(master, sk,
 185                                                                 skb, proto);
 186         }
 187 
 188         return skb;
 189 }
 190 
 191 static inline
 192 struct sk_buff *l3mdev_ip_out(struct sock *sk, struct sk_buff *skb)
 193 {
 194         return l3mdev_l3_out(sk, skb, AF_INET);
 195 }
 196 
 197 static inline
 198 struct sk_buff *l3mdev_ip6_out(struct sock *sk, struct sk_buff *skb)
 199 {
 200         return l3mdev_l3_out(sk, skb, AF_INET6);
 201 }
 202 #else
 203 
 204 static inline int l3mdev_master_ifindex_rcu(const struct net_device *dev)
 205 {
 206         return 0;
 207 }
 208 static inline int l3mdev_master_ifindex(struct net_device *dev)
 209 {
 210         return 0;
 211 }
 212 
 213 static inline int l3mdev_master_ifindex_by_index(struct net *net, int ifindex)
 214 {
 215         return 0;
 216 }
 217 
 218 static inline
 219 int l3mdev_master_upper_ifindex_by_index_rcu(struct net *net, int ifindex)
 220 {
 221         return 0;
 222 }
 223 static inline
 224 int l3mdev_master_upper_ifindex_by_index(struct net *net, int ifindex)
 225 {
 226         return 0;
 227 }
 228 
 229 static inline
 230 struct net_device *l3mdev_master_dev_rcu(const struct net_device *dev)
 231 {
 232         return NULL;
 233 }
 234 
 235 static inline u32 l3mdev_fib_table_rcu(const struct net_device *dev)
 236 {
 237         return 0;
 238 }
 239 static inline u32 l3mdev_fib_table(const struct net_device *dev)
 240 {
 241         return 0;
 242 }
 243 static inline u32 l3mdev_fib_table_by_index(struct net *net, int ifindex)
 244 {
 245         return 0;
 246 }
 247 
 248 static inline bool netif_index_is_l3_master(struct net *net, int ifindex)
 249 {
 250         return false;
 251 }
 252 
 253 static inline
 254 struct dst_entry *l3mdev_link_scope_lookup(struct net *net, struct flowi6 *fl6)
 255 {
 256         return NULL;
 257 }
 258 
 259 static inline
 260 struct sk_buff *l3mdev_ip_rcv(struct sk_buff *skb)
 261 {
 262         return skb;
 263 }
 264 
 265 static inline
 266 struct sk_buff *l3mdev_ip6_rcv(struct sk_buff *skb)
 267 {
 268         return skb;
 269 }
 270 
 271 static inline
 272 struct sk_buff *l3mdev_ip_out(struct sock *sk, struct sk_buff *skb)
 273 {
 274         return skb;
 275 }
 276 
 277 static inline
 278 struct sk_buff *l3mdev_ip6_out(struct sock *sk, struct sk_buff *skb)
 279 {
 280         return skb;
 281 }
 282 
 283 static inline
 284 int l3mdev_fib_rule_match(struct net *net, struct flowi *fl,
 285                           struct fib_lookup_arg *arg)
 286 {
 287         return 1;
 288 }
 289 static inline
 290 void l3mdev_update_flow(struct net *net, struct flowi *fl)
 291 {
 292 }
 293 #endif
 294 
 295 #endif /* _NET_L3MDEV_H_ */

/* [<][>][^][v][top][bottom][index][help] */