Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sfc: functions to register for conntrack zone offload

Bind a stub callback to the netfilter flow table.

Reviewed-by: Pieter Jansen van Vuuren <pieter.jansen-van-vuuren@amd.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Edward Cree <ecree.xilinx@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Edward Cree and committed by
David S. Miller
c3bb5c6a 3bf969e8

+156 -1
+1 -1
drivers/net/ethernet/sfc/Makefile
··· 11 11 sfc-$(CONFIG_SFC_MTD) += mtd.o 12 12 sfc-$(CONFIG_SFC_SRIOV) += sriov.o ef10_sriov.o ef100_sriov.o ef100_rep.o \ 13 13 mae.o tc.o tc_bindings.o tc_counters.o \ 14 - tc_encap_actions.o 14 + tc_encap_actions.o tc_conntrack.o 15 15 16 16 obj-$(CONFIG_SFC) += sfc.o 17 17
+7
drivers/net/ethernet/sfc/tc.c
··· 15 15 #include "tc.h" 16 16 #include "tc_bindings.h" 17 17 #include "tc_encap_actions.h" 18 + #include "tc_conntrack.h" 18 19 #include "mae.h" 19 20 #include "ef100_rep.h" 20 21 #include "efx.h" ··· 1748 1747 rc = rhashtable_init(&efx->tc->match_action_ht, &efx_tc_match_action_ht_params); 1749 1748 if (rc < 0) 1750 1749 goto fail_match_action_ht; 1750 + rc = efx_tc_init_conntrack(efx); 1751 + if (rc < 0) 1752 + goto fail_conntrack; 1751 1753 efx->tc->reps_filter_uc = -1; 1752 1754 efx->tc->reps_filter_mc = -1; 1753 1755 INIT_LIST_HEAD(&efx->tc->dflt.pf.acts.list); ··· 1763 1759 efx->tc->facts.reps.fw_id = MC_CMD_MAE_ACTION_SET_ALLOC_OUT_ACTION_SET_ID_NULL; 1764 1760 efx->extra_channel_type[EFX_EXTRA_CHANNEL_TC] = &efx_tc_channel_type; 1765 1761 return 0; 1762 + fail_conntrack: 1763 + rhashtable_destroy(&efx->tc->match_action_ht); 1766 1764 fail_match_action_ht: 1767 1765 rhashtable_destroy(&efx->tc->encap_match_ht); 1768 1766 fail_encap_match_ht: ··· 1798 1792 efx); 1799 1793 rhashtable_free_and_destroy(&efx->tc->encap_match_ht, 1800 1794 efx_tc_encap_match_free, NULL); 1795 + efx_tc_fini_conntrack(efx); 1801 1796 efx_tc_fini_counters(efx); 1802 1797 efx_tc_fini_encap_actions(efx); 1803 1798 mutex_unlock(&efx->tc->mutex);
+2
drivers/net/ethernet/sfc/tc.h
··· 196 196 * @encap_ht: Hashtable of TC encap actions 197 197 * @encap_match_ht: Hashtable of TC encap matches 198 198 * @match_action_ht: Hashtable of TC match-action rules 199 + * @ct_zone_ht: Hashtable of TC conntrack flowtable bindings 199 200 * @neigh_ht: Hashtable of neighbour watches (&struct efx_neigh_binder) 200 201 * @meta_ct: MAE table layout for conntrack table 201 202 * @reps_mport_id: MAE port allocated for representor RX ··· 229 228 struct rhashtable encap_ht; 230 229 struct rhashtable encap_match_ht; 231 230 struct rhashtable match_action_ht; 231 + struct rhashtable ct_zone_ht; 232 232 struct rhashtable neigh_ht; 233 233 struct efx_tc_table_ct meta_ct; 234 234 u32 reps_mport_id, reps_mport_vport_id;
+109
drivers/net/ethernet/sfc/tc_conntrack.c
··· 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 + #include "tc_conntrack.h" 12 + #include "tc.h" 13 + #include "mae.h" 14 + 15 + static int efx_tc_flow_block(enum tc_setup_type type, void *type_data, 16 + void *cb_priv); 17 + 18 + static const struct rhashtable_params efx_tc_ct_zone_ht_params = { 19 + .key_len = offsetof(struct efx_tc_ct_zone, linkage), 20 + .key_offset = 0, 21 + .head_offset = offsetof(struct efx_tc_ct_zone, linkage), 22 + }; 23 + 24 + static void efx_tc_ct_zone_free(void *ptr, void *arg) 25 + { 26 + struct efx_tc_ct_zone *zone = ptr; 27 + struct efx_nic *efx = zone->efx; 28 + 29 + netif_err(efx, drv, efx->net_dev, 30 + "tc ct_zone %u still present at teardown, removing\n", 31 + zone->zone); 32 + 33 + nf_flow_table_offload_del_cb(zone->nf_ft, efx_tc_flow_block, zone); 34 + kfree(zone); 35 + } 36 + 37 + int efx_tc_init_conntrack(struct efx_nic *efx) 38 + { 39 + int rc; 40 + 41 + rc = rhashtable_init(&efx->tc->ct_zone_ht, &efx_tc_ct_zone_ht_params); 42 + if (rc < 0) 43 + return rc; 44 + return 0; 45 + } 46 + 47 + void efx_tc_fini_conntrack(struct efx_nic *efx) 48 + { 49 + rhashtable_free_and_destroy(&efx->tc->ct_zone_ht, efx_tc_ct_zone_free, NULL); 50 + } 51 + 52 + static int efx_tc_flow_block(enum tc_setup_type type, void *type_data, 53 + void *cb_priv) 54 + { 55 + return -EOPNOTSUPP; 56 + } 57 + 58 + struct efx_tc_ct_zone *efx_tc_ct_register_zone(struct efx_nic *efx, u16 zone, 59 + struct nf_flowtable *ct_ft) 60 + { 61 + struct efx_tc_ct_zone *ct_zone, *old; 62 + int rc; 63 + 64 + ct_zone = kzalloc(sizeof(*ct_zone), GFP_USER); 65 + if (!ct_zone) 66 + return ERR_PTR(-ENOMEM); 67 + ct_zone->zone = zone; 68 + old = rhashtable_lookup_get_insert_fast(&efx->tc->ct_zone_ht, 69 + &ct_zone->linkage, 70 + efx_tc_ct_zone_ht_params); 71 + if (old) { 72 + /* don't need our new entry */ 73 + kfree(ct_zone); 74 + if (!refcount_inc_not_zero(&old->ref)) 75 + return ERR_PTR(-EAGAIN); 76 + /* existing entry found */ 77 + WARN_ON_ONCE(old->nf_ft != ct_ft); 78 + netif_dbg(efx, drv, efx->net_dev, 79 + "Found existing ct_zone for %u\n", zone); 80 + return old; 81 + } 82 + ct_zone->nf_ft = ct_ft; 83 + ct_zone->efx = efx; 84 + rc = nf_flow_table_offload_add_cb(ct_ft, efx_tc_flow_block, ct_zone); 85 + netif_dbg(efx, drv, efx->net_dev, "Adding new ct_zone for %u, rc %d\n", 86 + zone, rc); 87 + if (rc < 0) 88 + goto fail; 89 + refcount_set(&ct_zone->ref, 1); 90 + return ct_zone; 91 + fail: 92 + rhashtable_remove_fast(&efx->tc->ct_zone_ht, &ct_zone->linkage, 93 + efx_tc_ct_zone_ht_params); 94 + kfree(ct_zone); 95 + return ERR_PTR(rc); 96 + } 97 + 98 + void efx_tc_ct_unregister_zone(struct efx_nic *efx, 99 + struct efx_tc_ct_zone *ct_zone) 100 + { 101 + if (!refcount_dec_and_test(&ct_zone->ref)) 102 + return; /* still in use */ 103 + nf_flow_table_offload_del_cb(ct_zone->nf_ft, efx_tc_flow_block, ct_zone); 104 + rhashtable_remove_fast(&efx->tc->ct_zone_ht, &ct_zone->linkage, 105 + efx_tc_ct_zone_ht_params); 106 + netif_dbg(efx, drv, efx->net_dev, "Removed ct_zone for %u\n", 107 + ct_zone->zone); 108 + kfree(ct_zone); 109 + }
+37
drivers/net/ethernet/sfc/tc_conntrack.h
··· 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_CONNTRACK_H 12 + #define EFX_TC_CONNTRACK_H 13 + #include "net_driver.h" 14 + 15 + #if IS_ENABLED(CONFIG_SFC_SRIOV) 16 + #include <linux/refcount.h> 17 + #include <net/netfilter/nf_flow_table.h> 18 + 19 + struct efx_tc_ct_zone { 20 + u16 zone; 21 + struct rhash_head linkage; 22 + refcount_t ref; 23 + struct nf_flowtable *nf_ft; 24 + struct efx_nic *efx; 25 + }; 26 + 27 + /* create/teardown hashtables */ 28 + int efx_tc_init_conntrack(struct efx_nic *efx); 29 + void efx_tc_fini_conntrack(struct efx_nic *efx); 30 + 31 + struct efx_tc_ct_zone *efx_tc_ct_register_zone(struct efx_nic *efx, u16 zone, 32 + struct nf_flowtable *ct_ft); 33 + void efx_tc_ct_unregister_zone(struct efx_nic *efx, 34 + struct efx_tc_ct_zone *ct_zone); 35 + 36 + #endif /* CONFIG_SFC_SRIOV */ 37 + #endif /* EFX_TC_CONNTRACK_H */