blob: 7a265a07172bdff5b47d1644ba42824a475afece [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.openflow.controller;
tom7ef8ff92014-09-17 13:08:06 -070017
Marc De Leenheer49087752014-10-23 13:54:09 -070018
tom7ef8ff92014-09-17 13:08:06 -070019import org.onlab.packet.Ethernet;
20import org.projectfloodlight.openflow.protocol.OFPacketIn;
21import org.projectfloodlight.openflow.protocol.OFPacketOut;
22import org.projectfloodlight.openflow.protocol.action.OFAction;
23import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
24import org.projectfloodlight.openflow.protocol.match.MatchField;
25import org.projectfloodlight.openflow.types.OFBufferId;
26import org.projectfloodlight.openflow.types.OFPort;
tom1679e182014-10-09 13:50:45 -070027
Jonathan Harte46c0412015-01-20 13:19:55 -080028import java.nio.BufferUnderflowException;
29import java.util.Collections;
30import java.util.concurrent.atomic.AtomicBoolean;
31
tom7ef8ff92014-09-17 13:08:06 -070032public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext {
33
tom7ef8ff92014-09-17 13:08:06 -070034 private final AtomicBoolean free = new AtomicBoolean(true);
35 private final AtomicBoolean isBuilt = new AtomicBoolean(false);
36 private final OpenFlowSwitch sw;
37 private final OFPacketIn pktin;
38 private OFPacketOut pktout = null;
39
alshabibe9d3a322014-09-23 15:18:33 -070040 private final boolean isBuffered;
41
tom7ef8ff92014-09-17 13:08:06 -070042 private DefaultOpenFlowPacketContext(OpenFlowSwitch s, OFPacketIn pkt) {
43 this.sw = s;
44 this.pktin = pkt;
alshabibe9d3a322014-09-23 15:18:33 -070045 this.isBuffered = pktin.getBufferId() != OFBufferId.NO_BUFFER;
tom7ef8ff92014-09-17 13:08:06 -070046 }
47
48 @Override
49 public void send() {
50 if (block() && isBuilt.get()) {
51 sw.sendMsg(pktout);
52 }
53 }
54
55 @Override
56 public void build(OFPort outPort) {
57 if (isBuilt.getAndSet(true)) {
58 return;
59 }
60 OFPacketOut.Builder builder = sw.factory().buildPacketOut();
61 OFAction act = buildOutput(outPort.getPortNumber());
62 pktout = builder.setXid(pktin.getXid())
Pavlin Radoslavov20318992015-02-04 13:41:14 -080063 .setInPort(pktinInPort())
Thomas Vachuska5f998492014-10-31 00:46:11 -070064 .setBufferId(OFBufferId.NO_BUFFER)
65 .setData(pktin.getData())
66// .setBufferId(pktin.getBufferId())
tom7ef8ff92014-09-17 13:08:06 -070067 .setActions(Collections.singletonList(act))
68 .build();
69 }
70
71 @Override
72 public void build(Ethernet ethFrame, OFPort outPort) {
73 if (isBuilt.getAndSet(true)) {
74 return;
75 }
76 OFPacketOut.Builder builder = sw.factory().buildPacketOut();
77 OFAction act = buildOutput(outPort.getPortNumber());
78 pktout = builder.setXid(pktin.getXid())
79 .setBufferId(OFBufferId.NO_BUFFER)
Pavlin Radoslavov20318992015-02-04 13:41:14 -080080 .setInPort(pktinInPort())
tom7ef8ff92014-09-17 13:08:06 -070081 .setActions(Collections.singletonList(act))
82 .setData(ethFrame.serialize())
83 .build();
84 }
85
86 @Override
87 public Ethernet parsed() {
88 Ethernet eth = new Ethernet();
Jonathan Harte8600eb2015-01-12 10:30:45 -080089 try {
90 eth.deserialize(pktin.getData(), 0, pktin.getData().length);
91 return eth;
Jonathan Harte46c0412015-01-20 13:19:55 -080092 } catch (BufferUnderflowException | NullPointerException e) {
Jonathan Harte8600eb2015-01-12 10:30:45 -080093 return null;
94 }
tom7ef8ff92014-09-17 13:08:06 -070095 }
96
97 @Override
98 public Dpid dpid() {
99 return new Dpid(sw.getId());
100 }
101
102 public static OpenFlowPacketContext packetContextFromPacketIn(OpenFlowSwitch s,
tom1679e182014-10-09 13:50:45 -0700103 OFPacketIn pkt) {
tom7ef8ff92014-09-17 13:08:06 -0700104 return new DefaultOpenFlowPacketContext(s, pkt);
105 }
106
107 @Override
108 public Integer inPort() {
Pavlin Radoslavov20318992015-02-04 13:41:14 -0800109 return pktinInPort().getPortNumber();
alshabib6eb438a2014-10-01 16:39:37 -0700110 }
111
Pavlin Radoslavov20318992015-02-04 13:41:14 -0800112 private OFPort pktinInPort() {
Jonathan Harte1588ed2014-12-03 17:26:51 -0800113 //FIXME: this has to change in loxi
tom7ef8ff92014-09-17 13:08:06 -0700114 try {
alshabib6eb438a2014-10-01 16:39:37 -0700115 return pktin.getInPort();
tom7ef8ff92014-09-17 13:08:06 -0700116 } catch (UnsupportedOperationException e) {
alshabib6eb438a2014-10-01 16:39:37 -0700117 return pktin.getMatch().get(MatchField.IN_PORT);
tom7ef8ff92014-09-17 13:08:06 -0700118 }
119 }
120
121 @Override
122 public byte[] unparsed() {
123
124 return pktin.getData().clone();
125
126 }
127
128 private OFActionOutput buildOutput(Integer port) {
129 OFActionOutput act = sw.factory().actions()
130 .buildOutput()
131 .setPort(OFPort.of(port))
132 .build();
133 return act;
134 }
135
136 @Override
137 public boolean block() {
138 return free.getAndSet(false);
139 }
140
141 @Override
142 public boolean isHandled() {
143 return !free.get();
144 }
145
alshabibe9d3a322014-09-23 15:18:33 -0700146 @Override
147 public boolean isBuffered() {
148 return isBuffered;
149 }
150
tom7ef8ff92014-09-17 13:08:06 -0700151}