tom

Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next

...@@ -9,7 +9,7 @@ import org.onlab.onos.net.Host; ...@@ -9,7 +9,7 @@ import org.onlab.onos.net.Host;
9 import org.onlab.onos.net.HostId; 9 import org.onlab.onos.net.HostId;
10 import org.onlab.onos.net.Path; 10 import org.onlab.onos.net.Path;
11 import org.onlab.onos.net.PortNumber; 11 import org.onlab.onos.net.PortNumber;
12 -import org.onlab.onos.net.flow.Instructions; 12 +import org.onlab.onos.net.flow.instructions.Instructions;
13 import org.onlab.onos.net.host.HostService; 13 import org.onlab.onos.net.host.HostService;
14 import org.onlab.onos.net.packet.InboundPacket; 14 import org.onlab.onos.net.packet.InboundPacket;
15 import org.onlab.onos.net.packet.PacketContext; 15 import org.onlab.onos.net.packet.PacketContext;
......
...@@ -6,6 +6,7 @@ import java.util.Collections; ...@@ -6,6 +6,7 @@ import java.util.Collections;
6 import java.util.LinkedList; 6 import java.util.LinkedList;
7 import java.util.List; 7 import java.util.List;
8 8
9 +import org.onlab.onos.net.flow.instructions.Instruction;
9 import org.slf4j.Logger; 10 import org.slf4j.Logger;
10 11
11 @SuppressWarnings("rawtypes") 12 @SuppressWarnings("rawtypes")
......
...@@ -2,6 +2,8 @@ package org.onlab.onos.net.flow; ...@@ -2,6 +2,8 @@ package org.onlab.onos.net.flow;
2 2
3 import java.util.List; 3 import java.util.List;
4 4
5 +import org.onlab.onos.net.flow.instructions.Instruction;
6 +
5 /** 7 /**
6 * Abstraction of network traffic treatment. 8 * Abstraction of network traffic treatment.
7 */ 9 */
......
1 -package org.onlab.onos.net.flow; 1 +package org.onlab.onos.net.flow.instructions;
2 2
3 /** 3 /**
4 * Abstraction of a single traffic treatment step. 4 * Abstraction of a single traffic treatment step.
......
1 -package org.onlab.onos.net.flow; 1 +package org.onlab.onos.net.flow.instructions;
2 2
3 import static com.google.common.base.Preconditions.checkNotNull; 3 import static com.google.common.base.Preconditions.checkNotNull;
4 4
5 import org.onlab.onos.net.PortNumber; 5 import org.onlab.onos.net.PortNumber;
6 +import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
7 +import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.SubType;
8 +import org.onlab.packet.MACAddress;
6 /** 9 /**
7 * Factory class for creating various traffic treatment instructions. 10 * Factory class for creating various traffic treatment instructions.
8 */ 11 */
9 public final class Instructions { 12 public final class Instructions {
10 13
14 +
11 // Ban construction 15 // Ban construction
12 private Instructions() {} 16 private Instructions() {}
13 17
...@@ -23,12 +27,52 @@ public final class Instructions { ...@@ -23,12 +27,52 @@ public final class Instructions {
23 return new OutputInstruction(number); 27 return new OutputInstruction(number);
24 } 28 }
25 29
26 - // TODO: Move these out into separate classes and to flow.instruction package 30 + /**
31 + * Creates a drop instruction.
32 + * @return drop instruction
33 + */
27 public static DropInstruction createDrop() { 34 public static DropInstruction createDrop() {
28 return new DropInstruction(); 35 return new DropInstruction();
29 } 36 }
30 37
31 - // TODO: add create methods 38 + /**
39 + * Creates a l2 src modification.
40 + * @param addr the mac address to modify to.
41 + * @return a l2 modification
42 + */
43 + public static L2ModificationInstruction modL2Src(MACAddress addr) {
44 + checkNotNull(addr, "Src l2 address cannot be null");
45 + return new ModEtherInstruction(SubType.L2_SRC, addr);
46 + }
47 +
48 + /**
49 + * Creates a L2 dst modification.
50 + * @param addr the mac address to modify to.
51 + * @return a L2 modification
52 + */
53 + public static L2ModificationInstruction modL2Dst(MACAddress addr) {
54 + checkNotNull(addr, "Dst l2 address cannot be null");
55 + return new L2ModificationInstruction.ModEtherInstruction(SubType.L2_DST, addr);
56 + }
57 +
58 + /**
59 + * Creates a L2 type modification.
60 + * @param l2Type the type to change to
61 + * @return a L2 modifications
62 + */
63 + public static L2ModificationInstruction modL2Type(Short l2Type) {
64 + checkNotNull(l2Type, "L2 type cannot be null");
65 + return new L2ModificationInstruction.ModEtherTypeInstruction(l2Type);
66 + }
67 +
68 + public static L2ModificationInstruction modVlanId(Short vlanId) {
69 + checkNotNull(vlanId, "VLAN id cannot be null");
70 + return new L2ModificationInstruction.ModVlanIdInstruction(vlanId);
71 + }
72 +
73 + /*
74 + * Output instructions
75 + */
32 76
33 public static final class DropInstruction implements Instruction { 77 public static final class DropInstruction implements Instruction {
34 @Override 78 @Override
......
1 +package org.onlab.onos.net.flow.instructions;
2 +
3 +import org.onlab.packet.MACAddress;
4 +
5 +/**
6 + * Abstraction of a single traffic treatment step.
7 + * @param <T> the type parameter for the instruction
8 + */
9 +public abstract class L2ModificationInstruction implements Instruction {
10 +
11 + /**
12 + * Represents the type of traffic treatment.
13 + */
14 + public enum SubType {
15 + /**
16 + * Ether src modification.
17 + */
18 + L2_SRC,
19 +
20 + /**
21 + * Ether dst modification.
22 + */
23 + L2_DST,
24 +
25 + /**
26 + * Ethertype modification.
27 + */
28 + L2_TYPE,
29 +
30 + /**
31 + * VLAN id modification.
32 + */
33 + VLAN_ID,
34 +
35 + /**
36 + * VLAN priority modification.
37 + */
38 + VLAN_PCP
39 + }
40 +
41 + // TODO: Create factory class 'Instructions' that will have various factory
42 + // to create specific instructions.
43 +
44 + /**
45 + * Returns the subtype of the modification instruction.
46 + * @return type of instruction
47 + */
48 + public abstract SubType subtype();
49 +
50 + @Override
51 + public Type type() {
52 + return Type.MODIFICATION;
53 + }
54 +
55 + /**
56 + * Represents a L2 src/dst modification instruction.
57 + */
58 + public static final class ModEtherInstruction extends L2ModificationInstruction {
59 +
60 + private final SubType subtype;
61 + private final MACAddress mac;
62 +
63 + public ModEtherInstruction(SubType subType, MACAddress addr) {
64 + this.subtype = subType;
65 + this.mac = addr;
66 + }
67 +
68 + @Override
69 + public SubType subtype() {
70 + return this.subtype;
71 + }
72 +
73 + public MACAddress mac() {
74 + return this.mac;
75 + }
76 +
77 + }
78 +
79 + /**
80 + * Represents a L2 type modification instruction.
81 + */
82 + public static final class ModEtherTypeInstruction extends L2ModificationInstruction {
83 +
84 + public final short l2Type;
85 +
86 + public ModEtherTypeInstruction(short l2Type) {
87 + this.l2Type = l2Type;
88 + }
89 +
90 + @Override
91 + public SubType subtype() {
92 + return SubType.L2_TYPE;
93 + }
94 +
95 + public short l2Type() {
96 + return this.l2Type;
97 + }
98 +
99 + }
100 +
101 + /**
102 + * Represents a VLAN id modification instruction.
103 + */
104 + public static final class ModVlanIdInstruction extends L2ModificationInstruction {
105 +
106 + public final Short vlanId;
107 +
108 + public ModVlanIdInstruction(Short vlanId) {
109 + this.vlanId = vlanId;
110 + }
111 +
112 + @Override
113 + public SubType subtype() {
114 + return SubType.VLAN_ID;
115 + }
116 +
117 + public Short vlanId() {
118 + return this.vlanId;
119 + }
120 +
121 + }
122 +
123 +
124 +}
...@@ -59,7 +59,7 @@ public class DefaultTopologyProviderTest { ...@@ -59,7 +59,7 @@ public class DefaultTopologyProviderTest {
59 59
60 private void validateSubmission() { 60 private void validateSubmission() {
61 assertNotNull("registration expected", providerService); 61 assertNotNull("registration expected", providerService);
62 - assertEquals("incorrect providert", provider, providerService.provider()); 62 + assertEquals("incorrect provider", provider, providerService.provider());
63 assertNotNull("topo change should be submitted", providerService.graphDesc); 63 assertNotNull("topo change should be submitted", providerService.graphDesc);
64 assertEquals("incorrect vertex count", 6, providerService.graphDesc.vertexes().size()); 64 assertEquals("incorrect vertex count", 6, providerService.graphDesc.vertexes().size());
65 assertEquals("incorrect edge count", 10, providerService.graphDesc.edges().size()); 65 assertEquals("incorrect edge count", 10, providerService.graphDesc.edges().size());
......
...@@ -77,6 +77,11 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitchDriver { ...@@ -77,6 +77,11 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitchDriver {
77 this.dpid = dp; 77 this.dpid = dp;
78 } 78 }
79 79
80 + public AbstractOpenFlowSwitch(Dpid dpid, OFDescStatsReply desc) {
81 + this.dpid = dpid;
82 + this.desc = desc;
83 + }
84 +
80 //************************ 85 //************************
81 // Channel related 86 // Channel related
82 //************************ 87 //************************
......
...@@ -11,6 +11,7 @@ import org.onlab.onos.of.controller.driver.OpenFlowSwitchDriver; ...@@ -11,6 +11,7 @@ import org.onlab.onos.of.controller.driver.OpenFlowSwitchDriver;
11 import org.onlab.onos.of.controller.driver.OpenFlowSwitchDriverFactory; 11 import org.onlab.onos.of.controller.driver.OpenFlowSwitchDriverFactory;
12 import org.projectfloodlight.openflow.protocol.OFDescStatsReply; 12 import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
13 import org.projectfloodlight.openflow.protocol.OFMessage; 13 import org.projectfloodlight.openflow.protocol.OFMessage;
14 +import org.projectfloodlight.openflow.protocol.OFPortDesc;
14 import org.projectfloodlight.openflow.protocol.OFVersion; 15 import org.projectfloodlight.openflow.protocol.OFVersion;
15 import org.slf4j.Logger; 16 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory; 17 import org.slf4j.LoggerFactory;
...@@ -57,7 +58,7 @@ public final class DriverManager implements OpenFlowSwitchDriverFactory { ...@@ -57,7 +58,7 @@ public final class DriverManager implements OpenFlowSwitchDriverFactory {
57 58
58 log.warn("DriverManager could not identify switch desc: {}. " 59 log.warn("DriverManager could not identify switch desc: {}. "
59 + "Assigning AbstractOpenFlowSwich", desc); 60 + "Assigning AbstractOpenFlowSwich", desc);
60 - return new AbstractOpenFlowSwitch(dpid) { 61 + return new AbstractOpenFlowSwitch(dpid, desc) {
61 62
62 @Override 63 @Override
63 public void write(List<OFMessage> msgs) { 64 public void write(List<OFMessage> msgs) {
...@@ -85,6 +86,15 @@ public final class DriverManager implements OpenFlowSwitchDriverFactory { ...@@ -85,6 +86,15 @@ public final class DriverManager implements OpenFlowSwitchDriverFactory {
85 public boolean isDriverHandshakeComplete() { 86 public boolean isDriverHandshakeComplete() {
86 return true; 87 return true;
87 } 88 }
89 +
90 + @Override
91 + public List<OFPortDesc> getPorts() {
92 + if (this.factory().getVersion() == OFVersion.OF_10) {
93 + return Collections.unmodifiableList(features.getPorts());
94 + } else {
95 + return Collections.unmodifiableList(ports.getEntries());
96 + }
97 + }
88 }; 98 };
89 } 99 }
90 100
......
1 +package org.onlab.onos.provider.of.host.impl;
2 +
3 +import static org.junit.Assert.assertEquals;
4 +import static org.junit.Assert.assertNotNull;
5 +import static org.junit.Assert.assertNull;
6 +
7 +import java.util.Set;
8 +
9 +import org.junit.After;
10 +import org.junit.Before;
11 +import org.junit.Test;
12 +import org.onlab.onos.net.ConnectPoint;
13 +import org.onlab.onos.net.DeviceId;
14 +import org.onlab.onos.net.HostId;
15 +import org.onlab.onos.net.Link;
16 +import org.onlab.onos.net.Path;
17 +import org.onlab.onos.net.host.HostDescription;
18 +import org.onlab.onos.net.host.HostProvider;
19 +import org.onlab.onos.net.host.HostProviderRegistry;
20 +import org.onlab.onos.net.host.HostProviderService;
21 +import org.onlab.onos.net.provider.AbstractProviderService;
22 +import org.onlab.onos.net.provider.ProviderId;
23 +import org.onlab.onos.net.topology.ClusterId;
24 +import org.onlab.onos.net.topology.LinkWeight;
25 +import org.onlab.onos.net.topology.Topology;
26 +import org.onlab.onos.net.topology.TopologyCluster;
27 +import org.onlab.onos.net.topology.TopologyGraph;
28 +import org.onlab.onos.net.topology.TopologyListener;
29 +import org.onlab.onos.net.topology.TopologyService;
30 +import org.onlab.onos.of.controller.Dpid;
31 +import org.onlab.onos.of.controller.OpenFlowController;
32 +import org.onlab.onos.of.controller.OpenFlowPacketContext;
33 +import org.onlab.onos.of.controller.OpenFlowSwitch;
34 +import org.onlab.onos.of.controller.OpenFlowSwitchListener;
35 +import org.onlab.onos.of.controller.PacketListener;
36 +import org.onlab.onos.of.controller.RoleState;
37 +import org.onlab.packet.ARP;
38 +import org.onlab.packet.Ethernet;
39 +import org.onlab.packet.MACAddress;
40 +import org.onlab.packet.VLANID;
41 +import org.projectfloodlight.openflow.protocol.OFMessage;
42 +import org.projectfloodlight.openflow.types.OFPort;
43 +
44 +public class OpenFlowHostProviderTest {
45 +
46 + private static final Integer INPORT = 10;
47 + private static final Dpid DPID1 = new Dpid(100);
48 + private static final Dpid DPID2 = new Dpid(200);
49 + private static final Dpid DPID3 = new Dpid(300);
50 +
51 + private static final VLANID VLAN = VLANID.vlanId();
52 + private static final MACAddress MAC = MACAddress.valueOf("00:00:11:00:00:01");
53 + private static final MACAddress BCMAC = MACAddress.valueOf("ff:ff:ff:ff:ff:ff");
54 + private static byte [] IP = new byte [] { 10,0,0,1 };
55 +
56 + private OpenFlowHostProvider provider = new OpenFlowHostProvider();
57 + private TestHostRegistry hostService = new TestHostRegistry();
58 + private TestController controller = new TestController();
59 + private TestTopologyService topoService = new TestTopologyService();
60 + private TestHostProviderService providerService;
61 +
62 + @Before
63 + public void setUp() {
64 + provider.providerRegistry = hostService;
65 + provider.controller = controller;
66 + provider.topologyService = topoService;
67 + provider.activate();
68 + }
69 +
70 + @Test
71 + public void basics() {
72 + assertNotNull("registration expected", providerService);
73 + assertEquals("incorrect provider", provider, providerService.provider());
74 + }
75 +
76 + @Test
77 + public void events() {
78 + // new host
79 + controller.processPacket(DPID1, null);
80 + assertNotNull("new host expected", providerService.added);
81 + assertNull("host motion unexpected", providerService.moved);
82 +
83 + // the host moved to new switch
84 + controller.processPacket(DPID2, null);
85 + assertNotNull("host motion expected", providerService.moved);
86 +
87 + // the host was misheard on a spine
88 + controller.processPacket(DPID3, null);
89 + assertNull("host misheard on spine switch", providerService.spine);
90 + }
91 +
92 + @After
93 + public void tearDown() {
94 + provider.deactivate();
95 + provider.providerRegistry = null;
96 + provider.controller = null;
97 + }
98 +
99 + private class TestHostRegistry implements HostProviderRegistry {
100 +
101 + @Override
102 + public HostProviderService register(HostProvider provider) {
103 + providerService = new TestHostProviderService(provider);
104 + return providerService;
105 + }
106 +
107 + @Override
108 + public void unregister(HostProvider provider) {
109 + }
110 +
111 + @Override
112 + public Set<ProviderId> getProviders() {
113 + return null;
114 + }
115 +
116 + }
117 +
118 + private class TestHostProviderService
119 + extends AbstractProviderService<HostProvider>
120 + implements HostProviderService {
121 +
122 + Dpid added = null;
123 + Dpid moved = null;
124 + Dpid spine = null;
125 +
126 + protected TestHostProviderService(HostProvider provider) {
127 + super(provider);
128 + }
129 +
130 + @Override
131 + public void hostDetected(HostId hostId, HostDescription hostDescription) {
132 + Dpid descr = Dpid.dpid(hostDescription.location().deviceId().uri());
133 + if (added == null) {
134 + added = descr;
135 + } else if ((moved == null) && !descr.equals(added)) {
136 + moved = descr;
137 + } else {
138 + spine = descr;
139 + }
140 + }
141 +
142 + @Override
143 + public void hostVanished(HostId hostId) {
144 + }
145 +
146 + }
147 +
148 + private class TestController implements OpenFlowController {
149 +
150 + PacketListener pktListener;
151 +
152 + @Override
153 + public Iterable<OpenFlowSwitch> getSwitches() {
154 + return null;
155 + }
156 +
157 + @Override
158 + public Iterable<OpenFlowSwitch> getMasterSwitches() {
159 + return null;
160 + }
161 +
162 + @Override
163 + public Iterable<OpenFlowSwitch> getEqualSwitches() {
164 + return null;
165 + }
166 +
167 + @Override
168 + public OpenFlowSwitch getSwitch(Dpid dpid) {
169 + return null;
170 + }
171 +
172 + @Override
173 + public OpenFlowSwitch getMasterSwitch(Dpid dpid) {
174 + return null;
175 + }
176 +
177 + @Override
178 + public OpenFlowSwitch getEqualSwitch(Dpid dpid) {
179 + return null;
180 + }
181 +
182 + @Override
183 + public void addListener(OpenFlowSwitchListener listener) {
184 + }
185 +
186 + @Override
187 + public void removeListener(OpenFlowSwitchListener listener) {
188 + }
189 +
190 + @Override
191 + public void addPacketListener(int priority, PacketListener listener) {
192 + pktListener = listener;
193 + }
194 +
195 + @Override
196 + public void removePacketListener(PacketListener listener) {
197 + }
198 +
199 + @Override
200 + public void write(Dpid dpid, OFMessage msg) {
201 + }
202 +
203 + @Override
204 + public void processPacket(Dpid dpid, OFMessage msg) {
205 + OpenFlowPacketContext ctx =
206 + new TestPacketContext(dpid);
207 +
208 + pktListener.handlePacket(ctx);
209 + }
210 +
211 + @Override
212 + public void setRole(Dpid dpid, RoleState role) {
213 + }
214 + }
215 +
216 + private class TestTopologyService implements TopologyService {
217 +
218 + @Override
219 + public Topology currentTopology() {
220 + return null;
221 + }
222 +
223 + @Override
224 + public boolean isLatest(Topology topology) {
225 + return false;
226 + }
227 +
228 + @Override
229 + public TopologyGraph getGraph(Topology topology) {
230 + return null;
231 + }
232 +
233 + @Override
234 + public Set<TopologyCluster> getClusters(Topology topology) {
235 + return null;
236 + }
237 +
238 + @Override
239 + public TopologyCluster getCluster(Topology topology, ClusterId clusterId) {
240 + return null;
241 + }
242 +
243 + @Override
244 + public Set<DeviceId> getClusterDevices(Topology topology,
245 + TopologyCluster cluster) {
246 + return null;
247 + }
248 +
249 + @Override
250 + public Set<Link> getClusterLinks(Topology topology,
251 + TopologyCluster cluster) {
252 + return null;
253 + }
254 +
255 + @Override
256 + public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst) {
257 + return null;
258 + }
259 +
260 + @Override
261 + public Set<Path> getPaths(Topology topology, DeviceId src,
262 + DeviceId dst, LinkWeight weight) {
263 + return null;
264 + }
265 +
266 + @Override
267 + public boolean isInfrastructure(Topology topology,
268 + ConnectPoint connectPoint) {
269 + //simulate DPID3 as an infrastructure switch
270 + if (Dpid.dpid(connectPoint.deviceId().uri()).equals(DPID3)) {
271 + return true;
272 + }
273 + return false;
274 + }
275 +
276 + @Override
277 + public boolean isBroadcastPoint(Topology topology,
278 + ConnectPoint connectPoint) {
279 + return false;
280 + }
281 +
282 + @Override
283 + public void addListener(TopologyListener listener) {
284 + }
285 +
286 + @Override
287 + public void removeListener(TopologyListener listener) {
288 + }
289 +
290 + }
291 +
292 + private class TestPacketContext implements OpenFlowPacketContext {
293 +
294 + protected Dpid swid;
295 +
296 + public TestPacketContext(Dpid dpid) {
297 + swid = dpid;
298 + }
299 +
300 + @Override
301 + public boolean blocked() {
302 + return false;
303 + }
304 +
305 + @Override
306 + public void send() {
307 + }
308 +
309 + @Override
310 + public void build(OFPort outPort) {
311 + }
312 +
313 + @Override
314 + public void build(Ethernet ethFrame, OFPort outPort) {
315 + }
316 +
317 + @Override
318 + public Ethernet parsed() {
319 + // just things we (and serializers) need
320 + ARP arp = new ARP();
321 + arp.setSenderProtocolAddress(IP)
322 + .setSenderHardwareAddress(MAC.toBytes())
323 + .setTargetHardwareAddress(BCMAC.toBytes())
324 + .setTargetProtocolAddress(IP);
325 +
326 + Ethernet eth = new Ethernet();
327 + eth.setEtherType(Ethernet.TYPE_ARP)
328 + .setVlanID(VLAN.toShort())
329 + .setSourceMACAddress(MAC.toBytes())
330 + .setDestinationMACAddress(BCMAC.getAddress())
331 + .setPayload(arp);
332 +
333 + return eth;
334 + }
335 +
336 + @Override
337 + public byte[] unparsed() {
338 + return null;
339 + }
340 +
341 + @Override
342 + public Dpid dpid() {
343 + return swid;
344 + }
345 +
346 + @Override
347 + public Integer inPort() {
348 + return INPORT;
349 + }
350 +
351 + }
352 +}
...@@ -5,9 +5,9 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -5,9 +5,9 @@ import static org.slf4j.LoggerFactory.getLogger;
5 import java.util.List; 5 import java.util.List;
6 6
7 import org.onlab.onos.net.PortNumber; 7 import org.onlab.onos.net.PortNumber;
8 -import org.onlab.onos.net.flow.Instruction; 8 +import org.onlab.onos.net.flow.instructions.Instruction;
9 -import org.onlab.onos.net.flow.Instruction.Type; 9 +import org.onlab.onos.net.flow.instructions.Instruction.Type;
10 -import org.onlab.onos.net.flow.Instructions.OutputInstruction; 10 +import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction;
11 import org.onlab.onos.net.packet.DefaultPacketContext; 11 import org.onlab.onos.net.packet.DefaultPacketContext;
12 import org.onlab.onos.net.packet.InboundPacket; 12 import org.onlab.onos.net.packet.InboundPacket;
13 import org.onlab.onos.net.packet.OutboundPacket; 13 import org.onlab.onos.net.packet.OutboundPacket;
......