1 /* 2 * ebtables 3 * 4 * Authors: 5 * Bart De Schuymer <bdschuym (at) pandora.be> 6 * 7 * ebtables.c,v 2.0, April, 2002 8 * 9 * This code is stongly inspired on the iptables code which is 10 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling 11 */ 12 13 #ifndef __LINUX_BRIDGE_EFF_H 14 #define __LINUX_BRIDGE_EFF_H 15 #include <linux/if.h> 16 #include <linux/netfilter_bridge.h> 17 #include <linux/if_ether.h> 18 19 #define EBT_TABLE_MAXNAMELEN 32 20 #define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN 21 #define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN 22 23 /* verdicts >0 are "branches" */ 24 #define EBT_ACCEPT -1 25 #define EBT_DROP -2 26 #define EBT_CONTINUE -3 27 #define EBT_RETURN -4 28 #define NUM_STANDARD_TARGETS 4 29 /* ebtables target modules store the verdict inside an int. We can 30 * reclaim a part of this int for backwards compatible extensions. 31 * The 4 lsb are more than enough to store the verdict. */ 32 #define EBT_VERDICT_BITS 0x0000000F 33 34 struct ebt_counter 35 { 36 uint64_t pcnt; 37 uint64_t bcnt; 38 }; 39 40 struct ebt_replace 41 { 42 char name[EBT_TABLE_MAXNAMELEN]; 43 unsigned int valid_hooks; 44 /* nr of rules in the table */ 45 unsigned int nentries; 46 /* total size of the entries */ 47 unsigned int entries_size; 48 /* start of the chains */ 49 struct ebt_entries *hook_entry[NF_BR_NUMHOOKS]; 50 /* nr of counters userspace expects back */ 51 unsigned int num_counters; 52 /* where the kernel will put the old counters */ 53 struct ebt_counter *counters; 54 char *entries; 55 }; 56 57 struct ebt_replace_kernel 58 { 59 char name[EBT_TABLE_MAXNAMELEN]; 60 unsigned int valid_hooks; 61 /* nr of rules in the table */ 62 unsigned int nentries; 63 /* total size of the entries */ 64 unsigned int entries_size; 65 /* start of the chains */ 66 struct ebt_entries *hook_entry[NF_BR_NUMHOOKS]; 67 /* nr of counters userspace expects back */ 68 unsigned int num_counters; 69 /* where the kernel will put the old counters */ 70 struct ebt_counter *counters; 71 char *entries; 72 }; 73 74 struct ebt_entries { 75 /* this field is always set to zero 76 * See EBT_ENTRY_OR_ENTRIES. 77 * Must be same size as ebt_entry.bitmask */ 78 unsigned int distinguisher; 79 /* the chain name */ 80 char name[EBT_CHAIN_MAXNAMELEN]; 81 /* counter offset for this chain */ 82 unsigned int counter_offset; 83 /* one standard (accept, drop, return) per hook */ 84 int policy; 85 /* nr. of entries */ 86 unsigned int nentries; 87 /* entry list */ 88 char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); 89 }; 90 91 /* used for the bitmask of struct ebt_entry */ 92 93 /* This is a hack to make a difference between an ebt_entry struct and an 94 * ebt_entries struct when traversing the entries from start to end. 95 * Using this simplifies the code alot, while still being able to use 96 * ebt_entries. 97 * Contrary, iptables doesn't use something like ebt_entries and therefore uses 98 * different techniques for naming the policy and such. So, iptables doesn't 99 * need a hack like this. 100 */ 101 #define EBT_ENTRY_OR_ENTRIES 0x01 102 /* these are the normal masks */ 103 #define EBT_NOPROTO 0x02 104 #define EBT_802_3 0x04 105 #define EBT_SOURCEMAC 0x08 106 #define EBT_DESTMAC 0x10 107 #define EBT_F_MASK (EBT_NOPROTO | EBT_802_3 | EBT_SOURCEMAC | EBT_DESTMAC \ 108 | EBT_ENTRY_OR_ENTRIES) 109 110 #define EBT_IPROTO 0x01 111 #define EBT_IIN 0x02 112 #define EBT_IOUT 0x04 113 #define EBT_ISOURCE 0x8 114 #define EBT_IDEST 0x10 115 #define EBT_ILOGICALIN 0x20 116 #define EBT_ILOGICALOUT 0x40 117 #define EBT_INV_MASK (EBT_IPROTO | EBT_IIN | EBT_IOUT | EBT_ILOGICALIN \ 118 | EBT_ILOGICALOUT | EBT_ISOURCE | EBT_IDEST) 119 120 struct ebt_entry_match 121 { 122 union { 123 char name[EBT_FUNCTION_MAXNAMELEN]; 124 struct ebt_match *match; 125 } u; 126 /* size of data */ 127 unsigned int match_size; 128 unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); 129 }; 130 131 struct ebt_entry_watcher 132 { 133 union { 134 char name[EBT_FUNCTION_MAXNAMELEN]; 135 struct ebt_watcher *watcher; 136 } u; 137 /* size of data */ 138 unsigned int watcher_size; 139 unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); 140 }; 141 142 struct ebt_entry_target 143 { 144 union { 145 char name[EBT_FUNCTION_MAXNAMELEN]; 146 struct ebt_target *target; 147 } u; 148 /* size of data */ 149 unsigned int target_size; 150 unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); 151 }; 152 153 #define EBT_STANDARD_TARGET "standard" 154 struct ebt_standard_target 155 { 156 struct ebt_entry_target target; 157 int verdict; 158 }; 159 160 /* one entry */ 161 struct ebt_entry { 162 /* this needs to be the first field */ 163 unsigned int bitmask; 164 unsigned int invflags; 165 __be16 ethproto; 166 /* the physical in-dev */ 167 char in[IFNAMSIZ]; 168 /* the logical in-dev */ 169 char logical_in[IFNAMSIZ]; 170 /* the physical out-dev */ 171 char out[IFNAMSIZ]; 172 /* the logical out-dev */ 173 char logical_out[IFNAMSIZ]; 174 unsigned char sourcemac[ETH_ALEN]; 175 unsigned char sourcemsk[ETH_ALEN]; 176 unsigned char destmac[ETH_ALEN]; 177 unsigned char destmsk[ETH_ALEN]; 178 /* sizeof ebt_entry + matches */ 179 unsigned int watchers_offset; 180 /* sizeof ebt_entry + matches + watchers */ 181 unsigned int target_offset; 182 /* sizeof ebt_entry + matches + watchers + target */ 183 unsigned int next_offset; 184 unsigned char elems[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); 185 }; 186 187 /* {g,s}etsockopt numbers */ 188 #define EBT_BASE_CTL 128 189 190 #define EBT_SO_SET_ENTRIES (EBT_BASE_CTL) 191 #define EBT_SO_SET_COUNTERS (EBT_SO_SET_ENTRIES+1) 192 #define EBT_SO_SET_MAX (EBT_SO_SET_COUNTERS+1) 193 194 #define EBT_SO_GET_INFO (EBT_BASE_CTL) 195 #define EBT_SO_GET_ENTRIES (EBT_SO_GET_INFO+1) 196 #define EBT_SO_GET_INIT_INFO (EBT_SO_GET_ENTRIES+1) 197 #define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO+1) 198 #define EBT_SO_GET_MAX (EBT_SO_GET_INIT_ENTRIES+1) 199 200 201 /* blatently stolen from ip_tables.h 202 * fn returns 0 to continue iteration */ 203 #define EBT_MATCH_ITERATE(e, fn, args...) \ 204 ({ \ 205 unsigned int __i; \ 206 int __ret = 0; \ 207 struct ebt_entry_match *__match; \ 208 \ 209 for (__i = sizeof(struct ebt_entry); \ 210 __i < (e)->watchers_offset; \ 211 __i += __match->match_size + \ 212 sizeof(struct ebt_entry_match)) { \ 213 __match = (void *)(e) + __i; \ 214 \ 215 __ret = fn(__match , ## args); \ 216 if (__ret != 0) \ 217 break; \ 218 } \ 219 if (__ret == 0) { \ 220 if (__i != (e)->watchers_offset) \ 221 __ret = -EINVAL; \ 222 } \ 223 __ret; \ 224 }) 225 226 #define EBT_WATCHER_ITERATE(e, fn, args...) \ 227 ({ \ 228 unsigned int __i; \ 229 int __ret = 0; \ 230 struct ebt_entry_watcher *__watcher; \ 231 \ 232 for (__i = e->watchers_offset; \ 233 __i < (e)->target_offset; \ 234 __i += __watcher->watcher_size + \ 235 sizeof(struct ebt_entry_watcher)) { \ 236 __watcher = (void *)(e) + __i; \ 237 \ 238 __ret = fn(__watcher , ## args); \ 239 if (__ret != 0) \ 240 break; \ 241 } \ 242 if (__ret == 0) { \ 243 if (__i != (e)->target_offset) \ 244 __ret = -EINVAL; \ 245 } \ 246 __ret; \ 247 }) 248 249 #define EBT_ENTRY_ITERATE(entries, size, fn, args...) \ 250 ({ \ 251 unsigned int __i; \ 252 int __ret = 0; \ 253 struct ebt_entry *__entry; \ 254 \ 255 for (__i = 0; __i < (size);) { \ 256 __entry = (void *)(entries) + __i; \ 257 __ret = fn(__entry , ## args); \ 258 if (__ret != 0) \ 259 break; \ 260 if (__entry->bitmask != 0) \ 261 __i += __entry->next_offset; \ 262 else \ 263 __i += sizeof(struct ebt_entries); \ 264 } \ 265 if (__ret == 0) { \ 266 if (__i != (size)) \ 267 __ret = -EINVAL; \ 268 } \ 269 __ret; \ 270 }) 271 272 #endif 273