转:http://blog.csdn.net/nerdx/article/details/12291777
-
-
-
-
-
-
-
-
1.1 void br_transmit_config(struct net_bridge_port *p)
-
{
-
struct br_config_bpdu bpdu;
-
struct net_bridge *br;
-
-
-
if (timer_pending(&p->hold_timer)) {
-
p->config_pending = 1;
-
return;
-
}
-
-
br = p->br;
-
-
bpdu.topology_change = br->topology_change;
-
bpdu.topology_change_ack = p->topology_change_ack;
-
bpdu.root = br->designated_root;
-
bpdu.root_path_cost = br->root_path_cost;
-
bpdu.bridge_id = br->bridge_id;
-
bpdu.port_id = p->port_id;
-
if (br_is_root_bridge(br))
-
bpdu.message_age = 0;
-
else {
-
struct net_bridge_port *root
-
= br_get_port(br, br->root_port);
-
bpdu.message_age = br->max_age
-
- (root->message_age_timer.expires - jiffies)
-
+ MESSAGE_AGE_INCR;
-
}
-
bpdu.max_age = br->max_age;
-
bpdu.hello_time = br->hello_time;
-
bpdu.forward_delay = br->forward_delay;
-
-
if (bpdu.message_age < br->max_age) {
-
br_send_config_bpdu(p, &bpdu);
-
p->topology_change_ack = 0;
-
p->config_pending = 0;
-
mod_timer(&p->hold_timer, jiffies + BR_HOLD_TIME);
-
}
-
}
-
-
-
-
-
-
-
2.1 int br_stp_handle_bpdu(struct sk_buff *skb)
-
{
-
struct net_bridge_port *p = skb->dev->br_port;
-
struct net_bridge *br = p->br;
-
unsigned char *buf;
-
-
if (!pskb_may_pull(skb, sizeof(header)+1) ||
-
memcmp(skb->data, header, sizeof(header)))
-
goto err;
-
-
buf = skb_pull(skb, sizeof(header));
-
-
spin_lock_bh(&br->lock);
-
if (p->state == BR_STATE_DISABLED
-
|| !(br->dev->flags & IFF_UP)
-
|| !br->stp_enabled)
-
goto out;
-
-
if (buf[0] == BPDU_TYPE_CONFIG) {
-
struct br_config_bpdu bpdu;
-
-
if (!pskb_may_pull(skb, 32))
-
goto out;
-
-
buf = skb->data;
-
bpdu.topology_change = (buf[1] & 0x01) ? 1 : 0;
-
bpdu.topology_change_ack = (buf[1] & 0x80) ? 1 : 0;
-
-
bpdu.root.prio[0] = buf[2];
-
bpdu.root.prio[1] = buf[3];
-
bpdu.root.addr[0] = buf[4];
-
bpdu.root.addr[1] = buf[5];
-
bpdu.root.addr[2] = buf[6];
-
bpdu.root.addr[3] = buf[7];
-
bpdu.root.addr[4] = buf[8];
-
bpdu.root.addr[5] = buf[9];
-
bpdu.root_path_cost =
-
(buf[10] << 24) |
-
(buf[11] << 16) |
-
(buf[12] << 8) |
-
buf[13];
-
bpdu.bridge_id.prio[0] = buf[14];
-
bpdu.bridge_id.prio[1] = buf[15];
-
bpdu.bridge_id.addr[0] = buf[16];
-
bpdu.bridge_id.addr[1] = buf[17];
-
bpdu.bridge_id.addr[2] = buf[18];
-
bpdu.bridge_id.addr[3] = buf[19];
-
bpdu.bridge_id.addr[4] = buf[20];
-
bpdu.bridge_id.addr[5] = buf[21];
-
bpdu.port_id = (buf[22] << 8) | buf[23];
-
-
bpdu.message_age = br_get_ticks(buf+24);
-
bpdu.max_age = br_get_ticks(buf+26);
-
bpdu.hello_time = br_get_ticks(buf+28);
-
bpdu.forward_delay = br_get_ticks(buf+30);
-
-
br_received_config_bpdu(p, &bpdu);
-
}
-
-
else if (buf[0] == BPDU_TYPE_TCN) {
-
br_received_tcn_bpdu(p);
-
}
-
out:
-
spin_unlock_bh(&br->lock);
-
err:
-
kfree_skb(skb);
-
return 0;
-
}
-
-
-
-
-
-
-
-
-
-
-
-
2.2 void br_received_config_bpdu(struct net_bridge_port *p, struct br_config_bpdu *bpdu)
-
{
-
struct net_bridge *br;
-
int was_root;
-
-
br = p->br;
-
was_root = br_is_root_bridge(br);
-
-
if (br_supersedes_port_info(p, bpdu)) {
-
br_record_config_information(p, bpdu);
-
br_configuration_update(br);
-
br_port_state_selection(br);
-
-
if (!br_is_root_bridge(br) && was_root) {
-
del_timer(&br->hello_timer);
-
if (br->topology_change_detected) {
-
del_timer(&br->topology_change_timer);
-
br_transmit_tcn(br);
-
-
mod_timer(&br->tcn_timer,
-
jiffies + br->bridge_hello_time);
-
}
-
}
-
-
if (p->port_no == br->root_port) {
-
br_record_config_timeout_values(br, bpdu);
-
br_config_bpdu_generation(br);
-
if (bpdu->topology_change_ack)
-
br_topology_change_acknowledged(br);
-
}
-
} else if (br_is_designated_port(p)) {
-
br_reply(p);
-
}
-
}
-
阅读(1358) | 评论(0) | 转发(0) |