blob: 965426659df5c9e641013768557cc4c3fea811f1 [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() {
alshabib63d5afe2014-09-15 09:40:24 -070035 if (blocked() && 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)
64 .setActions(Collections.singletonList(act))
65 .setData(ethFrame.serialize())
66 .build();
67 isBuilt = true;
alshabibc4901cd2014-09-05 16:50:40 -070068 }
69
70 @Override
71 public Ethernet parsed() {
alshabib289652c2014-09-07 19:09:28 -070072 Ethernet eth = new Ethernet();
73 eth.deserialize(pktin.getData(), 0, pktin.getTotalLen());
74 return eth;
alshabibc4901cd2014-09-05 16:50:40 -070075 }
76
77 @Override
78 public Dpid dpid() {
alshabib289652c2014-09-07 19:09:28 -070079 return new Dpid(sw.getId());
alshabibc4901cd2014-09-05 16:50:40 -070080 }
81
alshabibe7031562014-09-12 18:17:37 -070082 public static OpenFlowPacketContext packetContextFromPacketIn(OpenFlowSwitch s, OFPacketIn pkt) {
83 return new DefaultOpenFlowPacketContext(s, pkt);
alshabibc4901cd2014-09-05 16:50:40 -070084 }
85
alshabibdf652ad2014-09-09 11:53:19 -070086 @Override
87 public Integer inPort() {
alshabib51622f72014-09-11 11:22:33 -070088 try {
89 return pktin.getInPort().getPortNumber();
90 } catch (UnsupportedOperationException e) {
91 return pktin.getMatch().get(MatchField.IN_PORT).getPortNumber();
92 }
alshabibdf652ad2014-09-09 11:53:19 -070093 }
94
alshabib9ee68172014-09-09 14:45:14 -070095 @Override
96 public byte[] unparsed() {
alshabib51622f72014-09-11 11:22:33 -070097
alshabib9ee68172014-09-09 14:45:14 -070098 return pktin.getData().clone();
alshabib51622f72014-09-11 11:22:33 -070099
alshabib9ee68172014-09-09 14:45:14 -0700100 }
101
alshabibddf02db2014-09-09 14:57:15 -0700102 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
alshabib63d5afe2014-09-15 09:40:24 -0700110 @Override
111 public boolean blocked() {
112 return free.getAndSet(false);
113 }
114
alshabibc4901cd2014-09-05 16:50:40 -0700115}