1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /**************************************************************************** |
3 | * Driver for Solarflare network controllers and boards |
4 | * Copyright 2023, Advanced Micro Devices, Inc. |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License version 2 as published |
8 | * by the Free Software Foundation, incorporated herein by reference. |
9 | */ |
10 | |
11 | #ifndef EFX_TC_ENCAP_ACTIONS_H |
12 | #define EFX_TC_ENCAP_ACTIONS_H |
13 | #include "net_driver.h" |
14 | |
15 | #if IS_ENABLED(CONFIG_SFC_SRIOV) |
16 | #include <linux/refcount.h> |
17 | #include <net/tc_act/tc_tunnel_key.h> |
18 | |
19 | /** |
20 | * struct efx_neigh_binder - driver state for a neighbour entry |
21 | * @net: the network namespace in which this neigh resides |
22 | * @dst_ip: the IPv4 destination address resolved by this neigh |
23 | * @dst_ip6: the IPv6 destination address resolved by this neigh |
24 | * @ha: the hardware (Ethernet) address of the neighbour |
25 | * @n_valid: true if the neighbour is in NUD_VALID state |
26 | * @lock: protects @ha and @n_valid |
27 | * @ttl: Time To Live associated with the route used |
28 | * @dying: set when egdev is going away, to skip further updates |
29 | * @egdev: egress device from the route lookup. Holds a reference |
30 | * @dev_tracker: reference tracker entry for @egdev |
31 | * @ns_tracker: reference tracker entry for @ns |
32 | * @ref: counts encap actions referencing this entry |
33 | * @used: jiffies of last time traffic hit any encap action using this. |
34 | * When counter reads update this, a new neighbour event is sent to |
35 | * indicate that the neighbour entry is still in use. |
36 | * @users: list of &struct efx_tc_encap_action |
37 | * @linkage: entry in efx->neigh_ht (keys are @net, @dst_ip, @dst_ip6). |
38 | * @work: processes neighbour state changes, updates the encap actions |
39 | * @efx: owning NIC instance. |
40 | * |
41 | * Associates a neighbour entry with the encap actions that are |
42 | * interested in it, allowing the latter to be updated when the |
43 | * neighbour details change. |
44 | * Whichever of @dst_ip and @dst_ip6 is not in use will be all-zeroes, |
45 | * this distinguishes IPv4 from IPv6 entries. |
46 | */ |
47 | struct efx_neigh_binder { |
48 | struct net *net; |
49 | __be32 dst_ip; |
50 | struct in6_addr dst_ip6; |
51 | char ha[ETH_ALEN]; |
52 | bool n_valid; |
53 | rwlock_t lock; |
54 | u8 ttl; |
55 | bool dying; |
56 | struct net_device *egdev; |
57 | netdevice_tracker dev_tracker; |
58 | netns_tracker ns_tracker; |
59 | refcount_t ref; |
60 | unsigned long used; |
61 | struct list_head users; |
62 | struct rhash_head linkage; |
63 | struct work_struct work; |
64 | struct efx_nic *efx; |
65 | }; |
66 | |
67 | /* This limit is arbitrary; current hardware (SN1022) handles encap headers |
68 | * of up to 126 bytes, but that limit is not enshrined in the MCDI protocol. |
69 | */ |
70 | #define EFX_TC_MAX_ENCAP_HDR 126 |
71 | struct efx_tc_encap_action { |
72 | enum efx_encap_type type; |
73 | struct ip_tunnel_key key; /* 52 bytes */ |
74 | u32 dest_mport; /* is copied into struct efx_tc_action_set */ |
75 | u8 encap_hdr_len; |
76 | bool n_valid; |
77 | u8 encap_hdr[EFX_TC_MAX_ENCAP_HDR]; |
78 | struct efx_neigh_binder *neigh; |
79 | struct list_head list; /* entry on neigh->users list */ |
80 | struct list_head users; /* action sets using this encap_md */ |
81 | struct rhash_head linkage; /* efx->tc_encap_ht */ |
82 | refcount_t ref; |
83 | u32 fw_id; /* index of this entry in firmware encap table */ |
84 | }; |
85 | |
86 | /* create/uncreate/teardown hashtables */ |
87 | int efx_tc_init_encap_actions(struct efx_nic *efx); |
88 | void efx_tc_destroy_encap_actions(struct efx_nic *efx); |
89 | void efx_tc_fini_encap_actions(struct efx_nic *efx); |
90 | |
91 | struct efx_tc_flow_rule; |
92 | bool efx_tc_check_ready(struct efx_nic *efx, struct efx_tc_flow_rule *rule); |
93 | |
94 | struct efx_tc_encap_action *efx_tc_flower_create_encap_md( |
95 | struct efx_nic *efx, const struct ip_tunnel_info *info, |
96 | struct net_device *egdev, struct netlink_ext_ack *extack); |
97 | void efx_tc_flower_release_encap_md(struct efx_nic *efx, |
98 | struct efx_tc_encap_action *encap); |
99 | |
100 | void efx_tc_unregister_egdev(struct efx_nic *efx, struct net_device *net_dev); |
101 | int efx_tc_netevent_event(struct efx_nic *efx, unsigned long event, |
102 | void *ptr); |
103 | |
104 | #else /* CONFIG_SFC_SRIOV */ |
105 | |
106 | static inline int efx_tc_netevent_event(struct efx_nic *efx, |
107 | unsigned long event, void *ptr) |
108 | { |
109 | return NOTIFY_DONE; |
110 | } |
111 | |
112 | #endif /* CONFIG_SFC_SRIOV */ |
113 | |
114 | #endif /* EFX_TC_ENCAP_ACTIONS_H */ |
115 | |