cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

l3mdev.h (7162B)


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