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