?? stp-8021d-d17.c
字號:
/* stp-8021d-d17.c - Spanning Tree Algorithm and Protocol */
/* Copyright 2001 Wind River Systems, Inc. */
/* Copyright 1998-2000 Wind River Systems, Inc. */
/* Copyright 1999 Wind River Systems, Inc. */
/* Copyright 1998-1999 XACT, Inc. */
#include "copyright_wrs.h"
/*
modification history
--------------------
00g,12jun01,tf In transmit_tcn(), port_no was being tested before even set.
00f,18apr01,kc Replaced "extern" with "IMPORT".
00e,10dec00,ajw Changes to comments for refgen web pages
01c,16nov00,kw Ran thru lint.
01b,24sep00,kw Change the code to handle Identifier as a structure and not
a unsigned long long value. Using the 64 bit word has some
little endian problems for the pcSwitch.
01a,24sep00,kw Updated.
*/
/*
DESCRIPTION:
The routines in this midule interface spanLib to the lower level Spanning Tree
routines.
*
INCLUDES:
\ml
\m tmsTypes.h
\m spantree.h
\m spanglob.h
\m trap.h
\me
*/
#define INCLUDE_ID_ROUTINES
/* includes */
#include <stp/types.h>
#include <stp/spantree.h>
#include <stp/spanglob.h>
/* defines */
/* typedefs */
/* locals */
#ifndef _lint
char * span_version =
"STP Version: ISO/IEC Final DIS 15802-3 (IEEE P802.1D/D17) May 25, 1998\n";
#endif
Bridge_data bridge_info; /* (8.5.3) */
Port_data* port_info; /* (8.5.5) */
Config_bpdu* config_bpdu;
Tcn_bpdu* tcn_bpdu;
Timer hello_timer; /* (8.5.4.1) */
Timer tcn_timer; /* (8.5.4.2) */
Timer topology_change_timer; /* (8.5.4.3) */
Timer* message_age_timer; /* (8.5.6.1) */
Timer* forward_delay_timer; /* (8.5.6.2) */
Timer* hold_timer; /* (8.5.6.3) */
Timer since_topology_change;
/* globals */
/* forward declarations */
IMPORT STATUS No_of_ports;
/*******************************************************************************
* transmit_config -
*
* INPUTS:
*
* RETURNS:
*
* ERRORS:
*
* ERRNO:
*
* NOMANUAL <this will be removed later>
*/
void transmit_config
(
Int port_no
) /* (8.6.1) */
{
if (hold_timer[port_no].active) /* (8.6.1.3.1) */
{
port_info[port_no].config_pending = True; /* (8.6.1.3.1) */
}
else
/* (8.6.1.3.2) */
{
config_bpdu[port_no].type = Config_bpdu_type;
id_equate(config_bpdu[port_no].root_id, bridge_info.designated_root);
/* (8.6.1.3.2(a)) */
config_bpdu[port_no].root_path_cost = bridge_info.root_path_cost;
/* (8.6.1.3.2(b)) */
id_equate(config_bpdu[port_no].bridge_id, bridge_info.bridge_id);
/* (8.6.1.3.2(c)) */
config_bpdu[port_no].port_id = port_info[port_no].port_id;
/* (8.6.1.3.2(d)) */
if (root_bridge())
{
config_bpdu[port_no].message_age = Zero; /* (8.6.1.3.2(e)) */
}
else
{
config_bpdu[port_no].message_age
= message_age_timer[bridge_info.root_port].value
+ Message_age_increment; /* (8.6.1.3.2(f)) */
}
config_bpdu[port_no].max_age = bridge_info.max_age; /* (8.6.1.3.2(g)) */
config_bpdu[port_no].hello_time = bridge_info.hello_time;
config_bpdu[port_no].forward_delay = bridge_info.forward_delay;
config_bpdu[port_no].topology_change_acknowledgment
= (uchar_t)port_info[port_no].topology_change_acknowledge;
/* (8.6.1.3.2(h)) */
config_bpdu[port_no].topology_change
= (uchar_t)bridge_info.topology_change; /* (8.6.1.3.2(i)) */
if (config_bpdu[port_no].message_age < bridge_info.max_age)
{
port_info[port_no].topology_change_acknowledge = False;
/* (8.6.1.3.3) */
port_info[port_no].config_pending = False; /* (8.6.1.3.3) */
send_config_bpdu(port_no, &config_bpdu[port_no]);
start_hold_timer(port_no); /* (8.6.3.3(b)) */
}
}
}
/*******************************************************************************
* send_config_bpdu -
*
* INPUTS:
*
* RETURNS:
*
* ERRORS:
*
* ERRNO:
*
* NOMANUAL <this will be removed later>
*/
void send_config_bpdu
(
Int port_no,
Config_bpdu * bpdu
)
{
span_send_config_bpdu(port_no, bpdu);
}
/*******************************************************************************
* root_bridge -
*
* INPUTS:
*
* RETURNS:
*
* ERRORS:
*
* ERRNO:
*
* NOMANUAL <this will be removed later>
*/
Boolean root_bridge
(
void
)
{
return (id_eq(bridge_info.designated_root, bridge_info.bridge_id));
}
/*******************************************************************************
* supersedes_port_info -
*
* INPUTS:
*
* RETURNS:
*
* ERRORS:
*
* ERRNO:
*
* NOMANUAL <this will be removed later>
*/ /* (8.6.2.2) */
Boolean supersedes_port_info
(
Int port_no,
Config_bpdu * config
)
{
return (
/* (8.6.2.2.1) */
(id_lt(config->root_id, port_info[port_no].designated_root))
||
(
(id_eq(config->root_id, port_info[port_no].designated_root))
&&
/* (8.6.2.2.2) */
(
(config->root_path_cost < port_info[port_no].designated_cost)
||
(
(config->root_path_cost == port_info[port_no].designated_cost)
&&
/* (8.6.2.2.3) */
(
(id_lt(config->bridge_id, port_info[port_no].designated_bridge))
||
/* (8.6.2.2.4) */
(
(id_eq(config->bridge_id, port_info[port_no].designated_bridge))
&&
/* (8.6.2.2.4(a)) */
(
(id_neq(config->bridge_id, bridge_info.bridge_id))
||
/* (8.6.2.2.4(b)) */
(config->port_id <= port_info[port_no].designated_port)
)
)
)
)
)
)
);
}
/*******************************************************************************
* record_config_information -
*
* INPUTS:
*
* RETURNS:
*
* ERRORS:
*
* ERRNO:
*
* NOMANUAL <this will be removed later>
*/
LOCAL void record_config_information
(
Int port_no,
Config_bpdu * config
) /* (8.6.2) */
{
/* (8.6.2.3.1) */
id_equate(port_info[port_no].designated_root, config->root_id);
port_info[port_no].designated_cost = config->root_path_cost;
id_equate(port_info[port_no].designated_bridge, config->bridge_id);
port_info[port_no].designated_port = config->port_id;
start_message_age_timer(port_no, config->message_age); /* (8.6.2.3.2) */
}
/*******************************************************************************
* record_config_timeout_values -
*
* INPUTS:
*
* RETURNS:
*
* ERRORS:
*
* ERRNO:
*
* NOMANUAL <this will be removed later>
*/
void record_config_timeout_values
(
Config_bpdu * config
) /* (8.6.3) */
{
bridge_info.max_age = config->max_age; /* (8.6.3.3) */
bridge_info.hello_time = config->hello_time;
bridge_info.forward_delay = config->forward_delay;
bridge_info.topology_change = config->topology_change;
}
/*******************************************************************************
* config_bpdu_generation -
*
* INPUTS:
*
* RETURNS:
*
* ERRORS:
*
* ERRNO:
*
* NOMANUAL <this will be removed later>
*/
void config_bpdu_generation
(
void
) /* (8.6.4) */
{
Int port_no;
for (port_no = One; port_no <= No_of_ports; port_no++) /* (8.6.4.3) */
{
if (designated_port(port_no) /* (8.6.4.3) */
&&
(port_info[port_no].state != Disabled) &&
(port_info[port_no].portLinkBlockSet != TRUE)
)
{
transmit_config(port_no); /* (8.6.4.3) */
} /* (8.6.1.2) */
}
}
/*******************************************************************************
* designated_port -
*
* INPUTS:
*
* RETURNS:
*
* ERRORS:
*
* ERRNO:
*
* NOMANUAL <this will be removed later>
*/
Boolean designated_port
(
Int port_no
)
{
return ((id_eq(port_info[port_no].designated_bridge, bridge_info.bridge_id))
&&
(port_info[port_no].designated_port == port_info[port_no].port_id)
);
}
/*******************************************************************************
* reply -
*
* INPUTS:
*
* RETURNS:
*
* ERRORS:
*
* ERRNO:
*
* NOMANUAL <this will be removed later>
*/
void reply
(
Int port_no
) /* (8.6.5) */
{
transmit_config(port_no); /* (8.6.5.3) */
}
/*******************************************************************************
* transmit_tcn -
*
* INPUTS:
*
* RETURNS:
*
* ERRORS:
*
* ERRNO:
*
* NOMANUAL <this will be removed later>
*/
void transmit_tcn
(
void
) /* (8.6.6) */
{
Int port_no;
port_no = bridge_info.root_port;
#ifdef ST_FAST
/* if the root port hasn't been set yet, just return */
if ((port_no < One) || (port_no > No_of_ports))
return;
#endif /* ST_FAST */
tcn_bpdu[port_no].type = Tcn_bpdu_type;
send_tcn_bpdu(port_no, &tcn_bpdu[bridge_info.root_port]); /* (8.6.6.3) */
}
/*******************************************************************************
* send_tcn_bpdu -
*
* INPUTS:
*
* RETURNS:
*
* ERRORS:
*
* ERRNO:
*
* NOMANUAL <this will be removed later>
*/
void send_tcn_bpdu
(
Int port_no,
Tcn_bpdu * bpdu
)
{
span_send_tcn_bpdu(port_no, bpdu);
}
/*******************************************************************************
* configuration_update -
*
* INPUTS:
*
* RETURNS:
*
* ERRORS:
*
* ERRNO:
*
* NOMANUAL <this will be removed later>
*/
void configuration_update
(
void
) /* (8.6.7) */
{
root_selection(); /* (8.6.7.3.1) */
/* (8.6.8.2) */
designated_port_selection(); /* (8.6.7.3.2) */
/* (8.6.9.2) */
}
/*******************************************************************************
* root_selection -
*
* INPUTS:
*
* RETURNS:
*
* ERRORS:
*
* ERRNO:
*
* NOMANUAL <this will be removed later>
*/
void root_selection
(
void
) /* (8.6.8) */
{
Int root_port;
Int port_no;
root_port = No_port;
for (port_no = One; port_no <= No_of_ports; port_no++) /* (8.6.8.3.1) */
{
if (((!designated_port(port_no))
&&
(port_info[port_no].state != Disabled)
&&
(port_info[port_no].portLinkBlockSet != TRUE)
&&
id_lt(port_info[port_no].designated_root, bridge_info.bridge_id)
)
&&
((root_port == No_port)
||
id_lt(port_info[port_no].designated_root,
port_info[root_port].designated_root) /* (8.6.8.3.1(a)) */
||
(id_eq(port_info[port_no].designated_root,
port_info[root_port].designated_root)
&&
(((port_info[port_no].designated_cost
+ port_info[port_no].path_cost
)
<
(port_info[root_port].designated_cost
+ port_info[root_port].path_cost
) /* (8.6.8.3.1(b)) */
)
||
(((port_info[port_no].designated_cost
+ port_info[port_no].path_cost
)
==
(port_info[root_port].designated_cost
+ port_info[root_port].path_cost
)
)
&&
(id_lt(port_info[port_no].designated_bridge,
port_info[root_port].designated_bridge)
/* (8.6.8.3.1(c)) */
||
(id_eq(port_info[port_no].designated_bridge,
port_info[root_port].designated_bridge)
&&
((port_info[port_no].designated_port
< port_info[root_port].designated_port
) /* (8.6.8.3.1(d)) */
||
((port_info[port_no].designated_port
== port_info[root_port].designated_port
)
&&
(port_info[port_no].port_id
< port_info[root_port].port_id
) /* (8.6.8.3.1(e)) */
)))))))))
{
root_port = port_no;
}
}
bridge_info.root_port = root_port; /* (8.6.8.3.1) */
if (root_port == No_port) /* (8.6.8.3.2) */
{
id_equate(bridge_info.designated_root, bridge_info.bridge_id);
/* (8.6.8.3.2(a)) */
bridge_info.root_path_cost = Zero; /* (8.6.8.3.2(b)) */
}
else
/* (8.6.8.3.3) */
{
id_equate(bridge_info.designated_root,
port_info[root_port].designated_root);
/* (8.6.8.3.3(a)) */
bridge_info.root_path_cost = (port_info[root_port].designated_cost
+ port_info[root_port].path_cost
); /* (8.6.8.3.3(b)) */
}
}
/*******************************************************************************
* designated_port_selection -
*
* INPUTS:
*
* RETURNS:
*
* ERRORS:
*
* ERRNO:
*
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -