blob: a1b1a6e2a31657df4ef673e1cb8faeebb3cc13e9 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 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;
Jonathan Hartcc36be82015-04-09 11:54:56 -070022import org.projectfloodlight.openflow.protocol.OFVersion;
tom7ef8ff92014-09-17 13:08:06 -070023import org.projectfloodlight.openflow.protocol.action.OFAction;
24import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
25import org.projectfloodlight.openflow.protocol.match.MatchField;
26import org.projectfloodlight.openflow.types.OFBufferId;
27import org.projectfloodlight.openflow.types.OFPort;
tom1679e182014-10-09 13:50:45 -070028
Jonathan Harte46c0412015-01-20 13:19:55 -080029import java.nio.BufferUnderflowException;
30import java.util.Collections;
31import java.util.concurrent.atomic.AtomicBoolean;
32
Jonathan Hartcc36be82015-04-09 11:54:56 -070033/**
34 * Default implementation of an OpenFlowPacketContext.
35 */
tom7ef8ff92014-09-17 13:08:06 -070036public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext {
37
tom7ef8ff92014-09-17 13:08:06 -070038 private final AtomicBoolean free = new AtomicBoolean(true);
39 private final AtomicBoolean isBuilt = new AtomicBoolean(false);
40 private final OpenFlowSwitch sw;
41 private final OFPacketIn pktin;
42 private OFPacketOut pktout = null;
43
alshabibe9d3a322014-09-23 15:18:33 -070044 private final boolean isBuffered;
45
tom7ef8ff92014-09-17 13:08:06 -070046 private DefaultOpenFlowPacketContext(OpenFlowSwitch s, OFPacketIn pkt) {
47 this.sw = s;
48 this.pktin = pkt;
alshabibe9d3a322014-09-23 15:18:33 -070049 this.isBuffered = pktin.getBufferId() != OFBufferId.NO_BUFFER;
tom7ef8ff92014-09-17 13:08:06 -070050 }
51
52 @Override
53 public void send() {
54 if (block() && isBuilt.get()) {
55 sw.sendMsg(pktout);
56 }
57 }
58
59 @Override
60 public void build(OFPort outPort) {
61 if (isBuilt.getAndSet(true)) {
62 return;
63 }
64 OFPacketOut.Builder builder = sw.factory().buildPacketOut();
65 OFAction act = buildOutput(outPort.getPortNumber());
66 pktout = builder.setXid(pktin.getXid())
Pavlin Radoslavov20318992015-02-04 13:41:14 -080067 .setInPort(pktinInPort())
Thomas Vachuska5f998492014-10-31 00:46:11 -070068 .setBufferId(OFBufferId.NO_BUFFER)
69 .setData(pktin.getData())
70// .setBufferId(pktin.getBufferId())
tom7ef8ff92014-09-17 13:08:06 -070071 .setActions(Collections.singletonList(act))
72 .build();
73 }
74
75 @Override
76 public void build(Ethernet ethFrame, OFPort outPort) {
77 if (isBuilt.getAndSet(true)) {
78 return;
79 }
80 OFPacketOut.Builder builder = sw.factory().buildPacketOut();
81 OFAction act = buildOutput(outPort.getPortNumber());
82 pktout = builder.setXid(pktin.getXid())
83 .setBufferId(OFBufferId.NO_BUFFER)
Pavlin Radoslavov20318992015-02-04 13:41:14 -080084 .setInPort(pktinInPort())
tom7ef8ff92014-09-17 13:08:06 -070085 .setActions(Collections.singletonList(act))
86 .setData(ethFrame.serialize())
87 .build();
88 }
89
90 @Override
91 public Ethernet parsed() {
92 Ethernet eth = new Ethernet();
Jonathan Harte8600eb2015-01-12 10:30:45 -080093 try {
94 eth.deserialize(pktin.getData(), 0, pktin.getData().length);
95 return eth;
Jonathan Harte46c0412015-01-20 13:19:55 -080096 } catch (BufferUnderflowException | NullPointerException e) {
Jonathan Harte8600eb2015-01-12 10:30:45 -080097 return null;
98 }
tom7ef8ff92014-09-17 13:08:06 -070099 }
100
101 @Override
102 public Dpid dpid() {
103 return new Dpid(sw.getId());
104 }
105
Jonathan Hartcc36be82015-04-09 11:54:56 -0700106 /**
107 * Creates an OpenFlow packet context based on a packet-in.
108 *
109 * @param s OpenFlow switch
110 * @param pkt OpenFlow packet-in
111 * @return the OpenFlow packet context
112 */
tom7ef8ff92014-09-17 13:08:06 -0700113 public static OpenFlowPacketContext packetContextFromPacketIn(OpenFlowSwitch s,
tom1679e182014-10-09 13:50:45 -0700114 OFPacketIn pkt) {
tom7ef8ff92014-09-17 13:08:06 -0700115 return new DefaultOpenFlowPacketContext(s, pkt);
116 }
117
118 @Override
119 public Integer inPort() {
Pavlin Radoslavov20318992015-02-04 13:41:14 -0800120 return pktinInPort().getPortNumber();
alshabib6eb438a2014-10-01 16:39:37 -0700121 }
122
Pavlin Radoslavov20318992015-02-04 13:41:14 -0800123 private OFPort pktinInPort() {
Jonathan Hartcc36be82015-04-09 11:54:56 -0700124 if (pktin.getVersion() == OFVersion.OF_10) {
alshabib6eb438a2014-10-01 16:39:37 -0700125 return pktin.getInPort();
tom7ef8ff92014-09-17 13:08:06 -0700126 }
Jonathan Hartcc36be82015-04-09 11:54:56 -0700127 return pktin.getMatch().get(MatchField.IN_PORT);
tom7ef8ff92014-09-17 13:08:06 -0700128 }
129
130 @Override
131 public byte[] unparsed() {
132
133 return pktin.getData().clone();
134
135 }
136
137 private OFActionOutput buildOutput(Integer port) {
138 OFActionOutput act = sw.factory().actions()
139 .buildOutput()
140 .setPort(OFPort.of(port))
141 .build();
142 return act;
143 }
144
145 @Override
146 public boolean block() {
147 return free.getAndSet(false);
148 }
149
150 @Override
151 public boolean isHandled() {
152 return !free.get();
153 }
154
alshabibe9d3a322014-09-23 15:18:33 -0700155 @Override
156 public boolean isBuffered() {
157 return isBuffered;
158 }
159
tom7ef8ff92014-09-17 13:08:06 -0700160}