blob: 4cd29c445518aa85d78db50ee27041a52f9672f4 [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())
51 .setInPort(pktin.getInPort())
52 .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)
66 .setInPort(pktin.getInPort())
67 .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() {
91 try {
92 return pktin.getInPort().getPortNumber();
93 } catch (UnsupportedOperationException e) {
94 return pktin.getMatch().get(MatchField.IN_PORT).getPortNumber();
95 }
96 }
97
98 @Override
99 public byte[] unparsed() {
100
101 return pktin.getData().clone();
102
103 }
104
105 private OFActionOutput buildOutput(Integer port) {
106 OFActionOutput act = sw.factory().actions()
107 .buildOutput()
108 .setPort(OFPort.of(port))
109 .build();
110 return act;
111 }
112
113 @Override
114 public boolean block() {
115 return free.getAndSet(false);
116 }
117
118 @Override
119 public boolean isHandled() {
120 return !free.get();
121 }
122
alshabibe9d3a322014-09-23 15:18:33 -0700123 @Override
124 public boolean isBuffered() {
125 return isBuffered;
126 }
127
tom7ef8ff92014-09-17 13:08:06 -0700128}