drivers/net/ethernet/sfc/tc_encap_actions.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/sfc/tc_encap_actions.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/sfc/tc_encap_actions.c- Extension
.c- Size
- 22094 bytes
- Lines
- 753
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
tc_encap_actions.htc.hmae.hnet/flow.hnet/inet_dscp.hnet/vxlan.hnet/geneve.hnet/netevent.hnet/arp.h
Detected Declarations
function efx_tc_encap_freefunction efx_neigh_freefunction efx_tc_init_encap_actionsfunction efx_tc_destroy_encap_actionsfunction efx_tc_fini_encap_actionsfunction efx_bind_neighfunction efx_free_neighfunction efx_release_neighfunction efx_gen_tun_header_ethfunction efx_gen_tun_header_ipv4function efx_gen_tun_header_ipv6function efx_gen_tun_header_udpfunction efx_gen_tun_header_vxlanfunction efx_gen_tun_header_genevefunction efx_gen_vxlan_header_ipv4function efx_gen_geneve_header_ipv4function efx_gen_vxlan_header_ipv6function efx_gen_geneve_header_ipv6function efx_gen_encap_headerfunction efx_tc_update_encapfunction efx_neigh_updatefunction efx_neigh_eventfunction efx_tc_check_readyfunction efx_tc_flower_release_encap_mdfunction efx_tc_remove_neigh_usersfunction list_for_each_entry_safefunction efx_tc_unregister_egdevfunction efx_tc_netevent_event
Annotated Snippet
if (encap->type & EFX_ENCAP_FLAG_IPV6) {
#if IS_ENABLED(CONFIG_IPV6)
struct dst_entry *dst;
dst = ip6_dst_lookup_flow(net, NULL, &flow6, NULL);
rc = PTR_ERR_OR_ZERO(dst);
if (rc) {
NL_SET_ERR_MSG_MOD(extack, "Failed to lookup route for IPv6 encap");
goto out_free;
}
neigh->egdev = dst->dev;
netdev_hold(neigh->egdev, &neigh->dev_tracker,
GFP_KERNEL_ACCOUNT);
neigh->ttl = ip6_dst_hoplimit(dst);
n = dst_neigh_lookup(dst, &flow6.daddr);
dst_release(dst);
#else
/* We shouldn't ever get here, because if IPv6 isn't
* enabled how did someone create an IPv6 tunnel_key?
*/
rc = -EOPNOTSUPP;
NL_SET_ERR_MSG_MOD(extack, "No IPv6 support (neigh bind)");
goto out_free;
#endif
} else {
rt = ip_route_output_key(net, &flow4);
if (IS_ERR_OR_NULL(rt)) {
rc = PTR_ERR_OR_ZERO(rt);
if (!rc)
rc = -EIO;
NL_SET_ERR_MSG_MOD(extack, "Failed to lookup route for encap");
goto out_free;
}
neigh->egdev = rt->dst.dev;
netdev_hold(neigh->egdev, &neigh->dev_tracker,
GFP_KERNEL_ACCOUNT);
neigh->ttl = ip4_dst_hoplimit(&rt->dst);
n = dst_neigh_lookup(&rt->dst, &flow4.daddr);
ip_rt_put(rt);
}
if (!n) {
rc = -ENETUNREACH;
NL_SET_ERR_MSG_MOD(extack, "Failed to lookup neighbour for encap");
netdev_put(neigh->egdev, &neigh->dev_tracker);
goto out_free;
}
refcount_set(&neigh->ref, 1);
INIT_LIST_HEAD(&neigh->users);
read_lock_bh(&n->lock);
ether_addr_copy(neigh->ha, n->ha);
neigh->n_valid = n->nud_state & NUD_VALID;
read_unlock_bh(&n->lock);
rwlock_init(&neigh->lock);
INIT_WORK(&neigh->work, efx_neigh_update);
neigh->efx = efx;
neigh->used = jiffies;
if (!neigh->n_valid)
/* Prod ARP to find us a neighbour */
neigh_event_send(n, NULL);
neigh_release(n);
}
/* Add us to this neigh */
encap->neigh = neigh;
list_add_tail(&encap->list, &neigh->users);
return 0;
out_free:
/* cleanup common to several error paths */
rhashtable_remove_fast(&efx->tc->neigh_ht, &neigh->linkage,
efx_neigh_ht_params);
synchronize_rcu();
put_net_track(net, &neigh->ns_tracker);
kfree(neigh);
return rc;
}
static void efx_free_neigh(struct efx_neigh_binder *neigh)
{
struct efx_nic *efx = neigh->efx;
rhashtable_remove_fast(&efx->tc->neigh_ht, &neigh->linkage,
efx_neigh_ht_params);
synchronize_rcu();
netdev_put(neigh->egdev, &neigh->dev_tracker);
put_net_track(neigh->net, &neigh->ns_tracker);
kfree(neigh);
}
static void efx_release_neigh(struct efx_nic *efx,
struct efx_tc_encap_action *encap)
Annotation
- Immediate include surface: `tc_encap_actions.h`, `tc.h`, `mae.h`, `net/flow.h`, `net/inet_dscp.h`, `net/vxlan.h`, `net/geneve.h`, `net/netevent.h`.
- Detected declarations: `function efx_tc_encap_free`, `function efx_neigh_free`, `function efx_tc_init_encap_actions`, `function efx_tc_destroy_encap_actions`, `function efx_tc_fini_encap_actions`, `function efx_bind_neigh`, `function efx_free_neigh`, `function efx_release_neigh`, `function efx_gen_tun_header_eth`, `function efx_gen_tun_header_ipv4`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.