blob: 80a01a344fa2d3565d47df9abf9a4f8c18211aa2 [file] [log] [blame]
Zayne Khouja31da33a2016-06-16 11:57:12 -07001/*
Brian O'Connor0a4e6742016-09-15 23:03:10 -07002 * Copyright 2016-present Open Networking Laboratory
Zayne Khouja31da33a2016-06-16 11:57:12 -07003 *
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 */
16package org.onosproject.learningswitch;
17
18import com.google.common.collect.Maps;
19import org.apache.felix.scr.annotations.Activate;
20import org.apache.felix.scr.annotations.Deactivate;
21import org.apache.felix.scr.annotations.Component;
22import org.apache.felix.scr.annotations.Reference;
23import org.apache.felix.scr.annotations.ReferenceCardinality;
24import org.onlab.packet.Ethernet;
25import org.onlab.packet.MacAddress;
26import org.onosproject.core.ApplicationId;
27import org.onosproject.core.CoreService;
28import org.onosproject.net.ConnectPoint;
29import org.onosproject.net.DeviceId;
30import org.onosproject.net.PortNumber;
31import org.onosproject.net.flow.DefaultTrafficSelector;
32import org.onosproject.net.flow.FlowRuleService;
33import org.onosproject.net.packet.PacketContext;
34import org.onosproject.net.packet.PacketPriority;
35import org.onosproject.net.packet.PacketProcessor;
36import org.onosproject.net.packet.PacketService;
37import org.slf4j.Logger;
38import org.slf4j.LoggerFactory;
39
40import java.util.Map;
41import java.util.Optional;
42
43/**
44 * Tutorial class used to help build a basic onos learning switch application.
45 * Edit your code in the activate, deactivate, and actLikeSwitch methods.
46 */
47@Component(immediate = true)
48public class LearningSwitchTutorial {
49 // Instantiates the relevant services.
50
51 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
52 protected PacketService packetService;
53
54 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
55 protected FlowRuleService flowRuleService;
56
57 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
58 protected CoreService coreService;
59
60 private final Logger log = LoggerFactory.getLogger(getClass());
61
62 /*
63 * Defining macTables as a concurrent map allows multiple threads and packets to
64 * use the map without an issue.
65 */
66 protected Map<DeviceId, Map<MacAddress, PortNumber>> macTables = Maps.newConcurrentMap();
67 private ApplicationId appId;
68 private PacketProcessor processor;
69
70 /**
71 * Create a variable of the SwitchPacketProcessor class using the PacketProcessor defined above.
72 * Activates the app.
73 *
74 * Create code to add a processor
75 */
76 @Activate
77 protected void activate() {
78 log.info("Started");
79 appId = coreService.getAppId("org.onosproject.learningswitch"); //equal to the name shown in pom.xml file
80
81 //Create and processor and add it using packetService
82
83 /*
84 * Restricts packet types to IPV4 and ARP by only requesting those types
85 */
86 packetService.requestPackets(DefaultTrafficSelector.builder()
87 .matchEthType(Ethernet.TYPE_IPV4).build(), PacketPriority.REACTIVE, appId, Optional.empty());
88 packetService.requestPackets(DefaultTrafficSelector.builder()
89 .matchEthType(Ethernet.TYPE_ARP).build(), PacketPriority.REACTIVE, appId, Optional.empty());
90 }
91
92 /**
93 * Deactivates the processor by removing it.
94 *
95 * Create code to remove the processor.
96 */
97 @Deactivate
98 protected void deactivate() {
99 log.info("Stopped");
100
101 //Remove the processor
102 }
103
104 /**
105 * This class contains pseudo code that you must replace with your own code in actLikeSwitch. Your job is to
106 * send the packet out the port previously learned for the destination MAC. If it does not exist,
107 * flood the packet out (to all ports).
108 */
109 private class SwitchPacketProcesser implements PacketProcessor {
110 /**
111 * Learns the source port associated with the packet's DeviceId if it has not already been learned.
112 * Calls actLikeSwitch to process and send the packet.
113 * @param pc PacketContext object containing packet info
114 */
115 @Override
116 public void process(PacketContext pc) {
117 log.info(pc.toString());
118 /*
119 * Puts the packet's source's device Id into the map macTables if it has not previously been added.
120 * (learns the output port)
121 */
122 ConnectPoint cp = pc.inPacket().receivedFrom();
123 macTables.putIfAbsent(cp.deviceId(), Maps.newConcurrentMap());
124
125
126
127 // This method simply floods all ports with the packet.
128 actLikeHub(pc);
129
130 /*
131 * This is the call to the actLikeSwitch method you will be creating. When
132 * you are ready to test it, uncomment the line below, and comment out the
133 * actLikeHub call above.
134 *
135 * NOTE: The perk of an actLikeSwitch method over actLikeHub is speed.
136 * FlowRule allows much faster processing.
137 */
138 //actLikeSwitch(pc);
139 }
140
141 /**
142 * Example method. Floods packet out of all switch ports.
143 *
144 * @param pc the PacketContext object passed through from activate method
145 */
146 public void actLikeHub(PacketContext pc) {
147 pc.treatmentBuilder().setOutput(PortNumber.FLOOD);
148 pc.send();
149 }
150
151 /**
152 * Ensures packet is of required type. Obtain the port number associated with the packet's source ID.
153 * If this port has previously been learned (in the process method) build a flow using the packet's
154 * out port, treatment, destination, and other properties. Send the flow to the learned out port.
155 * Otherwise, flood packet to all ports if out port has not been learned.
156 *
157 * @param pc the PacketContext object passed through from activate() method
158 */
159 public void actLikeSwitch(PacketContext pc) {
160
161 /*
162 * Ensures the type of packet being processed is only of type IPV4 or ARP (not LLDP or BDDP).
163 * If it is not, return and do nothing with the packet. actLikeSwitch can only process
164 * IPV4 and ARP packets.
165 */
166 Short type = pc.inPacket().parsed().getEtherType();
167 if (type != Ethernet.TYPE_IPV4 && type != Ethernet.TYPE_ARP) {
168 return;
169 }
170
171 /*
172 * Learn the destination, source, and output port of the packet using a ConnectPoint and the
173 * associated macTable. If there is a known port associated with the packet's destination MAC Address,
174 * the output port will not be null.
175 */
176 //find the packets connect point
177 //save the macTables port value for the deviceID
178 //save the outPort as a variable
179 //PortNumber outPort = ...
180
181 /*
182 * If port is known, set output port to the packet's learned output port and construct a
183 * FlowRule using a source, destination, treatment and other properties. Send the FlowRule
184 * to the designated output port.
185 */
186 //if outPort isn't null
187 //construct FlowRule
188 //FlowRule fr = ...
189 //send the packet
190
191 /*
192 * else, the output port has not been learned yet. Flood the packet to all ports using
193 * the actLikeHub method
194 */
195 //else
196 // call actLikeHub method
197 }
198 }
199}