blob: e56a4f994dd3a2c6c705128269afb0dbfab7c0a4 [file] [log] [blame]
tom9c94c5b2014-09-17 13:14:42 -07001package org.onlab.onos.openflow.controller;
tom7ef8ff92014-09-17 13:08:06 -07002
tom7ef8ff92014-09-17 13:08:06 -07003import org.onlab.packet.Ethernet;
4import org.projectfloodlight.openflow.protocol.OFPacketIn;
5import org.projectfloodlight.openflow.protocol.OFPacketOut;
6import org.projectfloodlight.openflow.protocol.action.OFAction;
7import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
8import org.projectfloodlight.openflow.protocol.match.MatchField;
9import org.projectfloodlight.openflow.types.OFBufferId;
10import org.projectfloodlight.openflow.types.OFPort;
tom1679e182014-10-09 13:50:45 -070011
12import java.util.Collections;
13import java.util.concurrent.atomic.AtomicBoolean;
tom7ef8ff92014-09-17 13:08:06 -070014
15public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext {
16
tom7ef8ff92014-09-17 13:08:06 -070017 private final AtomicBoolean free = new AtomicBoolean(true);
18 private final AtomicBoolean isBuilt = new AtomicBoolean(false);
19 private final OpenFlowSwitch sw;
20 private final OFPacketIn pktin;
21 private OFPacketOut pktout = null;
22
alshabibe9d3a322014-09-23 15:18:33 -070023 private final boolean isBuffered;
24
tom7ef8ff92014-09-17 13:08:06 -070025 private DefaultOpenFlowPacketContext(OpenFlowSwitch s, OFPacketIn pkt) {
26 this.sw = s;
27 this.pktin = pkt;
alshabibe9d3a322014-09-23 15:18:33 -070028 this.isBuffered = pktin.getBufferId() != OFBufferId.NO_BUFFER;
tom7ef8ff92014-09-17 13:08:06 -070029 }
30
31 @Override
32 public void send() {
33 if (block() && isBuilt.get()) {
34 sw.sendMsg(pktout);
35 }
36 }
37
38 @Override
39 public void build(OFPort outPort) {
40 if (isBuilt.getAndSet(true)) {
41 return;
42 }
43 OFPacketOut.Builder builder = sw.factory().buildPacketOut();
44 OFAction act = buildOutput(outPort.getPortNumber());
45 pktout = builder.setXid(pktin.getXid())
alshabib6eb438a2014-10-01 16:39:37 -070046 .setInPort(inport())
tom7ef8ff92014-09-17 13:08:06 -070047 .setBufferId(pktin.getBufferId())
48 .setActions(Collections.singletonList(act))
49 .build();
50 }
51
52 @Override
53 public void build(Ethernet ethFrame, OFPort outPort) {
54 if (isBuilt.getAndSet(true)) {
55 return;
56 }
57 OFPacketOut.Builder builder = sw.factory().buildPacketOut();
58 OFAction act = buildOutput(outPort.getPortNumber());
59 pktout = builder.setXid(pktin.getXid())
60 .setBufferId(OFBufferId.NO_BUFFER)
alshabib6eb438a2014-10-01 16:39:37 -070061 .setInPort(inport())
tom7ef8ff92014-09-17 13:08:06 -070062 .setActions(Collections.singletonList(act))
63 .setData(ethFrame.serialize())
64 .build();
65 }
66
67 @Override
68 public Ethernet parsed() {
69 Ethernet eth = new Ethernet();
70 eth.deserialize(pktin.getData(), 0, pktin.getTotalLen());
71 return eth;
72 }
73
74 @Override
75 public Dpid dpid() {
76 return new Dpid(sw.getId());
77 }
78
79 public static OpenFlowPacketContext packetContextFromPacketIn(OpenFlowSwitch s,
tom1679e182014-10-09 13:50:45 -070080 OFPacketIn pkt) {
tom7ef8ff92014-09-17 13:08:06 -070081 return new DefaultOpenFlowPacketContext(s, pkt);
82 }
83
84 @Override
85 public Integer inPort() {
alshabib6eb438a2014-10-01 16:39:37 -070086 return inport().getPortNumber();
87 }
88
89
90 private OFPort inport() {
91 //FIXME: this has to change in fucking loxi
tom7ef8ff92014-09-17 13:08:06 -070092 try {
alshabib6eb438a2014-10-01 16:39:37 -070093 return pktin.getInPort();
tom7ef8ff92014-09-17 13:08:06 -070094 } catch (UnsupportedOperationException e) {
alshabib6eb438a2014-10-01 16:39:37 -070095 return pktin.getMatch().get(MatchField.IN_PORT);
tom7ef8ff92014-09-17 13:08:06 -070096 }
97 }
98
99 @Override
100 public byte[] unparsed() {
101
102 return pktin.getData().clone();
103
104 }
105
106 private OFActionOutput buildOutput(Integer port) {
107 OFActionOutput act = sw.factory().actions()
108 .buildOutput()
109 .setPort(OFPort.of(port))
110 .build();
111 return act;
112 }
113
114 @Override
115 public boolean block() {
116 return free.getAndSet(false);
117 }
118
119 @Override
120 public boolean isHandled() {
121 return !free.get();
122 }
123
alshabibe9d3a322014-09-23 15:18:33 -0700124 @Override
125 public boolean isBuffered() {
126 return isBuffered;
127 }
128
tom7ef8ff92014-09-17 13:08:06 -0700129}