blob: 5f453df2553fdb27b6b9c7054088cdd563180c5e [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())
alshabib6eb438a2014-10-01 16:39:37 -070063 .setInPort(inport())
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)
alshabib6eb438a2014-10-01 16:39:37 -070080 .setInPort(inport())
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() {
alshabib6eb438a2014-10-01 16:39:37 -0700109 return inport().getPortNumber();
110 }
111
112
113 private OFPort inport() {
Jonathan Harte1588ed2014-12-03 17:26:51 -0800114 //FIXME: this has to change in loxi
tom7ef8ff92014-09-17 13:08:06 -0700115 try {
alshabib6eb438a2014-10-01 16:39:37 -0700116 return pktin.getInPort();
tom7ef8ff92014-09-17 13:08:06 -0700117 } catch (UnsupportedOperationException e) {
alshabib6eb438a2014-10-01 16:39:37 -0700118 return pktin.getMatch().get(MatchField.IN_PORT);
tom7ef8ff92014-09-17 13:08:06 -0700119 }
120 }
121
122 @Override
123 public byte[] unparsed() {
124
125 return pktin.getData().clone();
126
127 }
128
129 private OFActionOutput buildOutput(Integer port) {
130 OFActionOutput act = sw.factory().actions()
131 .buildOutput()
132 .setPort(OFPort.of(port))
133 .build();
134 return act;
135 }
136
137 @Override
138 public boolean block() {
139 return free.getAndSet(false);
140 }
141
142 @Override
143 public boolean isHandled() {
144 return !free.get();
145 }
146
alshabibe9d3a322014-09-23 15:18:33 -0700147 @Override
148 public boolean isBuffered() {
149 return isBuffered;
150 }
151
tom7ef8ff92014-09-17 13:08:06 -0700152}