drivers/net/ipvlan/ipvlan_l3s.c
Source file repositories/reference/linux-study-clean/drivers/net/ipvlan/ipvlan_l3s.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ipvlan/ipvlan_l3s.c- Extension
.c- Size
- 4731 bytes
- Lines
- 230
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
net/ip.hipvlan.h
Detected Declarations
struct ipvlan_netnsfunction ipvlan_nf_inputfunction ipvlan_register_nf_hookfunction ipvlan_unregister_nf_hookfunction ipvlan_migrate_l3s_hookfunction ipvlan_ns_exitfunction ipvlan_l3s_initfunction ipvlan_l3s_cleanupfunction ipvlan_l3s_registerfunction ipvlan_l3s_unregister
Annotated Snippet
struct ipvlan_netns {
unsigned int ipvl_nf_hook_refcnt;
};
static struct ipvl_addr *ipvlan_skb_to_addr(struct sk_buff *skb,
struct net_device *dev)
{
struct ipvl_addr *addr = NULL;
struct ipvl_port *port;
int addr_type;
void *lyr3h;
if (!dev || !netif_is_ipvlan_port(dev))
goto out;
port = ipvlan_port_get_rcu(dev);
if (!port || port->mode != IPVLAN_MODE_L3S)
goto out;
lyr3h = ipvlan_get_L3_hdr(port, skb, &addr_type);
if (!lyr3h)
goto out;
addr = ipvlan_addr_lookup(port, lyr3h, addr_type, true);
out:
return addr;
}
static struct sk_buff *ipvlan_l3_rcv(struct net_device *dev,
struct sk_buff *skb, u16 proto)
{
struct ipvl_addr *addr;
struct net_device *sdev;
addr = ipvlan_skb_to_addr(skb, dev);
if (!addr)
goto out;
sdev = addr->master->dev;
switch (proto) {
case AF_INET:
{
const struct iphdr *ip4h = ip_hdr(skb);
int err;
err = ip_route_input_noref(skb, ip4h->daddr, ip4h->saddr,
ip4h_dscp(ip4h), sdev);
if (unlikely(err))
goto out;
break;
}
#if IS_ENABLED(CONFIG_IPV6)
case AF_INET6:
{
struct dst_entry *dst;
struct ipv6hdr *ip6h = ipv6_hdr(skb);
int flags = RT6_LOOKUP_F_HAS_SADDR;
struct flowi6 fl6 = {
.flowi6_iif = sdev->ifindex,
.daddr = ip6h->daddr,
.saddr = ip6h->saddr,
.flowlabel = ip6_flowinfo(ip6h),
.flowi6_mark = skb->mark,
.flowi6_proto = ip6h->nexthdr,
};
skb_dst_drop(skb);
dst = ip6_route_input_lookup(dev_net(sdev), sdev, &fl6,
skb, flags);
skb_dst_set(skb, dst);
break;
}
#endif
default:
break;
}
out:
return skb;
}
static const struct l3mdev_ops ipvl_l3mdev_ops = {
.l3mdev_l3_rcv = ipvlan_l3_rcv,
};
static unsigned int ipvlan_nf_input(void *priv, struct sk_buff *skb,
const struct nf_hook_state *state)
{
struct ipvl_addr *addr;
unsigned int len;
Annotation
- Immediate include surface: `net/ip.h`, `ipvlan.h`.
- Detected declarations: `struct ipvlan_netns`, `function ipvlan_nf_input`, `function ipvlan_register_nf_hook`, `function ipvlan_unregister_nf_hook`, `function ipvlan_migrate_l3s_hook`, `function ipvlan_ns_exit`, `function ipvlan_l3s_init`, `function ipvlan_l3s_cleanup`, `function ipvlan_l3s_register`, `function ipvlan_l3s_unregister`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source implementation candidate.
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.