Showing
3 changed files
with
69 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; |
... | @@ -22,9 +25,20 @@ import org.onlab.onos.net.provider.ProviderId; | ... | @@ -22,9 +25,20 @@ import org.onlab.onos.net.provider.ProviderId; |
22 | import org.onlab.onos.openflow.controller.Dpid; | 25 | import org.onlab.onos.openflow.controller.Dpid; |
23 | import org.onlab.onos.openflow.controller.OpenFlowController; | 26 | import org.onlab.onos.openflow.controller.OpenFlowController; |
24 | import org.onlab.onos.openflow.controller.OpenFlowPacketContext; | 27 | import org.onlab.onos.openflow.controller.OpenFlowPacketContext; |
28 | +import org.onlab.onos.openflow.controller.OpenFlowSwitch; | ||
25 | import org.onlab.onos.openflow.controller.PacketListener; | 29 | import org.onlab.onos.openflow.controller.PacketListener; |
30 | +import org.onlab.packet.Ethernet; | ||
31 | +import org.projectfloodlight.openflow.protocol.OFPacketOut; | ||
32 | +import org.projectfloodlight.openflow.protocol.OFPortDesc; | ||
33 | +import org.projectfloodlight.openflow.protocol.action.OFAction; | ||
34 | +import org.projectfloodlight.openflow.protocol.ver10.OFFactoryVer10; | ||
35 | +import org.projectfloodlight.openflow.types.OFBufferId; | ||
36 | +import org.projectfloodlight.openflow.types.OFPort; | ||
26 | import org.slf4j.Logger; | 37 | import org.slf4j.Logger; |
27 | 38 | ||
39 | +import static org.onlab.onos.openflow.controller.RoleState.*; | ||
40 | + | ||
41 | + | ||
28 | /** | 42 | /** |
29 | * Provider which uses an OpenFlow controller to detect network | 43 | * Provider which uses an OpenFlow controller to detect network |
30 | * infrastructure links. | 44 | * infrastructure links. |
... | @@ -68,9 +82,61 @@ public class OpenFlowPacketProvider extends AbstractProvider implements PacketPr | ... | @@ -68,9 +82,61 @@ public class OpenFlowPacketProvider extends AbstractProvider implements PacketPr |
68 | 82 | ||
69 | @Override | 83 | @Override |
70 | public void emit(OutboundPacket packet) { | 84 | public void emit(OutboundPacket packet) { |
85 | + DeviceId devId = packet.sendThrough(); | ||
86 | + String scheme = devId.toString().split(":")[0]; | ||
87 | + | ||
88 | + if (!scheme.equals(this.id().scheme())) { | ||
89 | + throw new IllegalArgumentException( | ||
90 | + "Don't know how to handle Device with scheme " + scheme); | ||
91 | + } | ||
92 | + | ||
93 | + Dpid dpid = Dpid.dpid(devId.uri()); | ||
94 | + OpenFlowSwitch sw = controller.getSwitch(dpid); | ||
95 | + if (sw == null) { | ||
96 | + log.warn("Device {} isn't available?", devId); | ||
97 | + return; | ||
98 | + } else if (sw.getRole().equals(SLAVE)) { | ||
99 | + log.warn("Can't write to Device {} as slave", devId); | ||
100 | + return; | ||
101 | + } | ||
102 | + | ||
103 | + Ethernet eth = new Ethernet(); | ||
104 | + eth.deserialize(packet.data().array(), 0, packet.data().array().length); | ||
105 | + OFPortDesc p = null; | ||
106 | + for (Instruction inst : packet.treatment().instructions()) { | ||
107 | + if (inst.type().equals(Instruction.Type.OUTPUT)) { | ||
108 | + p = portDesc(((OutputInstruction) inst).port()); | ||
109 | + if (!sw.getPorts().contains(p)) { | ||
110 | + log.warn("Tried to write out non-existint port {}", p.getPortNo()); | ||
111 | + continue; | ||
112 | + } | ||
113 | + OFPacketOut po = packetOut(sw, eth, p.getPortNo()); | ||
114 | + sw.sendMsg(po); | ||
115 | + } | ||
116 | + } | ||
71 | 117 | ||
72 | } | 118 | } |
73 | 119 | ||
120 | + private OFPortDesc portDesc(PortNumber port) { | ||
121 | + OFPortDesc.Builder builder = OFFactoryVer10.INSTANCE.buildPortDesc(); | ||
122 | + builder.setPortNo(OFPort.of((int) port.toLong())); | ||
123 | + | ||
124 | + return builder.build(); | ||
125 | + } | ||
126 | + | ||
127 | + private OFPacketOut packetOut(OpenFlowSwitch sw, Ethernet eth, OFPort out) { | ||
128 | + OFPacketOut.Builder builder = sw.factory().buildPacketOut(); | ||
129 | + OFAction act = sw.factory().actions() | ||
130 | + .buildOutput() | ||
131 | + .setPort(out) | ||
132 | + .build(); | ||
133 | + return builder | ||
134 | + .setBufferId(OFBufferId.NO_BUFFER) | ||
135 | + .setInPort(OFPort.NO_MASK) | ||
136 | + .setActions(Collections.singletonList(act)) | ||
137 | + .setData(eth.serialize()) | ||
138 | + .build(); | ||
139 | + } | ||
74 | 140 | ||
75 | /** | 141 | /** |
76 | * Internal Packet Provider implementation. | 142 | * Internal Packet Provider implementation. | ... | ... |
This diff is collapsed. Click to expand it.
-
Please register or login to post a comment