blob: d45ae61325f36459d7a5200c25617a56be8cd94e [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
77 private DeviceId fabricDeviceId = DeviceId.deviceId("of:5e3e486e73000187");
78
79 private ConnectPoint oltConnectPoint =
80 new ConnectPoint(fabricDeviceId, PortNumber.portNumber(2));
81 private ConnectPoint oltControllerConnectPoint =
82 new ConnectPoint(fabricDeviceId, PortNumber.portNumber(1));
83
Jonathan Hartea750842015-04-23 17:44:49 -070084 private final Multimap<VlanId, ConnectPoint> vlans = HashMultimap.create();
85
86 @Activate
87 public void activate() {
88 appId = coreService.registerApplication("org.onosproject.cordfabric");
89
Jonathan Hart0b989982015-05-14 15:40:07 -070090 setupDefaultFlows();
91
Jonathan Hartea750842015-04-23 17:44:49 -070092 log.info("Started");
93 }
94
95 @Deactivate
96 public void deactivate() {
97 log.info("Stopped");
98 }
99
Jonathan Hart0b989982015-05-14 15:40:07 -0700100 private void setupDefaultFlows() {
101 TrafficSelector toControllerS = DefaultTrafficSelector.builder()
102 .matchEthType(Ethernet.TYPE_IPV4)
103 .matchIPProtocol(IPv4.PROTOCOL_TCP)
104 .matchTcpDst(openflowPort)
105 .build();
106
107 TrafficSelector fromControllerS = DefaultTrafficSelector.builder()
108 .matchEthType(Ethernet.TYPE_IPV4)
109 .matchIPProtocol(IPv4.PROTOCOL_TCP)
110 .matchTcpSrc(openflowPort)
111 .build();
112
113 TrafficTreatment forwardToController = DefaultTrafficTreatment.builder()
114 .setOutput(oltControllerConnectPoint.port())
115 .build();
116
117 TrafficTreatment forwardFromController = DefaultTrafficTreatment.builder()
118 .setOutput(oltConnectPoint.port())
119 .build();
120
121 ForwardingObjective ofToController = DefaultForwardingObjective.builder()
122 .fromApp(appId)
123 .makePermanent()
124 .withFlag(ForwardingObjective.Flag.VERSATILE)
125 .withPriority(PRIORITY)
126 .withSelector(toControllerS)
127 .withTreatment(forwardToController)
128 .add();
129
130 ForwardingObjective ofFromController = DefaultForwardingObjective.builder()
131 .fromApp(appId)
132 .makePermanent()
133 .withFlag(ForwardingObjective.Flag.VERSATILE)
134 .withPriority(PRIORITY)
135 .withSelector(fromControllerS)
136 .withTreatment(forwardFromController)
137 .add();
138
139 flowObjectiveService.forward(fabricDeviceId, ofToController);
140 flowObjectiveService.forward(fabricDeviceId, ofFromController);
141 }
142
Jonathan Hartea750842015-04-23 17:44:49 -0700143 @Override
Jonathan Hart443ebed2015-05-05 14:02:12 -0700144 public void addVlan(FabricVlan vlan) {
145 checkNotNull(vlan);
146 checkArgument(vlan.ports().size() > 1);
147 verifyPorts(vlan.ports());
Jonathan Hartea750842015-04-23 17:44:49 -0700148
Jonathan Hart443ebed2015-05-05 14:02:12 -0700149 removeVlan(vlan.vlan());
Jonathan Hartea750842015-04-23 17:44:49 -0700150
Jonathan Hart443ebed2015-05-05 14:02:12 -0700151 vlan.ports().forEach(cp -> {
152 if (vlans.put(vlan.vlan(), cp)) {
153 addForwarding(vlan.vlan(), cp.deviceId(), cp.port(),
154 vlan.ports().stream()
Jonathan Hartea750842015-04-23 17:44:49 -0700155 .filter(p -> p != cp)
156 .map(ConnectPoint::port)
157 .collect(Collectors.toList()));
158 }
159 });
160 }
161
162 @Override
163 public void removeVlan(VlanId vlanId) {
164 vlans.removeAll(vlanId)
165 .forEach(cp -> removeForwarding(vlanId, cp.deviceId(), cp.port()));
166 }
167
168 @Override
Jonathan Hart443ebed2015-05-05 14:02:12 -0700169 public List<FabricVlan> getVlans() {
170 List<FabricVlan> fVlans = new ArrayList<>();
171 vlans.keySet().forEach(vlan -> fVlans.add(
172 new FabricVlan(vlan, vlans.get(vlan))));
173 return fVlans;
Jonathan Hartea750842015-04-23 17:44:49 -0700174 }
175
176 private static void verifyPorts(List<ConnectPoint> ports) {
177 DeviceId deviceId = ports.get(0).deviceId();
178 for (ConnectPoint connectPoint : ports) {
179 if (!connectPoint.deviceId().equals(deviceId)) {
180 throw new IllegalArgumentException("Ports must all be on the same device");
181 }
182 }
183 }
184
185 private void addForwarding(VlanId vlanId, DeviceId deviceId, PortNumber inPort,
186 List<PortNumber> outPorts) {
187 TrafficSelector selector = DefaultTrafficSelector.builder()
188 .matchVlanId(vlanId)
189 .matchInPort(inPort)
190 .build();
191
192 TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
193
194 outPorts.forEach(p -> treatmentBuilder.setOutput(p));
195
196 ForwardingObjective objective = DefaultForwardingObjective.builder()
197 .fromApp(appId)
198 .makePermanent()
199 .withFlag(ForwardingObjective.Flag.VERSATILE)
200 .withPriority(PRIORITY)
201 .withSelector(selector)
202 .withTreatment(treatmentBuilder.build())
203 .add(new ObjectiveHandler());
204
205 flowObjectiveService.forward(deviceId, objective);
206 }
207
208 private void removeForwarding(VlanId vlanId, DeviceId deviceId, PortNumber inPort) {
209 TrafficSelector selector = DefaultTrafficSelector.builder()
210 .matchVlanId(vlanId)
211 .matchInPort(inPort)
212 .build();
213
214 ForwardingObjective objective = DefaultForwardingObjective.builder()
215 .fromApp(appId)
216 .makePermanent()
217 .withFlag(ForwardingObjective.Flag.VERSATILE)
218 .withPriority(PRIORITY)
219 .withSelector(selector)
220 .withTreatment(DefaultTrafficTreatment.builder().build())
221 .remove(new ObjectiveHandler());
222
223 flowObjectiveService.forward(deviceId, objective);
224 }
225
226 private static class ObjectiveHandler implements ObjectiveContext {
227 private static Logger log = LoggerFactory.getLogger(ObjectiveHandler.class);
228
229 @Override
230 public void onSuccess(Objective objective) {
231 log.info("Flow objective operation successful: {}", objective);
232 }
233
234 @Override
235 public void onError(Objective objective, ObjectiveError error) {
236 log.info("Flow objective operation failed: {}", objective);
237 }
238 }
239}