Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6

Conflicts:
Documentation/feature-removal-schedule.txt

+844 -556
+9
Documentation/feature-removal-schedule.txt
··· 637 637 Who: Michal Hocko <mhocko@suse.cz> 638 638 639 639 ---------------------------- 640 + 641 + What: ipt_addrtype match include file 642 + When: 2012 643 + Why: superseded by xt_addrtype 644 + Who: Florian Westphal <fw@strlen.de> 645 + Files: include/linux/netfilter_ipv4/ipt_addrtype.h 646 + >>>>>>> 2f5dc63123905a89d4260ab8ee08d19ec104db04 647 + 648 + ----------------------------
+1
include/linux/netfilter/Kbuild
··· 29 29 header-y += xt_TCPOPTSTRIP.h 30 30 header-y += xt_TEE.h 31 31 header-y += xt_TPROXY.h 32 + header-y += xt_addrtype.h 32 33 header-y += xt_cluster.h 33 34 header-y += xt_comment.h 34 35 header-y += xt_connbytes.h
+44
include/linux/netfilter/xt_addrtype.h
··· 1 + #ifndef _XT_ADDRTYPE_H 2 + #define _XT_ADDRTYPE_H 3 + 4 + #include <linux/types.h> 5 + 6 + enum { 7 + XT_ADDRTYPE_INVERT_SOURCE = 0x0001, 8 + XT_ADDRTYPE_INVERT_DEST = 0x0002, 9 + XT_ADDRTYPE_LIMIT_IFACE_IN = 0x0004, 10 + XT_ADDRTYPE_LIMIT_IFACE_OUT = 0x0008, 11 + }; 12 + 13 + 14 + /* rtn_type enum values from rtnetlink.h, but shifted */ 15 + enum { 16 + XT_ADDRTYPE_UNSPEC = 1 << 0, 17 + XT_ADDRTYPE_UNICAST = 1 << 1, /* 1 << RTN_UNICAST */ 18 + XT_ADDRTYPE_LOCAL = 1 << 2, /* 1 << RTN_LOCAL, etc */ 19 + XT_ADDRTYPE_BROADCAST = 1 << 3, 20 + XT_ADDRTYPE_ANYCAST = 1 << 4, 21 + XT_ADDRTYPE_MULTICAST = 1 << 5, 22 + XT_ADDRTYPE_BLACKHOLE = 1 << 6, 23 + XT_ADDRTYPE_UNREACHABLE = 1 << 7, 24 + XT_ADDRTYPE_PROHIBIT = 1 << 8, 25 + XT_ADDRTYPE_THROW = 1 << 9, 26 + XT_ADDRTYPE_NAT = 1 << 10, 27 + XT_ADDRTYPE_XRESOLVE = 1 << 11, 28 + }; 29 + 30 + struct xt_addrtype_info_v1 { 31 + __u16 source; /* source-type mask */ 32 + __u16 dest; /* dest-type mask */ 33 + __u32 flags; 34 + }; 35 + 36 + /* revision 0 */ 37 + struct xt_addrtype_info { 38 + __u16 source; /* source-type mask */ 39 + __u16 dest; /* dest-type mask */ 40 + __u32 invert_source; 41 + __u32 invert_dest; 42 + }; 43 + 44 + #endif
+179 -19
include/net/ip_vs.h
··· 374 374 struct ip_vs_estimator est; /* estimator */ 375 375 struct ip_vs_cpu_stats *cpustats; /* per cpu counters */ 376 376 spinlock_t lock; /* spin lock */ 377 + struct ip_vs_stats_user ustats0; /* reset values */ 377 378 }; 378 - 379 - /* 380 - * Helper Macros for per cpu 381 - * ipvs->tot_stats->ustats.count 382 - */ 383 - #define IPVS_STAT_INC(ipvs, count) \ 384 - __this_cpu_inc((ipvs)->ustats->count) 385 - 386 - #define IPVS_STAT_ADD(ipvs, count, value) \ 387 - do {\ 388 - write_seqcount_begin(per_cpu_ptr((ipvs)->ustats_seq, \ 389 - raw_smp_processor_id())); \ 390 - __this_cpu_add((ipvs)->ustats->count, value); \ 391 - write_seqcount_end(per_cpu_ptr((ipvs)->ustats_seq, \ 392 - raw_smp_processor_id())); \ 393 - } while (0) 394 379 395 380 struct dst_entry; 396 381 struct iphdr; ··· 788 803 void (*timeout_change)(struct ip_vs_app *app, int flags); 789 804 }; 790 805 806 + /* IPVS in network namespace */ 807 + struct netns_ipvs { 808 + int gen; /* Generation */ 809 + /* 810 + * Hash table: for real service lookups 811 + */ 812 + #define IP_VS_RTAB_BITS 4 813 + #define IP_VS_RTAB_SIZE (1 << IP_VS_RTAB_BITS) 814 + #define IP_VS_RTAB_MASK (IP_VS_RTAB_SIZE - 1) 815 + 816 + struct list_head rs_table[IP_VS_RTAB_SIZE]; 817 + /* ip_vs_app */ 818 + struct list_head app_list; 819 + struct mutex app_mutex; 820 + struct lock_class_key app_key; /* mutex debuging */ 821 + 822 + /* ip_vs_proto */ 823 + #define IP_VS_PROTO_TAB_SIZE 32 /* must be power of 2 */ 824 + struct ip_vs_proto_data *proto_data_table[IP_VS_PROTO_TAB_SIZE]; 825 + /* ip_vs_proto_tcp */ 826 + #ifdef CONFIG_IP_VS_PROTO_TCP 827 + #define TCP_APP_TAB_BITS 4 828 + #define TCP_APP_TAB_SIZE (1 << TCP_APP_TAB_BITS) 829 + #define TCP_APP_TAB_MASK (TCP_APP_TAB_SIZE - 1) 830 + struct list_head tcp_apps[TCP_APP_TAB_SIZE]; 831 + spinlock_t tcp_app_lock; 832 + #endif 833 + /* ip_vs_proto_udp */ 834 + #ifdef CONFIG_IP_VS_PROTO_UDP 835 + #define UDP_APP_TAB_BITS 4 836 + #define UDP_APP_TAB_SIZE (1 << UDP_APP_TAB_BITS) 837 + #define UDP_APP_TAB_MASK (UDP_APP_TAB_SIZE - 1) 838 + struct list_head udp_apps[UDP_APP_TAB_SIZE]; 839 + spinlock_t udp_app_lock; 840 + #endif 841 + /* ip_vs_proto_sctp */ 842 + #ifdef CONFIG_IP_VS_PROTO_SCTP 843 + #define SCTP_APP_TAB_BITS 4 844 + #define SCTP_APP_TAB_SIZE (1 << SCTP_APP_TAB_BITS) 845 + #define SCTP_APP_TAB_MASK (SCTP_APP_TAB_SIZE - 1) 846 + /* Hash table for SCTP application incarnations */ 847 + struct list_head sctp_apps[SCTP_APP_TAB_SIZE]; 848 + spinlock_t sctp_app_lock; 849 + #endif 850 + /* ip_vs_conn */ 851 + atomic_t conn_count; /* connection counter */ 852 + 853 + /* ip_vs_ctl */ 854 + struct ip_vs_stats tot_stats; /* Statistics & est. */ 855 + 856 + int num_services; /* no of virtual services */ 857 + 858 + rwlock_t rs_lock; /* real services table */ 859 + /* semaphore for IPVS sockopts. And, [gs]etsockopt may sleep. */ 860 + struct lock_class_key ctl_key; /* ctl_mutex debuging */ 861 + /* Trash for destinations */ 862 + struct list_head dest_trash; 863 + /* Service counters */ 864 + atomic_t ftpsvc_counter; 865 + atomic_t nullsvc_counter; 866 + 867 + #ifdef CONFIG_SYSCTL 868 + /* 1/rate drop and drop-entry variables */ 869 + struct delayed_work defense_work; /* Work handler */ 870 + int drop_rate; 871 + int drop_counter; 872 + atomic_t dropentry; 873 + /* locks in ctl.c */ 874 + spinlock_t dropentry_lock; /* drop entry handling */ 875 + spinlock_t droppacket_lock; /* drop packet handling */ 876 + spinlock_t securetcp_lock; /* state and timeout tables */ 877 + 878 + /* sys-ctl struct */ 879 + struct ctl_table_header *sysctl_hdr; 880 + struct ctl_table *sysctl_tbl; 881 + #endif 882 + 883 + /* sysctl variables */ 884 + int sysctl_amemthresh; 885 + int sysctl_am_droprate; 886 + int sysctl_drop_entry; 887 + int sysctl_drop_packet; 888 + int sysctl_secure_tcp; 889 + #ifdef CONFIG_IP_VS_NFCT 890 + int sysctl_conntrack; 891 + #endif 892 + int sysctl_snat_reroute; 893 + int sysctl_sync_ver; 894 + int sysctl_cache_bypass; 895 + int sysctl_expire_nodest_conn; 896 + int sysctl_expire_quiescent_template; 897 + int sysctl_sync_threshold[2]; 898 + int sysctl_nat_icmp_send; 899 + 900 + /* ip_vs_lblc */ 901 + int sysctl_lblc_expiration; 902 + struct ctl_table_header *lblc_ctl_header; 903 + struct ctl_table *lblc_ctl_table; 904 + /* ip_vs_lblcr */ 905 + int sysctl_lblcr_expiration; 906 + struct ctl_table_header *lblcr_ctl_header; 907 + struct ctl_table *lblcr_ctl_table; 908 + /* ip_vs_est */ 909 + struct list_head est_list; /* estimator list */ 910 + spinlock_t est_lock; 911 + struct timer_list est_timer; /* Estimation timer */ 912 + /* ip_vs_sync */ 913 + struct list_head sync_queue; 914 + spinlock_t sync_lock; 915 + struct ip_vs_sync_buff *sync_buff; 916 + spinlock_t sync_buff_lock; 917 + struct sockaddr_in sync_mcast_addr; 918 + struct task_struct *master_thread; 919 + struct task_struct *backup_thread; 920 + int send_mesg_maxlen; 921 + int recv_mesg_maxlen; 922 + volatile int sync_state; 923 + volatile int master_syncid; 924 + volatile int backup_syncid; 925 + /* multicast interface name */ 926 + char master_mcast_ifn[IP_VS_IFNAME_MAXLEN]; 927 + char backup_mcast_ifn[IP_VS_IFNAME_MAXLEN]; 928 + /* net name space ptr */ 929 + struct net *net; /* Needed by timer routines */ 930 + }; 931 + 932 + #define DEFAULT_SYNC_THRESHOLD 3 933 + #define DEFAULT_SYNC_PERIOD 50 934 + #define DEFAULT_SYNC_VER 1 935 + 936 + #ifdef CONFIG_SYSCTL 937 + 938 + static inline int sysctl_sync_threshold(struct netns_ipvs *ipvs) 939 + { 940 + return ipvs->sysctl_sync_threshold[0]; 941 + } 942 + 943 + static inline int sysctl_sync_period(struct netns_ipvs *ipvs) 944 + { 945 + return ipvs->sysctl_sync_threshold[1]; 946 + } 947 + 948 + static inline int sysctl_sync_ver(struct netns_ipvs *ipvs) 949 + { 950 + return ipvs->sysctl_sync_ver; 951 + } 952 + 953 + #else 954 + 955 + static inline int sysctl_sync_threshold(struct netns_ipvs *ipvs) 956 + { 957 + return DEFAULT_SYNC_THRESHOLD; 958 + } 959 + 960 + static inline int sysctl_sync_period(struct netns_ipvs *ipvs) 961 + { 962 + return DEFAULT_SYNC_PERIOD; 963 + } 964 + 965 + static inline int sysctl_sync_ver(struct netns_ipvs *ipvs) 966 + { 967 + return DEFAULT_SYNC_VER; 968 + } 969 + 970 + #endif 791 971 792 972 /* 793 973 * IPVS core functions ··· 1221 1071 */ 1222 1072 extern int ip_vs_estimator_init(void); 1223 1073 extern void ip_vs_estimator_cleanup(void); 1224 - extern void ip_vs_new_estimator(struct net *net, struct ip_vs_stats *stats); 1225 - extern void ip_vs_kill_estimator(struct net *net, struct ip_vs_stats *stats); 1074 + extern void ip_vs_start_estimator(struct net *net, struct ip_vs_stats *stats); 1075 + extern void ip_vs_stop_estimator(struct net *net, struct ip_vs_stats *stats); 1226 1076 extern void ip_vs_zero_estimator(struct ip_vs_stats *stats); 1077 + extern void ip_vs_read_estimator(struct ip_vs_stats_user *dst, 1078 + struct ip_vs_stats *stats); 1227 1079 1228 1080 /* 1229 1081 * Various IPVS packet transmitters (from ip_vs_xmit.c) ··· 1258 1106 int offset); 1259 1107 #endif 1260 1108 1109 + #ifdef CONFIG_SYSCTL 1261 1110 /* 1262 1111 * This is a simple mechanism to ignore packets when 1263 1112 * we are loaded. Just set ip_vs_drop_rate to 'n' and ··· 1274 1121 ipvs->drop_counter = ipvs->drop_rate; 1275 1122 return 1; 1276 1123 } 1124 + #else 1125 + static inline int ip_vs_todrop(struct netns_ipvs *ipvs) { return 0; } 1126 + #endif 1277 1127 1278 1128 /* 1279 1129 * ip_vs_fwd_tag returns the forwarding tag of the connection ··· 1346 1190 { 1347 1191 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 1348 1192 enum ip_conntrack_info ctinfo; 1349 - struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo); 1193 + struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 1350 1194 1351 1195 if (!ct || !nf_ct_is_untracked(ct)) { 1352 1196 nf_reset(skb); ··· 1364 1208 */ 1365 1209 static inline int ip_vs_conntrack_enabled(struct netns_ipvs *ipvs) 1366 1210 { 1211 + #ifdef CONFIG_SYSCTL 1367 1212 return ipvs->sysctl_conntrack; 1213 + #else 1214 + return 0; 1215 + #endif 1368 1216 } 1369 1217 1370 1218 extern void ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp,
+1 -1
include/net/net_namespace.h
··· 20 20 #include <net/netns/conntrack.h> 21 21 #endif 22 22 #include <net/netns/xfrm.h> 23 - #include <net/netns/ip_vs.h> 24 23 25 24 struct proc_dir_entry; 26 25 struct net_device; ··· 27 28 struct ctl_table_header; 28 29 struct net_generic; 29 30 struct sock; 31 + struct netns_ipvs; 30 32 31 33 32 34 #define NETDEV_HASHBITS 8
-143
include/net/netns/ip_vs.h
··· 1 - /* 2 - * IP Virtual Server 3 - * Data structure for network namspace 4 - * 5 - */ 6 - 7 - #ifndef IP_VS_H_ 8 - #define IP_VS_H_ 9 - 10 - #include <linux/list.h> 11 - #include <linux/mutex.h> 12 - #include <linux/list_nulls.h> 13 - #include <linux/ip_vs.h> 14 - #include <asm/atomic.h> 15 - #include <linux/in.h> 16 - 17 - struct ip_vs_stats; 18 - struct ip_vs_sync_buff; 19 - struct ctl_table_header; 20 - 21 - struct netns_ipvs { 22 - int gen; /* Generation */ 23 - /* 24 - * Hash table: for real service lookups 25 - */ 26 - #define IP_VS_RTAB_BITS 4 27 - #define IP_VS_RTAB_SIZE (1 << IP_VS_RTAB_BITS) 28 - #define IP_VS_RTAB_MASK (IP_VS_RTAB_SIZE - 1) 29 - 30 - struct list_head rs_table[IP_VS_RTAB_SIZE]; 31 - /* ip_vs_app */ 32 - struct list_head app_list; 33 - struct mutex app_mutex; 34 - struct lock_class_key app_key; /* mutex debuging */ 35 - 36 - /* ip_vs_proto */ 37 - #define IP_VS_PROTO_TAB_SIZE 32 /* must be power of 2 */ 38 - struct ip_vs_proto_data *proto_data_table[IP_VS_PROTO_TAB_SIZE]; 39 - /* ip_vs_proto_tcp */ 40 - #ifdef CONFIG_IP_VS_PROTO_TCP 41 - #define TCP_APP_TAB_BITS 4 42 - #define TCP_APP_TAB_SIZE (1 << TCP_APP_TAB_BITS) 43 - #define TCP_APP_TAB_MASK (TCP_APP_TAB_SIZE - 1) 44 - struct list_head tcp_apps[TCP_APP_TAB_SIZE]; 45 - spinlock_t tcp_app_lock; 46 - #endif 47 - /* ip_vs_proto_udp */ 48 - #ifdef CONFIG_IP_VS_PROTO_UDP 49 - #define UDP_APP_TAB_BITS 4 50 - #define UDP_APP_TAB_SIZE (1 << UDP_APP_TAB_BITS) 51 - #define UDP_APP_TAB_MASK (UDP_APP_TAB_SIZE - 1) 52 - struct list_head udp_apps[UDP_APP_TAB_SIZE]; 53 - spinlock_t udp_app_lock; 54 - #endif 55 - /* ip_vs_proto_sctp */ 56 - #ifdef CONFIG_IP_VS_PROTO_SCTP 57 - #define SCTP_APP_TAB_BITS 4 58 - #define SCTP_APP_TAB_SIZE (1 << SCTP_APP_TAB_BITS) 59 - #define SCTP_APP_TAB_MASK (SCTP_APP_TAB_SIZE - 1) 60 - /* Hash table for SCTP application incarnations */ 61 - struct list_head sctp_apps[SCTP_APP_TAB_SIZE]; 62 - spinlock_t sctp_app_lock; 63 - #endif 64 - /* ip_vs_conn */ 65 - atomic_t conn_count; /* connection counter */ 66 - 67 - /* ip_vs_ctl */ 68 - struct ip_vs_stats *tot_stats; /* Statistics & est. */ 69 - struct ip_vs_cpu_stats __percpu *cpustats; /* Stats per cpu */ 70 - seqcount_t *ustats_seq; /* u64 read retry */ 71 - 72 - int num_services; /* no of virtual services */ 73 - /* 1/rate drop and drop-entry variables */ 74 - struct delayed_work defense_work; /* Work handler */ 75 - int drop_rate; 76 - int drop_counter; 77 - atomic_t dropentry; 78 - /* locks in ctl.c */ 79 - spinlock_t dropentry_lock; /* drop entry handling */ 80 - spinlock_t droppacket_lock; /* drop packet handling */ 81 - spinlock_t securetcp_lock; /* state and timeout tables */ 82 - rwlock_t rs_lock; /* real services table */ 83 - /* semaphore for IPVS sockopts. And, [gs]etsockopt may sleep. */ 84 - struct lock_class_key ctl_key; /* ctl_mutex debuging */ 85 - /* Trash for destinations */ 86 - struct list_head dest_trash; 87 - /* Service counters */ 88 - atomic_t ftpsvc_counter; 89 - atomic_t nullsvc_counter; 90 - 91 - /* sys-ctl struct */ 92 - struct ctl_table_header *sysctl_hdr; 93 - struct ctl_table *sysctl_tbl; 94 - /* sysctl variables */ 95 - int sysctl_amemthresh; 96 - int sysctl_am_droprate; 97 - int sysctl_drop_entry; 98 - int sysctl_drop_packet; 99 - int sysctl_secure_tcp; 100 - #ifdef CONFIG_IP_VS_NFCT 101 - int sysctl_conntrack; 102 - #endif 103 - int sysctl_snat_reroute; 104 - int sysctl_sync_ver; 105 - int sysctl_cache_bypass; 106 - int sysctl_expire_nodest_conn; 107 - int sysctl_expire_quiescent_template; 108 - int sysctl_sync_threshold[2]; 109 - int sysctl_nat_icmp_send; 110 - 111 - /* ip_vs_lblc */ 112 - int sysctl_lblc_expiration; 113 - struct ctl_table_header *lblc_ctl_header; 114 - struct ctl_table *lblc_ctl_table; 115 - /* ip_vs_lblcr */ 116 - int sysctl_lblcr_expiration; 117 - struct ctl_table_header *lblcr_ctl_header; 118 - struct ctl_table *lblcr_ctl_table; 119 - /* ip_vs_est */ 120 - struct list_head est_list; /* estimator list */ 121 - spinlock_t est_lock; 122 - struct timer_list est_timer; /* Estimation timer */ 123 - /* ip_vs_sync */ 124 - struct list_head sync_queue; 125 - spinlock_t sync_lock; 126 - struct ip_vs_sync_buff *sync_buff; 127 - spinlock_t sync_buff_lock; 128 - struct sockaddr_in sync_mcast_addr; 129 - struct task_struct *master_thread; 130 - struct task_struct *backup_thread; 131 - int send_mesg_maxlen; 132 - int recv_mesg_maxlen; 133 - volatile int sync_state; 134 - volatile int master_syncid; 135 - volatile int backup_syncid; 136 - /* multicast interface name */ 137 - char master_mcast_ifn[IP_VS_IFNAME_MAXLEN]; 138 - char backup_mcast_ifn[IP_VS_IFNAME_MAXLEN]; 139 - /* net name space ptr */ 140 - struct net *net; /* Needed by timer routines */ 141 - }; 142 - 143 - #endif /* IP_VS_H_ */
-10
net/ipv4/netfilter/Kconfig
··· 64 64 if IP_NF_IPTABLES 65 65 66 66 # The matches. 67 - config IP_NF_MATCH_ADDRTYPE 68 - tristate '"addrtype" address type match support' 69 - depends on NETFILTER_ADVANCED 70 - help 71 - This option allows you to match what routing thinks of an address, 72 - eg. UNICAST, LOCAL, BROADCAST, ... 73 - 74 - If you want to compile it as a module, say M here and read 75 - <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. 76 - 77 67 config IP_NF_MATCH_AH 78 68 tristate '"ah" match support' 79 69 depends on NETFILTER_ADVANCED
-1
net/ipv4/netfilter/Makefile
··· 48 48 obj-$(CONFIG_IP_NF_SECURITY) += iptable_security.o 49 49 50 50 # matches 51 - obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o 52 51 obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o 53 52 obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o 54 53
+3
net/ipv4/netfilter/arp_tables.c
··· 1066 1066 /* overflow check */ 1067 1067 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) 1068 1068 return -ENOMEM; 1069 + tmp.name[sizeof(tmp.name)-1] = 0; 1069 1070 1070 1071 newinfo = xt_alloc_table_info(tmp.size); 1071 1072 if (!newinfo) ··· 1489 1488 return -ENOMEM; 1490 1489 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) 1491 1490 return -ENOMEM; 1491 + tmp.name[sizeof(tmp.name)-1] = 0; 1492 1492 1493 1493 newinfo = xt_alloc_table_info(tmp.size); 1494 1494 if (!newinfo) ··· 1742 1740 ret = -EFAULT; 1743 1741 break; 1744 1742 } 1743 + rev.name[sizeof(rev.name)-1] = 0; 1745 1744 1746 1745 try_then_request_module(xt_find_revision(NFPROTO_ARP, rev.name, 1747 1746 rev.revision, 1, &ret),
+3
net/ipv4/netfilter/ip_tables.c
··· 1262 1262 /* overflow check */ 1263 1263 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) 1264 1264 return -ENOMEM; 1265 + tmp.name[sizeof(tmp.name)-1] = 0; 1265 1266 1266 1267 newinfo = xt_alloc_table_info(tmp.size); 1267 1268 if (!newinfo) ··· 1808 1807 return -ENOMEM; 1809 1808 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) 1810 1809 return -ENOMEM; 1810 + tmp.name[sizeof(tmp.name)-1] = 0; 1811 1811 1812 1812 newinfo = xt_alloc_table_info(tmp.size); 1813 1813 if (!newinfo) ··· 2038 2036 ret = -EFAULT; 2039 2037 break; 2040 2038 } 2039 + rev.name[sizeof(rev.name)-1] = 0; 2041 2040 2042 2041 if (cmd == IPT_SO_GET_REVISION_TARGET) 2043 2042 target = 1;
-134
net/ipv4/netfilter/ipt_addrtype.c
··· 1 - /* 2 - * iptables module to match inet_addr_type() of an ip. 3 - * 4 - * Copyright (c) 2004 Patrick McHardy <kaber@trash.net> 5 - * (C) 2007 Laszlo Attila Toth <panther@balabit.hu> 6 - * 7 - * This program is free software; you can redistribute it and/or modify 8 - * it under the terms of the GNU General Public License version 2 as 9 - * published by the Free Software Foundation. 10 - */ 11 - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 12 - #include <linux/kernel.h> 13 - #include <linux/module.h> 14 - #include <linux/skbuff.h> 15 - #include <linux/netdevice.h> 16 - #include <linux/ip.h> 17 - #include <net/route.h> 18 - 19 - #include <linux/netfilter_ipv4/ipt_addrtype.h> 20 - #include <linux/netfilter/x_tables.h> 21 - 22 - MODULE_LICENSE("GPL"); 23 - MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 24 - MODULE_DESCRIPTION("Xtables: address type match for IPv4"); 25 - 26 - static inline bool match_type(struct net *net, const struct net_device *dev, 27 - __be32 addr, u_int16_t mask) 28 - { 29 - return !!(mask & (1 << inet_dev_addr_type(net, dev, addr))); 30 - } 31 - 32 - static bool 33 - addrtype_mt_v0(const struct sk_buff *skb, struct xt_action_param *par) 34 - { 35 - struct net *net = dev_net(par->in ? par->in : par->out); 36 - const struct ipt_addrtype_info *info = par->matchinfo; 37 - const struct iphdr *iph = ip_hdr(skb); 38 - bool ret = true; 39 - 40 - if (info->source) 41 - ret &= match_type(net, NULL, iph->saddr, info->source) ^ 42 - info->invert_source; 43 - if (info->dest) 44 - ret &= match_type(net, NULL, iph->daddr, info->dest) ^ 45 - info->invert_dest; 46 - 47 - return ret; 48 - } 49 - 50 - static bool 51 - addrtype_mt_v1(const struct sk_buff *skb, struct xt_action_param *par) 52 - { 53 - struct net *net = dev_net(par->in ? par->in : par->out); 54 - const struct ipt_addrtype_info_v1 *info = par->matchinfo; 55 - const struct iphdr *iph = ip_hdr(skb); 56 - const struct net_device *dev = NULL; 57 - bool ret = true; 58 - 59 - if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) 60 - dev = par->in; 61 - else if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) 62 - dev = par->out; 63 - 64 - if (info->source) 65 - ret &= match_type(net, dev, iph->saddr, info->source) ^ 66 - (info->flags & IPT_ADDRTYPE_INVERT_SOURCE); 67 - if (ret && info->dest) 68 - ret &= match_type(net, dev, iph->daddr, info->dest) ^ 69 - !!(info->flags & IPT_ADDRTYPE_INVERT_DEST); 70 - return ret; 71 - } 72 - 73 - static int addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par) 74 - { 75 - struct ipt_addrtype_info_v1 *info = par->matchinfo; 76 - 77 - if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN && 78 - info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { 79 - pr_info("both incoming and outgoing " 80 - "interface limitation cannot be selected\n"); 81 - return -EINVAL; 82 - } 83 - 84 - if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) | 85 - (1 << NF_INET_LOCAL_IN)) && 86 - info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { 87 - pr_info("output interface limitation " 88 - "not valid in PREROUTING and INPUT\n"); 89 - return -EINVAL; 90 - } 91 - 92 - if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) | 93 - (1 << NF_INET_LOCAL_OUT)) && 94 - info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) { 95 - pr_info("input interface limitation " 96 - "not valid in POSTROUTING and OUTPUT\n"); 97 - return -EINVAL; 98 - } 99 - 100 - return 0; 101 - } 102 - 103 - static struct xt_match addrtype_mt_reg[] __read_mostly = { 104 - { 105 - .name = "addrtype", 106 - .family = NFPROTO_IPV4, 107 - .match = addrtype_mt_v0, 108 - .matchsize = sizeof(struct ipt_addrtype_info), 109 - .me = THIS_MODULE 110 - }, 111 - { 112 - .name = "addrtype", 113 - .family = NFPROTO_IPV4, 114 - .revision = 1, 115 - .match = addrtype_mt_v1, 116 - .checkentry = addrtype_mt_checkentry_v1, 117 - .matchsize = sizeof(struct ipt_addrtype_info_v1), 118 - .me = THIS_MODULE 119 - } 120 - }; 121 - 122 - static int __init addrtype_mt_init(void) 123 - { 124 - return xt_register_matches(addrtype_mt_reg, 125 - ARRAY_SIZE(addrtype_mt_reg)); 126 - } 127 - 128 - static void __exit addrtype_mt_exit(void) 129 - { 130 - xt_unregister_matches(addrtype_mt_reg, ARRAY_SIZE(addrtype_mt_reg)); 131 - } 132 - 133 - module_init(addrtype_mt_init); 134 - module_exit(addrtype_mt_exit);
+3
net/ipv6/netfilter/ip6_tables.c
··· 1275 1275 /* overflow check */ 1276 1276 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) 1277 1277 return -ENOMEM; 1278 + tmp.name[sizeof(tmp.name)-1] = 0; 1278 1279 1279 1280 newinfo = xt_alloc_table_info(tmp.size); 1280 1281 if (!newinfo) ··· 1823 1822 return -ENOMEM; 1824 1823 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) 1825 1824 return -ENOMEM; 1825 + tmp.name[sizeof(tmp.name)-1] = 0; 1826 1826 1827 1827 newinfo = xt_alloc_table_info(tmp.size); 1828 1828 if (!newinfo) ··· 2053 2051 ret = -EFAULT; 2054 2052 break; 2055 2053 } 2054 + rev.name[sizeof(rev.name)-1] = 0; 2056 2055 2057 2056 if (cmd == IP6T_SO_GET_REVISION_TARGET) 2058 2057 target = 1;
+11
net/netfilter/Kconfig
··· 649 649 650 650 comment "Xtables matches" 651 651 652 + config NETFILTER_XT_MATCH_ADDRTYPE 653 + tristate '"addrtype" address type match support' 654 + depends on NETFILTER_ADVANCED 655 + depends on (IPV6 || IPV6=n) 656 + ---help--- 657 + This option allows you to match what routing thinks of an address, 658 + eg. UNICAST, LOCAL, BROADCAST, ... 659 + 660 + If you want to compile it as a module, say M here and read 661 + <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. 662 + 652 663 config NETFILTER_XT_MATCH_CLUSTER 653 664 tristate '"cluster" match support' 654 665 depends on NF_CONNTRACK
+1
net/netfilter/Makefile
··· 70 70 obj-$(CONFIG_NETFILTER_XT_TARGET_IDLETIMER) += xt_IDLETIMER.o 71 71 72 72 # matches 73 + obj-$(CONFIG_NETFILTER_XT_MATCH_ADDRTYPE) += xt_addrtype.o 73 74 obj-$(CONFIG_NETFILTER_XT_MATCH_CLUSTER) += xt_cluster.o 74 75 obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o 75 76 obj-$(CONFIG_NETFILTER_XT_MATCH_CONNBYTES) += xt_connbytes.o
+1 -1
net/netfilter/ipset/ip_set_core.c
··· 612 612 const struct nlmsghdr *nlh, 613 613 const struct nlattr * const attr[]) 614 614 { 615 - struct ip_set *set, *clash; 615 + struct ip_set *set, *clash = NULL; 616 616 ip_set_id_t index = IPSET_INVALID_ID; 617 617 struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1] = {}; 618 618 const char *name, *typename;
+11 -2
net/netfilter/ipvs/ip_vs_conn.c
··· 680 680 atomic_dec(&dest->refcnt); 681 681 } 682 682 683 + static int expire_quiescent_template(struct netns_ipvs *ipvs, 684 + struct ip_vs_dest *dest) 685 + { 686 + #ifdef CONFIG_SYSCTL 687 + return ipvs->sysctl_expire_quiescent_template && 688 + (atomic_read(&dest->weight) == 0); 689 + #else 690 + return 0; 691 + #endif 692 + } 683 693 684 694 /* 685 695 * Checking if the destination of a connection template is available. ··· 706 696 */ 707 697 if ((dest == NULL) || 708 698 !(dest->flags & IP_VS_DEST_F_AVAILABLE) || 709 - (ipvs->sysctl_expire_quiescent_template && 710 - (atomic_read(&dest->weight) == 0))) { 699 + expire_quiescent_template(ipvs, dest)) { 711 700 IP_VS_DBG_BUF(9, "check_template: dest not available for " 712 701 "protocol %s s:%s:%d v:%s:%d " 713 702 "-> d:%s:%d\n",
+64 -40
net/netfilter/ipvs/ip_vs_core.c
··· 132 132 s->ustats.inbytes += skb->len; 133 133 u64_stats_update_end(&s->syncp); 134 134 135 - s = this_cpu_ptr(ipvs->cpustats); 135 + s = this_cpu_ptr(ipvs->tot_stats.cpustats); 136 136 s->ustats.inpkts++; 137 137 u64_stats_update_begin(&s->syncp); 138 138 s->ustats.inbytes += skb->len; ··· 162 162 s->ustats.outbytes += skb->len; 163 163 u64_stats_update_end(&s->syncp); 164 164 165 - s = this_cpu_ptr(ipvs->cpustats); 165 + s = this_cpu_ptr(ipvs->tot_stats.cpustats); 166 166 s->ustats.outpkts++; 167 167 u64_stats_update_begin(&s->syncp); 168 168 s->ustats.outbytes += skb->len; ··· 183 183 s = this_cpu_ptr(svc->stats.cpustats); 184 184 s->ustats.conns++; 185 185 186 - s = this_cpu_ptr(ipvs->cpustats); 186 + s = this_cpu_ptr(ipvs->tot_stats.cpustats); 187 187 s->ustats.conns++; 188 188 } 189 189 ··· 499 499 int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, 500 500 struct ip_vs_proto_data *pd) 501 501 { 502 - struct net *net; 503 - struct netns_ipvs *ipvs; 504 502 __be16 _ports[2], *pptr; 505 503 struct ip_vs_iphdr iph; 504 + #ifdef CONFIG_SYSCTL 505 + struct net *net; 506 + struct netns_ipvs *ipvs; 506 507 int unicast; 508 + #endif 507 509 508 510 ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph); 509 511 ··· 514 512 ip_vs_service_put(svc); 515 513 return NF_DROP; 516 514 } 515 + 516 + #ifdef CONFIG_SYSCTL 517 517 net = skb_net(skb); 518 518 519 519 #ifdef CONFIG_IP_VS_IPV6 ··· 567 563 ip_vs_conn_put(cp); 568 564 return ret; 569 565 } 566 + #endif 570 567 571 568 /* 572 569 * When the virtual ftp service is presented, packets destined ··· 604 599 return NF_DROP; 605 600 } 606 601 602 + #ifdef CONFIG_SYSCTL 603 + 604 + static int sysctl_snat_reroute(struct sk_buff *skb) 605 + { 606 + struct netns_ipvs *ipvs = net_ipvs(skb_net(skb)); 607 + return ipvs->sysctl_snat_reroute; 608 + } 609 + 610 + static int sysctl_nat_icmp_send(struct net *net) 611 + { 612 + struct netns_ipvs *ipvs = net_ipvs(net); 613 + return ipvs->sysctl_nat_icmp_send; 614 + } 615 + 616 + static int sysctl_expire_nodest_conn(struct netns_ipvs *ipvs) 617 + { 618 + return ipvs->sysctl_expire_nodest_conn; 619 + } 620 + 621 + #else 622 + 623 + static int sysctl_snat_reroute(struct sk_buff *skb) { return 0; } 624 + static int sysctl_nat_icmp_send(struct net *net) { return 0; } 625 + static int sysctl_expire_nodest_conn(struct netns_ipvs *ipvs) { return 0; } 626 + 627 + #endif 628 + 607 629 __sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset) 608 630 { 609 631 return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0)); ··· 662 630 return 0; 663 631 } 664 632 #endif 633 + 634 + static int ip_vs_route_me_harder(int af, struct sk_buff *skb) 635 + { 636 + #ifdef CONFIG_IP_VS_IPV6 637 + if (af == AF_INET6) { 638 + if (sysctl_snat_reroute(skb) && ip6_route_me_harder(skb) != 0) 639 + return 1; 640 + } else 641 + #endif 642 + if ((sysctl_snat_reroute(skb) || 643 + skb_rtable(skb)->rt_flags & RTCF_LOCAL) && 644 + ip_route_me_harder(skb, RTN_LOCAL) != 0) 645 + return 1; 646 + 647 + return 0; 648 + } 665 649 666 650 /* 667 651 * Packet has been made sufficiently writable in caller ··· 785 737 struct ip_vs_protocol *pp, 786 738 unsigned int offset, unsigned int ihl) 787 739 { 788 - struct netns_ipvs *ipvs; 789 740 unsigned int verdict = NF_DROP; 790 741 791 742 if (IP_VS_FWD_METHOD(cp) != 0) { ··· 806 759 if (!skb_make_writable(skb, offset)) 807 760 goto out; 808 761 809 - ipvs = net_ipvs(skb_net(skb)); 810 - 811 762 #ifdef CONFIG_IP_VS_IPV6 812 763 if (af == AF_INET6) 813 764 ip_vs_nat_icmp_v6(skb, pp, cp, 1); ··· 813 768 #endif 814 769 ip_vs_nat_icmp(skb, pp, cp, 1); 815 770 816 - #ifdef CONFIG_IP_VS_IPV6 817 - if (af == AF_INET6) { 818 - if (ipvs->sysctl_snat_reroute && ip6_route_me_harder(skb) != 0) 819 - goto out; 820 - } else 821 - #endif 822 - if ((ipvs->sysctl_snat_reroute || 823 - skb_rtable(skb)->rt_flags & RTCF_LOCAL) && 824 - ip_route_me_harder(skb, RTN_LOCAL) != 0) 825 - goto out; 771 + if (ip_vs_route_me_harder(af, skb)) 772 + goto out; 826 773 827 774 /* do the statistics and put it back */ 828 775 ip_vs_out_stats(cp, skb); ··· 1022 985 struct ip_vs_conn *cp, int ihl) 1023 986 { 1024 987 struct ip_vs_protocol *pp = pd->pp; 1025 - struct netns_ipvs *ipvs; 1026 988 1027 989 IP_VS_DBG_PKT(11, af, pp, skb, 0, "Outgoing packet"); 1028 990 ··· 1057 1021 * if it came from this machine itself. So re-compute 1058 1022 * the routing information. 1059 1023 */ 1060 - ipvs = net_ipvs(skb_net(skb)); 1061 - 1062 - #ifdef CONFIG_IP_VS_IPV6 1063 - if (af == AF_INET6) { 1064 - if (ipvs->sysctl_snat_reroute && ip6_route_me_harder(skb) != 0) 1065 - goto drop; 1066 - } else 1067 - #endif 1068 - if ((ipvs->sysctl_snat_reroute || 1069 - skb_rtable(skb)->rt_flags & RTCF_LOCAL) && 1070 - ip_route_me_harder(skb, RTN_LOCAL) != 0) 1071 - goto drop; 1024 + if (ip_vs_route_me_harder(af, skb)) 1025 + goto drop; 1072 1026 1073 1027 IP_VS_DBG_PKT(10, af, pp, skb, 0, "After SNAT"); 1074 1028 ··· 1092 1066 struct ip_vs_protocol *pp; 1093 1067 struct ip_vs_proto_data *pd; 1094 1068 struct ip_vs_conn *cp; 1095 - struct netns_ipvs *ipvs; 1096 1069 1097 1070 EnterFunction(11); 1098 1071 ··· 1166 1141 * Check if the packet belongs to an existing entry 1167 1142 */ 1168 1143 cp = pp->conn_out_get(af, skb, &iph, iph.len, 0); 1169 - ipvs = net_ipvs(net); 1170 1144 1171 1145 if (likely(cp)) 1172 1146 return handle_response(af, skb, pd, cp, iph.len); 1173 - if (ipvs->sysctl_nat_icmp_send && 1147 + if (sysctl_nat_icmp_send(net) && 1174 1148 (pp->protocol == IPPROTO_TCP || 1175 1149 pp->protocol == IPPROTO_UDP || 1176 1150 pp->protocol == IPPROTO_SCTP)) { ··· 1594 1570 if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) { 1595 1571 /* the destination server is not available */ 1596 1572 1597 - if (ipvs->sysctl_expire_nodest_conn) { 1573 + if (sysctl_expire_nodest_conn(ipvs)) { 1598 1574 /* try to expire the connection immediately */ 1599 1575 ip_vs_conn_expire_now(cp); 1600 1576 } ··· 1624 1600 */ 1625 1601 1626 1602 if (cp->flags & IP_VS_CONN_F_ONE_PACKET) 1627 - pkts = ipvs->sysctl_sync_threshold[0]; 1603 + pkts = sysctl_sync_threshold(ipvs); 1628 1604 else 1629 1605 pkts = atomic_add_return(1, &cp->in_pkts); 1630 1606 1631 1607 if ((ipvs->sync_state & IP_VS_STATE_MASTER) && 1632 1608 cp->protocol == IPPROTO_SCTP) { 1633 1609 if ((cp->state == IP_VS_SCTP_S_ESTABLISHED && 1634 - (pkts % ipvs->sysctl_sync_threshold[1] 1635 - == ipvs->sysctl_sync_threshold[0])) || 1610 + (pkts % sysctl_sync_period(ipvs) 1611 + == sysctl_sync_threshold(ipvs))) || 1636 1612 (cp->old_state != cp->state && 1637 1613 ((cp->state == IP_VS_SCTP_S_CLOSED) || 1638 1614 (cp->state == IP_VS_SCTP_S_SHUT_ACK_CLI) || ··· 1646 1622 else if ((ipvs->sync_state & IP_VS_STATE_MASTER) && 1647 1623 (((cp->protocol != IPPROTO_TCP || 1648 1624 cp->state == IP_VS_TCP_S_ESTABLISHED) && 1649 - (pkts % ipvs->sysctl_sync_threshold[1] 1650 - == ipvs->sysctl_sync_threshold[0])) || 1625 + (pkts % sysctl_sync_period(ipvs) 1626 + == sysctl_sync_threshold(ipvs))) || 1651 1627 ((cp->protocol == IPPROTO_TCP) && (cp->old_state != cp->state) && 1652 1628 ((cp->state == IP_VS_TCP_S_FIN_WAIT) || 1653 1629 (cp->state == IP_VS_TCP_S_CLOSE) ||
+152 -104
net/netfilter/ipvs/ip_vs_ctl.c
··· 86 86 return 0; 87 87 } 88 88 #endif 89 + 90 + #ifdef CONFIG_SYSCTL 89 91 /* 90 92 * update_defense_level is called from keventd and from sysctl, 91 93 * so it needs to protect itself from softirqs ··· 229 227 ip_vs_random_dropentry(ipvs->net); 230 228 schedule_delayed_work(&ipvs->defense_work, DEFENSE_TIMER_PERIOD); 231 229 } 230 + #endif 232 231 233 232 int 234 233 ip_vs_use_count_inc(void) ··· 412 409 /* 413 410 * Check the table hashed by fwmark first 414 411 */ 415 - svc = __ip_vs_svc_fwm_find(net, af, fwmark); 416 - if (fwmark && svc) 417 - goto out; 412 + if (fwmark) { 413 + svc = __ip_vs_svc_fwm_find(net, af, fwmark); 414 + if (svc) 415 + goto out; 416 + } 418 417 419 418 /* 420 419 * Check the table hashed by <protocol,addr,port> ··· 712 707 } 713 708 } 714 709 710 + static void 711 + ip_vs_copy_stats(struct ip_vs_stats_user *dst, struct ip_vs_stats *src) 712 + { 713 + #define IP_VS_SHOW_STATS_COUNTER(c) dst->c = src->ustats.c - src->ustats0.c 714 + 715 + spin_lock_bh(&src->lock); 716 + 717 + IP_VS_SHOW_STATS_COUNTER(conns); 718 + IP_VS_SHOW_STATS_COUNTER(inpkts); 719 + IP_VS_SHOW_STATS_COUNTER(outpkts); 720 + IP_VS_SHOW_STATS_COUNTER(inbytes); 721 + IP_VS_SHOW_STATS_COUNTER(outbytes); 722 + 723 + ip_vs_read_estimator(dst, src); 724 + 725 + spin_unlock_bh(&src->lock); 726 + } 715 727 716 728 static void 717 729 ip_vs_zero_stats(struct ip_vs_stats *stats) 718 730 { 719 731 spin_lock_bh(&stats->lock); 720 732 721 - memset(&stats->ustats, 0, sizeof(stats->ustats)); 733 + /* get current counters as zero point, rates are zeroed */ 734 + 735 + #define IP_VS_ZERO_STATS_COUNTER(c) stats->ustats0.c = stats->ustats.c 736 + 737 + IP_VS_ZERO_STATS_COUNTER(conns); 738 + IP_VS_ZERO_STATS_COUNTER(inpkts); 739 + IP_VS_ZERO_STATS_COUNTER(outpkts); 740 + IP_VS_ZERO_STATS_COUNTER(inbytes); 741 + IP_VS_ZERO_STATS_COUNTER(outbytes); 742 + 722 743 ip_vs_zero_estimator(stats); 723 744 724 745 spin_unlock_bh(&stats->lock); ··· 803 772 spin_unlock_bh(&dest->dst_lock); 804 773 805 774 if (add) 806 - ip_vs_new_estimator(svc->net, &dest->stats); 775 + ip_vs_start_estimator(svc->net, &dest->stats); 807 776 808 777 write_lock_bh(&__ip_vs_svc_lock); 809 778 ··· 1009 978 { 1010 979 struct netns_ipvs *ipvs = net_ipvs(net); 1011 980 1012 - ip_vs_kill_estimator(net, &dest->stats); 981 + ip_vs_stop_estimator(net, &dest->stats); 1013 982 1014 983 /* 1015 984 * Remove it from the d-linked list with the real services. ··· 1202 1171 else if (svc->port == 0) 1203 1172 atomic_inc(&ipvs->nullsvc_counter); 1204 1173 1205 - ip_vs_new_estimator(net, &svc->stats); 1174 + ip_vs_start_estimator(net, &svc->stats); 1206 1175 1207 1176 /* Count only IPv4 services for old get/setsockopt interface */ 1208 1177 if (svc->af == AF_INET) ··· 1354 1323 if (svc->af == AF_INET) 1355 1324 ipvs->num_services--; 1356 1325 1357 - ip_vs_kill_estimator(svc->net, &svc->stats); 1326 + ip_vs_stop_estimator(svc->net, &svc->stats); 1358 1327 1359 1328 /* Unbind scheduler */ 1360 1329 old_sched = svc->scheduler; ··· 1508 1477 } 1509 1478 } 1510 1479 1511 - ip_vs_zero_stats(net_ipvs(net)->tot_stats); 1480 + ip_vs_zero_stats(&net_ipvs(net)->tot_stats); 1512 1481 return 0; 1513 1482 } 1514 1483 1515 - 1484 + #ifdef CONFIG_SYSCTL 1516 1485 static int 1517 1486 proc_do_defense_mode(ctl_table *table, int write, 1518 1487 void __user *buffer, size_t *lenp, loff_t *ppos) ··· 1533 1502 } 1534 1503 return rc; 1535 1504 } 1536 - 1537 1505 1538 1506 static int 1539 1507 proc_do_sync_threshold(ctl_table *table, int write, ··· 1767 1737 { } 1768 1738 }; 1769 1739 EXPORT_SYMBOL_GPL(net_vs_ctl_path); 1740 + #endif 1770 1741 1771 1742 #ifdef CONFIG_PROC_FS 1772 1743 ··· 1990 1959 static int ip_vs_stats_show(struct seq_file *seq, void *v) 1991 1960 { 1992 1961 struct net *net = seq_file_single_net(seq); 1993 - struct ip_vs_stats *tot_stats = net_ipvs(net)->tot_stats; 1962 + struct ip_vs_stats_user show; 1994 1963 1995 1964 /* 01234567 01234567 01234567 0123456701234567 0123456701234567 */ 1996 1965 seq_puts(seq, ··· 1998 1967 seq_printf(seq, 1999 1968 " Conns Packets Packets Bytes Bytes\n"); 2000 1969 2001 - spin_lock_bh(&tot_stats->lock); 2002 - seq_printf(seq, "%8X %8X %8X %16LX %16LX\n\n", tot_stats->ustats.conns, 2003 - tot_stats->ustats.inpkts, tot_stats->ustats.outpkts, 2004 - (unsigned long long) tot_stats->ustats.inbytes, 2005 - (unsigned long long) tot_stats->ustats.outbytes); 1970 + ip_vs_copy_stats(&show, &net_ipvs(net)->tot_stats); 1971 + seq_printf(seq, "%8X %8X %8X %16LX %16LX\n\n", show.conns, 1972 + show.inpkts, show.outpkts, 1973 + (unsigned long long) show.inbytes, 1974 + (unsigned long long) show.outbytes); 2006 1975 2007 1976 /* 01234567 01234567 01234567 0123456701234567 0123456701234567 */ 2008 1977 seq_puts(seq, 2009 1978 " Conns/s Pkts/s Pkts/s Bytes/s Bytes/s\n"); 2010 - seq_printf(seq,"%8X %8X %8X %16X %16X\n", 2011 - tot_stats->ustats.cps, 2012 - tot_stats->ustats.inpps, 2013 - tot_stats->ustats.outpps, 2014 - tot_stats->ustats.inbps, 2015 - tot_stats->ustats.outbps); 2016 - spin_unlock_bh(&tot_stats->lock); 1979 + seq_printf(seq, "%8X %8X %8X %16X %16X\n", 1980 + show.cps, show.inpps, show.outpps, 1981 + show.inbps, show.outbps); 2017 1982 2018 1983 return 0; 2019 1984 } ··· 2030 2003 static int ip_vs_stats_percpu_show(struct seq_file *seq, void *v) 2031 2004 { 2032 2005 struct net *net = seq_file_single_net(seq); 2033 - struct ip_vs_stats *tot_stats = net_ipvs(net)->tot_stats; 2006 + struct ip_vs_stats *tot_stats = &net_ipvs(net)->tot_stats; 2007 + struct ip_vs_cpu_stats *cpustats = tot_stats->cpustats; 2008 + struct ip_vs_stats_user rates; 2034 2009 int i; 2035 2010 2036 2011 /* 01234567 01234567 01234567 0123456701234567 0123456701234567 */ ··· 2042 2013 "CPU Conns Packets Packets Bytes Bytes\n"); 2043 2014 2044 2015 for_each_possible_cpu(i) { 2045 - struct ip_vs_cpu_stats *u = per_cpu_ptr(net->ipvs->cpustats, i); 2016 + struct ip_vs_cpu_stats *u = per_cpu_ptr(cpustats, i); 2017 + unsigned int start; 2018 + __u64 inbytes, outbytes; 2019 + 2020 + do { 2021 + start = u64_stats_fetch_begin_bh(&u->syncp); 2022 + inbytes = u->ustats.inbytes; 2023 + outbytes = u->ustats.outbytes; 2024 + } while (u64_stats_fetch_retry_bh(&u->syncp, start)); 2025 + 2046 2026 seq_printf(seq, "%3X %8X %8X %8X %16LX %16LX\n", 2047 - i, u->ustats.conns, u->ustats.inpkts, 2048 - u->ustats.outpkts, (__u64)u->ustats.inbytes, 2049 - (__u64)u->ustats.outbytes); 2027 + i, u->ustats.conns, u->ustats.inpkts, 2028 + u->ustats.outpkts, (__u64)inbytes, 2029 + (__u64)outbytes); 2050 2030 } 2051 2031 2052 2032 spin_lock_bh(&tot_stats->lock); 2033 + 2053 2034 seq_printf(seq, " ~ %8X %8X %8X %16LX %16LX\n\n", 2054 2035 tot_stats->ustats.conns, tot_stats->ustats.inpkts, 2055 2036 tot_stats->ustats.outpkts, 2056 2037 (unsigned long long) tot_stats->ustats.inbytes, 2057 2038 (unsigned long long) tot_stats->ustats.outbytes); 2058 2039 2040 + ip_vs_read_estimator(&rates, tot_stats); 2041 + 2042 + spin_unlock_bh(&tot_stats->lock); 2043 + 2059 2044 /* 01234567 01234567 01234567 0123456701234567 0123456701234567 */ 2060 2045 seq_puts(seq, 2061 2046 " Conns/s Pkts/s Pkts/s Bytes/s Bytes/s\n"); 2062 2047 seq_printf(seq, " %8X %8X %8X %16X %16X\n", 2063 - tot_stats->ustats.cps, 2064 - tot_stats->ustats.inpps, 2065 - tot_stats->ustats.outpps, 2066 - tot_stats->ustats.inbps, 2067 - tot_stats->ustats.outbps); 2068 - spin_unlock_bh(&tot_stats->lock); 2048 + rates.cps, 2049 + rates.inpps, 2050 + rates.outpps, 2051 + rates.inbps, 2052 + rates.outbps); 2069 2053 2070 2054 return 0; 2071 2055 } ··· 2324 2282 return ret; 2325 2283 } 2326 2284 2327 - 2328 - static void 2329 - ip_vs_copy_stats(struct ip_vs_stats_user *dst, struct ip_vs_stats *src) 2330 - { 2331 - spin_lock_bh(&src->lock); 2332 - memcpy(dst, &src->ustats, sizeof(*dst)); 2333 - spin_unlock_bh(&src->lock); 2334 - } 2335 2285 2336 2286 static void 2337 2287 ip_vs_copy_service(struct ip_vs_service_entry *dst, struct ip_vs_service *src) ··· 2711 2677 static int ip_vs_genl_fill_stats(struct sk_buff *skb, int container_type, 2712 2678 struct ip_vs_stats *stats) 2713 2679 { 2680 + struct ip_vs_stats_user ustats; 2714 2681 struct nlattr *nl_stats = nla_nest_start(skb, container_type); 2715 2682 if (!nl_stats) 2716 2683 return -EMSGSIZE; 2717 2684 2718 - spin_lock_bh(&stats->lock); 2685 + ip_vs_copy_stats(&ustats, stats); 2719 2686 2720 - NLA_PUT_U32(skb, IPVS_STATS_ATTR_CONNS, stats->ustats.conns); 2721 - NLA_PUT_U32(skb, IPVS_STATS_ATTR_INPKTS, stats->ustats.inpkts); 2722 - NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTPKTS, stats->ustats.outpkts); 2723 - NLA_PUT_U64(skb, IPVS_STATS_ATTR_INBYTES, stats->ustats.inbytes); 2724 - NLA_PUT_U64(skb, IPVS_STATS_ATTR_OUTBYTES, stats->ustats.outbytes); 2725 - NLA_PUT_U32(skb, IPVS_STATS_ATTR_CPS, stats->ustats.cps); 2726 - NLA_PUT_U32(skb, IPVS_STATS_ATTR_INPPS, stats->ustats.inpps); 2727 - NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTPPS, stats->ustats.outpps); 2728 - NLA_PUT_U32(skb, IPVS_STATS_ATTR_INBPS, stats->ustats.inbps); 2729 - NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTBPS, stats->ustats.outbps); 2730 - 2731 - spin_unlock_bh(&stats->lock); 2687 + NLA_PUT_U32(skb, IPVS_STATS_ATTR_CONNS, ustats.conns); 2688 + NLA_PUT_U32(skb, IPVS_STATS_ATTR_INPKTS, ustats.inpkts); 2689 + NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTPKTS, ustats.outpkts); 2690 + NLA_PUT_U64(skb, IPVS_STATS_ATTR_INBYTES, ustats.inbytes); 2691 + NLA_PUT_U64(skb, IPVS_STATS_ATTR_OUTBYTES, ustats.outbytes); 2692 + NLA_PUT_U32(skb, IPVS_STATS_ATTR_CPS, ustats.cps); 2693 + NLA_PUT_U32(skb, IPVS_STATS_ATTR_INPPS, ustats.inpps); 2694 + NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTPPS, ustats.outpps); 2695 + NLA_PUT_U32(skb, IPVS_STATS_ATTR_INBPS, ustats.inbps); 2696 + NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTBPS, ustats.outbps); 2732 2697 2733 2698 nla_nest_end(skb, nl_stats); 2734 2699 2735 2700 return 0; 2736 2701 2737 2702 nla_put_failure: 2738 - spin_unlock_bh(&stats->lock); 2739 2703 nla_nest_cancel(skb, nl_stats); 2740 2704 return -EMSGSIZE; 2741 2705 } ··· 3512 3480 /* 3513 3481 * per netns intit/exit func. 3514 3482 */ 3515 - int __net_init __ip_vs_control_init(struct net *net) 3483 + #ifdef CONFIG_SYSCTL 3484 + int __net_init __ip_vs_control_init_sysctl(struct net *net) 3516 3485 { 3517 3486 int idx; 3518 3487 struct netns_ipvs *ipvs = net_ipvs(net); ··· 3523 3490 spin_lock_init(&ipvs->dropentry_lock); 3524 3491 spin_lock_init(&ipvs->droppacket_lock); 3525 3492 spin_lock_init(&ipvs->securetcp_lock); 3526 - ipvs->rs_lock = __RW_LOCK_UNLOCKED(ipvs->rs_lock); 3527 - 3528 - /* Initialize rs_table */ 3529 - for (idx = 0; idx < IP_VS_RTAB_SIZE; idx++) 3530 - INIT_LIST_HEAD(&ipvs->rs_table[idx]); 3531 - 3532 - INIT_LIST_HEAD(&ipvs->dest_trash); 3533 - atomic_set(&ipvs->ftpsvc_counter, 0); 3534 - atomic_set(&ipvs->nullsvc_counter, 0); 3535 - 3536 - /* procfs stats */ 3537 - ipvs->tot_stats = kzalloc(sizeof(struct ip_vs_stats), GFP_KERNEL); 3538 - if (ipvs->tot_stats == NULL) { 3539 - pr_err("%s(): no memory.\n", __func__); 3540 - return -ENOMEM; 3541 - } 3542 - ipvs->cpustats = alloc_percpu(struct ip_vs_cpu_stats); 3543 - if (!ipvs->cpustats) { 3544 - pr_err("%s() alloc_percpu failed\n", __func__); 3545 - goto err_alloc; 3546 - } 3547 - spin_lock_init(&ipvs->tot_stats->lock); 3548 - 3549 - proc_net_fops_create(net, "ip_vs", 0, &ip_vs_info_fops); 3550 - proc_net_fops_create(net, "ip_vs_stats", 0, &ip_vs_stats_fops); 3551 - proc_net_fops_create(net, "ip_vs_stats_percpu", 0, 3552 - &ip_vs_stats_percpu_fops); 3553 3493 3554 3494 if (!net_eq(net, &init_net)) { 3555 3495 tbl = kmemdup(vs_vars, sizeof(vs_vars), GFP_KERNEL); 3556 3496 if (tbl == NULL) 3557 - goto err_dup; 3497 + return -ENOMEM; 3558 3498 } else 3559 3499 tbl = vs_vars; 3560 3500 /* Initialize sysctl defaults */ ··· 3549 3543 tbl[idx++].data = &ipvs->sysctl_cache_bypass; 3550 3544 tbl[idx++].data = &ipvs->sysctl_expire_nodest_conn; 3551 3545 tbl[idx++].data = &ipvs->sysctl_expire_quiescent_template; 3552 - ipvs->sysctl_sync_threshold[0] = 3; 3553 - ipvs->sysctl_sync_threshold[1] = 50; 3546 + ipvs->sysctl_sync_threshold[0] = DEFAULT_SYNC_THRESHOLD; 3547 + ipvs->sysctl_sync_threshold[1] = DEFAULT_SYNC_PERIOD; 3554 3548 tbl[idx].data = &ipvs->sysctl_sync_threshold; 3555 3549 tbl[idx++].maxlen = sizeof(ipvs->sysctl_sync_threshold); 3556 3550 tbl[idx++].data = &ipvs->sysctl_nat_icmp_send; 3557 3551 3558 3552 3559 - #ifdef CONFIG_SYSCTL 3560 3553 ipvs->sysctl_hdr = register_net_sysctl_table(net, net_vs_ctl_path, 3561 3554 tbl); 3562 3555 if (ipvs->sysctl_hdr == NULL) { 3563 3556 if (!net_eq(net, &init_net)) 3564 3557 kfree(tbl); 3565 - goto err_dup; 3558 + return -ENOMEM; 3566 3559 } 3567 - #endif 3568 - ip_vs_new_estimator(net, ipvs->tot_stats); 3560 + ip_vs_start_estimator(net, &ipvs->tot_stats); 3569 3561 ipvs->sysctl_tbl = tbl; 3570 3562 /* Schedule defense work */ 3571 3563 INIT_DELAYED_WORK(&ipvs->defense_work, defense_work_handler); 3572 3564 schedule_delayed_work(&ipvs->defense_work, DEFENSE_TIMER_PERIOD); 3565 + 3566 + return 0; 3567 + } 3568 + 3569 + void __net_init __ip_vs_control_cleanup_sysctl(struct net *net) 3570 + { 3571 + struct netns_ipvs *ipvs = net_ipvs(net); 3572 + 3573 + cancel_delayed_work_sync(&ipvs->defense_work); 3574 + cancel_work_sync(&ipvs->defense_work.work); 3575 + unregister_net_sysctl_table(ipvs->sysctl_hdr); 3576 + } 3577 + 3578 + #else 3579 + 3580 + int __net_init __ip_vs_control_init_sysctl(struct net *net) { return 0; } 3581 + void __net_init __ip_vs_control_cleanup_sysctl(struct net *net) { } 3582 + 3583 + #endif 3584 + 3585 + int __net_init __ip_vs_control_init(struct net *net) 3586 + { 3587 + int idx; 3588 + struct netns_ipvs *ipvs = net_ipvs(net); 3589 + 3590 + ipvs->rs_lock = __RW_LOCK_UNLOCKED(ipvs->rs_lock); 3591 + 3592 + /* Initialize rs_table */ 3593 + for (idx = 0; idx < IP_VS_RTAB_SIZE; idx++) 3594 + INIT_LIST_HEAD(&ipvs->rs_table[idx]); 3595 + 3596 + INIT_LIST_HEAD(&ipvs->dest_trash); 3597 + atomic_set(&ipvs->ftpsvc_counter, 0); 3598 + atomic_set(&ipvs->nullsvc_counter, 0); 3599 + 3600 + /* procfs stats */ 3601 + ipvs->tot_stats.cpustats = alloc_percpu(struct ip_vs_cpu_stats); 3602 + if (ipvs->tot_stats.cpustats) { 3603 + pr_err("%s(): alloc_percpu.\n", __func__); 3604 + return -ENOMEM; 3605 + } 3606 + spin_lock_init(&ipvs->tot_stats.lock); 3607 + 3608 + proc_net_fops_create(net, "ip_vs", 0, &ip_vs_info_fops); 3609 + proc_net_fops_create(net, "ip_vs_stats", 0, &ip_vs_stats_fops); 3610 + proc_net_fops_create(net, "ip_vs_stats_percpu", 0, 3611 + &ip_vs_stats_percpu_fops); 3612 + 3613 + if (__ip_vs_control_init_sysctl(net)) 3614 + goto err; 3615 + 3573 3616 return 0; 3574 3617 3575 - err_dup: 3576 - free_percpu(ipvs->cpustats); 3577 - err_alloc: 3578 - kfree(ipvs->tot_stats); 3618 + err: 3619 + free_percpu(ipvs->tot_stats.cpustats); 3579 3620 return -ENOMEM; 3580 3621 } 3581 3622 ··· 3631 3578 struct netns_ipvs *ipvs = net_ipvs(net); 3632 3579 3633 3580 ip_vs_trash_cleanup(net); 3634 - ip_vs_kill_estimator(net, ipvs->tot_stats); 3635 - cancel_delayed_work_sync(&ipvs->defense_work); 3636 - cancel_work_sync(&ipvs->defense_work.work); 3637 - #ifdef CONFIG_SYSCTL 3638 - unregister_net_sysctl_table(ipvs->sysctl_hdr); 3639 - #endif 3581 + ip_vs_stop_estimator(net, &ipvs->tot_stats); 3582 + __ip_vs_control_cleanup_sysctl(net); 3640 3583 proc_net_remove(net, "ip_vs_stats_percpu"); 3641 3584 proc_net_remove(net, "ip_vs_stats"); 3642 3585 proc_net_remove(net, "ip_vs"); 3643 - free_percpu(ipvs->cpustats); 3644 - kfree(ipvs->tot_stats); 3586 + free_percpu(ipvs->tot_stats.cpustats); 3645 3587 } 3646 3588 3647 3589 static struct pernet_operations ipvs_control_ops = {
+27 -34
net/netfilter/ipvs/ip_vs_est.c
··· 69 69 sum->inpkts += s->ustats.inpkts; 70 70 sum->outpkts += s->ustats.outpkts; 71 71 do { 72 - start = u64_stats_fetch_begin_bh(&s->syncp); 72 + start = u64_stats_fetch_begin(&s->syncp); 73 73 inbytes = s->ustats.inbytes; 74 74 outbytes = s->ustats.outbytes; 75 - } while (u64_stats_fetch_retry_bh(&s->syncp, start)); 75 + } while (u64_stats_fetch_retry(&s->syncp, start)); 76 76 sum->inbytes += inbytes; 77 77 sum->outbytes += outbytes; 78 78 } else { ··· 80 80 sum->inpkts = s->ustats.inpkts; 81 81 sum->outpkts = s->ustats.outpkts; 82 82 do { 83 - start = u64_stats_fetch_begin_bh(&s->syncp); 83 + start = u64_stats_fetch_begin(&s->syncp); 84 84 sum->inbytes = s->ustats.inbytes; 85 85 sum->outbytes = s->ustats.outbytes; 86 - } while (u64_stats_fetch_retry_bh(&s->syncp, start)); 86 + } while (u64_stats_fetch_retry(&s->syncp, start)); 87 87 } 88 88 } 89 89 } ··· 101 101 struct netns_ipvs *ipvs; 102 102 103 103 ipvs = net_ipvs(net); 104 - ip_vs_read_cpu_stats(&ipvs->tot_stats->ustats, ipvs->cpustats); 105 104 spin_lock(&ipvs->est_lock); 106 105 list_for_each_entry(e, &ipvs->est_list, list) { 107 106 s = container_of(e, struct ip_vs_stats, est); 108 107 109 - ip_vs_read_cpu_stats(&s->ustats, s->cpustats); 110 108 spin_lock(&s->lock); 109 + ip_vs_read_cpu_stats(&s->ustats, s->cpustats); 111 110 n_conns = s->ustats.conns; 112 111 n_inpkts = s->ustats.inpkts; 113 112 n_outpkts = s->ustats.outpkts; ··· 117 118 rate = (n_conns - e->last_conns) << 9; 118 119 e->last_conns = n_conns; 119 120 e->cps += ((long)rate - (long)e->cps) >> 2; 120 - s->ustats.cps = (e->cps + 0x1FF) >> 10; 121 121 122 122 rate = (n_inpkts - e->last_inpkts) << 9; 123 123 e->last_inpkts = n_inpkts; 124 124 e->inpps += ((long)rate - (long)e->inpps) >> 2; 125 - s->ustats.inpps = (e->inpps + 0x1FF) >> 10; 126 125 127 126 rate = (n_outpkts - e->last_outpkts) << 9; 128 127 e->last_outpkts = n_outpkts; 129 128 e->outpps += ((long)rate - (long)e->outpps) >> 2; 130 - s->ustats.outpps = (e->outpps + 0x1FF) >> 10; 131 129 132 130 rate = (n_inbytes - e->last_inbytes) << 4; 133 131 e->last_inbytes = n_inbytes; 134 132 e->inbps += ((long)rate - (long)e->inbps) >> 2; 135 - s->ustats.inbps = (e->inbps + 0xF) >> 5; 136 133 137 134 rate = (n_outbytes - e->last_outbytes) << 4; 138 135 e->last_outbytes = n_outbytes; 139 136 e->outbps += ((long)rate - (long)e->outbps) >> 2; 140 - s->ustats.outbps = (e->outbps + 0xF) >> 5; 141 137 spin_unlock(&s->lock); 142 138 } 143 139 spin_unlock(&ipvs->est_lock); 144 140 mod_timer(&ipvs->est_timer, jiffies + 2*HZ); 145 141 } 146 142 147 - void ip_vs_new_estimator(struct net *net, struct ip_vs_stats *stats) 143 + void ip_vs_start_estimator(struct net *net, struct ip_vs_stats *stats) 148 144 { 149 145 struct netns_ipvs *ipvs = net_ipvs(net); 150 146 struct ip_vs_estimator *est = &stats->est; 151 147 152 148 INIT_LIST_HEAD(&est->list); 153 149 154 - est->last_conns = stats->ustats.conns; 155 - est->cps = stats->ustats.cps<<10; 156 - 157 - est->last_inpkts = stats->ustats.inpkts; 158 - est->inpps = stats->ustats.inpps<<10; 159 - 160 - est->last_outpkts = stats->ustats.outpkts; 161 - est->outpps = stats->ustats.outpps<<10; 162 - 163 - est->last_inbytes = stats->ustats.inbytes; 164 - est->inbps = stats->ustats.inbps<<5; 165 - 166 - est->last_outbytes = stats->ustats.outbytes; 167 - est->outbps = stats->ustats.outbps<<5; 168 - 169 150 spin_lock_bh(&ipvs->est_lock); 170 151 list_add(&est->list, &ipvs->est_list); 171 152 spin_unlock_bh(&ipvs->est_lock); 172 153 } 173 154 174 - void ip_vs_kill_estimator(struct net *net, struct ip_vs_stats *stats) 155 + void ip_vs_stop_estimator(struct net *net, struct ip_vs_stats *stats) 175 156 { 176 157 struct netns_ipvs *ipvs = net_ipvs(net); 177 158 struct ip_vs_estimator *est = &stats->est; ··· 164 185 void ip_vs_zero_estimator(struct ip_vs_stats *stats) 165 186 { 166 187 struct ip_vs_estimator *est = &stats->est; 188 + struct ip_vs_stats_user *u = &stats->ustats; 167 189 168 - /* set counters zero, caller must hold the stats->lock lock */ 169 - est->last_inbytes = 0; 170 - est->last_outbytes = 0; 171 - est->last_conns = 0; 172 - est->last_inpkts = 0; 173 - est->last_outpkts = 0; 190 + /* reset counters, caller must hold the stats->lock lock */ 191 + est->last_inbytes = u->inbytes; 192 + est->last_outbytes = u->outbytes; 193 + est->last_conns = u->conns; 194 + est->last_inpkts = u->inpkts; 195 + est->last_outpkts = u->outpkts; 174 196 est->cps = 0; 175 197 est->inpps = 0; 176 198 est->outpps = 0; 177 199 est->inbps = 0; 178 200 est->outbps = 0; 201 + } 202 + 203 + /* Get decoded rates */ 204 + void ip_vs_read_estimator(struct ip_vs_stats_user *dst, 205 + struct ip_vs_stats *stats) 206 + { 207 + struct ip_vs_estimator *e = &stats->est; 208 + 209 + dst->cps = (e->cps + 0x1FF) >> 10; 210 + dst->inpps = (e->inpps + 0x1FF) >> 10; 211 + dst->outpps = (e->outpps + 0x1FF) >> 10; 212 + dst->inbps = (e->inbps + 0xF) >> 5; 213 + dst->outbps = (e->outbps + 0xF) >> 5; 179 214 } 180 215 181 216 static int __net_init __ip_vs_estimator_init(struct net *net)
+23 -8
net/netfilter/ipvs/ip_vs_lblc.c
··· 63 63 #define CHECK_EXPIRE_INTERVAL (60*HZ) 64 64 #define ENTRY_TIMEOUT (6*60*HZ) 65 65 66 + #define DEFAULT_EXPIRATION (24*60*60*HZ) 67 + 66 68 /* 67 69 * It is for full expiration check. 68 70 * When there is no partial expiration check (garbage collection) ··· 114 112 /* 115 113 * IPVS LBLC sysctl table 116 114 */ 117 - 115 + #ifdef CONFIG_SYSCTL 118 116 static ctl_table vs_vars_table[] = { 119 117 { 120 118 .procname = "lblc_expiration", ··· 125 123 }, 126 124 { } 127 125 }; 126 + #endif 128 127 129 128 static inline void ip_vs_lblc_free(struct ip_vs_lblc_entry *en) 130 129 { ··· 241 238 } 242 239 } 243 240 241 + static int sysctl_lblc_expiration(struct ip_vs_service *svc) 242 + { 243 + #ifdef CONFIG_SYSCTL 244 + struct netns_ipvs *ipvs = net_ipvs(svc->net); 245 + return ipvs->sysctl_lblc_expiration; 246 + #else 247 + return DEFAULT_EXPIRATION; 248 + #endif 249 + } 244 250 245 251 static inline void ip_vs_lblc_full_check(struct ip_vs_service *svc) 246 252 { ··· 257 245 struct ip_vs_lblc_entry *en, *nxt; 258 246 unsigned long now = jiffies; 259 247 int i, j; 260 - struct netns_ipvs *ipvs = net_ipvs(svc->net); 261 248 262 249 for (i=0, j=tbl->rover; i<IP_VS_LBLC_TAB_SIZE; i++) { 263 250 j = (j + 1) & IP_VS_LBLC_TAB_MASK; ··· 265 254 list_for_each_entry_safe(en, nxt, &tbl->bucket[j], list) { 266 255 if (time_before(now, 267 256 en->lastuse + 268 - ipvs->sysctl_lblc_expiration)) 257 + sysctl_lblc_expiration(svc))) 269 258 continue; 270 259 271 260 ip_vs_lblc_free(en); ··· 549 538 /* 550 539 * per netns init. 551 540 */ 541 + #ifdef CONFIG_SYSCTL 552 542 static int __net_init __ip_vs_lblc_init(struct net *net) 553 543 { 554 544 struct netns_ipvs *ipvs = net_ipvs(net); ··· 562 550 return -ENOMEM; 563 551 } else 564 552 ipvs->lblc_ctl_table = vs_vars_table; 565 - ipvs->sysctl_lblc_expiration = 24*60*60*HZ; 553 + ipvs->sysctl_lblc_expiration = DEFAULT_EXPIRATION; 566 554 ipvs->lblc_ctl_table[0].data = &ipvs->sysctl_lblc_expiration; 567 555 568 - #ifdef CONFIG_SYSCTL 569 556 ipvs->lblc_ctl_header = 570 557 register_net_sysctl_table(net, net_vs_ctl_path, 571 558 ipvs->lblc_ctl_table); ··· 573 562 kfree(ipvs->lblc_ctl_table); 574 563 return -ENOMEM; 575 564 } 576 - #endif 577 565 578 566 return 0; 579 567 } ··· 581 571 { 582 572 struct netns_ipvs *ipvs = net_ipvs(net); 583 573 584 - #ifdef CONFIG_SYSCTL 585 574 unregister_net_sysctl_table(ipvs->lblc_ctl_header); 586 - #endif 587 575 588 576 if (!net_eq(net, &init_net)) 589 577 kfree(ipvs->lblc_ctl_table); 590 578 } 579 + 580 + #else 581 + 582 + static int __net_init __ip_vs_lblc_init(struct net *net) { return 0; } 583 + static void __net_exit __ip_vs_lblc_exit(struct net *net) { } 584 + 585 + #endif 591 586 592 587 static struct pernet_operations ip_vs_lblc_ops = { 593 588 .init = __ip_vs_lblc_init,
+25 -10
net/netfilter/ipvs/ip_vs_lblcr.c
··· 63 63 #define CHECK_EXPIRE_INTERVAL (60*HZ) 64 64 #define ENTRY_TIMEOUT (6*60*HZ) 65 65 66 + #define DEFAULT_EXPIRATION (24*60*60*HZ) 67 + 66 68 /* 67 69 * It is for full expiration check. 68 70 * When there is no partial expiration check (garbage collection) ··· 285 283 }; 286 284 287 285 286 + #ifdef CONFIG_SYSCTL 288 287 /* 289 288 * IPVS LBLCR sysctl table 290 289 */ ··· 300 297 }, 301 298 { } 302 299 }; 300 + #endif 303 301 304 302 static inline void ip_vs_lblcr_free(struct ip_vs_lblcr_entry *en) 305 303 { ··· 414 410 } 415 411 } 416 412 413 + static int sysctl_lblcr_expiration(struct ip_vs_service *svc) 414 + { 415 + #ifdef CONFIG_SYSCTL 416 + struct netns_ipvs *ipvs = net_ipvs(svc->net); 417 + return ipvs->sysctl_lblcr_expiration; 418 + #else 419 + return DEFAULT_EXPIRATION; 420 + #endif 421 + } 417 422 418 423 static inline void ip_vs_lblcr_full_check(struct ip_vs_service *svc) 419 424 { ··· 430 417 unsigned long now = jiffies; 431 418 int i, j; 432 419 struct ip_vs_lblcr_entry *en, *nxt; 433 - struct netns_ipvs *ipvs = net_ipvs(svc->net); 434 420 435 421 for (i=0, j=tbl->rover; i<IP_VS_LBLCR_TAB_SIZE; i++) { 436 422 j = (j + 1) & IP_VS_LBLCR_TAB_MASK; 437 423 438 424 write_lock(&svc->sched_lock); 439 425 list_for_each_entry_safe(en, nxt, &tbl->bucket[j], list) { 440 - if (time_after(en->lastuse 441 - + ipvs->sysctl_lblcr_expiration, now)) 426 + if (time_after(en->lastuse + 427 + sysctl_lblcr_expiration(svc), now)) 442 428 continue; 443 429 444 430 ip_vs_lblcr_free(en); ··· 662 650 read_lock(&svc->sched_lock); 663 651 en = ip_vs_lblcr_get(svc->af, tbl, &iph.daddr); 664 652 if (en) { 665 - struct netns_ipvs *ipvs = net_ipvs(svc->net); 666 653 /* We only hold a read lock, but this is atomic */ 667 654 en->lastuse = jiffies; 668 655 ··· 673 662 /* More than one destination + enough time passed by, cleanup */ 674 663 if (atomic_read(&en->set.size) > 1 && 675 664 time_after(jiffies, en->set.lastmod + 676 - ipvs->sysctl_lblcr_expiration)) { 665 + sysctl_lblcr_expiration(svc))) { 677 666 struct ip_vs_dest *m; 678 667 679 668 write_lock(&en->set.lock); ··· 745 734 /* 746 735 * per netns init. 747 736 */ 737 + #ifdef CONFIG_SYSCTL 748 738 static int __net_init __ip_vs_lblcr_init(struct net *net) 749 739 { 750 740 struct netns_ipvs *ipvs = net_ipvs(net); ··· 758 746 return -ENOMEM; 759 747 } else 760 748 ipvs->lblcr_ctl_table = vs_vars_table; 761 - ipvs->sysctl_lblcr_expiration = 24*60*60*HZ; 749 + ipvs->sysctl_lblcr_expiration = DEFAULT_EXPIRATION; 762 750 ipvs->lblcr_ctl_table[0].data = &ipvs->sysctl_lblcr_expiration; 763 751 764 - #ifdef CONFIG_SYSCTL 765 752 ipvs->lblcr_ctl_header = 766 753 register_net_sysctl_table(net, net_vs_ctl_path, 767 754 ipvs->lblcr_ctl_table); ··· 769 758 kfree(ipvs->lblcr_ctl_table); 770 759 return -ENOMEM; 771 760 } 772 - #endif 773 761 774 762 return 0; 775 763 } ··· 777 767 { 778 768 struct netns_ipvs *ipvs = net_ipvs(net); 779 769 780 - #ifdef CONFIG_SYSCTL 781 770 unregister_net_sysctl_table(ipvs->lblcr_ctl_header); 782 - #endif 783 771 784 772 if (!net_eq(net, &init_net)) 785 773 kfree(ipvs->lblcr_ctl_table); 786 774 } 775 + 776 + #else 777 + 778 + static int __net_init __ip_vs_lblcr_init(struct net *net) { return 0; } 779 + static void __net_exit __ip_vs_lblcr_exit(struct net *net) { } 780 + 781 + #endif 787 782 788 783 static struct pernet_operations ip_vs_lblcr_ops = { 789 784 .init = __ip_vs_lblcr_init,
+4 -5
net/netfilter/ipvs/ip_vs_pe_sip.c
··· 92 92 if (get_callid(dptr, dataoff, datalen, &matchoff, &matchlen)) 93 93 return -EINVAL; 94 94 95 - p->pe_data = kmalloc(matchlen, GFP_ATOMIC); 96 - if (!p->pe_data) 97 - return -ENOMEM; 98 - 99 95 /* N.B: pe_data is only set on success, 100 96 * this allows fallback to the default persistence logic on failure 101 97 */ 102 - memcpy(p->pe_data, dptr + matchoff, matchlen); 98 + p->pe_data = kmemdup(dptr + matchoff, matchlen, GFP_ATOMIC); 99 + if (!p->pe_data) 100 + return -ENOMEM; 101 + 103 102 p->pe_data_len = matchlen; 104 103 105 104 return 0;
+5 -6
net/netfilter/ipvs/ip_vs_sync.c
··· 394 394 395 395 if (!(ipvs->sync_state & IP_VS_STATE_MASTER)) 396 396 return; 397 - if (mode == ipvs->sysctl_sync_ver || !ipvs->sync_buff) 397 + if (mode == sysctl_sync_ver(ipvs) || !ipvs->sync_buff) 398 398 return; 399 399 400 400 spin_lock_bh(&ipvs->sync_buff_lock); ··· 521 521 unsigned int len, pe_name_len, pad; 522 522 523 523 /* Handle old version of the protocol */ 524 - if (ipvs->sysctl_sync_ver == 0) { 524 + if (sysctl_sync_ver(ipvs) == 0) { 525 525 ip_vs_sync_conn_v0(net, cp); 526 526 return; 527 527 } ··· 650 650 if (cp->flags & IP_VS_CONN_F_TEMPLATE) { 651 651 int pkts = atomic_add_return(1, &cp->in_pkts); 652 652 653 - if (pkts % ipvs->sysctl_sync_threshold[1] != 1) 653 + if (pkts % sysctl_sync_period(ipvs) != 1) 654 654 return; 655 655 } 656 656 goto sloop; ··· 697 697 return 1; 698 698 } 699 699 700 - p->pe_data = kmalloc(pe_data_len, GFP_ATOMIC); 700 + p->pe_data = kmemdup(pe_data, pe_data_len, GFP_ATOMIC); 701 701 if (!p->pe_data) { 702 702 if (p->pe->module) 703 703 module_put(p->pe->module); 704 704 return -ENOMEM; 705 705 } 706 - memcpy(p->pe_data, pe_data, pe_data_len); 707 706 p->pe_data_len = pe_data_len; 708 707 } 709 708 return 0; ··· 794 795 795 796 if (opt) 796 797 memcpy(&cp->in_seq, opt, sizeof(*opt)); 797 - atomic_set(&cp->in_pkts, ipvs->sysctl_sync_threshold[0]); 798 + atomic_set(&cp->in_pkts, sysctl_sync_threshold(ipvs)); 798 799 cp->state = state; 799 800 cp->old_state = cp->state; 800 801 /*
+1
net/netfilter/nf_conntrack_core.c
··· 1301 1301 1302 1302 nf_ct_free_hashtable(net->ct.hash, net->ct.htable_size); 1303 1303 nf_conntrack_ecache_fini(net); 1304 + nf_conntrack_tstamp_fini(net); 1304 1305 nf_conntrack_acct_fini(net); 1305 1306 nf_conntrack_expect_fini(net); 1306 1307 kmem_cache_destroy(net->ct.nf_conntrack_cachep);
+17 -9
net/netfilter/x_tables.c
··· 183 183 /* 184 184 * These are weird, but module loading must not be done with mutex 185 185 * held (since they will register), and we have to have a single 186 - * function to use try_then_request_module(). 186 + * function to use. 187 187 */ 188 188 189 189 /* Find match, grabs ref. Returns ERR_PTR() on error. */ 190 190 struct xt_match *xt_find_match(u8 af, const char *name, u8 revision) 191 191 { 192 192 struct xt_match *m; 193 - int err = 0; 193 + int err = -ENOENT; 194 194 195 195 if (mutex_lock_interruptible(&xt[af].mutex) != 0) 196 196 return ERR_PTR(-EINTR); ··· 221 221 { 222 222 struct xt_match *match; 223 223 224 - match = try_then_request_module(xt_find_match(nfproto, name, revision), 225 - "%st_%s", xt_prefix[nfproto], name); 226 - return (match != NULL) ? match : ERR_PTR(-ENOENT); 224 + match = xt_find_match(nfproto, name, revision); 225 + if (IS_ERR(match)) { 226 + request_module("%st_%s", xt_prefix[nfproto], name); 227 + match = xt_find_match(nfproto, name, revision); 228 + } 229 + 230 + return match; 227 231 } 228 232 EXPORT_SYMBOL_GPL(xt_request_find_match); 229 233 ··· 235 231 struct xt_target *xt_find_target(u8 af, const char *name, u8 revision) 236 232 { 237 233 struct xt_target *t; 238 - int err = 0; 234 + int err = -ENOENT; 239 235 240 236 if (mutex_lock_interruptible(&xt[af].mutex) != 0) 241 237 return ERR_PTR(-EINTR); ··· 265 261 { 266 262 struct xt_target *target; 267 263 268 - target = try_then_request_module(xt_find_target(af, name, revision), 269 - "%st_%s", xt_prefix[af], name); 270 - return (target != NULL) ? target : ERR_PTR(-ENOENT); 264 + target = xt_find_target(af, name, revision); 265 + if (IS_ERR(target)) { 266 + request_module("%st_%s", xt_prefix[af], name); 267 + target = xt_find_target(af, name, revision); 268 + } 269 + 270 + return target; 271 271 } 272 272 EXPORT_SYMBOL_GPL(xt_request_find_target); 273 273
+229
net/netfilter/xt_addrtype.c
··· 1 + /* 2 + * iptables module to match inet_addr_type() of an ip. 3 + * 4 + * Copyright (c) 2004 Patrick McHardy <kaber@trash.net> 5 + * (C) 2007 Laszlo Attila Toth <panther@balabit.hu> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + */ 11 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 12 + #include <linux/kernel.h> 13 + #include <linux/module.h> 14 + #include <linux/skbuff.h> 15 + #include <linux/netdevice.h> 16 + #include <linux/ip.h> 17 + #include <net/route.h> 18 + 19 + #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) 20 + #include <net/ipv6.h> 21 + #include <net/ip6_route.h> 22 + #include <net/ip6_fib.h> 23 + #endif 24 + 25 + #include <linux/netfilter/xt_addrtype.h> 26 + #include <linux/netfilter/x_tables.h> 27 + 28 + MODULE_LICENSE("GPL"); 29 + MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 30 + MODULE_DESCRIPTION("Xtables: address type match"); 31 + MODULE_ALIAS("ipt_addrtype"); 32 + MODULE_ALIAS("ip6t_addrtype"); 33 + 34 + #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) 35 + static u32 xt_addrtype_rt6_to_type(const struct rt6_info *rt) 36 + { 37 + u32 ret; 38 + 39 + if (!rt) 40 + return XT_ADDRTYPE_UNREACHABLE; 41 + 42 + if (rt->rt6i_flags & RTF_REJECT) 43 + ret = XT_ADDRTYPE_UNREACHABLE; 44 + else 45 + ret = 0; 46 + 47 + if (rt->rt6i_flags & RTF_LOCAL) 48 + ret |= XT_ADDRTYPE_LOCAL; 49 + if (rt->rt6i_flags & RTF_ANYCAST) 50 + ret |= XT_ADDRTYPE_ANYCAST; 51 + return ret; 52 + } 53 + 54 + static bool match_type6(struct net *net, const struct net_device *dev, 55 + const struct in6_addr *addr, u16 mask) 56 + { 57 + int addr_type = ipv6_addr_type(addr); 58 + 59 + if ((mask & XT_ADDRTYPE_MULTICAST) && 60 + !(addr_type & IPV6_ADDR_MULTICAST)) 61 + return false; 62 + if ((mask & XT_ADDRTYPE_UNICAST) && !(addr_type & IPV6_ADDR_UNICAST)) 63 + return false; 64 + if ((mask & XT_ADDRTYPE_UNSPEC) && addr_type != IPV6_ADDR_ANY) 65 + return false; 66 + 67 + if ((XT_ADDRTYPE_LOCAL | XT_ADDRTYPE_ANYCAST | 68 + XT_ADDRTYPE_UNREACHABLE) & mask) { 69 + struct rt6_info *rt; 70 + u32 type; 71 + int ifindex = dev ? dev->ifindex : 0; 72 + 73 + rt = rt6_lookup(net, addr, NULL, ifindex, !!dev); 74 + 75 + type = xt_addrtype_rt6_to_type(rt); 76 + 77 + dst_release(&rt->dst); 78 + return !!(mask & type); 79 + } 80 + return true; 81 + } 82 + 83 + static bool 84 + addrtype_mt6(struct net *net, const struct net_device *dev, 85 + const struct sk_buff *skb, const struct xt_addrtype_info_v1 *info) 86 + { 87 + const struct ipv6hdr *iph = ipv6_hdr(skb); 88 + bool ret = true; 89 + 90 + if (info->source) 91 + ret &= match_type6(net, dev, &iph->saddr, info->source) ^ 92 + (info->flags & XT_ADDRTYPE_INVERT_SOURCE); 93 + if (ret && info->dest) 94 + ret &= match_type6(net, dev, &iph->daddr, info->dest) ^ 95 + !!(info->flags & XT_ADDRTYPE_INVERT_DEST); 96 + return ret; 97 + } 98 + #endif 99 + 100 + static inline bool match_type(struct net *net, const struct net_device *dev, 101 + __be32 addr, u_int16_t mask) 102 + { 103 + return !!(mask & (1 << inet_dev_addr_type(net, dev, addr))); 104 + } 105 + 106 + static bool 107 + addrtype_mt_v0(const struct sk_buff *skb, struct xt_action_param *par) 108 + { 109 + struct net *net = dev_net(par->in ? par->in : par->out); 110 + const struct xt_addrtype_info *info = par->matchinfo; 111 + const struct iphdr *iph = ip_hdr(skb); 112 + bool ret = true; 113 + 114 + if (info->source) 115 + ret &= match_type(net, NULL, iph->saddr, info->source) ^ 116 + info->invert_source; 117 + if (info->dest) 118 + ret &= match_type(net, NULL, iph->daddr, info->dest) ^ 119 + info->invert_dest; 120 + 121 + return ret; 122 + } 123 + 124 + static bool 125 + addrtype_mt_v1(const struct sk_buff *skb, struct xt_action_param *par) 126 + { 127 + struct net *net = dev_net(par->in ? par->in : par->out); 128 + const struct xt_addrtype_info_v1 *info = par->matchinfo; 129 + const struct iphdr *iph; 130 + const struct net_device *dev = NULL; 131 + bool ret = true; 132 + 133 + if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN) 134 + dev = par->in; 135 + else if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT) 136 + dev = par->out; 137 + 138 + #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) 139 + if (par->family == NFPROTO_IPV6) 140 + return addrtype_mt6(net, dev, skb, info); 141 + #endif 142 + iph = ip_hdr(skb); 143 + if (info->source) 144 + ret &= match_type(net, dev, iph->saddr, info->source) ^ 145 + (info->flags & XT_ADDRTYPE_INVERT_SOURCE); 146 + if (ret && info->dest) 147 + ret &= match_type(net, dev, iph->daddr, info->dest) ^ 148 + !!(info->flags & XT_ADDRTYPE_INVERT_DEST); 149 + return ret; 150 + } 151 + 152 + static int addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par) 153 + { 154 + struct xt_addrtype_info_v1 *info = par->matchinfo; 155 + 156 + if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN && 157 + info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT) { 158 + pr_info("both incoming and outgoing " 159 + "interface limitation cannot be selected\n"); 160 + return -EINVAL; 161 + } 162 + 163 + if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) | 164 + (1 << NF_INET_LOCAL_IN)) && 165 + info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT) { 166 + pr_info("output interface limitation " 167 + "not valid in PREROUTING and INPUT\n"); 168 + return -EINVAL; 169 + } 170 + 171 + if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) | 172 + (1 << NF_INET_LOCAL_OUT)) && 173 + info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN) { 174 + pr_info("input interface limitation " 175 + "not valid in POSTROUTING and OUTPUT\n"); 176 + return -EINVAL; 177 + } 178 + 179 + #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) 180 + if (par->family == NFPROTO_IPV6) { 181 + if ((info->source | info->dest) & XT_ADDRTYPE_BLACKHOLE) { 182 + pr_err("ipv6 BLACKHOLE matching not supported\n"); 183 + return -EINVAL; 184 + } 185 + if ((info->source | info->dest) >= XT_ADDRTYPE_PROHIBIT) { 186 + pr_err("ipv6 PROHIBT (THROW, NAT ..) matching not supported\n"); 187 + return -EINVAL; 188 + } 189 + if ((info->source | info->dest) & XT_ADDRTYPE_BROADCAST) { 190 + pr_err("ipv6 does not support BROADCAST matching\n"); 191 + return -EINVAL; 192 + } 193 + } 194 + #endif 195 + return 0; 196 + } 197 + 198 + static struct xt_match addrtype_mt_reg[] __read_mostly = { 199 + { 200 + .name = "addrtype", 201 + .family = NFPROTO_IPV4, 202 + .match = addrtype_mt_v0, 203 + .matchsize = sizeof(struct xt_addrtype_info), 204 + .me = THIS_MODULE 205 + }, 206 + { 207 + .name = "addrtype", 208 + .family = NFPROTO_UNSPEC, 209 + .revision = 1, 210 + .match = addrtype_mt_v1, 211 + .checkentry = addrtype_mt_checkentry_v1, 212 + .matchsize = sizeof(struct xt_addrtype_info_v1), 213 + .me = THIS_MODULE 214 + } 215 + }; 216 + 217 + static int __init addrtype_mt_init(void) 218 + { 219 + return xt_register_matches(addrtype_mt_reg, 220 + ARRAY_SIZE(addrtype_mt_reg)); 221 + } 222 + 223 + static void __exit addrtype_mt_exit(void) 224 + { 225 + xt_unregister_matches(addrtype_mt_reg, ARRAY_SIZE(addrtype_mt_reg)); 226 + } 227 + 228 + module_init(addrtype_mt_init); 229 + module_exit(addrtype_mt_exit);
+30 -29
net/netfilter/xt_connlimit.c
··· 33 33 34 34 /* we will save the tuples of all connections we care about */ 35 35 struct xt_connlimit_conn { 36 - struct list_head list; 37 - struct nf_conntrack_tuple tuple; 36 + struct hlist_node node; 37 + struct nf_conntrack_tuple tuple; 38 + union nf_inet_addr addr; 38 39 }; 39 40 40 41 struct xt_connlimit_data { 41 - struct list_head iphash[256]; 42 - spinlock_t lock; 42 + struct hlist_head iphash[256]; 43 + spinlock_t lock; 43 44 }; 44 45 45 46 static u_int32_t connlimit_rnd __read_mostly; 46 - static bool connlimit_rnd_inited __read_mostly; 47 47 48 48 static inline unsigned int connlimit_iphash(__be32 addr) 49 49 { ··· 101 101 { 102 102 const struct nf_conntrack_tuple_hash *found; 103 103 struct xt_connlimit_conn *conn; 104 - struct xt_connlimit_conn *tmp; 104 + struct hlist_node *pos, *n; 105 105 struct nf_conn *found_ct; 106 - struct list_head *hash; 106 + struct hlist_head *hash; 107 107 bool addit = true; 108 108 int matches = 0; 109 109 ··· 115 115 rcu_read_lock(); 116 116 117 117 /* check the saved connections */ 118 - list_for_each_entry_safe(conn, tmp, hash, list) { 118 + hlist_for_each_entry_safe(conn, pos, n, hash, node) { 119 119 found = nf_conntrack_find_get(net, NF_CT_DEFAULT_ZONE, 120 120 &conn->tuple); 121 121 found_ct = NULL; ··· 135 135 136 136 if (found == NULL) { 137 137 /* this one is gone */ 138 - list_del(&conn->list); 138 + hlist_del(&conn->node); 139 139 kfree(conn); 140 140 continue; 141 141 } ··· 146 146 * closed already -> ditch it 147 147 */ 148 148 nf_ct_put(found_ct); 149 - list_del(&conn->list); 149 + hlist_del(&conn->node); 150 150 kfree(conn); 151 151 continue; 152 152 } 153 153 154 - if (same_source_net(addr, mask, &conn->tuple.src.u3, family)) 154 + if (same_source_net(addr, mask, &conn->addr, family)) 155 155 /* same source network -> be counted! */ 156 156 ++matches; 157 157 nf_ct_put(found_ct); ··· 161 161 162 162 if (addit) { 163 163 /* save the new connection in our list */ 164 - conn = kzalloc(sizeof(*conn), GFP_ATOMIC); 164 + conn = kmalloc(sizeof(*conn), GFP_ATOMIC); 165 165 if (conn == NULL) 166 166 return -ENOMEM; 167 167 conn->tuple = *tuple; 168 - list_add(&conn->list, hash); 168 + conn->addr = *addr; 169 + hlist_add_head(&conn->node, hash); 169 170 ++matches; 170 171 } 171 172 ··· 186 185 int connections; 187 186 188 187 ct = nf_ct_get(skb, &ctinfo); 189 - if (ct != NULL) { 190 - if (info->flags & XT_CONNLIMIT_DADDR) 191 - tuple_ptr = &ct->tuplehash[IP_CT_DIR_REPLY].tuple; 192 - else 193 - tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; 194 - } else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), 195 - par->family, &tuple)) { 188 + if (ct != NULL) 189 + tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; 190 + else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), 191 + par->family, &tuple)) 196 192 goto hotdrop; 197 - } 198 193 199 194 if (par->family == NFPROTO_IPV6) { 200 195 const struct ipv6hdr *iph = ipv6_hdr(skb); ··· 225 228 unsigned int i; 226 229 int ret; 227 230 228 - if (unlikely(!connlimit_rnd_inited)) { 229 - get_random_bytes(&connlimit_rnd, sizeof(connlimit_rnd)); 230 - connlimit_rnd_inited = true; 231 + if (unlikely(!connlimit_rnd)) { 232 + u_int32_t rand; 233 + 234 + do { 235 + get_random_bytes(&rand, sizeof(rand)); 236 + } while (!rand); 237 + cmpxchg(&connlimit_rnd, 0, rand); 231 238 } 232 239 ret = nf_ct_l3proto_try_module_get(par->family); 233 240 if (ret < 0) { ··· 249 248 250 249 spin_lock_init(&info->data->lock); 251 250 for (i = 0; i < ARRAY_SIZE(info->data->iphash); ++i) 252 - INIT_LIST_HEAD(&info->data->iphash[i]); 251 + INIT_HLIST_HEAD(&info->data->iphash[i]); 253 252 254 253 return 0; 255 254 } ··· 258 257 { 259 258 const struct xt_connlimit_info *info = par->matchinfo; 260 259 struct xt_connlimit_conn *conn; 261 - struct xt_connlimit_conn *tmp; 262 - struct list_head *hash = info->data->iphash; 260 + struct hlist_node *pos, *n; 261 + struct hlist_head *hash = info->data->iphash; 263 262 unsigned int i; 264 263 265 264 nf_ct_l3proto_module_put(par->family); 266 265 267 266 for (i = 0; i < ARRAY_SIZE(info->data->iphash); ++i) { 268 - list_for_each_entry_safe(conn, tmp, &hash[i], list) { 269 - list_del(&conn->list); 267 + hlist_for_each_entry_safe(conn, pos, n, &hash[i], node) { 268 + hlist_del(&conn->node); 270 269 kfree(conn); 271 270 } 272 271 }