blob: f419d24ffa01e0de1c7b376c648900b37a653c9d [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
28 private DefaultOpenFlowPacketContext(OpenFlowSwitch s, OFPacketIn pkt) {
29 this.sw = s;
30 this.pktin = pkt;
31 }
32
33 @Override
34 public void send() {
35 if (block() && isBuilt.get()) {
36 sw.sendMsg(pktout);
37 }
38 }
39
40 @Override
41 public void build(OFPort outPort) {
42 if (isBuilt.getAndSet(true)) {
43 return;
44 }
45 OFPacketOut.Builder builder = sw.factory().buildPacketOut();
46 OFAction act = buildOutput(outPort.getPortNumber());
47 pktout = builder.setXid(pktin.getXid())
48 .setInPort(pktin.getInPort())
49 .setBufferId(pktin.getBufferId())
50 .setActions(Collections.singletonList(act))
51 .build();
52 }
53
54 @Override
55 public void build(Ethernet ethFrame, OFPort outPort) {
56 if (isBuilt.getAndSet(true)) {
57 return;
58 }
59 OFPacketOut.Builder builder = sw.factory().buildPacketOut();
60 OFAction act = buildOutput(outPort.getPortNumber());
61 pktout = builder.setXid(pktin.getXid())
62 .setBufferId(OFBufferId.NO_BUFFER)
63 .setInPort(pktin.getInPort())
64 .setActions(Collections.singletonList(act))
65 .setData(ethFrame.serialize())
66 .build();
67 }
68
69 @Override
70 public Ethernet parsed() {
71 Ethernet eth = new Ethernet();
72 eth.deserialize(pktin.getData(), 0, pktin.getTotalLen());
73 return eth;
74 }
75
76 @Override
77 public Dpid dpid() {
78 return new Dpid(sw.getId());
79 }
80
81 public static OpenFlowPacketContext packetContextFromPacketIn(OpenFlowSwitch s,
82 OFPacketIn pkt) {
83 return new DefaultOpenFlowPacketContext(s, pkt);
84 }
85
86 @Override
87 public Integer inPort() {
88 try {
89 return pktin.getInPort().getPortNumber();
90 } catch (UnsupportedOperationException e) {
91 return pktin.getMatch().get(MatchField.IN_PORT).getPortNumber();
92 }
93 }
94
95 @Override
96 public byte[] unparsed() {
97
98 return pktin.getData().clone();
99
100 }
101
102 private OFActionOutput buildOutput(Integer port) {
103 OFActionOutput act = sw.factory().actions()
104 .buildOutput()
105 .setPort(OFPort.of(port))
106 .build();
107 return act;
108 }
109
110 @Override
111 public boolean block() {
112 return free.getAndSet(false);
113 }
114
115 @Override
116 public boolean isHandled() {
117 return !free.get();
118 }
119
120}