#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>
struct pdp_ctx { … };
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)
{ … }
static struct pdp_ctx *gtp0_pdp_find(struct gtp_dev *gtp, u64 tid, u16 family)
{ … }
static struct pdp_ctx *gtp1_pdp_find(struct gtp_dev *gtp, u32 tid, u16 family)
{ … }
static struct pdp_ctx *ipv4_pdp_find(struct gtp_dev *gtp, __be32 ms_addr)
{ … }
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)
{ … }
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)
{ … }
static bool gtp0_validate_echo_hdr(struct gtp0_header *gtp0)
{ … }
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)
{ … }
static int gtp0_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb)
{ … }
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)
{ … }
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(…) …;