Committed by
Thomas Vachuska
[ONOS-3833] Identify the port chain for the packet
Change-Id: Id2ca1373588c8bc77c031149c7e85337c776bc4b
Showing
1 changed file
with
195 additions
and
13 deletions
... | @@ -17,6 +17,8 @@ package org.onosproject.sfc.manager.impl; | ... | @@ -17,6 +17,8 @@ package org.onosproject.sfc.manager.impl; |
17 | 17 | ||
18 | import static org.slf4j.LoggerFactory.getLogger; | 18 | import static org.slf4j.LoggerFactory.getLogger; |
19 | 19 | ||
20 | +import java.util.Collection; | ||
21 | +import java.util.Set; | ||
20 | import java.util.concurrent.ConcurrentHashMap; | 22 | import java.util.concurrent.ConcurrentHashMap; |
21 | import java.util.concurrent.ConcurrentMap; | 23 | import java.util.concurrent.ConcurrentMap; |
22 | 24 | ||
... | @@ -28,15 +30,16 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; | ... | @@ -28,15 +30,16 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; |
28 | import org.apache.felix.scr.annotations.Service; | 30 | import org.apache.felix.scr.annotations.Service; |
29 | import org.onlab.packet.Ethernet; | 31 | import org.onlab.packet.Ethernet; |
30 | import org.onlab.packet.IPv4; | 32 | import org.onlab.packet.IPv4; |
31 | -import org.onlab.packet.IPv6; | ||
32 | import org.onlab.packet.IpAddress; | 33 | import org.onlab.packet.IpAddress; |
33 | import org.onlab.packet.MacAddress; | 34 | import org.onlab.packet.MacAddress; |
34 | -import org.onlab.packet.VlanId; | 35 | +import org.onlab.packet.TCP; |
36 | +import org.onlab.packet.UDP; | ||
35 | import org.onlab.util.ItemNotFoundException; | 37 | import org.onlab.util.ItemNotFoundException; |
36 | import org.onlab.util.KryoNamespace; | 38 | import org.onlab.util.KryoNamespace; |
37 | import org.onosproject.core.ApplicationId; | 39 | import org.onosproject.core.ApplicationId; |
38 | import org.onosproject.core.CoreService; | 40 | import org.onosproject.core.CoreService; |
39 | import org.onosproject.net.NshServicePathId; | 41 | import org.onosproject.net.NshServicePathId; |
42 | +import org.onosproject.net.PortNumber; | ||
40 | import org.onosproject.net.packet.PacketContext; | 43 | import org.onosproject.net.packet.PacketContext; |
41 | import org.onosproject.net.packet.PacketProcessor; | 44 | import org.onosproject.net.packet.PacketProcessor; |
42 | import org.onosproject.net.packet.PacketService; | 45 | import org.onosproject.net.packet.PacketService; |
... | @@ -46,6 +49,9 @@ import org.onosproject.sfc.installer.FlowClassifierInstallerService; | ... | @@ -46,6 +49,9 @@ import org.onosproject.sfc.installer.FlowClassifierInstallerService; |
46 | import org.onosproject.sfc.installer.impl.FlowClassifierInstallerImpl; | 49 | import org.onosproject.sfc.installer.impl.FlowClassifierInstallerImpl; |
47 | import org.onosproject.sfc.manager.NshSpiIdGenerators; | 50 | import org.onosproject.sfc.manager.NshSpiIdGenerators; |
48 | import org.onosproject.sfc.manager.SfcService; | 51 | import org.onosproject.sfc.manager.SfcService; |
52 | +import org.onosproject.vtnrsc.DefaultFiveTuple; | ||
53 | +import org.onosproject.vtnrsc.FiveTuple; | ||
54 | +import org.onosproject.vtnrsc.FixedIp; | ||
49 | import org.onosproject.vtnrsc.FlowClassifier; | 55 | import org.onosproject.vtnrsc.FlowClassifier; |
50 | import org.onosproject.vtnrsc.FlowClassifierId; | 56 | import org.onosproject.vtnrsc.FlowClassifierId; |
51 | import org.onosproject.vtnrsc.PortChain; | 57 | import org.onosproject.vtnrsc.PortChain; |
... | @@ -55,10 +61,15 @@ import org.onosproject.vtnrsc.PortPairGroup; | ... | @@ -55,10 +61,15 @@ import org.onosproject.vtnrsc.PortPairGroup; |
55 | import org.onosproject.vtnrsc.PortPairGroupId; | 61 | import org.onosproject.vtnrsc.PortPairGroupId; |
56 | import org.onosproject.vtnrsc.PortPairId; | 62 | import org.onosproject.vtnrsc.PortPairId; |
57 | import org.onosproject.vtnrsc.TenantId; | 63 | import org.onosproject.vtnrsc.TenantId; |
64 | +import org.onosproject.vtnrsc.VirtualPort; | ||
65 | +import org.onosproject.vtnrsc.VirtualPortId; | ||
58 | import org.onosproject.vtnrsc.event.VtnRscEvent; | 66 | import org.onosproject.vtnrsc.event.VtnRscEvent; |
59 | import org.onosproject.vtnrsc.event.VtnRscEventFeedback; | 67 | import org.onosproject.vtnrsc.event.VtnRscEventFeedback; |
60 | import org.onosproject.vtnrsc.event.VtnRscListener; | 68 | import org.onosproject.vtnrsc.event.VtnRscListener; |
69 | +import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService; | ||
70 | +import org.onosproject.vtnrsc.portchain.PortChainService; | ||
61 | import org.onosproject.vtnrsc.service.VtnRscService; | 71 | import org.onosproject.vtnrsc.service.VtnRscService; |
72 | +import org.onosproject.vtnrsc.virtualport.VirtualPortService; | ||
62 | import org.slf4j.Logger; | 73 | import org.slf4j.Logger; |
63 | 74 | ||
64 | /** | 75 | /** |
... | @@ -71,6 +82,7 @@ public class SfcManager implements SfcService { | ... | @@ -71,6 +82,7 @@ public class SfcManager implements SfcService { |
71 | private final Logger log = getLogger(getClass()); | 82 | private final Logger log = getLogger(getClass()); |
72 | private static final String APP_ID = "org.onosproject.app.vtn"; | 83 | private static final String APP_ID = "org.onosproject.app.vtn"; |
73 | private static final int SFC_PRIORITY = 1000; | 84 | private static final int SFC_PRIORITY = 1000; |
85 | + private static final int NULL_PORT = 0; | ||
74 | 86 | ||
75 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 87 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
76 | protected VtnRscService vtnRscService; | 88 | protected VtnRscService vtnRscService; |
... | @@ -81,6 +93,15 @@ public class SfcManager implements SfcService { | ... | @@ -81,6 +93,15 @@ public class SfcManager implements SfcService { |
81 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 93 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
82 | protected PacketService packetService; | 94 | protected PacketService packetService; |
83 | 95 | ||
96 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
97 | + protected PortChainService portChainService; | ||
98 | + | ||
99 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
100 | + protected FlowClassifierService flowClassifierService; | ||
101 | + | ||
102 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
103 | + protected VirtualPortService virtualPortService; | ||
104 | + | ||
84 | private SfcPacketProcessor processor = new SfcPacketProcessor(); | 105 | private SfcPacketProcessor processor = new SfcPacketProcessor(); |
85 | 106 | ||
86 | protected ApplicationId appId; | 107 | protected ApplicationId appId; |
... | @@ -238,32 +259,193 @@ public class SfcManager implements SfcService { | ... | @@ -238,32 +259,193 @@ public class SfcManager implements SfcService { |
238 | 259 | ||
239 | private class SfcPacketProcessor implements PacketProcessor { | 260 | private class SfcPacketProcessor implements PacketProcessor { |
240 | 261 | ||
262 | + /** | ||
263 | + * Check for given ip match with the fixed ips for the virtual port. | ||
264 | + * | ||
265 | + * @param vPortId virtual port id | ||
266 | + * @param ip ip address to match | ||
267 | + * @return true if the ip match with the fixed ips in virtual port false otherwise | ||
268 | + */ | ||
269 | + private boolean checkIpInVirtualPort(VirtualPortId vPortId, IpAddress ip) { | ||
270 | + boolean found = false; | ||
271 | + Set<FixedIp> ips = virtualPortService.getPort(vPortId).fixedIps(); | ||
272 | + for (FixedIp fixedIp : ips) { | ||
273 | + if (fixedIp.ip().equals(ip)) { | ||
274 | + found = true; | ||
275 | + break; | ||
276 | + } | ||
277 | + } | ||
278 | + return found; | ||
279 | + } | ||
280 | + | ||
281 | + /** | ||
282 | + * Find the port chain for the received packet. | ||
283 | + * | ||
284 | + * @param fiveTuple five tuple info from the packet | ||
285 | + * @return portChainId id of port chain | ||
286 | + */ | ||
287 | + private PortChainId findPortChainFromFiveTuple(FiveTuple fiveTuple) { | ||
288 | + | ||
289 | + PortChainId portChainId = null; | ||
290 | + | ||
291 | + Iterable<PortChain> portChains = portChainService.getPortChains(); | ||
292 | + if (portChains == null) { | ||
293 | + log.error("Could not retrive port chain list"); | ||
294 | + } | ||
295 | + | ||
296 | + // Identify the port chain to which the packet belongs | ||
297 | + for (final PortChain portChain : portChains) { | ||
298 | + | ||
299 | + Iterable<FlowClassifierId> flowClassifiers = portChain.flowClassifiers(); | ||
300 | + | ||
301 | + // One port chain can have multiple flow classifiers. | ||
302 | + for (final FlowClassifierId flowClassifierId : flowClassifiers) { | ||
303 | + | ||
304 | + FlowClassifier flowClassifier = flowClassifierService.getFlowClassifier(flowClassifierId); | ||
305 | + boolean match = false; | ||
306 | + // Check whether protocol is set in flow classifier | ||
307 | + if (flowClassifier.protocol() != null) { | ||
308 | + if ((flowClassifier.protocol().equals("TCP") && fiveTuple.protocol() == IPv4.PROTOCOL_TCP) || | ||
309 | + (flowClassifier.protocol().equals("UDP") && | ||
310 | + fiveTuple.protocol() == IPv4.PROTOCOL_UDP)) { | ||
311 | + match = true; | ||
312 | + } else { | ||
313 | + continue; | ||
314 | + } | ||
315 | + } | ||
316 | + | ||
317 | + // Check whether source ip prefix is set in flow classifier | ||
318 | + if (flowClassifier.srcIpPrefix() != null) { | ||
319 | + if (flowClassifier.srcIpPrefix().contains(fiveTuple.ipSrc())) { | ||
320 | + match = true; | ||
321 | + } else { | ||
322 | + continue; | ||
323 | + } | ||
324 | + } | ||
325 | + | ||
326 | + // Check whether destination ip prefix is set in flow classifier | ||
327 | + if (flowClassifier.dstIpPrefix() != null) { | ||
328 | + if (flowClassifier.dstIpPrefix().contains(fiveTuple.ipDst())) { | ||
329 | + match = true; | ||
330 | + } else { | ||
331 | + continue; | ||
332 | + } | ||
333 | + } | ||
334 | + | ||
335 | + // Check whether source port is set in flow classifier | ||
336 | + if (fiveTuple.portSrc().toLong() >= flowClassifier.minSrcPortRange() || | ||
337 | + fiveTuple.portSrc().toLong() <= flowClassifier.maxSrcPortRange()) { | ||
338 | + match = true; | ||
339 | + } else { | ||
340 | + continue; | ||
341 | + } | ||
342 | + | ||
343 | + // Check whether destination port is set in flow classifier | ||
344 | + if (fiveTuple.portDst().toLong() >= flowClassifier.minSrcPortRange() || | ||
345 | + fiveTuple.portDst().toLong() <= flowClassifier.maxSrcPortRange()) { | ||
346 | + match = true; | ||
347 | + } else { | ||
348 | + continue; | ||
349 | + } | ||
350 | + | ||
351 | + // Check whether neutron source port is set in flow classfier | ||
352 | + if ((flowClassifier.srcPort() != null) && (!flowClassifier.srcPort().portId().isEmpty())) { | ||
353 | + match = checkIpInVirtualPort(VirtualPortId.portId(flowClassifier.srcPort().portId()), | ||
354 | + fiveTuple.ipSrc()); | ||
355 | + if (!match) { | ||
356 | + continue; | ||
357 | + } | ||
358 | + } | ||
359 | + | ||
360 | + // Check whether destination neutron destination port is set in flow classifier | ||
361 | + if ((flowClassifier.dstPort() != null) && (!flowClassifier.dstPort().portId().isEmpty())) { | ||
362 | + match = checkIpInVirtualPort(VirtualPortId.portId(flowClassifier.dstPort().portId()), | ||
363 | + fiveTuple.ipDst()); | ||
364 | + if (!match) { | ||
365 | + continue; | ||
366 | + } | ||
367 | + } | ||
368 | + | ||
369 | + if (match) { | ||
370 | + portChainId = portChain.portChainId(); | ||
371 | + break; | ||
372 | + } | ||
373 | + } | ||
374 | + } | ||
375 | + return portChainId; | ||
376 | + } | ||
377 | + | ||
378 | + | ||
379 | + /** | ||
380 | + * Get the tenant id for the given mac address. | ||
381 | + * | ||
382 | + * @param mac mac address | ||
383 | + * @return tenantId tenant id for the given mac address | ||
384 | + */ | ||
385 | + private TenantId getTenantId(MacAddress mac) { | ||
386 | + Collection<VirtualPort> virtualPorts = virtualPortService.getPorts(); | ||
387 | + for (VirtualPort virtualPort : virtualPorts) { | ||
388 | + if (virtualPort.macAddress().equals(mac)) { | ||
389 | + return virtualPort.tenantId(); | ||
390 | + } | ||
391 | + } | ||
392 | + return null; | ||
393 | + } | ||
394 | + | ||
241 | @Override | 395 | @Override |
242 | public void process(PacketContext context) { | 396 | public void process(PacketContext context) { |
243 | Ethernet packet = context.inPacket().parsed(); | 397 | Ethernet packet = context.inPacket().parsed(); |
244 | if (packet == null) { | 398 | if (packet == null) { |
245 | return; | 399 | return; |
246 | } | 400 | } |
247 | - // get the five tupple parameters for the packet | 401 | + // get the five tuple parameters for the packet |
248 | short ethType = packet.getEtherType(); | 402 | short ethType = packet.getEtherType(); |
249 | - VlanId vlanId = VlanId.vlanId(packet.getVlanID()); | 403 | + IpAddress ipSrc = null; |
250 | - MacAddress srcMac = packet.getSourceMAC(); | 404 | + IpAddress ipDst = null; |
251 | - MacAddress dstMac = packet.getDestinationMAC(); | 405 | + int portSrc = 0; |
252 | - IpAddress ipSrc; | 406 | + int portDst = 0; |
253 | - IpAddress ipDst; | 407 | + byte protocol = 0; |
408 | + MacAddress macSrc = packet.getSourceMAC(); | ||
409 | + TenantId tenantId = getTenantId(macSrc); | ||
254 | 410 | ||
255 | if (ethType == Ethernet.TYPE_IPV4) { | 411 | if (ethType == Ethernet.TYPE_IPV4) { |
256 | IPv4 ipv4Packet = (IPv4) packet.getPayload(); | 412 | IPv4 ipv4Packet = (IPv4) packet.getPayload(); |
257 | ipSrc = IpAddress.valueOf(ipv4Packet.getSourceAddress()); | 413 | ipSrc = IpAddress.valueOf(ipv4Packet.getSourceAddress()); |
258 | ipDst = IpAddress.valueOf(ipv4Packet.getDestinationAddress()); | 414 | ipDst = IpAddress.valueOf(ipv4Packet.getDestinationAddress()); |
415 | + protocol = ipv4Packet.getProtocol(); | ||
416 | + if (protocol == IPv4.PROTOCOL_TCP) { | ||
417 | + TCP tcpPacket = (TCP) ipv4Packet.getPayload(); | ||
418 | + portSrc = tcpPacket.getSourcePort(); | ||
419 | + portDst = tcpPacket.getDestinationPort(); | ||
420 | + } else if (protocol == IPv4.PROTOCOL_UDP) { | ||
421 | + UDP udpPacket = (UDP) ipv4Packet.getPayload(); | ||
422 | + portSrc = udpPacket.getSourcePort(); | ||
423 | + portDst = udpPacket.getDestinationPort(); | ||
424 | + } | ||
259 | } else if (ethType == Ethernet.TYPE_IPV6) { | 425 | } else if (ethType == Ethernet.TYPE_IPV6) { |
260 | - IPv6 ipv6Packet = (IPv6) packet.getPayload(); | 426 | + return; |
261 | - ipSrc = IpAddress.valueOf(ipv6Packet.getSourceAddress().toString()); | 427 | + } |
262 | - ipDst = IpAddress.valueOf(ipv6Packet.getDestinationAddress().toString()); | 428 | + |
429 | + | ||
430 | + FiveTuple fiveTuple = DefaultFiveTuple.builder() | ||
431 | + .setIpSrc(ipSrc) | ||
432 | + .setIpDst(ipDst) | ||
433 | + .setPortSrc(PortNumber.portNumber(portSrc)) | ||
434 | + .setPortDst(PortNumber.portNumber(portDst)) | ||
435 | + .setProtocol(protocol) | ||
436 | + .setTenantId(tenantId) | ||
437 | + .build(); | ||
438 | + | ||
439 | + PortChainId portChainId = findPortChainFromFiveTuple(fiveTuple); | ||
440 | + | ||
441 | + if (portChainId == null) { | ||
442 | + log.error("Packet does not match with any classifier"); | ||
443 | + return; | ||
263 | } | 444 | } |
264 | 445 | ||
265 | - //todo | 446 | + // TODO |
266 | - //identify the port chain to which the packet belongs | 447 | + // download the required flow rules for classifier and forwarding |
448 | + // resend the packet back to classifier | ||
267 | } | 449 | } |
268 | } | 450 | } |
269 | } | 451 | } | ... | ... |
-
Please register or login to post a comment