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 | /*
* 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) */
#define No_of_ports 8
/* 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 300
/*
* 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
#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
typedef struct {
unsigned short protocol_id;
unsigned char protocol_version_id;
unsigned char type;
unsigned char flags;
#define TOPOLOGY_CHANGE 0x01
#define TOPOLOGY_CHANGE_ACK 0x80
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) */
} Config_bpdu;
/** 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 topology_change_detected; /* (4.5.3.11) */
unsigned int topology_change; /* (4.5.3.12) */
unsigned short topology_change_time; /* (4.5.3.13) */
unsigned short hold_time; /* (4.5.3.14) */
unsigned int top_change;
unsigned int top_change_detected;
} 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) */
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 int flags;
#define FDB_ENT_VALID 0x01
/* 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;
};
#define IS_BRIDGED 0x2e
struct br_stat {
unsigned int flags;
Bridge_data bridge_data;
Port_data port_data[No_of_ports];
};
/* defined flags for br_stat.flags */
#define BR_UP 0x0001 /* bridging enabled */
#define BR_DEBUG 0x0002 /* debugging enabled */
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 /* arg1 = port */
#define BRCMD_ENABLE_DEBUG 9
#define BRCMD_DISABLE_DEBUG 10
/* prototypes of all bridging functions... */
void transmit_config(int port_no);
int root_bridge(void);
int supersedes_port_info(int port_no, Config_bpdu *config);
void record_config_information(int port_no, Config_bpdu *config);
void record_config_timeout_values(Config_bpdu *config);
void config_bpdu_generation(void);
int designated_port(int port_no);
void reply(int port_no);
void transmit_tcn(void);
void configuration_update(void);
void root_selection(void);
void designated_port_selection(void);
void become_designated_port(int port_no);
void port_state_selection(void);
void make_forwarding(int port_no);
void topology_change_detection(void);
void topology_change_acknowledged(void);
void acknowledge_topology_change(int port_no);
void make_blocking(int port_no);
void set_port_state(int port_no, int state);
void received_config_bpdu(int port_no, Config_bpdu *config);
void received_tcn_bpdu(int port_no, Tcn_bpdu *tcn);
void hello_timer_expiry(void);
void message_age_timer_expiry(int port_no);
void forward_delay_timer_expiry(int port_no);
int designated_for_some_port(void);
void tcn_timer_expiry(void);
void topology_change_timer_expiry(void);
void hold_timer_expiry(int port_no);
void br_init(void);
void br_init_port(int port_no);
void enable_port(int port_no);
void disable_port(int port_no);
void set_bridge_priority(bridge_id_t *new_bridge_id);
void set_port_priority(int port_no, unsigned short new_port_id);
void set_path_cost(int port_no, unsigned short path_cost);
void start_hello_timer(void);
void stop_hello_timer(void);
int hello_timer_expired(void);
void start_tcn_timer(void);
void stop_tcn_timer(void);
int tcn_timer_expired(void);
void start_topology_change_timer(void);
void stop_topology_change_timer(void);
int topology_change_timer_expired(void);
void start_message_age_timer(int port_no, unsigned short message_age);
void stop_message_age_timer(int port_no);
int message_age_timer_expired(int port_no);
void start_forward_delay_timer(int port_no);
void stop_forward_delay_timer(int port_no);
int forward_delay_timer_expired(int port_no);
void start_hold_timer(int port_no);
void stop_hold_timer(int port_no);
int hold_timer_expired(int port_no);
struct fdb *br_avl_find_addr(unsigned char addr[6]);
int br_avl_insert (struct fdb * new_node);
int br_avl_remove (struct fdb * node_to_delete);
int send_tcn_bpdu(int port_no, Tcn_bpdu *bpdu);
int send_config_bpdu(int port_no, Config_bpdu *config_bpdu);
int find_port(struct device *dev);
int br_flood(struct sk_buff *skb, int port);
int br_drop(struct sk_buff *skb);
int br_learn(struct sk_buff *skb, int port); /* 3.8 */
int br_receive_frame(struct sk_buff *skb); /* 3.5 */
int br_tx_frame(struct sk_buff *skb);
int br_ioctl(unsigned int cmd, void *arg);
void free_fdb(struct fdb *);
struct fdb *get_fdb(void);
/* externs */
extern struct br_stat br_stats;
|