#define KMSG_COMPONENT …
#define pr_fmt(fmt) …
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/capability.h>
#include <linux/fs.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/workqueue.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/mutex.h>
#include <net/net_namespace.h>
#include <linux/nsproxy.h>
#include <net/ip.h>
#ifdef CONFIG_IP_VS_IPV6
#include <net/ipv6.h>
#include <net/ip6_route.h>
#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
#endif
#include <net/route.h>
#include <net/sock.h>
#include <net/genetlink.h>
#include <linux/uaccess.h>
#include <net/ip_vs.h>
MODULE_ALIAS_GENL_FAMILY(…);
DEFINE_MUTEX(…) …;
#ifdef CONFIG_IP_VS_DEBUG
static int sysctl_ip_vs_debug_level = …;
int ip_vs_get_debug_level(void)
{ … }
#endif
static void __ip_vs_del_service(struct ip_vs_service *svc, bool cleanup);
#ifdef CONFIG_IP_VS_IPV6
static bool __ip_vs_addr_is_local_v6(struct net *net,
const struct in6_addr *addr)
{ … }
#endif
#ifdef CONFIG_SYSCTL
static void update_defense_level(struct netns_ipvs *ipvs)
{ … }
static void expire_nodest_conn_handler(struct work_struct *work)
{ … }
#define DEFENSE_TIMER_PERIOD …
static void defense_work_handler(struct work_struct *work)
{ … }
#endif
static void est_reload_work_handler(struct work_struct *work)
{ … }
int
ip_vs_use_count_inc(void)
{ … }
void
ip_vs_use_count_dec(void)
{ … }
#define IP_VS_SVC_TAB_BITS …
#define IP_VS_SVC_TAB_SIZE …
#define IP_VS_SVC_TAB_MASK …
static struct hlist_head ip_vs_svc_table[IP_VS_SVC_TAB_SIZE];
static struct hlist_head ip_vs_svc_fwm_table[IP_VS_SVC_TAB_SIZE];
static inline unsigned int
ip_vs_svc_hashkey(struct netns_ipvs *ipvs, int af, unsigned int proto,
const union nf_inet_addr *addr, __be16 port)
{ … }
static inline unsigned int ip_vs_svc_fwm_hashkey(struct netns_ipvs *ipvs, __u32 fwmark)
{ … }
static int ip_vs_svc_hash(struct ip_vs_service *svc)
{ … }
static int ip_vs_svc_unhash(struct ip_vs_service *svc)
{ … }
static inline struct ip_vs_service *
__ip_vs_service_find(struct netns_ipvs *ipvs, int af, __u16 protocol,
const union nf_inet_addr *vaddr, __be16 vport)
{ … }
static inline struct ip_vs_service *
__ip_vs_svc_fwm_find(struct netns_ipvs *ipvs, int af, __u32 fwmark)
{ … }
struct ip_vs_service *
ip_vs_service_find(struct netns_ipvs *ipvs, int af, __u32 fwmark, __u16 protocol,
const union nf_inet_addr *vaddr, __be16 vport)
{ … }
static inline void
__ip_vs_bind_svc(struct ip_vs_dest *dest, struct ip_vs_service *svc)
{ … }
static void ip_vs_service_free(struct ip_vs_service *svc)
{ … }
static void ip_vs_service_rcu_free(struct rcu_head *head)
{ … }
static void __ip_vs_svc_put(struct ip_vs_service *svc)
{ … }
static inline unsigned int ip_vs_rs_hashkey(int af,
const union nf_inet_addr *addr,
__be16 port)
{ … }
static void ip_vs_rs_hash(struct netns_ipvs *ipvs, struct ip_vs_dest *dest)
{ … }
static void ip_vs_rs_unhash(struct ip_vs_dest *dest)
{ … }
bool ip_vs_has_real_service(struct netns_ipvs *ipvs, int af, __u16 protocol,
const union nf_inet_addr *daddr, __be16 dport)
{ … }
struct ip_vs_dest *ip_vs_find_real_service(struct netns_ipvs *ipvs, int af,
__u16 protocol,
const union nf_inet_addr *daddr,
__be16 dport)
{ … }
struct ip_vs_dest *ip_vs_find_tunnel(struct netns_ipvs *ipvs, int af,
const union nf_inet_addr *daddr,
__be16 tun_port)
{ … }
static struct ip_vs_dest *
ip_vs_lookup_dest(struct ip_vs_service *svc, int dest_af,
const union nf_inet_addr *daddr, __be16 dport)
{ … }
struct ip_vs_dest *ip_vs_find_dest(struct netns_ipvs *ipvs, int svc_af, int dest_af,
const union nf_inet_addr *daddr,
__be16 dport,
const union nf_inet_addr *vaddr,
__be16 vport, __u16 protocol, __u32 fwmark,
__u32 flags)
{ … }
void ip_vs_dest_dst_rcu_free(struct rcu_head *head)
{ … }
static void __ip_vs_dst_cache_reset(struct ip_vs_dest *dest)
{ … }
static struct ip_vs_dest *
ip_vs_trash_get_dest(struct ip_vs_service *svc, int dest_af,
const union nf_inet_addr *daddr, __be16 dport)
{ … }
static void ip_vs_dest_rcu_free(struct rcu_head *head)
{ … }
static void ip_vs_dest_free(struct ip_vs_dest *dest)
{ … }
static void ip_vs_trash_cleanup(struct netns_ipvs *ipvs)
{ … }
static void ip_vs_stats_rcu_free(struct rcu_head *head)
{ … }
static void
ip_vs_copy_stats(struct ip_vs_kstats *dst, struct ip_vs_stats *src)
{ … }
static void
ip_vs_export_stats_user(struct ip_vs_stats_user *dst, struct ip_vs_kstats *src)
{ … }
static void
ip_vs_zero_stats(struct ip_vs_stats *stats)
{ … }
int ip_vs_stats_init_alloc(struct ip_vs_stats *s)
{ … }
struct ip_vs_stats *ip_vs_stats_alloc(void)
{ … }
void ip_vs_stats_release(struct ip_vs_stats *stats)
{ … }
void ip_vs_stats_free(struct ip_vs_stats *stats)
{ … }
static void
__ip_vs_update_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest,
struct ip_vs_dest_user_kern *udest, int add)
{ … }
static int
ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest)
{ … }
static int
ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest)
{ … }
static int
ip_vs_edit_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest)
{ … }
static void __ip_vs_del_dest(struct netns_ipvs *ipvs, struct ip_vs_dest *dest,
bool cleanup)
{ … }
static void __ip_vs_unlink_dest(struct ip_vs_service *svc,
struct ip_vs_dest *dest,
int svcupd)
{ … }
static int
ip_vs_del_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest)
{ … }
static void ip_vs_dest_trash_expire(struct timer_list *t)
{ … }
static int
ip_vs_add_service(struct netns_ipvs *ipvs, struct ip_vs_service_user_kern *u,
struct ip_vs_service **svc_p)
{ … }
static int
ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user_kern *u)
{ … }
static void __ip_vs_del_service(struct ip_vs_service *svc, bool cleanup)
{ … }
static void ip_vs_unlink_service(struct ip_vs_service *svc, bool cleanup)
{ … }
static int ip_vs_del_service(struct ip_vs_service *svc)
{ … }
static int ip_vs_flush(struct netns_ipvs *ipvs, bool cleanup)
{ … }
void ip_vs_service_nets_cleanup(struct list_head *net_list)
{ … }
static inline void
ip_vs_forget_dev(struct ip_vs_dest *dest, struct net_device *dev)
{ … }
static int ip_vs_dst_event(struct notifier_block *this, unsigned long event,
void *ptr)
{ … }
static int ip_vs_zero_service(struct ip_vs_service *svc)
{ … }
static int ip_vs_zero_all(struct netns_ipvs *ipvs)
{ … }
#ifdef CONFIG_SYSCTL
static int
proc_do_defense_mode(const struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{ … }
static int
proc_do_sync_threshold(const struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{ … }
static int
proc_do_sync_ports(const struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{ … }
static int ipvs_proc_est_cpumask_set(const struct ctl_table *table,
void *buffer)
{ … }
static int ipvs_proc_est_cpumask_get(const struct ctl_table *table,
void *buffer, size_t size)
{ … }
static int ipvs_proc_est_cpulist(const struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{ … }
static int ipvs_proc_est_nice(const struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{ … }
static int ipvs_proc_run_estimation(const struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{ … }
static struct ctl_table vs_vars[] = …;
#endif
#ifdef CONFIG_PROC_FS
struct ip_vs_iter { … };
static inline const char *ip_vs_fwd_name(unsigned int flags)
{ … }
static struct ip_vs_service *ip_vs_info_array(struct seq_file *seq, loff_t pos)
{ … }
static void *ip_vs_info_seq_start(struct seq_file *seq, loff_t *pos)
__acquires(RCU)
{ … }
static void *ip_vs_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{ … }
static void ip_vs_info_seq_stop(struct seq_file *seq, void *v)
__releases(RCU)
{ … }
static int ip_vs_info_seq_show(struct seq_file *seq, void *v)
{ … }
static const struct seq_operations ip_vs_info_seq_ops = …;
static int ip_vs_stats_show(struct seq_file *seq, void *v)
{ … }
static int ip_vs_stats_percpu_show(struct seq_file *seq, void *v)
{ … }
#endif
static int ip_vs_set_timeout(struct netns_ipvs *ipvs, struct ip_vs_timeout_user *u)
{ … }
#define CMDID(cmd) …
struct ip_vs_svcdest_user { … };
static const unsigned char set_arglen[CMDID(IP_VS_SO_SET_MAX) + 1] = …;
ip_vs_set_arglen;
#define MAX_SET_ARGLEN …
static void ip_vs_copy_usvc_compat(struct ip_vs_service_user_kern *usvc,
struct ip_vs_service_user *usvc_compat)
{ … }
static void ip_vs_copy_udest_compat(struct ip_vs_dest_user_kern *udest,
struct ip_vs_dest_user *udest_compat)
{ … }
static int
do_ip_vs_set_ctl(struct sock *sk, int cmd, sockptr_t ptr, unsigned int len)
{ … }
static void
ip_vs_copy_service(struct ip_vs_service_entry *dst, struct ip_vs_service *src)
{ … }
static inline int
__ip_vs_get_service_entries(struct netns_ipvs *ipvs,
const struct ip_vs_get_services *get,
struct ip_vs_get_services __user *uptr)
{ … }
static inline int
__ip_vs_get_dest_entries(struct netns_ipvs *ipvs, const struct ip_vs_get_dests *get,
struct ip_vs_get_dests __user *uptr)
{ … }
static inline void
__ip_vs_get_timeouts(struct netns_ipvs *ipvs, struct ip_vs_timeout_user *u)
{ … }
static const unsigned char get_arglen[CMDID(IP_VS_SO_GET_MAX) + 1] = …;
ip_vs_get_arglen;
#define MAX_GET_ARGLEN …
static int
do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
{ … }
static struct nf_sockopt_ops ip_vs_sockopts = …;
static struct genl_family ip_vs_genl_family;
static const struct nla_policy ip_vs_cmd_policy[IPVS_CMD_ATTR_MAX + 1] = …;
static const struct nla_policy ip_vs_daemon_policy[IPVS_DAEMON_ATTR_MAX + 1] = …;
static const struct nla_policy ip_vs_svc_policy[IPVS_SVC_ATTR_MAX + 1] = …;
static const struct nla_policy ip_vs_dest_policy[IPVS_DEST_ATTR_MAX + 1] = …;
static int ip_vs_genl_fill_stats(struct sk_buff *skb, int container_type,
struct ip_vs_kstats *kstats)
{ … }
static int ip_vs_genl_fill_stats64(struct sk_buff *skb, int container_type,
struct ip_vs_kstats *kstats)
{ … }
static int ip_vs_genl_fill_service(struct sk_buff *skb,
struct ip_vs_service *svc)
{ … }
static int ip_vs_genl_dump_service(struct sk_buff *skb,
struct ip_vs_service *svc,
struct netlink_callback *cb)
{ … }
static int ip_vs_genl_dump_services(struct sk_buff *skb,
struct netlink_callback *cb)
{ … }
static bool ip_vs_is_af_valid(int af)
{ … }
static int ip_vs_genl_parse_service(struct netns_ipvs *ipvs,
struct ip_vs_service_user_kern *usvc,
struct nlattr *nla, bool full_entry,
struct ip_vs_service **ret_svc)
{ … }
static struct ip_vs_service *ip_vs_genl_find_service(struct netns_ipvs *ipvs,
struct nlattr *nla)
{ … }
static int ip_vs_genl_fill_dest(struct sk_buff *skb, struct ip_vs_dest *dest)
{ … }
static int ip_vs_genl_dump_dest(struct sk_buff *skb, struct ip_vs_dest *dest,
struct netlink_callback *cb)
{ … }
static int ip_vs_genl_dump_dests(struct sk_buff *skb,
struct netlink_callback *cb)
{ … }
static int ip_vs_genl_parse_dest(struct ip_vs_dest_user_kern *udest,
struct nlattr *nla, bool full_entry)
{ … }
static int ip_vs_genl_fill_daemon(struct sk_buff *skb, __u32 state,
struct ipvs_sync_daemon_cfg *c)
{ … }
static int ip_vs_genl_dump_daemon(struct sk_buff *skb, __u32 state,
struct ipvs_sync_daemon_cfg *c,
struct netlink_callback *cb)
{ … }
static int ip_vs_genl_dump_daemons(struct sk_buff *skb,
struct netlink_callback *cb)
{ … }
static int ip_vs_genl_new_daemon(struct netns_ipvs *ipvs, struct nlattr **attrs)
{ … }
static int ip_vs_genl_del_daemon(struct netns_ipvs *ipvs, struct nlattr **attrs)
{ … }
static int ip_vs_genl_set_config(struct netns_ipvs *ipvs, struct nlattr **attrs)
{ … }
static int ip_vs_genl_set_daemon(struct sk_buff *skb, struct genl_info *info)
{ … }
static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info)
{ … }
static int ip_vs_genl_get_cmd(struct sk_buff *skb, struct genl_info *info)
{ … }
static const struct genl_small_ops ip_vs_genl_ops[] = …;
static struct genl_family ip_vs_genl_family __ro_after_init = …;
static int __init ip_vs_genl_register(void)
{ … }
static void ip_vs_genl_unregister(void)
{ … }
#ifdef CONFIG_SYSCTL
static int __net_init ip_vs_control_net_init_sysctl(struct netns_ipvs *ipvs)
{ … }
static void __net_exit ip_vs_control_net_cleanup_sysctl(struct netns_ipvs *ipvs)
{ … }
#else
static int __net_init ip_vs_control_net_init_sysctl(struct netns_ipvs *ipvs) { return 0; }
static void __net_exit ip_vs_control_net_cleanup_sysctl(struct netns_ipvs *ipvs) { }
#endif
static struct notifier_block ip_vs_dst_notifier = …;
int __net_init ip_vs_control_net_init(struct netns_ipvs *ipvs)
{ … }
void __net_exit ip_vs_control_net_cleanup(struct netns_ipvs *ipvs)
{ … }
int __init ip_vs_register_nl_ioctl(void)
{ … }
void ip_vs_unregister_nl_ioctl(void)
{ … }
int __init ip_vs_control_init(void)
{ … }
void ip_vs_control_cleanup(void)
{ … }