···637637Who: Michal Hocko <mhocko@suse.cz>638638639639----------------------------640640+641641+What: ipt_addrtype match include file642642+When: 2012643643+Why: superseded by xt_addrtype644644+Who: Florian Westphal <fw@strlen.de>645645+Files: include/linux/netfilter_ipv4/ipt_addrtype.h646646+>>>>>>> 2f5dc63123905a89d4260ab8ee08d19ec104db04647647+648648+----------------------------
···11-/*22- * IP Virtual Server33- * Data structure for network namspace44- *55- */66-77-#ifndef IP_VS_H_88-#define IP_VS_H_99-1010-#include <linux/list.h>1111-#include <linux/mutex.h>1212-#include <linux/list_nulls.h>1313-#include <linux/ip_vs.h>1414-#include <asm/atomic.h>1515-#include <linux/in.h>1616-1717-struct ip_vs_stats;1818-struct ip_vs_sync_buff;1919-struct ctl_table_header;2020-2121-struct netns_ipvs {2222- int gen; /* Generation */2323- /*2424- * Hash table: for real service lookups2525- */2626- #define IP_VS_RTAB_BITS 42727- #define IP_VS_RTAB_SIZE (1 << IP_VS_RTAB_BITS)2828- #define IP_VS_RTAB_MASK (IP_VS_RTAB_SIZE - 1)2929-3030- struct list_head rs_table[IP_VS_RTAB_SIZE];3131- /* ip_vs_app */3232- struct list_head app_list;3333- struct mutex app_mutex;3434- struct lock_class_key app_key; /* mutex debuging */3535-3636- /* ip_vs_proto */3737- #define IP_VS_PROTO_TAB_SIZE 32 /* must be power of 2 */3838- struct ip_vs_proto_data *proto_data_table[IP_VS_PROTO_TAB_SIZE];3939- /* ip_vs_proto_tcp */4040-#ifdef CONFIG_IP_VS_PROTO_TCP4141- #define TCP_APP_TAB_BITS 44242- #define TCP_APP_TAB_SIZE (1 << TCP_APP_TAB_BITS)4343- #define TCP_APP_TAB_MASK (TCP_APP_TAB_SIZE - 1)4444- struct list_head tcp_apps[TCP_APP_TAB_SIZE];4545- spinlock_t tcp_app_lock;4646-#endif4747- /* ip_vs_proto_udp */4848-#ifdef CONFIG_IP_VS_PROTO_UDP4949- #define UDP_APP_TAB_BITS 45050- #define UDP_APP_TAB_SIZE (1 << UDP_APP_TAB_BITS)5151- #define UDP_APP_TAB_MASK (UDP_APP_TAB_SIZE - 1)5252- struct list_head udp_apps[UDP_APP_TAB_SIZE];5353- spinlock_t udp_app_lock;5454-#endif5555- /* ip_vs_proto_sctp */5656-#ifdef CONFIG_IP_VS_PROTO_SCTP5757- #define SCTP_APP_TAB_BITS 45858- #define SCTP_APP_TAB_SIZE (1 << SCTP_APP_TAB_BITS)5959- #define SCTP_APP_TAB_MASK (SCTP_APP_TAB_SIZE - 1)6060- /* Hash table for SCTP application incarnations */6161- struct list_head sctp_apps[SCTP_APP_TAB_SIZE];6262- spinlock_t sctp_app_lock;6363-#endif6464- /* ip_vs_conn */6565- atomic_t conn_count; /* connection counter */6666-6767- /* ip_vs_ctl */6868- struct ip_vs_stats *tot_stats; /* Statistics & est. */6969- struct ip_vs_cpu_stats __percpu *cpustats; /* Stats per cpu */7070- seqcount_t *ustats_seq; /* u64 read retry */7171-7272- int num_services; /* no of virtual services */7373- /* 1/rate drop and drop-entry variables */7474- struct delayed_work defense_work; /* Work handler */7575- int drop_rate;7676- int drop_counter;7777- atomic_t dropentry;7878- /* locks in ctl.c */7979- spinlock_t dropentry_lock; /* drop entry handling */8080- spinlock_t droppacket_lock; /* drop packet handling */8181- spinlock_t securetcp_lock; /* state and timeout tables */8282- rwlock_t rs_lock; /* real services table */8383- /* semaphore for IPVS sockopts. And, [gs]etsockopt may sleep. */8484- struct lock_class_key ctl_key; /* ctl_mutex debuging */8585- /* Trash for destinations */8686- struct list_head dest_trash;8787- /* Service counters */8888- atomic_t ftpsvc_counter;8989- atomic_t nullsvc_counter;9090-9191- /* sys-ctl struct */9292- struct ctl_table_header *sysctl_hdr;9393- struct ctl_table *sysctl_tbl;9494- /* sysctl variables */9595- int sysctl_amemthresh;9696- int sysctl_am_droprate;9797- int sysctl_drop_entry;9898- int sysctl_drop_packet;9999- int sysctl_secure_tcp;100100-#ifdef CONFIG_IP_VS_NFCT101101- int sysctl_conntrack;102102-#endif103103- int sysctl_snat_reroute;104104- int sysctl_sync_ver;105105- int sysctl_cache_bypass;106106- int sysctl_expire_nodest_conn;107107- int sysctl_expire_quiescent_template;108108- int sysctl_sync_threshold[2];109109- int sysctl_nat_icmp_send;110110-111111- /* ip_vs_lblc */112112- int sysctl_lblc_expiration;113113- struct ctl_table_header *lblc_ctl_header;114114- struct ctl_table *lblc_ctl_table;115115- /* ip_vs_lblcr */116116- int sysctl_lblcr_expiration;117117- struct ctl_table_header *lblcr_ctl_header;118118- struct ctl_table *lblcr_ctl_table;119119- /* ip_vs_est */120120- struct list_head est_list; /* estimator list */121121- spinlock_t est_lock;122122- struct timer_list est_timer; /* Estimation timer */123123- /* ip_vs_sync */124124- struct list_head sync_queue;125125- spinlock_t sync_lock;126126- struct ip_vs_sync_buff *sync_buff;127127- spinlock_t sync_buff_lock;128128- struct sockaddr_in sync_mcast_addr;129129- struct task_struct *master_thread;130130- struct task_struct *backup_thread;131131- int send_mesg_maxlen;132132- int recv_mesg_maxlen;133133- volatile int sync_state;134134- volatile int master_syncid;135135- volatile int backup_syncid;136136- /* multicast interface name */137137- char master_mcast_ifn[IP_VS_IFNAME_MAXLEN];138138- char backup_mcast_ifn[IP_VS_IFNAME_MAXLEN];139139- /* net name space ptr */140140- struct net *net; /* Needed by timer routines */141141-};142142-143143-#endif /* IP_VS_H_ */
-10
net/ipv4/netfilter/Kconfig
···6464if IP_NF_IPTABLES65656666# The matches.6767-config IP_NF_MATCH_ADDRTYPE6868- tristate '"addrtype" address type match support'6969- depends on NETFILTER_ADVANCED7070- help7171- This option allows you to match what routing thinks of an address,7272- eg. UNICAST, LOCAL, BROADCAST, ...7373-7474- If you want to compile it as a module, say M here and read7575- <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.7676-7767config IP_NF_MATCH_AH7868 tristate '"ah" match support'7969 depends on NETFILTER_ADVANCED
···12621262 /* overflow check */12631263 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))12641264 return -ENOMEM;12651265+ tmp.name[sizeof(tmp.name)-1] = 0;1265126612661267 newinfo = xt_alloc_table_info(tmp.size);12671268 if (!newinfo)···18081807 return -ENOMEM;18091808 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))18101809 return -ENOMEM;18101810+ tmp.name[sizeof(tmp.name)-1] = 0;1811181118121812 newinfo = xt_alloc_table_info(tmp.size);18131813 if (!newinfo)···20382036 ret = -EFAULT;20392037 break;20402038 }20392039+ rev.name[sizeof(rev.name)-1] = 0;2041204020422041 if (cmd == IPT_SO_GET_REVISION_TARGET)20432042 target = 1;
-134
net/ipv4/netfilter/ipt_addrtype.c
···11-/*22- * iptables module to match inet_addr_type() of an ip.33- *44- * Copyright (c) 2004 Patrick McHardy <kaber@trash.net>55- * (C) 2007 Laszlo Attila Toth <panther@balabit.hu>66- *77- * This program is free software; you can redistribute it and/or modify88- * it under the terms of the GNU General Public License version 2 as99- * published by the Free Software Foundation.1010- */1111-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt1212-#include <linux/kernel.h>1313-#include <linux/module.h>1414-#include <linux/skbuff.h>1515-#include <linux/netdevice.h>1616-#include <linux/ip.h>1717-#include <net/route.h>1818-1919-#include <linux/netfilter_ipv4/ipt_addrtype.h>2020-#include <linux/netfilter/x_tables.h>2121-2222-MODULE_LICENSE("GPL");2323-MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");2424-MODULE_DESCRIPTION("Xtables: address type match for IPv4");2525-2626-static inline bool match_type(struct net *net, const struct net_device *dev,2727- __be32 addr, u_int16_t mask)2828-{2929- return !!(mask & (1 << inet_dev_addr_type(net, dev, addr)));3030-}3131-3232-static bool3333-addrtype_mt_v0(const struct sk_buff *skb, struct xt_action_param *par)3434-{3535- struct net *net = dev_net(par->in ? par->in : par->out);3636- const struct ipt_addrtype_info *info = par->matchinfo;3737- const struct iphdr *iph = ip_hdr(skb);3838- bool ret = true;3939-4040- if (info->source)4141- ret &= match_type(net, NULL, iph->saddr, info->source) ^4242- info->invert_source;4343- if (info->dest)4444- ret &= match_type(net, NULL, iph->daddr, info->dest) ^4545- info->invert_dest;4646-4747- return ret;4848-}4949-5050-static bool5151-addrtype_mt_v1(const struct sk_buff *skb, struct xt_action_param *par)5252-{5353- struct net *net = dev_net(par->in ? par->in : par->out);5454- const struct ipt_addrtype_info_v1 *info = par->matchinfo;5555- const struct iphdr *iph = ip_hdr(skb);5656- const struct net_device *dev = NULL;5757- bool ret = true;5858-5959- if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN)6060- dev = par->in;6161- else if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT)6262- dev = par->out;6363-6464- if (info->source)6565- ret &= match_type(net, dev, iph->saddr, info->source) ^6666- (info->flags & IPT_ADDRTYPE_INVERT_SOURCE);6767- if (ret && info->dest)6868- ret &= match_type(net, dev, iph->daddr, info->dest) ^6969- !!(info->flags & IPT_ADDRTYPE_INVERT_DEST);7070- return ret;7171-}7272-7373-static int addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par)7474-{7575- struct ipt_addrtype_info_v1 *info = par->matchinfo;7676-7777- if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN &&7878- info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {7979- pr_info("both incoming and outgoing "8080- "interface limitation cannot be selected\n");8181- return -EINVAL;8282- }8383-8484- if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) |8585- (1 << NF_INET_LOCAL_IN)) &&8686- info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {8787- pr_info("output interface limitation "8888- "not valid in PREROUTING and INPUT\n");8989- return -EINVAL;9090- }9191-9292- if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) |9393- (1 << NF_INET_LOCAL_OUT)) &&9494- info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) {9595- pr_info("input interface limitation "9696- "not valid in POSTROUTING and OUTPUT\n");9797- return -EINVAL;9898- }9999-100100- return 0;101101-}102102-103103-static struct xt_match addrtype_mt_reg[] __read_mostly = {104104- {105105- .name = "addrtype",106106- .family = NFPROTO_IPV4,107107- .match = addrtype_mt_v0,108108- .matchsize = sizeof(struct ipt_addrtype_info),109109- .me = THIS_MODULE110110- },111111- {112112- .name = "addrtype",113113- .family = NFPROTO_IPV4,114114- .revision = 1,115115- .match = addrtype_mt_v1,116116- .checkentry = addrtype_mt_checkentry_v1,117117- .matchsize = sizeof(struct ipt_addrtype_info_v1),118118- .me = THIS_MODULE119119- }120120-};121121-122122-static int __init addrtype_mt_init(void)123123-{124124- return xt_register_matches(addrtype_mt_reg,125125- ARRAY_SIZE(addrtype_mt_reg));126126-}127127-128128-static void __exit addrtype_mt_exit(void)129129-{130130- xt_unregister_matches(addrtype_mt_reg, ARRAY_SIZE(addrtype_mt_reg));131131-}132132-133133-module_init(addrtype_mt_init);134134-module_exit(addrtype_mt_exit);
+3
net/ipv6/netfilter/ip6_tables.c
···12751275 /* overflow check */12761276 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))12771277 return -ENOMEM;12781278+ tmp.name[sizeof(tmp.name)-1] = 0;1278127912791280 newinfo = xt_alloc_table_info(tmp.size);12801281 if (!newinfo)···18231822 return -ENOMEM;18241823 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))18251824 return -ENOMEM;18251825+ tmp.name[sizeof(tmp.name)-1] = 0;1826182618271827 newinfo = xt_alloc_table_info(tmp.size);18281828 if (!newinfo)···20532051 ret = -EFAULT;20542052 break;20552053 }20542054+ rev.name[sizeof(rev.name)-1] = 0;2056205520572056 if (cmd == IP6T_SO_GET_REVISION_TARGET)20582057 target = 1;
+11
net/netfilter/Kconfig
···649649650650comment "Xtables matches"651651652652+config NETFILTER_XT_MATCH_ADDRTYPE653653+ tristate '"addrtype" address type match support'654654+ depends on NETFILTER_ADVANCED655655+ depends on (IPV6 || IPV6=n)656656+ ---help---657657+ This option allows you to match what routing thinks of an address,658658+ eg. UNICAST, LOCAL, BROADCAST, ...659659+660660+ If you want to compile it as a module, say M here and read661661+ <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.662662+652663config NETFILTER_XT_MATCH_CLUSTER653664 tristate '"cluster" match support'654665 depends on NF_CONNTRACK
···183183/*184184 * These are weird, but module loading must not be done with mutex185185 * held (since they will register), and we have to have a single186186- * function to use try_then_request_module().186186+ * function to use.187187 */188188189189/* Find match, grabs ref. Returns ERR_PTR() on error. */190190struct xt_match *xt_find_match(u8 af, const char *name, u8 revision)191191{192192 struct xt_match *m;193193- int err = 0;193193+ int err = -ENOENT;194194195195 if (mutex_lock_interruptible(&xt[af].mutex) != 0)196196 return ERR_PTR(-EINTR);···221221{222222 struct xt_match *match;223223224224- match = try_then_request_module(xt_find_match(nfproto, name, revision),225225- "%st_%s", xt_prefix[nfproto], name);226226- return (match != NULL) ? match : ERR_PTR(-ENOENT);224224+ match = xt_find_match(nfproto, name, revision);225225+ if (IS_ERR(match)) {226226+ request_module("%st_%s", xt_prefix[nfproto], name);227227+ match = xt_find_match(nfproto, name, revision);228228+ }229229+230230+ return match;227231}228232EXPORT_SYMBOL_GPL(xt_request_find_match);229233···235231struct xt_target *xt_find_target(u8 af, const char *name, u8 revision)236232{237233 struct xt_target *t;238238- int err = 0;234234+ int err = -ENOENT;239235240236 if (mutex_lock_interruptible(&xt[af].mutex) != 0)241237 return ERR_PTR(-EINTR);···265261{266262 struct xt_target *target;267263268268- target = try_then_request_module(xt_find_target(af, name, revision),269269- "%st_%s", xt_prefix[af], name);270270- return (target != NULL) ? target : ERR_PTR(-ENOENT);264264+ target = xt_find_target(af, name, revision);265265+ if (IS_ERR(target)) {266266+ request_module("%st_%s", xt_prefix[af], name);267267+ target = xt_find_target(af, name, revision);268268+ }269269+270270+ return target;271271}272272EXPORT_SYMBOL_GPL(xt_request_find_target);273273
+229
net/netfilter/xt_addrtype.c
···11+/*22+ * iptables module to match inet_addr_type() of an ip.33+ *44+ * Copyright (c) 2004 Patrick McHardy <kaber@trash.net>55+ * (C) 2007 Laszlo Attila Toth <panther@balabit.hu>66+ *77+ * This program is free software; you can redistribute it and/or modify88+ * it under the terms of the GNU General Public License version 2 as99+ * published by the Free Software Foundation.1010+ */1111+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt1212+#include <linux/kernel.h>1313+#include <linux/module.h>1414+#include <linux/skbuff.h>1515+#include <linux/netdevice.h>1616+#include <linux/ip.h>1717+#include <net/route.h>1818+1919+#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)2020+#include <net/ipv6.h>2121+#include <net/ip6_route.h>2222+#include <net/ip6_fib.h>2323+#endif2424+2525+#include <linux/netfilter/xt_addrtype.h>2626+#include <linux/netfilter/x_tables.h>2727+2828+MODULE_LICENSE("GPL");2929+MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");3030+MODULE_DESCRIPTION("Xtables: address type match");3131+MODULE_ALIAS("ipt_addrtype");3232+MODULE_ALIAS("ip6t_addrtype");3333+3434+#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)3535+static u32 xt_addrtype_rt6_to_type(const struct rt6_info *rt)3636+{3737+ u32 ret;3838+3939+ if (!rt)4040+ return XT_ADDRTYPE_UNREACHABLE;4141+4242+ if (rt->rt6i_flags & RTF_REJECT)4343+ ret = XT_ADDRTYPE_UNREACHABLE;4444+ else4545+ ret = 0;4646+4747+ if (rt->rt6i_flags & RTF_LOCAL)4848+ ret |= XT_ADDRTYPE_LOCAL;4949+ if (rt->rt6i_flags & RTF_ANYCAST)5050+ ret |= XT_ADDRTYPE_ANYCAST;5151+ return ret;5252+}5353+5454+static bool match_type6(struct net *net, const struct net_device *dev,5555+ const struct in6_addr *addr, u16 mask)5656+{5757+ int addr_type = ipv6_addr_type(addr);5858+5959+ if ((mask & XT_ADDRTYPE_MULTICAST) &&6060+ !(addr_type & IPV6_ADDR_MULTICAST))6161+ return false;6262+ if ((mask & XT_ADDRTYPE_UNICAST) && !(addr_type & IPV6_ADDR_UNICAST))6363+ return false;6464+ if ((mask & XT_ADDRTYPE_UNSPEC) && addr_type != IPV6_ADDR_ANY)6565+ return false;6666+6767+ if ((XT_ADDRTYPE_LOCAL | XT_ADDRTYPE_ANYCAST |6868+ XT_ADDRTYPE_UNREACHABLE) & mask) {6969+ struct rt6_info *rt;7070+ u32 type;7171+ int ifindex = dev ? dev->ifindex : 0;7272+7373+ rt = rt6_lookup(net, addr, NULL, ifindex, !!dev);7474+7575+ type = xt_addrtype_rt6_to_type(rt);7676+7777+ dst_release(&rt->dst);7878+ return !!(mask & type);7979+ }8080+ return true;8181+}8282+8383+static bool8484+addrtype_mt6(struct net *net, const struct net_device *dev,8585+ const struct sk_buff *skb, const struct xt_addrtype_info_v1 *info)8686+{8787+ const struct ipv6hdr *iph = ipv6_hdr(skb);8888+ bool ret = true;8989+9090+ if (info->source)9191+ ret &= match_type6(net, dev, &iph->saddr, info->source) ^9292+ (info->flags & XT_ADDRTYPE_INVERT_SOURCE);9393+ if (ret && info->dest)9494+ ret &= match_type6(net, dev, &iph->daddr, info->dest) ^9595+ !!(info->flags & XT_ADDRTYPE_INVERT_DEST);9696+ return ret;9797+}9898+#endif9999+100100+static inline bool match_type(struct net *net, const struct net_device *dev,101101+ __be32 addr, u_int16_t mask)102102+{103103+ return !!(mask & (1 << inet_dev_addr_type(net, dev, addr)));104104+}105105+106106+static bool107107+addrtype_mt_v0(const struct sk_buff *skb, struct xt_action_param *par)108108+{109109+ struct net *net = dev_net(par->in ? par->in : par->out);110110+ const struct xt_addrtype_info *info = par->matchinfo;111111+ const struct iphdr *iph = ip_hdr(skb);112112+ bool ret = true;113113+114114+ if (info->source)115115+ ret &= match_type(net, NULL, iph->saddr, info->source) ^116116+ info->invert_source;117117+ if (info->dest)118118+ ret &= match_type(net, NULL, iph->daddr, info->dest) ^119119+ info->invert_dest;120120+121121+ return ret;122122+}123123+124124+static bool125125+addrtype_mt_v1(const struct sk_buff *skb, struct xt_action_param *par)126126+{127127+ struct net *net = dev_net(par->in ? par->in : par->out);128128+ const struct xt_addrtype_info_v1 *info = par->matchinfo;129129+ const struct iphdr *iph;130130+ const struct net_device *dev = NULL;131131+ bool ret = true;132132+133133+ if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN)134134+ dev = par->in;135135+ else if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT)136136+ dev = par->out;137137+138138+#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)139139+ if (par->family == NFPROTO_IPV6)140140+ return addrtype_mt6(net, dev, skb, info);141141+#endif142142+ iph = ip_hdr(skb);143143+ if (info->source)144144+ ret &= match_type(net, dev, iph->saddr, info->source) ^145145+ (info->flags & XT_ADDRTYPE_INVERT_SOURCE);146146+ if (ret && info->dest)147147+ ret &= match_type(net, dev, iph->daddr, info->dest) ^148148+ !!(info->flags & XT_ADDRTYPE_INVERT_DEST);149149+ return ret;150150+}151151+152152+static int addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par)153153+{154154+ struct xt_addrtype_info_v1 *info = par->matchinfo;155155+156156+ if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN &&157157+ info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT) {158158+ pr_info("both incoming and outgoing "159159+ "interface limitation cannot be selected\n");160160+ return -EINVAL;161161+ }162162+163163+ if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) |164164+ (1 << NF_INET_LOCAL_IN)) &&165165+ info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT) {166166+ pr_info("output interface limitation "167167+ "not valid in PREROUTING and INPUT\n");168168+ return -EINVAL;169169+ }170170+171171+ if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) |172172+ (1 << NF_INET_LOCAL_OUT)) &&173173+ info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN) {174174+ pr_info("input interface limitation "175175+ "not valid in POSTROUTING and OUTPUT\n");176176+ return -EINVAL;177177+ }178178+179179+#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)180180+ if (par->family == NFPROTO_IPV6) {181181+ if ((info->source | info->dest) & XT_ADDRTYPE_BLACKHOLE) {182182+ pr_err("ipv6 BLACKHOLE matching not supported\n");183183+ return -EINVAL;184184+ }185185+ if ((info->source | info->dest) >= XT_ADDRTYPE_PROHIBIT) {186186+ pr_err("ipv6 PROHIBT (THROW, NAT ..) matching not supported\n");187187+ return -EINVAL;188188+ }189189+ if ((info->source | info->dest) & XT_ADDRTYPE_BROADCAST) {190190+ pr_err("ipv6 does not support BROADCAST matching\n");191191+ return -EINVAL;192192+ }193193+ }194194+#endif195195+ return 0;196196+}197197+198198+static struct xt_match addrtype_mt_reg[] __read_mostly = {199199+ {200200+ .name = "addrtype",201201+ .family = NFPROTO_IPV4,202202+ .match = addrtype_mt_v0,203203+ .matchsize = sizeof(struct xt_addrtype_info),204204+ .me = THIS_MODULE205205+ },206206+ {207207+ .name = "addrtype",208208+ .family = NFPROTO_UNSPEC,209209+ .revision = 1,210210+ .match = addrtype_mt_v1,211211+ .checkentry = addrtype_mt_checkentry_v1,212212+ .matchsize = sizeof(struct xt_addrtype_info_v1),213213+ .me = THIS_MODULE214214+ }215215+};216216+217217+static int __init addrtype_mt_init(void)218218+{219219+ return xt_register_matches(addrtype_mt_reg,220220+ ARRAY_SIZE(addrtype_mt_reg));221221+}222222+223223+static void __exit addrtype_mt_exit(void)224224+{225225+ xt_unregister_matches(addrtype_mt_reg, ARRAY_SIZE(addrtype_mt_reg));226226+}227227+228228+module_init(addrtype_mt_init);229229+module_exit(addrtype_mt_exit);
+30-29
net/netfilter/xt_connlimit.c
···33333434/* we will save the tuples of all connections we care about */3535struct xt_connlimit_conn {3636- struct list_head list;3737- struct nf_conntrack_tuple tuple;3636+ struct hlist_node node;3737+ struct nf_conntrack_tuple tuple;3838+ union nf_inet_addr addr;3839};39404041struct xt_connlimit_data {4141- struct list_head iphash[256];4242- spinlock_t lock;4242+ struct hlist_head iphash[256];4343+ spinlock_t lock;4344};44454546static u_int32_t connlimit_rnd __read_mostly;4646-static bool connlimit_rnd_inited __read_mostly;47474848static inline unsigned int connlimit_iphash(__be32 addr)4949{···101101{102102 const struct nf_conntrack_tuple_hash *found;103103 struct xt_connlimit_conn *conn;104104- struct xt_connlimit_conn *tmp;104104+ struct hlist_node *pos, *n;105105 struct nf_conn *found_ct;106106- struct list_head *hash;106106+ struct hlist_head *hash;107107 bool addit = true;108108 int matches = 0;109109···115115 rcu_read_lock();116116117117 /* check the saved connections */118118- list_for_each_entry_safe(conn, tmp, hash, list) {118118+ hlist_for_each_entry_safe(conn, pos, n, hash, node) {119119 found = nf_conntrack_find_get(net, NF_CT_DEFAULT_ZONE,120120 &conn->tuple);121121 found_ct = NULL;···135135136136 if (found == NULL) {137137 /* this one is gone */138138- list_del(&conn->list);138138+ hlist_del(&conn->node);139139 kfree(conn);140140 continue;141141 }···146146 * closed already -> ditch it147147 */148148 nf_ct_put(found_ct);149149- list_del(&conn->list);149149+ hlist_del(&conn->node);150150 kfree(conn);151151 continue;152152 }153153154154- if (same_source_net(addr, mask, &conn->tuple.src.u3, family))154154+ if (same_source_net(addr, mask, &conn->addr, family))155155 /* same source network -> be counted! */156156 ++matches;157157 nf_ct_put(found_ct);···161161162162 if (addit) {163163 /* save the new connection in our list */164164- conn = kzalloc(sizeof(*conn), GFP_ATOMIC);164164+ conn = kmalloc(sizeof(*conn), GFP_ATOMIC);165165 if (conn == NULL)166166 return -ENOMEM;167167 conn->tuple = *tuple;168168- list_add(&conn->list, hash);168168+ conn->addr = *addr;169169+ hlist_add_head(&conn->node, hash);169170 ++matches;170171 }171172···186185 int connections;187186188187 ct = nf_ct_get(skb, &ctinfo);189189- if (ct != NULL) {190190- if (info->flags & XT_CONNLIMIT_DADDR)191191- tuple_ptr = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;192192- else193193- tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;194194- } else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb),195195- par->family, &tuple)) {188188+ if (ct != NULL)189189+ tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;190190+ else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb),191191+ par->family, &tuple))196192 goto hotdrop;197197- }198193199194 if (par->family == NFPROTO_IPV6) {200195 const struct ipv6hdr *iph = ipv6_hdr(skb);···225228 unsigned int i;226229 int ret;227230228228- if (unlikely(!connlimit_rnd_inited)) {229229- get_random_bytes(&connlimit_rnd, sizeof(connlimit_rnd));230230- connlimit_rnd_inited = true;231231+ if (unlikely(!connlimit_rnd)) {232232+ u_int32_t rand;233233+234234+ do {235235+ get_random_bytes(&rand, sizeof(rand));236236+ } while (!rand);237237+ cmpxchg(&connlimit_rnd, 0, rand);231238 }232239 ret = nf_ct_l3proto_try_module_get(par->family);233240 if (ret < 0) {···249248250249 spin_lock_init(&info->data->lock);251250 for (i = 0; i < ARRAY_SIZE(info->data->iphash); ++i)252252- INIT_LIST_HEAD(&info->data->iphash[i]);251251+ INIT_HLIST_HEAD(&info->data->iphash[i]);253252254253 return 0;255254}···258257{259258 const struct xt_connlimit_info *info = par->matchinfo;260259 struct xt_connlimit_conn *conn;261261- struct xt_connlimit_conn *tmp;262262- struct list_head *hash = info->data->iphash;260260+ struct hlist_node *pos, *n;261261+ struct hlist_head *hash = info->data->iphash;263262 unsigned int i;264263265264 nf_ct_l3proto_module_put(par->family);266265267266 for (i = 0; i < ARRAY_SIZE(info->data->iphash); ++i) {268268- list_for_each_entry_safe(conn, tmp, &hash[i], list) {269269- list_del(&conn->list);267267+ hlist_for_each_entry_safe(conn, pos, n, &hash[i], node) {268268+ hlist_del(&conn->node);270269 kfree(conn);271270 }272271 }