blob: 45f615a67aad40ddb103950f8c03ebd296884e47 [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);
alshabib9842a4e2014-09-16 21:42:35 -070023 private final AtomicBoolean isBuilt = new AtomicBoolean(false);
alshabibc4901cd2014-09-05 16:50:40 -070024 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() {
alshabib9842a4e2014-09-16 21:42:35 -070035 if (block() && isBuilt.get()) {
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
alshabib9842a4e2014-09-16 21:42:35 -070041 public void build(OFPort outPort) {
42 if (isBuilt.getAndSet(true)) {
alshabib289652c2014-09-07 19:09:28 -070043 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 }
53
54 @Override
alshabib9842a4e2014-09-16 21:42:35 -070055 public void build(Ethernet ethFrame, OFPort outPort) {
56 if (isBuilt.getAndSet(true)) {
alshabibddf02db2014-09-09 14:57:15 -070057 return;
58 }
59 OFPacketOut.Builder builder = sw.factory().buildPacketOut();
60 OFAction act = buildOutput(outPort.getPortNumber());
alshabib289652c2014-09-07 19:09:28 -070061 pktout = builder.setXid(pktin.getXid())
62 .setBufferId(OFBufferId.NO_BUFFER)
alshabibf4f463b2014-09-15 10:06:32 -070063 .setInPort(pktin.getInPort())
alshabib289652c2014-09-07 19:09:28 -070064 .setActions(Collections.singletonList(act))
65 .setData(ethFrame.serialize())
66 .build();
alshabibc4901cd2014-09-05 16:50:40 -070067 }
68
69 @Override
70 public Ethernet parsed() {
alshabib289652c2014-09-07 19:09:28 -070071 Ethernet eth = new Ethernet();
72 eth.deserialize(pktin.getData(), 0, pktin.getTotalLen());
73 return eth;
alshabibc4901cd2014-09-05 16:50:40 -070074 }
75
76 @Override
77 public Dpid dpid() {
alshabib289652c2014-09-07 19:09:28 -070078 return new Dpid(sw.getId());
alshabibc4901cd2014-09-05 16:50:40 -070079 }
80
alshabibe79bf952014-09-17 09:22:51 -070081 public static OpenFlowPacketContext packetContextFromPacketIn(OpenFlowSwitch s,
82 OFPacketIn pkt) {
alshabibe7031562014-09-12 18:17:37 -070083 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
alshabib7b2748f2014-09-16 20:21:11 -0700111 public boolean block() {
alshabib63d5afe2014-09-15 09:40:24 -0700112 return free.getAndSet(false);
113 }
114
alshabib7b2748f2014-09-16 20:21:11 -0700115 @Override
116 public boolean isHandled() {
117 return !free.get();
118 }
119
alshabibc4901cd2014-09-05 16:50:40 -0700120}