blob: fd47ad390cace565aa94a05209e5e540cea6cc5d [file] [log] [blame]
alshabibc4901cd2014-09-05 16:50:40 -07001package org.onlab.onos.of.controller;
2
alshabib1d4cace2014-09-13 19:16:26 -07003import static org.slf4j.LoggerFactory.getLogger;
4
alshabib289652c2014-09-07 19:09:28 -07005import java.util.Collections;
alshabib63d5afe2014-09-15 09:40:24 -07006import java.util.concurrent.atomic.AtomicBoolean;
alshabib289652c2014-09-07 19:09:28 -07007
alshabibc4901cd2014-09-05 16:50:40 -07008import org.onlab.packet.Ethernet;
9import org.projectfloodlight.openflow.protocol.OFPacketIn;
10import org.projectfloodlight.openflow.protocol.OFPacketOut;
alshabib289652c2014-09-07 19:09:28 -070011import org.projectfloodlight.openflow.protocol.action.OFAction;
alshabibddf02db2014-09-09 14:57:15 -070012import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
alshabib51622f72014-09-11 11:22:33 -070013import org.projectfloodlight.openflow.protocol.match.MatchField;
alshabib289652c2014-09-07 19:09:28 -070014import org.projectfloodlight.openflow.types.OFBufferId;
alshabibc4901cd2014-09-05 16:50:40 -070015import org.projectfloodlight.openflow.types.OFPort;
alshabib1d4cace2014-09-13 19:16:26 -070016import org.slf4j.Logger;
alshabibc4901cd2014-09-05 16:50:40 -070017
alshabibe7031562014-09-12 18:17:37 -070018public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext {
alshabibc4901cd2014-09-05 16:50:40 -070019
alshabib1d4cace2014-09-13 19:16:26 -070020 private final Logger log = getLogger(getClass());
21
alshabib63d5afe2014-09-15 09:40:24 -070022 private final AtomicBoolean free = new AtomicBoolean(true);
alshabibc4901cd2014-09-05 16:50:40 -070023 private boolean isBuilt = false;
24 private final OpenFlowSwitch sw;
25 private final OFPacketIn pktin;
alshabib289652c2014-09-07 19:09:28 -070026 private OFPacketOut pktout = null;
alshabibc4901cd2014-09-05 16:50:40 -070027
alshabibe7031562014-09-12 18:17:37 -070028 private DefaultOpenFlowPacketContext(OpenFlowSwitch s, OFPacketIn pkt) {
alshabibc4901cd2014-09-05 16:50:40 -070029 this.sw = s;
30 this.pktin = pkt;
31 }
32
33 @Override
alshabibc4901cd2014-09-05 16:50:40 -070034 public void send() {
alshabib7b2748f2014-09-16 20:21:11 -070035 if (block() && isBuilt) {
alshabib1d4cace2014-09-13 19:16:26 -070036 sw.sendMsg(pktout);
alshabibc4901cd2014-09-05 16:50:40 -070037 }
alshabibc4901cd2014-09-05 16:50:40 -070038 }
39
40 @Override
alshabibddf02db2014-09-09 14:57:15 -070041 public synchronized void build(OFPort outPort) {
alshabib289652c2014-09-07 19:09:28 -070042 if (isBuilt) {
43 return;
44 }
45 OFPacketOut.Builder builder = sw.factory().buildPacketOut();
alshabibddf02db2014-09-09 14:57:15 -070046 OFAction act = buildOutput(outPort.getPortNumber());
47 pktout = builder.setXid(pktin.getXid())
alshabib632a78c2014-09-15 10:06:05 -070048 .setInPort(pktin.getInPort())
alshabibddf02db2014-09-09 14:57:15 -070049 .setBufferId(pktin.getBufferId())
50 .setActions(Collections.singletonList(act))
alshabib289652c2014-09-07 19:09:28 -070051 .build();
alshabibddf02db2014-09-09 14:57:15 -070052 isBuilt = true;
53 }
54
55 @Override
56 public synchronized void build(Ethernet ethFrame, OFPort outPort) {
57 if (isBuilt) {
58 return;
59 }
60 OFPacketOut.Builder builder = sw.factory().buildPacketOut();
61 OFAction act = buildOutput(outPort.getPortNumber());
alshabib289652c2014-09-07 19:09:28 -070062 pktout = builder.setXid(pktin.getXid())
63 .setBufferId(OFBufferId.NO_BUFFER)
alshabibf4f463b2014-09-15 10:06:32 -070064 .setInPort(pktin.getInPort())
alshabib289652c2014-09-07 19:09:28 -070065 .setActions(Collections.singletonList(act))
66 .setData(ethFrame.serialize())
67 .build();
68 isBuilt = true;
alshabibc4901cd2014-09-05 16:50:40 -070069 }
70
71 @Override
72 public Ethernet parsed() {
alshabib289652c2014-09-07 19:09:28 -070073 Ethernet eth = new Ethernet();
74 eth.deserialize(pktin.getData(), 0, pktin.getTotalLen());
75 return eth;
alshabibc4901cd2014-09-05 16:50:40 -070076 }
77
78 @Override
79 public Dpid dpid() {
alshabib289652c2014-09-07 19:09:28 -070080 return new Dpid(sw.getId());
alshabibc4901cd2014-09-05 16:50:40 -070081 }
82
alshabibe7031562014-09-12 18:17:37 -070083 public static OpenFlowPacketContext packetContextFromPacketIn(OpenFlowSwitch s, OFPacketIn pkt) {
84 return new DefaultOpenFlowPacketContext(s, pkt);
alshabibc4901cd2014-09-05 16:50:40 -070085 }
86
alshabibdf652ad2014-09-09 11:53:19 -070087 @Override
88 public Integer inPort() {
alshabib51622f72014-09-11 11:22:33 -070089 try {
90 return pktin.getInPort().getPortNumber();
91 } catch (UnsupportedOperationException e) {
92 return pktin.getMatch().get(MatchField.IN_PORT).getPortNumber();
93 }
alshabibdf652ad2014-09-09 11:53:19 -070094 }
95
alshabib9ee68172014-09-09 14:45:14 -070096 @Override
97 public byte[] unparsed() {
alshabib51622f72014-09-11 11:22:33 -070098
alshabib9ee68172014-09-09 14:45:14 -070099 return pktin.getData().clone();
alshabib51622f72014-09-11 11:22:33 -0700100
alshabib9ee68172014-09-09 14:45:14 -0700101 }
102
alshabibddf02db2014-09-09 14:57:15 -0700103 private OFActionOutput buildOutput(Integer port) {
104 OFActionOutput act = sw.factory().actions()
105 .buildOutput()
106 .setPort(OFPort.of(port))
107 .build();
108 return act;
109 }
110
alshabib63d5afe2014-09-15 09:40:24 -0700111 @Override
alshabib7b2748f2014-09-16 20:21:11 -0700112 public boolean block() {
alshabib63d5afe2014-09-15 09:40:24 -0700113 return free.getAndSet(false);
114 }
115
alshabib7b2748f2014-09-16 20:21:11 -0700116 @Override
117 public boolean isHandled() {
118 return !free.get();
119 }
120
alshabibc4901cd2014-09-05 16:50:40 -0700121}