[ONOS-4612]Update SFC flows inline with the Official OVS NSH patch
Change-Id: I4635818ae94be8bd481331329250a119b39d294c
Showing
60 changed files
with
3729 additions
and
1207 deletions
1 | -/* | ||
2 | - * Copyright 2015-present 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.forwarder; | ||
17 | - | ||
18 | -import java.util.List; | ||
19 | - | ||
20 | -import org.onosproject.net.NshServicePathId; | ||
21 | -import org.onosproject.vtnrsc.PortChain; | ||
22 | -import org.onosproject.vtnrsc.PortPairId; | ||
23 | - | ||
24 | -/** | ||
25 | - * Abstraction of an entity which provides service function forwarder. | ||
26 | - */ | ||
27 | -public interface ServiceFunctionForwarderService { | ||
28 | - | ||
29 | - /** | ||
30 | - * Install forwarding rule. | ||
31 | - * | ||
32 | - * @param portChain port-chain | ||
33 | - * @param nshSpi nsh spi | ||
34 | - */ | ||
35 | - @Deprecated | ||
36 | - void installForwardingRule(PortChain portChain, NshServicePathId nshSpi); | ||
37 | - | ||
38 | - /** | ||
39 | - * Uninstall forwarding rule. | ||
40 | - * | ||
41 | - * @param portChain port-chain | ||
42 | - * @param nshSpi nsh spi | ||
43 | - */ | ||
44 | - @Deprecated | ||
45 | - void unInstallForwardingRule(PortChain portChain, NshServicePathId nshSpi); | ||
46 | - | ||
47 | - /** | ||
48 | - * Install load balanced forwarding rules. | ||
49 | - * | ||
50 | - * @param path load balanced path of port pairs | ||
51 | - * @param nshSpi nsh service path index | ||
52 | - */ | ||
53 | - void installLoadBalancedForwardingRule(List<PortPairId> path, NshServicePathId nshSpi); | ||
54 | - | ||
55 | - /** | ||
56 | - * Uninstall load balanced forwarding rules. | ||
57 | - * | ||
58 | - * @param path load balanced path of port pairs | ||
59 | - * @param nshSpi nsh service path index | ||
60 | - */ | ||
61 | - void unInstallLoadBalancedForwardingRule(List<PortPairId> path, NshServicePathId nshSpi); | ||
62 | -} |
1 | -/* | ||
2 | - * Copyright 2015-present 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.forwarder.impl; | ||
17 | - | ||
18 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
19 | -import static org.onosproject.net.flow.criteria.ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_SPI; | ||
20 | -import static org.slf4j.LoggerFactory.getLogger; | ||
21 | - | ||
22 | -import java.util.List; | ||
23 | -import java.util.ListIterator; | ||
24 | - | ||
25 | -import org.onlab.osgi.DefaultServiceDirectory; | ||
26 | -import org.onlab.osgi.ServiceDirectory; | ||
27 | -import org.onlab.packet.MacAddress; | ||
28 | -import org.onlab.packet.TpPort; | ||
29 | -import org.onlab.packet.VlanId; | ||
30 | -import org.onosproject.core.ApplicationId; | ||
31 | -import org.onosproject.net.DeviceId; | ||
32 | -import org.onosproject.net.Host; | ||
33 | -import org.onosproject.net.HostId; | ||
34 | -import org.onosproject.net.NshServicePathId; | ||
35 | -import org.onosproject.net.PortNumber; | ||
36 | -import org.onosproject.net.behaviour.ExtensionSelectorResolver; | ||
37 | -import org.onosproject.net.driver.DriverHandler; | ||
38 | -import org.onosproject.net.driver.DriverService; | ||
39 | -import org.onosproject.net.flow.DefaultTrafficSelector; | ||
40 | -import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
41 | -import org.onosproject.net.flow.TrafficSelector; | ||
42 | -import org.onosproject.net.flow.TrafficTreatment; | ||
43 | -import org.onosproject.net.flow.criteria.ExtensionSelector; | ||
44 | -import org.onosproject.net.flowobjective.DefaultForwardingObjective; | ||
45 | -import org.onosproject.net.flowobjective.FlowObjectiveService; | ||
46 | -import org.onosproject.net.flowobjective.ForwardingObjective; | ||
47 | -import org.onosproject.net.flowobjective.ForwardingObjective.Flag; | ||
48 | -import org.onosproject.net.flowobjective.Objective; | ||
49 | -import org.onosproject.net.host.HostService; | ||
50 | -import org.onosproject.sfc.forwarder.ServiceFunctionForwarderService; | ||
51 | -import org.onosproject.vtnrsc.PortChain; | ||
52 | -import org.onosproject.vtnrsc.PortPair; | ||
53 | -import org.onosproject.vtnrsc.PortPairId; | ||
54 | -import org.onosproject.vtnrsc.VirtualPortId; | ||
55 | -import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService; | ||
56 | -import org.onosproject.vtnrsc.portchain.PortChainService; | ||
57 | -import org.onosproject.vtnrsc.portpair.PortPairService; | ||
58 | -import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService; | ||
59 | -import org.onosproject.vtnrsc.service.VtnRscService; | ||
60 | -import org.onosproject.vtnrsc.virtualport.VirtualPortService; | ||
61 | -import org.slf4j.Logger; | ||
62 | - | ||
63 | -/** | ||
64 | - * Provides service function forwarder implementation. | ||
65 | - */ | ||
66 | -public class ServiceFunctionForwarderImpl implements ServiceFunctionForwarderService { | ||
67 | - | ||
68 | - private final Logger log = getLogger(getClass()); | ||
69 | - protected VirtualPortService virtualPortService; | ||
70 | - protected VtnRscService vtnRscService; | ||
71 | - protected PortPairService portPairService; | ||
72 | - protected PortPairGroupService portPairGroupService; | ||
73 | - protected FlowClassifierService flowClassifierService; | ||
74 | - protected PortChainService portChainService; | ||
75 | - protected DriverService driverService; | ||
76 | - protected FlowObjectiveService flowObjectiveService; | ||
77 | - protected HostService hostService; | ||
78 | - protected ApplicationId appId; | ||
79 | - | ||
80 | - private static final String PATH_NOT_NULL = "Load balanced path cannot be null"; | ||
81 | - private static final String APP_ID_NOT_NULL = "Application-Id cannot be null"; | ||
82 | - | ||
83 | - /** | ||
84 | - * Default constructor. | ||
85 | - */ | ||
86 | - public ServiceFunctionForwarderImpl() { | ||
87 | - } | ||
88 | - | ||
89 | - /** | ||
90 | - * Explicit constructor. | ||
91 | - * | ||
92 | - * @param appId application id | ||
93 | - */ | ||
94 | - public ServiceFunctionForwarderImpl(ApplicationId appId) { | ||
95 | - this.appId = checkNotNull(appId, APP_ID_NOT_NULL); | ||
96 | - ServiceDirectory serviceDirectory = new DefaultServiceDirectory(); | ||
97 | - this.flowObjectiveService = serviceDirectory.get(FlowObjectiveService.class); | ||
98 | - this.driverService = serviceDirectory.get(DriverService.class); | ||
99 | - this.virtualPortService = serviceDirectory.get(VirtualPortService.class); | ||
100 | - this.vtnRscService = serviceDirectory.get(VtnRscService.class); | ||
101 | - this.portPairService = serviceDirectory.get(PortPairService.class); | ||
102 | - this.portPairGroupService = serviceDirectory.get(PortPairGroupService.class); | ||
103 | - this.flowClassifierService = serviceDirectory.get(FlowClassifierService.class); | ||
104 | - this.hostService = serviceDirectory.get(HostService.class); | ||
105 | - this.portChainService = serviceDirectory.get(PortChainService.class); | ||
106 | - } | ||
107 | - | ||
108 | - @Override | ||
109 | - public void installForwardingRule(PortChain portChain, NshServicePathId nshSpi) { | ||
110 | - //TODO this method will be removed | ||
111 | - } | ||
112 | - | ||
113 | - @Override | ||
114 | - public void unInstallForwardingRule(PortChain portChain, NshServicePathId nshSpi) { | ||
115 | - //TODO this method will be removed | ||
116 | - } | ||
117 | - | ||
118 | - @Override | ||
119 | - public void installLoadBalancedForwardingRule(List<PortPairId> path, NshServicePathId nshSpi) { | ||
120 | - checkNotNull(path, PATH_NOT_NULL); | ||
121 | - processForwardingRule(path, nshSpi, Objective.Operation.ADD); | ||
122 | - } | ||
123 | - | ||
124 | - @Override | ||
125 | - public void unInstallLoadBalancedForwardingRule(List<PortPairId> path, NshServicePathId nshSpi) { | ||
126 | - checkNotNull(path, PATH_NOT_NULL); | ||
127 | - processForwardingRule(path, nshSpi, Objective.Operation.REMOVE); | ||
128 | - } | ||
129 | - | ||
130 | - /** | ||
131 | - * Process the required forwarding rules for the given path. | ||
132 | - * | ||
133 | - * @param path list of port pair ids | ||
134 | - * @param nshSpi service path index | ||
135 | - * @param type operation type ADD/REMOVE | ||
136 | - */ | ||
137 | - private void processForwardingRule(List<PortPairId> path, NshServicePathId nshSpi, | ||
138 | - Objective.Operation type) { | ||
139 | - | ||
140 | - // Get the first port pair | ||
141 | - ListIterator<PortPairId> portPairListIterator = path.listIterator(); | ||
142 | - PortPair currentPortPair = portPairService.getPortPair(portPairListIterator.next()); | ||
143 | - | ||
144 | - // Get destination port pair group | ||
145 | - if (!portPairListIterator.hasNext()) { | ||
146 | - log.debug("Path is empty"); | ||
147 | - return; | ||
148 | - } | ||
149 | - PortPair nextPortPair = portPairService.getPortPair(portPairListIterator.next()); | ||
150 | - DeviceId currentDeviceId = null; | ||
151 | - DeviceId nextDeviceId = null; | ||
152 | - | ||
153 | - // Travel from SF to SF. | ||
154 | - do { | ||
155 | - currentDeviceId = vtnRscService.getSfToSffMaping(VirtualPortId.portId(currentPortPair.egress())); | ||
156 | - nextDeviceId = vtnRscService.getSfToSffMaping(VirtualPortId.portId(nextPortPair.ingress())); | ||
157 | - // pack traffic selector | ||
158 | - TrafficSelector.Builder selector = packTrafficSelector(currentDeviceId, currentPortPair, nshSpi); | ||
159 | - // Pack treatment | ||
160 | - if (currentDeviceId.equals(nextDeviceId)) { | ||
161 | - TrafficTreatment.Builder treatment = packTrafficTreatment(nextPortPair, true); | ||
162 | - // Send SFF to SFF | ||
163 | - sendServiceFunctionForwarder(selector, treatment, currentDeviceId, type); | ||
164 | - } else { | ||
165 | - TrafficTreatment.Builder treatment = packTrafficTreatment(nextPortPair, false); | ||
166 | - // Send SFF to OVS | ||
167 | - sendServiceFunctionForwarder(selector, treatment, currentDeviceId, type); | ||
168 | - | ||
169 | - // At the other device get the packet from vlan and send to first port pair | ||
170 | - TrafficSelector.Builder selectorDst = DefaultTrafficSelector.builder(); | ||
171 | - selectorDst.matchVlanId((VlanId.vlanId(Short.parseShort((vtnRscService | ||
172 | - .getL3vni(nextPortPair.tenantId()).toString()))))); | ||
173 | - TrafficTreatment.Builder treatmentDst = DefaultTrafficTreatment.builder(); | ||
174 | - MacAddress macAddr = virtualPortService.getPort(VirtualPortId.portId(nextPortPair.ingress())) | ||
175 | - .macAddress(); | ||
176 | - Host host = hostService.getHost(HostId.hostId(macAddr)); | ||
177 | - PortNumber port = host.location().port(); | ||
178 | - treatmentDst.setOutput(port); | ||
179 | - // Send OVS to SFF | ||
180 | - sendServiceFunctionForwarder(selectorDst, treatmentDst, nextDeviceId, type); | ||
181 | - } | ||
182 | - | ||
183 | - // Move to next service function | ||
184 | - currentPortPair = nextPortPair; | ||
185 | - if (!portPairListIterator.hasNext()) { | ||
186 | - break; | ||
187 | - } | ||
188 | - nextPortPair = portPairService.getPortPair(portPairListIterator.next()); | ||
189 | - } while (true); | ||
190 | - } | ||
191 | - | ||
192 | - /** | ||
193 | - * Pack traffic selector. | ||
194 | - * | ||
195 | - * @param deviceId device id | ||
196 | - * @param portPair port-pair | ||
197 | - * @param nshSpi nsh service path index | ||
198 | - * @return traffic selector | ||
199 | - */ | ||
200 | - public TrafficSelector.Builder packTrafficSelector(DeviceId deviceId, | ||
201 | - PortPair portPair, NshServicePathId nshSpi) { | ||
202 | - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
203 | - | ||
204 | - MacAddress dstMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.egress())).macAddress(); | ||
205 | - Host host = hostService.getHost(HostId.hostId(dstMacAddress)); | ||
206 | - PortNumber port = host.location().port(); | ||
207 | - selector.matchInPort(port); | ||
208 | - | ||
209 | - DriverHandler handler = driverService.createHandler(deviceId); | ||
210 | - ExtensionSelectorResolver resolver = handler.behaviour(ExtensionSelectorResolver.class); | ||
211 | - ExtensionSelector nspSpiSelector = resolver.getExtensionSelector(NICIRA_MATCH_NSH_SPI.type()); | ||
212 | - | ||
213 | - try { | ||
214 | - nspSpiSelector.setPropertyValue("nshSpi", nshSpi); | ||
215 | - } catch (Exception e) { | ||
216 | - log.error("Failed to get extension instruction to set Nsh Spi Id {}", deviceId); | ||
217 | - } | ||
218 | - | ||
219 | - selector.extension(nspSpiSelector, deviceId); | ||
220 | - | ||
221 | - return selector; | ||
222 | - } | ||
223 | - | ||
224 | - /** | ||
225 | - * Pack traffic treatment. | ||
226 | - * | ||
227 | - * @param portPair port pair | ||
228 | - * @param isSameOvs whether the next port pair is in the same ovs | ||
229 | - * @return traffic treatment | ||
230 | - */ | ||
231 | - public TrafficTreatment.Builder packTrafficTreatment(PortPair portPair, boolean isSameOvs) { | ||
232 | - MacAddress srcMacAddress = null; | ||
233 | - | ||
234 | - // Check the treatment whether destination SF is on same OVS or in | ||
235 | - // different OVS. | ||
236 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
237 | - if (isSameOvs) { | ||
238 | - srcMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.ingress())).macAddress(); | ||
239 | - Host host = hostService.getHost(HostId.hostId(srcMacAddress)); | ||
240 | - PortNumber port = host.location().port(); | ||
241 | - treatment.setOutput(port); | ||
242 | - } else { | ||
243 | - // Vxlan tunnel port for NSH header(Vxlan + NSH). | ||
244 | - TpPort nshDstPort = TpPort.tpPort(6633); | ||
245 | - // TODO check whether this logic is correct | ||
246 | - VlanId vlanId = VlanId.vlanId(Short.parseShort((vtnRscService.getL3vni(portPair.tenantId()).toString()))); | ||
247 | - treatment.setVlanId(vlanId); | ||
248 | - treatment.setUdpDst(nshDstPort); | ||
249 | - } | ||
250 | - | ||
251 | - return treatment; | ||
252 | - } | ||
253 | - | ||
254 | - /** | ||
255 | - * Send service function forwarder to OVS. | ||
256 | - * | ||
257 | - * @param selector traffic selector | ||
258 | - * @param treatment traffic treatment | ||
259 | - * @param deviceId device id | ||
260 | - * @param type operation type | ||
261 | - */ | ||
262 | - public void sendServiceFunctionForwarder(TrafficSelector.Builder selector, TrafficTreatment.Builder treatment, | ||
263 | - DeviceId deviceId, Objective.Operation type) { | ||
264 | - log.info("Sending flow to serfice-function-forwarder. Selector {}, Treatment {}", | ||
265 | - selector.toString(), treatment.toString()); | ||
266 | - ForwardingObjective.Builder objective = DefaultForwardingObjective.builder().withTreatment(treatment.build()) | ||
267 | - .withSelector(selector.build()).fromApp(appId).makePermanent().withFlag(Flag.VERSATILE); | ||
268 | - if (type.equals(Objective.Operation.ADD)) { | ||
269 | - log.debug("ADD"); | ||
270 | - flowObjectiveService.forward(deviceId, objective.add()); | ||
271 | - } else { | ||
272 | - log.debug("REMOVE"); | ||
273 | - flowObjectiveService.forward(deviceId, objective.remove()); | ||
274 | - } | ||
275 | - } | ||
276 | -} |
1 | -/* | ||
2 | - * Copyright 2015-present 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 | - | ||
17 | -/** | ||
18 | - * Service function forwarder for SFC. | ||
19 | - */ | ||
20 | -package org.onosproject.sfc.forwarder; |
... | @@ -23,7 +23,7 @@ import org.onosproject.vtnrsc.PortChain; | ... | @@ -23,7 +23,7 @@ import org.onosproject.vtnrsc.PortChain; |
23 | /** | 23 | /** |
24 | * Abstraction of an entity which installs flow classification rules in ovs. | 24 | * Abstraction of an entity which installs flow classification rules in ovs. |
25 | */ | 25 | */ |
26 | -public interface FlowClassifierInstallerService { | 26 | +public interface SfcFlowRuleInstallerService { |
27 | 27 | ||
28 | /** | 28 | /** |
29 | * Install flow classifier. | 29 | * Install flow classifier. |
... | @@ -44,24 +44,24 @@ public interface FlowClassifierInstallerService { | ... | @@ -44,24 +44,24 @@ public interface FlowClassifierInstallerService { |
44 | ConnectPoint unInstallFlowClassifier(PortChain portChain, NshServicePathId nshSpiId); | 44 | ConnectPoint unInstallFlowClassifier(PortChain portChain, NshServicePathId nshSpiId); |
45 | 45 | ||
46 | /** | 46 | /** |
47 | - * Install load balanced flow classifier. | 47 | + * Install load balanced flow rules. |
48 | * | 48 | * |
49 | * @param portChain port-chain | 49 | * @param portChain port-chain |
50 | * @param fiveTuple five tuple packet information | 50 | * @param fiveTuple five tuple packet information |
51 | * @param nshSpiId service path index identifier | 51 | * @param nshSpiId service path index identifier |
52 | * @return connectPoint the network identifier | 52 | * @return connectPoint the network identifier |
53 | */ | 53 | */ |
54 | - ConnectPoint installLoadBalancedFlowClassifier(PortChain portChain, FiveTuple fiveTuple, | 54 | + ConnectPoint installLoadBalancedFlowRules(PortChain portChain, FiveTuple fiveTuple, |
55 | - NshServicePathId nshSpiId); | 55 | + NshServicePathId nshSpiId); |
56 | 56 | ||
57 | /** | 57 | /** |
58 | - * Uninstall load balanced flow classifier. | 58 | + * Uninstall load balanced flow rules. |
59 | * | 59 | * |
60 | * @param portChain port-chain | 60 | * @param portChain port-chain |
61 | * @param fiveTuple five tuple packet information | 61 | * @param fiveTuple five tuple packet information |
62 | * @param nshSpiId service path index identifier | 62 | * @param nshSpiId service path index identifier |
63 | * @return connectPoint the network identifier | 63 | * @return connectPoint the network identifier |
64 | */ | 64 | */ |
65 | - ConnectPoint unInstallLoadBalancedFlowClassifier(PortChain portChain, FiveTuple fiveTuple, | 65 | + ConnectPoint unInstallLoadBalancedFlowRules(PortChain portChain, FiveTuple fiveTuple, |
66 | - NshServicePathId nshSpiId); | 66 | + NshServicePathId nshSpiId); |
67 | } | 67 | } | ... | ... |
1 | -/* | ||
2 | - * Copyright 2015-present 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.installer.impl; | ||
17 | - | ||
18 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
19 | -import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SI; | ||
20 | -import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SPI; | ||
21 | -import static org.slf4j.LoggerFactory.getLogger; | ||
22 | - | ||
23 | -import java.util.LinkedList; | ||
24 | -import java.util.List; | ||
25 | -import java.util.ListIterator; | ||
26 | - | ||
27 | -import org.onlab.osgi.DefaultServiceDirectory; | ||
28 | -import org.onlab.osgi.ServiceDirectory; | ||
29 | -import org.onlab.packet.Ethernet; | ||
30 | -import org.onlab.packet.IPv4; | ||
31 | -import org.onlab.packet.IpPrefix; | ||
32 | -import org.onlab.packet.MacAddress; | ||
33 | -import org.onlab.packet.TpPort; | ||
34 | -import org.onlab.packet.VlanId; | ||
35 | -import org.onosproject.core.ApplicationId; | ||
36 | -import org.onosproject.net.ConnectPoint; | ||
37 | -import org.onosproject.net.DeviceId; | ||
38 | -import org.onosproject.net.Host; | ||
39 | -import org.onosproject.net.HostId; | ||
40 | -import org.onosproject.net.NshServiceIndex; | ||
41 | -import org.onosproject.net.NshServicePathId; | ||
42 | -import org.onosproject.net.PortNumber; | ||
43 | -import org.onosproject.net.behaviour.ExtensionTreatmentResolver; | ||
44 | -import org.onosproject.net.device.DeviceService; | ||
45 | -import org.onosproject.net.driver.DriverHandler; | ||
46 | -import org.onosproject.net.driver.DriverService; | ||
47 | -import org.onosproject.net.flow.DefaultTrafficSelector; | ||
48 | -import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
49 | -import org.onosproject.net.flow.TrafficSelector; | ||
50 | -import org.onosproject.net.flow.TrafficTreatment; | ||
51 | -import org.onosproject.net.flow.criteria.Criteria; | ||
52 | -import org.onosproject.net.flow.instructions.ExtensionTreatment; | ||
53 | -import org.onosproject.net.flowobjective.DefaultForwardingObjective; | ||
54 | -import org.onosproject.net.flowobjective.FlowObjectiveService; | ||
55 | -import org.onosproject.net.flowobjective.ForwardingObjective; | ||
56 | -import org.onosproject.net.flowobjective.ForwardingObjective.Flag; | ||
57 | -import org.onosproject.net.flowobjective.Objective; | ||
58 | -import org.onosproject.net.host.HostService; | ||
59 | -import org.onosproject.sfc.installer.FlowClassifierInstallerService; | ||
60 | -import org.onosproject.vtnrsc.FiveTuple; | ||
61 | -import org.onosproject.vtnrsc.FlowClassifier; | ||
62 | -import org.onosproject.vtnrsc.FlowClassifierId; | ||
63 | -import org.onosproject.vtnrsc.PortChain; | ||
64 | -import org.onosproject.vtnrsc.PortPair; | ||
65 | -import org.onosproject.vtnrsc.PortPairGroup; | ||
66 | -import org.onosproject.vtnrsc.PortPairGroupId; | ||
67 | -import org.onosproject.vtnrsc.PortPairId; | ||
68 | -import org.onosproject.vtnrsc.VirtualPortId; | ||
69 | -import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService; | ||
70 | -import org.onosproject.vtnrsc.portpair.PortPairService; | ||
71 | -import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService; | ||
72 | -import org.onosproject.vtnrsc.service.VtnRscService; | ||
73 | -import org.onosproject.vtnrsc.virtualport.VirtualPortService; | ||
74 | -import org.slf4j.Logger; | ||
75 | - | ||
76 | -/** | ||
77 | - * Provides flow classifier installer implementation. | ||
78 | - */ | ||
79 | -public class FlowClassifierInstallerImpl implements FlowClassifierInstallerService { | ||
80 | - private final Logger log = getLogger(getClass()); | ||
81 | - | ||
82 | - protected VirtualPortService virtualPortService; | ||
83 | - protected VtnRscService vtnRscService; | ||
84 | - protected PortPairService portPairService; | ||
85 | - protected PortPairGroupService portPairGroupService; | ||
86 | - protected FlowClassifierService flowClassifierService; | ||
87 | - protected DriverService driverService; | ||
88 | - protected DeviceService deviceService; | ||
89 | - protected HostService hostService; | ||
90 | - protected FlowObjectiveService flowObjectiveService; | ||
91 | - protected ApplicationId appId; | ||
92 | - | ||
93 | - private static final String DRIVER_NAME = "onosfw"; | ||
94 | - private static final String FLOW_CLASSIFIER_NOT_NULL = "Flow-Classifier cannot be null"; | ||
95 | - private static final String FLOW_CLASSIFIER_ID_NOT_NULL = "Flow-Classifier-Id cannot be null"; | ||
96 | - private static final String PORT_CHAIN_NOT_NULL = "Port-Chain cannot be null"; | ||
97 | - private static final int NULL = 0; | ||
98 | - private static final int FLOW_CLASSIFIER_PRIORITY = 0x7fff; | ||
99 | - private static final short NSH_SI_ID = 0xff; | ||
100 | - | ||
101 | - /** | ||
102 | - * Default constructor. | ||
103 | - */ | ||
104 | - public FlowClassifierInstallerImpl() { | ||
105 | - } | ||
106 | - | ||
107 | - /** | ||
108 | - * Explicit constructor. | ||
109 | - * | ||
110 | - * @param appId application id. | ||
111 | - */ | ||
112 | - public FlowClassifierInstallerImpl(ApplicationId appId) { | ||
113 | - this.appId = checkNotNull(appId, "ApplicationId can not be null"); | ||
114 | - ServiceDirectory serviceDirectory = new DefaultServiceDirectory(); | ||
115 | - this.flowObjectiveService = serviceDirectory.get(FlowObjectiveService.class); | ||
116 | - this.driverService = serviceDirectory.get(DriverService.class); | ||
117 | - this.deviceService = serviceDirectory.get(DeviceService.class); | ||
118 | - this.hostService = serviceDirectory.get(HostService.class); | ||
119 | - this.virtualPortService = serviceDirectory.get(VirtualPortService.class); | ||
120 | - this.vtnRscService = serviceDirectory.get(VtnRscService.class); | ||
121 | - this.portPairService = serviceDirectory.get(PortPairService.class); | ||
122 | - this.portPairGroupService = serviceDirectory.get(PortPairGroupService.class); | ||
123 | - this.flowClassifierService = serviceDirectory.get(FlowClassifierService.class); | ||
124 | - } | ||
125 | - | ||
126 | - @Override | ||
127 | - public ConnectPoint installFlowClassifier(PortChain portChain, NshServicePathId nshSpiId) { | ||
128 | - checkNotNull(portChain, PORT_CHAIN_NOT_NULL); | ||
129 | - // Get the portPairGroup | ||
130 | - List<PortPairGroupId> llPortPairGroupIdList = portChain.portPairGroups(); | ||
131 | - ListIterator<PortPairGroupId> portPairGroupIdListIterator = llPortPairGroupIdList.listIterator(); | ||
132 | - PortPairGroupId portPairGroupId = portPairGroupIdListIterator.next(); | ||
133 | - PortPairGroup portPairGroup = portPairGroupService.getPortPairGroup(portPairGroupId); | ||
134 | - List<PortPairId> llPortPairIdList = portPairGroup.portPairs(); | ||
135 | - | ||
136 | - // Get port pair | ||
137 | - ListIterator<PortPairId> portPairListIterator = llPortPairIdList.listIterator(); | ||
138 | - PortPairId portPairId = portPairListIterator.next(); | ||
139 | - PortPair portPair = portPairService.getPortPair(portPairId); | ||
140 | - | ||
141 | - return processFlowClassifier(portChain, portPair, nshSpiId, null, Objective.Operation.ADD); | ||
142 | - } | ||
143 | - | ||
144 | - @Override | ||
145 | - public ConnectPoint unInstallFlowClassifier(PortChain portChain, NshServicePathId nshSpiId) { | ||
146 | - checkNotNull(portChain, PORT_CHAIN_NOT_NULL); | ||
147 | - // Get the portPairGroup | ||
148 | - List<PortPairGroupId> llPortPairGroupIdList = portChain.portPairGroups(); | ||
149 | - ListIterator<PortPairGroupId> portPairGroupIdListIterator = llPortPairGroupIdList.listIterator(); | ||
150 | - PortPairGroupId portPairGroupId = portPairGroupIdListIterator.next(); | ||
151 | - PortPairGroup portPairGroup = portPairGroupService.getPortPairGroup(portPairGroupId); | ||
152 | - List<PortPairId> llPortPairIdList = portPairGroup.portPairs(); | ||
153 | - | ||
154 | - // Get port pair | ||
155 | - ListIterator<PortPairId> portPairListIterator = llPortPairIdList.listIterator(); | ||
156 | - PortPairId portPairId = portPairListIterator.next(); | ||
157 | - PortPair portPair = portPairService.getPortPair(portPairId); | ||
158 | - | ||
159 | - return processFlowClassifier(portChain, portPair, nshSpiId, null, Objective.Operation.REMOVE); | ||
160 | - } | ||
161 | - | ||
162 | - @Override | ||
163 | - public ConnectPoint installLoadBalancedFlowClassifier(PortChain portChain, FiveTuple fiveTuple, | ||
164 | - NshServicePathId nshSpiId) { | ||
165 | - checkNotNull(portChain, PORT_CHAIN_NOT_NULL); | ||
166 | - | ||
167 | - // Get the load balanced path | ||
168 | - List<PortPairId> portPairs = portChain.getLoadBalancePath(fiveTuple); | ||
169 | - | ||
170 | - // Get the first port pair | ||
171 | - ListIterator<PortPairId> portPairListIterator = portPairs.listIterator(); | ||
172 | - PortPairId portPairId = portPairListIterator.next(); | ||
173 | - PortPair portPair = portPairService.getPortPair(portPairId); | ||
174 | - | ||
175 | - return processFlowClassifier(portChain, portPair, nshSpiId, fiveTuple, Objective.Operation.ADD); | ||
176 | - } | ||
177 | - | ||
178 | - @Override | ||
179 | - public ConnectPoint unInstallLoadBalancedFlowClassifier(PortChain portChain, FiveTuple fiveTuple, | ||
180 | - NshServicePathId nshSpiId) { | ||
181 | - checkNotNull(portChain, PORT_CHAIN_NOT_NULL); | ||
182 | - // Get the load balanced path | ||
183 | - List<PortPairId> portPairs = portChain.getLoadBalancePath(fiveTuple); | ||
184 | - | ||
185 | - // Get the first port pair | ||
186 | - ListIterator<PortPairId> portPairListIterator = portPairs.listIterator(); | ||
187 | - PortPairId portPairId = portPairListIterator.next(); | ||
188 | - PortPair portPair = portPairService.getPortPair(portPairId); | ||
189 | - | ||
190 | - return processFlowClassifier(portChain, portPair, nshSpiId, fiveTuple, Objective.Operation.REMOVE); | ||
191 | - } | ||
192 | - | ||
193 | - public ConnectPoint processFlowClassifier(PortChain portChain, PortPair portPair, NshServicePathId nshSpiId, | ||
194 | - FiveTuple fiveTuple, Objective.Operation type) { | ||
195 | - | ||
196 | - DeviceId deviceIdfromPortPair = vtnRscService.getSfToSffMaping(VirtualPortId.portId(portPair.ingress())); | ||
197 | - MacAddress srcMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.ingress())).macAddress(); | ||
198 | - Host host = hostService.getHost(HostId.hostId(srcMacAddress)); | ||
199 | - PortNumber port = host.location().port(); | ||
200 | - | ||
201 | - DeviceId deviceId = deviceIdfromPortPair; | ||
202 | - | ||
203 | - // Vxlan tunnel port for NSH header(Vxlan + NSH). | ||
204 | - TpPort nshDstPort = TpPort.tpPort(6633); | ||
205 | - | ||
206 | - FlowClassifierInstallerService flowclassifierinstallerService; | ||
207 | - // get flow classifiers | ||
208 | - List<FlowClassifierId> llFlowClassifierList = portChain.flowClassifiers(); | ||
209 | - ListIterator<FlowClassifierId> flowClassifierListIterator = llFlowClassifierList.listIterator(); | ||
210 | - | ||
211 | - while (flowClassifierListIterator.hasNext()) { | ||
212 | - FlowClassifierId flowclassifierId = flowClassifierListIterator.next(); | ||
213 | - FlowClassifier flowClassifier = flowClassifierService.getFlowClassifier(flowclassifierId); | ||
214 | - | ||
215 | - if ((flowClassifier.srcPort() != null) && (!flowClassifier.srcPort().portId().isEmpty())) { | ||
216 | - deviceId = vtnRscService.getSfToSffMaping(flowClassifier.srcPort()); | ||
217 | - } | ||
218 | - | ||
219 | - // Build Traffic selector. | ||
220 | - TrafficSelector.Builder selector = packTrafficSelector(flowClassifier, fiveTuple); | ||
221 | - | ||
222 | - if (fiveTuple == null) { | ||
223 | - // Send the packet to controller | ||
224 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
225 | - treatment.setOutput(PortNumber.CONTROLLER); | ||
226 | - sendServiceFunctionClassifier(selector, treatment, deviceId, type, flowClassifier.priority()); | ||
227 | - } else if (deviceId.equals(deviceIdfromPortPair)) { | ||
228 | - // classifier and source device are in the same OVS. So directly send packet to first port pair | ||
229 | - TrafficTreatment.Builder treatment = packTrafficTreatment(deviceId, port, nshDstPort, | ||
230 | - nshSpiId, flowClassifier, true); | ||
231 | - // Build forwarding objective and send to OVS. | ||
232 | - sendServiceFunctionClassifier(selector, treatment, deviceId, type, flowClassifier.priority()); | ||
233 | - } else { | ||
234 | - // classifier and source device are not in the same OVS. Send packet on vlan Tunnel | ||
235 | - TrafficTreatment.Builder treatment = packTrafficTreatment(deviceId, port, nshDstPort, | ||
236 | - nshSpiId, flowClassifier, false); | ||
237 | - // Build forwarding objective and send to OVS. | ||
238 | - sendServiceFunctionClassifier(selector, treatment, deviceId, type, flowClassifier.priority()); | ||
239 | - | ||
240 | - // At the other device get the packet from vlan and send to first port pair | ||
241 | - TrafficSelector.Builder selectorDst = DefaultTrafficSelector.builder(); | ||
242 | - selectorDst.matchVlanId((VlanId.vlanId(Short.parseShort((vtnRscService | ||
243 | - .getL3vni(flowClassifier.tenantId()).toString()))))); | ||
244 | - TrafficTreatment.Builder treatmentDst = DefaultTrafficTreatment.builder(); | ||
245 | - Host hostDst = hostService.getHost(HostId.hostId(srcMacAddress)); | ||
246 | - treatmentDst.setOutput(hostDst.location().port()); | ||
247 | - sendServiceFunctionClassifier(selectorDst, treatmentDst, deviceIdfromPortPair, type, | ||
248 | - flowClassifier.priority()); | ||
249 | - } | ||
250 | - } | ||
251 | - return host.location(); | ||
252 | - } | ||
253 | - | ||
254 | - /** | ||
255 | - * Pack Traffic selector. | ||
256 | - * | ||
257 | - * @param flowClassifier flow-classifier | ||
258 | - * @param fiveTuple five tuple info for the packet | ||
259 | - * @return traffic selector | ||
260 | - */ | ||
261 | - public TrafficSelector.Builder packTrafficSelector(FlowClassifier flowClassifier, FiveTuple fiveTuple) { | ||
262 | - | ||
263 | - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
264 | - | ||
265 | - if ((flowClassifier.srcIpPrefix() != null) && (flowClassifier.srcIpPrefix().prefixLength() != 0)) { | ||
266 | - selector.matchIPSrc(flowClassifier.srcIpPrefix()); | ||
267 | - } else if (fiveTuple != null && fiveTuple.ipSrc() != null) { | ||
268 | - selector.matchIPSrc(IpPrefix.valueOf(fiveTuple.ipSrc(), 24)); | ||
269 | - } | ||
270 | - | ||
271 | - if ((flowClassifier.dstIpPrefix() != null) && (flowClassifier.dstIpPrefix().prefixLength() != 0)) { | ||
272 | - selector.matchIPDst(flowClassifier.dstIpPrefix()); | ||
273 | - } else if (fiveTuple != null && fiveTuple.ipDst() != null) { | ||
274 | - selector.matchIPDst(IpPrefix.valueOf(fiveTuple.ipDst(), 24)); | ||
275 | - } | ||
276 | - | ||
277 | - if ((flowClassifier.protocol() != null) && (!flowClassifier.protocol().isEmpty())) { | ||
278 | - if (flowClassifier.protocol().equalsIgnoreCase("TCP")) { | ||
279 | - selector.add(Criteria.matchIPProtocol(IPv4.PROTOCOL_TCP)); | ||
280 | - } else if (flowClassifier.protocol().equalsIgnoreCase("UDP")) { | ||
281 | - selector.add(Criteria.matchIPProtocol(IPv4.PROTOCOL_UDP)); | ||
282 | - } | ||
283 | - } else if (fiveTuple != null && fiveTuple.protocol() != 0) { | ||
284 | - selector.add(Criteria.matchIPProtocol(fiveTuple.protocol())); | ||
285 | - } | ||
286 | - | ||
287 | - if (((flowClassifier.etherType() != null) && (!flowClassifier.etherType().isEmpty())) | ||
288 | - && (flowClassifier.etherType().equals("IPv4") || flowClassifier.etherType().equals("IPv6"))) { | ||
289 | - if (flowClassifier.etherType().equals("IPv4")) { | ||
290 | - selector.matchEthType(Ethernet.TYPE_IPV4); | ||
291 | - } else { | ||
292 | - selector.matchEthType(Ethernet.TYPE_IPV6); | ||
293 | - } | ||
294 | - } | ||
295 | - | ||
296 | - if ((flowClassifier.srcPort() != null) && (!flowClassifier.srcPort().portId().isEmpty())) { | ||
297 | - VirtualPortId vPortId = VirtualPortId.portId(flowClassifier.srcPort().portId()); | ||
298 | - MacAddress macAddress = virtualPortService.getPort(vPortId).macAddress(); | ||
299 | - Host host = hostService.getHost(HostId.hostId(macAddress)); | ||
300 | - selector.matchInPort(host.location().port()); | ||
301 | - } | ||
302 | - | ||
303 | - // Take the port information from five tuple only when the protocol is TCP. | ||
304 | - if (fiveTuple != null && fiveTuple.protocol() == IPv4.PROTOCOL_TCP) { | ||
305 | - selector.matchTcpSrc(TpPort.tpPort((int) fiveTuple.portSrc().toLong())); | ||
306 | - selector.matchTcpDst(TpPort.tpPort((int) fiveTuple.portDst().toLong())); | ||
307 | - } else { | ||
308 | - // For udp packets take the port information from flow classifier | ||
309 | - List<TpPort> srcPortRange = new LinkedList<>(); | ||
310 | - List<TpPort> dstPortRange = new LinkedList<>(); | ||
311 | - if ((flowClassifier.minSrcPortRange() != 0) && flowClassifier.maxSrcPortRange() != 0 | ||
312 | - && flowClassifier.minDstPortRange() != 0 && flowClassifier.maxDstPortRange() != 0) { | ||
313 | - | ||
314 | - for (int port = flowClassifier.minSrcPortRange(); port <= flowClassifier.maxSrcPortRange(); port++) { | ||
315 | - srcPortRange.add(TpPort.tpPort(port)); | ||
316 | - } | ||
317 | - for (int port = flowClassifier.minDstPortRange(); port <= flowClassifier.maxDstPortRange(); port++) { | ||
318 | - dstPortRange.add(TpPort.tpPort(port)); | ||
319 | - } | ||
320 | - } | ||
321 | - | ||
322 | - for (TpPort inPort : srcPortRange) { | ||
323 | - selector.matchUdpSrc(inPort); | ||
324 | - } | ||
325 | - for (TpPort outPort : dstPortRange) { | ||
326 | - selector.matchUdpDst(outPort); | ||
327 | - } | ||
328 | - } | ||
329 | - return selector; | ||
330 | - } | ||
331 | - | ||
332 | - /** | ||
333 | - * Pack traffic treatment. | ||
334 | - * | ||
335 | - * @param deviceId device id | ||
336 | - * @param port port number | ||
337 | - * @param nshDstPort vxlan tunnel port for nsh header | ||
338 | - * @param nshSpi nsh spi | ||
339 | - * @param flowClassifier flow-classifier | ||
340 | - * @param isSameOvs whether the next service function is in same ovs | ||
341 | - * @return traffic treatment | ||
342 | - */ | ||
343 | - public TrafficTreatment.Builder packTrafficTreatment(DeviceId deviceId, PortNumber port, | ||
344 | - TpPort nshDstPort, NshServicePathId nshSpi, | ||
345 | - FlowClassifier flowClassifier, boolean isSameOvs) { | ||
346 | - | ||
347 | - TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder(); | ||
348 | - | ||
349 | - if (isSameOvs) { | ||
350 | - treatmentBuilder.setOutput(port); | ||
351 | - } else { | ||
352 | - treatmentBuilder.setVlanId((VlanId.vlanId(Short.parseShort((vtnRscService | ||
353 | - .getL3vni(flowClassifier.tenantId()).toString()))))); | ||
354 | - treatmentBuilder.setUdpDst(nshDstPort); | ||
355 | - } | ||
356 | - | ||
357 | - // Set NSH | ||
358 | - DriverHandler handler = driverService.createHandler(deviceId); | ||
359 | - ExtensionTreatmentResolver resolver = handler.behaviour(ExtensionTreatmentResolver.class); | ||
360 | - ExtensionTreatment nspIdTreatment = resolver.getExtensionInstruction(NICIRA_SET_NSH_SPI.type()); | ||
361 | - ExtensionTreatment nsiIdTreatment = resolver.getExtensionInstruction(NICIRA_SET_NSH_SI.type()); | ||
362 | - | ||
363 | - treatmentBuilder.extension(nspIdTreatment, deviceId); | ||
364 | - treatmentBuilder.extension(nsiIdTreatment, deviceId); | ||
365 | - | ||
366 | - try { | ||
367 | - nspIdTreatment.setPropertyValue("nshSpi", nshSpi); | ||
368 | - } catch (Exception e) { | ||
369 | - log.error("Failed to get extension instruction to set Nsh Spi Id {}", deviceId); | ||
370 | - } | ||
371 | - try { | ||
372 | - nsiIdTreatment.setPropertyValue("nshSi", NshServiceIndex.of(NSH_SI_ID)); | ||
373 | - } catch (Exception e) { | ||
374 | - log.error("Failed to get extension instruction to set Nsh Si Id {}", deviceId); | ||
375 | - } | ||
376 | - | ||
377 | - return treatmentBuilder; | ||
378 | - } | ||
379 | - | ||
380 | - /** | ||
381 | - * Send service-function-forwarder to OVS. | ||
382 | - * | ||
383 | - * @param selector traffic selector | ||
384 | - * @param treatment traffic treatment | ||
385 | - * @param deviceId device id | ||
386 | - * @param type operation type | ||
387 | - * @param priority priority of classifier | ||
388 | - */ | ||
389 | - public void sendServiceFunctionClassifier(TrafficSelector.Builder selector, TrafficTreatment.Builder treatment, | ||
390 | - DeviceId deviceId, Objective.Operation type, int priority) { | ||
391 | - log.info("Sending flow to service function classifier. Selector {}, Treatment {}", | ||
392 | - selector.toString(), treatment.toString()); | ||
393 | - ForwardingObjective.Builder objective = DefaultForwardingObjective.builder().withTreatment(treatment.build()) | ||
394 | - .withSelector(selector.build()).fromApp(appId).makePermanent().withFlag(Flag.VERSATILE) | ||
395 | - .withPriority(priority); | ||
396 | - | ||
397 | - if (type.equals(Objective.Operation.ADD)) { | ||
398 | - log.debug("flowClassifierRules-->ADD"); | ||
399 | - flowObjectiveService.forward(deviceId, objective.add()); | ||
400 | - } else { | ||
401 | - log.debug("flowClassifierRules-->REMOVE"); | ||
402 | - flowObjectiveService.forward(deviceId, objective.remove()); | ||
403 | - } | ||
404 | - } | ||
405 | -} |
apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/impl/SfcFlowRuleInstallerImpl.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2015-present 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.installer.impl; | ||
17 | + | ||
18 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
19 | +import static org.onosproject.net.flow.criteria.ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_ENCAP_ETH_TYPE; | ||
20 | +import static org.onosproject.net.flow.criteria.ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_SI; | ||
21 | +import static org.onosproject.net.flow.criteria.ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_SPI; | ||
22 | +import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_DST; | ||
23 | +import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_SRC; | ||
24 | +import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_MDTYPE; | ||
25 | +import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_NP; | ||
26 | +import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_POP_NSH; | ||
27 | +import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_PUSH_NSH; | ||
28 | +import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_RESUBMIT_TABLE; | ||
29 | +import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH1; | ||
30 | +import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH2; | ||
31 | +import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH3; | ||
32 | +import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH4; | ||
33 | +import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SI; | ||
34 | +import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SPI; | ||
35 | +import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST; | ||
36 | +import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_TUN_GPE_NP; | ||
37 | +import static org.slf4j.LoggerFactory.getLogger; | ||
38 | + | ||
39 | +import java.util.LinkedList; | ||
40 | +import java.util.List; | ||
41 | +import java.util.ListIterator; | ||
42 | +import java.util.Set; | ||
43 | + | ||
44 | +import org.onlab.osgi.DefaultServiceDirectory; | ||
45 | +import org.onlab.osgi.ServiceDirectory; | ||
46 | +import org.onlab.packet.Ethernet; | ||
47 | +import org.onlab.packet.IPv4; | ||
48 | +import org.onlab.packet.Ip4Address; | ||
49 | +import org.onlab.packet.IpPrefix; | ||
50 | +import org.onlab.packet.MacAddress; | ||
51 | +import org.onlab.packet.TpPort; | ||
52 | +import org.onosproject.core.ApplicationId; | ||
53 | +import org.onosproject.net.AnnotationKeys; | ||
54 | +import org.onosproject.net.ConnectPoint; | ||
55 | +import org.onosproject.net.Device; | ||
56 | +import org.onosproject.net.DeviceId; | ||
57 | +import org.onosproject.net.Host; | ||
58 | +import org.onosproject.net.HostId; | ||
59 | +import org.onosproject.net.NshContextHeader; | ||
60 | +import org.onosproject.net.NshServiceIndex; | ||
61 | +import org.onosproject.net.NshServicePathId; | ||
62 | +import org.onosproject.net.Port; | ||
63 | +import org.onosproject.net.PortNumber; | ||
64 | +import org.onosproject.net.behaviour.BridgeConfig; | ||
65 | +import org.onosproject.net.behaviour.ExtensionSelectorResolver; | ||
66 | +import org.onosproject.net.behaviour.ExtensionTreatmentResolver; | ||
67 | +import org.onosproject.net.device.DeviceService; | ||
68 | +import org.onosproject.net.driver.DriverHandler; | ||
69 | +import org.onosproject.net.driver.DriverService; | ||
70 | +import org.onosproject.net.flow.DefaultTrafficSelector; | ||
71 | +import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
72 | +import org.onosproject.net.flow.TrafficSelector; | ||
73 | +import org.onosproject.net.flow.TrafficTreatment; | ||
74 | +import org.onosproject.net.flow.criteria.Criteria; | ||
75 | +import org.onosproject.net.flow.criteria.ExtensionSelector; | ||
76 | +import org.onosproject.net.flow.instructions.ExtensionTreatment; | ||
77 | +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; | ||
78 | +import org.onosproject.net.flow.instructions.Instructions; | ||
79 | +import org.onosproject.net.flowobjective.DefaultForwardingObjective; | ||
80 | +import org.onosproject.net.flowobjective.FlowObjectiveService; | ||
81 | +import org.onosproject.net.flowobjective.ForwardingObjective; | ||
82 | +import org.onosproject.net.flowobjective.ForwardingObjective.Flag; | ||
83 | +import org.onosproject.net.flowobjective.Objective; | ||
84 | +import org.onosproject.net.host.HostService; | ||
85 | +import org.onosproject.sfc.installer.SfcFlowRuleInstallerService; | ||
86 | +import org.onosproject.vtnrsc.FiveTuple; | ||
87 | +import org.onosproject.vtnrsc.FlowClassifier; | ||
88 | +import org.onosproject.vtnrsc.FlowClassifierId; | ||
89 | +import org.onosproject.vtnrsc.PortChain; | ||
90 | +import org.onosproject.vtnrsc.PortPair; | ||
91 | +import org.onosproject.vtnrsc.PortPairGroup; | ||
92 | +import org.onosproject.vtnrsc.PortPairGroupId; | ||
93 | +import org.onosproject.vtnrsc.PortPairId; | ||
94 | +import org.onosproject.vtnrsc.SegmentationId; | ||
95 | +import org.onosproject.vtnrsc.VirtualPort; | ||
96 | +import org.onosproject.vtnrsc.VirtualPortId; | ||
97 | +import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService; | ||
98 | +import org.onosproject.vtnrsc.portpair.PortPairService; | ||
99 | +import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService; | ||
100 | +import org.onosproject.vtnrsc.service.VtnRscService; | ||
101 | +import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService; | ||
102 | +import org.onosproject.vtnrsc.virtualport.VirtualPortService; | ||
103 | +import org.slf4j.Logger; | ||
104 | + | ||
105 | +import com.google.common.collect.Lists; | ||
106 | +import com.google.common.collect.Sets; | ||
107 | + | ||
108 | +/** | ||
109 | + * Provides flow classifier installer implementation. | ||
110 | + */ | ||
111 | +public class SfcFlowRuleInstallerImpl implements SfcFlowRuleInstallerService { | ||
112 | + private final Logger log = getLogger(getClass()); | ||
113 | + | ||
114 | + protected VirtualPortService virtualPortService; | ||
115 | + protected VtnRscService vtnRscService; | ||
116 | + protected PortPairService portPairService; | ||
117 | + protected PortPairGroupService portPairGroupService; | ||
118 | + protected FlowClassifierService flowClassifierService; | ||
119 | + protected DriverService driverService; | ||
120 | + protected DeviceService deviceService; | ||
121 | + protected HostService hostService; | ||
122 | + protected TenantNetworkService tenantNetworkService; | ||
123 | + protected FlowObjectiveService flowObjectiveService; | ||
124 | + protected ApplicationId appId; | ||
125 | + | ||
126 | + private static final String PORT_CHAIN_NOT_NULL = "Port-Chain cannot be null"; | ||
127 | + private static final int FLOW_CLASSIFIER_PRIORITY = 0xC738; | ||
128 | + private static final int DEFAULT_FORWARDER_PRIORITY = 0xD6D8; | ||
129 | + private static final int ENCAP_OUTPUT_PRIORITY = 0x64; | ||
130 | + private static final int TUNNEL_SEND_PRIORITY = 0xC8; | ||
131 | + private static final String SWITCH_CHANNEL_ID = "channelId"; | ||
132 | + private static final int ENCAP_OUTPUT_TABLE = 4; | ||
133 | + private static final int TUNNEL_SEND_TABLE = 7; | ||
134 | + private static final short ENCAP_ETH_TYPE = (short) 0x894f; | ||
135 | + private static final String DEFAULT_IP = "0.0.0.0"; | ||
136 | + private static final String VXLANPORT_HEAD = "vxlan-0.0.0.0"; | ||
137 | + | ||
138 | + /* Port chain params */ | ||
139 | + private short nshSi; | ||
140 | + List<DeviceId> classifierList; | ||
141 | + List<DeviceId> forwarderList; | ||
142 | + | ||
143 | + /** | ||
144 | + * Default constructor. | ||
145 | + */ | ||
146 | + public SfcFlowRuleInstallerImpl() { | ||
147 | + } | ||
148 | + | ||
149 | + /** | ||
150 | + * Explicit constructor. | ||
151 | + * | ||
152 | + * @param appId application id. | ||
153 | + */ | ||
154 | + public SfcFlowRuleInstallerImpl(ApplicationId appId) { | ||
155 | + this.appId = checkNotNull(appId, "ApplicationId can not be null"); | ||
156 | + ServiceDirectory serviceDirectory = new DefaultServiceDirectory(); | ||
157 | + this.flowObjectiveService = serviceDirectory.get(FlowObjectiveService.class); | ||
158 | + this.driverService = serviceDirectory.get(DriverService.class); | ||
159 | + this.deviceService = serviceDirectory.get(DeviceService.class); | ||
160 | + this.hostService = serviceDirectory.get(HostService.class); | ||
161 | + this.virtualPortService = serviceDirectory.get(VirtualPortService.class); | ||
162 | + this.vtnRscService = serviceDirectory.get(VtnRscService.class); | ||
163 | + this.portPairService = serviceDirectory.get(PortPairService.class); | ||
164 | + this.portPairGroupService = serviceDirectory.get(PortPairGroupService.class); | ||
165 | + this.flowClassifierService = serviceDirectory.get(FlowClassifierService.class); | ||
166 | + this.tenantNetworkService = serviceDirectory.get(TenantNetworkService.class); | ||
167 | + nshSi = 0xff; | ||
168 | + } | ||
169 | + | ||
170 | + @Override | ||
171 | + public ConnectPoint installFlowClassifier(PortChain portChain, NshServicePathId nshSpiId) { | ||
172 | + checkNotNull(portChain, PORT_CHAIN_NOT_NULL); | ||
173 | + // Get the portPairGroup | ||
174 | + List<PortPairGroupId> llPortPairGroupIdList = portChain.portPairGroups(); | ||
175 | + ListIterator<PortPairGroupId> portPairGroupIdListIterator = llPortPairGroupIdList.listIterator(); | ||
176 | + PortPairGroupId portPairGroupId = portPairGroupIdListIterator.next(); | ||
177 | + PortPairGroup portPairGroup = portPairGroupService.getPortPairGroup(portPairGroupId); | ||
178 | + List<PortPairId> llPortPairIdList = portPairGroup.portPairs(); | ||
179 | + | ||
180 | + // Get port pair | ||
181 | + ListIterator<PortPairId> portPairListIterator = llPortPairIdList.listIterator(); | ||
182 | + PortPairId portPairId = portPairListIterator.next(); | ||
183 | + PortPair portPair = portPairService.getPortPair(portPairId); | ||
184 | + | ||
185 | + return installSfcClassifierRules(portChain, portPair, nshSpiId, null, Objective.Operation.ADD); | ||
186 | + } | ||
187 | + | ||
188 | + @Override | ||
189 | + public ConnectPoint unInstallFlowClassifier(PortChain portChain, NshServicePathId nshSpiId) { | ||
190 | + checkNotNull(portChain, PORT_CHAIN_NOT_NULL); | ||
191 | + // Get the portPairGroup | ||
192 | + List<PortPairGroupId> llPortPairGroupIdList = portChain.portPairGroups(); | ||
193 | + ListIterator<PortPairGroupId> portPairGroupIdListIterator = llPortPairGroupIdList.listIterator(); | ||
194 | + PortPairGroupId portPairGroupId = portPairGroupIdListIterator.next(); | ||
195 | + PortPairGroup portPairGroup = portPairGroupService.getPortPairGroup(portPairGroupId); | ||
196 | + List<PortPairId> llPortPairIdList = portPairGroup.portPairs(); | ||
197 | + | ||
198 | + // Get port pair | ||
199 | + ListIterator<PortPairId> portPairListIterator = llPortPairIdList.listIterator(); | ||
200 | + PortPairId portPairId = portPairListIterator.next(); | ||
201 | + PortPair portPair = portPairService.getPortPair(portPairId); | ||
202 | + | ||
203 | + return installSfcClassifierRules(portChain, portPair, nshSpiId, null, Objective.Operation.REMOVE); | ||
204 | + } | ||
205 | + | ||
206 | + @Override | ||
207 | + public ConnectPoint installLoadBalancedFlowRules(PortChain portChain, FiveTuple fiveTuple, | ||
208 | + NshServicePathId nshSpiId) { | ||
209 | + checkNotNull(portChain, PORT_CHAIN_NOT_NULL); | ||
210 | + | ||
211 | + return installSfcFlowRules(portChain, fiveTuple, nshSpiId, Objective.Operation.ADD); | ||
212 | + } | ||
213 | + | ||
214 | + @Override | ||
215 | + public ConnectPoint unInstallLoadBalancedFlowRules(PortChain portChain, FiveTuple fiveTuple, | ||
216 | + NshServicePathId nshSpiId) { | ||
217 | + checkNotNull(portChain, PORT_CHAIN_NOT_NULL); | ||
218 | + return installSfcFlowRules(portChain, fiveTuple, nshSpiId, Objective.Operation.REMOVE); | ||
219 | + } | ||
220 | + | ||
221 | + public ConnectPoint installSfcFlowRules(PortChain portChain, FiveTuple fiveTuple, NshServicePathId nshSpiId, | ||
222 | + Objective.Operation type) { | ||
223 | + checkNotNull(portChain, PORT_CHAIN_NOT_NULL); | ||
224 | + | ||
225 | + classifierList = Lists.newArrayList(); | ||
226 | + forwarderList = Lists.newArrayList(); | ||
227 | + | ||
228 | + // Get the load balanced path | ||
229 | + List<PortPairId> portPairs = portChain.getLoadBalancePath(fiveTuple); | ||
230 | + | ||
231 | + // Get the first port pair | ||
232 | + ListIterator<PortPairId> portPairListIterator = portPairs.listIterator(); | ||
233 | + PortPairId portPairId = portPairListIterator.next(); | ||
234 | + PortPair currentPortPair = portPairService.getPortPair(portPairId); | ||
235 | + | ||
236 | + ConnectPoint connectPoint = installSfcClassifierRules(portChain, currentPortPair, nshSpiId, fiveTuple, type); | ||
237 | + | ||
238 | + log.info("Installing encap and output for first port pair"); | ||
239 | + | ||
240 | + installSfcEncapOutputRule(currentPortPair, nshSpiId, type); | ||
241 | + | ||
242 | + PortPair nextPortPair; | ||
243 | + while (portPairListIterator.hasNext()) { | ||
244 | + portPairId = portPairListIterator.next(); | ||
245 | + nextPortPair = portPairService.getPortPair(portPairId); | ||
246 | + installSfcForwardRule(currentPortPair, nextPortPair, nshSpiId, type); | ||
247 | + installSfcEncapOutputRule(nextPortPair, nshSpiId, type); | ||
248 | + currentPortPair = nextPortPair; | ||
249 | + } | ||
250 | + installSfcEndRule(currentPortPair, nshSpiId, type); | ||
251 | + | ||
252 | + if (type.equals(Objective.Operation.ADD)) { | ||
253 | + portChain.addSfcClassifiers(portChain.getLoadBalanceId(fiveTuple), classifierList); | ||
254 | + portChain.addSfcForwarders(portChain.getLoadBalanceId(fiveTuple), forwarderList); | ||
255 | + } else { | ||
256 | + portChain.removeSfcClassifiers(portChain.getLoadBalanceId(fiveTuple), classifierList); | ||
257 | + portChain.removeSfcForwarders(portChain.getLoadBalanceId(fiveTuple), forwarderList); | ||
258 | + } | ||
259 | + return connectPoint; | ||
260 | + } | ||
261 | + | ||
262 | + public void installSfcTunnelReceiveRule(DeviceId deviceId, NshServicePathId nshSpiId, Objective.Operation type) { | ||
263 | + | ||
264 | + DriverHandler handler = driverService.createHandler(deviceId); | ||
265 | + ExtensionSelectorResolver selectorResolver = handler.behaviour(ExtensionSelectorResolver.class); | ||
266 | + ExtensionSelector nshSpiSelector = selectorResolver.getExtensionSelector(NICIRA_MATCH_NSH_SPI.type()); | ||
267 | + ExtensionSelector nshSiSelector = selectorResolver.getExtensionSelector(NICIRA_MATCH_NSH_SI.type()); | ||
268 | + | ||
269 | + try { | ||
270 | + nshSpiSelector.setPropertyValue("nshSpi", nshSpiId); | ||
271 | + } catch (Exception e) { | ||
272 | + log.error("Failed to set extension selector to match Nsh Spi Id for end rule {}", e.getMessage()); | ||
273 | + } | ||
274 | + try { | ||
275 | + nshSiSelector.setPropertyValue("nshSi", NshServiceIndex.of(nshSi)); | ||
276 | + } catch (Exception e) { | ||
277 | + log.error("Failed to set extension selector to match Nsh Si Id for end rule {}", e.getMessage()); | ||
278 | + } | ||
279 | + | ||
280 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
281 | + selector.extension(nshSpiSelector, deviceId); | ||
282 | + selector.extension(nshSiSelector, deviceId); | ||
283 | + | ||
284 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
285 | + treatment.transition(ENCAP_OUTPUT_TABLE); | ||
286 | + | ||
287 | + sendSfcRule(selector, treatment, deviceId, type, DEFAULT_FORWARDER_PRIORITY); | ||
288 | + } | ||
289 | + | ||
290 | + public void installSfcTunnelSendRule(DeviceId deviceId, NshServicePathId nshSpiId, Objective.Operation type) { | ||
291 | + | ||
292 | + // Prepare selector with nsp, nsi and inport from egress of port pair | ||
293 | + DriverHandler handler = driverService.createHandler(deviceId); | ||
294 | + ExtensionSelectorResolver selectorResolver = handler.behaviour(ExtensionSelectorResolver.class); | ||
295 | + ExtensionSelector nshSpiSelector = selectorResolver.getExtensionSelector(NICIRA_MATCH_NSH_SPI.type()); | ||
296 | + ExtensionSelector nshSiSelector = selectorResolver.getExtensionSelector(NICIRA_MATCH_NSH_SI.type()); | ||
297 | + ExtensionSelector encapEthTypeSelector = selectorResolver.getExtensionSelector(NICIRA_MATCH_ENCAP_ETH_TYPE | ||
298 | + .type()); | ||
299 | + try { | ||
300 | + nshSpiSelector.setPropertyValue("nshSpi", nshSpiId); | ||
301 | + } catch (Exception e) { | ||
302 | + log.error("Failed to set extension selector to match Nsh Spi Id for end rule {}", e.getMessage()); | ||
303 | + } | ||
304 | + try { | ||
305 | + nshSiSelector.setPropertyValue("nshSi", NshServiceIndex.of(nshSi)); | ||
306 | + } catch (Exception e) { | ||
307 | + log.error("Failed to set extension selector to match Nsh Si Id for end rule {}", e.getMessage()); | ||
308 | + } | ||
309 | + try { | ||
310 | + encapEthTypeSelector.setPropertyValue("encapEthType", ENCAP_ETH_TYPE); | ||
311 | + } catch (Exception e) { | ||
312 | + log.error("Failed to set extension selector to match encapEthType {}", deviceId); | ||
313 | + } | ||
314 | + | ||
315 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
316 | + selector.extension(nshSpiSelector, deviceId); | ||
317 | + selector.extension(nshSiSelector, deviceId); | ||
318 | + // selector.extension(encapEthTypeSelector, deviceId); | ||
319 | + | ||
320 | + ExtensionTreatmentResolver treatmentResolver = handler.behaviour(ExtensionTreatmentResolver.class); | ||
321 | + ExtensionTreatment tunGpeNpTreatment = treatmentResolver.getExtensionInstruction(NICIRA_TUN_GPE_NP.type()); | ||
322 | + try { | ||
323 | + tunGpeNpTreatment.setPropertyValue("tunGpeNp", ((byte) 4)); | ||
324 | + } catch (Exception e) { | ||
325 | + log.error("Failed to get extension instruction to set tunGpeNp {}", deviceId); | ||
326 | + } | ||
327 | + | ||
328 | + ExtensionTreatment moveC1ToC1 = treatmentResolver | ||
329 | + .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes | ||
330 | + .NICIRA_MOV_NSH_C1_TO_C1.type()); | ||
331 | + | ||
332 | + ExtensionTreatment moveC2ToC2 = treatmentResolver | ||
333 | + .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes | ||
334 | + .NICIRA_MOV_NSH_C2_TO_C2.type()); | ||
335 | + | ||
336 | + ExtensionTreatment moveC3ToC3 = treatmentResolver | ||
337 | + .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes | ||
338 | + .NICIRA_MOV_NSH_C3_TO_C3.type()); | ||
339 | + | ||
340 | + ExtensionTreatment moveC4ToC4 = treatmentResolver | ||
341 | + .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes | ||
342 | + .NICIRA_MOV_NSH_C4_TO_C4.type()); | ||
343 | + | ||
344 | + ExtensionTreatment moveTunIpv4DstToTunIpv4Dst = treatmentResolver | ||
345 | + .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes | ||
346 | + .NICIRA_MOV_TUN_IPV4_DST_TO_TUN_IPV4_DST.type()); | ||
347 | + | ||
348 | + ExtensionTreatment moveTunIdToTunId = treatmentResolver | ||
349 | + .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes | ||
350 | + .NICIRA_MOV_TUN_ID_TO_TUN_ID.type()); | ||
351 | + | ||
352 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
353 | + treatment.extension(tunGpeNpTreatment, deviceId); | ||
354 | + treatment.extension(moveC1ToC1, deviceId); | ||
355 | + treatment.extension(moveC2ToC2, deviceId); | ||
356 | + treatment.extension(moveC3ToC3, deviceId); | ||
357 | + treatment.extension(moveC4ToC4, deviceId); | ||
358 | + treatment.extension(moveTunIpv4DstToTunIpv4Dst, deviceId); | ||
359 | + treatment.extension(moveTunIdToTunId, deviceId); | ||
360 | + | ||
361 | + Iterable<Device> devices = deviceService.getAvailableDevices(); | ||
362 | + DeviceId localControllerId = getControllerId(deviceService.getDevice(deviceId), devices); | ||
363 | + DriverHandler controllerHandler = driverService.createHandler(localControllerId); | ||
364 | + | ||
365 | + BridgeConfig bridgeConfig = controllerHandler.behaviour(BridgeConfig.class); | ||
366 | + Set<PortNumber> ports = bridgeConfig.getPortNumbers(); | ||
367 | + String tunnelName = "vxlan-" + DEFAULT_IP; | ||
368 | + ports.stream() | ||
369 | + .filter(p ->p.name().equalsIgnoreCase(tunnelName)) | ||
370 | + .forEach(p -> { | ||
371 | + treatment.setOutput(p); | ||
372 | + sendSfcRule(selector, treatment, deviceId, type, TUNNEL_SEND_PRIORITY); | ||
373 | + }); | ||
374 | + } | ||
375 | + | ||
376 | + public void installSfcEndRule(PortPair portPair, NshServicePathId nshSpiId, Objective.Operation type) { | ||
377 | + DeviceId deviceId = vtnRscService.getSfToSffMaping(VirtualPortId.portId(portPair.egress())); | ||
378 | + MacAddress srcMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.egress())).macAddress(); | ||
379 | + Host host = hostService.getHost(HostId.hostId(srcMacAddress)); | ||
380 | + PortNumber port = host.location().port(); | ||
381 | + | ||
382 | + // Prepare selector with nsp, nsi and inport from egress of port pair | ||
383 | + DriverHandler handler = driverService.createHandler(deviceId); | ||
384 | + ExtensionSelectorResolver selectorResolver = handler.behaviour(ExtensionSelectorResolver.class); | ||
385 | + ExtensionSelector nshSpiSelector = selectorResolver.getExtensionSelector(NICIRA_MATCH_NSH_SPI.type()); | ||
386 | + ExtensionSelector nshSiSelector = selectorResolver.getExtensionSelector(NICIRA_MATCH_NSH_SI.type()); | ||
387 | + ExtensionSelector encapEthTypeSelector = selectorResolver.getExtensionSelector(NICIRA_MATCH_ENCAP_ETH_TYPE | ||
388 | + .type()); | ||
389 | + try { | ||
390 | + nshSpiSelector.setPropertyValue("nshSpi", nshSpiId); | ||
391 | + } catch (Exception e) { | ||
392 | + log.error("Failed to set extension selector to match Nsh Spi Id for end rule {}", e.getMessage()); | ||
393 | + } | ||
394 | + // Decrement the SI | ||
395 | + nshSi = (short) (nshSi - 1); | ||
396 | + try { | ||
397 | + nshSiSelector.setPropertyValue("nshSi", NshServiceIndex.of(nshSi)); | ||
398 | + } catch (Exception e) { | ||
399 | + log.error("Failed to set extension selector to match Nsh Si Id for end rule {}", e.getMessage()); | ||
400 | + } | ||
401 | + try { | ||
402 | + encapEthTypeSelector.setPropertyValue("encapEthType", ENCAP_ETH_TYPE); | ||
403 | + } catch (Exception e) { | ||
404 | + log.error("Failed to set extension selector to match encapEthType {}", deviceId); | ||
405 | + } | ||
406 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
407 | + selector.extension(encapEthTypeSelector, deviceId); | ||
408 | + selector.extension(nshSpiSelector, deviceId); | ||
409 | + selector.extension(nshSiSelector, deviceId); | ||
410 | + selector.matchInPort(port); | ||
411 | + | ||
412 | + // Set treatment to pop nsh header, set tunnel id and resubmit to table | ||
413 | + // 0. | ||
414 | + ExtensionTreatmentResolver treatmentResolver = handler.behaviour(ExtensionTreatmentResolver.class); | ||
415 | + ExtensionTreatment popNshTreatment = treatmentResolver.getExtensionInstruction(NICIRA_POP_NSH.type()); | ||
416 | + | ||
417 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
418 | + treatment.extension(popNshTreatment, deviceId); | ||
419 | + | ||
420 | + VirtualPort virtualPort = virtualPortService.getPort(VirtualPortId.portId(portPair.ingress())); | ||
421 | + SegmentationId segmentationId = tenantNetworkService.getNetwork(virtualPort.networkId()).segmentationId(); | ||
422 | + treatment.add(Instructions.modTunnelId(Long.parseLong(segmentationId.toString()))); | ||
423 | + | ||
424 | + ExtensionTreatment resubmitTableTreatment = treatmentResolver.getExtensionInstruction(NICIRA_RESUBMIT_TABLE | ||
425 | + .type()); | ||
426 | + | ||
427 | + PortNumber vxlanPortNumber = getVxlanPortNumber(deviceId); | ||
428 | + | ||
429 | + try { | ||
430 | + resubmitTableTreatment.setPropertyValue("inPort", vxlanPortNumber); | ||
431 | + } catch (Exception e) { | ||
432 | + log.error("Failed to set extension treatment for resubmit table in port {}", deviceId); | ||
433 | + } | ||
434 | + try { | ||
435 | + resubmitTableTreatment.setPropertyValue("table", ((short) 0)); | ||
436 | + } catch (Exception e) { | ||
437 | + log.error("Failed to set extension treatment for resubmit table {}", deviceId); | ||
438 | + } | ||
439 | + treatment.extension(resubmitTableTreatment, deviceId); | ||
440 | + | ||
441 | + sendSfcRule(selector, treatment, deviceId, type, DEFAULT_FORWARDER_PRIORITY); | ||
442 | + } | ||
443 | + | ||
444 | + public void installSfcForwardRule(PortPair portPair, PortPair nextPortPair, NshServicePathId nshSpiId, | ||
445 | + Objective.Operation type) { | ||
446 | + DeviceId deviceId = vtnRscService.getSfToSffMaping(VirtualPortId.portId(portPair.egress())); | ||
447 | + MacAddress srcMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.egress())).macAddress(); | ||
448 | + Host host = hostService.getHost(HostId.hostId(srcMacAddress)); | ||
449 | + PortNumber port = host.location().port(); | ||
450 | + | ||
451 | + DriverHandler handler = driverService.createHandler(deviceId); | ||
452 | + ExtensionSelectorResolver resolver = handler.behaviour(ExtensionSelectorResolver.class); | ||
453 | + | ||
454 | + // Prepare selector with nsp, nsi and inport from egress of port pair | ||
455 | + ExtensionSelector nshSpiSelector = resolver.getExtensionSelector(NICIRA_MATCH_NSH_SPI.type()); | ||
456 | + ExtensionSelector nshSiSelector = resolver.getExtensionSelector(NICIRA_MATCH_NSH_SI.type()); | ||
457 | + try { | ||
458 | + nshSpiSelector.setPropertyValue("nshSpi", nshSpiId); | ||
459 | + } catch (Exception e) { | ||
460 | + log.error("Failed to set extension selector to match Nsh Spi Id for forward rule {}", e.getMessage()); | ||
461 | + } | ||
462 | + // Decrement the SI | ||
463 | + nshSi = (short) (nshSi - 1); | ||
464 | + try { | ||
465 | + nshSiSelector.setPropertyValue("nshSi", NshServiceIndex.of(nshSi)); | ||
466 | + } catch (Exception e) { | ||
467 | + log.error("Failed to set extension selector to match Nsh Si Id for forward rule {}", e.getMessage()); | ||
468 | + } | ||
469 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
470 | + selector.extension(nshSpiSelector, deviceId); | ||
471 | + selector.extension(nshSiSelector, deviceId); | ||
472 | + selector.matchInPort(port); | ||
473 | + | ||
474 | + DeviceId nextDeviceId = vtnRscService.getSfToSffMaping(VirtualPortId.portId(nextPortPair.ingress())); | ||
475 | + if (deviceId.equals(nextDeviceId)) { | ||
476 | + | ||
477 | + // Treatment with transition | ||
478 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
479 | + treatment.transition(ENCAP_OUTPUT_TABLE); | ||
480 | + | ||
481 | + sendSfcRule(selector, treatment, deviceId, type, DEFAULT_FORWARDER_PRIORITY); | ||
482 | + } else { | ||
483 | + // Treatment with with transition to send on tunnel | ||
484 | + ExtensionTreatmentResolver treatmentResolver = handler.behaviour(ExtensionTreatmentResolver.class); | ||
485 | + ExtensionTreatment moveC2ToTunId = treatmentResolver | ||
486 | + .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes | ||
487 | + .NICIRA_MOV_NSH_C2_TO_TUN_ID.type()); | ||
488 | + | ||
489 | + Device remoteDevice = deviceService.getDevice(nextDeviceId); | ||
490 | + String url = remoteDevice.annotations().value(SWITCH_CHANNEL_ID); | ||
491 | + String remoteControllerIp = url.substring(0, url.lastIndexOf(":")); | ||
492 | + if (remoteControllerIp == null) { | ||
493 | + log.error("Can't find remote controller of device: {}", nextDeviceId.toString()); | ||
494 | + return; | ||
495 | + } | ||
496 | + | ||
497 | + ExtensionTreatment tunnelDsttreatment = treatmentResolver.getExtensionInstruction(NICIRA_SET_TUNNEL_DST | ||
498 | + .type()); | ||
499 | + try { | ||
500 | + tunnelDsttreatment.setPropertyValue("tunnelDst", Ip4Address.valueOf(remoteControllerIp)); | ||
501 | + } catch (Exception e) { | ||
502 | + log.error("Failed to get extension instruction to set tunnel dst {}", deviceId); | ||
503 | + } | ||
504 | + | ||
505 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
506 | + treatment.extension(moveC2ToTunId, deviceId); | ||
507 | + treatment.extension(tunnelDsttreatment, deviceId); | ||
508 | + treatment.transition(TUNNEL_SEND_TABLE); | ||
509 | + | ||
510 | + sendSfcRule(selector, treatment, deviceId, type, DEFAULT_FORWARDER_PRIORITY); | ||
511 | + | ||
512 | + installSfcTunnelSendRule(deviceId, nshSpiId, type); | ||
513 | + installSfcTunnelReceiveRule(nextDeviceId, nshSpiId, type); | ||
514 | + } | ||
515 | + } | ||
516 | + | ||
517 | + public void installSfcEncapOutputRule(PortPair portPair, NshServicePathId nshSpiId, Objective.Operation type) { | ||
518 | + | ||
519 | + DeviceId deviceId = vtnRscService.getSfToSffMaping(VirtualPortId.portId(portPair.ingress())); | ||
520 | + MacAddress srcMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.ingress())).macAddress(); | ||
521 | + Host host = hostService.getHost(HostId.hostId(srcMacAddress)); | ||
522 | + PortNumber port = host.location().port(); | ||
523 | + | ||
524 | + DriverHandler handler = driverService.createHandler(deviceId); | ||
525 | + ExtensionSelectorResolver resolver = handler.behaviour(ExtensionSelectorResolver.class); | ||
526 | + | ||
527 | + // Prepare selector with nsp, nsi and encap eth type | ||
528 | + ExtensionSelector nshSpiSelector = resolver.getExtensionSelector(NICIRA_MATCH_NSH_SPI.type()); | ||
529 | + ExtensionSelector nshSiSelector = resolver.getExtensionSelector(NICIRA_MATCH_NSH_SI.type()); | ||
530 | + ExtensionSelector nshEncapEthTypeSelector = resolver.getExtensionSelector(NICIRA_MATCH_ENCAP_ETH_TYPE.type()); | ||
531 | + | ||
532 | + try { | ||
533 | + nshSpiSelector.setPropertyValue("nshSpi", nshSpiId); | ||
534 | + } catch (Exception e) { | ||
535 | + log.error("Failed to set extension selector to match Nsh Spi Id for encap rule {}", e.getMessage()); | ||
536 | + } | ||
537 | + try { | ||
538 | + nshSiSelector.setPropertyValue("nshSi", NshServiceIndex.of(nshSi)); | ||
539 | + } catch (Exception e) { | ||
540 | + log.error("Failed to set extension selector to match Nsh Si Id for encap rule {}", e.getMessage()); | ||
541 | + } | ||
542 | + try { | ||
543 | + nshEncapEthTypeSelector.setPropertyValue("encapEthType", ENCAP_ETH_TYPE); | ||
544 | + } catch (Exception e) { | ||
545 | + log.error("Failed to set extension selector to match Nsh Si Id {}", deviceId); | ||
546 | + } | ||
547 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
548 | + selector.extension(nshSpiSelector, deviceId); | ||
549 | + selector.extension(nshSiSelector, deviceId); | ||
550 | + | ||
551 | + ExtensionTreatmentResolver treatmentResolver = handler.behaviour(ExtensionTreatmentResolver.class); | ||
552 | + ExtensionTreatment encapEthSrcTreatment = treatmentResolver | ||
553 | + .getExtensionInstruction(NICIRA_ENCAP_ETH_SRC.type()); | ||
554 | + ExtensionTreatment encapEthDstTreatment = treatmentResolver | ||
555 | + .getExtensionInstruction(NICIRA_ENCAP_ETH_DST.type()); | ||
556 | + | ||
557 | + try { | ||
558 | + encapEthDstTreatment.setPropertyValue("encapEthDst", srcMacAddress); | ||
559 | + } catch (Exception e) { | ||
560 | + log.error("Failed to set extension treatment to set encap eth dst {}", deviceId); | ||
561 | + } | ||
562 | + // TODO: move from packet source mac address | ||
563 | + try { | ||
564 | + encapEthSrcTreatment.setPropertyValue("encapEthSrc", srcMacAddress); | ||
565 | + } catch (Exception e) { | ||
566 | + log.error("Failed to set extension treatment to set encap eth src {}", deviceId); | ||
567 | + } | ||
568 | + | ||
569 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
570 | + treatment.extension(encapEthSrcTreatment, deviceId); | ||
571 | + treatment.extension(encapEthDstTreatment, deviceId); | ||
572 | + treatment.setOutput(port); | ||
573 | + | ||
574 | + sendSfcRule(selector, treatment, deviceId, type, ENCAP_OUTPUT_PRIORITY); | ||
575 | + forwarderList.add(deviceId); | ||
576 | + } | ||
577 | + | ||
578 | + public ConnectPoint installSfcClassifierRules(PortChain portChain, PortPair portPair, NshServicePathId nshSpiId, | ||
579 | + FiveTuple fiveTuple, Objective.Operation type) { | ||
580 | + | ||
581 | + DeviceId deviceIdfromPortPair = vtnRscService.getSfToSffMaping(VirtualPortId.portId(portPair.ingress())); | ||
582 | + MacAddress srcMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.ingress())).macAddress(); | ||
583 | + VirtualPort virtualPort = virtualPortService.getPort(VirtualPortId.portId(portPair.ingress())); | ||
584 | + Host host = hostService.getHost(HostId.hostId(srcMacAddress)); | ||
585 | + PortNumber port = host.location().port(); | ||
586 | + | ||
587 | + DeviceId deviceId = deviceIdfromPortPair; | ||
588 | + | ||
589 | + // get flow classifiers | ||
590 | + List<FlowClassifierId> llFlowClassifierList = portChain.flowClassifiers(); | ||
591 | + ListIterator<FlowClassifierId> flowClassifierListIterator = llFlowClassifierList.listIterator(); | ||
592 | + | ||
593 | + while (flowClassifierListIterator.hasNext()) { | ||
594 | + FlowClassifierId flowclassifierId = flowClassifierListIterator.next(); | ||
595 | + FlowClassifier flowClassifier = flowClassifierService.getFlowClassifier(flowclassifierId); | ||
596 | + | ||
597 | + if ((flowClassifier.srcPort() != null) && (!flowClassifier.srcPort().portId().isEmpty())) { | ||
598 | + deviceId = vtnRscService.getSfToSffMaping(flowClassifier.srcPort()); | ||
599 | + } | ||
600 | + | ||
601 | + // Build Traffic selector. | ||
602 | + TrafficSelector.Builder selector = packClassifierSelector(flowClassifier, fiveTuple); | ||
603 | + | ||
604 | + if (fiveTuple == null) { | ||
605 | + // Send the packet to controller | ||
606 | + log.info("Downloading rule to send packet to controller"); | ||
607 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
608 | + treatment.setOutput(PortNumber.CONTROLLER); | ||
609 | + sendSfcRule(selector, treatment, deviceId, type, FLOW_CLASSIFIER_PRIORITY); | ||
610 | + continue; | ||
611 | + } | ||
612 | + | ||
613 | + if (deviceId != null && !deviceId.equals(deviceIdfromPortPair)) { | ||
614 | + // First SF is in another device. Set tunnel ipv4 destination to | ||
615 | + // treatment | ||
616 | + Device remoteDevice = deviceService.getDevice(deviceIdfromPortPair); | ||
617 | + String url = remoteDevice.annotations().value(SWITCH_CHANNEL_ID); | ||
618 | + String remoteControllerIp = url.substring(0, url.lastIndexOf(":")); | ||
619 | + if (remoteControllerIp == null) { | ||
620 | + log.error("Can't find remote controller of device: {}", deviceIdfromPortPair.toString()); | ||
621 | + return null; | ||
622 | + } | ||
623 | + | ||
624 | + DriverHandler handler = driverService.createHandler(deviceId); | ||
625 | + ExtensionTreatmentResolver resolver = handler.behaviour(ExtensionTreatmentResolver.class); | ||
626 | + ExtensionTreatment tunnelDsttreatment = resolver.getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type()); | ||
627 | + try { | ||
628 | + tunnelDsttreatment.setPropertyValue("tunnelDst", Ip4Address.valueOf(remoteControllerIp)); | ||
629 | + } catch (Exception e) { | ||
630 | + log.error("Failed to get extension instruction to set tunnel dst {}", deviceId); | ||
631 | + } | ||
632 | + | ||
633 | + TrafficTreatment.Builder treatment = packClassifierTreatment(deviceId, virtualPort, port, | ||
634 | + nshSpiId, flowClassifier); | ||
635 | + treatment.extension(tunnelDsttreatment, deviceId); | ||
636 | + treatment.transition(TUNNEL_SEND_TABLE); | ||
637 | + sendSfcRule(selector, treatment, deviceId, type, flowClassifier.priority()); | ||
638 | + classifierList.add(deviceIdfromPortPair); | ||
639 | + | ||
640 | + installSfcTunnelSendRule(deviceId, nshSpiId, type); | ||
641 | + installSfcTunnelReceiveRule(deviceIdfromPortPair, nshSpiId, type); | ||
642 | + | ||
643 | + } else { | ||
644 | + // classifier and port pair are in the same OVS. So directly | ||
645 | + // send packet to first port pair | ||
646 | + TrafficTreatment.Builder treatment = packClassifierTreatment(deviceIdfromPortPair, virtualPort, port, | ||
647 | + nshSpiId, flowClassifier); | ||
648 | + treatment.transition(ENCAP_OUTPUT_TABLE); | ||
649 | + sendSfcRule(selector, treatment, deviceIdfromPortPair, type, flowClassifier.priority()); | ||
650 | + classifierList.add(deviceIdfromPortPair); | ||
651 | + } | ||
652 | + } | ||
653 | + | ||
654 | + return host.location(); | ||
655 | + } | ||
656 | + | ||
657 | + /** | ||
658 | + * Pack Traffic selector. | ||
659 | + * | ||
660 | + * @param flowClassifier flow-classifier | ||
661 | + * @param fiveTuple five tuple info for the packet | ||
662 | + * @return traffic selector | ||
663 | + */ | ||
664 | + public TrafficSelector.Builder packClassifierSelector(FlowClassifier flowClassifier, FiveTuple fiveTuple) { | ||
665 | + | ||
666 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
667 | + | ||
668 | + if ((flowClassifier.srcIpPrefix() != null) && (flowClassifier.srcIpPrefix().prefixLength() != 0)) { | ||
669 | + selector.matchIPSrc(flowClassifier.srcIpPrefix()); | ||
670 | + } else if (fiveTuple != null && fiveTuple.ipSrc() != null) { | ||
671 | + selector.matchIPSrc(IpPrefix.valueOf(fiveTuple.ipSrc(), 24)); | ||
672 | + } | ||
673 | + | ||
674 | + if ((flowClassifier.dstIpPrefix() != null) && (flowClassifier.dstIpPrefix().prefixLength() != 0)) { | ||
675 | + selector.matchIPDst(flowClassifier.dstIpPrefix()); | ||
676 | + } else if (fiveTuple != null && fiveTuple.ipDst() != null) { | ||
677 | + selector.matchIPDst(IpPrefix.valueOf(fiveTuple.ipDst(), 24)); | ||
678 | + } | ||
679 | + | ||
680 | + if ((flowClassifier.protocol() != null) && (!flowClassifier.protocol().isEmpty())) { | ||
681 | + if (flowClassifier.protocol().equalsIgnoreCase("TCP")) { | ||
682 | + selector.add(Criteria.matchIPProtocol(IPv4.PROTOCOL_TCP)); | ||
683 | + } else if (flowClassifier.protocol().equalsIgnoreCase("UDP")) { | ||
684 | + selector.add(Criteria.matchIPProtocol(IPv4.PROTOCOL_UDP)); | ||
685 | + } else if (flowClassifier.protocol().equalsIgnoreCase("ICMP")) { | ||
686 | + selector.add(Criteria.matchIPProtocol(IPv4.PROTOCOL_ICMP)); | ||
687 | + } | ||
688 | + } else if (fiveTuple != null && fiveTuple.protocol() != 0) { | ||
689 | + selector.add(Criteria.matchIPProtocol(fiveTuple.protocol())); | ||
690 | + } | ||
691 | + | ||
692 | + if (((flowClassifier.etherType() != null) && (!flowClassifier.etherType().isEmpty())) | ||
693 | + && (flowClassifier.etherType().equals("IPv4") || flowClassifier.etherType().equals("IPv6"))) { | ||
694 | + if (flowClassifier.etherType().equals("IPv4")) { | ||
695 | + selector.matchEthType(Ethernet.TYPE_IPV4); | ||
696 | + } else { | ||
697 | + selector.matchEthType(Ethernet.TYPE_IPV6); | ||
698 | + } | ||
699 | + } | ||
700 | + | ||
701 | + if ((flowClassifier.srcPort() != null) && (!flowClassifier.srcPort().portId().isEmpty())) { | ||
702 | + VirtualPortId vPortId = VirtualPortId.portId(flowClassifier.srcPort().portId()); | ||
703 | + MacAddress macAddress = virtualPortService.getPort(vPortId).macAddress(); | ||
704 | + Host host = hostService.getHost(HostId.hostId(macAddress)); | ||
705 | + selector.matchInPort(host.location().port()); | ||
706 | + } | ||
707 | + | ||
708 | + // Take the port information from five tuple only when the protocol is | ||
709 | + // TCP. | ||
710 | + if (fiveTuple != null && fiveTuple.protocol() == IPv4.PROTOCOL_TCP) { | ||
711 | + selector.matchTcpSrc(TpPort.tpPort((int) fiveTuple.portSrc().toLong())); | ||
712 | + selector.matchTcpDst(TpPort.tpPort((int) fiveTuple.portDst().toLong())); | ||
713 | + } else { | ||
714 | + // For udp packets take the port information from flow classifier | ||
715 | + List<TpPort> srcPortRange = new LinkedList<>(); | ||
716 | + List<TpPort> dstPortRange = new LinkedList<>(); | ||
717 | + if ((flowClassifier.minSrcPortRange() != 0) && flowClassifier.maxSrcPortRange() != 0 | ||
718 | + && flowClassifier.minDstPortRange() != 0 && flowClassifier.maxDstPortRange() != 0) { | ||
719 | + | ||
720 | + for (int port = flowClassifier.minSrcPortRange(); port <= flowClassifier.maxSrcPortRange(); port++) { | ||
721 | + srcPortRange.add(TpPort.tpPort(port)); | ||
722 | + } | ||
723 | + for (int port = flowClassifier.minDstPortRange(); port <= flowClassifier.maxDstPortRange(); port++) { | ||
724 | + dstPortRange.add(TpPort.tpPort(port)); | ||
725 | + } | ||
726 | + } | ||
727 | + | ||
728 | + for (TpPort inPort : srcPortRange) { | ||
729 | + selector.matchUdpSrc(inPort); | ||
730 | + } | ||
731 | + for (TpPort outPort : dstPortRange) { | ||
732 | + selector.matchUdpDst(outPort); | ||
733 | + } | ||
734 | + } | ||
735 | + return selector; | ||
736 | + } | ||
737 | + | ||
738 | + /** | ||
739 | + * Pack traffic treatment. | ||
740 | + * | ||
741 | + * @param deviceId device id | ||
742 | + * @param virtualPort virtual port | ||
743 | + * @param port port number | ||
744 | + * @param nshSpi nsh spi | ||
745 | + * @param flowClassifier flow-classifier | ||
746 | + * @return traffic treatment | ||
747 | + */ | ||
748 | + public TrafficTreatment.Builder packClassifierTreatment(DeviceId deviceId, VirtualPort virtualPort, | ||
749 | + PortNumber port, NshServicePathId nshSpi, FlowClassifier flowClassifier) { | ||
750 | + | ||
751 | + TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder(); | ||
752 | + | ||
753 | + // set tunnel id | ||
754 | + SegmentationId segmentationId = tenantNetworkService.getNetwork(virtualPort.networkId()).segmentationId(); | ||
755 | + treatmentBuilder.add(Instructions.modTunnelId(Long.parseLong(segmentationId.toString()))); | ||
756 | + | ||
757 | + // Set all NSH header fields | ||
758 | + DriverHandler handler = driverService.createHandler(deviceId); | ||
759 | + ExtensionTreatmentResolver resolver = handler.behaviour(ExtensionTreatmentResolver.class); | ||
760 | + ExtensionTreatment nspIdTreatment = resolver.getExtensionInstruction(NICIRA_SET_NSH_SPI.type()); | ||
761 | + ExtensionTreatment nsiIdTreatment = resolver.getExtensionInstruction(NICIRA_SET_NSH_SI.type()); | ||
762 | + ExtensionTreatment pushNshTreatment = resolver.getExtensionInstruction(NICIRA_PUSH_NSH.type()); | ||
763 | + | ||
764 | + ExtensionTreatment nshCh1Treatment = resolver.getExtensionInstruction(NICIRA_SET_NSH_CH1.type()); | ||
765 | + ExtensionTreatment nshCh2Treatment = resolver.getExtensionInstruction(NICIRA_SET_NSH_CH2.type()); | ||
766 | + ExtensionTreatment nshCh3Treatment = resolver.getExtensionInstruction(NICIRA_SET_NSH_CH3.type()); | ||
767 | + ExtensionTreatment nshCh4Treatment = resolver.getExtensionInstruction(NICIRA_SET_NSH_CH4.type()); | ||
768 | + ExtensionTreatment nshMdTypeTreatment = resolver.getExtensionInstruction(NICIRA_NSH_MDTYPE.type()); | ||
769 | + ExtensionTreatment nshNpTreatment = resolver.getExtensionInstruction(NICIRA_NSH_NP.type()); | ||
770 | + | ||
771 | + try { | ||
772 | + nshMdTypeTreatment.setPropertyValue("nshMdType", ((byte) 1)); | ||
773 | + } catch (Exception e) { | ||
774 | + log.error("Failed to get extension instruction to set nshMdType {}", deviceId); | ||
775 | + } | ||
776 | + try { | ||
777 | + nshNpTreatment.setPropertyValue("nshNp", ((byte) 3)); | ||
778 | + } catch (Exception e) { | ||
779 | + log.error("Failed to get extension instruction to set nshNp {}", deviceId); | ||
780 | + } | ||
781 | + try { | ||
782 | + nspIdTreatment.setPropertyValue("nshSpi", nshSpi); | ||
783 | + } catch (Exception e) { | ||
784 | + log.error("Failed to get extension instruction to set Nsh Spi Id {}", deviceId); | ||
785 | + } | ||
786 | + try { | ||
787 | + nsiIdTreatment.setPropertyValue("nshSi", NshServiceIndex.of(nshSi)); | ||
788 | + } catch (Exception e) { | ||
789 | + log.error("Failed to get extension instruction to set Nsh Si Id {}", deviceId); | ||
790 | + } | ||
791 | + try { | ||
792 | + nshCh1Treatment.setPropertyValue("nshCh", NshContextHeader.of(1)); | ||
793 | + } catch (Exception e) { | ||
794 | + log.error("Failed to get extension instruction to set NshCh1 {}", deviceId); | ||
795 | + } | ||
796 | + try { | ||
797 | + nshCh2Treatment.setPropertyValue("nshCh", NshContextHeader.of(Integer.parseInt(segmentationId.toString()))); | ||
798 | + } catch (Exception e) { | ||
799 | + log.error("Failed to get extension instruction to set NshCh2 {}", deviceId); | ||
800 | + } | ||
801 | + try { | ||
802 | + nshCh3Treatment.setPropertyValue("nshCh", NshContextHeader.of(3)); | ||
803 | + } catch (Exception e) { | ||
804 | + log.error("Failed to get extension instruction to set NshCh3 {}", deviceId); | ||
805 | + } | ||
806 | + try { | ||
807 | + nshCh4Treatment.setPropertyValue("nshCh", NshContextHeader.of(4)); | ||
808 | + } catch (Exception e) { | ||
809 | + log.error("Failed to get extension instruction to set NshCh4 {}", deviceId); | ||
810 | + } | ||
811 | + treatmentBuilder.extension(pushNshTreatment, deviceId); | ||
812 | + treatmentBuilder.extension(nshMdTypeTreatment, deviceId); | ||
813 | + treatmentBuilder.extension(nshNpTreatment, deviceId); | ||
814 | + treatmentBuilder.extension(nspIdTreatment, deviceId); | ||
815 | + treatmentBuilder.extension(nsiIdTreatment, deviceId); | ||
816 | + treatmentBuilder.extension(nshCh1Treatment, deviceId); | ||
817 | + treatmentBuilder.extension(nshCh2Treatment, deviceId); | ||
818 | + treatmentBuilder.extension(nshCh3Treatment, deviceId); | ||
819 | + treatmentBuilder.extension(nshCh4Treatment, deviceId); | ||
820 | + | ||
821 | + return treatmentBuilder; | ||
822 | + } | ||
823 | + | ||
824 | + /** | ||
825 | + * Get the ControllerId from the device . | ||
826 | + * | ||
827 | + * @param device Device | ||
828 | + * @param devices Devices | ||
829 | + * @return Controller Id | ||
830 | + */ | ||
831 | + public DeviceId getControllerId(Device device, Iterable<Device> devices) { | ||
832 | + for (Device d : devices) { | ||
833 | + if (d.type() == Device.Type.CONTROLLER && d.id().toString() | ||
834 | + .contains(getControllerIpOfSwitch(device))) { | ||
835 | + return d.id(); | ||
836 | + } | ||
837 | + } | ||
838 | + log.info("Can not find controller for device : {}", device.id()); | ||
839 | + return null; | ||
840 | + } | ||
841 | + | ||
842 | + /** | ||
843 | + * Get the ControllerIp from the device . | ||
844 | + * | ||
845 | + * @param device Device | ||
846 | + * @return Controller Ip | ||
847 | + */ | ||
848 | + public String getControllerIpOfSwitch(Device device) { | ||
849 | + String url = device.annotations().value(SWITCH_CHANNEL_ID); | ||
850 | + return url.substring(0, url.lastIndexOf(":")); | ||
851 | + } | ||
852 | + | ||
853 | + /** | ||
854 | + * Send service-function-forwarder to OVS. | ||
855 | + * | ||
856 | + * @param selector traffic selector | ||
857 | + * @param treatment traffic treatment | ||
858 | + * @param deviceId device id | ||
859 | + * @param type operation type | ||
860 | + * @param priority priority of classifier | ||
861 | + */ | ||
862 | + public void sendSfcRule(TrafficSelector.Builder selector, TrafficTreatment.Builder treatment, DeviceId deviceId, | ||
863 | + Objective.Operation type, int priority) { | ||
864 | + | ||
865 | + log.info("Sending sfc flow rule. Selector {}, Treatment {}", selector.toString(), | ||
866 | + treatment.toString()); | ||
867 | + ForwardingObjective.Builder objective = DefaultForwardingObjective.builder().withTreatment(treatment.build()) | ||
868 | + .withSelector(selector.build()).fromApp(appId).makePermanent().withFlag(Flag.VERSATILE) | ||
869 | + .withPriority(priority); | ||
870 | + | ||
871 | + if (type.equals(Objective.Operation.ADD)) { | ||
872 | + log.debug("flowClassifierRules-->ADD"); | ||
873 | + flowObjectiveService.forward(deviceId, objective.add()); | ||
874 | + } else { | ||
875 | + log.debug("flowClassifierRules-->REMOVE"); | ||
876 | + flowObjectiveService.forward(deviceId, objective.remove()); | ||
877 | + } | ||
878 | + } | ||
879 | + | ||
880 | + private PortNumber getVxlanPortNumber(DeviceId deviceId) { | ||
881 | + Iterable<Port> ports = deviceService.getPorts(deviceId); | ||
882 | + Port vxlanPort = Sets.newHashSet(ports).stream() | ||
883 | + .filter(p ->!p.number().equals(PortNumber.LOCAL)) | ||
884 | + .filter(p ->p.annotations().value(AnnotationKeys.PORT_NAME) | ||
885 | + .startsWith(VXLANPORT_HEAD)) | ||
886 | + .findFirst().get(); | ||
887 | + return vxlanPort.number(); | ||
888 | + } | ||
889 | +} |
... | @@ -20,8 +20,9 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -20,8 +20,9 @@ import static org.slf4j.LoggerFactory.getLogger; |
20 | import java.util.Collection; | 20 | import java.util.Collection; |
21 | import java.util.Iterator; | 21 | import java.util.Iterator; |
22 | import java.util.List; | 22 | import java.util.List; |
23 | -import java.util.Optional; | 23 | +import java.util.ListIterator; |
24 | import java.util.Set; | 24 | import java.util.Set; |
25 | +import java.util.UUID; | ||
25 | 26 | ||
26 | import org.apache.felix.scr.annotations.Activate; | 27 | import org.apache.felix.scr.annotations.Activate; |
27 | import org.apache.felix.scr.annotations.Component; | 28 | import org.apache.felix.scr.annotations.Component; |
... | @@ -50,10 +51,7 @@ import org.onosproject.net.packet.OutboundPacket; | ... | @@ -50,10 +51,7 @@ import org.onosproject.net.packet.OutboundPacket; |
50 | import org.onosproject.net.packet.PacketContext; | 51 | import org.onosproject.net.packet.PacketContext; |
51 | import org.onosproject.net.packet.PacketProcessor; | 52 | import org.onosproject.net.packet.PacketProcessor; |
52 | import org.onosproject.net.packet.PacketService; | 53 | import org.onosproject.net.packet.PacketService; |
53 | -import org.onosproject.sfc.forwarder.ServiceFunctionForwarderService; | 54 | +import org.onosproject.sfc.installer.impl.SfcFlowRuleInstallerImpl; |
54 | -import org.onosproject.sfc.forwarder.impl.ServiceFunctionForwarderImpl; | ||
55 | -import org.onosproject.sfc.installer.FlowClassifierInstallerService; | ||
56 | -import org.onosproject.sfc.installer.impl.FlowClassifierInstallerImpl; | ||
57 | import org.onosproject.sfc.manager.SfcService; | 55 | import org.onosproject.sfc.manager.SfcService; |
58 | import org.onosproject.store.serializers.KryoNamespaces; | 56 | import org.onosproject.store.serializers.KryoNamespaces; |
59 | import org.onosproject.store.service.DistributedSet; | 57 | import org.onosproject.store.service.DistributedSet; |
... | @@ -77,7 +75,6 @@ import org.onosproject.vtnrsc.TenantId; | ... | @@ -77,7 +75,6 @@ import org.onosproject.vtnrsc.TenantId; |
77 | import org.onosproject.vtnrsc.VirtualPort; | 75 | import org.onosproject.vtnrsc.VirtualPort; |
78 | import org.onosproject.vtnrsc.VirtualPortId; | 76 | import org.onosproject.vtnrsc.VirtualPortId; |
79 | import org.onosproject.vtnrsc.event.VtnRscEvent; | 77 | import org.onosproject.vtnrsc.event.VtnRscEvent; |
80 | -import org.onosproject.vtnrsc.event.VtnRscEventFeedback; | ||
81 | import org.onosproject.vtnrsc.event.VtnRscListener; | 78 | import org.onosproject.vtnrsc.event.VtnRscListener; |
82 | import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService; | 79 | import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService; |
83 | import org.onosproject.vtnrsc.portchain.PortChainService; | 80 | import org.onosproject.vtnrsc.portchain.PortChainService; |
... | @@ -100,7 +97,6 @@ public class SfcManager implements SfcService { | ... | @@ -100,7 +97,6 @@ public class SfcManager implements SfcService { |
100 | private String nshSpiIdTopic = "nsh-spi-id"; | 97 | private String nshSpiIdTopic = "nsh-spi-id"; |
101 | private static final String APP_ID = "org.onosproject.app.vtn"; | 98 | private static final String APP_ID = "org.onosproject.app.vtn"; |
102 | private static final int SFC_PRIORITY = 1000; | 99 | private static final int SFC_PRIORITY = 1000; |
103 | - private static final int NULL_PORT = 0; | ||
104 | private static final int MAX_NSH_SPI_ID = 0x7FFFF; | 100 | private static final int MAX_NSH_SPI_ID = 0x7FFFF; |
105 | private static final int MAX_LOAD_BALANCE_ID = 0x20; | 101 | private static final int MAX_LOAD_BALANCE_ID = 0x20; |
106 | 102 | ||
... | @@ -131,10 +127,9 @@ public class SfcManager implements SfcService { | ... | @@ -131,10 +127,9 @@ public class SfcManager implements SfcService { |
131 | protected SfcPacketProcessor processor = new SfcPacketProcessor(); | 127 | protected SfcPacketProcessor processor = new SfcPacketProcessor(); |
132 | 128 | ||
133 | protected ApplicationId appId; | 129 | protected ApplicationId appId; |
134 | - protected ServiceFunctionForwarderService serviceFunctionForwarder; | ||
135 | - protected FlowClassifierInstallerService flowClassifierInstaller; | ||
136 | protected IdGenerator nshSpiIdGenerator; | 130 | protected IdGenerator nshSpiIdGenerator; |
137 | protected EventuallyConsistentMap<PortChainId, Integer> nshSpiPortChainMap; | 131 | protected EventuallyConsistentMap<PortChainId, Integer> nshSpiPortChainMap; |
132 | + protected EventuallyConsistentMap<PortChainId, List<FiveTuple>> portChainFiveTupleMap; | ||
138 | protected DistributedSet<Integer> nshSpiIdFreeList; | 133 | protected DistributedSet<Integer> nshSpiIdFreeList; |
139 | 134 | ||
140 | private final VtnRscListener vtnRscListener = new InnerVtnRscListener(); | 135 | private final VtnRscListener vtnRscListener = new InnerVtnRscListener(); |
... | @@ -142,24 +137,22 @@ public class SfcManager implements SfcService { | ... | @@ -142,24 +137,22 @@ public class SfcManager implements SfcService { |
142 | @Activate | 137 | @Activate |
143 | public void activate() { | 138 | public void activate() { |
144 | appId = coreService.registerApplication(APP_ID); | 139 | appId = coreService.registerApplication(APP_ID); |
145 | - serviceFunctionForwarder = new ServiceFunctionForwarderImpl(appId); | ||
146 | - flowClassifierInstaller = new FlowClassifierInstallerImpl(appId); | ||
147 | nshSpiIdGenerator = coreService.getIdGenerator(nshSpiIdTopic); | 140 | nshSpiIdGenerator = coreService.getIdGenerator(nshSpiIdTopic); |
148 | 141 | ||
149 | vtnRscService.addListener(vtnRscListener); | 142 | vtnRscService.addListener(vtnRscListener); |
150 | 143 | ||
151 | - KryoNamespace.Builder serializer = KryoNamespace.newBuilder() | 144 | + KryoNamespace.Builder serializer = KryoNamespace |
152 | - .register(TenantId.class) | 145 | + .newBuilder() |
153 | - .register(PortPairId.class) | 146 | + .register(PortChainId.class, UUID.class, FiveTuple.class, IpAddress.class, PortNumber.class, |
154 | - .register(PortPairGroupId.class) | 147 | + DefaultFiveTuple.class, IpAddress.Version.class, TenantId.class); |
155 | - .register(FlowClassifierId.class) | ||
156 | - .register(PortChainId.class); | ||
157 | 148 | ||
158 | nshSpiPortChainMap = storageService.<PortChainId, Integer>eventuallyConsistentMapBuilder() | 149 | nshSpiPortChainMap = storageService.<PortChainId, Integer>eventuallyConsistentMapBuilder() |
159 | - .withName("nshSpiPortChainMap") | 150 | + .withName("nshSpiPortChainMap").withSerializer(serializer) |
160 | - .withSerializer(serializer) | 151 | + .withTimestampProvider((k, v) ->new WallClockTimestamp()).build(); |
161 | - .withTimestampProvider((k, v) -> new WallClockTimestamp()) | 152 | + |
162 | - .build(); | 153 | + portChainFiveTupleMap = storageService.<PortChainId, List<FiveTuple>>eventuallyConsistentMapBuilder() |
154 | + .withName("portChainFiveTupleMap").withSerializer(serializer) | ||
155 | + .withTimestampProvider((k, v) ->new WallClockTimestamp()).build(); | ||
163 | 156 | ||
164 | nshSpiIdFreeList = storageService.<Integer>setBuilder() | 157 | nshSpiIdFreeList = storageService.<Integer>setBuilder() |
165 | .withName("nshSpiIdDeletedList") | 158 | .withName("nshSpiIdDeletedList") |
... | @@ -186,43 +179,47 @@ public class SfcManager implements SfcService { | ... | @@ -186,43 +179,47 @@ public class SfcManager implements SfcService { |
186 | public void event(VtnRscEvent event) { | 179 | public void event(VtnRscEvent event) { |
187 | 180 | ||
188 | if (VtnRscEvent.Type.PORT_PAIR_PUT == event.type()) { | 181 | if (VtnRscEvent.Type.PORT_PAIR_PUT == event.type()) { |
189 | - PortPair portPair = ((VtnRscEventFeedback) event.subject()).portPair(); | 182 | + PortPair portPair = event.subject().portPair(); |
190 | onPortPairCreated(portPair); | 183 | onPortPairCreated(portPair); |
191 | } else if (VtnRscEvent.Type.PORT_PAIR_DELETE == event.type()) { | 184 | } else if (VtnRscEvent.Type.PORT_PAIR_DELETE == event.type()) { |
192 | - PortPair portPair = ((VtnRscEventFeedback) event.subject()).portPair(); | 185 | + PortPair portPair = event.subject().portPair(); |
193 | onPortPairDeleted(portPair); | 186 | onPortPairDeleted(portPair); |
194 | } else if (VtnRscEvent.Type.PORT_PAIR_UPDATE == event.type()) { | 187 | } else if (VtnRscEvent.Type.PORT_PAIR_UPDATE == event.type()) { |
195 | - PortPair portPair = ((VtnRscEventFeedback) event.subject()).portPair(); | 188 | + PortPair portPair = event.subject().portPair(); |
196 | onPortPairDeleted(portPair); | 189 | onPortPairDeleted(portPair); |
197 | onPortPairCreated(portPair); | 190 | onPortPairCreated(portPair); |
198 | } else if (VtnRscEvent.Type.PORT_PAIR_GROUP_PUT == event.type()) { | 191 | } else if (VtnRscEvent.Type.PORT_PAIR_GROUP_PUT == event.type()) { |
199 | - PortPairGroup portPairGroup = ((VtnRscEventFeedback) event.subject()).portPairGroup(); | 192 | + PortPairGroup portPairGroup = event.subject().portPairGroup(); |
200 | onPortPairGroupCreated(portPairGroup); | 193 | onPortPairGroupCreated(portPairGroup); |
201 | } else if (VtnRscEvent.Type.PORT_PAIR_GROUP_DELETE == event.type()) { | 194 | } else if (VtnRscEvent.Type.PORT_PAIR_GROUP_DELETE == event.type()) { |
202 | - PortPairGroup portPairGroup = ((VtnRscEventFeedback) event.subject()).portPairGroup(); | 195 | + PortPairGroup portPairGroup = event.subject().portPairGroup(); |
203 | onPortPairGroupDeleted(portPairGroup); | 196 | onPortPairGroupDeleted(portPairGroup); |
204 | } else if (VtnRscEvent.Type.PORT_PAIR_GROUP_UPDATE == event.type()) { | 197 | } else if (VtnRscEvent.Type.PORT_PAIR_GROUP_UPDATE == event.type()) { |
205 | - PortPairGroup portPairGroup = ((VtnRscEventFeedback) event.subject()).portPairGroup(); | 198 | + PortPairGroup portPairGroup = event.subject().portPairGroup(); |
206 | onPortPairGroupDeleted(portPairGroup); | 199 | onPortPairGroupDeleted(portPairGroup); |
207 | onPortPairGroupCreated(portPairGroup); | 200 | onPortPairGroupCreated(portPairGroup); |
208 | } else if (VtnRscEvent.Type.FLOW_CLASSIFIER_PUT == event.type()) { | 201 | } else if (VtnRscEvent.Type.FLOW_CLASSIFIER_PUT == event.type()) { |
209 | - FlowClassifier flowClassifier = ((VtnRscEventFeedback) event.subject()).flowClassifier(); | 202 | + FlowClassifier flowClassifier = event.subject().flowClassifier(); |
210 | onFlowClassifierCreated(flowClassifier); | 203 | onFlowClassifierCreated(flowClassifier); |
211 | } else if (VtnRscEvent.Type.FLOW_CLASSIFIER_DELETE == event.type()) { | 204 | } else if (VtnRscEvent.Type.FLOW_CLASSIFIER_DELETE == event.type()) { |
212 | - FlowClassifier flowClassifier = ((VtnRscEventFeedback) event.subject()).flowClassifier(); | 205 | + FlowClassifier flowClassifier = event.subject().flowClassifier(); |
213 | onFlowClassifierDeleted(flowClassifier); | 206 | onFlowClassifierDeleted(flowClassifier); |
214 | } else if (VtnRscEvent.Type.FLOW_CLASSIFIER_UPDATE == event.type()) { | 207 | } else if (VtnRscEvent.Type.FLOW_CLASSIFIER_UPDATE == event.type()) { |
215 | - FlowClassifier flowClassifier = ((VtnRscEventFeedback) event.subject()).flowClassifier(); | 208 | + FlowClassifier flowClassifier = event.subject().flowClassifier(); |
216 | onFlowClassifierDeleted(flowClassifier); | 209 | onFlowClassifierDeleted(flowClassifier); |
217 | onFlowClassifierCreated(flowClassifier); | 210 | onFlowClassifierCreated(flowClassifier); |
218 | } else if (VtnRscEvent.Type.PORT_CHAIN_PUT == event.type()) { | 211 | } else if (VtnRscEvent.Type.PORT_CHAIN_PUT == event.type()) { |
219 | - PortChain portChain = (PortChain) ((VtnRscEventFeedback) event.subject()).portChain(); | 212 | + PortChain portChain = event.subject().portChain(); |
213 | + if (portChain.oldPortChain() != null) { | ||
214 | + onPortChainDeleted(portChain.oldPortChain()); | ||
215 | + } | ||
220 | onPortChainCreated(portChain); | 216 | onPortChainCreated(portChain); |
221 | } else if (VtnRscEvent.Type.PORT_CHAIN_DELETE == event.type()) { | 217 | } else if (VtnRscEvent.Type.PORT_CHAIN_DELETE == event.type()) { |
222 | - PortChain portChain = (PortChain) ((VtnRscEventFeedback) event.subject()).portChain(); | 218 | + PortChain portChain = event.subject().portChain(); |
223 | onPortChainDeleted(portChain); | 219 | onPortChainDeleted(portChain); |
220 | + portChainFiveTupleMap.remove(portChain.portChainId()); | ||
224 | } else if (VtnRscEvent.Type.PORT_CHAIN_UPDATE == event.type()) { | 221 | } else if (VtnRscEvent.Type.PORT_CHAIN_UPDATE == event.type()) { |
225 | - PortChain portChain = (PortChain) ((VtnRscEventFeedback) event.subject()).portChain(); | 222 | + PortChain portChain = event.subject().portChain(); |
226 | onPortChainDeleted(portChain); | 223 | onPortChainDeleted(portChain); |
227 | onPortChainCreated(portChain); | 224 | onPortChainCreated(portChain); |
228 | } | 225 | } |
... | @@ -232,58 +229,69 @@ public class SfcManager implements SfcService { | ... | @@ -232,58 +229,69 @@ public class SfcManager implements SfcService { |
232 | @Override | 229 | @Override |
233 | public void onPortPairCreated(PortPair portPair) { | 230 | public void onPortPairCreated(PortPair portPair) { |
234 | log.debug("onPortPairCreated"); | 231 | log.debug("onPortPairCreated"); |
235 | - // TODO: Modify forwarding rule on port-pair creation. | 232 | + // Do nothing |
236 | } | 233 | } |
237 | 234 | ||
238 | @Override | 235 | @Override |
239 | public void onPortPairDeleted(PortPair portPair) { | 236 | public void onPortPairDeleted(PortPair portPair) { |
240 | log.debug("onPortPairDeleted"); | 237 | log.debug("onPortPairDeleted"); |
241 | - // TODO: Modify forwarding rule on port-pair deletion. | 238 | + // Do nothing |
242 | } | 239 | } |
243 | 240 | ||
244 | @Override | 241 | @Override |
245 | public void onPortPairGroupCreated(PortPairGroup portPairGroup) { | 242 | public void onPortPairGroupCreated(PortPairGroup portPairGroup) { |
246 | log.debug("onPortPairGroupCreated"); | 243 | log.debug("onPortPairGroupCreated"); |
247 | - // TODO: Modify forwarding rule on port-pair-group creation. | 244 | + // Do nothing |
248 | } | 245 | } |
249 | 246 | ||
250 | @Override | 247 | @Override |
251 | public void onPortPairGroupDeleted(PortPairGroup portPairGroup) { | 248 | public void onPortPairGroupDeleted(PortPairGroup portPairGroup) { |
252 | log.debug("onPortPairGroupDeleted"); | 249 | log.debug("onPortPairGroupDeleted"); |
253 | - // TODO: Modify forwarding rule on port-pair-group deletion. | 250 | + // Do nothing |
254 | } | 251 | } |
255 | 252 | ||
256 | @Override | 253 | @Override |
257 | public void onFlowClassifierCreated(FlowClassifier flowClassifier) { | 254 | public void onFlowClassifierCreated(FlowClassifier flowClassifier) { |
258 | log.debug("onFlowClassifierCreated"); | 255 | log.debug("onFlowClassifierCreated"); |
259 | - // TODO: Modify forwarding rule on flow-classifier creation. | 256 | + // Do nothing |
260 | } | 257 | } |
261 | 258 | ||
262 | @Override | 259 | @Override |
263 | public void onFlowClassifierDeleted(FlowClassifier flowClassifier) { | 260 | public void onFlowClassifierDeleted(FlowClassifier flowClassifier) { |
264 | log.debug("onFlowClassifierDeleted"); | 261 | log.debug("onFlowClassifierDeleted"); |
265 | - // TODO: Modify forwarding rule on flow-classifier deletion. | 262 | + // Do nothing |
266 | } | 263 | } |
267 | 264 | ||
268 | @Override | 265 | @Override |
269 | public void onPortChainCreated(PortChain portChain) { | 266 | public void onPortChainCreated(PortChain portChain) { |
270 | NshServicePathId nshSpi; | 267 | NshServicePathId nshSpi; |
271 | - log.info("onPortChainCreated"); | 268 | + log.info("On port chain created"); |
272 | - if (nshSpiPortChainMap.containsKey(portChain.portChainId())) { | ||
273 | - nshSpi = NshServicePathId.of(nshSpiPortChainMap.get(portChain.portChainId())); | ||
274 | - } else { | ||
275 | - int id = getNextNshSpi(); | ||
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)); | ||
283 | - } | ||
284 | 269 | ||
270 | + int spi = getNextNshSpi(); | ||
271 | + if (spi > MAX_NSH_SPI_ID) { | ||
272 | + log.error("Reached max limit of service path index." + "Failed to install SFC for port chain {}", | ||
273 | + portChain.portChainId().toString()); | ||
274 | + return; | ||
275 | + } | ||
276 | + nshSpi = NshServicePathId.of(spi); | ||
277 | + nshSpiPortChainMap.put(portChain.portChainId(), new Integer(spi)); | ||
278 | + if (!portChainFiveTupleMap.containsKey(portChain.portChainId())) { | ||
279 | + portChainFiveTupleMap.put(portChain.portChainId(), Lists.newArrayList()); | ||
280 | + } | ||
285 | // Install classifier rule to send the packet to controller | 281 | // Install classifier rule to send the packet to controller |
286 | - flowClassifierInstaller.installFlowClassifier(portChain, nshSpi); | 282 | + SfcFlowRuleInstallerImpl flowRuleInstaller = new SfcFlowRuleInstallerImpl(appId); |
283 | + flowRuleInstaller.installFlowClassifier(portChain, nshSpi); | ||
284 | + | ||
285 | + // Install rules for already identified five tuples. | ||
286 | + List<FiveTuple> list = portChainFiveTupleMap.get(portChain.portChainId()); | ||
287 | + for (FiveTuple fiveTuple : list) { | ||
288 | + LoadBalanceId id = loadBalanceSfc(portChain.portChainId(), fiveTuple); | ||
289 | + // Get nsh service path index | ||
290 | + nshSpi = NshServicePathId.of(getNshServicePathId(id, spi)); | ||
291 | + // download the required flow rules for classifier and | ||
292 | + // forwarding | ||
293 | + flowRuleInstaller.installLoadBalancedFlowRules(portChain, fiveTuple, nshSpi); | ||
294 | + } | ||
287 | } | 295 | } |
288 | 296 | ||
289 | @Override | 297 | @Override |
... | @@ -295,7 +303,8 @@ public class SfcManager implements SfcService { | ... | @@ -295,7 +303,8 @@ public class SfcManager implements SfcService { |
295 | 303 | ||
296 | int nshSpiId = nshSpiPortChainMap.get(portChain.portChainId()); | 304 | int nshSpiId = nshSpiPortChainMap.get(portChain.portChainId()); |
297 | // Uninstall classifier rules | 305 | // Uninstall classifier rules |
298 | - flowClassifierInstaller.unInstallFlowClassifier(portChain, NshServicePathId.of(nshSpiId)); | 306 | + SfcFlowRuleInstallerImpl flowRuleInstaller = new SfcFlowRuleInstallerImpl(appId); |
307 | + flowRuleInstaller.unInstallFlowClassifier(portChain, NshServicePathId.of(nshSpiId)); | ||
299 | // remove from nshSpiPortChainMap and add to nshSpiIdFreeList | 308 | // remove from nshSpiPortChainMap and add to nshSpiIdFreeList |
300 | nshSpiPortChainMap.remove(portChain.portChainId()); | 309 | nshSpiPortChainMap.remove(portChain.portChainId()); |
301 | nshSpiIdFreeList.add(nshSpiId); | 310 | nshSpiIdFreeList.add(nshSpiId); |
... | @@ -314,9 +323,16 @@ public class SfcManager implements SfcService { | ... | @@ -314,9 +323,16 @@ public class SfcManager implements SfcService { |
314 | processedIdList.add(id); | 323 | processedIdList.add(id); |
315 | } | 324 | } |
316 | nshSpi = NshServicePathId.of(getNshServicePathId(id, nshSpiId)); | 325 | nshSpi = NshServicePathId.of(getNshServicePathId(id, nshSpiId)); |
317 | - flowClassifierInstaller.unInstallLoadBalancedFlowClassifier(portChain, fiveTuple, nshSpi); | 326 | + flowRuleInstaller.unInstallLoadBalancedFlowRules(portChain, fiveTuple, nshSpi); |
318 | - serviceFunctionForwarder.unInstallLoadBalancedForwardingRule(portChain.getLoadBalancePath(fiveTuple), | 327 | + } |
319 | - nshSpi); | 328 | + |
329 | + // Reset load for all the port pairs | ||
330 | + List<PortPairGroupId> ppgIdlist = portChain.portPairGroups(); | ||
331 | + ListIterator<PortPairGroupId> ppgIdListIterator = ppgIdlist.listIterator(); | ||
332 | + while (ppgIdListIterator.hasNext()) { | ||
333 | + PortPairGroupId portPairGroupId = ppgIdListIterator.next(); | ||
334 | + PortPairGroup ppg = portPairGroupService.getPortPairGroup(portPairGroupId); | ||
335 | + ppg.resetLoad(); | ||
320 | } | 336 | } |
321 | } | 337 | } |
322 | 338 | ||
... | @@ -388,9 +404,12 @@ public class SfcManager implements SfcService { | ... | @@ -388,9 +404,12 @@ public class SfcManager implements SfcService { |
388 | boolean match = false; | 404 | boolean match = false; |
389 | // Check whether protocol is set in flow classifier | 405 | // Check whether protocol is set in flow classifier |
390 | if (flowClassifier.protocol() != null) { | 406 | if (flowClassifier.protocol() != null) { |
391 | - if ((flowClassifier.protocol().equals("TCP") && fiveTuple.protocol() == IPv4.PROTOCOL_TCP) || | 407 | + if ((flowClassifier.protocol().equalsIgnoreCase("TCP") |
392 | - (flowClassifier.protocol().equals("UDP") && | 408 | + && fiveTuple.protocol() == IPv4.PROTOCOL_TCP) |
393 | - fiveTuple.protocol() == IPv4.PROTOCOL_UDP)) { | 409 | + || (flowClassifier.protocol().equalsIgnoreCase("UDP") |
410 | + && fiveTuple.protocol() == IPv4.PROTOCOL_UDP) | ||
411 | + || (flowClassifier.protocol().equalsIgnoreCase("ICMP") | ||
412 | + && fiveTuple.protocol() == IPv4.PROTOCOL_ICMP)) { | ||
394 | match = true; | 413 | match = true; |
395 | } else { | 414 | } else { |
396 | continue; | 415 | continue; |
... | @@ -459,68 +478,6 @@ public class SfcManager implements SfcService { | ... | @@ -459,68 +478,6 @@ public class SfcManager implements SfcService { |
459 | } | 478 | } |
460 | 479 | ||
461 | /** | 480 | /** |
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 | - } | ||
522 | - | ||
523 | - /** | ||
524 | * Get the tenant id for the given mac address. | 481 | * Get the tenant id for the given mac address. |
525 | * | 482 | * |
526 | * @param mac mac address | 483 | * @param mac mac address |
... | @@ -561,7 +518,7 @@ public class SfcManager implements SfcService { | ... | @@ -561,7 +518,7 @@ public class SfcManager implements SfcService { |
561 | TCP tcpPacket = (TCP) ipv4Packet.getPayload(); | 518 | TCP tcpPacket = (TCP) ipv4Packet.getPayload(); |
562 | portSrc = tcpPacket.getSourcePort(); | 519 | portSrc = tcpPacket.getSourcePort(); |
563 | portDst = tcpPacket.getDestinationPort(); | 520 | portDst = tcpPacket.getDestinationPort(); |
564 | - } else if (protocol == IPv4.PROTOCOL_UDP) { | 521 | + } else if (protocol == IPv4.PROTOCOL_UDP) { |
565 | UDP udpPacket = (UDP) ipv4Packet.getPayload(); | 522 | UDP udpPacket = (UDP) ipv4Packet.getPayload(); |
566 | portSrc = udpPacket.getSourcePort(); | 523 | portSrc = udpPacket.getSourcePort(); |
567 | portDst = udpPacket.getDestinationPort(); | 524 | portDst = udpPacket.getDestinationPort(); |
... | @@ -571,7 +528,7 @@ public class SfcManager implements SfcService { | ... | @@ -571,7 +528,7 @@ public class SfcManager implements SfcService { |
571 | // No need to process other packets received by controller. | 528 | // No need to process other packets received by controller. |
572 | return; | 529 | return; |
573 | } | 530 | } |
574 | - } else if (ethType == Ethernet.TYPE_IPV6) { | 531 | + } else { |
575 | return; | 532 | return; |
576 | } | 533 | } |
577 | 534 | ||
... | @@ -587,11 +544,11 @@ public class SfcManager implements SfcService { | ... | @@ -587,11 +544,11 @@ public class SfcManager implements SfcService { |
587 | PortChainId portChainId = findPortChainFromFiveTuple(fiveTuple); | 544 | PortChainId portChainId = findPortChainFromFiveTuple(fiveTuple); |
588 | 545 | ||
589 | if (portChainId == null) { | 546 | if (portChainId == null) { |
590 | - log.error("Packet does not match with any classifier"); | ||
591 | return; | 547 | return; |
592 | } | 548 | } |
593 | 549 | ||
594 | // Once the 5 tuple and port chain are identified, give this input for load balancing | 550 | // Once the 5 tuple and port chain are identified, give this input for load balancing |
551 | + addToPortChainIdFiveTupleMap(portChainId, fiveTuple); | ||
595 | LoadBalanceId id = loadBalanceSfc(portChainId, fiveTuple); | 552 | LoadBalanceId id = loadBalanceSfc(portChainId, fiveTuple); |
596 | // Get nsh service path index | 553 | // Get nsh service path index |
597 | NshServicePathId nshSpi; | 554 | NshServicePathId nshSpi; |
... | @@ -611,11 +568,9 @@ public class SfcManager implements SfcService { | ... | @@ -611,11 +568,9 @@ public class SfcManager implements SfcService { |
611 | } | 568 | } |
612 | // download the required flow rules for classifier and forwarding | 569 | // download the required flow rules for classifier and forwarding |
613 | // install in OVS. | 570 | // install in OVS. |
614 | - ConnectPoint connectPoint = flowClassifierInstaller.installLoadBalancedFlowClassifier(portChain, | 571 | + SfcFlowRuleInstallerImpl flowRuleInstaller = new SfcFlowRuleInstallerImpl(appId); |
615 | - fiveTuple, nshSpi); | 572 | + flowRuleInstaller.installLoadBalancedFlowRules(portChain, fiveTuple, nshSpi); |
616 | - serviceFunctionForwarder.installLoadBalancedForwardingRule(portChain.getLoadBalancePath(fiveTuple), | 573 | + sendPacket(context); |
617 | - nshSpi); | ||
618 | - sendPacket(context, connectPoint); | ||
619 | } | 574 | } |
620 | 575 | ||
621 | /** | 576 | /** |
... | @@ -624,11 +579,13 @@ public class SfcManager implements SfcService { | ... | @@ -624,11 +579,13 @@ public class SfcManager implements SfcService { |
624 | * @param context packet context | 579 | * @param context packet context |
625 | * @param connectPoint connect point of first service function | 580 | * @param connectPoint connect point of first service function |
626 | */ | 581 | */ |
627 | - private void sendPacket(PacketContext context, ConnectPoint connectPoint) { | 582 | + private void sendPacket(PacketContext context) { |
583 | + | ||
584 | + ConnectPoint sourcePoint = context.inPacket().receivedFrom(); | ||
628 | 585 | ||
629 | - TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(connectPoint.port()).build(); | 586 | + TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(sourcePoint.port()).build(); |
630 | - OutboundPacket packet = new DefaultOutboundPacket(connectPoint.deviceId(), treatment, | 587 | + OutboundPacket packet = new DefaultOutboundPacket(sourcePoint.deviceId(), treatment, context.inPacket() |
631 | - context.inPacket().unparsed()); | 588 | + .unparsed()); |
632 | packetService.emit(packet); | 589 | packetService.emit(packet); |
633 | log.trace("Sending packet: {}", packet); | 590 | log.trace("Sending packet: {}", packet); |
634 | } | 591 | } |
... | @@ -646,4 +603,71 @@ public class SfcManager implements SfcService { | ... | @@ -646,4 +603,71 @@ public class SfcManager implements SfcService { |
646 | nshSpiNew = nshSpiNew | id.loadBalanceId(); | 603 | nshSpiNew = nshSpiNew | id.loadBalanceId(); |
647 | return nshSpiNew; | 604 | return nshSpiNew; |
648 | } | 605 | } |
606 | + | ||
607 | + private void addToPortChainIdFiveTupleMap(PortChainId portChainId, FiveTuple fiveTuple) { | ||
608 | + List<FiveTuple> list = portChainFiveTupleMap.get(portChainId); | ||
609 | + list.add(fiveTuple); | ||
610 | + portChainFiveTupleMap.put(portChainId, list); | ||
611 | + } | ||
612 | + | ||
613 | + /** | ||
614 | + * Find the load balanced path set it to port chain for the given five | ||
615 | + * tuple. | ||
616 | + * | ||
617 | + * @param portChainId port chain id | ||
618 | + * @param fiveTuple five tuple info | ||
619 | + * @return load balance id | ||
620 | + */ | ||
621 | + private LoadBalanceId loadBalanceSfc(PortChainId portChainId, FiveTuple fiveTuple) { | ||
622 | + | ||
623 | + // Get the port chain | ||
624 | + PortChain portChain = portChainService.getPortChain(portChainId); | ||
625 | + List<PortPairId> loadBalancePath = Lists.newArrayList(); | ||
626 | + LoadBalanceId id; | ||
627 | + int paths = portChain.getLoadBalancePathSize(); | ||
628 | + if (paths >= MAX_LOAD_BALANCE_ID) { | ||
629 | + log.info("Max limit reached for load balance paths. " | ||
630 | + + "Reusing the created path for port chain {} with five tuple {}", portChainId, fiveTuple); | ||
631 | + id = LoadBalanceId.of((byte) ((paths + 1) % MAX_LOAD_BALANCE_ID)); | ||
632 | + portChain.addLoadBalancePath(fiveTuple, id, portChain.getLoadBalancePath(id)); | ||
633 | + } | ||
634 | + | ||
635 | + // Get the list of port pair groups from port chain | ||
636 | + Iterable<PortPairGroupId> portPairGroups = portChain.portPairGroups(); | ||
637 | + for (final PortPairGroupId portPairGroupId : portPairGroups) { | ||
638 | + PortPairGroup portPairGroup = portPairGroupService.getPortPairGroup(portPairGroupId); | ||
639 | + | ||
640 | + // Get the list of port pair ids from port pair group. | ||
641 | + Iterable<PortPairId> portPairs = portPairGroup.portPairs(); | ||
642 | + int minLoad = 0xFFF; | ||
643 | + PortPairId minLoadPortPairId = null; | ||
644 | + for (final PortPairId portPairId : portPairs) { | ||
645 | + int load = portPairGroup.getLoad(portPairId); | ||
646 | + if (load == 0) { | ||
647 | + minLoadPortPairId = portPairId; | ||
648 | + break; | ||
649 | + } else { | ||
650 | + // Check the port pair which has min load. | ||
651 | + if (load < minLoad) { | ||
652 | + minLoad = load; | ||
653 | + minLoadPortPairId = portPairId; | ||
654 | + } | ||
655 | + } | ||
656 | + } | ||
657 | + if (minLoadPortPairId != null) { | ||
658 | + loadBalancePath.add(minLoadPortPairId); | ||
659 | + portPairGroup.addLoad(minLoadPortPairId); | ||
660 | + } | ||
661 | + } | ||
662 | + | ||
663 | + // Check if the path already exists, if not create a new id | ||
664 | + id = portChain.matchPath(loadBalancePath); | ||
665 | + if (id == null) { | ||
666 | + id = LoadBalanceId.of((byte) (paths + 1)); | ||
667 | + } | ||
668 | + | ||
669 | + portChain.addLoadBalancePath(fiveTuple, id, loadBalancePath); | ||
670 | + return id; | ||
671 | + } | ||
672 | + | ||
649 | } | 673 | } | ... | ... |
1 | -/* | ||
2 | - * Copyright 2016-present 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.forwarder.impl; | ||
17 | - | ||
18 | -import static org.easymock.EasyMock.createMock; | ||
19 | -import static org.easymock.EasyMock.expect; | ||
20 | -import static org.easymock.EasyMock.replay; | ||
21 | -import static org.hamcrest.Matchers.instanceOf; | ||
22 | -import static org.hamcrest.Matchers.is; | ||
23 | -import static org.junit.Assert.assertThat; | ||
24 | - | ||
25 | -import java.util.List; | ||
26 | -import java.util.Map; | ||
27 | -import java.util.Set; | ||
28 | - | ||
29 | -import org.junit.Test; | ||
30 | -import org.onlab.packet.IpAddress; | ||
31 | -import org.onlab.packet.MacAddress; | ||
32 | -import org.onosproject.core.ApplicationId; | ||
33 | -import org.onosproject.core.DefaultApplicationId; | ||
34 | -import org.onosproject.net.DeviceId; | ||
35 | -import org.onosproject.net.NshServicePathId; | ||
36 | -import org.onosproject.net.PortNumber; | ||
37 | -import org.onosproject.net.device.DeviceService; | ||
38 | -import org.onosproject.net.device.DeviceServiceAdapter; | ||
39 | -import org.onosproject.net.driver.DriverHandler; | ||
40 | -import org.onosproject.net.driver.DriverService; | ||
41 | -import org.onosproject.net.flow.criteria.Criterion; | ||
42 | -import org.onosproject.net.flow.criteria.PortCriterion; | ||
43 | -import org.onosproject.net.flow.instructions.Instruction; | ||
44 | -import org.onosproject.net.flow.instructions.Instructions.OutputInstruction; | ||
45 | -import org.onosproject.net.flowobjective.FlowObjectiveService; | ||
46 | -import org.onosproject.net.flowobjective.ForwardingObjective; | ||
47 | -import org.onosproject.net.host.HostService; | ||
48 | -import org.onosproject.net.host.HostServiceAdapter; | ||
49 | -import org.onosproject.sfc.util.FlowClassifierAdapter; | ||
50 | -import org.onosproject.sfc.util.FlowObjectiveAdapter; | ||
51 | -import org.onosproject.sfc.util.MockDriverHandler; | ||
52 | -import org.onosproject.sfc.util.PortPairAdapter; | ||
53 | -import org.onosproject.sfc.util.PortPairGroupAdapter; | ||
54 | -import org.onosproject.sfc.util.VirtualPortAdapter; | ||
55 | -import org.onosproject.sfc.util.VtnRscAdapter; | ||
56 | -import org.onosproject.vtnrsc.AllowedAddressPair; | ||
57 | -import org.onosproject.vtnrsc.BindingHostId; | ||
58 | -import org.onosproject.vtnrsc.DefaultPortPair; | ||
59 | -import org.onosproject.vtnrsc.DefaultVirtualPort; | ||
60 | -import org.onosproject.vtnrsc.FixedIp; | ||
61 | -import org.onosproject.vtnrsc.PortPair; | ||
62 | -import org.onosproject.vtnrsc.PortPairId; | ||
63 | -import org.onosproject.vtnrsc.SecurityGroup; | ||
64 | -import org.onosproject.vtnrsc.SubnetId; | ||
65 | -import org.onosproject.vtnrsc.TenantId; | ||
66 | -import org.onosproject.vtnrsc.TenantNetworkId; | ||
67 | -import org.onosproject.vtnrsc.VirtualPort; | ||
68 | -import org.onosproject.vtnrsc.VirtualPortId; | ||
69 | -import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService; | ||
70 | -import org.onosproject.vtnrsc.portpair.PortPairService; | ||
71 | -import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService; | ||
72 | -import org.onosproject.vtnrsc.service.VtnRscService; | ||
73 | -import org.onosproject.vtnrsc.virtualport.VirtualPortService; | ||
74 | - | ||
75 | -import com.google.common.collect.Lists; | ||
76 | -import com.google.common.collect.Maps; | ||
77 | -import com.google.common.collect.Sets; | ||
78 | - | ||
79 | -public class ServiceFunctionForwarderImplTest { | ||
80 | - | ||
81 | - FlowObjectiveService flowObjectiveService = new FlowObjectiveAdapter(); | ||
82 | - DeviceService deviceService = new DeviceServiceAdapter(); | ||
83 | - HostService hostService = new HostServiceAdapter(); | ||
84 | - VirtualPortService virtualPortService = new VirtualPortAdapter(); | ||
85 | - VtnRscService vtnRscService = new VtnRscAdapter(); | ||
86 | - PortPairService portPairService = new PortPairAdapter(); | ||
87 | - PortPairGroupService portPairGroupService = new PortPairGroupAdapter(); | ||
88 | - FlowClassifierService flowClassifierService = new FlowClassifierAdapter(); | ||
89 | - | ||
90 | - final DriverService driverService = createMock(DriverService.class); | ||
91 | - | ||
92 | - DeviceId deviceId = DeviceId.deviceId("of:000000000000001"); | ||
93 | - final TenantId tenantId = TenantId.tenantId("1"); | ||
94 | - | ||
95 | - final DriverHandler driverHandler = new MockDriverHandler(); | ||
96 | - | ||
97 | - private VirtualPort createVirtualPort(VirtualPortId id) { | ||
98 | - Set<FixedIp> fixedIps; | ||
99 | - Map<String, String> propertyMap; | ||
100 | - Set<AllowedAddressPair> allowedAddressPairs; | ||
101 | - Set<SecurityGroup> securityGroups = Sets.newHashSet(); | ||
102 | - | ||
103 | - String macAddressStr = "fa:12:3e:56:ee:a2"; | ||
104 | - String ipAddress = "10.1.1.1"; | ||
105 | - String tenantNetworkId = "1234567"; | ||
106 | - String subnet = "1212"; | ||
107 | - String hostIdStr = "fa:e2:3e:56:ee:a2"; | ||
108 | - String deviceOwner = "james"; | ||
109 | - propertyMap = Maps.newHashMap(); | ||
110 | - propertyMap.putIfAbsent("deviceOwner", deviceOwner); | ||
111 | - | ||
112 | - TenantNetworkId networkId = TenantNetworkId.networkId(tenantNetworkId); | ||
113 | - MacAddress macAddress = MacAddress.valueOf(macAddressStr); | ||
114 | - BindingHostId bindingHostId = BindingHostId.bindingHostId(hostIdStr); | ||
115 | - FixedIp fixedIp = FixedIp.fixedIp(SubnetId.subnetId(subnet), | ||
116 | - IpAddress.valueOf(ipAddress)); | ||
117 | - fixedIps = Sets.newHashSet(); | ||
118 | - fixedIps.add(fixedIp); | ||
119 | - | ||
120 | - allowedAddressPairs = Sets.newHashSet(); | ||
121 | - AllowedAddressPair allowedAddressPair = AllowedAddressPair | ||
122 | - .allowedAddressPair(IpAddress.valueOf(ipAddress), | ||
123 | - MacAddress.valueOf(macAddressStr)); | ||
124 | - allowedAddressPairs.add(allowedAddressPair); | ||
125 | - | ||
126 | - VirtualPort d1 = new DefaultVirtualPort(id, networkId, true, | ||
127 | - propertyMap, | ||
128 | - VirtualPort.State.ACTIVE, | ||
129 | - macAddress, tenantId, deviceId, | ||
130 | - fixedIps, bindingHostId, | ||
131 | - allowedAddressPairs, | ||
132 | - securityGroups); | ||
133 | - return d1; | ||
134 | - } | ||
135 | - | ||
136 | - @Test | ||
137 | - public void testInstallFlowClassifier() { | ||
138 | - | ||
139 | - PortPairId portPairId1 = PortPairId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae"); | ||
140 | - PortPairId portPairId2 = PortPairId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae"); | ||
141 | - | ||
142 | - final String ppName1 = "PortPair1"; | ||
143 | - final String ppDescription1 = "PortPair1"; | ||
144 | - final String ingress1 = "d3333333-24fc-4fae-af4b-321c5e2eb3d1"; | ||
145 | - final String egress1 = "a4444444-4a56-2a6e-cd3a-9dee4e2ec345"; | ||
146 | - DefaultPortPair.Builder portPairBuilder = new DefaultPortPair.Builder(); | ||
147 | - PortPair portPair1 = portPairBuilder.setId(portPairId1).setName(ppName1).setTenantId(tenantId) | ||
148 | - .setDescription(ppDescription1).setIngress(ingress1).setEgress(egress1).build(); | ||
149 | - | ||
150 | - final String ppName2 = "PortPair2"; | ||
151 | - final String ppDescription2 = "PortPair2"; | ||
152 | - final String ingress2 = "d5555555-24fc-4fae-af4b-321c5e2eb3d1"; | ||
153 | - final String egress2 = "a6666666-4a56-2a6e-cd3a-9dee4e2ec345"; | ||
154 | - PortPair portPair2 = portPairBuilder.setId(portPairId2).setName(ppName2).setTenantId(tenantId) | ||
155 | - .setDescription(ppDescription2).setIngress(ingress2).setEgress(egress2).build(); | ||
156 | - | ||
157 | - ApplicationId appId = new DefaultApplicationId(1, "test"); | ||
158 | - ServiceFunctionForwarderImpl serviceFunctionForwarder = new ServiceFunctionForwarderImpl(); | ||
159 | - serviceFunctionForwarder.virtualPortService = virtualPortService; | ||
160 | - serviceFunctionForwarder.vtnRscService = vtnRscService; | ||
161 | - serviceFunctionForwarder.portPairService = portPairService; | ||
162 | - serviceFunctionForwarder.portPairGroupService = portPairGroupService; | ||
163 | - serviceFunctionForwarder.flowClassifierService = flowClassifierService; | ||
164 | - serviceFunctionForwarder.driverService = driverService; | ||
165 | - serviceFunctionForwarder.hostService = hostService; | ||
166 | - serviceFunctionForwarder.flowObjectiveService = flowObjectiveService; | ||
167 | - serviceFunctionForwarder.appId = appId; | ||
168 | - | ||
169 | - NshServicePathId nshSpiId = NshServicePathId.of(10); | ||
170 | - | ||
171 | - portPairService.createPortPair(portPair1); | ||
172 | - portPairService.createPortPair(portPair2); | ||
173 | - | ||
174 | - List<PortPairId> path = Lists.newArrayList(); | ||
175 | - path.add(portPairId1); | ||
176 | - path.add(portPairId2); | ||
177 | - | ||
178 | - List<VirtualPort> virtualPortList = Lists.newArrayList(); | ||
179 | - virtualPortList.add(createVirtualPort(VirtualPortId.portId(egress1))); | ||
180 | - virtualPortList.add(createVirtualPort(VirtualPortId.portId(ingress2))); | ||
181 | - virtualPortService.createPorts(virtualPortList); | ||
182 | - | ||
183 | - expect(driverService.createHandler(deviceId)).andReturn(driverHandler).anyTimes(); | ||
184 | - replay(driverService); | ||
185 | - | ||
186 | - serviceFunctionForwarder.installLoadBalancedForwardingRule(path, nshSpiId); | ||
187 | - | ||
188 | - ForwardingObjective forObj = ((FlowObjectiveAdapter) flowObjectiveService).forwardingObjective(); | ||
189 | - | ||
190 | - // Check for Selector | ||
191 | - assertThat(forObj.selector().getCriterion(Criterion.Type.IN_PORT), instanceOf(PortCriterion.class)); | ||
192 | - | ||
193 | - // Check for treatment | ||
194 | - List<Instruction> instructions = forObj.treatment().allInstructions(); | ||
195 | - for (Instruction instruction : instructions) { | ||
196 | - if (instruction.type() == Instruction.Type.OUTPUT) { | ||
197 | - assertThat(((OutputInstruction) instruction).port(), is(PortNumber.P0)); | ||
198 | - } | ||
199 | - } | ||
200 | - } | ||
201 | -} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
... | @@ -18,48 +18,74 @@ package org.onosproject.sfc.installer.impl; | ... | @@ -18,48 +18,74 @@ package org.onosproject.sfc.installer.impl; |
18 | import static org.easymock.EasyMock.createMock; | 18 | import static org.easymock.EasyMock.createMock; |
19 | import static org.easymock.EasyMock.expect; | 19 | import static org.easymock.EasyMock.expect; |
20 | import static org.easymock.EasyMock.replay; | 20 | import static org.easymock.EasyMock.replay; |
21 | +import static org.hamcrest.Matchers.instanceOf; | ||
21 | import static org.hamcrest.Matchers.is; | 22 | import static org.hamcrest.Matchers.is; |
22 | import static org.junit.Assert.assertThat; | 23 | import static org.junit.Assert.assertThat; |
24 | +import static org.onosproject.net.Device.Type.SWITCH; | ||
25 | +import static org.onosproject.net.Port.Type.COPPER; | ||
23 | 26 | ||
27 | +import java.util.Collections; | ||
24 | import java.util.LinkedList; | 28 | import java.util.LinkedList; |
25 | import java.util.List; | 29 | import java.util.List; |
26 | import java.util.Map; | 30 | import java.util.Map; |
27 | import java.util.Set; | 31 | import java.util.Set; |
28 | 32 | ||
29 | import org.junit.Test; | 33 | import org.junit.Test; |
34 | +import org.onlab.packet.ChassisId; | ||
35 | +import org.onlab.packet.IPv4; | ||
30 | import org.onlab.packet.IpAddress; | 36 | import org.onlab.packet.IpAddress; |
31 | import org.onlab.packet.IpPrefix; | 37 | import org.onlab.packet.IpPrefix; |
32 | import org.onlab.packet.MacAddress; | 38 | import org.onlab.packet.MacAddress; |
33 | import org.onosproject.core.ApplicationId; | 39 | import org.onosproject.core.ApplicationId; |
34 | import org.onosproject.core.DefaultApplicationId; | 40 | import org.onosproject.core.DefaultApplicationId; |
41 | +import org.onosproject.net.AnnotationKeys; | ||
42 | +import org.onosproject.net.Annotations; | ||
35 | import org.onosproject.net.ConnectPoint; | 43 | import org.onosproject.net.ConnectPoint; |
44 | +import org.onosproject.net.DefaultAnnotations; | ||
45 | +import org.onosproject.net.DefaultDevice; | ||
46 | +import org.onosproject.net.DefaultPort; | ||
47 | +import org.onosproject.net.Device; | ||
36 | import org.onosproject.net.DeviceId; | 48 | import org.onosproject.net.DeviceId; |
37 | import org.onosproject.net.HostLocation; | 49 | import org.onosproject.net.HostLocation; |
38 | import org.onosproject.net.NshServicePathId; | 50 | import org.onosproject.net.NshServicePathId; |
51 | +import org.onosproject.net.Port; | ||
52 | +import org.onosproject.net.PortNumber; | ||
39 | import org.onosproject.net.device.DeviceService; | 53 | import org.onosproject.net.device.DeviceService; |
40 | import org.onosproject.net.device.DeviceServiceAdapter; | 54 | import org.onosproject.net.device.DeviceServiceAdapter; |
41 | import org.onosproject.net.driver.DriverHandler; | 55 | import org.onosproject.net.driver.DriverHandler; |
42 | import org.onosproject.net.driver.DriverService; | 56 | import org.onosproject.net.driver.DriverService; |
57 | +import org.onosproject.net.flow.criteria.Criterion; | ||
58 | +import org.onosproject.net.flow.criteria.PortCriterion; | ||
59 | +import org.onosproject.net.flow.instructions.Instruction; | ||
60 | +import org.onosproject.net.flow.instructions.Instructions.OutputInstruction; | ||
43 | import org.onosproject.net.flowobjective.FlowObjectiveService; | 61 | import org.onosproject.net.flowobjective.FlowObjectiveService; |
62 | +import org.onosproject.net.flowobjective.ForwardingObjective; | ||
44 | import org.onosproject.net.host.HostService; | 63 | import org.onosproject.net.host.HostService; |
45 | import org.onosproject.net.host.HostServiceAdapter; | 64 | import org.onosproject.net.host.HostServiceAdapter; |
65 | +import org.onosproject.net.provider.ProviderId; | ||
46 | import org.onosproject.sfc.util.FlowClassifierAdapter; | 66 | import org.onosproject.sfc.util.FlowClassifierAdapter; |
47 | import org.onosproject.sfc.util.FlowObjectiveAdapter; | 67 | import org.onosproject.sfc.util.FlowObjectiveAdapter; |
48 | import org.onosproject.sfc.util.MockDriverHandler; | 68 | import org.onosproject.sfc.util.MockDriverHandler; |
49 | import org.onosproject.sfc.util.PortPairAdapter; | 69 | import org.onosproject.sfc.util.PortPairAdapter; |
50 | import org.onosproject.sfc.util.PortPairGroupAdapter; | 70 | import org.onosproject.sfc.util.PortPairGroupAdapter; |
71 | +import org.onosproject.sfc.util.TenantNetworkAdapter; | ||
51 | import org.onosproject.sfc.util.VirtualPortAdapter; | 72 | import org.onosproject.sfc.util.VirtualPortAdapter; |
52 | import org.onosproject.sfc.util.VtnRscAdapter; | 73 | import org.onosproject.sfc.util.VtnRscAdapter; |
53 | import org.onosproject.vtnrsc.AllowedAddressPair; | 74 | import org.onosproject.vtnrsc.AllowedAddressPair; |
54 | import org.onosproject.vtnrsc.BindingHostId; | 75 | import org.onosproject.vtnrsc.BindingHostId; |
76 | +import org.onosproject.vtnrsc.DefaultFiveTuple; | ||
55 | import org.onosproject.vtnrsc.DefaultFlowClassifier; | 77 | import org.onosproject.vtnrsc.DefaultFlowClassifier; |
56 | import org.onosproject.vtnrsc.DefaultPortChain; | 78 | import org.onosproject.vtnrsc.DefaultPortChain; |
57 | import org.onosproject.vtnrsc.DefaultPortPair; | 79 | import org.onosproject.vtnrsc.DefaultPortPair; |
58 | import org.onosproject.vtnrsc.DefaultPortPairGroup; | 80 | import org.onosproject.vtnrsc.DefaultPortPairGroup; |
81 | +import org.onosproject.vtnrsc.DefaultTenantNetwork; | ||
59 | import org.onosproject.vtnrsc.DefaultVirtualPort; | 82 | import org.onosproject.vtnrsc.DefaultVirtualPort; |
83 | +import org.onosproject.vtnrsc.FiveTuple; | ||
60 | import org.onosproject.vtnrsc.FixedIp; | 84 | import org.onosproject.vtnrsc.FixedIp; |
61 | import org.onosproject.vtnrsc.FlowClassifier; | 85 | import org.onosproject.vtnrsc.FlowClassifier; |
62 | import org.onosproject.vtnrsc.FlowClassifierId; | 86 | import org.onosproject.vtnrsc.FlowClassifierId; |
87 | +import org.onosproject.vtnrsc.LoadBalanceId; | ||
88 | +import org.onosproject.vtnrsc.PhysicalNetwork; | ||
63 | import org.onosproject.vtnrsc.PortChain; | 89 | import org.onosproject.vtnrsc.PortChain; |
64 | import org.onosproject.vtnrsc.PortChainId; | 90 | import org.onosproject.vtnrsc.PortChainId; |
65 | import org.onosproject.vtnrsc.PortPair; | 91 | import org.onosproject.vtnrsc.PortPair; |
... | @@ -67,8 +93,10 @@ import org.onosproject.vtnrsc.PortPairGroup; | ... | @@ -67,8 +93,10 @@ import org.onosproject.vtnrsc.PortPairGroup; |
67 | import org.onosproject.vtnrsc.PortPairGroupId; | 93 | import org.onosproject.vtnrsc.PortPairGroupId; |
68 | import org.onosproject.vtnrsc.PortPairId; | 94 | import org.onosproject.vtnrsc.PortPairId; |
69 | import org.onosproject.vtnrsc.SecurityGroup; | 95 | import org.onosproject.vtnrsc.SecurityGroup; |
96 | +import org.onosproject.vtnrsc.SegmentationId; | ||
70 | import org.onosproject.vtnrsc.SubnetId; | 97 | import org.onosproject.vtnrsc.SubnetId; |
71 | import org.onosproject.vtnrsc.TenantId; | 98 | import org.onosproject.vtnrsc.TenantId; |
99 | +import org.onosproject.vtnrsc.TenantNetwork; | ||
72 | import org.onosproject.vtnrsc.TenantNetworkId; | 100 | import org.onosproject.vtnrsc.TenantNetworkId; |
73 | import org.onosproject.vtnrsc.VirtualPort; | 101 | import org.onosproject.vtnrsc.VirtualPort; |
74 | import org.onosproject.vtnrsc.VirtualPortId; | 102 | import org.onosproject.vtnrsc.VirtualPortId; |
... | @@ -76,25 +104,30 @@ import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService; | ... | @@ -76,25 +104,30 @@ import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService; |
76 | import org.onosproject.vtnrsc.portpair.PortPairService; | 104 | import org.onosproject.vtnrsc.portpair.PortPairService; |
77 | import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService; | 105 | import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService; |
78 | import org.onosproject.vtnrsc.service.VtnRscService; | 106 | import org.onosproject.vtnrsc.service.VtnRscService; |
107 | +import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService; | ||
79 | import org.onosproject.vtnrsc.virtualport.VirtualPortService; | 108 | import org.onosproject.vtnrsc.virtualport.VirtualPortService; |
80 | 109 | ||
81 | import com.google.common.collect.Lists; | 110 | import com.google.common.collect.Lists; |
82 | import com.google.common.collect.Maps; | 111 | import com.google.common.collect.Maps; |
83 | import com.google.common.collect.Sets; | 112 | import com.google.common.collect.Sets; |
84 | 113 | ||
85 | -public class FlowClassifierInstallerImplTest { | 114 | +public class SfcFlowRuleInstallerImplTest { |
86 | 115 | ||
87 | FlowObjectiveService flowObjectiveService = new FlowObjectiveAdapter(); | 116 | FlowObjectiveService flowObjectiveService = new FlowObjectiveAdapter(); |
88 | - DeviceService deviceService = new DeviceServiceAdapter(); | 117 | + DeviceService deviceService = new DeviceServiceAdapter(createPortList()); |
118 | + | ||
89 | HostService hostService = new HostServiceAdapter(); | 119 | HostService hostService = new HostServiceAdapter(); |
90 | VirtualPortService virtualPortService = new VirtualPortAdapter(); | 120 | VirtualPortService virtualPortService = new VirtualPortAdapter(); |
91 | VtnRscService vtnRscService = new VtnRscAdapter(); | 121 | VtnRscService vtnRscService = new VtnRscAdapter(); |
92 | PortPairService portPairService = new PortPairAdapter(); | 122 | PortPairService portPairService = new PortPairAdapter(); |
93 | PortPairGroupService portPairGroupService = new PortPairGroupAdapter(); | 123 | PortPairGroupService portPairGroupService = new PortPairGroupAdapter(); |
94 | FlowClassifierService flowClassifierService = new FlowClassifierAdapter(); | 124 | FlowClassifierService flowClassifierService = new FlowClassifierAdapter(); |
125 | + TenantNetworkService tenantNetworkService = new TenantNetworkAdapter(); | ||
95 | 126 | ||
96 | final DriverService driverService = createMock(DriverService.class); | 127 | final DriverService driverService = createMock(DriverService.class); |
97 | 128 | ||
129 | + private final String networkIdStr = "123"; | ||
130 | + | ||
98 | final PortChainId portChainId = PortChainId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae"); | 131 | final PortChainId portChainId = PortChainId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae"); |
99 | final TenantId tenantId = TenantId.tenantId("1"); | 132 | final TenantId tenantId = TenantId.tenantId("1"); |
100 | final String name = "PortChain"; | 133 | final String name = "PortChain"; |
... | @@ -115,7 +148,6 @@ public class FlowClassifierInstallerImplTest { | ... | @@ -115,7 +148,6 @@ public class FlowClassifierInstallerImplTest { |
115 | final String ingress = "d3333333-24fc-4fae-af4b-321c5e2eb3d1"; | 148 | final String ingress = "d3333333-24fc-4fae-af4b-321c5e2eb3d1"; |
116 | final String egress = "a4444444-4a56-2a6e-cd3a-9dee4e2ec345"; | 149 | final String egress = "a4444444-4a56-2a6e-cd3a-9dee4e2ec345"; |
117 | 150 | ||
118 | - | ||
119 | final String ppgName = "PortPairGroup"; | 151 | final String ppgName = "PortPairGroup"; |
120 | final String ppgDescription = "PortPairGroup"; | 152 | final String ppgDescription = "PortPairGroup"; |
121 | final List<PortPairId> portPairList = new LinkedList<PortPairId>(); | 153 | final List<PortPairId> portPairList = new LinkedList<PortPairId>(); |
... | @@ -127,7 +159,21 @@ public class FlowClassifierInstallerImplTest { | ... | @@ -127,7 +159,21 @@ public class FlowClassifierInstallerImplTest { |
127 | 159 | ||
128 | final DriverHandler driverHandler = new MockDriverHandler(); | 160 | final DriverHandler driverHandler = new MockDriverHandler(); |
129 | 161 | ||
130 | - private PortPair createPortPair(PortPairId ppId) { | 162 | + private List<Port> createPortList() { |
163 | + List<Port> portList = Lists.newArrayList(); | ||
164 | + long sp1 = 1_000_000; | ||
165 | + ProviderId pid = new ProviderId("of", "foo"); | ||
166 | + ChassisId cid = new ChassisId(); | ||
167 | + Device device = new DefaultDevice(pid, deviceId, SWITCH, "whitebox", "1.1.x", "3.9.1", "43311-12345", cid); | ||
168 | + Annotations annotations = DefaultAnnotations | ||
169 | + .builder() | ||
170 | + .set(AnnotationKeys.PORT_NAME, "vxlan-0.0.0.0").build(); | ||
171 | + Port p1 = new DefaultPort(device, PortNumber.ANY, true, COPPER, sp1, annotations); | ||
172 | + portList.add(p1); | ||
173 | + return portList; | ||
174 | + } | ||
175 | + | ||
176 | + private PortPair createPortPair(PortPairId ppId) { | ||
131 | DefaultPortPair.Builder portPairBuilder = new DefaultPortPair.Builder(); | 177 | DefaultPortPair.Builder portPairBuilder = new DefaultPortPair.Builder(); |
132 | PortPair portPair = portPairBuilder.setId(ppId).setName(ppName).setTenantId(tenantId) | 178 | PortPair portPair = portPairBuilder.setId(ppId).setName(ppName).setTenantId(tenantId) |
133 | .setDescription(ppDescription).setIngress(ingress).setEgress(egress).build(); | 179 | .setDescription(ppDescription).setIngress(ingress).setEgress(egress).build(); |
... | @@ -193,7 +239,7 @@ public class FlowClassifierInstallerImplTest { | ... | @@ -193,7 +239,7 @@ public class FlowClassifierInstallerImplTest { |
193 | return flowClassifier; | 239 | return flowClassifier; |
194 | } | 240 | } |
195 | 241 | ||
196 | - private VirtualPort createVirtualPort() { | 242 | + private VirtualPort createVirtualPort(VirtualPortId id) { |
197 | Set<FixedIp> fixedIps; | 243 | Set<FixedIp> fixedIps; |
198 | Map<String, String> propertyMap; | 244 | Map<String, String> propertyMap; |
199 | Set<AllowedAddressPair> allowedAddressPairs; | 245 | Set<AllowedAddressPair> allowedAddressPairs; |
... | @@ -201,14 +247,13 @@ public class FlowClassifierInstallerImplTest { | ... | @@ -201,14 +247,13 @@ public class FlowClassifierInstallerImplTest { |
201 | 247 | ||
202 | String macAddressStr = "fa:12:3e:56:ee:a2"; | 248 | String macAddressStr = "fa:12:3e:56:ee:a2"; |
203 | String ipAddress = "10.1.1.1"; | 249 | String ipAddress = "10.1.1.1"; |
204 | - String tenantNetworkId = "1234567"; | ||
205 | String subnet = "1212"; | 250 | String subnet = "1212"; |
206 | String hostIdStr = "fa:e2:3e:56:ee:a2"; | 251 | String hostIdStr = "fa:e2:3e:56:ee:a2"; |
207 | String deviceOwner = "james"; | 252 | String deviceOwner = "james"; |
208 | propertyMap = Maps.newHashMap(); | 253 | propertyMap = Maps.newHashMap(); |
209 | propertyMap.putIfAbsent("deviceOwner", deviceOwner); | 254 | propertyMap.putIfAbsent("deviceOwner", deviceOwner); |
210 | 255 | ||
211 | - TenantNetworkId networkId = TenantNetworkId.networkId(tenantNetworkId); | 256 | + TenantNetworkId networkId = TenantNetworkId.networkId(networkIdStr); |
212 | MacAddress macAddress = MacAddress.valueOf(macAddressStr); | 257 | MacAddress macAddress = MacAddress.valueOf(macAddressStr); |
213 | BindingHostId bindingHostId = BindingHostId.bindingHostId(hostIdStr); | 258 | BindingHostId bindingHostId = BindingHostId.bindingHostId(hostIdStr); |
214 | FixedIp fixedIp = FixedIp.fixedIp(SubnetId.subnetId(subnet), | 259 | FixedIp fixedIp = FixedIp.fixedIp(SubnetId.subnetId(subnet), |
... | @@ -222,7 +267,7 @@ public class FlowClassifierInstallerImplTest { | ... | @@ -222,7 +267,7 @@ public class FlowClassifierInstallerImplTest { |
222 | MacAddress.valueOf(macAddressStr)); | 267 | MacAddress.valueOf(macAddressStr)); |
223 | allowedAddressPairs.add(allowedAddressPair); | 268 | allowedAddressPairs.add(allowedAddressPair); |
224 | 269 | ||
225 | - VirtualPort d1 = new DefaultVirtualPort(id1, networkId, true, | 270 | + VirtualPort d1 = new DefaultVirtualPort(id, networkId, true, |
226 | propertyMap, | 271 | propertyMap, |
227 | VirtualPort.State.ACTIVE, | 272 | VirtualPort.State.ACTIVE, |
228 | macAddress, tenantId, deviceId, | 273 | macAddress, tenantId, deviceId, |
... | @@ -236,7 +281,7 @@ public class FlowClassifierInstallerImplTest { | ... | @@ -236,7 +281,7 @@ public class FlowClassifierInstallerImplTest { |
236 | public void testInstallFlowClassifier() { | 281 | public void testInstallFlowClassifier() { |
237 | 282 | ||
238 | ApplicationId appId = new DefaultApplicationId(1, "test"); | 283 | ApplicationId appId = new DefaultApplicationId(1, "test"); |
239 | - FlowClassifierInstallerImpl flowClassifierInstaller = new FlowClassifierInstallerImpl(); | 284 | + SfcFlowRuleInstallerImpl flowClassifierInstaller = new SfcFlowRuleInstallerImpl(); |
240 | flowClassifierInstaller.virtualPortService = virtualPortService; | 285 | flowClassifierInstaller.virtualPortService = virtualPortService; |
241 | flowClassifierInstaller.vtnRscService = vtnRscService; | 286 | flowClassifierInstaller.vtnRscService = vtnRscService; |
242 | flowClassifierInstaller.portPairService = portPairService; | 287 | flowClassifierInstaller.portPairService = portPairService; |
... | @@ -261,7 +306,7 @@ public class FlowClassifierInstallerImplTest { | ... | @@ -261,7 +306,7 @@ public class FlowClassifierInstallerImplTest { |
261 | flowClassifierService.createFlowClassifier(fc2); | 306 | flowClassifierService.createFlowClassifier(fc2); |
262 | 307 | ||
263 | List<VirtualPort> virtualPortList = Lists.newArrayList(); | 308 | List<VirtualPort> virtualPortList = Lists.newArrayList(); |
264 | - virtualPortList.add(createVirtualPort()); | 309 | + virtualPortList.add(createVirtualPort(VirtualPortId.portId(ingress))); |
265 | virtualPortService.createPorts(virtualPortList); | 310 | virtualPortService.createPorts(virtualPortList); |
266 | 311 | ||
267 | expect(driverService.createHandler(deviceId)).andReturn(driverHandler).anyTimes(); | 312 | expect(driverService.createHandler(deviceId)).andReturn(driverHandler).anyTimes(); |
... | @@ -271,4 +316,102 @@ public class FlowClassifierInstallerImplTest { | ... | @@ -271,4 +316,102 @@ public class FlowClassifierInstallerImplTest { |
271 | 316 | ||
272 | assertThat(connectPoint, is(HostLocation.NONE)); | 317 | assertThat(connectPoint, is(HostLocation.NONE)); |
273 | } | 318 | } |
274 | -} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
319 | + | ||
320 | + @Test | ||
321 | + public void testInstallLoadBalancedFlowRules() { | ||
322 | + ApplicationId appId = new DefaultApplicationId(1, "test"); | ||
323 | + SfcFlowRuleInstallerImpl flowRuleInstaller = new SfcFlowRuleInstallerImpl(); | ||
324 | + flowRuleInstaller.virtualPortService = virtualPortService; | ||
325 | + flowRuleInstaller.vtnRscService = vtnRscService; | ||
326 | + flowRuleInstaller.portPairService = portPairService; | ||
327 | + flowRuleInstaller.portPairGroupService = portPairGroupService; | ||
328 | + flowRuleInstaller.flowClassifierService = flowClassifierService; | ||
329 | + flowRuleInstaller.driverService = driverService; | ||
330 | + flowRuleInstaller.deviceService = deviceService; | ||
331 | + flowRuleInstaller.hostService = hostService; | ||
332 | + flowRuleInstaller.flowObjectiveService = flowObjectiveService; | ||
333 | + flowRuleInstaller.tenantNetworkService = tenantNetworkService; | ||
334 | + flowRuleInstaller.appId = appId; | ||
335 | + | ||
336 | + final PortChain portChain = createPortChain(); | ||
337 | + | ||
338 | + final String ppName1 = "PortPair1"; | ||
339 | + final String ppDescription1 = "PortPair1"; | ||
340 | + final String ingress1 = "d3333333-24fc-4fae-af4b-321c5e2eb3d1"; | ||
341 | + final String egress1 = "a4444444-4a56-2a6e-cd3a-9dee4e2ec345"; | ||
342 | + DefaultPortPair.Builder portPairBuilder = new DefaultPortPair.Builder(); | ||
343 | + PortPair portPair1 = portPairBuilder.setId(portPairId1).setName(ppName1).setTenantId(tenantId) | ||
344 | + .setDescription(ppDescription1).setIngress(ingress1).setEgress(egress1).build(); | ||
345 | + | ||
346 | + final String ppName2 = "PortPair2"; | ||
347 | + final String ppDescription2 = "PortPair2"; | ||
348 | + final String ingress2 = "d5555555-24fc-4fae-af4b-321c5e2eb3d1"; | ||
349 | + final String egress2 = "a6666666-4a56-2a6e-cd3a-9dee4e2ec345"; | ||
350 | + PortPair portPair2 = portPairBuilder.setId(portPairId2).setName(ppName2).setTenantId(tenantId) | ||
351 | + .setDescription(ppDescription2).setIngress(ingress2).setEgress(egress2).build(); | ||
352 | + | ||
353 | + portPairService.createPortPair(portPair1); | ||
354 | + portPairService.createPortPair(portPair2); | ||
355 | + | ||
356 | + FlowClassifier fc1 = createFlowClassifier(flowClassifierId1); | ||
357 | + FlowClassifier fc2 = createFlowClassifier(flowClassifierId2); | ||
358 | + flowClassifierService.createFlowClassifier(fc1); | ||
359 | + flowClassifierService.createFlowClassifier(fc2); | ||
360 | + | ||
361 | + NshServicePathId nshSpiId = NshServicePathId.of(10); | ||
362 | + FiveTuple fiveTuple = DefaultFiveTuple.builder().setIpSrc(IpAddress.valueOf("3.3.3.3")) | ||
363 | + .setIpDst(IpAddress.valueOf("4.4.4.4")) | ||
364 | + .setPortSrc(PortNumber.portNumber(1500)) | ||
365 | + .setPortDst(PortNumber.portNumber(2000)) | ||
366 | + .setProtocol(IPv4.PROTOCOL_UDP) | ||
367 | + .setTenantId(TenantId.tenantId("bbb")) | ||
368 | + .build(); | ||
369 | + LoadBalanceId id = LoadBalanceId.of((byte) 1); | ||
370 | + | ||
371 | + List<PortPairId> path = Lists.newArrayList(); | ||
372 | + path.add(portPairId1); | ||
373 | + path.add(portPairId2); | ||
374 | + | ||
375 | + List<VirtualPort> virtualPortList = Lists.newArrayList(); | ||
376 | + virtualPortList.add(createVirtualPort(VirtualPortId.portId(ingress1))); | ||
377 | + virtualPortList.add(createVirtualPort(VirtualPortId.portId(egress1))); | ||
378 | + virtualPortList.add(createVirtualPort(VirtualPortId.portId(ingress2))); | ||
379 | + virtualPortList.add(createVirtualPort(VirtualPortId.portId(egress2))); | ||
380 | + virtualPortService.createPorts(virtualPortList); | ||
381 | + | ||
382 | + portChain.addLoadBalancePath(fiveTuple, id, path); | ||
383 | + | ||
384 | + String physicalNetworkStr = "1234"; | ||
385 | + String segmentationIdStr = "1"; | ||
386 | + SegmentationId segmentationID = SegmentationId | ||
387 | + .segmentationId(segmentationIdStr); | ||
388 | + TenantNetworkId networkid1 = TenantNetworkId.networkId(networkIdStr); | ||
389 | + PhysicalNetwork physicalNetwork = PhysicalNetwork | ||
390 | + .physicalNetwork(physicalNetworkStr); | ||
391 | + TenantNetwork p1 = new DefaultTenantNetwork(networkid1, name, false, | ||
392 | + TenantNetwork.State.ACTIVE, | ||
393 | + false, tenantId, false, | ||
394 | + TenantNetwork.Type.LOCAL, | ||
395 | + physicalNetwork, | ||
396 | + segmentationID); | ||
397 | + tenantNetworkService.createNetworks(Collections.singletonList(p1)); | ||
398 | + | ||
399 | + expect(driverService.createHandler(deviceId)).andReturn(driverHandler).anyTimes(); | ||
400 | + replay(driverService); | ||
401 | + | ||
402 | + flowRuleInstaller.installLoadBalancedFlowRules(portChain, fiveTuple, nshSpiId); | ||
403 | + | ||
404 | + ForwardingObjective forObj = ((FlowObjectiveAdapter) flowObjectiveService).forwardingObjective(); | ||
405 | + | ||
406 | + // Check for Selector | ||
407 | + assertThat(forObj.selector().getCriterion(Criterion.Type.IN_PORT), instanceOf(PortCriterion.class)); | ||
408 | + | ||
409 | + // Check for treatment | ||
410 | + List<Instruction> instructions = forObj.treatment().allInstructions(); | ||
411 | + for (Instruction instruction : instructions) { | ||
412 | + if (instruction.type() == Instruction.Type.OUTPUT) { | ||
413 | + assertThat(((OutputInstruction) instruction).port(), is(PortNumber.P0)); | ||
414 | + } | ||
415 | + } | ||
416 | + } | ||
417 | +} | ... | ... |
... | @@ -23,6 +23,12 @@ import org.onosproject.net.flow.instructions.ExtensionPropertyException; | ... | @@ -23,6 +23,12 @@ import org.onosproject.net.flow.instructions.ExtensionPropertyException; |
23 | 23 | ||
24 | public class MockExtensionSelector implements ExtensionSelector { | 24 | public class MockExtensionSelector implements ExtensionSelector { |
25 | 25 | ||
26 | + private ExtensionSelectorType type; | ||
27 | + | ||
28 | + public MockExtensionSelector(ExtensionSelectorType type) { | ||
29 | + this.type = type; | ||
30 | + } | ||
31 | + | ||
26 | @Override | 32 | @Override |
27 | public <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException { | 33 | public <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException { |
28 | } | 34 | } |
... | @@ -48,6 +54,6 @@ public class MockExtensionSelector implements ExtensionSelector { | ... | @@ -48,6 +54,6 @@ public class MockExtensionSelector implements ExtensionSelector { |
48 | 54 | ||
49 | @Override | 55 | @Override |
50 | public ExtensionSelectorType type() { | 56 | public ExtensionSelectorType type() { |
51 | - return null; | 57 | + return type; |
52 | } | 58 | } |
53 | } | 59 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -43,6 +43,6 @@ public class MockExtensionSelectorResolver implements ExtensionSelectorResolver | ... | @@ -43,6 +43,6 @@ public class MockExtensionSelectorResolver implements ExtensionSelectorResolver |
43 | 43 | ||
44 | @Override | 44 | @Override |
45 | public ExtensionSelector getExtensionSelector(ExtensionSelectorType type) { | 45 | public ExtensionSelector getExtensionSelector(ExtensionSelectorType type) { |
46 | - return new MockExtensionSelector(); | 46 | + return new MockExtensionSelector(type); |
47 | } | 47 | } |
48 | } | 48 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -23,6 +23,12 @@ import org.onosproject.net.flow.instructions.ExtensionTreatmentType; | ... | @@ -23,6 +23,12 @@ import org.onosproject.net.flow.instructions.ExtensionTreatmentType; |
23 | 23 | ||
24 | public class MockExtensionTreatment implements ExtensionTreatment { | 24 | public class MockExtensionTreatment implements ExtensionTreatment { |
25 | 25 | ||
26 | + private ExtensionTreatmentType type; | ||
27 | + | ||
28 | + public MockExtensionTreatment(ExtensionTreatmentType type) { | ||
29 | + this.type = type; | ||
30 | + } | ||
31 | + | ||
26 | @Override | 32 | @Override |
27 | public <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException { | 33 | public <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException { |
28 | } | 34 | } |
... | @@ -48,7 +54,7 @@ public class MockExtensionTreatment implements ExtensionTreatment { | ... | @@ -48,7 +54,7 @@ public class MockExtensionTreatment implements ExtensionTreatment { |
48 | 54 | ||
49 | @Override | 55 | @Override |
50 | public ExtensionTreatmentType type() { | 56 | public ExtensionTreatmentType type() { |
51 | - return null; | 57 | + return type; |
52 | } | 58 | } |
53 | 59 | ||
54 | } | 60 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -43,7 +43,7 @@ public class MockExtensionTreatmentResolver implements ExtensionTreatmentResolve | ... | @@ -43,7 +43,7 @@ public class MockExtensionTreatmentResolver implements ExtensionTreatmentResolve |
43 | 43 | ||
44 | @Override | 44 | @Override |
45 | public ExtensionTreatment getExtensionInstruction(ExtensionTreatmentType type) { | 45 | public ExtensionTreatment getExtensionInstruction(ExtensionTreatmentType type) { |
46 | - return new MockExtensionTreatment(); | 46 | + return new MockExtensionTreatment(type); |
47 | } | 47 | } |
48 | 48 | ||
49 | } | 49 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
1 | +/* | ||
2 | + * Copyright 2016-present 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.util; | ||
17 | + | ||
18 | +import java.util.concurrent.ConcurrentHashMap; | ||
19 | +import java.util.concurrent.ConcurrentMap; | ||
20 | + | ||
21 | +import org.onosproject.vtnrsc.TenantNetwork; | ||
22 | +import org.onosproject.vtnrsc.TenantNetworkId; | ||
23 | +import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService; | ||
24 | + | ||
25 | +import com.google.common.collect.ImmutableList; | ||
26 | + | ||
27 | +/** | ||
28 | + * Provides implementation of the VtnRsc service. | ||
29 | + */ | ||
30 | +public class TenantNetworkAdapter implements TenantNetworkService { | ||
31 | + | ||
32 | + private final ConcurrentMap<TenantNetworkId, TenantNetwork> tenantNetworkStore = new ConcurrentHashMap<>(); | ||
33 | + | ||
34 | + @Override | ||
35 | + public boolean exists(TenantNetworkId networkId) { | ||
36 | + return tenantNetworkStore.containsKey(networkId); | ||
37 | + } | ||
38 | + | ||
39 | + @Override | ||
40 | + public int getNetworkCount() { | ||
41 | + return tenantNetworkStore.size(); | ||
42 | + } | ||
43 | + | ||
44 | + @Override | ||
45 | + public Iterable<TenantNetwork> getNetworks() { | ||
46 | + return ImmutableList.copyOf(tenantNetworkStore.values()); | ||
47 | + } | ||
48 | + | ||
49 | + @Override | ||
50 | + public TenantNetwork getNetwork(TenantNetworkId networkId) { | ||
51 | + return tenantNetworkStore.get(networkId); | ||
52 | + } | ||
53 | + | ||
54 | + @Override | ||
55 | + public boolean createNetworks(Iterable<TenantNetwork> networks) { | ||
56 | + for (TenantNetwork network : networks) { | ||
57 | + tenantNetworkStore.put(network.id(), network); | ||
58 | + if (!tenantNetworkStore.containsKey(network.id())) { | ||
59 | + return false; | ||
60 | + } | ||
61 | + } | ||
62 | + return true; | ||
63 | + } | ||
64 | + | ||
65 | + @Override | ||
66 | + public boolean updateNetworks(Iterable<TenantNetwork> networks) { | ||
67 | + return false; | ||
68 | + } | ||
69 | + | ||
70 | + @Override | ||
71 | + public boolean removeNetworks(Iterable<TenantNetworkId> networksIds) { | ||
72 | + return false; | ||
73 | + } | ||
74 | + | ||
75 | +} |
... | @@ -43,6 +43,20 @@ public final class VtnConfig { | ... | @@ -43,6 +43,20 @@ public final class VtnConfig { |
43 | { | 43 | { |
44 | put("key", "flow"); | 44 | put("key", "flow"); |
45 | put("remote_ip", "flow"); | 45 | put("remote_ip", "flow"); |
46 | + put("dst_port", "4790"); | ||
47 | + put("in_nsi", "flow"); | ||
48 | + put("in_nsp", "flow"); | ||
49 | + put("out_nsi", "flow"); | ||
50 | + put("out_nsp", "flow"); | ||
51 | + put("in_nshc1", "flow"); | ||
52 | + put("out_nshc1", "flow"); | ||
53 | + put("in_nshc2", "flow"); | ||
54 | + put("out_nshc2", "flow"); | ||
55 | + put("in_nshc3", "flow"); | ||
56 | + put("out_nshc3", "flow"); | ||
57 | + put("in_nshc4", "flow"); | ||
58 | + put("out_nshc4", "flow"); | ||
59 | + put("exts", "gpe"); | ||
46 | } | 60 | } |
47 | }; | 61 | }; |
48 | /** | 62 | /** | ... | ... |
... | @@ -48,7 +48,7 @@ public final class DefaultFlowClassifier implements FlowClassifier { | ... | @@ -48,7 +48,7 @@ public final class DefaultFlowClassifier implements FlowClassifier { |
48 | private static final String TENANT_ID_NOT_NULL = "Tenant id can not be null."; | 48 | private static final String TENANT_ID_NOT_NULL = "Tenant id can not be null."; |
49 | private static final String NAME_NOT_NULL = "Name can not be null."; | 49 | private static final String NAME_NOT_NULL = "Name can not be null."; |
50 | private static final String ETHER_TYPE_NOT_NULL = "Ether Type can not be null."; | 50 | private static final String ETHER_TYPE_NOT_NULL = "Ether Type can not be null."; |
51 | - private static final int DEFAULT_CLASSIFIER_PRIORITY = 0xFFFF; | 51 | + private static final int DEFAULT_CLASSIFIER_PRIORITY = 0xCB20; |
52 | 52 | ||
53 | /** | 53 | /** |
54 | * Constructor to create default flow classifier. | 54 | * Constructor to create default flow classifier. | ... | ... |
... | @@ -22,7 +22,6 @@ import java.util.Iterator; | ... | @@ -22,7 +22,6 @@ import java.util.Iterator; |
22 | import java.util.List; | 22 | import java.util.List; |
23 | import java.util.Map; | 23 | import java.util.Map; |
24 | import java.util.Objects; | 24 | import java.util.Objects; |
25 | -import java.util.Optional; | ||
26 | import java.util.Set; | 25 | import java.util.Set; |
27 | import java.util.concurrent.ConcurrentHashMap; | 26 | import java.util.concurrent.ConcurrentHashMap; |
28 | 27 | ||
... | @@ -42,11 +41,13 @@ public final class DefaultPortChain implements PortChain { | ... | @@ -42,11 +41,13 @@ public final class DefaultPortChain implements PortChain { |
42 | private final String description; | 41 | private final String description; |
43 | private final List<PortPairGroupId> portPairGroupList; | 42 | private final List<PortPairGroupId> portPairGroupList; |
44 | private final List<FlowClassifierId> flowClassifierList; | 43 | private final List<FlowClassifierId> flowClassifierList; |
44 | + private final PortChain oldPortChain; | ||
45 | 45 | ||
46 | private final Map<FiveTuple, LoadBalanceId> sfcLoadBalanceIdMap = new ConcurrentHashMap<>(); | 46 | private final Map<FiveTuple, LoadBalanceId> sfcLoadBalanceIdMap = new ConcurrentHashMap<>(); |
47 | private final Map<LoadBalanceId, List<PortPairId>> sfcLoadBalancePathMap = new ConcurrentHashMap<>(); | 47 | private final Map<LoadBalanceId, List<PortPairId>> sfcLoadBalancePathMap = new ConcurrentHashMap<>(); |
48 | private final Map<LoadBalanceId, List<DeviceId>> sfcClassifiersMap = new ConcurrentHashMap<>(); | 48 | private final Map<LoadBalanceId, List<DeviceId>> sfcClassifiersMap = new ConcurrentHashMap<>(); |
49 | private final Map<LoadBalanceId, List<DeviceId>> sfcForwardersMap = new ConcurrentHashMap<>(); | 49 | private final Map<LoadBalanceId, List<DeviceId>> sfcForwardersMap = new ConcurrentHashMap<>(); |
50 | + | ||
50 | /** | 51 | /** |
51 | * Default constructor to create port chain. | 52 | * Default constructor to create port chain. |
52 | * | 53 | * |
... | @@ -58,9 +59,10 @@ public final class DefaultPortChain implements PortChain { | ... | @@ -58,9 +59,10 @@ public final class DefaultPortChain implements PortChain { |
58 | * @param flowClassifierList flow classifier list | 59 | * @param flowClassifierList flow classifier list |
59 | */ | 60 | */ |
60 | private DefaultPortChain(PortChainId portChainId, TenantId tenantId, | 61 | private DefaultPortChain(PortChainId portChainId, TenantId tenantId, |
61 | - String name, String description, | 62 | + String name, String description, |
62 | - List<PortPairGroupId> portPairGroupList, | 63 | + List<PortPairGroupId> portPairGroupList, |
63 | - List<FlowClassifierId> flowClassifierList) { | 64 | + List<FlowClassifierId> flowClassifierList, |
65 | + PortChain portChain) { | ||
64 | 66 | ||
65 | this.portChainId = portChainId; | 67 | this.portChainId = portChainId; |
66 | this.tenantId = tenantId; | 68 | this.tenantId = tenantId; |
... | @@ -68,6 +70,20 @@ public final class DefaultPortChain implements PortChain { | ... | @@ -68,6 +70,20 @@ public final class DefaultPortChain implements PortChain { |
68 | this.description = description; | 70 | this.description = description; |
69 | this.portPairGroupList = portPairGroupList; | 71 | this.portPairGroupList = portPairGroupList; |
70 | this.flowClassifierList = flowClassifierList; | 72 | this.flowClassifierList = flowClassifierList; |
73 | + this.oldPortChain = portChain; | ||
74 | + } | ||
75 | + | ||
76 | + /** | ||
77 | + * To create port chain for update with old port chain. | ||
78 | + * | ||
79 | + * @param newPortChain updated port chain | ||
80 | + * @param oldPortChain old port chain | ||
81 | + * @return port chain | ||
82 | + */ | ||
83 | + public static PortChain create(PortChain newPortChain, PortChain oldPortChain) { | ||
84 | + return new DefaultPortChain(newPortChain.portChainId(), newPortChain.tenantId(), | ||
85 | + newPortChain.name(), newPortChain.description(), | ||
86 | + newPortChain.portPairGroups(), newPortChain.flowClassifiers(), oldPortChain); | ||
71 | } | 87 | } |
72 | 88 | ||
73 | /** | 89 | /** |
... | @@ -109,7 +125,7 @@ public final class DefaultPortChain implements PortChain { | ... | @@ -109,7 +125,7 @@ public final class DefaultPortChain implements PortChain { |
109 | 125 | ||
110 | @Override | 126 | @Override |
111 | public List<PortPairGroupId> portPairGroups() { | 127 | public List<PortPairGroupId> portPairGroups() { |
112 | - return ImmutableList.copyOf(portPairGroupList); | 128 | + return ImmutableList.copyOf(portPairGroupList); |
113 | } | 129 | } |
114 | 130 | ||
115 | @Override | 131 | @Override |
... | @@ -118,6 +134,11 @@ public final class DefaultPortChain implements PortChain { | ... | @@ -118,6 +134,11 @@ public final class DefaultPortChain implements PortChain { |
118 | } | 134 | } |
119 | 135 | ||
120 | @Override | 136 | @Override |
137 | + public PortChain oldPortChain() { | ||
138 | + return oldPortChain; | ||
139 | + } | ||
140 | + | ||
141 | + @Override | ||
121 | public void addLoadBalancePath(FiveTuple fiveTuple, LoadBalanceId id, | 142 | public void addLoadBalancePath(FiveTuple fiveTuple, LoadBalanceId id, |
122 | List<PortPairId> path) { | 143 | List<PortPairId> path) { |
123 | this.sfcLoadBalanceIdMap.put(fiveTuple, id); | 144 | this.sfcLoadBalanceIdMap.put(fiveTuple, id); |
... | @@ -136,14 +157,14 @@ public final class DefaultPortChain implements PortChain { | ... | @@ -136,14 +157,14 @@ public final class DefaultPortChain implements PortChain { |
136 | 157 | ||
137 | @Override | 158 | @Override |
138 | public void removeSfcClassifiers(LoadBalanceId id, List<DeviceId> classifierList) { | 159 | public void removeSfcClassifiers(LoadBalanceId id, List<DeviceId> classifierList) { |
139 | - List<DeviceId> list = getSfcClassifiers(id); | 160 | + List<DeviceId> list = sfcClassifiersMap.get(id); |
140 | list.removeAll(classifierList); | 161 | list.removeAll(classifierList); |
141 | this.sfcForwardersMap.put(id, list); | 162 | this.sfcForwardersMap.put(id, list); |
142 | } | 163 | } |
143 | 164 | ||
144 | @Override | 165 | @Override |
145 | public void removeSfcForwarders(LoadBalanceId id, List<DeviceId> forwarderList) { | 166 | public void removeSfcForwarders(LoadBalanceId id, List<DeviceId> forwarderList) { |
146 | - List<DeviceId> list = getSfcForwarders(id); | 167 | + List<DeviceId> list = sfcForwardersMap.get(id); |
147 | list.removeAll(forwarderList); | 168 | list.removeAll(forwarderList); |
148 | this.sfcForwardersMap.put(id, list); | 169 | this.sfcForwardersMap.put(id, list); |
149 | } | 170 | } |
... | @@ -192,7 +213,7 @@ public final class DefaultPortChain implements PortChain { | ... | @@ -192,7 +213,7 @@ public final class DefaultPortChain implements PortChain { |
192 | } | 213 | } |
193 | 214 | ||
194 | @Override | 215 | @Override |
195 | - public Optional<LoadBalanceId> matchPath(List<PortPairId> path) { | 216 | + public LoadBalanceId matchPath(List<PortPairId> path) { |
196 | 217 | ||
197 | LoadBalanceId id = null; | 218 | LoadBalanceId id = null; |
198 | for (Map.Entry<LoadBalanceId, List<PortPairId>> entry : sfcLoadBalancePathMap.entrySet()) { | 219 | for (Map.Entry<LoadBalanceId, List<PortPairId>> entry : sfcLoadBalancePathMap.entrySet()) { |
... | @@ -202,7 +223,7 @@ public final class DefaultPortChain implements PortChain { | ... | @@ -202,7 +223,7 @@ public final class DefaultPortChain implements PortChain { |
202 | break; | 223 | break; |
203 | } | 224 | } |
204 | } | 225 | } |
205 | - return Optional.of(id); | 226 | + return id; |
206 | } | 227 | } |
207 | 228 | ||
208 | @Override | 229 | @Override |
... | @@ -267,6 +288,7 @@ public final class DefaultPortChain implements PortChain { | ... | @@ -267,6 +288,7 @@ public final class DefaultPortChain implements PortChain { |
267 | private String description; | 288 | private String description; |
268 | private List<PortPairGroupId> portPairGroupList; | 289 | private List<PortPairGroupId> portPairGroupList; |
269 | private List<FlowClassifierId> flowClassifierList; | 290 | private List<FlowClassifierId> flowClassifierList; |
291 | + private PortChain portChain; | ||
270 | 292 | ||
271 | @Override | 293 | @Override |
272 | public Builder setId(PortChainId portChainId) { | 294 | public Builder setId(PortChainId portChainId) { |
... | @@ -312,7 +334,7 @@ public final class DefaultPortChain implements PortChain { | ... | @@ -312,7 +334,7 @@ public final class DefaultPortChain implements PortChain { |
312 | checkNotNull(portPairGroupList, "Port pair groups cannot be null"); | 334 | checkNotNull(portPairGroupList, "Port pair groups cannot be null"); |
313 | 335 | ||
314 | return new DefaultPortChain(portChainId, tenantId, name, description, | 336 | return new DefaultPortChain(portChainId, tenantId, name, description, |
315 | - portPairGroupList, flowClassifierList); | 337 | + portPairGroupList, flowClassifierList, portChain); |
316 | } | 338 | } |
317 | } | 339 | } |
318 | } | 340 | } | ... | ... |
... | @@ -95,6 +95,13 @@ public final class DefaultPortPairGroup implements PortPairGroup { | ... | @@ -95,6 +95,13 @@ public final class DefaultPortPairGroup implements PortPairGroup { |
95 | } | 95 | } |
96 | 96 | ||
97 | @Override | 97 | @Override |
98 | + public void resetLoad() { | ||
99 | + for (PortPairId portPairId : portPairList) { | ||
100 | + portPairLoadMap.put(portPairId, new Integer(0)); | ||
101 | + } | ||
102 | + } | ||
103 | + | ||
104 | + @Override | ||
98 | public int getLoad(PortPairId portPairId) { | 105 | public int getLoad(PortPairId portPairId) { |
99 | return portPairLoadMap.get(portPairId); | 106 | return portPairLoadMap.get(portPairId); |
100 | } | 107 | } | ... | ... |
... | @@ -16,7 +16,6 @@ | ... | @@ -16,7 +16,6 @@ |
16 | package org.onosproject.vtnrsc; | 16 | package org.onosproject.vtnrsc; |
17 | 17 | ||
18 | import java.util.List; | 18 | import java.util.List; |
19 | -import java.util.Optional; | ||
20 | import java.util.Set; | 19 | import java.util.Set; |
21 | 20 | ||
22 | import org.onosproject.net.DeviceId; | 21 | import org.onosproject.net.DeviceId; |
... | @@ -74,6 +73,13 @@ public interface PortChain { | ... | @@ -74,6 +73,13 @@ public interface PortChain { |
74 | List<FlowClassifierId> flowClassifiers(); | 73 | List<FlowClassifierId> flowClassifiers(); |
75 | 74 | ||
76 | /** | 75 | /** |
76 | + * Returns the old port chain. | ||
77 | + * | ||
78 | + * @return old port chain | ||
79 | + */ | ||
80 | + PortChain oldPortChain(); | ||
81 | + | ||
82 | + /** | ||
77 | * Adds a new load balanced path. | 83 | * Adds a new load balanced path. |
78 | * | 84 | * |
79 | * @param fiveTuple five tuple from the packet | 85 | * @param fiveTuple five tuple from the packet |
... | @@ -182,7 +188,7 @@ public interface PortChain { | ... | @@ -182,7 +188,7 @@ public interface PortChain { |
182 | * @param path load balanced path | 188 | * @param path load balanced path |
183 | * @return load balance id if the path matches, null otherwise. | 189 | * @return load balance id if the path matches, null otherwise. |
184 | */ | 190 | */ |
185 | - Optional<LoadBalanceId> matchPath(List<PortPairId> path); | 191 | + LoadBalanceId matchPath(List<PortPairId> path); |
186 | 192 | ||
187 | /** | 193 | /** |
188 | * Returns whether this port chain is an exact match to the port chain given | 194 | * Returns whether this port chain is an exact match to the port chain given | ... | ... |
... | @@ -67,6 +67,11 @@ public interface PortPairGroup { | ... | @@ -67,6 +67,11 @@ public interface PortPairGroup { |
67 | void addLoad(PortPairId portPairId); | 67 | void addLoad(PortPairId portPairId); |
68 | 68 | ||
69 | /** | 69 | /** |
70 | + * Reset the load for all the port pairs in the group. | ||
71 | + */ | ||
72 | + void resetLoad(); | ||
73 | + | ||
74 | + /** | ||
70 | * Get the load on the given port pair id. | 75 | * Get the load on the given port pair id. |
71 | * | 76 | * |
72 | * @param portPairId port pair id | 77 | * @param portPairId port pair id | ... | ... |
... | @@ -15,8 +15,10 @@ | ... | @@ -15,8 +15,10 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.vtnrsc.flowclassifier.impl; | 16 | package org.onosproject.vtnrsc.flowclassifier.impl; |
17 | 17 | ||
18 | -import static org.slf4j.LoggerFactory.getLogger; | ||
19 | import static com.google.common.base.Preconditions.checkNotNull; | 18 | import static com.google.common.base.Preconditions.checkNotNull; |
19 | +import static org.slf4j.LoggerFactory.getLogger; | ||
20 | + | ||
21 | +import java.util.UUID; | ||
20 | 22 | ||
21 | import org.apache.felix.scr.annotations.Activate; | 23 | import org.apache.felix.scr.annotations.Activate; |
22 | import org.apache.felix.scr.annotations.Component; | 24 | import org.apache.felix.scr.annotations.Component; |
... | @@ -24,6 +26,7 @@ import org.apache.felix.scr.annotations.Deactivate; | ... | @@ -24,6 +26,7 @@ import org.apache.felix.scr.annotations.Deactivate; |
24 | import org.apache.felix.scr.annotations.Reference; | 26 | import org.apache.felix.scr.annotations.Reference; |
25 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 27 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
26 | import org.apache.felix.scr.annotations.Service; | 28 | import org.apache.felix.scr.annotations.Service; |
29 | +import org.onlab.packet.IpPrefix; | ||
27 | import org.onlab.util.KryoNamespace; | 30 | import org.onlab.util.KryoNamespace; |
28 | import org.onosproject.event.AbstractListenerManager; | 31 | import org.onosproject.event.AbstractListenerManager; |
29 | import org.onosproject.store.serializers.KryoNamespaces; | 32 | import org.onosproject.store.serializers.KryoNamespaces; |
... | @@ -33,8 +36,11 @@ import org.onosproject.store.service.EventuallyConsistentMapListener; | ... | @@ -33,8 +36,11 @@ import org.onosproject.store.service.EventuallyConsistentMapListener; |
33 | import org.onosproject.store.service.MultiValuedTimestamp; | 36 | import org.onosproject.store.service.MultiValuedTimestamp; |
34 | import org.onosproject.store.service.StorageService; | 37 | import org.onosproject.store.service.StorageService; |
35 | import org.onosproject.store.service.WallClockTimestamp; | 38 | import org.onosproject.store.service.WallClockTimestamp; |
36 | -import org.onosproject.vtnrsc.FlowClassifierId; | 39 | +import org.onosproject.vtnrsc.DefaultFlowClassifier; |
37 | import org.onosproject.vtnrsc.FlowClassifier; | 40 | import org.onosproject.vtnrsc.FlowClassifier; |
41 | +import org.onosproject.vtnrsc.FlowClassifierId; | ||
42 | +import org.onosproject.vtnrsc.TenantId; | ||
43 | +import org.onosproject.vtnrsc.VirtualPortId; | ||
38 | import org.onosproject.vtnrsc.flowclassifier.FlowClassifierEvent; | 44 | import org.onosproject.vtnrsc.flowclassifier.FlowClassifierEvent; |
39 | import org.onosproject.vtnrsc.flowclassifier.FlowClassifierListener; | 45 | import org.onosproject.vtnrsc.flowclassifier.FlowClassifierListener; |
40 | import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService; | 46 | import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService; |
... | @@ -71,7 +77,8 @@ public class FlowClassifierManager extends AbstractListenerManager<FlowClassifie | ... | @@ -71,7 +77,8 @@ public class FlowClassifierManager extends AbstractListenerManager<FlowClassifie |
71 | KryoNamespace.Builder serializer = KryoNamespace.newBuilder() | 77 | KryoNamespace.Builder serializer = KryoNamespace.newBuilder() |
72 | .register(KryoNamespaces.API) | 78 | .register(KryoNamespaces.API) |
73 | .register(MultiValuedTimestamp.class) | 79 | .register(MultiValuedTimestamp.class) |
74 | - .register(FlowClassifier.class); | 80 | + .register(FlowClassifier.class, FlowClassifierId.class, UUID.class, IpPrefix.class, |
81 | + VirtualPortId.class, DefaultFlowClassifier.class, TenantId.class); | ||
75 | flowClassifierStore = storageService | 82 | flowClassifierStore = storageService |
76 | .<FlowClassifierId, FlowClassifier>eventuallyConsistentMapBuilder() | 83 | .<FlowClassifierId, FlowClassifier>eventuallyConsistentMapBuilder() |
77 | .withName("flowclassifierstore").withSerializer(serializer) | 84 | .withName("flowclassifierstore").withSerializer(serializer) | ... | ... |
... | @@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull; |
19 | import static org.slf4j.LoggerFactory.getLogger; | 19 | import static org.slf4j.LoggerFactory.getLogger; |
20 | 20 | ||
21 | import java.util.Collections; | 21 | import java.util.Collections; |
22 | +import java.util.UUID; | ||
22 | 23 | ||
23 | import org.apache.felix.scr.annotations.Activate; | 24 | import org.apache.felix.scr.annotations.Activate; |
24 | import org.apache.felix.scr.annotations.Component; | 25 | import org.apache.felix.scr.annotations.Component; |
... | @@ -28,6 +29,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; | ... | @@ -28,6 +29,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; |
28 | import org.apache.felix.scr.annotations.Service; | 29 | import org.apache.felix.scr.annotations.Service; |
29 | import org.onlab.util.KryoNamespace; | 30 | import org.onlab.util.KryoNamespace; |
30 | import org.onosproject.event.AbstractListenerManager; | 31 | import org.onosproject.event.AbstractListenerManager; |
32 | +import org.onosproject.net.DeviceId; | ||
31 | import org.onosproject.store.serializers.KryoNamespaces; | 33 | import org.onosproject.store.serializers.KryoNamespaces; |
32 | import org.onosproject.store.service.EventuallyConsistentMap; | 34 | import org.onosproject.store.service.EventuallyConsistentMap; |
33 | import org.onosproject.store.service.EventuallyConsistentMapEvent; | 35 | import org.onosproject.store.service.EventuallyConsistentMapEvent; |
... | @@ -35,8 +37,15 @@ import org.onosproject.store.service.EventuallyConsistentMapListener; | ... | @@ -35,8 +37,15 @@ import org.onosproject.store.service.EventuallyConsistentMapListener; |
35 | import org.onosproject.store.service.MultiValuedTimestamp; | 37 | import org.onosproject.store.service.MultiValuedTimestamp; |
36 | import org.onosproject.store.service.StorageService; | 38 | import org.onosproject.store.service.StorageService; |
37 | import org.onosproject.store.service.WallClockTimestamp; | 39 | import org.onosproject.store.service.WallClockTimestamp; |
40 | +import org.onosproject.vtnrsc.DefaultPortChain; | ||
41 | +import org.onosproject.vtnrsc.FiveTuple; | ||
42 | +import org.onosproject.vtnrsc.FlowClassifierId; | ||
43 | +import org.onosproject.vtnrsc.LoadBalanceId; | ||
38 | import org.onosproject.vtnrsc.PortChain; | 44 | import org.onosproject.vtnrsc.PortChain; |
39 | import org.onosproject.vtnrsc.PortChainId; | 45 | import org.onosproject.vtnrsc.PortChainId; |
46 | +import org.onosproject.vtnrsc.PortPairGroupId; | ||
47 | +import org.onosproject.vtnrsc.PortPairId; | ||
48 | +import org.onosproject.vtnrsc.TenantId; | ||
40 | import org.onosproject.vtnrsc.portchain.PortChainEvent; | 49 | import org.onosproject.vtnrsc.portchain.PortChainEvent; |
41 | import org.onosproject.vtnrsc.portchain.PortChainListener; | 50 | import org.onosproject.vtnrsc.portchain.PortChainListener; |
42 | import org.onosproject.vtnrsc.portchain.PortChainService; | 51 | import org.onosproject.vtnrsc.portchain.PortChainService; |
... | @@ -71,7 +80,9 @@ public class PortChainManager extends AbstractListenerManager<PortChainEvent, Po | ... | @@ -71,7 +80,9 @@ public class PortChainManager extends AbstractListenerManager<PortChainEvent, Po |
71 | KryoNamespace.Builder serializer = KryoNamespace.newBuilder() | 80 | KryoNamespace.Builder serializer = KryoNamespace.newBuilder() |
72 | .register(KryoNamespaces.API) | 81 | .register(KryoNamespaces.API) |
73 | .register(MultiValuedTimestamp.class) | 82 | .register(MultiValuedTimestamp.class) |
74 | - .register(PortChain.class); | 83 | + .register(PortChain.class, PortChainId.class, UUID.class, PortPairGroupId.class, |
84 | + FlowClassifierId.class, FiveTuple.class, LoadBalanceId.class, DeviceId.class, | ||
85 | + DefaultPortChain.class, PortPairId.class, TenantId.class); | ||
75 | 86 | ||
76 | portChainStore = storageService | 87 | portChainStore = storageService |
77 | .<PortChainId, PortChain>eventuallyConsistentMapBuilder() | 88 | .<PortChainId, PortChain>eventuallyConsistentMapBuilder() |
... | @@ -118,7 +129,7 @@ public class PortChainManager extends AbstractListenerManager<PortChainEvent, Po | ... | @@ -118,7 +129,7 @@ public class PortChainManager extends AbstractListenerManager<PortChainEvent, Po |
118 | 129 | ||
119 | portChainStore.put(portChain.portChainId(), portChain); | 130 | portChainStore.put(portChain.portChainId(), portChain); |
120 | if (!portChainStore.containsKey(portChain.portChainId())) { | 131 | if (!portChainStore.containsKey(portChain.portChainId())) { |
121 | - log.debug("The portChain is created failed which identifier was {}", portChain.portChainId() | 132 | + log.error("The portChain created is failed which identifier was {}", portChain.portChainId() |
122 | .toString()); | 133 | .toString()); |
123 | return false; | 134 | return false; |
124 | } | 135 | } |
... | @@ -128,18 +139,20 @@ public class PortChainManager extends AbstractListenerManager<PortChainEvent, Po | ... | @@ -128,18 +139,20 @@ public class PortChainManager extends AbstractListenerManager<PortChainEvent, Po |
128 | @Override | 139 | @Override |
129 | public boolean updatePortChain(PortChain portChain) { | 140 | public boolean updatePortChain(PortChain portChain) { |
130 | checkNotNull(portChain, PORT_CHAIN_NULL); | 141 | checkNotNull(portChain, PORT_CHAIN_NULL); |
131 | - | 142 | + PortChain oldPortChain = null; |
132 | if (!portChainStore.containsKey(portChain.portChainId())) { | 143 | if (!portChainStore.containsKey(portChain.portChainId())) { |
133 | - log.debug("The portChain is not exist whose identifier was {} ", | 144 | + log.warn("The portChain is not exist whose identifier was {} ", |
134 | - portChain.portChainId().toString()); | 145 | + portChain.portChainId().toString()); |
135 | return false; | 146 | return false; |
147 | + } else { | ||
148 | + oldPortChain = portChainStore.get(portChain.portChainId()); | ||
136 | } | 149 | } |
150 | + PortChain newPortChain = DefaultPortChain.create(portChain, oldPortChain); | ||
151 | + portChainStore.put(newPortChain.portChainId(), newPortChain); | ||
137 | 152 | ||
138 | - portChainStore.put(portChain.portChainId(), portChain); | 153 | + if (!newPortChain.equals(portChainStore.get(newPortChain.portChainId()))) { |
139 | - | ||
140 | - if (!portChain.equals(portChainStore.get(portChain.portChainId()))) { | ||
141 | log.debug("The portChain is updated failed whose identifier was {} ", | 154 | log.debug("The portChain is updated failed whose identifier was {} ", |
142 | - portChain.portChainId().toString()); | 155 | + newPortChain.portChainId().toString()); |
143 | return false; | 156 | return false; |
144 | } | 157 | } |
145 | return true; | 158 | return true; | ... | ... |
... | @@ -38,6 +38,7 @@ import org.onosproject.vtnrsc.portpair.PortPairService; | ... | @@ -38,6 +38,7 @@ import org.onosproject.vtnrsc.portpair.PortPairService; |
38 | import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService; | 38 | import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService; |
39 | import org.slf4j.Logger; | 39 | import org.slf4j.Logger; |
40 | 40 | ||
41 | +import com.google.common.collect.ImmutableList; | ||
41 | import com.google.common.collect.Lists; | 42 | import com.google.common.collect.Lists; |
42 | 43 | ||
43 | /** | 44 | /** |
... | @@ -86,13 +87,13 @@ public class PortChainSfMapManager implements PortChainSfMapService { | ... | @@ -86,13 +87,13 @@ public class PortChainSfMapManager implements PortChainSfMapService { |
86 | List<PortPairGroupId> portPairGrpList = portChain.portPairGroups(); | 87 | List<PortPairGroupId> portPairGrpList = portChain.portPairGroups(); |
87 | ListIterator<PortPairGroupId> listGrpIterator = portPairGrpList.listIterator(); | 88 | ListIterator<PortPairGroupId> listGrpIterator = portPairGrpList.listIterator(); |
88 | 89 | ||
89 | - while (listGrpIterator.next() != null) { | 90 | + while (listGrpIterator.hasNext()) { |
90 | PortPairGroupId portPairGroupId = listGrpIterator.next(); | 91 | PortPairGroupId portPairGroupId = listGrpIterator.next(); |
91 | PortPairGroup portPairGroup = portPairGroupService.getPortPairGroup(portPairGroupId); | 92 | PortPairGroup portPairGroup = portPairGroupService.getPortPairGroup(portPairGroupId); |
92 | ServiceFunctionGroup sfg = new ServiceFunctionGroup(portPairGroup.name(), portPairGroup.description(), | 93 | ServiceFunctionGroup sfg = new ServiceFunctionGroup(portPairGroup.name(), portPairGroup.description(), |
93 | portPairGroup.portPairLoadMap()); | 94 | portPairGroup.portPairLoadMap()); |
94 | serviceFunctionGroupList.add(sfg); | 95 | serviceFunctionGroupList.add(sfg); |
95 | } | 96 | } |
96 | - return serviceFunctionGroupList; | 97 | + return ImmutableList.copyOf(serviceFunctionGroupList); |
97 | } | 98 | } |
98 | } | 99 | } | ... | ... |
... | @@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull; |
19 | import static org.slf4j.LoggerFactory.getLogger; | 19 | import static org.slf4j.LoggerFactory.getLogger; |
20 | 20 | ||
21 | import java.util.Collections; | 21 | import java.util.Collections; |
22 | +import java.util.UUID; | ||
22 | 23 | ||
23 | import org.apache.felix.scr.annotations.Activate; | 24 | import org.apache.felix.scr.annotations.Activate; |
24 | import org.apache.felix.scr.annotations.Component; | 25 | import org.apache.felix.scr.annotations.Component; |
... | @@ -35,8 +36,10 @@ import org.onosproject.store.service.EventuallyConsistentMapListener; | ... | @@ -35,8 +36,10 @@ import org.onosproject.store.service.EventuallyConsistentMapListener; |
35 | import org.onosproject.store.service.MultiValuedTimestamp; | 36 | import org.onosproject.store.service.MultiValuedTimestamp; |
36 | import org.onosproject.store.service.StorageService; | 37 | import org.onosproject.store.service.StorageService; |
37 | import org.onosproject.store.service.WallClockTimestamp; | 38 | import org.onosproject.store.service.WallClockTimestamp; |
39 | +import org.onosproject.vtnrsc.DefaultPortPair; | ||
38 | import org.onosproject.vtnrsc.PortPair; | 40 | import org.onosproject.vtnrsc.PortPair; |
39 | import org.onosproject.vtnrsc.PortPairId; | 41 | import org.onosproject.vtnrsc.PortPairId; |
42 | +import org.onosproject.vtnrsc.TenantId; | ||
40 | import org.onosproject.vtnrsc.portpair.PortPairEvent; | 43 | import org.onosproject.vtnrsc.portpair.PortPairEvent; |
41 | import org.onosproject.vtnrsc.portpair.PortPairListener; | 44 | import org.onosproject.vtnrsc.portpair.PortPairListener; |
42 | import org.onosproject.vtnrsc.portpair.PortPairService; | 45 | import org.onosproject.vtnrsc.portpair.PortPairService; |
... | @@ -72,7 +75,7 @@ public class PortPairManager extends AbstractListenerManager<PortPairEvent, Port | ... | @@ -72,7 +75,7 @@ public class PortPairManager extends AbstractListenerManager<PortPairEvent, Port |
72 | KryoNamespace.Builder serializer = KryoNamespace.newBuilder() | 75 | KryoNamespace.Builder serializer = KryoNamespace.newBuilder() |
73 | .register(KryoNamespaces.API) | 76 | .register(KryoNamespaces.API) |
74 | .register(MultiValuedTimestamp.class) | 77 | .register(MultiValuedTimestamp.class) |
75 | - .register(PortPair.class); | 78 | + .register(PortPair.class, PortPairId.class, UUID.class, DefaultPortPair.class, TenantId.class); |
76 | 79 | ||
77 | portPairStore = storageService.<PortPairId, PortPair>eventuallyConsistentMapBuilder() | 80 | portPairStore = storageService.<PortPairId, PortPair>eventuallyConsistentMapBuilder() |
78 | .withName("portpairstore") | 81 | .withName("portpairstore") | ... | ... |
... | @@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull; |
19 | import static org.slf4j.LoggerFactory.getLogger; | 19 | import static org.slf4j.LoggerFactory.getLogger; |
20 | 20 | ||
21 | import java.util.Collections; | 21 | import java.util.Collections; |
22 | +import java.util.UUID; | ||
22 | 23 | ||
23 | import org.apache.felix.scr.annotations.Activate; | 24 | import org.apache.felix.scr.annotations.Activate; |
24 | import org.apache.felix.scr.annotations.Component; | 25 | import org.apache.felix.scr.annotations.Component; |
... | @@ -35,8 +36,11 @@ import org.onosproject.store.service.EventuallyConsistentMapListener; | ... | @@ -35,8 +36,11 @@ import org.onosproject.store.service.EventuallyConsistentMapListener; |
35 | import org.onosproject.store.service.MultiValuedTimestamp; | 36 | import org.onosproject.store.service.MultiValuedTimestamp; |
36 | import org.onosproject.store.service.StorageService; | 37 | import org.onosproject.store.service.StorageService; |
37 | import org.onosproject.store.service.WallClockTimestamp; | 38 | import org.onosproject.store.service.WallClockTimestamp; |
39 | +import org.onosproject.vtnrsc.DefaultPortPairGroup; | ||
38 | import org.onosproject.vtnrsc.PortPairGroup; | 40 | import org.onosproject.vtnrsc.PortPairGroup; |
39 | import org.onosproject.vtnrsc.PortPairGroupId; | 41 | import org.onosproject.vtnrsc.PortPairGroupId; |
42 | +import org.onosproject.vtnrsc.PortPairId; | ||
43 | +import org.onosproject.vtnrsc.TenantId; | ||
40 | import org.onosproject.vtnrsc.portpairgroup.PortPairGroupEvent; | 44 | import org.onosproject.vtnrsc.portpairgroup.PortPairGroupEvent; |
41 | import org.onosproject.vtnrsc.portpairgroup.PortPairGroupListener; | 45 | import org.onosproject.vtnrsc.portpairgroup.PortPairGroupListener; |
42 | import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService; | 46 | import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService; |
... | @@ -71,7 +75,8 @@ public class PortPairGroupManager extends AbstractListenerManager<PortPairGroupE | ... | @@ -71,7 +75,8 @@ public class PortPairGroupManager extends AbstractListenerManager<PortPairGroupE |
71 | KryoNamespace.Builder serializer = KryoNamespace.newBuilder() | 75 | KryoNamespace.Builder serializer = KryoNamespace.newBuilder() |
72 | .register(KryoNamespaces.API) | 76 | .register(KryoNamespaces.API) |
73 | .register(MultiValuedTimestamp.class) | 77 | .register(MultiValuedTimestamp.class) |
74 | - .register(PortPairGroup.class); | 78 | + .register(PortPairGroup.class, PortPairGroupId.class, UUID.class, DefaultPortPairGroup.class, |
79 | + TenantId.class, PortPairId.class); | ||
75 | 80 | ||
76 | portPairGroupStore = storageService | 81 | portPairGroupStore = storageService |
77 | .<PortPairGroupId, PortPairGroup>eventuallyConsistentMapBuilder() | 82 | .<PortPairGroupId, PortPairGroup>eventuallyConsistentMapBuilder() | ... | ... |
apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortChainDeviceMapWebResource.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2014-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.vtnweb.resources; | ||
17 | + | ||
18 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
19 | +import static org.onlab.util.Tools.nullIsNotFound; | ||
20 | + | ||
21 | +import java.util.Set; | ||
22 | + | ||
23 | +import javax.ws.rs.Consumes; | ||
24 | +import javax.ws.rs.GET; | ||
25 | +import javax.ws.rs.Path; | ||
26 | +import javax.ws.rs.PathParam; | ||
27 | +import javax.ws.rs.Produces; | ||
28 | +import javax.ws.rs.core.MediaType; | ||
29 | +import javax.ws.rs.core.Response; | ||
30 | + | ||
31 | +import org.onosproject.codec.CodecContext; | ||
32 | +import org.onosproject.rest.AbstractWebResource; | ||
33 | +import org.onosproject.vtnrsc.LoadBalanceId; | ||
34 | +import org.onosproject.vtnrsc.PortChain; | ||
35 | +import org.onosproject.vtnrsc.PortChainId; | ||
36 | +import org.onosproject.vtnrsc.portchain.PortChainService; | ||
37 | + | ||
38 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
39 | + | ||
40 | +/** | ||
41 | + * Query and program port chain. | ||
42 | + */ | ||
43 | + | ||
44 | +@Path("portChainDeviceMap") | ||
45 | +public class PortChainDeviceMapWebResource extends AbstractWebResource { | ||
46 | + | ||
47 | + public static final String PORT_CHAIN_NOT_FOUND = "Port chain not found"; | ||
48 | + public static final String PORT_CHAIN_ID_EXIST = "Port chain exists"; | ||
49 | + public static final String PORT_CHAIN_ID_NOT_EXIST = "Port chain does not exist with identifier"; | ||
50 | + | ||
51 | + private static final String NAME = "name"; | ||
52 | + private static final String ID = "id"; | ||
53 | + private static final String CLASSIFIERS = "classifiers"; | ||
54 | + private static final String FORWARDERS = "forwarders"; | ||
55 | + private static final String LOADBALANCEID = "loadBalanceId"; | ||
56 | + | ||
57 | + /** | ||
58 | + * Get details of a specified port chain id. | ||
59 | + * | ||
60 | + * @param id port chain id | ||
61 | + * @return 200 OK, 404 if given identifier does not exist | ||
62 | + */ | ||
63 | + @GET | ||
64 | + @Path("{chain_id}") | ||
65 | + @Produces(MediaType.APPLICATION_JSON) | ||
66 | + @Consumes(MediaType.APPLICATION_JSON) | ||
67 | + public Response getPortChainDeviceMap(@PathParam("chain_id") String id) { | ||
68 | + | ||
69 | + PortChain portChain = nullIsNotFound(get(PortChainService.class).getPortChain(PortChainId.of(id)), | ||
70 | + PORT_CHAIN_NOT_FOUND); | ||
71 | + ObjectNode result = mapper().createObjectNode(); | ||
72 | + result.set("portChainDeviceMap", encode(portChain, this)); | ||
73 | + | ||
74 | + return ok(result.toString()).build(); | ||
75 | + } | ||
76 | + | ||
77 | + private ObjectNode encode(PortChain portChain, CodecContext context) { | ||
78 | + checkNotNull(portChain, "portChain cannot be null"); | ||
79 | + ObjectNode result = context.mapper().createObjectNode(); | ||
80 | + result.put(ID, portChain.portChainId().toString()) | ||
81 | + .put(NAME, portChain.name()); | ||
82 | + | ||
83 | + Set<LoadBalanceId> loadBalanceIds = portChain.getLoadBalancePathMapKeys(); | ||
84 | + for (LoadBalanceId id : loadBalanceIds) { | ||
85 | + result.put(LOADBALANCEID, id.toString()) | ||
86 | + .put(CLASSIFIERS, portChain.getSfcClassifiers(id).toString()) | ||
87 | + .put(FORWARDERS, portChain.getSfcForwarders(id).toString()); | ||
88 | + } | ||
89 | + return result; | ||
90 | + } | ||
91 | +} |
apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortChainSfMapWebResource.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2016-present 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.vtnweb.resources; | ||
17 | + | ||
18 | +import static org.onlab.util.Tools.nullIsNotFound; | ||
19 | + | ||
20 | +import javax.ws.rs.Consumes; | ||
21 | +import javax.ws.rs.GET; | ||
22 | +import javax.ws.rs.Path; | ||
23 | +import javax.ws.rs.PathParam; | ||
24 | +import javax.ws.rs.Produces; | ||
25 | +import javax.ws.rs.core.MediaType; | ||
26 | +import javax.ws.rs.core.Response; | ||
27 | + | ||
28 | +import org.onosproject.rest.AbstractWebResource; | ||
29 | +import org.onosproject.vtnrsc.PortChainId; | ||
30 | +import org.onosproject.vtnrsc.ServiceFunctionGroup; | ||
31 | +import org.onosproject.vtnrsc.portchainsfmap.PortChainSfMapService; | ||
32 | + | ||
33 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
34 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
35 | + | ||
36 | +/** | ||
37 | + * Query service function and load details by port chain. | ||
38 | + */ | ||
39 | + | ||
40 | +@Path("portChainSfMap") | ||
41 | +public class PortChainSfMapWebResource extends AbstractWebResource { | ||
42 | + | ||
43 | + public static final String PORT_CHAIN_NOT_FOUND = "Port chain not found"; | ||
44 | + public static final String PORT_CHAIN_ID_EXIST = "Port chain exists"; | ||
45 | + public static final String PORT_CHAIN_ID_NOT_EXIST = "Port chain does not exist with identifier"; | ||
46 | + | ||
47 | + /** | ||
48 | + * Get service function details of a specified port chain id. | ||
49 | + * | ||
50 | + * @param id port chain id | ||
51 | + * @return 200 OK, 404 if given identifier does not exist | ||
52 | + */ | ||
53 | + @GET | ||
54 | + @Path("{chainId}") | ||
55 | + @Produces(MediaType.APPLICATION_JSON) | ||
56 | + @Consumes(MediaType.APPLICATION_JSON) | ||
57 | + public Response getPortChainSfMap(@PathParam("chainId") String id) { | ||
58 | + | ||
59 | + Iterable<ServiceFunctionGroup> serviceFunctionGroups = nullIsNotFound(get(PortChainSfMapService.class) | ||
60 | + .getServiceFunctions(PortChainId.of(id)), | ||
61 | + PORT_CHAIN_NOT_FOUND); | ||
62 | + ObjectNode result = mapper().createObjectNode(); | ||
63 | + ArrayNode portChainSfMap = result.putArray("portChainSfMap"); | ||
64 | + if (serviceFunctionGroups != null) { | ||
65 | + for (final ServiceFunctionGroup serviceFunctionGroup : serviceFunctionGroups) { | ||
66 | + portChainSfMap.add(codec(ServiceFunctionGroup.class).encode(serviceFunctionGroup, this)); | ||
67 | + } | ||
68 | + } | ||
69 | + return ok(result.toString()).build(); | ||
70 | + } | ||
71 | +} |
... | @@ -35,7 +35,9 @@ public class VtnWebApplication extends AbstractWebApplication { | ... | @@ -35,7 +35,9 @@ public class VtnWebApplication extends AbstractWebApplication { |
35 | PortPairWebResource.class, | 35 | PortPairWebResource.class, |
36 | FloatingIpWebResource.class, | 36 | FloatingIpWebResource.class, |
37 | RouterWebResource.class, | 37 | RouterWebResource.class, |
38 | - ClassifierWebResource.class); | 38 | + ClassifierWebResource.class, |
39 | + PortChainSfMapWebResource.class, | ||
40 | + PortChainDeviceMapWebResource.class); | ||
39 | } | 41 | } |
40 | } | 42 | } |
41 | 43 | ... | ... |
... | @@ -80,8 +80,10 @@ public final class FlowClassifierCodec extends JsonCodec<FlowClassifier> { | ... | @@ -80,8 +80,10 @@ public final class FlowClassifierCodec extends JsonCodec<FlowClassifier> { |
80 | resultBuilder.setProtocol(protocol); | 80 | resultBuilder.setProtocol(protocol); |
81 | } | 81 | } |
82 | 82 | ||
83 | - int priority = (json.get(PRIORITY)).asInt(); | 83 | + if (json.get(PRIORITY) != null && !(json.get(PRIORITY)).asText().equals("null")) { |
84 | - resultBuilder.setPriority(priority); | 84 | + int priority = (json.get(PRIORITY)).asInt(); |
85 | + resultBuilder.setPriority(priority); | ||
86 | + } | ||
85 | 87 | ||
86 | int minSrcPortRange = (json.get(MIN_SRC_PORT_RANGE)).asInt(); | 88 | int minSrcPortRange = (json.get(MIN_SRC_PORT_RANGE)).asInt(); |
87 | resultBuilder.setMinSrcPortRange(minSrcPortRange); | 89 | resultBuilder.setMinSrcPortRange(minSrcPortRange); | ... | ... |
1 | /* | 1 | /* |
2 | - * Copyright 2015-present Open Networking Laboratory | 2 | + * Copyright 2015 Open Networking Laboratory |
3 | * | 3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. | 5 | * you may not use this file except in compliance with the License. |
... | @@ -13,8 +13,32 @@ | ... | @@ -13,8 +13,32 @@ |
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | +package org.onosproject.vtnweb.web; | ||
17 | + | ||
18 | + | ||
19 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
20 | + | ||
21 | +import org.onosproject.codec.CodecContext; | ||
22 | +import org.onosproject.codec.JsonCodec; | ||
23 | +import org.onosproject.vtnrsc.ServiceFunctionGroup; | ||
24 | + | ||
25 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
16 | 26 | ||
17 | /** | 27 | /** |
18 | - * SFC Service manager for interacting with SFC. | 28 | + * Service function JSON codec. |
19 | */ | 29 | */ |
20 | -package org.onosproject.sfc.forwarder.impl; | 30 | +public final class ServiceFunctionCodec extends JsonCodec<ServiceFunctionGroup> { |
31 | + | ||
32 | + private static final String NAME = "name"; | ||
33 | + private static final String DESCRIPTION = "description"; | ||
34 | + private static final String PORT_PAIR_LOAD = "port_pair_load"; | ||
35 | + @Override | ||
36 | + public ObjectNode encode(ServiceFunctionGroup serviceFunction, CodecContext context) { | ||
37 | + checkNotNull(serviceFunction, "service cannot be null"); | ||
38 | + ObjectNode result = context.mapper().createObjectNode() | ||
39 | + .put(NAME, serviceFunction.name()) | ||
40 | + .put(DESCRIPTION, serviceFunction.description()) | ||
41 | + .put(PORT_PAIR_LOAD, serviceFunction.portPairLoadMap().toString()); | ||
42 | + return result; | ||
43 | + } | ||
44 | +} | ... | ... |
... | @@ -25,6 +25,7 @@ import org.onosproject.vtnrsc.FlowClassifier; | ... | @@ -25,6 +25,7 @@ import org.onosproject.vtnrsc.FlowClassifier; |
25 | import org.onosproject.vtnrsc.PortChain; | 25 | import org.onosproject.vtnrsc.PortChain; |
26 | import org.onosproject.vtnrsc.PortPair; | 26 | import org.onosproject.vtnrsc.PortPair; |
27 | import org.onosproject.vtnrsc.PortPairGroup; | 27 | import org.onosproject.vtnrsc.PortPairGroup; |
28 | +import org.onosproject.vtnrsc.ServiceFunctionGroup; | ||
28 | import org.slf4j.Logger; | 29 | import org.slf4j.Logger; |
29 | import org.slf4j.LoggerFactory; | 30 | import org.slf4j.LoggerFactory; |
30 | 31 | ||
... | @@ -45,7 +46,7 @@ public class VtnCodecRegistrator { | ... | @@ -45,7 +46,7 @@ public class VtnCodecRegistrator { |
45 | codecService.registerCodec(PortPairGroup.class, new PortPairGroupCodec()); | 46 | codecService.registerCodec(PortPairGroup.class, new PortPairGroupCodec()); |
46 | codecService.registerCodec(FlowClassifier.class, new FlowClassifierCodec()); | 47 | codecService.registerCodec(FlowClassifier.class, new FlowClassifierCodec()); |
47 | codecService.registerCodec(PortChain.class, new PortChainCodec()); | 48 | codecService.registerCodec(PortChain.class, new PortChainCodec()); |
48 | - | 49 | + codecService.registerCodec(ServiceFunctionGroup.class, new ServiceFunctionCodec()); |
49 | log.info("Started"); | 50 | log.info("Started"); |
50 | } | 51 | } |
51 | 52 | ... | ... |
apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortChainDeviceMapResourceTest.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2016-present 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.vtnweb.resources; | ||
17 | + | ||
18 | +import static org.easymock.EasyMock.anyObject; | ||
19 | +import static org.easymock.EasyMock.createMock; | ||
20 | +import static org.easymock.EasyMock.expect; | ||
21 | +import static org.easymock.EasyMock.replay; | ||
22 | +import static org.hamcrest.Matchers.is; | ||
23 | +import static org.hamcrest.Matchers.notNullValue; | ||
24 | +import static org.junit.Assert.assertThat; | ||
25 | + | ||
26 | +import java.util.HashSet; | ||
27 | +import java.util.List; | ||
28 | +import java.util.Objects; | ||
29 | +import java.util.Set; | ||
30 | + | ||
31 | +import javax.ws.rs.client.WebTarget; | ||
32 | + | ||
33 | +import org.junit.After; | ||
34 | +import org.junit.Before; | ||
35 | +import org.junit.Test; | ||
36 | +import org.onlab.osgi.ServiceDirectory; | ||
37 | +import org.onlab.osgi.TestServiceDirectory; | ||
38 | +import org.onlab.rest.BaseResource; | ||
39 | +import org.onosproject.codec.CodecService; | ||
40 | +import org.onosproject.net.DeviceId; | ||
41 | +import org.onosproject.vtnrsc.FiveTuple; | ||
42 | +import org.onosproject.vtnrsc.FlowClassifierId; | ||
43 | +import org.onosproject.vtnrsc.LoadBalanceId; | ||
44 | +import org.onosproject.vtnrsc.PortChain; | ||
45 | +import org.onosproject.vtnrsc.PortChainId; | ||
46 | +import org.onosproject.vtnrsc.PortPairGroupId; | ||
47 | +import org.onosproject.vtnrsc.PortPairId; | ||
48 | +import org.onosproject.vtnrsc.TenantId; | ||
49 | +import org.onosproject.vtnrsc.portchain.PortChainService; | ||
50 | +import org.onosproject.vtnweb.web.SfcCodecContext; | ||
51 | + | ||
52 | +import com.eclipsesource.json.Json; | ||
53 | +import com.eclipsesource.json.JsonObject; | ||
54 | +import com.google.common.collect.ImmutableList; | ||
55 | +import com.google.common.collect.Lists; | ||
56 | + | ||
57 | +/** | ||
58 | + * Unit tests for port chain device map REST APIs. | ||
59 | + */ | ||
60 | +public class PortChainDeviceMapResourceTest extends VtnResourceTest { | ||
61 | + | ||
62 | + final PortChainService portChainService = createMock(PortChainService.class); | ||
63 | + | ||
64 | + PortChainId portChainId1 = PortChainId.of("78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae"); | ||
65 | + TenantId tenantId1 = TenantId.tenantId("d382007aa9904763a801f68ecf065cf5"); | ||
66 | + private final List<PortPairGroupId> portPairGroupList1 = Lists.newArrayList(); | ||
67 | + private final List<FlowClassifierId> flowClassifierList1 = Lists.newArrayList(); | ||
68 | + | ||
69 | + final MockPortChain portChain1 = new MockPortChain(portChainId1, tenantId1, "portChain1", | ||
70 | + "Mock port chain", portPairGroupList1, | ||
71 | + flowClassifierList1); | ||
72 | + | ||
73 | + /** | ||
74 | + * Mock class for a port chain. | ||
75 | + */ | ||
76 | + private static class MockPortChain implements PortChain { | ||
77 | + | ||
78 | + private final PortChainId portChainId; | ||
79 | + private final TenantId tenantId; | ||
80 | + private final String name; | ||
81 | + private final String description; | ||
82 | + private final List<PortPairGroupId> portPairGroupList; | ||
83 | + private final List<FlowClassifierId> flowClassifierList; | ||
84 | + | ||
85 | + public MockPortChain(PortChainId portChainId, TenantId tenantId, | ||
86 | + String name, String description, | ||
87 | + List<PortPairGroupId> portPairGroupList, | ||
88 | + List<FlowClassifierId> flowClassifierList) { | ||
89 | + | ||
90 | + this.portChainId = portChainId; | ||
91 | + this.tenantId = tenantId; | ||
92 | + this.name = name; | ||
93 | + this.description = description; | ||
94 | + this.portPairGroupList = portPairGroupList; | ||
95 | + this.flowClassifierList = flowClassifierList; | ||
96 | + } | ||
97 | + | ||
98 | + @Override | ||
99 | + public PortChainId portChainId() { | ||
100 | + return portChainId; | ||
101 | + } | ||
102 | + | ||
103 | + @Override | ||
104 | + public TenantId tenantId() { | ||
105 | + return tenantId; | ||
106 | + } | ||
107 | + | ||
108 | + @Override | ||
109 | + public String name() { | ||
110 | + return name; | ||
111 | + } | ||
112 | + | ||
113 | + @Override | ||
114 | + public String description() { | ||
115 | + return description; | ||
116 | + } | ||
117 | + | ||
118 | + @Override | ||
119 | + public List<PortPairGroupId> portPairGroups() { | ||
120 | + return ImmutableList.copyOf(portPairGroupList); | ||
121 | + } | ||
122 | + | ||
123 | + @Override | ||
124 | + public List<FlowClassifierId> flowClassifiers() { | ||
125 | + return ImmutableList.copyOf(flowClassifierList); | ||
126 | + } | ||
127 | + | ||
128 | + @Override | ||
129 | + public boolean exactMatch(PortChain portChain) { | ||
130 | + return this.equals(portChain) && | ||
131 | + Objects.equals(this.portChainId, portChain.portChainId()) && | ||
132 | + Objects.equals(this.tenantId, portChain.tenantId()); | ||
133 | + } | ||
134 | + | ||
135 | + @Override | ||
136 | + public void addLoadBalancePath(FiveTuple fiveTuple, LoadBalanceId id, List<PortPairId> path) { | ||
137 | + } | ||
138 | + | ||
139 | + @Override | ||
140 | + public LoadBalanceId getLoadBalanceId(FiveTuple fiveTuple) { | ||
141 | + return null; | ||
142 | + } | ||
143 | + | ||
144 | + @Override | ||
145 | + public Set<FiveTuple> getLoadBalanceIdMapKeys() { | ||
146 | + return null; | ||
147 | + } | ||
148 | + | ||
149 | + @Override | ||
150 | + public List<PortPairId> getLoadBalancePath(LoadBalanceId id) { | ||
151 | + return null; | ||
152 | + } | ||
153 | + | ||
154 | + @Override | ||
155 | + public List<PortPairId> getLoadBalancePath(FiveTuple fiveTuple) { | ||
156 | + return null; | ||
157 | + } | ||
158 | + | ||
159 | + @Override | ||
160 | + public LoadBalanceId matchPath(List<PortPairId> path) { | ||
161 | + return null; | ||
162 | + } | ||
163 | + | ||
164 | + @Override | ||
165 | + public int getLoadBalancePathSize() { | ||
166 | + return 0; | ||
167 | + } | ||
168 | + | ||
169 | + @Override | ||
170 | + public void addSfcClassifiers(LoadBalanceId id, List<DeviceId> classifierList) { | ||
171 | + } | ||
172 | + | ||
173 | + @Override | ||
174 | + public void addSfcForwarders(LoadBalanceId id, List<DeviceId> forwarderList) { | ||
175 | + } | ||
176 | + | ||
177 | + @Override | ||
178 | + public void removeSfcClassifiers(LoadBalanceId id, List<DeviceId> classifierList) { | ||
179 | + } | ||
180 | + | ||
181 | + @Override | ||
182 | + public void removeSfcForwarders(LoadBalanceId id, List<DeviceId> forwarderList) { | ||
183 | + } | ||
184 | + | ||
185 | + @Override | ||
186 | + public List<DeviceId> getSfcClassifiers(LoadBalanceId id) { | ||
187 | + DeviceId deviceId1 = DeviceId.deviceId("of:000000000000001"); | ||
188 | + List<DeviceId> classifierList = Lists.newArrayList(); | ||
189 | + classifierList.add(deviceId1); | ||
190 | + return classifierList; | ||
191 | + } | ||
192 | + | ||
193 | + @Override | ||
194 | + public List<DeviceId> getSfcForwarders(LoadBalanceId id) { | ||
195 | + DeviceId deviceId1 = DeviceId.deviceId("of:000000000000002"); | ||
196 | + DeviceId deviceId2 = DeviceId.deviceId("of:000000000000003"); | ||
197 | + List<DeviceId> forwarderList = Lists.newArrayList(); | ||
198 | + forwarderList.add(deviceId1); | ||
199 | + forwarderList.add(deviceId2); | ||
200 | + return forwarderList; | ||
201 | + } | ||
202 | + | ||
203 | + @Override | ||
204 | + public Set<LoadBalanceId> getLoadBalancePathMapKeys() { | ||
205 | + LoadBalanceId id = LoadBalanceId.of((byte) 1); | ||
206 | + Set<LoadBalanceId> set = new HashSet<LoadBalanceId>(); | ||
207 | + set.add(id); | ||
208 | + return set; | ||
209 | + } | ||
210 | + | ||
211 | + @Override | ||
212 | + public PortChain oldPortChain() { | ||
213 | + return null; | ||
214 | + } | ||
215 | + } | ||
216 | + | ||
217 | + /** | ||
218 | + * Sets up the global values for all the tests. | ||
219 | + */ | ||
220 | + @Before | ||
221 | + public void setUpTest() { | ||
222 | + SfcCodecContext context = new SfcCodecContext(); | ||
223 | + ServiceDirectory testDirectory = new TestServiceDirectory() | ||
224 | + .add(PortChainService.class, portChainService) | ||
225 | + .add(CodecService.class, context.codecManager()); | ||
226 | + BaseResource.setServiceDirectory(testDirectory); | ||
227 | + } | ||
228 | + | ||
229 | + /** | ||
230 | + * Cleans up. | ||
231 | + */ | ||
232 | + @After | ||
233 | + public void tearDownTest() { | ||
234 | + } | ||
235 | + | ||
236 | + /** | ||
237 | + * Tests the result of a rest api GET for port chain id. | ||
238 | + */ | ||
239 | + @Test | ||
240 | + public void testGetPortChainDeviceMap() { | ||
241 | + | ||
242 | + expect(portChainService.getPortChain(anyObject())).andReturn(portChain1).anyTimes(); | ||
243 | + replay(portChainService); | ||
244 | + | ||
245 | + final WebTarget wt = target(); | ||
246 | + final String response = wt.path("portChainDeviceMap/1278dcd4-459f-62ed-754b-87fc5e4a6751").request() | ||
247 | + .get(String.class); | ||
248 | + final JsonObject result = Json.parse(response).asObject(); | ||
249 | + assertThat(result, notNullValue()); | ||
250 | + assertThat(result.names().get(0), is("portChainDeviceMap")); | ||
251 | + | ||
252 | + } | ||
253 | +} |
... | @@ -15,10 +15,29 @@ | ... | @@ -15,10 +15,29 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.vtnweb.resources; | 16 | package org.onosproject.vtnweb.resources; |
17 | 17 | ||
18 | -import com.eclipsesource.json.Json; | 18 | +import static org.easymock.EasyMock.anyObject; |
19 | -import com.eclipsesource.json.JsonObject; | 19 | +import static org.easymock.EasyMock.createMock; |
20 | -import com.google.common.collect.ImmutableList; | 20 | +import static org.easymock.EasyMock.expect; |
21 | -import com.google.common.collect.Lists; | 21 | +import static org.easymock.EasyMock.replay; |
22 | +import static org.hamcrest.Matchers.containsString; | ||
23 | +import static org.hamcrest.Matchers.is; | ||
24 | +import static org.hamcrest.Matchers.notNullValue; | ||
25 | +import static org.junit.Assert.assertThat; | ||
26 | +import static org.junit.Assert.fail; | ||
27 | + | ||
28 | +import java.io.InputStream; | ||
29 | +import java.net.HttpURLConnection; | ||
30 | +import java.util.HashSet; | ||
31 | +import java.util.List; | ||
32 | +import java.util.Objects; | ||
33 | +import java.util.Set; | ||
34 | + | ||
35 | +import javax.ws.rs.NotFoundException; | ||
36 | +import javax.ws.rs.client.Entity; | ||
37 | +import javax.ws.rs.client.WebTarget; | ||
38 | +import javax.ws.rs.core.MediaType; | ||
39 | +import javax.ws.rs.core.Response; | ||
40 | + | ||
22 | import org.junit.After; | 41 | import org.junit.After; |
23 | import org.junit.Before; | 42 | import org.junit.Before; |
24 | import org.junit.Test; | 43 | import org.junit.Test; |
... | @@ -38,28 +57,10 @@ import org.onosproject.vtnrsc.TenantId; | ... | @@ -38,28 +57,10 @@ import org.onosproject.vtnrsc.TenantId; |
38 | import org.onosproject.vtnrsc.portchain.PortChainService; | 57 | import org.onosproject.vtnrsc.portchain.PortChainService; |
39 | import org.onosproject.vtnweb.web.SfcCodecContext; | 58 | import org.onosproject.vtnweb.web.SfcCodecContext; |
40 | 59 | ||
41 | -import javax.ws.rs.NotFoundException; | 60 | +import com.eclipsesource.json.Json; |
42 | -import javax.ws.rs.client.Entity; | 61 | +import com.eclipsesource.json.JsonObject; |
43 | -import javax.ws.rs.client.WebTarget; | 62 | +import com.google.common.collect.ImmutableList; |
44 | -import javax.ws.rs.core.MediaType; | 63 | +import com.google.common.collect.Lists; |
45 | -import javax.ws.rs.core.Response; | ||
46 | -import java.io.InputStream; | ||
47 | -import java.net.HttpURLConnection; | ||
48 | -import java.util.HashSet; | ||
49 | -import java.util.List; | ||
50 | -import java.util.Objects; | ||
51 | -import java.util.Optional; | ||
52 | -import java.util.Set; | ||
53 | - | ||
54 | -import static org.easymock.EasyMock.anyObject; | ||
55 | -import static org.easymock.EasyMock.createMock; | ||
56 | -import static org.easymock.EasyMock.expect; | ||
57 | -import static org.easymock.EasyMock.replay; | ||
58 | -import static org.hamcrest.Matchers.containsString; | ||
59 | -import static org.hamcrest.Matchers.is; | ||
60 | -import static org.hamcrest.Matchers.notNullValue; | ||
61 | -import static org.junit.Assert.assertThat; | ||
62 | -import static org.junit.Assert.fail; | ||
63 | 64 | ||
64 | /** | 65 | /** |
65 | * Unit tests for port chain REST APIs. | 66 | * Unit tests for port chain REST APIs. |
... | @@ -165,7 +166,7 @@ public class PortChainResourceTest extends VtnResourceTest { | ... | @@ -165,7 +166,7 @@ public class PortChainResourceTest extends VtnResourceTest { |
165 | } | 166 | } |
166 | 167 | ||
167 | @Override | 168 | @Override |
168 | - public Optional<LoadBalanceId> matchPath(List<PortPairId> path) { | 169 | + public LoadBalanceId matchPath(List<PortPairId> path) { |
169 | return null; | 170 | return null; |
170 | } | 171 | } |
171 | 172 | ||
... | @@ -204,6 +205,11 @@ public class PortChainResourceTest extends VtnResourceTest { | ... | @@ -204,6 +205,11 @@ public class PortChainResourceTest extends VtnResourceTest { |
204 | public Set<LoadBalanceId> getLoadBalancePathMapKeys() { | 205 | public Set<LoadBalanceId> getLoadBalancePathMapKeys() { |
205 | return null; | 206 | return null; |
206 | } | 207 | } |
208 | + | ||
209 | + @Override | ||
210 | + public PortChain oldPortChain() { | ||
211 | + return null; | ||
212 | + } | ||
207 | } | 213 | } |
208 | 214 | ||
209 | /** | 215 | /** | ... | ... |
apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortChainSfMapResourceTest.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2016-present 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.vtnweb.resources; | ||
17 | + | ||
18 | +import static org.easymock.EasyMock.anyObject; | ||
19 | +import static org.easymock.EasyMock.createMock; | ||
20 | +import static org.easymock.EasyMock.expect; | ||
21 | +import static org.easymock.EasyMock.replay; | ||
22 | +import static org.hamcrest.Matchers.is; | ||
23 | +import static org.hamcrest.Matchers.notNullValue; | ||
24 | +import static org.junit.Assert.assertThat; | ||
25 | + | ||
26 | +import java.util.List; | ||
27 | +import java.util.Map; | ||
28 | +import java.util.concurrent.ConcurrentHashMap; | ||
29 | + | ||
30 | +import javax.ws.rs.client.WebTarget; | ||
31 | + | ||
32 | +import org.junit.After; | ||
33 | +import org.junit.Before; | ||
34 | +import org.junit.Test; | ||
35 | +import org.onlab.osgi.ServiceDirectory; | ||
36 | +import org.onlab.osgi.TestServiceDirectory; | ||
37 | +import org.onlab.rest.BaseResource; | ||
38 | +import org.onosproject.codec.CodecService; | ||
39 | +import org.onosproject.vtnrsc.PortPairId; | ||
40 | +import org.onosproject.vtnrsc.ServiceFunctionGroup; | ||
41 | +import org.onosproject.vtnrsc.portchainsfmap.PortChainSfMapService; | ||
42 | +import org.onosproject.vtnweb.web.SfcCodecContext; | ||
43 | + | ||
44 | +import com.eclipsesource.json.Json; | ||
45 | +import com.eclipsesource.json.JsonObject; | ||
46 | +import com.google.common.collect.Lists; | ||
47 | + | ||
48 | +/** | ||
49 | + * Unit tests for port chain sf map REST APIs. | ||
50 | + */ | ||
51 | +public class PortChainSfMapResourceTest extends VtnResourceTest { | ||
52 | + | ||
53 | + final PortChainSfMapService portChainSfMapService = createMock(PortChainSfMapService.class); | ||
54 | + | ||
55 | + String name1 = "Firewall"; | ||
56 | + String description1 = "Firewall service function"; | ||
57 | + Map<PortPairId, Integer> portPairLoadMap1 = new ConcurrentHashMap<>(); | ||
58 | + | ||
59 | + ServiceFunctionGroup serviceFunction1 = new ServiceFunctionGroup(name1, description1, | ||
60 | + portPairLoadMap1); | ||
61 | + | ||
62 | + /** | ||
63 | + * Sets up the global values for all the tests. | ||
64 | + */ | ||
65 | + @Before | ||
66 | + public void setUpTest() { | ||
67 | + SfcCodecContext context = new SfcCodecContext(); | ||
68 | + ServiceDirectory testDirectory = new TestServiceDirectory() | ||
69 | + .add(PortChainSfMapService.class, portChainSfMapService) | ||
70 | + .add(CodecService.class, context.codecManager()); | ||
71 | + BaseResource.setServiceDirectory(testDirectory); | ||
72 | + } | ||
73 | + | ||
74 | + /** | ||
75 | + * Cleans up. | ||
76 | + */ | ||
77 | + @After | ||
78 | + public void tearDownTest() { | ||
79 | + } | ||
80 | + | ||
81 | + /** | ||
82 | + * Tests the result of a rest api GET for port chain id. | ||
83 | + */ | ||
84 | + @Test | ||
85 | + public void testGetPortChainId() { | ||
86 | + | ||
87 | + final List<ServiceFunctionGroup> serviceFunctions = Lists.newArrayList(); | ||
88 | + serviceFunctions.add(serviceFunction1); | ||
89 | + | ||
90 | + expect(portChainSfMapService.getServiceFunctions(anyObject())).andReturn(serviceFunctions).anyTimes(); | ||
91 | + replay(portChainSfMapService); | ||
92 | + | ||
93 | + final WebTarget wt = target(); | ||
94 | + final String response = wt.path("portChainSfMap/1278dcd4-459f-62ed-754b-87fc5e4a6751").request() | ||
95 | + .get(String.class); | ||
96 | + final JsonObject result = Json.parse(response).asObject(); | ||
97 | + assertThat(result, notNullValue()); | ||
98 | + assertThat(result.names().get(0), is("portChainSfMap")); | ||
99 | + } | ||
100 | +} |
... | @@ -136,6 +136,10 @@ public class PortPairGroupResourceTest extends VtnResourceTest { | ... | @@ -136,6 +136,10 @@ public class PortPairGroupResourceTest extends VtnResourceTest { |
136 | Objects.equals(this.portPairGroupId, portPairGroup.portPairGroupId()) && | 136 | Objects.equals(this.portPairGroupId, portPairGroup.portPairGroupId()) && |
137 | Objects.equals(this.tenantId, portPairGroup.tenantId()); | 137 | Objects.equals(this.tenantId, portPairGroup.tenantId()); |
138 | } | 138 | } |
139 | + | ||
140 | + @Override | ||
141 | + public void resetLoad() { | ||
142 | + } | ||
139 | } | 143 | } |
140 | 144 | ||
141 | /** | 145 | /** | ... | ... |
... | @@ -38,6 +38,7 @@ public class ExtensionSelectorType { | ... | @@ -38,6 +38,7 @@ public class ExtensionSelectorType { |
38 | NICIRA_MATCH_NSH_CH2(3), | 38 | NICIRA_MATCH_NSH_CH2(3), |
39 | NICIRA_MATCH_NSH_CH3(4), | 39 | NICIRA_MATCH_NSH_CH3(4), |
40 | NICIRA_MATCH_NSH_CH4(5), | 40 | NICIRA_MATCH_NSH_CH4(5), |
41 | + NICIRA_MATCH_ENCAP_ETH_TYPE(6), | ||
41 | OFDPA_MATCH_VLAN_VID(16), | 42 | OFDPA_MATCH_VLAN_VID(16), |
42 | BMV2_MATCH_PARAMS(128); | 43 | BMV2_MATCH_PARAMS(128); |
43 | 44 | ... | ... |
... | @@ -38,15 +38,30 @@ public final class ExtensionTreatmentType { | ... | @@ -38,15 +38,30 @@ public final class ExtensionTreatmentType { |
38 | NICIRA_MOV_ARP_SPA_TO_TPA(3), | 38 | NICIRA_MOV_ARP_SPA_TO_TPA(3), |
39 | NICIRA_MOV_ETH_SRC_TO_DST(4), | 39 | NICIRA_MOV_ETH_SRC_TO_DST(4), |
40 | NICIRA_MOV_IP_SRC_TO_DST(5), | 40 | NICIRA_MOV_IP_SRC_TO_DST(5), |
41 | + NICIRA_MOV_NSH_C1_TO_C1(6), | ||
42 | + NICIRA_MOV_NSH_C2_TO_C2(7), | ||
43 | + NICIRA_MOV_NSH_C3_TO_C3(8), | ||
44 | + NICIRA_MOV_NSH_C4_TO_C4(9), | ||
45 | + NICIRA_MOV_TUN_IPV4_DST_TO_TUN_IPV4_DST(10), | ||
46 | + NICIRA_MOV_TUN_ID_TO_TUN_ID(11), | ||
47 | + NICIRA_MOV_NSH_C2_TO_TUN_ID(12), | ||
41 | NICIRA_RESUBMIT_TABLE(14), | 48 | NICIRA_RESUBMIT_TABLE(14), |
42 | - NICIRA_SET_NSH_SPI(32), | 49 | + NICIRA_PUSH_NSH(38), |
43 | - NICIRA_SET_NSH_SI(33), | 50 | + NICIRA_POP_NSH(39), |
44 | - NICIRA_SET_NSH_CH1(34), | ||
45 | - NICIRA_SET_NSH_CH2(35), | ||
46 | - NICIRA_SET_NSH_CH3(36), | ||
47 | - NICIRA_SET_NSH_CH4(37), | ||
48 | OFDPA_SET_VLAN_ID(64), | 51 | OFDPA_SET_VLAN_ID(64), |
49 | - BMV2_ACTION(128); | 52 | + NICIRA_TUN_GPE_NP(111), |
53 | + NICIRA_SET_NSH_SPI(113), | ||
54 | + NICIRA_SET_NSH_SI(114), | ||
55 | + NICIRA_SET_NSH_CH1(115), | ||
56 | + NICIRA_SET_NSH_CH2(116), | ||
57 | + NICIRA_SET_NSH_CH3(117), | ||
58 | + NICIRA_SET_NSH_CH4(118), | ||
59 | + NICIRA_NSH_MDTYPE(119), | ||
60 | + NICIRA_NSH_NP(120), | ||
61 | + NICIRA_ENCAP_ETH_SRC(121), | ||
62 | + NICIRA_ENCAP_ETH_DST(122), | ||
63 | + NICIRA_ENCAP_ETH_TYPE(123), | ||
64 | + P4_BMV2_ACTION(128); | ||
50 | 65 | ||
51 | private ExtensionTreatmentType type; | 66 | private ExtensionTreatmentType type; |
52 | 67 | ... | ... |
... | @@ -15,7 +15,8 @@ | ... | @@ -15,7 +15,8 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.net.device; | 16 | package org.onosproject.net.device; |
17 | 17 | ||
18 | -import com.google.common.collect.FluentIterable; | 18 | +import java.util.Collections; |
19 | +import java.util.List; | ||
19 | 20 | ||
20 | import org.onosproject.net.Device; | 21 | import org.onosproject.net.Device; |
21 | import org.onosproject.net.Device.Type; | 22 | import org.onosproject.net.Device.Type; |
... | @@ -24,13 +25,31 @@ import org.onosproject.net.MastershipRole; | ... | @@ -24,13 +25,31 @@ import org.onosproject.net.MastershipRole; |
24 | import org.onosproject.net.Port; | 25 | import org.onosproject.net.Port; |
25 | import org.onosproject.net.PortNumber; | 26 | import org.onosproject.net.PortNumber; |
26 | 27 | ||
27 | -import java.util.Collections; | 28 | +import com.google.common.collect.FluentIterable; |
28 | -import java.util.List; | ||
29 | 29 | ||
30 | /** | 30 | /** |
31 | * Test adapter for device service. | 31 | * Test adapter for device service. |
32 | */ | 32 | */ |
33 | public class DeviceServiceAdapter implements DeviceService { | 33 | public class DeviceServiceAdapter implements DeviceService { |
34 | + | ||
35 | + private List<Port> portList; | ||
36 | + | ||
37 | + /** | ||
38 | + * Constructor with port list. | ||
39 | + * | ||
40 | + * @param portList port list | ||
41 | + */ | ||
42 | + public DeviceServiceAdapter(List<Port> portList) { | ||
43 | + this.portList = portList; | ||
44 | + } | ||
45 | + | ||
46 | + /** | ||
47 | + * Default constructor. | ||
48 | + */ | ||
49 | + public DeviceServiceAdapter() { | ||
50 | + | ||
51 | + } | ||
52 | + | ||
34 | @Override | 53 | @Override |
35 | public int getDeviceCount() { | 54 | public int getDeviceCount() { |
36 | return 0; | 55 | return 0; |
... | @@ -59,7 +78,7 @@ public class DeviceServiceAdapter implements DeviceService { | ... | @@ -59,7 +78,7 @@ public class DeviceServiceAdapter implements DeviceService { |
59 | 78 | ||
60 | @Override | 79 | @Override |
61 | public List<Port> getPorts(DeviceId deviceId) { | 80 | public List<Port> getPorts(DeviceId deviceId) { |
62 | - return Collections.emptyList(); | 81 | + return portList; |
63 | } | 82 | } |
64 | 83 | ||
65 | @Override | 84 | @Override | ... | ... |
1 | +/* | ||
2 | + * Copyright 2016-present 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 | + | ||
17 | +package org.onosproject.driver.extensions; | ||
18 | + | ||
19 | +import java.util.Objects; | ||
20 | + | ||
21 | +import org.onlab.packet.MacAddress; | ||
22 | +import org.onlab.util.KryoNamespace; | ||
23 | +import org.onosproject.net.flow.AbstractExtension; | ||
24 | +import org.onosproject.net.flow.instructions.ExtensionTreatment; | ||
25 | +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; | ||
26 | +import org.onosproject.store.serializers.MacAddressSerializer; | ||
27 | + | ||
28 | +import com.google.common.base.MoreObjects; | ||
29 | + | ||
30 | +/** | ||
31 | + * Nicira EncapEthDst extension instruction to set encapsulated eth destination. | ||
32 | + */ | ||
33 | +public class NiciraEncapEthDst extends AbstractExtension implements ExtensionTreatment { | ||
34 | + | ||
35 | + private MacAddress encapEthDst; | ||
36 | + | ||
37 | + private final KryoNamespace appKryo = new KryoNamespace.Builder() | ||
38 | + .register(new MacAddressSerializer(), MacAddress.class).register(byte[].class).build();; | ||
39 | + | ||
40 | + /** | ||
41 | + * Creates a new nshEncapEthDst instruction. | ||
42 | + */ | ||
43 | + NiciraEncapEthDst() { | ||
44 | + } | ||
45 | + | ||
46 | + /** | ||
47 | + * Creates a new encapEthDst instruction with given mac address. | ||
48 | + * | ||
49 | + * @param encapEthDst encapsulated ethernet destination | ||
50 | + */ | ||
51 | + public NiciraEncapEthDst(MacAddress encapEthDst) { | ||
52 | + this.encapEthDst = encapEthDst; | ||
53 | + } | ||
54 | + | ||
55 | + /** | ||
56 | + * Gets the encapEthDst. | ||
57 | + * | ||
58 | + * @return encapEthDst | ||
59 | + */ | ||
60 | + public MacAddress encapEthDst() { | ||
61 | + return encapEthDst; | ||
62 | + } | ||
63 | + | ||
64 | + @Override | ||
65 | + public ExtensionTreatmentType type() { | ||
66 | + return ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_DST.type(); | ||
67 | + } | ||
68 | + | ||
69 | + @Override | ||
70 | + public void deserialize(byte[] data) { | ||
71 | + encapEthDst = appKryo.deserialize(data); | ||
72 | + } | ||
73 | + | ||
74 | + @Override | ||
75 | + public byte[] serialize() { | ||
76 | + return appKryo.serialize(encapEthDst); | ||
77 | + } | ||
78 | + | ||
79 | + @Override | ||
80 | + public int hashCode() { | ||
81 | + return Objects.hash(encapEthDst); | ||
82 | + } | ||
83 | + | ||
84 | + @Override | ||
85 | + public boolean equals(Object obj) { | ||
86 | + if (this == obj) { | ||
87 | + return true; | ||
88 | + } | ||
89 | + if (obj instanceof NiciraEncapEthDst) { | ||
90 | + NiciraEncapEthDst that = (NiciraEncapEthDst) obj; | ||
91 | + return Objects.equals(encapEthDst, that.encapEthDst); | ||
92 | + | ||
93 | + } | ||
94 | + return false; | ||
95 | + } | ||
96 | + | ||
97 | + @Override | ||
98 | + public String toString() { | ||
99 | + return MoreObjects.toStringHelper(getClass()).add("encapEthDst", encapEthDst).toString(); | ||
100 | + } | ||
101 | +} |
1 | +/* | ||
2 | + * Copyright 2016-present 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 | + | ||
17 | +package org.onosproject.driver.extensions; | ||
18 | + | ||
19 | +import java.util.Objects; | ||
20 | + | ||
21 | +import org.onlab.packet.MacAddress; | ||
22 | +import org.onlab.util.KryoNamespace; | ||
23 | +import org.onosproject.net.flow.AbstractExtension; | ||
24 | +import org.onosproject.net.flow.instructions.ExtensionTreatment; | ||
25 | +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; | ||
26 | +import org.onosproject.store.serializers.MacAddressSerializer; | ||
27 | + | ||
28 | +import com.google.common.base.MoreObjects; | ||
29 | + | ||
30 | +/** | ||
31 | + * Nicira EncapEthSrc extension instruction to set encapsulated eth source. | ||
32 | + */ | ||
33 | +public class NiciraEncapEthSrc extends AbstractExtension implements ExtensionTreatment { | ||
34 | + | ||
35 | + private MacAddress encapEthSrc; | ||
36 | + | ||
37 | + private final KryoNamespace appKryo = new KryoNamespace.Builder() | ||
38 | + .register(new MacAddressSerializer(), MacAddress.class).register(byte[].class).build();; | ||
39 | + | ||
40 | + /** | ||
41 | + * Creates a new nshEncapEthSrc instruction. | ||
42 | + */ | ||
43 | + NiciraEncapEthSrc() { | ||
44 | + } | ||
45 | + | ||
46 | + /** | ||
47 | + * Creates a new encapEthSrc instruction with given mac address. | ||
48 | + * | ||
49 | + * @param encapEthSrc encapsulated ethernet source | ||
50 | + */ | ||
51 | + public NiciraEncapEthSrc(MacAddress encapEthSrc) { | ||
52 | + this.encapEthSrc = encapEthSrc; | ||
53 | + } | ||
54 | + | ||
55 | + /** | ||
56 | + * Gets the encapEthSrc. | ||
57 | + * | ||
58 | + * @return encapEthSrc | ||
59 | + */ | ||
60 | + public MacAddress encapEthSrc() { | ||
61 | + return encapEthSrc; | ||
62 | + } | ||
63 | + | ||
64 | + @Override | ||
65 | + public ExtensionTreatmentType type() { | ||
66 | + return ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_SRC.type(); | ||
67 | + } | ||
68 | + | ||
69 | + @Override | ||
70 | + public void deserialize(byte[] data) { | ||
71 | + encapEthSrc = appKryo.deserialize(data); | ||
72 | + } | ||
73 | + | ||
74 | + @Override | ||
75 | + public byte[] serialize() { | ||
76 | + return appKryo.serialize(encapEthSrc); | ||
77 | + } | ||
78 | + | ||
79 | + @Override | ||
80 | + public int hashCode() { | ||
81 | + return Objects.hash(encapEthSrc); | ||
82 | + } | ||
83 | + | ||
84 | + @Override | ||
85 | + public boolean equals(Object obj) { | ||
86 | + if (this == obj) { | ||
87 | + return true; | ||
88 | + } | ||
89 | + if (obj instanceof NiciraEncapEthSrc) { | ||
90 | + NiciraEncapEthSrc that = (NiciraEncapEthSrc) obj; | ||
91 | + return Objects.equals(encapEthSrc, that.encapEthSrc); | ||
92 | + | ||
93 | + } | ||
94 | + return false; | ||
95 | + } | ||
96 | + | ||
97 | + @Override | ||
98 | + public String toString() { | ||
99 | + return MoreObjects.toStringHelper(getClass()).add("encapEthSrc", encapEthSrc).toString(); | ||
100 | + } | ||
101 | +} |
1 | +/* | ||
2 | + * Copyright 2016-present 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 | + | ||
17 | +package org.onosproject.driver.extensions; | ||
18 | + | ||
19 | +import java.util.Objects; | ||
20 | + | ||
21 | +import org.onlab.util.KryoNamespace; | ||
22 | +import org.onosproject.net.flow.AbstractExtension; | ||
23 | +import org.onosproject.net.flow.instructions.ExtensionTreatment; | ||
24 | +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; | ||
25 | + | ||
26 | +import com.google.common.base.MoreObjects; | ||
27 | + | ||
28 | +/** | ||
29 | + * Nicira EncapEthType extension instruction to set encapsulated eth type. | ||
30 | + */ | ||
31 | +public class NiciraEncapEthType extends AbstractExtension implements ExtensionTreatment { | ||
32 | + | ||
33 | + private short encapEthType; | ||
34 | + | ||
35 | + private final KryoNamespace appKryo = new KryoNamespace.Builder().build(); | ||
36 | + | ||
37 | + /** | ||
38 | + * Creates a new nshEncapEthType instruction. | ||
39 | + */ | ||
40 | + NiciraEncapEthType() { | ||
41 | + encapEthType = (short) 0; | ||
42 | + } | ||
43 | + | ||
44 | + /** | ||
45 | + * Creates a new nshEncapEthType instruction with given eth type. | ||
46 | + * | ||
47 | + * @param encapEthType encapsulated ethernet type | ||
48 | + */ | ||
49 | + public NiciraEncapEthType(short encapEthType) { | ||
50 | + this.encapEthType = encapEthType; | ||
51 | + } | ||
52 | + | ||
53 | + /** | ||
54 | + * Gets the encapEthType. | ||
55 | + * | ||
56 | + * @return encapEthType | ||
57 | + */ | ||
58 | + public short encapEthType() { | ||
59 | + return encapEthType; | ||
60 | + } | ||
61 | + | ||
62 | + @Override | ||
63 | + public ExtensionTreatmentType type() { | ||
64 | + return ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_TYPE.type(); | ||
65 | + } | ||
66 | + | ||
67 | + @Override | ||
68 | + public void deserialize(byte[] data) { | ||
69 | + encapEthType = (short) (appKryo.deserialize(data)); | ||
70 | + } | ||
71 | + | ||
72 | + @Override | ||
73 | + public byte[] serialize() { | ||
74 | + return appKryo.serialize(encapEthType); | ||
75 | + } | ||
76 | + | ||
77 | + @Override | ||
78 | + public int hashCode() { | ||
79 | + return Objects.hash(encapEthType); | ||
80 | + } | ||
81 | + | ||
82 | + @Override | ||
83 | + public boolean equals(Object obj) { | ||
84 | + if (this == obj) { | ||
85 | + return true; | ||
86 | + } | ||
87 | + if (obj instanceof NiciraEncapEthType) { | ||
88 | + NiciraEncapEthType that = (NiciraEncapEthType) obj; | ||
89 | + return Objects.equals(encapEthType, that.encapEthType); | ||
90 | + | ||
91 | + } | ||
92 | + return false; | ||
93 | + } | ||
94 | + | ||
95 | + @Override | ||
96 | + public String toString() { | ||
97 | + return MoreObjects.toStringHelper(getClass()).add("encapEthType", encapEthType).toString(); | ||
98 | + } | ||
99 | +} |
... | @@ -18,13 +18,22 @@ package org.onosproject.driver.extensions; | ... | @@ -18,13 +18,22 @@ package org.onosproject.driver.extensions; |
18 | 18 | ||
19 | import com.fasterxml.jackson.databind.node.ObjectNode; | 19 | import com.fasterxml.jackson.databind.node.ObjectNode; |
20 | import org.onosproject.codec.CodecContext; | 20 | import org.onosproject.codec.CodecContext; |
21 | +import org.onosproject.net.NshServiceIndex; | ||
22 | +import org.onosproject.net.NshServicePathId; | ||
21 | import org.onosproject.net.behaviour.ExtensionSelectorResolver; | 23 | import org.onosproject.net.behaviour.ExtensionSelectorResolver; |
22 | import org.onosproject.net.driver.AbstractHandlerBehaviour; | 24 | import org.onosproject.net.driver.AbstractHandlerBehaviour; |
23 | import org.onosproject.net.flow.criteria.ExtensionSelector; | 25 | import org.onosproject.net.flow.criteria.ExtensionSelector; |
24 | import org.onosproject.net.flow.criteria.ExtensionSelectorType; | 26 | import org.onosproject.net.flow.criteria.ExtensionSelectorType; |
25 | import org.onosproject.openflow.controller.ExtensionSelectorInterpreter; | 27 | import org.onosproject.openflow.controller.ExtensionSelectorInterpreter; |
26 | import org.projectfloodlight.openflow.protocol.OFFactory; | 28 | import org.projectfloodlight.openflow.protocol.OFFactory; |
29 | +import org.projectfloodlight.openflow.protocol.match.MatchField; | ||
27 | import org.projectfloodlight.openflow.protocol.oxm.OFOxm; | 30 | import org.projectfloodlight.openflow.protocol.oxm.OFOxm; |
31 | +import org.projectfloodlight.openflow.protocol.oxm.OFOxmEncapEthType; | ||
32 | +import org.projectfloodlight.openflow.protocol.oxm.OFOxmNsi; | ||
33 | +import org.projectfloodlight.openflow.protocol.oxm.OFOxmNsp; | ||
34 | +import org.projectfloodlight.openflow.types.U16; | ||
35 | +import org.projectfloodlight.openflow.types.U32; | ||
36 | +import org.projectfloodlight.openflow.types.U8; | ||
28 | 37 | ||
29 | /** | 38 | /** |
30 | * Interpreter for Nicira OpenFlow selector extensions. | 39 | * Interpreter for Nicira OpenFlow selector extensions. |
... | @@ -53,17 +62,28 @@ public class NiciraExtensionSelectorInterpreter | ... | @@ -53,17 +62,28 @@ public class NiciraExtensionSelectorInterpreter |
53 | if (extensionSelectorType.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH4.type())) { | 62 | if (extensionSelectorType.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH4.type())) { |
54 | return true; | 63 | return true; |
55 | } | 64 | } |
65 | + if (extensionSelectorType.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_ENCAP_ETH_TYPE | ||
66 | + .type())) { | ||
67 | + return true; | ||
68 | + } | ||
56 | return false; | 69 | return false; |
57 | } | 70 | } |
58 | 71 | ||
59 | @Override | 72 | @Override |
60 | public OFOxm<?> mapSelector(OFFactory factory, ExtensionSelector extensionSelector) { | 73 | public OFOxm<?> mapSelector(OFFactory factory, ExtensionSelector extensionSelector) { |
61 | ExtensionSelectorType type = extensionSelector.type(); | 74 | ExtensionSelectorType type = extensionSelector.type(); |
75 | + | ||
62 | if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_SPI.type())) { | 76 | if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_SPI.type())) { |
63 | - // TODO | 77 | + NiciraMatchNshSpi niciraNshSpi = (NiciraMatchNshSpi) extensionSelector; |
78 | + return factory.oxms().nsp(U32.of(niciraNshSpi.nshSpi().servicePathId())); | ||
64 | } | 79 | } |
65 | if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_SI.type())) { | 80 | if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_SI.type())) { |
66 | - // TODO | 81 | + NiciraMatchNshSi niciraNshSi = (NiciraMatchNshSi) extensionSelector; |
82 | + return factory.oxms().nsi(U8.of(niciraNshSi.nshSi().serviceIndex())); | ||
83 | + } | ||
84 | + if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_ENCAP_ETH_TYPE.type())) { | ||
85 | + NiciraMatchEncapEthType niciraEncapEthType = (NiciraMatchEncapEthType) extensionSelector; | ||
86 | + return factory.oxms().encapEthType(U16.of(niciraEncapEthType.encapEthType())); | ||
67 | } | 87 | } |
68 | if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH1.type())) { | 88 | if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH1.type())) { |
69 | // TODO | 89 | // TODO |
... | @@ -82,6 +102,20 @@ public class NiciraExtensionSelectorInterpreter | ... | @@ -82,6 +102,20 @@ public class NiciraExtensionSelectorInterpreter |
82 | 102 | ||
83 | @Override | 103 | @Override |
84 | public ExtensionSelector mapOxm(OFOxm<?> oxm) { | 104 | public ExtensionSelector mapOxm(OFOxm<?> oxm) { |
105 | + | ||
106 | + if (oxm.getMatchField() == MatchField.NSP) { | ||
107 | + OFOxmNsp oxmField = (OFOxmNsp) oxm; | ||
108 | + return new NiciraMatchNshSpi(NshServicePathId.of(oxmField.getValue().getRaw())); | ||
109 | + } | ||
110 | + if (oxm.getMatchField() == MatchField.NSI) { | ||
111 | + OFOxmNsi oxmField = (OFOxmNsi) oxm; | ||
112 | + return new NiciraMatchNshSi(NshServiceIndex.of(oxmField.getValue().getRaw())); | ||
113 | + } | ||
114 | + if (oxm.getMatchField() == MatchField.ENCAP_ETH_TYPE) { | ||
115 | + OFOxmEncapEthType oxmField = (OFOxmEncapEthType) oxm; | ||
116 | + return new NiciraMatchEncapEthType(oxmField.getValue().getRaw()); | ||
117 | + } | ||
118 | + | ||
85 | return null; | 119 | return null; |
86 | } | 120 | } |
87 | 121 | ||
... | @@ -93,6 +127,9 @@ public class NiciraExtensionSelectorInterpreter | ... | @@ -93,6 +127,9 @@ public class NiciraExtensionSelectorInterpreter |
93 | if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_SI.type())) { | 127 | if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_SI.type())) { |
94 | return new NiciraMatchNshSi(); | 128 | return new NiciraMatchNshSi(); |
95 | } | 129 | } |
130 | + if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_ENCAP_ETH_TYPE.type())) { | ||
131 | + return new NiciraMatchEncapEthType(); | ||
132 | + } | ||
96 | if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH1.type()) | 133 | if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH1.type()) |
97 | || type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH2.type()) | 134 | || type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH2.type()) |
98 | || type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH3.type()) | 135 | || type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH3.type()) | ... | ... |
... | @@ -16,9 +16,14 @@ | ... | @@ -16,9 +16,14 @@ |
16 | 16 | ||
17 | package org.onosproject.driver.extensions; | 17 | package org.onosproject.driver.extensions; |
18 | 18 | ||
19 | -import com.fasterxml.jackson.databind.node.ObjectNode; | 19 | +import static com.google.common.base.Preconditions.checkNotNull; |
20 | +import static org.onlab.util.Tools.nullIsIllegal; | ||
21 | + | ||
20 | import org.onlab.packet.Ip4Address; | 22 | import org.onlab.packet.Ip4Address; |
21 | import org.onosproject.codec.CodecContext; | 23 | import org.onosproject.codec.CodecContext; |
24 | +import org.onosproject.net.NshContextHeader; | ||
25 | +import org.onosproject.net.NshServiceIndex; | ||
26 | +import org.onosproject.net.NshServicePathId; | ||
22 | import org.onosproject.net.PortNumber; | 27 | import org.onosproject.net.PortNumber; |
23 | import org.onosproject.net.behaviour.ExtensionTreatmentResolver; | 28 | import org.onosproject.net.behaviour.ExtensionTreatmentResolver; |
24 | import org.onosproject.net.driver.AbstractHandlerBehaviour; | 29 | import org.onosproject.net.driver.AbstractHandlerBehaviour; |
... | @@ -32,13 +37,29 @@ import org.projectfloodlight.openflow.protocol.action.OFActionExperimenter; | ... | @@ -32,13 +37,29 @@ import org.projectfloodlight.openflow.protocol.action.OFActionExperimenter; |
32 | import org.projectfloodlight.openflow.protocol.action.OFActionNicira; | 37 | import org.projectfloodlight.openflow.protocol.action.OFActionNicira; |
33 | import org.projectfloodlight.openflow.protocol.action.OFActionNiciraMove; | 38 | import org.projectfloodlight.openflow.protocol.action.OFActionNiciraMove; |
34 | import org.projectfloodlight.openflow.protocol.action.OFActionNiciraResubmit; | 39 | import org.projectfloodlight.openflow.protocol.action.OFActionNiciraResubmit; |
40 | +import org.projectfloodlight.openflow.protocol.action.OFActionNiciraResubmitTable; | ||
35 | import org.projectfloodlight.openflow.protocol.action.OFActionSetField; | 41 | import org.projectfloodlight.openflow.protocol.action.OFActionSetField; |
36 | import org.projectfloodlight.openflow.protocol.oxm.OFOxm; | 42 | import org.projectfloodlight.openflow.protocol.oxm.OFOxm; |
43 | +import org.projectfloodlight.openflow.protocol.oxm.OFOxmEncapEthDst; | ||
44 | +import org.projectfloodlight.openflow.protocol.oxm.OFOxmEncapEthSrc; | ||
45 | +import org.projectfloodlight.openflow.protocol.oxm.OFOxmEncapEthType; | ||
46 | +import org.projectfloodlight.openflow.protocol.oxm.OFOxmNshC1; | ||
47 | +import org.projectfloodlight.openflow.protocol.oxm.OFOxmNshC2; | ||
48 | +import org.projectfloodlight.openflow.protocol.oxm.OFOxmNshC3; | ||
49 | +import org.projectfloodlight.openflow.protocol.oxm.OFOxmNshC4; | ||
50 | +import org.projectfloodlight.openflow.protocol.oxm.OFOxmNshMdtype; | ||
51 | +import org.projectfloodlight.openflow.protocol.oxm.OFOxmNshNp; | ||
52 | +import org.projectfloodlight.openflow.protocol.oxm.OFOxmNsi; | ||
53 | +import org.projectfloodlight.openflow.protocol.oxm.OFOxmNsp; | ||
54 | +import org.projectfloodlight.openflow.protocol.oxm.OFOxmTunGpeNp; | ||
37 | import org.projectfloodlight.openflow.protocol.oxm.OFOxmTunnelIpv4Dst; | 55 | import org.projectfloodlight.openflow.protocol.oxm.OFOxmTunnelIpv4Dst; |
38 | import org.projectfloodlight.openflow.types.IPv4Address; | 56 | import org.projectfloodlight.openflow.types.IPv4Address; |
57 | +import org.projectfloodlight.openflow.types.MacAddress; | ||
58 | +import org.projectfloodlight.openflow.types.U16; | ||
59 | +import org.projectfloodlight.openflow.types.U32; | ||
60 | +import org.projectfloodlight.openflow.types.U8; | ||
39 | 61 | ||
40 | -import static com.google.common.base.Preconditions.checkNotNull; | 62 | +import com.fasterxml.jackson.databind.node.ObjectNode; |
41 | -import static org.onlab.util.Tools.nullIsIllegal; | ||
42 | 63 | ||
43 | /** | 64 | /** |
44 | * Interpreter for Nicira OpenFlow treatment extensions. | 65 | * Interpreter for Nicira OpenFlow treatment extensions. |
... | @@ -52,8 +73,18 @@ public class NiciraExtensionTreatmentInterpreter extends AbstractHandlerBehaviou | ... | @@ -52,8 +73,18 @@ public class NiciraExtensionTreatmentInterpreter extends AbstractHandlerBehaviou |
52 | private static final int SRC_ETH = 0x00000406; | 73 | private static final int SRC_ETH = 0x00000406; |
53 | private static final int SRC_IP = 0x00000e04; | 74 | private static final int SRC_IP = 0x00000e04; |
54 | 75 | ||
76 | + private static final int NSH_C1 = 0x0001e604; | ||
77 | + private static final int NSH_C2 = 0x0001e804; | ||
78 | + private static final int NSH_C3 = 0x0001ea04; | ||
79 | + private static final int NSH_C4 = 0x0001ec04; | ||
80 | + private static final int TUN_IPV4_DST = 0x00014004; | ||
81 | + private static final int TUN_ID = 0x12008; | ||
82 | + | ||
55 | private static final int SUB_TYPE_RESUBMIT = 1; | 83 | private static final int SUB_TYPE_RESUBMIT = 1; |
84 | + private static final int SUB_TYPE_RESUBMIT_TABLE = 14; | ||
56 | private static final int SUB_TYPE_MOVE = 6; | 85 | private static final int SUB_TYPE_MOVE = 6; |
86 | + private static final int SUB_TYPE_PUSH_NSH = 38; | ||
87 | + private static final int SUB_TYPE_POP_NSH = 39; | ||
57 | 88 | ||
58 | private static final String TUNNEL_DST = "tunnelDst"; | 89 | private static final String TUNNEL_DST = "tunnelDst"; |
59 | private static final String RESUBMIT = "resubmit"; | 90 | private static final String RESUBMIT = "resubmit"; |
... | @@ -115,6 +146,59 @@ public class NiciraExtensionTreatmentInterpreter extends AbstractHandlerBehaviou | ... | @@ -115,6 +146,59 @@ public class NiciraExtensionTreatmentInterpreter extends AbstractHandlerBehaviou |
115 | ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_IP_SRC_TO_DST.type())) { | 146 | ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_IP_SRC_TO_DST.type())) { |
116 | return true; | 147 | return true; |
117 | } | 148 | } |
149 | + if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_MDTYPE.type())) { | ||
150 | + return true; | ||
151 | + } | ||
152 | + if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_NP.type())) { | ||
153 | + return true; | ||
154 | + } | ||
155 | + if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_SRC.type())) { | ||
156 | + return true; | ||
157 | + } | ||
158 | + if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_DST.type())) { | ||
159 | + return true; | ||
160 | + } | ||
161 | + if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_TYPE | ||
162 | + .type())) { | ||
163 | + return true; | ||
164 | + } | ||
165 | + if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_PUSH_NSH.type())) { | ||
166 | + return true; | ||
167 | + } | ||
168 | + if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_POP_NSH.type())) { | ||
169 | + return true; | ||
170 | + } | ||
171 | + if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_TUN_GPE_NP.type())) { | ||
172 | + return true; | ||
173 | + } | ||
174 | + if (extensionTreatmentType | ||
175 | + .equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C1_TO_C1.type())) { | ||
176 | + return true; | ||
177 | + } | ||
178 | + if (extensionTreatmentType | ||
179 | + .equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C2_TO_C2.type())) { | ||
180 | + return true; | ||
181 | + } | ||
182 | + if (extensionTreatmentType | ||
183 | + .equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C3_TO_C3.type())) { | ||
184 | + return true; | ||
185 | + } | ||
186 | + if (extensionTreatmentType | ||
187 | + .equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C4_TO_C4.type())) { | ||
188 | + return true; | ||
189 | + } | ||
190 | + if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes | ||
191 | + .NICIRA_MOV_TUN_IPV4_DST_TO_TUN_IPV4_DST.type())) { | ||
192 | + return true; | ||
193 | + } | ||
194 | + if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_TUN_ID_TO_TUN_ID | ||
195 | + .type())) { | ||
196 | + return true; | ||
197 | + } | ||
198 | + if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C2_TO_TUN_ID | ||
199 | + .type())) { | ||
200 | + return true; | ||
201 | + } | ||
118 | return false; | 202 | return false; |
119 | } | 203 | } |
120 | 204 | ||
... | @@ -136,10 +220,75 @@ public class NiciraExtensionTreatmentInterpreter extends AbstractHandlerBehaviou | ... | @@ -136,10 +220,75 @@ public class NiciraExtensionTreatmentInterpreter extends AbstractHandlerBehaviou |
136 | return factory.actions().niciraResubmitTable((int) resubmitTable.inPort().toLong(), | 220 | return factory.actions().niciraResubmitTable((int) resubmitTable.inPort().toLong(), |
137 | resubmitTable.table()); | 221 | resubmitTable.table()); |
138 | } | 222 | } |
223 | + | ||
224 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SPI.type())) { | ||
225 | + NiciraSetNshSpi niciraNshSpi = (NiciraSetNshSpi) extensionTreatment; | ||
226 | + return factory.actions().setField(factory.oxms().nsp(U32.of(niciraNshSpi.nshSpi().servicePathId()))); | ||
227 | + } | ||
228 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SI.type())) { | ||
229 | + NiciraSetNshSi niciraNshSi = (NiciraSetNshSi) extensionTreatment; | ||
230 | + return factory.actions().setField(factory.oxms().nsi(U8.of(niciraNshSi.nshSi().serviceIndex()))); | ||
231 | + } | ||
232 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH1.type())) { | ||
233 | + NiciraSetNshContextHeader niciraNshch = (NiciraSetNshContextHeader) extensionTreatment; | ||
234 | + return factory.actions().setField(factory.oxms().nshC1(U32.of(niciraNshch.nshCh().nshContextHeader()))); | ||
235 | + } | ||
236 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH2.type())) { | ||
237 | + NiciraSetNshContextHeader niciraNshch = (NiciraSetNshContextHeader) extensionTreatment; | ||
238 | + return factory.actions().setField(factory.oxms().nshC2(U32.of(niciraNshch.nshCh().nshContextHeader()))); | ||
239 | + } | ||
240 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH3.type())) { | ||
241 | + NiciraSetNshContextHeader niciraNshch = (NiciraSetNshContextHeader) extensionTreatment; | ||
242 | + return factory.actions().setField(factory.oxms().nshC3(U32.of(niciraNshch.nshCh().nshContextHeader()))); | ||
243 | + } | ||
244 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH4.type())) { | ||
245 | + NiciraSetNshContextHeader niciraNshch = (NiciraSetNshContextHeader) extensionTreatment; | ||
246 | + return factory.actions().setField(factory.oxms().nshC4(U32.of(niciraNshch.nshCh().nshContextHeader()))); | ||
247 | + } | ||
248 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_MDTYPE.type())) { | ||
249 | + NiciraNshMdType niciraNshMdType = (NiciraNshMdType) extensionTreatment; | ||
250 | + return factory.actions().setField(factory.oxms().nshMdtype(U8.of(niciraNshMdType.nshMdType()))); | ||
251 | + } | ||
252 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_NP.type())) { | ||
253 | + NiciraNshNp niciraNshNp = (NiciraNshNp) extensionTreatment; | ||
254 | + return factory.actions().setField(factory.oxms().nshNp(U8.of(niciraNshNp.nshNp()))); | ||
255 | + } | ||
256 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_SRC.type())) { | ||
257 | + NiciraEncapEthSrc niciraEncapEthSrc = (NiciraEncapEthSrc) extensionTreatment; | ||
258 | + return factory.actions().setField(factory.oxms().encapEthSrc(MacAddress.of(niciraEncapEthSrc.encapEthSrc() | ||
259 | + .toBytes()))); | ||
260 | + } | ||
261 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_DST.type())) { | ||
262 | + NiciraEncapEthDst niciraEncapEthDst = (NiciraEncapEthDst) extensionTreatment; | ||
263 | + return factory.actions().setField(factory.oxms().encapEthDst(MacAddress.of(niciraEncapEthDst.encapEthDst() | ||
264 | + .toBytes()))); | ||
265 | + } | ||
266 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_TYPE.type())) { | ||
267 | + NiciraEncapEthType niciraEncapEthType = (NiciraEncapEthType) extensionTreatment; | ||
268 | + return factory.actions().setField(factory.oxms().encapEthType(U16.of(niciraEncapEthType.encapEthType()))); | ||
269 | + } | ||
270 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_PUSH_NSH.type())) { | ||
271 | + return factory.actions().niciraPushNsh(); | ||
272 | + } | ||
273 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_POP_NSH.type())) { | ||
274 | + return factory.actions().niciraPopNsh(); | ||
275 | + } | ||
276 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_TUN_GPE_NP.type())) { | ||
277 | + NiciraTunGpeNp niciraTunGpeNp = (NiciraTunGpeNp) extensionTreatment; | ||
278 | + return factory.actions().setField(factory.oxms().tunGpeNp(U8.of(niciraTunGpeNp.tunGpeNp()))); | ||
279 | + } | ||
139 | if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ARP_SHA_TO_THA.type()) | 280 | if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ARP_SHA_TO_THA.type()) |
140 | || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ARP_SPA_TO_TPA.type()) | 281 | || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ARP_SPA_TO_TPA.type()) |
141 | || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ETH_SRC_TO_DST.type()) | 282 | || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ETH_SRC_TO_DST.type()) |
142 | - || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_IP_SRC_TO_DST.type())) { | 283 | + || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_IP_SRC_TO_DST.type()) |
284 | + || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C1_TO_C1.type()) | ||
285 | + || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C2_TO_C2.type()) | ||
286 | + || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C3_TO_C3.type()) | ||
287 | + || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C4_TO_C4.type()) | ||
288 | + || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_TUN_IPV4_DST_TO_TUN_IPV4_DST | ||
289 | + .type()) | ||
290 | + || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_TUN_ID_TO_TUN_ID.type()) | ||
291 | + || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C2_TO_TUN_ID.type())) { | ||
143 | MoveExtensionTreatment mov = (MoveExtensionTreatment) extensionTreatment; | 292 | MoveExtensionTreatment mov = (MoveExtensionTreatment) extensionTreatment; |
144 | OFActionNiciraMove.Builder action = factory.actions() | 293 | OFActionNiciraMove.Builder action = factory.actions() |
145 | .buildNiciraMove(); | 294 | .buildNiciraMove(); |
... | @@ -162,6 +311,51 @@ public class NiciraExtensionTreatmentInterpreter extends AbstractHandlerBehaviou | ... | @@ -162,6 +311,51 @@ public class NiciraExtensionTreatmentInterpreter extends AbstractHandlerBehaviou |
162 | case TUNNEL_IPV4_DST: | 311 | case TUNNEL_IPV4_DST: |
163 | OFOxmTunnelIpv4Dst tunnelIpv4Dst = (OFOxmTunnelIpv4Dst) oxm; | 312 | OFOxmTunnelIpv4Dst tunnelIpv4Dst = (OFOxmTunnelIpv4Dst) oxm; |
164 | return new NiciraSetTunnelDst(Ip4Address.valueOf(tunnelIpv4Dst.getValue().getInt())); | 313 | return new NiciraSetTunnelDst(Ip4Address.valueOf(tunnelIpv4Dst.getValue().getInt())); |
314 | + | ||
315 | + case NSP: | ||
316 | + OFOxmNsp nsp = (OFOxmNsp) oxm; | ||
317 | + return new NiciraSetNshSpi(NshServicePathId.of((nsp.getValue().getRaw()))); | ||
318 | + case NSI: | ||
319 | + OFOxmNsi nsi = (OFOxmNsi) oxm; | ||
320 | + return new NiciraSetNshSi(NshServiceIndex.of((nsi.getValue().getRaw()))); | ||
321 | + case NSH_C1: | ||
322 | + OFOxmNshC1 nshC1 = (OFOxmNshC1) oxm; | ||
323 | + return new NiciraSetNshContextHeader(NshContextHeader.of((nshC1.getValue().getRaw())), | ||
324 | + ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH1 | ||
325 | + .type()); | ||
326 | + case NSH_C2: | ||
327 | + OFOxmNshC2 nshC2 = (OFOxmNshC2) oxm; | ||
328 | + return new NiciraSetNshContextHeader(NshContextHeader.of((nshC2.getValue().getRaw())), | ||
329 | + ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH2 | ||
330 | + .type()); | ||
331 | + case NSH_C3: | ||
332 | + OFOxmNshC3 nshC3 = (OFOxmNshC3) oxm; | ||
333 | + return new NiciraSetNshContextHeader(NshContextHeader.of((nshC3.getValue().getRaw())), | ||
334 | + ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH3 | ||
335 | + .type()); | ||
336 | + case NSH_C4: | ||
337 | + OFOxmNshC4 nshC4 = (OFOxmNshC4) oxm; | ||
338 | + return new NiciraSetNshContextHeader(NshContextHeader.of((nshC4.getValue().getRaw())), | ||
339 | + ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH4 | ||
340 | + .type()); | ||
341 | + case NSH_MDTYPE: | ||
342 | + OFOxmNshMdtype nshMdType = (OFOxmNshMdtype) oxm; | ||
343 | + return new NiciraNshMdType((nshMdType.getValue().getRaw())); | ||
344 | + case NSH_NP: | ||
345 | + OFOxmNshNp nshNp = (OFOxmNshNp) oxm; | ||
346 | + return new NiciraNshNp((nshNp.getValue().getRaw())); | ||
347 | + case ENCAP_ETH_SRC: | ||
348 | + OFOxmEncapEthSrc encapEthSrc = (OFOxmEncapEthSrc) oxm; | ||
349 | + return new NiciraEncapEthSrc(org.onlab.packet.MacAddress.valueOf((encapEthSrc.getValue().getBytes()))); | ||
350 | + case ENCAP_ETH_DST: | ||
351 | + OFOxmEncapEthDst encapEthDst = (OFOxmEncapEthDst) oxm; | ||
352 | + return new NiciraEncapEthDst(org.onlab.packet.MacAddress.valueOf((encapEthDst.getValue().getBytes()))); | ||
353 | + case ENCAP_ETH_TYPE: | ||
354 | + OFOxmEncapEthType encapEthType = (OFOxmEncapEthType) oxm; | ||
355 | + return new NiciraEncapEthType((encapEthType.getValue().getRaw())); | ||
356 | + case TUN_GPE_NP: | ||
357 | + OFOxmTunGpeNp tunGpeNp = (OFOxmTunGpeNp) oxm; | ||
358 | + return new NiciraTunGpeNp((tunGpeNp.getValue().getRaw())); | ||
165 | default: | 359 | default: |
166 | throw new UnsupportedOperationException( | 360 | throw new UnsupportedOperationException( |
167 | "Driver does not support extension type " + oxm.getMatchField().id); | 361 | "Driver does not support extension type " + oxm.getMatchField().id); |
... | @@ -188,14 +382,37 @@ public class NiciraExtensionTreatmentInterpreter extends AbstractHandlerBehaviou | ... | @@ -188,14 +382,37 @@ public class NiciraExtensionTreatmentInterpreter extends AbstractHandlerBehaviou |
188 | case SRC_ARP_SPA: | 382 | case SRC_ARP_SPA: |
189 | return NiciraMoveTreatmentFactory | 383 | return NiciraMoveTreatmentFactory |
190 | .createNiciraMovArpSpaToTpa(); | 384 | .createNiciraMovArpSpaToTpa(); |
385 | + case NSH_C1: | ||
386 | + return NiciraMoveTreatmentFactory.createNiciraMovNshC1ToC1(); | ||
387 | + case NSH_C2: | ||
388 | + if (Long.valueOf(moveAction.getDst()).intValue() == TUN_ID) { | ||
389 | + return NiciraMoveTreatmentFactory.createNiciraMovNshC2ToTunId(); | ||
390 | + } | ||
391 | + return NiciraMoveTreatmentFactory.createNiciraMovNshC2ToC2(); | ||
392 | + case NSH_C3: | ||
393 | + return NiciraMoveTreatmentFactory.createNiciraMovNshC3ToC3(); | ||
394 | + case NSH_C4: | ||
395 | + return NiciraMoveTreatmentFactory.createNiciraMovNshC4ToC4(); | ||
396 | + case TUN_IPV4_DST: | ||
397 | + return NiciraMoveTreatmentFactory.createNiciraMovTunDstToTunDst(); | ||
398 | + case TUN_ID: | ||
399 | + return NiciraMoveTreatmentFactory.createNiciraMovTunIdToTunId(); | ||
191 | default: | 400 | default: |
192 | throw new UnsupportedOperationException("Driver does not support move from " | 401 | throw new UnsupportedOperationException("Driver does not support move from " |
193 | - + moveAction.getSrc() + " to " | 402 | + + moveAction.getSrc() + " to " + moveAction.getDst() + "of length " |
194 | - + moveAction.getDst()); | 403 | + + moveAction.getNBits()); |
195 | } | 404 | } |
196 | case SUB_TYPE_RESUBMIT: | 405 | case SUB_TYPE_RESUBMIT: |
197 | OFActionNiciraResubmit resubmitAction = (OFActionNiciraResubmit) nicira; | 406 | OFActionNiciraResubmit resubmitAction = (OFActionNiciraResubmit) nicira; |
198 | return new NiciraResubmit(PortNumber.portNumber(resubmitAction.getInPort())); | 407 | return new NiciraResubmit(PortNumber.portNumber(resubmitAction.getInPort())); |
408 | + case SUB_TYPE_PUSH_NSH: | ||
409 | + return new NiciraPushNsh(); | ||
410 | + case SUB_TYPE_POP_NSH: | ||
411 | + return new NiciraPopNsh(); | ||
412 | + case SUB_TYPE_RESUBMIT_TABLE: | ||
413 | + OFActionNiciraResubmitTable resubmitTable = (OFActionNiciraResubmitTable) nicira; | ||
414 | + return new NiciraResubmitTable(PortNumber.portNumber(resubmitTable.getInPort()), | ||
415 | + resubmitTable.getTable()); | ||
199 | default: | 416 | default: |
200 | throw new UnsupportedOperationException("Driver does not support extension subtype " | 417 | throw new UnsupportedOperationException("Driver does not support extension subtype " |
201 | + nicira.getSubtype()); | 418 | + nicira.getSubtype()); |
... | @@ -228,6 +445,27 @@ public class NiciraExtensionTreatmentInterpreter extends AbstractHandlerBehaviou | ... | @@ -228,6 +445,27 @@ public class NiciraExtensionTreatmentInterpreter extends AbstractHandlerBehaviou |
228 | || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH4.type())) { | 445 | || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH4.type())) { |
229 | return new NiciraSetNshContextHeader(type); | 446 | return new NiciraSetNshContextHeader(type); |
230 | } | 447 | } |
448 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_PUSH_NSH.type())) { | ||
449 | + return new NiciraPushNsh(); | ||
450 | + } | ||
451 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_POP_NSH.type())) { | ||
452 | + return new NiciraPopNsh(); | ||
453 | + } | ||
454 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_MDTYPE.type())) { | ||
455 | + return new NiciraNshMdType(); | ||
456 | + } | ||
457 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_NP.type())) { | ||
458 | + return new NiciraNshNp(); | ||
459 | + } | ||
460 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_SRC.type())) { | ||
461 | + return new NiciraEncapEthSrc(); | ||
462 | + } | ||
463 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_DST.type())) { | ||
464 | + return new NiciraEncapEthDst(); | ||
465 | + } | ||
466 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_TYPE.type())) { | ||
467 | + return new NiciraEncapEthType(); | ||
468 | + } | ||
231 | if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ARP_SHA_TO_THA.type())) { | 469 | if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ARP_SHA_TO_THA.type())) { |
232 | return NiciraMoveTreatmentFactory.createNiciraMovArpShaToTha(); | 470 | return NiciraMoveTreatmentFactory.createNiciraMovArpShaToTha(); |
233 | } | 471 | } |
... | @@ -240,8 +478,32 @@ public class NiciraExtensionTreatmentInterpreter extends AbstractHandlerBehaviou | ... | @@ -240,8 +478,32 @@ public class NiciraExtensionTreatmentInterpreter extends AbstractHandlerBehaviou |
240 | if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_IP_SRC_TO_DST.type())) { | 478 | if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_IP_SRC_TO_DST.type())) { |
241 | return NiciraMoveTreatmentFactory.createNiciraMovIpSrcToDst(); | 479 | return NiciraMoveTreatmentFactory.createNiciraMovIpSrcToDst(); |
242 | } | 480 | } |
243 | - throw new UnsupportedOperationException( | 481 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_TUN_GPE_NP.type())) { |
244 | - "Driver does not support extension type " + type.toString()); | 482 | + return new NiciraTunGpeNp(); |
483 | + } | ||
484 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C1_TO_C1.type())) { | ||
485 | + return NiciraMoveTreatmentFactory.createNiciraMovNshC1ToC1(); | ||
486 | + } | ||
487 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C2_TO_C2.type())) { | ||
488 | + return NiciraMoveTreatmentFactory.createNiciraMovNshC2ToC2(); | ||
489 | + } | ||
490 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C3_TO_C3.type())) { | ||
491 | + return NiciraMoveTreatmentFactory.createNiciraMovNshC3ToC3(); | ||
492 | + } | ||
493 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C4_TO_C4.type())) { | ||
494 | + return NiciraMoveTreatmentFactory.createNiciraMovNshC4ToC4(); | ||
495 | + } | ||
496 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_TUN_IPV4_DST_TO_TUN_IPV4_DST | ||
497 | + .type())) { | ||
498 | + return NiciraMoveTreatmentFactory.createNiciraMovTunDstToTunDst(); | ||
499 | + } | ||
500 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_TUN_ID_TO_TUN_ID.type())) { | ||
501 | + return NiciraMoveTreatmentFactory.createNiciraMovTunIdToTunId(); | ||
502 | + } | ||
503 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C2_TO_TUN_ID.type())) { | ||
504 | + return NiciraMoveTreatmentFactory.createNiciraMovNshC2ToTunId(); | ||
505 | + } | ||
506 | + throw new UnsupportedOperationException("Driver does not support extension type " + type.toString()); | ||
245 | } | 507 | } |
246 | 508 | ||
247 | @Override | 509 | @Override | ... | ... |
drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraMatchEncapEthType.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2016-present 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 | + | ||
17 | +package org.onosproject.driver.extensions; | ||
18 | + | ||
19 | +import java.util.Objects; | ||
20 | + | ||
21 | +import org.onlab.util.KryoNamespace; | ||
22 | +import org.onosproject.net.flow.AbstractExtension; | ||
23 | +import org.onosproject.net.flow.criteria.ExtensionSelector; | ||
24 | +import org.onosproject.net.flow.criteria.ExtensionSelectorType; | ||
25 | + | ||
26 | +import com.google.common.base.MoreObjects; | ||
27 | + | ||
28 | +/** | ||
29 | + * Nicira EncapEthType extension selector to set encapsulated eth type. | ||
30 | + */ | ||
31 | +public class NiciraMatchEncapEthType extends AbstractExtension implements ExtensionSelector { | ||
32 | + | ||
33 | + private short encapEthType; | ||
34 | + | ||
35 | + private final KryoNamespace appKryo = new KryoNamespace.Builder().build(); | ||
36 | + | ||
37 | + /** | ||
38 | + * Creates a new nshEncapEthType selector. | ||
39 | + */ | ||
40 | + NiciraMatchEncapEthType() { | ||
41 | + encapEthType = (short) 0; | ||
42 | + } | ||
43 | + | ||
44 | + /** | ||
45 | + * Creates a new nshEncapEthType selector with given eth type. | ||
46 | + * | ||
47 | + * @param encapEthType encapsulated ethernet type | ||
48 | + */ | ||
49 | + public NiciraMatchEncapEthType(short encapEthType) { | ||
50 | + this.encapEthType = encapEthType; | ||
51 | + } | ||
52 | + | ||
53 | + /** | ||
54 | + * Gets the encapEthType. | ||
55 | + * | ||
56 | + * @return encapEthType | ||
57 | + */ | ||
58 | + public short encapEthType() { | ||
59 | + return encapEthType; | ||
60 | + } | ||
61 | + | ||
62 | + @Override | ||
63 | + public ExtensionSelectorType type() { | ||
64 | + return ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_ENCAP_ETH_TYPE.type(); | ||
65 | + } | ||
66 | + | ||
67 | + @Override | ||
68 | + public void deserialize(byte[] data) { | ||
69 | + encapEthType = (short) (appKryo.deserialize(data)); | ||
70 | + } | ||
71 | + | ||
72 | + @Override | ||
73 | + public byte[] serialize() { | ||
74 | + return appKryo.serialize(encapEthType); | ||
75 | + } | ||
76 | + | ||
77 | + @Override | ||
78 | + public int hashCode() { | ||
79 | + return Objects.hash(encapEthType); | ||
80 | + } | ||
81 | + | ||
82 | + @Override | ||
83 | + public boolean equals(Object obj) { | ||
84 | + if (this == obj) { | ||
85 | + return true; | ||
86 | + } | ||
87 | + if (obj instanceof NiciraMatchEncapEthType) { | ||
88 | + NiciraMatchEncapEthType that = (NiciraMatchEncapEthType) obj; | ||
89 | + return Objects.equals(encapEthType, that.encapEthType); | ||
90 | + | ||
91 | + } | ||
92 | + return false; | ||
93 | + } | ||
94 | + | ||
95 | + @Override | ||
96 | + public String toString() { | ||
97 | + return MoreObjects.toStringHelper(getClass()).add("encapEthType", encapEthType).toString(); | ||
98 | + } | ||
99 | +} |
... | @@ -97,4 +97,88 @@ public final class NiciraMoveTreatmentFactory { | ... | @@ -97,4 +97,88 @@ public final class NiciraMoveTreatmentFactory { |
97 | ExtensionTreatmentType.ExtensionTreatmentTypes | 97 | ExtensionTreatmentType.ExtensionTreatmentTypes |
98 | .NICIRA_MOV_IP_SRC_TO_DST.type()); | 98 | .NICIRA_MOV_IP_SRC_TO_DST.type()); |
99 | } | 99 | } |
100 | + | ||
101 | + public static ExtensionTreatment createNiciraMovNshC1ToC1() { | ||
102 | + int srcOfs = 0; | ||
103 | + int dstOfs = 0; | ||
104 | + int nBits = 32; | ||
105 | + int srcC1 = 0x0001e604; | ||
106 | + int dstC1 = 0x0001e604; | ||
107 | + return new DefaultMoveExtensionTreatment(srcOfs, dstOfs, nBits, srcC1, | ||
108 | + dstC1, | ||
109 | + ExtensionTreatmentType.ExtensionTreatmentTypes | ||
110 | + .NICIRA_MOV_NSH_C1_TO_C1.type()); | ||
111 | + } | ||
112 | + | ||
113 | + public static ExtensionTreatment createNiciraMovNshC2ToC2() { | ||
114 | + int srcOfs = 0; | ||
115 | + int dstOfs = 0; | ||
116 | + int nBits = 32; | ||
117 | + int srcC2 = 0x0001e804; | ||
118 | + int dstC2 = 0x0001e804; | ||
119 | + return new DefaultMoveExtensionTreatment(srcOfs, dstOfs, nBits, srcC2, | ||
120 | + dstC2, | ||
121 | + ExtensionTreatmentType.ExtensionTreatmentTypes | ||
122 | + .NICIRA_MOV_NSH_C2_TO_C2.type()); | ||
123 | + } | ||
124 | + | ||
125 | + public static ExtensionTreatment createNiciraMovNshC3ToC3() { | ||
126 | + int srcOfs = 0; | ||
127 | + int dstOfs = 0; | ||
128 | + int nBits = 32; | ||
129 | + int srcC3 = 0x0001ea04; | ||
130 | + int dstC3 = 0x0001ea04; | ||
131 | + return new DefaultMoveExtensionTreatment(srcOfs, dstOfs, nBits, srcC3, | ||
132 | + dstC3, | ||
133 | + ExtensionTreatmentType.ExtensionTreatmentTypes | ||
134 | + .NICIRA_MOV_NSH_C3_TO_C3.type()); | ||
135 | + } | ||
136 | + | ||
137 | + public static ExtensionTreatment createNiciraMovNshC4ToC4() { | ||
138 | + int srcOfs = 0; | ||
139 | + int dstOfs = 0; | ||
140 | + int nBits = 32; | ||
141 | + int srcC4 = 0x0001ec04; | ||
142 | + int dstC4 = 0x0001ec04; | ||
143 | + return new DefaultMoveExtensionTreatment(srcOfs, dstOfs, nBits, srcC4, | ||
144 | + dstC4, | ||
145 | + ExtensionTreatmentType.ExtensionTreatmentTypes | ||
146 | + .NICIRA_MOV_NSH_C4_TO_C4.type()); | ||
147 | + } | ||
148 | + | ||
149 | + public static ExtensionTreatment createNiciraMovTunDstToTunDst() { | ||
150 | + int srcOfs = 0; | ||
151 | + int dstOfs = 0; | ||
152 | + int nBits = 32; | ||
153 | + int srcTunIpv4Dst = 0x00014004; | ||
154 | + int dstTunIpv4Dst = 0x00014004; | ||
155 | + return new DefaultMoveExtensionTreatment(srcOfs, dstOfs, nBits, srcTunIpv4Dst, | ||
156 | + dstTunIpv4Dst, | ||
157 | + ExtensionTreatmentType.ExtensionTreatmentTypes | ||
158 | + .NICIRA_MOV_TUN_IPV4_DST_TO_TUN_IPV4_DST.type()); | ||
159 | + } | ||
160 | + | ||
161 | + public static ExtensionTreatment createNiciraMovTunIdToTunId() { | ||
162 | + int srcOfs = 0; | ||
163 | + int dstOfs = 0; | ||
164 | + int nBits = 64; | ||
165 | + int srcTunId = 0x12008; | ||
166 | + int dstTunId = 0x12008; // 0x80004c08; | ||
167 | + return new DefaultMoveExtensionTreatment(srcOfs, dstOfs, nBits, srcTunId, | ||
168 | + dstTunId, | ||
169 | + ExtensionTreatmentType.ExtensionTreatmentTypes | ||
170 | + .NICIRA_MOV_TUN_ID_TO_TUN_ID.type()); | ||
171 | + } | ||
172 | + | ||
173 | + public static ExtensionTreatment createNiciraMovNshC2ToTunId() { | ||
174 | + int srcOfs = 0; | ||
175 | + int dstOfs = 0; | ||
176 | + int nBits = 32; | ||
177 | + int srcC2 = 0x0001e804; | ||
178 | + int dstTunId = 0x80004c08; | ||
179 | + return new DefaultMoveExtensionTreatment(srcOfs, dstOfs, nBits, srcC2, | ||
180 | + dstTunId, | ||
181 | + ExtensionTreatmentType.ExtensionTreatmentTypes | ||
182 | + .NICIRA_MOV_NSH_C2_TO_TUN_ID.type()); | ||
183 | + } | ||
100 | } | 184 | } | ... | ... |
1 | +/* | ||
2 | + * Copyright 2016-present 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 | + | ||
17 | +package org.onosproject.driver.extensions; | ||
18 | + | ||
19 | +import java.util.Objects; | ||
20 | + | ||
21 | +import org.onlab.util.KryoNamespace; | ||
22 | +import org.onosproject.net.flow.AbstractExtension; | ||
23 | +import org.onosproject.net.flow.instructions.ExtensionTreatment; | ||
24 | +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; | ||
25 | + | ||
26 | +import com.google.common.base.MoreObjects; | ||
27 | + | ||
28 | +/** | ||
29 | + * Nicira nshMdType extension instruction. | ||
30 | + */ | ||
31 | +public class NiciraNshMdType extends AbstractExtension implements ExtensionTreatment { | ||
32 | + | ||
33 | + private byte nshMdType; | ||
34 | + | ||
35 | + private final KryoNamespace appKryo = new KryoNamespace.Builder().build(); | ||
36 | + | ||
37 | + /** | ||
38 | + * Creates a new nshMdType instruction. | ||
39 | + */ | ||
40 | + NiciraNshMdType() { | ||
41 | + nshMdType = (byte) 0; | ||
42 | + } | ||
43 | + | ||
44 | + /** | ||
45 | + * Creates a new nshMdType instruction with given nsh md type. | ||
46 | + * | ||
47 | + * @param nshMdType nsh md type | ||
48 | + */ | ||
49 | + public NiciraNshMdType(byte nshMdType) { | ||
50 | + this.nshMdType = nshMdType; | ||
51 | + } | ||
52 | + | ||
53 | + /** | ||
54 | + * Gets the nsh md type. | ||
55 | + * | ||
56 | + * @return nshMdType | ||
57 | + */ | ||
58 | + public byte nshMdType() { | ||
59 | + return nshMdType; | ||
60 | + } | ||
61 | + | ||
62 | + @Override | ||
63 | + public ExtensionTreatmentType type() { | ||
64 | + return ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_MDTYPE.type(); | ||
65 | + } | ||
66 | + | ||
67 | + @Override | ||
68 | + public void deserialize(byte[] data) { | ||
69 | + nshMdType = (byte) (appKryo.deserialize(data)); | ||
70 | + } | ||
71 | + | ||
72 | + @Override | ||
73 | + public byte[] serialize() { | ||
74 | + return appKryo.serialize(nshMdType); | ||
75 | + } | ||
76 | + | ||
77 | + @Override | ||
78 | + public int hashCode() { | ||
79 | + return Objects.hash(nshMdType); | ||
80 | + } | ||
81 | + | ||
82 | + @Override | ||
83 | + public boolean equals(Object obj) { | ||
84 | + if (this == obj) { | ||
85 | + return true; | ||
86 | + } | ||
87 | + if (obj instanceof NiciraNshMdType) { | ||
88 | + NiciraNshMdType that = (NiciraNshMdType) obj; | ||
89 | + return Objects.equals(nshMdType, that.nshMdType); | ||
90 | + | ||
91 | + } | ||
92 | + return false; | ||
93 | + } | ||
94 | + | ||
95 | + @Override | ||
96 | + public String toString() { | ||
97 | + return MoreObjects.toStringHelper(getClass()).add("nshMdType", nshMdType).toString(); | ||
98 | + } | ||
99 | +} |
1 | +/* | ||
2 | + * Copyright 2016-present 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 | + | ||
17 | +package org.onosproject.driver.extensions; | ||
18 | + | ||
19 | +import java.util.Objects; | ||
20 | + | ||
21 | +import org.onlab.util.KryoNamespace; | ||
22 | +import org.onosproject.net.flow.AbstractExtension; | ||
23 | +import org.onosproject.net.flow.instructions.ExtensionTreatment; | ||
24 | +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; | ||
25 | + | ||
26 | +import com.google.common.base.MoreObjects; | ||
27 | + | ||
28 | +/** | ||
29 | + * Nicira nshNp extension instruction to set next protocol value in nsh header. | ||
30 | + */ | ||
31 | +public class NiciraNshNp extends AbstractExtension implements ExtensionTreatment { | ||
32 | + | ||
33 | + private byte nshNp; | ||
34 | + | ||
35 | + private final KryoNamespace appKryo = new KryoNamespace.Builder().build(); | ||
36 | + | ||
37 | + /** | ||
38 | + * Creates a new nshNp instruction. | ||
39 | + */ | ||
40 | + NiciraNshNp() { | ||
41 | + nshNp = (byte) 0; | ||
42 | + } | ||
43 | + | ||
44 | + /** | ||
45 | + * Creates a new nshNp instruction with given nsh np. | ||
46 | + * | ||
47 | + * @param nshNp nsh next protocol value | ||
48 | + */ | ||
49 | + public NiciraNshNp(byte nshNp) { | ||
50 | + this.nshNp = nshNp; | ||
51 | + } | ||
52 | + | ||
53 | + /** | ||
54 | + * Gets the nsh np. | ||
55 | + * | ||
56 | + * @return nshNp | ||
57 | + */ | ||
58 | + public byte nshNp() { | ||
59 | + return nshNp; | ||
60 | + } | ||
61 | + | ||
62 | + @Override | ||
63 | + public ExtensionTreatmentType type() { | ||
64 | + return ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_NP.type(); | ||
65 | + } | ||
66 | + | ||
67 | + @Override | ||
68 | + public void deserialize(byte[] data) { | ||
69 | + nshNp = (byte) (appKryo.deserialize(data)); | ||
70 | + } | ||
71 | + | ||
72 | + @Override | ||
73 | + public byte[] serialize() { | ||
74 | + return appKryo.serialize(nshNp); | ||
75 | + } | ||
76 | + | ||
77 | + @Override | ||
78 | + public int hashCode() { | ||
79 | + return Objects.hash(nshNp); | ||
80 | + } | ||
81 | + | ||
82 | + @Override | ||
83 | + public boolean equals(Object obj) { | ||
84 | + if (this == obj) { | ||
85 | + return true; | ||
86 | + } | ||
87 | + if (obj instanceof NiciraNshNp) { | ||
88 | + NiciraNshNp that = (NiciraNshNp) obj; | ||
89 | + return Objects.equals(nshNp, that.nshNp); | ||
90 | + | ||
91 | + } | ||
92 | + return false; | ||
93 | + } | ||
94 | + | ||
95 | + @Override | ||
96 | + public String toString() { | ||
97 | + return MoreObjects.toStringHelper(getClass()).add("nshNp", nshNp).toString(); | ||
98 | + } | ||
99 | +} |
1 | +/* | ||
2 | + * Copyright 2016-present 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 | + | ||
17 | +package org.onosproject.driver.extensions; | ||
18 | + | ||
19 | +import org.onlab.util.KryoNamespace; | ||
20 | +import org.onosproject.net.flow.AbstractExtension; | ||
21 | +import org.onosproject.net.flow.instructions.ExtensionTreatment; | ||
22 | +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; | ||
23 | + | ||
24 | +/** | ||
25 | + * Nicira pop nsh extension instruction. | ||
26 | + */ | ||
27 | +public class NiciraPopNsh extends AbstractExtension implements ExtensionTreatment { | ||
28 | + | ||
29 | + private final KryoNamespace appKryo = new KryoNamespace.Builder().build(); | ||
30 | + | ||
31 | + /** | ||
32 | + * Creates a new pop nsh instruction. | ||
33 | + */ | ||
34 | + public NiciraPopNsh() { | ||
35 | + } | ||
36 | + | ||
37 | + @Override | ||
38 | + public ExtensionTreatmentType type() { | ||
39 | + return ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_POP_NSH.type(); | ||
40 | + } | ||
41 | + | ||
42 | + @Override | ||
43 | + public void deserialize(byte[] data) { | ||
44 | + } | ||
45 | + | ||
46 | + @Override | ||
47 | + public byte[] serialize() { | ||
48 | + return appKryo.serialize(0); | ||
49 | + } | ||
50 | + | ||
51 | + @Override | ||
52 | + public int hashCode() { | ||
53 | + return 1; | ||
54 | + } | ||
55 | + | ||
56 | + @Override | ||
57 | + public boolean equals(Object obj) { | ||
58 | + if (this == obj) { | ||
59 | + return true; | ||
60 | + } | ||
61 | + if (obj instanceof NiciraPopNsh) { | ||
62 | + return true; | ||
63 | + } | ||
64 | + return false; | ||
65 | + } | ||
66 | +} |
1 | +/* | ||
2 | + * Copyright 2016-present 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 | + | ||
17 | +package org.onosproject.driver.extensions; | ||
18 | + | ||
19 | +import org.onlab.util.KryoNamespace; | ||
20 | +import org.onosproject.net.flow.AbstractExtension; | ||
21 | +import org.onosproject.net.flow.instructions.ExtensionTreatment; | ||
22 | +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; | ||
23 | + | ||
24 | +/** | ||
25 | + * Nicira push nsh extension instruction. | ||
26 | + */ | ||
27 | +public class NiciraPushNsh extends AbstractExtension implements ExtensionTreatment { | ||
28 | + | ||
29 | + private final KryoNamespace appKryo = new KryoNamespace.Builder().build(); | ||
30 | + | ||
31 | + /** | ||
32 | + * Creates a new push nsh instruction. | ||
33 | + */ | ||
34 | + public NiciraPushNsh() { | ||
35 | + | ||
36 | + } | ||
37 | + | ||
38 | + @Override | ||
39 | + public ExtensionTreatmentType type() { | ||
40 | + return ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_PUSH_NSH.type(); | ||
41 | + } | ||
42 | + | ||
43 | + @Override | ||
44 | + public void deserialize(byte[] data) { | ||
45 | + } | ||
46 | + | ||
47 | + @Override | ||
48 | + public byte[] serialize() { | ||
49 | + return appKryo.serialize(0); | ||
50 | + } | ||
51 | + | ||
52 | + @Override | ||
53 | + public int hashCode() { | ||
54 | + return 1; | ||
55 | + } | ||
56 | + | ||
57 | + @Override | ||
58 | + public boolean equals(Object obj) { | ||
59 | + if (this == obj) { | ||
60 | + return true; | ||
61 | + } | ||
62 | + if (obj instanceof NiciraPushNsh) { | ||
63 | + return true; | ||
64 | + } | ||
65 | + return false; | ||
66 | + } | ||
67 | +} |
... | @@ -16,6 +16,7 @@ | ... | @@ -16,6 +16,7 @@ |
16 | 16 | ||
17 | package org.onosproject.driver.extensions; | 17 | package org.onosproject.driver.extensions; |
18 | 18 | ||
19 | +import java.util.Map; | ||
19 | import java.util.Objects; | 20 | import java.util.Objects; |
20 | 21 | ||
21 | import org.onlab.util.KryoNamespace; | 22 | import org.onlab.util.KryoNamespace; |
... | @@ -25,6 +26,7 @@ import org.onosproject.net.flow.instructions.ExtensionTreatment; | ... | @@ -25,6 +26,7 @@ import org.onosproject.net.flow.instructions.ExtensionTreatment; |
25 | import org.onosproject.net.flow.instructions.ExtensionTreatmentType; | 26 | import org.onosproject.net.flow.instructions.ExtensionTreatmentType; |
26 | 27 | ||
27 | import com.google.common.base.MoreObjects; | 28 | import com.google.common.base.MoreObjects; |
29 | +import com.google.common.collect.Maps; | ||
28 | 30 | ||
29 | /** | 31 | /** |
30 | * Nicira set NSH Context header extension instruction. | 32 | * Nicira set NSH Context header extension instruction. |
... | @@ -74,12 +76,17 @@ public class NiciraSetNshContextHeader extends AbstractExtension implements | ... | @@ -74,12 +76,17 @@ public class NiciraSetNshContextHeader extends AbstractExtension implements |
74 | 76 | ||
75 | @Override | 77 | @Override |
76 | public void deserialize(byte[] data) { | 78 | public void deserialize(byte[] data) { |
77 | - nshCh = NshContextHeader.of(appKryo.deserialize(data)); | 79 | + Map<String, Object> values = appKryo.deserialize(data); |
80 | + nshCh = (NshContextHeader) values.get("nshCh"); | ||
81 | + type = (ExtensionTreatmentType) values.get("type"); | ||
78 | } | 82 | } |
79 | 83 | ||
80 | @Override | 84 | @Override |
81 | public byte[] serialize() { | 85 | public byte[] serialize() { |
82 | - return appKryo.serialize(nshCh.nshContextHeader()); | 86 | + Map<String, Object> values = Maps.newHashMap(); |
87 | + values.put("nshCh", nshCh); | ||
88 | + values.put("type", type); | ||
89 | + return appKryo.serialize(values); | ||
83 | } | 90 | } |
84 | 91 | ||
85 | @Override | 92 | @Override | ... | ... |
1 | +/* | ||
2 | + * Copyright 2016-present 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 | + | ||
17 | +package org.onosproject.driver.extensions; | ||
18 | + | ||
19 | +import java.util.Objects; | ||
20 | + | ||
21 | +import org.onlab.util.KryoNamespace; | ||
22 | +import org.onosproject.net.flow.AbstractExtension; | ||
23 | +import org.onosproject.net.flow.instructions.ExtensionTreatment; | ||
24 | +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; | ||
25 | + | ||
26 | +import com.google.common.base.MoreObjects; | ||
27 | + | ||
28 | +/** | ||
29 | + * Nicira tunnel gpe next protocol extension instruction to tunGpeNp value. | ||
30 | + */ | ||
31 | +public class NiciraTunGpeNp extends AbstractExtension implements ExtensionTreatment { | ||
32 | + | ||
33 | + private byte tunGpeNp; | ||
34 | + | ||
35 | + private final KryoNamespace appKryo = new KryoNamespace.Builder().build(); | ||
36 | + | ||
37 | + /** | ||
38 | + * Creates a new NiciraTunGpeNp instruction. | ||
39 | + */ | ||
40 | + NiciraTunGpeNp() { | ||
41 | + tunGpeNp = (byte) 0; | ||
42 | + } | ||
43 | + | ||
44 | + /** | ||
45 | + * Creates a new NiciraTunGpeNp instruction with given value. | ||
46 | + * | ||
47 | + * @param tunGpeNp tunnel gpe next protocol value | ||
48 | + */ | ||
49 | + public NiciraTunGpeNp(byte tunGpeNp) { | ||
50 | + this.tunGpeNp = tunGpeNp; | ||
51 | + } | ||
52 | + | ||
53 | + /** | ||
54 | + * Gets the tunGpeNp. | ||
55 | + * | ||
56 | + * @return tunGpeNp | ||
57 | + */ | ||
58 | + public byte tunGpeNp() { | ||
59 | + return tunGpeNp; | ||
60 | + } | ||
61 | + | ||
62 | + @Override | ||
63 | + public ExtensionTreatmentType type() { | ||
64 | + return ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_TUN_GPE_NP.type(); | ||
65 | + } | ||
66 | + | ||
67 | + @Override | ||
68 | + public void deserialize(byte[] data) { | ||
69 | + tunGpeNp = (byte) (appKryo.deserialize(data)); | ||
70 | + } | ||
71 | + | ||
72 | + @Override | ||
73 | + public byte[] serialize() { | ||
74 | + return appKryo.serialize(tunGpeNp); | ||
75 | + } | ||
76 | + | ||
77 | + @Override | ||
78 | + public int hashCode() { | ||
79 | + return Objects.hash(tunGpeNp); | ||
80 | + } | ||
81 | + | ||
82 | + @Override | ||
83 | + public boolean equals(Object obj) { | ||
84 | + if (this == obj) { | ||
85 | + return true; | ||
86 | + } | ||
87 | + if (obj instanceof NiciraTunGpeNp) { | ||
88 | + NiciraTunGpeNp that = (NiciraTunGpeNp) obj; | ||
89 | + return Objects.equals(tunGpeNp, that.tunGpeNp); | ||
90 | + | ||
91 | + } | ||
92 | + return false; | ||
93 | + } | ||
94 | + | ||
95 | + @Override | ||
96 | + public String toString() { | ||
97 | + return MoreObjects.toStringHelper(getClass()).add("tunGpeNp", tunGpeNp).toString(); | ||
98 | + } | ||
99 | +} |
... | @@ -70,6 +70,8 @@ public class OpenVSwitchPipeline extends DefaultSingleTablePipeline | ... | @@ -70,6 +70,8 @@ public class OpenVSwitchPipeline extends DefaultSingleTablePipeline |
70 | protected DeviceService deviceService; | 70 | protected DeviceService deviceService; |
71 | private static final int TIME_OUT = 0; | 71 | private static final int TIME_OUT = 0; |
72 | private static final int CLASSIFIER_TABLE = 0; | 72 | private static final int CLASSIFIER_TABLE = 0; |
73 | + private static final int ENCAP_OUTPUT_TABLE = 4; | ||
74 | + private static final int TUN_SEND_TABLE = 7; | ||
73 | private static final int ARP_TABLE = 10; | 75 | private static final int ARP_TABLE = 10; |
74 | private static final int DNAT_TABLE = 20; | 76 | private static final int DNAT_TABLE = 20; |
75 | private static final int L3FWD_TABLE = 30; | 77 | private static final int L3FWD_TABLE = 30; |
... | @@ -278,7 +280,23 @@ public class OpenVSwitchPipeline extends DefaultSingleTablePipeline | ... | @@ -278,7 +280,23 @@ public class OpenVSwitchPipeline extends DefaultSingleTablePipeline |
278 | 280 | ||
279 | private Collection<FlowRule> processVersatile(ForwardingObjective fwd) { | 281 | private Collection<FlowRule> processVersatile(ForwardingObjective fwd) { |
280 | log.debug("Processing versatile forwarding objective"); | 282 | log.debug("Processing versatile forwarding objective"); |
281 | - return Collections.emptyList(); | 283 | + TrafficSelector selector = fwd.selector(); |
284 | + TrafficTreatment tb = fwd.treatment(); | ||
285 | + FlowRule.Builder ruleBuilder = DefaultFlowRule.builder().fromApp(fwd.appId()).withPriority(fwd.priority()) | ||
286 | + .forDevice(deviceId).withSelector(selector).withTreatment(tb).makeTemporary(TIME_OUT); | ||
287 | + ruleBuilder.withPriority(fwd.priority()); | ||
288 | + if (fwd.priority() == 100) { | ||
289 | + ruleBuilder.forTable(ENCAP_OUTPUT_TABLE); | ||
290 | + } else if (fwd.priority() == 200) { | ||
291 | + ruleBuilder.forTable(TUN_SEND_TABLE); | ||
292 | + } else { | ||
293 | + ruleBuilder.forTable(CLASSIFIER_TABLE); | ||
294 | + } | ||
295 | + | ||
296 | + if (fwd.permanent()) { | ||
297 | + ruleBuilder.makePermanent(); | ||
298 | + } | ||
299 | + return Collections.singletonList(ruleBuilder.build()); | ||
282 | } | 300 | } |
283 | 301 | ||
284 | private Collection<FlowRule> processSpecific(ForwardingObjective fwd) { | 302 | private Collection<FlowRule> processSpecific(ForwardingObjective fwd) { | ... | ... |
drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraEncapEthDstTest.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2016-present 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.driver.extensions; | ||
17 | + | ||
18 | +import static org.hamcrest.MatcherAssert.assertThat; | ||
19 | +import static org.hamcrest.Matchers.is; | ||
20 | +import static org.hamcrest.Matchers.notNullValue; | ||
21 | + | ||
22 | +import org.junit.Test; | ||
23 | +import org.onlab.packet.MacAddress; | ||
24 | + | ||
25 | +import com.google.common.testing.EqualsTester; | ||
26 | + | ||
27 | +/** | ||
28 | + * Unit tests for NiciraEncapEthDstTest class. | ||
29 | + */ | ||
30 | +public class NiciraEncapEthDstTest { | ||
31 | + | ||
32 | + private final MacAddress mac1 = MacAddress.valueOf("fa:16:3e:da:45:23"); | ||
33 | + private final MacAddress mac2 = MacAddress.valueOf("fa:16:3e:f3:d1:fe"); | ||
34 | + | ||
35 | + /** | ||
36 | + * Checks the operation of equals() methods. | ||
37 | + */ | ||
38 | + @Test | ||
39 | + public void testEquals() { | ||
40 | + final NiciraEncapEthDst encapEthDst1 = new NiciraEncapEthDst(mac1); | ||
41 | + final NiciraEncapEthDst sameAsEncapEthDst1 = new NiciraEncapEthDst(mac1); | ||
42 | + final NiciraEncapEthDst encapEthDst2 = new NiciraEncapEthDst(mac2); | ||
43 | + | ||
44 | + new EqualsTester().addEqualityGroup(encapEthDst1, sameAsEncapEthDst1).addEqualityGroup(encapEthDst2) | ||
45 | + .testEquals(); | ||
46 | + } | ||
47 | + | ||
48 | + /** | ||
49 | + * Checks the construction of a NiciraEncapEthDstTest object. | ||
50 | + */ | ||
51 | + @Test | ||
52 | + public void testConstruction() { | ||
53 | + final NiciraEncapEthDst encapEthDst1 = new NiciraEncapEthDst(mac1); | ||
54 | + assertThat(encapEthDst1, is(notNullValue())); | ||
55 | + assertThat(encapEthDst1.encapEthDst(), is(mac1)); | ||
56 | + } | ||
57 | +} |
drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraEncapEthSrcTest.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2016-present 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.driver.extensions; | ||
17 | + | ||
18 | +import static org.hamcrest.MatcherAssert.assertThat; | ||
19 | +import static org.hamcrest.Matchers.is; | ||
20 | +import static org.hamcrest.Matchers.notNullValue; | ||
21 | + | ||
22 | +import org.junit.Test; | ||
23 | +import org.onlab.packet.MacAddress; | ||
24 | + | ||
25 | +import com.google.common.testing.EqualsTester; | ||
26 | + | ||
27 | +/** | ||
28 | + * Unit tests for NiciraEncapEthSrcTest class. | ||
29 | + */ | ||
30 | +public class NiciraEncapEthSrcTest { | ||
31 | + | ||
32 | + private final MacAddress mac1 = MacAddress.valueOf("fa:16:3e:11:00:01"); | ||
33 | + private final MacAddress mac2 = MacAddress.valueOf("fa:16:3e:22:00:02"); | ||
34 | + | ||
35 | + /** | ||
36 | + * Checks the operation of equals() methods. | ||
37 | + */ | ||
38 | + @Test | ||
39 | + public void testEquals() { | ||
40 | + final NiciraEncapEthDst encapEthDst1 = new NiciraEncapEthDst(mac1); | ||
41 | + final NiciraEncapEthDst sameAsEncapEthDst1 = new NiciraEncapEthDst(mac1); | ||
42 | + final NiciraEncapEthDst encapEthDst2 = new NiciraEncapEthDst(mac2); | ||
43 | + | ||
44 | + new EqualsTester().addEqualityGroup(encapEthDst1, sameAsEncapEthDst1).addEqualityGroup(encapEthDst2) | ||
45 | + .testEquals(); | ||
46 | + } | ||
47 | + | ||
48 | + /** | ||
49 | + * Checks the construction of a NiciraEncapEthSrcTest object. | ||
50 | + */ | ||
51 | + @Test | ||
52 | + public void testConstruction() { | ||
53 | + | ||
54 | + final NiciraEncapEthDst encapEthDst1 = new NiciraEncapEthDst(mac1); | ||
55 | + assertThat(encapEthDst1, is(notNullValue())); | ||
56 | + assertThat(encapEthDst1.encapEthDst(), is(mac1)); | ||
57 | + } | ||
58 | +} |
drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraEncapEthTypeTest.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2016-present 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.driver.extensions; | ||
17 | + | ||
18 | +import static org.hamcrest.MatcherAssert.assertThat; | ||
19 | +import static org.hamcrest.Matchers.is; | ||
20 | +import static org.hamcrest.Matchers.notNullValue; | ||
21 | + | ||
22 | +import org.junit.Test; | ||
23 | + | ||
24 | +import com.google.common.testing.EqualsTester; | ||
25 | + | ||
26 | +/** | ||
27 | + * Unit tests for NiciraEncapEthType class. | ||
28 | + */ | ||
29 | +public class NiciraEncapEthTypeTest { | ||
30 | + final short ethType1 = (short) 0x894f; | ||
31 | + final short ethType2 = (short) 0x800; | ||
32 | + | ||
33 | + /** | ||
34 | + * Checks the operation of equals() methods. | ||
35 | + */ | ||
36 | + @Test | ||
37 | + public void testEquals() { | ||
38 | + final NiciraEncapEthType encapEthType1 = new NiciraEncapEthType(ethType1); | ||
39 | + final NiciraEncapEthType sameAsEncapEthType1 = new NiciraEncapEthType(ethType1); | ||
40 | + final NiciraEncapEthType encapEthType2 = new NiciraEncapEthType(ethType2); | ||
41 | + | ||
42 | + new EqualsTester().addEqualityGroup(encapEthType1, sameAsEncapEthType1).addEqualityGroup(encapEthType2) | ||
43 | + .testEquals(); | ||
44 | + } | ||
45 | + | ||
46 | + /** | ||
47 | + * Checks the construction of a NiciraEncapEthType object. | ||
48 | + */ | ||
49 | + @Test | ||
50 | + public void testConstruction() { | ||
51 | + final NiciraEncapEthType encapEthType = new NiciraEncapEthType(ethType1); | ||
52 | + assertThat(encapEthType, is(notNullValue())); | ||
53 | + assertThat(encapEthType.encapEthType(), is(ethType1)); | ||
54 | + } | ||
55 | +} |
drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraMatchEncapEthTypeTest.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2016-present 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.driver.extensions; | ||
17 | + | ||
18 | +import static org.hamcrest.MatcherAssert.assertThat; | ||
19 | +import static org.hamcrest.Matchers.is; | ||
20 | +import static org.hamcrest.Matchers.notNullValue; | ||
21 | + | ||
22 | +import org.junit.Test; | ||
23 | + | ||
24 | +import com.google.common.testing.EqualsTester; | ||
25 | + | ||
26 | +/** | ||
27 | + * Unit tests for NiciraMatchEncapEthType class. | ||
28 | + */ | ||
29 | +public class NiciraMatchEncapEthTypeTest { | ||
30 | + final short ethType1 = (short) 0x894f; | ||
31 | + final short ethType2 = (short) 0x800; | ||
32 | + | ||
33 | + /** | ||
34 | + * Checks the operation of equals() methods. | ||
35 | + */ | ||
36 | + @Test | ||
37 | + public void testEquals() { | ||
38 | + final NiciraMatchEncapEthType encapEthType1 = new NiciraMatchEncapEthType(ethType1); | ||
39 | + final NiciraMatchEncapEthType sameAsEncapEthType1 = new NiciraMatchEncapEthType(ethType1); | ||
40 | + final NiciraMatchEncapEthType encapEthType2 = new NiciraMatchEncapEthType(ethType2); | ||
41 | + | ||
42 | + new EqualsTester().addEqualityGroup(encapEthType1, sameAsEncapEthType1).addEqualityGroup(encapEthType2) | ||
43 | + .testEquals(); | ||
44 | + } | ||
45 | + | ||
46 | + /** | ||
47 | + * Checks the construction of a NiciraMatchEncapEthType object. | ||
48 | + */ | ||
49 | + @Test | ||
50 | + public void testConstruction() { | ||
51 | + final NiciraMatchEncapEthType encapEthType = new NiciraMatchEncapEthType(ethType1); | ||
52 | + assertThat(encapEthType, is(notNullValue())); | ||
53 | + assertThat(encapEthType.encapEthType(), is(ethType1)); | ||
54 | + } | ||
55 | +} |
1 | +/* | ||
2 | + * Copyright 2016-present 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.driver.extensions; | ||
17 | + | ||
18 | +import static org.hamcrest.MatcherAssert.assertThat; | ||
19 | +import static org.hamcrest.Matchers.is; | ||
20 | +import static org.hamcrest.Matchers.notNullValue; | ||
21 | + | ||
22 | +import org.junit.Test; | ||
23 | + | ||
24 | +import com.google.common.testing.EqualsTester; | ||
25 | + | ||
26 | +/** | ||
27 | + * Unit tests for NiciraNshMdType class. | ||
28 | + */ | ||
29 | +public class NiciraNshMdTypeTest { | ||
30 | + final byte mdType1 = (byte) 1; | ||
31 | + final byte mdType2 = (byte) 2; | ||
32 | + | ||
33 | + /** | ||
34 | + * Checks the operation of equals() methods. | ||
35 | + */ | ||
36 | + @Test | ||
37 | + public void testEquals() { | ||
38 | + final NiciraNshMdType nshMdType1 = new NiciraNshMdType(mdType1); | ||
39 | + final NiciraNshMdType sameAsnshMdType1 = new NiciraNshMdType(mdType1); | ||
40 | + final NiciraNshMdType nshMdType2 = new NiciraNshMdType(mdType2); | ||
41 | + | ||
42 | + new EqualsTester().addEqualityGroup(nshMdType1, sameAsnshMdType1).addEqualityGroup(nshMdType2) | ||
43 | + .testEquals(); | ||
44 | + } | ||
45 | + | ||
46 | + /** | ||
47 | + * Checks the construction of a NiciraNshMdType object. | ||
48 | + */ | ||
49 | + @Test | ||
50 | + public void testConstruction() { | ||
51 | + final NiciraNshMdType nshMdType = new NiciraNshMdType(mdType1); | ||
52 | + assertThat(nshMdType, is(notNullValue())); | ||
53 | + assertThat(nshMdType.nshMdType(), is(mdType1)); | ||
54 | + } | ||
55 | +} |
1 | +/* | ||
2 | + * Copyright 2016-present 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.driver.extensions; | ||
17 | + | ||
18 | +import static org.hamcrest.MatcherAssert.assertThat; | ||
19 | +import static org.hamcrest.Matchers.is; | ||
20 | +import static org.hamcrest.Matchers.notNullValue; | ||
21 | + | ||
22 | +import org.junit.Test; | ||
23 | + | ||
24 | +import com.google.common.testing.EqualsTester; | ||
25 | + | ||
26 | +/** | ||
27 | + * Unit tests for NiciraNshNp class. | ||
28 | + */ | ||
29 | +public class NiciraNshNpTest { | ||
30 | + final byte np1 = (byte) 1; | ||
31 | + final byte np2 = (byte) 4; | ||
32 | + | ||
33 | + /** | ||
34 | + * Checks the operation of equals() methods. | ||
35 | + */ | ||
36 | + @Test | ||
37 | + public void testEquals() { | ||
38 | + final NiciraNshNp nshNp1 = new NiciraNshNp(np1); | ||
39 | + final NiciraNshNp sameAsNshNp1 = new NiciraNshNp(np1); | ||
40 | + final NiciraNshNp nshNp2 = new NiciraNshNp(np2); | ||
41 | + | ||
42 | + new EqualsTester().addEqualityGroup(nshNp1, sameAsNshNp1).addEqualityGroup(nshNp2) | ||
43 | + .testEquals(); | ||
44 | + } | ||
45 | + | ||
46 | + /** | ||
47 | + * Checks the construction of a NiciraNshNp object. | ||
48 | + */ | ||
49 | + @Test | ||
50 | + public void testConstruction() { | ||
51 | + final NiciraNshNp nshNp1 = new NiciraNshNp(np1); | ||
52 | + assertThat(nshNp1, is(notNullValue())); | ||
53 | + assertThat(nshNp1.nshNp(), is(np1)); | ||
54 | + } | ||
55 | +} |
1 | +/* | ||
2 | + * Copyright 2016-present 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.driver.extensions; | ||
17 | + | ||
18 | +import static org.hamcrest.MatcherAssert.assertThat; | ||
19 | +import static org.hamcrest.Matchers.is; | ||
20 | +import static org.hamcrest.Matchers.notNullValue; | ||
21 | + | ||
22 | +import org.junit.Test; | ||
23 | + | ||
24 | +import com.google.common.testing.EqualsTester; | ||
25 | + | ||
26 | +/** | ||
27 | + * Unit tests for NiciraTunGpeNp class. | ||
28 | + */ | ||
29 | +public class NiciraTunGpeNpTest { | ||
30 | + final byte np1 = (byte) 1; | ||
31 | + final byte np2 = (byte) 2; | ||
32 | + | ||
33 | + /** | ||
34 | + * Checks the operation of equals() methods. | ||
35 | + */ | ||
36 | + @Test | ||
37 | + public void testEquals() { | ||
38 | + final NiciraTunGpeNp tunGpeNp1 = new NiciraTunGpeNp(np1); | ||
39 | + final NiciraTunGpeNp sameAsTunGpeNp1 = new NiciraTunGpeNp(np1); | ||
40 | + final NiciraTunGpeNp tunGpeNp2 = new NiciraTunGpeNp(np2); | ||
41 | + | ||
42 | + new EqualsTester().addEqualityGroup(tunGpeNp1, sameAsTunGpeNp1).addEqualityGroup(tunGpeNp2) | ||
43 | + .testEquals(); | ||
44 | + } | ||
45 | + | ||
46 | + /** | ||
47 | + * Checks the construction of a NiciraTunGpeNp object. | ||
48 | + */ | ||
49 | + @Test | ||
50 | + public void testConstruction() { | ||
51 | + final NiciraTunGpeNp tunGpeNp1 = new NiciraTunGpeNp(np1); | ||
52 | + assertThat(tunGpeNp1, is(notNullValue())); | ||
53 | + assertThat(tunGpeNp1.tunGpeNp(), is(np1)); | ||
54 | + } | ||
55 | +} |
... | @@ -511,6 +511,18 @@ public class FlowEntryBuilder { | ... | @@ -511,6 +511,18 @@ public class FlowEntryBuilder { |
511 | builder.setUdpSrc(TpPort.tpPort(udpsrc.getValue().getPort())); | 511 | builder.setUdpSrc(TpPort.tpPort(udpsrc.getValue().getPort())); |
512 | break; | 512 | break; |
513 | case TUNNEL_IPV4_DST: | 513 | case TUNNEL_IPV4_DST: |
514 | + case NSP: | ||
515 | + case NSI: | ||
516 | + case NSH_C1: | ||
517 | + case NSH_C2: | ||
518 | + case NSH_C3: | ||
519 | + case NSH_C4: | ||
520 | + case NSH_MDTYPE: | ||
521 | + case NSH_NP: | ||
522 | + case ENCAP_ETH_SRC: | ||
523 | + case ENCAP_ETH_DST: | ||
524 | + case ENCAP_ETH_TYPE: | ||
525 | + case TUN_GPE_NP: | ||
514 | if (treatmentInterpreter != null) { | 526 | if (treatmentInterpreter != null) { |
515 | try { | 527 | try { |
516 | builder.extension(treatmentInterpreter.mapAction(action), deviceId); | 528 | builder.extension(treatmentInterpreter.mapAction(action), deviceId); |
... | @@ -900,6 +912,37 @@ public class FlowEntryBuilder { | ... | @@ -900,6 +912,37 @@ public class FlowEntryBuilder { |
900 | ip = Ip4Address.valueOf(match.get(MatchField.ARP_TPA).getInt()); | 912 | ip = Ip4Address.valueOf(match.get(MatchField.ARP_TPA).getInt()); |
901 | builder.matchArpTpa(ip); | 913 | builder.matchArpTpa(ip); |
902 | break; | 914 | break; |
915 | + | ||
916 | + case NSP: | ||
917 | + if (selectorInterpreter != null) { | ||
918 | + try { | ||
919 | + OFOxm oxm = ((OFMatchV3) match).getOxmList().get(MatchField.NSP); | ||
920 | + builder.extension(selectorInterpreter.mapOxm(oxm), deviceId); | ||
921 | + } catch (UnsupportedOperationException e) { | ||
922 | + log.debug(e.getMessage()); | ||
923 | + } | ||
924 | + } | ||
925 | + break; | ||
926 | + case NSI: | ||
927 | + if (selectorInterpreter != null) { | ||
928 | + try { | ||
929 | + OFOxm oxm = ((OFMatchV3) match).getOxmList().get(MatchField.NSI); | ||
930 | + builder.extension(selectorInterpreter.mapOxm(oxm), deviceId); | ||
931 | + } catch (UnsupportedOperationException e) { | ||
932 | + log.debug(e.getMessage()); | ||
933 | + } | ||
934 | + } | ||
935 | + break; | ||
936 | + case ENCAP_ETH_TYPE: | ||
937 | + if (selectorInterpreter != null) { | ||
938 | + try { | ||
939 | + OFOxm oxm = ((OFMatchV3) match).getOxmList().get(MatchField.ENCAP_ETH_TYPE); | ||
940 | + builder.extension(selectorInterpreter.mapOxm(oxm), deviceId); | ||
941 | + } catch (UnsupportedOperationException e) { | ||
942 | + log.debug(e.getMessage()); | ||
943 | + } | ||
944 | + } | ||
945 | + break; | ||
903 | case MPLS_TC: | 946 | case MPLS_TC: |
904 | default: | 947 | default: |
905 | log.warn("Match type {} not yet implemented.", field.id); | 948 | log.warn("Match type {} not yet implemented.", field.id); | ... | ... |
-
Please register or login to post a comment