#define pr_fmt(fmt) …
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/udp.h>
#include <linux/jhash.h>
#include <linux/if_tunnel.h>
#include <linux/net.h>
#include <linux/igmp.h>
#include <linux/workqueue.h>
#include <net/pkt_sched.h>
#include <net/net_namespace.h>
#include <net/ip.h>
#include <net/udp.h>
#include <net/udp_tunnel.h>
#include <net/icmp.h>
#include <net/mld.h>
#include <net/amt.h>
#include <uapi/linux/amt.h>
#include <linux/security.h>
#include <net/gro_cells.h>
#include <net/ipv6.h>
#include <net/if_inet6.h>
#include <net/ndisc.h>
#include <net/addrconf.h>
#include <net/ip6_route.h>
#include <net/inet_common.h>
#include <net/ip6_checksum.h>
static struct workqueue_struct *amt_wq;
static HLIST_HEAD(source_gc_list);
static spinlock_t source_gc_lock;
static struct delayed_work source_gc_wq;
static char *status_str[] = …;
static char *type_str[] = …;
static char *action_str[] = …;
static struct igmpv3_grec igmpv3_zero_grec;
#if IS_ENABLED(CONFIG_IPV6)
#define MLD2_ALL_NODE_INIT …
static struct in6_addr mld2_all_node = …;
static struct mld2_grec mldv2_zero_grec;
#endif
static struct amt_skb_cb *amt_skb_cb(struct sk_buff *skb)
{ … }
static void __amt_source_gc_work(void)
{ … }
static void amt_source_gc_work(struct work_struct *work)
{ … }
static bool amt_addr_equal(union amt_addr *a, union amt_addr *b)
{ … }
static u32 amt_source_hash(struct amt_tunnel_list *tunnel, union amt_addr *src)
{ … }
static bool amt_status_filter(struct amt_source_node *snode,
enum amt_filter filter)
{ … }
static struct amt_source_node *amt_lookup_src(struct amt_tunnel_list *tunnel,
struct amt_group_node *gnode,
enum amt_filter filter,
union amt_addr *src)
{ … }
static u32 amt_group_hash(struct amt_tunnel_list *tunnel, union amt_addr *group)
{ … }
static struct amt_group_node *amt_lookup_group(struct amt_tunnel_list *tunnel,
union amt_addr *group,
union amt_addr *host,
bool v6)
{ … }
static void amt_destroy_source(struct amt_source_node *snode)
{ … }
static void amt_del_group(struct amt_dev *amt, struct amt_group_node *gnode)
{ … }
static void amt_source_work(struct work_struct *work)
{ … }
static void amt_act_src(struct amt_tunnel_list *tunnel,
struct amt_group_node *gnode,
struct amt_source_node *snode,
enum amt_act act)
{ … }
static struct amt_source_node *amt_alloc_snode(struct amt_group_node *gnode,
union amt_addr *src)
{ … }
static void amt_group_work(struct work_struct *work)
{ … }
static struct amt_group_node *amt_add_group(struct amt_dev *amt,
struct amt_tunnel_list *tunnel,
union amt_addr *group,
union amt_addr *host,
bool v6)
{ … }
static struct sk_buff *amt_build_igmp_gq(struct amt_dev *amt)
{ … }
static void amt_update_gw_status(struct amt_dev *amt, enum amt_status status,
bool validate)
{ … }
static void __amt_update_relay_status(struct amt_tunnel_list *tunnel,
enum amt_status status,
bool validate)
{ … }
static void amt_update_relay_status(struct amt_tunnel_list *tunnel,
enum amt_status status, bool validate)
{ … }
static void amt_send_discovery(struct amt_dev *amt)
{ … }
static void amt_send_request(struct amt_dev *amt, bool v6)
{ … }
static void amt_send_igmp_gq(struct amt_dev *amt,
struct amt_tunnel_list *tunnel)
{ … }
#if IS_ENABLED(CONFIG_IPV6)
static struct sk_buff *amt_build_mld_gq(struct amt_dev *amt)
{ … }
static void amt_send_mld_gq(struct amt_dev *amt, struct amt_tunnel_list *tunnel)
{ … }
#else
static void amt_send_mld_gq(struct amt_dev *amt, struct amt_tunnel_list *tunnel)
{
}
#endif
static bool amt_queue_event(struct amt_dev *amt, enum amt_event event,
struct sk_buff *skb)
{ … }
static void amt_secret_work(struct work_struct *work)
{ … }
static void amt_event_send_discovery(struct amt_dev *amt)
{ … }
static void amt_discovery_work(struct work_struct *work)
{ … }
static void amt_event_send_request(struct amt_dev *amt)
{ … }
static void amt_req_work(struct work_struct *work)
{ … }
static bool amt_send_membership_update(struct amt_dev *amt,
struct sk_buff *skb,
bool v6)
{ … }
static void amt_send_multicast_data(struct amt_dev *amt,
const struct sk_buff *oskb,
struct amt_tunnel_list *tunnel,
bool v6)
{ … }
static bool amt_send_membership_query(struct amt_dev *amt,
struct sk_buff *skb,
struct amt_tunnel_list *tunnel,
bool v6)
{ … }
static netdev_tx_t amt_dev_xmit(struct sk_buff *skb, struct net_device *dev)
{ … }
static int amt_parse_type(struct sk_buff *skb)
{ … }
static void amt_clear_groups(struct amt_tunnel_list *tunnel)
{ … }
static void amt_tunnel_expire(struct work_struct *work)
{ … }
static void amt_cleanup_srcs(struct amt_dev *amt,
struct amt_tunnel_list *tunnel,
struct amt_group_node *gnode)
{ … }
static void amt_add_srcs(struct amt_dev *amt, struct amt_tunnel_list *tunnel,
struct amt_group_node *gnode, void *grec,
bool v6)
{ … }
static void amt_lookup_act_srcs(struct amt_tunnel_list *tunnel,
struct amt_group_node *gnode,
void *grec,
enum amt_ops ops,
enum amt_filter filter,
enum amt_act act,
bool v6)
{ … }
static void amt_mcast_is_in_handler(struct amt_dev *amt,
struct amt_tunnel_list *tunnel,
struct amt_group_node *gnode,
void *grec, void *zero_grec, bool v6)
{ … }
static void amt_mcast_is_ex_handler(struct amt_dev *amt,
struct amt_tunnel_list *tunnel,
struct amt_group_node *gnode,
void *grec, void *zero_grec, bool v6)
{ … }
static void amt_mcast_to_in_handler(struct amt_dev *amt,
struct amt_tunnel_list *tunnel,
struct amt_group_node *gnode,
void *grec, void *zero_grec, bool v6)
{ … }
static void amt_mcast_to_ex_handler(struct amt_dev *amt,
struct amt_tunnel_list *tunnel,
struct amt_group_node *gnode,
void *grec, void *zero_grec, bool v6)
{ … }
static void amt_mcast_allow_handler(struct amt_dev *amt,
struct amt_tunnel_list *tunnel,
struct amt_group_node *gnode,
void *grec, void *zero_grec, bool v6)
{ … }
static void amt_mcast_block_handler(struct amt_dev *amt,
struct amt_tunnel_list *tunnel,
struct amt_group_node *gnode,
void *grec, void *zero_grec, bool v6)
{ … }
static void amt_igmpv2_report_handler(struct amt_dev *amt, struct sk_buff *skb,
struct amt_tunnel_list *tunnel)
{ … }
static void amt_igmpv2_leave_handler(struct amt_dev *amt, struct sk_buff *skb,
struct amt_tunnel_list *tunnel)
{ … }
static void amt_igmpv3_report_handler(struct amt_dev *amt, struct sk_buff *skb,
struct amt_tunnel_list *tunnel)
{ … }
static void amt_igmp_report_handler(struct amt_dev *amt, struct sk_buff *skb,
struct amt_tunnel_list *tunnel)
{ … }
#if IS_ENABLED(CONFIG_IPV6)
static void amt_mldv1_report_handler(struct amt_dev *amt, struct sk_buff *skb,
struct amt_tunnel_list *tunnel)
{ … }
static void amt_mldv1_leave_handler(struct amt_dev *amt, struct sk_buff *skb,
struct amt_tunnel_list *tunnel)
{ … }
static void amt_mldv2_report_handler(struct amt_dev *amt, struct sk_buff *skb,
struct amt_tunnel_list *tunnel)
{ … }
static void amt_mld_report_handler(struct amt_dev *amt, struct sk_buff *skb,
struct amt_tunnel_list *tunnel)
{ … }
#endif
static bool amt_advertisement_handler(struct amt_dev *amt, struct sk_buff *skb)
{ … }
static bool amt_multicast_data_handler(struct amt_dev *amt, struct sk_buff *skb)
{ … }
static bool amt_membership_query_handler(struct amt_dev *amt,
struct sk_buff *skb)
{ … }
static bool amt_update_handler(struct amt_dev *amt, struct sk_buff *skb)
{ … }
static void amt_send_advertisement(struct amt_dev *amt, __be32 nonce,
__be32 daddr, __be16 dport)
{ … }
static bool amt_discovery_handler(struct amt_dev *amt, struct sk_buff *skb)
{ … }
static bool amt_request_handler(struct amt_dev *amt, struct sk_buff *skb)
{ … }
static void amt_gw_rcv(struct amt_dev *amt, struct sk_buff *skb)
{ … }
static int amt_rcv(struct sock *sk, struct sk_buff *skb)
{ … }
static void amt_event_work(struct work_struct *work)
{ … }
static int amt_err_lookup(struct sock *sk, struct sk_buff *skb)
{ … }
static struct socket *amt_create_sock(struct net *net, __be16 port)
{ … }
static int amt_socket_create(struct amt_dev *amt)
{ … }
static int amt_dev_open(struct net_device *dev)
{ … }
static int amt_dev_stop(struct net_device *dev)
{ … }
static const struct device_type amt_type = …;
static int amt_dev_init(struct net_device *dev)
{ … }
static void amt_dev_uninit(struct net_device *dev)
{ … }
static const struct net_device_ops amt_netdev_ops = …;
static void amt_link_setup(struct net_device *dev)
{ … }
static const struct nla_policy amt_policy[IFLA_AMT_MAX + 1] = …;
static int amt_validate(struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
{ … }
static int amt_newlink(struct net *net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
{ … }
static void amt_dellink(struct net_device *dev, struct list_head *head)
{ … }
static size_t amt_get_size(const struct net_device *dev)
{ … }
static int amt_fill_info(struct sk_buff *skb, const struct net_device *dev)
{ … }
static struct rtnl_link_ops amt_link_ops __read_mostly = …;
static struct net_device *amt_lookup_upper_dev(struct net_device *dev)
{ … }
static int amt_device_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{ … }
static struct notifier_block amt_notifier_block __read_mostly = …;
static int __init amt_init(void)
{ … }
late_initcall(amt_init);
static void __exit amt_fini(void)
{ … }
module_exit(amt_fini);
MODULE_LICENSE(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_AUTHOR(…) …;
MODULE_ALIAS_RTNL_LINK(…) …;