emit + tests for OFPacketProvider
Change-Id: I9d6a2a641f857742fa68597189a9047dd16989d1
Showing
2 changed files
with
70 additions
and
2 deletions
... | @@ -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 | + } | ||
71 | 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 | + } | ||
118 | + | ||
119 | + } | ||
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(); | ||
72 | } | 126 | } |
73 | 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. | ... | ... |
-
Please register or login to post a comment