tom

Merge remote-tracking branch 'origin/master'

...@@ -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.
......