drivers/net/gtp.c
Source file repositories/reference/linux-study-clean/drivers/net/gtp.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/gtp.c- Extension
.c- Size
- 60356 bytes
- Lines
- 2547
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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 an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- 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
linux/module.hlinux/skbuff.hlinux/udp.hlinux/rculist.hlinux/jhash.hlinux/if_tunnel.hlinux/net.hlinux/file.hlinux/gtp.hnet/flow.hnet/inet_dscp.hnet/net_namespace.hnet/protocol.hnet/inet_sock.hnet/ip.hnet/ipv6.hnet/udp.hnet/udp_tunnel.hnet/icmp.hnet/xfrm.hnet/genetlink.hnet/netns/generic.hnet/gtp.h
Detected Declarations
struct pdp_ctxstruct gtp_devstruct echo_infostruct gtp_netstruct gtp_pktinfoenum gtp_multicast_groupsfunction gtp0_hashfnfunction gtp1u_hashfnfunction ipv4_hashfnfunction ipv6_hashfnfunction hlist_for_each_entry_rcufunction hlist_for_each_entry_rcufunction hlist_for_each_entry_rcufunction ipv6_pdp_addr_equalfunction hlist_for_each_entry_rcufunction gtp_check_ms_ipv4function gtp_check_ms_ipv6function gtp_check_msfunction gtp_inner_protofunction gtp_rxfunction gtp0_validate_echo_hdrfunction gtp0_build_echo_msgfunction gtp0_send_echo_resp_ipfunction gtp0_send_echo_respfunction gtp_genl_fill_echofunction gtp0_handle_echo_resp_ipfunction gtp0_handle_echo_respfunction gtp_proto_to_familyfunction gtp0_udp_encap_recvfunction gtp1u_build_echo_msgfunction gtp1u_send_echo_respfunction gtp1u_handle_echo_respfunction gtp_parse_exthdrsfunction gtp1u_udp_encap_recvfunction __gtp_encap_destroyfunction gtp_encap_destroyfunction gtp_encap_disable_sockfunction gtp_encap_disablefunction gtp_encap_recvfunction gtp_dev_uninitfunction gtp0_push_headerfunction gtp1_push_headerfunction gtp_push_headerfunction gtp_set_pktinfo_ipv4function gtp_set_pktinfo_ipv6function gtp_build_skb_outer_ip4function gtp_build_skb_outer_ip6function gtp_build_skb_ip4
Annotated Snippet
static const struct net_device_ops gtp_netdev_ops = {
.ndo_uninit = gtp_dev_uninit,
.ndo_start_xmit = gtp_dev_xmit,
};
static const struct device_type gtp_type = {
.name = "gtp",
};
#define GTP_TH_MAXLEN (sizeof(struct udphdr) + sizeof(struct gtp0_header))
#define GTP_IPV4_MAXLEN (sizeof(struct iphdr) + GTP_TH_MAXLEN)
static void gtp_link_setup(struct net_device *dev)
{
struct gtp_dev *gtp = netdev_priv(dev);
dev->netdev_ops = >p_netdev_ops;
dev->needs_free_netdev = true;
SET_NETDEV_DEVTYPE(dev, >p_type);
dev->hard_header_len = 0;
dev->addr_len = 0;
dev->mtu = ETH_DATA_LEN - GTP_IPV4_MAXLEN;
/* Zero header length. */
dev->type = ARPHRD_NONE;
dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
dev->priv_flags |= IFF_NO_QUEUE;
dev->lltx = true;
netif_keep_dst(dev);
dev->needed_headroom = LL_MAX_HEADER + GTP_IPV4_MAXLEN;
gtp->dev = dev;
}
static int gtp_hashtable_new(struct gtp_dev *gtp, int hsize);
static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[]);
static void gtp_destructor(struct net_device *dev)
{
struct gtp_dev *gtp = netdev_priv(dev);
kfree(gtp->addr_hash);
kfree(gtp->tid_hash);
}
static int gtp_sock_udp_config(struct udp_port_cfg *udp_conf,
const struct nlattr *nla, int family)
{
udp_conf->family = family;
switch (udp_conf->family) {
case AF_INET:
udp_conf->local_ip.s_addr = nla_get_be32(nla);
break;
#if IS_ENABLED(CONFIG_IPV6)
case AF_INET6:
udp_conf->local_ip6 = nla_get_in6_addr(nla);
break;
#endif
default:
return -EOPNOTSUPP;
}
return 0;
}
static struct sock *gtp_create_sock(int type, struct gtp_dev *gtp,
const struct nlattr *nla, int family)
{
struct udp_tunnel_sock_cfg tuncfg = {};
struct udp_port_cfg udp_conf = {};
struct net *net = gtp->net;
struct socket *sock;
int err;
if (nla) {
err = gtp_sock_udp_config(&udp_conf, nla, family);
if (err < 0)
return ERR_PTR(err);
} else {
udp_conf.local_ip.s_addr = htonl(INADDR_ANY);
udp_conf.family = AF_INET;
}
if (type == UDP_ENCAP_GTP0)
udp_conf.local_udp_port = htons(GTP0_PORT);
else if (type == UDP_ENCAP_GTP1U)
Annotation
- Immediate include surface: `linux/module.h`, `linux/skbuff.h`, `linux/udp.h`, `linux/rculist.h`, `linux/jhash.h`, `linux/if_tunnel.h`, `linux/net.h`, `linux/file.h`.
- Detected declarations: `struct pdp_ctx`, `struct gtp_dev`, `struct echo_info`, `struct gtp_net`, `struct gtp_pktinfo`, `enum gtp_multicast_groups`, `function gtp0_hashfn`, `function gtp1u_hashfn`, `function ipv4_hashfn`, `function ipv6_hashfn`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: pattern 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.