linux/drivers/net/gtp.c

// SPDX-License-Identifier: GPL-2.0-or-later
/* GTP according to GSM TS 09.60 / 3GPP TS 29.060
 *
 * (C) 2012-2014 by sysmocom - s.f.m.c. GmbH
 * (C) 2016 by Pablo Neira Ayuso <[email protected]>
 *
 * Author: Harald Welte <[email protected]>
 *	   Pablo Neira Ayuso <[email protected]>
 *	   Andreas Schultz <[email protected]>
 */

#define pr_fmt(fmt)

#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/udp.h>
#include <linux/rculist.h>
#include <linux/jhash.h>
#include <linux/if_tunnel.h>
#include <linux/net.h>
#include <linux/file.h>
#include <linux/gtp.h>

#include <net/net_namespace.h>
#include <net/protocol.h>
#include <net/ip.h>
#include <net/ipv6.h>
#include <net/udp.h>
#include <net/udp_tunnel.h>
#include <net/icmp.h>
#include <net/xfrm.h>
#include <net/genetlink.h>
#include <net/netns/generic.h>
#include <net/gtp.h>

/* An active session for the subscriber. */
struct pdp_ctx {};

/* One instance of the GTP device. */
struct gtp_dev {};

struct echo_info {};

static unsigned int gtp_net_id __read_mostly;

struct gtp_net {};

static u32 gtp_h_initval;

static struct genl_family gtp_genl_family;

enum gtp_multicast_groups {};

static const struct genl_multicast_group gtp_genl_mcgrps[] =;

static void pdp_context_delete(struct pdp_ctx *pctx);

static inline u32 gtp0_hashfn(u64 tid)
{}

static inline u32 gtp1u_hashfn(u32 tid)
{}

static inline u32 ipv4_hashfn(__be32 ip)
{}

static u32 ipv6_hashfn(const struct in6_addr *ip6)
{}

/* Resolve a PDP context structure based on the 64bit TID. */
static struct pdp_ctx *gtp0_pdp_find(struct gtp_dev *gtp, u64 tid, u16 family)
{}

/* Resolve a PDP context structure based on the 32bit TEI. */
static struct pdp_ctx *gtp1_pdp_find(struct gtp_dev *gtp, u32 tid, u16 family)
{}

/* Resolve a PDP context based on IPv4 address of MS. */
static struct pdp_ctx *ipv4_pdp_find(struct gtp_dev *gtp, __be32 ms_addr)
{}

/* 3GPP TS 29.060: PDN Connection: the association between a MS represented by
 * [...] one IPv6 *prefix* and a PDN represented by an APN.
 *
 * Then, 3GPP TS 29.061, Section 11.2.1.3 says: The size of the prefix shall be
 * according to the maximum prefix length for a global IPv6 address as
 * specified in the IPv6 Addressing Architecture, see RFC 4291.
 *
 * Finally, RFC 4291 section 2.5.4 states: All Global Unicast addresses other
 * than those that start with binary 000 have a 64-bit interface ID field
 * (i.e., n + m = 64).
 */
static bool ipv6_pdp_addr_equal(const struct in6_addr *a,
				const struct in6_addr *b)
{}

static struct pdp_ctx *ipv6_pdp_find(struct gtp_dev *gtp,
				     const struct in6_addr *ms_addr)
{}

static bool gtp_check_ms_ipv4(struct sk_buff *skb, struct pdp_ctx *pctx,
				  unsigned int hdrlen, unsigned int role)
{}

static bool gtp_check_ms_ipv6(struct sk_buff *skb, struct pdp_ctx *pctx,
			      unsigned int hdrlen, unsigned int role)
{}

/* Check if the inner IP address in this packet is assigned to any
 * existing mobile subscriber.
 */
static bool gtp_check_ms(struct sk_buff *skb, struct pdp_ctx *pctx,
			 unsigned int hdrlen, unsigned int role,
			 __u16 inner_proto)
{}

static int gtp_inner_proto(struct sk_buff *skb, unsigned int hdrlen,
			   __u16 *inner_proto)
{}

static int gtp_rx(struct pdp_ctx *pctx, struct sk_buff *skb,
		  unsigned int hdrlen, unsigned int role, __u16 inner_proto)
{}

static struct rtable *ip4_route_output_gtp(struct flowi4 *fl4,
					   const struct sock *sk,
					   __be32 daddr, __be32 saddr)
{}

static struct rt6_info *ip6_route_output_gtp(struct net *net,
					     struct flowi6 *fl6,
					     const struct sock *sk,
					     const struct in6_addr *daddr,
					     struct in6_addr *saddr)
{}

/* GSM TS 09.60. 7.3
 * In all Path Management messages:
 * - TID: is not used and shall be set to 0.
 * - Flow Label is not used and shall be set to 0
 * In signalling messages:
 * - number: this field is not yet used in signalling messages.
 *   It shall be set to 255 by the sender and shall be ignored
 *   by the receiver
 * Returns true if the echo req was correct, false otherwise.
 */
static bool gtp0_validate_echo_hdr(struct gtp0_header *gtp0)
{}

/* msg_type has to be GTP_ECHO_REQ or GTP_ECHO_RSP */
static void gtp0_build_echo_msg(struct gtp0_header *hdr, __u8 msg_type)
{}

static int gtp0_send_echo_resp_ip(struct gtp_dev *gtp, struct sk_buff *skb)
{}

static int gtp0_send_echo_resp(struct gtp_dev *gtp, struct sk_buff *skb)
{}

static int gtp_genl_fill_echo(struct sk_buff *skb, u32 snd_portid, u32 snd_seq,
			      int flags, u32 type, struct echo_info echo)
{}

static void gtp0_handle_echo_resp_ip(struct sk_buff *skb, struct echo_info *echo)
{}

static int gtp0_handle_echo_resp(struct gtp_dev *gtp, struct sk_buff *skb)
{}

static int gtp_proto_to_family(__u16 proto)
{}

/* 1 means pass up to the stack, -1 means drop and 0 means decapsulated. */
static int gtp0_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb)
{}

/* msg_type has to be GTP_ECHO_REQ or GTP_ECHO_RSP */
static void gtp1u_build_echo_msg(struct gtp1_header_long *hdr, __u8 msg_type)
{}

static int gtp1u_send_echo_resp(struct gtp_dev *gtp, struct sk_buff *skb)
{}

static int gtp1u_handle_echo_resp(struct gtp_dev *gtp, struct sk_buff *skb)
{}

static int gtp_parse_exthdrs(struct sk_buff *skb, unsigned int *hdrlen)
{}

static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb)
{}

static void __gtp_encap_destroy(struct sock *sk)
{}

static void gtp_encap_destroy(struct sock *sk)
{}

static void gtp_encap_disable_sock(struct sock *sk)
{}

static void gtp_encap_disable(struct gtp_dev *gtp)
{}

/* UDP encapsulation receive handler. See net/ipv4/udp.c.
 * Return codes: 0: success, <0: error, >0: pass up to userspace UDP socket.
 */
static int gtp_encap_recv(struct sock *sk, struct sk_buff *skb)
{}

static void gtp_dev_uninit(struct net_device *dev)
{}

static inline void gtp0_push_header(struct sk_buff *skb, struct pdp_ctx *pctx)
{}

static inline void gtp1_push_header(struct sk_buff *skb, struct pdp_ctx *pctx)
{}

struct gtp_pktinfo {};

static void gtp_push_header(struct sk_buff *skb, struct gtp_pktinfo *pktinfo)
{}

static inline void gtp_set_pktinfo_ipv4(struct gtp_pktinfo *pktinfo,
					struct sock *sk, __u8 tos,
					struct pdp_ctx *pctx, struct rtable *rt,
					struct flowi4 *fl4,
					struct net_device *dev)
{}

static void gtp_set_pktinfo_ipv6(struct gtp_pktinfo *pktinfo,
				 struct sock *sk, __u8 tos,
				 struct pdp_ctx *pctx, struct rt6_info *rt6,
				 struct flowi6 *fl6,
				 struct net_device *dev)
{}

static int gtp_build_skb_outer_ip4(struct sk_buff *skb, struct net_device *dev,
				   struct gtp_pktinfo *pktinfo,
				   struct pdp_ctx *pctx, __u8 tos,
				   __be16 frag_off)
{}

static int gtp_build_skb_outer_ip6(struct net *net, struct sk_buff *skb,
				   struct net_device *dev,
				   struct gtp_pktinfo *pktinfo,
				   struct pdp_ctx *pctx, __u8 tos)
{}

static int gtp_build_skb_ip4(struct sk_buff *skb, struct net_device *dev,
			     struct gtp_pktinfo *pktinfo)
{}

static int gtp_build_skb_ip6(struct sk_buff *skb, struct net_device *dev,
			     struct gtp_pktinfo *pktinfo)
{}

static netdev_tx_t gtp_dev_xmit(struct sk_buff *skb, struct net_device *dev)
{}

static const struct net_device_ops gtp_netdev_ops =;

static const struct device_type gtp_type =;

#define GTP_TH_MAXLEN
#define GTP_IPV4_MAXLEN

static void gtp_link_setup(struct net_device *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)
{}

static int gtp_sock_udp_config(struct udp_port_cfg *udp_conf,
			       const struct nlattr *nla, int family)
{}

static struct sock *gtp_create_sock(int type, struct gtp_dev *gtp,
				    const struct nlattr *nla, int family)
{}

static int gtp_create_sockets(struct gtp_dev *gtp, const struct nlattr *nla,
			      int family)
{}

#define GTP_TH_MAXLEN
#define GTP_IPV6_MAXLEN

static int gtp_newlink(struct net *src_net, struct net_device *dev,
		       struct nlattr *tb[], struct nlattr *data[],
		       struct netlink_ext_ack *extack)
{}

static void gtp_dellink(struct net_device *dev, struct list_head *head)
{}

static const struct nla_policy gtp_policy[IFLA_GTP_MAX + 1] =;

static int gtp_validate(struct nlattr *tb[], struct nlattr *data[],
			struct netlink_ext_ack *extack)
{}

static size_t gtp_get_size(const struct net_device *dev)
{}

static int gtp_fill_info(struct sk_buff *skb, const struct net_device *dev)
{}

static struct rtnl_link_ops gtp_link_ops __read_mostly =;

static int gtp_hashtable_new(struct gtp_dev *gtp, int hsize)
{}

static struct sock *gtp_encap_enable_socket(int fd, int type,
					    struct gtp_dev *gtp)
{}

static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[])
{}

static struct gtp_dev *gtp_find_dev(struct net *src_net, struct nlattr *nla[])
{}

static void gtp_pdp_fill(struct pdp_ctx *pctx, struct genl_info *info)
{}

static void ip_pdp_peer_fill(struct pdp_ctx *pctx, struct genl_info *info)
{}

static void ipv4_pdp_fill(struct pdp_ctx *pctx, struct genl_info *info)
{}

static bool ipv6_pdp_fill(struct pdp_ctx *pctx, struct genl_info *info)
{}

static struct pdp_ctx *gtp_pdp_add(struct gtp_dev *gtp, struct sock *sk,
				   struct genl_info *info)
{}

static void pdp_context_free(struct rcu_head *head)
{}

static void pdp_context_delete(struct pdp_ctx *pctx)
{}

static int gtp_tunnel_notify(struct pdp_ctx *pctx, u8 cmd, gfp_t allocation);

static int gtp_genl_new_pdp(struct sk_buff *skb, struct genl_info *info)
{}

static struct pdp_ctx *gtp_find_pdp_by_link(struct net *net,
					    struct nlattr *nla[])
{}

static struct pdp_ctx *gtp_find_pdp(struct net *net, struct nlattr *nla[])
{}

static int gtp_genl_del_pdp(struct sk_buff *skb, struct genl_info *info)
{}

static int gtp_genl_fill_info(struct sk_buff *skb, u32 snd_portid, u32 snd_seq,
			      int flags, u32 type, struct pdp_ctx *pctx)
{}

static int gtp_tunnel_notify(struct pdp_ctx *pctx, u8 cmd, gfp_t allocation)
{}

static int gtp_genl_get_pdp(struct sk_buff *skb, struct genl_info *info)
{}

static int gtp_genl_dump_pdp(struct sk_buff *skb,
				struct netlink_callback *cb)
{}

static int gtp_genl_send_echo_req(struct sk_buff *skb, struct genl_info *info)
{}

static const struct nla_policy gtp_genl_policy[GTPA_MAX + 1] =;

static const struct genl_small_ops gtp_genl_ops[] =;

static struct genl_family gtp_genl_family __ro_after_init =;

static int __net_init gtp_net_init(struct net *net)
{}

static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list,
					       struct list_head *dev_to_kill)
{}

static struct pernet_operations gtp_net_ops =;

static int __init gtp_init(void)
{}
late_initcall(gtp_init);

static void __exit gtp_fini(void)
{}
module_exit(gtp_fini);

MODULE_LICENSE();
MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_ALIAS_RTNL_LINK();
MODULE_ALIAS_GENL_FAMILY();