Skip to content

Commit

Permalink
stp: Add link-state checking support for stp ports.
Browse files Browse the repository at this point in the history
When bridge stp enabled, we can enable the stp ports
despite ports are down. When initializing, this patch checks
link-state of ports and enable or disable them according
to their link-state. This patch also allow user to enable
and disable a port when bridge stp is running. If a stp
port is in disable state, it can forward packets. If its
link is down and this patch sets it to disable, there is
no L2 loop.

Signed-off-by: nickcooper-zhangtonghao <[email protected]>
Signed-off-by: Ben Pfaff <[email protected]>
  • Loading branch information
xpu22 authored and blp committed May 31, 2017
1 parent 5b77696 commit 52182c5
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 2 deletions.
38 changes: 37 additions & 1 deletion ofproto/ofproto-dpif.c
Original file line number Diff line number Diff line change
Expand Up @@ -2577,6 +2577,34 @@ update_stp_port_state(struct ofport_dpif *ofport)
}
}

static void
stp_check_and_update_link_state(struct ofproto_dpif *ofproto)
{
struct ofport_dpif *ofport;

HMAP_FOR_EACH (ofport, up.hmap_node, &ofproto->up.ports) {
bool up = netdev_get_carrier(ofport->up.netdev);

if (ofport->stp_port &&
up != (stp_port_get_state(ofport->stp_port) != STP_DISABLED)) {

VLOG_DBG("bridge %s, port %s is %s, %s it.",
ofproto->up.name, netdev_get_name(ofport->up.netdev),
up ? "up" : "down",
up ? "enabling" : "disabling");

if (up) {
stp_port_enable(ofport->stp_port);
stp_port_set_aux(ofport->stp_port, ofport);
} else {
stp_port_disable(ofport->stp_port);
}

update_stp_port_state(ofport);
}
}
}

/* Configures STP on 'ofport_' using the settings defined in 's'. The
* caller is responsible for assigning STP port numbers and ensuring
* there are no duplicates. */
Expand Down Expand Up @@ -2607,7 +2635,12 @@ set_stp_port(struct ofport *ofport_,
/* Set name before enabling the port so that debugging messages can print
* the name. */
stp_port_set_name(sp, netdev_get_name(ofport->up.netdev));
stp_port_enable(sp);

if (netdev_get_carrier(ofport_->netdev)) {
stp_port_enable(sp);
} else {
stp_port_disable(sp);
}

stp_port_set_aux(sp, ofport);
stp_port_set_priority(sp, s->priority);
Expand Down Expand Up @@ -2669,6 +2702,9 @@ stp_run(struct ofproto_dpif *ofproto)
stp_tick(ofproto->stp, MIN(INT_MAX, elapsed));
ofproto->stp_last_tick = now;
}

stp_check_and_update_link_state(ofproto);

while (stp_get_changed_port(ofproto->stp, &sp)) {
struct ofport_dpif *ofport = stp_port_get_aux(sp);

Expand Down
71 changes: 70 additions & 1 deletion tests/stp.at
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,7 @@ AT_CHECK([ovs-vsctl add-port br1 p8 -- \
set port p8 other_config:stp-enable=false -- \
])

ovs-appctl netdev-dummy/set-admin-state up
ovs-appctl time/stop

AT_CHECK([ovs-ofctl add-flow br0 "in_port=7 icmp actions=1"])
Expand Down Expand Up @@ -519,7 +520,7 @@ AT_CHECK([
set interface p6 type=dummy options:pstream=punix:$OVS_RUNDIR/p6.sock ofport_request=6
], [0])


ovs-appctl netdev-dummy/set-admin-state up
ovs-appctl time/stop

# give time for STP to move initially
Expand Down Expand Up @@ -626,5 +627,73 @@ AT_CHECK([ovs-appctl mdb/show br2], [0], [dnl
port VLAN GROUP Age
])

AT_CLEANUP

AT_SETUP([STP - check link-state when stp is running])
OVS_VSWITCHD_START([])

AT_CHECK([
ovs-vsctl -- \
set port br0 other_config:stp-enable=false -- \
set bridge br0 datapath-type=dummy stp_enable=true \
other-config:hwaddr=aa:66:aa:66:00:00
], [0])

AT_CHECK([
ovs-vsctl add-port br0 p1 -- \
set interface p1 type=dummy -- \
set port p1 other_config:stp-port-num=1
ovs-vsctl add-port br0 p2 -- \
set interface p2 type=dummy -- \
set port p2 other_config:stp-port-num=2
], [0])

ovs-appctl netdev-dummy/set-admin-state up
ovs-appctl time/stop

# give time for STP to move initially
for i in $(seq 0 30); do
ovs-appctl time/warp 1000
done

AT_CHECK([ovs-appctl stp/show br0 | grep p1], [0], [dnl
p1 designated forwarding 19 128.1
])
AT_CHECK([ovs-appctl stp/show br0 | grep p2], [0], [dnl
p2 designated forwarding 19 128.2
])

# add a stp port
AT_CHECK([
ovs-vsctl add-port br0 p3 -- \
set interface p3 type=dummy -- \
set port p3 other_config:stp-port-num=3
], [0])

ovs-appctl netdev-dummy/set-admin-state p3 down

# We should not show the p3 because its link-state is down
AT_CHECK([ovs-appctl stp/show br0 | grep p1], [0], [dnl
p1 designated forwarding 19 128.1
])
AT_CHECK([ovs-appctl stp/show br0 | grep p2], [0], [dnl
p2 designated forwarding 19 128.2
])
AT_CHECK([ovs-appctl stp/show br0 | grep p3], [1], [dnl
])

ovs-appctl netdev-dummy/set-admin-state p3 up

AT_CHECK([ovs-appctl stp/show br0 | grep p1], [0], [dnl
p1 designated forwarding 19 128.1
])
AT_CHECK([ovs-appctl stp/show br0 | grep p2], [0], [dnl
p2 designated forwarding 19 128.2
])
AT_CHECK([ovs-appctl stp/show br0 | grep p3], [0], [dnl
p3 designated listening 19 128.3
])


OVS_VSWITCHD_STOP
AT_CLEANUP

0 comments on commit 52182c5

Please sign in to comment.