Commit febcee8a authored by Miguel  Baizan's avatar Miguel Baizan

userspace/wrsw_rstpd: data structures holding port flags and BPDUs simplified

parent 110823ce
......@@ -124,15 +124,12 @@ int init_data(void)
((bridge.ports[i].mng.PortPriority << 8) |
(bridge.ports[i].port_number));
/* Set some flags */
bridge.ports[i].rstp_flags = 0x0;
bridge.ports[i].operPointToPointMAC = FALSE;
/* 17.19.18 */
if (bridge.ports[i].link_status &&
bridge.ports[i].mng.AdminPortEnabled) {
set_port_flag(bridge.ports[i].rstp_flags, portEnabled);
bridge.ports[i].portEnabled = TRUE;
} else { /* Link status down or administrative port state disabled */
remove_port_flag(bridge.ports[i].rstp_flags, portEnabled);
bridge.ports[i].portEnabled = FALSE;
}
/* Set priority vectors */
......@@ -182,9 +179,8 @@ void recompute_stmchs(void)
/* Update the tick flag */
int i;
for (i = 0; i < MAX_NUM_PORTS ; i++) {
set_port_flag(bridge.ports[i].rstp_flags, tick);
}
for (i = 0; i < MAX_NUM_PORTS ; i++)
bridge.ports[i].tick = TRUE;
stmch_compute_transitions(&bridge);
}
......
......@@ -124,41 +124,6 @@
#define DEFAULT_PORT_PATH_COST_10_TBPS 0x0000002 /* 2 */
#define MAX_PORT_PATH_COST 0xBEBC200 /* 200000000 */
/* RSTP port flags (rstp_flags). See 802.1D-2004, clause 17.19 */
enum port_flag {
agree = 0, /* 17.19.2 */
agreed, /* 17.19.3 */
disputed, /* 17.19.6 */
fdbFlush, /* 17.19.7 */
forward, /* 17.19.8 */
forwarding, /* 17.19.9 */
learn, /* 17.19.11 */
learning, /* 17.19.12 */
mcheck, /* 17.19.13 */
newInfo, /* 17.19.16 */
operEdge, /* 17.19.17 */
portEnabled, /* 17.19.18 */
proposed, /* 17.19.23 */
proposing, /* 17.19.24 */
rcvdBPDU, /* 17.19.25 */
rcvdMsg, /* 17.19.27 */
rcvdRSTP, /* 17.19.28 */
rcvdSTP, /* 17.19.29 */
rcvdTc, /* 17.19.30 */
rcvdTcAck, /* 17.19.31 */
rcvdTcn, /* 17.19.32 */
reRoot, /* 17.19.33 */
reselect, /* 17.19.34 */
selected, /* 17.19.36 */
sendRSTP, /* 17.19.38 */
_sync, /* 17.19.39 */ /* renamed because of a previous declaration
in unistd.h */
synced, /* 17.19.40 */
tcAck, /* 17.19.41 */
tcProp, /* 17.19.42 */
tick, /* 17.19.43 */
updtInfo /* 17.19.45 */
};
/* Indicate the origin/state of the Port's ST information. See 802.1D,
clause 17.19.10 */
......@@ -222,15 +187,12 @@ struct rstp_times {
uint16_t forward_delay;
};
/* Configuration BPDU. See 802.1D, clause 9.3.1. Note that the Port
ID is 2 octets long. See 802.1D-2004, clause 9.2.7, for encoding
(the less significant 12 bits are used to encode the Port Number, while
the 4 more significant bits are used to encode the Port Priority) */
struct cfg_bpdu {
/* This structure can act as a Configuration BPDU (9.3.1), a Topology
Change Notification BPDU (9.3.2) or a Rapid Spanning Tree BPDU (9.3.3). */
struct generic_bpdu {
uint16_t protocol_identifier;
uint8_t protocol_version_identifier;
uint8_t bpdu_type;
uint8_t type;
uint8_t flags;
struct bridge_id root_identifier;
......@@ -239,24 +201,10 @@ struct cfg_bpdu {
uint16_t port_identifier;
struct rstp_times times;
}; /* TODO: should we use: __attribute__((packed))?. Decide when BPDUs
processing functions be written */;
/* Topology Change Notification BPDU. See 802.1D, clause 9.3.2 */
struct tcn_bpdu {
uint16_t protocol_identifier;
uint8_t protocol_version_identifier;
uint8_t bpdu_type;
};
/* Rapid Spanning Tree BPDU. See 802.1D, clause 9.3.3. This BPDU can act as
a Configuration BPDU, as a TCN BPDU or as a RSTP BPDU */
struct rstp_bpdu {
struct cfg_bpdu configuration_bpdu;
uint8_t version1_length;
uint8_t version1_length; /* Only for RSTP BPDUs */
};
/* Spanning Tree priority vector. See 802.1D, clause 17.5 */
struct st_priority_vector {
struct bridge_id RootBridgeId;
......@@ -305,7 +253,7 @@ struct port_data {
struct state_machine stmch[NUM_STMCH_PER_PORT];
struct rstp_port_mng_data mng;
struct rstp_bpdu bpdu; /* This is to store the information of the
struct generic_bpdu bpdu; /* This is to store the information of the
last BPDU received in this port */
/* RSTP data.
......@@ -330,15 +278,44 @@ struct port_data {
enum port_role role; /* 17.19.35 */
enum port_role selectedRole; /* 17.19.37 */
uint16_t portId; /* 17.19.19 */
uint16_t portId; /* 17.19.19, 9.2.7 */
uint8_t txCount; /* 17.19.44 */
uint8_t operPointToPointMAC; /* 6.4.3 and 17.12 */
int operPointToPointMAC; /* 6.4.3 and 17.12 */
/* RSTP port flags. TODO: Consider using bitfields instead of int */
int agree; /* 17.19.2 */
int agreed; /* 17.19.3 */
int disputed; /* 17.19.6 */
int fdbFlush; /* 17.19.7 */
int forward; /* 17.19.8 */
int forwarding; /* 17.19.9 */
int learn; /* 17.19.11 */
int learning; /* 17.19.12 */
int mcheck; /* 17.19.13 */
int newInfo; /* 17.19.16 */
int operEdge; /* 17.19.17 */
int portEnabled; /* 17.19.18 */
int proposed; /* 17.19.23 */
int proposing; /* 17.19.24 */
int rcvdBPDU; /* 17.19.25 */
int rcvdMsg; /* 17.19.27 */
int rcvdRSTP; /* 17.19.28 */
int rcvdSTP; /* 17.19.29 */
int rcvdTc; /* 17.19.30 */
int rcvdTcAck; /* 17.19.31 */
int rcvdTcn; /* 17.19.32 */
int reRoot; /* 17.19.33 */
int reselect; /* 17.19.34 */
int selected; /* 17.19.36 */
int sendRSTP; /* 17.19.38 */
int sync; /* 17.19.39 */
int synced; /* 17.19.40 */
int tcAck; /* 17.19.41 */
int tcProp; /* 17.19.42 */
int tick; /* 17.19.43 */
int updtInfo; /* 17.19.45 */
/* RSTP port flags */
uint32_t rstp_flags; /* Flags defined above. Use the
macros to get/set/remove
each flag */
/* Timers */
uint16_t edgeDelayWhile; /* 17.17.1 */
uint16_t fdWhile; /* 17.17.2 */
......@@ -381,25 +358,6 @@ struct bridge_data {
};
/* Operations on RSTP port flags */
/* Test whether the flag is set or not */
static inline uint32_t get_port_flag(uint32_t bitfield, enum port_flag flag)
{
return ((bitfield >> flag) & 0x01);
}
/* Sets the flag to zero */
static inline void remove_port_flag(uint32_t bitfield, enum port_flag flag)
{
(bitfield &= (~(0x01 << flag)));
}
/* Sets the flag to one */
static inline void set_port_flag(uint32_t bitfield, enum port_flag flag)
{
(bitfield |= (0x01 << flag));
}
/* Rounds the timer to the nearest whole second */
static inline void round_timer(uint16_t timer)
{
......
......@@ -123,7 +123,8 @@ static void frame_recv(uint32_t events, struct epoll_event_handler *h)
sl.sll_addr[3], sl.sll_addr[4], sl.sll_addr[5]);
dump_frame(buf, octets);
/* TODO Parse and process the received frame */
/* TODO Parse the received frame. Fill in port->bpdu with data. Then
recompute state machines */
//bpdu_rcv(sl.sll_ifindex, buf, octets);
}
......
......@@ -53,9 +53,9 @@ static void clearReselectTree(struct bridge_data *br)
int i;
for (i = 0; i < MAX_NUM_PORTS ; i++)
remove_port_flag(br->ports[i].rstp_flags, reselect);
br->ports[i].reselect = FALSE;
TRACEV(TRACE_INFO, "PRS: RESELECT flag set to 0 on every port");
TRACEV(TRACE_INFO, "PRS: RESELECT flag set to FALSE on every port");
}
/* 17.21.25 */
......@@ -119,7 +119,7 @@ static void updtRolesTree(struct bridge_data *br)
case Received: /* 17.21.25 i), j), k), l) */
if (root_port_num == i) {
br->ports[i].selectedRole = RootPort;
remove_port_flag(br->ports[i].rstp_flags, updtInfo);
br->ports[i].updtInfo = FALSE;
TRACEV(TRACE_INFO, "PRS: port %s is ROOT port",
br->ports[i].port_name);
break;
......@@ -140,16 +140,16 @@ static void updtRolesTree(struct bridge_data *br)
TRACEV(TRACE_INFO, "PRS: port %s is BACKUP port",
br->ports[i].port_name);
}
remove_port_flag(br->ports[i].rstp_flags, updtInfo);
br->ports[i].updtInfo = FALSE;
break;
}
br->ports[i].selectedRole = DesignatedPort;
set_port_flag(br->ports[i].rstp_flags, updtInfo);
br->ports[i].updtInfo = TRUE;
TRACEV(TRACE_INFO, "PRS: port %s is DESIGNATED port",
br->ports[i].port_name);
break;
case Aged: /* 17.21.25 g) */
set_port_flag(br->ports[i].rstp_flags, updtInfo);
br->ports[i].updtInfo = TRUE;
br->ports[i].selectedRole = DesignatedPort;
TRACEV(TRACE_INFO, "PRS: port %s is DESIGNATED port",
br->ports[i].port_name);
......@@ -158,7 +158,7 @@ static void updtRolesTree(struct bridge_data *br)
if (cmp_priority_vectors(&br->ports[i].designatedPriority,
&br->ports[i].portPriority, 1) ||
cmp_times(&br->ports[i].portTimes, &root_port->portTimes)) {
set_port_flag(br->ports[i].rstp_flags, updtInfo);
br->ports[i].updtInfo = TRUE;
}
br->ports[i].selectedRole = DesignatedPort;
TRACEV(TRACE_INFO, "PRS: port %s is DESIGNATED port",
......@@ -181,12 +181,12 @@ static void setSelectedTree(struct bridge_data *br)
int i;
for (i = 0; i < MAX_NUM_PORTS ; i++) {
if (get_port_flag(br->ports[i].rstp_flags, reselect))
if (br->ports[i].reselect == TRUE)
return;
}
for (i = 0; i < MAX_NUM_PORTS ; i++)
set_port_flag(br->ports[i].rstp_flags, selected);
br->ports[i].selected = TRUE;
TRACEV(TRACE_INFO, "PRS: SELECTED variable set to TRUE for all Ports");
}
......@@ -231,7 +231,7 @@ static void compute_transitions(struct state_machine *stmch)
switch (stmch->state) {
case ROLE_SELECTION:
for (i = 0; i < MAX_NUM_PORTS ; i++) {
if (get_port_flag(br->ports[i].rstp_flags, reselect)) {
if (br->ports[i].reselect == TRUE) {
enter_state(stmch, ROLE_SELECTION);
break;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment