Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 | /*
* Constants and structure definitions for the bridging code
*/
#if !defined(One)
#define Zero 0
#define One 1
#endif /* !defined(One) */
#if !defined(TRUE)
#define FALSE 0
#define TRUE 1
#endif /* !defined(TRUE) */
/** port states. **/
#define Disabled 0 /* (4.4 5) */
#define Listening 1 /* (4.4.2) */
#define Learning 2 /* (4.4.3) */
#define Forwarding 3 /* (4 4 4) */
#define Blocking 4 /* (4.4.1) */
/* MAG Yich! Easiest way of giving a configurable number of ports
* If you want more than 32, change BR_MAX_PORTS and recompile brcfg!
*/
#define BR_MAX_PORTS (32)
#if CONFIG_BRIDGE_NUM_PORTS > BR_MAX_PORTS
#undef CONFIG_BRIDGE_NUM_PORTS
#define CONFIG_BRIDGE_NUM_PORTS BR_MAX_PORTS
#endif
#define No_of_ports CONFIG_BRIDGE_NUM_PORTS
/* arbitrary choice, to allow the code below to compile */
#define All_ports (No_of_ports + 1)
/*
* We time out our entries in the FDB after this many seconds.
*/
#define FDB_TIMEOUT 20 /* JRP: 20s as NSC bridge code, was 300 for Linux */
/*
* the following defines are the initial values used when the
* bridge is booted. These may be overridden when this bridge is
* not the root bridge. These are the recommended default values
* from the 802.1d specification.
*/
#define BRIDGE_MAX_AGE 20
#define BRIDGE_HELLO_TIME 2
#define BRIDGE_FORWARD_DELAY 15
#define HOLD_TIME 1
/* broacast/multicast storm limitation. This per source. */
#define MAX_MCAST_PER_PERIOD 32
#define MCAST_HOLD_TIME (10*HZ/100)
#define Default_path_cost 10
/*
* minimum increment possible to avoid underestimating age, allows for BPDU
* transmission time
*/
#define Message_age_increment 1
#define No_port 0
/*
* reserved value for Bridge's root port parameter indicating no root port,
* used when Bridge is the root - also used to indicate the source when
* a frame is being generated by a higher layer protocol on this host
*/
/** Configuration BPDU Parameters (4.5.1) **/
typedef struct {
union {
struct {
unsigned short priority;
unsigned char ula[6];
} p_u;
unsigned int id[2];
} bi;
} bridge_id_t;
#define BRIDGE_PRIORITY bi.p_u.priority
#define BRIDGE_ID_ULA bi.p_u.ula
#define BRIDGE_ID bi.id
/* JRP: on the network the flags field is between "type" and "root_id"
* this is unfortunated! To make the code portable to a RISC machine
* the pdus are now massaged a little bit for processing
*/
#define TOPOLOGY_CHANGE 0x01
#define TOPOLOGY_CHANGE_ACK 0x80
#define BRIDGE_BPDU_8021_CONFIG_SIZE 35 /* real size */
#define BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET 4
#define BRIDGE_BPDU_8021_PROTOCOL_ID 0
#define BRIDGE_BPDU_8021_PROTOCOL_VERSION_ID 0
#define BRIDGE_LLC1_HS 3
#define BRIDGE_LLC1_DSAP 0x42
#define BRIDGE_LLC1_SSAP 0x42
#define BRIDGE_LLC1_CTRL 0x03
typedef struct {
unsigned short protocol_id;
unsigned char protocol_version_id;
unsigned char type;
bridge_id_t root_id; /* (4.5.1.1) */
unsigned int root_path_cost; /* (4.5.1.2) */
bridge_id_t bridge_id; /* (4.5.1.3) */
unsigned short port_id; /* (4.5.1.4) */
unsigned short message_age; /* (4.5.1.5) */
unsigned short max_age; /* (4.5.1.6) */
unsigned short hello_time; /* (4.5.1.7) */
unsigned short forward_delay; /* (4.5.1.8) */
unsigned char top_change_ack;
unsigned char top_change;
} Config_bpdu;
#ifdef __LITTLE_ENDIAN
#define config_bpdu_hton(config_bpdu) \
(config_bpdu)->root_path_cost = htonl((config_bpdu)->root_path_cost); \
(config_bpdu)->port_id = htons((config_bpdu)->port_id); \
(config_bpdu)->message_age = htons((config_bpdu)->message_age); \
(config_bpdu)->max_age = htons((config_bpdu)->max_age); \
(config_bpdu)->hello_time = htons((config_bpdu)->hello_time); \
(config_bpdu)->forward_delay = htons((config_bpdu)->forward_delay);
#else
#define config_bpdu_hton(config_bpdu)
#endif
#define config_bpdu_ntoh config_bpdu_hton
/** Topology Change Notification BPDU Parameters (4.5.2) **/
typedef struct {
unsigned short protocol_id;
unsigned char protocol_version_id;
unsigned char type;
} Tcn_bpdu;
#define BPDU_TYPE_CONFIG 0
#define BPDU_TYPE_TOPO_CHANGE 128
/** Bridge Parameters (4.5.3) **/
typedef struct {
bridge_id_t designated_root; /* (4.5.3.1) */
unsigned int root_path_cost; /* (4.5.3.2) */
unsigned int root_port; /* (4.5.3.3) */
unsigned short max_age; /* (4.5.3.4) */
unsigned short hello_time; /* (4.5.3.5) */
unsigned short forward_delay; /* (4.5.3.6) */
bridge_id_t bridge_id; /* (4.5.3.7) */
unsigned short bridge_max_age; /* (4.5.3.8) */
unsigned short bridge_hello_time; /* (4.5.3.9) */
unsigned short bridge_forward_delay; /* (4.5.3.10) */
unsigned int top_change_detected; /* (4.5.3.11) */
unsigned int top_change; /* (4.5.3.12) */
unsigned short topology_change_time; /* (4.5.3.13) */
unsigned short hold_time; /* (4.5.3.14) */
unsigned int instance;
} Bridge_data;
/** Port Parameters (4.5.5) **/
typedef struct {
unsigned short port_id; /* (4.5.5.1) */
unsigned int state; /* (4.5.5.2) */
unsigned int path_cost; /* (4.5.5.3) */
bridge_id_t designated_root; /* (4.5.5.4) */
unsigned int designated_cost; /* (4.5.5.5) */
bridge_id_t designated_bridge; /* (4.5.5.6) */
unsigned short designated_port; /* (4.5.5.7) */
unsigned int top_change_ack; /* (4.5.5.8) */
unsigned int config_pending; /* (4.5.5.9) */
bridge_id_t ifmac;
unsigned int admin_state;
char ifname[IFNAMSIZ]; /* Make life easier for brcfg */
struct device *dev;
struct fdb *fdb; /* head of per port fdb chain */
} Port_data;
/** types to support timers for this pseudo-implementation. **/
typedef struct {
unsigned int active; /* timer in use. */
unsigned int value; /* current value of timer,
* counting up. */
} Timer;
struct fdb {
unsigned char ula[6];
unsigned char pad[2];
unsigned short port;
unsigned int timer;
unsigned short flags;
#define FDB_ENT_VALID 0x01
unsigned short mcast_count;
unsigned int mcast_timer; /* oldest xxxxxcast */
/* AVL tree of all addresses, sorted by address */
short fdb_avl_height;
struct fdb *fdb_avl_left;
struct fdb *fdb_avl_right;
/* linked list of addresses for each port */
struct fdb *fdb_next;
};
/* data returned on BRCMD_DISPLAY_FDB */
struct fdb_info {
unsigned char ula[6];
unsigned char port;
unsigned char flags;
unsigned int timer;
};
struct fdb_info_hdr {
int copied; /* nb of entries copied to user */
int not_copied; /* when user buffer is too small */
int cmd_time;
};
#define IS_BRIDGED 0x2e
#define BR_MAX_PROTOCOLS 32
#define BR_MAX_PROT_STATS BR_MAX_PROTOCOLS
/* policy values for policy field */
#define BR_ACCEPT 1
#define BR_REJECT 0
/* JRP: extra statistics for debug */
typedef struct {
/* br_receive_frame counters */
int port_disable_up_stack;
int rcv_bpdu;
int notForwarding;
int forwarding_up_stack;
int unknown_state;
/* br_tx_frame counters */
int port_disable;
int port_not_disable;
/* br_forward counters */
int local_multicast;
int forwarded_multicast; /* up stack as well */
int flood_unicast;
int aged_flood_unicast;
int forwarded_unicast;
int forwarded_unicast_up_stack;
int forwarded_ip_up_stack;
int forwarded_ip_up_stack_lie; /* received on alternate device */
int arp_for_local_mac;
int drop_same_port;
int drop_same_port_aged;
int drop_multicast;
} br_stats_counter;
struct br_stat {
unsigned int flags;
Bridge_data bridge_data;
unsigned int policy;
unsigned int exempt_protocols;
unsigned short protocols[BR_MAX_PROTOCOLS];
unsigned short prot_id[BR_MAX_PROT_STATS]; /* Protocol encountered */
unsigned int prot_counter[BR_MAX_PROT_STATS]; /* How many packets ? */
br_stats_counter packet_cnts;
unsigned int num_ports;
Port_data port_data[BR_MAX_PORTS + 1];
};
/* defined flags for br_stat.flags */
#define BR_UP 0x0001 /* bridging enabled */
#define BR_DEBUG 0x0002 /* debugging enabled */
#define BR_PROT_STATS 0x0004 /* protocol statistics enabled */
#define BR_STP_DISABLED 0x0008 /* Spanning tree protocol disabled */
struct br_cf {
unsigned int cmd;
unsigned int arg1;
unsigned int arg2;
};
/* defined cmds */
#define BRCMD_BRIDGE_ENABLE 1
#define BRCMD_BRIDGE_DISABLE 2
#define BRCMD_PORT_ENABLE 3 /* arg1 = port */
#define BRCMD_PORT_DISABLE 4 /* arg1 = port */
#define BRCMD_SET_BRIDGE_PRIORITY 5 /* arg1 = priority */
#define BRCMD_SET_PORT_PRIORITY 6 /* arg1 = port, arg2 = priority */
#define BRCMD_SET_PATH_COST 7 /* arg1 = port, arg2 = cost */
#define BRCMD_DISPLAY_FDB 8
#define BRCMD_ENABLE_DEBUG 9
#define BRCMD_DISABLE_DEBUG 10
#define BRCMD_SET_POLICY 11 /* arg1 = default policy (1==bridge all) */
#define BRCMD_EXEMPT_PROTOCOL 12 /* arg1 = protocol (see net/if_ether.h) */
#define BRCMD_ENABLE_PROT_STATS 13
#define BRCMD_DISABLE_PROT_STATS 14
#define BRCMD_ZERO_PROT_STATS 15
#define BRCMD_TOGGLE_STP 16
#define BRCMD_IF_ENABLE 17 /* arg1 = if_index */
#define BRCMD_IF_DISABLE 18 /* arg1 = if_index */
#define BRCMD_SET_IF_PRIORITY 19 /* arg1 = if_index, arg2 = priority */
#define BRCMD_SET_IF_PATH_COST 20 /* arg1 = if_index, arg2 = cost */
/* prototypes of exported bridging functions... */
#ifdef __KERNEL__
void br_init(void);
int br_receive_frame(struct sk_buff *skb); /* 3.5 */
int br_tx_frame(struct sk_buff *skb);
int brg_init(void);
int br_ioctl(unsigned int cmd, void *arg);
void requeue_fdb(struct fdb *node, int new_port);
struct fdb *br_avl_find_addr(unsigned char addr[6]);
struct fdb *br_avl_insert (struct fdb * new_node);
void sprintf_avl (char **pbuffer, struct fdb * tree, off_t *pos,int* len, off_t offset, int length);
int br_tree_get_info(char *buffer, char **start, off_t offset, int length, int dummy);
void br_avl_delete_by_port(int port);
int br_call_bridge(struct sk_buff *skb, unsigned short type);
void br_spacedevice_register(void);
/* externs */
extern struct br_stat br_stats;
extern Port_data port_info[];
#endif
|