Skip to content

Commit 8804021

Browse files
authored
Merge pull request #2851 from anarkiwi/resetpcp
Ensure vlan_pcp is 0 when loop protection enabled.
2 parents 04a1a09 + 5690bf1 commit 8804021

File tree

4 files changed

+29
-9
lines changed

4 files changed

+29
-9
lines changed

faucet/dp.py

+13-6
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,9 @@ def _configure_tables(self):
470470
flood_table.match_types += ((faucet_pipeline.STACK_LOOP_PROTECT_FIELD, False),)
471471
vlan_table = table_configs['vlan']
472472
vlan_table.set_fields += (faucet_pipeline.STACK_LOOP_PROTECT_FIELD,)
473+
vlan_table.match_types += ((faucet_pipeline.STACK_LOOP_PROTECT_FIELD, False),)
474+
eth_dst_table = table_configs['eth_dst']
475+
eth_dst_table.set_fields = (faucet_pipeline.STACK_LOOP_PROTECT_FIELD,)
473476

474477
oxm_fields = set(valve_of.MATCH_FIELDS.keys())
475478

@@ -807,7 +810,7 @@ def is_in_path(self, src_dp, dst_dp):
807810
path = self.shortest_path(dst_dp.name, src_dp.name)
808811
return self.name in path
809812

810-
def reset_refs(self, vlans=None):
813+
def reset_refs(self, vlans=None, root_dp=None):
811814
"""Resets vlan references"""
812815
if vlans is None:
813816
vlans = self.vlans
@@ -816,6 +819,8 @@ def reset_refs(self, vlans=None):
816819
vlan.reset_ports(self.ports.values())
817820
if vlan.get_ports() or vlan.reserved_internal_vlan:
818821
self.vlans[vlan.vid] = vlan
822+
if root_dp is not None:
823+
self.stack['root_dp'] = root_dp
819824

820825
def resolve_port(self, port_name):
821826
"""Resolve a port by number or name."""
@@ -833,6 +838,7 @@ def finalize_config(self, dps):
833838

834839
dp_by_name = {}
835840
vlan_by_name = {}
841+
external_ports = False
836842

837843
def resolve_ports(port_names):
838844
"""Resolve list of ports, by port by name or number."""
@@ -858,7 +864,7 @@ def resolve_stack_dps():
858864
if self.stack_ports:
859865
if self.stack is None:
860866
self.stack = {}
861-
self.stack['externals'] = False
867+
self.stack['externals'] = external_ports
862868
port_stack_dp = {}
863869
for port in self.stack_ports:
864870
stack_dp = port.stack['dp']
@@ -871,10 +877,6 @@ def resolve_stack_dps():
871877
test_config_condition(stack_port is None, (
872878
'stack port %s not defined in DP %s' % (port.stack['port'], dp.name)))
873879
port.stack['port'] = stack_port
874-
for vlan in vlan_by_name.values():
875-
if vlan.loop_protect_external_ports():
876-
self.stack['externals'] = True
877-
break
878880

879881
def resolve_mirror_destinations():
880882
"""Resolve mirror port references and destinations."""
@@ -1075,6 +1077,11 @@ def resolve_vlan_names_in_routers():
10751077
test_config_condition(
10761078
self.global_vlan == vlan.vid, 'VLAN %u is reserved by global_vlan' % vlan.vid)
10771079

1080+
for vlan in vlan_by_name.values():
1081+
if vlan.loop_protect_external_ports():
1082+
external_ports = True
1083+
break
1084+
10781085
resolve_stack_dps()
10791086
resolve_mirror_destinations()
10801087
resolve_override_output_ports()

faucet/valve.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ def dp_init(self):
203203
self.dp.vlans, self.dp.tables['eth_src'],
204204
self.dp.tables['eth_dst'], eth_dst_hairpin_table, self.pipeline,
205205
self.dp.timeout, self.dp.learn_jitter, self.dp.learn_ban_timeout,
206-
self.dp.cache_update_guard_time, self.dp.idle_dst)
206+
self.dp.cache_update_guard_time, self.dp.idle_dst, self.dp.stack)
207207
if 'port_acl' in self.dp.tables or 'vlan_acl' in self.dp.tables or self.dp.tunnel_acls:
208208
self.acl_manager = valve_acl.ValveAclManager(
209209
self.dp.tables.get('port_acl'), self.dp.tables.get('vlan_acl'),

faucet/valve_host.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class ValveHostManager(ValveManagerBase):
2828

2929
def __init__(self, logger, ports, vlans, eth_src_table, eth_dst_table,
3030
eth_dst_hairpin_table, pipeline, learn_timeout, learn_jitter,
31-
learn_ban_timeout, cache_update_guard_time, idle_dst):
31+
learn_ban_timeout, cache_update_guard_time, idle_dst, stack):
3232
self.logger = logger
3333
self.ports = ports
3434
self.vlans = vlans
@@ -44,6 +44,7 @@ def __init__(self, logger, ports, vlans, eth_src_table, eth_dst_table,
4444
self.cache_update_guard_time = cache_update_guard_time
4545
self.output_table = self.eth_dst_table
4646
self.idle_dst = idle_dst
47+
self.stack = stack
4748
if self.eth_dst_hairpin_table:
4849
self.output_table = self.eth_dst_hairpin_table
4950

@@ -201,6 +202,11 @@ def learn_host_on_vlan_port_flows(self, port, vlan, eth_src,
201202
if port.override_output_port:
202203
inst = valve_of.apply_actions([
203204
valve_of.output_port(port.override_output_port.number)])
205+
206+
loop_protect_field = None
207+
if port.tagged_vlans and port.loop_protect_external and self.stack:
208+
loop_protect_field = 0
209+
204210
ofmsgs.append(self.eth_src_table.flowmod(
205211
match=src_match,
206212
priority=src_priority,
@@ -218,7 +224,7 @@ def learn_host_on_vlan_port_flows(self, port, vlan, eth_src,
218224
ofmsgs.append(self.eth_dst_table.flowmod(
219225
self.eth_dst_table.match(vlan=vlan, eth_dst=eth_src),
220226
priority=self.host_priority,
221-
inst=self.pipeline.output(port, vlan),
227+
inst=self.pipeline.output(port, vlan, loop_protect_field=loop_protect_field),
222228
idle_timeout=dst_rule_idle_timeout))
223229

224230
# If port is in hairpin mode, install a special rule

tests/integration/mininet_tests.py

+7
Original file line numberDiff line numberDiff line change
@@ -4493,6 +4493,13 @@ def test_tagged(self):
44934493
self.verify_broadcast(hosts=(ext_port1, ext_port2), broadcast_expected=False)
44944494
self.verify_broadcast(hosts=(ext_port1, int_port1), broadcast_expected=True)
44954495
self.verify_broadcast(hosts=(int_port1, int_port2), broadcast_expected=True)
4496+
self.one_ipv4_ping(ext_port1, int_port2.IP())
4497+
tcpdump_filter = 'ether dst %s' % int_port2.MAC()
4498+
tcpdump_txt = self.tcpdump_helper(
4499+
ext_port1, tcpdump_filter, [
4500+
lambda: ext_port1.cmd(
4501+
'ping -c3 %s' % int_port2.IP())], root_intf=True, packets=1)
4502+
self.assertTrue(re.search('vlan 100, p 0,', tcpdump_txt))
44964503

44974504

44984505
class FaucetTaggedWithUntaggedTest(FaucetTaggedTest):

0 commit comments

Comments
 (0)