blob: 79885c3c674c68d723192a1b4c02ee223add9718 [file] [log] [blame]
Jonathan Hartea750842015-04-23 17:44:49 -07001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.cordfabric;
18
19import com.google.common.collect.HashMultimap;
20import com.google.common.collect.Multimap;
Jonathan Hartea750842015-04-23 17:44:49 -070021import org.apache.felix.scr.annotations.Activate;
22import org.apache.felix.scr.annotations.Component;
23import org.apache.felix.scr.annotations.Deactivate;
24import org.apache.felix.scr.annotations.Reference;
25import org.apache.felix.scr.annotations.ReferenceCardinality;
26import org.apache.felix.scr.annotations.Service;
Jonathan Hart0b989982015-05-14 15:40:07 -070027import org.onlab.packet.Ethernet;
28import org.onlab.packet.IPv4;
Jonathan Hartea750842015-04-23 17:44:49 -070029import org.onlab.packet.VlanId;
30import org.onosproject.core.ApplicationId;
31import org.onosproject.core.CoreService;
32import org.onosproject.net.ConnectPoint;
33import org.onosproject.net.DeviceId;
34import org.onosproject.net.PortNumber;
35import org.onosproject.net.flow.DefaultTrafficSelector;
36import org.onosproject.net.flow.DefaultTrafficTreatment;
37import org.onosproject.net.flow.TrafficSelector;
38import org.onosproject.net.flow.TrafficTreatment;
39import org.onosproject.net.flowobjective.DefaultForwardingObjective;
40import org.onosproject.net.flowobjective.FlowObjectiveService;
41import org.onosproject.net.flowobjective.ForwardingObjective;
42import org.onosproject.net.flowobjective.Objective;
43import org.onosproject.net.flowobjective.ObjectiveContext;
44import org.onosproject.net.flowobjective.ObjectiveError;
45import org.slf4j.Logger;
46import org.slf4j.LoggerFactory;
47
Jonathan Hart443ebed2015-05-05 14:02:12 -070048import java.util.ArrayList;
Jonathan Hartea750842015-04-23 17:44:49 -070049import java.util.List;
50import java.util.stream.Collectors;
51
52import static com.google.common.base.Preconditions.checkArgument;
53import static com.google.common.base.Preconditions.checkNotNull;
54import static org.slf4j.LoggerFactory.getLogger;
55
56/**
57 * CORD fabric application.
58 */
59@Service
60@Component(immediate = true)
61public class CordFabricManager implements FabricService {
62
63 private final Logger log = getLogger(getClass());
64
65 private ApplicationId appId;
66
67 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
68 protected CoreService coreService;
69
70 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
71 protected FlowObjectiveService flowObjectiveService;
72
73 private static final int PRIORITY = 1000;
74
Jonathan Hart0b989982015-05-14 15:40:07 -070075 private short openflowPort = 6633;
76
alshabibc494f992015-05-15 09:51:54 -070077 private short radiusPort = 1812;
78
Jonathan Hart0b989982015-05-14 15:40:07 -070079 private DeviceId fabricDeviceId = DeviceId.deviceId("of:5e3e486e73000187");
80
81 private ConnectPoint oltConnectPoint =
82 new ConnectPoint(fabricDeviceId, PortNumber.portNumber(2));
83 private ConnectPoint oltControllerConnectPoint =
84 new ConnectPoint(fabricDeviceId, PortNumber.portNumber(1));
85
Jonathan Hartea750842015-04-23 17:44:49 -070086 private final Multimap<VlanId, ConnectPoint> vlans = HashMultimap.create();
87
88 @Activate
89 public void activate() {
90 appId = coreService.registerApplication("org.onosproject.cordfabric");
91
Jonathan Hart0b989982015-05-14 15:40:07 -070092 setupDefaultFlows();
93
Jonathan Hartea750842015-04-23 17:44:49 -070094 log.info("Started");
95 }
96
97 @Deactivate
98 public void deactivate() {
99 log.info("Stopped");
100 }
101
Jonathan Hart0b989982015-05-14 15:40:07 -0700102 private void setupDefaultFlows() {
alshabibc494f992015-05-15 09:51:54 -0700103 TrafficSelector toControllerOF = DefaultTrafficSelector.builder()
Jonathan Hart0b989982015-05-14 15:40:07 -0700104 .matchEthType(Ethernet.TYPE_IPV4)
105 .matchIPProtocol(IPv4.PROTOCOL_TCP)
106 .matchTcpDst(openflowPort)
107 .build();
108
alshabibc494f992015-05-15 09:51:54 -0700109 TrafficSelector fromControllerOF = DefaultTrafficSelector.builder()
Jonathan Hart0b989982015-05-14 15:40:07 -0700110 .matchEthType(Ethernet.TYPE_IPV4)
111 .matchIPProtocol(IPv4.PROTOCOL_TCP)
112 .matchTcpSrc(openflowPort)
113 .build();
114
alshabibc494f992015-05-15 09:51:54 -0700115 TrafficSelector toControllerRadius = DefaultTrafficSelector.builder()
116 .matchEthType(Ethernet.TYPE_IPV4)
117 .matchInPort(oltConnectPoint.port())
118 .matchIPProtocol(IPv4.PROTOCOL_UDP)
119 .matchUdpDst(radiusPort)
120 .build();
121
122 TrafficSelector fromControllerRadius = DefaultTrafficSelector.builder()
123 .matchEthType(Ethernet.TYPE_IPV4)
124 .matchInPort(oltControllerConnectPoint.port())
125 .matchIPProtocol(IPv4.PROTOCOL_UDP)
126 .matchUdpDst(radiusPort)
127 .build();
128
129
Jonathan Hart0b989982015-05-14 15:40:07 -0700130 TrafficTreatment forwardToController = DefaultTrafficTreatment.builder()
131 .setOutput(oltControllerConnectPoint.port())
132 .build();
133
134 TrafficTreatment forwardFromController = DefaultTrafficTreatment.builder()
135 .setOutput(oltConnectPoint.port())
136 .build();
137
138 ForwardingObjective ofToController = DefaultForwardingObjective.builder()
139 .fromApp(appId)
140 .makePermanent()
141 .withFlag(ForwardingObjective.Flag.VERSATILE)
142 .withPriority(PRIORITY)
alshabibc494f992015-05-15 09:51:54 -0700143 .withSelector(toControllerOF)
Jonathan Hart0b989982015-05-14 15:40:07 -0700144 .withTreatment(forwardToController)
145 .add();
146
147 ForwardingObjective ofFromController = DefaultForwardingObjective.builder()
148 .fromApp(appId)
149 .makePermanent()
150 .withFlag(ForwardingObjective.Flag.VERSATILE)
151 .withPriority(PRIORITY)
alshabibc494f992015-05-15 09:51:54 -0700152 .withSelector(fromControllerOF)
153 .withTreatment(forwardFromController)
154 .add();
155
156 ForwardingObjective radiusToController = DefaultForwardingObjective.builder()
157 .fromApp(appId)
158 .makePermanent()
159 .withFlag(ForwardingObjective.Flag.VERSATILE)
160 .withPriority(PRIORITY)
161 .withSelector(toControllerRadius)
162 .withTreatment(forwardToController)
163 .add();
164
165 ForwardingObjective radiusFromController = DefaultForwardingObjective.builder()
166 .fromApp(appId)
167 .makePermanent()
168 .withFlag(ForwardingObjective.Flag.VERSATILE)
169 .withPriority(PRIORITY)
170 .withSelector(fromControllerRadius)
Jonathan Hart0b989982015-05-14 15:40:07 -0700171 .withTreatment(forwardFromController)
172 .add();
173
174 flowObjectiveService.forward(fabricDeviceId, ofToController);
175 flowObjectiveService.forward(fabricDeviceId, ofFromController);
alshabibc494f992015-05-15 09:51:54 -0700176 flowObjectiveService.forward(fabricDeviceId, radiusToController);
177 flowObjectiveService.forward(fabricDeviceId, radiusFromController);
Jonathan Hart0b989982015-05-14 15:40:07 -0700178 }
179
Jonathan Hartea750842015-04-23 17:44:49 -0700180 @Override
Jonathan Hart443ebed2015-05-05 14:02:12 -0700181 public void addVlan(FabricVlan vlan) {
182 checkNotNull(vlan);
183 checkArgument(vlan.ports().size() > 1);
184 verifyPorts(vlan.ports());
Jonathan Hartea750842015-04-23 17:44:49 -0700185
Jonathan Hart443ebed2015-05-05 14:02:12 -0700186 removeVlan(vlan.vlan());
Jonathan Hartea750842015-04-23 17:44:49 -0700187
Jonathan Hart443ebed2015-05-05 14:02:12 -0700188 vlan.ports().forEach(cp -> {
189 if (vlans.put(vlan.vlan(), cp)) {
190 addForwarding(vlan.vlan(), cp.deviceId(), cp.port(),
191 vlan.ports().stream()
Jonathan Hartea750842015-04-23 17:44:49 -0700192 .filter(p -> p != cp)
193 .map(ConnectPoint::port)
194 .collect(Collectors.toList()));
195 }
196 });
197 }
198
199 @Override
200 public void removeVlan(VlanId vlanId) {
201 vlans.removeAll(vlanId)
202 .forEach(cp -> removeForwarding(vlanId, cp.deviceId(), cp.port()));
203 }
204
205 @Override
Jonathan Hart443ebed2015-05-05 14:02:12 -0700206 public List<FabricVlan> getVlans() {
207 List<FabricVlan> fVlans = new ArrayList<>();
208 vlans.keySet().forEach(vlan -> fVlans.add(
209 new FabricVlan(vlan, vlans.get(vlan))));
210 return fVlans;
Jonathan Hartea750842015-04-23 17:44:49 -0700211 }
212
213 private static void verifyPorts(List<ConnectPoint> ports) {
214 DeviceId deviceId = ports.get(0).deviceId();
215 for (ConnectPoint connectPoint : ports) {
216 if (!connectPoint.deviceId().equals(deviceId)) {
217 throw new IllegalArgumentException("Ports must all be on the same device");
218 }
219 }
220 }
221
222 private void addForwarding(VlanId vlanId, DeviceId deviceId, PortNumber inPort,
223 List<PortNumber> outPorts) {
224 TrafficSelector selector = DefaultTrafficSelector.builder()
225 .matchVlanId(vlanId)
226 .matchInPort(inPort)
227 .build();
228
229 TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
230
231 outPorts.forEach(p -> treatmentBuilder.setOutput(p));
232
233 ForwardingObjective objective = DefaultForwardingObjective.builder()
234 .fromApp(appId)
235 .makePermanent()
236 .withFlag(ForwardingObjective.Flag.VERSATILE)
237 .withPriority(PRIORITY)
238 .withSelector(selector)
239 .withTreatment(treatmentBuilder.build())
240 .add(new ObjectiveHandler());
241
242 flowObjectiveService.forward(deviceId, objective);
243 }
244
245 private void removeForwarding(VlanId vlanId, DeviceId deviceId, PortNumber inPort) {
246 TrafficSelector selector = DefaultTrafficSelector.builder()
247 .matchVlanId(vlanId)
248 .matchInPort(inPort)
249 .build();
250
251 ForwardingObjective objective = DefaultForwardingObjective.builder()
252 .fromApp(appId)
253 .makePermanent()
254 .withFlag(ForwardingObjective.Flag.VERSATILE)
255 .withPriority(PRIORITY)
256 .withSelector(selector)
257 .withTreatment(DefaultTrafficTreatment.builder().build())
258 .remove(new ObjectiveHandler());
259
260 flowObjectiveService.forward(deviceId, objective);
261 }
262
263 private static class ObjectiveHandler implements ObjectiveContext {
264 private static Logger log = LoggerFactory.getLogger(ObjectiveHandler.class);
265
266 @Override
267 public void onSuccess(Objective objective) {
268 log.info("Flow objective operation successful: {}", objective);
269 }
270
271 @Override
272 public void onError(Objective objective, ObjectiveError error) {
273 log.info("Flow objective operation failed: {}", objective);
274 }
275 }
276}