blob: 998e4e69aec35f527561a3e6ae000a0e901e693e [file] [log] [blame]
wu2883c762017-07-20 16:24:48 +08001/*
2 * Copyright 2017-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.p4runtime.packet.impl;
18
19
20import org.apache.felix.scr.annotations.Activate;
21import org.apache.felix.scr.annotations.Component;
22import org.apache.felix.scr.annotations.Deactivate;
23import org.apache.felix.scr.annotations.Reference;
24import org.apache.felix.scr.annotations.ReferenceCardinality;
25import org.onosproject.net.Device;
26import org.onosproject.net.DeviceId;
27import org.onosproject.net.device.DeviceService;
28import org.onosproject.net.flow.TrafficTreatment;
29import org.onosproject.net.packet.DefaultOutboundPacket;
30import org.onosproject.net.packet.DefaultPacketContext;
31import org.onosproject.net.packet.InboundPacket;
32import org.onosproject.net.packet.OutboundPacket;
33import org.onosproject.net.packet.PacketProgrammable;
34import org.onosproject.net.packet.PacketProvider;
35import org.onosproject.net.packet.PacketProviderRegistry;
36import org.onosproject.net.packet.PacketProviderService;
37import org.onosproject.net.provider.AbstractProvider;
38import org.onosproject.net.provider.ProviderId;
39import org.onosproject.p4runtime.api.P4RuntimeController;
40import org.onosproject.p4runtime.api.P4RuntimeEvent;
41import org.onosproject.p4runtime.api.P4RuntimeEventListener;
42import org.slf4j.Logger;
43
44import java.nio.ByteBuffer;
45
46import static org.onosproject.net.flow.DefaultTrafficTreatment.emptyTreatment;
47import static org.slf4j.LoggerFactory.getLogger;
48
49/**
50 * Implementation of a packet provider for P4Runtime device.
51 */
52@Component(immediate = true)
53public class P4RuntimePacketProvider extends AbstractProvider implements PacketProvider {
54
55 private final Logger log = getLogger(getClass());
56
57 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
58 protected P4RuntimeController controller;
59
60 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
61 protected PacketProviderRegistry providerRegistry;
62
63 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
64 protected DeviceService deviceService;
65
66 private PacketProviderService providerService;
67
68 private InternalPacketListener packetListener = new InternalPacketListener();
69
70 /**
71 * Creates a new P4Runtime packet provider.
72 */
73 public P4RuntimePacketProvider() {
74 super(new ProviderId("p4runtime", "org.onosproject.provider.p4runtime.packet"));
75 }
76
77 @Activate
78 protected void activate() {
79 providerService = providerRegistry.register(this);
80 controller.addListener(packetListener);
81 log.info("Started");
82 }
83
84 @Deactivate
85 public void deactivate() {
86 controller.removeListener(packetListener);
87 providerRegistry.unregister(this);
88 providerService = null;
89 log.info("Stopped");
90 }
91
92 @Override
93 public void emit(OutboundPacket packet) {
94 if (packet != null) {
95 DeviceId deviceId = packet.sendThrough();
96 Device device = deviceService.getDevice(deviceId);
97 if (device.is(PacketProgrammable.class)) {
98 PacketProgrammable packetProgrammable = device.as(PacketProgrammable.class);
99 packetProgrammable.emit(packet);
100 } else {
101 log.warn("No PacketProgrammable behavior for device {}", deviceId);
102 }
103 }
104 }
105
106 /**
107 * Internal packet context implementation.
108 */
109 private class P4RuntimePacketContext extends DefaultPacketContext {
110
111 P4RuntimePacketContext(long time, InboundPacket inPkt, OutboundPacket outPkt, boolean block) {
112 super(time, inPkt, outPkt, block);
113 }
114
115 @Override
116 public void send() {
117
118 if (this.block()) {
119 log.info("Unable to send, packet context is blocked");
120 return;
121 }
122
123 DeviceId deviceId = outPacket().sendThrough();
124 ByteBuffer rawData = outPacket().data();
125
126 TrafficTreatment treatment;
127 if (outPacket().treatment() == null) {
128 treatment = (treatmentBuilder() == null) ? emptyTreatment() : treatmentBuilder().build();
129 } else {
130 treatment = outPacket().treatment();
131 }
132
133 emit(new DefaultOutboundPacket(deviceId, treatment, rawData));
134 }
135 }
136
137 /**
138 * Internal packet listener to handle packet-in events received from the P4Runtime controller.
139 */
140 private class InternalPacketListener implements P4RuntimeEventListener {
141
142
143 @Override
144 public void event(P4RuntimeEvent event) {
145 /**
146 * TODO: handle packet-in event.
147 * The inputport need parse from metadata() of packet_in event,
148 * but support for parsing metadata() is not ready yet.
149 */
150
151 }
152 }
153}