blob: e10b0970bf6cffc0c6f3c765f573844a27a64d02 [file] [log] [blame]
Parvathi Mef749632016-07-07 13:30:43 -07001/*
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
Parvathi Mef749632016-07-07 13:30:43 -070017package org.onosproject.patchpanel.impl;
18
Jonathan Hart194e7642016-12-15 15:33:34 -080019import com.google.common.collect.ImmutableList;
20import com.google.common.collect.ImmutableSet;
Parvathi Mef749632016-07-07 13:30:43 -070021import org.apache.felix.scr.annotations.Activate;
Jonathan Hart194e7642016-12-15 15:33:34 -080022import org.apache.felix.scr.annotations.Component;
Parvathi Mef749632016-07-07 13:30:43 -070023import org.apache.felix.scr.annotations.Deactivate;
Jonathan Hart194e7642016-12-15 15:33:34 -080024import org.apache.felix.scr.annotations.Reference;
25import org.apache.felix.scr.annotations.ReferenceCardinality;
26import org.apache.felix.scr.annotations.Service;
Jonathan Hart382119e2016-09-02 13:14:49 -070027import org.onosproject.cli.net.ConnectPointCompleter;
Parvathi Mef749632016-07-07 13:30:43 -070028import org.onosproject.core.ApplicationId;
29import org.onosproject.core.CoreService;
Jonathan Hart194e7642016-12-15 15:33:34 -080030import org.onosproject.net.ConnectPoint;
31import org.onosproject.net.DeviceId;
Parvathi Mef749632016-07-07 13:30:43 -070032import org.onosproject.net.PortNumber;
33import org.onosproject.net.flow.DefaultFlowRule;
Parvathi Mef749632016-07-07 13:30:43 -070034import org.onosproject.net.flow.DefaultTrafficSelector;
35import org.onosproject.net.flow.DefaultTrafficTreatment;
Jonathan Hart194e7642016-12-15 15:33:34 -080036import org.onosproject.net.flow.FlowRule;
37import org.onosproject.net.flow.FlowRuleService;
Parvathi Mef749632016-07-07 13:30:43 -070038import org.onosproject.net.packet.PacketPriority;
Parvathi Mef749632016-07-07 13:30:43 -070039import org.slf4j.Logger;
40import org.slf4j.LoggerFactory;
Jonathan Hart194e7642016-12-15 15:33:34 -080041
42import java.util.Collection;
43import java.util.HashMap;
44import java.util.Map;
45import java.util.Set;
46import java.util.concurrent.atomic.AtomicInteger;
47
48import static com.google.common.base.Preconditions.checkArgument;
49import static com.google.common.base.Preconditions.checkNotNull;
Parvathi Mef749632016-07-07 13:30:43 -070050
Jonathan Hart382119e2016-09-02 13:14:49 -070051/**
52 * This class acts as a software patch panel application.
53 * The user specifies 2 connectpoint on the same device that he/she would like to patch.
54 * Using a flow rule, the 2 connectpoints are patched.
55 */
Parvathi Mef749632016-07-07 13:30:43 -070056@Component(immediate = true)
57@Service
58public class PatchPanel implements PatchPanelService {
59
Jonathan Hart194e7642016-12-15 15:33:34 -080060 private final Logger log = LoggerFactory.getLogger(getClass());
61
Jonathan Hart382119e2016-09-02 13:14:49 -070062 // OSGI: help bundle plugin discover runtime package dependency.
63 @SuppressWarnings("unused")
64 private ConnectPointCompleter connectPointCompleter;
65
Parvathi Mef749632016-07-07 13:30:43 -070066 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
67 protected FlowRuleService flowRuleService;
68
69 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
70 protected CoreService coreService;
71
Jonathan Hart194e7642016-12-15 15:33:34 -080072 private Map<PatchId, Patch> patches;
73
Parvathi Mef749632016-07-07 13:30:43 -070074 private ApplicationId appId;
Jonathan Hart194e7642016-12-15 15:33:34 -080075
76 private AtomicInteger ids = new AtomicInteger();
Parvathi Mef749632016-07-07 13:30:43 -070077
78
79 @Activate
80 protected void activate() throws NullPointerException {
Jonathan Hart194e7642016-12-15 15:33:34 -080081 patches = new HashMap<>();
82
Jonathan Hart382119e2016-09-02 13:14:49 -070083 appId = coreService.registerApplication("org.onosproject.patchpanel");
Parvathi Mef749632016-07-07 13:30:43 -070084 log.info("Started");
Parvathi Mef749632016-07-07 13:30:43 -070085 }
86
87 @Deactivate
88 protected void deactivate() {
89 log.info("Stopped");
90 }
91
92 @Override
Jonathan Hart194e7642016-12-15 15:33:34 -080093 public boolean addPatch(ConnectPoint cp1, ConnectPoint cp2) {
94 checkNotNull(cp1);
95 checkNotNull(cp2);
96
97 checkArgument(cp1.deviceId().equals(cp2.deviceId()), "Ports must be on the same device");
98 checkArgument(!cp1.equals(cp2), "Ports cannot be the same");
99
100 if (patches.values().stream()
101 .filter(patch -> patch.port1().equals(cp1) || patch.port1().equals(cp2)
102 || patch.port2().equals(cp1) || patch.port2().equals(cp2))
103 .findAny().isPresent()) {
Parvathi Mef749632016-07-07 13:30:43 -0700104 log.info("One or both of these ports are already in use, NO FLOW");
105 return false;
Parvathi Mef749632016-07-07 13:30:43 -0700106 }
Jonathan Hart194e7642016-12-15 15:33:34 -0800107
108 Patch patch = new Patch(PatchId.patchId(ids.incrementAndGet()), cp1, cp2);
109
110 patches.put(patch.id(), patch);
111
112 setFlowRuleService(patch);
113
114 return true;
Parvathi Mef749632016-07-07 13:30:43 -0700115 }
116
Jonathan Hart194e7642016-12-15 15:33:34 -0800117 @Override
118 public boolean removePatch(PatchId id) {
119 Patch patch = patches.remove(id);
120 if (patch == null) {
121 return false;
122 }
123
124 removePatchFlows(patch);
125 return true;
126 }
127
128 @Override
129 public Set<Patch> getPatches() {
130 return ImmutableSet.copyOf(patches.values());
131 }
132
133 public void setFlowRuleService(Patch patch) {
134 createFlowRules(patch).forEach(flowRuleService::applyFlowRules);
135 }
136
137 private void removePatchFlows(Patch patch) {
138 createFlowRules(patch).forEach(flowRuleService::removeFlowRules);
139 }
140
141 private Collection<FlowRule> createFlowRules(Patch patch) {
142 DeviceId deviceId = patch.port1().deviceId();
143 PortNumber outPort = patch.port2().port();
144 PortNumber inPort = patch.port1().port();
Parvathi Mef749632016-07-07 13:30:43 -0700145 FlowRule fr = DefaultFlowRule.builder()
Jonathan Hart194e7642016-12-15 15:33:34 -0800146 .forDevice(deviceId)
Parvathi Mef749632016-07-07 13:30:43 -0700147 .withSelector(DefaultTrafficSelector.builder().matchInPort(inPort).build())
148 .withTreatment(DefaultTrafficTreatment.builder().setOutput(outPort).build())
149 .withPriority(PacketPriority.REACTIVE.priorityValue())
Jonathan Hart382119e2016-09-02 13:14:49 -0700150 .makePermanent()
Parvathi Mef749632016-07-07 13:30:43 -0700151 .fromApp(appId).build();
152
Jonathan Hart382119e2016-09-02 13:14:49 -0700153 FlowRule fr2 = DefaultFlowRule.builder()
Jonathan Hart194e7642016-12-15 15:33:34 -0800154 .forDevice(deviceId)
Jonathan Hart382119e2016-09-02 13:14:49 -0700155 .withSelector(DefaultTrafficSelector.builder().matchInPort(outPort).build())
156 .withTreatment(DefaultTrafficTreatment.builder().setOutput(inPort).build())
157 .withPriority(PacketPriority.REACTIVE.priorityValue())
158 .makePermanent()
159 .fromApp(appId).build();
160
Jonathan Hart194e7642016-12-15 15:33:34 -0800161 return ImmutableList.of(fr, fr2);
Parvathi Mef749632016-07-07 13:30:43 -0700162 }
Parvathi Mef749632016-07-07 13:30:43 -0700163}