blob: f05a7ff23d6373ec4a4d8dc76e213c01d4b88523 [file] [log] [blame]
alshabibc4901cd2014-09-05 16:50:40 -07001package org.onlab.onos.of.controller;
2
alshabib289652c2014-09-07 19:09:28 -07003import java.util.Collections;
4
alshabibc4901cd2014-09-05 16:50:40 -07005import org.onlab.packet.Ethernet;
6import org.projectfloodlight.openflow.protocol.OFPacketIn;
7import org.projectfloodlight.openflow.protocol.OFPacketOut;
alshabib289652c2014-09-07 19:09:28 -07008import org.projectfloodlight.openflow.protocol.action.OFAction;
alshabibddf02db2014-09-09 14:57:15 -07009import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
alshabib51622f72014-09-11 11:22:33 -070010import org.projectfloodlight.openflow.protocol.match.MatchField;
alshabib289652c2014-09-07 19:09:28 -070011import org.projectfloodlight.openflow.types.OFBufferId;
alshabibc4901cd2014-09-05 16:50:40 -070012import org.projectfloodlight.openflow.types.OFPort;
13
alshabibe7031562014-09-12 18:17:37 -070014public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext {
alshabibc4901cd2014-09-05 16:50:40 -070015
16 private boolean free = true;
17 private boolean isBuilt = false;
18 private final OpenFlowSwitch sw;
19 private final OFPacketIn pktin;
alshabib289652c2014-09-07 19:09:28 -070020 private OFPacketOut pktout = null;
alshabibc4901cd2014-09-05 16:50:40 -070021
alshabibe7031562014-09-12 18:17:37 -070022 private DefaultOpenFlowPacketContext(OpenFlowSwitch s, OFPacketIn pkt) {
alshabibc4901cd2014-09-05 16:50:40 -070023 this.sw = s;
24 this.pktin = pkt;
25 }
26
27 @Override
28 public void block() {
29 free = false;
30 }
31
32 @Override
33 public void send() {
34 if (free && isBuilt) {
35 sw.sendMsg(pktout);
36 }
37
38 }
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())
48 .setBufferId(pktin.getBufferId())
49 .setActions(Collections.singletonList(act))
alshabib289652c2014-09-07 19:09:28 -070050 .build();
alshabibddf02db2014-09-09 14:57:15 -070051 isBuilt = true;
52 }
53
54 @Override
55 public synchronized void build(Ethernet ethFrame, OFPort outPort) {
56 if (isBuilt) {
57 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)
63 .setActions(Collections.singletonList(act))
64 .setData(ethFrame.serialize())
65 .build();
66 isBuilt = true;
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
alshabibe7031562014-09-12 18:17:37 -070081 public static OpenFlowPacketContext packetContextFromPacketIn(OpenFlowSwitch s, OFPacketIn pkt) {
82 return new DefaultOpenFlowPacketContext(s, pkt);
alshabibc4901cd2014-09-05 16:50:40 -070083 }
84
alshabibdf652ad2014-09-09 11:53:19 -070085 @Override
86 public Integer inPort() {
alshabib51622f72014-09-11 11:22:33 -070087 try {
88 return pktin.getInPort().getPortNumber();
89 } catch (UnsupportedOperationException e) {
90 return pktin.getMatch().get(MatchField.IN_PORT).getPortNumber();
91 }
alshabibdf652ad2014-09-09 11:53:19 -070092 }
93
alshabib9ee68172014-09-09 14:45:14 -070094 @Override
95 public byte[] unparsed() {
alshabib51622f72014-09-11 11:22:33 -070096
alshabib9ee68172014-09-09 14:45:14 -070097 return pktin.getData().clone();
alshabib51622f72014-09-11 11:22:33 -070098
alshabib9ee68172014-09-09 14:45:14 -070099 }
100
alshabibddf02db2014-09-09 14:57:15 -0700101 private OFActionOutput buildOutput(Integer port) {
102 OFActionOutput act = sw.factory().actions()
103 .buildOutput()
104 .setPort(OFPort.of(port))
105 .build();
106 return act;
107 }
108
alshabibc4901cd2014-09-05 16:50:40 -0700109}