[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables

This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.

o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers

Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.

Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by Harald Welte and committed by David S. Miller 2e4e6a17 880b005f

+5671 -6205
+3
include/linux/netfilter/nf_conntrack_common.h
··· 154 154 unsigned int expect_delete; 155 155 }; 156 156 157 + /* call to create an explicit dependency on nf_conntrack. */ 158 + extern void need_conntrack(void); 159 + 157 160 #endif /* __KERNEL__ */ 158 161 159 162 #endif /* _NF_CONNTRACK_COMMON_H */
+224
include/linux/netfilter/x_tables.h
··· 1 + #ifndef _X_TABLES_H 2 + #define _X_TABLES_H 3 + 4 + #define XT_FUNCTION_MAXNAMELEN 30 5 + #define XT_TABLE_MAXNAMELEN 32 6 + 7 + /* The argument to IPT_SO_GET_REVISION_*. Returns highest revision 8 + * kernel supports, if >= revision. */ 9 + struct xt_get_revision 10 + { 11 + char name[XT_FUNCTION_MAXNAMELEN-1]; 12 + 13 + u_int8_t revision; 14 + }; 15 + 16 + /* CONTINUE verdict for targets */ 17 + #define XT_CONTINUE 0xFFFFFFFF 18 + 19 + /* For standard target */ 20 + #define XT_RETURN (-NF_REPEAT - 1) 21 + 22 + #define XT_ALIGN(s) (((s) + (__alignof__(void *)-1)) & ~(__alignof__(void *)-1)) 23 + 24 + /* Standard return verdict, or do jump. */ 25 + #define XT_STANDARD_TARGET "" 26 + /* Error verdict. */ 27 + #define XT_ERROR_TARGET "ERROR" 28 + 29 + /* 30 + * New IP firewall options for [gs]etsockopt at the RAW IP level. 31 + * Unlike BSD Linux inherits IP options so you don't have to use a raw 32 + * socket for this. Instead we check rights in the calls. */ 33 + #define XT_BASE_CTL 64 /* base for firewall socket options */ 34 + 35 + #define XT_SO_SET_REPLACE (XT_BASE_CTL) 36 + #define XT_SO_SET_ADD_COUNTERS (XT_BASE_CTL + 1) 37 + #define XT_SO_SET_MAX XT_SO_SET_ADD_COUNTERS 38 + 39 + #define XT_SO_GET_INFO (XT_BASE_CTL) 40 + #define XT_SO_GET_ENTRIES (XT_BASE_CTL + 1) 41 + #define XT_SO_GET_REVISION_MATCH (XT_BASE_CTL + 2) 42 + #define XT_SO_GET_REVISION_TARGET (XT_BASE_CTL + 3) 43 + #define XT_SO_GET_MAX XT_SO_GET_REVISION_TARGET 44 + 45 + #define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0) 46 + #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) 47 + 48 + struct xt_counters 49 + { 50 + u_int64_t pcnt, bcnt; /* Packet and byte counters */ 51 + }; 52 + 53 + /* The argument to IPT_SO_ADD_COUNTERS. */ 54 + struct xt_counters_info 55 + { 56 + /* Which table. */ 57 + char name[XT_TABLE_MAXNAMELEN]; 58 + 59 + unsigned int num_counters; 60 + 61 + /* The counters (actually `number' of these). */ 62 + struct xt_counters counters[0]; 63 + }; 64 + 65 + #define XT_INV_PROTO 0x40 /* Invert the sense of PROTO. */ 66 + 67 + #ifdef __KERNEL__ 68 + 69 + #include <linux/netdevice.h> 70 + 71 + #define ASSERT_READ_LOCK(x) 72 + #define ASSERT_WRITE_LOCK(x) 73 + #include <linux/netfilter_ipv4/listhelp.h> 74 + 75 + struct xt_match 76 + { 77 + struct list_head list; 78 + 79 + const char name[XT_FUNCTION_MAXNAMELEN-1]; 80 + 81 + u_int8_t revision; 82 + 83 + /* Return true or false: return FALSE and set *hotdrop = 1 to 84 + force immediate packet drop. */ 85 + /* Arguments changed since 2.6.9, as this must now handle 86 + non-linear skb, using skb_header_pointer and 87 + skb_ip_make_writable. */ 88 + int (*match)(const struct sk_buff *skb, 89 + const struct net_device *in, 90 + const struct net_device *out, 91 + const void *matchinfo, 92 + int offset, 93 + unsigned int protoff, 94 + int *hotdrop); 95 + 96 + /* Called when user tries to insert an entry of this type. */ 97 + /* Should return true or false. */ 98 + int (*checkentry)(const char *tablename, 99 + const void *ip, 100 + void *matchinfo, 101 + unsigned int matchinfosize, 102 + unsigned int hook_mask); 103 + 104 + /* Called when entry of this type deleted. */ 105 + void (*destroy)(void *matchinfo, unsigned int matchinfosize); 106 + 107 + /* Set this to THIS_MODULE if you are a module, otherwise NULL */ 108 + struct module *me; 109 + }; 110 + 111 + /* Registration hooks for targets. */ 112 + struct xt_target 113 + { 114 + struct list_head list; 115 + 116 + const char name[XT_FUNCTION_MAXNAMELEN-1]; 117 + 118 + u_int8_t revision; 119 + 120 + /* Returns verdict. Argument order changed since 2.6.9, as this 121 + must now handle non-linear skbs, using skb_copy_bits and 122 + skb_ip_make_writable. */ 123 + unsigned int (*target)(struct sk_buff **pskb, 124 + const struct net_device *in, 125 + const struct net_device *out, 126 + unsigned int hooknum, 127 + const void *targinfo, 128 + void *userdata); 129 + 130 + /* Called when user tries to insert an entry of this type: 131 + hook_mask is a bitmask of hooks from which it can be 132 + called. */ 133 + /* Should return true or false. */ 134 + int (*checkentry)(const char *tablename, 135 + const void *entry, 136 + void *targinfo, 137 + unsigned int targinfosize, 138 + unsigned int hook_mask); 139 + 140 + /* Called when entry of this type deleted. */ 141 + void (*destroy)(void *targinfo, unsigned int targinfosize); 142 + 143 + /* Set this to THIS_MODULE if you are a module, otherwise NULL */ 144 + struct module *me; 145 + }; 146 + 147 + /* Furniture shopping... */ 148 + struct xt_table 149 + { 150 + struct list_head list; 151 + 152 + /* A unique name... */ 153 + char name[XT_TABLE_MAXNAMELEN]; 154 + 155 + /* What hooks you will enter on */ 156 + unsigned int valid_hooks; 157 + 158 + /* Lock for the curtain */ 159 + rwlock_t lock; 160 + 161 + /* Man behind the curtain... */ 162 + //struct ip6t_table_info *private; 163 + void *private; 164 + 165 + /* Set this to THIS_MODULE if you are a module, otherwise NULL */ 166 + struct module *me; 167 + 168 + int af; /* address/protocol family */ 169 + }; 170 + 171 + #include <linux/netfilter_ipv4.h> 172 + 173 + /* The table itself */ 174 + struct xt_table_info 175 + { 176 + /* Size per table */ 177 + unsigned int size; 178 + /* Number of entries: FIXME. --RR */ 179 + unsigned int number; 180 + /* Initial number of entries. Needed for module usage count */ 181 + unsigned int initial_entries; 182 + 183 + /* Entry points and underflows */ 184 + unsigned int hook_entry[NF_IP_NUMHOOKS]; 185 + unsigned int underflow[NF_IP_NUMHOOKS]; 186 + 187 + /* ipt_entry tables: one per CPU */ 188 + char *entries[NR_CPUS]; 189 + }; 190 + 191 + extern int xt_register_target(int af, struct xt_target *target); 192 + extern void xt_unregister_target(int af, struct xt_target *target); 193 + extern int xt_register_match(int af, struct xt_match *target); 194 + extern void xt_unregister_match(int af, struct xt_match *target); 195 + 196 + extern int xt_register_table(struct xt_table *table, 197 + struct xt_table_info *bootstrap, 198 + struct xt_table_info *newinfo); 199 + extern void *xt_unregister_table(struct xt_table *table); 200 + 201 + extern struct xt_table_info *xt_replace_table(struct xt_table *table, 202 + unsigned int num_counters, 203 + struct xt_table_info *newinfo, 204 + int *error); 205 + 206 + extern struct xt_match *xt_find_match(int af, const char *name, u8 revision); 207 + extern struct xt_target *xt_find_target(int af, const char *name, u8 revision); 208 + extern struct xt_target *xt_request_find_target(int af, const char *name, 209 + u8 revision); 210 + extern int xt_find_revision(int af, const char *name, u8 revision, int target, 211 + int *err); 212 + 213 + extern struct xt_table *xt_find_table_lock(int af, const char *name); 214 + extern void xt_table_unlock(struct xt_table *t); 215 + 216 + extern int xt_proto_init(int af); 217 + extern void xt_proto_fini(int af); 218 + 219 + extern struct xt_table_info *xt_alloc_table_info(unsigned int size); 220 + extern void xt_free_table_info(struct xt_table_info *info); 221 + 222 + #endif /* __KERNEL__ */ 223 + 224 + #endif /* _X_TABLES_H */
+8
include/linux/netfilter/xt_CLASSIFY.h
··· 1 + #ifndef _XT_CLASSIFY_H 2 + #define _XT_CLASSIFY_H 3 + 4 + struct xt_classify_target_info { 5 + u_int32_t priority; 6 + }; 7 + 8 + #endif /*_XT_CLASSIFY_H */
+25
include/linux/netfilter/xt_CONNMARK.h
··· 1 + #ifndef _XT_CONNMARK_H_target 2 + #define _XT_CONNMARK_H_target 3 + 4 + /* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> 5 + * by Henrik Nordstrom <hno@marasystems.com> 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 as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + */ 12 + 13 + enum { 14 + XT_CONNMARK_SET = 0, 15 + XT_CONNMARK_SAVE, 16 + XT_CONNMARK_RESTORE 17 + }; 18 + 19 + struct xt_connmark_target_info { 20 + unsigned long mark; 21 + unsigned long mask; 22 + u_int8_t mode; 23 + }; 24 + 25 + #endif /*_XT_CONNMARK_H_target*/
+21
include/linux/netfilter/xt_MARK.h
··· 1 + #ifndef _XT_MARK_H_target 2 + #define _XT_MARK_H_target 3 + 4 + /* Version 0 */ 5 + struct xt_mark_target_info { 6 + unsigned long mark; 7 + }; 8 + 9 + /* Version 1 */ 10 + enum { 11 + XT_MARK_SET=0, 12 + XT_MARK_AND, 13 + XT_MARK_OR, 14 + }; 15 + 16 + struct xt_mark_target_info_v1 { 17 + unsigned long mark; 18 + u_int8_t mode; 19 + }; 20 + 21 + #endif /*_XT_MARK_H_target */
+16
include/linux/netfilter/xt_NFQUEUE.h
··· 1 + /* iptables module for using NFQUEUE mechanism 2 + * 3 + * (C) 2005 Harald Welte <laforge@netfilter.org> 4 + * 5 + * This software is distributed under GNU GPL v2, 1991 6 + * 7 + */ 8 + #ifndef _XT_NFQ_TARGET_H 9 + #define _XT_NFQ_TARGET_H 10 + 11 + /* target info */ 12 + struct xt_NFQ_info { 13 + u_int16_t queuenum; 14 + }; 15 + 16 + #endif /* _XT_NFQ_TARGET_H */
+10
include/linux/netfilter/xt_comment.h
··· 1 + #ifndef _XT_COMMENT_H 2 + #define _XT_COMMENT_H 3 + 4 + #define XT_MAX_COMMENT_LEN 256 5 + 6 + struct xt_comment_info { 7 + unsigned char comment[XT_MAX_COMMENT_LEN]; 8 + }; 9 + 10 + #endif /* XT_COMMENT_H */
+25
include/linux/netfilter/xt_connbytes.h
··· 1 + #ifndef _XT_CONNBYTES_H 2 + #define _XT_CONNBYTES_H 3 + 4 + enum xt_connbytes_what { 5 + XT_CONNBYTES_PKTS, 6 + XT_CONNBYTES_BYTES, 7 + XT_CONNBYTES_AVGPKT, 8 + }; 9 + 10 + enum xt_connbytes_direction { 11 + XT_CONNBYTES_DIR_ORIGINAL, 12 + XT_CONNBYTES_DIR_REPLY, 13 + XT_CONNBYTES_DIR_BOTH, 14 + }; 15 + 16 + struct xt_connbytes_info 17 + { 18 + struct { 19 + aligned_u64 from; /* count to be matched */ 20 + aligned_u64 to; /* count to be matched */ 21 + } count; 22 + u_int8_t what; /* ipt_connbytes_what */ 23 + u_int8_t direction; /* ipt_connbytes_direction */ 24 + }; 25 + #endif
+18
include/linux/netfilter/xt_connmark.h
··· 1 + #ifndef _XT_CONNMARK_H 2 + #define _XT_CONNMARK_H 3 + 4 + /* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> 5 + * by Henrik Nordstrom <hno@marasystems.com> 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 as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + */ 12 + 13 + struct xt_connmark_info { 14 + unsigned long mark, mask; 15 + u_int8_t invert; 16 + }; 17 + 18 + #endif /*_XT_CONNMARK_H*/
+63
include/linux/netfilter/xt_conntrack.h
··· 1 + /* Header file for kernel module to match connection tracking information. 2 + * GPL (C) 2001 Marc Boucher (marc@mbsi.ca). 3 + */ 4 + 5 + #ifndef _XT_CONNTRACK_H 6 + #define _XT_CONNTRACK_H 7 + 8 + #include <linux/netfilter/nf_conntrack_tuple_common.h> 9 + #include <linux/in.h> 10 + 11 + #define XT_CONNTRACK_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1)) 12 + #define XT_CONNTRACK_STATE_INVALID (1 << 0) 13 + 14 + #define XT_CONNTRACK_STATE_SNAT (1 << (IP_CT_NUMBER + 1)) 15 + #define XT_CONNTRACK_STATE_DNAT (1 << (IP_CT_NUMBER + 2)) 16 + #define XT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3)) 17 + 18 + /* flags, invflags: */ 19 + #define XT_CONNTRACK_STATE 0x01 20 + #define XT_CONNTRACK_PROTO 0x02 21 + #define XT_CONNTRACK_ORIGSRC 0x04 22 + #define XT_CONNTRACK_ORIGDST 0x08 23 + #define XT_CONNTRACK_REPLSRC 0x10 24 + #define XT_CONNTRACK_REPLDST 0x20 25 + #define XT_CONNTRACK_STATUS 0x40 26 + #define XT_CONNTRACK_EXPIRES 0x80 27 + 28 + /* This is exposed to userspace, so remains frozen in time. */ 29 + struct ip_conntrack_old_tuple 30 + { 31 + struct { 32 + __u32 ip; 33 + union { 34 + __u16 all; 35 + } u; 36 + } src; 37 + 38 + struct { 39 + __u32 ip; 40 + union { 41 + __u16 all; 42 + } u; 43 + 44 + /* The protocol. */ 45 + u16 protonum; 46 + } dst; 47 + }; 48 + 49 + struct xt_conntrack_info 50 + { 51 + unsigned int statemask, statusmask; 52 + 53 + struct ip_conntrack_old_tuple tuple[IP_CT_DIR_MAX]; 54 + struct in_addr sipmsk[IP_CT_DIR_MAX], dipmsk[IP_CT_DIR_MAX]; 55 + 56 + unsigned long expires_min, expires_max; 57 + 58 + /* Flags word */ 59 + u_int8_t flags; 60 + /* Inverse flags */ 61 + u_int8_t invflags; 62 + }; 63 + #endif /*_XT_CONNTRACK_H*/
+23
include/linux/netfilter/xt_dccp.h
··· 1 + #ifndef _XT_DCCP_H_ 2 + #define _XT_DCCP_H_ 3 + 4 + #define XT_DCCP_SRC_PORTS 0x01 5 + #define XT_DCCP_DEST_PORTS 0x02 6 + #define XT_DCCP_TYPE 0x04 7 + #define XT_DCCP_OPTION 0x08 8 + 9 + #define XT_DCCP_VALID_FLAGS 0x0f 10 + 11 + struct xt_dccp_info { 12 + u_int16_t dpts[2]; /* Min, Max */ 13 + u_int16_t spts[2]; /* Min, Max */ 14 + 15 + u_int16_t flags; 16 + u_int16_t invflags; 17 + 18 + u_int16_t typemask; 19 + u_int8_t option; 20 + }; 21 + 22 + #endif /* _XT_DCCP_H_ */ 23 +
+8
include/linux/netfilter/xt_helper.h
··· 1 + #ifndef _XT_HELPER_H 2 + #define _XT_HELPER_H 3 + 4 + struct xt_helper_info { 5 + int invert; 6 + char name[30]; 7 + }; 8 + #endif /* _XT_HELPER_H */
+9
include/linux/netfilter/xt_length.h
··· 1 + #ifndef _XT_LENGTH_H 2 + #define _XT_LENGTH_H 3 + 4 + struct xt_length_info { 5 + u_int16_t min, max; 6 + u_int8_t invert; 7 + }; 8 + 9 + #endif /*_XT_LENGTH_H*/
+21
include/linux/netfilter/xt_limit.h
··· 1 + #ifndef _XT_RATE_H 2 + #define _XT_RATE_H 3 + 4 + /* timings are in milliseconds. */ 5 + #define XT_LIMIT_SCALE 10000 6 + 7 + /* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490 8 + seconds, or one every 59 hours. */ 9 + struct xt_rateinfo { 10 + u_int32_t avg; /* Average secs between packets * scale */ 11 + u_int32_t burst; /* Period multiplier for upper limit. */ 12 + 13 + /* Used internally by the kernel */ 14 + unsigned long prev; 15 + u_int32_t credit; 16 + u_int32_t credit_cap, cost; 17 + 18 + /* Ugly, ugly fucker. */ 19 + struct xt_rateinfo *master; 20 + }; 21 + #endif /*_XT_RATE_H*/
+8
include/linux/netfilter/xt_mac.h
··· 1 + #ifndef _XT_MAC_H 2 + #define _XT_MAC_H 3 + 4 + struct xt_mac_info { 5 + unsigned char srcaddr[ETH_ALEN]; 6 + int invert; 7 + }; 8 + #endif /*_XT_MAC_H*/
+9
include/linux/netfilter/xt_mark.h
··· 1 + #ifndef _XT_MARK_H 2 + #define _XT_MARK_H 3 + 4 + struct xt_mark_info { 5 + unsigned long mark, mask; 6 + u_int8_t invert; 7 + }; 8 + 9 + #endif /*_XT_MARK_H*/
+24
include/linux/netfilter/xt_physdev.h
··· 1 + #ifndef _XT_PHYSDEV_H 2 + #define _XT_PHYSDEV_H 3 + 4 + #ifdef __KERNEL__ 5 + #include <linux/if.h> 6 + #endif 7 + 8 + #define XT_PHYSDEV_OP_IN 0x01 9 + #define XT_PHYSDEV_OP_OUT 0x02 10 + #define XT_PHYSDEV_OP_BRIDGED 0x04 11 + #define XT_PHYSDEV_OP_ISIN 0x08 12 + #define XT_PHYSDEV_OP_ISOUT 0x10 13 + #define XT_PHYSDEV_OP_MASK (0x20 - 1) 14 + 15 + struct xt_physdev_info { 16 + char physindev[IFNAMSIZ]; 17 + char in_mask[IFNAMSIZ]; 18 + char physoutdev[IFNAMSIZ]; 19 + char out_mask[IFNAMSIZ]; 20 + u_int8_t invert; 21 + u_int8_t bitmask; 22 + }; 23 + 24 + #endif /*_XT_PHYSDEV_H*/
+8
include/linux/netfilter/xt_pkttype.h
··· 1 + #ifndef _XT_PKTTYPE_H 2 + #define _XT_PKTTYPE_H 3 + 4 + struct xt_pkttype_info { 5 + int pkttype; 6 + int invert; 7 + }; 8 + #endif /*_XT_PKTTYPE_H*/
+10
include/linux/netfilter/xt_realm.h
··· 1 + #ifndef _XT_REALM_H 2 + #define _XT_REALM_H 3 + 4 + struct xt_realm_info { 5 + u_int32_t id; 6 + u_int32_t mask; 7 + u_int8_t invert; 8 + }; 9 + 10 + #endif /* _XT_REALM_H */
+107
include/linux/netfilter/xt_sctp.h
··· 1 + #ifndef _XT_SCTP_H_ 2 + #define _XT_SCTP_H_ 3 + 4 + #define XT_SCTP_SRC_PORTS 0x01 5 + #define XT_SCTP_DEST_PORTS 0x02 6 + #define XT_SCTP_CHUNK_TYPES 0x04 7 + 8 + #define XT_SCTP_VALID_FLAGS 0x07 9 + 10 + #define ELEMCOUNT(x) (sizeof(x)/sizeof(x[0])) 11 + 12 + 13 + struct xt_sctp_flag_info { 14 + u_int8_t chunktype; 15 + u_int8_t flag; 16 + u_int8_t flag_mask; 17 + }; 18 + 19 + #define XT_NUM_SCTP_FLAGS 4 20 + 21 + struct xt_sctp_info { 22 + u_int16_t dpts[2]; /* Min, Max */ 23 + u_int16_t spts[2]; /* Min, Max */ 24 + 25 + u_int32_t chunkmap[256 / sizeof (u_int32_t)]; /* Bit mask of chunks to be matched according to RFC 2960 */ 26 + 27 + #define SCTP_CHUNK_MATCH_ANY 0x01 /* Match if any of the chunk types are present */ 28 + #define SCTP_CHUNK_MATCH_ALL 0x02 /* Match if all of the chunk types are present */ 29 + #define SCTP_CHUNK_MATCH_ONLY 0x04 /* Match if these are the only chunk types present */ 30 + 31 + u_int32_t chunk_match_type; 32 + struct xt_sctp_flag_info flag_info[XT_NUM_SCTP_FLAGS]; 33 + int flag_count; 34 + 35 + u_int32_t flags; 36 + u_int32_t invflags; 37 + }; 38 + 39 + #define bytes(type) (sizeof(type) * 8) 40 + 41 + #define SCTP_CHUNKMAP_SET(chunkmap, type) \ 42 + do { \ 43 + chunkmap[type / bytes(u_int32_t)] |= \ 44 + 1 << (type % bytes(u_int32_t)); \ 45 + } while (0) 46 + 47 + #define SCTP_CHUNKMAP_CLEAR(chunkmap, type) \ 48 + do { \ 49 + chunkmap[type / bytes(u_int32_t)] &= \ 50 + ~(1 << (type % bytes(u_int32_t))); \ 51 + } while (0) 52 + 53 + #define SCTP_CHUNKMAP_IS_SET(chunkmap, type) \ 54 + ({ \ 55 + (chunkmap[type / bytes (u_int32_t)] & \ 56 + (1 << (type % bytes (u_int32_t)))) ? 1: 0; \ 57 + }) 58 + 59 + #define SCTP_CHUNKMAP_RESET(chunkmap) \ 60 + do { \ 61 + int i; \ 62 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \ 63 + chunkmap[i] = 0; \ 64 + } while (0) 65 + 66 + #define SCTP_CHUNKMAP_SET_ALL(chunkmap) \ 67 + do { \ 68 + int i; \ 69 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \ 70 + chunkmap[i] = ~0; \ 71 + } while (0) 72 + 73 + #define SCTP_CHUNKMAP_COPY(destmap, srcmap) \ 74 + do { \ 75 + int i; \ 76 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \ 77 + destmap[i] = srcmap[i]; \ 78 + } while (0) 79 + 80 + #define SCTP_CHUNKMAP_IS_CLEAR(chunkmap) \ 81 + ({ \ 82 + int i; \ 83 + int flag = 1; \ 84 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) { \ 85 + if (chunkmap[i]) { \ 86 + flag = 0; \ 87 + break; \ 88 + } \ 89 + } \ 90 + flag; \ 91 + }) 92 + 93 + #define SCTP_CHUNKMAP_IS_ALL_SET(chunkmap) \ 94 + ({ \ 95 + int i; \ 96 + int flag = 1; \ 97 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) { \ 98 + if (chunkmap[i] != ~0) { \ 99 + flag = 0; \ 100 + break; \ 101 + } \ 102 + } \ 103 + flag; \ 104 + }) 105 + 106 + #endif /* _XT_SCTP_H_ */ 107 +
+13
include/linux/netfilter/xt_state.h
··· 1 + #ifndef _XT_STATE_H 2 + #define _XT_STATE_H 3 + 4 + #define XT_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1)) 5 + #define XT_STATE_INVALID (1 << 0) 6 + 7 + #define XT_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 1)) 8 + 9 + struct xt_state_info 10 + { 11 + unsigned int statemask; 12 + }; 13 + #endif /*_XT_STATE_H*/
+18
include/linux/netfilter/xt_string.h
··· 1 + #ifndef _XT_STRING_H 2 + #define _XT_STRING_H 3 + 4 + #define XT_STRING_MAX_PATTERN_SIZE 128 5 + #define XT_STRING_MAX_ALGO_NAME_SIZE 16 6 + 7 + struct xt_string_info 8 + { 9 + u_int16_t from_offset; 10 + u_int16_t to_offset; 11 + char algo[XT_STRING_MAX_ALGO_NAME_SIZE]; 12 + char pattern[XT_STRING_MAX_PATTERN_SIZE]; 13 + u_int8_t patlen; 14 + u_int8_t invert; 15 + struct ts_config __attribute__((aligned(8))) *config; 16 + }; 17 + 18 + #endif /*_XT_STRING_H*/
+9
include/linux/netfilter/xt_tcpmss.h
··· 1 + #ifndef _XT_TCPMSS_MATCH_H 2 + #define _XT_TCPMSS_MATCH_H 3 + 4 + struct xt_tcpmss_match_info { 5 + u_int16_t mss_min, mss_max; 6 + u_int8_t invert; 7 + }; 8 + 9 + #endif /*_XT_TCPMSS_MATCH_H*/
+36
include/linux/netfilter/xt_tcpudp.h
··· 1 + #ifndef _XT_TCPUDP_H 2 + #define _XT_TCPUDP_H 3 + 4 + /* TCP matching stuff */ 5 + struct xt_tcp 6 + { 7 + u_int16_t spts[2]; /* Source port range. */ 8 + u_int16_t dpts[2]; /* Destination port range. */ 9 + u_int8_t option; /* TCP Option iff non-zero*/ 10 + u_int8_t flg_mask; /* TCP flags mask byte */ 11 + u_int8_t flg_cmp; /* TCP flags compare byte */ 12 + u_int8_t invflags; /* Inverse flags */ 13 + }; 14 + 15 + /* Values for "inv" field in struct ipt_tcp. */ 16 + #define XT_TCP_INV_SRCPT 0x01 /* Invert the sense of source ports. */ 17 + #define XT_TCP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */ 18 + #define XT_TCP_INV_FLAGS 0x04 /* Invert the sense of TCP flags. */ 19 + #define XT_TCP_INV_OPTION 0x08 /* Invert the sense of option test. */ 20 + #define XT_TCP_INV_MASK 0x0F /* All possible flags. */ 21 + 22 + /* UDP matching stuff */ 23 + struct xt_udp 24 + { 25 + u_int16_t spts[2]; /* Source port range. */ 26 + u_int16_t dpts[2]; /* Destination port range. */ 27 + u_int8_t invflags; /* Inverse flags */ 28 + }; 29 + 30 + /* Values for "invflags" field in struct ipt_udp. */ 31 + #define XT_UDP_INV_SRCPT 0x01 /* Invert the sense of source ports. */ 32 + #define XT_UDP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */ 33 + #define XT_UDP_INV_MASK 0x03 /* All possible flags. */ 34 + 35 + 36 + #endif
+25 -98
include/linux/netfilter_arp/arp_tables.h
··· 19 19 #include <linux/compiler.h> 20 20 #include <linux/netfilter_arp.h> 21 21 22 - #define ARPT_FUNCTION_MAXNAMELEN 30 23 - #define ARPT_TABLE_MAXNAMELEN 32 22 + #include <linux/netfilter/x_tables.h> 23 + 24 + #define ARPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN 25 + #define ARPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN 26 + #define arpt_target xt_target 27 + #define arpt_table xt_table 24 28 25 29 #define ARPT_DEV_ADDR_LEN_MAX 16 26 30 ··· 95 91 int verdict; 96 92 }; 97 93 98 - struct arpt_counters 99 - { 100 - u_int64_t pcnt, bcnt; /* Packet and byte counters */ 101 - }; 102 - 103 94 /* Values for "flag" field in struct arpt_ip (general arp structure). 104 95 * No flags defined yet. 105 96 */ ··· 129 130 unsigned int comefrom; 130 131 131 132 /* Packet and byte counters. */ 132 - struct arpt_counters counters; 133 + struct xt_counters counters; 133 134 134 135 /* The matches (if any), then the target. */ 135 136 unsigned char elems[0]; ··· 140 141 * Unlike BSD Linux inherits IP options so you don't have to use a raw 141 142 * socket for this. Instead we check rights in the calls. 142 143 */ 143 - #define ARPT_BASE_CTL 96 /* base for firewall socket options */ 144 + #define ARPT_CTL_OFFSET 32 145 + #define ARPT_BASE_CTL (XT_BASE_CTL+ARPT_CTL_OFFSET) 144 146 145 - #define ARPT_SO_SET_REPLACE (ARPT_BASE_CTL) 146 - #define ARPT_SO_SET_ADD_COUNTERS (ARPT_BASE_CTL + 1) 147 - #define ARPT_SO_SET_MAX ARPT_SO_SET_ADD_COUNTERS 147 + #define ARPT_SO_SET_REPLACE (XT_SO_SET_REPLACE+ARPT_CTL_OFFSET) 148 + #define ARPT_SO_SET_ADD_COUNTERS (XT_SO_SET_ADD_COUNTERS+ARPT_CTL_OFFSET) 149 + #define ARPT_SO_SET_MAX (XT_SO_SET_MAX+ARPT_CTL_OFFSET) 148 150 149 - #define ARPT_SO_GET_INFO (ARPT_BASE_CTL) 150 - #define ARPT_SO_GET_ENTRIES (ARPT_BASE_CTL + 1) 151 - /* #define ARPT_SO_GET_REVISION_MATCH (ARPT_BASE_CTL + 2)*/ 152 - #define ARPT_SO_GET_REVISION_TARGET (ARPT_BASE_CTL + 3) 153 - #define ARPT_SO_GET_MAX ARPT_SO_GET_REVISION_TARGET 151 + #define ARPT_SO_GET_INFO (XT_SO_GET_INFO+ARPT_CTL_OFFSET) 152 + #define ARPT_SO_GET_ENTRIES (XT_SO_GET_ENTRIES+ARPT_CTL_OFFSET) 153 + /* #define ARPT_SO_GET_REVISION_MATCH XT_SO_GET_REVISION_MATCH */ 154 + #define ARPT_SO_GET_REVISION_TARGET (XT_SO_GET_REVISION_TARGET+ARPT_CTL_OFFSET) 155 + #define ARPT_SO_GET_MAX (XT_SO_GET_REVISION_TARGET+ARPT_CTL_OFFSET) 154 156 155 157 /* CONTINUE verdict for targets */ 156 - #define ARPT_CONTINUE 0xFFFFFFFF 158 + #define ARPT_CONTINUE XT_CONTINUE 157 159 158 160 /* For standard target */ 159 - #define ARPT_RETURN (-NF_REPEAT - 1) 161 + #define ARPT_RETURN XT_RETURN 160 162 161 163 /* The argument to ARPT_SO_GET_INFO */ 162 164 struct arpt_getinfo ··· 208 208 /* Number of counters (must be equal to current number of entries). */ 209 209 unsigned int num_counters; 210 210 /* The old entries' counters. */ 211 - struct arpt_counters __user *counters; 211 + struct xt_counters __user *counters; 212 212 213 213 /* The entries (hang off end: not really an array). */ 214 214 struct arpt_entry entries[0]; 215 215 }; 216 216 217 217 /* The argument to ARPT_SO_ADD_COUNTERS. */ 218 - struct arpt_counters_info 219 - { 220 - /* Which table. */ 221 - char name[ARPT_TABLE_MAXNAMELEN]; 222 - 223 - unsigned int num_counters; 224 - 225 - /* The counters (actually `number' of these). */ 226 - struct arpt_counters counters[0]; 227 - }; 218 + #define arpt_counters_info xt_counters_info 228 219 229 220 /* The argument to ARPT_SO_GET_ENTRIES. */ 230 221 struct arpt_get_entries ··· 230 239 struct arpt_entry entrytable[0]; 231 240 }; 232 241 233 - /* The argument to ARPT_SO_GET_REVISION_*. Returns highest revision 234 - * kernel supports, if >= revision. */ 235 - struct arpt_get_revision 236 - { 237 - char name[ARPT_FUNCTION_MAXNAMELEN-1]; 238 - 239 - u_int8_t revision; 240 - }; 241 - 242 242 /* Standard return verdict, or do jump. */ 243 - #define ARPT_STANDARD_TARGET "" 243 + #define ARPT_STANDARD_TARGET XT_STANDARD_TARGET 244 244 /* Error verdict. */ 245 - #define ARPT_ERROR_TARGET "ERROR" 245 + #define ARPT_ERROR_TARGET XT_ERROR_TARGET 246 246 247 247 /* Helper functions */ 248 248 static __inline__ struct arpt_entry_target *arpt_get_target(struct arpt_entry *e) ··· 263 281 */ 264 282 #ifdef __KERNEL__ 265 283 266 - /* Registration hooks for targets. */ 267 - struct arpt_target 268 - { 269 - struct list_head list; 270 - 271 - const char name[ARPT_FUNCTION_MAXNAMELEN-1]; 272 - 273 - u_int8_t revision; 274 - 275 - /* Returns verdict. */ 276 - unsigned int (*target)(struct sk_buff **pskb, 277 - unsigned int hooknum, 278 - const struct net_device *in, 279 - const struct net_device *out, 280 - const void *targinfo, 281 - void *userdata); 282 - 283 - /* Called when user tries to insert an entry of this type: 284 - hook_mask is a bitmask of hooks from which it can be 285 - called. */ 286 - /* Should return true or false. */ 287 - int (*checkentry)(const char *tablename, 288 - const struct arpt_entry *e, 289 - void *targinfo, 290 - unsigned int targinfosize, 291 - unsigned int hook_mask); 292 - 293 - /* Called when entry of this type deleted. */ 294 - void (*destroy)(void *targinfo, unsigned int targinfosize); 295 - 296 - /* Set this to THIS_MODULE if you are a module, otherwise NULL */ 297 - struct module *me; 298 - }; 299 - 300 - extern int arpt_register_target(struct arpt_target *target); 301 - extern void arpt_unregister_target(struct arpt_target *target); 302 - 303 - /* Furniture shopping... */ 304 - struct arpt_table 305 - { 306 - struct list_head list; 307 - 308 - /* A unique name... */ 309 - char name[ARPT_TABLE_MAXNAMELEN]; 310 - 311 - /* What hooks you will enter on */ 312 - unsigned int valid_hooks; 313 - 314 - /* Lock for the curtain */ 315 - rwlock_t lock; 316 - 317 - /* Man behind the curtain... */ 318 - struct arpt_table_info *private; 319 - 320 - /* Set this to THIS_MODULE if you are a module, otherwise NULL */ 321 - struct module *me; 322 - }; 284 + #define arpt_register_target(tgt) xt_register_target(NF_ARP, tgt) 285 + #define arpt_unregister_target(tgt) xt_unregister_target(NF_ARP, tgt) 323 286 324 287 extern int arpt_register_table(struct arpt_table *table, 325 288 const struct arpt_replace *repl);
-3
include/linux/netfilter_ipv4/ip_conntrack.h
··· 199 199 nf_conntrack_put(&ct->ct_general); 200 200 } 201 201 202 - /* call to create an explicit dependency on ip_conntrack. */ 203 - extern void need_ip_conntrack(void); 204 - 205 202 extern int invert_tuplepr(struct ip_conntrack_tuple *inverse, 206 203 const struct ip_conntrack_tuple *orig); 207 204
+47 -170
include/linux/netfilter_ipv4/ip_tables.h
··· 25 25 #include <linux/compiler.h> 26 26 #include <linux/netfilter_ipv4.h> 27 27 28 - #define IPT_FUNCTION_MAXNAMELEN 30 29 - #define IPT_TABLE_MAXNAMELEN 32 28 + #include <linux/netfilter/x_tables.h> 29 + 30 + #define IPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN 31 + #define IPT_TABLE_MAXNAMELEN XT_FUNCTION_MAXNAMELEN 32 + #define ipt_match xt_match 33 + #define ipt_target xt_target 34 + #define ipt_table xt_table 35 + #define ipt_get_revision xt_get_revision 30 36 31 37 /* Yes, Virginia, you have to zero the padding. */ 32 38 struct ipt_ip { ··· 108 102 int verdict; 109 103 }; 110 104 111 - struct ipt_counters 112 - { 113 - u_int64_t pcnt, bcnt; /* Packet and byte counters */ 114 - }; 105 + #define ipt_counters xt_counters 115 106 116 107 /* Values for "flag" field in struct ipt_ip (general ip structure). */ 117 108 #define IPT_F_FRAG 0x01 /* Set if rule is a fragment rule */ ··· 122 119 #define IPT_INV_SRCIP 0x08 /* Invert the sense of SRC IP. */ 123 120 #define IPT_INV_DSTIP 0x10 /* Invert the sense of DST OP. */ 124 121 #define IPT_INV_FRAG 0x20 /* Invert the sense of FRAG. */ 125 - #define IPT_INV_PROTO 0x40 /* Invert the sense of PROTO. */ 122 + #define IPT_INV_PROTO XT_INV_PROTO 126 123 #define IPT_INV_MASK 0x7F /* All possible flag bits mask. */ 127 124 128 125 /* This structure defines each of the firewall rules. Consists of 3 ··· 144 141 unsigned int comefrom; 145 142 146 143 /* Packet and byte counters. */ 147 - struct ipt_counters counters; 144 + struct xt_counters counters; 148 145 149 146 /* The matches (if any), then the target. */ 150 147 unsigned char elems[0]; ··· 154 151 * New IP firewall options for [gs]etsockopt at the RAW IP level. 155 152 * Unlike BSD Linux inherits IP options so you don't have to use a raw 156 153 * socket for this. Instead we check rights in the calls. */ 157 - #define IPT_BASE_CTL 64 /* base for firewall socket options */ 154 + #define IPT_BASE_CTL XT_BASE_CTL 158 155 159 - #define IPT_SO_SET_REPLACE (IPT_BASE_CTL) 160 - #define IPT_SO_SET_ADD_COUNTERS (IPT_BASE_CTL + 1) 161 - #define IPT_SO_SET_MAX IPT_SO_SET_ADD_COUNTERS 156 + #define IPT_SO_SET_REPLACE XT_SO_SET_REPLACE 157 + #define IPT_SO_SET_ADD_COUNTERS XT_SO_SET_ADD_COUNTERS 158 + #define IPT_SO_SET_MAX XT_SO_SET_MAX 162 159 163 - #define IPT_SO_GET_INFO (IPT_BASE_CTL) 164 - #define IPT_SO_GET_ENTRIES (IPT_BASE_CTL + 1) 165 - #define IPT_SO_GET_REVISION_MATCH (IPT_BASE_CTL + 2) 166 - #define IPT_SO_GET_REVISION_TARGET (IPT_BASE_CTL + 3) 167 - #define IPT_SO_GET_MAX IPT_SO_GET_REVISION_TARGET 160 + #define IPT_SO_GET_INFO XT_SO_GET_INFO 161 + #define IPT_SO_GET_ENTRIES XT_SO_GET_ENTRIES 162 + #define IPT_SO_GET_REVISION_MATCH XT_SO_GET_REVISION_MATCH 163 + #define IPT_SO_GET_REVISION_TARGET XT_SO_GET_REVISION_TARGET 164 + #define IPT_SO_GET_MAX XT_SO_GET_REVISION_TARGET 168 165 169 - /* CONTINUE verdict for targets */ 170 - #define IPT_CONTINUE 0xFFFFFFFF 166 + #define IPT_CONTINUE XT_CONTINUE 167 + #define IPT_RETURN XT_RETURN 171 168 172 - /* For standard target */ 173 - #define IPT_RETURN (-NF_REPEAT - 1) 169 + #include <linux/netfilter/xt_tcpudp.h> 170 + #define ipt_udp xt_udp 171 + #define ipt_tcp xt_tcp 174 172 175 - /* TCP matching stuff */ 176 - struct ipt_tcp 177 - { 178 - u_int16_t spts[2]; /* Source port range. */ 179 - u_int16_t dpts[2]; /* Destination port range. */ 180 - u_int8_t option; /* TCP Option iff non-zero*/ 181 - u_int8_t flg_mask; /* TCP flags mask byte */ 182 - u_int8_t flg_cmp; /* TCP flags compare byte */ 183 - u_int8_t invflags; /* Inverse flags */ 184 - }; 173 + #define IPT_TCP_INV_SRCPT XT_TCP_INV_SRCPT 174 + #define IPT_TCP_INV_DSTPT XT_TCP_INV_DSTPT 175 + #define IPT_TCP_INV_FLAGS XT_TCP_INV_FLAGS 176 + #define IPT_TCP_INV_OPTION XT_TCP_INV_OPTION 177 + #define IPT_TCP_INV_MASK XT_TCP_INV_MASK 185 178 186 - /* Values for "inv" field in struct ipt_tcp. */ 187 - #define IPT_TCP_INV_SRCPT 0x01 /* Invert the sense of source ports. */ 188 - #define IPT_TCP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */ 189 - #define IPT_TCP_INV_FLAGS 0x04 /* Invert the sense of TCP flags. */ 190 - #define IPT_TCP_INV_OPTION 0x08 /* Invert the sense of option test. */ 191 - #define IPT_TCP_INV_MASK 0x0F /* All possible flags. */ 192 - 193 - /* UDP matching stuff */ 194 - struct ipt_udp 195 - { 196 - u_int16_t spts[2]; /* Source port range. */ 197 - u_int16_t dpts[2]; /* Destination port range. */ 198 - u_int8_t invflags; /* Inverse flags */ 199 - }; 200 - 201 - /* Values for "invflags" field in struct ipt_udp. */ 202 - #define IPT_UDP_INV_SRCPT 0x01 /* Invert the sense of source ports. */ 203 - #define IPT_UDP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */ 204 - #define IPT_UDP_INV_MASK 0x03 /* All possible flags. */ 179 + #define IPT_UDP_INV_SRCPT XT_UDP_INV_SRCPT 180 + #define IPT_UDP_INV_DSTPT XT_UDP_INV_DSTPT 181 + #define IPT_UDP_INV_MASK XT_UDP_INV_MASK 205 182 206 183 /* ICMP matching stuff */ 207 184 struct ipt_icmp ··· 243 260 /* Number of counters (must be equal to current number of entries). */ 244 261 unsigned int num_counters; 245 262 /* The old entries' counters. */ 246 - struct ipt_counters __user *counters; 263 + struct xt_counters __user *counters; 247 264 248 265 /* The entries (hang off end: not really an array). */ 249 266 struct ipt_entry entries[0]; 250 267 }; 251 268 252 269 /* The argument to IPT_SO_ADD_COUNTERS. */ 253 - struct ipt_counters_info 254 - { 255 - /* Which table. */ 256 - char name[IPT_TABLE_MAXNAMELEN]; 257 - 258 - unsigned int num_counters; 259 - 260 - /* The counters (actually `number' of these). */ 261 - struct ipt_counters counters[0]; 262 - }; 270 + #define ipt_counters_info xt_counters_info 263 271 264 272 /* The argument to IPT_SO_GET_ENTRIES. */ 265 273 struct ipt_get_entries ··· 265 291 struct ipt_entry entrytable[0]; 266 292 }; 267 293 268 - /* The argument to IPT_SO_GET_REVISION_*. Returns highest revision 269 - * kernel supports, if >= revision. */ 270 - struct ipt_get_revision 271 - { 272 - char name[IPT_FUNCTION_MAXNAMELEN-1]; 273 - 274 - u_int8_t revision; 275 - }; 276 - 277 294 /* Standard return verdict, or do jump. */ 278 - #define IPT_STANDARD_TARGET "" 295 + #define IPT_STANDARD_TARGET XT_STANDARD_TARGET 279 296 /* Error verdict. */ 280 - #define IPT_ERROR_TARGET "ERROR" 297 + #define IPT_ERROR_TARGET XT_ERROR_TARGET 281 298 282 299 /* Helper functions */ 283 300 static __inline__ struct ipt_entry_target * ··· 321 356 #include <linux/init.h> 322 357 extern void ipt_init(void) __init; 323 358 324 - struct ipt_match 325 - { 326 - struct list_head list; 359 + #define ipt_register_target(tgt) xt_register_target(AF_INET, tgt) 360 + #define ipt_unregister_target(tgt) xt_unregister_target(AF_INET, tgt) 327 361 328 - const char name[IPT_FUNCTION_MAXNAMELEN-1]; 362 + #define ipt_register_match(mtch) xt_register_match(AF_INET, mtch) 363 + #define ipt_unregister_match(mtch) xt_unregister_match(AF_INET, mtch) 329 364 330 - u_int8_t revision; 365 + //#define ipt_register_table(tbl, repl) xt_register_table(AF_INET, tbl, repl) 366 + //#define ipt_unregister_table(tbl) xt_unregister_table(AF_INET, tbl) 331 367 332 - /* Return true or false: return FALSE and set *hotdrop = 1 to 333 - force immediate packet drop. */ 334 - /* Arguments changed since 2.4, as this must now handle 335 - non-linear skbs, using skb_copy_bits and 336 - skb_ip_make_writable. */ 337 - int (*match)(const struct sk_buff *skb, 338 - const struct net_device *in, 339 - const struct net_device *out, 340 - const void *matchinfo, 341 - int offset, 342 - int *hotdrop); 343 - 344 - /* Called when user tries to insert an entry of this type. */ 345 - /* Should return true or false. */ 346 - int (*checkentry)(const char *tablename, 347 - const struct ipt_ip *ip, 348 - void *matchinfo, 349 - unsigned int matchinfosize, 350 - unsigned int hook_mask); 351 - 352 - /* Called when entry of this type deleted. */ 353 - void (*destroy)(void *matchinfo, unsigned int matchinfosize); 354 - 355 - /* Set this to THIS_MODULE. */ 356 - struct module *me; 357 - }; 358 - 359 - /* Registration hooks for targets. */ 360 - struct ipt_target 361 - { 362 - struct list_head list; 363 - 364 - const char name[IPT_FUNCTION_MAXNAMELEN-1]; 365 - 366 - u_int8_t revision; 367 - 368 - /* Called when user tries to insert an entry of this type: 369 - hook_mask is a bitmask of hooks from which it can be 370 - called. */ 371 - /* Should return true or false. */ 372 - int (*checkentry)(const char *tablename, 373 - const struct ipt_entry *e, 374 - void *targinfo, 375 - unsigned int targinfosize, 376 - unsigned int hook_mask); 377 - 378 - /* Called when entry of this type deleted. */ 379 - void (*destroy)(void *targinfo, unsigned int targinfosize); 380 - 381 - /* Returns verdict. Argument order changed since 2.4, as this 382 - must now handle non-linear skbs, using skb_copy_bits and 383 - skb_ip_make_writable. */ 384 - unsigned int (*target)(struct sk_buff **pskb, 385 - const struct net_device *in, 386 - const struct net_device *out, 387 - unsigned int hooknum, 388 - const void *targinfo, 389 - void *userdata); 390 - 391 - /* Set this to THIS_MODULE. */ 392 - struct module *me; 393 - }; 394 - 395 - extern int ipt_register_target(struct ipt_target *target); 396 - extern void ipt_unregister_target(struct ipt_target *target); 397 - 398 - extern int ipt_register_match(struct ipt_match *match); 399 - extern void ipt_unregister_match(struct ipt_match *match); 400 - 401 - /* Furniture shopping... */ 402 - struct ipt_table 403 - { 404 - struct list_head list; 405 - 406 - /* A unique name... */ 407 - char name[IPT_TABLE_MAXNAMELEN]; 408 - 409 - /* What hooks you will enter on */ 410 - unsigned int valid_hooks; 411 - 412 - /* Lock for the curtain */ 413 - rwlock_t lock; 414 - 415 - /* Man behind the curtain... */ 416 - struct ipt_table_info *private; 417 - 418 - /* Set to THIS_MODULE. */ 419 - struct module *me; 420 - }; 368 + extern int ipt_register_table(struct ipt_table *table, 369 + const struct ipt_replace *repl); 370 + extern void ipt_unregister_table(struct ipt_table *table); 421 371 422 372 /* net/sched/ipt.c: Gimme access to your targets! Gets target->me. */ 423 373 extern struct ipt_target *ipt_find_target(const char *name, u8 revision); ··· 356 476 struct ipt_error_target target; 357 477 }; 358 478 359 - extern int ipt_register_table(struct ipt_table *table, 360 - const struct ipt_replace *repl); 361 - extern void ipt_unregister_table(struct ipt_table *table); 362 479 extern unsigned int ipt_do_table(struct sk_buff **pskb, 363 480 unsigned int hook, 364 481 const struct net_device *in, ··· 363 486 struct ipt_table *table, 364 487 void *userdata); 365 488 366 - #define IPT_ALIGN(s) (((s) + (__alignof__(struct ipt_entry)-1)) & ~(__alignof__(struct ipt_entry)-1)) 489 + #define IPT_ALIGN(s) XT_ALIGN(s) 367 490 #endif /*__KERNEL__*/ 368 491 #endif /* _IPTABLES_H */
+2 -3
include/linux/netfilter_ipv4/ipt_CLASSIFY.h
··· 1 1 #ifndef _IPT_CLASSIFY_H 2 2 #define _IPT_CLASSIFY_H 3 3 4 - struct ipt_classify_target_info { 5 - u_int32_t priority; 6 - }; 4 + #include <linux/netfilter/xt_CLASSIFY.h> 5 + #define ipt_classify_target_info xt_classify_target_info 7 6 8 7 #endif /*_IPT_CLASSIFY_H */
+5 -11
include/linux/netfilter_ipv4/ipt_CONNMARK.h
··· 9 9 * the Free Software Foundation; either version 2 of the License, or 10 10 * (at your option) any later version. 11 11 */ 12 + #include <linux/netfilter/xt_CONNMARK.h> 13 + #define IPT_CONNMARK_SET XT_CONNMARK_SET 14 + #define IPT_CONNMARK_SAVE XT_CONNMARK_SAVE 15 + #define IPT_CONNMARK_RESTORE XT_CONNMARK_RESTORE 12 16 13 - enum { 14 - IPT_CONNMARK_SET = 0, 15 - IPT_CONNMARK_SAVE, 16 - IPT_CONNMARK_RESTORE 17 - }; 18 - 19 - struct ipt_connmark_target_info { 20 - unsigned long mark; 21 - unsigned long mask; 22 - u_int8_t mode; 23 - }; 17 + #define ipt_connmark_target_info xt_connmark_target_info 24 18 25 19 #endif /*_IPT_CONNMARK_H_target*/
+10 -12
include/linux/netfilter_ipv4/ipt_MARK.h
··· 1 1 #ifndef _IPT_MARK_H_target 2 2 #define _IPT_MARK_H_target 3 3 4 + /* Backwards compatibility for old userspace */ 5 + 6 + #include <linux/netfilter/xt_MARK.h> 7 + 4 8 /* Version 0 */ 5 - struct ipt_mark_target_info { 6 - unsigned long mark; 7 - }; 9 + #define ipt_mark_target_info xt_mark_target_info 8 10 9 11 /* Version 1 */ 10 - enum { 11 - IPT_MARK_SET=0, 12 - IPT_MARK_AND, 13 - IPT_MARK_OR 14 - }; 12 + #define IPT_MARK_SET XT_MARK_SET 13 + #define IPT_MARK_AND XT_MARK_AND 14 + #define IPT_MARK_OR XT_MARK_OR 15 15 16 - struct ipt_mark_target_info_v1 { 17 - unsigned long mark; 18 - u_int8_t mode; 19 - }; 16 + #define ipt_mark_target_info_v1 xt_mark_target_info_v1 17 + 20 18 #endif /*_IPT_MARK_H_target*/
+4 -4
include/linux/netfilter_ipv4/ipt_NFQUEUE.h
··· 8 8 #ifndef _IPT_NFQ_TARGET_H 9 9 #define _IPT_NFQ_TARGET_H 10 10 11 - /* target info */ 12 - struct ipt_NFQ_info { 13 - u_int16_t queuenum; 14 - }; 11 + /* Backwards compatibility for old userspace */ 12 + #include <linux/netfilter/xt_NFQUEUE.h> 13 + 14 + #define ipt_NFQ_info xt_NFQ_info 15 15 16 16 #endif /* _IPT_DSCP_TARGET_H */
+4 -4
include/linux/netfilter_ipv4/ipt_comment.h
··· 1 1 #ifndef _IPT_COMMENT_H 2 2 #define _IPT_COMMENT_H 3 3 4 - #define IPT_MAX_COMMENT_LEN 256 4 + #include <linux/netfilter/xt_comment.h> 5 5 6 - struct ipt_comment_info { 7 - unsigned char comment[IPT_MAX_COMMENT_LEN]; 8 - }; 6 + #define IPT_MAX_COMMENT_LEN XT_MAX_COMMENT_LEN 7 + 8 + #define ipt_comment_info xt_comment_info 9 9 10 10 #endif /* _IPT_COMMENT_H */
+12 -19
include/linux/netfilter_ipv4/ipt_connbytes.h
··· 1 1 #ifndef _IPT_CONNBYTES_H 2 2 #define _IPT_CONNBYTES_H 3 3 4 - enum ipt_connbytes_what { 5 - IPT_CONNBYTES_PKTS, 6 - IPT_CONNBYTES_BYTES, 7 - IPT_CONNBYTES_AVGPKT, 8 - }; 4 + #include <net/netfilter/xt_connbytes.h> 5 + #define ipt_connbytes_what xt_connbytes_what 9 6 10 - enum ipt_connbytes_direction { 11 - IPT_CONNBYTES_DIR_ORIGINAL, 12 - IPT_CONNBYTES_DIR_REPLY, 13 - IPT_CONNBYTES_DIR_BOTH, 14 - }; 7 + #define IPT_CONNBYTES_PKTS XT_CONNBYTES_PACKETS 8 + #define IPT_CONNBYTES_BYTES XT_CONNBYTES_BYTES 9 + #define IPT_CONNBYTES_AVGPKT XT_CONNBYTES_AVGPKT 15 10 16 - struct ipt_connbytes_info 17 - { 18 - struct { 19 - aligned_u64 from; /* count to be matched */ 20 - aligned_u64 to; /* count to be matched */ 21 - } count; 22 - u_int8_t what; /* ipt_connbytes_what */ 23 - u_int8_t direction; /* ipt_connbytes_direction */ 24 - }; 11 + #define ipt_connbytes_direction xt_connbytes_direction 12 + #define IPT_CONNBYTES_DIR_ORIGINAL XT_CONNBYTES_DIR_ORIGINAL 13 + #define IPT_CONNBYTES_DIR_REPLY XT_CONNBYTES_DIR_REPLY 14 + #define IPT_CONNBYTES_DIR_BOTH XT_CONNBYTES_DIR_BOTH 15 + 16 + #define ipt_connbytes_info xt_connbytes_info 17 + 25 18 #endif
+2 -13
include/linux/netfilter_ipv4/ipt_connmark.h
··· 1 1 #ifndef _IPT_CONNMARK_H 2 2 #define _IPT_CONNMARK_H 3 3 4 - /* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> 5 - * by Henrik Nordstrom <hno@marasystems.com> 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 as published by 9 - * the Free Software Foundation; either version 2 of the License, or 10 - * (at your option) any later version. 11 - */ 12 - 13 - struct ipt_connmark_info { 14 - unsigned long mark, mask; 15 - u_int8_t invert; 16 - }; 4 + #include <linux/netfilter/xt_connmark.h> 5 + #define ipt_connmark_info xt_connmark_info 17 6 18 7 #endif /*_IPT_CONNMARK_H*/
+16 -48
include/linux/netfilter_ipv4/ipt_conntrack.h
··· 5 5 #ifndef _IPT_CONNTRACK_H 6 6 #define _IPT_CONNTRACK_H 7 7 8 - #define IPT_CONNTRACK_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1)) 9 - #define IPT_CONNTRACK_STATE_INVALID (1 << 0) 8 + #include <linux/netfilter/xt_conntrack.h> 10 9 11 - #define IPT_CONNTRACK_STATE_SNAT (1 << (IP_CT_NUMBER + 1)) 12 - #define IPT_CONNTRACK_STATE_DNAT (1 << (IP_CT_NUMBER + 2)) 13 - #define IPT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3)) 10 + #define IPT_CONNTRACK_STATE_BIT(ctinfo) XT_CONNTRACK_STATE_BIT(ctinfo) 11 + #define IPT_CONNTRACK_STATE_INVALID XT_CONNTRACK_STATE_INVALID 12 + 13 + #define IPT_CONNTRACK_STATE_SNAT XT_CONNTRACK_STATE_SNAT 14 + #define IPT_CONNTRACK_STATE_DNAT XT_CONNTRACK_STATE_DNAT 15 + #define IPT_CONNTRACK_STATE_UNTRACKED XT_CONNTRACK_STATE_UNTRACKED 14 16 15 17 /* flags, invflags: */ 16 - #define IPT_CONNTRACK_STATE 0x01 17 - #define IPT_CONNTRACK_PROTO 0x02 18 - #define IPT_CONNTRACK_ORIGSRC 0x04 19 - #define IPT_CONNTRACK_ORIGDST 0x08 20 - #define IPT_CONNTRACK_REPLSRC 0x10 21 - #define IPT_CONNTRACK_REPLDST 0x20 22 - #define IPT_CONNTRACK_STATUS 0x40 23 - #define IPT_CONNTRACK_EXPIRES 0x80 18 + #define IPT_CONNTRACK_STATE XT_CONNTRACK_STATE 19 + #define IPT_CONNTRACK_PROTO XT_CONNTRACK_PROTO 20 + #define IPT_CONNTRACK_ORIGSRC XT_CONNTRACK_ORIGSRC 21 + #define IPT_CONNTRACK_ORIGDST XT_CONNTRACK_ORIGDST 22 + #define IPT_CONNTRACK_REPLSRC XT_CONNTRACK_REPLSRC 23 + #define IPT_CONNTRACK_REPLDST XT_CONNTRACK_REPLDST 24 + #define IPT_CONNTRACK_STATUS XT_CONNTRACK_STATUS 25 + #define IPT_CONNTRACK_EXPIRES XT_CONNTRACK_EXPIRES 24 26 25 - /* This is exposed to userspace, so remains frozen in time. */ 26 - struct ip_conntrack_old_tuple 27 - { 28 - struct { 29 - __u32 ip; 30 - union { 31 - __u16 all; 32 - } u; 33 - } src; 34 - 35 - struct { 36 - __u32 ip; 37 - union { 38 - __u16 all; 39 - } u; 40 - 41 - /* The protocol. */ 42 - u16 protonum; 43 - } dst; 44 - }; 45 - 46 - struct ipt_conntrack_info 47 - { 48 - unsigned int statemask, statusmask; 49 - 50 - struct ip_conntrack_old_tuple tuple[IP_CT_DIR_MAX]; 51 - struct in_addr sipmsk[IP_CT_DIR_MAX], dipmsk[IP_CT_DIR_MAX]; 52 - 53 - unsigned long expires_min, expires_max; 54 - 55 - /* Flags word */ 56 - u_int8_t flags; 57 - /* Inverse flags */ 58 - u_int8_t invflags; 59 - }; 27 + #define ipt_conntrack_info xt_conntrack_info 60 28 #endif /*_IPT_CONNTRACK_H*/
+7 -15
include/linux/netfilter_ipv4/ipt_dccp.h
··· 1 1 #ifndef _IPT_DCCP_H_ 2 2 #define _IPT_DCCP_H_ 3 3 4 - #define IPT_DCCP_SRC_PORTS 0x01 5 - #define IPT_DCCP_DEST_PORTS 0x02 6 - #define IPT_DCCP_TYPE 0x04 7 - #define IPT_DCCP_OPTION 0x08 4 + #include <linux/netfilter/xt_dccp.h> 5 + #define IPT_DCCP_SRC_PORTS XT_DCCP_SRC_PORTS 6 + #define IPT_DCCP_DEST_PORTS XT_DCCP_DEST_PORTS 7 + #define IPT_DCCP_TYPE XT_DCCP_TYPE 8 + #define IPT_DCCP_OPTION XT_DCCP_OPTION 8 9 9 - #define IPT_DCCP_VALID_FLAGS 0x0f 10 + #define IPT_DCCP_VALID_FLAGS XT_DCCP_VALID_FLAGS 10 11 11 - struct ipt_dccp_info { 12 - u_int16_t dpts[2]; /* Min, Max */ 13 - u_int16_t spts[2]; /* Min, Max */ 14 - 15 - u_int16_t flags; 16 - u_int16_t invflags; 17 - 18 - u_int16_t typemask; 19 - u_int8_t option; 20 - }; 12 + #define ipt_dccp_info xt_dccp_info 21 13 22 14 #endif /* _IPT_DCCP_H_ */ 23 15
+3 -4
include/linux/netfilter_ipv4/ipt_helper.h
··· 1 1 #ifndef _IPT_HELPER_H 2 2 #define _IPT_HELPER_H 3 3 4 - struct ipt_helper_info { 5 - int invert; 6 - char name[30]; 7 - }; 4 + #include <linux/netfilter/xt_helper.h> 5 + #define ipt_helper_info xt_helper_info 6 + 8 7 #endif /* _IPT_HELPER_H */
+2 -4
include/linux/netfilter_ipv4/ipt_length.h
··· 1 1 #ifndef _IPT_LENGTH_H 2 2 #define _IPT_LENGTH_H 3 3 4 - struct ipt_length_info { 5 - u_int16_t min, max; 6 - u_int8_t invert; 7 - }; 4 + #include <linux/netfilter/xt_length.h> 5 + #define ipt_length_info xt_length_info 8 6 9 7 #endif /*_IPT_LENGTH_H*/
+3 -16
include/linux/netfilter_ipv4/ipt_limit.h
··· 1 1 #ifndef _IPT_RATE_H 2 2 #define _IPT_RATE_H 3 3 4 - /* timings are in milliseconds. */ 5 - #define IPT_LIMIT_SCALE 10000 4 + #include <linux/netfilter/xt_limit.h> 5 + #define IPT_LIMIT_SCALE XT_LIMIT_SCALE 6 + #define ipt_rateinfo xt_rateinfo 6 7 7 - /* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490 8 - seconds, or one every 59 hours. */ 9 - struct ipt_rateinfo { 10 - u_int32_t avg; /* Average secs between packets * scale */ 11 - u_int32_t burst; /* Period multiplier for upper limit. */ 12 - 13 - /* Used internally by the kernel */ 14 - unsigned long prev; 15 - u_int32_t credit; 16 - u_int32_t credit_cap, cost; 17 - 18 - /* Ugly, ugly fucker. */ 19 - struct ipt_rateinfo *master; 20 - }; 21 8 #endif /*_IPT_RATE_H*/
+3 -4
include/linux/netfilter_ipv4/ipt_mac.h
··· 1 1 #ifndef _IPT_MAC_H 2 2 #define _IPT_MAC_H 3 3 4 - struct ipt_mac_info { 5 - unsigned char srcaddr[ETH_ALEN]; 6 - int invert; 7 - }; 4 + #include <linux/netfilter/xt_mac.h> 5 + #define ipt_mac_info xt_mac_info 6 + 8 7 #endif /*_IPT_MAC_H*/
+4 -4
include/linux/netfilter_ipv4/ipt_mark.h
··· 1 1 #ifndef _IPT_MARK_H 2 2 #define _IPT_MARK_H 3 3 4 - struct ipt_mark_info { 5 - unsigned long mark, mask; 6 - u_int8_t invert; 7 - }; 4 + /* Backwards compatibility for old userspace */ 5 + #include <linux/netfilter/xt_mark.h> 6 + 7 + #define ipt_mark_info xt_mark_info 8 8 9 9 #endif /*_IPT_MARK_H*/
+10 -17
include/linux/netfilter_ipv4/ipt_physdev.h
··· 1 1 #ifndef _IPT_PHYSDEV_H 2 2 #define _IPT_PHYSDEV_H 3 3 4 - #ifdef __KERNEL__ 5 - #include <linux/if.h> 6 - #endif 4 + /* Backwards compatibility for old userspace */ 7 5 8 - #define IPT_PHYSDEV_OP_IN 0x01 9 - #define IPT_PHYSDEV_OP_OUT 0x02 10 - #define IPT_PHYSDEV_OP_BRIDGED 0x04 11 - #define IPT_PHYSDEV_OP_ISIN 0x08 12 - #define IPT_PHYSDEV_OP_ISOUT 0x10 13 - #define IPT_PHYSDEV_OP_MASK (0x20 - 1) 6 + #include <linux/netfilter/xt_physdev.h> 14 7 15 - struct ipt_physdev_info { 16 - char physindev[IFNAMSIZ]; 17 - char in_mask[IFNAMSIZ]; 18 - char physoutdev[IFNAMSIZ]; 19 - char out_mask[IFNAMSIZ]; 20 - u_int8_t invert; 21 - u_int8_t bitmask; 22 - }; 8 + #define IPT_PHYSDEV_OP_IN XT_PHYSDEV_OP_IN 9 + #define IPT_PHYSDEV_OP_OUT XT_PHYSDEV_OP_OUT 10 + #define IPT_PHYSDEV_OP_BRIDGED XT_PHYSDEV_OP_BRIDGED 11 + #define IPT_PHYSDEV_OP_ISIN XT_PHYSDEV_OP_ISIN 12 + #define IPT_PHYSDEV_OP_ISOUT XT_PHYSDEV_OP_ISOUT 13 + #define IPT_PHYSDEV_OP_MASK XT_PHYSDEV_OP_MASK 14 + 15 + #define ipt_physdev_info xt_physdev_info 23 16 24 17 #endif /*_IPT_PHYSDEV_H*/
+3 -4
include/linux/netfilter_ipv4/ipt_pkttype.h
··· 1 1 #ifndef _IPT_PKTTYPE_H 2 2 #define _IPT_PKTTYPE_H 3 3 4 - struct ipt_pkttype_info { 5 - int pkttype; 6 - int invert; 7 - }; 4 + #include <linux/netfilter/xt_pkttype.h> 5 + #define ipt_pkttype_info xt_pkttype_info 6 + 8 7 #endif /*_IPT_PKTTYPE_H*/
+2 -5
include/linux/netfilter_ipv4/ipt_realm.h
··· 1 1 #ifndef _IPT_REALM_H 2 2 #define _IPT_REALM_H 3 3 4 - struct ipt_realm_info { 5 - u_int32_t id; 6 - u_int32_t mask; 7 - u_int8_t invert; 8 - }; 4 + #include <linux/netfilter/xt_realm.h> 5 + #define ipt_realm_info xt_realm_info 9 6 10 7 #endif /* _IPT_REALM_H */
+9 -7
include/linux/netfilter_ipv4/ipt_state.h
··· 1 1 #ifndef _IPT_STATE_H 2 2 #define _IPT_STATE_H 3 3 4 - #define IPT_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1)) 5 - #define IPT_STATE_INVALID (1 << 0) 4 + /* Backwards compatibility for old userspace */ 6 5 7 - #define IPT_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 1)) 6 + #include <linux/netfilter/xt_state.h> 8 7 9 - struct ipt_state_info 10 - { 11 - unsigned int statemask; 12 - }; 8 + #define IPT_STATE_BIT XT_STATE_BIT 9 + #define IPT_STATE_INVALID XT_STATE_INVALID 10 + 11 + #define IPT_STATE_UNTRACKED XT_STATE_UNTRACKED 12 + 13 + #define ipt_state_info xt_state_info 14 + 13 15 #endif /*_IPT_STATE_H*/
+4 -12
include/linux/netfilter_ipv4/ipt_string.h
··· 1 1 #ifndef _IPT_STRING_H 2 2 #define _IPT_STRING_H 3 3 4 - #define IPT_STRING_MAX_PATTERN_SIZE 128 5 - #define IPT_STRING_MAX_ALGO_NAME_SIZE 16 4 + #include <linux/netfilter/xt_string.h> 6 5 7 - struct ipt_string_info 8 - { 9 - u_int16_t from_offset; 10 - u_int16_t to_offset; 11 - char algo[IPT_STRING_MAX_ALGO_NAME_SIZE]; 12 - char pattern[IPT_STRING_MAX_PATTERN_SIZE]; 13 - u_int8_t patlen; 14 - u_int8_t invert; 15 - struct ts_config __attribute__((aligned(8))) *config; 16 - }; 6 + #define IPT_STRING_MAX_PATTERN_SIZE XT_STRING_MAX_PATTERN_SIZE 7 + #define IPT_STRING_MAX_ALGO_NAME_SIZE XT_STRING_MAX_ALGO_NAME_SIZE 8 + #define ipt_string_info xt_string_info 17 9 18 10 #endif /*_IPT_STRING_H*/
+2 -4
include/linux/netfilter_ipv4/ipt_tcpmss.h
··· 1 1 #ifndef _IPT_TCPMSS_MATCH_H 2 2 #define _IPT_TCPMSS_MATCH_H 3 3 4 - struct ipt_tcpmss_match_info { 5 - u_int16_t mss_min, mss_max; 6 - u_int8_t invert; 7 - }; 4 + #include <linux/netfilter/xt_tcpmss.h> 5 + #define ipt_tcpmss_match_info xt_tcpmss_match_info 8 6 9 7 #endif /*_IPT_TCPMSS_MATCH_H*/
+44 -164
include/linux/netfilter_ipv6/ip6_tables.h
··· 25 25 #include <linux/compiler.h> 26 26 #include <linux/netfilter_ipv6.h> 27 27 28 - #define IP6T_FUNCTION_MAXNAMELEN 30 29 - #define IP6T_TABLE_MAXNAMELEN 32 28 + #include <linux/netfilter/x_tables.h> 29 + 30 + #define IP6T_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN 31 + #define IP6T_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN 32 + 33 + #define ip6t_match xt_match 34 + #define ip6t_target xt_target 35 + #define ip6t_table xt_table 36 + #define ip6t_get_revision xt_get_revision 30 37 31 38 /* Yes, Virginia, you have to zero the padding. */ 32 39 struct ip6t_ip6 { ··· 111 104 int verdict; 112 105 }; 113 106 114 - struct ip6t_counters 115 - { 116 - u_int64_t pcnt, bcnt; /* Packet and byte counters */ 117 - }; 107 + #define ip6t_counters xt_counters 118 108 119 109 /* Values for "flag" field in struct ip6t_ip6 (general ip6 structure). */ 120 110 #define IP6T_F_PROTO 0x01 /* Set if rule cares about upper ··· 127 123 #define IP6T_INV_SRCIP 0x08 /* Invert the sense of SRC IP. */ 128 124 #define IP6T_INV_DSTIP 0x10 /* Invert the sense of DST OP. */ 129 125 #define IP6T_INV_FRAG 0x20 /* Invert the sense of FRAG. */ 130 - #define IP6T_INV_PROTO 0x40 /* Invert the sense of PROTO. */ 126 + #define IP6T_INV_PROTO XT_INV_PROTO 131 127 #define IP6T_INV_MASK 0x7F /* All possible flag bits mask. */ 132 128 133 129 /* This structure defines each of the firewall rules. Consists of 3 ··· 149 145 unsigned int comefrom; 150 146 151 147 /* Packet and byte counters. */ 152 - struct ip6t_counters counters; 148 + struct xt_counters counters; 153 149 154 150 /* The matches (if any), then the target. */ 155 151 unsigned char elems[0]; ··· 159 155 * New IP firewall options for [gs]etsockopt at the RAW IP level. 160 156 * Unlike BSD Linux inherits IP options so you don't have to use 161 157 * a raw socket for this. Instead we check rights in the calls. */ 162 - #define IP6T_BASE_CTL 64 /* base for firewall socket options */ 158 + #define IP6T_BASE_CTL XT_BASE_CTL 163 159 164 - #define IP6T_SO_SET_REPLACE (IP6T_BASE_CTL) 165 - #define IP6T_SO_SET_ADD_COUNTERS (IP6T_BASE_CTL + 1) 166 - #define IP6T_SO_SET_MAX IP6T_SO_SET_ADD_COUNTERS 160 + #define IP6T_SO_SET_REPLACE XT_SO_SET_REPLACE 161 + #define IP6T_SO_SET_ADD_COUNTERS XT_SO_SET_ADD_COUNTERS 162 + #define IP6T_SO_SET_MAX XT_SO_SET_MAX 167 163 168 - #define IP6T_SO_GET_INFO (IP6T_BASE_CTL) 169 - #define IP6T_SO_GET_ENTRIES (IP6T_BASE_CTL + 1) 170 - #define IP6T_SO_GET_REVISION_MATCH (IP6T_BASE_CTL + 2) 171 - #define IP6T_SO_GET_REVISION_TARGET (IP6T_BASE_CTL + 3) 172 - #define IP6T_SO_GET_MAX IP6T_SO_GET_REVISION_TARGET 164 + #define IP6T_SO_GET_INFO XT_SO_GET_INFO 165 + #define IP6T_SO_GET_ENTRIES XT_SO_GET_ENTRIES 166 + #define IP6T_SO_GET_REVISION_MATCH XT_SO_GET_REVISION_MATCH 167 + #define IP6T_SO_GET_REVISION_TARGET XT_SO_GET_REVISION_TARGET 168 + #define IP6T_SO_GET_MAX XT_SO_GET_REVISION_TARGET 173 169 174 170 /* CONTINUE verdict for targets */ 175 - #define IP6T_CONTINUE 0xFFFFFFFF 171 + #define IP6T_CONTINUE XT_CONTINUE 176 172 177 173 /* For standard target */ 178 - #define IP6T_RETURN (-NF_REPEAT - 1) 174 + #define IP6T_RETURN XT_RETURN 179 175 180 - /* TCP matching stuff */ 181 - struct ip6t_tcp 182 - { 183 - u_int16_t spts[2]; /* Source port range. */ 184 - u_int16_t dpts[2]; /* Destination port range. */ 185 - u_int8_t option; /* TCP Option iff non-zero*/ 186 - u_int8_t flg_mask; /* TCP flags mask byte */ 187 - u_int8_t flg_cmp; /* TCP flags compare byte */ 188 - u_int8_t invflags; /* Inverse flags */ 189 - }; 176 + /* TCP/UDP matching stuff */ 177 + #include <linux/netfilter/xt_tcpudp.h> 178 + 179 + #define ip6t_tcp xt_tcp 180 + #define ip6t_udp xt_udp 190 181 191 182 /* Values for "inv" field in struct ipt_tcp. */ 192 - #define IP6T_TCP_INV_SRCPT 0x01 /* Invert the sense of source ports. */ 193 - #define IP6T_TCP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */ 194 - #define IP6T_TCP_INV_FLAGS 0x04 /* Invert the sense of TCP flags. */ 195 - #define IP6T_TCP_INV_OPTION 0x08 /* Invert the sense of option test. */ 196 - #define IP6T_TCP_INV_MASK 0x0F /* All possible flags. */ 197 - 198 - /* UDP matching stuff */ 199 - struct ip6t_udp 200 - { 201 - u_int16_t spts[2]; /* Source port range. */ 202 - u_int16_t dpts[2]; /* Destination port range. */ 203 - u_int8_t invflags; /* Inverse flags */ 204 - }; 183 + #define IP6T_TCP_INV_SRCPT XT_TCP_INV_SRCPT 184 + #define IP6T_TCP_INV_DSTPT XT_TCP_INV_DSTPT 185 + #define IP6T_TCP_INV_FLAGS XT_TCP_INV_FLAGS 186 + #define IP6T_TCP_INV_OPTION XT_TCP_INV_OPTION 187 + #define IP6T_TCP_INV_MASK XT_TCP_INV_MASK 205 188 206 189 /* Values for "invflags" field in struct ipt_udp. */ 207 - #define IP6T_UDP_INV_SRCPT 0x01 /* Invert the sense of source ports. */ 208 - #define IP6T_UDP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */ 209 - #define IP6T_UDP_INV_MASK 0x03 /* All possible flags. */ 190 + #define IP6T_UDP_INV_SRCPT XT_UDP_INV_SRCPT 191 + #define IP6T_UDP_INV_DSTPT XT_UDP_INV_DSTPT 192 + #define IP6T_UDP_INV_MASK XT_UDP_INV_MASK 210 193 211 194 /* ICMP matching stuff */ 212 195 struct ip6t_icmp ··· 255 264 /* Number of counters (must be equal to current number of entries). */ 256 265 unsigned int num_counters; 257 266 /* The old entries' counters. */ 258 - struct ip6t_counters __user *counters; 267 + struct xt_counters __user *counters; 259 268 260 269 /* The entries (hang off end: not really an array). */ 261 270 struct ip6t_entry entries[0]; 262 271 }; 263 272 264 273 /* The argument to IP6T_SO_ADD_COUNTERS. */ 265 - struct ip6t_counters_info 266 - { 267 - /* Which table. */ 268 - char name[IP6T_TABLE_MAXNAMELEN]; 269 - 270 - unsigned int num_counters; 271 - 272 - /* The counters (actually `number' of these). */ 273 - struct ip6t_counters counters[0]; 274 - }; 274 + #define ip6t_counters_info xt_counters_info 275 275 276 276 /* The argument to IP6T_SO_GET_ENTRIES. */ 277 277 struct ip6t_get_entries ··· 277 295 struct ip6t_entry entrytable[0]; 278 296 }; 279 297 280 - /* The argument to IP6T_SO_GET_REVISION_*. Returns highest revision 281 - * kernel supports, if >= revision. */ 282 - struct ip6t_get_revision 283 - { 284 - char name[IP6T_FUNCTION_MAXNAMELEN-1]; 285 - 286 - u_int8_t revision; 287 - }; 288 - 289 298 /* Standard return verdict, or do jump. */ 290 - #define IP6T_STANDARD_TARGET "" 299 + #define IP6T_STANDARD_TARGET XT_STANDARD_TARGET 291 300 /* Error verdict. */ 292 - #define IP6T_ERROR_TARGET "ERROR" 301 + #define IP6T_ERROR_TARGET XT_ERROR_TARGET 293 302 294 303 /* Helper functions */ 295 304 static __inline__ struct ip6t_entry_target * ··· 334 361 #include <linux/init.h> 335 362 extern void ip6t_init(void) __init; 336 363 337 - struct ip6t_match 338 - { 339 - struct list_head list; 364 + #define ip6t_register_target(tgt) xt_register_target(AF_INET6, tgt) 365 + #define ip6t_unregister_target(tgt) xt_unregister_target(AF_INET6, tgt) 340 366 341 - const char name[IP6T_FUNCTION_MAXNAMELEN-1]; 342 - 343 - u_int8_t revision; 344 - 345 - /* Return true or false: return FALSE and set *hotdrop = 1 to 346 - force immediate packet drop. */ 347 - /* Arguments changed since 2.6.9, as this must now handle 348 - non-linear skb, using skb_header_pointer and 349 - skb_ip_make_writable. */ 350 - int (*match)(const struct sk_buff *skb, 351 - const struct net_device *in, 352 - const struct net_device *out, 353 - const void *matchinfo, 354 - int offset, 355 - unsigned int protoff, 356 - int *hotdrop); 357 - 358 - /* Called when user tries to insert an entry of this type. */ 359 - /* Should return true or false. */ 360 - int (*checkentry)(const char *tablename, 361 - const struct ip6t_ip6 *ip, 362 - void *matchinfo, 363 - unsigned int matchinfosize, 364 - unsigned int hook_mask); 365 - 366 - /* Called when entry of this type deleted. */ 367 - void (*destroy)(void *matchinfo, unsigned int matchinfosize); 368 - 369 - /* Set this to THIS_MODULE if you are a module, otherwise NULL */ 370 - struct module *me; 371 - }; 372 - 373 - /* Registration hooks for targets. */ 374 - struct ip6t_target 375 - { 376 - struct list_head list; 377 - 378 - const char name[IP6T_FUNCTION_MAXNAMELEN-1]; 379 - 380 - u_int8_t revision; 381 - 382 - /* Returns verdict. Argument order changed since 2.6.9, as this 383 - must now handle non-linear skbs, using skb_copy_bits and 384 - skb_ip_make_writable. */ 385 - unsigned int (*target)(struct sk_buff **pskb, 386 - const struct net_device *in, 387 - const struct net_device *out, 388 - unsigned int hooknum, 389 - const void *targinfo, 390 - void *userdata); 391 - 392 - /* Called when user tries to insert an entry of this type: 393 - hook_mask is a bitmask of hooks from which it can be 394 - called. */ 395 - /* Should return true or false. */ 396 - int (*checkentry)(const char *tablename, 397 - const struct ip6t_entry *e, 398 - void *targinfo, 399 - unsigned int targinfosize, 400 - unsigned int hook_mask); 401 - 402 - /* Called when entry of this type deleted. */ 403 - void (*destroy)(void *targinfo, unsigned int targinfosize); 404 - 405 - /* Set this to THIS_MODULE if you are a module, otherwise NULL */ 406 - struct module *me; 407 - }; 408 - 409 - extern int ip6t_register_target(struct ip6t_target *target); 410 - extern void ip6t_unregister_target(struct ip6t_target *target); 411 - 412 - extern int ip6t_register_match(struct ip6t_match *match); 413 - extern void ip6t_unregister_match(struct ip6t_match *match); 414 - 415 - /* Furniture shopping... */ 416 - struct ip6t_table 417 - { 418 - struct list_head list; 419 - 420 - /* A unique name... */ 421 - char name[IP6T_TABLE_MAXNAMELEN]; 422 - 423 - /* What hooks you will enter on */ 424 - unsigned int valid_hooks; 425 - 426 - /* Lock for the curtain */ 427 - rwlock_t lock; 428 - 429 - /* Man behind the curtain... */ 430 - struct ip6t_table_info *private; 431 - 432 - /* Set this to THIS_MODULE if you are a module, otherwise NULL */ 433 - struct module *me; 434 - }; 367 + #define ip6t_register_match(match) xt_register_match(AF_INET6, match) 368 + #define ip6t_unregister_match(match) xt_unregister_match(AF_INET6, match) 435 369 436 370 extern int ip6t_register_table(struct ip6t_table *table, 437 371 const struct ip6t_replace *repl);
+5 -4
include/linux/netfilter_ipv6/ip6t_MARK.h
··· 1 1 #ifndef _IP6T_MARK_H_target 2 2 #define _IP6T_MARK_H_target 3 3 4 - struct ip6t_mark_target_info { 5 - unsigned long mark; 6 - }; 4 + /* Backwards compatibility for old userspace */ 5 + #include <linux/netfilter/xt_MARK.h> 7 6 8 - #endif /*_IPT_MARK_H_target*/ 7 + #define ip6t_mark_target_info xt_mark_target_info 8 + 9 + #endif /*_IP6T_MARK_H_target*/
+2 -4
include/linux/netfilter_ipv6/ip6t_length.h
··· 1 1 #ifndef _IP6T_LENGTH_H 2 2 #define _IP6T_LENGTH_H 3 3 4 - struct ip6t_length_info { 5 - u_int16_t min, max; 6 - u_int8_t invert; 7 - }; 4 + #include <linux/netfilter/xt_length.h> 5 + #define ip6t_length_info xt_length_info 8 6 9 7 #endif /*_IP6T_LENGTH_H*/ 10 8
+4 -17
include/linux/netfilter_ipv6/ip6t_limit.h
··· 1 1 #ifndef _IP6T_RATE_H 2 2 #define _IP6T_RATE_H 3 3 4 - /* timings are in milliseconds. */ 5 - #define IP6T_LIMIT_SCALE 10000 4 + #include <linux/netfilter/xt_limit.h> 5 + #define IP6T_LIMIT_SCALE XT_LIMIT_SCALE 6 + #define ip6t_rateinfo xt_rateinfo 6 7 7 - /* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490 8 - seconds, or one every 59 hours. */ 9 - struct ip6t_rateinfo { 10 - u_int32_t avg; /* Average secs between packets * scale */ 11 - u_int32_t burst; /* Period multiplier for upper limit. */ 12 - 13 - /* Used internally by the kernel */ 14 - unsigned long prev; 15 - u_int32_t credit; 16 - u_int32_t credit_cap, cost; 17 - 18 - /* Ugly, ugly fucker. */ 19 - struct ip6t_rateinfo *master; 20 - }; 21 - #endif /*_IPT_RATE_H*/ 8 + #endif /*_IP6T_RATE_H*/
+4 -5
include/linux/netfilter_ipv6/ip6t_mac.h
··· 1 1 #ifndef _IP6T_MAC_H 2 2 #define _IP6T_MAC_H 3 3 4 - struct ip6t_mac_info { 5 - unsigned char srcaddr[ETH_ALEN]; 6 - int invert; 7 - }; 8 - #endif /*_IPT_MAC_H*/ 4 + #include <linux/netfilter/xt_mac.h> 5 + #define ip6t_mac_info xt_mac_info 6 + 7 + #endif /*_IP6T_MAC_H*/
+4 -4
include/linux/netfilter_ipv6/ip6t_mark.h
··· 1 1 #ifndef _IP6T_MARK_H 2 2 #define _IP6T_MARK_H 3 3 4 - struct ip6t_mark_info { 5 - unsigned long mark, mask; 6 - u_int8_t invert; 7 - }; 4 + /* Backwards compatibility for old userspace */ 5 + #include <linux/netfilter/xt_mark.h> 6 + 7 + #define ip6t_mark_info xt_mark_info 8 8 9 9 #endif /*_IPT_MARK_H*/
+10 -17
include/linux/netfilter_ipv6/ip6t_physdev.h
··· 1 1 #ifndef _IP6T_PHYSDEV_H 2 2 #define _IP6T_PHYSDEV_H 3 3 4 - #ifdef __KERNEL__ 5 - #include <linux/if.h> 6 - #endif 4 + /* Backwards compatibility for old userspace */ 7 5 8 - #define IP6T_PHYSDEV_OP_IN 0x01 9 - #define IP6T_PHYSDEV_OP_OUT 0x02 10 - #define IP6T_PHYSDEV_OP_BRIDGED 0x04 11 - #define IP6T_PHYSDEV_OP_ISIN 0x08 12 - #define IP6T_PHYSDEV_OP_ISOUT 0x10 13 - #define IP6T_PHYSDEV_OP_MASK (0x20 - 1) 6 + #include <linux/netfilter/xt_physdev.h> 14 7 15 - struct ip6t_physdev_info { 16 - char physindev[IFNAMSIZ]; 17 - char in_mask[IFNAMSIZ]; 18 - char physoutdev[IFNAMSIZ]; 19 - char out_mask[IFNAMSIZ]; 20 - u_int8_t invert; 21 - u_int8_t bitmask; 22 - }; 8 + #define IP6T_PHYSDEV_OP_IN XT_PHYSDEV_OP_IN 9 + #define IP6T_PHYSDEV_OP_OUT XT_PHYSDEV_OP_OUT 10 + #define IP6T_PHYSDEV_OP_BRIDGED XT_PHYSDEV_OP_BRIDGED 11 + #define IP6T_PHYSDEV_OP_ISIN XT_PHYSDEV_OP_ISIN 12 + #define IP6T_PHYSDEV_OP_ISOUT XT_PHYSDEV_OP_ISOUT 13 + #define IP6T_PHYSDEV_OP_MASK XT_PHYSDEV_OP_MASK 14 + 15 + #define ip6t_physdev_info xt_physdev_info 23 16 24 17 #endif /*_IP6T_PHYSDEV_H*/
-3
include/net/netfilter/ipv4/nf_conntrack_ipv4.h
··· 37 37 struct sk_buff * 38 38 nf_ct_ipv4_ct_gather_frags(struct sk_buff *skb); 39 39 40 - /* call to create an explicit dependency on nf_conntrack_l3proto_ipv4. */ 41 - extern void need_ip_conntrack(void); 42 - 43 40 #endif /*_NF_CONNTRACK_IPV4_H*/
-3
include/net/netfilter/nf_conntrack.h
··· 221 221 extern struct nf_conntrack_helper * 222 222 __nf_conntrack_helper_find_byname(const char *name); 223 223 224 - /* call to create an explicit dependency on nf_conntrack. */ 225 - extern void need_nf_conntrack(void); 226 - 227 224 extern int nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse, 228 225 const struct nf_conntrack_tuple *orig); 229 226
+1
net/bridge/netfilter/ebt_log.c
··· 15 15 #include <linux/netfilter.h> 16 16 #include <linux/module.h> 17 17 #include <linux/ip.h> 18 + #include <linux/in.h> 18 19 #include <linux/if_arp.h> 19 20 #include <linux/spinlock.h> 20 21
+2 -248
net/ipv4/netfilter/Kconfig
··· 182 182 183 183 config IP_NF_IPTABLES 184 184 tristate "IP tables support (required for filtering/masq/NAT)" 185 + depends on NETFILTER_XTABLES 185 186 help 186 187 iptables is a general, extensible packet identification framework. 187 188 The packet filtering and full NAT (masquerading, port forwarding, ··· 192 191 To compile it as a module, choose M here. If unsure, say N. 193 192 194 193 # The matches. 195 - config IP_NF_MATCH_LIMIT 196 - tristate "limit match support" 197 - depends on IP_NF_IPTABLES 198 - help 199 - limit matching allows you to control the rate at which a rule can be 200 - matched: mainly useful in combination with the LOG target ("LOG 201 - target support", below) and to avoid some Denial of Service attacks. 202 - 203 - To compile it as a module, choose M here. If unsure, say N. 204 - 205 194 config IP_NF_MATCH_IPRANGE 206 195 tristate "IP range match support" 207 196 depends on IP_NF_IPTABLES 208 197 help 209 198 This option makes possible to match IP addresses against IP address 210 199 ranges. 211 - 212 - To compile it as a module, choose M here. If unsure, say N. 213 - 214 - config IP_NF_MATCH_MAC 215 - tristate "MAC address match support" 216 - depends on IP_NF_IPTABLES 217 - help 218 - MAC matching allows you to match packets based on the source 219 - Ethernet address of the packet. 220 - 221 - To compile it as a module, choose M here. If unsure, say N. 222 - 223 - config IP_NF_MATCH_PKTTYPE 224 - tristate "Packet type match support" 225 - depends on IP_NF_IPTABLES 226 - help 227 - Packet type matching allows you to match a packet by 228 - its "class", eg. BROADCAST, MULTICAST, ... 229 - 230 - Typical usage: 231 - iptables -A INPUT -m pkttype --pkt-type broadcast -j LOG 232 - 233 - To compile it as a module, choose M here. If unsure, say N. 234 - 235 - config IP_NF_MATCH_MARK 236 - tristate "netfilter MARK match support" 237 - depends on IP_NF_IPTABLES 238 - help 239 - Netfilter mark matching allows you to match packets based on the 240 - `nfmark' value in the packet. This can be set by the MARK target 241 - (see below). 242 200 243 201 To compile it as a module, choose M here. If unsure, say N. 244 202 ··· 261 301 262 302 To compile it as a module, choose M here. If unsure, say N. 263 303 264 - config IP_NF_MATCH_LENGTH 265 - tristate "LENGTH match support" 266 - depends on IP_NF_IPTABLES 267 - help 268 - This option allows you to match the length of a packet against a 269 - specific value or range of values. 270 - 271 - To compile it as a module, choose M here. If unsure, say N. 272 - 273 304 config IP_NF_MATCH_TTL 274 305 tristate "TTL match support" 275 306 depends on IP_NF_IPTABLES 276 307 help 277 308 This adds CONFIG_IP_NF_MATCH_TTL option, which enabled the user 278 309 to match packets by their TTL value. 279 - 280 - To compile it as a module, choose M here. If unsure, say N. 281 - 282 - config IP_NF_MATCH_TCPMSS 283 - tristate "tcpmss match support" 284 - depends on IP_NF_IPTABLES 285 - help 286 - This option adds a `tcpmss' match, which allows you to examine the 287 - MSS value of TCP SYN packets, which control the maximum packet size 288 - for that connection. 289 - 290 - To compile it as a module, choose M here. If unsure, say N. 291 - 292 - config IP_NF_MATCH_HELPER 293 - tristate "Helper match support" 294 - depends on IP_NF_IPTABLES 295 - depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4 296 - help 297 - Helper matching allows you to match packets in dynamic connections 298 - tracked by a conntrack-helper, ie. ip_conntrack_ftp 299 - 300 - To compile it as a module, choose M here. If unsure, say Y. 301 - 302 - config IP_NF_MATCH_STATE 303 - tristate "Connection state match support" 304 - depends on IP_NF_IPTABLES 305 - depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4 306 - help 307 - Connection state matching allows you to match packets based on their 308 - relationship to a tracked connection (ie. previous packets). This 309 - is a powerful tool for packet classification. 310 - 311 - To compile it as a module, choose M here. If unsure, say N. 312 - 313 - config IP_NF_MATCH_CONNTRACK 314 - tristate "Connection tracking match support" 315 - depends on IP_NF_IPTABLES 316 - depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4 317 - help 318 - This is a general conntrack match module, a superset of the state match. 319 - 320 - It allows matching on additional conntrack information, which is 321 - useful in complex configurations, such as NAT gateways with multiple 322 - internet links or tunnels. 323 310 324 311 To compile it as a module, choose M here. If unsure, say N. 325 312 ··· 279 372 280 373 To compile it as a module, choose M here. If unsure, say N. 281 374 282 - config IP_NF_MATCH_PHYSDEV 283 - tristate "Physdev match support" 284 - depends on IP_NF_IPTABLES && BRIDGE_NETFILTER 285 - help 286 - Physdev packet matching matches against the physical bridge ports 287 - the IP packet arrived on or will leave by. 288 - 289 - To compile it as a module, choose M here. If unsure, say N. 290 - 291 375 config IP_NF_MATCH_ADDRTYPE 292 376 tristate 'address type match support' 293 377 depends on IP_NF_IPTABLES ··· 286 388 This option allows you to match what routing thinks of an address, 287 389 eg. UNICAST, LOCAL, BROADCAST, ... 288 390 289 - If you want to compile it as a module, say M here and read 290 - <file:Documentation/modules.txt>. If unsure, say `N'. 291 - 292 - config IP_NF_MATCH_REALM 293 - tristate 'realm match support' 294 - depends on IP_NF_IPTABLES 295 - select NET_CLS_ROUTE 296 - help 297 - This option adds a `realm' match, which allows you to use the realm 298 - key from the routing subsystem inside iptables. 299 - 300 - This match pretty much resembles the CONFIG_NET_CLS_ROUTE4 option 301 - in tc world. 302 - 303 - If you want to compile it as a module, say M here and read 304 - <file:Documentation/modules.txt>. If unsure, say `N'. 305 - 306 - config IP_NF_MATCH_SCTP 307 - tristate 'SCTP protocol match support' 308 - depends on IP_NF_IPTABLES 309 - help 310 - With this option enabled, you will be able to use the iptables 311 - `sctp' match in order to match on SCTP source/destination ports 312 - and SCTP chunk types. 313 - 314 - If you want to compile it as a module, say M here and read 315 - <file:Documentation/modules.txt>. If unsure, say `N'. 316 - 317 - config IP_NF_MATCH_DCCP 318 - tristate 'DCCP protocol match support' 319 - depends on IP_NF_IPTABLES 320 - help 321 - With this option enabled, you will be able to use the iptables 322 - `dccp' match in order to match on DCCP source/destination ports 323 - and DCCP flags. 324 - 325 - If you want to compile it as a module, say M here and read 326 - <file:Documentation/modules.txt>. If unsure, say `N'. 327 - 328 - config IP_NF_MATCH_COMMENT 329 - tristate 'comment match support' 330 - depends on IP_NF_IPTABLES 331 - help 332 - This option adds a `comment' dummy-match, which allows you to put 333 - comments in your iptables ruleset. 334 - 335 - If you want to compile it as a module, say M here and read 336 - <file:Documentation/modules.txt>. If unsure, say `N'. 337 - 338 - config IP_NF_MATCH_CONNMARK 339 - tristate 'Connection mark match support' 340 - depends on IP_NF_IPTABLES 341 - depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4) 342 - help 343 - This option adds a `connmark' match, which allows you to match the 344 - connection mark value previously set for the session by `CONNMARK'. 345 - 346 - If you want to compile it as a module, say M here and read 347 - <file:Documentation/modules.txt>. The module will be called 348 - ipt_connmark.o. If unsure, say `N'. 349 - 350 - config IP_NF_MATCH_CONNBYTES 351 - tristate 'Connection byte/packet counter match support' 352 - depends on IP_NF_IPTABLES 353 - depends on (IP_NF_CONNTRACK && IP_NF_CT_ACCT) || (NF_CT_ACCT && NF_CONNTRACK_IPV4) 354 - help 355 - This option adds a `connbytes' match, which allows you to match the 356 - number of bytes and/or packets for each direction within a connection. 357 - 358 391 If you want to compile it as a module, say M here and read 359 392 <file:Documentation/modules.txt>. If unsure, say `N'. 360 393 ··· 302 473 It enables you to express policies like `10kpps for any given 303 474 destination IP' or `500pps from any given source IP' with a single 304 475 IPtables rule. 305 - 306 - config IP_NF_MATCH_STRING 307 - tristate 'string match support' 308 - depends on IP_NF_IPTABLES 309 - select TEXTSEARCH 310 - select TEXTSEARCH_KMP 311 - select TEXTSEARCH_BM 312 - select TEXTSEARCH_FSM 313 - help 314 - This option adds a `string' match, which allows you to look for 315 - pattern matchings in packets. 316 - 317 - To compile it as a module, choose M here. If unsure, say N. 318 476 319 477 config IP_NF_MATCH_POLICY 320 478 tristate "IPsec policy match support" ··· 385 569 386 570 iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN \ 387 571 -j TCPMSS --clamp-mss-to-pmtu 388 - 389 - To compile it as a module, choose M here. If unsure, say N. 390 - 391 - config IP_NF_TARGET_NFQUEUE 392 - tristate "NFQUEUE Target Support" 393 - depends on IP_NF_IPTABLES 394 - help 395 - This Target replaced the old obsolete QUEUE target. 396 - 397 - As opposed to QUEUE, it supports 65535 different queues, 398 - not just one. 399 572 400 573 To compile it as a module, choose M here. If unsure, say N. 401 574 ··· 540 735 541 736 To compile it as a module, choose M here. If unsure, say N. 542 737 543 - config IP_NF_TARGET_MARK 544 - tristate "MARK target support" 545 - depends on IP_NF_MANGLE 546 - help 547 - This option adds a `MARK' target, which allows you to create rules 548 - in the `mangle' table which alter the netfilter mark (nfmark) field 549 - associated with the packet prior to routing. This can change 550 - the routing method (see `Use netfilter MARK value as routing 551 - key') and can also be used by other subsystems to change their 552 - behavior. 553 - 554 - To compile it as a module, choose M here. If unsure, say N. 555 - 556 - config IP_NF_TARGET_CLASSIFY 557 - tristate "CLASSIFY target support" 558 - depends on IP_NF_MANGLE 559 - help 560 - This option adds a `CLASSIFY' target, which enables the user to set 561 - the priority of a packet. Some qdiscs can use this value for 562 - classification, among these are: 563 - 564 - atm, cbq, dsmark, pfifo_fast, htb, prio 565 - 566 - To compile it as a module, choose M here. If unsure, say N. 567 - 568 738 config IP_NF_TARGET_TTL 569 739 tristate 'TTL target support' 570 740 depends on IP_NF_MANGLE ··· 553 773 create immortal packets that loop forever on the network. 554 774 555 775 To compile it as a module, choose M here. If unsure, say N. 556 - 557 - config IP_NF_TARGET_CONNMARK 558 - tristate 'CONNMARK target support' 559 - depends on IP_NF_MANGLE 560 - depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4) 561 - help 562 - This option adds a `CONNMARK' target, which allows one to manipulate 563 - the connection mark value. Similar to the MARK target, but 564 - affects the connection mark value rather than the packet mark value. 565 - 566 - If you want to compile it as a module, say M here and read 567 - <file:Documentation/modules.txt>. The module will be called 568 - ipt_CONNMARK.o. If unsure, say `N'. 569 776 570 777 config IP_NF_TARGET_CLUSTERIP 571 778 tristate "CLUSTERIP target support (EXPERIMENTAL)" ··· 577 810 If you want to compile it as a module, say M here and read 578 811 <file:Documentation/modules.txt>. If unsure, say `N'. 579 812 580 - config IP_NF_TARGET_NOTRACK 581 - tristate 'NOTRACK target support' 582 - depends on IP_NF_RAW 583 - depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4 584 - help 585 - The NOTRACK target allows a select rule to specify 586 - which packets *not* to enter the conntrack/NAT 587 - subsystem with all the consequences (no ICMP error tracking, 588 - no protocol helpers for the selected packets). 589 - 590 - If you want to compile it as a module, say M here and read 591 - <file:Documentation/modules.txt>. If unsure, say `N'. 592 - 593 - 594 813 # ARP tables 595 814 config IP_NF_ARPTABLES 596 815 tristate "ARP tables support" 816 + depends on NETFILTER_XTABLES 597 817 help 598 818 arptables is a general, extensible packet identification framework. 599 819 The ARP packet filtering and mangling (manipulation)subsystems
-21
net/ipv4/netfilter/Makefile
··· 47 47 48 48 # matches 49 49 obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o 50 - obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o 51 50 obj-$(CONFIG_IP_NF_MATCH_HASHLIMIT) += ipt_hashlimit.o 52 - obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o 53 - obj-$(CONFIG_IP_NF_MATCH_DCCP) += ipt_dccp.o 54 - obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o 55 - obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o 56 51 obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o 57 - obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o 58 52 obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o 59 53 obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o 60 54 obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o ··· 56 62 obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o 57 63 obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o 58 64 obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_ah.o ipt_esp.o 59 - obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_length.o 60 65 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o 61 - obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o 62 - obj-$(CONFIG_IP_NF_MATCH_CONNMARK) += ipt_connmark.o 63 - obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o 64 - obj-$(CONFIG_IP_NF_MATCH_CONNBYTES) += ipt_connbytes.o 65 - obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o 66 - obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o 67 66 obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o 68 - obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o 69 67 obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o 70 - obj-$(CONFIG_IP_NF_MATCH_COMMENT) += ipt_comment.o 71 - obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o 72 68 73 69 # targets 74 70 obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o 75 71 obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o 76 72 obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o 77 73 obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_DSCP.o 78 - obj-$(CONFIG_IP_NF_TARGET_MARK) += ipt_MARK.o 79 74 obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o 80 75 obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o 81 76 obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o 82 77 obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o 83 - obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o 84 78 obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o 85 79 obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o 86 - obj-$(CONFIG_IP_NF_TARGET_CONNMARK) += ipt_CONNMARK.o 87 80 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o 88 81 obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o 89 - obj-$(CONFIG_IP_NF_TARGET_NOTRACK) += ipt_NOTRACK.o 90 82 obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o 91 83 obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o 92 - obj-$(CONFIG_IP_NF_TARGET_NFQUEUE) += ipt_NFQUEUE.o 93 84 94 85 # generic ARP tables 95 86 obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o
+79 -365
net/ipv4/netfilter/arp_tables.c
··· 24 24 #include <asm/uaccess.h> 25 25 #include <asm/semaphore.h> 26 26 27 + #include <linux/netfilter/x_tables.h> 27 28 #include <linux/netfilter_arp/arp_tables.h> 28 29 29 30 MODULE_LICENSE("GPL"); ··· 56 55 #else 57 56 #define ARP_NF_ASSERT(x) 58 57 #endif 59 - #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) 60 58 61 - static DECLARE_MUTEX(arpt_mutex); 62 - 63 - #define ASSERT_READ_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0) 64 - #define ASSERT_WRITE_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0) 65 59 #include <linux/netfilter_ipv4/listhelp.h> 66 - 67 - struct arpt_table_info { 68 - unsigned int size; 69 - unsigned int number; 70 - unsigned int initial_entries; 71 - unsigned int hook_entry[NF_ARP_NUMHOOKS]; 72 - unsigned int underflow[NF_ARP_NUMHOOKS]; 73 - void *entries[NR_CPUS]; 74 - }; 75 - 76 - static LIST_HEAD(arpt_target); 77 - static LIST_HEAD(arpt_tables); 78 - #define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0) 79 - #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) 80 60 81 61 static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap, 82 62 char *hdr_addr, int len) ··· 205 223 } 206 224 207 225 static unsigned int arpt_error(struct sk_buff **pskb, 208 - unsigned int hooknum, 209 226 const struct net_device *in, 210 227 const struct net_device *out, 228 + unsigned int hooknum, 211 229 const void *targinfo, 212 230 void *userinfo) 213 231 { ··· 236 254 struct arpt_entry *e, *back; 237 255 const char *indev, *outdev; 238 256 void *table_base; 257 + struct xt_table_info *private = table->private; 239 258 240 259 /* ARP header, plus 2 device addresses, plus 2 IP addresses. */ 241 260 if (!pskb_may_pull((*pskb), (sizeof(struct arphdr) + ··· 248 265 outdev = out ? out->name : nulldevname; 249 266 250 267 read_lock_bh(&table->lock); 251 - table_base = (void *)table->private->entries[smp_processor_id()]; 252 - e = get_entry(table_base, table->private->hook_entry[hook]); 253 - back = get_entry(table_base, table->private->underflow[hook]); 268 + table_base = (void *)private->entries[smp_processor_id()]; 269 + e = get_entry(table_base, private->hook_entry[hook]); 270 + back = get_entry(table_base, private->underflow[hook]); 254 271 255 272 arp = (*pskb)->nh.arph; 256 273 do { ··· 298 315 * abs. verdicts 299 316 */ 300 317 verdict = t->u.kernel.target->target(pskb, 301 - hook, 302 318 in, out, 319 + hook, 303 320 t->data, 304 321 userdata); 305 322 ··· 324 341 return verdict; 325 342 } 326 343 327 - /* 328 - * These are weird, but module loading must not be done with mutex 329 - * held (since they will register), and we have to have a single 330 - * function to use try_then_request_module(). 331 - */ 332 - 333 - /* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ 334 - static inline struct arpt_table *find_table_lock(const char *name) 335 - { 336 - struct arpt_table *t; 337 - 338 - if (down_interruptible(&arpt_mutex) != 0) 339 - return ERR_PTR(-EINTR); 340 - 341 - list_for_each_entry(t, &arpt_tables, list) 342 - if (strcmp(t->name, name) == 0 && try_module_get(t->me)) 343 - return t; 344 - up(&arpt_mutex); 345 - return NULL; 346 - } 347 - 348 - 349 - /* Find target, grabs ref. Returns ERR_PTR() on error. */ 350 - static inline struct arpt_target *find_target(const char *name, u8 revision) 351 - { 352 - struct arpt_target *t; 353 - int err = 0; 354 - 355 - if (down_interruptible(&arpt_mutex) != 0) 356 - return ERR_PTR(-EINTR); 357 - 358 - list_for_each_entry(t, &arpt_target, list) { 359 - if (strcmp(t->name, name) == 0) { 360 - if (t->revision == revision) { 361 - if (try_module_get(t->me)) { 362 - up(&arpt_mutex); 363 - return t; 364 - } 365 - } else 366 - err = -EPROTOTYPE; /* Found something. */ 367 - } 368 - } 369 - up(&arpt_mutex); 370 - return ERR_PTR(err); 371 - } 372 - 373 - struct arpt_target *arpt_find_target(const char *name, u8 revision) 374 - { 375 - struct arpt_target *target; 376 - 377 - target = try_then_request_module(find_target(name, revision), 378 - "arpt_%s", name); 379 - if (IS_ERR(target) || !target) 380 - return NULL; 381 - return target; 382 - } 383 - 384 - static int target_revfn(const char *name, u8 revision, int *bestp) 385 - { 386 - struct arpt_target *t; 387 - int have_rev = 0; 388 - 389 - list_for_each_entry(t, &arpt_target, list) { 390 - if (strcmp(t->name, name) == 0) { 391 - if (t->revision > *bestp) 392 - *bestp = t->revision; 393 - if (t->revision == revision) 394 - have_rev =1; 395 - } 396 - } 397 - return have_rev; 398 - } 399 - 400 - /* Returns true or false (if no such extension at all) */ 401 - static inline int find_revision(const char *name, u8 revision, 402 - int (*revfn)(const char *, u8, int *), 403 - int *err) 404 - { 405 - int have_rev, best = -1; 406 - 407 - if (down_interruptible(&arpt_mutex) != 0) { 408 - *err = -EINTR; 409 - return 1; 410 - } 411 - have_rev = revfn(name, revision, &best); 412 - up(&arpt_mutex); 413 - 414 - /* Nothing at all? Return 0 to try loading module. */ 415 - if (best == -1) { 416 - *err = -ENOENT; 417 - return 0; 418 - } 419 - 420 - *err = best; 421 - if (!have_rev) 422 - *err = -EPROTONOSUPPORT; 423 - return 1; 424 - } 425 - 426 - 427 344 /* All zeroes == unconditional rule. */ 428 345 static inline int unconditional(const struct arpt_arp *arp) 429 346 { ··· 339 456 /* Figures out from what hook each rule can be called: returns 0 if 340 457 * there are loops. Puts hook bitmask in comefrom. 341 458 */ 342 - static int mark_source_chains(struct arpt_table_info *newinfo, 459 + static int mark_source_chains(struct xt_table_info *newinfo, 343 460 unsigned int valid_hooks, void *entry0) 344 461 { 345 462 unsigned int hook; ··· 470 587 } 471 588 472 589 t = arpt_get_target(e); 473 - target = try_then_request_module(find_target(t->u.user.name, 474 - t->u.user.revision), 590 + target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name, 591 + t->u.user.revision), 475 592 "arpt_%s", t->u.user.name); 476 593 if (IS_ERR(target) || !target) { 477 594 duprintf("check_entry: `%s' not found\n", t->u.user.name); ··· 505 622 } 506 623 507 624 static inline int check_entry_size_and_hooks(struct arpt_entry *e, 508 - struct arpt_table_info *newinfo, 625 + struct xt_table_info *newinfo, 509 626 unsigned char *base, 510 627 unsigned char *limit, 511 628 const unsigned int *hook_entries, ··· 539 656 < 0 (not ARPT_RETURN). --RR */ 540 657 541 658 /* Clear counters and comefrom */ 542 - e->counters = ((struct arpt_counters) { 0, 0 }); 659 + e->counters = ((struct xt_counters) { 0, 0 }); 543 660 e->comefrom = 0; 544 661 545 662 (*i)++; ··· 566 683 */ 567 684 static int translate_table(const char *name, 568 685 unsigned int valid_hooks, 569 - struct arpt_table_info *newinfo, 686 + struct xt_table_info *newinfo, 570 687 void *entry0, 571 688 unsigned int size, 572 689 unsigned int number, ··· 647 764 return ret; 648 765 } 649 766 650 - static struct arpt_table_info *replace_table(struct arpt_table *table, 651 - unsigned int num_counters, 652 - struct arpt_table_info *newinfo, 653 - int *error) 654 - { 655 - struct arpt_table_info *oldinfo; 656 - 657 - /* Do the substitution. */ 658 - write_lock_bh(&table->lock); 659 - /* Check inside lock: is the old number correct? */ 660 - if (num_counters != table->private->number) { 661 - duprintf("num_counters != table->private->number (%u/%u)\n", 662 - num_counters, table->private->number); 663 - write_unlock_bh(&table->lock); 664 - *error = -EAGAIN; 665 - return NULL; 666 - } 667 - oldinfo = table->private; 668 - table->private = newinfo; 669 - newinfo->initial_entries = oldinfo->initial_entries; 670 - write_unlock_bh(&table->lock); 671 - 672 - return oldinfo; 673 - } 674 - 675 767 /* Gets counters. */ 676 768 static inline int add_entry_to_counter(const struct arpt_entry *e, 677 - struct arpt_counters total[], 769 + struct xt_counters total[], 678 770 unsigned int *i) 679 771 { 680 772 ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); ··· 659 801 } 660 802 661 803 static inline int set_entry_to_counter(const struct arpt_entry *e, 662 - struct arpt_counters total[], 804 + struct xt_counters total[], 663 805 unsigned int *i) 664 806 { 665 807 SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); ··· 668 810 return 0; 669 811 } 670 812 671 - static void get_counters(const struct arpt_table_info *t, 672 - struct arpt_counters counters[]) 813 + static void get_counters(const struct xt_table_info *t, 814 + struct xt_counters counters[]) 673 815 { 674 816 unsigned int cpu; 675 817 unsigned int i; ··· 707 849 { 708 850 unsigned int off, num, countersize; 709 851 struct arpt_entry *e; 710 - struct arpt_counters *counters; 852 + struct xt_counters *counters; 853 + struct xt_table_info *private = table->private; 711 854 int ret = 0; 712 855 void *loc_cpu_entry; 713 856 ··· 716 857 * (other than comefrom, which userspace doesn't care 717 858 * about). 718 859 */ 719 - countersize = sizeof(struct arpt_counters) * table->private->number; 720 - counters = vmalloc(countersize); 860 + countersize = sizeof(struct xt_counters) * private->number; 861 + counters = vmalloc_node(countersize, numa_node_id()); 721 862 722 863 if (counters == NULL) 723 864 return -ENOMEM; 724 865 725 866 /* First, sum counters... */ 726 867 write_lock_bh(&table->lock); 727 - get_counters(table->private, counters); 868 + get_counters(private, counters); 728 869 write_unlock_bh(&table->lock); 729 870 730 - loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; 871 + loc_cpu_entry = private->entries[raw_smp_processor_id()]; 731 872 /* ... then copy entire thing ... */ 732 873 if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { 733 874 ret = -EFAULT; ··· 770 911 int ret; 771 912 struct arpt_table *t; 772 913 773 - t = find_table_lock(entries->name); 914 + t = xt_find_table_lock(NF_ARP, entries->name); 774 915 if (t || !IS_ERR(t)) { 916 + struct xt_table_info *private = t->private; 775 917 duprintf("t->private->number = %u\n", 776 - t->private->number); 777 - if (entries->size == t->private->size) 778 - ret = copy_entries_to_user(t->private->size, 918 + private->number); 919 + if (entries->size == private->size) 920 + ret = copy_entries_to_user(private->size, 779 921 t, uptr->entrytable); 780 922 else { 781 923 duprintf("get_entries: I've got %u not %u!\n", 782 - t->private->size, 783 - entries->size); 924 + private->size, entries->size); 784 925 ret = -EINVAL; 785 926 } 786 927 module_put(t->me); 787 - up(&arpt_mutex); 928 + xt_table_unlock(t); 788 929 } else 789 930 ret = t ? PTR_ERR(t) : -ENOENT; 790 931 791 932 return ret; 792 - } 793 - 794 - static void free_table_info(struct arpt_table_info *info) 795 - { 796 - int cpu; 797 - for_each_cpu(cpu) { 798 - if (info->size <= PAGE_SIZE) 799 - kfree(info->entries[cpu]); 800 - else 801 - vfree(info->entries[cpu]); 802 - } 803 - kfree(info); 804 - } 805 - 806 - static struct arpt_table_info *alloc_table_info(unsigned int size) 807 - { 808 - struct arpt_table_info *newinfo; 809 - int cpu; 810 - 811 - newinfo = kzalloc(sizeof(struct arpt_table_info), GFP_KERNEL); 812 - if (!newinfo) 813 - return NULL; 814 - 815 - newinfo->size = size; 816 - 817 - for_each_cpu(cpu) { 818 - if (size <= PAGE_SIZE) 819 - newinfo->entries[cpu] = kmalloc_node(size, 820 - GFP_KERNEL, 821 - cpu_to_node(cpu)); 822 - else 823 - newinfo->entries[cpu] = vmalloc_node(size, 824 - cpu_to_node(cpu)); 825 - 826 - if (newinfo->entries[cpu] == NULL) { 827 - free_table_info(newinfo); 828 - return NULL; 829 - } 830 - } 831 - 832 - return newinfo; 833 933 } 834 934 835 935 static int do_replace(void __user *user, unsigned int len) ··· 796 978 int ret; 797 979 struct arpt_replace tmp; 798 980 struct arpt_table *t; 799 - struct arpt_table_info *newinfo, *oldinfo; 800 - struct arpt_counters *counters; 981 + struct xt_table_info *newinfo, *oldinfo; 982 + struct xt_counters *counters; 801 983 void *loc_cpu_entry, *loc_cpu_old_entry; 802 984 803 985 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) ··· 807 989 if (len != sizeof(tmp) + tmp.size) 808 990 return -ENOPROTOOPT; 809 991 810 - /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */ 811 - if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages) 812 - return -ENOMEM; 813 - 814 - newinfo = alloc_table_info(tmp.size); 992 + newinfo = xt_alloc_table_info(tmp.size); 815 993 if (!newinfo) 816 994 return -ENOMEM; 817 995 ··· 819 1005 goto free_newinfo; 820 1006 } 821 1007 822 - counters = vmalloc(tmp.num_counters * sizeof(struct arpt_counters)); 1008 + counters = vmalloc(tmp.num_counters * sizeof(struct xt_counters)); 823 1009 if (!counters) { 824 1010 ret = -ENOMEM; 825 1011 goto free_newinfo; ··· 833 1019 834 1020 duprintf("arp_tables: Translated table\n"); 835 1021 836 - t = try_then_request_module(find_table_lock(tmp.name), 1022 + t = try_then_request_module(xt_find_table_lock(NF_ARP, tmp.name), 837 1023 "arptable_%s", tmp.name); 838 1024 if (!t || IS_ERR(t)) { 839 1025 ret = t ? PTR_ERR(t) : -ENOENT; ··· 848 1034 goto put_module; 849 1035 } 850 1036 851 - oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret); 1037 + oldinfo = xt_replace_table(t, tmp.num_counters, newinfo, &ret); 852 1038 if (!oldinfo) 853 1039 goto put_module; 854 1040 ··· 868 1054 loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; 869 1055 ARPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); 870 1056 871 - free_table_info(oldinfo); 1057 + xt_free_table_info(oldinfo); 872 1058 if (copy_to_user(tmp.counters, counters, 873 - sizeof(struct arpt_counters) * tmp.num_counters) != 0) 1059 + sizeof(struct xt_counters) * tmp.num_counters) != 0) 874 1060 ret = -EFAULT; 875 1061 vfree(counters); 876 - up(&arpt_mutex); 1062 + xt_table_unlock(t); 877 1063 return ret; 878 1064 879 1065 put_module: 880 1066 module_put(t->me); 881 - up(&arpt_mutex); 1067 + xt_table_unlock(t); 882 1068 free_newinfo_counters_untrans: 883 1069 ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); 884 1070 free_newinfo_counters: 885 1071 vfree(counters); 886 1072 free_newinfo: 887 - free_table_info(newinfo); 1073 + xt_free_table_info(newinfo); 888 1074 return ret; 889 1075 } 890 1076 ··· 892 1078 * and everything is OK. 893 1079 */ 894 1080 static inline int add_counter_to_entry(struct arpt_entry *e, 895 - const struct arpt_counters addme[], 1081 + const struct xt_counters addme[], 896 1082 unsigned int *i) 897 1083 { 898 1084 ··· 905 1091 static int do_add_counters(void __user *user, unsigned int len) 906 1092 { 907 1093 unsigned int i; 908 - struct arpt_counters_info tmp, *paddc; 1094 + struct xt_counters_info tmp, *paddc; 909 1095 struct arpt_table *t; 1096 + struct xt_table_info *private; 910 1097 int ret = 0; 911 1098 void *loc_cpu_entry; 912 1099 913 1100 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 914 1101 return -EFAULT; 915 1102 916 - if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct arpt_counters)) 1103 + if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct xt_counters)) 917 1104 return -EINVAL; 918 1105 919 1106 paddc = vmalloc(len); ··· 926 1111 goto free; 927 1112 } 928 1113 929 - t = find_table_lock(tmp.name); 1114 + t = xt_find_table_lock(NF_ARP, tmp.name); 930 1115 if (!t || IS_ERR(t)) { 931 1116 ret = t ? PTR_ERR(t) : -ENOENT; 932 1117 goto free; 933 1118 } 934 1119 935 1120 write_lock_bh(&t->lock); 936 - if (t->private->number != paddc->num_counters) { 1121 + private = t->private; 1122 + if (private->number != paddc->num_counters) { 937 1123 ret = -EINVAL; 938 1124 goto unlock_up_free; 939 1125 } 940 1126 941 1127 i = 0; 942 1128 /* Choose the copy that is on our node */ 943 - loc_cpu_entry = t->private->entries[smp_processor_id()]; 1129 + loc_cpu_entry = private->entries[smp_processor_id()]; 944 1130 ARPT_ENTRY_ITERATE(loc_cpu_entry, 945 - t->private->size, 1131 + private->size, 946 1132 add_counter_to_entry, 947 1133 paddc->counters, 948 1134 &i); 949 1135 unlock_up_free: 950 1136 write_unlock_bh(&t->lock); 951 - up(&arpt_mutex); 1137 + xt_table_unlock(t); 952 1138 module_put(t->me); 953 1139 free: 954 1140 vfree(paddc); ··· 1006 1190 } 1007 1191 name[ARPT_TABLE_MAXNAMELEN-1] = '\0'; 1008 1192 1009 - t = try_then_request_module(find_table_lock(name), 1193 + t = try_then_request_module(xt_find_table_lock(NF_ARP, name), 1010 1194 "arptable_%s", name); 1011 1195 if (t && !IS_ERR(t)) { 1012 1196 struct arpt_getinfo info; 1197 + struct xt_table_info *private = t->private; 1013 1198 1014 1199 info.valid_hooks = t->valid_hooks; 1015 - memcpy(info.hook_entry, t->private->hook_entry, 1200 + memcpy(info.hook_entry, private->hook_entry, 1016 1201 sizeof(info.hook_entry)); 1017 - memcpy(info.underflow, t->private->underflow, 1202 + memcpy(info.underflow, private->underflow, 1018 1203 sizeof(info.underflow)); 1019 - info.num_entries = t->private->number; 1020 - info.size = t->private->size; 1204 + info.num_entries = private->number; 1205 + info.size = private->size; 1021 1206 strcpy(info.name, name); 1022 1207 1023 1208 if (copy_to_user(user, &info, *len) != 0) 1024 1209 ret = -EFAULT; 1025 1210 else 1026 1211 ret = 0; 1027 - up(&arpt_mutex); 1212 + xt_table_unlock(t); 1028 1213 module_put(t->me); 1029 1214 } else 1030 1215 ret = t ? PTR_ERR(t) : -ENOENT; ··· 1050 1233 } 1051 1234 1052 1235 case ARPT_SO_GET_REVISION_TARGET: { 1053 - struct arpt_get_revision rev; 1236 + struct xt_get_revision rev; 1054 1237 1055 1238 if (*len != sizeof(rev)) { 1056 1239 ret = -EINVAL; ··· 1061 1244 break; 1062 1245 } 1063 1246 1064 - try_then_request_module(find_revision(rev.name, rev.revision, 1065 - target_revfn, &ret), 1247 + try_then_request_module(xt_find_revision(NF_ARP, rev.name, 1248 + rev.revision, 1, &ret), 1066 1249 "arpt_%s", rev.name); 1067 1250 break; 1068 1251 } ··· 1075 1258 return ret; 1076 1259 } 1077 1260 1078 - /* Registration hooks for targets. */ 1079 - int arpt_register_target(struct arpt_target *target) 1080 - { 1081 - int ret; 1082 - 1083 - ret = down_interruptible(&arpt_mutex); 1084 - if (ret != 0) 1085 - return ret; 1086 - 1087 - list_add(&target->list, &arpt_target); 1088 - up(&arpt_mutex); 1089 - 1090 - return ret; 1091 - } 1092 - 1093 - void arpt_unregister_target(struct arpt_target *target) 1094 - { 1095 - down(&arpt_mutex); 1096 - LIST_DELETE(&arpt_target, target); 1097 - up(&arpt_mutex); 1098 - } 1099 - 1100 1261 int arpt_register_table(struct arpt_table *table, 1101 1262 const struct arpt_replace *repl) 1102 1263 { 1103 1264 int ret; 1104 - struct arpt_table_info *newinfo; 1105 - static struct arpt_table_info bootstrap 1265 + struct xt_table_info *newinfo; 1266 + static struct xt_table_info bootstrap 1106 1267 = { 0, 0, 0, { 0 }, { 0 }, { } }; 1107 1268 void *loc_cpu_entry; 1108 1269 1109 - newinfo = alloc_table_info(repl->size); 1270 + newinfo = xt_alloc_table_info(repl->size); 1110 1271 if (!newinfo) { 1111 1272 ret = -ENOMEM; 1112 1273 return ret; ··· 1099 1304 repl->num_entries, 1100 1305 repl->hook_entry, 1101 1306 repl->underflow); 1307 + 1102 1308 duprintf("arpt_register_table: translate table gives %d\n", ret); 1103 1309 if (ret != 0) { 1104 - free_table_info(newinfo); 1310 + xt_free_table_info(newinfo); 1105 1311 return ret; 1106 1312 } 1107 1313 1108 - ret = down_interruptible(&arpt_mutex); 1109 - if (ret != 0) { 1110 - free_table_info(newinfo); 1314 + if (xt_register_table(table, &bootstrap, newinfo) != 0) { 1315 + xt_free_table_info(newinfo); 1111 1316 return ret; 1112 1317 } 1113 1318 1114 - /* Don't autoload: we'd eat our tail... */ 1115 - if (list_named_find(&arpt_tables, table->name)) { 1116 - ret = -EEXIST; 1117 - goto free_unlock; 1118 - } 1119 - 1120 - /* Simplifies replace_table code. */ 1121 - table->private = &bootstrap; 1122 - if (!replace_table(table, 0, newinfo, &ret)) 1123 - goto free_unlock; 1124 - 1125 - duprintf("table->private->number = %u\n", 1126 - table->private->number); 1127 - 1128 - /* save number of initial entries */ 1129 - table->private->initial_entries = table->private->number; 1130 - 1131 - rwlock_init(&table->lock); 1132 - list_prepend(&arpt_tables, table); 1133 - 1134 - unlock: 1135 - up(&arpt_mutex); 1136 - return ret; 1137 - 1138 - free_unlock: 1139 - free_table_info(newinfo); 1140 - goto unlock; 1319 + return 0; 1141 1320 } 1142 1321 1143 1322 void arpt_unregister_table(struct arpt_table *table) 1144 1323 { 1324 + struct xt_table_info *private; 1145 1325 void *loc_cpu_entry; 1146 1326 1147 - down(&arpt_mutex); 1148 - LIST_DELETE(&arpt_tables, table); 1149 - up(&arpt_mutex); 1327 + private = xt_unregister_table(table); 1150 1328 1151 1329 /* Decrease module usage counts and free resources */ 1152 - loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; 1153 - ARPT_ENTRY_ITERATE(loc_cpu_entry, table->private->size, 1330 + loc_cpu_entry = private->entries[raw_smp_processor_id()]; 1331 + ARPT_ENTRY_ITERATE(loc_cpu_entry, private->size, 1154 1332 cleanup_entry, NULL); 1155 - free_table_info(table->private); 1333 + xt_free_table_info(private); 1156 1334 } 1157 1335 1158 1336 /* The built-in targets: standard (NULL) and error. */ ··· 1148 1380 .get = do_arpt_get_ctl, 1149 1381 }; 1150 1382 1151 - #ifdef CONFIG_PROC_FS 1152 - static inline int print_name(const struct arpt_table *t, 1153 - off_t start_offset, char *buffer, int length, 1154 - off_t *pos, unsigned int *count) 1155 - { 1156 - if ((*count)++ >= start_offset) { 1157 - unsigned int namelen; 1158 - 1159 - namelen = sprintf(buffer + *pos, "%s\n", t->name); 1160 - if (*pos + namelen > length) { 1161 - /* Stop iterating */ 1162 - return 1; 1163 - } 1164 - *pos += namelen; 1165 - } 1166 - return 0; 1167 - } 1168 - 1169 - static int arpt_get_tables(char *buffer, char **start, off_t offset, int length) 1170 - { 1171 - off_t pos = 0; 1172 - unsigned int count = 0; 1173 - 1174 - if (down_interruptible(&arpt_mutex) != 0) 1175 - return 0; 1176 - 1177 - LIST_FIND(&arpt_tables, print_name, struct arpt_table *, 1178 - offset, buffer, length, &pos, &count); 1179 - 1180 - up(&arpt_mutex); 1181 - 1182 - /* `start' hack - see fs/proc/generic.c line ~105 */ 1183 - *start=(char *)((unsigned long)count-offset); 1184 - return pos; 1185 - } 1186 - #endif /*CONFIG_PROC_FS*/ 1187 - 1188 1383 static int __init init(void) 1189 1384 { 1190 1385 int ret; 1191 1386 1387 + xt_proto_init(NF_ARP); 1388 + 1192 1389 /* Noone else will be downing sem now, so we won't sleep */ 1193 - down(&arpt_mutex); 1194 - list_append(&arpt_target, &arpt_standard_target); 1195 - list_append(&arpt_target, &arpt_error_target); 1196 - up(&arpt_mutex); 1390 + xt_register_target(NF_ARP, &arpt_standard_target); 1391 + xt_register_target(NF_ARP, &arpt_error_target); 1197 1392 1198 1393 /* Register setsockopt */ 1199 1394 ret = nf_register_sockopt(&arpt_sockopts); ··· 1165 1434 return ret; 1166 1435 } 1167 1436 1168 - #ifdef CONFIG_PROC_FS 1169 - { 1170 - struct proc_dir_entry *proc; 1171 - 1172 - proc = proc_net_create("arp_tables_names", 0, arpt_get_tables); 1173 - if (!proc) { 1174 - nf_unregister_sockopt(&arpt_sockopts); 1175 - return -ENOMEM; 1176 - } 1177 - proc->owner = THIS_MODULE; 1178 - } 1179 - #endif 1180 - 1181 1437 printk("arp_tables: (C) 2002 David S. Miller\n"); 1182 1438 return 0; 1183 1439 } ··· 1172 1454 static void __exit fini(void) 1173 1455 { 1174 1456 nf_unregister_sockopt(&arpt_sockopts); 1175 - #ifdef CONFIG_PROC_FS 1176 - proc_net_remove("arp_tables_names"); 1177 - #endif 1457 + xt_proto_fini(NF_ARP); 1178 1458 } 1179 1459 1180 1460 EXPORT_SYMBOL(arpt_register_table); 1181 1461 EXPORT_SYMBOL(arpt_unregister_table); 1182 1462 EXPORT_SYMBOL(arpt_do_table); 1183 - EXPORT_SYMBOL(arpt_register_target); 1184 - EXPORT_SYMBOL(arpt_unregister_target); 1185 1463 1186 1464 module_init(init); 1187 1465 module_exit(fini);
+4 -3
net/ipv4/netfilter/arpt_mangle.c
··· 8 8 MODULE_DESCRIPTION("arptables arp payload mangle target"); 9 9 10 10 static unsigned int 11 - target(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in, 12 - const struct net_device *out, const void *targinfo, void *userinfo) 11 + target(struct sk_buff **pskb, const struct net_device *in, 12 + const struct net_device *out, unsigned int hooknum, const void *targinfo, 13 + void *userinfo) 13 14 { 14 15 const struct arpt_mangle *mangle = targinfo; 15 16 struct arphdr *arp; ··· 65 64 } 66 65 67 66 static int 68 - checkentry(const char *tablename, const struct arpt_entry *e, void *targinfo, 67 + checkentry(const char *tablename, const void *e, void *targinfo, 69 68 unsigned int targinfosize, unsigned int hook_mask) 70 69 { 71 70 const struct arpt_mangle *mangle = targinfo;
+1
net/ipv4/netfilter/arptable_filter.c
··· 145 145 .lock = RW_LOCK_UNLOCKED, 146 146 .private = NULL, 147 147 .me = THIS_MODULE, 148 + .af = NF_ARP, 148 149 }; 149 150 150 151 /* The work comes in here from netfilter.c */
+2 -2
net/ipv4/netfilter/ip_conntrack_standalone.c
··· 944 944 945 945 /* Some modules need us, but don't depend directly on any symbol. 946 946 They should call this. */ 947 - void need_ip_conntrack(void) 947 + void need_conntrack(void) 948 948 { 949 949 } 950 950 ··· 962 962 EXPORT_SYMBOL(invert_tuplepr); 963 963 EXPORT_SYMBOL(ip_conntrack_alter_reply); 964 964 EXPORT_SYMBOL(ip_conntrack_destroyed); 965 - EXPORT_SYMBOL(need_ip_conntrack); 965 + EXPORT_SYMBOL(need_conntrack); 966 966 EXPORT_SYMBOL(ip_conntrack_helper_register); 967 967 EXPORT_SYMBOL(ip_conntrack_helper_unregister); 968 968 EXPORT_SYMBOL(ip_ct_iterate_cleanup);
+3 -2
net/ipv4/netfilter/ip_nat_rule.c
··· 95 95 .valid_hooks = NAT_VALID_HOOKS, 96 96 .lock = RW_LOCK_UNLOCKED, 97 97 .me = THIS_MODULE, 98 + .af = AF_INET, 98 99 }; 99 100 100 101 /* Source NAT */ ··· 169 168 } 170 169 171 170 static int ipt_snat_checkentry(const char *tablename, 172 - const struct ipt_entry *e, 171 + const void *entry, 173 172 void *targinfo, 174 173 unsigned int targinfosize, 175 174 unsigned int hook_mask) ··· 202 201 } 203 202 204 203 static int ipt_dnat_checkentry(const char *tablename, 205 - const struct ipt_entry *e, 204 + const void *entry, 206 205 void *targinfo, 207 206 unsigned int targinfosize, 208 207 unsigned int hook_mask)
+1 -1
net/ipv4/netfilter/ip_nat_standalone.c
··· 364 364 { 365 365 int ret = 0; 366 366 367 - need_ip_conntrack(); 367 + need_conntrack(); 368 368 369 369 if (!init) goto cleanup; 370 370
+95 -747
net/ipv4/netfilter/ip_tables.c
··· 2 2 * Packet matching code. 3 3 * 4 4 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling 5 - * Copyright (C) 2000-2004 Netfilter Core Team <coreteam@netfilter.org> 5 + * Copyright (C) 2000-2005 Netfilter Core Team <coreteam@netfilter.org> 6 6 * 7 7 * This program is free software; you can redistribute it and/or modify 8 8 * it under the terms of the GNU General Public License version 2 as ··· 11 11 * 19 Jan 2002 Harald Welte <laforge@gnumonks.org> 12 12 * - increase module usage count as soon as we have rules inside 13 13 * a table 14 + * 08 Oct 2005 Harald Welte <lafore@netfilter.org> 15 + * - Generalize into "x_tables" layer and "{ip,ip6,arp}_tables" 14 16 */ 15 17 #include <linux/config.h> 16 18 #include <linux/cache.h> ··· 22 20 #include <linux/vmalloc.h> 23 21 #include <linux/netdevice.h> 24 22 #include <linux/module.h> 25 - #include <linux/tcp.h> 26 - #include <linux/udp.h> 27 23 #include <linux/icmp.h> 28 24 #include <net/ip.h> 29 25 #include <asm/uaccess.h> ··· 30 30 #include <linux/err.h> 31 31 #include <linux/cpumask.h> 32 32 33 + #include <linux/netfilter/x_tables.h> 33 34 #include <linux/netfilter_ipv4/ip_tables.h> 34 35 35 36 MODULE_LICENSE("GPL"); ··· 63 62 #else 64 63 #define IP_NF_ASSERT(x) 65 64 #endif 66 - #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) 67 - 68 - static DECLARE_MUTEX(ipt_mutex); 69 - 70 - /* Must have mutex */ 71 - #define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0) 72 - #define ASSERT_WRITE_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0) 73 - #include <linux/netfilter_ipv4/listhelp.h> 74 65 75 66 #if 0 76 67 /* All the better to debug you with... */ ··· 78 85 the counters or update the rules. 79 86 80 87 Hence the start of any table is given by get_table() below. */ 81 - 82 - /* The table itself */ 83 - struct ipt_table_info 84 - { 85 - /* Size per table */ 86 - unsigned int size; 87 - /* Number of entries: FIXME. --RR */ 88 - unsigned int number; 89 - /* Initial number of entries. Needed for module usage count */ 90 - unsigned int initial_entries; 91 - 92 - /* Entry points and underflows */ 93 - unsigned int hook_entry[NF_IP_NUMHOOKS]; 94 - unsigned int underflow[NF_IP_NUMHOOKS]; 95 - 96 - /* ipt_entry tables: one per CPU */ 97 - void *entries[NR_CPUS]; 98 - }; 99 - 100 - static LIST_HEAD(ipt_target); 101 - static LIST_HEAD(ipt_match); 102 - static LIST_HEAD(ipt_tables); 103 - #define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0) 104 - #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) 105 - 106 - #if 0 107 - #define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0) 108 - #define down_interruptible(x) ({ int __r; printk("DOWNi:%u:" #x "\n", __LINE__); __r = down_interruptible(x); if (__r != 0) printk("ABORT-DOWNi:%u\n", __LINE__); __r; }) 109 - #define up(x) do { printk("UP:%u:" #x "\n", __LINE__); up(x); } while(0) 110 - #endif 111 88 112 89 /* Returns whether matches rule or not. */ 113 90 static inline int ··· 197 234 int *hotdrop) 198 235 { 199 236 /* Stop iteration if it doesn't match */ 200 - if (!m->u.kernel.match->match(skb, in, out, m->data, offset, hotdrop)) 237 + if (!m->u.kernel.match->match(skb, in, out, m->data, offset, 238 + skb->nh.iph->ihl*4, hotdrop)) 201 239 return 1; 202 240 else 203 241 return 0; ··· 229 265 const char *indev, *outdev; 230 266 void *table_base; 231 267 struct ipt_entry *e, *back; 268 + struct xt_table_info *private = table->private; 232 269 233 270 /* Initialization */ 234 271 ip = (*pskb)->nh.iph; ··· 246 281 247 282 read_lock_bh(&table->lock); 248 283 IP_NF_ASSERT(table->valid_hooks & (1 << hook)); 249 - table_base = (void *)table->private->entries[smp_processor_id()]; 250 - e = get_entry(table_base, table->private->hook_entry[hook]); 251 - 252 - #ifdef CONFIG_NETFILTER_DEBUG 253 - /* Check noone else using our table */ 254 - if (((struct ipt_entry *)table_base)->comefrom != 0xdead57ac 255 - && ((struct ipt_entry *)table_base)->comefrom != 0xeeeeeeec) { 256 - printk("ASSERT: CPU #%u, %s comefrom(%p) = %X\n", 257 - smp_processor_id(), 258 - table->name, 259 - &((struct ipt_entry *)table_base)->comefrom, 260 - ((struct ipt_entry *)table_base)->comefrom); 261 - } 262 - ((struct ipt_entry *)table_base)->comefrom = 0x57acc001; 263 - #endif 284 + table_base = (void *)private->entries[smp_processor_id()]; 285 + e = get_entry(table_base, private->hook_entry[hook]); 264 286 265 287 /* For return from builtin chain */ 266 - back = get_entry(table_base, table->private->underflow[hook]); 288 + back = get_entry(table_base, private->underflow[hook]); 267 289 268 290 do { 269 291 IP_NF_ASSERT(e); ··· 336 384 } 337 385 } while (!hotdrop); 338 386 339 - #ifdef CONFIG_NETFILTER_DEBUG 340 - ((struct ipt_entry *)table_base)->comefrom = 0xdead57ac; 341 - #endif 342 387 read_unlock_bh(&table->lock); 343 388 344 389 #ifdef DEBUG_ALLOW_ALL ··· 346 397 else return verdict; 347 398 #endif 348 399 } 349 - 350 - /* 351 - * These are weird, but module loading must not be done with mutex 352 - * held (since they will register), and we have to have a single 353 - * function to use try_then_request_module(). 354 - */ 355 - 356 - /* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ 357 - static inline struct ipt_table *find_table_lock(const char *name) 358 - { 359 - struct ipt_table *t; 360 - 361 - if (down_interruptible(&ipt_mutex) != 0) 362 - return ERR_PTR(-EINTR); 363 - 364 - list_for_each_entry(t, &ipt_tables, list) 365 - if (strcmp(t->name, name) == 0 && try_module_get(t->me)) 366 - return t; 367 - up(&ipt_mutex); 368 - return NULL; 369 - } 370 - 371 - /* Find match, grabs ref. Returns ERR_PTR() on error. */ 372 - static inline struct ipt_match *find_match(const char *name, u8 revision) 373 - { 374 - struct ipt_match *m; 375 - int err = 0; 376 - 377 - if (down_interruptible(&ipt_mutex) != 0) 378 - return ERR_PTR(-EINTR); 379 - 380 - list_for_each_entry(m, &ipt_match, list) { 381 - if (strcmp(m->name, name) == 0) { 382 - if (m->revision == revision) { 383 - if (try_module_get(m->me)) { 384 - up(&ipt_mutex); 385 - return m; 386 - } 387 - } else 388 - err = -EPROTOTYPE; /* Found something. */ 389 - } 390 - } 391 - up(&ipt_mutex); 392 - return ERR_PTR(err); 393 - } 394 - 395 - /* Find target, grabs ref. Returns ERR_PTR() on error. */ 396 - static inline struct ipt_target *find_target(const char *name, u8 revision) 397 - { 398 - struct ipt_target *t; 399 - int err = 0; 400 - 401 - if (down_interruptible(&ipt_mutex) != 0) 402 - return ERR_PTR(-EINTR); 403 - 404 - list_for_each_entry(t, &ipt_target, list) { 405 - if (strcmp(t->name, name) == 0) { 406 - if (t->revision == revision) { 407 - if (try_module_get(t->me)) { 408 - up(&ipt_mutex); 409 - return t; 410 - } 411 - } else 412 - err = -EPROTOTYPE; /* Found something. */ 413 - } 414 - } 415 - up(&ipt_mutex); 416 - return ERR_PTR(err); 417 - } 418 - 419 - struct ipt_target *ipt_find_target(const char *name, u8 revision) 420 - { 421 - struct ipt_target *target; 422 - 423 - target = try_then_request_module(find_target(name, revision), 424 - "ipt_%s", name); 425 - if (IS_ERR(target) || !target) 426 - return NULL; 427 - return target; 428 - } 429 - 430 - static int match_revfn(const char *name, u8 revision, int *bestp) 431 - { 432 - struct ipt_match *m; 433 - int have_rev = 0; 434 - 435 - list_for_each_entry(m, &ipt_match, list) { 436 - if (strcmp(m->name, name) == 0) { 437 - if (m->revision > *bestp) 438 - *bestp = m->revision; 439 - if (m->revision == revision) 440 - have_rev = 1; 441 - } 442 - } 443 - return have_rev; 444 - } 445 - 446 - static int target_revfn(const char *name, u8 revision, int *bestp) 447 - { 448 - struct ipt_target *t; 449 - int have_rev = 0; 450 - 451 - list_for_each_entry(t, &ipt_target, list) { 452 - if (strcmp(t->name, name) == 0) { 453 - if (t->revision > *bestp) 454 - *bestp = t->revision; 455 - if (t->revision == revision) 456 - have_rev = 1; 457 - } 458 - } 459 - return have_rev; 460 - } 461 - 462 - /* Returns true or false (if no such extension at all) */ 463 - static inline int find_revision(const char *name, u8 revision, 464 - int (*revfn)(const char *, u8, int *), 465 - int *err) 466 - { 467 - int have_rev, best = -1; 468 - 469 - if (down_interruptible(&ipt_mutex) != 0) { 470 - *err = -EINTR; 471 - return 1; 472 - } 473 - have_rev = revfn(name, revision, &best); 474 - up(&ipt_mutex); 475 - 476 - /* Nothing at all? Return 0 to try loading module. */ 477 - if (best == -1) { 478 - *err = -ENOENT; 479 - return 0; 480 - } 481 - 482 - *err = best; 483 - if (!have_rev) 484 - *err = -EPROTONOSUPPORT; 485 - return 1; 486 - } 487 - 488 400 489 401 /* All zeroes == unconditional rule. */ 490 402 static inline int ··· 363 553 /* Figures out from what hook each rule can be called: returns 0 if 364 554 there are loops. Puts hook bitmask in comefrom. */ 365 555 static int 366 - mark_source_chains(struct ipt_table_info *newinfo, 556 + mark_source_chains(struct xt_table_info *newinfo, 367 557 unsigned int valid_hooks, void *entry0) 368 558 { 369 559 unsigned int hook; ··· 509 699 { 510 700 struct ipt_match *match; 511 701 512 - match = try_then_request_module(find_match(m->u.user.name, 702 + match = try_then_request_module(xt_find_match(AF_INET, m->u.user.name, 513 703 m->u.user.revision), 514 704 "ipt_%s", m->u.user.name); 515 705 if (IS_ERR(match) || !match) { ··· 554 744 goto cleanup_matches; 555 745 556 746 t = ipt_get_target(e); 557 - target = try_then_request_module(find_target(t->u.user.name, 747 + target = try_then_request_module(xt_find_target(AF_INET, 748 + t->u.user.name, 558 749 t->u.user.revision), 559 750 "ipt_%s", t->u.user.name); 560 751 if (IS_ERR(target) || !target) { ··· 592 781 593 782 static inline int 594 783 check_entry_size_and_hooks(struct ipt_entry *e, 595 - struct ipt_table_info *newinfo, 784 + struct xt_table_info *newinfo, 596 785 unsigned char *base, 597 786 unsigned char *limit, 598 787 const unsigned int *hook_entries, ··· 626 815 < 0 (not IPT_RETURN). --RR */ 627 816 628 817 /* Clear counters and comefrom */ 629 - e->counters = ((struct ipt_counters) { 0, 0 }); 818 + e->counters = ((struct xt_counters) { 0, 0 }); 630 819 e->comefrom = 0; 631 820 632 821 (*i)++; ··· 656 845 static int 657 846 translate_table(const char *name, 658 847 unsigned int valid_hooks, 659 - struct ipt_table_info *newinfo, 848 + struct xt_table_info *newinfo, 660 849 void *entry0, 661 850 unsigned int size, 662 851 unsigned int number, ··· 733 922 return ret; 734 923 } 735 924 736 - static struct ipt_table_info * 737 - replace_table(struct ipt_table *table, 738 - unsigned int num_counters, 739 - struct ipt_table_info *newinfo, 740 - int *error) 741 - { 742 - struct ipt_table_info *oldinfo; 743 - 744 - #ifdef CONFIG_NETFILTER_DEBUG 745 - { 746 - int cpu; 747 - 748 - for_each_cpu(cpu) { 749 - struct ipt_entry *table_base = newinfo->entries[cpu]; 750 - if (table_base) 751 - table_base->comefrom = 0xdead57ac; 752 - } 753 - } 754 - #endif 755 - 756 - /* Do the substitution. */ 757 - write_lock_bh(&table->lock); 758 - /* Check inside lock: is the old number correct? */ 759 - if (num_counters != table->private->number) { 760 - duprintf("num_counters != table->private->number (%u/%u)\n", 761 - num_counters, table->private->number); 762 - write_unlock_bh(&table->lock); 763 - *error = -EAGAIN; 764 - return NULL; 765 - } 766 - oldinfo = table->private; 767 - table->private = newinfo; 768 - newinfo->initial_entries = oldinfo->initial_entries; 769 - write_unlock_bh(&table->lock); 770 - 771 - return oldinfo; 772 - } 773 - 774 925 /* Gets counters. */ 775 926 static inline int 776 927 add_entry_to_counter(const struct ipt_entry *e, 777 - struct ipt_counters total[], 928 + struct xt_counters total[], 778 929 unsigned int *i) 779 930 { 780 931 ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); ··· 757 984 } 758 985 759 986 static void 760 - get_counters(const struct ipt_table_info *t, 761 - struct ipt_counters counters[]) 987 + get_counters(const struct xt_table_info *t, 988 + struct xt_counters counters[]) 762 989 { 763 990 unsigned int cpu; 764 991 unsigned int i; ··· 797 1024 { 798 1025 unsigned int off, num, countersize; 799 1026 struct ipt_entry *e; 800 - struct ipt_counters *counters; 1027 + struct xt_counters *counters; 1028 + struct xt_table_info *private = table->private; 801 1029 int ret = 0; 802 1030 void *loc_cpu_entry; 803 1031 804 1032 /* We need atomic snapshot of counters: rest doesn't change 805 1033 (other than comefrom, which userspace doesn't care 806 1034 about). */ 807 - countersize = sizeof(struct ipt_counters) * table->private->number; 1035 + countersize = sizeof(struct xt_counters) * private->number; 808 1036 counters = vmalloc_node(countersize, numa_node_id()); 809 1037 810 1038 if (counters == NULL) ··· 813 1039 814 1040 /* First, sum counters... */ 815 1041 write_lock_bh(&table->lock); 816 - get_counters(table->private, counters); 1042 + get_counters(private, counters); 817 1043 write_unlock_bh(&table->lock); 818 1044 819 1045 /* choose the copy that is on our node/cpu, ... 820 1046 * This choice is lazy (because current thread is 821 1047 * allowed to migrate to another cpu) 822 1048 */ 823 - loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; 1049 + loc_cpu_entry = private->entries[raw_smp_processor_id()]; 824 1050 /* ... then copy entire thing ... */ 825 1051 if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { 826 1052 ret = -EFAULT; ··· 882 1108 int ret; 883 1109 struct ipt_table *t; 884 1110 885 - t = find_table_lock(entries->name); 1111 + t = xt_find_table_lock(AF_INET, entries->name); 886 1112 if (t && !IS_ERR(t)) { 1113 + struct xt_table_info *private = t->private; 887 1114 duprintf("t->private->number = %u\n", 888 - t->private->number); 889 - if (entries->size == t->private->size) 890 - ret = copy_entries_to_user(t->private->size, 1115 + private->number); 1116 + if (entries->size == private->size) 1117 + ret = copy_entries_to_user(private->size, 891 1118 t, uptr->entrytable); 892 1119 else { 893 1120 duprintf("get_entries: I've got %u not %u!\n", 894 - t->private->size, 1121 + private->size, 895 1122 entries->size); 896 1123 ret = -EINVAL; 897 1124 } 898 1125 module_put(t->me); 899 - up(&ipt_mutex); 1126 + xt_table_unlock(t); 900 1127 } else 901 1128 ret = t ? PTR_ERR(t) : -ENOENT; 902 1129 903 1130 return ret; 904 - } 905 - 906 - static void free_table_info(struct ipt_table_info *info) 907 - { 908 - int cpu; 909 - for_each_cpu(cpu) { 910 - if (info->size <= PAGE_SIZE) 911 - kfree(info->entries[cpu]); 912 - else 913 - vfree(info->entries[cpu]); 914 - } 915 - kfree(info); 916 - } 917 - 918 - static struct ipt_table_info *alloc_table_info(unsigned int size) 919 - { 920 - struct ipt_table_info *newinfo; 921 - int cpu; 922 - 923 - newinfo = kzalloc(sizeof(struct ipt_table_info), GFP_KERNEL); 924 - if (!newinfo) 925 - return NULL; 926 - 927 - newinfo->size = size; 928 - 929 - for_each_cpu(cpu) { 930 - if (size <= PAGE_SIZE) 931 - newinfo->entries[cpu] = kmalloc_node(size, 932 - GFP_KERNEL, 933 - cpu_to_node(cpu)); 934 - else 935 - newinfo->entries[cpu] = vmalloc_node(size, cpu_to_node(cpu)); 936 - if (newinfo->entries[cpu] == 0) { 937 - free_table_info(newinfo); 938 - return NULL; 939 - } 940 - } 941 - 942 - return newinfo; 943 1131 } 944 1132 945 1133 static int ··· 910 1174 int ret; 911 1175 struct ipt_replace tmp; 912 1176 struct ipt_table *t; 913 - struct ipt_table_info *newinfo, *oldinfo; 914 - struct ipt_counters *counters; 1177 + struct xt_table_info *newinfo, *oldinfo; 1178 + struct xt_counters *counters; 915 1179 void *loc_cpu_entry, *loc_cpu_old_entry; 916 1180 917 1181 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) ··· 921 1185 if (len != sizeof(tmp) + tmp.size) 922 1186 return -ENOPROTOOPT; 923 1187 924 - /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */ 925 - if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages) 926 - return -ENOMEM; 927 - 928 - newinfo = alloc_table_info(tmp.size); 1188 + newinfo = xt_alloc_table_info(tmp.size); 929 1189 if (!newinfo) 930 1190 return -ENOMEM; 931 1191 ··· 933 1201 goto free_newinfo; 934 1202 } 935 1203 936 - counters = vmalloc(tmp.num_counters * sizeof(struct ipt_counters)); 1204 + counters = vmalloc(tmp.num_counters * sizeof(struct xt_counters)); 937 1205 if (!counters) { 938 1206 ret = -ENOMEM; 939 1207 goto free_newinfo; ··· 947 1215 948 1216 duprintf("ip_tables: Translated table\n"); 949 1217 950 - t = try_then_request_module(find_table_lock(tmp.name), 1218 + t = try_then_request_module(xt_find_table_lock(AF_INET, tmp.name), 951 1219 "iptable_%s", tmp.name); 952 1220 if (!t || IS_ERR(t)) { 953 1221 ret = t ? PTR_ERR(t) : -ENOENT; ··· 962 1230 goto put_module; 963 1231 } 964 1232 965 - oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret); 1233 + oldinfo = xt_replace_table(t, tmp.num_counters, newinfo, &ret); 966 1234 if (!oldinfo) 967 1235 goto put_module; 968 1236 ··· 981 1249 /* Decrease module usage counts and free resource */ 982 1250 loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; 983 1251 IPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); 984 - free_table_info(oldinfo); 1252 + xt_free_table_info(oldinfo); 985 1253 if (copy_to_user(tmp.counters, counters, 986 - sizeof(struct ipt_counters) * tmp.num_counters) != 0) 1254 + sizeof(struct xt_counters) * tmp.num_counters) != 0) 987 1255 ret = -EFAULT; 988 1256 vfree(counters); 989 - up(&ipt_mutex); 1257 + xt_table_unlock(t); 990 1258 return ret; 991 1259 992 1260 put_module: 993 1261 module_put(t->me); 994 - up(&ipt_mutex); 1262 + xt_table_unlock(t); 995 1263 free_newinfo_counters_untrans: 996 1264 IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL); 997 1265 free_newinfo_counters: 998 1266 vfree(counters); 999 1267 free_newinfo: 1000 - free_table_info(newinfo); 1268 + xt_free_table_info(newinfo); 1001 1269 return ret; 1002 1270 } 1003 1271 ··· 1005 1273 * and everything is OK. */ 1006 1274 static inline int 1007 1275 add_counter_to_entry(struct ipt_entry *e, 1008 - const struct ipt_counters addme[], 1276 + const struct xt_counters addme[], 1009 1277 unsigned int *i) 1010 1278 { 1011 1279 #if 0 ··· 1027 1295 do_add_counters(void __user *user, unsigned int len) 1028 1296 { 1029 1297 unsigned int i; 1030 - struct ipt_counters_info tmp, *paddc; 1298 + struct xt_counters_info tmp, *paddc; 1031 1299 struct ipt_table *t; 1300 + struct xt_table_info *private; 1032 1301 int ret = 0; 1033 1302 void *loc_cpu_entry; 1034 1303 1035 1304 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 1036 1305 return -EFAULT; 1037 1306 1038 - if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct ipt_counters)) 1307 + if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct xt_counters)) 1039 1308 return -EINVAL; 1040 1309 1041 1310 paddc = vmalloc_node(len, numa_node_id()); ··· 1048 1315 goto free; 1049 1316 } 1050 1317 1051 - t = find_table_lock(tmp.name); 1318 + t = xt_find_table_lock(AF_INET, tmp.name); 1052 1319 if (!t || IS_ERR(t)) { 1053 1320 ret = t ? PTR_ERR(t) : -ENOENT; 1054 1321 goto free; 1055 1322 } 1056 1323 1057 1324 write_lock_bh(&t->lock); 1058 - if (t->private->number != paddc->num_counters) { 1325 + private = t->private; 1326 + if (private->number != paddc->num_counters) { 1059 1327 ret = -EINVAL; 1060 1328 goto unlock_up_free; 1061 1329 } 1062 1330 1063 1331 i = 0; 1064 1332 /* Choose the copy that is on our node */ 1065 - loc_cpu_entry = t->private->entries[raw_smp_processor_id()]; 1333 + loc_cpu_entry = private->entries[raw_smp_processor_id()]; 1066 1334 IPT_ENTRY_ITERATE(loc_cpu_entry, 1067 - t->private->size, 1335 + private->size, 1068 1336 add_counter_to_entry, 1069 1337 paddc->counters, 1070 1338 &i); 1071 1339 unlock_up_free: 1072 1340 write_unlock_bh(&t->lock); 1073 - up(&ipt_mutex); 1341 + xt_table_unlock(t); 1074 1342 module_put(t->me); 1075 1343 free: 1076 1344 vfree(paddc); ··· 1130 1396 } 1131 1397 name[IPT_TABLE_MAXNAMELEN-1] = '\0'; 1132 1398 1133 - t = try_then_request_module(find_table_lock(name), 1399 + t = try_then_request_module(xt_find_table_lock(AF_INET, name), 1134 1400 "iptable_%s", name); 1135 1401 if (t && !IS_ERR(t)) { 1136 1402 struct ipt_getinfo info; 1403 + struct xt_table_info *private = t->private; 1137 1404 1138 1405 info.valid_hooks = t->valid_hooks; 1139 - memcpy(info.hook_entry, t->private->hook_entry, 1406 + memcpy(info.hook_entry, private->hook_entry, 1140 1407 sizeof(info.hook_entry)); 1141 - memcpy(info.underflow, t->private->underflow, 1408 + memcpy(info.underflow, private->underflow, 1142 1409 sizeof(info.underflow)); 1143 - info.num_entries = t->private->number; 1144 - info.size = t->private->size; 1410 + info.num_entries = private->number; 1411 + info.size = private->size; 1145 1412 memcpy(info.name, name, sizeof(info.name)); 1146 1413 1147 1414 if (copy_to_user(user, &info, *len) != 0) 1148 1415 ret = -EFAULT; 1149 1416 else 1150 1417 ret = 0; 1151 - up(&ipt_mutex); 1418 + xt_table_unlock(t); 1152 1419 module_put(t->me); 1153 1420 } else 1154 1421 ret = t ? PTR_ERR(t) : -ENOENT; ··· 1176 1441 case IPT_SO_GET_REVISION_MATCH: 1177 1442 case IPT_SO_GET_REVISION_TARGET: { 1178 1443 struct ipt_get_revision rev; 1179 - int (*revfn)(const char *, u8, int *); 1444 + int target; 1180 1445 1181 1446 if (*len != sizeof(rev)) { 1182 1447 ret = -EINVAL; ··· 1188 1453 } 1189 1454 1190 1455 if (cmd == IPT_SO_GET_REVISION_TARGET) 1191 - revfn = target_revfn; 1456 + target = 1; 1192 1457 else 1193 - revfn = match_revfn; 1458 + target = 0; 1194 1459 1195 - try_then_request_module(find_revision(rev.name, rev.revision, 1196 - revfn, &ret), 1460 + try_then_request_module(xt_find_revision(AF_INET, rev.name, 1461 + rev.revision, 1462 + target, &ret), 1197 1463 "ipt_%s", rev.name); 1198 1464 break; 1199 1465 } ··· 1207 1471 return ret; 1208 1472 } 1209 1473 1210 - /* Registration hooks for targets. */ 1211 - int 1212 - ipt_register_target(struct ipt_target *target) 1474 + int ipt_register_table(struct xt_table *table, const struct ipt_replace *repl) 1213 1475 { 1214 1476 int ret; 1215 - 1216 - ret = down_interruptible(&ipt_mutex); 1217 - if (ret != 0) 1218 - return ret; 1219 - list_add(&target->list, &ipt_target); 1220 - up(&ipt_mutex); 1221 - return ret; 1222 - } 1223 - 1224 - void 1225 - ipt_unregister_target(struct ipt_target *target) 1226 - { 1227 - down(&ipt_mutex); 1228 - LIST_DELETE(&ipt_target, target); 1229 - up(&ipt_mutex); 1230 - } 1231 - 1232 - int 1233 - ipt_register_match(struct ipt_match *match) 1234 - { 1235 - int ret; 1236 - 1237 - ret = down_interruptible(&ipt_mutex); 1238 - if (ret != 0) 1239 - return ret; 1240 - 1241 - list_add(&match->list, &ipt_match); 1242 - up(&ipt_mutex); 1243 - 1244 - return ret; 1245 - } 1246 - 1247 - void 1248 - ipt_unregister_match(struct ipt_match *match) 1249 - { 1250 - down(&ipt_mutex); 1251 - LIST_DELETE(&ipt_match, match); 1252 - up(&ipt_mutex); 1253 - } 1254 - 1255 - int ipt_register_table(struct ipt_table *table, const struct ipt_replace *repl) 1256 - { 1257 - int ret; 1258 - struct ipt_table_info *newinfo; 1259 - static struct ipt_table_info bootstrap 1477 + struct xt_table_info *newinfo; 1478 + static struct xt_table_info bootstrap 1260 1479 = { 0, 0, 0, { 0 }, { 0 }, { } }; 1261 1480 void *loc_cpu_entry; 1262 1481 1263 - newinfo = alloc_table_info(repl->size); 1482 + newinfo = xt_alloc_table_info(repl->size); 1264 1483 if (!newinfo) 1265 1484 return -ENOMEM; 1266 1485 ··· 1231 1540 repl->hook_entry, 1232 1541 repl->underflow); 1233 1542 if (ret != 0) { 1234 - free_table_info(newinfo); 1543 + xt_free_table_info(newinfo); 1235 1544 return ret; 1236 1545 } 1237 1546 1238 - ret = down_interruptible(&ipt_mutex); 1239 - if (ret != 0) { 1240 - free_table_info(newinfo); 1547 + if (xt_register_table(table, &bootstrap, newinfo) != 0) { 1548 + xt_free_table_info(newinfo); 1241 1549 return ret; 1242 1550 } 1243 1551 1244 - /* Don't autoload: we'd eat our tail... */ 1245 - if (list_named_find(&ipt_tables, table->name)) { 1246 - ret = -EEXIST; 1247 - goto free_unlock; 1248 - } 1249 - 1250 - /* Simplifies replace_table code. */ 1251 - table->private = &bootstrap; 1252 - if (!replace_table(table, 0, newinfo, &ret)) 1253 - goto free_unlock; 1254 - 1255 - duprintf("table->private->number = %u\n", 1256 - table->private->number); 1257 - 1258 - /* save number of initial entries */ 1259 - table->private->initial_entries = table->private->number; 1260 - 1261 - rwlock_init(&table->lock); 1262 - list_prepend(&ipt_tables, table); 1263 - 1264 - unlock: 1265 - up(&ipt_mutex); 1266 - return ret; 1267 - 1268 - free_unlock: 1269 - free_table_info(newinfo); 1270 - goto unlock; 1552 + return 0; 1271 1553 } 1272 1554 1273 1555 void ipt_unregister_table(struct ipt_table *table) 1274 1556 { 1557 + struct xt_table_info *private; 1275 1558 void *loc_cpu_entry; 1276 1559 1277 - down(&ipt_mutex); 1278 - LIST_DELETE(&ipt_tables, table); 1279 - up(&ipt_mutex); 1560 + private = xt_unregister_table(table); 1280 1561 1281 1562 /* Decrease module usage counts and free resources */ 1282 - loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; 1283 - IPT_ENTRY_ITERATE(loc_cpu_entry, table->private->size, 1284 - cleanup_entry, NULL); 1285 - free_table_info(table->private); 1286 - } 1287 - 1288 - /* Returns 1 if the port is matched by the range, 0 otherwise */ 1289 - static inline int 1290 - port_match(u_int16_t min, u_int16_t max, u_int16_t port, int invert) 1291 - { 1292 - int ret; 1293 - 1294 - ret = (port >= min && port <= max) ^ invert; 1295 - return ret; 1296 - } 1297 - 1298 - static int 1299 - tcp_find_option(u_int8_t option, 1300 - const struct sk_buff *skb, 1301 - unsigned int optlen, 1302 - int invert, 1303 - int *hotdrop) 1304 - { 1305 - /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ 1306 - u_int8_t _opt[60 - sizeof(struct tcphdr)], *op; 1307 - unsigned int i; 1308 - 1309 - duprintf("tcp_match: finding option\n"); 1310 - 1311 - if (!optlen) 1312 - return invert; 1313 - 1314 - /* If we don't have the whole header, drop packet. */ 1315 - op = skb_header_pointer(skb, 1316 - skb->nh.iph->ihl*4 + sizeof(struct tcphdr), 1317 - optlen, _opt); 1318 - if (op == NULL) { 1319 - *hotdrop = 1; 1320 - return 0; 1321 - } 1322 - 1323 - for (i = 0; i < optlen; ) { 1324 - if (op[i] == option) return !invert; 1325 - if (op[i] < 2) i++; 1326 - else i += op[i+1]?:1; 1327 - } 1328 - 1329 - return invert; 1330 - } 1331 - 1332 - static int 1333 - tcp_match(const struct sk_buff *skb, 1334 - const struct net_device *in, 1335 - const struct net_device *out, 1336 - const void *matchinfo, 1337 - int offset, 1338 - int *hotdrop) 1339 - { 1340 - struct tcphdr _tcph, *th; 1341 - const struct ipt_tcp *tcpinfo = matchinfo; 1342 - 1343 - if (offset) { 1344 - /* To quote Alan: 1345 - 1346 - Don't allow a fragment of TCP 8 bytes in. Nobody normal 1347 - causes this. Its a cracker trying to break in by doing a 1348 - flag overwrite to pass the direction checks. 1349 - */ 1350 - if (offset == 1) { 1351 - duprintf("Dropping evil TCP offset=1 frag.\n"); 1352 - *hotdrop = 1; 1353 - } 1354 - /* Must not be a fragment. */ 1355 - return 0; 1356 - } 1357 - 1358 - #define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg)) 1359 - 1360 - th = skb_header_pointer(skb, skb->nh.iph->ihl*4, 1361 - sizeof(_tcph), &_tcph); 1362 - if (th == NULL) { 1363 - /* We've been asked to examine this packet, and we 1364 - can't. Hence, no choice but to drop. */ 1365 - duprintf("Dropping evil TCP offset=0 tinygram.\n"); 1366 - *hotdrop = 1; 1367 - return 0; 1368 - } 1369 - 1370 - if (!port_match(tcpinfo->spts[0], tcpinfo->spts[1], 1371 - ntohs(th->source), 1372 - !!(tcpinfo->invflags & IPT_TCP_INV_SRCPT))) 1373 - return 0; 1374 - if (!port_match(tcpinfo->dpts[0], tcpinfo->dpts[1], 1375 - ntohs(th->dest), 1376 - !!(tcpinfo->invflags & IPT_TCP_INV_DSTPT))) 1377 - return 0; 1378 - if (!FWINVTCP((((unsigned char *)th)[13] & tcpinfo->flg_mask) 1379 - == tcpinfo->flg_cmp, 1380 - IPT_TCP_INV_FLAGS)) 1381 - return 0; 1382 - if (tcpinfo->option) { 1383 - if (th->doff * 4 < sizeof(_tcph)) { 1384 - *hotdrop = 1; 1385 - return 0; 1386 - } 1387 - if (!tcp_find_option(tcpinfo->option, skb, 1388 - th->doff*4 - sizeof(_tcph), 1389 - tcpinfo->invflags & IPT_TCP_INV_OPTION, 1390 - hotdrop)) 1391 - return 0; 1392 - } 1393 - return 1; 1394 - } 1395 - 1396 - /* Called when user tries to insert an entry of this type. */ 1397 - static int 1398 - tcp_checkentry(const char *tablename, 1399 - const struct ipt_ip *ip, 1400 - void *matchinfo, 1401 - unsigned int matchsize, 1402 - unsigned int hook_mask) 1403 - { 1404 - const struct ipt_tcp *tcpinfo = matchinfo; 1405 - 1406 - /* Must specify proto == TCP, and no unknown invflags */ 1407 - return ip->proto == IPPROTO_TCP 1408 - && !(ip->invflags & IPT_INV_PROTO) 1409 - && matchsize == IPT_ALIGN(sizeof(struct ipt_tcp)) 1410 - && !(tcpinfo->invflags & ~IPT_TCP_INV_MASK); 1411 - } 1412 - 1413 - static int 1414 - udp_match(const struct sk_buff *skb, 1415 - const struct net_device *in, 1416 - const struct net_device *out, 1417 - const void *matchinfo, 1418 - int offset, 1419 - int *hotdrop) 1420 - { 1421 - struct udphdr _udph, *uh; 1422 - const struct ipt_udp *udpinfo = matchinfo; 1423 - 1424 - /* Must not be a fragment. */ 1425 - if (offset) 1426 - return 0; 1427 - 1428 - uh = skb_header_pointer(skb, skb->nh.iph->ihl*4, 1429 - sizeof(_udph), &_udph); 1430 - if (uh == NULL) { 1431 - /* We've been asked to examine this packet, and we 1432 - can't. Hence, no choice but to drop. */ 1433 - duprintf("Dropping evil UDP tinygram.\n"); 1434 - *hotdrop = 1; 1435 - return 0; 1436 - } 1437 - 1438 - return port_match(udpinfo->spts[0], udpinfo->spts[1], 1439 - ntohs(uh->source), 1440 - !!(udpinfo->invflags & IPT_UDP_INV_SRCPT)) 1441 - && port_match(udpinfo->dpts[0], udpinfo->dpts[1], 1442 - ntohs(uh->dest), 1443 - !!(udpinfo->invflags & IPT_UDP_INV_DSTPT)); 1444 - } 1445 - 1446 - /* Called when user tries to insert an entry of this type. */ 1447 - static int 1448 - udp_checkentry(const char *tablename, 1449 - const struct ipt_ip *ip, 1450 - void *matchinfo, 1451 - unsigned int matchinfosize, 1452 - unsigned int hook_mask) 1453 - { 1454 - const struct ipt_udp *udpinfo = matchinfo; 1455 - 1456 - /* Must specify proto == UDP, and no unknown invflags */ 1457 - if (ip->proto != IPPROTO_UDP || (ip->invflags & IPT_INV_PROTO)) { 1458 - duprintf("ipt_udp: Protocol %u != %u\n", ip->proto, 1459 - IPPROTO_UDP); 1460 - return 0; 1461 - } 1462 - if (matchinfosize != IPT_ALIGN(sizeof(struct ipt_udp))) { 1463 - duprintf("ipt_udp: matchsize %u != %u\n", 1464 - matchinfosize, IPT_ALIGN(sizeof(struct ipt_udp))); 1465 - return 0; 1466 - } 1467 - if (udpinfo->invflags & ~IPT_UDP_INV_MASK) { 1468 - duprintf("ipt_udp: unknown flags %X\n", 1469 - udpinfo->invflags); 1470 - return 0; 1471 - } 1472 - 1473 - return 1; 1563 + loc_cpu_entry = private->entries[raw_smp_processor_id()]; 1564 + IPT_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, NULL); 1565 + xt_free_table_info(private); 1474 1566 } 1475 1567 1476 1568 /* Returns 1 if the type and code is matched by the range, 0 otherwise */ ··· 1272 1798 const struct net_device *out, 1273 1799 const void *matchinfo, 1274 1800 int offset, 1801 + unsigned int protoff, 1275 1802 int *hotdrop) 1276 1803 { 1277 1804 struct icmphdr _icmph, *ic; ··· 1282 1807 if (offset) 1283 1808 return 0; 1284 1809 1285 - ic = skb_header_pointer(skb, skb->nh.iph->ihl*4, 1286 - sizeof(_icmph), &_icmph); 1810 + ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph); 1287 1811 if (ic == NULL) { 1288 1812 /* We've been asked to examine this packet, and we 1289 1813 * can't. Hence, no choice but to drop. ··· 1302 1828 /* Called when user tries to insert an entry of this type. */ 1303 1829 static int 1304 1830 icmp_checkentry(const char *tablename, 1305 - const struct ipt_ip *ip, 1831 + const void *info, 1306 1832 void *matchinfo, 1307 1833 unsigned int matchsize, 1308 1834 unsigned int hook_mask) 1309 1835 { 1836 + const struct ipt_ip *ip = info; 1310 1837 const struct ipt_icmp *icmpinfo = matchinfo; 1311 1838 1312 1839 /* Must specify proto == ICMP, and no unknown invflags */ ··· 1337 1862 .get = do_ipt_get_ctl, 1338 1863 }; 1339 1864 1340 - static struct ipt_match tcp_matchstruct = { 1341 - .name = "tcp", 1342 - .match = &tcp_match, 1343 - .checkentry = &tcp_checkentry, 1344 - }; 1345 - 1346 - static struct ipt_match udp_matchstruct = { 1347 - .name = "udp", 1348 - .match = &udp_match, 1349 - .checkentry = &udp_checkentry, 1350 - }; 1351 - 1352 1865 static struct ipt_match icmp_matchstruct = { 1353 1866 .name = "icmp", 1354 1867 .match = &icmp_match, 1355 1868 .checkentry = &icmp_checkentry, 1356 1869 }; 1357 1870 1358 - #ifdef CONFIG_PROC_FS 1359 - static inline int print_name(const char *i, 1360 - off_t start_offset, char *buffer, int length, 1361 - off_t *pos, unsigned int *count) 1362 - { 1363 - if ((*count)++ >= start_offset) { 1364 - unsigned int namelen; 1365 - 1366 - namelen = sprintf(buffer + *pos, "%s\n", 1367 - i + sizeof(struct list_head)); 1368 - if (*pos + namelen > length) { 1369 - /* Stop iterating */ 1370 - return 1; 1371 - } 1372 - *pos += namelen; 1373 - } 1374 - return 0; 1375 - } 1376 - 1377 - static inline int print_target(const struct ipt_target *t, 1378 - off_t start_offset, char *buffer, int length, 1379 - off_t *pos, unsigned int *count) 1380 - { 1381 - if (t == &ipt_standard_target || t == &ipt_error_target) 1382 - return 0; 1383 - return print_name((char *)t, start_offset, buffer, length, pos, count); 1384 - } 1385 - 1386 - static int ipt_get_tables(char *buffer, char **start, off_t offset, int length) 1387 - { 1388 - off_t pos = 0; 1389 - unsigned int count = 0; 1390 - 1391 - if (down_interruptible(&ipt_mutex) != 0) 1392 - return 0; 1393 - 1394 - LIST_FIND(&ipt_tables, print_name, void *, 1395 - offset, buffer, length, &pos, &count); 1396 - 1397 - up(&ipt_mutex); 1398 - 1399 - /* `start' hack - see fs/proc/generic.c line ~105 */ 1400 - *start=(char *)((unsigned long)count-offset); 1401 - return pos; 1402 - } 1403 - 1404 - static int ipt_get_targets(char *buffer, char **start, off_t offset, int length) 1405 - { 1406 - off_t pos = 0; 1407 - unsigned int count = 0; 1408 - 1409 - if (down_interruptible(&ipt_mutex) != 0) 1410 - return 0; 1411 - 1412 - LIST_FIND(&ipt_target, print_target, struct ipt_target *, 1413 - offset, buffer, length, &pos, &count); 1414 - 1415 - up(&ipt_mutex); 1416 - 1417 - *start = (char *)((unsigned long)count - offset); 1418 - return pos; 1419 - } 1420 - 1421 - static int ipt_get_matches(char *buffer, char **start, off_t offset, int length) 1422 - { 1423 - off_t pos = 0; 1424 - unsigned int count = 0; 1425 - 1426 - if (down_interruptible(&ipt_mutex) != 0) 1427 - return 0; 1428 - 1429 - LIST_FIND(&ipt_match, print_name, void *, 1430 - offset, buffer, length, &pos, &count); 1431 - 1432 - up(&ipt_mutex); 1433 - 1434 - *start = (char *)((unsigned long)count - offset); 1435 - return pos; 1436 - } 1437 - 1438 - static const struct { char *name; get_info_t *get_info; } ipt_proc_entry[] = 1439 - { { "ip_tables_names", ipt_get_tables }, 1440 - { "ip_tables_targets", ipt_get_targets }, 1441 - { "ip_tables_matches", ipt_get_matches }, 1442 - { NULL, NULL} }; 1443 - #endif /*CONFIG_PROC_FS*/ 1444 - 1445 1871 static int __init init(void) 1446 1872 { 1447 1873 int ret; 1448 1874 1875 + xt_proto_init(AF_INET); 1876 + 1449 1877 /* Noone else will be downing sem now, so we won't sleep */ 1450 - down(&ipt_mutex); 1451 - list_append(&ipt_target, &ipt_standard_target); 1452 - list_append(&ipt_target, &ipt_error_target); 1453 - list_append(&ipt_match, &tcp_matchstruct); 1454 - list_append(&ipt_match, &udp_matchstruct); 1455 - list_append(&ipt_match, &icmp_matchstruct); 1456 - up(&ipt_mutex); 1878 + xt_register_target(AF_INET, &ipt_standard_target); 1879 + xt_register_target(AF_INET, &ipt_error_target); 1880 + xt_register_match(AF_INET, &icmp_matchstruct); 1457 1881 1458 1882 /* Register setsockopt */ 1459 1883 ret = nf_register_sockopt(&ipt_sockopts); ··· 1361 1987 return ret; 1362 1988 } 1363 1989 1364 - #ifdef CONFIG_PROC_FS 1365 - { 1366 - struct proc_dir_entry *proc; 1367 - int i; 1368 - 1369 - for (i = 0; ipt_proc_entry[i].name; i++) { 1370 - proc = proc_net_create(ipt_proc_entry[i].name, 0, 1371 - ipt_proc_entry[i].get_info); 1372 - if (!proc) { 1373 - while (--i >= 0) 1374 - proc_net_remove(ipt_proc_entry[i].name); 1375 - nf_unregister_sockopt(&ipt_sockopts); 1376 - return -ENOMEM; 1377 - } 1378 - proc->owner = THIS_MODULE; 1379 - } 1380 - } 1381 - #endif 1382 - 1383 - printk("ip_tables: (C) 2000-2002 Netfilter core team\n"); 1990 + printk("ip_tables: (C) 2000-2006 Netfilter Core Team\n"); 1384 1991 return 0; 1385 1992 } 1386 1993 1387 1994 static void __exit fini(void) 1388 1995 { 1389 1996 nf_unregister_sockopt(&ipt_sockopts); 1390 - #ifdef CONFIG_PROC_FS 1391 - { 1392 - int i; 1393 - for (i = 0; ipt_proc_entry[i].name; i++) 1394 - proc_net_remove(ipt_proc_entry[i].name); 1395 - } 1396 - #endif 1997 + 1998 + xt_unregister_match(AF_INET, &icmp_matchstruct); 1999 + xt_unregister_target(AF_INET, &ipt_error_target); 2000 + xt_unregister_target(AF_INET, &ipt_standard_target); 2001 + 2002 + xt_proto_fini(AF_INET); 1397 2003 } 1398 2004 1399 2005 EXPORT_SYMBOL(ipt_register_table); 1400 2006 EXPORT_SYMBOL(ipt_unregister_table); 1401 - EXPORT_SYMBOL(ipt_register_match); 1402 - EXPORT_SYMBOL(ipt_unregister_match); 1403 2007 EXPORT_SYMBOL(ipt_do_table); 1404 - EXPORT_SYMBOL(ipt_register_target); 1405 - EXPORT_SYMBOL(ipt_unregister_target); 1406 - EXPORT_SYMBOL(ipt_find_target); 1407 - 1408 2008 module_init(init); 1409 2009 module_exit(fini);
-90
net/ipv4/netfilter/ipt_CLASSIFY.c
··· 1 - /* 2 - * This is a module which is used for setting the skb->priority field 3 - * of an skb for qdisc classification. 4 - */ 5 - 6 - /* (C) 2001-2002 Patrick McHardy <kaber@trash.net> 7 - * 8 - * This program is free software; you can redistribute it and/or modify 9 - * it under the terms of the GNU General Public License version 2 as 10 - * published by the Free Software Foundation. 11 - */ 12 - 13 - #include <linux/module.h> 14 - #include <linux/skbuff.h> 15 - #include <linux/ip.h> 16 - #include <net/checksum.h> 17 - 18 - #include <linux/netfilter_ipv4/ip_tables.h> 19 - #include <linux/netfilter_ipv4/ipt_CLASSIFY.h> 20 - 21 - MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 22 - MODULE_LICENSE("GPL"); 23 - MODULE_DESCRIPTION("iptables qdisc classification target module"); 24 - 25 - static unsigned int 26 - target(struct sk_buff **pskb, 27 - const struct net_device *in, 28 - const struct net_device *out, 29 - unsigned int hooknum, 30 - const void *targinfo, 31 - void *userinfo) 32 - { 33 - const struct ipt_classify_target_info *clinfo = targinfo; 34 - 35 - if((*pskb)->priority != clinfo->priority) 36 - (*pskb)->priority = clinfo->priority; 37 - 38 - return IPT_CONTINUE; 39 - } 40 - 41 - static int 42 - checkentry(const char *tablename, 43 - const struct ipt_entry *e, 44 - void *targinfo, 45 - unsigned int targinfosize, 46 - unsigned int hook_mask) 47 - { 48 - if (targinfosize != IPT_ALIGN(sizeof(struct ipt_classify_target_info))){ 49 - printk(KERN_ERR "CLASSIFY: invalid size (%u != %Zu).\n", 50 - targinfosize, 51 - IPT_ALIGN(sizeof(struct ipt_classify_target_info))); 52 - return 0; 53 - } 54 - 55 - if (hook_mask & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) | 56 - (1 << NF_IP_POST_ROUTING))) { 57 - printk(KERN_ERR "CLASSIFY: only valid in LOCAL_OUT, FORWARD " 58 - "and POST_ROUTING.\n"); 59 - return 0; 60 - } 61 - 62 - if (strcmp(tablename, "mangle") != 0) { 63 - printk(KERN_ERR "CLASSIFY: can only be called from " 64 - "\"mangle\" table, not \"%s\".\n", 65 - tablename); 66 - return 0; 67 - } 68 - 69 - return 1; 70 - } 71 - 72 - static struct ipt_target ipt_classify_reg = { 73 - .name = "CLASSIFY", 74 - .target = target, 75 - .checkentry = checkentry, 76 - .me = THIS_MODULE, 77 - }; 78 - 79 - static int __init init(void) 80 - { 81 - return ipt_register_target(&ipt_classify_reg); 82 - } 83 - 84 - static void __exit fini(void) 85 - { 86 - ipt_unregister_target(&ipt_classify_reg); 87 - } 88 - 89 - module_init(init); 90 - module_exit(fini);
+2 -1
net/ipv4/netfilter/ipt_CLUSTERIP.c
··· 379 379 380 380 static int 381 381 checkentry(const char *tablename, 382 - const struct ipt_entry *e, 382 + const void *e_void, 383 383 void *targinfo, 384 384 unsigned int targinfosize, 385 385 unsigned int hook_mask) 386 386 { 387 387 struct ipt_clusterip_tgt_info *cipinfo = targinfo; 388 + const struct ipt_entry *e = e_void; 388 389 389 390 struct clusterip_config *config; 390 391
-122
net/ipv4/netfilter/ipt_CONNMARK.c
··· 1 - /* This kernel module is used to modify the connection mark values, or 2 - * to optionally restore the skb nfmark from the connection mark 3 - * 4 - * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> 5 - * by Henrik Nordstrom <hno@marasystems.com> 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 as published by 9 - * the Free Software Foundation; either version 2 of the License, or 10 - * (at your option) any later version. 11 - * 12 - * This program is distributed in the hope that it will be useful, 13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 - * GNU General Public License for more details. 16 - * 17 - * You should have received a copy of the GNU General Public License 18 - * along with this program; if not, write to the Free Software 19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 - */ 21 - #include <linux/module.h> 22 - #include <linux/skbuff.h> 23 - #include <linux/ip.h> 24 - #include <net/checksum.h> 25 - 26 - MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>"); 27 - MODULE_DESCRIPTION("IP tables CONNMARK matching module"); 28 - MODULE_LICENSE("GPL"); 29 - 30 - #include <linux/netfilter_ipv4/ip_tables.h> 31 - #include <linux/netfilter_ipv4/ipt_CONNMARK.h> 32 - #include <net/netfilter/nf_conntrack_compat.h> 33 - 34 - static unsigned int 35 - target(struct sk_buff **pskb, 36 - const struct net_device *in, 37 - const struct net_device *out, 38 - unsigned int hooknum, 39 - const void *targinfo, 40 - void *userinfo) 41 - { 42 - const struct ipt_connmark_target_info *markinfo = targinfo; 43 - u_int32_t diff; 44 - u_int32_t nfmark; 45 - u_int32_t newmark; 46 - u_int32_t ctinfo; 47 - u_int32_t *ctmark = nf_ct_get_mark(*pskb, &ctinfo); 48 - 49 - if (ctmark) { 50 - switch(markinfo->mode) { 51 - case IPT_CONNMARK_SET: 52 - newmark = (*ctmark & ~markinfo->mask) | markinfo->mark; 53 - if (newmark != *ctmark) 54 - *ctmark = newmark; 55 - break; 56 - case IPT_CONNMARK_SAVE: 57 - newmark = (*ctmark & ~markinfo->mask) | ((*pskb)->nfmark & markinfo->mask); 58 - if (*ctmark != newmark) 59 - *ctmark = newmark; 60 - break; 61 - case IPT_CONNMARK_RESTORE: 62 - nfmark = (*pskb)->nfmark; 63 - diff = (*ctmark ^ nfmark) & markinfo->mask; 64 - if (diff != 0) 65 - (*pskb)->nfmark = nfmark ^ diff; 66 - break; 67 - } 68 - } 69 - 70 - return IPT_CONTINUE; 71 - } 72 - 73 - static int 74 - checkentry(const char *tablename, 75 - const struct ipt_entry *e, 76 - void *targinfo, 77 - unsigned int targinfosize, 78 - unsigned int hook_mask) 79 - { 80 - struct ipt_connmark_target_info *matchinfo = targinfo; 81 - if (targinfosize != IPT_ALIGN(sizeof(struct ipt_connmark_target_info))) { 82 - printk(KERN_WARNING "CONNMARK: targinfosize %u != %Zu\n", 83 - targinfosize, 84 - IPT_ALIGN(sizeof(struct ipt_connmark_target_info))); 85 - return 0; 86 - } 87 - 88 - if (matchinfo->mode == IPT_CONNMARK_RESTORE) { 89 - if (strcmp(tablename, "mangle") != 0) { 90 - printk(KERN_WARNING "CONNMARK: restore can only be called from \"mangle\" table, not \"%s\"\n", tablename); 91 - return 0; 92 - } 93 - } 94 - 95 - if (matchinfo->mark > 0xffffffff || matchinfo->mask > 0xffffffff) { 96 - printk(KERN_WARNING "CONNMARK: Only supports 32bit mark\n"); 97 - return 0; 98 - } 99 - 100 - return 1; 101 - } 102 - 103 - static struct ipt_target ipt_connmark_reg = { 104 - .name = "CONNMARK", 105 - .target = &target, 106 - .checkentry = &checkentry, 107 - .me = THIS_MODULE 108 - }; 109 - 110 - static int __init init(void) 111 - { 112 - need_ip_conntrack(); 113 - return ipt_register_target(&ipt_connmark_reg); 114 - } 115 - 116 - static void __exit fini(void) 117 - { 118 - ipt_unregister_target(&ipt_connmark_reg); 119 - } 120 - 121 - module_init(init); 122 - module_exit(fini);
+1 -1
net/ipv4/netfilter/ipt_DSCP.c
··· 57 57 58 58 static int 59 59 checkentry(const char *tablename, 60 - const struct ipt_entry *e, 60 + const void *e_void, 61 61 void *targinfo, 62 62 unsigned int targinfosize, 63 63 unsigned int hook_mask)
+2 -1
net/ipv4/netfilter/ipt_ECN.c
··· 113 113 114 114 static int 115 115 checkentry(const char *tablename, 116 - const struct ipt_entry *e, 116 + const void *e_void, 117 117 void *targinfo, 118 118 unsigned int targinfosize, 119 119 unsigned int hook_mask) 120 120 { 121 121 const struct ipt_ECN_info *einfo = (struct ipt_ECN_info *)targinfo; 122 + const struct ipt_entry *e = e_void; 122 123 123 124 if (targinfosize != IPT_ALIGN(sizeof(struct ipt_ECN_info))) { 124 125 printk(KERN_WARNING "ECN: targinfosize %u != %Zu\n",
+1 -1
net/ipv4/netfilter/ipt_LOG.c
··· 431 431 } 432 432 433 433 static int ipt_log_checkentry(const char *tablename, 434 - const struct ipt_entry *e, 434 + const void *e, 435 435 void *targinfo, 436 436 unsigned int targinfosize, 437 437 unsigned int hook_mask)
-172
net/ipv4/netfilter/ipt_MARK.c
··· 1 - /* This is a module which is used for setting the NFMARK field of an skb. */ 2 - 3 - /* (C) 1999-2001 Marc Boucher <marc@mbsi.ca> 4 - * 5 - * This program is free software; you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License version 2 as 7 - * published by the Free Software Foundation. 8 - */ 9 - 10 - #include <linux/module.h> 11 - #include <linux/skbuff.h> 12 - #include <linux/ip.h> 13 - #include <net/checksum.h> 14 - 15 - #include <linux/netfilter_ipv4/ip_tables.h> 16 - #include <linux/netfilter_ipv4/ipt_MARK.h> 17 - 18 - MODULE_LICENSE("GPL"); 19 - MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 20 - MODULE_DESCRIPTION("iptables MARK modification module"); 21 - 22 - static unsigned int 23 - target_v0(struct sk_buff **pskb, 24 - const struct net_device *in, 25 - const struct net_device *out, 26 - unsigned int hooknum, 27 - const void *targinfo, 28 - void *userinfo) 29 - { 30 - const struct ipt_mark_target_info *markinfo = targinfo; 31 - 32 - if((*pskb)->nfmark != markinfo->mark) 33 - (*pskb)->nfmark = markinfo->mark; 34 - 35 - return IPT_CONTINUE; 36 - } 37 - 38 - static unsigned int 39 - target_v1(struct sk_buff **pskb, 40 - const struct net_device *in, 41 - const struct net_device *out, 42 - unsigned int hooknum, 43 - const void *targinfo, 44 - void *userinfo) 45 - { 46 - const struct ipt_mark_target_info_v1 *markinfo = targinfo; 47 - int mark = 0; 48 - 49 - switch (markinfo->mode) { 50 - case IPT_MARK_SET: 51 - mark = markinfo->mark; 52 - break; 53 - 54 - case IPT_MARK_AND: 55 - mark = (*pskb)->nfmark & markinfo->mark; 56 - break; 57 - 58 - case IPT_MARK_OR: 59 - mark = (*pskb)->nfmark | markinfo->mark; 60 - break; 61 - } 62 - 63 - if((*pskb)->nfmark != mark) 64 - (*pskb)->nfmark = mark; 65 - 66 - return IPT_CONTINUE; 67 - } 68 - 69 - 70 - static int 71 - checkentry_v0(const char *tablename, 72 - const struct ipt_entry *e, 73 - void *targinfo, 74 - unsigned int targinfosize, 75 - unsigned int hook_mask) 76 - { 77 - struct ipt_mark_target_info *markinfo = targinfo; 78 - 79 - if (targinfosize != IPT_ALIGN(sizeof(struct ipt_mark_target_info))) { 80 - printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n", 81 - targinfosize, 82 - IPT_ALIGN(sizeof(struct ipt_mark_target_info))); 83 - return 0; 84 - } 85 - 86 - if (strcmp(tablename, "mangle") != 0) { 87 - printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename); 88 - return 0; 89 - } 90 - 91 - if (markinfo->mark > 0xffffffff) { 92 - printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n"); 93 - return 0; 94 - } 95 - 96 - return 1; 97 - } 98 - 99 - static int 100 - checkentry_v1(const char *tablename, 101 - const struct ipt_entry *e, 102 - void *targinfo, 103 - unsigned int targinfosize, 104 - unsigned int hook_mask) 105 - { 106 - struct ipt_mark_target_info_v1 *markinfo = targinfo; 107 - 108 - if (targinfosize != IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1))){ 109 - printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n", 110 - targinfosize, 111 - IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1))); 112 - return 0; 113 - } 114 - 115 - if (strcmp(tablename, "mangle") != 0) { 116 - printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename); 117 - return 0; 118 - } 119 - 120 - if (markinfo->mode != IPT_MARK_SET 121 - && markinfo->mode != IPT_MARK_AND 122 - && markinfo->mode != IPT_MARK_OR) { 123 - printk(KERN_WARNING "MARK: unknown mode %u\n", 124 - markinfo->mode); 125 - return 0; 126 - } 127 - 128 - if (markinfo->mark > 0xffffffff) { 129 - printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n"); 130 - return 0; 131 - } 132 - 133 - return 1; 134 - } 135 - 136 - static struct ipt_target ipt_mark_reg_v0 = { 137 - .name = "MARK", 138 - .target = target_v0, 139 - .checkentry = checkentry_v0, 140 - .me = THIS_MODULE, 141 - .revision = 0, 142 - }; 143 - 144 - static struct ipt_target ipt_mark_reg_v1 = { 145 - .name = "MARK", 146 - .target = target_v1, 147 - .checkentry = checkentry_v1, 148 - .me = THIS_MODULE, 149 - .revision = 1, 150 - }; 151 - 152 - static int __init init(void) 153 - { 154 - int err; 155 - 156 - err = ipt_register_target(&ipt_mark_reg_v0); 157 - if (!err) { 158 - err = ipt_register_target(&ipt_mark_reg_v1); 159 - if (err) 160 - ipt_unregister_target(&ipt_mark_reg_v0); 161 - } 162 - return err; 163 - } 164 - 165 - static void __exit fini(void) 166 - { 167 - ipt_unregister_target(&ipt_mark_reg_v0); 168 - ipt_unregister_target(&ipt_mark_reg_v1); 169 - } 170 - 171 - module_init(init); 172 - module_exit(fini);
+1 -1
net/ipv4/netfilter/ipt_MASQUERADE.c
··· 40 40 /* FIXME: Multiple targets. --RR */ 41 41 static int 42 42 masquerade_check(const char *tablename, 43 - const struct ipt_entry *e, 43 + const void *e, 44 44 void *targinfo, 45 45 unsigned int targinfosize, 46 46 unsigned int hook_mask)
+1 -1
net/ipv4/netfilter/ipt_NETMAP.c
··· 31 31 32 32 static int 33 33 check(const char *tablename, 34 - const struct ipt_entry *e, 34 + const void *e, 35 35 void *targinfo, 36 36 unsigned int targinfosize, 37 37 unsigned int hook_mask)
-70
net/ipv4/netfilter/ipt_NFQUEUE.c
··· 1 - /* iptables module for using new netfilter netlink queue 2 - * 3 - * (C) 2005 by Harald Welte <laforge@netfilter.org> 4 - * 5 - * This program is free software; you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License version 2 as 7 - * published by the Free Software Foundation. 8 - * 9 - */ 10 - 11 - #include <linux/module.h> 12 - #include <linux/skbuff.h> 13 - 14 - #include <linux/netfilter.h> 15 - #include <linux/netfilter_ipv4/ip_tables.h> 16 - #include <linux/netfilter_ipv4/ipt_NFQUEUE.h> 17 - 18 - MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 19 - MODULE_DESCRIPTION("iptables NFQUEUE target"); 20 - MODULE_LICENSE("GPL"); 21 - 22 - static unsigned int 23 - target(struct sk_buff **pskb, 24 - const struct net_device *in, 25 - const struct net_device *out, 26 - unsigned int hooknum, 27 - const void *targinfo, 28 - void *userinfo) 29 - { 30 - const struct ipt_NFQ_info *tinfo = targinfo; 31 - 32 - return NF_QUEUE_NR(tinfo->queuenum); 33 - } 34 - 35 - static int 36 - checkentry(const char *tablename, 37 - const struct ipt_entry *e, 38 - void *targinfo, 39 - unsigned int targinfosize, 40 - unsigned int hook_mask) 41 - { 42 - if (targinfosize != IPT_ALIGN(sizeof(struct ipt_NFQ_info))) { 43 - printk(KERN_WARNING "NFQUEUE: targinfosize %u != %Zu\n", 44 - targinfosize, 45 - IPT_ALIGN(sizeof(struct ipt_NFQ_info))); 46 - return 0; 47 - } 48 - 49 - return 1; 50 - } 51 - 52 - static struct ipt_target ipt_NFQ_reg = { 53 - .name = "NFQUEUE", 54 - .target = target, 55 - .checkentry = checkentry, 56 - .me = THIS_MODULE, 57 - }; 58 - 59 - static int __init init(void) 60 - { 61 - return ipt_register_target(&ipt_NFQ_reg); 62 - } 63 - 64 - static void __exit fini(void) 65 - { 66 - ipt_unregister_target(&ipt_NFQ_reg); 67 - } 68 - 69 - module_init(init); 70 - module_exit(fini);
-76
net/ipv4/netfilter/ipt_NOTRACK.c
··· 1 - /* This is a module which is used for setting up fake conntracks 2 - * on packets so that they are not seen by the conntrack/NAT code. 3 - */ 4 - #include <linux/module.h> 5 - #include <linux/skbuff.h> 6 - 7 - #include <linux/netfilter_ipv4/ip_tables.h> 8 - #include <net/netfilter/nf_conntrack_compat.h> 9 - 10 - static unsigned int 11 - target(struct sk_buff **pskb, 12 - const struct net_device *in, 13 - const struct net_device *out, 14 - unsigned int hooknum, 15 - const void *targinfo, 16 - void *userinfo) 17 - { 18 - /* Previously seen (loopback)? Ignore. */ 19 - if ((*pskb)->nfct != NULL) 20 - return IPT_CONTINUE; 21 - 22 - /* Attach fake conntrack entry. 23 - If there is a real ct entry correspondig to this packet, 24 - it'll hang aroun till timing out. We don't deal with it 25 - for performance reasons. JK */ 26 - nf_ct_untrack(*pskb); 27 - (*pskb)->nfctinfo = IP_CT_NEW; 28 - nf_conntrack_get((*pskb)->nfct); 29 - 30 - return IPT_CONTINUE; 31 - } 32 - 33 - static int 34 - checkentry(const char *tablename, 35 - const struct ipt_entry *e, 36 - void *targinfo, 37 - unsigned int targinfosize, 38 - unsigned int hook_mask) 39 - { 40 - if (targinfosize != 0) { 41 - printk(KERN_WARNING "NOTRACK: targinfosize %u != 0\n", 42 - targinfosize); 43 - return 0; 44 - } 45 - 46 - if (strcmp(tablename, "raw") != 0) { 47 - printk(KERN_WARNING "NOTRACK: can only be called from \"raw\" table, not \"%s\"\n", tablename); 48 - return 0; 49 - } 50 - 51 - return 1; 52 - } 53 - 54 - static struct ipt_target ipt_notrack_reg = { 55 - .name = "NOTRACK", 56 - .target = target, 57 - .checkentry = checkentry, 58 - .me = THIS_MODULE 59 - }; 60 - 61 - static int __init init(void) 62 - { 63 - if (ipt_register_target(&ipt_notrack_reg)) 64 - return -EINVAL; 65 - 66 - return 0; 67 - } 68 - 69 - static void __exit fini(void) 70 - { 71 - ipt_unregister_target(&ipt_notrack_reg); 72 - } 73 - 74 - module_init(init); 75 - module_exit(fini); 76 - MODULE_LICENSE("GPL");
+1 -1
net/ipv4/netfilter/ipt_REDIRECT.c
··· 33 33 /* FIXME: Take multiple ranges --RR */ 34 34 static int 35 35 redirect_check(const char *tablename, 36 - const struct ipt_entry *e, 36 + const void *e, 37 37 void *targinfo, 38 38 unsigned int targinfosize, 39 39 unsigned int hook_mask)
+2 -1
net/ipv4/netfilter/ipt_REJECT.c
··· 282 282 } 283 283 284 284 static int check(const char *tablename, 285 - const struct ipt_entry *e, 285 + const void *e_void, 286 286 void *targinfo, 287 287 unsigned int targinfosize, 288 288 unsigned int hook_mask) 289 289 { 290 290 const struct ipt_reject_info *rejinfo = targinfo; 291 + const struct ipt_entry *e = e_void; 291 292 292 293 if (targinfosize != IPT_ALIGN(sizeof(struct ipt_reject_info))) { 293 294 DEBUGP("REJECT: targinfosize %u != 0\n", targinfosize);
+1 -1
net/ipv4/netfilter/ipt_SAME.c
··· 49 49 50 50 static int 51 51 same_check(const char *tablename, 52 - const struct ipt_entry *e, 52 + const void *e, 53 53 void *targinfo, 54 54 unsigned int targinfosize, 55 55 unsigned int hook_mask)
+2 -1
net/ipv4/netfilter/ipt_TCPMSS.c
··· 210 210 /* Must specify -p tcp --syn/--tcp-flags SYN */ 211 211 static int 212 212 ipt_tcpmss_checkentry(const char *tablename, 213 - const struct ipt_entry *e, 213 + const void *e_void, 214 214 void *targinfo, 215 215 unsigned int targinfosize, 216 216 unsigned int hook_mask) 217 217 { 218 218 const struct ipt_tcpmss_info *tcpmssinfo = targinfo; 219 + const struct ipt_entry *e = e_void; 219 220 220 221 if (targinfosize != IPT_ALIGN(sizeof(struct ipt_tcpmss_info))) { 221 222 DEBUGP("ipt_tcpmss_checkentry: targinfosize %u != %u\n",
+1 -1
net/ipv4/netfilter/ipt_TOS.c
··· 52 52 53 53 static int 54 54 checkentry(const char *tablename, 55 - const struct ipt_entry *e, 55 + const void *e_void, 56 56 void *targinfo, 57 57 unsigned int targinfosize, 58 58 unsigned int hook_mask)
+1 -1
net/ipv4/netfilter/ipt_TTL.c
··· 66 66 } 67 67 68 68 static int ipt_ttl_checkentry(const char *tablename, 69 - const struct ipt_entry *e, 69 + const void *e, 70 70 void *targinfo, 71 71 unsigned int targinfosize, 72 72 unsigned int hook_mask)
+1 -1
net/ipv4/netfilter/ipt_ULOG.c
··· 330 330 } 331 331 332 332 static int ipt_ulog_checkentry(const char *tablename, 333 - const struct ipt_entry *e, 333 + const void *e, 334 334 void *targinfo, 335 335 unsigned int targinfosize, 336 336 unsigned int hookmask)
+2 -2
net/ipv4/netfilter/ipt_addrtype.c
··· 29 29 30 30 static int match(const struct sk_buff *skb, const struct net_device *in, 31 31 const struct net_device *out, const void *matchinfo, 32 - int offset, int *hotdrop) 32 + int offset, unsigned int protoff, int *hotdrop) 33 33 { 34 34 const struct ipt_addrtype_info *info = matchinfo; 35 35 const struct iphdr *iph = skb->nh.iph; ··· 43 43 return ret; 44 44 } 45 45 46 - static int checkentry(const char *tablename, const struct ipt_ip *ip, 46 + static int checkentry(const char *tablename, const void *ip, 47 47 void *matchinfo, unsigned int matchsize, 48 48 unsigned int hook_mask) 49 49 {
+4 -2
net/ipv4/netfilter/ipt_ah.c
··· 41 41 const struct net_device *out, 42 42 const void *matchinfo, 43 43 int offset, 44 + unsigned int protoff, 44 45 int *hotdrop) 45 46 { 46 47 struct ip_auth_hdr _ahdr, *ah; ··· 51 50 if (offset) 52 51 return 0; 53 52 54 - ah = skb_header_pointer(skb, skb->nh.iph->ihl * 4, 53 + ah = skb_header_pointer(skb, protoff, 55 54 sizeof(_ahdr), &_ahdr); 56 55 if (ah == NULL) { 57 56 /* We've been asked to examine this packet, and we ··· 70 69 /* Called when user tries to insert an entry of this type. */ 71 70 static int 72 71 checkentry(const char *tablename, 73 - const struct ipt_ip *ip, 72 + const void *ip_void, 74 73 void *matchinfo, 75 74 unsigned int matchinfosize, 76 75 unsigned int hook_mask) 77 76 { 78 77 const struct ipt_ah *ahinfo = matchinfo; 78 + const struct ipt_ip *ip = ip_void; 79 79 80 80 /* Must specify proto == AH, and no unknown invflags */ 81 81 if (ip->proto != IPPROTO_AH || (ip->invflags & IPT_INV_PROTO)) {
-59
net/ipv4/netfilter/ipt_comment.c
··· 1 - /* 2 - * Implements a dummy match to allow attaching comments to rules 3 - * 4 - * 2003-05-13 Brad Fisher (brad@info-link.net) 5 - */ 6 - 7 - #include <linux/module.h> 8 - #include <linux/skbuff.h> 9 - #include <linux/netfilter_ipv4/ip_tables.h> 10 - #include <linux/netfilter_ipv4/ipt_comment.h> 11 - 12 - MODULE_AUTHOR("Brad Fisher <brad@info-link.net>"); 13 - MODULE_DESCRIPTION("iptables comment match module"); 14 - MODULE_LICENSE("GPL"); 15 - 16 - static int 17 - match(const struct sk_buff *skb, 18 - const struct net_device *in, 19 - const struct net_device *out, 20 - const void *matchinfo, 21 - int offset, 22 - int *hotdrop) 23 - { 24 - /* We always match */ 25 - return 1; 26 - } 27 - 28 - static int 29 - checkentry(const char *tablename, 30 - const struct ipt_ip *ip, 31 - void *matchinfo, 32 - unsigned int matchsize, 33 - unsigned int hook_mask) 34 - { 35 - /* Check the size */ 36 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_comment_info))) 37 - return 0; 38 - return 1; 39 - } 40 - 41 - static struct ipt_match comment_match = { 42 - .name = "comment", 43 - .match = match, 44 - .checkentry = checkentry, 45 - .me = THIS_MODULE 46 - }; 47 - 48 - static int __init init(void) 49 - { 50 - return ipt_register_match(&comment_match); 51 - } 52 - 53 - static void __exit fini(void) 54 - { 55 - ipt_unregister_match(&comment_match); 56 - } 57 - 58 - module_init(init); 59 - module_exit(fini);
-161
net/ipv4/netfilter/ipt_connbytes.c
··· 1 - /* Kernel module to match connection tracking byte counter. 2 - * GPL (C) 2002 Martin Devera (devik@cdi.cz). 3 - * 4 - * 2004-07-20 Harald Welte <laforge@netfilter.org> 5 - * - reimplemented to use per-connection accounting counters 6 - * - add functionality to match number of packets 7 - * - add functionality to match average packet size 8 - * - add support to match directions seperately 9 - * 10 - */ 11 - #include <linux/module.h> 12 - #include <linux/skbuff.h> 13 - #include <net/netfilter/nf_conntrack_compat.h> 14 - #include <linux/netfilter_ipv4/ip_tables.h> 15 - #include <linux/netfilter_ipv4/ipt_connbytes.h> 16 - 17 - #include <asm/div64.h> 18 - #include <asm/bitops.h> 19 - 20 - MODULE_LICENSE("GPL"); 21 - MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 22 - MODULE_DESCRIPTION("iptables match for matching number of pkts/bytes per connection"); 23 - 24 - /* 64bit divisor, dividend and result. dynamic precision */ 25 - static u_int64_t div64_64(u_int64_t dividend, u_int64_t divisor) 26 - { 27 - u_int32_t d = divisor; 28 - 29 - if (divisor > 0xffffffffULL) { 30 - unsigned int shift = fls(divisor >> 32); 31 - 32 - d = divisor >> shift; 33 - dividend >>= shift; 34 - } 35 - 36 - do_div(dividend, d); 37 - return dividend; 38 - } 39 - 40 - static int 41 - match(const struct sk_buff *skb, 42 - const struct net_device *in, 43 - const struct net_device *out, 44 - const void *matchinfo, 45 - int offset, 46 - int *hotdrop) 47 - { 48 - const struct ipt_connbytes_info *sinfo = matchinfo; 49 - u_int64_t what = 0; /* initialize to make gcc happy */ 50 - const struct ip_conntrack_counter *counters; 51 - 52 - if (!(counters = nf_ct_get_counters(skb))) 53 - return 0; /* no match */ 54 - 55 - switch (sinfo->what) { 56 - case IPT_CONNBYTES_PKTS: 57 - switch (sinfo->direction) { 58 - case IPT_CONNBYTES_DIR_ORIGINAL: 59 - what = counters[IP_CT_DIR_ORIGINAL].packets; 60 - break; 61 - case IPT_CONNBYTES_DIR_REPLY: 62 - what = counters[IP_CT_DIR_REPLY].packets; 63 - break; 64 - case IPT_CONNBYTES_DIR_BOTH: 65 - what = counters[IP_CT_DIR_ORIGINAL].packets; 66 - what += counters[IP_CT_DIR_REPLY].packets; 67 - break; 68 - } 69 - break; 70 - case IPT_CONNBYTES_BYTES: 71 - switch (sinfo->direction) { 72 - case IPT_CONNBYTES_DIR_ORIGINAL: 73 - what = counters[IP_CT_DIR_ORIGINAL].bytes; 74 - break; 75 - case IPT_CONNBYTES_DIR_REPLY: 76 - what = counters[IP_CT_DIR_REPLY].bytes; 77 - break; 78 - case IPT_CONNBYTES_DIR_BOTH: 79 - what = counters[IP_CT_DIR_ORIGINAL].bytes; 80 - what += counters[IP_CT_DIR_REPLY].bytes; 81 - break; 82 - } 83 - break; 84 - case IPT_CONNBYTES_AVGPKT: 85 - switch (sinfo->direction) { 86 - case IPT_CONNBYTES_DIR_ORIGINAL: 87 - what = div64_64(counters[IP_CT_DIR_ORIGINAL].bytes, 88 - counters[IP_CT_DIR_ORIGINAL].packets); 89 - break; 90 - case IPT_CONNBYTES_DIR_REPLY: 91 - what = div64_64(counters[IP_CT_DIR_REPLY].bytes, 92 - counters[IP_CT_DIR_REPLY].packets); 93 - break; 94 - case IPT_CONNBYTES_DIR_BOTH: 95 - { 96 - u_int64_t bytes; 97 - u_int64_t pkts; 98 - bytes = counters[IP_CT_DIR_ORIGINAL].bytes + 99 - counters[IP_CT_DIR_REPLY].bytes; 100 - pkts = counters[IP_CT_DIR_ORIGINAL].packets+ 101 - counters[IP_CT_DIR_REPLY].packets; 102 - 103 - /* FIXME_THEORETICAL: what to do if sum 104 - * overflows ? */ 105 - 106 - what = div64_64(bytes, pkts); 107 - } 108 - break; 109 - } 110 - break; 111 - } 112 - 113 - if (sinfo->count.to) 114 - return (what <= sinfo->count.to && what >= sinfo->count.from); 115 - else 116 - return (what >= sinfo->count.from); 117 - } 118 - 119 - static int check(const char *tablename, 120 - const struct ipt_ip *ip, 121 - void *matchinfo, 122 - unsigned int matchsize, 123 - unsigned int hook_mask) 124 - { 125 - const struct ipt_connbytes_info *sinfo = matchinfo; 126 - 127 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_connbytes_info))) 128 - return 0; 129 - 130 - if (sinfo->what != IPT_CONNBYTES_PKTS && 131 - sinfo->what != IPT_CONNBYTES_BYTES && 132 - sinfo->what != IPT_CONNBYTES_AVGPKT) 133 - return 0; 134 - 135 - if (sinfo->direction != IPT_CONNBYTES_DIR_ORIGINAL && 136 - sinfo->direction != IPT_CONNBYTES_DIR_REPLY && 137 - sinfo->direction != IPT_CONNBYTES_DIR_BOTH) 138 - return 0; 139 - 140 - return 1; 141 - } 142 - 143 - static struct ipt_match state_match = { 144 - .name = "connbytes", 145 - .match = &match, 146 - .checkentry = &check, 147 - .me = THIS_MODULE 148 - }; 149 - 150 - static int __init init(void) 151 - { 152 - return ipt_register_match(&state_match); 153 - } 154 - 155 - static void __exit fini(void) 156 - { 157 - ipt_unregister_match(&state_match); 158 - } 159 - 160 - module_init(init); 161 - module_exit(fini);
-88
net/ipv4/netfilter/ipt_connmark.c
··· 1 - /* This kernel module matches connection mark values set by the 2 - * CONNMARK target 3 - * 4 - * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> 5 - * by Henrik Nordstrom <hno@marasystems.com> 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 as published by 9 - * the Free Software Foundation; either version 2 of the License, or 10 - * (at your option) any later version. 11 - * 12 - * This program is distributed in the hope that it will be useful, 13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 - * GNU General Public License for more details. 16 - * 17 - * You should have received a copy of the GNU General Public License 18 - * along with this program; if not, write to the Free Software 19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 - */ 21 - 22 - #include <linux/module.h> 23 - #include <linux/skbuff.h> 24 - 25 - MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>"); 26 - MODULE_DESCRIPTION("IP tables connmark match module"); 27 - MODULE_LICENSE("GPL"); 28 - 29 - #include <linux/netfilter_ipv4/ip_tables.h> 30 - #include <linux/netfilter_ipv4/ipt_connmark.h> 31 - #include <net/netfilter/nf_conntrack_compat.h> 32 - 33 - static int 34 - match(const struct sk_buff *skb, 35 - const struct net_device *in, 36 - const struct net_device *out, 37 - const void *matchinfo, 38 - int offset, 39 - int *hotdrop) 40 - { 41 - const struct ipt_connmark_info *info = matchinfo; 42 - u_int32_t ctinfo; 43 - const u_int32_t *ctmark = nf_ct_get_mark(skb, &ctinfo); 44 - if (!ctmark) 45 - return 0; 46 - 47 - return (((*ctmark) & info->mask) == info->mark) ^ info->invert; 48 - } 49 - 50 - static int 51 - checkentry(const char *tablename, 52 - const struct ipt_ip *ip, 53 - void *matchinfo, 54 - unsigned int matchsize, 55 - unsigned int hook_mask) 56 - { 57 - struct ipt_connmark_info *cm = 58 - (struct ipt_connmark_info *)matchinfo; 59 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_connmark_info))) 60 - return 0; 61 - 62 - if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) { 63 - printk(KERN_WARNING "connmark: only support 32bit mark\n"); 64 - return 0; 65 - } 66 - 67 - return 1; 68 - } 69 - 70 - static struct ipt_match connmark_match = { 71 - .name = "connmark", 72 - .match = &match, 73 - .checkentry = &checkentry, 74 - .me = THIS_MODULE 75 - }; 76 - 77 - static int __init init(void) 78 - { 79 - return ipt_register_match(&connmark_match); 80 - } 81 - 82 - static void __exit fini(void) 83 - { 84 - ipt_unregister_match(&connmark_match); 85 - } 86 - 87 - module_init(init); 88 - module_exit(fini);
-232
net/ipv4/netfilter/ipt_conntrack.c
··· 1 - /* Kernel module to match connection tracking information. 2 - * Superset of Rusty's minimalistic state match. 3 - * 4 - * (C) 2001 Marc Boucher (marc@mbsi.ca). 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License version 2 as 8 - * published by the Free Software Foundation. 9 - */ 10 - 11 - #include <linux/module.h> 12 - #include <linux/skbuff.h> 13 - 14 - #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) 15 - #include <linux/netfilter_ipv4/ip_conntrack.h> 16 - #include <linux/netfilter_ipv4/ip_conntrack_tuple.h> 17 - #else 18 - #include <net/netfilter/nf_conntrack.h> 19 - #endif 20 - 21 - #include <linux/netfilter_ipv4/ip_tables.h> 22 - #include <linux/netfilter_ipv4/ipt_conntrack.h> 23 - 24 - MODULE_LICENSE("GPL"); 25 - MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 26 - MODULE_DESCRIPTION("iptables connection tracking match module"); 27 - 28 - #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) 29 - 30 - static int 31 - match(const struct sk_buff *skb, 32 - const struct net_device *in, 33 - const struct net_device *out, 34 - const void *matchinfo, 35 - int offset, 36 - int *hotdrop) 37 - { 38 - const struct ipt_conntrack_info *sinfo = matchinfo; 39 - struct ip_conntrack *ct; 40 - enum ip_conntrack_info ctinfo; 41 - unsigned int statebit; 42 - 43 - ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo); 44 - 45 - #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg)) 46 - 47 - if (ct == &ip_conntrack_untracked) 48 - statebit = IPT_CONNTRACK_STATE_UNTRACKED; 49 - else if (ct) 50 - statebit = IPT_CONNTRACK_STATE_BIT(ctinfo); 51 - else 52 - statebit = IPT_CONNTRACK_STATE_INVALID; 53 - 54 - if(sinfo->flags & IPT_CONNTRACK_STATE) { 55 - if (ct) { 56 - if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip != 57 - ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip) 58 - statebit |= IPT_CONNTRACK_STATE_SNAT; 59 - 60 - if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip != 61 - ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip) 62 - statebit |= IPT_CONNTRACK_STATE_DNAT; 63 - } 64 - 65 - if (FWINV((statebit & sinfo->statemask) == 0, IPT_CONNTRACK_STATE)) 66 - return 0; 67 - } 68 - 69 - if(sinfo->flags & IPT_CONNTRACK_PROTO) { 70 - if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, IPT_CONNTRACK_PROTO)) 71 - return 0; 72 - } 73 - 74 - if(sinfo->flags & IPT_CONNTRACK_ORIGSRC) { 75 - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip&sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, IPT_CONNTRACK_ORIGSRC)) 76 - return 0; 77 - } 78 - 79 - if(sinfo->flags & IPT_CONNTRACK_ORIGDST) { 80 - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip&sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, IPT_CONNTRACK_ORIGDST)) 81 - return 0; 82 - } 83 - 84 - if(sinfo->flags & IPT_CONNTRACK_REPLSRC) { 85 - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip&sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].src.ip, IPT_CONNTRACK_REPLSRC)) 86 - return 0; 87 - } 88 - 89 - if(sinfo->flags & IPT_CONNTRACK_REPLDST) { 90 - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip&sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, IPT_CONNTRACK_REPLDST)) 91 - return 0; 92 - } 93 - 94 - if(sinfo->flags & IPT_CONNTRACK_STATUS) { 95 - if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, IPT_CONNTRACK_STATUS)) 96 - return 0; 97 - } 98 - 99 - if(sinfo->flags & IPT_CONNTRACK_EXPIRES) { 100 - unsigned long expires; 101 - 102 - if(!ct) 103 - return 0; 104 - 105 - expires = timer_pending(&ct->timeout) ? (ct->timeout.expires - jiffies)/HZ : 0; 106 - 107 - if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), IPT_CONNTRACK_EXPIRES)) 108 - return 0; 109 - } 110 - 111 - return 1; 112 - } 113 - 114 - #else /* CONFIG_IP_NF_CONNTRACK */ 115 - static int 116 - match(const struct sk_buff *skb, 117 - const struct net_device *in, 118 - const struct net_device *out, 119 - const void *matchinfo, 120 - int offset, 121 - int *hotdrop) 122 - { 123 - const struct ipt_conntrack_info *sinfo = matchinfo; 124 - struct nf_conn *ct; 125 - enum ip_conntrack_info ctinfo; 126 - unsigned int statebit; 127 - 128 - ct = nf_ct_get((struct sk_buff *)skb, &ctinfo); 129 - 130 - #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg)) 131 - 132 - if (ct == &nf_conntrack_untracked) 133 - statebit = IPT_CONNTRACK_STATE_UNTRACKED; 134 - else if (ct) 135 - statebit = IPT_CONNTRACK_STATE_BIT(ctinfo); 136 - else 137 - statebit = IPT_CONNTRACK_STATE_INVALID; 138 - 139 - if(sinfo->flags & IPT_CONNTRACK_STATE) { 140 - if (ct) { 141 - if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip != 142 - ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip) 143 - statebit |= IPT_CONNTRACK_STATE_SNAT; 144 - 145 - if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip != 146 - ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip) 147 - statebit |= IPT_CONNTRACK_STATE_DNAT; 148 - } 149 - 150 - if (FWINV((statebit & sinfo->statemask) == 0, IPT_CONNTRACK_STATE)) 151 - return 0; 152 - } 153 - 154 - if(sinfo->flags & IPT_CONNTRACK_PROTO) { 155 - if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, IPT_CONNTRACK_PROTO)) 156 - return 0; 157 - } 158 - 159 - if(sinfo->flags & IPT_CONNTRACK_ORIGSRC) { 160 - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, IPT_CONNTRACK_ORIGSRC)) 161 - return 0; 162 - } 163 - 164 - if(sinfo->flags & IPT_CONNTRACK_ORIGDST) { 165 - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, IPT_CONNTRACK_ORIGDST)) 166 - return 0; 167 - } 168 - 169 - if(sinfo->flags & IPT_CONNTRACK_REPLSRC) { 170 - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].src.ip, IPT_CONNTRACK_REPLSRC)) 171 - return 0; 172 - } 173 - 174 - if(sinfo->flags & IPT_CONNTRACK_REPLDST) { 175 - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, IPT_CONNTRACK_REPLDST)) 176 - return 0; 177 - } 178 - 179 - if(sinfo->flags & IPT_CONNTRACK_STATUS) { 180 - if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, IPT_CONNTRACK_STATUS)) 181 - return 0; 182 - } 183 - 184 - if(sinfo->flags & IPT_CONNTRACK_EXPIRES) { 185 - unsigned long expires; 186 - 187 - if(!ct) 188 - return 0; 189 - 190 - expires = timer_pending(&ct->timeout) ? (ct->timeout.expires - jiffies)/HZ : 0; 191 - 192 - if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), IPT_CONNTRACK_EXPIRES)) 193 - return 0; 194 - } 195 - 196 - return 1; 197 - } 198 - 199 - #endif /* CONFIG_NF_IP_CONNTRACK */ 200 - 201 - static int check(const char *tablename, 202 - const struct ipt_ip *ip, 203 - void *matchinfo, 204 - unsigned int matchsize, 205 - unsigned int hook_mask) 206 - { 207 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_conntrack_info))) 208 - return 0; 209 - 210 - return 1; 211 - } 212 - 213 - static struct ipt_match conntrack_match = { 214 - .name = "conntrack", 215 - .match = &match, 216 - .checkentry = &check, 217 - .me = THIS_MODULE, 218 - }; 219 - 220 - static int __init init(void) 221 - { 222 - need_ip_conntrack(); 223 - return ipt_register_match(&conntrack_match); 224 - } 225 - 226 - static void __exit fini(void) 227 - { 228 - ipt_unregister_match(&conntrack_match); 229 - } 230 - 231 - module_init(init); 232 - module_exit(fini);
-176
net/ipv4/netfilter/ipt_dccp.c
··· 1 - /* 2 - * iptables module for DCCP protocol header matching 3 - * 4 - * (C) 2005 by Harald Welte <laforge@netfilter.org> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License version 2 as 8 - * published by the Free Software Foundation. 9 - */ 10 - 11 - #include <linux/module.h> 12 - #include <linux/skbuff.h> 13 - #include <linux/spinlock.h> 14 - #include <net/ip.h> 15 - #include <linux/dccp.h> 16 - 17 - #include <linux/netfilter_ipv4/ip_tables.h> 18 - #include <linux/netfilter_ipv4/ipt_dccp.h> 19 - 20 - #define DCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \ 21 - || (!!((invflag) & (option)) ^ (cond))) 22 - 23 - static unsigned char *dccp_optbuf; 24 - static DEFINE_SPINLOCK(dccp_buflock); 25 - 26 - static inline int 27 - dccp_find_option(u_int8_t option, 28 - const struct sk_buff *skb, 29 - const struct dccp_hdr *dh, 30 - int *hotdrop) 31 - { 32 - /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ 33 - unsigned char *op; 34 - unsigned int optoff = __dccp_hdr_len(dh); 35 - unsigned int optlen = dh->dccph_doff*4 - __dccp_hdr_len(dh); 36 - unsigned int i; 37 - 38 - if (dh->dccph_doff * 4 < __dccp_hdr_len(dh)) { 39 - *hotdrop = 1; 40 - return 0; 41 - } 42 - 43 - if (!optlen) 44 - return 0; 45 - 46 - spin_lock_bh(&dccp_buflock); 47 - op = skb_header_pointer(skb, 48 - skb->nh.iph->ihl*4 + optoff, 49 - optlen, dccp_optbuf); 50 - if (op == NULL) { 51 - /* If we don't have the whole header, drop packet. */ 52 - spin_unlock_bh(&dccp_buflock); 53 - *hotdrop = 1; 54 - return 0; 55 - } 56 - 57 - for (i = 0; i < optlen; ) { 58 - if (op[i] == option) { 59 - spin_unlock_bh(&dccp_buflock); 60 - return 1; 61 - } 62 - 63 - if (op[i] < 2) 64 - i++; 65 - else 66 - i += op[i+1]?:1; 67 - } 68 - 69 - spin_unlock_bh(&dccp_buflock); 70 - return 0; 71 - } 72 - 73 - 74 - static inline int 75 - match_types(const struct dccp_hdr *dh, u_int16_t typemask) 76 - { 77 - return (typemask & (1 << dh->dccph_type)); 78 - } 79 - 80 - static inline int 81 - match_option(u_int8_t option, const struct sk_buff *skb, 82 - const struct dccp_hdr *dh, int *hotdrop) 83 - { 84 - return dccp_find_option(option, skb, dh, hotdrop); 85 - } 86 - 87 - static int 88 - match(const struct sk_buff *skb, 89 - const struct net_device *in, 90 - const struct net_device *out, 91 - const void *matchinfo, 92 - int offset, 93 - int *hotdrop) 94 - { 95 - const struct ipt_dccp_info *info = 96 - (const struct ipt_dccp_info *)matchinfo; 97 - struct dccp_hdr _dh, *dh; 98 - 99 - if (offset) 100 - return 0; 101 - 102 - dh = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_dh), &_dh); 103 - if (dh == NULL) { 104 - *hotdrop = 1; 105 - return 0; 106 - } 107 - 108 - return DCCHECK(((ntohs(dh->dccph_sport) >= info->spts[0]) 109 - && (ntohs(dh->dccph_sport) <= info->spts[1])), 110 - IPT_DCCP_SRC_PORTS, info->flags, info->invflags) 111 - && DCCHECK(((ntohs(dh->dccph_dport) >= info->dpts[0]) 112 - && (ntohs(dh->dccph_dport) <= info->dpts[1])), 113 - IPT_DCCP_DEST_PORTS, info->flags, info->invflags) 114 - && DCCHECK(match_types(dh, info->typemask), 115 - IPT_DCCP_TYPE, info->flags, info->invflags) 116 - && DCCHECK(match_option(info->option, skb, dh, hotdrop), 117 - IPT_DCCP_OPTION, info->flags, info->invflags); 118 - } 119 - 120 - static int 121 - checkentry(const char *tablename, 122 - const struct ipt_ip *ip, 123 - void *matchinfo, 124 - unsigned int matchsize, 125 - unsigned int hook_mask) 126 - { 127 - const struct ipt_dccp_info *info; 128 - 129 - info = (const struct ipt_dccp_info *)matchinfo; 130 - 131 - return ip->proto == IPPROTO_DCCP 132 - && !(ip->invflags & IPT_INV_PROTO) 133 - && matchsize == IPT_ALIGN(sizeof(struct ipt_dccp_info)) 134 - && !(info->flags & ~IPT_DCCP_VALID_FLAGS) 135 - && !(info->invflags & ~IPT_DCCP_VALID_FLAGS) 136 - && !(info->invflags & ~info->flags); 137 - } 138 - 139 - static struct ipt_match dccp_match = 140 - { 141 - .name = "dccp", 142 - .match = &match, 143 - .checkentry = &checkentry, 144 - .me = THIS_MODULE, 145 - }; 146 - 147 - static int __init init(void) 148 - { 149 - int ret; 150 - 151 - /* doff is 8 bits, so the maximum option size is (4*256). Don't put 152 - * this in BSS since DaveM is worried about locked TLB's for kernel 153 - * BSS. */ 154 - dccp_optbuf = kmalloc(256 * 4, GFP_KERNEL); 155 - if (!dccp_optbuf) 156 - return -ENOMEM; 157 - ret = ipt_register_match(&dccp_match); 158 - if (ret) 159 - kfree(dccp_optbuf); 160 - 161 - return ret; 162 - } 163 - 164 - static void __exit fini(void) 165 - { 166 - ipt_unregister_match(&dccp_match); 167 - kfree(dccp_optbuf); 168 - } 169 - 170 - module_init(init); 171 - module_exit(fini); 172 - 173 - MODULE_LICENSE("GPL"); 174 - MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 175 - MODULE_DESCRIPTION("Match for DCCP protocol packets"); 176 -
+2 -2
net/ipv4/netfilter/ipt_dscp.c
··· 21 21 22 22 static int match(const struct sk_buff *skb, const struct net_device *in, 23 23 const struct net_device *out, const void *matchinfo, 24 - int offset, int *hotdrop) 24 + int offset, unsigned int protoff, int *hotdrop) 25 25 { 26 26 const struct ipt_dscp_info *info = matchinfo; 27 27 const struct iphdr *iph = skb->nh.iph; ··· 31 31 return ((iph->tos&IPT_DSCP_MASK) == sh_dscp) ^ info->invert; 32 32 } 33 33 34 - static int checkentry(const char *tablename, const struct ipt_ip *ip, 34 + static int checkentry(const char *tablename, const void *ip, 35 35 void *matchinfo, unsigned int matchsize, 36 36 unsigned int hook_mask) 37 37 {
+3 -2
net/ipv4/netfilter/ipt_ecn.c
··· 67 67 68 68 static int match(const struct sk_buff *skb, const struct net_device *in, 69 69 const struct net_device *out, const void *matchinfo, 70 - int offset, int *hotdrop) 70 + int offset, unsigned int protoff, int *hotdrop) 71 71 { 72 72 const struct ipt_ecn_info *info = matchinfo; 73 73 ··· 85 85 return 1; 86 86 } 87 87 88 - static int checkentry(const char *tablename, const struct ipt_ip *ip, 88 + static int checkentry(const char *tablename, const void *ip_void, 89 89 void *matchinfo, unsigned int matchsize, 90 90 unsigned int hook_mask) 91 91 { 92 92 const struct ipt_ecn_info *info = matchinfo; 93 + const struct ipt_ip *ip = ip_void; 93 94 94 95 if (matchsize != IPT_ALIGN(sizeof(struct ipt_ecn_info))) 95 96 return 0;
+4 -2
net/ipv4/netfilter/ipt_esp.c
··· 42 42 const struct net_device *out, 43 43 const void *matchinfo, 44 44 int offset, 45 + unsigned int protoff, 45 46 int *hotdrop) 46 47 { 47 48 struct ip_esp_hdr _esp, *eh; ··· 52 51 if (offset) 53 52 return 0; 54 53 55 - eh = skb_header_pointer(skb, skb->nh.iph->ihl * 4, 54 + eh = skb_header_pointer(skb, protoff, 56 55 sizeof(_esp), &_esp); 57 56 if (eh == NULL) { 58 57 /* We've been asked to examine this packet, and we ··· 71 70 /* Called when user tries to insert an entry of this type. */ 72 71 static int 73 72 checkentry(const char *tablename, 74 - const struct ipt_ip *ip, 73 + const void *ip_void, 75 74 void *matchinfo, 76 75 unsigned int matchinfosize, 77 76 unsigned int hook_mask) 78 77 { 79 78 const struct ipt_esp *espinfo = matchinfo; 79 + const struct ipt_ip *ip = ip_void; 80 80 81 81 /* Must specify proto == ESP, and no unknown invflags */ 82 82 if (ip->proto != IPPROTO_ESP || (ip->invflags & IPT_INV_PROTO)) {
+2 -1
net/ipv4/netfilter/ipt_hashlimit.c
··· 429 429 const struct net_device *out, 430 430 const void *matchinfo, 431 431 int offset, 432 + unsigned int protoff, 432 433 int *hotdrop) 433 434 { 434 435 struct ipt_hashlimit_info *r = ··· 505 504 506 505 static int 507 506 hashlimit_checkentry(const char *tablename, 508 - const struct ipt_ip *ip, 507 + const void *inf, 509 508 void *matchinfo, 510 509 unsigned int matchsize, 511 510 unsigned int hook_mask)
-168
net/ipv4/netfilter/ipt_helper.c
··· 1 - /* iptables module to match on related connections */ 2 - /* 3 - * (C) 2001 Martin Josefsson <gandalf@wlug.westbo.se> 4 - * 5 - * This program is free software; you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License version 2 as 7 - * published by the Free Software Foundation. 8 - * 9 - * 19 Mar 2002 Harald Welte <laforge@gnumonks.org>: 10 - * - Port to newnat infrastructure 11 - */ 12 - 13 - #include <linux/module.h> 14 - #include <linux/skbuff.h> 15 - #include <linux/netfilter.h> 16 - #include <linux/interrupt.h> 17 - #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) 18 - #include <linux/netfilter_ipv4/ip_conntrack.h> 19 - #include <linux/netfilter_ipv4/ip_conntrack_core.h> 20 - #include <linux/netfilter_ipv4/ip_conntrack_helper.h> 21 - #else 22 - #include <net/netfilter/nf_conntrack.h> 23 - #include <net/netfilter/nf_conntrack_core.h> 24 - #include <net/netfilter/nf_conntrack_helper.h> 25 - #endif 26 - #include <linux/netfilter_ipv4/ip_tables.h> 27 - #include <linux/netfilter_ipv4/ipt_helper.h> 28 - 29 - MODULE_LICENSE("GPL"); 30 - MODULE_AUTHOR("Martin Josefsson <gandalf@netfilter.org>"); 31 - MODULE_DESCRIPTION("iptables helper match module"); 32 - 33 - #if 0 34 - #define DEBUGP printk 35 - #else 36 - #define DEBUGP(format, args...) 37 - #endif 38 - 39 - #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) 40 - static int 41 - match(const struct sk_buff *skb, 42 - const struct net_device *in, 43 - const struct net_device *out, 44 - const void *matchinfo, 45 - int offset, 46 - int *hotdrop) 47 - { 48 - const struct ipt_helper_info *info = matchinfo; 49 - struct ip_conntrack *ct; 50 - enum ip_conntrack_info ctinfo; 51 - int ret = info->invert; 52 - 53 - ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo); 54 - if (!ct) { 55 - DEBUGP("ipt_helper: Eek! invalid conntrack?\n"); 56 - return ret; 57 - } 58 - 59 - if (!ct->master) { 60 - DEBUGP("ipt_helper: conntrack %p has no master\n", ct); 61 - return ret; 62 - } 63 - 64 - read_lock_bh(&ip_conntrack_lock); 65 - if (!ct->master->helper) { 66 - DEBUGP("ipt_helper: master ct %p has no helper\n", 67 - exp->expectant); 68 - goto out_unlock; 69 - } 70 - 71 - DEBUGP("master's name = %s , info->name = %s\n", 72 - ct->master->helper->name, info->name); 73 - 74 - if (info->name[0] == '\0') 75 - ret ^= 1; 76 - else 77 - ret ^= !strncmp(ct->master->helper->name, info->name, 78 - strlen(ct->master->helper->name)); 79 - out_unlock: 80 - read_unlock_bh(&ip_conntrack_lock); 81 - return ret; 82 - } 83 - 84 - #else /* CONFIG_IP_NF_CONNTRACK */ 85 - 86 - static int 87 - match(const struct sk_buff *skb, 88 - const struct net_device *in, 89 - const struct net_device *out, 90 - const void *matchinfo, 91 - int offset, 92 - int *hotdrop) 93 - { 94 - const struct ipt_helper_info *info = matchinfo; 95 - struct nf_conn *ct; 96 - enum ip_conntrack_info ctinfo; 97 - int ret = info->invert; 98 - 99 - ct = nf_ct_get((struct sk_buff *)skb, &ctinfo); 100 - if (!ct) { 101 - DEBUGP("ipt_helper: Eek! invalid conntrack?\n"); 102 - return ret; 103 - } 104 - 105 - if (!ct->master) { 106 - DEBUGP("ipt_helper: conntrack %p has no master\n", ct); 107 - return ret; 108 - } 109 - 110 - read_lock_bh(&nf_conntrack_lock); 111 - if (!ct->master->helper) { 112 - DEBUGP("ipt_helper: master ct %p has no helper\n", 113 - exp->expectant); 114 - goto out_unlock; 115 - } 116 - 117 - DEBUGP("master's name = %s , info->name = %s\n", 118 - ct->master->helper->name, info->name); 119 - 120 - if (info->name[0] == '\0') 121 - ret ^= 1; 122 - else 123 - ret ^= !strncmp(ct->master->helper->name, info->name, 124 - strlen(ct->master->helper->name)); 125 - out_unlock: 126 - read_unlock_bh(&nf_conntrack_lock); 127 - return ret; 128 - } 129 - #endif 130 - 131 - static int check(const char *tablename, 132 - const struct ipt_ip *ip, 133 - void *matchinfo, 134 - unsigned int matchsize, 135 - unsigned int hook_mask) 136 - { 137 - struct ipt_helper_info *info = matchinfo; 138 - 139 - info->name[29] = '\0'; 140 - 141 - /* verify size */ 142 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_helper_info))) 143 - return 0; 144 - 145 - return 1; 146 - } 147 - 148 - static struct ipt_match helper_match = { 149 - .name = "helper", 150 - .match = &match, 151 - .checkentry = &check, 152 - .me = THIS_MODULE, 153 - }; 154 - 155 - static int __init init(void) 156 - { 157 - need_ip_conntrack(); 158 - return ipt_register_match(&helper_match); 159 - } 160 - 161 - static void __exit fini(void) 162 - { 163 - ipt_unregister_match(&helper_match); 164 - } 165 - 166 - module_init(init); 167 - module_exit(fini); 168 -
+2 -2
net/ipv4/netfilter/ipt_iprange.c
··· 28 28 const struct net_device *in, 29 29 const struct net_device *out, 30 30 const void *matchinfo, 31 - int offset, int *hotdrop) 31 + int offset, unsigned int protoff, int *hotdrop) 32 32 { 33 33 const struct ipt_iprange_info *info = matchinfo; 34 34 const struct iphdr *iph = skb->nh.iph; ··· 63 63 } 64 64 65 65 static int check(const char *tablename, 66 - const struct ipt_ip *ip, 66 + const void *inf, 67 67 void *matchinfo, 68 68 unsigned int matchsize, 69 69 unsigned int hook_mask)
-64
net/ipv4/netfilter/ipt_length.c
··· 1 - /* Kernel module to match packet length. */ 2 - /* (C) 1999-2001 James Morris <jmorros@intercode.com.au> 3 - * 4 - * This program is free software; you can redistribute it and/or modify 5 - * it under the terms of the GNU General Public License version 2 as 6 - * published by the Free Software Foundation. 7 - */ 8 - 9 - #include <linux/module.h> 10 - #include <linux/skbuff.h> 11 - 12 - #include <linux/netfilter_ipv4/ipt_length.h> 13 - #include <linux/netfilter_ipv4/ip_tables.h> 14 - 15 - MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); 16 - MODULE_DESCRIPTION("IP tables packet length matching module"); 17 - MODULE_LICENSE("GPL"); 18 - 19 - static int 20 - match(const struct sk_buff *skb, 21 - const struct net_device *in, 22 - const struct net_device *out, 23 - const void *matchinfo, 24 - int offset, 25 - int *hotdrop) 26 - { 27 - const struct ipt_length_info *info = matchinfo; 28 - u_int16_t pktlen = ntohs(skb->nh.iph->tot_len); 29 - 30 - return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; 31 - } 32 - 33 - static int 34 - checkentry(const char *tablename, 35 - const struct ipt_ip *ip, 36 - void *matchinfo, 37 - unsigned int matchsize, 38 - unsigned int hook_mask) 39 - { 40 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_length_info))) 41 - return 0; 42 - 43 - return 1; 44 - } 45 - 46 - static struct ipt_match length_match = { 47 - .name = "length", 48 - .match = &match, 49 - .checkentry = &checkentry, 50 - .me = THIS_MODULE, 51 - }; 52 - 53 - static int __init init(void) 54 - { 55 - return ipt_register_match(&length_match); 56 - } 57 - 58 - static void __exit fini(void) 59 - { 60 - ipt_unregister_match(&length_match); 61 - } 62 - 63 - module_init(init); 64 - module_exit(fini);
-157
net/ipv4/netfilter/ipt_limit.c
··· 1 - /* Kernel module to control the rate 2 - * 3 - * 2 September 1999: Changed from the target RATE to the match 4 - * `limit', removed logging. Did I mention that 5 - * Alexey is a fucking genius? 6 - * Rusty Russell (rusty@rustcorp.com.au). */ 7 - 8 - /* (C) 1999 J�r�me de Vivie <devivie@info.enserb.u-bordeaux.fr> 9 - * (C) 1999 Herv� Eychenne <eychenne@info.enserb.u-bordeaux.fr> 10 - * 11 - * This program is free software; you can redistribute it and/or modify 12 - * it under the terms of the GNU General Public License version 2 as 13 - * published by the Free Software Foundation. 14 - */ 15 - 16 - #include <linux/module.h> 17 - #include <linux/skbuff.h> 18 - #include <linux/spinlock.h> 19 - #include <linux/interrupt.h> 20 - 21 - #include <linux/netfilter_ipv4/ip_tables.h> 22 - #include <linux/netfilter_ipv4/ipt_limit.h> 23 - 24 - MODULE_LICENSE("GPL"); 25 - MODULE_AUTHOR("Herve Eychenne <rv@wallfire.org>"); 26 - MODULE_DESCRIPTION("iptables rate limit match"); 27 - 28 - /* The algorithm used is the Simple Token Bucket Filter (TBF) 29 - * see net/sched/sch_tbf.c in the linux source tree 30 - */ 31 - 32 - static DEFINE_SPINLOCK(limit_lock); 33 - 34 - /* Rusty: This is my (non-mathematically-inclined) understanding of 35 - this algorithm. The `average rate' in jiffies becomes your initial 36 - amount of credit `credit' and the most credit you can ever have 37 - `credit_cap'. The `peak rate' becomes the cost of passing the 38 - test, `cost'. 39 - 40 - `prev' tracks the last packet hit: you gain one credit per jiffy. 41 - If you get credit balance more than this, the extra credit is 42 - discarded. Every time the match passes, you lose `cost' credits; 43 - if you don't have that many, the test fails. 44 - 45 - See Alexey's formal explanation in net/sched/sch_tbf.c. 46 - 47 - To get the maxmum range, we multiply by this factor (ie. you get N 48 - credits per jiffy). We want to allow a rate as low as 1 per day 49 - (slowest userspace tool allows), which means 50 - CREDITS_PER_JIFFY*HZ*60*60*24 < 2^32. ie. */ 51 - #define MAX_CPJ (0xFFFFFFFF / (HZ*60*60*24)) 52 - 53 - /* Repeated shift and or gives us all 1s, final shift and add 1 gives 54 - * us the power of 2 below the theoretical max, so GCC simply does a 55 - * shift. */ 56 - #define _POW2_BELOW2(x) ((x)|((x)>>1)) 57 - #define _POW2_BELOW4(x) (_POW2_BELOW2(x)|_POW2_BELOW2((x)>>2)) 58 - #define _POW2_BELOW8(x) (_POW2_BELOW4(x)|_POW2_BELOW4((x)>>4)) 59 - #define _POW2_BELOW16(x) (_POW2_BELOW8(x)|_POW2_BELOW8((x)>>8)) 60 - #define _POW2_BELOW32(x) (_POW2_BELOW16(x)|_POW2_BELOW16((x)>>16)) 61 - #define POW2_BELOW32(x) ((_POW2_BELOW32(x)>>1) + 1) 62 - 63 - #define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ) 64 - 65 - static int 66 - ipt_limit_match(const struct sk_buff *skb, 67 - const struct net_device *in, 68 - const struct net_device *out, 69 - const void *matchinfo, 70 - int offset, 71 - int *hotdrop) 72 - { 73 - struct ipt_rateinfo *r = ((struct ipt_rateinfo *)matchinfo)->master; 74 - unsigned long now = jiffies; 75 - 76 - spin_lock_bh(&limit_lock); 77 - r->credit += (now - xchg(&r->prev, now)) * CREDITS_PER_JIFFY; 78 - if (r->credit > r->credit_cap) 79 - r->credit = r->credit_cap; 80 - 81 - if (r->credit >= r->cost) { 82 - /* We're not limited. */ 83 - r->credit -= r->cost; 84 - spin_unlock_bh(&limit_lock); 85 - return 1; 86 - } 87 - 88 - spin_unlock_bh(&limit_lock); 89 - return 0; 90 - } 91 - 92 - /* Precision saver. */ 93 - static u_int32_t 94 - user2credits(u_int32_t user) 95 - { 96 - /* If multiplying would overflow... */ 97 - if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY)) 98 - /* Divide first. */ 99 - return (user / IPT_LIMIT_SCALE) * HZ * CREDITS_PER_JIFFY; 100 - 101 - return (user * HZ * CREDITS_PER_JIFFY) / IPT_LIMIT_SCALE; 102 - } 103 - 104 - static int 105 - ipt_limit_checkentry(const char *tablename, 106 - const struct ipt_ip *ip, 107 - void *matchinfo, 108 - unsigned int matchsize, 109 - unsigned int hook_mask) 110 - { 111 - struct ipt_rateinfo *r = matchinfo; 112 - 113 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_rateinfo))) 114 - return 0; 115 - 116 - /* Check for overflow. */ 117 - if (r->burst == 0 118 - || user2credits(r->avg * r->burst) < user2credits(r->avg)) { 119 - printk("Overflow in ipt_limit, try lower: %u/%u\n", 120 - r->avg, r->burst); 121 - return 0; 122 - } 123 - 124 - /* User avg in seconds * IPT_LIMIT_SCALE: convert to jiffies * 125 - 128. */ 126 - r->prev = jiffies; 127 - r->credit = user2credits(r->avg * r->burst); /* Credits full. */ 128 - r->credit_cap = user2credits(r->avg * r->burst); /* Credits full. */ 129 - r->cost = user2credits(r->avg); 130 - 131 - /* For SMP, we only want to use one set of counters. */ 132 - r->master = r; 133 - 134 - return 1; 135 - } 136 - 137 - static struct ipt_match ipt_limit_reg = { 138 - .name = "limit", 139 - .match = ipt_limit_match, 140 - .checkentry = ipt_limit_checkentry, 141 - .me = THIS_MODULE, 142 - }; 143 - 144 - static int __init init(void) 145 - { 146 - if (ipt_register_match(&ipt_limit_reg)) 147 - return -EINVAL; 148 - return 0; 149 - } 150 - 151 - static void __exit fini(void) 152 - { 153 - ipt_unregister_match(&ipt_limit_reg); 154 - } 155 - 156 - module_init(init); 157 - module_exit(fini);
-80
net/ipv4/netfilter/ipt_mac.c
··· 1 - /* Kernel module to match MAC address parameters. */ 2 - 3 - /* (C) 1999-2001 Paul `Rusty' Russell 4 - * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License version 2 as 8 - * published by the Free Software Foundation. 9 - */ 10 - 11 - #include <linux/module.h> 12 - #include <linux/skbuff.h> 13 - #include <linux/if_ether.h> 14 - #include <linux/etherdevice.h> 15 - 16 - #include <linux/netfilter_ipv4/ipt_mac.h> 17 - #include <linux/netfilter_ipv4/ip_tables.h> 18 - 19 - MODULE_LICENSE("GPL"); 20 - MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 21 - MODULE_DESCRIPTION("iptables mac matching module"); 22 - 23 - static int 24 - match(const struct sk_buff *skb, 25 - const struct net_device *in, 26 - const struct net_device *out, 27 - const void *matchinfo, 28 - int offset, 29 - int *hotdrop) 30 - { 31 - const struct ipt_mac_info *info = matchinfo; 32 - 33 - /* Is mac pointer valid? */ 34 - return (skb->mac.raw >= skb->head 35 - && (skb->mac.raw + ETH_HLEN) <= skb->data 36 - /* If so, compare... */ 37 - && ((!compare_ether_addr(eth_hdr(skb)->h_source, info->srcaddr)) 38 - ^ info->invert)); 39 - } 40 - 41 - static int 42 - ipt_mac_checkentry(const char *tablename, 43 - const struct ipt_ip *ip, 44 - void *matchinfo, 45 - unsigned int matchsize, 46 - unsigned int hook_mask) 47 - { 48 - /* FORWARD isn't always valid, but it's nice to be able to do --RR */ 49 - if (hook_mask 50 - & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) 51 - | (1 << NF_IP_FORWARD))) { 52 - printk("ipt_mac: only valid for PRE_ROUTING, LOCAL_IN or FORWARD.\n"); 53 - return 0; 54 - } 55 - 56 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_mac_info))) 57 - return 0; 58 - 59 - return 1; 60 - } 61 - 62 - static struct ipt_match mac_match = { 63 - .name = "mac", 64 - .match = &match, 65 - .checkentry = &ipt_mac_checkentry, 66 - .me = THIS_MODULE, 67 - }; 68 - 69 - static int __init init(void) 70 - { 71 - return ipt_register_match(&mac_match); 72 - } 73 - 74 - static void __exit fini(void) 75 - { 76 - ipt_unregister_match(&mac_match); 77 - } 78 - 79 - module_init(init); 80 - module_exit(fini);
-71
net/ipv4/netfilter/ipt_mark.c
··· 1 - /* Kernel module to match NFMARK values. */ 2 - 3 - /* (C) 1999-2001 Marc Boucher <marc@mbsi.ca> 4 - * 5 - * This program is free software; you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License version 2 as 7 - * published by the Free Software Foundation. 8 - */ 9 - 10 - #include <linux/module.h> 11 - #include <linux/skbuff.h> 12 - 13 - #include <linux/netfilter_ipv4/ipt_mark.h> 14 - #include <linux/netfilter_ipv4/ip_tables.h> 15 - 16 - MODULE_LICENSE("GPL"); 17 - MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 18 - MODULE_DESCRIPTION("iptables mark matching module"); 19 - 20 - static int 21 - match(const struct sk_buff *skb, 22 - const struct net_device *in, 23 - const struct net_device *out, 24 - const void *matchinfo, 25 - int offset, 26 - int *hotdrop) 27 - { 28 - const struct ipt_mark_info *info = matchinfo; 29 - 30 - return ((skb->nfmark & info->mask) == info->mark) ^ info->invert; 31 - } 32 - 33 - static int 34 - checkentry(const char *tablename, 35 - const struct ipt_ip *ip, 36 - void *matchinfo, 37 - unsigned int matchsize, 38 - unsigned int hook_mask) 39 - { 40 - struct ipt_mark_info *minfo = (struct ipt_mark_info *) matchinfo; 41 - 42 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_mark_info))) 43 - return 0; 44 - 45 - if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) { 46 - printk(KERN_WARNING "mark: only supports 32bit mark\n"); 47 - return 0; 48 - } 49 - 50 - return 1; 51 - } 52 - 53 - static struct ipt_match mark_match = { 54 - .name = "mark", 55 - .match = &match, 56 - .checkentry = &checkentry, 57 - .me = THIS_MODULE, 58 - }; 59 - 60 - static int __init init(void) 61 - { 62 - return ipt_register_match(&mark_match); 63 - } 64 - 65 - static void __exit fini(void) 66 - { 67 - ipt_unregister_match(&mark_match); 68 - } 69 - 70 - module_init(init); 71 - module_exit(fini);
+6 -4
net/ipv4/netfilter/ipt_multiport.c
··· 97 97 const struct net_device *out, 98 98 const void *matchinfo, 99 99 int offset, 100 + unsigned int protoff, 100 101 int *hotdrop) 101 102 { 102 103 u16 _ports[2], *pptr; ··· 106 105 if (offset) 107 106 return 0; 108 107 109 - pptr = skb_header_pointer(skb, skb->nh.iph->ihl * 4, 108 + pptr = skb_header_pointer(skb, protoff, 110 109 sizeof(_ports), _ports); 111 110 if (pptr == NULL) { 112 111 /* We've been asked to examine this packet, and we ··· 129 128 const struct net_device *out, 130 129 const void *matchinfo, 131 130 int offset, 131 + unsigned int protoff, 132 132 int *hotdrop) 133 133 { 134 134 u16 _ports[2], *pptr; ··· 138 136 if (offset) 139 137 return 0; 140 138 141 - pptr = skb_header_pointer(skb, skb->nh.iph->ihl * 4, 139 + pptr = skb_header_pointer(skb, protoff, 142 140 sizeof(_ports), _ports); 143 141 if (pptr == NULL) { 144 142 /* We've been asked to examine this packet, and we ··· 156 154 /* Called when user tries to insert an entry of this type. */ 157 155 static int 158 156 checkentry(const char *tablename, 159 - const struct ipt_ip *ip, 157 + const void *ip, 160 158 void *matchinfo, 161 159 unsigned int matchsize, 162 160 unsigned int hook_mask) ··· 166 164 167 165 static int 168 166 checkentry_v1(const char *tablename, 169 - const struct ipt_ip *ip, 167 + const void *ip, 170 168 void *matchinfo, 171 169 unsigned int matchsize, 172 170 unsigned int hook_mask)
+2 -1
net/ipv4/netfilter/ipt_owner.c
··· 27 27 const struct net_device *out, 28 28 const void *matchinfo, 29 29 int offset, 30 + unsigned int protoff, 30 31 int *hotdrop) 31 32 { 32 33 const struct ipt_owner_info *info = matchinfo; ··· 52 51 53 52 static int 54 53 checkentry(const char *tablename, 55 - const struct ipt_ip *ip, 54 + const void *ip, 56 55 void *matchinfo, 57 56 unsigned int matchsize, 58 57 unsigned int hook_mask)
-135
net/ipv4/netfilter/ipt_physdev.c
··· 1 - /* Kernel module to match the bridge port in and 2 - * out device for IP packets coming into contact with a bridge. */ 3 - 4 - /* (C) 2001-2003 Bart De Schuymer <bdschuym@pandora.be> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License version 2 as 8 - * published by the Free Software Foundation. 9 - */ 10 - 11 - #include <linux/module.h> 12 - #include <linux/netdevice.h> 13 - #include <linux/skbuff.h> 14 - #include <linux/netfilter_ipv4/ipt_physdev.h> 15 - #include <linux/netfilter_ipv4/ip_tables.h> 16 - #include <linux/netfilter_bridge.h> 17 - #define MATCH 1 18 - #define NOMATCH 0 19 - 20 - MODULE_LICENSE("GPL"); 21 - MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>"); 22 - MODULE_DESCRIPTION("iptables bridge physical device match module"); 23 - 24 - static int 25 - match(const struct sk_buff *skb, 26 - const struct net_device *in, 27 - const struct net_device *out, 28 - const void *matchinfo, 29 - int offset, 30 - int *hotdrop) 31 - { 32 - int i; 33 - static const char nulldevname[IFNAMSIZ]; 34 - const struct ipt_physdev_info *info = matchinfo; 35 - unsigned int ret; 36 - const char *indev, *outdev; 37 - struct nf_bridge_info *nf_bridge; 38 - 39 - /* Not a bridged IP packet or no info available yet: 40 - * LOCAL_OUT/mangle and LOCAL_OUT/nat don't know if 41 - * the destination device will be a bridge. */ 42 - if (!(nf_bridge = skb->nf_bridge)) { 43 - /* Return MATCH if the invert flags of the used options are on */ 44 - if ((info->bitmask & IPT_PHYSDEV_OP_BRIDGED) && 45 - !(info->invert & IPT_PHYSDEV_OP_BRIDGED)) 46 - return NOMATCH; 47 - if ((info->bitmask & IPT_PHYSDEV_OP_ISIN) && 48 - !(info->invert & IPT_PHYSDEV_OP_ISIN)) 49 - return NOMATCH; 50 - if ((info->bitmask & IPT_PHYSDEV_OP_ISOUT) && 51 - !(info->invert & IPT_PHYSDEV_OP_ISOUT)) 52 - return NOMATCH; 53 - if ((info->bitmask & IPT_PHYSDEV_OP_IN) && 54 - !(info->invert & IPT_PHYSDEV_OP_IN)) 55 - return NOMATCH; 56 - if ((info->bitmask & IPT_PHYSDEV_OP_OUT) && 57 - !(info->invert & IPT_PHYSDEV_OP_OUT)) 58 - return NOMATCH; 59 - return MATCH; 60 - } 61 - 62 - /* This only makes sense in the FORWARD and POSTROUTING chains */ 63 - if ((info->bitmask & IPT_PHYSDEV_OP_BRIDGED) && 64 - (!!(nf_bridge->mask & BRNF_BRIDGED) ^ 65 - !(info->invert & IPT_PHYSDEV_OP_BRIDGED))) 66 - return NOMATCH; 67 - 68 - if ((info->bitmask & IPT_PHYSDEV_OP_ISIN && 69 - (!nf_bridge->physindev ^ !!(info->invert & IPT_PHYSDEV_OP_ISIN))) || 70 - (info->bitmask & IPT_PHYSDEV_OP_ISOUT && 71 - (!nf_bridge->physoutdev ^ !!(info->invert & IPT_PHYSDEV_OP_ISOUT)))) 72 - return NOMATCH; 73 - 74 - if (!(info->bitmask & IPT_PHYSDEV_OP_IN)) 75 - goto match_outdev; 76 - indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname; 77 - for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) { 78 - ret |= (((const unsigned int *)indev)[i] 79 - ^ ((const unsigned int *)info->physindev)[i]) 80 - & ((const unsigned int *)info->in_mask)[i]; 81 - } 82 - 83 - if ((ret == 0) ^ !(info->invert & IPT_PHYSDEV_OP_IN)) 84 - return NOMATCH; 85 - 86 - match_outdev: 87 - if (!(info->bitmask & IPT_PHYSDEV_OP_OUT)) 88 - return MATCH; 89 - outdev = nf_bridge->physoutdev ? 90 - nf_bridge->physoutdev->name : nulldevname; 91 - for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) { 92 - ret |= (((const unsigned int *)outdev)[i] 93 - ^ ((const unsigned int *)info->physoutdev)[i]) 94 - & ((const unsigned int *)info->out_mask)[i]; 95 - } 96 - 97 - return (ret != 0) ^ !(info->invert & IPT_PHYSDEV_OP_OUT); 98 - } 99 - 100 - static int 101 - checkentry(const char *tablename, 102 - const struct ipt_ip *ip, 103 - void *matchinfo, 104 - unsigned int matchsize, 105 - unsigned int hook_mask) 106 - { 107 - const struct ipt_physdev_info *info = matchinfo; 108 - 109 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_physdev_info))) 110 - return 0; 111 - if (!(info->bitmask & IPT_PHYSDEV_OP_MASK) || 112 - info->bitmask & ~IPT_PHYSDEV_OP_MASK) 113 - return 0; 114 - return 1; 115 - } 116 - 117 - static struct ipt_match physdev_match = { 118 - .name = "physdev", 119 - .match = &match, 120 - .checkentry = &checkentry, 121 - .me = THIS_MODULE, 122 - }; 123 - 124 - static int __init init(void) 125 - { 126 - return ipt_register_match(&physdev_match); 127 - } 128 - 129 - static void __exit fini(void) 130 - { 131 - ipt_unregister_match(&physdev_match); 132 - } 133 - 134 - module_init(init); 135 - module_exit(fini);
-70
net/ipv4/netfilter/ipt_pkttype.c
··· 1 - /* (C) 1999-2001 Michal Ludvig <michal@logix.cz> 2 - * 3 - * This program is free software; you can redistribute it and/or modify 4 - * it under the terms of the GNU General Public License version 2 as 5 - * published by the Free Software Foundation. 6 - */ 7 - 8 - #include <linux/module.h> 9 - #include <linux/skbuff.h> 10 - #include <linux/if_ether.h> 11 - #include <linux/if_packet.h> 12 - 13 - #include <linux/netfilter_ipv4/ipt_pkttype.h> 14 - #include <linux/netfilter_ipv4/ip_tables.h> 15 - 16 - MODULE_LICENSE("GPL"); 17 - MODULE_AUTHOR("Michal Ludvig <michal@logix.cz>"); 18 - MODULE_DESCRIPTION("IP tables match to match on linklayer packet type"); 19 - 20 - static int match(const struct sk_buff *skb, 21 - const struct net_device *in, 22 - const struct net_device *out, 23 - const void *matchinfo, 24 - int offset, 25 - int *hotdrop) 26 - { 27 - const struct ipt_pkttype_info *info = matchinfo; 28 - 29 - return (skb->pkt_type == info->pkttype) ^ info->invert; 30 - } 31 - 32 - static int checkentry(const char *tablename, 33 - const struct ipt_ip *ip, 34 - void *matchinfo, 35 - unsigned int matchsize, 36 - unsigned int hook_mask) 37 - { 38 - /* 39 - if (hook_mask 40 - & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) 41 - | (1 << NF_IP_FORWARD))) { 42 - printk("ipt_pkttype: only valid for PRE_ROUTING, LOCAL_IN or FORWARD.\n"); 43 - return 0; 44 - } 45 - */ 46 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_pkttype_info))) 47 - return 0; 48 - 49 - return 1; 50 - } 51 - 52 - static struct ipt_match pkttype_match = { 53 - .name = "pkttype", 54 - .match = &match, 55 - .checkentry = &checkentry, 56 - .me = THIS_MODULE, 57 - }; 58 - 59 - static int __init init(void) 60 - { 61 - return ipt_register_match(&pkttype_match); 62 - } 63 - 64 - static void __exit fini(void) 65 - { 66 - ipt_unregister_match(&pkttype_match); 67 - } 68 - 69 - module_init(init); 70 - module_exit(fini);
-76
net/ipv4/netfilter/ipt_realm.c
··· 1 - /* IP tables module for matching the routing realm 2 - * 3 - * $Id: ipt_realm.c,v 1.3 2004/03/05 13:25:40 laforge Exp $ 4 - * 5 - * (C) 2003 by Sampsa Ranta <sampsa@netsonic.fi> 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 - 12 - #include <linux/module.h> 13 - #include <linux/skbuff.h> 14 - #include <linux/netdevice.h> 15 - #include <net/route.h> 16 - 17 - #include <linux/netfilter_ipv4/ipt_realm.h> 18 - #include <linux/netfilter_ipv4/ip_tables.h> 19 - 20 - MODULE_AUTHOR("Sampsa Ranta <sampsa@netsonic.fi>"); 21 - MODULE_LICENSE("GPL"); 22 - MODULE_DESCRIPTION("iptables realm match"); 23 - 24 - static int 25 - match(const struct sk_buff *skb, 26 - const struct net_device *in, 27 - const struct net_device *out, 28 - const void *matchinfo, 29 - int offset, 30 - int *hotdrop) 31 - { 32 - const struct ipt_realm_info *info = matchinfo; 33 - struct dst_entry *dst = skb->dst; 34 - 35 - return (info->id == (dst->tclassid & info->mask)) ^ info->invert; 36 - } 37 - 38 - static int check(const char *tablename, 39 - const struct ipt_ip *ip, 40 - void *matchinfo, 41 - unsigned int matchsize, 42 - unsigned int hook_mask) 43 - { 44 - if (hook_mask 45 - & ~((1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) | 46 - (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_LOCAL_IN))) { 47 - printk("ipt_realm: only valid for POST_ROUTING, LOCAL_OUT, " 48 - "LOCAL_IN or FORWARD.\n"); 49 - return 0; 50 - } 51 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_realm_info))) { 52 - printk("ipt_realm: invalid matchsize.\n"); 53 - return 0; 54 - } 55 - return 1; 56 - } 57 - 58 - static struct ipt_match realm_match = { 59 - .name = "realm", 60 - .match = match, 61 - .checkentry = check, 62 - .me = THIS_MODULE 63 - }; 64 - 65 - static int __init init(void) 66 - { 67 - return ipt_register_match(&realm_match); 68 - } 69 - 70 - static void __exit fini(void) 71 - { 72 - ipt_unregister_match(&realm_match); 73 - } 74 - 75 - module_init(init); 76 - module_exit(fini);
+4 -2
net/ipv4/netfilter/ipt_recent.c
··· 104 104 const struct net_device *out, 105 105 const void *matchinfo, 106 106 int offset, 107 + unsigned int protoff, 107 108 int *hotdrop); 108 109 109 110 /* Function to hash a given address into the hash table of table_size size */ ··· 318 317 skb->nh.iph->daddr = 0; 319 318 /* Clear ttl since we have no way of knowing it */ 320 319 skb->nh.iph->ttl = 0; 321 - match(skb,NULL,NULL,info,0,NULL); 320 + match(skb,NULL,NULL,info,0,0,NULL); 322 321 323 322 kfree(skb->nh.iph); 324 323 out_free_skb: ··· 358 357 const struct net_device *out, 359 358 const void *matchinfo, 360 359 int offset, 360 + unsigned int protoff, 361 361 int *hotdrop) 362 362 { 363 363 int pkt_count, hits_found, ans; ··· 656 654 */ 657 655 static int 658 656 checkentry(const char *tablename, 659 - const struct ipt_ip *ip, 657 + const void *ip, 660 658 void *matchinfo, 661 659 unsigned int matchsize, 662 660 unsigned int hook_mask)
-203
net/ipv4/netfilter/ipt_sctp.c
··· 1 - #include <linux/module.h> 2 - #include <linux/skbuff.h> 3 - #include <net/ip.h> 4 - #include <linux/sctp.h> 5 - 6 - #include <linux/netfilter_ipv4/ip_tables.h> 7 - #include <linux/netfilter_ipv4/ipt_sctp.h> 8 - 9 - #ifdef DEBUG_SCTP 10 - #define duprintf(format, args...) printk(format , ## args) 11 - #else 12 - #define duprintf(format, args...) 13 - #endif 14 - 15 - #define SCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \ 16 - || (!!((invflag) & (option)) ^ (cond))) 17 - 18 - static int 19 - match_flags(const struct ipt_sctp_flag_info *flag_info, 20 - const int flag_count, 21 - u_int8_t chunktype, 22 - u_int8_t chunkflags) 23 - { 24 - int i; 25 - 26 - for (i = 0; i < flag_count; i++) { 27 - if (flag_info[i].chunktype == chunktype) { 28 - return (chunkflags & flag_info[i].flag_mask) == flag_info[i].flag; 29 - } 30 - } 31 - 32 - return 1; 33 - } 34 - 35 - static int 36 - match_packet(const struct sk_buff *skb, 37 - const u_int32_t *chunkmap, 38 - int chunk_match_type, 39 - const struct ipt_sctp_flag_info *flag_info, 40 - const int flag_count, 41 - int *hotdrop) 42 - { 43 - int offset; 44 - u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)]; 45 - sctp_chunkhdr_t _sch, *sch; 46 - 47 - #ifdef DEBUG_SCTP 48 - int i = 0; 49 - #endif 50 - 51 - if (chunk_match_type == SCTP_CHUNK_MATCH_ALL) { 52 - SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap); 53 - } 54 - 55 - offset = skb->nh.iph->ihl * 4 + sizeof (sctp_sctphdr_t); 56 - do { 57 - sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch); 58 - if (sch == NULL) { 59 - duprintf("Dropping invalid SCTP packet.\n"); 60 - *hotdrop = 1; 61 - return 0; 62 - } 63 - 64 - duprintf("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d\tflags: %x\n", 65 - ++i, offset, sch->type, htons(sch->length), sch->flags); 66 - 67 - offset += (htons(sch->length) + 3) & ~3; 68 - 69 - duprintf("skb->len: %d\toffset: %d\n", skb->len, offset); 70 - 71 - if (SCTP_CHUNKMAP_IS_SET(chunkmap, sch->type)) { 72 - switch (chunk_match_type) { 73 - case SCTP_CHUNK_MATCH_ANY: 74 - if (match_flags(flag_info, flag_count, 75 - sch->type, sch->flags)) { 76 - return 1; 77 - } 78 - break; 79 - 80 - case SCTP_CHUNK_MATCH_ALL: 81 - if (match_flags(flag_info, flag_count, 82 - sch->type, sch->flags)) { 83 - SCTP_CHUNKMAP_CLEAR(chunkmapcopy, sch->type); 84 - } 85 - break; 86 - 87 - case SCTP_CHUNK_MATCH_ONLY: 88 - if (!match_flags(flag_info, flag_count, 89 - sch->type, sch->flags)) { 90 - return 0; 91 - } 92 - break; 93 - } 94 - } else { 95 - switch (chunk_match_type) { 96 - case SCTP_CHUNK_MATCH_ONLY: 97 - return 0; 98 - } 99 - } 100 - } while (offset < skb->len); 101 - 102 - switch (chunk_match_type) { 103 - case SCTP_CHUNK_MATCH_ALL: 104 - return SCTP_CHUNKMAP_IS_CLEAR(chunkmap); 105 - case SCTP_CHUNK_MATCH_ANY: 106 - return 0; 107 - case SCTP_CHUNK_MATCH_ONLY: 108 - return 1; 109 - } 110 - 111 - /* This will never be reached, but required to stop compiler whine */ 112 - return 0; 113 - } 114 - 115 - static int 116 - match(const struct sk_buff *skb, 117 - const struct net_device *in, 118 - const struct net_device *out, 119 - const void *matchinfo, 120 - int offset, 121 - int *hotdrop) 122 - { 123 - const struct ipt_sctp_info *info; 124 - sctp_sctphdr_t _sh, *sh; 125 - 126 - info = (const struct ipt_sctp_info *)matchinfo; 127 - 128 - if (offset) { 129 - duprintf("Dropping non-first fragment.. FIXME\n"); 130 - return 0; 131 - } 132 - 133 - sh = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_sh), &_sh); 134 - if (sh == NULL) { 135 - duprintf("Dropping evil TCP offset=0 tinygram.\n"); 136 - *hotdrop = 1; 137 - return 0; 138 - } 139 - duprintf("spt: %d\tdpt: %d\n", ntohs(sh->source), ntohs(sh->dest)); 140 - 141 - return SCCHECK(((ntohs(sh->source) >= info->spts[0]) 142 - && (ntohs(sh->source) <= info->spts[1])), 143 - IPT_SCTP_SRC_PORTS, info->flags, info->invflags) 144 - && SCCHECK(((ntohs(sh->dest) >= info->dpts[0]) 145 - && (ntohs(sh->dest) <= info->dpts[1])), 146 - IPT_SCTP_DEST_PORTS, info->flags, info->invflags) 147 - && SCCHECK(match_packet(skb, info->chunkmap, info->chunk_match_type, 148 - info->flag_info, info->flag_count, 149 - hotdrop), 150 - IPT_SCTP_CHUNK_TYPES, info->flags, info->invflags); 151 - } 152 - 153 - static int 154 - checkentry(const char *tablename, 155 - const struct ipt_ip *ip, 156 - void *matchinfo, 157 - unsigned int matchsize, 158 - unsigned int hook_mask) 159 - { 160 - const struct ipt_sctp_info *info; 161 - 162 - info = (const struct ipt_sctp_info *)matchinfo; 163 - 164 - return ip->proto == IPPROTO_SCTP 165 - && !(ip->invflags & IPT_INV_PROTO) 166 - && matchsize == IPT_ALIGN(sizeof(struct ipt_sctp_info)) 167 - && !(info->flags & ~IPT_SCTP_VALID_FLAGS) 168 - && !(info->invflags & ~IPT_SCTP_VALID_FLAGS) 169 - && !(info->invflags & ~info->flags) 170 - && ((!(info->flags & IPT_SCTP_CHUNK_TYPES)) || 171 - (info->chunk_match_type & 172 - (SCTP_CHUNK_MATCH_ALL 173 - | SCTP_CHUNK_MATCH_ANY 174 - | SCTP_CHUNK_MATCH_ONLY))); 175 - } 176 - 177 - static struct ipt_match sctp_match = 178 - { 179 - .list = { NULL, NULL}, 180 - .name = "sctp", 181 - .match = &match, 182 - .checkentry = &checkentry, 183 - .destroy = NULL, 184 - .me = THIS_MODULE 185 - }; 186 - 187 - static int __init init(void) 188 - { 189 - return ipt_register_match(&sctp_match); 190 - } 191 - 192 - static void __exit fini(void) 193 - { 194 - ipt_unregister_match(&sctp_match); 195 - } 196 - 197 - module_init(init); 198 - module_exit(fini); 199 - 200 - MODULE_LICENSE("GPL"); 201 - MODULE_AUTHOR("Kiran Kumar Immidi"); 202 - MODULE_DESCRIPTION("Match for SCTP protocol packets"); 203 -
-74
net/ipv4/netfilter/ipt_state.c
··· 1 - /* Kernel module to match connection tracking information. */ 2 - 3 - /* (C) 1999-2001 Paul `Rusty' Russell 4 - * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License version 2 as 8 - * published by the Free Software Foundation. 9 - */ 10 - 11 - #include <linux/module.h> 12 - #include <linux/skbuff.h> 13 - #include <net/netfilter/nf_conntrack_compat.h> 14 - #include <linux/netfilter_ipv4/ip_tables.h> 15 - #include <linux/netfilter_ipv4/ipt_state.h> 16 - 17 - MODULE_LICENSE("GPL"); 18 - MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>"); 19 - MODULE_DESCRIPTION("iptables connection tracking state match module"); 20 - 21 - static int 22 - match(const struct sk_buff *skb, 23 - const struct net_device *in, 24 - const struct net_device *out, 25 - const void *matchinfo, 26 - int offset, 27 - int *hotdrop) 28 - { 29 - const struct ipt_state_info *sinfo = matchinfo; 30 - enum ip_conntrack_info ctinfo; 31 - unsigned int statebit; 32 - 33 - if (nf_ct_is_untracked(skb)) 34 - statebit = IPT_STATE_UNTRACKED; 35 - else if (!nf_ct_get_ctinfo(skb, &ctinfo)) 36 - statebit = IPT_STATE_INVALID; 37 - else 38 - statebit = IPT_STATE_BIT(ctinfo); 39 - 40 - return (sinfo->statemask & statebit); 41 - } 42 - 43 - static int check(const char *tablename, 44 - const struct ipt_ip *ip, 45 - void *matchinfo, 46 - unsigned int matchsize, 47 - unsigned int hook_mask) 48 - { 49 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_state_info))) 50 - return 0; 51 - 52 - return 1; 53 - } 54 - 55 - static struct ipt_match state_match = { 56 - .name = "state", 57 - .match = &match, 58 - .checkentry = &check, 59 - .me = THIS_MODULE, 60 - }; 61 - 62 - static int __init init(void) 63 - { 64 - need_ip_conntrack(); 65 - return ipt_register_match(&state_match); 66 - } 67 - 68 - static void __exit fini(void) 69 - { 70 - ipt_unregister_match(&state_match); 71 - } 72 - 73 - module_init(init); 74 - module_exit(fini);
-91
net/ipv4/netfilter/ipt_string.c
··· 1 - /* String matching match for iptables 2 - * 3 - * (C) 2005 Pablo Neira Ayuso <pablo@eurodev.net> 4 - * 5 - * This program is free software; you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License version 2 as 7 - * published by the Free Software Foundation. 8 - */ 9 - 10 - #include <linux/init.h> 11 - #include <linux/module.h> 12 - #include <linux/kernel.h> 13 - #include <linux/skbuff.h> 14 - #include <linux/netfilter_ipv4/ip_tables.h> 15 - #include <linux/netfilter_ipv4/ipt_string.h> 16 - #include <linux/textsearch.h> 17 - 18 - MODULE_AUTHOR("Pablo Neira Ayuso <pablo@eurodev.net>"); 19 - MODULE_DESCRIPTION("IP tables string match module"); 20 - MODULE_LICENSE("GPL"); 21 - 22 - static int match(const struct sk_buff *skb, 23 - const struct net_device *in, 24 - const struct net_device *out, 25 - const void *matchinfo, 26 - int offset, 27 - int *hotdrop) 28 - { 29 - struct ts_state state; 30 - struct ipt_string_info *conf = (struct ipt_string_info *) matchinfo; 31 - 32 - memset(&state, 0, sizeof(struct ts_state)); 33 - 34 - return (skb_find_text((struct sk_buff *)skb, conf->from_offset, 35 - conf->to_offset, conf->config, &state) 36 - != UINT_MAX) && !conf->invert; 37 - } 38 - 39 - #define STRING_TEXT_PRIV(m) ((struct ipt_string_info *) m) 40 - 41 - static int checkentry(const char *tablename, 42 - const struct ipt_ip *ip, 43 - void *matchinfo, 44 - unsigned int matchsize, 45 - unsigned int hook_mask) 46 - { 47 - struct ipt_string_info *conf = matchinfo; 48 - struct ts_config *ts_conf; 49 - 50 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_string_info))) 51 - return 0; 52 - 53 - /* Damn, can't handle this case properly with iptables... */ 54 - if (conf->from_offset > conf->to_offset) 55 - return 0; 56 - 57 - ts_conf = textsearch_prepare(conf->algo, conf->pattern, conf->patlen, 58 - GFP_KERNEL, TS_AUTOLOAD); 59 - if (IS_ERR(ts_conf)) 60 - return 0; 61 - 62 - conf->config = ts_conf; 63 - 64 - return 1; 65 - } 66 - 67 - static void destroy(void *matchinfo, unsigned int matchsize) 68 - { 69 - textsearch_destroy(STRING_TEXT_PRIV(matchinfo)->config); 70 - } 71 - 72 - static struct ipt_match string_match = { 73 - .name = "string", 74 - .match = match, 75 - .checkentry = checkentry, 76 - .destroy = destroy, 77 - .me = THIS_MODULE 78 - }; 79 - 80 - static int __init init(void) 81 - { 82 - return ipt_register_match(&string_match); 83 - } 84 - 85 - static void __exit fini(void) 86 - { 87 - ipt_unregister_match(&string_match); 88 - } 89 - 90 - module_init(init); 91 - module_exit(fini);
-127
net/ipv4/netfilter/ipt_tcpmss.c
··· 1 - /* Kernel module to match TCP MSS values. */ 2 - 3 - /* Copyright (C) 2000 Marc Boucher <marc@mbsi.ca> 4 - * 5 - * This program is free software; you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License version 2 as 7 - * published by the Free Software Foundation. 8 - */ 9 - 10 - #include <linux/module.h> 11 - #include <linux/skbuff.h> 12 - #include <net/tcp.h> 13 - 14 - #include <linux/netfilter_ipv4/ipt_tcpmss.h> 15 - #include <linux/netfilter_ipv4/ip_tables.h> 16 - 17 - #define TH_SYN 0x02 18 - 19 - MODULE_LICENSE("GPL"); 20 - MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 21 - MODULE_DESCRIPTION("iptables TCP MSS match module"); 22 - 23 - /* Returns 1 if the mss option is set and matched by the range, 0 otherwise */ 24 - static inline int 25 - mssoption_match(u_int16_t min, u_int16_t max, 26 - const struct sk_buff *skb, 27 - int invert, 28 - int *hotdrop) 29 - { 30 - struct tcphdr _tcph, *th; 31 - /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ 32 - u8 _opt[15 * 4 - sizeof(_tcph)], *op; 33 - unsigned int i, optlen; 34 - 35 - /* If we don't have the whole header, drop packet. */ 36 - th = skb_header_pointer(skb, skb->nh.iph->ihl * 4, 37 - sizeof(_tcph), &_tcph); 38 - if (th == NULL) 39 - goto dropit; 40 - 41 - /* Malformed. */ 42 - if (th->doff*4 < sizeof(*th)) 43 - goto dropit; 44 - 45 - optlen = th->doff*4 - sizeof(*th); 46 - if (!optlen) 47 - goto out; 48 - 49 - /* Truncated options. */ 50 - op = skb_header_pointer(skb, skb->nh.iph->ihl * 4 + sizeof(*th), 51 - optlen, _opt); 52 - if (op == NULL) 53 - goto dropit; 54 - 55 - for (i = 0; i < optlen; ) { 56 - if (op[i] == TCPOPT_MSS 57 - && (optlen - i) >= TCPOLEN_MSS 58 - && op[i+1] == TCPOLEN_MSS) { 59 - u_int16_t mssval; 60 - 61 - mssval = (op[i+2] << 8) | op[i+3]; 62 - 63 - return (mssval >= min && mssval <= max) ^ invert; 64 - } 65 - if (op[i] < 2) i++; 66 - else i += op[i+1]?:1; 67 - } 68 - out: 69 - return invert; 70 - 71 - dropit: 72 - *hotdrop = 1; 73 - return 0; 74 - } 75 - 76 - static int 77 - match(const struct sk_buff *skb, 78 - const struct net_device *in, 79 - const struct net_device *out, 80 - const void *matchinfo, 81 - int offset, 82 - int *hotdrop) 83 - { 84 - const struct ipt_tcpmss_match_info *info = matchinfo; 85 - 86 - return mssoption_match(info->mss_min, info->mss_max, skb, 87 - info->invert, hotdrop); 88 - } 89 - 90 - static int 91 - checkentry(const char *tablename, 92 - const struct ipt_ip *ip, 93 - void *matchinfo, 94 - unsigned int matchsize, 95 - unsigned int hook_mask) 96 - { 97 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_tcpmss_match_info))) 98 - return 0; 99 - 100 - /* Must specify -p tcp */ 101 - if (ip->proto != IPPROTO_TCP || (ip->invflags & IPT_INV_PROTO)) { 102 - printk("tcpmss: Only works on TCP packets\n"); 103 - return 0; 104 - } 105 - 106 - return 1; 107 - } 108 - 109 - static struct ipt_match tcpmss_match = { 110 - .name = "tcpmss", 111 - .match = &match, 112 - .checkentry = &checkentry, 113 - .me = THIS_MODULE, 114 - }; 115 - 116 - static int __init init(void) 117 - { 118 - return ipt_register_match(&tcpmss_match); 119 - } 120 - 121 - static void __exit fini(void) 122 - { 123 - ipt_unregister_match(&tcpmss_match); 124 - } 125 - 126 - module_init(init); 127 - module_exit(fini);
+2 -1
net/ipv4/netfilter/ipt_tos.c
··· 23 23 const struct net_device *out, 24 24 const void *matchinfo, 25 25 int offset, 26 + unsigned int protoff, 26 27 int *hotdrop) 27 28 { 28 29 const struct ipt_tos_info *info = matchinfo; ··· 33 32 34 33 static int 35 34 checkentry(const char *tablename, 36 - const struct ipt_ip *ip, 35 + const void *ip, 37 36 void *matchinfo, 38 37 unsigned int matchsize, 39 38 unsigned int hook_mask)
+2 -2
net/ipv4/netfilter/ipt_ttl.c
··· 21 21 22 22 static int match(const struct sk_buff *skb, const struct net_device *in, 23 23 const struct net_device *out, const void *matchinfo, 24 - int offset, int *hotdrop) 24 + int offset, unsigned int protoff, int *hotdrop) 25 25 { 26 26 const struct ipt_ttl_info *info = matchinfo; 27 27 ··· 47 47 return 0; 48 48 } 49 49 50 - static int checkentry(const char *tablename, const struct ipt_ip *ip, 50 + static int checkentry(const char *tablename, const void *ip, 51 51 void *matchinfo, unsigned int matchsize, 52 52 unsigned int hook_mask) 53 53 {
+2 -1
net/ipv4/netfilter/iptable_filter.c
··· 78 78 .name = "filter", 79 79 .valid_hooks = FILTER_VALID_HOOKS, 80 80 .lock = RW_LOCK_UNLOCKED, 81 - .me = THIS_MODULE 81 + .me = THIS_MODULE, 82 + .af = AF_INET, 82 83 }; 83 84 84 85 /* The work comes in here from netfilter.c. */
+1
net/ipv4/netfilter/iptable_mangle.c
··· 109 109 .valid_hooks = MANGLE_VALID_HOOKS, 110 110 .lock = RW_LOCK_UNLOCKED, 111 111 .me = THIS_MODULE, 112 + .af = AF_INET, 112 113 }; 113 114 114 115 /* The work comes in here from netfilter.c. */
+2 -1
net/ipv4/netfilter/iptable_raw.c
··· 83 83 .name = "raw", 84 84 .valid_hooks = RAW_VALID_HOOKS, 85 85 .lock = RW_LOCK_UNLOCKED, 86 - .me = THIS_MODULE 86 + .me = THIS_MODULE, 87 + .af = AF_INET, 87 88 }; 88 89 89 90 /* The work comes in here from netfilter.c. */
+1 -6
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
··· 575 575 576 576 static int __init init(void) 577 577 { 578 - need_nf_conntrack(); 578 + need_conntrack(); 579 579 return init_or_cleanup(1); 580 580 } 581 581 ··· 587 587 module_init(init); 588 588 module_exit(fini); 589 589 590 - void need_ip_conntrack(void) 591 - { 592 - } 593 - 594 - EXPORT_SYMBOL(need_ip_conntrack); 595 590 EXPORT_SYMBOL(nf_ct_ipv4_gather_frags);
+1 -71
net/ipv6/netfilter/Kconfig
··· 41 41 42 42 config IP6_NF_IPTABLES 43 43 tristate "IP6 tables support (required for filtering/masq/NAT)" 44 + depends on NETFILTER_XTABLES 44 45 help 45 46 ip6tables is a general, extensible packet identification framework. 46 47 Currently only the packet filtering and packet mangling subsystem ··· 51 50 To compile it as a module, choose M here. If unsure, say N. 52 51 53 52 # The simple matches. 54 - config IP6_NF_MATCH_LIMIT 55 - tristate "limit match support" 56 - depends on IP6_NF_IPTABLES 57 - help 58 - limit matching allows you to control the rate at which a rule can be 59 - matched: mainly useful in combination with the LOG target ("LOG 60 - target support", below) and to avoid some Denial of Service attacks. 61 - 62 - To compile it as a module, choose M here. If unsure, say N. 63 - 64 - config IP6_NF_MATCH_MAC 65 - tristate "MAC address match support" 66 - depends on IP6_NF_IPTABLES 67 - help 68 - mac matching allows you to match packets based on the source 69 - Ethernet address of the packet. 70 - 71 - To compile it as a module, choose M here. If unsure, say N. 72 - 73 53 config IP6_NF_MATCH_RT 74 54 tristate "Routing header match support" 75 55 depends on IP6_NF_IPTABLES ··· 106 124 107 125 To compile it as a module, choose M here. If unsure, say N. 108 126 109 - config IP6_NF_MATCH_MARK 110 - tristate "netfilter MARK match support" 111 - depends on IP6_NF_IPTABLES 112 - help 113 - Netfilter mark matching allows you to match packets based on the 114 - `nfmark' value in the packet. This can be set by the MARK target 115 - (see below). 116 - 117 - To compile it as a module, choose M here. If unsure, say N. 118 - 119 127 config IP6_NF_MATCH_IPV6HEADER 120 128 tristate "IPv6 Extension Headers Match" 121 129 depends on IP6_NF_IPTABLES ··· 123 151 124 152 To compile it as a module, choose M here. If unsure, say N. 125 153 126 - config IP6_NF_MATCH_LENGTH 127 - tristate "Packet Length match support" 128 - depends on IP6_NF_IPTABLES 129 - help 130 - This option allows you to match the length of a packet against a 131 - specific value or range of values. 132 - 133 - To compile it as a module, choose M here. If unsure, say N. 134 - 135 154 config IP6_NF_MATCH_EUI64 136 155 tristate "EUI64 address check" 137 156 depends on IP6_NF_IPTABLES ··· 130 167 This module performs checking on the IPv6 source address 131 168 Compares the last 64 bits with the EUI64 (delivered 132 169 from the MAC address) address 133 - 134 - To compile it as a module, choose M here. If unsure, say N. 135 - 136 - config IP6_NF_MATCH_PHYSDEV 137 - tristate "Physdev match support" 138 - depends on IP6_NF_IPTABLES && BRIDGE_NETFILTER 139 - help 140 - Physdev packet matching matches against the physical bridge ports 141 - the IP packet arrived on or will leave by. 142 170 143 171 To compile it as a module, choose M here. If unsure, say N. 144 172 ··· 173 219 174 220 To compile it as a module, choose M here. If unsure, say N. 175 221 176 - config IP6_NF_TARGET_NFQUEUE 177 - tristate "NFQUEUE Target Support" 178 - depends on IP6_NF_IPTABLES 179 - help 180 - This Target replaced the old obsolete QUEUE target. 181 - 182 - As opposed to QUEUE, it supports 65535 different queues, 183 - not just one. 184 - 185 - To compile it as a module, choose M here. If unsure, say N. 186 - 187 222 config IP6_NF_MANGLE 188 223 tristate "Packet mangling" 189 224 depends on IP6_NF_IPTABLES ··· 180 237 This option adds a `mangle' table to iptables: see the man page for 181 238 iptables(8). This table is used for various packet alterations 182 239 which can effect how the packet is routed. 183 - 184 - To compile it as a module, choose M here. If unsure, say N. 185 - 186 - config IP6_NF_TARGET_MARK 187 - tristate "MARK target support" 188 - depends on IP6_NF_MANGLE 189 - help 190 - This option adds a `MARK' target, which allows you to create rules 191 - in the `mangle' table which alter the netfilter mark (nfmark) field 192 - associated with the packet packet prior to routing. This can change 193 - the routing method (see `Use netfilter MARK value as routing 194 - key') and can also be used by other subsystems to change their 195 - behavior. 196 240 197 241 To compile it as a module, choose M here. If unsure, say N. 198 242
-6
net/ipv6/netfilter/Makefile
··· 4 4 5 5 # Link order matters here. 6 6 obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o 7 - obj-$(CONFIG_IP6_NF_MATCH_LIMIT) += ip6t_limit.o 8 - obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.o 9 7 obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o 10 - obj-$(CONFIG_IP6_NF_MATCH_MAC) += ip6t_mac.o 11 8 obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o 12 9 obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o 13 10 obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o ··· 14 17 obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o 15 18 obj-$(CONFIG_IP6_NF_MATCH_MULTIPORT) += ip6t_multiport.o 16 19 obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o 17 - obj-$(CONFIG_IP6_NF_MATCH_PHYSDEV) += ip6t_physdev.o 18 20 obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o 19 21 obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o 20 - obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o 21 22 obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o 22 - obj-$(CONFIG_IP6_NF_TARGET_NFQUEUE) += ip6t_NFQUEUE.o 23 23 obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o 24 24 obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o 25 25 obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
+101 -727
net/ipv6/netfilter/ip6_tables.c
··· 13 13 * a table 14 14 * 06 Jun 2002 Andras Kis-Szabo <kisza@sch.bme.hu> 15 15 * - new extension header parser code 16 + * 15 Oct 2005 Harald Welte <laforge@netfilter.org> 17 + * - Unification of {ip,ip6}_tables into x_tables 18 + * - Removed tcp and udp code, since it's not ipv6 specific 16 19 */ 17 20 18 21 #include <linux/capability.h> ··· 26 23 #include <linux/vmalloc.h> 27 24 #include <linux/netdevice.h> 28 25 #include <linux/module.h> 29 - #include <linux/tcp.h> 30 - #include <linux/udp.h> 31 26 #include <linux/icmpv6.h> 32 27 #include <net/ipv6.h> 33 28 #include <asm/uaccess.h> ··· 34 33 #include <linux/cpumask.h> 35 34 36 35 #include <linux/netfilter_ipv6/ip6_tables.h> 36 + #include <linux/netfilter/x_tables.h> 37 37 38 38 MODULE_LICENSE("GPL"); 39 39 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); ··· 69 67 #else 70 68 #define IP_NF_ASSERT(x) 71 69 #endif 72 - #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) 73 70 74 - static DECLARE_MUTEX(ip6t_mutex); 75 71 76 - /* Must have mutex */ 77 - #define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ip6t_mutex) != 0) 78 - #define ASSERT_WRITE_LOCK(x) IP_NF_ASSERT(down_trylock(&ip6t_mutex) != 0) 79 72 #include <linux/netfilter_ipv4/listhelp.h> 80 73 81 74 #if 0 ··· 87 90 the counters or update the rules. 88 91 89 92 Hence the start of any table is given by get_table() below. */ 90 - 91 - /* The table itself */ 92 - struct ip6t_table_info 93 - { 94 - /* Size per table */ 95 - unsigned int size; 96 - /* Number of entries: FIXME. --RR */ 97 - unsigned int number; 98 - /* Initial number of entries. Needed for module usage count */ 99 - unsigned int initial_entries; 100 - 101 - /* Entry points and underflows */ 102 - unsigned int hook_entry[NF_IP6_NUMHOOKS]; 103 - unsigned int underflow[NF_IP6_NUMHOOKS]; 104 - 105 - /* ip6t_entry tables: one per CPU */ 106 - void *entries[NR_CPUS]; 107 - }; 108 - 109 - static LIST_HEAD(ip6t_target); 110 - static LIST_HEAD(ip6t_match); 111 - static LIST_HEAD(ip6t_tables); 112 - #define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0) 113 - #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) 114 93 115 94 #if 0 116 95 #define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0) ··· 270 297 unsigned int hook, 271 298 const struct net_device *in, 272 299 const struct net_device *out, 273 - struct ip6t_table *table, 300 + struct xt_table *table, 274 301 void *userdata) 275 302 { 276 303 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); ··· 282 309 const char *indev, *outdev; 283 310 void *table_base; 284 311 struct ip6t_entry *e, *back; 312 + struct xt_table_info *private; 285 313 286 314 /* Initialization */ 287 315 indev = in ? in->name : nulldevname; ··· 295 321 * match it. */ 296 322 297 323 read_lock_bh(&table->lock); 324 + private = table->private; 298 325 IP_NF_ASSERT(table->valid_hooks & (1 << hook)); 299 - table_base = (void *)table->private->entries[smp_processor_id()]; 300 - e = get_entry(table_base, table->private->hook_entry[hook]); 326 + table_base = (void *)private->entries[smp_processor_id()]; 327 + e = get_entry(table_base, private->hook_entry[hook]); 301 328 302 329 #ifdef CONFIG_NETFILTER_DEBUG 303 330 /* Check noone else using our table */ ··· 314 339 #endif 315 340 316 341 /* For return from builtin chain */ 317 - back = get_entry(table_base, table->private->underflow[hook]); 342 + back = get_entry(table_base, private->underflow[hook]); 318 343 319 344 do { 320 345 IP_NF_ASSERT(e); ··· 414 439 #endif 415 440 } 416 441 417 - /* 418 - * These are weird, but module loading must not be done with mutex 419 - * held (since they will register), and we have to have a single 420 - * function to use try_then_request_module(). 421 - */ 422 - 423 - /* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ 424 - static inline struct ip6t_table *find_table_lock(const char *name) 425 - { 426 - struct ip6t_table *t; 427 - 428 - if (down_interruptible(&ip6t_mutex) != 0) 429 - return ERR_PTR(-EINTR); 430 - 431 - list_for_each_entry(t, &ip6t_tables, list) 432 - if (strcmp(t->name, name) == 0 && try_module_get(t->me)) 433 - return t; 434 - up(&ip6t_mutex); 435 - return NULL; 436 - } 437 - 438 - /* Find match, grabs ref. Returns ERR_PTR() on error. */ 439 - static inline struct ip6t_match *find_match(const char *name, u8 revision) 440 - { 441 - struct ip6t_match *m; 442 - int err = 0; 443 - 444 - if (down_interruptible(&ip6t_mutex) != 0) 445 - return ERR_PTR(-EINTR); 446 - 447 - list_for_each_entry(m, &ip6t_match, list) { 448 - if (strcmp(m->name, name) == 0) { 449 - if (m->revision == revision) { 450 - if (try_module_get(m->me)) { 451 - up(&ip6t_mutex); 452 - return m; 453 - } 454 - } else 455 - err = -EPROTOTYPE; /* Found something. */ 456 - } 457 - } 458 - up(&ip6t_mutex); 459 - return ERR_PTR(err); 460 - } 461 - 462 - /* Find target, grabs ref. Returns ERR_PTR() on error. */ 463 - static inline struct ip6t_target *find_target(const char *name, u8 revision) 464 - { 465 - struct ip6t_target *t; 466 - int err = 0; 467 - 468 - if (down_interruptible(&ip6t_mutex) != 0) 469 - return ERR_PTR(-EINTR); 470 - 471 - list_for_each_entry(t, &ip6t_target, list) { 472 - if (strcmp(t->name, name) == 0) { 473 - if (t->revision == revision) { 474 - if (try_module_get(t->me)) { 475 - up(&ip6t_mutex); 476 - return t; 477 - } 478 - } else 479 - err = -EPROTOTYPE; /* Found something. */ 480 - } 481 - } 482 - up(&ip6t_mutex); 483 - return ERR_PTR(err); 484 - } 485 - 486 - struct ip6t_target *ip6t_find_target(const char *name, u8 revision) 487 - { 488 - struct ip6t_target *target; 489 - 490 - target = try_then_request_module(find_target(name, revision), 491 - "ip6t_%s", name); 492 - if (IS_ERR(target) || !target) 493 - return NULL; 494 - return target; 495 - } 496 - 497 - static int match_revfn(const char *name, u8 revision, int *bestp) 498 - { 499 - struct ip6t_match *m; 500 - int have_rev = 0; 501 - 502 - list_for_each_entry(m, &ip6t_match, list) { 503 - if (strcmp(m->name, name) == 0) { 504 - if (m->revision > *bestp) 505 - *bestp = m->revision; 506 - if (m->revision == revision) 507 - have_rev = 1; 508 - } 509 - } 510 - return have_rev; 511 - } 512 - 513 - static int target_revfn(const char *name, u8 revision, int *bestp) 514 - { 515 - struct ip6t_target *t; 516 - int have_rev = 0; 517 - 518 - list_for_each_entry(t, &ip6t_target, list) { 519 - if (strcmp(t->name, name) == 0) { 520 - if (t->revision > *bestp) 521 - *bestp = t->revision; 522 - if (t->revision == revision) 523 - have_rev = 1; 524 - } 525 - } 526 - return have_rev; 527 - } 528 - 529 - /* Returns true or fals (if no such extension at all) */ 530 - static inline int find_revision(const char *name, u8 revision, 531 - int (*revfn)(const char *, u8, int *), 532 - int *err) 533 - { 534 - int have_rev, best = -1; 535 - 536 - if (down_interruptible(&ip6t_mutex) != 0) { 537 - *err = -EINTR; 538 - return 1; 539 - } 540 - have_rev = revfn(name, revision, &best); 541 - up(&ip6t_mutex); 542 - 543 - /* Nothing at all? Return 0 to try loading module. */ 544 - if (best == -1) { 545 - *err = -ENOENT; 546 - return 0; 547 - } 548 - 549 - *err = best; 550 - if (!have_rev) 551 - *err = -EPROTONOSUPPORT; 552 - return 1; 553 - } 554 - 555 - 556 442 /* All zeroes == unconditional rule. */ 557 443 static inline int 558 444 unconditional(const struct ip6t_ip6 *ipv6) ··· 430 594 /* Figures out from what hook each rule can be called: returns 0 if 431 595 there are loops. Puts hook bitmask in comefrom. */ 432 596 static int 433 - mark_source_chains(struct ip6t_table_info *newinfo, 597 + mark_source_chains(struct xt_table_info *newinfo, 434 598 unsigned int valid_hooks, void *entry0) 435 599 { 436 600 unsigned int hook; ··· 576 740 { 577 741 struct ip6t_match *match; 578 742 579 - match = try_then_request_module(find_match(m->u.user.name, 580 - m->u.user.revision), 743 + match = try_then_request_module(xt_find_match(AF_INET6, m->u.user.name, 744 + m->u.user.revision), 581 745 "ip6t_%s", m->u.user.name); 582 746 if (IS_ERR(match) || !match) { 583 - duprintf("check_match: `%s' not found\n", m->u.user.name); 747 + duprintf("check_match: `%s' not found\n", m->u.user.name); 584 748 return match ? PTR_ERR(match) : -ENOENT; 585 749 } 586 750 m->u.kernel.match = match; ··· 621 785 goto cleanup_matches; 622 786 623 787 t = ip6t_get_target(e); 624 - target = try_then_request_module(find_target(t->u.user.name, 625 - t->u.user.revision), 788 + target = try_then_request_module(xt_find_target(AF_INET6, 789 + t->u.user.name, 790 + t->u.user.revision), 626 791 "ip6t_%s", t->u.user.name); 627 792 if (IS_ERR(target) || !target) { 628 793 duprintf("check_entry: `%s' not found\n", t->u.user.name); ··· 659 822 660 823 static inline int 661 824 check_entry_size_and_hooks(struct ip6t_entry *e, 662 - struct ip6t_table_info *newinfo, 825 + struct xt_table_info *newinfo, 663 826 unsigned char *base, 664 827 unsigned char *limit, 665 828 const unsigned int *hook_entries, ··· 693 856 < 0 (not IP6T_RETURN). --RR */ 694 857 695 858 /* Clear counters and comefrom */ 696 - e->counters = ((struct ip6t_counters) { 0, 0 }); 859 + e->counters = ((struct xt_counters) { 0, 0 }); 697 860 e->comefrom = 0; 698 861 699 862 (*i)++; ··· 723 886 static int 724 887 translate_table(const char *name, 725 888 unsigned int valid_hooks, 726 - struct ip6t_table_info *newinfo, 889 + struct xt_table_info *newinfo, 727 890 void *entry0, 728 891 unsigned int size, 729 892 unsigned int number, ··· 800 963 return ret; 801 964 } 802 965 803 - static struct ip6t_table_info * 804 - replace_table(struct ip6t_table *table, 805 - unsigned int num_counters, 806 - struct ip6t_table_info *newinfo, 807 - int *error) 808 - { 809 - struct ip6t_table_info *oldinfo; 810 - 811 - #ifdef CONFIG_NETFILTER_DEBUG 812 - { 813 - int cpu; 814 - 815 - for_each_cpu(cpu) { 816 - struct ip6t_entry *table_base = newinfo->entries[cpu]; 817 - if (table_base) 818 - table_base->comefrom = 0xdead57ac; 819 - } 820 - } 821 - #endif 822 - 823 - /* Do the substitution. */ 824 - write_lock_bh(&table->lock); 825 - /* Check inside lock: is the old number correct? */ 826 - if (num_counters != table->private->number) { 827 - duprintf("num_counters != table->private->number (%u/%u)\n", 828 - num_counters, table->private->number); 829 - write_unlock_bh(&table->lock); 830 - *error = -EAGAIN; 831 - return NULL; 832 - } 833 - oldinfo = table->private; 834 - table->private = newinfo; 835 - newinfo->initial_entries = oldinfo->initial_entries; 836 - write_unlock_bh(&table->lock); 837 - 838 - return oldinfo; 839 - } 840 - 841 966 /* Gets counters. */ 842 967 static inline int 843 968 add_entry_to_counter(const struct ip6t_entry *e, 844 - struct ip6t_counters total[], 969 + struct xt_counters total[], 845 970 unsigned int *i) 846 971 { 847 972 ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); ··· 824 1025 } 825 1026 826 1027 static void 827 - get_counters(const struct ip6t_table_info *t, 828 - struct ip6t_counters counters[]) 1028 + get_counters(const struct xt_table_info *t, 1029 + struct xt_counters counters[]) 829 1030 { 830 1031 unsigned int cpu; 831 1032 unsigned int i; ··· 859 1060 860 1061 static int 861 1062 copy_entries_to_user(unsigned int total_size, 862 - struct ip6t_table *table, 1063 + struct xt_table *table, 863 1064 void __user *userptr) 864 1065 { 865 1066 unsigned int off, num, countersize; 866 1067 struct ip6t_entry *e; 867 - struct ip6t_counters *counters; 1068 + struct xt_counters *counters; 1069 + struct xt_table_info *private = table->private; 868 1070 int ret = 0; 869 1071 void *loc_cpu_entry; 870 1072 871 1073 /* We need atomic snapshot of counters: rest doesn't change 872 1074 (other than comefrom, which userspace doesn't care 873 1075 about). */ 874 - countersize = sizeof(struct ip6t_counters) * table->private->number; 1076 + countersize = sizeof(struct xt_counters) * private->number; 875 1077 counters = vmalloc(countersize); 876 1078 877 1079 if (counters == NULL) ··· 880 1080 881 1081 /* First, sum counters... */ 882 1082 write_lock_bh(&table->lock); 883 - get_counters(table->private, counters); 1083 + get_counters(private, counters); 884 1084 write_unlock_bh(&table->lock); 885 1085 886 1086 /* choose the copy that is on ourc node/cpu */ 887 - loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; 1087 + loc_cpu_entry = private->entries[raw_smp_processor_id()]; 888 1088 if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { 889 1089 ret = -EFAULT; 890 1090 goto free_counters; ··· 943 1143 struct ip6t_get_entries __user *uptr) 944 1144 { 945 1145 int ret; 946 - struct ip6t_table *t; 1146 + struct xt_table *t; 947 1147 948 - t = find_table_lock(entries->name); 1148 + t = xt_find_table_lock(AF_INET6, entries->name); 949 1149 if (t && !IS_ERR(t)) { 950 - duprintf("t->private->number = %u\n", 951 - t->private->number); 952 - if (entries->size == t->private->size) 953 - ret = copy_entries_to_user(t->private->size, 1150 + struct xt_table_info *private = t->private; 1151 + duprintf("t->private->number = %u\n", private->number); 1152 + if (entries->size == private->size) 1153 + ret = copy_entries_to_user(private->size, 954 1154 t, uptr->entrytable); 955 1155 else { 956 1156 duprintf("get_entries: I've got %u not %u!\n", 957 - t->private->size, 958 - entries->size); 1157 + private->size, entries->size); 959 1158 ret = -EINVAL; 960 1159 } 961 1160 module_put(t->me); 962 - up(&ip6t_mutex); 1161 + xt_table_unlock(t); 963 1162 } else 964 1163 ret = t ? PTR_ERR(t) : -ENOENT; 965 1164 966 1165 return ret; 967 - } 968 - 969 - static void free_table_info(struct ip6t_table_info *info) 970 - { 971 - int cpu; 972 - for_each_cpu(cpu) { 973 - if (info->size <= PAGE_SIZE) 974 - kfree(info->entries[cpu]); 975 - else 976 - vfree(info->entries[cpu]); 977 - } 978 - kfree(info); 979 - } 980 - 981 - static struct ip6t_table_info *alloc_table_info(unsigned int size) 982 - { 983 - struct ip6t_table_info *newinfo; 984 - int cpu; 985 - 986 - newinfo = kzalloc(sizeof(struct ip6t_table_info), GFP_KERNEL); 987 - if (!newinfo) 988 - return NULL; 989 - 990 - newinfo->size = size; 991 - 992 - for_each_cpu(cpu) { 993 - if (size <= PAGE_SIZE) 994 - newinfo->entries[cpu] = kmalloc_node(size, 995 - GFP_KERNEL, 996 - cpu_to_node(cpu)); 997 - else 998 - newinfo->entries[cpu] = vmalloc_node(size, 999 - cpu_to_node(cpu)); 1000 - if (newinfo->entries[cpu] == NULL) { 1001 - free_table_info(newinfo); 1002 - return NULL; 1003 - } 1004 - } 1005 - 1006 - return newinfo; 1007 1166 } 1008 1167 1009 1168 static int ··· 970 1211 { 971 1212 int ret; 972 1213 struct ip6t_replace tmp; 973 - struct ip6t_table *t; 974 - struct ip6t_table_info *newinfo, *oldinfo; 975 - struct ip6t_counters *counters; 1214 + struct xt_table *t; 1215 + struct xt_table_info *newinfo, *oldinfo; 1216 + struct xt_counters *counters; 976 1217 void *loc_cpu_entry, *loc_cpu_old_entry; 977 1218 978 1219 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 979 1220 return -EFAULT; 980 1221 981 - /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */ 982 - if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages) 983 - return -ENOMEM; 984 - 985 - newinfo = alloc_table_info(tmp.size); 1222 + newinfo = xt_alloc_table_info(tmp.size); 986 1223 if (!newinfo) 987 1224 return -ENOMEM; 988 1225 ··· 990 1235 goto free_newinfo; 991 1236 } 992 1237 993 - counters = vmalloc(tmp.num_counters * sizeof(struct ip6t_counters)); 1238 + counters = vmalloc(tmp.num_counters * sizeof(struct xt_counters)); 994 1239 if (!counters) { 995 1240 ret = -ENOMEM; 996 1241 goto free_newinfo; ··· 1004 1249 1005 1250 duprintf("ip_tables: Translated table\n"); 1006 1251 1007 - t = try_then_request_module(find_table_lock(tmp.name), 1252 + t = try_then_request_module(xt_find_table_lock(AF_INET6, tmp.name), 1008 1253 "ip6table_%s", tmp.name); 1009 1254 if (!t || IS_ERR(t)) { 1010 1255 ret = t ? PTR_ERR(t) : -ENOENT; ··· 1019 1264 goto put_module; 1020 1265 } 1021 1266 1022 - oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret); 1267 + oldinfo = xt_replace_table(t, tmp.num_counters, newinfo, &ret); 1023 1268 if (!oldinfo) 1024 1269 goto put_module; 1025 1270 ··· 1038 1283 /* Decrease module usage counts and free resource */ 1039 1284 loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; 1040 1285 IP6T_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); 1041 - free_table_info(oldinfo); 1286 + xt_free_table_info(oldinfo); 1042 1287 if (copy_to_user(tmp.counters, counters, 1043 - sizeof(struct ip6t_counters) * tmp.num_counters) != 0) 1288 + sizeof(struct xt_counters) * tmp.num_counters) != 0) 1044 1289 ret = -EFAULT; 1045 1290 vfree(counters); 1046 - up(&ip6t_mutex); 1291 + xt_table_unlock(t); 1047 1292 return ret; 1048 1293 1049 1294 put_module: 1050 1295 module_put(t->me); 1051 - up(&ip6t_mutex); 1296 + xt_table_unlock(t); 1052 1297 free_newinfo_counters_untrans: 1053 1298 IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL); 1054 1299 free_newinfo_counters: 1055 1300 vfree(counters); 1056 1301 free_newinfo: 1057 - free_table_info(newinfo); 1302 + xt_free_table_info(newinfo); 1058 1303 return ret; 1059 1304 } 1060 1305 ··· 1062 1307 * and everything is OK. */ 1063 1308 static inline int 1064 1309 add_counter_to_entry(struct ip6t_entry *e, 1065 - const struct ip6t_counters addme[], 1310 + const struct xt_counters addme[], 1066 1311 unsigned int *i) 1067 1312 { 1068 1313 #if 0 ··· 1084 1329 do_add_counters(void __user *user, unsigned int len) 1085 1330 { 1086 1331 unsigned int i; 1087 - struct ip6t_counters_info tmp, *paddc; 1088 - struct ip6t_table *t; 1332 + struct xt_counters_info tmp, *paddc; 1333 + struct xt_table_info *private; 1334 + struct xt_table *t; 1089 1335 int ret = 0; 1090 1336 void *loc_cpu_entry; 1091 1337 1092 1338 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 1093 1339 return -EFAULT; 1094 1340 1095 - if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct ip6t_counters)) 1341 + if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct xt_counters)) 1096 1342 return -EINVAL; 1097 1343 1098 1344 paddc = vmalloc(len); ··· 1105 1349 goto free; 1106 1350 } 1107 1351 1108 - t = find_table_lock(tmp.name); 1352 + t = xt_find_table_lock(AF_INET6, tmp.name); 1109 1353 if (!t || IS_ERR(t)) { 1110 1354 ret = t ? PTR_ERR(t) : -ENOENT; 1111 1355 goto free; 1112 1356 } 1113 1357 1114 1358 write_lock_bh(&t->lock); 1115 - if (t->private->number != paddc->num_counters) { 1359 + private = t->private; 1360 + if (private->number != paddc->num_counters) { 1116 1361 ret = -EINVAL; 1117 1362 goto unlock_up_free; 1118 1363 } 1119 1364 1120 1365 i = 0; 1121 1366 /* Choose the copy that is on our node */ 1122 - loc_cpu_entry = t->private->entries[smp_processor_id()]; 1367 + loc_cpu_entry = private->entries[smp_processor_id()]; 1123 1368 IP6T_ENTRY_ITERATE(loc_cpu_entry, 1124 - t->private->size, 1369 + private->size, 1125 1370 add_counter_to_entry, 1126 1371 paddc->counters, 1127 1372 &i); 1128 1373 unlock_up_free: 1129 1374 write_unlock_bh(&t->lock); 1130 - up(&ip6t_mutex); 1375 + xt_table_unlock(t); 1131 1376 module_put(t->me); 1132 1377 free: 1133 1378 vfree(paddc); ··· 1172 1415 switch (cmd) { 1173 1416 case IP6T_SO_GET_INFO: { 1174 1417 char name[IP6T_TABLE_MAXNAMELEN]; 1175 - struct ip6t_table *t; 1418 + struct xt_table *t; 1176 1419 1177 1420 if (*len != sizeof(struct ip6t_getinfo)) { 1178 1421 duprintf("length %u != %u\n", *len, ··· 1187 1430 } 1188 1431 name[IP6T_TABLE_MAXNAMELEN-1] = '\0'; 1189 1432 1190 - t = try_then_request_module(find_table_lock(name), 1433 + t = try_then_request_module(xt_find_table_lock(AF_INET6, name), 1191 1434 "ip6table_%s", name); 1192 1435 if (t && !IS_ERR(t)) { 1193 1436 struct ip6t_getinfo info; 1437 + struct xt_table_info *private = t->private; 1194 1438 1195 1439 info.valid_hooks = t->valid_hooks; 1196 - memcpy(info.hook_entry, t->private->hook_entry, 1440 + memcpy(info.hook_entry, private->hook_entry, 1197 1441 sizeof(info.hook_entry)); 1198 - memcpy(info.underflow, t->private->underflow, 1442 + memcpy(info.underflow, private->underflow, 1199 1443 sizeof(info.underflow)); 1200 - info.num_entries = t->private->number; 1201 - info.size = t->private->size; 1444 + info.num_entries = private->number; 1445 + info.size = private->size; 1202 1446 memcpy(info.name, name, sizeof(info.name)); 1203 1447 1204 1448 if (copy_to_user(user, &info, *len) != 0) 1205 1449 ret = -EFAULT; 1206 1450 else 1207 1451 ret = 0; 1208 - up(&ip6t_mutex); 1452 + xt_table_unlock(t); 1209 1453 module_put(t->me); 1210 1454 } else 1211 1455 ret = t ? PTR_ERR(t) : -ENOENT; ··· 1233 1475 case IP6T_SO_GET_REVISION_MATCH: 1234 1476 case IP6T_SO_GET_REVISION_TARGET: { 1235 1477 struct ip6t_get_revision rev; 1236 - int (*revfn)(const char *, u8, int *); 1478 + int target; 1237 1479 1238 1480 if (*len != sizeof(rev)) { 1239 1481 ret = -EINVAL; ··· 1245 1487 } 1246 1488 1247 1489 if (cmd == IP6T_SO_GET_REVISION_TARGET) 1248 - revfn = target_revfn; 1490 + target = 1; 1249 1491 else 1250 - revfn = match_revfn; 1492 + target = 0; 1251 1493 1252 - try_then_request_module(find_revision(rev.name, rev.revision, 1253 - revfn, &ret), 1494 + try_then_request_module(xt_find_revision(AF_INET6, rev.name, 1495 + rev.revision, 1496 + target, &ret), 1254 1497 "ip6t_%s", rev.name); 1255 1498 break; 1256 1499 } ··· 1264 1505 return ret; 1265 1506 } 1266 1507 1267 - /* Registration hooks for targets. */ 1268 - int 1269 - ip6t_register_target(struct ip6t_target *target) 1270 - { 1271 - int ret; 1272 - 1273 - ret = down_interruptible(&ip6t_mutex); 1274 - if (ret != 0) 1275 - return ret; 1276 - list_add(&target->list, &ip6t_target); 1277 - up(&ip6t_mutex); 1278 - return ret; 1279 - } 1280 - 1281 - void 1282 - ip6t_unregister_target(struct ip6t_target *target) 1283 - { 1284 - down(&ip6t_mutex); 1285 - LIST_DELETE(&ip6t_target, target); 1286 - up(&ip6t_mutex); 1287 - } 1288 - 1289 - int 1290 - ip6t_register_match(struct ip6t_match *match) 1291 - { 1292 - int ret; 1293 - 1294 - ret = down_interruptible(&ip6t_mutex); 1295 - if (ret != 0) 1296 - return ret; 1297 - 1298 - list_add(&match->list, &ip6t_match); 1299 - up(&ip6t_mutex); 1300 - 1301 - return ret; 1302 - } 1303 - 1304 - void 1305 - ip6t_unregister_match(struct ip6t_match *match) 1306 - { 1307 - down(&ip6t_mutex); 1308 - LIST_DELETE(&ip6t_match, match); 1309 - up(&ip6t_mutex); 1310 - } 1311 - 1312 - int ip6t_register_table(struct ip6t_table *table, 1508 + int ip6t_register_table(struct xt_table *table, 1313 1509 const struct ip6t_replace *repl) 1314 1510 { 1315 1511 int ret; 1316 - struct ip6t_table_info *newinfo; 1317 - static struct ip6t_table_info bootstrap 1512 + struct xt_table_info *newinfo; 1513 + static struct xt_table_info bootstrap 1318 1514 = { 0, 0, 0, { 0 }, { 0 }, { } }; 1319 1515 void *loc_cpu_entry; 1320 1516 1321 - newinfo = alloc_table_info(repl->size); 1517 + newinfo = xt_alloc_table_info(repl->size); 1322 1518 if (!newinfo) 1323 1519 return -ENOMEM; 1324 1520 ··· 1287 1573 repl->hook_entry, 1288 1574 repl->underflow); 1289 1575 if (ret != 0) { 1290 - free_table_info(newinfo); 1576 + xt_free_table_info(newinfo); 1291 1577 return ret; 1292 1578 } 1293 1579 1294 - ret = down_interruptible(&ip6t_mutex); 1295 - if (ret != 0) { 1296 - free_table_info(newinfo); 1580 + if (xt_register_table(table, &bootstrap, newinfo) != 0) { 1581 + xt_free_table_info(newinfo); 1297 1582 return ret; 1298 1583 } 1299 1584 1300 - /* Don't autoload: we'd eat our tail... */ 1301 - if (list_named_find(&ip6t_tables, table->name)) { 1302 - ret = -EEXIST; 1303 - goto free_unlock; 1304 - } 1305 - 1306 - /* Simplifies replace_table code. */ 1307 - table->private = &bootstrap; 1308 - if (!replace_table(table, 0, newinfo, &ret)) 1309 - goto free_unlock; 1310 - 1311 - duprintf("table->private->number = %u\n", 1312 - table->private->number); 1313 - 1314 - /* save number of initial entries */ 1315 - table->private->initial_entries = table->private->number; 1316 - 1317 - rwlock_init(&table->lock); 1318 - list_prepend(&ip6t_tables, table); 1319 - 1320 - unlock: 1321 - up(&ip6t_mutex); 1322 - return ret; 1323 - 1324 - free_unlock: 1325 - free_table_info(newinfo); 1326 - goto unlock; 1585 + return 0; 1327 1586 } 1328 1587 1329 - void ip6t_unregister_table(struct ip6t_table *table) 1588 + void ip6t_unregister_table(struct xt_table *table) 1330 1589 { 1590 + struct xt_table_info *private; 1331 1591 void *loc_cpu_entry; 1332 1592 1333 - down(&ip6t_mutex); 1334 - LIST_DELETE(&ip6t_tables, table); 1335 - up(&ip6t_mutex); 1593 + private = xt_unregister_table(table); 1336 1594 1337 1595 /* Decrease module usage counts and free resources */ 1338 - loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; 1339 - IP6T_ENTRY_ITERATE(loc_cpu_entry, table->private->size, 1340 - cleanup_entry, NULL); 1341 - free_table_info(table->private); 1342 - } 1343 - 1344 - /* Returns 1 if the port is matched by the range, 0 otherwise */ 1345 - static inline int 1346 - port_match(u_int16_t min, u_int16_t max, u_int16_t port, int invert) 1347 - { 1348 - int ret; 1349 - 1350 - ret = (port >= min && port <= max) ^ invert; 1351 - return ret; 1352 - } 1353 - 1354 - static int 1355 - tcp_find_option(u_int8_t option, 1356 - const struct sk_buff *skb, 1357 - unsigned int tcpoff, 1358 - unsigned int optlen, 1359 - int invert, 1360 - int *hotdrop) 1361 - { 1362 - /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ 1363 - u_int8_t _opt[60 - sizeof(struct tcphdr)], *op; 1364 - unsigned int i; 1365 - 1366 - duprintf("tcp_match: finding option\n"); 1367 - if (!optlen) 1368 - return invert; 1369 - /* If we don't have the whole header, drop packet. */ 1370 - op = skb_header_pointer(skb, tcpoff + sizeof(struct tcphdr), optlen, 1371 - _opt); 1372 - if (op == NULL) { 1373 - *hotdrop = 1; 1374 - return 0; 1375 - } 1376 - 1377 - for (i = 0; i < optlen; ) { 1378 - if (op[i] == option) return !invert; 1379 - if (op[i] < 2) i++; 1380 - else i += op[i+1]?:1; 1381 - } 1382 - 1383 - return invert; 1384 - } 1385 - 1386 - static int 1387 - tcp_match(const struct sk_buff *skb, 1388 - const struct net_device *in, 1389 - const struct net_device *out, 1390 - const void *matchinfo, 1391 - int offset, 1392 - unsigned int protoff, 1393 - int *hotdrop) 1394 - { 1395 - struct tcphdr _tcph, *th; 1396 - const struct ip6t_tcp *tcpinfo = matchinfo; 1397 - 1398 - if (offset) { 1399 - /* To quote Alan: 1400 - 1401 - Don't allow a fragment of TCP 8 bytes in. Nobody normal 1402 - causes this. Its a cracker trying to break in by doing a 1403 - flag overwrite to pass the direction checks. 1404 - */ 1405 - if (offset == 1) { 1406 - duprintf("Dropping evil TCP offset=1 frag.\n"); 1407 - *hotdrop = 1; 1408 - } 1409 - /* Must not be a fragment. */ 1410 - return 0; 1411 - } 1412 - 1413 - #define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg)) 1414 - 1415 - th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph); 1416 - if (th == NULL) { 1417 - /* We've been asked to examine this packet, and we 1418 - can't. Hence, no choice but to drop. */ 1419 - duprintf("Dropping evil TCP offset=0 tinygram.\n"); 1420 - *hotdrop = 1; 1421 - return 0; 1422 - } 1423 - 1424 - if (!port_match(tcpinfo->spts[0], tcpinfo->spts[1], 1425 - ntohs(th->source), 1426 - !!(tcpinfo->invflags & IP6T_TCP_INV_SRCPT))) 1427 - return 0; 1428 - if (!port_match(tcpinfo->dpts[0], tcpinfo->dpts[1], 1429 - ntohs(th->dest), 1430 - !!(tcpinfo->invflags & IP6T_TCP_INV_DSTPT))) 1431 - return 0; 1432 - if (!FWINVTCP((((unsigned char *)th)[13] & tcpinfo->flg_mask) 1433 - == tcpinfo->flg_cmp, 1434 - IP6T_TCP_INV_FLAGS)) 1435 - return 0; 1436 - if (tcpinfo->option) { 1437 - if (th->doff * 4 < sizeof(_tcph)) { 1438 - *hotdrop = 1; 1439 - return 0; 1440 - } 1441 - if (!tcp_find_option(tcpinfo->option, skb, protoff, 1442 - th->doff*4 - sizeof(*th), 1443 - tcpinfo->invflags & IP6T_TCP_INV_OPTION, 1444 - hotdrop)) 1445 - return 0; 1446 - } 1447 - return 1; 1448 - } 1449 - 1450 - /* Called when user tries to insert an entry of this type. */ 1451 - static int 1452 - tcp_checkentry(const char *tablename, 1453 - const struct ip6t_ip6 *ipv6, 1454 - void *matchinfo, 1455 - unsigned int matchsize, 1456 - unsigned int hook_mask) 1457 - { 1458 - const struct ip6t_tcp *tcpinfo = matchinfo; 1459 - 1460 - /* Must specify proto == TCP, and no unknown invflags */ 1461 - return ipv6->proto == IPPROTO_TCP 1462 - && !(ipv6->invflags & IP6T_INV_PROTO) 1463 - && matchsize == IP6T_ALIGN(sizeof(struct ip6t_tcp)) 1464 - && !(tcpinfo->invflags & ~IP6T_TCP_INV_MASK); 1465 - } 1466 - 1467 - static int 1468 - udp_match(const struct sk_buff *skb, 1469 - const struct net_device *in, 1470 - const struct net_device *out, 1471 - const void *matchinfo, 1472 - int offset, 1473 - unsigned int protoff, 1474 - int *hotdrop) 1475 - { 1476 - struct udphdr _udph, *uh; 1477 - const struct ip6t_udp *udpinfo = matchinfo; 1478 - 1479 - /* Must not be a fragment. */ 1480 - if (offset) 1481 - return 0; 1482 - 1483 - uh = skb_header_pointer(skb, protoff, sizeof(_udph), &_udph); 1484 - if (uh == NULL) { 1485 - /* We've been asked to examine this packet, and we 1486 - can't. Hence, no choice but to drop. */ 1487 - duprintf("Dropping evil UDP tinygram.\n"); 1488 - *hotdrop = 1; 1489 - return 0; 1490 - } 1491 - 1492 - return port_match(udpinfo->spts[0], udpinfo->spts[1], 1493 - ntohs(uh->source), 1494 - !!(udpinfo->invflags & IP6T_UDP_INV_SRCPT)) 1495 - && port_match(udpinfo->dpts[0], udpinfo->dpts[1], 1496 - ntohs(uh->dest), 1497 - !!(udpinfo->invflags & IP6T_UDP_INV_DSTPT)); 1498 - } 1499 - 1500 - /* Called when user tries to insert an entry of this type. */ 1501 - static int 1502 - udp_checkentry(const char *tablename, 1503 - const struct ip6t_ip6 *ipv6, 1504 - void *matchinfo, 1505 - unsigned int matchinfosize, 1506 - unsigned int hook_mask) 1507 - { 1508 - const struct ip6t_udp *udpinfo = matchinfo; 1509 - 1510 - /* Must specify proto == UDP, and no unknown invflags */ 1511 - if (ipv6->proto != IPPROTO_UDP || (ipv6->invflags & IP6T_INV_PROTO)) { 1512 - duprintf("ip6t_udp: Protocol %u != %u\n", ipv6->proto, 1513 - IPPROTO_UDP); 1514 - return 0; 1515 - } 1516 - if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_udp))) { 1517 - duprintf("ip6t_udp: matchsize %u != %u\n", 1518 - matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_udp))); 1519 - return 0; 1520 - } 1521 - if (udpinfo->invflags & ~IP6T_UDP_INV_MASK) { 1522 - duprintf("ip6t_udp: unknown flags %X\n", 1523 - udpinfo->invflags); 1524 - return 0; 1525 - } 1526 - 1527 - return 1; 1596 + loc_cpu_entry = private->entries[raw_smp_processor_id()]; 1597 + IP6T_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, NULL); 1598 + xt_free_table_info(private); 1528 1599 } 1529 1600 1530 1601 /* Returns 1 if the type and code is matched by the range, 0 otherwise */ ··· 1357 1858 /* Called when user tries to insert an entry of this type. */ 1358 1859 static int 1359 1860 icmp6_checkentry(const char *tablename, 1360 - const struct ip6t_ip6 *ipv6, 1861 + const void *entry, 1361 1862 void *matchinfo, 1362 1863 unsigned int matchsize, 1363 1864 unsigned int hook_mask) 1364 1865 { 1866 + const struct ip6t_ip6 *ipv6 = entry; 1365 1867 const struct ip6t_icmp *icmpinfo = matchinfo; 1366 1868 1367 1869 /* Must specify proto == ICMP, and no unknown invflags */ ··· 1392 1892 .get = do_ip6t_get_ctl, 1393 1893 }; 1394 1894 1395 - static struct ip6t_match tcp_matchstruct = { 1396 - .name = "tcp", 1397 - .match = &tcp_match, 1398 - .checkentry = &tcp_checkentry, 1399 - }; 1400 - 1401 - static struct ip6t_match udp_matchstruct = { 1402 - .name = "udp", 1403 - .match = &udp_match, 1404 - .checkentry = &udp_checkentry, 1405 - }; 1406 - 1407 1895 static struct ip6t_match icmp6_matchstruct = { 1408 1896 .name = "icmp6", 1409 1897 .match = &icmp6_match, 1410 1898 .checkentry = &icmp6_checkentry, 1411 1899 }; 1412 1900 1413 - #ifdef CONFIG_PROC_FS 1414 - static inline int print_name(const char *i, 1415 - off_t start_offset, char *buffer, int length, 1416 - off_t *pos, unsigned int *count) 1417 - { 1418 - if ((*count)++ >= start_offset) { 1419 - unsigned int namelen; 1420 - 1421 - namelen = sprintf(buffer + *pos, "%s\n", 1422 - i + sizeof(struct list_head)); 1423 - if (*pos + namelen > length) { 1424 - /* Stop iterating */ 1425 - return 1; 1426 - } 1427 - *pos += namelen; 1428 - } 1429 - return 0; 1430 - } 1431 - 1432 - static inline int print_target(const struct ip6t_target *t, 1433 - off_t start_offset, char *buffer, int length, 1434 - off_t *pos, unsigned int *count) 1435 - { 1436 - if (t == &ip6t_standard_target || t == &ip6t_error_target) 1437 - return 0; 1438 - return print_name((char *)t, start_offset, buffer, length, pos, count); 1439 - } 1440 - 1441 - static int ip6t_get_tables(char *buffer, char **start, off_t offset, int length) 1442 - { 1443 - off_t pos = 0; 1444 - unsigned int count = 0; 1445 - 1446 - if (down_interruptible(&ip6t_mutex) != 0) 1447 - return 0; 1448 - 1449 - LIST_FIND(&ip6t_tables, print_name, char *, 1450 - offset, buffer, length, &pos, &count); 1451 - 1452 - up(&ip6t_mutex); 1453 - 1454 - /* `start' hack - see fs/proc/generic.c line ~105 */ 1455 - *start=(char *)((unsigned long)count-offset); 1456 - return pos; 1457 - } 1458 - 1459 - static int ip6t_get_targets(char *buffer, char **start, off_t offset, int length) 1460 - { 1461 - off_t pos = 0; 1462 - unsigned int count = 0; 1463 - 1464 - if (down_interruptible(&ip6t_mutex) != 0) 1465 - return 0; 1466 - 1467 - LIST_FIND(&ip6t_target, print_target, struct ip6t_target *, 1468 - offset, buffer, length, &pos, &count); 1469 - 1470 - up(&ip6t_mutex); 1471 - 1472 - *start = (char *)((unsigned long)count - offset); 1473 - return pos; 1474 - } 1475 - 1476 - static int ip6t_get_matches(char *buffer, char **start, off_t offset, int length) 1477 - { 1478 - off_t pos = 0; 1479 - unsigned int count = 0; 1480 - 1481 - if (down_interruptible(&ip6t_mutex) != 0) 1482 - return 0; 1483 - 1484 - LIST_FIND(&ip6t_match, print_name, char *, 1485 - offset, buffer, length, &pos, &count); 1486 - 1487 - up(&ip6t_mutex); 1488 - 1489 - *start = (char *)((unsigned long)count - offset); 1490 - return pos; 1491 - } 1492 - 1493 - static const struct { char *name; get_info_t *get_info; } ip6t_proc_entry[] = 1494 - { { "ip6_tables_names", ip6t_get_tables }, 1495 - { "ip6_tables_targets", ip6t_get_targets }, 1496 - { "ip6_tables_matches", ip6t_get_matches }, 1497 - { NULL, NULL} }; 1498 - #endif /*CONFIG_PROC_FS*/ 1499 - 1500 1901 static int __init init(void) 1501 1902 { 1502 1903 int ret; 1503 1904 1905 + xt_proto_init(AF_INET6); 1906 + 1504 1907 /* Noone else will be downing sem now, so we won't sleep */ 1505 - down(&ip6t_mutex); 1506 - list_append(&ip6t_target, &ip6t_standard_target); 1507 - list_append(&ip6t_target, &ip6t_error_target); 1508 - list_append(&ip6t_match, &tcp_matchstruct); 1509 - list_append(&ip6t_match, &udp_matchstruct); 1510 - list_append(&ip6t_match, &icmp6_matchstruct); 1511 - up(&ip6t_mutex); 1908 + xt_register_target(AF_INET6, &ip6t_standard_target); 1909 + xt_register_target(AF_INET6, &ip6t_error_target); 1910 + xt_register_match(AF_INET6, &icmp6_matchstruct); 1512 1911 1513 1912 /* Register setsockopt */ 1514 1913 ret = nf_register_sockopt(&ip6t_sockopts); 1515 1914 if (ret < 0) { 1516 1915 duprintf("Unable to register sockopts.\n"); 1916 + xt_proto_fini(AF_INET6); 1517 1917 return ret; 1518 1918 } 1519 1919 1520 - #ifdef CONFIG_PROC_FS 1521 - { 1522 - struct proc_dir_entry *proc; 1523 - int i; 1524 - 1525 - for (i = 0; ip6t_proc_entry[i].name; i++) { 1526 - proc = proc_net_create(ip6t_proc_entry[i].name, 0, 1527 - ip6t_proc_entry[i].get_info); 1528 - if (!proc) { 1529 - while (--i >= 0) 1530 - proc_net_remove(ip6t_proc_entry[i].name); 1531 - nf_unregister_sockopt(&ip6t_sockopts); 1532 - return -ENOMEM; 1533 - } 1534 - proc->owner = THIS_MODULE; 1535 - } 1536 - } 1537 - #endif 1538 - 1539 - printk("ip6_tables: (C) 2000-2002 Netfilter core team\n"); 1920 + printk("ip6_tables: (C) 2000-2006 Netfilter Core Team\n"); 1540 1921 return 0; 1541 1922 } 1542 1923 1543 1924 static void __exit fini(void) 1544 1925 { 1545 1926 nf_unregister_sockopt(&ip6t_sockopts); 1546 - #ifdef CONFIG_PROC_FS 1547 - { 1548 - int i; 1549 - for (i = 0; ip6t_proc_entry[i].name; i++) 1550 - proc_net_remove(ip6t_proc_entry[i].name); 1551 - } 1552 - #endif 1927 + xt_unregister_match(AF_INET6, &icmp6_matchstruct); 1928 + xt_unregister_target(AF_INET6, &ip6t_error_target); 1929 + xt_unregister_target(AF_INET6, &ip6t_standard_target); 1930 + xt_proto_fini(AF_INET6); 1553 1931 } 1554 1932 1555 1933 /* ··· 1506 2128 EXPORT_SYMBOL(ip6t_register_table); 1507 2129 EXPORT_SYMBOL(ip6t_unregister_table); 1508 2130 EXPORT_SYMBOL(ip6t_do_table); 1509 - EXPORT_SYMBOL(ip6t_register_match); 1510 - EXPORT_SYMBOL(ip6t_unregister_match); 1511 - EXPORT_SYMBOL(ip6t_register_target); 1512 - EXPORT_SYMBOL(ip6t_unregister_target); 1513 2131 EXPORT_SYMBOL(ip6t_ext_hdr); 1514 2132 EXPORT_SYMBOL(ipv6_find_hdr); 1515 2133 EXPORT_SYMBOL(ip6_masked_addrcmp);
+1 -1
net/ipv6/netfilter/ip6t_HL.c
··· 62 62 } 63 63 64 64 static int ip6t_hl_checkentry(const char *tablename, 65 - const struct ip6t_entry *e, 65 + const void *entry, 66 66 void *targinfo, 67 67 unsigned int targinfosize, 68 68 unsigned int hook_mask)
+1 -1
net/ipv6/netfilter/ip6t_LOG.c
··· 444 444 445 445 446 446 static int ip6t_log_checkentry(const char *tablename, 447 - const struct ip6t_entry *e, 447 + const void *entry, 448 448 void *targinfo, 449 449 unsigned int targinfosize, 450 450 unsigned int hook_mask)
-81
net/ipv6/netfilter/ip6t_MARK.c
··· 1 - /* This is a module which is used for setting the NFMARK field of an skb. */ 2 - 3 - /* (C) 1999-2001 Marc Boucher <marc@mbsi.ca> 4 - * 5 - * This program is free software; you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License version 2 as 7 - * published by the Free Software Foundation. 8 - */ 9 - 10 - #include <linux/module.h> 11 - #include <linux/skbuff.h> 12 - #include <linux/ip.h> 13 - #include <net/checksum.h> 14 - 15 - #include <linux/netfilter_ipv6/ip6_tables.h> 16 - #include <linux/netfilter_ipv6/ip6t_MARK.h> 17 - 18 - MODULE_LICENSE("GPL"); 19 - MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 20 - 21 - static unsigned int 22 - target(struct sk_buff **pskb, 23 - const struct net_device *in, 24 - const struct net_device *out, 25 - unsigned int hooknum, 26 - const void *targinfo, 27 - void *userinfo) 28 - { 29 - const struct ip6t_mark_target_info *markinfo = targinfo; 30 - 31 - if((*pskb)->nfmark != markinfo->mark) 32 - (*pskb)->nfmark = markinfo->mark; 33 - 34 - return IP6T_CONTINUE; 35 - } 36 - 37 - static int 38 - checkentry(const char *tablename, 39 - const struct ip6t_entry *e, 40 - void *targinfo, 41 - unsigned int targinfosize, 42 - unsigned int hook_mask) 43 - { 44 - if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_mark_target_info))) { 45 - printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n", 46 - targinfosize, 47 - IP6T_ALIGN(sizeof(struct ip6t_mark_target_info))); 48 - return 0; 49 - } 50 - 51 - if (strcmp(tablename, "mangle") != 0) { 52 - printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename); 53 - return 0; 54 - } 55 - 56 - return 1; 57 - } 58 - 59 - static struct ip6t_target ip6t_mark_reg = { 60 - .name = "MARK", 61 - .target = target, 62 - .checkentry = checkentry, 63 - .me = THIS_MODULE 64 - }; 65 - 66 - static int __init init(void) 67 - { 68 - printk(KERN_DEBUG "registering ipv6 mark target\n"); 69 - if (ip6t_register_target(&ip6t_mark_reg)) 70 - return -EINVAL; 71 - 72 - return 0; 73 - } 74 - 75 - static void __exit fini(void) 76 - { 77 - ip6t_unregister_target(&ip6t_mark_reg); 78 - } 79 - 80 - module_init(init); 81 - module_exit(fini);
-70
net/ipv6/netfilter/ip6t_NFQUEUE.c
··· 1 - /* ip6tables module for using new netfilter netlink queue 2 - * 3 - * (C) 2005 by Harald Welte <laforge@netfilter.org> 4 - * 5 - * This program is free software; you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License version 2 as 7 - * published by the Free Software Foundation. 8 - * 9 - */ 10 - 11 - #include <linux/module.h> 12 - #include <linux/skbuff.h> 13 - 14 - #include <linux/netfilter.h> 15 - #include <linux/netfilter_ipv6/ip6_tables.h> 16 - #include <linux/netfilter_ipv4/ipt_NFQUEUE.h> 17 - 18 - MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 19 - MODULE_DESCRIPTION("ip6tables NFQUEUE target"); 20 - MODULE_LICENSE("GPL"); 21 - 22 - static unsigned int 23 - target(struct sk_buff **pskb, 24 - const struct net_device *in, 25 - const struct net_device *out, 26 - unsigned int hooknum, 27 - const void *targinfo, 28 - void *userinfo) 29 - { 30 - const struct ipt_NFQ_info *tinfo = targinfo; 31 - 32 - return NF_QUEUE_NR(tinfo->queuenum); 33 - } 34 - 35 - static int 36 - checkentry(const char *tablename, 37 - const struct ip6t_entry *e, 38 - void *targinfo, 39 - unsigned int targinfosize, 40 - unsigned int hook_mask) 41 - { 42 - if (targinfosize != IP6T_ALIGN(sizeof(struct ipt_NFQ_info))) { 43 - printk(KERN_WARNING "NFQUEUE: targinfosize %u != %Zu\n", 44 - targinfosize, 45 - IP6T_ALIGN(sizeof(struct ipt_NFQ_info))); 46 - return 0; 47 - } 48 - 49 - return 1; 50 - } 51 - 52 - static struct ip6t_target ipt_NFQ_reg = { 53 - .name = "NFQUEUE", 54 - .target = target, 55 - .checkentry = checkentry, 56 - .me = THIS_MODULE, 57 - }; 58 - 59 - static int __init init(void) 60 - { 61 - return ip6t_register_target(&ipt_NFQ_reg); 62 - } 63 - 64 - static void __exit fini(void) 65 - { 66 - ip6t_unregister_target(&ipt_NFQ_reg); 67 - } 68 - 69 - module_init(init); 70 - module_exit(fini);
+2 -1
net/ipv6/netfilter/ip6t_REJECT.c
··· 218 218 } 219 219 220 220 static int check(const char *tablename, 221 - const struct ip6t_entry *e, 221 + const void *entry, 222 222 void *targinfo, 223 223 unsigned int targinfosize, 224 224 unsigned int hook_mask) 225 225 { 226 226 const struct ip6t_reject_info *rejinfo = targinfo; 227 + const struct ip6t_entry *e = entry; 227 228 228 229 if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) { 229 230 DEBUGP("ip6t_REJECT: targinfosize %u != 0\n", targinfosize);
+1 -1
net/ipv6/netfilter/ip6t_ah.c
··· 98 98 /* Called when user tries to insert an entry of this type. */ 99 99 static int 100 100 checkentry(const char *tablename, 101 - const struct ip6t_ip6 *ip, 101 + const void *entry, 102 102 void *matchinfo, 103 103 unsigned int matchinfosize, 104 104 unsigned int hook_mask)
+1 -1
net/ipv6/netfilter/ip6t_dst.c
··· 178 178 /* Called when user tries to insert an entry of this type. */ 179 179 static int 180 180 checkentry(const char *tablename, 181 - const struct ip6t_ip6 *ip, 181 + const void *info, 182 182 void *matchinfo, 183 183 unsigned int matchinfosize, 184 184 unsigned int hook_mask)
+1 -1
net/ipv6/netfilter/ip6t_esp.c
··· 76 76 /* Called when user tries to insert an entry of this type. */ 77 77 static int 78 78 checkentry(const char *tablename, 79 - const struct ip6t_ip6 *ip, 79 + const void *ip, 80 80 void *matchinfo, 81 81 unsigned int matchinfosize, 82 82 unsigned int hook_mask)
+1 -1
net/ipv6/netfilter/ip6t_eui64.c
··· 62 62 63 63 static int 64 64 ip6t_eui64_checkentry(const char *tablename, 65 - const struct ip6t_ip6 *ip, 65 + const void *ip, 66 66 void *matchinfo, 67 67 unsigned int matchsize, 68 68 unsigned int hook_mask)
+1 -1
net/ipv6/netfilter/ip6t_frag.c
··· 115 115 /* Called when user tries to insert an entry of this type. */ 116 116 static int 117 117 checkentry(const char *tablename, 118 - const struct ip6t_ip6 *ip, 118 + const void *ip, 119 119 void *matchinfo, 120 120 unsigned int matchinfosize, 121 121 unsigned int hook_mask)
+1 -1
net/ipv6/netfilter/ip6t_hbh.c
··· 178 178 /* Called when user tries to insert an entry of this type. */ 179 179 static int 180 180 checkentry(const char *tablename, 181 - const struct ip6t_ip6 *ip, 181 + const void *entry, 182 182 void *matchinfo, 183 183 unsigned int matchinfosize, 184 184 unsigned int hook_mask)
+1 -1
net/ipv6/netfilter/ip6t_hl.c
··· 48 48 return 0; 49 49 } 50 50 51 - static int checkentry(const char *tablename, const struct ip6t_ip6 *ip, 51 + static int checkentry(const char *tablename, const void *entry, 52 52 void *matchinfo, unsigned int matchsize, 53 53 unsigned int hook_mask) 54 54 {
+1 -1
net/ipv6/netfilter/ip6t_ipv6header.c
··· 124 124 125 125 static int 126 126 ipv6header_checkentry(const char *tablename, 127 - const struct ip6t_ip6 *ip, 127 + const void *ip, 128 128 void *matchinfo, 129 129 unsigned int matchsize, 130 130 unsigned int hook_mask)
-66
net/ipv6/netfilter/ip6t_length.c
··· 1 - /* Length Match - IPv6 Port */ 2 - 3 - /* (C) 1999-2001 James Morris <jmorros@intercode.com.au> 4 - * 5 - * This program is free software; you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License version 2 as 7 - * published by the Free Software Foundation. 8 - */ 9 - 10 - 11 - #include <linux/module.h> 12 - #include <linux/skbuff.h> 13 - #include <linux/netfilter_ipv6/ip6t_length.h> 14 - #include <linux/netfilter_ipv6/ip6_tables.h> 15 - 16 - MODULE_LICENSE("GPL"); 17 - MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); 18 - MODULE_DESCRIPTION("IPv6 packet length match"); 19 - 20 - static int 21 - match(const struct sk_buff *skb, 22 - const struct net_device *in, 23 - const struct net_device *out, 24 - const void *matchinfo, 25 - int offset, 26 - unsigned int protoff, 27 - int *hotdrop) 28 - { 29 - const struct ip6t_length_info *info = matchinfo; 30 - u_int16_t pktlen = ntohs(skb->nh.ipv6h->payload_len) + sizeof(struct ipv6hdr); 31 - 32 - return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; 33 - } 34 - 35 - static int 36 - checkentry(const char *tablename, 37 - const struct ip6t_ip6 *ip, 38 - void *matchinfo, 39 - unsigned int matchsize, 40 - unsigned int hook_mask) 41 - { 42 - if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_length_info))) 43 - return 0; 44 - 45 - return 1; 46 - } 47 - 48 - static struct ip6t_match length_match = { 49 - .name = "length", 50 - .match = &match, 51 - .checkentry = &checkentry, 52 - .me = THIS_MODULE, 53 - }; 54 - 55 - static int __init init(void) 56 - { 57 - return ip6t_register_match(&length_match); 58 - } 59 - 60 - static void __exit fini(void) 61 - { 62 - ip6t_unregister_match(&length_match); 63 - } 64 - 65 - module_init(init); 66 - module_exit(fini);
-147
net/ipv6/netfilter/ip6t_limit.c
··· 1 - /* Kernel module to control the rate 2 - * 3 - * 2 September 1999: Changed from the target RATE to the match 4 - * `limit', removed logging. Did I mention that 5 - * Alexey is a fucking genius? 6 - * Rusty Russell (rusty@rustcorp.com.au). */ 7 - 8 - /* (C) 1999 J�r�me de Vivie <devivie@info.enserb.u-bordeaux.fr> 9 - * (C) 1999 Herv� Eychenne <eychenne@info.enserb.u-bordeaux.fr> 10 - * 11 - * This program is free software; you can redistribute it and/or modify 12 - * it under the terms of the GNU General Public License version 2 as 13 - * published by the Free Software Foundation. 14 - */ 15 - 16 - #include <linux/module.h> 17 - #include <linux/skbuff.h> 18 - #include <linux/spinlock.h> 19 - #include <linux/interrupt.h> 20 - 21 - #include <linux/netfilter_ipv6/ip6_tables.h> 22 - #include <linux/netfilter_ipv6/ip6t_limit.h> 23 - 24 - MODULE_LICENSE("GPL"); 25 - MODULE_AUTHOR("Herve Eychenne <rv@wallfire.org>"); 26 - MODULE_DESCRIPTION("rate limiting within ip6tables"); 27 - 28 - /* The algorithm used is the Simple Token Bucket Filter (TBF) 29 - * see net/sched/sch_tbf.c in the linux source tree 30 - */ 31 - 32 - static DEFINE_SPINLOCK(limit_lock); 33 - 34 - /* Rusty: This is my (non-mathematically-inclined) understanding of 35 - this algorithm. The `average rate' in jiffies becomes your initial 36 - amount of credit `credit' and the most credit you can ever have 37 - `credit_cap'. The `peak rate' becomes the cost of passing the 38 - test, `cost'. 39 - 40 - `prev' tracks the last packet hit: you gain one credit per jiffy. 41 - If you get credit balance more than this, the extra credit is 42 - discarded. Every time the match passes, you lose `cost' credits; 43 - if you don't have that many, the test fails. 44 - 45 - See Alexey's formal explanation in net/sched/sch_tbf.c. 46 - 47 - To avoid underflow, we multiply by 128 (ie. you get 128 credits per 48 - jiffy). Hence a cost of 2^32-1, means one pass per 32768 seconds 49 - at 1024HZ (or one every 9 hours). A cost of 1 means 12800 passes 50 - per second at 100HZ. */ 51 - 52 - #define CREDITS_PER_JIFFY 128 53 - 54 - static int 55 - ip6t_limit_match(const struct sk_buff *skb, 56 - const struct net_device *in, 57 - const struct net_device *out, 58 - const void *matchinfo, 59 - int offset, 60 - unsigned int protoff, 61 - int *hotdrop) 62 - { 63 - struct ip6t_rateinfo *r = ((struct ip6t_rateinfo *)matchinfo)->master; 64 - unsigned long now = jiffies; 65 - 66 - spin_lock_bh(&limit_lock); 67 - r->credit += (now - xchg(&r->prev, now)) * CREDITS_PER_JIFFY; 68 - if (r->credit > r->credit_cap) 69 - r->credit = r->credit_cap; 70 - 71 - if (r->credit >= r->cost) { 72 - /* We're not limited. */ 73 - r->credit -= r->cost; 74 - spin_unlock_bh(&limit_lock); 75 - return 1; 76 - } 77 - 78 - spin_unlock_bh(&limit_lock); 79 - return 0; 80 - } 81 - 82 - /* Precision saver. */ 83 - static u_int32_t 84 - user2credits(u_int32_t user) 85 - { 86 - /* If multiplying would overflow... */ 87 - if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY)) 88 - /* Divide first. */ 89 - return (user / IP6T_LIMIT_SCALE) * HZ * CREDITS_PER_JIFFY; 90 - 91 - return (user * HZ * CREDITS_PER_JIFFY) / IP6T_LIMIT_SCALE; 92 - } 93 - 94 - static int 95 - ip6t_limit_checkentry(const char *tablename, 96 - const struct ip6t_ip6 *ip, 97 - void *matchinfo, 98 - unsigned int matchsize, 99 - unsigned int hook_mask) 100 - { 101 - struct ip6t_rateinfo *r = matchinfo; 102 - 103 - if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_rateinfo))) 104 - return 0; 105 - 106 - /* Check for overflow. */ 107 - if (r->burst == 0 108 - || user2credits(r->avg * r->burst) < user2credits(r->avg)) { 109 - printk("Call rusty: overflow in ip6t_limit: %u/%u\n", 110 - r->avg, r->burst); 111 - return 0; 112 - } 113 - 114 - /* User avg in seconds * IP6T_LIMIT_SCALE: convert to jiffies * 115 - 128. */ 116 - r->prev = jiffies; 117 - r->credit = user2credits(r->avg * r->burst); /* Credits full. */ 118 - r->credit_cap = user2credits(r->avg * r->burst); /* Credits full. */ 119 - r->cost = user2credits(r->avg); 120 - 121 - /* For SMP, we only want to use one set of counters. */ 122 - r->master = r; 123 - 124 - return 1; 125 - } 126 - 127 - static struct ip6t_match ip6t_limit_reg = { 128 - .name = "limit", 129 - .match = ip6t_limit_match, 130 - .checkentry = ip6t_limit_checkentry, 131 - .me = THIS_MODULE, 132 - }; 133 - 134 - static int __init init(void) 135 - { 136 - if (ip6t_register_match(&ip6t_limit_reg)) 137 - return -EINVAL; 138 - return 0; 139 - } 140 - 141 - static void __exit fini(void) 142 - { 143 - ip6t_unregister_match(&ip6t_limit_reg); 144 - } 145 - 146 - module_init(init); 147 - module_exit(fini);
-81
net/ipv6/netfilter/ip6t_mac.c
··· 1 - /* Kernel module to match MAC address parameters. */ 2 - 3 - /* (C) 1999-2001 Paul `Rusty' Russell 4 - * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License version 2 as 8 - * published by the Free Software Foundation. 9 - */ 10 - 11 - #include <linux/module.h> 12 - #include <linux/skbuff.h> 13 - #include <linux/if_ether.h> 14 - #include <linux/etherdevice.h> 15 - 16 - #include <linux/netfilter_ipv6/ip6t_mac.h> 17 - #include <linux/netfilter_ipv6/ip6_tables.h> 18 - 19 - MODULE_LICENSE("GPL"); 20 - MODULE_DESCRIPTION("MAC address matching module for IPv6"); 21 - MODULE_AUTHOR("Netfilter Core Teaam <coreteam@netfilter.org>"); 22 - 23 - static int 24 - match(const struct sk_buff *skb, 25 - const struct net_device *in, 26 - const struct net_device *out, 27 - const void *matchinfo, 28 - int offset, 29 - unsigned int protoff, 30 - int *hotdrop) 31 - { 32 - const struct ip6t_mac_info *info = matchinfo; 33 - 34 - /* Is mac pointer valid? */ 35 - return (skb->mac.raw >= skb->head 36 - && (skb->mac.raw + ETH_HLEN) <= skb->data 37 - /* If so, compare... */ 38 - && ((!compare_ether_addr(eth_hdr(skb)->h_source, info->srcaddr)) 39 - ^ info->invert)); 40 - } 41 - 42 - static int 43 - ip6t_mac_checkentry(const char *tablename, 44 - const struct ip6t_ip6 *ip, 45 - void *matchinfo, 46 - unsigned int matchsize, 47 - unsigned int hook_mask) 48 - { 49 - if (hook_mask 50 - & ~((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_IN) 51 - | (1 << NF_IP6_FORWARD))) { 52 - printk("ip6t_mac: only valid for PRE_ROUTING, LOCAL_IN or" 53 - " FORWARD\n"); 54 - return 0; 55 - } 56 - 57 - if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_mac_info))) 58 - return 0; 59 - 60 - return 1; 61 - } 62 - 63 - static struct ip6t_match mac_match = { 64 - .name = "mac", 65 - .match = &match, 66 - .checkentry = &ip6t_mac_checkentry, 67 - .me = THIS_MODULE, 68 - }; 69 - 70 - static int __init init(void) 71 - { 72 - return ip6t_register_match(&mac_match); 73 - } 74 - 75 - static void __exit fini(void) 76 - { 77 - ip6t_unregister_match(&mac_match); 78 - } 79 - 80 - module_init(init); 81 - module_exit(fini);
-66
net/ipv6/netfilter/ip6t_mark.c
··· 1 - /* Kernel module to match NFMARK values. */ 2 - 3 - /* (C) 1999-2001 Marc Boucher <marc@mbsi.ca> 4 - * 5 - * This program is free software; you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License version 2 as 7 - * published by the Free Software Foundation. 8 - */ 9 - 10 - 11 - #include <linux/module.h> 12 - #include <linux/skbuff.h> 13 - 14 - #include <linux/netfilter_ipv6/ip6t_mark.h> 15 - #include <linux/netfilter_ipv6/ip6_tables.h> 16 - 17 - MODULE_LICENSE("GPL"); 18 - MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 19 - MODULE_DESCRIPTION("ip6tables mark match"); 20 - 21 - static int 22 - match(const struct sk_buff *skb, 23 - const struct net_device *in, 24 - const struct net_device *out, 25 - const void *matchinfo, 26 - int offset, 27 - unsigned int protoff, 28 - int *hotdrop) 29 - { 30 - const struct ip6t_mark_info *info = matchinfo; 31 - 32 - return ((skb->nfmark & info->mask) == info->mark) ^ info->invert; 33 - } 34 - 35 - static int 36 - checkentry(const char *tablename, 37 - const struct ip6t_ip6 *ip, 38 - void *matchinfo, 39 - unsigned int matchsize, 40 - unsigned int hook_mask) 41 - { 42 - if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_mark_info))) 43 - return 0; 44 - 45 - return 1; 46 - } 47 - 48 - static struct ip6t_match mark_match = { 49 - .name = "mark", 50 - .match = &match, 51 - .checkentry = &checkentry, 52 - .me = THIS_MODULE, 53 - }; 54 - 55 - static int __init init(void) 56 - { 57 - return ip6t_register_match(&mark_match); 58 - } 59 - 60 - static void __exit fini(void) 61 - { 62 - ip6t_unregister_match(&mark_match); 63 - } 64 - 65 - module_init(init); 66 - module_exit(fini);
+2 -1
net/ipv6/netfilter/ip6t_multiport.c
··· 84 84 /* Called when user tries to insert an entry of this type. */ 85 85 static int 86 86 checkentry(const char *tablename, 87 - const struct ip6t_ip6 *ip, 87 + const void *info, 88 88 void *matchinfo, 89 89 unsigned int matchsize, 90 90 unsigned int hook_mask) 91 91 { 92 + const struct ip6t_ip6 *ip = info; 92 93 const struct ip6t_multiport *multiinfo = matchinfo; 93 94 94 95 if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_multiport)))
+1 -1
net/ipv6/netfilter/ip6t_owner.c
··· 53 53 54 54 static int 55 55 checkentry(const char *tablename, 56 - const struct ip6t_ip6 *ip, 56 + const void *ip, 57 57 void *matchinfo, 58 58 unsigned int matchsize, 59 59 unsigned int hook_mask)
-135
net/ipv6/netfilter/ip6t_physdev.c
··· 1 - /* Kernel module to match the bridge port in and 2 - * out device for IP packets coming into contact with a bridge. */ 3 - 4 - /* (C) 2001-2003 Bart De Schuymer <bdschuym@pandora.be> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License version 2 as 8 - * published by the Free Software Foundation. 9 - */ 10 - 11 - #include <linux/module.h> 12 - #include <linux/skbuff.h> 13 - #include <linux/netfilter_ipv6/ip6t_physdev.h> 14 - #include <linux/netfilter_ipv6/ip6_tables.h> 15 - #include <linux/netfilter_bridge.h> 16 - #define MATCH 1 17 - #define NOMATCH 0 18 - 19 - MODULE_LICENSE("GPL"); 20 - MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>"); 21 - MODULE_DESCRIPTION("iptables bridge physical device match module"); 22 - 23 - static int 24 - match(const struct sk_buff *skb, 25 - const struct net_device *in, 26 - const struct net_device *out, 27 - const void *matchinfo, 28 - int offset, 29 - unsigned int protoff, 30 - int *hotdrop) 31 - { 32 - int i; 33 - static const char nulldevname[IFNAMSIZ]; 34 - const struct ip6t_physdev_info *info = matchinfo; 35 - unsigned int ret; 36 - const char *indev, *outdev; 37 - struct nf_bridge_info *nf_bridge; 38 - 39 - /* Not a bridged IP packet or no info available yet: 40 - * LOCAL_OUT/mangle and LOCAL_OUT/nat don't know if 41 - * the destination device will be a bridge. */ 42 - if (!(nf_bridge = skb->nf_bridge)) { 43 - /* Return MATCH if the invert flags of the used options are on */ 44 - if ((info->bitmask & IP6T_PHYSDEV_OP_BRIDGED) && 45 - !(info->invert & IP6T_PHYSDEV_OP_BRIDGED)) 46 - return NOMATCH; 47 - if ((info->bitmask & IP6T_PHYSDEV_OP_ISIN) && 48 - !(info->invert & IP6T_PHYSDEV_OP_ISIN)) 49 - return NOMATCH; 50 - if ((info->bitmask & IP6T_PHYSDEV_OP_ISOUT) && 51 - !(info->invert & IP6T_PHYSDEV_OP_ISOUT)) 52 - return NOMATCH; 53 - if ((info->bitmask & IP6T_PHYSDEV_OP_IN) && 54 - !(info->invert & IP6T_PHYSDEV_OP_IN)) 55 - return NOMATCH; 56 - if ((info->bitmask & IP6T_PHYSDEV_OP_OUT) && 57 - !(info->invert & IP6T_PHYSDEV_OP_OUT)) 58 - return NOMATCH; 59 - return MATCH; 60 - } 61 - 62 - /* This only makes sense in the FORWARD and POSTROUTING chains */ 63 - if ((info->bitmask & IP6T_PHYSDEV_OP_BRIDGED) && 64 - (!!(nf_bridge->mask & BRNF_BRIDGED) ^ 65 - !(info->invert & IP6T_PHYSDEV_OP_BRIDGED))) 66 - return NOMATCH; 67 - 68 - if ((info->bitmask & IP6T_PHYSDEV_OP_ISIN && 69 - (!nf_bridge->physindev ^ !!(info->invert & IP6T_PHYSDEV_OP_ISIN))) || 70 - (info->bitmask & IP6T_PHYSDEV_OP_ISOUT && 71 - (!nf_bridge->physoutdev ^ !!(info->invert & IP6T_PHYSDEV_OP_ISOUT)))) 72 - return NOMATCH; 73 - 74 - if (!(info->bitmask & IP6T_PHYSDEV_OP_IN)) 75 - goto match_outdev; 76 - indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname; 77 - for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) { 78 - ret |= (((const unsigned int *)indev)[i] 79 - ^ ((const unsigned int *)info->physindev)[i]) 80 - & ((const unsigned int *)info->in_mask)[i]; 81 - } 82 - 83 - if ((ret == 0) ^ !(info->invert & IP6T_PHYSDEV_OP_IN)) 84 - return NOMATCH; 85 - 86 - match_outdev: 87 - if (!(info->bitmask & IP6T_PHYSDEV_OP_OUT)) 88 - return MATCH; 89 - outdev = nf_bridge->physoutdev ? 90 - nf_bridge->physoutdev->name : nulldevname; 91 - for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) { 92 - ret |= (((const unsigned int *)outdev)[i] 93 - ^ ((const unsigned int *)info->physoutdev)[i]) 94 - & ((const unsigned int *)info->out_mask)[i]; 95 - } 96 - 97 - return (ret != 0) ^ !(info->invert & IP6T_PHYSDEV_OP_OUT); 98 - } 99 - 100 - static int 101 - checkentry(const char *tablename, 102 - const struct ip6t_ip6 *ip, 103 - void *matchinfo, 104 - unsigned int matchsize, 105 - unsigned int hook_mask) 106 - { 107 - const struct ip6t_physdev_info *info = matchinfo; 108 - 109 - if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_physdev_info))) 110 - return 0; 111 - if (!(info->bitmask & IP6T_PHYSDEV_OP_MASK) || 112 - info->bitmask & ~IP6T_PHYSDEV_OP_MASK) 113 - return 0; 114 - return 1; 115 - } 116 - 117 - static struct ip6t_match physdev_match = { 118 - .name = "physdev", 119 - .match = &match, 120 - .checkentry = &checkentry, 121 - .me = THIS_MODULE, 122 - }; 123 - 124 - static int __init init(void) 125 - { 126 - return ip6t_register_match(&physdev_match); 127 - } 128 - 129 - static void __exit fini(void) 130 - { 131 - ip6t_unregister_match(&physdev_match); 132 - } 133 - 134 - module_init(init); 135 - module_exit(fini);
+1 -1
net/ipv6/netfilter/ip6t_rt.c
··· 183 183 /* Called when user tries to insert an entry of this type. */ 184 184 static int 185 185 checkentry(const char *tablename, 186 - const struct ip6t_ip6 *ip, 186 + const void *entry, 187 187 void *matchinfo, 188 188 unsigned int matchinfosize, 189 189 unsigned int hook_mask)
+1
net/ipv6/netfilter/ip6table_filter.c
··· 97 97 .valid_hooks = FILTER_VALID_HOOKS, 98 98 .lock = RW_LOCK_UNLOCKED, 99 99 .me = THIS_MODULE, 100 + .af = AF_INET6, 100 101 }; 101 102 102 103 /* The work comes in here from netfilter.c. */
+1
net/ipv6/netfilter/ip6table_mangle.c
··· 127 127 .valid_hooks = MANGLE_VALID_HOOKS, 128 128 .lock = RW_LOCK_UNLOCKED, 129 129 .me = THIS_MODULE, 130 + .af = AF_INET6, 130 131 }; 131 132 132 133 /* The work comes in here from netfilter.c. */
+3 -2
net/ipv6/netfilter/ip6table_raw.c
··· 106 106 } 107 107 }; 108 108 109 - static struct ip6t_table packet_raw = { 109 + static struct xt_table packet_raw = { 110 110 .name = "raw", 111 111 .valid_hooks = RAW_VALID_HOOKS, 112 112 .lock = RW_LOCK_UNLOCKED, 113 - .me = THIS_MODULE 113 + .me = THIS_MODULE, 114 + .af = AF_INET6, 114 115 }; 115 116 116 117 /* The work comes in here from netfilter.c. */
+1 -7
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
··· 584 584 585 585 static int __init init(void) 586 586 { 587 - need_nf_conntrack(); 587 + need_conntrack(); 588 588 return init_or_cleanup(1); 589 589 } 590 590 ··· 595 595 596 596 module_init(init); 597 597 module_exit(fini); 598 - 599 - void need_ip6_conntrack(void) 600 - { 601 - } 602 - 603 - EXPORT_SYMBOL(need_ip6_conntrack);
+16 -29
net/ipv6/netfilter/nf_conntrack_reasm.c
··· 70 70 71 71 struct nf_ct_frag6_queue 72 72 { 73 - struct nf_ct_frag6_queue *next; 74 - struct list_head lru_list; /* lru list member */ 73 + struct hlist_node list; 74 + struct list_head lru_list; /* lru list member */ 75 75 76 76 __u32 id; /* fragment id */ 77 77 struct in6_addr saddr; ··· 90 90 #define FIRST_IN 2 91 91 #define LAST_IN 1 92 92 __u16 nhoffset; 93 - struct nf_ct_frag6_queue **pprev; 94 93 }; 95 94 96 95 /* Hash table. */ 97 96 98 97 #define FRAG6Q_HASHSZ 64 99 98 100 - static struct nf_ct_frag6_queue *nf_ct_frag6_hash[FRAG6Q_HASHSZ]; 99 + static struct hlist_head nf_ct_frag6_hash[FRAG6Q_HASHSZ]; 101 100 static DEFINE_RWLOCK(nf_ct_frag6_lock); 102 101 static u32 nf_ct_frag6_hash_rnd; 103 102 static LIST_HEAD(nf_ct_frag6_lru_list); ··· 104 105 105 106 static __inline__ void __fq_unlink(struct nf_ct_frag6_queue *fq) 106 107 { 107 - if (fq->next) 108 - fq->next->pprev = fq->pprev; 109 - *fq->pprev = fq->next; 108 + hlist_del(&fq->list); 110 109 list_del(&fq->lru_list); 111 110 nf_ct_frag6_nqueues--; 112 111 } ··· 155 158 get_random_bytes(&nf_ct_frag6_hash_rnd, sizeof(u32)); 156 159 for (i = 0; i < FRAG6Q_HASHSZ; i++) { 157 160 struct nf_ct_frag6_queue *q; 161 + struct hlist_node *p, *n; 158 162 159 - q = nf_ct_frag6_hash[i]; 160 - while (q) { 161 - struct nf_ct_frag6_queue *next = q->next; 163 + hlist_for_each_entry_safe(q, p, n, &nf_ct_frag6_hash[i], list) { 162 164 unsigned int hval = ip6qhashfn(q->id, 163 165 &q->saddr, 164 166 &q->daddr); 165 - 166 167 if (hval != i) { 167 - /* Unlink. */ 168 - if (q->next) 169 - q->next->pprev = q->pprev; 170 - *q->pprev = q->next; 171 - 168 + hlist_del(&q->list); 172 169 /* Relink to new hash chain. */ 173 - if ((q->next = nf_ct_frag6_hash[hval]) != NULL) 174 - q->next->pprev = &q->next; 175 - nf_ct_frag6_hash[hval] = q; 176 - q->pprev = &nf_ct_frag6_hash[hval]; 170 + hlist_add_head(&q->list, 171 + &nf_ct_frag6_hash[hval]); 177 172 } 178 - 179 - q = next; 180 173 } 181 174 } 182 175 write_unlock(&nf_ct_frag6_lock); ··· 301 314 302 315 /* Creation primitives. */ 303 316 304 - 305 317 static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash, 306 318 struct nf_ct_frag6_queue *fq_in) 307 319 { 308 320 struct nf_ct_frag6_queue *fq; 321 + #ifdef CONFIG_SMP 322 + struct hlist_node *n; 323 + #endif 309 324 310 325 write_lock(&nf_ct_frag6_lock); 311 326 #ifdef CONFIG_SMP 312 - for (fq = nf_ct_frag6_hash[hash]; fq; fq = fq->next) { 327 + hlist_for_each_entry(fq, n, &nf_ct_frag6_hash[hash], list) { 313 328 if (fq->id == fq_in->id && 314 329 !ipv6_addr_cmp(&fq_in->saddr, &fq->saddr) && 315 330 !ipv6_addr_cmp(&fq_in->daddr, &fq->daddr)) { ··· 329 340 atomic_inc(&fq->refcnt); 330 341 331 342 atomic_inc(&fq->refcnt); 332 - if ((fq->next = nf_ct_frag6_hash[hash]) != NULL) 333 - fq->next->pprev = &fq->next; 334 - nf_ct_frag6_hash[hash] = fq; 335 - fq->pprev = &nf_ct_frag6_hash[hash]; 343 + hlist_add_head(&fq->list, &nf_ct_frag6_hash[hash]); 336 344 INIT_LIST_HEAD(&fq->lru_list); 337 345 list_add_tail(&fq->lru_list, &nf_ct_frag6_lru_list); 338 346 nf_ct_frag6_nqueues++; ··· 370 384 fq_find(u32 id, struct in6_addr *src, struct in6_addr *dst) 371 385 { 372 386 struct nf_ct_frag6_queue *fq; 387 + struct hlist_node *n; 373 388 unsigned int hash = ip6qhashfn(id, src, dst); 374 389 375 390 read_lock(&nf_ct_frag6_lock); 376 - for (fq = nf_ct_frag6_hash[hash]; fq; fq = fq->next) { 391 + hlist_for_each_entry(fq, n, &nf_ct_frag6_hash[hash], list) { 377 392 if (fq->id == id && 378 393 !ipv6_addr_cmp(src, &fq->saddr) && 379 394 !ipv6_addr_cmp(dst, &fq->daddr)) {
+258
net/netfilter/Kconfig
··· 103 103 This option enables support for a netlink-based userspace interface 104 104 105 105 endmenu 106 + 107 + config NETFILTER_XTABLES 108 + tristate "Netfilter Xtables support (required for ip_tables)" 109 + help 110 + This is required if you intend to use any of ip_tables, 111 + ip6_tables or arp_tables. 112 + 113 + # alphabetically ordered list of targets 114 + 115 + config NETFILTER_XT_TARGET_CLASSIFY 116 + tristate '"CLASSIFY" target support' 117 + depends on NETFILTER_XTABLES 118 + help 119 + This option adds a `CLASSIFY' target, which enables the user to set 120 + the priority of a packet. Some qdiscs can use this value for 121 + classification, among these are: 122 + 123 + atm, cbq, dsmark, pfifo_fast, htb, prio 124 + 125 + To compile it as a module, choose M here. If unsure, say N. 126 + 127 + config NETFILTER_XT_TARGET_CONNMARK 128 + tristate '"CONNMARK" target support' 129 + depends on NETFILTER_XTABLES 130 + depends on IP_NF_MANGLE || IP6_NF_MANGLE 131 + depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4) 132 + help 133 + This option adds a `CONNMARK' target, which allows one to manipulate 134 + the connection mark value. Similar to the MARK target, but 135 + affects the connection mark value rather than the packet mark value. 136 + 137 + If you want to compile it as a module, say M here and read 138 + <file:Documentation/modules.txt>. The module will be called 139 + ipt_CONNMARK.o. If unsure, say `N'. 140 + 141 + config NETFILTER_XT_TARGET_MARK 142 + tristate '"MARK" target support' 143 + depends on NETFILTER_XTABLES 144 + help 145 + This option adds a `MARK' target, which allows you to create rules 146 + in the `mangle' table which alter the netfilter mark (nfmark) field 147 + associated with the packet prior to routing. This can change 148 + the routing method (see `Use netfilter MARK value as routing 149 + key') and can also be used by other subsystems to change their 150 + behavior. 151 + 152 + To compile it as a module, choose M here. If unsure, say N. 153 + 154 + config NETFILTER_XT_TARGET_NFQUEUE 155 + tristate '"NFQUEUE" target Support' 156 + depends on NETFILTER_XTABLES 157 + help 158 + This Target replaced the old obsolete QUEUE target. 159 + 160 + As opposed to QUEUE, it supports 65535 different queues, 161 + not just one. 162 + 163 + To compile it as a module, choose M here. If unsure, say N. 164 + 165 + config NETFILTER_XT_TARGET_NOTRACK 166 + tristate '"NOTRACK" target support' 167 + depends on NETFILTER_XTABLES 168 + depends on IP_NF_RAW || IP6_NF_RAW 169 + depends on IP_NF_CONNTRACK || NF_CONNTRACK 170 + help 171 + The NOTRACK target allows a select rule to specify 172 + which packets *not* to enter the conntrack/NAT 173 + subsystem with all the consequences (no ICMP error tracking, 174 + no protocol helpers for the selected packets). 175 + 176 + If you want to compile it as a module, say M here and read 177 + <file:Documentation/modules.txt>. If unsure, say `N'. 178 + 179 + config NETFILTER_XT_MATCH_COMMENT 180 + tristate '"comment" match support' 181 + depends on NETFILTER_XTABLES 182 + help 183 + This option adds a `comment' dummy-match, which allows you to put 184 + comments in your iptables ruleset. 185 + 186 + If you want to compile it as a module, say M here and read 187 + <file:Documentation/modules.txt>. If unsure, say `N'. 188 + 189 + config NETFILTER_XT_MATCH_CONNBYTES 190 + tristate '"connbytes" per-connection counter match support' 191 + depends on NETFILTER_XTABLES 192 + depends on (IP_NF_CONNTRACK && IP_NF_CT_ACCT) || NF_CT_ACCT 193 + help 194 + This option adds a `connbytes' match, which allows you to match the 195 + number of bytes and/or packets for each direction within a connection. 196 + 197 + If you want to compile it as a module, say M here and read 198 + <file:Documentation/modules.txt>. If unsure, say `N'. 199 + 200 + config NETFILTER_XT_MATCH_CONNMARK 201 + tristate '"connmark" connection mark match support' 202 + depends on NETFILTER_XTABLES 203 + depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || NF_CONNTRACK_MARK 204 + help 205 + This option adds a `connmark' match, which allows you to match the 206 + connection mark value previously set for the session by `CONNMARK'. 207 + 208 + If you want to compile it as a module, say M here and read 209 + <file:Documentation/modules.txt>. The module will be called 210 + ipt_connmark.o. If unsure, say `N'. 211 + 212 + config NETFILTER_XT_MATCH_CONNTRACK 213 + tristate '"conntrack" connection tracking match support' 214 + depends on NETFILTER_XTABLES 215 + depends on IP_NF_CONNTRACK || NF_CONNTRACK 216 + help 217 + This is a general conntrack match module, a superset of the state match. 218 + 219 + It allows matching on additional conntrack information, which is 220 + useful in complex configurations, such as NAT gateways with multiple 221 + internet links or tunnels. 222 + 223 + To compile it as a module, choose M here. If unsure, say N. 224 + 225 + config NETFILTER_XT_MATCH_DCCP 226 + tristate '"DCCP" protocol match support' 227 + depends on NETFILTER_XTABLES 228 + help 229 + With this option enabled, you will be able to use the iptables 230 + `dccp' match in order to match on DCCP source/destination ports 231 + and DCCP flags. 232 + 233 + If you want to compile it as a module, say M here and read 234 + <file:Documentation/modules.txt>. If unsure, say `N'. 235 + 236 + config NETFILTER_XT_MATCH_HELPER 237 + tristate '"helper" match support' 238 + depends on NETFILTER_XTABLES 239 + depends on IP_NF_CONNTRACK || NF_CONNTRACK 240 + help 241 + Helper matching allows you to match packets in dynamic connections 242 + tracked by a conntrack-helper, ie. ip_conntrack_ftp 243 + 244 + To compile it as a module, choose M here. If unsure, say Y. 245 + 246 + config NETFILTER_XT_MATCH_LENGTH 247 + tristate '"length" match support' 248 + depends on NETFILTER_XTABLES 249 + help 250 + This option allows you to match the length of a packet against a 251 + specific value or range of values. 252 + 253 + To compile it as a module, choose M here. If unsure, say N. 254 + 255 + config NETFILTER_XT_MATCH_LIMIT 256 + tristate '"limit" match support' 257 + depends on NETFILTER_XTABLES 258 + help 259 + limit matching allows you to control the rate at which a rule can be 260 + matched: mainly useful in combination with the LOG target ("LOG 261 + target support", below) and to avoid some Denial of Service attacks. 262 + 263 + To compile it as a module, choose M here. If unsure, say N. 264 + 265 + config NETFILTER_XT_MATCH_MAC 266 + tristate '"mac" address match support' 267 + depends on NETFILTER_XTABLES 268 + help 269 + MAC matching allows you to match packets based on the source 270 + Ethernet address of the packet. 271 + 272 + To compile it as a module, choose M here. If unsure, say N. 273 + 274 + config NETFILTER_XT_MATCH_MARK 275 + tristate '"mark" match support' 276 + depends on NETFILTER_XTABLES 277 + help 278 + Netfilter mark matching allows you to match packets based on the 279 + `nfmark' value in the packet. This can be set by the MARK target 280 + (see below). 281 + 282 + To compile it as a module, choose M here. If unsure, say N. 283 + 284 + config NETFILTER_XT_MATCH_PHYSDEV 285 + tristate '"physdev" match support' 286 + depends on NETFILTER_XTABLES && BRIDGE_NETFILTER 287 + help 288 + Physdev packet matching matches against the physical bridge ports 289 + the IP packet arrived on or will leave by. 290 + 291 + To compile it as a module, choose M here. If unsure, say N. 292 + 293 + config NETFILTER_XT_MATCH_PKTTYPE 294 + tristate '"pkttype" packet type match support' 295 + depends on NETFILTER_XTABLES 296 + help 297 + Packet type matching allows you to match a packet by 298 + its "class", eg. BROADCAST, MULTICAST, ... 299 + 300 + Typical usage: 301 + iptables -A INPUT -m pkttype --pkt-type broadcast -j LOG 302 + 303 + To compile it as a module, choose M here. If unsure, say N. 304 + 305 + config NETFILTER_XT_MATCH_REALM 306 + tristate '"realm" match support' 307 + depends on NETFILTER_XTABLES 308 + select NET_CLS_ROUTE 309 + help 310 + This option adds a `realm' match, which allows you to use the realm 311 + key from the routing subsystem inside iptables. 312 + 313 + This match pretty much resembles the CONFIG_NET_CLS_ROUTE4 option 314 + in tc world. 315 + 316 + If you want to compile it as a module, say M here and read 317 + <file:Documentation/modules.txt>. If unsure, say `N'. 318 + 319 + config NETFILTER_XT_MATCH_SCTP 320 + tristate '"sctp" protocol match support' 321 + depends on NETFILTER_XTABLES 322 + help 323 + With this option enabled, you will be able to use the 324 + `sctp' match in order to match on SCTP source/destination ports 325 + and SCTP chunk types. 326 + 327 + If you want to compile it as a module, say M here and read 328 + <file:Documentation/modules.txt>. If unsure, say `N'. 329 + 330 + config NETFILTER_XT_MATCH_STATE 331 + tristate '"state" match support' 332 + depends on NETFILTER_XTABLES 333 + depends on IP_NF_CONNTRACK || NF_CONNTRACK 334 + help 335 + Connection state matching allows you to match packets based on their 336 + relationship to a tracked connection (ie. previous packets). This 337 + is a powerful tool for packet classification. 338 + 339 + To compile it as a module, choose M here. If unsure, say N. 340 + 341 + config NETFILTER_XT_MATCH_STRING 342 + tristate '"string" match support' 343 + depends on NETFILTER_XTABLES 344 + select TEXTSEARCH 345 + select TEXTSEARCH_KMP 346 + select TEXTSEARCH_BM 347 + select TEXTSEARCH_FSM 348 + help 349 + This option adds a `string' match, which allows you to look for 350 + pattern matchings in packets. 351 + 352 + To compile it as a module, choose M here. If unsure, say N. 353 + 354 + config NETFILTER_XT_MATCH_TCPMSS 355 + tristate '"tcpmss" match support' 356 + depends on NETFILTER_XTABLES 357 + help 358 + This option adds a `tcpmss' match, which allows you to examine the 359 + MSS value of TCP SYN packets, which control the maximum packet size 360 + for that connection. 361 + 362 + To compile it as a module, choose M here. If unsure, say N. 363 +
+34 -3
net/netfilter/Makefile
··· 1 1 netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o 2 + nf_conntrack-objs := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o 2 3 3 4 obj-$(CONFIG_NETFILTER) = netfilter.o 4 5 ··· 7 6 obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o 8 7 obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o 9 8 10 - nf_conntrack-objs := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o 11 - 9 + # connection tracking 12 10 obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o 13 - obj-$(CONFIG_NF_CONNTRACK_FTP) += nf_conntrack_ftp.o 14 11 15 12 # SCTP protocol connection tracking 16 13 obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o 17 14 18 15 # netlink interface for nf_conntrack 19 16 obj-$(CONFIG_NF_CT_NETLINK) += nf_conntrack_netlink.o 17 + 18 + # connection tracking helpers 19 + obj-$(CONFIG_NF_CONNTRACK_FTP) += nf_conntrack_ftp.o 20 + 21 + # generic X tables 22 + obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o 23 + 24 + # targets 25 + obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIFY) += xt_CLASSIFY.o 26 + obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMARK) += xt_CONNMARK.o 27 + obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o 28 + obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o 29 + obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o 30 + 31 + # matches 32 + obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o 33 + obj-$(CONFIG_NETFILTER_XT_MATCH_CONNBYTES) += xt_connbytes.o 34 + obj-$(CONFIG_NETFILTER_XT_MATCH_CONNMARK) += xt_connmark.o 35 + obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o 36 + obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.o 37 + obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o 38 + obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o 39 + obj-$(CONFIG_NETFILTER_XT_MATCH_LIMIT) += xt_limit.o 40 + obj-$(CONFIG_NETFILTER_XT_MATCH_MAC) += xt_mac.o 41 + obj-$(CONFIG_NETFILTER_XT_MATCH_MARK) += xt_mark.o 42 + obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o 43 + obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o 44 + obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o 45 + obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o 46 + obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o 47 + obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o 48 + obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o
+2 -2
net/netfilter/nf_conntrack_standalone.c
··· 821 821 822 822 /* Some modules need us, but don't depend directly on any symbol. 823 823 They should call this. */ 824 - void need_nf_conntrack(void) 824 + void need_conntrack(void) 825 825 { 826 826 } 827 827 ··· 841 841 EXPORT_SYMBOL(nf_ct_invert_tuplepr); 842 842 EXPORT_SYMBOL(nf_conntrack_alter_reply); 843 843 EXPORT_SYMBOL(nf_conntrack_destroyed); 844 - EXPORT_SYMBOL(need_nf_conntrack); 844 + EXPORT_SYMBOL(need_conntrack); 845 845 EXPORT_SYMBOL(nf_conntrack_helper_register); 846 846 EXPORT_SYMBOL(nf_conntrack_helper_unregister); 847 847 EXPORT_SYMBOL(nf_ct_iterate_cleanup);
+624
net/netfilter/x_tables.c
··· 1 + /* 2 + * x_tables core - Backend for {ip,ip6,arp}_tables 3 + * 4 + * Copyright (C) 2006-2006 Harald Welte <laforge@netfilter.org> 5 + * 6 + * Based on existing ip_tables code which is 7 + * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling 8 + * Copyright (C) 2000-2005 Netfilter Core Team <coreteam@netfilter.org> 9 + * 10 + * This program is free software; you can redistribute it and/or modify 11 + * it under the terms of the GNU General Public License version 2 as 12 + * published by the Free Software Foundation. 13 + * 14 + */ 15 + 16 + #include <linux/config.h> 17 + #include <linux/kernel.h> 18 + #include <linux/socket.h> 19 + #include <linux/net.h> 20 + #include <linux/proc_fs.h> 21 + #include <linux/seq_file.h> 22 + #include <linux/string.h> 23 + #include <linux/vmalloc.h> 24 + 25 + #include <linux/netfilter/x_tables.h> 26 + #include <linux/netfilter_arp.h> 27 + 28 + MODULE_LICENSE("GPL"); 29 + MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 30 + MODULE_DESCRIPTION("[ip,ip6,arp]_tables backend module"); 31 + 32 + #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) 33 + 34 + struct xt_af { 35 + struct semaphore mutex; 36 + struct list_head match; 37 + struct list_head target; 38 + struct list_head tables; 39 + }; 40 + 41 + static struct xt_af *xt; 42 + 43 + #ifdef DEBUG_IP_FIREWALL_USER 44 + #define duprintf(format, args...) printk(format , ## args) 45 + #else 46 + #define duprintf(format, args...) 47 + #endif 48 + 49 + enum { 50 + TABLE, 51 + TARGET, 52 + MATCH, 53 + }; 54 + 55 + /* Registration hooks for targets. */ 56 + int 57 + xt_register_target(int af, struct xt_target *target) 58 + { 59 + int ret; 60 + 61 + ret = down_interruptible(&xt[af].mutex); 62 + if (ret != 0) 63 + return ret; 64 + list_add(&target->list, &xt[af].target); 65 + up(&xt[af].mutex); 66 + return ret; 67 + } 68 + EXPORT_SYMBOL(xt_register_target); 69 + 70 + void 71 + xt_unregister_target(int af, struct xt_target *target) 72 + { 73 + down(&xt[af].mutex); 74 + LIST_DELETE(&xt[af].target, target); 75 + up(&xt[af].mutex); 76 + } 77 + EXPORT_SYMBOL(xt_unregister_target); 78 + 79 + int 80 + xt_register_match(int af, struct xt_match *match) 81 + { 82 + int ret; 83 + 84 + ret = down_interruptible(&xt[af].mutex); 85 + if (ret != 0) 86 + return ret; 87 + 88 + list_add(&match->list, &xt[af].match); 89 + up(&xt[af].mutex); 90 + 91 + return ret; 92 + } 93 + EXPORT_SYMBOL(xt_register_match); 94 + 95 + void 96 + xt_unregister_match(int af, struct xt_match *match) 97 + { 98 + down(&xt[af].mutex); 99 + LIST_DELETE(&xt[af].match, match); 100 + up(&xt[af].mutex); 101 + } 102 + EXPORT_SYMBOL(xt_unregister_match); 103 + 104 + 105 + /* 106 + * These are weird, but module loading must not be done with mutex 107 + * held (since they will register), and we have to have a single 108 + * function to use try_then_request_module(). 109 + */ 110 + 111 + /* Find match, grabs ref. Returns ERR_PTR() on error. */ 112 + struct xt_match *xt_find_match(int af, const char *name, u8 revision) 113 + { 114 + struct xt_match *m; 115 + int err = 0; 116 + 117 + if (down_interruptible(&xt[af].mutex) != 0) 118 + return ERR_PTR(-EINTR); 119 + 120 + list_for_each_entry(m, &xt[af].match, list) { 121 + if (strcmp(m->name, name) == 0) { 122 + if (m->revision == revision) { 123 + if (try_module_get(m->me)) { 124 + up(&xt[af].mutex); 125 + return m; 126 + } 127 + } else 128 + err = -EPROTOTYPE; /* Found something. */ 129 + } 130 + } 131 + up(&xt[af].mutex); 132 + return ERR_PTR(err); 133 + } 134 + EXPORT_SYMBOL(xt_find_match); 135 + 136 + /* Find target, grabs ref. Returns ERR_PTR() on error. */ 137 + struct xt_target *xt_find_target(int af, const char *name, u8 revision) 138 + { 139 + struct xt_target *t; 140 + int err = 0; 141 + 142 + if (down_interruptible(&xt[af].mutex) != 0) 143 + return ERR_PTR(-EINTR); 144 + 145 + list_for_each_entry(t, &xt[af].target, list) { 146 + if (strcmp(t->name, name) == 0) { 147 + if (t->revision == revision) { 148 + if (try_module_get(t->me)) { 149 + up(&xt[af].mutex); 150 + return t; 151 + } 152 + } else 153 + err = -EPROTOTYPE; /* Found something. */ 154 + } 155 + } 156 + up(&xt[af].mutex); 157 + return ERR_PTR(err); 158 + } 159 + EXPORT_SYMBOL(xt_find_target); 160 + 161 + static const char *xt_prefix[NPROTO] = { 162 + [AF_INET] = "ipt_%s", 163 + [AF_INET6] = "ip6t_%s", 164 + [NF_ARP] = "arpt_%s", 165 + }; 166 + 167 + struct xt_target *xt_request_find_target(int af, const char *name, u8 revision) 168 + { 169 + struct xt_target *target; 170 + 171 + target = try_then_request_module(xt_find_target(af, name, revision), 172 + xt_prefix[af], name); 173 + if (IS_ERR(target) || !target) 174 + return NULL; 175 + return target; 176 + } 177 + EXPORT_SYMBOL_GPL(xt_request_find_target); 178 + 179 + static int match_revfn(int af, const char *name, u8 revision, int *bestp) 180 + { 181 + struct xt_match *m; 182 + int have_rev = 0; 183 + 184 + list_for_each_entry(m, &xt[af].match, list) { 185 + if (strcmp(m->name, name) == 0) { 186 + if (m->revision > *bestp) 187 + *bestp = m->revision; 188 + if (m->revision == revision) 189 + have_rev = 1; 190 + } 191 + } 192 + return have_rev; 193 + } 194 + 195 + static int target_revfn(int af, const char *name, u8 revision, int *bestp) 196 + { 197 + struct xt_target *t; 198 + int have_rev = 0; 199 + 200 + list_for_each_entry(t, &xt[af].target, list) { 201 + if (strcmp(t->name, name) == 0) { 202 + if (t->revision > *bestp) 203 + *bestp = t->revision; 204 + if (t->revision == revision) 205 + have_rev = 1; 206 + } 207 + } 208 + return have_rev; 209 + } 210 + 211 + /* Returns true or false (if no such extension at all) */ 212 + int xt_find_revision(int af, const char *name, u8 revision, int target, 213 + int *err) 214 + { 215 + int have_rev, best = -1; 216 + 217 + if (down_interruptible(&xt[af].mutex) != 0) { 218 + *err = -EINTR; 219 + return 1; 220 + } 221 + if (target == 1) 222 + have_rev = target_revfn(af, name, revision, &best); 223 + else 224 + have_rev = match_revfn(af, name, revision, &best); 225 + up(&xt[af].mutex); 226 + 227 + /* Nothing at all? Return 0 to try loading module. */ 228 + if (best == -1) { 229 + *err = -ENOENT; 230 + return 0; 231 + } 232 + 233 + *err = best; 234 + if (!have_rev) 235 + *err = -EPROTONOSUPPORT; 236 + return 1; 237 + } 238 + EXPORT_SYMBOL_GPL(xt_find_revision); 239 + 240 + struct xt_table_info *xt_alloc_table_info(unsigned int size) 241 + { 242 + struct xt_table_info *newinfo; 243 + int cpu; 244 + 245 + /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */ 246 + if ((SMP_ALIGN(size) >> PAGE_SHIFT) + 2 > num_physpages) 247 + return NULL; 248 + 249 + newinfo = kzalloc(sizeof(struct xt_table_info), GFP_KERNEL); 250 + if (!newinfo) 251 + return NULL; 252 + 253 + newinfo->size = size; 254 + 255 + for_each_cpu(cpu) { 256 + if (size <= PAGE_SIZE) 257 + newinfo->entries[cpu] = kmalloc_node(size, 258 + GFP_KERNEL, 259 + cpu_to_node(cpu)); 260 + else 261 + newinfo->entries[cpu] = vmalloc_node(size, 262 + cpu_to_node(cpu)); 263 + 264 + if (newinfo->entries[cpu] == NULL) { 265 + xt_free_table_info(newinfo); 266 + return NULL; 267 + } 268 + } 269 + 270 + return newinfo; 271 + } 272 + EXPORT_SYMBOL(xt_alloc_table_info); 273 + 274 + void xt_free_table_info(struct xt_table_info *info) 275 + { 276 + int cpu; 277 + 278 + for_each_cpu(cpu) { 279 + if (info->size <= PAGE_SIZE) 280 + kfree(info->entries[cpu]); 281 + else 282 + vfree(info->entries[cpu]); 283 + } 284 + kfree(info); 285 + } 286 + EXPORT_SYMBOL(xt_free_table_info); 287 + 288 + /* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ 289 + struct xt_table *xt_find_table_lock(int af, const char *name) 290 + { 291 + struct xt_table *t; 292 + 293 + if (down_interruptible(&xt[af].mutex) != 0) 294 + return ERR_PTR(-EINTR); 295 + 296 + list_for_each_entry(t, &xt[af].tables, list) 297 + if (strcmp(t->name, name) == 0 && try_module_get(t->me)) 298 + return t; 299 + up(&xt[af].mutex); 300 + return NULL; 301 + } 302 + EXPORT_SYMBOL_GPL(xt_find_table_lock); 303 + 304 + void xt_table_unlock(struct xt_table *table) 305 + { 306 + up(&xt[table->af].mutex); 307 + } 308 + EXPORT_SYMBOL_GPL(xt_table_unlock); 309 + 310 + 311 + struct xt_table_info * 312 + xt_replace_table(struct xt_table *table, 313 + unsigned int num_counters, 314 + struct xt_table_info *newinfo, 315 + int *error) 316 + { 317 + struct xt_table_info *oldinfo, *private; 318 + 319 + /* Do the substitution. */ 320 + write_lock_bh(&table->lock); 321 + private = table->private; 322 + /* Check inside lock: is the old number correct? */ 323 + if (num_counters != private->number) { 324 + duprintf("num_counters != table->private->number (%u/%u)\n", 325 + num_counters, private->number); 326 + write_unlock_bh(&table->lock); 327 + *error = -EAGAIN; 328 + return NULL; 329 + } 330 + oldinfo = private; 331 + table->private = newinfo; 332 + newinfo->initial_entries = oldinfo->initial_entries; 333 + write_unlock_bh(&table->lock); 334 + 335 + return oldinfo; 336 + } 337 + EXPORT_SYMBOL_GPL(xt_replace_table); 338 + 339 + int xt_register_table(struct xt_table *table, 340 + struct xt_table_info *bootstrap, 341 + struct xt_table_info *newinfo) 342 + { 343 + int ret; 344 + struct xt_table_info *private; 345 + 346 + ret = down_interruptible(&xt[table->af].mutex); 347 + if (ret != 0) 348 + return ret; 349 + 350 + /* Don't autoload: we'd eat our tail... */ 351 + if (list_named_find(&xt[table->af].tables, table->name)) { 352 + ret = -EEXIST; 353 + goto unlock; 354 + } 355 + 356 + /* Simplifies replace_table code. */ 357 + table->private = bootstrap; 358 + if (!xt_replace_table(table, 0, newinfo, &ret)) 359 + goto unlock; 360 + 361 + private = table->private; 362 + duprintf("table->private->number = %u\n", private->number); 363 + 364 + /* save number of initial entries */ 365 + private->initial_entries = private->number; 366 + 367 + rwlock_init(&table->lock); 368 + list_prepend(&xt[table->af].tables, table); 369 + 370 + ret = 0; 371 + unlock: 372 + up(&xt[table->af].mutex); 373 + return ret; 374 + } 375 + EXPORT_SYMBOL_GPL(xt_register_table); 376 + 377 + void *xt_unregister_table(struct xt_table *table) 378 + { 379 + struct xt_table_info *private; 380 + 381 + down(&xt[table->af].mutex); 382 + private = table->private; 383 + LIST_DELETE(&xt[table->af].tables, table); 384 + up(&xt[table->af].mutex); 385 + 386 + return private; 387 + } 388 + EXPORT_SYMBOL_GPL(xt_unregister_table); 389 + 390 + #ifdef CONFIG_PROC_FS 391 + static char *xt_proto_prefix[NPROTO] = { 392 + [AF_INET] = "ip", 393 + [AF_INET6] = "ip6", 394 + [NF_ARP] = "arp", 395 + }; 396 + 397 + static struct list_head *xt_get_idx(struct list_head *list, struct seq_file *seq, loff_t pos) 398 + { 399 + struct list_head *head = list->next; 400 + 401 + if (!head || list_empty(list)) 402 + return NULL; 403 + 404 + while (pos && (head = head->next)) { 405 + if (head == list) 406 + return NULL; 407 + pos--; 408 + } 409 + return pos ? NULL : head; 410 + } 411 + 412 + static struct list_head *type2list(u_int16_t af, u_int16_t type) 413 + { 414 + struct list_head *list; 415 + 416 + switch (type) { 417 + case TARGET: 418 + list = &xt[af].target; 419 + break; 420 + case MATCH: 421 + list = &xt[af].match; 422 + break; 423 + case TABLE: 424 + list = &xt[af].tables; 425 + break; 426 + default: 427 + list = NULL; 428 + break; 429 + } 430 + 431 + return list; 432 + } 433 + 434 + static void *xt_tgt_seq_start(struct seq_file *seq, loff_t *pos) 435 + { 436 + struct proc_dir_entry *pde = (struct proc_dir_entry *) seq->private; 437 + u_int16_t af = (unsigned long)pde->data & 0xffff; 438 + u_int16_t type = (unsigned long)pde->data >> 16; 439 + struct list_head *list; 440 + 441 + if (af >= NPROTO) 442 + return NULL; 443 + 444 + list = type2list(af, type); 445 + if (!list) 446 + return NULL; 447 + 448 + if (down_interruptible(&xt[af].mutex) != 0) 449 + return NULL; 450 + 451 + return xt_get_idx(list, seq, *pos); 452 + } 453 + 454 + static void *xt_tgt_seq_next(struct seq_file *seq, void *v, loff_t *pos) 455 + { 456 + struct proc_dir_entry *pde = seq->private; 457 + u_int16_t af = (unsigned long)pde->data & 0xffff; 458 + u_int16_t type = (unsigned long)pde->data >> 16; 459 + struct list_head *list; 460 + 461 + if (af >= NPROTO) 462 + return NULL; 463 + 464 + list = type2list(af, type); 465 + if (!list) 466 + return NULL; 467 + 468 + (*pos)++; 469 + return xt_get_idx(list, seq, *pos); 470 + } 471 + 472 + static void xt_tgt_seq_stop(struct seq_file *seq, void *v) 473 + { 474 + struct proc_dir_entry *pde = seq->private; 475 + u_int16_t af = (unsigned long)pde->data & 0xffff; 476 + 477 + up(&xt[af].mutex); 478 + } 479 + 480 + static int xt_name_seq_show(struct seq_file *seq, void *v) 481 + { 482 + char *name = (char *)v + sizeof(struct list_head); 483 + 484 + if (strlen(name)) 485 + return seq_printf(seq, "%s\n", name); 486 + else 487 + return 0; 488 + } 489 + 490 + static struct seq_operations xt_tgt_seq_ops = { 491 + .start = xt_tgt_seq_start, 492 + .next = xt_tgt_seq_next, 493 + .stop = xt_tgt_seq_stop, 494 + .show = xt_name_seq_show, 495 + }; 496 + 497 + static int xt_tgt_open(struct inode *inode, struct file *file) 498 + { 499 + int ret; 500 + 501 + ret = seq_open(file, &xt_tgt_seq_ops); 502 + if (!ret) { 503 + struct seq_file *seq = file->private_data; 504 + struct proc_dir_entry *pde = PDE(inode); 505 + 506 + seq->private = pde; 507 + } 508 + 509 + return ret; 510 + } 511 + 512 + static struct file_operations xt_file_ops = { 513 + .owner = THIS_MODULE, 514 + .open = xt_tgt_open, 515 + .read = seq_read, 516 + .llseek = seq_lseek, 517 + .release = seq_release, 518 + }; 519 + 520 + #define FORMAT_TABLES "_tables_names" 521 + #define FORMAT_MATCHES "_tables_matches" 522 + #define FORMAT_TARGETS "_tables_targets" 523 + 524 + #endif /* CONFIG_PROC_FS */ 525 + 526 + int xt_proto_init(int af) 527 + { 528 + #ifdef CONFIG_PROC_FS 529 + char buf[XT_FUNCTION_MAXNAMELEN]; 530 + struct proc_dir_entry *proc; 531 + #endif 532 + 533 + if (af >= NPROTO) 534 + return -EINVAL; 535 + 536 + 537 + #ifdef CONFIG_PROC_FS 538 + strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); 539 + strlcat(buf, FORMAT_TABLES, sizeof(buf)); 540 + proc = proc_net_fops_create(buf, 0440, &xt_file_ops); 541 + if (!proc) 542 + goto out; 543 + proc->data = (void *) ((unsigned long) af | (TABLE << 16)); 544 + 545 + 546 + strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); 547 + strlcat(buf, FORMAT_MATCHES, sizeof(buf)); 548 + proc = proc_net_fops_create(buf, 0440, &xt_file_ops); 549 + if (!proc) 550 + goto out_remove_tables; 551 + proc->data = (void *) ((unsigned long) af | (MATCH << 16)); 552 + 553 + strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); 554 + strlcat(buf, FORMAT_TARGETS, sizeof(buf)); 555 + proc = proc_net_fops_create(buf, 0440, &xt_file_ops); 556 + if (!proc) 557 + goto out_remove_matches; 558 + proc->data = (void *) ((unsigned long) af | (TARGET << 16)); 559 + #endif 560 + 561 + return 0; 562 + 563 + #ifdef CONFIG_PROC_FS 564 + out_remove_matches: 565 + strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); 566 + strlcat(buf, FORMAT_MATCHES, sizeof(buf)); 567 + proc_net_remove(buf); 568 + 569 + out_remove_tables: 570 + strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); 571 + strlcat(buf, FORMAT_TABLES, sizeof(buf)); 572 + proc_net_remove(buf); 573 + out: 574 + return -1; 575 + #endif 576 + } 577 + EXPORT_SYMBOL_GPL(xt_proto_init); 578 + 579 + void xt_proto_fini(int af) 580 + { 581 + #ifdef CONFIG_PROC_FS 582 + char buf[XT_FUNCTION_MAXNAMELEN]; 583 + 584 + strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); 585 + strlcat(buf, FORMAT_TABLES, sizeof(buf)); 586 + proc_net_remove(buf); 587 + 588 + strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); 589 + strlcat(buf, FORMAT_TARGETS, sizeof(buf)); 590 + proc_net_remove(buf); 591 + 592 + strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); 593 + strlcat(buf, FORMAT_MATCHES, sizeof(buf)); 594 + proc_net_remove(buf); 595 + #endif /*CONFIG_PROC_FS*/ 596 + } 597 + EXPORT_SYMBOL_GPL(xt_proto_fini); 598 + 599 + 600 + static int __init xt_init(void) 601 + { 602 + int i; 603 + 604 + xt = kmalloc(sizeof(struct xt_af) * NPROTO, GFP_KERNEL); 605 + if (!xt) 606 + return -ENOMEM; 607 + 608 + for (i = 0; i < NPROTO; i++) { 609 + init_MUTEX(&xt[i].mutex); 610 + INIT_LIST_HEAD(&xt[i].target); 611 + INIT_LIST_HEAD(&xt[i].match); 612 + INIT_LIST_HEAD(&xt[i].tables); 613 + } 614 + return 0; 615 + } 616 + 617 + static void __exit xt_fini(void) 618 + { 619 + kfree(xt); 620 + } 621 + 622 + module_init(xt_init); 623 + module_exit(xt_fini); 624 +
+109
net/netfilter/xt_CLASSIFY.c
··· 1 + /* 2 + * This is a module which is used for setting the skb->priority field 3 + * of an skb for qdisc classification. 4 + */ 5 + 6 + /* (C) 2001-2002 Patrick McHardy <kaber@trash.net> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #include <linux/module.h> 14 + #include <linux/skbuff.h> 15 + #include <linux/ip.h> 16 + #include <net/checksum.h> 17 + 18 + #include <linux/netfilter/x_tables.h> 19 + #include <linux/netfilter/xt_CLASSIFY.h> 20 + 21 + MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 22 + MODULE_LICENSE("GPL"); 23 + MODULE_DESCRIPTION("iptables qdisc classification target module"); 24 + MODULE_ALIAS("ipt_CLASSIFY"); 25 + 26 + static unsigned int 27 + target(struct sk_buff **pskb, 28 + const struct net_device *in, 29 + const struct net_device *out, 30 + unsigned int hooknum, 31 + const void *targinfo, 32 + void *userinfo) 33 + { 34 + const struct xt_classify_target_info *clinfo = targinfo; 35 + 36 + if ((*pskb)->priority != clinfo->priority) 37 + (*pskb)->priority = clinfo->priority; 38 + 39 + return XT_CONTINUE; 40 + } 41 + 42 + static int 43 + checkentry(const char *tablename, 44 + const void *e, 45 + void *targinfo, 46 + unsigned int targinfosize, 47 + unsigned int hook_mask) 48 + { 49 + if (targinfosize != XT_ALIGN(sizeof(struct xt_classify_target_info))){ 50 + printk(KERN_ERR "CLASSIFY: invalid size (%u != %Zu).\n", 51 + targinfosize, 52 + XT_ALIGN(sizeof(struct xt_classify_target_info))); 53 + return 0; 54 + } 55 + 56 + if (hook_mask & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) | 57 + (1 << NF_IP_POST_ROUTING))) { 58 + printk(KERN_ERR "CLASSIFY: only valid in LOCAL_OUT, FORWARD " 59 + "and POST_ROUTING.\n"); 60 + return 0; 61 + } 62 + 63 + if (strcmp(tablename, "mangle") != 0) { 64 + printk(KERN_ERR "CLASSIFY: can only be called from " 65 + "\"mangle\" table, not \"%s\".\n", 66 + tablename); 67 + return 0; 68 + } 69 + 70 + return 1; 71 + } 72 + 73 + static struct xt_target classify_reg = { 74 + .name = "CLASSIFY", 75 + .target = target, 76 + .checkentry = checkentry, 77 + .me = THIS_MODULE, 78 + }; 79 + static struct xt_target classify6_reg = { 80 + .name = "CLASSIFY", 81 + .target = target, 82 + .checkentry = checkentry, 83 + .me = THIS_MODULE, 84 + }; 85 + 86 + 87 + static int __init init(void) 88 + { 89 + int ret; 90 + 91 + ret = xt_register_target(AF_INET, &classify_reg); 92 + if (ret) 93 + return ret; 94 + 95 + ret = xt_register_target(AF_INET6, &classify6_reg); 96 + if (ret) 97 + xt_unregister_target(AF_INET, &classify_reg); 98 + 99 + return ret; 100 + } 101 + 102 + static void __exit fini(void) 103 + { 104 + xt_unregister_target(AF_INET, &classify_reg); 105 + xt_unregister_target(AF_INET6, &classify6_reg); 106 + } 107 + 108 + module_init(init); 109 + module_exit(fini);
+141
net/netfilter/xt_CONNMARK.c
··· 1 + /* This kernel module is used to modify the connection mark values, or 2 + * to optionally restore the skb nfmark from the connection mark 3 + * 4 + * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> 5 + * by Henrik Nordstrom <hno@marasystems.com> 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 as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 + */ 21 + #include <linux/module.h> 22 + #include <linux/skbuff.h> 23 + #include <linux/ip.h> 24 + #include <net/checksum.h> 25 + 26 + MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>"); 27 + MODULE_DESCRIPTION("IP tables CONNMARK matching module"); 28 + MODULE_LICENSE("GPL"); 29 + MODULE_ALIAS("ipt_CONNMARK"); 30 + 31 + #include <linux/netfilter/x_tables.h> 32 + #include <linux/netfilter/xt_CONNMARK.h> 33 + #include <net/netfilter/nf_conntrack_compat.h> 34 + 35 + static unsigned int 36 + target(struct sk_buff **pskb, 37 + const struct net_device *in, 38 + const struct net_device *out, 39 + unsigned int hooknum, 40 + const void *targinfo, 41 + void *userinfo) 42 + { 43 + const struct xt_connmark_target_info *markinfo = targinfo; 44 + u_int32_t diff; 45 + u_int32_t nfmark; 46 + u_int32_t newmark; 47 + u_int32_t ctinfo; 48 + u_int32_t *ctmark = nf_ct_get_mark(*pskb, &ctinfo); 49 + 50 + if (ctmark) { 51 + switch(markinfo->mode) { 52 + case XT_CONNMARK_SET: 53 + newmark = (*ctmark & ~markinfo->mask) | markinfo->mark; 54 + if (newmark != *ctmark) 55 + *ctmark = newmark; 56 + break; 57 + case XT_CONNMARK_SAVE: 58 + newmark = (*ctmark & ~markinfo->mask) | ((*pskb)->nfmark & markinfo->mask); 59 + if (*ctmark != newmark) 60 + *ctmark = newmark; 61 + break; 62 + case XT_CONNMARK_RESTORE: 63 + nfmark = (*pskb)->nfmark; 64 + diff = (*ctmark ^ nfmark) & markinfo->mask; 65 + if (diff != 0) 66 + (*pskb)->nfmark = nfmark ^ diff; 67 + break; 68 + } 69 + } 70 + 71 + return XT_CONTINUE; 72 + } 73 + 74 + static int 75 + checkentry(const char *tablename, 76 + const void *entry, 77 + void *targinfo, 78 + unsigned int targinfosize, 79 + unsigned int hook_mask) 80 + { 81 + struct xt_connmark_target_info *matchinfo = targinfo; 82 + if (targinfosize != XT_ALIGN(sizeof(struct xt_connmark_target_info))) { 83 + printk(KERN_WARNING "CONNMARK: targinfosize %u != %Zu\n", 84 + targinfosize, 85 + XT_ALIGN(sizeof(struct xt_connmark_target_info))); 86 + return 0; 87 + } 88 + 89 + if (matchinfo->mode == XT_CONNMARK_RESTORE) { 90 + if (strcmp(tablename, "mangle") != 0) { 91 + printk(KERN_WARNING "CONNMARK: restore can only be called from \"mangle\" table, not \"%s\"\n", tablename); 92 + return 0; 93 + } 94 + } 95 + 96 + if (matchinfo->mark > 0xffffffff || matchinfo->mask > 0xffffffff) { 97 + printk(KERN_WARNING "CONNMARK: Only supports 32bit mark\n"); 98 + return 0; 99 + } 100 + 101 + return 1; 102 + } 103 + 104 + static struct xt_target connmark_reg = { 105 + .name = "CONNMARK", 106 + .target = &target, 107 + .checkentry = &checkentry, 108 + .me = THIS_MODULE 109 + }; 110 + static struct xt_target connmark6_reg = { 111 + .name = "CONNMARK", 112 + .target = &target, 113 + .checkentry = &checkentry, 114 + .me = THIS_MODULE 115 + }; 116 + 117 + static int __init init(void) 118 + { 119 + int ret; 120 + 121 + need_conntrack(); 122 + 123 + ret = xt_register_target(AF_INET, &connmark_reg); 124 + if (ret) 125 + return ret; 126 + 127 + ret = xt_register_target(AF_INET6, &connmark6_reg); 128 + if (ret) 129 + xt_unregister_target(AF_INET, &connmark_reg); 130 + 131 + return ret; 132 + } 133 + 134 + static void __exit fini(void) 135 + { 136 + xt_unregister_target(AF_INET, &connmark_reg); 137 + xt_unregister_target(AF_INET6, &connmark6_reg); 138 + } 139 + 140 + module_init(init); 141 + module_exit(fini);
+191
net/netfilter/xt_MARK.c
··· 1 + /* This is a module which is used for setting the NFMARK field of an skb. */ 2 + 3 + /* (C) 1999-2001 Marc Boucher <marc@mbsi.ca> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License version 2 as 7 + * published by the Free Software Foundation. 8 + */ 9 + 10 + #include <linux/module.h> 11 + #include <linux/skbuff.h> 12 + #include <linux/ip.h> 13 + #include <net/checksum.h> 14 + 15 + #include <linux/netfilter/x_tables.h> 16 + #include <linux/netfilter/xt_MARK.h> 17 + 18 + MODULE_LICENSE("GPL"); 19 + MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 20 + MODULE_DESCRIPTION("ip[6]tables MARK modification module"); 21 + MODULE_ALIAS("ipt_MARK"); 22 + MODULE_ALIAS("ip6t_MARK"); 23 + 24 + static unsigned int 25 + target_v0(struct sk_buff **pskb, 26 + const struct net_device *in, 27 + const struct net_device *out, 28 + unsigned int hooknum, 29 + const void *targinfo, 30 + void *userinfo) 31 + { 32 + const struct xt_mark_target_info *markinfo = targinfo; 33 + 34 + if((*pskb)->nfmark != markinfo->mark) 35 + (*pskb)->nfmark = markinfo->mark; 36 + 37 + return XT_CONTINUE; 38 + } 39 + 40 + static unsigned int 41 + target_v1(struct sk_buff **pskb, 42 + const struct net_device *in, 43 + const struct net_device *out, 44 + unsigned int hooknum, 45 + const void *targinfo, 46 + void *userinfo) 47 + { 48 + const struct xt_mark_target_info_v1 *markinfo = targinfo; 49 + int mark = 0; 50 + 51 + switch (markinfo->mode) { 52 + case XT_MARK_SET: 53 + mark = markinfo->mark; 54 + break; 55 + 56 + case XT_MARK_AND: 57 + mark = (*pskb)->nfmark & markinfo->mark; 58 + break; 59 + 60 + case XT_MARK_OR: 61 + mark = (*pskb)->nfmark | markinfo->mark; 62 + break; 63 + } 64 + 65 + if((*pskb)->nfmark != mark) 66 + (*pskb)->nfmark = mark; 67 + 68 + return XT_CONTINUE; 69 + } 70 + 71 + 72 + static int 73 + checkentry_v0(const char *tablename, 74 + const void *entry, 75 + void *targinfo, 76 + unsigned int targinfosize, 77 + unsigned int hook_mask) 78 + { 79 + struct xt_mark_target_info *markinfo = targinfo; 80 + 81 + if (targinfosize != XT_ALIGN(sizeof(struct xt_mark_target_info))) { 82 + printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n", 83 + targinfosize, 84 + XT_ALIGN(sizeof(struct xt_mark_target_info))); 85 + return 0; 86 + } 87 + 88 + if (strcmp(tablename, "mangle") != 0) { 89 + printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename); 90 + return 0; 91 + } 92 + 93 + if (markinfo->mark > 0xffffffff) { 94 + printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n"); 95 + return 0; 96 + } 97 + 98 + return 1; 99 + } 100 + 101 + static int 102 + checkentry_v1(const char *tablename, 103 + const void *entry, 104 + void *targinfo, 105 + unsigned int targinfosize, 106 + unsigned int hook_mask) 107 + { 108 + struct xt_mark_target_info_v1 *markinfo = targinfo; 109 + 110 + if (targinfosize != XT_ALIGN(sizeof(struct xt_mark_target_info_v1))){ 111 + printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n", 112 + targinfosize, 113 + XT_ALIGN(sizeof(struct xt_mark_target_info_v1))); 114 + return 0; 115 + } 116 + 117 + if (strcmp(tablename, "mangle") != 0) { 118 + printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename); 119 + return 0; 120 + } 121 + 122 + if (markinfo->mode != XT_MARK_SET 123 + && markinfo->mode != XT_MARK_AND 124 + && markinfo->mode != XT_MARK_OR) { 125 + printk(KERN_WARNING "MARK: unknown mode %u\n", 126 + markinfo->mode); 127 + return 0; 128 + } 129 + 130 + if (markinfo->mark > 0xffffffff) { 131 + printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n"); 132 + return 0; 133 + } 134 + 135 + return 1; 136 + } 137 + 138 + static struct xt_target ipt_mark_reg_v0 = { 139 + .name = "MARK", 140 + .target = target_v0, 141 + .checkentry = checkentry_v0, 142 + .me = THIS_MODULE, 143 + .revision = 0, 144 + }; 145 + 146 + static struct xt_target ipt_mark_reg_v1 = { 147 + .name = "MARK", 148 + .target = target_v1, 149 + .checkentry = checkentry_v1, 150 + .me = THIS_MODULE, 151 + .revision = 1, 152 + }; 153 + 154 + static struct xt_target ip6t_mark_reg_v0 = { 155 + .name = "MARK", 156 + .target = target_v0, 157 + .checkentry = checkentry_v0, 158 + .me = THIS_MODULE, 159 + .revision = 0, 160 + }; 161 + 162 + static int __init init(void) 163 + { 164 + int err; 165 + 166 + err = xt_register_target(AF_INET, &ipt_mark_reg_v0); 167 + if (err) 168 + return err; 169 + 170 + err = xt_register_target(AF_INET, &ipt_mark_reg_v1); 171 + if (err) 172 + xt_unregister_target(AF_INET, &ipt_mark_reg_v0); 173 + 174 + err = xt_register_target(AF_INET6, &ip6t_mark_reg_v0); 175 + if (err) { 176 + xt_unregister_target(AF_INET, &ipt_mark_reg_v0); 177 + xt_unregister_target(AF_INET, &ipt_mark_reg_v1); 178 + } 179 + 180 + return err; 181 + } 182 + 183 + static void __exit fini(void) 184 + { 185 + xt_unregister_target(AF_INET, &ipt_mark_reg_v0); 186 + xt_unregister_target(AF_INET, &ipt_mark_reg_v1); 187 + xt_unregister_target(AF_INET6, &ip6t_mark_reg_v0); 188 + } 189 + 190 + module_init(init); 191 + module_exit(fini);
+107
net/netfilter/xt_NFQUEUE.c
··· 1 + /* iptables module for using new netfilter netlink queue 2 + * 3 + * (C) 2005 by Harald Welte <laforge@netfilter.org> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License version 2 as 7 + * published by the Free Software Foundation. 8 + * 9 + */ 10 + 11 + #include <linux/module.h> 12 + #include <linux/skbuff.h> 13 + 14 + #include <linux/netfilter.h> 15 + #include <linux/netfilter_arp.h> 16 + #include <linux/netfilter/x_tables.h> 17 + #include <linux/netfilter/xt_NFQUEUE.h> 18 + 19 + MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 20 + MODULE_DESCRIPTION("[ip,ip6,arp]_tables NFQUEUE target"); 21 + MODULE_LICENSE("GPL"); 22 + MODULE_ALIAS("ipt_NFQUEUE"); 23 + MODULE_ALIAS("ip6t_NFQUEUE"); 24 + MODULE_ALIAS("arpt_NFQUEUE"); 25 + 26 + static unsigned int 27 + target(struct sk_buff **pskb, 28 + const struct net_device *in, 29 + const struct net_device *out, 30 + unsigned int hooknum, 31 + const void *targinfo, 32 + void *userinfo) 33 + { 34 + const struct xt_NFQ_info *tinfo = targinfo; 35 + 36 + return NF_QUEUE_NR(tinfo->queuenum); 37 + } 38 + 39 + static int 40 + checkentry(const char *tablename, 41 + const void *entry, 42 + void *targinfo, 43 + unsigned int targinfosize, 44 + unsigned int hook_mask) 45 + { 46 + if (targinfosize != XT_ALIGN(sizeof(struct xt_NFQ_info))) { 47 + printk(KERN_WARNING "NFQUEUE: targinfosize %u != %Zu\n", 48 + targinfosize, 49 + XT_ALIGN(sizeof(struct xt_NFQ_info))); 50 + return 0; 51 + } 52 + 53 + return 1; 54 + } 55 + 56 + static struct xt_target ipt_NFQ_reg = { 57 + .name = "NFQUEUE", 58 + .target = target, 59 + .checkentry = checkentry, 60 + .me = THIS_MODULE, 61 + }; 62 + 63 + static struct xt_target ip6t_NFQ_reg = { 64 + .name = "NFQUEUE", 65 + .target = target, 66 + .checkentry = checkentry, 67 + .me = THIS_MODULE, 68 + }; 69 + 70 + static struct xt_target arpt_NFQ_reg = { 71 + .name = "NFQUEUE", 72 + .target = target, 73 + .checkentry = checkentry, 74 + .me = THIS_MODULE, 75 + }; 76 + 77 + static int __init init(void) 78 + { 79 + int ret; 80 + ret = xt_register_target(AF_INET, &ipt_NFQ_reg); 81 + if (ret) 82 + return ret; 83 + ret = xt_register_target(AF_INET6, &ip6t_NFQ_reg); 84 + if (ret) 85 + goto out_ip; 86 + ret = xt_register_target(NF_ARP, &arpt_NFQ_reg); 87 + if (ret) 88 + goto out_ip6; 89 + 90 + return ret; 91 + out_ip6: 92 + xt_unregister_target(AF_INET6, &ip6t_NFQ_reg); 93 + out_ip: 94 + xt_unregister_target(AF_INET, &ipt_NFQ_reg); 95 + 96 + return ret; 97 + } 98 + 99 + static void __exit fini(void) 100 + { 101 + xt_unregister_target(NF_ARP, &arpt_NFQ_reg); 102 + xt_unregister_target(AF_INET6, &ip6t_NFQ_reg); 103 + xt_unregister_target(AF_INET, &ipt_NFQ_reg); 104 + } 105 + 106 + module_init(init); 107 + module_exit(fini);
+92
net/netfilter/xt_NOTRACK.c
··· 1 + /* This is a module which is used for setting up fake conntracks 2 + * on packets so that they are not seen by the conntrack/NAT code. 3 + */ 4 + #include <linux/module.h> 5 + #include <linux/skbuff.h> 6 + 7 + #include <linux/netfilter/x_tables.h> 8 + #include <net/netfilter/nf_conntrack_compat.h> 9 + 10 + MODULE_LICENSE("GPL"); 11 + MODULE_ALIAS("ipt_NOTRACK"); 12 + 13 + static unsigned int 14 + target(struct sk_buff **pskb, 15 + const struct net_device *in, 16 + const struct net_device *out, 17 + unsigned int hooknum, 18 + const void *targinfo, 19 + void *userinfo) 20 + { 21 + /* Previously seen (loopback)? Ignore. */ 22 + if ((*pskb)->nfct != NULL) 23 + return XT_CONTINUE; 24 + 25 + /* Attach fake conntrack entry. 26 + If there is a real ct entry correspondig to this packet, 27 + it'll hang aroun till timing out. We don't deal with it 28 + for performance reasons. JK */ 29 + nf_ct_untrack(*pskb); 30 + (*pskb)->nfctinfo = IP_CT_NEW; 31 + nf_conntrack_get((*pskb)->nfct); 32 + 33 + return XT_CONTINUE; 34 + } 35 + 36 + static int 37 + checkentry(const char *tablename, 38 + const void *entry, 39 + void *targinfo, 40 + unsigned int targinfosize, 41 + unsigned int hook_mask) 42 + { 43 + if (targinfosize != 0) { 44 + printk(KERN_WARNING "NOTRACK: targinfosize %u != 0\n", 45 + targinfosize); 46 + return 0; 47 + } 48 + 49 + if (strcmp(tablename, "raw") != 0) { 50 + printk(KERN_WARNING "NOTRACK: can only be called from \"raw\" table, not \"%s\"\n", tablename); 51 + return 0; 52 + } 53 + 54 + return 1; 55 + } 56 + 57 + static struct xt_target notrack_reg = { 58 + .name = "NOTRACK", 59 + .target = target, 60 + .checkentry = checkentry, 61 + .me = THIS_MODULE, 62 + }; 63 + static struct xt_target notrack6_reg = { 64 + .name = "NOTRACK", 65 + .target = target, 66 + .checkentry = checkentry, 67 + .me = THIS_MODULE, 68 + }; 69 + 70 + static int __init init(void) 71 + { 72 + int ret; 73 + 74 + ret = xt_register_target(AF_INET, &notrack_reg); 75 + if (ret) 76 + return ret; 77 + 78 + ret = xt_register_target(AF_INET6, &notrack6_reg); 79 + if (ret) 80 + xt_unregister_target(AF_INET, &notrack_reg); 81 + 82 + return ret; 83 + } 84 + 85 + static void __exit fini(void) 86 + { 87 + xt_unregister_target(AF_INET6, &notrack6_reg); 88 + xt_unregister_target(AF_INET, &notrack_reg); 89 + } 90 + 91 + module_init(init); 92 + module_exit(fini);
+80
net/netfilter/xt_comment.c
··· 1 + /* 2 + * Implements a dummy match to allow attaching comments to rules 3 + * 4 + * 2003-05-13 Brad Fisher (brad@info-link.net) 5 + */ 6 + 7 + #include <linux/module.h> 8 + #include <linux/skbuff.h> 9 + #include <linux/netfilter/x_tables.h> 10 + #include <linux/netfilter/xt_comment.h> 11 + 12 + MODULE_AUTHOR("Brad Fisher <brad@info-link.net>"); 13 + MODULE_DESCRIPTION("iptables comment match module"); 14 + MODULE_LICENSE("GPL"); 15 + MODULE_ALIAS("ipt_comment"); 16 + MODULE_ALIAS("ip6t_comment"); 17 + 18 + static int 19 + match(const struct sk_buff *skb, 20 + const struct net_device *in, 21 + const struct net_device *out, 22 + const void *matchinfo, 23 + int offset, 24 + unsigned int protooff, 25 + int *hotdrop) 26 + { 27 + /* We always match */ 28 + return 1; 29 + } 30 + 31 + static int 32 + checkentry(const char *tablename, 33 + const void *ip, 34 + void *matchinfo, 35 + unsigned int matchsize, 36 + unsigned int hook_mask) 37 + { 38 + /* Check the size */ 39 + if (matchsize != XT_ALIGN(sizeof(struct xt_comment_info))) 40 + return 0; 41 + return 1; 42 + } 43 + 44 + static struct xt_match comment_match = { 45 + .name = "comment", 46 + .match = match, 47 + .checkentry = checkentry, 48 + .me = THIS_MODULE 49 + }; 50 + 51 + static struct xt_match comment6_match = { 52 + .name = "comment", 53 + .match = match, 54 + .checkentry = checkentry, 55 + .me = THIS_MODULE 56 + }; 57 + 58 + static int __init init(void) 59 + { 60 + int ret; 61 + 62 + ret = xt_register_match(AF_INET, &comment_match); 63 + if (ret) 64 + return ret; 65 + 66 + ret = xt_register_match(AF_INET6, &comment6_match); 67 + if (ret) 68 + xt_unregister_match(AF_INET, &comment_match); 69 + 70 + return ret; 71 + } 72 + 73 + static void __exit fini(void) 74 + { 75 + xt_unregister_match(AF_INET, &comment_match); 76 + xt_unregister_match(AF_INET6, &comment6_match); 77 + } 78 + 79 + module_init(init); 80 + module_exit(fini);
+180
net/netfilter/xt_connbytes.c
··· 1 + /* Kernel module to match connection tracking byte counter. 2 + * GPL (C) 2002 Martin Devera (devik@cdi.cz). 3 + * 4 + * 2004-07-20 Harald Welte <laforge@netfilter.org> 5 + * - reimplemented to use per-connection accounting counters 6 + * - add functionality to match number of packets 7 + * - add functionality to match average packet size 8 + * - add support to match directions seperately 9 + * 2005-10-16 Harald Welte <laforge@netfilter.org> 10 + * - Port to x_tables 11 + * 12 + */ 13 + #include <linux/module.h> 14 + #include <linux/skbuff.h> 15 + #include <net/netfilter/nf_conntrack_compat.h> 16 + #include <linux/netfilter/x_tables.h> 17 + #include <linux/netfilter/xt_connbytes.h> 18 + 19 + #include <asm/div64.h> 20 + #include <asm/bitops.h> 21 + 22 + MODULE_LICENSE("GPL"); 23 + MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 24 + MODULE_DESCRIPTION("iptables match for matching number of pkts/bytes per connection"); 25 + MODULE_ALIAS("ipt_connbytes"); 26 + 27 + /* 64bit divisor, dividend and result. dynamic precision */ 28 + static u_int64_t div64_64(u_int64_t dividend, u_int64_t divisor) 29 + { 30 + u_int32_t d = divisor; 31 + 32 + if (divisor > 0xffffffffULL) { 33 + unsigned int shift = fls(divisor >> 32); 34 + 35 + d = divisor >> shift; 36 + dividend >>= shift; 37 + } 38 + 39 + do_div(dividend, d); 40 + return dividend; 41 + } 42 + 43 + static int 44 + match(const struct sk_buff *skb, 45 + const struct net_device *in, 46 + const struct net_device *out, 47 + const void *matchinfo, 48 + int offset, 49 + unsigned int protoff, 50 + int *hotdrop) 51 + { 52 + const struct xt_connbytes_info *sinfo = matchinfo; 53 + u_int64_t what = 0; /* initialize to make gcc happy */ 54 + const struct ip_conntrack_counter *counters; 55 + 56 + if (!(counters = nf_ct_get_counters(skb))) 57 + return 0; /* no match */ 58 + 59 + switch (sinfo->what) { 60 + case XT_CONNBYTES_PKTS: 61 + switch (sinfo->direction) { 62 + case XT_CONNBYTES_DIR_ORIGINAL: 63 + what = counters[IP_CT_DIR_ORIGINAL].packets; 64 + break; 65 + case XT_CONNBYTES_DIR_REPLY: 66 + what = counters[IP_CT_DIR_REPLY].packets; 67 + break; 68 + case XT_CONNBYTES_DIR_BOTH: 69 + what = counters[IP_CT_DIR_ORIGINAL].packets; 70 + what += counters[IP_CT_DIR_REPLY].packets; 71 + break; 72 + } 73 + break; 74 + case XT_CONNBYTES_BYTES: 75 + switch (sinfo->direction) { 76 + case XT_CONNBYTES_DIR_ORIGINAL: 77 + what = counters[IP_CT_DIR_ORIGINAL].bytes; 78 + break; 79 + case XT_CONNBYTES_DIR_REPLY: 80 + what = counters[IP_CT_DIR_REPLY].bytes; 81 + break; 82 + case XT_CONNBYTES_DIR_BOTH: 83 + what = counters[IP_CT_DIR_ORIGINAL].bytes; 84 + what += counters[IP_CT_DIR_REPLY].bytes; 85 + break; 86 + } 87 + break; 88 + case XT_CONNBYTES_AVGPKT: 89 + switch (sinfo->direction) { 90 + case XT_CONNBYTES_DIR_ORIGINAL: 91 + what = div64_64(counters[IP_CT_DIR_ORIGINAL].bytes, 92 + counters[IP_CT_DIR_ORIGINAL].packets); 93 + break; 94 + case XT_CONNBYTES_DIR_REPLY: 95 + what = div64_64(counters[IP_CT_DIR_REPLY].bytes, 96 + counters[IP_CT_DIR_REPLY].packets); 97 + break; 98 + case XT_CONNBYTES_DIR_BOTH: 99 + { 100 + u_int64_t bytes; 101 + u_int64_t pkts; 102 + bytes = counters[IP_CT_DIR_ORIGINAL].bytes + 103 + counters[IP_CT_DIR_REPLY].bytes; 104 + pkts = counters[IP_CT_DIR_ORIGINAL].packets+ 105 + counters[IP_CT_DIR_REPLY].packets; 106 + 107 + /* FIXME_THEORETICAL: what to do if sum 108 + * overflows ? */ 109 + 110 + what = div64_64(bytes, pkts); 111 + } 112 + break; 113 + } 114 + break; 115 + } 116 + 117 + if (sinfo->count.to) 118 + return (what <= sinfo->count.to && what >= sinfo->count.from); 119 + else 120 + return (what >= sinfo->count.from); 121 + } 122 + 123 + static int check(const char *tablename, 124 + const void *ip, 125 + void *matchinfo, 126 + unsigned int matchsize, 127 + unsigned int hook_mask) 128 + { 129 + const struct xt_connbytes_info *sinfo = matchinfo; 130 + 131 + if (matchsize != XT_ALIGN(sizeof(struct xt_connbytes_info))) 132 + return 0; 133 + 134 + if (sinfo->what != XT_CONNBYTES_PKTS && 135 + sinfo->what != XT_CONNBYTES_BYTES && 136 + sinfo->what != XT_CONNBYTES_AVGPKT) 137 + return 0; 138 + 139 + if (sinfo->direction != XT_CONNBYTES_DIR_ORIGINAL && 140 + sinfo->direction != XT_CONNBYTES_DIR_REPLY && 141 + sinfo->direction != XT_CONNBYTES_DIR_BOTH) 142 + return 0; 143 + 144 + return 1; 145 + } 146 + 147 + static struct xt_match connbytes_match = { 148 + .name = "connbytes", 149 + .match = &match, 150 + .checkentry = &check, 151 + .me = THIS_MODULE 152 + }; 153 + static struct xt_match connbytes6_match = { 154 + .name = "connbytes", 155 + .match = &match, 156 + .checkentry = &check, 157 + .me = THIS_MODULE 158 + }; 159 + 160 + static int __init init(void) 161 + { 162 + int ret; 163 + ret = xt_register_match(AF_INET, &connbytes_match); 164 + if (ret) 165 + return ret; 166 + 167 + ret = xt_register_match(AF_INET6, &connbytes6_match); 168 + if (ret) 169 + xt_unregister_match(AF_INET, &connbytes_match); 170 + return ret; 171 + } 172 + 173 + static void __exit fini(void) 174 + { 175 + xt_unregister_match(AF_INET, &connbytes_match); 176 + xt_unregister_match(AF_INET6, &connbytes6_match); 177 + } 178 + 179 + module_init(init); 180 + module_exit(fini);
+109
net/netfilter/xt_connmark.c
··· 1 + /* This kernel module matches connection mark values set by the 2 + * CONNMARK target 3 + * 4 + * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> 5 + * by Henrik Nordstrom <hno@marasystems.com> 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 as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 + */ 21 + 22 + #include <linux/module.h> 23 + #include <linux/skbuff.h> 24 + 25 + MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>"); 26 + MODULE_DESCRIPTION("IP tables connmark match module"); 27 + MODULE_LICENSE("GPL"); 28 + MODULE_ALIAS("ipt_connmark"); 29 + 30 + #include <linux/netfilter/x_tables.h> 31 + #include <linux/netfilter/xt_connmark.h> 32 + #include <net/netfilter/nf_conntrack_compat.h> 33 + 34 + static int 35 + match(const struct sk_buff *skb, 36 + const struct net_device *in, 37 + const struct net_device *out, 38 + const void *matchinfo, 39 + int offset, 40 + unsigned int protoff, 41 + int *hotdrop) 42 + { 43 + const struct xt_connmark_info *info = matchinfo; 44 + u_int32_t ctinfo; 45 + const u_int32_t *ctmark = nf_ct_get_mark(skb, &ctinfo); 46 + if (!ctmark) 47 + return 0; 48 + 49 + return (((*ctmark) & info->mask) == info->mark) ^ info->invert; 50 + } 51 + 52 + static int 53 + checkentry(const char *tablename, 54 + const void *ip, 55 + void *matchinfo, 56 + unsigned int matchsize, 57 + unsigned int hook_mask) 58 + { 59 + struct xt_connmark_info *cm = 60 + (struct xt_connmark_info *)matchinfo; 61 + if (matchsize != XT_ALIGN(sizeof(struct xt_connmark_info))) 62 + return 0; 63 + 64 + if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) { 65 + printk(KERN_WARNING "connmark: only support 32bit mark\n"); 66 + return 0; 67 + } 68 + 69 + return 1; 70 + } 71 + 72 + static struct xt_match connmark_match = { 73 + .name = "connmark", 74 + .match = &match, 75 + .checkentry = &checkentry, 76 + .me = THIS_MODULE 77 + }; 78 + static struct xt_match connmark6_match = { 79 + .name = "connmark", 80 + .match = &match, 81 + .checkentry = &checkentry, 82 + .me = THIS_MODULE 83 + }; 84 + 85 + 86 + static int __init init(void) 87 + { 88 + int ret; 89 + 90 + need_conntrack(); 91 + 92 + ret = xt_register_match(AF_INET, &connmark_match); 93 + if (ret) 94 + return ret; 95 + 96 + ret = xt_register_match(AF_INET6, &connmark6_match); 97 + if (ret) 98 + xt_unregister_match(AF_INET, &connmark_match); 99 + return ret; 100 + } 101 + 102 + static void __exit fini(void) 103 + { 104 + xt_unregister_match(AF_INET6, &connmark6_match); 105 + xt_unregister_match(AF_INET, &connmark_match); 106 + } 107 + 108 + module_init(init); 109 + module_exit(fini);
+238
net/netfilter/xt_conntrack.c
··· 1 + /* Kernel module to match connection tracking information. 2 + * Superset of Rusty's minimalistic state match. 3 + * 4 + * (C) 2001 Marc Boucher (marc@mbsi.ca). 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + */ 10 + 11 + #include <linux/module.h> 12 + #include <linux/skbuff.h> 13 + 14 + #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) 15 + #include <linux/netfilter_ipv4/ip_conntrack.h> 16 + #include <linux/netfilter_ipv4/ip_conntrack_tuple.h> 17 + #else 18 + #include <net/netfilter/nf_conntrack.h> 19 + #endif 20 + 21 + #include <linux/netfilter/x_tables.h> 22 + #include <linux/netfilter/xt_conntrack.h> 23 + 24 + MODULE_LICENSE("GPL"); 25 + MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 26 + MODULE_DESCRIPTION("iptables connection tracking match module"); 27 + MODULE_ALIAS("ipt_conntrack"); 28 + 29 + #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) 30 + 31 + static int 32 + match(const struct sk_buff *skb, 33 + const struct net_device *in, 34 + const struct net_device *out, 35 + const void *matchinfo, 36 + int offset, 37 + unsigned int protoff, 38 + int *hotdrop) 39 + { 40 + const struct xt_conntrack_info *sinfo = matchinfo; 41 + struct ip_conntrack *ct; 42 + enum ip_conntrack_info ctinfo; 43 + unsigned int statebit; 44 + 45 + ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo); 46 + 47 + #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg)) 48 + 49 + if (ct == &ip_conntrack_untracked) 50 + statebit = XT_CONNTRACK_STATE_UNTRACKED; 51 + else if (ct) 52 + statebit = XT_CONNTRACK_STATE_BIT(ctinfo); 53 + else 54 + statebit = XT_CONNTRACK_STATE_INVALID; 55 + 56 + if(sinfo->flags & XT_CONNTRACK_STATE) { 57 + if (ct) { 58 + if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip != 59 + ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip) 60 + statebit |= XT_CONNTRACK_STATE_SNAT; 61 + 62 + if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip != 63 + ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip) 64 + statebit |= XT_CONNTRACK_STATE_DNAT; 65 + } 66 + 67 + if (FWINV((statebit & sinfo->statemask) == 0, XT_CONNTRACK_STATE)) 68 + return 0; 69 + } 70 + 71 + if(sinfo->flags & XT_CONNTRACK_PROTO) { 72 + if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, XT_CONNTRACK_PROTO)) 73 + return 0; 74 + } 75 + 76 + if(sinfo->flags & XT_CONNTRACK_ORIGSRC) { 77 + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip&sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, XT_CONNTRACK_ORIGSRC)) 78 + return 0; 79 + } 80 + 81 + if(sinfo->flags & XT_CONNTRACK_ORIGDST) { 82 + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip&sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, XT_CONNTRACK_ORIGDST)) 83 + return 0; 84 + } 85 + 86 + if(sinfo->flags & XT_CONNTRACK_REPLSRC) { 87 + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip&sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].src.ip, XT_CONNTRACK_REPLSRC)) 88 + return 0; 89 + } 90 + 91 + if(sinfo->flags & XT_CONNTRACK_REPLDST) { 92 + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip&sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, XT_CONNTRACK_REPLDST)) 93 + return 0; 94 + } 95 + 96 + if(sinfo->flags & XT_CONNTRACK_STATUS) { 97 + if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, XT_CONNTRACK_STATUS)) 98 + return 0; 99 + } 100 + 101 + if(sinfo->flags & XT_CONNTRACK_EXPIRES) { 102 + unsigned long expires; 103 + 104 + if(!ct) 105 + return 0; 106 + 107 + expires = timer_pending(&ct->timeout) ? (ct->timeout.expires - jiffies)/HZ : 0; 108 + 109 + if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), XT_CONNTRACK_EXPIRES)) 110 + return 0; 111 + } 112 + 113 + return 1; 114 + } 115 + 116 + #else /* CONFIG_IP_NF_CONNTRACK */ 117 + static int 118 + match(const struct sk_buff *skb, 119 + const struct net_device *in, 120 + const struct net_device *out, 121 + const void *matchinfo, 122 + int offset, 123 + unsigned int protoff, 124 + int *hotdrop) 125 + { 126 + const struct xt_conntrack_info *sinfo = matchinfo; 127 + struct nf_conn *ct; 128 + enum ip_conntrack_info ctinfo; 129 + unsigned int statebit; 130 + 131 + ct = nf_ct_get((struct sk_buff *)skb, &ctinfo); 132 + 133 + #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg)) 134 + 135 + if (ct == &nf_conntrack_untracked) 136 + statebit = XT_CONNTRACK_STATE_UNTRACKED; 137 + else if (ct) 138 + statebit = XT_CONNTRACK_STATE_BIT(ctinfo); 139 + else 140 + statebit = XT_CONNTRACK_STATE_INVALID; 141 + 142 + if(sinfo->flags & XT_CONNTRACK_STATE) { 143 + if (ct) { 144 + if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip != 145 + ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip) 146 + statebit |= XT_CONNTRACK_STATE_SNAT; 147 + 148 + if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip != 149 + ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip) 150 + statebit |= XT_CONNTRACK_STATE_DNAT; 151 + } 152 + 153 + if (FWINV((statebit & sinfo->statemask) == 0, XT_CONNTRACK_STATE)) 154 + return 0; 155 + } 156 + 157 + if(sinfo->flags & XT_CONNTRACK_PROTO) { 158 + if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, XT_CONNTRACK_PROTO)) 159 + return 0; 160 + } 161 + 162 + if(sinfo->flags & XT_CONNTRACK_ORIGSRC) { 163 + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, XT_CONNTRACK_ORIGSRC)) 164 + return 0; 165 + } 166 + 167 + if(sinfo->flags & XT_CONNTRACK_ORIGDST) { 168 + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, XT_CONNTRACK_ORIGDST)) 169 + return 0; 170 + } 171 + 172 + if(sinfo->flags & XT_CONNTRACK_REPLSRC) { 173 + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].src.ip, XT_CONNTRACK_REPLSRC)) 174 + return 0; 175 + } 176 + 177 + if(sinfo->flags & XT_CONNTRACK_REPLDST) { 178 + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, XT_CONNTRACK_REPLDST)) 179 + return 0; 180 + } 181 + 182 + if(sinfo->flags & XT_CONNTRACK_STATUS) { 183 + if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, XT_CONNTRACK_STATUS)) 184 + return 0; 185 + } 186 + 187 + if(sinfo->flags & XT_CONNTRACK_EXPIRES) { 188 + unsigned long expires; 189 + 190 + if(!ct) 191 + return 0; 192 + 193 + expires = timer_pending(&ct->timeout) ? (ct->timeout.expires - jiffies)/HZ : 0; 194 + 195 + if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), XT_CONNTRACK_EXPIRES)) 196 + return 0; 197 + } 198 + 199 + return 1; 200 + } 201 + 202 + #endif /* CONFIG_NF_IP_CONNTRACK */ 203 + 204 + static int check(const char *tablename, 205 + const void *ip, 206 + void *matchinfo, 207 + unsigned int matchsize, 208 + unsigned int hook_mask) 209 + { 210 + if (matchsize != XT_ALIGN(sizeof(struct xt_conntrack_info))) 211 + return 0; 212 + 213 + return 1; 214 + } 215 + 216 + static struct xt_match conntrack_match = { 217 + .name = "conntrack", 218 + .match = &match, 219 + .checkentry = &check, 220 + .me = THIS_MODULE, 221 + }; 222 + 223 + static int __init init(void) 224 + { 225 + int ret; 226 + need_conntrack(); 227 + ret = xt_register_match(AF_INET, &conntrack_match); 228 + 229 + return ret; 230 + } 231 + 232 + static void __exit fini(void) 233 + { 234 + xt_unregister_match(AF_INET, &conntrack_match); 235 + } 236 + 237 + module_init(init); 238 + module_exit(fini);
+221
net/netfilter/xt_dccp.c
··· 1 + /* 2 + * iptables module for DCCP protocol header matching 3 + * 4 + * (C) 2005 by Harald Welte <laforge@netfilter.org> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + */ 10 + 11 + #include <linux/module.h> 12 + #include <linux/skbuff.h> 13 + #include <linux/spinlock.h> 14 + #include <net/ip.h> 15 + #include <linux/dccp.h> 16 + 17 + #include <linux/netfilter/x_tables.h> 18 + #include <linux/netfilter/xt_dccp.h> 19 + 20 + #include <linux/netfilter_ipv4/ip_tables.h> 21 + #include <linux/netfilter_ipv6/ip6_tables.h> 22 + 23 + MODULE_LICENSE("GPL"); 24 + MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 25 + MODULE_DESCRIPTION("Match for DCCP protocol packets"); 26 + MODULE_ALIAS("ipt_dccp"); 27 + 28 + #define DCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \ 29 + || (!!((invflag) & (option)) ^ (cond))) 30 + 31 + static unsigned char *dccp_optbuf; 32 + static DEFINE_SPINLOCK(dccp_buflock); 33 + 34 + static inline int 35 + dccp_find_option(u_int8_t option, 36 + const struct sk_buff *skb, 37 + unsigned int protoff, 38 + const struct dccp_hdr *dh, 39 + int *hotdrop) 40 + { 41 + /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ 42 + unsigned char *op; 43 + unsigned int optoff = __dccp_hdr_len(dh); 44 + unsigned int optlen = dh->dccph_doff*4 - __dccp_hdr_len(dh); 45 + unsigned int i; 46 + 47 + if (dh->dccph_doff * 4 < __dccp_hdr_len(dh)) { 48 + *hotdrop = 1; 49 + return 0; 50 + } 51 + 52 + if (!optlen) 53 + return 0; 54 + 55 + spin_lock_bh(&dccp_buflock); 56 + op = skb_header_pointer(skb, protoff + optoff, optlen, dccp_optbuf); 57 + if (op == NULL) { 58 + /* If we don't have the whole header, drop packet. */ 59 + spin_unlock_bh(&dccp_buflock); 60 + *hotdrop = 1; 61 + return 0; 62 + } 63 + 64 + for (i = 0; i < optlen; ) { 65 + if (op[i] == option) { 66 + spin_unlock_bh(&dccp_buflock); 67 + return 1; 68 + } 69 + 70 + if (op[i] < 2) 71 + i++; 72 + else 73 + i += op[i+1]?:1; 74 + } 75 + 76 + spin_unlock_bh(&dccp_buflock); 77 + return 0; 78 + } 79 + 80 + 81 + static inline int 82 + match_types(const struct dccp_hdr *dh, u_int16_t typemask) 83 + { 84 + return (typemask & (1 << dh->dccph_type)); 85 + } 86 + 87 + static inline int 88 + match_option(u_int8_t option, const struct sk_buff *skb, unsigned int protoff, 89 + const struct dccp_hdr *dh, int *hotdrop) 90 + { 91 + return dccp_find_option(option, skb, protoff, dh, hotdrop); 92 + } 93 + 94 + static int 95 + match(const struct sk_buff *skb, 96 + const struct net_device *in, 97 + const struct net_device *out, 98 + const void *matchinfo, 99 + int offset, 100 + unsigned int protoff, 101 + int *hotdrop) 102 + { 103 + const struct xt_dccp_info *info = 104 + (const struct xt_dccp_info *)matchinfo; 105 + struct dccp_hdr _dh, *dh; 106 + 107 + if (offset) 108 + return 0; 109 + 110 + dh = skb_header_pointer(skb, protoff, sizeof(_dh), &_dh); 111 + if (dh == NULL) { 112 + *hotdrop = 1; 113 + return 0; 114 + } 115 + 116 + return DCCHECK(((ntohs(dh->dccph_sport) >= info->spts[0]) 117 + && (ntohs(dh->dccph_sport) <= info->spts[1])), 118 + XT_DCCP_SRC_PORTS, info->flags, info->invflags) 119 + && DCCHECK(((ntohs(dh->dccph_dport) >= info->dpts[0]) 120 + && (ntohs(dh->dccph_dport) <= info->dpts[1])), 121 + XT_DCCP_DEST_PORTS, info->flags, info->invflags) 122 + && DCCHECK(match_types(dh, info->typemask), 123 + XT_DCCP_TYPE, info->flags, info->invflags) 124 + && DCCHECK(match_option(info->option, skb, protoff, dh, 125 + hotdrop), 126 + XT_DCCP_OPTION, info->flags, info->invflags); 127 + } 128 + 129 + static int 130 + checkentry(const char *tablename, 131 + const void *inf, 132 + void *matchinfo, 133 + unsigned int matchsize, 134 + unsigned int hook_mask) 135 + { 136 + const struct ipt_ip *ip = inf; 137 + const struct xt_dccp_info *info; 138 + 139 + info = (const struct xt_dccp_info *)matchinfo; 140 + 141 + return ip->proto == IPPROTO_DCCP 142 + && !(ip->invflags & XT_INV_PROTO) 143 + && matchsize == XT_ALIGN(sizeof(struct xt_dccp_info)) 144 + && !(info->flags & ~XT_DCCP_VALID_FLAGS) 145 + && !(info->invflags & ~XT_DCCP_VALID_FLAGS) 146 + && !(info->invflags & ~info->flags); 147 + } 148 + 149 + static int 150 + checkentry6(const char *tablename, 151 + const void *inf, 152 + void *matchinfo, 153 + unsigned int matchsize, 154 + unsigned int hook_mask) 155 + { 156 + const struct ip6t_ip6 *ip = inf; 157 + const struct xt_dccp_info *info; 158 + 159 + info = (const struct xt_dccp_info *)matchinfo; 160 + 161 + return ip->proto == IPPROTO_DCCP 162 + && !(ip->invflags & XT_INV_PROTO) 163 + && matchsize == XT_ALIGN(sizeof(struct xt_dccp_info)) 164 + && !(info->flags & ~XT_DCCP_VALID_FLAGS) 165 + && !(info->invflags & ~XT_DCCP_VALID_FLAGS) 166 + && !(info->invflags & ~info->flags); 167 + } 168 + 169 + 170 + static struct xt_match dccp_match = 171 + { 172 + .name = "dccp", 173 + .match = &match, 174 + .checkentry = &checkentry, 175 + .me = THIS_MODULE, 176 + }; 177 + static struct xt_match dccp6_match = 178 + { 179 + .name = "dccp", 180 + .match = &match, 181 + .checkentry = &checkentry6, 182 + .me = THIS_MODULE, 183 + }; 184 + 185 + 186 + static int __init init(void) 187 + { 188 + int ret; 189 + 190 + /* doff is 8 bits, so the maximum option size is (4*256). Don't put 191 + * this in BSS since DaveM is worried about locked TLB's for kernel 192 + * BSS. */ 193 + dccp_optbuf = kmalloc(256 * 4, GFP_KERNEL); 194 + if (!dccp_optbuf) 195 + return -ENOMEM; 196 + ret = xt_register_match(AF_INET, &dccp_match); 197 + if (ret) 198 + goto out_kfree; 199 + ret = xt_register_match(AF_INET6, &dccp6_match); 200 + if (ret) 201 + goto out_unreg; 202 + 203 + return ret; 204 + 205 + out_unreg: 206 + xt_unregister_match(AF_INET, &dccp_match); 207 + out_kfree: 208 + kfree(dccp_optbuf); 209 + 210 + return ret; 211 + } 212 + 213 + static void __exit fini(void) 214 + { 215 + xt_unregister_match(AF_INET6, &dccp6_match); 216 + xt_unregister_match(AF_INET, &dccp_match); 217 + kfree(dccp_optbuf); 218 + } 219 + 220 + module_init(init); 221 + module_exit(fini);
+188
net/netfilter/xt_helper.c
··· 1 + /* iptables module to match on related connections */ 2 + /* 3 + * (C) 2001 Martin Josefsson <gandalf@wlug.westbo.se> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License version 2 as 7 + * published by the Free Software Foundation. 8 + * 9 + * 19 Mar 2002 Harald Welte <laforge@gnumonks.org>: 10 + * - Port to newnat infrastructure 11 + */ 12 + 13 + #include <linux/module.h> 14 + #include <linux/skbuff.h> 15 + #include <linux/netfilter.h> 16 + #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) 17 + #include <linux/netfilter_ipv4/ip_conntrack.h> 18 + #include <linux/netfilter_ipv4/ip_conntrack_core.h> 19 + #include <linux/netfilter_ipv4/ip_conntrack_helper.h> 20 + #else 21 + #include <net/netfilter/nf_conntrack.h> 22 + #include <net/netfilter/nf_conntrack_core.h> 23 + #include <net/netfilter/nf_conntrack_helper.h> 24 + #endif 25 + #include <linux/netfilter/x_tables.h> 26 + #include <linux/netfilter/xt_helper.h> 27 + 28 + MODULE_LICENSE("GPL"); 29 + MODULE_AUTHOR("Martin Josefsson <gandalf@netfilter.org>"); 30 + MODULE_DESCRIPTION("iptables helper match module"); 31 + MODULE_ALIAS("ipt_helper"); 32 + MODULE_ALIAS("ip6t_helper"); 33 + 34 + #if 0 35 + #define DEBUGP printk 36 + #else 37 + #define DEBUGP(format, args...) 38 + #endif 39 + 40 + #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) 41 + static int 42 + match(const struct sk_buff *skb, 43 + const struct net_device *in, 44 + const struct net_device *out, 45 + const void *matchinfo, 46 + int offset, 47 + unsigned int protoff, 48 + int *hotdrop) 49 + { 50 + const struct xt_helper_info *info = matchinfo; 51 + struct ip_conntrack *ct; 52 + enum ip_conntrack_info ctinfo; 53 + int ret = info->invert; 54 + 55 + ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo); 56 + if (!ct) { 57 + DEBUGP("xt_helper: Eek! invalid conntrack?\n"); 58 + return ret; 59 + } 60 + 61 + if (!ct->master) { 62 + DEBUGP("xt_helper: conntrack %p has no master\n", ct); 63 + return ret; 64 + } 65 + 66 + read_lock_bh(&ip_conntrack_lock); 67 + if (!ct->master->helper) { 68 + DEBUGP("xt_helper: master ct %p has no helper\n", 69 + exp->expectant); 70 + goto out_unlock; 71 + } 72 + 73 + DEBUGP("master's name = %s , info->name = %s\n", 74 + ct->master->helper->name, info->name); 75 + 76 + if (info->name[0] == '\0') 77 + ret ^= 1; 78 + else 79 + ret ^= !strncmp(ct->master->helper->name, info->name, 80 + strlen(ct->master->helper->name)); 81 + out_unlock: 82 + read_unlock_bh(&ip_conntrack_lock); 83 + return ret; 84 + } 85 + 86 + #else /* CONFIG_IP_NF_CONNTRACK */ 87 + 88 + static int 89 + match(const struct sk_buff *skb, 90 + const struct net_device *in, 91 + const struct net_device *out, 92 + const void *matchinfo, 93 + int offset, 94 + unsigned int protoff, 95 + int *hotdrop) 96 + { 97 + const struct xt_helper_info *info = matchinfo; 98 + struct nf_conn *ct; 99 + enum ip_conntrack_info ctinfo; 100 + int ret = info->invert; 101 + 102 + ct = nf_ct_get((struct sk_buff *)skb, &ctinfo); 103 + if (!ct) { 104 + DEBUGP("xt_helper: Eek! invalid conntrack?\n"); 105 + return ret; 106 + } 107 + 108 + if (!ct->master) { 109 + DEBUGP("xt_helper: conntrack %p has no master\n", ct); 110 + return ret; 111 + } 112 + 113 + read_lock_bh(&nf_conntrack_lock); 114 + if (!ct->master->helper) { 115 + DEBUGP("xt_helper: master ct %p has no helper\n", 116 + exp->expectant); 117 + goto out_unlock; 118 + } 119 + 120 + DEBUGP("master's name = %s , info->name = %s\n", 121 + ct->master->helper->name, info->name); 122 + 123 + if (info->name[0] == '\0') 124 + ret ^= 1; 125 + else 126 + ret ^= !strncmp(ct->master->helper->name, info->name, 127 + strlen(ct->master->helper->name)); 128 + out_unlock: 129 + read_unlock_bh(&nf_conntrack_lock); 130 + return ret; 131 + } 132 + #endif 133 + 134 + static int check(const char *tablename, 135 + const void *inf, 136 + void *matchinfo, 137 + unsigned int matchsize, 138 + unsigned int hook_mask) 139 + { 140 + struct xt_helper_info *info = matchinfo; 141 + 142 + info->name[29] = '\0'; 143 + 144 + /* verify size */ 145 + if (matchsize != XT_ALIGN(sizeof(struct xt_helper_info))) 146 + return 0; 147 + 148 + return 1; 149 + } 150 + 151 + static struct xt_match helper_match = { 152 + .name = "helper", 153 + .match = &match, 154 + .checkentry = &check, 155 + .me = THIS_MODULE, 156 + }; 157 + static struct xt_match helper6_match = { 158 + .name = "helper", 159 + .match = &match, 160 + .checkentry = &check, 161 + .me = THIS_MODULE, 162 + }; 163 + 164 + static int __init init(void) 165 + { 166 + int ret; 167 + need_conntrack(); 168 + 169 + ret = xt_register_match(AF_INET, &helper_match); 170 + if (ret < 0) 171 + return ret; 172 + 173 + ret = xt_register_match(AF_INET6, &helper6_match); 174 + if (ret < 0) 175 + xt_unregister_match(AF_INET, &helper_match); 176 + 177 + return ret; 178 + } 179 + 180 + static void __exit fini(void) 181 + { 182 + xt_unregister_match(AF_INET, &helper_match); 183 + xt_unregister_match(AF_INET6, &helper6_match); 184 + } 185 + 186 + module_init(init); 187 + module_exit(fini); 188 +
+98
net/netfilter/xt_length.c
··· 1 + /* Kernel module to match packet length. */ 2 + /* (C) 1999-2001 James Morris <jmorros@intercode.com.au> 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + */ 8 + 9 + #include <linux/module.h> 10 + #include <linux/skbuff.h> 11 + #include <net/ip.h> 12 + 13 + #include <linux/netfilter/xt_length.h> 14 + #include <linux/netfilter/x_tables.h> 15 + 16 + MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); 17 + MODULE_DESCRIPTION("IP tables packet length matching module"); 18 + MODULE_LICENSE("GPL"); 19 + MODULE_ALIAS("ipt_length"); 20 + MODULE_ALIAS("ip6t_length"); 21 + 22 + static int 23 + match(const struct sk_buff *skb, 24 + const struct net_device *in, 25 + const struct net_device *out, 26 + const void *matchinfo, 27 + int offset, 28 + unsigned int protoff, 29 + int *hotdrop) 30 + { 31 + const struct xt_length_info *info = matchinfo; 32 + u_int16_t pktlen = ntohs(skb->nh.iph->tot_len); 33 + 34 + return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; 35 + } 36 + 37 + static int 38 + match6(const struct sk_buff *skb, 39 + const struct net_device *in, 40 + const struct net_device *out, 41 + const void *matchinfo, 42 + int offset, 43 + unsigned int protoff, 44 + int *hotdrop) 45 + { 46 + const struct xt_length_info *info = matchinfo; 47 + u_int16_t pktlen = ntohs(skb->nh.ipv6h->payload_len) + sizeof(struct ipv6hdr); 48 + 49 + return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; 50 + } 51 + 52 + static int 53 + checkentry(const char *tablename, 54 + const void *ip, 55 + void *matchinfo, 56 + unsigned int matchsize, 57 + unsigned int hook_mask) 58 + { 59 + if (matchsize != XT_ALIGN(sizeof(struct xt_length_info))) 60 + return 0; 61 + 62 + return 1; 63 + } 64 + 65 + static struct xt_match length_match = { 66 + .name = "length", 67 + .match = &match, 68 + .checkentry = &checkentry, 69 + .me = THIS_MODULE, 70 + }; 71 + static struct xt_match length6_match = { 72 + .name = "length", 73 + .match = &match6, 74 + .checkentry = &checkentry, 75 + .me = THIS_MODULE, 76 + }; 77 + 78 + static int __init init(void) 79 + { 80 + int ret; 81 + ret = xt_register_match(AF_INET, &length_match); 82 + if (ret) 83 + return ret; 84 + ret = xt_register_match(AF_INET6, &length6_match); 85 + if (ret) 86 + xt_unregister_match(AF_INET, &length_match); 87 + 88 + return ret; 89 + } 90 + 91 + static void __exit fini(void) 92 + { 93 + xt_unregister_match(AF_INET, &length_match); 94 + xt_unregister_match(AF_INET6, &length6_match); 95 + } 96 + 97 + module_init(init); 98 + module_exit(fini);
+175
net/netfilter/xt_limit.c
··· 1 + /* Kernel module to control the rate 2 + * 3 + * 2 September 1999: Changed from the target RATE to the match 4 + * `limit', removed logging. Did I mention that 5 + * Alexey is a fucking genius? 6 + * Rusty Russell (rusty@rustcorp.com.au). */ 7 + 8 + /* (C) 1999 J�r�me de Vivie <devivie@info.enserb.u-bordeaux.fr> 9 + * (C) 1999 Herv� Eychenne <eychenne@info.enserb.u-bordeaux.fr> 10 + * 11 + * This program is free software; you can redistribute it and/or modify 12 + * it under the terms of the GNU General Public License version 2 as 13 + * published by the Free Software Foundation. 14 + */ 15 + 16 + #include <linux/module.h> 17 + #include <linux/skbuff.h> 18 + #include <linux/spinlock.h> 19 + #include <linux/interrupt.h> 20 + 21 + #include <linux/netfilter/x_tables.h> 22 + #include <linux/netfilter/xt_limit.h> 23 + 24 + MODULE_LICENSE("GPL"); 25 + MODULE_AUTHOR("Herve Eychenne <rv@wallfire.org>"); 26 + MODULE_DESCRIPTION("iptables rate limit match"); 27 + MODULE_ALIAS("ipt_limit"); 28 + MODULE_ALIAS("ip6t_limit"); 29 + 30 + /* The algorithm used is the Simple Token Bucket Filter (TBF) 31 + * see net/sched/sch_tbf.c in the linux source tree 32 + */ 33 + 34 + static DEFINE_SPINLOCK(limit_lock); 35 + 36 + /* Rusty: This is my (non-mathematically-inclined) understanding of 37 + this algorithm. The `average rate' in jiffies becomes your initial 38 + amount of credit `credit' and the most credit you can ever have 39 + `credit_cap'. The `peak rate' becomes the cost of passing the 40 + test, `cost'. 41 + 42 + `prev' tracks the last packet hit: you gain one credit per jiffy. 43 + If you get credit balance more than this, the extra credit is 44 + discarded. Every time the match passes, you lose `cost' credits; 45 + if you don't have that many, the test fails. 46 + 47 + See Alexey's formal explanation in net/sched/sch_tbf.c. 48 + 49 + To get the maxmum range, we multiply by this factor (ie. you get N 50 + credits per jiffy). We want to allow a rate as low as 1 per day 51 + (slowest userspace tool allows), which means 52 + CREDITS_PER_JIFFY*HZ*60*60*24 < 2^32. ie. */ 53 + #define MAX_CPJ (0xFFFFFFFF / (HZ*60*60*24)) 54 + 55 + /* Repeated shift and or gives us all 1s, final shift and add 1 gives 56 + * us the power of 2 below the theoretical max, so GCC simply does a 57 + * shift. */ 58 + #define _POW2_BELOW2(x) ((x)|((x)>>1)) 59 + #define _POW2_BELOW4(x) (_POW2_BELOW2(x)|_POW2_BELOW2((x)>>2)) 60 + #define _POW2_BELOW8(x) (_POW2_BELOW4(x)|_POW2_BELOW4((x)>>4)) 61 + #define _POW2_BELOW16(x) (_POW2_BELOW8(x)|_POW2_BELOW8((x)>>8)) 62 + #define _POW2_BELOW32(x) (_POW2_BELOW16(x)|_POW2_BELOW16((x)>>16)) 63 + #define POW2_BELOW32(x) ((_POW2_BELOW32(x)>>1) + 1) 64 + 65 + #define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ) 66 + 67 + static int 68 + ipt_limit_match(const struct sk_buff *skb, 69 + const struct net_device *in, 70 + const struct net_device *out, 71 + const void *matchinfo, 72 + int offset, 73 + unsigned int protoff, 74 + int *hotdrop) 75 + { 76 + struct xt_rateinfo *r = ((struct xt_rateinfo *)matchinfo)->master; 77 + unsigned long now = jiffies; 78 + 79 + spin_lock_bh(&limit_lock); 80 + r->credit += (now - xchg(&r->prev, now)) * CREDITS_PER_JIFFY; 81 + if (r->credit > r->credit_cap) 82 + r->credit = r->credit_cap; 83 + 84 + if (r->credit >= r->cost) { 85 + /* We're not limited. */ 86 + r->credit -= r->cost; 87 + spin_unlock_bh(&limit_lock); 88 + return 1; 89 + } 90 + 91 + spin_unlock_bh(&limit_lock); 92 + return 0; 93 + } 94 + 95 + /* Precision saver. */ 96 + static u_int32_t 97 + user2credits(u_int32_t user) 98 + { 99 + /* If multiplying would overflow... */ 100 + if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY)) 101 + /* Divide first. */ 102 + return (user / XT_LIMIT_SCALE) * HZ * CREDITS_PER_JIFFY; 103 + 104 + return (user * HZ * CREDITS_PER_JIFFY) / XT_LIMIT_SCALE; 105 + } 106 + 107 + static int 108 + ipt_limit_checkentry(const char *tablename, 109 + const void *inf, 110 + void *matchinfo, 111 + unsigned int matchsize, 112 + unsigned int hook_mask) 113 + { 114 + struct xt_rateinfo *r = matchinfo; 115 + 116 + if (matchsize != XT_ALIGN(sizeof(struct xt_rateinfo))) 117 + return 0; 118 + 119 + /* Check for overflow. */ 120 + if (r->burst == 0 121 + || user2credits(r->avg * r->burst) < user2credits(r->avg)) { 122 + printk("Overflow in xt_limit, try lower: %u/%u\n", 123 + r->avg, r->burst); 124 + return 0; 125 + } 126 + 127 + /* User avg in seconds * XT_LIMIT_SCALE: convert to jiffies * 128 + 128. */ 129 + r->prev = jiffies; 130 + r->credit = user2credits(r->avg * r->burst); /* Credits full. */ 131 + r->credit_cap = user2credits(r->avg * r->burst); /* Credits full. */ 132 + r->cost = user2credits(r->avg); 133 + 134 + /* For SMP, we only want to use one set of counters. */ 135 + r->master = r; 136 + 137 + return 1; 138 + } 139 + 140 + static struct xt_match ipt_limit_reg = { 141 + .name = "limit", 142 + .match = ipt_limit_match, 143 + .checkentry = ipt_limit_checkentry, 144 + .me = THIS_MODULE, 145 + }; 146 + static struct xt_match limit6_reg = { 147 + .name = "limit", 148 + .match = ipt_limit_match, 149 + .checkentry = ipt_limit_checkentry, 150 + .me = THIS_MODULE, 151 + }; 152 + 153 + static int __init init(void) 154 + { 155 + int ret; 156 + 157 + ret = xt_register_match(AF_INET, &ipt_limit_reg); 158 + if (ret) 159 + return ret; 160 + 161 + ret = xt_register_match(AF_INET6, &limit6_reg); 162 + if (ret) 163 + xt_unregister_match(AF_INET, &ipt_limit_reg); 164 + 165 + return ret; 166 + } 167 + 168 + static void __exit fini(void) 169 + { 170 + xt_unregister_match(AF_INET, &ipt_limit_reg); 171 + xt_unregister_match(AF_INET6, &limit6_reg); 172 + } 173 + 174 + module_init(init); 175 + module_exit(fini);
+100
net/netfilter/xt_mac.c
··· 1 + /* Kernel module to match MAC address parameters. */ 2 + 3 + /* (C) 1999-2001 Paul `Rusty' Russell 4 + * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + */ 10 + 11 + #include <linux/module.h> 12 + #include <linux/skbuff.h> 13 + #include <linux/if_ether.h> 14 + #include <linux/etherdevice.h> 15 + 16 + #include <linux/netfilter_ipv4.h> 17 + #include <linux/netfilter/xt_mac.h> 18 + #include <linux/netfilter/x_tables.h> 19 + 20 + MODULE_LICENSE("GPL"); 21 + MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 22 + MODULE_DESCRIPTION("iptables mac matching module"); 23 + MODULE_ALIAS("ipt_mac"); 24 + MODULE_ALIAS("ip6t_mac"); 25 + 26 + static int 27 + match(const struct sk_buff *skb, 28 + const struct net_device *in, 29 + const struct net_device *out, 30 + const void *matchinfo, 31 + int offset, 32 + unsigned int protoff, 33 + int *hotdrop) 34 + { 35 + const struct xt_mac_info *info = matchinfo; 36 + 37 + /* Is mac pointer valid? */ 38 + return (skb->mac.raw >= skb->head 39 + && (skb->mac.raw + ETH_HLEN) <= skb->data 40 + /* If so, compare... */ 41 + && ((!compare_ether_addr(eth_hdr(skb)->h_source, info->srcaddr)) 42 + ^ info->invert)); 43 + } 44 + 45 + static int 46 + ipt_mac_checkentry(const char *tablename, 47 + const void *inf, 48 + void *matchinfo, 49 + unsigned int matchsize, 50 + unsigned int hook_mask) 51 + { 52 + /* FORWARD isn't always valid, but it's nice to be able to do --RR */ 53 + if (hook_mask 54 + & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) 55 + | (1 << NF_IP_FORWARD))) { 56 + printk("xt_mac: only valid for PRE_ROUTING, LOCAL_IN or FORWARD.\n"); 57 + return 0; 58 + } 59 + 60 + if (matchsize != XT_ALIGN(sizeof(struct xt_mac_info))) 61 + return 0; 62 + 63 + return 1; 64 + } 65 + 66 + static struct xt_match mac_match = { 67 + .name = "mac", 68 + .match = &match, 69 + .checkentry = &ipt_mac_checkentry, 70 + .me = THIS_MODULE, 71 + }; 72 + static struct xt_match mac6_match = { 73 + .name = "mac", 74 + .match = &match, 75 + .checkentry = &ipt_mac_checkentry, 76 + .me = THIS_MODULE, 77 + }; 78 + 79 + static int __init init(void) 80 + { 81 + int ret; 82 + ret = xt_register_match(AF_INET, &mac_match); 83 + if (ret) 84 + return ret; 85 + 86 + ret = xt_register_match(AF_INET6, &mac6_match); 87 + if (ret) 88 + xt_unregister_match(AF_INET, &mac_match); 89 + 90 + return ret; 91 + } 92 + 93 + static void __exit fini(void) 94 + { 95 + xt_unregister_match(AF_INET, &mac_match); 96 + xt_unregister_match(AF_INET6, &mac6_match); 97 + } 98 + 99 + module_init(init); 100 + module_exit(fini);
+91
net/netfilter/xt_mark.c
··· 1 + /* Kernel module to match NFMARK values. */ 2 + 3 + /* (C) 1999-2001 Marc Boucher <marc@mbsi.ca> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License version 2 as 7 + * published by the Free Software Foundation. 8 + */ 9 + 10 + #include <linux/module.h> 11 + #include <linux/skbuff.h> 12 + 13 + #include <linux/netfilter/xt_mark.h> 14 + #include <linux/netfilter/x_tables.h> 15 + 16 + MODULE_LICENSE("GPL"); 17 + MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 18 + MODULE_DESCRIPTION("iptables mark matching module"); 19 + MODULE_ALIAS("ipt_mark"); 20 + MODULE_ALIAS("ip6t_mark"); 21 + 22 + static int 23 + match(const struct sk_buff *skb, 24 + const struct net_device *in, 25 + const struct net_device *out, 26 + const void *matchinfo, 27 + int offset, 28 + unsigned int protoff, 29 + int *hotdrop) 30 + { 31 + const struct xt_mark_info *info = matchinfo; 32 + 33 + return ((skb->nfmark & info->mask) == info->mark) ^ info->invert; 34 + } 35 + 36 + static int 37 + checkentry(const char *tablename, 38 + const void *entry, 39 + void *matchinfo, 40 + unsigned int matchsize, 41 + unsigned int hook_mask) 42 + { 43 + struct xt_mark_info *minfo = (struct xt_mark_info *) matchinfo; 44 + 45 + if (matchsize != XT_ALIGN(sizeof(struct xt_mark_info))) 46 + return 0; 47 + 48 + if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) { 49 + printk(KERN_WARNING "mark: only supports 32bit mark\n"); 50 + return 0; 51 + } 52 + 53 + return 1; 54 + } 55 + 56 + static struct xt_match mark_match = { 57 + .name = "mark", 58 + .match = &match, 59 + .checkentry = &checkentry, 60 + .me = THIS_MODULE, 61 + }; 62 + 63 + static struct xt_match mark6_match = { 64 + .name = "mark", 65 + .match = &match, 66 + .checkentry = &checkentry, 67 + .me = THIS_MODULE, 68 + }; 69 + 70 + static int __init init(void) 71 + { 72 + int ret; 73 + ret = xt_register_match(AF_INET, &mark_match); 74 + if (ret) 75 + return ret; 76 + 77 + ret = xt_register_match(AF_INET6, &mark6_match); 78 + if (ret) 79 + xt_unregister_match(AF_INET, &mark_match); 80 + 81 + return ret; 82 + } 83 + 84 + static void __exit fini(void) 85 + { 86 + xt_unregister_match(AF_INET, &mark_match); 87 + xt_unregister_match(AF_INET6, &mark6_match); 88 + } 89 + 90 + module_init(init); 91 + module_exit(fini);
+155
net/netfilter/xt_physdev.c
··· 1 + /* Kernel module to match the bridge port in and 2 + * out device for IP packets coming into contact with a bridge. */ 3 + 4 + /* (C) 2001-2003 Bart De Schuymer <bdschuym@pandora.be> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + */ 10 + 11 + #include <linux/module.h> 12 + #include <linux/skbuff.h> 13 + #include <linux/netfilter/xt_physdev.h> 14 + #include <linux/netfilter/x_tables.h> 15 + #include <linux/netfilter_bridge.h> 16 + #define MATCH 1 17 + #define NOMATCH 0 18 + 19 + MODULE_LICENSE("GPL"); 20 + MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>"); 21 + MODULE_DESCRIPTION("iptables bridge physical device match module"); 22 + MODULE_ALIAS("ipt_physdev"); 23 + MODULE_ALIAS("ip6t_physdev"); 24 + 25 + static int 26 + match(const struct sk_buff *skb, 27 + const struct net_device *in, 28 + const struct net_device *out, 29 + const void *matchinfo, 30 + int offset, 31 + unsigned int protoff, 32 + int *hotdrop) 33 + { 34 + int i; 35 + static const char nulldevname[IFNAMSIZ]; 36 + const struct xt_physdev_info *info = matchinfo; 37 + unsigned int ret; 38 + const char *indev, *outdev; 39 + struct nf_bridge_info *nf_bridge; 40 + 41 + /* Not a bridged IP packet or no info available yet: 42 + * LOCAL_OUT/mangle and LOCAL_OUT/nat don't know if 43 + * the destination device will be a bridge. */ 44 + if (!(nf_bridge = skb->nf_bridge)) { 45 + /* Return MATCH if the invert flags of the used options are on */ 46 + if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) && 47 + !(info->invert & XT_PHYSDEV_OP_BRIDGED)) 48 + return NOMATCH; 49 + if ((info->bitmask & XT_PHYSDEV_OP_ISIN) && 50 + !(info->invert & XT_PHYSDEV_OP_ISIN)) 51 + return NOMATCH; 52 + if ((info->bitmask & XT_PHYSDEV_OP_ISOUT) && 53 + !(info->invert & XT_PHYSDEV_OP_ISOUT)) 54 + return NOMATCH; 55 + if ((info->bitmask & XT_PHYSDEV_OP_IN) && 56 + !(info->invert & XT_PHYSDEV_OP_IN)) 57 + return NOMATCH; 58 + if ((info->bitmask & XT_PHYSDEV_OP_OUT) && 59 + !(info->invert & XT_PHYSDEV_OP_OUT)) 60 + return NOMATCH; 61 + return MATCH; 62 + } 63 + 64 + /* This only makes sense in the FORWARD and POSTROUTING chains */ 65 + if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) && 66 + (!!(nf_bridge->mask & BRNF_BRIDGED) ^ 67 + !(info->invert & XT_PHYSDEV_OP_BRIDGED))) 68 + return NOMATCH; 69 + 70 + if ((info->bitmask & XT_PHYSDEV_OP_ISIN && 71 + (!nf_bridge->physindev ^ !!(info->invert & XT_PHYSDEV_OP_ISIN))) || 72 + (info->bitmask & XT_PHYSDEV_OP_ISOUT && 73 + (!nf_bridge->physoutdev ^ !!(info->invert & XT_PHYSDEV_OP_ISOUT)))) 74 + return NOMATCH; 75 + 76 + if (!(info->bitmask & XT_PHYSDEV_OP_IN)) 77 + goto match_outdev; 78 + indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname; 79 + for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) { 80 + ret |= (((const unsigned int *)indev)[i] 81 + ^ ((const unsigned int *)info->physindev)[i]) 82 + & ((const unsigned int *)info->in_mask)[i]; 83 + } 84 + 85 + if ((ret == 0) ^ !(info->invert & XT_PHYSDEV_OP_IN)) 86 + return NOMATCH; 87 + 88 + match_outdev: 89 + if (!(info->bitmask & XT_PHYSDEV_OP_OUT)) 90 + return MATCH; 91 + outdev = nf_bridge->physoutdev ? 92 + nf_bridge->physoutdev->name : nulldevname; 93 + for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) { 94 + ret |= (((const unsigned int *)outdev)[i] 95 + ^ ((const unsigned int *)info->physoutdev)[i]) 96 + & ((const unsigned int *)info->out_mask)[i]; 97 + } 98 + 99 + return (ret != 0) ^ !(info->invert & XT_PHYSDEV_OP_OUT); 100 + } 101 + 102 + static int 103 + checkentry(const char *tablename, 104 + const void *ip, 105 + void *matchinfo, 106 + unsigned int matchsize, 107 + unsigned int hook_mask) 108 + { 109 + const struct xt_physdev_info *info = matchinfo; 110 + 111 + if (matchsize != XT_ALIGN(sizeof(struct xt_physdev_info))) 112 + return 0; 113 + if (!(info->bitmask & XT_PHYSDEV_OP_MASK) || 114 + info->bitmask & ~XT_PHYSDEV_OP_MASK) 115 + return 0; 116 + return 1; 117 + } 118 + 119 + static struct xt_match physdev_match = { 120 + .name = "physdev", 121 + .match = &match, 122 + .checkentry = &checkentry, 123 + .me = THIS_MODULE, 124 + }; 125 + 126 + static struct xt_match physdev6_match = { 127 + .name = "physdev", 128 + .match = &match, 129 + .checkentry = &checkentry, 130 + .me = THIS_MODULE, 131 + }; 132 + 133 + static int __init init(void) 134 + { 135 + int ret; 136 + 137 + ret = xt_register_match(AF_INET, &physdev_match); 138 + if (ret < 0) 139 + return ret; 140 + 141 + ret = xt_register_match(AF_INET6, &physdev6_match); 142 + if (ret < 0) 143 + xt_unregister_match(AF_INET, &physdev_match); 144 + 145 + return ret; 146 + } 147 + 148 + static void __exit fini(void) 149 + { 150 + xt_unregister_match(AF_INET, &physdev_match); 151 + xt_unregister_match(AF_INET6, &physdev6_match); 152 + } 153 + 154 + module_init(init); 155 + module_exit(fini);
+82
net/netfilter/xt_pkttype.c
··· 1 + /* (C) 1999-2001 Michal Ludvig <michal@logix.cz> 2 + * 3 + * This program is free software; you can redistribute it and/or modify 4 + * it under the terms of the GNU General Public License version 2 as 5 + * published by the Free Software Foundation. 6 + */ 7 + 8 + #include <linux/module.h> 9 + #include <linux/skbuff.h> 10 + #include <linux/if_ether.h> 11 + #include <linux/if_packet.h> 12 + 13 + #include <linux/netfilter/xt_pkttype.h> 14 + #include <linux/netfilter/x_tables.h> 15 + 16 + MODULE_LICENSE("GPL"); 17 + MODULE_AUTHOR("Michal Ludvig <michal@logix.cz>"); 18 + MODULE_DESCRIPTION("IP tables match to match on linklayer packet type"); 19 + MODULE_ALIAS("ipt_pkttype"); 20 + MODULE_ALIAS("ip6t_pkttype"); 21 + 22 + static int match(const struct sk_buff *skb, 23 + const struct net_device *in, 24 + const struct net_device *out, 25 + const void *matchinfo, 26 + int offset, 27 + unsigned int protoff, 28 + int *hotdrop) 29 + { 30 + const struct xt_pkttype_info *info = matchinfo; 31 + 32 + return (skb->pkt_type == info->pkttype) ^ info->invert; 33 + } 34 + 35 + static int checkentry(const char *tablename, 36 + const void *ip, 37 + void *matchinfo, 38 + unsigned int matchsize, 39 + unsigned int hook_mask) 40 + { 41 + if (matchsize != XT_ALIGN(sizeof(struct xt_pkttype_info))) 42 + return 0; 43 + 44 + return 1; 45 + } 46 + 47 + static struct xt_match pkttype_match = { 48 + .name = "pkttype", 49 + .match = &match, 50 + .checkentry = &checkentry, 51 + .me = THIS_MODULE, 52 + }; 53 + static struct xt_match pkttype6_match = { 54 + .name = "pkttype", 55 + .match = &match, 56 + .checkentry = &checkentry, 57 + .me = THIS_MODULE, 58 + }; 59 + 60 + 61 + static int __init init(void) 62 + { 63 + int ret; 64 + ret = xt_register_match(AF_INET, &pkttype_match); 65 + if (ret) 66 + return ret; 67 + 68 + ret = xt_register_match(AF_INET6, &pkttype6_match); 69 + if (ret) 70 + xt_unregister_match(AF_INET, &pkttype_match); 71 + 72 + return ret; 73 + } 74 + 75 + static void __exit fini(void) 76 + { 77 + xt_unregister_match(AF_INET, &pkttype_match); 78 + xt_unregister_match(AF_INET6, &pkttype6_match); 79 + } 80 + 81 + module_init(init); 82 + module_exit(fini);
+79
net/netfilter/xt_realm.c
··· 1 + /* IP tables module for matching the routing realm 2 + * 3 + * $Id: ipt_realm.c,v 1.3 2004/03/05 13:25:40 laforge Exp $ 4 + * 5 + * (C) 2003 by Sampsa Ranta <sampsa@netsonic.fi> 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 + 12 + #include <linux/module.h> 13 + #include <linux/skbuff.h> 14 + #include <linux/netdevice.h> 15 + #include <net/route.h> 16 + 17 + #include <linux/netfilter_ipv4.h> 18 + #include <linux/netfilter/xt_realm.h> 19 + #include <linux/netfilter/x_tables.h> 20 + 21 + MODULE_AUTHOR("Sampsa Ranta <sampsa@netsonic.fi>"); 22 + MODULE_LICENSE("GPL"); 23 + MODULE_DESCRIPTION("X_tables realm match"); 24 + MODULE_ALIAS("ipt_realm"); 25 + 26 + static int 27 + match(const struct sk_buff *skb, 28 + const struct net_device *in, 29 + const struct net_device *out, 30 + const void *matchinfo, 31 + int offset, 32 + unsigned int protoff, 33 + int *hotdrop) 34 + { 35 + const struct xt_realm_info *info = matchinfo; 36 + struct dst_entry *dst = skb->dst; 37 + 38 + return (info->id == (dst->tclassid & info->mask)) ^ info->invert; 39 + } 40 + 41 + static int check(const char *tablename, 42 + const void *ip, 43 + void *matchinfo, 44 + unsigned int matchsize, 45 + unsigned int hook_mask) 46 + { 47 + if (hook_mask 48 + & ~((1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) | 49 + (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_LOCAL_IN))) { 50 + printk("xt_realm: only valid for POST_ROUTING, LOCAL_OUT, " 51 + "LOCAL_IN or FORWARD.\n"); 52 + return 0; 53 + } 54 + if (matchsize != XT_ALIGN(sizeof(struct xt_realm_info))) { 55 + printk("xt_realm: invalid matchsize.\n"); 56 + return 0; 57 + } 58 + return 1; 59 + } 60 + 61 + static struct xt_match realm_match = { 62 + .name = "realm", 63 + .match = match, 64 + .checkentry = check, 65 + .me = THIS_MODULE 66 + }; 67 + 68 + static int __init init(void) 69 + { 70 + return xt_register_match(AF_INET, &realm_match); 71 + } 72 + 73 + static void __exit fini(void) 74 + { 75 + xt_unregister_match(AF_INET, &realm_match); 76 + } 77 + 78 + module_init(init); 79 + module_exit(fini);
+250
net/netfilter/xt_sctp.c
··· 1 + #include <linux/module.h> 2 + #include <linux/skbuff.h> 3 + #include <net/ip.h> 4 + #include <net/ipv6.h> 5 + #include <linux/sctp.h> 6 + 7 + #include <linux/netfilter/x_tables.h> 8 + #include <linux/netfilter/xt_sctp.h> 9 + #include <linux/netfilter_ipv4/ip_tables.h> 10 + #include <linux/netfilter_ipv6/ip6_tables.h> 11 + 12 + MODULE_LICENSE("GPL"); 13 + MODULE_AUTHOR("Kiran Kumar Immidi"); 14 + MODULE_DESCRIPTION("Match for SCTP protocol packets"); 15 + MODULE_ALIAS("ipt_sctp"); 16 + 17 + #ifdef DEBUG_SCTP 18 + #define duprintf(format, args...) printk(format , ## args) 19 + #else 20 + #define duprintf(format, args...) 21 + #endif 22 + 23 + #define SCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \ 24 + || (!!((invflag) & (option)) ^ (cond))) 25 + 26 + static int 27 + match_flags(const struct xt_sctp_flag_info *flag_info, 28 + const int flag_count, 29 + u_int8_t chunktype, 30 + u_int8_t chunkflags) 31 + { 32 + int i; 33 + 34 + for (i = 0; i < flag_count; i++) { 35 + if (flag_info[i].chunktype == chunktype) { 36 + return (chunkflags & flag_info[i].flag_mask) == flag_info[i].flag; 37 + } 38 + } 39 + 40 + return 1; 41 + } 42 + 43 + static inline int 44 + match_packet(const struct sk_buff *skb, 45 + unsigned int offset, 46 + const u_int32_t *chunkmap, 47 + int chunk_match_type, 48 + const struct xt_sctp_flag_info *flag_info, 49 + const int flag_count, 50 + int *hotdrop) 51 + { 52 + u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)]; 53 + sctp_chunkhdr_t _sch, *sch; 54 + 55 + #ifdef DEBUG_SCTP 56 + int i = 0; 57 + #endif 58 + 59 + if (chunk_match_type == SCTP_CHUNK_MATCH_ALL) { 60 + SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap); 61 + } 62 + 63 + do { 64 + sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch); 65 + if (sch == NULL) { 66 + duprintf("Dropping invalid SCTP packet.\n"); 67 + *hotdrop = 1; 68 + return 0; 69 + } 70 + 71 + duprintf("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d\tflags: %x\n", 72 + ++i, offset, sch->type, htons(sch->length), sch->flags); 73 + 74 + offset += (htons(sch->length) + 3) & ~3; 75 + 76 + duprintf("skb->len: %d\toffset: %d\n", skb->len, offset); 77 + 78 + if (SCTP_CHUNKMAP_IS_SET(chunkmap, sch->type)) { 79 + switch (chunk_match_type) { 80 + case SCTP_CHUNK_MATCH_ANY: 81 + if (match_flags(flag_info, flag_count, 82 + sch->type, sch->flags)) { 83 + return 1; 84 + } 85 + break; 86 + 87 + case SCTP_CHUNK_MATCH_ALL: 88 + if (match_flags(flag_info, flag_count, 89 + sch->type, sch->flags)) { 90 + SCTP_CHUNKMAP_CLEAR(chunkmapcopy, sch->type); 91 + } 92 + break; 93 + 94 + case SCTP_CHUNK_MATCH_ONLY: 95 + if (!match_flags(flag_info, flag_count, 96 + sch->type, sch->flags)) { 97 + return 0; 98 + } 99 + break; 100 + } 101 + } else { 102 + switch (chunk_match_type) { 103 + case SCTP_CHUNK_MATCH_ONLY: 104 + return 0; 105 + } 106 + } 107 + } while (offset < skb->len); 108 + 109 + switch (chunk_match_type) { 110 + case SCTP_CHUNK_MATCH_ALL: 111 + return SCTP_CHUNKMAP_IS_CLEAR(chunkmap); 112 + case SCTP_CHUNK_MATCH_ANY: 113 + return 0; 114 + case SCTP_CHUNK_MATCH_ONLY: 115 + return 1; 116 + } 117 + 118 + /* This will never be reached, but required to stop compiler whine */ 119 + return 0; 120 + } 121 + 122 + static int 123 + match(const struct sk_buff *skb, 124 + const struct net_device *in, 125 + const struct net_device *out, 126 + const void *matchinfo, 127 + int offset, 128 + unsigned int protoff, 129 + int *hotdrop) 130 + { 131 + const struct xt_sctp_info *info; 132 + sctp_sctphdr_t _sh, *sh; 133 + 134 + info = (const struct xt_sctp_info *)matchinfo; 135 + 136 + if (offset) { 137 + duprintf("Dropping non-first fragment.. FIXME\n"); 138 + return 0; 139 + } 140 + 141 + sh = skb_header_pointer(skb, protoff, sizeof(_sh), &_sh); 142 + if (sh == NULL) { 143 + duprintf("Dropping evil TCP offset=0 tinygram.\n"); 144 + *hotdrop = 1; 145 + return 0; 146 + } 147 + duprintf("spt: %d\tdpt: %d\n", ntohs(sh->source), ntohs(sh->dest)); 148 + 149 + return SCCHECK(((ntohs(sh->source) >= info->spts[0]) 150 + && (ntohs(sh->source) <= info->spts[1])), 151 + XT_SCTP_SRC_PORTS, info->flags, info->invflags) 152 + && SCCHECK(((ntohs(sh->dest) >= info->dpts[0]) 153 + && (ntohs(sh->dest) <= info->dpts[1])), 154 + XT_SCTP_DEST_PORTS, info->flags, info->invflags) 155 + && SCCHECK(match_packet(skb, protoff, 156 + info->chunkmap, info->chunk_match_type, 157 + info->flag_info, info->flag_count, 158 + hotdrop), 159 + XT_SCTP_CHUNK_TYPES, info->flags, info->invflags); 160 + } 161 + 162 + static int 163 + checkentry(const char *tablename, 164 + const void *inf, 165 + void *matchinfo, 166 + unsigned int matchsize, 167 + unsigned int hook_mask) 168 + { 169 + const struct xt_sctp_info *info; 170 + const struct ipt_ip *ip = inf; 171 + 172 + info = (const struct xt_sctp_info *)matchinfo; 173 + 174 + return ip->proto == IPPROTO_SCTP 175 + && !(ip->invflags & XT_INV_PROTO) 176 + && matchsize == XT_ALIGN(sizeof(struct xt_sctp_info)) 177 + && !(info->flags & ~XT_SCTP_VALID_FLAGS) 178 + && !(info->invflags & ~XT_SCTP_VALID_FLAGS) 179 + && !(info->invflags & ~info->flags) 180 + && ((!(info->flags & XT_SCTP_CHUNK_TYPES)) || 181 + (info->chunk_match_type & 182 + (SCTP_CHUNK_MATCH_ALL 183 + | SCTP_CHUNK_MATCH_ANY 184 + | SCTP_CHUNK_MATCH_ONLY))); 185 + } 186 + 187 + static int 188 + checkentry6(const char *tablename, 189 + const void *inf, 190 + void *matchinfo, 191 + unsigned int matchsize, 192 + unsigned int hook_mask) 193 + { 194 + const struct xt_sctp_info *info; 195 + const struct ip6t_ip6 *ip = inf; 196 + 197 + info = (const struct xt_sctp_info *)matchinfo; 198 + 199 + return ip->proto == IPPROTO_SCTP 200 + && !(ip->invflags & XT_INV_PROTO) 201 + && matchsize == XT_ALIGN(sizeof(struct xt_sctp_info)) 202 + && !(info->flags & ~XT_SCTP_VALID_FLAGS) 203 + && !(info->invflags & ~XT_SCTP_VALID_FLAGS) 204 + && !(info->invflags & ~info->flags) 205 + && ((!(info->flags & XT_SCTP_CHUNK_TYPES)) || 206 + (info->chunk_match_type & 207 + (SCTP_CHUNK_MATCH_ALL 208 + | SCTP_CHUNK_MATCH_ANY 209 + | SCTP_CHUNK_MATCH_ONLY))); 210 + } 211 + 212 + 213 + static struct xt_match sctp_match = 214 + { 215 + .name = "sctp", 216 + .match = &match, 217 + .checkentry = &checkentry, 218 + .me = THIS_MODULE 219 + }; 220 + static struct xt_match sctp6_match = 221 + { 222 + .name = "sctp", 223 + .match = &match, 224 + .checkentry = &checkentry6, 225 + .me = THIS_MODULE 226 + }; 227 + 228 + 229 + static int __init init(void) 230 + { 231 + int ret; 232 + ret = xt_register_match(AF_INET, &sctp_match); 233 + if (ret) 234 + return ret; 235 + 236 + ret = xt_register_match(AF_INET6, &sctp6_match); 237 + if (ret) 238 + xt_unregister_match(AF_INET, &sctp_match); 239 + 240 + return ret; 241 + } 242 + 243 + static void __exit fini(void) 244 + { 245 + xt_unregister_match(AF_INET6, &sctp6_match); 246 + xt_unregister_match(AF_INET, &sctp_match); 247 + } 248 + 249 + module_init(init); 250 + module_exit(fini);
+96
net/netfilter/xt_state.c
··· 1 + /* Kernel module to match connection tracking information. */ 2 + 3 + /* (C) 1999-2001 Paul `Rusty' Russell 4 + * (C) 2002-2005 Netfilter Core Team <coreteam@netfilter.org> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + */ 10 + 11 + #include <linux/module.h> 12 + #include <linux/skbuff.h> 13 + #include <net/netfilter/nf_conntrack_compat.h> 14 + #include <linux/netfilter/x_tables.h> 15 + #include <linux/netfilter/xt_state.h> 16 + 17 + MODULE_LICENSE("GPL"); 18 + MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>"); 19 + MODULE_DESCRIPTION("ip[6]_tables connection tracking state match module"); 20 + MODULE_ALIAS("ipt_state"); 21 + MODULE_ALIAS("ip6t_state"); 22 + 23 + static int 24 + match(const struct sk_buff *skb, 25 + const struct net_device *in, 26 + const struct net_device *out, 27 + const void *matchinfo, 28 + int offset, 29 + unsigned int protoff, 30 + int *hotdrop) 31 + { 32 + const struct xt_state_info *sinfo = matchinfo; 33 + enum ip_conntrack_info ctinfo; 34 + unsigned int statebit; 35 + 36 + if (nf_ct_is_untracked(skb)) 37 + statebit = XT_STATE_UNTRACKED; 38 + else if (!nf_ct_get_ctinfo(skb, &ctinfo)) 39 + statebit = XT_STATE_INVALID; 40 + else 41 + statebit = XT_STATE_BIT(ctinfo); 42 + 43 + return (sinfo->statemask & statebit); 44 + } 45 + 46 + static int check(const char *tablename, 47 + const void *ip, 48 + void *matchinfo, 49 + unsigned int matchsize, 50 + unsigned int hook_mask) 51 + { 52 + if (matchsize != XT_ALIGN(sizeof(struct xt_state_info))) 53 + return 0; 54 + 55 + return 1; 56 + } 57 + 58 + static struct xt_match state_match = { 59 + .name = "state", 60 + .match = &match, 61 + .checkentry = &check, 62 + .me = THIS_MODULE, 63 + }; 64 + 65 + static struct xt_match state6_match = { 66 + .name = "state", 67 + .match = &match, 68 + .checkentry = &check, 69 + .me = THIS_MODULE, 70 + }; 71 + 72 + static int __init init(void) 73 + { 74 + int ret; 75 + 76 + need_conntrack(); 77 + 78 + ret = xt_register_match(AF_INET, &state_match); 79 + if (ret < 0) 80 + return ret; 81 + 82 + ret = xt_register_match(AF_INET6, &state6_match); 83 + if (ret < 0) 84 + xt_unregister_match(AF_INET,&state_match); 85 + 86 + return ret; 87 + } 88 + 89 + static void __exit fini(void) 90 + { 91 + xt_unregister_match(AF_INET, &state_match); 92 + xt_unregister_match(AF_INET6, &state6_match); 93 + } 94 + 95 + module_init(init); 96 + module_exit(fini);
+111
net/netfilter/xt_string.c
··· 1 + /* String matching match for iptables 2 + * 3 + * (C) 2005 Pablo Neira Ayuso <pablo@eurodev.net> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License version 2 as 7 + * published by the Free Software Foundation. 8 + */ 9 + 10 + #include <linux/init.h> 11 + #include <linux/module.h> 12 + #include <linux/kernel.h> 13 + #include <linux/skbuff.h> 14 + #include <linux/netfilter/x_tables.h> 15 + #include <linux/netfilter/xt_string.h> 16 + #include <linux/textsearch.h> 17 + 18 + MODULE_AUTHOR("Pablo Neira Ayuso <pablo@eurodev.net>"); 19 + MODULE_DESCRIPTION("IP tables string match module"); 20 + MODULE_LICENSE("GPL"); 21 + MODULE_ALIAS("ipt_string"); 22 + MODULE_ALIAS("ip6t_string"); 23 + 24 + static int match(const struct sk_buff *skb, 25 + const struct net_device *in, 26 + const struct net_device *out, 27 + const void *matchinfo, 28 + int offset, 29 + unsigned int protoff, 30 + int *hotdrop) 31 + { 32 + struct ts_state state; 33 + struct xt_string_info *conf = (struct xt_string_info *) matchinfo; 34 + 35 + memset(&state, 0, sizeof(struct ts_state)); 36 + 37 + return (skb_find_text((struct sk_buff *)skb, conf->from_offset, 38 + conf->to_offset, conf->config, &state) 39 + != UINT_MAX) && !conf->invert; 40 + } 41 + 42 + #define STRING_TEXT_PRIV(m) ((struct xt_string_info *) m) 43 + 44 + static int checkentry(const char *tablename, 45 + const void *ip, 46 + void *matchinfo, 47 + unsigned int matchsize, 48 + unsigned int hook_mask) 49 + { 50 + struct xt_string_info *conf = matchinfo; 51 + struct ts_config *ts_conf; 52 + 53 + if (matchsize != XT_ALIGN(sizeof(struct xt_string_info))) 54 + return 0; 55 + 56 + /* Damn, can't handle this case properly with iptables... */ 57 + if (conf->from_offset > conf->to_offset) 58 + return 0; 59 + 60 + ts_conf = textsearch_prepare(conf->algo, conf->pattern, conf->patlen, 61 + GFP_KERNEL, TS_AUTOLOAD); 62 + if (IS_ERR(ts_conf)) 63 + return 0; 64 + 65 + conf->config = ts_conf; 66 + 67 + return 1; 68 + } 69 + 70 + static void destroy(void *matchinfo, unsigned int matchsize) 71 + { 72 + textsearch_destroy(STRING_TEXT_PRIV(matchinfo)->config); 73 + } 74 + 75 + static struct xt_match string_match = { 76 + .name = "string", 77 + .match = match, 78 + .checkentry = checkentry, 79 + .destroy = destroy, 80 + .me = THIS_MODULE 81 + }; 82 + static struct xt_match string6_match = { 83 + .name = "string", 84 + .match = match, 85 + .checkentry = checkentry, 86 + .destroy = destroy, 87 + .me = THIS_MODULE 88 + }; 89 + 90 + static int __init init(void) 91 + { 92 + int ret; 93 + 94 + ret = xt_register_match(AF_INET, &string_match); 95 + if (ret) 96 + return ret; 97 + ret = xt_register_match(AF_INET6, &string6_match); 98 + if (ret) 99 + xt_unregister_match(AF_INET, &string_match); 100 + 101 + return ret; 102 + } 103 + 104 + static void __exit fini(void) 105 + { 106 + xt_unregister_match(AF_INET, &string_match); 107 + xt_unregister_match(AF_INET6, &string6_match); 108 + } 109 + 110 + module_init(init); 111 + module_exit(fini);
+172
net/netfilter/xt_tcpmss.c
··· 1 + /* Kernel module to match TCP MSS values. */ 2 + 3 + /* Copyright (C) 2000 Marc Boucher <marc@mbsi.ca> 4 + * Portions (C) 2005 by Harald Welte <laforge@netfilter.org> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + */ 10 + 11 + #include <linux/module.h> 12 + #include <linux/skbuff.h> 13 + #include <net/tcp.h> 14 + 15 + #include <linux/netfilter/xt_tcpmss.h> 16 + #include <linux/netfilter/x_tables.h> 17 + 18 + #include <linux/netfilter_ipv4/ip_tables.h> 19 + #include <linux/netfilter_ipv6/ip6_tables.h> 20 + 21 + #define TH_SYN 0x02 22 + 23 + MODULE_LICENSE("GPL"); 24 + MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 25 + MODULE_DESCRIPTION("iptables TCP MSS match module"); 26 + MODULE_ALIAS("ipt_tcpmss"); 27 + 28 + /* Returns 1 if the mss option is set and matched by the range, 0 otherwise */ 29 + static inline int 30 + mssoption_match(u_int16_t min, u_int16_t max, 31 + const struct sk_buff *skb, 32 + unsigned int protoff, 33 + int invert, 34 + int *hotdrop) 35 + { 36 + struct tcphdr _tcph, *th; 37 + /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ 38 + u8 _opt[15 * 4 - sizeof(_tcph)], *op; 39 + unsigned int i, optlen; 40 + 41 + /* If we don't have the whole header, drop packet. */ 42 + th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph); 43 + if (th == NULL) 44 + goto dropit; 45 + 46 + /* Malformed. */ 47 + if (th->doff*4 < sizeof(*th)) 48 + goto dropit; 49 + 50 + optlen = th->doff*4 - sizeof(*th); 51 + if (!optlen) 52 + goto out; 53 + 54 + /* Truncated options. */ 55 + op = skb_header_pointer(skb, protoff + sizeof(*th), optlen, _opt); 56 + if (op == NULL) 57 + goto dropit; 58 + 59 + for (i = 0; i < optlen; ) { 60 + if (op[i] == TCPOPT_MSS 61 + && (optlen - i) >= TCPOLEN_MSS 62 + && op[i+1] == TCPOLEN_MSS) { 63 + u_int16_t mssval; 64 + 65 + mssval = (op[i+2] << 8) | op[i+3]; 66 + 67 + return (mssval >= min && mssval <= max) ^ invert; 68 + } 69 + if (op[i] < 2) i++; 70 + else i += op[i+1]?:1; 71 + } 72 + out: 73 + return invert; 74 + 75 + dropit: 76 + *hotdrop = 1; 77 + return 0; 78 + } 79 + 80 + static int 81 + match(const struct sk_buff *skb, 82 + const struct net_device *in, 83 + const struct net_device *out, 84 + const void *matchinfo, 85 + int offset, 86 + unsigned int protoff, 87 + int *hotdrop) 88 + { 89 + const struct xt_tcpmss_match_info *info = matchinfo; 90 + 91 + return mssoption_match(info->mss_min, info->mss_max, skb, protoff, 92 + info->invert, hotdrop); 93 + } 94 + 95 + static int 96 + checkentry(const char *tablename, 97 + const void *ipinfo, 98 + void *matchinfo, 99 + unsigned int matchsize, 100 + unsigned int hook_mask) 101 + { 102 + const struct ipt_ip *ip = ipinfo; 103 + if (matchsize != XT_ALIGN(sizeof(struct xt_tcpmss_match_info))) 104 + return 0; 105 + 106 + /* Must specify -p tcp */ 107 + if (ip->proto != IPPROTO_TCP || (ip->invflags & IPT_INV_PROTO)) { 108 + printk("tcpmss: Only works on TCP packets\n"); 109 + return 0; 110 + } 111 + 112 + return 1; 113 + } 114 + 115 + static int 116 + checkentry6(const char *tablename, 117 + const void *ipinfo, 118 + void *matchinfo, 119 + unsigned int matchsize, 120 + unsigned int hook_mask) 121 + { 122 + const struct ip6t_ip6 *ip = ipinfo; 123 + 124 + if (matchsize != XT_ALIGN(sizeof(struct xt_tcpmss_match_info))) 125 + return 0; 126 + 127 + /* Must specify -p tcp */ 128 + if (ip->proto != IPPROTO_TCP || (ip->invflags & XT_INV_PROTO)) { 129 + printk("tcpmss: Only works on TCP packets\n"); 130 + return 0; 131 + } 132 + 133 + return 1; 134 + } 135 + 136 + static struct xt_match tcpmss_match = { 137 + .name = "tcpmss", 138 + .match = &match, 139 + .checkentry = &checkentry, 140 + .me = THIS_MODULE, 141 + }; 142 + 143 + static struct xt_match tcpmss6_match = { 144 + .name = "tcpmss", 145 + .match = &match, 146 + .checkentry = &checkentry6, 147 + .me = THIS_MODULE, 148 + }; 149 + 150 + 151 + static int __init init(void) 152 + { 153 + int ret; 154 + ret = xt_register_match(AF_INET, &tcpmss_match); 155 + if (ret) 156 + return ret; 157 + 158 + ret = xt_register_match(AF_INET6, &tcpmss6_match); 159 + if (ret) 160 + xt_unregister_match(AF_INET, &tcpmss_match); 161 + 162 + return ret; 163 + } 164 + 165 + static void __exit fini(void) 166 + { 167 + xt_unregister_match(AF_INET6, &tcpmss6_match); 168 + xt_unregister_match(AF_INET, &tcpmss_match); 169 + } 170 + 171 + module_init(init); 172 + module_exit(fini);
+333
net/netfilter/xt_tcpudp.c
··· 1 + #include <linux/types.h> 2 + #include <linux/module.h> 3 + #include <net/ip.h> 4 + #include <net/ipv6.h> 5 + #include <net/tcp.h> 6 + #include <net/udp.h> 7 + #include <linux/netfilter/x_tables.h> 8 + #include <linux/netfilter/xt_tcpudp.h> 9 + #include <linux/netfilter_ipv4/ip_tables.h> 10 + #include <linux/netfilter_ipv6/ip6_tables.h> 11 + 12 + MODULE_DESCRIPTION("x_tables match for TCP and UDP, supports IPv4 and IPv6"); 13 + MODULE_LICENSE("GPL"); 14 + MODULE_ALIAS("xt_tcp"); 15 + MODULE_ALIAS("xt_udp"); 16 + MODULE_ALIAS("ipt_udp"); 17 + MODULE_ALIAS("ipt_tcp"); 18 + MODULE_ALIAS("ip6t_udp"); 19 + MODULE_ALIAS("ip6t_tcp"); 20 + 21 + #ifdef DEBUG_IP_FIREWALL_USER 22 + #define duprintf(format, args...) printk(format , ## args) 23 + #else 24 + #define duprintf(format, args...) 25 + #endif 26 + 27 + 28 + /* Returns 1 if the port is matched by the range, 0 otherwise */ 29 + static inline int 30 + port_match(u_int16_t min, u_int16_t max, u_int16_t port, int invert) 31 + { 32 + int ret; 33 + 34 + ret = (port >= min && port <= max) ^ invert; 35 + return ret; 36 + } 37 + 38 + static int 39 + tcp_find_option(u_int8_t option, 40 + const struct sk_buff *skb, 41 + unsigned int protoff, 42 + unsigned int optlen, 43 + int invert, 44 + int *hotdrop) 45 + { 46 + /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ 47 + u_int8_t _opt[60 - sizeof(struct tcphdr)], *op; 48 + unsigned int i; 49 + 50 + duprintf("tcp_match: finding option\n"); 51 + 52 + if (!optlen) 53 + return invert; 54 + 55 + /* If we don't have the whole header, drop packet. */ 56 + op = skb_header_pointer(skb, protoff + sizeof(struct tcphdr), 57 + optlen, _opt); 58 + if (op == NULL) { 59 + *hotdrop = 1; 60 + return 0; 61 + } 62 + 63 + for (i = 0; i < optlen; ) { 64 + if (op[i] == option) return !invert; 65 + if (op[i] < 2) i++; 66 + else i += op[i+1]?:1; 67 + } 68 + 69 + return invert; 70 + } 71 + 72 + static int 73 + tcp_match(const struct sk_buff *skb, 74 + const struct net_device *in, 75 + const struct net_device *out, 76 + const void *matchinfo, 77 + int offset, 78 + unsigned int protoff, 79 + int *hotdrop) 80 + { 81 + struct tcphdr _tcph, *th; 82 + const struct xt_tcp *tcpinfo = matchinfo; 83 + 84 + if (offset) { 85 + /* To quote Alan: 86 + 87 + Don't allow a fragment of TCP 8 bytes in. Nobody normal 88 + causes this. Its a cracker trying to break in by doing a 89 + flag overwrite to pass the direction checks. 90 + */ 91 + if (offset == 1) { 92 + duprintf("Dropping evil TCP offset=1 frag.\n"); 93 + *hotdrop = 1; 94 + } 95 + /* Must not be a fragment. */ 96 + return 0; 97 + } 98 + 99 + #define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg)) 100 + 101 + th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph); 102 + if (th == NULL) { 103 + /* We've been asked to examine this packet, and we 104 + can't. Hence, no choice but to drop. */ 105 + duprintf("Dropping evil TCP offset=0 tinygram.\n"); 106 + *hotdrop = 1; 107 + return 0; 108 + } 109 + 110 + if (!port_match(tcpinfo->spts[0], tcpinfo->spts[1], 111 + ntohs(th->source), 112 + !!(tcpinfo->invflags & XT_TCP_INV_SRCPT))) 113 + return 0; 114 + if (!port_match(tcpinfo->dpts[0], tcpinfo->dpts[1], 115 + ntohs(th->dest), 116 + !!(tcpinfo->invflags & XT_TCP_INV_DSTPT))) 117 + return 0; 118 + if (!FWINVTCP((((unsigned char *)th)[13] & tcpinfo->flg_mask) 119 + == tcpinfo->flg_cmp, 120 + XT_TCP_INV_FLAGS)) 121 + return 0; 122 + if (tcpinfo->option) { 123 + if (th->doff * 4 < sizeof(_tcph)) { 124 + *hotdrop = 1; 125 + return 0; 126 + } 127 + if (!tcp_find_option(tcpinfo->option, skb, protoff, 128 + th->doff*4 - sizeof(_tcph), 129 + tcpinfo->invflags & XT_TCP_INV_OPTION, 130 + hotdrop)) 131 + return 0; 132 + } 133 + return 1; 134 + } 135 + 136 + /* Called when user tries to insert an entry of this type. */ 137 + static int 138 + tcp_checkentry(const char *tablename, 139 + const void *info, 140 + void *matchinfo, 141 + unsigned int matchsize, 142 + unsigned int hook_mask) 143 + { 144 + const struct ipt_ip *ip = info; 145 + const struct xt_tcp *tcpinfo = matchinfo; 146 + 147 + /* Must specify proto == TCP, and no unknown invflags */ 148 + return ip->proto == IPPROTO_TCP 149 + && !(ip->invflags & XT_INV_PROTO) 150 + && matchsize == XT_ALIGN(sizeof(struct xt_tcp)) 151 + && !(tcpinfo->invflags & ~XT_TCP_INV_MASK); 152 + } 153 + 154 + /* Called when user tries to insert an entry of this type. */ 155 + static int 156 + tcp6_checkentry(const char *tablename, 157 + const void *entry, 158 + void *matchinfo, 159 + unsigned int matchsize, 160 + unsigned int hook_mask) 161 + { 162 + const struct ip6t_ip6 *ipv6 = entry; 163 + const struct xt_tcp *tcpinfo = matchinfo; 164 + 165 + /* Must specify proto == TCP, and no unknown invflags */ 166 + return ipv6->proto == IPPROTO_TCP 167 + && !(ipv6->invflags & XT_INV_PROTO) 168 + && matchsize == XT_ALIGN(sizeof(struct xt_tcp)) 169 + && !(tcpinfo->invflags & ~XT_TCP_INV_MASK); 170 + } 171 + 172 + 173 + static int 174 + udp_match(const struct sk_buff *skb, 175 + const struct net_device *in, 176 + const struct net_device *out, 177 + const void *matchinfo, 178 + int offset, 179 + unsigned int protoff, 180 + int *hotdrop) 181 + { 182 + struct udphdr _udph, *uh; 183 + const struct xt_udp *udpinfo = matchinfo; 184 + 185 + /* Must not be a fragment. */ 186 + if (offset) 187 + return 0; 188 + 189 + uh = skb_header_pointer(skb, protoff, sizeof(_udph), &_udph); 190 + if (uh == NULL) { 191 + /* We've been asked to examine this packet, and we 192 + can't. Hence, no choice but to drop. */ 193 + duprintf("Dropping evil UDP tinygram.\n"); 194 + *hotdrop = 1; 195 + return 0; 196 + } 197 + 198 + return port_match(udpinfo->spts[0], udpinfo->spts[1], 199 + ntohs(uh->source), 200 + !!(udpinfo->invflags & XT_UDP_INV_SRCPT)) 201 + && port_match(udpinfo->dpts[0], udpinfo->dpts[1], 202 + ntohs(uh->dest), 203 + !!(udpinfo->invflags & XT_UDP_INV_DSTPT)); 204 + } 205 + 206 + /* Called when user tries to insert an entry of this type. */ 207 + static int 208 + udp_checkentry(const char *tablename, 209 + const void *info, 210 + void *matchinfo, 211 + unsigned int matchinfosize, 212 + unsigned int hook_mask) 213 + { 214 + const struct ipt_ip *ip = info; 215 + const struct xt_udp *udpinfo = matchinfo; 216 + 217 + /* Must specify proto == UDP, and no unknown invflags */ 218 + if (ip->proto != IPPROTO_UDP || (ip->invflags & XT_INV_PROTO)) { 219 + duprintf("ipt_udp: Protocol %u != %u\n", ip->proto, 220 + IPPROTO_UDP); 221 + return 0; 222 + } 223 + if (matchinfosize != XT_ALIGN(sizeof(struct xt_udp))) { 224 + duprintf("ipt_udp: matchsize %u != %u\n", 225 + matchinfosize, XT_ALIGN(sizeof(struct xt_udp))); 226 + return 0; 227 + } 228 + if (udpinfo->invflags & ~XT_UDP_INV_MASK) { 229 + duprintf("ipt_udp: unknown flags %X\n", 230 + udpinfo->invflags); 231 + return 0; 232 + } 233 + 234 + return 1; 235 + } 236 + 237 + /* Called when user tries to insert an entry of this type. */ 238 + static int 239 + udp6_checkentry(const char *tablename, 240 + const void *entry, 241 + void *matchinfo, 242 + unsigned int matchinfosize, 243 + unsigned int hook_mask) 244 + { 245 + const struct ip6t_ip6 *ipv6 = entry; 246 + const struct xt_udp *udpinfo = matchinfo; 247 + 248 + /* Must specify proto == UDP, and no unknown invflags */ 249 + if (ipv6->proto != IPPROTO_UDP || (ipv6->invflags & XT_INV_PROTO)) { 250 + duprintf("ip6t_udp: Protocol %u != %u\n", ipv6->proto, 251 + IPPROTO_UDP); 252 + return 0; 253 + } 254 + if (matchinfosize != XT_ALIGN(sizeof(struct xt_udp))) { 255 + duprintf("ip6t_udp: matchsize %u != %u\n", 256 + matchinfosize, XT_ALIGN(sizeof(struct xt_udp))); 257 + return 0; 258 + } 259 + if (udpinfo->invflags & ~XT_UDP_INV_MASK) { 260 + duprintf("ip6t_udp: unknown flags %X\n", 261 + udpinfo->invflags); 262 + return 0; 263 + } 264 + 265 + return 1; 266 + } 267 + 268 + static struct xt_match tcp_matchstruct = { 269 + .name = "tcp", 270 + .match = &tcp_match, 271 + .checkentry = &tcp_checkentry, 272 + .me = THIS_MODULE, 273 + }; 274 + static struct xt_match tcp6_matchstruct = { 275 + .name = "tcp", 276 + .match = &tcp_match, 277 + .checkentry = &tcp6_checkentry, 278 + .me = THIS_MODULE, 279 + }; 280 + 281 + static struct xt_match udp_matchstruct = { 282 + .name = "udp", 283 + .match = &udp_match, 284 + .checkentry = &udp_checkentry, 285 + .me = THIS_MODULE, 286 + }; 287 + static struct xt_match udp6_matchstruct = { 288 + .name = "udp", 289 + .match = &udp_match, 290 + .checkentry = &udp6_checkentry, 291 + .me = THIS_MODULE, 292 + }; 293 + 294 + static int __init init(void) 295 + { 296 + int ret; 297 + ret = xt_register_match(AF_INET, &tcp_matchstruct); 298 + if (ret) 299 + return ret; 300 + 301 + ret = xt_register_match(AF_INET6, &tcp6_matchstruct); 302 + if (ret) 303 + goto out_unreg_tcp; 304 + 305 + ret = xt_register_match(AF_INET, &udp_matchstruct); 306 + if (ret) 307 + goto out_unreg_tcp6; 308 + 309 + ret = xt_register_match(AF_INET6, &udp6_matchstruct); 310 + if (ret) 311 + goto out_unreg_udp; 312 + 313 + return ret; 314 + 315 + out_unreg_udp: 316 + xt_unregister_match(AF_INET, &tcp_matchstruct); 317 + out_unreg_tcp6: 318 + xt_unregister_match(AF_INET6, &tcp6_matchstruct); 319 + out_unreg_tcp: 320 + xt_unregister_match(AF_INET, &tcp_matchstruct); 321 + return ret; 322 + } 323 + 324 + static void __exit fini(void) 325 + { 326 + xt_unregister_match(AF_INET6, &udp6_matchstruct); 327 + xt_unregister_match(AF_INET, &udp_matchstruct); 328 + xt_unregister_match(AF_INET6, &tcp6_matchstruct); 329 + xt_unregister_match(AF_INET, &tcp_matchstruct); 330 + } 331 + 332 + module_init(init); 333 + module_exit(fini);
+1 -1
net/sched/act_ipt.c
··· 62 62 struct ipt_target *target; 63 63 int ret = 0; 64 64 65 - target = ipt_find_target(t->u.user.name, t->u.user.revision); 65 + target = xt_find_target(AF_INET, t->u.user.name, t->u.user.revision); 66 66 if (!target) 67 67 return -ENOENT; 68 68