Committed by
Gerrit Code Review
Reactive forwarding apps should explicitly ask for packets they want to receive.
Previously we relied on the table-miss entry set up for OVS switches, but this doesn't work for non-OVS switches 1.3 switches. Fixes ONOS-661. Change-Id: Ibc0aee09f304eaf240691a4d5d2f8765a5f8cdd5
Showing
2 changed files
with
131 additions
and
0 deletions
... | @@ -30,10 +30,14 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; | ... | @@ -30,10 +30,14 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; |
30 | import org.onlab.packet.Ethernet; | 30 | import org.onlab.packet.Ethernet; |
31 | import org.onosproject.core.ApplicationId; | 31 | import org.onosproject.core.ApplicationId; |
32 | import org.onosproject.core.CoreService; | 32 | import org.onosproject.core.CoreService; |
33 | +import org.onosproject.net.Device; | ||
33 | import org.onosproject.net.Host; | 34 | import org.onosproject.net.Host; |
34 | import org.onosproject.net.HostId; | 35 | import org.onosproject.net.HostId; |
35 | import org.onosproject.net.Path; | 36 | import org.onosproject.net.Path; |
36 | import org.onosproject.net.PortNumber; | 37 | import org.onosproject.net.PortNumber; |
38 | +import org.onosproject.net.device.DeviceEvent; | ||
39 | +import org.onosproject.net.device.DeviceListener; | ||
40 | +import org.onosproject.net.device.DeviceService; | ||
37 | import org.onosproject.net.flow.DefaultFlowRule; | 41 | import org.onosproject.net.flow.DefaultFlowRule; |
38 | import org.onosproject.net.flow.DefaultTrafficSelector; | 42 | import org.onosproject.net.flow.DefaultTrafficSelector; |
39 | import org.onosproject.net.flow.DefaultTrafficTreatment; | 43 | import org.onosproject.net.flow.DefaultTrafficTreatment; |
... | @@ -58,6 +62,7 @@ public class ReactiveForwarding { | ... | @@ -58,6 +62,7 @@ public class ReactiveForwarding { |
58 | 62 | ||
59 | private static final int TIMEOUT = 10; | 63 | private static final int TIMEOUT = 10; |
60 | private static final int PRIORITY = 10; | 64 | private static final int PRIORITY = 10; |
65 | + private static final int PUNT_RULE_PRIORITY = 5; | ||
61 | 66 | ||
62 | private final Logger log = getLogger(getClass()); | 67 | private final Logger log = getLogger(getClass()); |
63 | 68 | ||
... | @@ -74,6 +79,9 @@ public class ReactiveForwarding { | ... | @@ -74,6 +79,9 @@ public class ReactiveForwarding { |
74 | protected FlowRuleService flowRuleService; | 79 | protected FlowRuleService flowRuleService; |
75 | 80 | ||
76 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 81 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
82 | + protected DeviceService deviceService; | ||
83 | + | ||
84 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
77 | protected CoreService coreService; | 85 | protected CoreService coreService; |
78 | 86 | ||
79 | private ReactivePacketProcessor processor = new ReactivePacketProcessor(); | 87 | private ReactivePacketProcessor processor = new ReactivePacketProcessor(); |
... | @@ -91,6 +99,8 @@ public class ReactiveForwarding { | ... | @@ -91,6 +99,8 @@ public class ReactiveForwarding { |
91 | @Activate | 99 | @Activate |
92 | public void activate(ComponentContext context) { | 100 | public void activate(ComponentContext context) { |
93 | appId = coreService.registerApplication("org.onosproject.fwd"); | 101 | appId = coreService.registerApplication("org.onosproject.fwd"); |
102 | + deviceService.addListener(new InternalDeviceListener()); | ||
103 | + pushRules(); | ||
94 | packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2); | 104 | packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2); |
95 | readComponentConfiguration(context); | 105 | readComponentConfiguration(context); |
96 | log.info("Started with Application ID {}", appId.id()); | 106 | log.info("Started with Application ID {}", appId.id()); |
... | @@ -293,6 +303,58 @@ public class ReactiveForwarding { | ... | @@ -293,6 +303,58 @@ public class ReactiveForwarding { |
293 | } | 303 | } |
294 | } | 304 | } |
295 | 305 | ||
306 | + /** | ||
307 | + * Pushes flow rules to all devices. | ||
308 | + */ | ||
309 | + private void pushRules() { | ||
310 | + for (Device device : deviceService.getDevices()) { | ||
311 | + pushRules(device); | ||
312 | + } | ||
313 | + } | ||
314 | + | ||
315 | + /** | ||
316 | + * Pushes flow rules to the device to receive packets that need | ||
317 | + * to be processed. | ||
318 | + * | ||
319 | + * @param device the device to push the rules to | ||
320 | + */ | ||
321 | + private synchronized void pushRules(Device device) { | ||
322 | + TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); | ||
323 | + TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); | ||
324 | + | ||
325 | + // Get all IPv4 packets | ||
326 | + sbuilder.matchEthType(Ethernet.TYPE_IPV4); | ||
327 | + tbuilder.punt(); | ||
328 | + FlowRule flowArp = | ||
329 | + new DefaultFlowRule(device.id(), | ||
330 | + sbuilder.build(), tbuilder.build(), | ||
331 | + PUNT_RULE_PRIORITY, appId, 0, true); | ||
332 | + | ||
333 | + flowRuleService.applyFlowRules(flowArp); | ||
334 | + } | ||
335 | + | ||
336 | + public class InternalDeviceListener implements DeviceListener { | ||
337 | + | ||
338 | + @Override | ||
339 | + public void event(DeviceEvent event) { | ||
340 | + Device device = event.subject(); | ||
341 | + switch (event.type()) { | ||
342 | + case DEVICE_ADDED: | ||
343 | + pushRules(device); | ||
344 | + break; | ||
345 | + case DEVICE_AVAILABILITY_CHANGED: | ||
346 | + case DEVICE_SUSPENDED: | ||
347 | + case DEVICE_UPDATED: | ||
348 | + case DEVICE_REMOVED: | ||
349 | + case PORT_ADDED: | ||
350 | + case PORT_UPDATED: | ||
351 | + case PORT_REMOVED: | ||
352 | + default: | ||
353 | + break; | ||
354 | + } | ||
355 | + } | ||
356 | + } | ||
357 | + | ||
296 | } | 358 | } |
297 | 359 | ||
298 | 360 | ... | ... |
... | @@ -25,11 +25,18 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; | ... | @@ -25,11 +25,18 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; |
25 | import org.onlab.packet.Ethernet; | 25 | import org.onlab.packet.Ethernet; |
26 | import org.onosproject.core.ApplicationId; | 26 | import org.onosproject.core.ApplicationId; |
27 | import org.onosproject.core.CoreService; | 27 | import org.onosproject.core.CoreService; |
28 | +import org.onosproject.net.Device; | ||
28 | import org.onosproject.net.Host; | 29 | import org.onosproject.net.Host; |
29 | import org.onosproject.net.HostId; | 30 | import org.onosproject.net.HostId; |
30 | import org.onosproject.net.PortNumber; | 31 | import org.onosproject.net.PortNumber; |
32 | +import org.onosproject.net.device.DeviceEvent; | ||
33 | +import org.onosproject.net.device.DeviceListener; | ||
34 | +import org.onosproject.net.device.DeviceService; | ||
35 | +import org.onosproject.net.flow.DefaultFlowRule; | ||
31 | import org.onosproject.net.flow.DefaultTrafficSelector; | 36 | import org.onosproject.net.flow.DefaultTrafficSelector; |
32 | import org.onosproject.net.flow.DefaultTrafficTreatment; | 37 | import org.onosproject.net.flow.DefaultTrafficTreatment; |
38 | +import org.onosproject.net.flow.FlowRule; | ||
39 | +import org.onosproject.net.flow.FlowRuleService; | ||
33 | import org.onosproject.net.flow.TrafficSelector; | 40 | import org.onosproject.net.flow.TrafficSelector; |
34 | import org.onosproject.net.flow.TrafficTreatment; | 41 | import org.onosproject.net.flow.TrafficTreatment; |
35 | import org.onosproject.net.host.HostService; | 42 | import org.onosproject.net.host.HostService; |
... | @@ -52,6 +59,8 @@ public class IntentReactiveForwarding { | ... | @@ -52,6 +59,8 @@ public class IntentReactiveForwarding { |
52 | 59 | ||
53 | private final Logger log = getLogger(getClass()); | 60 | private final Logger log = getLogger(getClass()); |
54 | 61 | ||
62 | + private static final int PUNT_RULE_PRIORITY = 5; | ||
63 | + | ||
55 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 64 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
56 | protected CoreService coreService; | 65 | protected CoreService coreService; |
57 | 66 | ||
... | @@ -67,12 +76,20 @@ public class IntentReactiveForwarding { | ... | @@ -67,12 +76,20 @@ public class IntentReactiveForwarding { |
67 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 76 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
68 | protected HostService hostService; | 77 | protected HostService hostService; |
69 | 78 | ||
79 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
80 | + protected FlowRuleService flowRuleService; | ||
81 | + | ||
82 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
83 | + protected DeviceService deviceService; | ||
84 | + | ||
70 | private ReactivePacketProcessor processor = new ReactivePacketProcessor(); | 85 | private ReactivePacketProcessor processor = new ReactivePacketProcessor(); |
71 | private ApplicationId appId; | 86 | private ApplicationId appId; |
72 | 87 | ||
73 | @Activate | 88 | @Activate |
74 | public void activate() { | 89 | public void activate() { |
75 | appId = coreService.registerApplication("org.onosproject.ifwd"); | 90 | appId = coreService.registerApplication("org.onosproject.ifwd"); |
91 | + deviceService.addListener(new InternalDeviceListener()); | ||
92 | + pushRules(); | ||
76 | packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2); | 93 | packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2); |
77 | log.info("Started"); | 94 | log.info("Started"); |
78 | } | 95 | } |
... | @@ -155,4 +172,56 @@ public class IntentReactiveForwarding { | ... | @@ -155,4 +172,56 @@ public class IntentReactiveForwarding { |
155 | intentService.submit(intent); | 172 | intentService.submit(intent); |
156 | } | 173 | } |
157 | 174 | ||
175 | + /** | ||
176 | + * Pushes flow rules to all devices. | ||
177 | + */ | ||
178 | + private void pushRules() { | ||
179 | + for (Device device : deviceService.getDevices()) { | ||
180 | + pushRules(device); | ||
181 | + } | ||
182 | + } | ||
183 | + | ||
184 | + /** | ||
185 | + * Pushes flow rules to the device to receive packets that need | ||
186 | + * to be processed. | ||
187 | + * | ||
188 | + * @param device the device to push the rules to | ||
189 | + */ | ||
190 | + private synchronized void pushRules(Device device) { | ||
191 | + TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); | ||
192 | + TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); | ||
193 | + | ||
194 | + // Get all IPv4 packets | ||
195 | + sbuilder.matchEthType(Ethernet.TYPE_IPV4); | ||
196 | + tbuilder.punt(); | ||
197 | + FlowRule flowArp = | ||
198 | + new DefaultFlowRule(device.id(), | ||
199 | + sbuilder.build(), tbuilder.build(), | ||
200 | + PUNT_RULE_PRIORITY, appId, 0, true); | ||
201 | + | ||
202 | + flowRuleService.applyFlowRules(flowArp); | ||
203 | + } | ||
204 | + | ||
205 | + public class InternalDeviceListener implements DeviceListener { | ||
206 | + | ||
207 | + @Override | ||
208 | + public void event(DeviceEvent event) { | ||
209 | + Device device = event.subject(); | ||
210 | + switch (event.type()) { | ||
211 | + case DEVICE_ADDED: | ||
212 | + pushRules(device); | ||
213 | + break; | ||
214 | + case DEVICE_AVAILABILITY_CHANGED: | ||
215 | + case DEVICE_SUSPENDED: | ||
216 | + case DEVICE_UPDATED: | ||
217 | + case DEVICE_REMOVED: | ||
218 | + case PORT_ADDED: | ||
219 | + case PORT_UPDATED: | ||
220 | + case PORT_REMOVED: | ||
221 | + default: | ||
222 | + break; | ||
223 | + } | ||
224 | + } | ||
225 | + } | ||
226 | + | ||
158 | } | 227 | } | ... | ... |
-
Please register or login to post a comment