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