blob: 0f69bacee27b6568546ac096e6906213d224d248 [file] [log] [blame]
tom9c94c5b2014-09-17 13:14:42 -07001package org.onlab.onos.openflow.controller;
tom7ef8ff92014-09-17 13:08:06 -07002
3import static org.slf4j.LoggerFactory.getLogger;
4
5import java.util.Collections;
6import java.util.concurrent.atomic.AtomicBoolean;
7
8import org.onlab.packet.Ethernet;
9import org.projectfloodlight.openflow.protocol.OFPacketIn;
10import org.projectfloodlight.openflow.protocol.OFPacketOut;
11import org.projectfloodlight.openflow.protocol.action.OFAction;
12import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
13import org.projectfloodlight.openflow.protocol.match.MatchField;
14import org.projectfloodlight.openflow.types.OFBufferId;
15import org.projectfloodlight.openflow.types.OFPort;
16import org.slf4j.Logger;
17
18public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext {
19
20 private final Logger log = getLogger(getClass());
21
22 private final AtomicBoolean free = new AtomicBoolean(true);
23 private final AtomicBoolean isBuilt = new AtomicBoolean(false);
24 private final OpenFlowSwitch sw;
25 private final OFPacketIn pktin;
26 private OFPacketOut pktout = null;
27
alshabibe9d3a322014-09-23 15:18:33 -070028 private final boolean isBuffered;
29
tom7ef8ff92014-09-17 13:08:06 -070030 private DefaultOpenFlowPacketContext(OpenFlowSwitch s, OFPacketIn pkt) {
31 this.sw = s;
32 this.pktin = pkt;
alshabibe9d3a322014-09-23 15:18:33 -070033 this.isBuffered = pktin.getBufferId() != OFBufferId.NO_BUFFER;
tom7ef8ff92014-09-17 13:08:06 -070034 }
35
36 @Override
37 public void send() {
38 if (block() && isBuilt.get()) {
39 sw.sendMsg(pktout);
40 }
41 }
42
43 @Override
44 public void build(OFPort outPort) {
45 if (isBuilt.getAndSet(true)) {
46 return;
47 }
48 OFPacketOut.Builder builder = sw.factory().buildPacketOut();
49 OFAction act = buildOutput(outPort.getPortNumber());
50 pktout = builder.setXid(pktin.getXid())
alshabib6eb438a2014-10-01 16:39:37 -070051 .setInPort(inport())
tom7ef8ff92014-09-17 13:08:06 -070052 .setBufferId(pktin.getBufferId())
53 .setActions(Collections.singletonList(act))
54 .build();
55 }
56
57 @Override
58 public void build(Ethernet ethFrame, OFPort outPort) {
59 if (isBuilt.getAndSet(true)) {
60 return;
61 }
62 OFPacketOut.Builder builder = sw.factory().buildPacketOut();
63 OFAction act = buildOutput(outPort.getPortNumber());
64 pktout = builder.setXid(pktin.getXid())
65 .setBufferId(OFBufferId.NO_BUFFER)
alshabib6eb438a2014-10-01 16:39:37 -070066 .setInPort(inport())
tom7ef8ff92014-09-17 13:08:06 -070067 .setActions(Collections.singletonList(act))
68 .setData(ethFrame.serialize())
69 .build();
70 }
71
72 @Override
73 public Ethernet parsed() {
74 Ethernet eth = new Ethernet();
75 eth.deserialize(pktin.getData(), 0, pktin.getTotalLen());
76 return eth;
77 }
78
79 @Override
80 public Dpid dpid() {
81 return new Dpid(sw.getId());
82 }
83
84 public static OpenFlowPacketContext packetContextFromPacketIn(OpenFlowSwitch s,
85 OFPacketIn pkt) {
86 return new DefaultOpenFlowPacketContext(s, pkt);
87 }
88
89 @Override
90 public Integer inPort() {
alshabib6eb438a2014-10-01 16:39:37 -070091 return inport().getPortNumber();
92 }
93
94
95 private OFPort inport() {
96 //FIXME: this has to change in fucking loxi
tom7ef8ff92014-09-17 13:08:06 -070097 try {
alshabib6eb438a2014-10-01 16:39:37 -070098 return pktin.getInPort();
tom7ef8ff92014-09-17 13:08:06 -070099 } catch (UnsupportedOperationException e) {
alshabib6eb438a2014-10-01 16:39:37 -0700100 return pktin.getMatch().get(MatchField.IN_PORT);
tom7ef8ff92014-09-17 13:08:06 -0700101 }
102 }
103
104 @Override
105 public byte[] unparsed() {
106
107 return pktin.getData().clone();
108
109 }
110
111 private OFActionOutput buildOutput(Integer port) {
112 OFActionOutput act = sw.factory().actions()
113 .buildOutput()
114 .setPort(OFPort.of(port))
115 .build();
116 return act;
117 }
118
119 @Override
120 public boolean block() {
121 return free.getAndSet(false);
122 }
123
124 @Override
125 public boolean isHandled() {
126 return !free.get();
127 }
128
alshabibe9d3a322014-09-23 15:18:33 -0700129 @Override
130 public boolean isBuffered() {
131 return isBuffered;
132 }
133
tom7ef8ff92014-09-17 13:08:06 -0700134}