Ayaka Koshibe

emit + tests for OFPacketProvider

Change-Id: I9d6a2a641f857742fa68597189a9047dd16989d1
...@@ -5,8 +5,9 @@ import org.projectfloodlight.openflow.types.OFPort; ...@@ -5,8 +5,9 @@ import org.projectfloodlight.openflow.types.OFPort;
5 5
6 /** 6 /**
7 * A representation of a packet context which allows any provider 7 * A representation of a packet context which allows any provider
8 - * to view the packet in event but may block the response to the 8 + * to view a packet in event, but may block the response to the
9 - * event if blocked has been called. 9 + * event if blocked has been called. This packet context can be used
10 + * to react to the packet in event with a packet out.
10 */ 11 */
11 public interface OpenFlowPacketContext { 12 public interface OpenFlowPacketContext {
12 13
......
...@@ -3,6 +3,7 @@ package org.onlab.onos.provider.of.packet.impl; ...@@ -3,6 +3,7 @@ package org.onlab.onos.provider.of.packet.impl;
3 import static org.slf4j.LoggerFactory.getLogger; 3 import static org.slf4j.LoggerFactory.getLogger;
4 4
5 import java.nio.ByteBuffer; 5 import java.nio.ByteBuffer;
6 +import java.util.Collections;
6 7
7 import org.apache.felix.scr.annotations.Activate; 8 import org.apache.felix.scr.annotations.Activate;
8 import org.apache.felix.scr.annotations.Component; 9 import org.apache.felix.scr.annotations.Component;
...@@ -12,6 +13,8 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; ...@@ -12,6 +13,8 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
12 import org.onlab.onos.net.ConnectPoint; 13 import org.onlab.onos.net.ConnectPoint;
13 import org.onlab.onos.net.DeviceId; 14 import org.onlab.onos.net.DeviceId;
14 import org.onlab.onos.net.PortNumber; 15 import org.onlab.onos.net.PortNumber;
16 +import org.onlab.onos.net.flow.instructions.Instruction;
17 +import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction;
15 import org.onlab.onos.net.packet.DefaultInboundPacket; 18 import org.onlab.onos.net.packet.DefaultInboundPacket;
16 import org.onlab.onos.net.packet.OutboundPacket; 19 import org.onlab.onos.net.packet.OutboundPacket;
17 import org.onlab.onos.net.packet.PacketProvider; 20 import org.onlab.onos.net.packet.PacketProvider;
...@@ -19,12 +22,24 @@ import org.onlab.onos.net.packet.PacketProviderRegistry; ...@@ -19,12 +22,24 @@ import org.onlab.onos.net.packet.PacketProviderRegistry;
19 import org.onlab.onos.net.packet.PacketProviderService; 22 import org.onlab.onos.net.packet.PacketProviderService;
20 import org.onlab.onos.net.provider.AbstractProvider; 23 import org.onlab.onos.net.provider.AbstractProvider;
21 import org.onlab.onos.net.provider.ProviderId; 24 import org.onlab.onos.net.provider.ProviderId;
25 +import org.onlab.onos.openflow.controller.DefaultOpenFlowPacketContext;
22 import org.onlab.onos.openflow.controller.Dpid; 26 import org.onlab.onos.openflow.controller.Dpid;
23 import org.onlab.onos.openflow.controller.OpenFlowController; 27 import org.onlab.onos.openflow.controller.OpenFlowController;
24 import org.onlab.onos.openflow.controller.OpenFlowPacketContext; 28 import org.onlab.onos.openflow.controller.OpenFlowPacketContext;
29 +import org.onlab.onos.openflow.controller.OpenFlowSwitch;
25 import org.onlab.onos.openflow.controller.PacketListener; 30 import org.onlab.onos.openflow.controller.PacketListener;
31 +import org.onlab.packet.Ethernet;
32 +import org.projectfloodlight.openflow.protocol.OFPacketOut;
33 +import org.projectfloodlight.openflow.protocol.OFPortDesc;
34 +import org.projectfloodlight.openflow.protocol.action.OFAction;
35 +import org.projectfloodlight.openflow.protocol.ver10.OFFactoryVer10;
36 +import org.projectfloodlight.openflow.types.OFBufferId;
37 +import org.projectfloodlight.openflow.types.OFPort;
26 import org.slf4j.Logger; 38 import org.slf4j.Logger;
27 39
40 +import static org.onlab.onos.openflow.controller.RoleState.*;
41 +
42 +
28 /** 43 /**
29 * Provider which uses an OpenFlow controller to detect network 44 * Provider which uses an OpenFlow controller to detect network
30 * infrastructure links. 45 * infrastructure links.
...@@ -68,9 +83,61 @@ public class OpenFlowPacketProvider extends AbstractProvider implements PacketPr ...@@ -68,9 +83,61 @@ public class OpenFlowPacketProvider extends AbstractProvider implements PacketPr
68 83
69 @Override 84 @Override
70 public void emit(OutboundPacket packet) { 85 public void emit(OutboundPacket packet) {
86 + DeviceId devId = packet.sendThrough();
87 + String scheme = devId.toString().split(":")[0];
88 +
89 + if (!scheme.equals(this.id().scheme())) {
90 + throw new IllegalArgumentException(
91 + "Don't know how to handle Device with scheme " + scheme);
92 + }
93 +
94 + Dpid dpid = Dpid.dpid(devId.uri());
95 + OpenFlowSwitch sw = controller.getSwitch(dpid);
96 + if (sw == null) {
97 + log.warn("Device {} isn't available?", devId);
98 + return;
99 + } else if (sw.getRole().equals(SLAVE)) {
100 + log.warn("Can't write to Device {} as slave", devId);
101 + return;
102 + }
103 +
104 + Ethernet eth = new Ethernet();
105 + eth.deserialize(packet.data().array(), 0, packet.data().array().length);
106 + OFPortDesc p = null;
107 + for (Instruction inst : packet.treatment().instructions()) {
108 + if (inst.type().equals(Instruction.Type.OUTPUT)) {
109 + p = portDesc(((OutputInstruction) inst).port());
110 + if (!sw.getPorts().contains(p)) {
111 + log.warn("Tried to write out non-existint port {}", p.getPortNo());
112 + continue;
113 + }
114 + OFPacketOut po = packetOut(sw, eth, p.getPortNo());
115 + sw.sendMsg(po);
116 + }
117 + }
71 118
72 } 119 }
73 120
121 + private OFPortDesc portDesc(PortNumber port) {
122 + OFPortDesc.Builder builder = OFFactoryVer10.INSTANCE.buildPortDesc();
123 + builder.setPortNo(OFPort.of((int) port.toLong()));
124 +
125 + return builder.build();
126 + }
127 +
128 + private OFPacketOut packetOut(OpenFlowSwitch sw, Ethernet eth, OFPort out) {
129 + OFPacketOut.Builder builder = sw.factory().buildPacketOut();
130 + OFAction act = sw.factory().actions()
131 + .buildOutput()
132 + .setPort(out)
133 + .build();
134 + return builder
135 + .setBufferId(OFBufferId.NO_BUFFER)
136 + .setInPort(OFPort.NO_MASK)
137 + .setActions(Collections.singletonList(act))
138 + .setData(eth.serialize())
139 + .build();
140 + }
74 141
75 /** 142 /**
76 * Internal Packet Provider implementation. 143 * Internal Packet Provider implementation.
......