blob: edb61591441cf826c08d0b1d70dd309f2b83a8e3 [file] [log] [blame]
Carmelo Casconec0fbbee2016-04-27 18:03:36 -07001/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
4 * 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
7 *
8 * 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.
15 */
16
17package org.onosproject.provider.bmv2.packet.impl;
18
19import org.apache.felix.scr.annotations.Activate;
20import org.apache.felix.scr.annotations.Component;
21import org.apache.felix.scr.annotations.Deactivate;
22import org.apache.felix.scr.annotations.Reference;
23import org.apache.felix.scr.annotations.ReferenceCardinality;
24import org.onlab.packet.Ethernet;
25import org.onlab.util.ImmutableByteSequence;
26import org.onosproject.bmv2.api.runtime.Bmv2ControlPlaneServer;
27import org.onosproject.bmv2.api.runtime.Bmv2Device;
28import org.onosproject.core.CoreService;
29import org.onosproject.net.ConnectPoint;
30import org.onosproject.net.Device;
31import org.onosproject.net.DeviceId;
32import org.onosproject.net.PortNumber;
33import org.onosproject.net.device.DeviceService;
34import org.onosproject.net.flow.DefaultTrafficTreatment;
35import org.onosproject.net.flow.TrafficTreatment;
36import org.onosproject.net.packet.DefaultInboundPacket;
37import org.onosproject.net.packet.DefaultOutboundPacket;
38import org.onosproject.net.packet.DefaultPacketContext;
39import org.onosproject.net.packet.InboundPacket;
40import org.onosproject.net.packet.OutboundPacket;
41import org.onosproject.net.packet.PacketContext;
42import org.onosproject.net.packet.PacketProgrammable;
43import org.onosproject.net.packet.PacketProvider;
44import org.onosproject.net.packet.PacketProviderRegistry;
45import org.onosproject.net.packet.PacketProviderService;
46import org.onosproject.net.provider.AbstractProvider;
47import org.onosproject.net.provider.ProviderId;
48import org.slf4j.Logger;
49import org.slf4j.LoggerFactory;
50
51import java.nio.ByteBuffer;
52
53/**
54 * Implementation of a packet provider for BMv2.
55 */
56@Component(immediate = true)
57public class Bmv2PacketProvider extends AbstractProvider implements PacketProvider {
58
59 private static final Logger LOG = LoggerFactory.getLogger(Bmv2PacketProvider.class);
60 private static final String APP_NAME = "org.onosproject.bmv2";
61
62 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
63 protected Bmv2ControlPlaneServer controlPlaneServer;
64
65 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
66 protected CoreService coreService;
67
68 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
69 protected PacketProviderRegistry providerRegistry;
70
71 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
72 protected DeviceService deviceService;
73
74 private PacketProviderService providerService;
75
76 private InternalPacketListener packetListener = new InternalPacketListener();
77
78 /**
79 * Creates a new BMv2 packet provider.
80 */
81 public Bmv2PacketProvider() {
82 super(new ProviderId("bmv2", "org.onosproject.provider.packet"));
83 }
84
85 @Activate
86 protected void activate() {
87 providerService = providerRegistry.register(this);
88 coreService.registerApplication(APP_NAME);
89 controlPlaneServer.addPacketListener(packetListener);
90 LOG.info("Started");
91 }
92
93 @Deactivate
94 public void deactivate() {
95 controlPlaneServer.removePacketListener(packetListener);
96 providerRegistry.unregister(this);
97 providerService = null;
98 LOG.info("Stopped");
99 }
100
101 @Override
102 public void emit(OutboundPacket packet) {
103 if (packet != null) {
104 DeviceId did = packet.sendThrough();
105 Device device = deviceService.getDevice(did);
106 if (device.is(PacketProgrammable.class)) {
107 PacketProgrammable packetProgrammable = device.as(PacketProgrammable.class);
108 packetProgrammable.emit(packet);
109 } else {
110 LOG.info("Unable to send packet, no PacketProgrammable behavior for device {}", did);
111 }
112 }
113 }
114
115 /**
116 * Internal packet context implementation.
117 */
118 private class Bmv2PacketContext extends DefaultPacketContext {
119
120 public Bmv2PacketContext(long time, InboundPacket inPkt, OutboundPacket outPkt, boolean block) {
121 super(time, inPkt, outPkt, block);
122 }
123
124 @Override
125 public void send() {
126 if (!this.block()) {
127 if (this.outPacket().treatment() == null) {
128 TrafficTreatment treatment = (this.treatmentBuilder() == null)
129 ? DefaultTrafficTreatment.emptyTreatment()
130 : this.treatmentBuilder().build();
131 OutboundPacket newPkt = new DefaultOutboundPacket(this.outPacket().sendThrough(),
132 treatment,
133 this.outPacket().data());
134 emit(newPkt);
135 } else {
136 emit(outPacket());
137 }
138 } else {
139 LOG.info("Unable to send, packet context not blocked");
140 }
141 }
142 }
143
144 /**
145 * Internal packet listener to get packet events from the Bmv2ControlPlaneServer.
146 */
147 private class InternalPacketListener implements Bmv2ControlPlaneServer.PacketListener {
148 @Override
149 public void handlePacketIn(Bmv2Device device, int inputPort, long reason, int tableId, int contextId,
150 ImmutableByteSequence packet) {
151
152 Ethernet eth = new Ethernet();
153 eth.deserialize(packet.asArray(), 0, packet.size());
154
155 InboundPacket inPkt = new DefaultInboundPacket(new ConnectPoint(device.asDeviceId(),
156 PortNumber.portNumber(inputPort)),
157 eth, ByteBuffer.wrap(packet.asArray()));
158 OutboundPacket outPkt = new DefaultOutboundPacket(device.asDeviceId(), null,
159 ByteBuffer.wrap(packet.asArray()));
160 PacketContext pktCtx = new Bmv2PacketContext(System.currentTimeMillis(), inPkt, outPkt, false);
161 providerService.processPacket(pktCtx);
162 }
163 }
164}