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