Phaneendra Manda
Committed by Gerrit Code Review

[ONOS-3831,ONOS-3836] Load balance algorithm for sfc

Change-Id: I48a428587420ce6d782c128b835b5bb90e0cacfe
1 -/*
2 - * Copyright 2015 Open Networking Laboratory
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - */
16 -package org.onosproject.sfc.manager;
17 -
18 -import java.util.concurrent.atomic.AtomicInteger;
19 -
20 -/**
21 - * Unique NSH SPI Id generator for NSH header.
22 - */
23 -public final class NshSpiIdGenerators {
24 -
25 - private static final AtomicInteger NSH_SPI_ID_GEN = new AtomicInteger();
26 - private static final int MAX_NSH_SPI_ID = 0x7FFFFFFF;
27 - private static int nshSpiId;
28 -
29 - /**
30 - * Default constructor.
31 - */
32 - private NshSpiIdGenerators() {
33 - }
34 -
35 - /**
36 - * Get the next NSH SPI id.
37 - *
38 - * @return NSH SPI id
39 - */
40 - public static int create() {
41 - do {
42 - if (nshSpiId >= MAX_NSH_SPI_ID) {
43 - if (NSH_SPI_ID_GEN.get() >= MAX_NSH_SPI_ID) {
44 - NSH_SPI_ID_GEN.set(0);
45 - }
46 - }
47 - nshSpiId = NSH_SPI_ID_GEN.incrementAndGet();
48 - } while (nshSpiId > MAX_NSH_SPI_ID);
49 - return nshSpiId;
50 - }
51 -}
...@@ -18,9 +18,10 @@ package org.onosproject.sfc.manager.impl; ...@@ -18,9 +18,10 @@ package org.onosproject.sfc.manager.impl;
18 import static org.slf4j.LoggerFactory.getLogger; 18 import static org.slf4j.LoggerFactory.getLogger;
19 19
20 import java.util.Collection; 20 import java.util.Collection;
21 +import java.util.Iterator;
22 +import java.util.List;
23 +import java.util.Optional;
21 import java.util.Set; 24 import java.util.Set;
22 -import java.util.concurrent.ConcurrentHashMap;
23 -import java.util.concurrent.ConcurrentMap;
24 25
25 import org.apache.felix.scr.annotations.Activate; 26 import org.apache.felix.scr.annotations.Activate;
26 import org.apache.felix.scr.annotations.Component; 27 import org.apache.felix.scr.annotations.Component;
...@@ -38,8 +39,14 @@ import org.onlab.util.ItemNotFoundException; ...@@ -38,8 +39,14 @@ import org.onlab.util.ItemNotFoundException;
38 import org.onlab.util.KryoNamespace; 39 import org.onlab.util.KryoNamespace;
39 import org.onosproject.core.ApplicationId; 40 import org.onosproject.core.ApplicationId;
40 import org.onosproject.core.CoreService; 41 import org.onosproject.core.CoreService;
42 +import org.onosproject.core.IdGenerator;
43 +import org.onosproject.net.ConnectPoint;
41 import org.onosproject.net.NshServicePathId; 44 import org.onosproject.net.NshServicePathId;
42 import org.onosproject.net.PortNumber; 45 import org.onosproject.net.PortNumber;
46 +import org.onosproject.net.flow.DefaultTrafficTreatment;
47 +import org.onosproject.net.flow.TrafficTreatment;
48 +import org.onosproject.net.packet.DefaultOutboundPacket;
49 +import org.onosproject.net.packet.OutboundPacket;
43 import org.onosproject.net.packet.PacketContext; 50 import org.onosproject.net.packet.PacketContext;
44 import org.onosproject.net.packet.PacketProcessor; 51 import org.onosproject.net.packet.PacketProcessor;
45 import org.onosproject.net.packet.PacketService; 52 import org.onosproject.net.packet.PacketService;
...@@ -47,13 +54,19 @@ import org.onosproject.sfc.forwarder.ServiceFunctionForwarderService; ...@@ -47,13 +54,19 @@ import org.onosproject.sfc.forwarder.ServiceFunctionForwarderService;
47 import org.onosproject.sfc.forwarder.impl.ServiceFunctionForwarderImpl; 54 import org.onosproject.sfc.forwarder.impl.ServiceFunctionForwarderImpl;
48 import org.onosproject.sfc.installer.FlowClassifierInstallerService; 55 import org.onosproject.sfc.installer.FlowClassifierInstallerService;
49 import org.onosproject.sfc.installer.impl.FlowClassifierInstallerImpl; 56 import org.onosproject.sfc.installer.impl.FlowClassifierInstallerImpl;
50 -import org.onosproject.sfc.manager.NshSpiIdGenerators;
51 import org.onosproject.sfc.manager.SfcService; 57 import org.onosproject.sfc.manager.SfcService;
58 +import org.onosproject.store.serializers.KryoNamespaces;
59 +import org.onosproject.store.service.DistributedSet;
60 +import org.onosproject.store.service.EventuallyConsistentMap;
61 +import org.onosproject.store.service.Serializer;
62 +import org.onosproject.store.service.StorageService;
63 +import org.onosproject.store.service.WallClockTimestamp;
52 import org.onosproject.vtnrsc.DefaultFiveTuple; 64 import org.onosproject.vtnrsc.DefaultFiveTuple;
53 import org.onosproject.vtnrsc.FiveTuple; 65 import org.onosproject.vtnrsc.FiveTuple;
54 import org.onosproject.vtnrsc.FixedIp; 66 import org.onosproject.vtnrsc.FixedIp;
55 import org.onosproject.vtnrsc.FlowClassifier; 67 import org.onosproject.vtnrsc.FlowClassifier;
56 import org.onosproject.vtnrsc.FlowClassifierId; 68 import org.onosproject.vtnrsc.FlowClassifierId;
69 +import org.onosproject.vtnrsc.LoadBalanceId;
57 import org.onosproject.vtnrsc.PortChain; 70 import org.onosproject.vtnrsc.PortChain;
58 import org.onosproject.vtnrsc.PortChainId; 71 import org.onosproject.vtnrsc.PortChainId;
59 import org.onosproject.vtnrsc.PortPair; 72 import org.onosproject.vtnrsc.PortPair;
...@@ -68,10 +81,13 @@ import org.onosproject.vtnrsc.event.VtnRscEventFeedback; ...@@ -68,10 +81,13 @@ import org.onosproject.vtnrsc.event.VtnRscEventFeedback;
68 import org.onosproject.vtnrsc.event.VtnRscListener; 81 import org.onosproject.vtnrsc.event.VtnRscListener;
69 import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService; 82 import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService;
70 import org.onosproject.vtnrsc.portchain.PortChainService; 83 import org.onosproject.vtnrsc.portchain.PortChainService;
84 +import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService;
71 import org.onosproject.vtnrsc.service.VtnRscService; 85 import org.onosproject.vtnrsc.service.VtnRscService;
72 import org.onosproject.vtnrsc.virtualport.VirtualPortService; 86 import org.onosproject.vtnrsc.virtualport.VirtualPortService;
73 import org.slf4j.Logger; 87 import org.slf4j.Logger;
74 88
89 +import com.google.common.collect.Lists;
90 +
75 /** 91 /**
76 * Provides implementation of SFC Service. 92 * Provides implementation of SFC Service.
77 */ 93 */
...@@ -80,9 +96,13 @@ import org.slf4j.Logger; ...@@ -80,9 +96,13 @@ import org.slf4j.Logger;
80 public class SfcManager implements SfcService { 96 public class SfcManager implements SfcService {
81 97
82 private final Logger log = getLogger(getClass()); 98 private final Logger log = getLogger(getClass());
99 +
100 + private String nshSpiIdTopic = "nsh-spi-id";
83 private static final String APP_ID = "org.onosproject.app.vtn"; 101 private static final String APP_ID = "org.onosproject.app.vtn";
84 private static final int SFC_PRIORITY = 1000; 102 private static final int SFC_PRIORITY = 1000;
85 private static final int NULL_PORT = 0; 103 private static final int NULL_PORT = 0;
104 + private static final int MAX_NSH_SPI_ID = 0x7FFFF;
105 + private static final int MAX_LOAD_BALANCE_ID = 0x20;
86 106
87 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 107 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
88 protected VtnRscService vtnRscService; 108 protected VtnRscService vtnRscService;
...@@ -97,26 +117,34 @@ public class SfcManager implements SfcService { ...@@ -97,26 +117,34 @@ public class SfcManager implements SfcService {
97 protected PortChainService portChainService; 117 protected PortChainService portChainService;
98 118
99 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 119 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
120 + protected PortPairGroupService portPairGroupService;
121 +
122 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
100 protected FlowClassifierService flowClassifierService; 123 protected FlowClassifierService flowClassifierService;
101 124
102 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 125 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
103 protected VirtualPortService virtualPortService; 126 protected VirtualPortService virtualPortService;
104 127
105 - private SfcPacketProcessor processor = new SfcPacketProcessor(); 128 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
129 + protected StorageService storageService;
130 +
131 + protected SfcPacketProcessor processor = new SfcPacketProcessor();
106 132
107 protected ApplicationId appId; 133 protected ApplicationId appId;
108 - private ServiceFunctionForwarderService serviceFunctionForwarderService; 134 + protected ServiceFunctionForwarderService serviceFunctionForwarder;
109 - private FlowClassifierInstallerService flowClassifierInstallerService; 135 + protected FlowClassifierInstallerService flowClassifierInstaller;
136 + protected IdGenerator nshSpiIdGenerator;
137 + protected EventuallyConsistentMap<PortChainId, Integer> nshSpiPortChainMap;
138 + protected DistributedSet<Integer> nshSpiIdFreeList;
110 139
111 private final VtnRscListener vtnRscListener = new InnerVtnRscListener(); 140 private final VtnRscListener vtnRscListener = new InnerVtnRscListener();
112 141
113 - private ConcurrentMap<PortChainId, NshServicePathId> nshSpiPortChainMap = new ConcurrentHashMap<>();
114 -
115 @Activate 142 @Activate
116 public void activate() { 143 public void activate() {
117 appId = coreService.registerApplication(APP_ID); 144 appId = coreService.registerApplication(APP_ID);
118 - serviceFunctionForwarderService = new ServiceFunctionForwarderImpl(appId); 145 + serviceFunctionForwarder = new ServiceFunctionForwarderImpl(appId);
119 - flowClassifierInstallerService = new FlowClassifierInstallerImpl(appId); 146 + flowClassifierInstaller = new FlowClassifierInstallerImpl(appId);
147 + nshSpiIdGenerator = coreService.getIdGenerator(nshSpiIdTopic);
120 148
121 vtnRscService.addListener(vtnRscListener); 149 vtnRscService.addListener(vtnRscListener);
122 150
...@@ -127,6 +155,18 @@ public class SfcManager implements SfcService { ...@@ -127,6 +155,18 @@ public class SfcManager implements SfcService {
127 .register(FlowClassifierId.class) 155 .register(FlowClassifierId.class)
128 .register(PortChainId.class); 156 .register(PortChainId.class);
129 157
158 + nshSpiPortChainMap = storageService.<PortChainId, Integer>eventuallyConsistentMapBuilder()
159 + .withName("nshSpiPortChainMap")
160 + .withSerializer(serializer)
161 + .withTimestampProvider((k, v) -> new WallClockTimestamp())
162 + .build();
163 +
164 + nshSpiIdFreeList = storageService.<Integer>setBuilder()
165 + .withName("nshSpiIdDeletedList")
166 + .withSerializer(Serializer.using(KryoNamespaces.API))
167 + .build()
168 + .asDistributedSet();
169 +
130 packetService.addProcessor(processor, PacketProcessor.director(SFC_PRIORITY)); 170 packetService.addProcessor(processor, PacketProcessor.director(SFC_PRIORITY));
131 log.info("Started"); 171 log.info("Started");
132 } 172 }
...@@ -230,15 +270,20 @@ public class SfcManager implements SfcService { ...@@ -230,15 +270,20 @@ public class SfcManager implements SfcService {
230 NshServicePathId nshSpi; 270 NshServicePathId nshSpi;
231 log.info("onPortChainCreated"); 271 log.info("onPortChainCreated");
232 if (nshSpiPortChainMap.containsKey(portChain.portChainId())) { 272 if (nshSpiPortChainMap.containsKey(portChain.portChainId())) {
233 - nshSpi = nshSpiPortChainMap.get(portChain.portChainId()); 273 + nshSpi = NshServicePathId.of(nshSpiPortChainMap.get(portChain.portChainId()));
234 } else { 274 } else {
235 - nshSpi = NshServicePathId.of(NshSpiIdGenerators.create()); 275 + int id = getNextNshSpi();
236 - nshSpiPortChainMap.put(portChain.portChainId(), nshSpi); 276 + if (id > MAX_NSH_SPI_ID) {
277 + log.error("Reached max limit of service path index."
278 + + "Failed to install SFC for port chain {}", portChain.portChainId().toString());
279 + return;
280 + }
281 + nshSpi = NshServicePathId.of(id);
282 + nshSpiPortChainMap.put(portChain.portChainId(), new Integer(id));
237 } 283 }
238 284
239 - // install in OVS. 285 + // Install classifier rule to send the packet to controller
240 - flowClassifierInstallerService.installFlowClassifier(portChain, nshSpi); 286 + flowClassifierInstaller.installFlowClassifier(portChain, nshSpi);
241 - serviceFunctionForwarderService.installForwardingRule(portChain, nshSpi);
242 } 287 }
243 288
244 @Override 289 @Override
...@@ -248,13 +293,47 @@ public class SfcManager implements SfcService { ...@@ -248,13 +293,47 @@ public class SfcManager implements SfcService {
248 throw new ItemNotFoundException("Unable to find NSH SPI"); 293 throw new ItemNotFoundException("Unable to find NSH SPI");
249 } 294 }
250 295
251 - NshServicePathId nshSpi = nshSpiPortChainMap.get(portChain.portChainId()); 296 + int nshSpiId = nshSpiPortChainMap.get(portChain.portChainId());
252 - // uninstall from OVS. 297 + // Uninstall classifier rules
253 - flowClassifierInstallerService.unInstallFlowClassifier(portChain, nshSpi); 298 + flowClassifierInstaller.unInstallFlowClassifier(portChain, NshServicePathId.of(nshSpiId));
254 - serviceFunctionForwarderService.unInstallForwardingRule(portChain, nshSpi); 299 + // remove from nshSpiPortChainMap and add to nshSpiIdFreeList
300 + nshSpiPortChainMap.remove(portChain.portChainId());
301 + nshSpiIdFreeList.add(nshSpiId);
302 +
303 + // Uninstall load balanced classifier and forwarding rules.
304 + NshServicePathId nshSpi;
305 + LoadBalanceId id;
306 + List<LoadBalanceId> processedIdList = Lists.newArrayList();
307 + Set<FiveTuple> fiveTupleSet = portChain.getLoadBalanceIdMapKeys();
308 + for (FiveTuple fiveTuple : fiveTupleSet) {
309 + id = portChain.getLoadBalanceId(fiveTuple);
310 + if (processedIdList.contains(id)) {
311 + // multiple five tuple can have single path.
312 + continue;
313 + } else {
314 + processedIdList.add(id);
315 + }
316 + nshSpi = NshServicePathId.of(getNshServicePathId(id, nshSpiId));
317 + flowClassifierInstaller.unInstallLoadBalancedFlowClassifier(portChain, fiveTuple, nshSpi);
318 + serviceFunctionForwarder.unInstallLoadBalancedForwardingRule(portChain.getLoadBalancePath(fiveTuple),
319 + nshSpi);
320 + }
321 + }
255 322
256 - // remove SPI. No longer it will be used. 323 + /**
257 - nshSpiPortChainMap.remove(nshSpi); 324 + * Get next nsh service path identifier.
325 + *
326 + * @return value of service path identifier
327 + */
328 + int getNextNshSpi() {
329 + // If there is any free id use it. Otherwise generate new id.
330 + if (nshSpiIdFreeList.isEmpty()) {
331 + return (int) nshSpiIdGenerator.getNewId();
332 + }
333 + Iterator<Integer> it = nshSpiIdFreeList.iterator();
334 + Integer value = it.next();
335 + nshSpiIdFreeList.remove(value);
336 + return value;
258 } 337 }
259 338
260 private class SfcPacketProcessor implements PacketProcessor { 339 private class SfcPacketProcessor implements PacketProcessor {
...@@ -296,6 +375,10 @@ public class SfcManager implements SfcService { ...@@ -296,6 +375,10 @@ public class SfcManager implements SfcService {
296 // Identify the port chain to which the packet belongs 375 // Identify the port chain to which the packet belongs
297 for (final PortChain portChain : portChains) { 376 for (final PortChain portChain : portChains) {
298 377
378 + if (!portChain.tenantId().equals(fiveTuple.tenantId())) {
379 + continue;
380 + }
381 +
299 Iterable<FlowClassifierId> flowClassifiers = portChain.flowClassifiers(); 382 Iterable<FlowClassifierId> flowClassifiers = portChain.flowClassifiers();
300 383
301 // One port chain can have multiple flow classifiers. 384 // One port chain can have multiple flow classifiers.
...@@ -375,6 +458,67 @@ public class SfcManager implements SfcService { ...@@ -375,6 +458,67 @@ public class SfcManager implements SfcService {
375 return portChainId; 458 return portChainId;
376 } 459 }
377 460
461 + /**
462 + * Find the load balanced path set it to port chain for the given five tuple.
463 + *
464 + * @param portChainId port chain id
465 + * @param fiveTuple five tuple info
466 + * @return load balance id
467 + */
468 + private LoadBalanceId loadBalanceSfc(PortChainId portChainId, FiveTuple fiveTuple) {
469 +
470 + // Get the port chain
471 + PortChain portChain = portChainService.getPortChain(portChainId);
472 + List<PortPairId> loadBalancePath = Lists.newArrayList();
473 + LoadBalanceId id;
474 + int paths = portChain.getLoadBalancePathSize();
475 + if (paths >= MAX_LOAD_BALANCE_ID) {
476 + log.info("Max limit reached for load balance paths. "
477 + + "Reusing the created path for port chain {} with five tuple {}",
478 + portChainId, fiveTuple);
479 + id = LoadBalanceId.of((byte) ((paths + 1) % MAX_LOAD_BALANCE_ID));
480 + portChain.addLoadBalancePath(fiveTuple, id, portChain.getLoadBalancePath(id));
481 + }
482 +
483 + // Get the list of port pair groups from port chain
484 + Iterable<PortPairGroupId> portPairGroups = portChain.portPairGroups();
485 + for (final PortPairGroupId portPairGroupId : portPairGroups) {
486 + PortPairGroup portPairGroup = portPairGroupService.getPortPairGroup(portPairGroupId);
487 +
488 + // Get the list of port pair ids from port pair group.
489 + Iterable<PortPairId> portPairs = portPairGroup.portPairs();
490 + int minLoad = 0xFFF;
491 + PortPairId minLoadPortPairId = null;
492 + for (final PortPairId portPairId : portPairs) {
493 + int load = portPairGroup.getLoad(portPairId);
494 + if (load == 0) {
495 + minLoadPortPairId = portPairId;
496 + break;
497 + } else {
498 + // Check the port pair which has min load.
499 + if (load < minLoad) {
500 + minLoad = load;
501 + minLoadPortPairId = portPairId;
502 + }
503 + }
504 + }
505 + if (minLoadPortPairId != null) {
506 + loadBalancePath.add(minLoadPortPairId);
507 + portPairGroup.addLoad(minLoadPortPairId);
508 + }
509 + }
510 +
511 + // Check if the path already exists, if not create a new id
512 + Optional<LoadBalanceId> output = portChain.matchPath(loadBalancePath);
513 + if (output.isPresent()) {
514 + id = output.get();
515 + } else {
516 + id = LoadBalanceId.of((byte) (paths + 1));
517 + }
518 +
519 + portChain.addLoadBalancePath(fiveTuple, id, loadBalancePath);
520 + return id;
521 + }
378 522
379 /** 523 /**
380 * Get the tenant id for the given mac address. 524 * Get the tenant id for the given mac address.
...@@ -443,9 +587,59 @@ public class SfcManager implements SfcService { ...@@ -443,9 +587,59 @@ public class SfcManager implements SfcService {
443 return; 587 return;
444 } 588 }
445 589
446 - // TODO 590 + // Once the 5 tuple and port chain are identified, give this input for load balancing
591 + LoadBalanceId id = loadBalanceSfc(portChainId, fiveTuple);
592 + // Get nsh service path index
593 + NshServicePathId nshSpi;
594 + PortChain portChain = portChainService.getPortChain(portChainId);
595 + if (nshSpiPortChainMap.containsKey(portChain.portChainId())) {
596 + int nshSpiId = nshSpiPortChainMap.get(portChain.portChainId());
597 + nshSpi = NshServicePathId.of(getNshServicePathId(id, nshSpiId));
598 + } else {
599 + int nshSpiId = getNextNshSpi();
600 + if (nshSpiId > MAX_NSH_SPI_ID) {
601 + log.error("Reached max limit of service path index."
602 + + "Failed to install SFC for port chain {}", portChain.portChainId());
603 + return;
604 + }
605 + nshSpi = NshServicePathId.of(getNshServicePathId(id, nshSpiId));
606 + nshSpiPortChainMap.put(portChain.portChainId(), new Integer(nshSpiId));
607 + }
447 // download the required flow rules for classifier and forwarding 608 // download the required flow rules for classifier and forwarding
448 - // resend the packet back to classifier 609 + // install in OVS.
610 + ConnectPoint connectPoint = flowClassifierInstaller.installLoadBalancedFlowClassifier(portChain,
611 + fiveTuple, nshSpi);
612 + serviceFunctionForwarder.installLoadBalancedForwardingRule(portChain.getLoadBalancePath(fiveTuple),
613 + nshSpi);
614 + sendPacket(context, connectPoint);
449 } 615 }
616 +
617 + /**
618 + * Send packet back to classifier.
619 + *
620 + * @param context packet context
621 + * @param connectPoint connect point of first service function
622 + */
623 + private void sendPacket(PacketContext context, ConnectPoint connectPoint) {
624 +
625 + TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(connectPoint.port()).build();
626 + OutboundPacket packet = new DefaultOutboundPacket(connectPoint.deviceId(), treatment,
627 + context.inPacket().unparsed());
628 + packetService.emit(packet);
629 + log.trace("Sending packet: {}", packet);
630 + }
631 + }
632 +
633 + /**
634 + * Encapsulate 5 bit load balance id to nsh spi.
635 + *
636 + * @param id load balance identifier
637 + * @param nshSpiId nsh service path index
638 + * @return updated service path index
639 + */
640 + protected int getNshServicePathId(LoadBalanceId id, int nshSpiId) {
641 + int nshSpiNew = nshSpiId << 5;
642 + nshSpiNew = nshSpiNew | id.loadBalanceId();
643 + return nshSpiNew;
450 } 644 }
451 } 645 }
......
...@@ -142,6 +142,14 @@ public final class DefaultPortChain implements PortChain { ...@@ -142,6 +142,14 @@ public final class DefaultPortChain implements PortChain {
142 } 142 }
143 143
144 @Override 144 @Override
145 + public int getLoadBalancePathSize() {
146 + if (sfcLoadBalanceIdMap.isEmpty()) {
147 + return 0;
148 + }
149 + return sfcLoadBalanceIdMap.size();
150 + }
151 +
152 + @Override
145 public Optional<LoadBalanceId> matchPath(List<PortPairId> path) { 153 public Optional<LoadBalanceId> matchPath(List<PortPairId> path) {
146 154
147 LoadBalanceId id = null; 155 LoadBalanceId id = null;
......
...@@ -113,6 +113,13 @@ public interface PortChain { ...@@ -113,6 +113,13 @@ public interface PortChain {
113 List<PortPairId> getLoadBalancePath(FiveTuple fiveTuple); 113 List<PortPairId> getLoadBalancePath(FiveTuple fiveTuple);
114 114
115 /** 115 /**
116 + * Get the no of load balance paths created.
117 + *
118 + * @return size of load balanced paths
119 + */
120 + int getLoadBalancePathSize();
121 +
122 + /**
116 * Match the given path with existing load balanced paths. 123 * Match the given path with existing load balanced paths.
117 * 124 *
118 * @param path load balanced path 125 * @param path load balanced path
......
...@@ -142,38 +142,37 @@ public class PortChainResourceTest extends VtnResourceTest { ...@@ -142,38 +142,37 @@ public class PortChainResourceTest extends VtnResourceTest {
142 142
143 @Override 143 @Override
144 public void addLoadBalancePath(FiveTuple fiveTuple, LoadBalanceId id, List<PortPairId> path) { 144 public void addLoadBalancePath(FiveTuple fiveTuple, LoadBalanceId id, List<PortPairId> path) {
145 - // TODO Auto-generated method stub
146 } 145 }
147 146
148 @Override 147 @Override
149 public LoadBalanceId getLoadBalanceId(FiveTuple fiveTuple) { 148 public LoadBalanceId getLoadBalanceId(FiveTuple fiveTuple) {
150 - // TODO Auto-generated method stub
151 return null; 149 return null;
152 } 150 }
153 151
154 @Override 152 @Override
155 public Set<FiveTuple> getLoadBalanceIdMapKeys() { 153 public Set<FiveTuple> getLoadBalanceIdMapKeys() {
156 - // TODO Auto-generated method stub
157 return null; 154 return null;
158 } 155 }
159 156
160 @Override 157 @Override
161 public List<PortPairId> getLoadBalancePath(LoadBalanceId id) { 158 public List<PortPairId> getLoadBalancePath(LoadBalanceId id) {
162 - // TODO Auto-generated method stub
163 return null; 159 return null;
164 } 160 }
165 161
166 @Override 162 @Override
167 public List<PortPairId> getLoadBalancePath(FiveTuple fiveTuple) { 163 public List<PortPairId> getLoadBalancePath(FiveTuple fiveTuple) {
168 - // TODO Auto-generated method stub
169 return null; 164 return null;
170 } 165 }
171 166
172 @Override 167 @Override
173 public Optional<LoadBalanceId> matchPath(List<PortPairId> path) { 168 public Optional<LoadBalanceId> matchPath(List<PortPairId> path) {
174 - // TODO Auto-generated method stub
175 return null; 169 return null;
176 } 170 }
171 +
172 + @Override
173 + public int getLoadBalancePathSize() {
174 + return 0;
175 + }
177 } 176 }
178 177
179 /** 178 /**
......