Committed by
Gerrit Code Review
CORD-48 Added to support for OFDPA emulation with CPQD switch, via more table-miss-entries.
Fixed a race condition where device processing starts before config has fully loaded. GroupHandler in SR app is now created only once, not every time a Device update happens. Change-Id: I945c47ee9caa2f5740296f49d5d223783271bba4
Showing
3 changed files
with
113 additions
and
10 deletions
... | @@ -596,12 +596,18 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -596,12 +596,18 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
596 | 596 | ||
597 | private void processDeviceAdded(Device device) { | 597 | private void processDeviceAdded(Device device) { |
598 | log.debug("A new device with ID {} was added", device.id()); | 598 | log.debug("A new device with ID {} was added", device.id()); |
599 | + if (deviceConfiguration == null) { | ||
600 | + log.warn("Device configuration uploading. Device {} will be " | ||
601 | + + "processed after config completes.", device.id()); | ||
602 | + return; | ||
603 | + } | ||
599 | // Irrespective of whether the local is a MASTER or not for this device, | 604 | // Irrespective of whether the local is a MASTER or not for this device, |
600 | // we need to create a SR-group-handler instance. This is because in a | 605 | // we need to create a SR-group-handler instance. This is because in a |
601 | // multi-instance setup, any instance can initiate forwarding/next-objectives | 606 | // multi-instance setup, any instance can initiate forwarding/next-objectives |
602 | // for any switch (even if this instance is a SLAVE or not even connected | 607 | // for any switch (even if this instance is a SLAVE or not even connected |
603 | // to the switch). To handle this, a default-group-handler instance is necessary | 608 | // to the switch). To handle this, a default-group-handler instance is necessary |
604 | // per switch. | 609 | // per switch. |
610 | + if (groupHandlerMap.get(device.id()) == null) { | ||
605 | DefaultGroupHandler groupHandler = DefaultGroupHandler. | 611 | DefaultGroupHandler groupHandler = DefaultGroupHandler. |
606 | createGroupHandler(device.id(), | 612 | createGroupHandler(device.id(), |
607 | appId, | 613 | appId, |
... | @@ -611,14 +617,14 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -611,14 +617,14 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
611 | nsNextObjStore, | 617 | nsNextObjStore, |
612 | subnetNextObjStore); | 618 | subnetNextObjStore); |
613 | groupHandlerMap.put(device.id(), groupHandler); | 619 | groupHandlerMap.put(device.id(), groupHandler); |
614 | - | ||
615 | // Also, in some cases, drivers may need extra | 620 | // Also, in some cases, drivers may need extra |
616 | // information to process rules (eg. Router IP/MAC); and so, we send | 621 | // information to process rules (eg. Router IP/MAC); and so, we send |
617 | // port addressing rules to the driver as well irrespective of whether | 622 | // port addressing rules to the driver as well irrespective of whether |
618 | // this instance is the master or not. | 623 | // this instance is the master or not. |
619 | defaultRoutingHandler.populatePortAddressingRules(device.id()); | 624 | defaultRoutingHandler.populatePortAddressingRules(device.id()); |
620 | - | 625 | + } |
621 | if (mastershipService.isLocalMaster(device.id())) { | 626 | if (mastershipService.isLocalMaster(device.id())) { |
627 | + DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id()); | ||
622 | groupHandler.createGroupsFromSubnetConfig(); | 628 | groupHandler.createGroupsFromSubnetConfig(); |
623 | } | 629 | } |
624 | } | 630 | } |
... | @@ -660,6 +666,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -660,6 +666,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
660 | // for any switch (even if this instance is a SLAVE or not even connected | 666 | // for any switch (even if this instance is a SLAVE or not even connected |
661 | // to the switch). To handle this, a default-group-handler instance is necessary | 667 | // to the switch). To handle this, a default-group-handler instance is necessary |
662 | // per switch. | 668 | // per switch. |
669 | + if (groupHandlerMap.get(device.id()) == null) { | ||
663 | DefaultGroupHandler groupHandler = DefaultGroupHandler | 670 | DefaultGroupHandler groupHandler = DefaultGroupHandler |
664 | .createGroupHandler(device.id(), appId, | 671 | .createGroupHandler(device.id(), appId, |
665 | deviceConfiguration, linkService, | 672 | deviceConfiguration, linkService, |
... | @@ -673,8 +680,9 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -673,8 +680,9 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
673 | // port addressing rules to the driver as well, irrespective of whether | 680 | // port addressing rules to the driver as well, irrespective of whether |
674 | // this instance is the master or not. | 681 | // this instance is the master or not. |
675 | defaultRoutingHandler.populatePortAddressingRules(device.id()); | 682 | defaultRoutingHandler.populatePortAddressingRules(device.id()); |
676 | - | 683 | + } |
677 | if (mastershipService.isLocalMaster(device.id())) { | 684 | if (mastershipService.isLocalMaster(device.id())) { |
685 | + DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id()); | ||
678 | groupHandler.createGroupsFromSubnetConfig(); | 686 | groupHandler.createGroupsFromSubnetConfig(); |
679 | } | 687 | } |
680 | } | 688 | } | ... | ... |
... | @@ -17,6 +17,13 @@ package org.onosproject.driver.pipeline; | ... | @@ -17,6 +17,13 @@ package org.onosproject.driver.pipeline; |
17 | 17 | ||
18 | import static org.slf4j.LoggerFactory.getLogger; | 18 | import static org.slf4j.LoggerFactory.getLogger; |
19 | 19 | ||
20 | +import java.util.ArrayList; | ||
21 | +import java.util.List; | ||
22 | + | ||
23 | +import org.onlab.packet.VlanId; | ||
24 | +import org.onosproject.core.ApplicationId; | ||
25 | +import org.onosproject.net.Port; | ||
26 | +import org.onosproject.net.PortNumber; | ||
20 | import org.onosproject.net.flow.DefaultFlowRule; | 27 | import org.onosproject.net.flow.DefaultFlowRule; |
21 | import org.onosproject.net.flow.DefaultTrafficSelector; | 28 | import org.onosproject.net.flow.DefaultTrafficSelector; |
22 | import org.onosproject.net.flow.DefaultTrafficTreatment; | 29 | import org.onosproject.net.flow.DefaultTrafficTreatment; |
... | @@ -25,6 +32,8 @@ import org.onosproject.net.flow.FlowRuleOperations; | ... | @@ -25,6 +32,8 @@ import org.onosproject.net.flow.FlowRuleOperations; |
25 | import org.onosproject.net.flow.FlowRuleOperationsContext; | 32 | import org.onosproject.net.flow.FlowRuleOperationsContext; |
26 | import org.onosproject.net.flow.TrafficSelector; | 33 | import org.onosproject.net.flow.TrafficSelector; |
27 | import org.onosproject.net.flow.TrafficTreatment; | 34 | import org.onosproject.net.flow.TrafficTreatment; |
35 | +import org.onosproject.net.flow.criteria.PortCriterion; | ||
36 | +import org.onosproject.net.flow.criteria.VlanIdCriterion; | ||
28 | import org.slf4j.Logger; | 37 | import org.slf4j.Logger; |
29 | 38 | ||
30 | 39 | ||
... | @@ -37,16 +46,58 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { | ... | @@ -37,16 +46,58 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { |
37 | private final Logger log = getLogger(getClass()); | 46 | private final Logger log = getLogger(getClass()); |
38 | 47 | ||
39 | @Override | 48 | @Override |
49 | + protected List<FlowRule> processVlanIdFilter(PortCriterion portCriterion, | ||
50 | + VlanIdCriterion vidCriterion, | ||
51 | + VlanId assignedVlan, | ||
52 | + ApplicationId applicationId) { | ||
53 | + List<FlowRule> rules = new ArrayList<FlowRule>(); | ||
54 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
55 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
56 | + selector.matchVlanId(vidCriterion.vlanId()); | ||
57 | + if (vidCriterion.vlanId() == VlanId.NONE) { | ||
58 | + // untagged packets are assigned vlans | ||
59 | + treatment.pushVlan().setVlanId(assignedVlan); | ||
60 | + } | ||
61 | + treatment.transition(TMAC_TABLE); | ||
62 | + | ||
63 | + // ofdpa cannot match on ALL portnumber, so we need to use separate | ||
64 | + // rules for each port. | ||
65 | + List<PortNumber> portnums = new ArrayList<PortNumber>(); | ||
66 | + if (portCriterion.port() == PortNumber.ALL) { | ||
67 | + for (Port port : deviceService.getPorts(deviceId)) { | ||
68 | + if (port.number().toLong() > 0 && port.number().toLong() < OFPP_MAX) { | ||
69 | + portnums.add(port.number()); | ||
70 | + } | ||
71 | + } | ||
72 | + } else { | ||
73 | + portnums.add(portCriterion.port()); | ||
74 | + } | ||
75 | + for (PortNumber pnum : portnums) { | ||
76 | + selector.matchInPort(pnum); | ||
77 | + FlowRule rule = DefaultFlowRule.builder() | ||
78 | + .forDevice(deviceId) | ||
79 | + .withSelector(selector.build()) | ||
80 | + .withTreatment(treatment.build()) | ||
81 | + .withPriority(DEFAULT_PRIORITY) | ||
82 | + .fromApp(applicationId) | ||
83 | + .makePermanent() | ||
84 | + .forTable(VLAN_TABLE).build(); | ||
85 | + rules.add(rule); | ||
86 | + } | ||
87 | + return rules; | ||
88 | + } | ||
89 | + | ||
90 | + | ||
91 | + @Override | ||
40 | protected void initializePipeline() { | 92 | protected void initializePipeline() { |
41 | processPortTable(); | 93 | processPortTable(); |
94 | + // vlan table processing not required, as default is to drop packets | ||
95 | + // which can be accomplished without a table-miss-entry. | ||
42 | processTmacTable(); | 96 | processTmacTable(); |
43 | processIpTable(); | 97 | processIpTable(); |
98 | + processMplsTable(); | ||
44 | processBridgingTable(); | 99 | processBridgingTable(); |
45 | processAclTable(); | 100 | processAclTable(); |
46 | - // XXX implement table miss entries and default groups | ||
47 | - //processVlanTable(); | ||
48 | - //processMPLSTable(); | ||
49 | - //processGroupTable(); | ||
50 | } | 101 | } |
51 | 102 | ||
52 | @Override | 103 | @Override |
... | @@ -140,6 +191,49 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { | ... | @@ -140,6 +191,49 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { |
140 | })); | 191 | })); |
141 | } | 192 | } |
142 | 193 | ||
194 | + @Override | ||
195 | + protected void processMplsTable() { | ||
196 | + //table miss entry | ||
197 | + FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | ||
198 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
199 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
200 | + selector = DefaultTrafficSelector.builder(); | ||
201 | + treatment = DefaultTrafficTreatment.builder(); | ||
202 | + treatment.transition(MPLS_TABLE_1); | ||
203 | + FlowRule rule = DefaultFlowRule.builder() | ||
204 | + .forDevice(deviceId) | ||
205 | + .withSelector(selector.build()) | ||
206 | + .withTreatment(treatment.build()) | ||
207 | + .withPriority(LOWEST_PRIORITY) | ||
208 | + .fromApp(driverId) | ||
209 | + .makePermanent() | ||
210 | + .forTable(MPLS_TABLE_0).build(); | ||
211 | + ops = ops.add(rule); | ||
212 | + | ||
213 | + treatment.transition(ACL_TABLE); | ||
214 | + rule = DefaultFlowRule.builder() | ||
215 | + .forDevice(deviceId) | ||
216 | + .withSelector(selector.build()) | ||
217 | + .withTreatment(treatment.build()) | ||
218 | + .withPriority(LOWEST_PRIORITY) | ||
219 | + .fromApp(driverId) | ||
220 | + .makePermanent() | ||
221 | + .forTable(MPLS_TABLE_1).build(); | ||
222 | + ops = ops.add(rule); | ||
223 | + | ||
224 | + flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { | ||
225 | + @Override | ||
226 | + public void onSuccess(FlowRuleOperations ops) { | ||
227 | + log.info("Initialized MPLS tables"); | ||
228 | + } | ||
229 | + | ||
230 | + @Override | ||
231 | + public void onError(FlowRuleOperations ops) { | ||
232 | + log.info("Failed to initialize MPLS tables"); | ||
233 | + } | ||
234 | + })); | ||
235 | + } | ||
236 | + | ||
143 | private void processBridgingTable() { | 237 | private void processBridgingTable() { |
144 | //table miss entry | 238 | //table miss entry |
145 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | 239 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | ... | ... |
... | @@ -122,7 +122,7 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -122,7 +122,7 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline |
122 | protected static final long OFPP_MAX = 0xffffff00L; | 122 | protected static final long OFPP_MAX = 0xffffff00L; |
123 | 123 | ||
124 | private static final int HIGHEST_PRIORITY = 0xffff; | 124 | private static final int HIGHEST_PRIORITY = 0xffff; |
125 | - private static final int DEFAULT_PRIORITY = 0x8000; | 125 | + protected static final int DEFAULT_PRIORITY = 0x8000; |
126 | protected static final int LOWEST_PRIORITY = 0x0; | 126 | protected static final int LOWEST_PRIORITY = 0x0; |
127 | 127 | ||
128 | /* | 128 | /* |
... | @@ -458,8 +458,9 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -458,8 +458,9 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline |
458 | if (vidCriterion.vlanId() == VlanId.NONE) { | 458 | if (vidCriterion.vlanId() == VlanId.NONE) { |
459 | // untagged packets are assigned vlans | 459 | // untagged packets are assigned vlans |
460 | treatment.pushVlan().setVlanId(assignedVlan); | 460 | treatment.pushVlan().setVlanId(assignedVlan); |
461 | - // XXX ofdpa may require an additional vlan match on the assigned vlan | 461 | + // XXX ofdpa will require an additional vlan match on the assigned vlan |
462 | - // and it may not require the push. | 462 | + // and it may not require the push. This is not in compliance with OF |
463 | + // standard. Waiting on what the exact flows are going to look like. | ||
463 | } | 464 | } |
464 | treatment.transition(TMAC_TABLE); | 465 | treatment.transition(TMAC_TABLE); |
465 | 466 | ... | ... |
-
Please register or login to post a comment