/*
|
/*
|
* Constants and structure definitions for the bridging code
|
* Constants and structure definitions for the bridging code
|
*/
|
*/
|
|
|
#if !defined(One)
|
#if !defined(One)
|
#define Zero 0
|
#define Zero 0
|
#define One 1
|
#define One 1
|
#endif /* !defined(One) */
|
#endif /* !defined(One) */
|
|
|
#if !defined(TRUE)
|
#if !defined(TRUE)
|
#define FALSE 0
|
#define FALSE 0
|
#define TRUE 1
|
#define TRUE 1
|
#endif /* !defined(TRUE) */
|
#endif /* !defined(TRUE) */
|
|
|
/** port states. **/
|
/** port states. **/
|
#define Disabled 0 /* (4.4 5) */
|
#define Disabled 0 /* (4.4 5) */
|
#define Listening 1 /* (4.4.2) */
|
#define Listening 1 /* (4.4.2) */
|
#define Learning 2 /* (4.4.3) */
|
#define Learning 2 /* (4.4.3) */
|
#define Forwarding 3 /* (4 4 4) */
|
#define Forwarding 3 /* (4 4 4) */
|
#define Blocking 4 /* (4.4.1) */
|
#define Blocking 4 /* (4.4.1) */
|
|
|
#define No_of_ports 8
|
#define No_of_ports 8
|
/* arbitrary choice, to allow the code below to compile */
|
/* arbitrary choice, to allow the code below to compile */
|
|
|
#define All_ports (No_of_ports + 1)
|
#define All_ports (No_of_ports + 1)
|
|
|
/*
|
/*
|
* We time out our entries in the FDB after this many seconds.
|
* We time out our entries in the FDB after this many seconds.
|
*/
|
*/
|
#define FDB_TIMEOUT 300
|
#define FDB_TIMEOUT 300
|
|
|
/*
|
/*
|
* the following defines are the initial values used when the
|
* the following defines are the initial values used when the
|
* bridge is booted. These may be overridden when this bridge is
|
* bridge is booted. These may be overridden when this bridge is
|
* not the root bridge. These are the recommended default values
|
* not the root bridge. These are the recommended default values
|
* from the 802.1d specification.
|
* from the 802.1d specification.
|
*/
|
*/
|
#define BRIDGE_MAX_AGE 20
|
#define BRIDGE_MAX_AGE 20
|
#define BRIDGE_HELLO_TIME 2
|
#define BRIDGE_HELLO_TIME 2
|
#define BRIDGE_FORWARD_DELAY 15
|
#define BRIDGE_FORWARD_DELAY 15
|
#define HOLD_TIME 1
|
#define HOLD_TIME 1
|
|
|
#define Default_path_cost 10
|
#define Default_path_cost 10
|
|
|
/*
|
/*
|
* minimum increment possible to avoid underestimating age, allows for BPDU
|
* minimum increment possible to avoid underestimating age, allows for BPDU
|
* transmission time
|
* transmission time
|
*/
|
*/
|
#define Message_age_increment 1
|
#define Message_age_increment 1
|
|
|
#define No_port 0
|
#define No_port 0
|
/*
|
/*
|
* reserved value for Bridge's root port parameter indicating no root port,
|
* 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
|
* 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
|
* a frame is being generated by a higher layer protocol on this host
|
*/
|
*/
|
|
|
/** Configuration BPDU Parameters (4.5.1) **/
|
/** Configuration BPDU Parameters (4.5.1) **/
|
|
|
typedef struct {
|
typedef struct {
|
union {
|
union {
|
struct {
|
struct {
|
unsigned short priority;
|
unsigned short priority;
|
unsigned char ula[6];
|
unsigned char ula[6];
|
} p_u;
|
} p_u;
|
unsigned int id[2];
|
unsigned int id[2];
|
} bi;
|
} bi;
|
} bridge_id_t;
|
} bridge_id_t;
|
|
|
#define BRIDGE_PRIORITY bi.p_u.priority
|
#define BRIDGE_PRIORITY bi.p_u.priority
|
#define BRIDGE_ID_ULA bi.p_u.ula
|
#define BRIDGE_ID_ULA bi.p_u.ula
|
#define BRIDGE_ID bi.id
|
#define BRIDGE_ID bi.id
|
|
|
typedef struct {
|
typedef struct {
|
unsigned short protocol_id;
|
unsigned short protocol_id;
|
unsigned char protocol_version_id;
|
unsigned char protocol_version_id;
|
unsigned char type;
|
unsigned char type;
|
unsigned char flags;
|
unsigned char flags;
|
#define TOPOLOGY_CHANGE 0x01
|
#define TOPOLOGY_CHANGE 0x01
|
#define TOPOLOGY_CHANGE_ACK 0x80
|
#define TOPOLOGY_CHANGE_ACK 0x80
|
bridge_id_t root_id; /* (4.5.1.1) */
|
bridge_id_t root_id; /* (4.5.1.1) */
|
unsigned int root_path_cost; /* (4.5.1.2) */
|
unsigned int root_path_cost; /* (4.5.1.2) */
|
bridge_id_t bridge_id; /* (4.5.1.3) */
|
bridge_id_t bridge_id; /* (4.5.1.3) */
|
unsigned short port_id; /* (4.5.1.4) */
|
unsigned short port_id; /* (4.5.1.4) */
|
unsigned short message_age; /* (4.5.1.5) */
|
unsigned short message_age; /* (4.5.1.5) */
|
unsigned short max_age; /* (4.5.1.6) */
|
unsigned short max_age; /* (4.5.1.6) */
|
unsigned short hello_time; /* (4.5.1.7) */
|
unsigned short hello_time; /* (4.5.1.7) */
|
unsigned short forward_delay; /* (4.5.1.8) */
|
unsigned short forward_delay; /* (4.5.1.8) */
|
} Config_bpdu;
|
} Config_bpdu;
|
|
|
|
|
/** Topology Change Notification BPDU Parameters (4.5.2) **/
|
/** Topology Change Notification BPDU Parameters (4.5.2) **/
|
|
|
typedef struct {
|
typedef struct {
|
unsigned short protocol_id;
|
unsigned short protocol_id;
|
unsigned char protocol_version_id;
|
unsigned char protocol_version_id;
|
unsigned char type;
|
unsigned char type;
|
} Tcn_bpdu;
|
} Tcn_bpdu;
|
|
|
#define BPDU_TYPE_CONFIG 0
|
#define BPDU_TYPE_CONFIG 0
|
#define BPDU_TYPE_TOPO_CHANGE 128
|
#define BPDU_TYPE_TOPO_CHANGE 128
|
|
|
/** Bridge Parameters (4.5.3) **/
|
/** Bridge Parameters (4.5.3) **/
|
typedef struct {
|
typedef struct {
|
bridge_id_t designated_root; /* (4.5.3.1) */
|
bridge_id_t designated_root; /* (4.5.3.1) */
|
unsigned int root_path_cost; /* (4.5.3.2) */
|
unsigned int root_path_cost; /* (4.5.3.2) */
|
unsigned int root_port; /* (4.5.3.3) */
|
unsigned int root_port; /* (4.5.3.3) */
|
unsigned short max_age; /* (4.5.3.4) */
|
unsigned short max_age; /* (4.5.3.4) */
|
unsigned short hello_time; /* (4.5.3.5) */
|
unsigned short hello_time; /* (4.5.3.5) */
|
unsigned short forward_delay; /* (4.5.3.6) */
|
unsigned short forward_delay; /* (4.5.3.6) */
|
bridge_id_t bridge_id; /* (4.5.3.7) */
|
bridge_id_t bridge_id; /* (4.5.3.7) */
|
unsigned short bridge_max_age; /* (4.5.3.8) */
|
unsigned short bridge_max_age; /* (4.5.3.8) */
|
unsigned short bridge_hello_time; /* (4.5.3.9) */
|
unsigned short bridge_hello_time; /* (4.5.3.9) */
|
unsigned short bridge_forward_delay; /* (4.5.3.10) */
|
unsigned short bridge_forward_delay; /* (4.5.3.10) */
|
unsigned int topology_change_detected; /* (4.5.3.11) */
|
unsigned int topology_change_detected; /* (4.5.3.11) */
|
unsigned int topology_change; /* (4.5.3.12) */
|
unsigned int topology_change; /* (4.5.3.12) */
|
unsigned short topology_change_time; /* (4.5.3.13) */
|
unsigned short topology_change_time; /* (4.5.3.13) */
|
unsigned short hold_time; /* (4.5.3.14) */
|
unsigned short hold_time; /* (4.5.3.14) */
|
unsigned int top_change;
|
unsigned int top_change;
|
unsigned int top_change_detected;
|
unsigned int top_change_detected;
|
} Bridge_data;
|
} Bridge_data;
|
|
|
/** Port Parameters (4.5.5) **/
|
/** Port Parameters (4.5.5) **/
|
typedef struct {
|
typedef struct {
|
unsigned short port_id; /* (4.5.5.1) */
|
unsigned short port_id; /* (4.5.5.1) */
|
unsigned int state; /* (4.5.5.2) */
|
unsigned int state; /* (4.5.5.2) */
|
unsigned int path_cost; /* (4.5.5.3) */
|
unsigned int path_cost; /* (4.5.5.3) */
|
bridge_id_t designated_root; /* (4.5.5.4) */
|
bridge_id_t designated_root; /* (4.5.5.4) */
|
unsigned int designated_cost; /* (4.5.5.5) */
|
unsigned int designated_cost; /* (4.5.5.5) */
|
bridge_id_t designated_bridge; /* (4.5.5.6) */
|
bridge_id_t designated_bridge; /* (4.5.5.6) */
|
unsigned short designated_port; /* (4.5.5.7) */
|
unsigned short designated_port; /* (4.5.5.7) */
|
unsigned int top_change_ack; /* (4.5.5.8) */
|
unsigned int top_change_ack; /* (4.5.5.8) */
|
unsigned int config_pending; /* (4.5.5.9) */
|
unsigned int config_pending; /* (4.5.5.9) */
|
struct device *dev;
|
struct device *dev;
|
struct fdb *fdb; /* head of per port fdb chain */
|
struct fdb *fdb; /* head of per port fdb chain */
|
} Port_data;
|
} Port_data;
|
|
|
|
|
|
|
/** types to support timers for this pseudo-implementation. **/
|
/** types to support timers for this pseudo-implementation. **/
|
typedef struct {
|
typedef struct {
|
unsigned int active; /* timer in use. */
|
unsigned int active; /* timer in use. */
|
unsigned int value; /* current value of timer,
|
unsigned int value; /* current value of timer,
|
* counting up. */
|
* counting up. */
|
} Timer;
|
} Timer;
|
|
|
struct fdb {
|
struct fdb {
|
unsigned char ula[6];
|
unsigned char ula[6];
|
unsigned char pad[2];
|
unsigned char pad[2];
|
unsigned short port;
|
unsigned short port;
|
unsigned int timer;
|
unsigned int timer;
|
unsigned int flags;
|
unsigned int flags;
|
#define FDB_ENT_VALID 0x01
|
#define FDB_ENT_VALID 0x01
|
/* AVL tree of all addresses, sorted by address */
|
/* AVL tree of all addresses, sorted by address */
|
short fdb_avl_height;
|
short fdb_avl_height;
|
struct fdb *fdb_avl_left;
|
struct fdb *fdb_avl_left;
|
struct fdb *fdb_avl_right;
|
struct fdb *fdb_avl_right;
|
/* linked list of addresses for each port */
|
/* linked list of addresses for each port */
|
struct fdb *fdb_next;
|
struct fdb *fdb_next;
|
};
|
};
|
|
|
#define IS_BRIDGED 0x2e
|
#define IS_BRIDGED 0x2e
|
|
|
struct br_stat {
|
struct br_stat {
|
unsigned int flags;
|
unsigned int flags;
|
Bridge_data bridge_data;
|
Bridge_data bridge_data;
|
Port_data port_data[No_of_ports];
|
Port_data port_data[No_of_ports];
|
};
|
};
|
|
|
/* defined flags for br_stat.flags */
|
/* defined flags for br_stat.flags */
|
#define BR_UP 0x0001 /* bridging enabled */
|
#define BR_UP 0x0001 /* bridging enabled */
|
#define BR_DEBUG 0x0002 /* debugging enabled */
|
#define BR_DEBUG 0x0002 /* debugging enabled */
|
|
|
struct br_cf {
|
struct br_cf {
|
unsigned int cmd;
|
unsigned int cmd;
|
unsigned int arg1;
|
unsigned int arg1;
|
unsigned int arg2;
|
unsigned int arg2;
|
};
|
};
|
|
|
/* defined cmds */
|
/* defined cmds */
|
#define BRCMD_BRIDGE_ENABLE 1
|
#define BRCMD_BRIDGE_ENABLE 1
|
#define BRCMD_BRIDGE_DISABLE 2
|
#define BRCMD_BRIDGE_DISABLE 2
|
#define BRCMD_PORT_ENABLE 3 /* arg1 = port */
|
#define BRCMD_PORT_ENABLE 3 /* arg1 = port */
|
#define BRCMD_PORT_DISABLE 4 /* arg1 = port */
|
#define BRCMD_PORT_DISABLE 4 /* arg1 = port */
|
#define BRCMD_SET_BRIDGE_PRIORITY 5 /* arg1 = priority */
|
#define BRCMD_SET_BRIDGE_PRIORITY 5 /* arg1 = priority */
|
#define BRCMD_SET_PORT_PRIORITY 6 /* arg1 = port, arg2 = priority */
|
#define BRCMD_SET_PORT_PRIORITY 6 /* arg1 = port, arg2 = priority */
|
#define BRCMD_SET_PATH_COST 7 /* arg1 = port, arg2 = cost */
|
#define BRCMD_SET_PATH_COST 7 /* arg1 = port, arg2 = cost */
|
#define BRCMD_DISPLAY_FDB 8 /* arg1 = port */
|
#define BRCMD_DISPLAY_FDB 8 /* arg1 = port */
|
#define BRCMD_ENABLE_DEBUG 9
|
#define BRCMD_ENABLE_DEBUG 9
|
#define BRCMD_DISABLE_DEBUG 10
|
#define BRCMD_DISABLE_DEBUG 10
|
|
|
/* prototypes of all bridging functions... */
|
/* prototypes of all bridging functions... */
|
|
|
void transmit_config(int port_no);
|
void transmit_config(int port_no);
|
int root_bridge(void);
|
int root_bridge(void);
|
int supersedes_port_info(int port_no, Config_bpdu *config);
|
int supersedes_port_info(int port_no, Config_bpdu *config);
|
void record_config_information(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 record_config_timeout_values(Config_bpdu *config);
|
void config_bpdu_generation(void);
|
void config_bpdu_generation(void);
|
int designated_port(int port_no);
|
int designated_port(int port_no);
|
void reply(int port_no);
|
void reply(int port_no);
|
void transmit_tcn(void);
|
void transmit_tcn(void);
|
void configuration_update(void);
|
void configuration_update(void);
|
void root_selection(void);
|
void root_selection(void);
|
void designated_port_selection(void);
|
void designated_port_selection(void);
|
void become_designated_port(int port_no);
|
void become_designated_port(int port_no);
|
void port_state_selection(void);
|
void port_state_selection(void);
|
void make_forwarding(int port_no);
|
void make_forwarding(int port_no);
|
void topology_change_detection(void);
|
void topology_change_detection(void);
|
void topology_change_acknowledged(void);
|
void topology_change_acknowledged(void);
|
void acknowledge_topology_change(int port_no);
|
void acknowledge_topology_change(int port_no);
|
void make_blocking(int port_no);
|
void make_blocking(int port_no);
|
void set_port_state(int port_no, int state);
|
void set_port_state(int port_no, int state);
|
void received_config_bpdu(int port_no, Config_bpdu *config);
|
void received_config_bpdu(int port_no, Config_bpdu *config);
|
void received_tcn_bpdu(int port_no, Tcn_bpdu *tcn);
|
void received_tcn_bpdu(int port_no, Tcn_bpdu *tcn);
|
void hello_timer_expiry(void);
|
void hello_timer_expiry(void);
|
void message_age_timer_expiry(int port_no);
|
void message_age_timer_expiry(int port_no);
|
void forward_delay_timer_expiry(int port_no);
|
void forward_delay_timer_expiry(int port_no);
|
int designated_for_some_port(void);
|
int designated_for_some_port(void);
|
void tcn_timer_expiry(void);
|
void tcn_timer_expiry(void);
|
void topology_change_timer_expiry(void);
|
void topology_change_timer_expiry(void);
|
void hold_timer_expiry(int port_no);
|
void hold_timer_expiry(int port_no);
|
void br_init(void);
|
void br_init(void);
|
void br_init_port(int port_no);
|
void br_init_port(int port_no);
|
void enable_port(int port_no);
|
void enable_port(int port_no);
|
void disable_port(int port_no);
|
void disable_port(int port_no);
|
void set_bridge_priority(bridge_id_t *new_bridge_id);
|
void set_bridge_priority(bridge_id_t *new_bridge_id);
|
void set_port_priority(int port_no, unsigned short new_port_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 set_path_cost(int port_no, unsigned short path_cost);
|
void start_hello_timer(void);
|
void start_hello_timer(void);
|
void stop_hello_timer(void);
|
void stop_hello_timer(void);
|
int hello_timer_expired(void);
|
int hello_timer_expired(void);
|
void start_tcn_timer(void);
|
void start_tcn_timer(void);
|
void stop_tcn_timer(void);
|
void stop_tcn_timer(void);
|
int tcn_timer_expired(void);
|
int tcn_timer_expired(void);
|
void start_topology_change_timer(void);
|
void start_topology_change_timer(void);
|
void stop_topology_change_timer(void);
|
void stop_topology_change_timer(void);
|
int topology_change_timer_expired(void);
|
int topology_change_timer_expired(void);
|
void start_message_age_timer(int port_no, unsigned short message_age);
|
void start_message_age_timer(int port_no, unsigned short message_age);
|
void stop_message_age_timer(int port_no);
|
void stop_message_age_timer(int port_no);
|
int message_age_timer_expired(int port_no);
|
int message_age_timer_expired(int port_no);
|
void start_forward_delay_timer(int port_no);
|
void start_forward_delay_timer(int port_no);
|
void stop_forward_delay_timer(int port_no);
|
void stop_forward_delay_timer(int port_no);
|
int forward_delay_timer_expired(int port_no);
|
int forward_delay_timer_expired(int port_no);
|
void start_hold_timer(int port_no);
|
void start_hold_timer(int port_no);
|
void stop_hold_timer(int port_no);
|
void stop_hold_timer(int port_no);
|
int hold_timer_expired(int port_no);
|
int hold_timer_expired(int port_no);
|
|
|
struct fdb *br_avl_find_addr(unsigned char addr[6]);
|
struct fdb *br_avl_find_addr(unsigned char addr[6]);
|
int br_avl_insert (struct fdb * new_node);
|
int br_avl_insert (struct fdb * new_node);
|
int br_avl_remove (struct fdb * node_to_delete);
|
int br_avl_remove (struct fdb * node_to_delete);
|
|
|
int send_tcn_bpdu(int port_no, Tcn_bpdu *bpdu);
|
int send_tcn_bpdu(int port_no, Tcn_bpdu *bpdu);
|
int send_config_bpdu(int port_no, Config_bpdu *config_bpdu);
|
int send_config_bpdu(int port_no, Config_bpdu *config_bpdu);
|
int find_port(struct device *dev);
|
int find_port(struct device *dev);
|
int br_flood(struct sk_buff *skb, int port);
|
int br_flood(struct sk_buff *skb, int port);
|
int br_drop(struct sk_buff *skb);
|
int br_drop(struct sk_buff *skb);
|
int br_learn(struct sk_buff *skb, int port); /* 3.8 */
|
int br_learn(struct sk_buff *skb, int port); /* 3.8 */
|
|
|
int br_receive_frame(struct sk_buff *skb); /* 3.5 */
|
int br_receive_frame(struct sk_buff *skb); /* 3.5 */
|
int br_tx_frame(struct sk_buff *skb);
|
int br_tx_frame(struct sk_buff *skb);
|
int br_ioctl(unsigned int cmd, void *arg);
|
int br_ioctl(unsigned int cmd, void *arg);
|
|
|
void free_fdb(struct fdb *);
|
void free_fdb(struct fdb *);
|
struct fdb *get_fdb(void);
|
struct fdb *get_fdb(void);
|
|
|
/* externs */
|
/* externs */
|
|
|
extern struct br_stat br_stats;
|
extern struct br_stat br_stats;
|
|
|
|
|